diff options
Diffstat (limited to 'target-s390x/op_helper.c')
-rw-r--r-- | target-s390x/op_helper.c | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c index cd57678150..137bae74a0 100644 --- a/target-s390x/op_helper.c +++ b/target-s390x/op_helper.c @@ -29,6 +29,10 @@ #include <linux/kvm.h> #endif +#if !defined (CONFIG_USER_ONLY) +#include "sysemu.h" +#endif + /*****************************************************************************/ /* Softmmu support */ #if !defined (CONFIG_USER_ONLY) @@ -1631,6 +1635,15 @@ void HELPER(maebr)(uint32_t f1, uint32_t f3, uint32_t f2) &env->fpu_status); } +/* convert 32-bit float to 64-bit float */ +void HELPER(ldeb)(uint32_t f1, uint64_t a2) +{ + uint32_t v2; + v2 = ldl(a2); + env->fregs[f1].d = float32_to_float64(v2, + &env->fpu_status); +} + /* convert 64-bit float to 128-bit float */ void HELPER(lxdb)(uint32_t f1, uint64_t a2) { @@ -2752,7 +2765,6 @@ uint64_t HELPER(iske)(uint64_t r2) return 0; } - /* XXX maybe use qemu's internal keys? */ return env->storage_keys[addr / TARGET_PAGE_SIZE]; } @@ -2771,14 +2783,15 @@ void HELPER(sske)(uint32_t r1, uint64_t r2) /* reset reference bit extended */ uint32_t HELPER(rrbe)(uint32_t r1, uint64_t r2) { + uint8_t re; + uint8_t key; if (r2 > ram_size) { return 0; } - /* XXX implement */ -#if 0 - env->storage_keys[r2 / TARGET_PAGE_SIZE] &= ~SK_REFERENCED; -#endif + key = env->storage_keys[r2 / TARGET_PAGE_SIZE]; + re = key & (SK_R | SK_C); + env->storage_keys[r2 / TARGET_PAGE_SIZE] = (key & ~SK_R); /* * cc @@ -2788,7 +2801,8 @@ uint32_t HELPER(rrbe)(uint32_t r1, uint64_t r2) * 2 Reference bit one; change bit zero * 3 Reference bit one; change bit one */ - return 0; + + return re >> 1; } /* compare and swap and purge */ @@ -2891,6 +2905,16 @@ uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr) env->regs[r1] &= 0xffffffff00000000ULL; cc = 1; break; +#if !defined (CONFIG_USER_ONLY) + case SIGP_RESTART: + qemu_system_reset_request(); + cpu_loop_exit(env); + break; + case SIGP_STOP: + qemu_system_shutdown_request(); + cpu_loop_exit(env); + break; +#endif default: /* unknown sigp */ fprintf(stderr, "XXX unknown sigp: 0x%" PRIx64 "\n", order_code); @@ -2941,6 +2965,13 @@ void HELPER(ipte)(uint64_t pte_addr, uint64_t vaddr) /* XXX we exploit the fact that Linux passes the exact virtual address here - it's not obliged to! */ tlb_flush_page(env, page); + + /* XXX 31-bit hack */ + if (page & 0x80000000) { + tlb_flush_page(env, page & ~0x80000000); + } else { + tlb_flush_page(env, page | 0x80000000); + } } /* flush local tlb */ |