* [Qemu-devel] [PATCH 01/12] target-s390x: fix style
2012-09-10 11:40 [Qemu-devel] [PULL 00/12] s390 patch queue 2012-09-10 Alexander Graf
@ 2012-09-10 11:40 ` Alexander Graf
2012-09-10 11:40 ` [Qemu-devel] [PATCH 02/12] target-s390x: split FPU ops Alexander Graf
` (11 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Alexander Graf @ 2012-09-10 11:40 UTC (permalink / raw)
To: qemu-devel qemu-devel; +Cc: Blue Swirl, Aurelien Jarno
From: Blue Swirl <blauwirbel@gmail.com>
Before splitting op_helper.c and helper.c in the next patches,
fix style issues. No functional changes.
Replace also GCC specific __FUNCTION__ with
standard __func__.
Don't init static variable (cpu_s390x_init:inited) with 0.
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-s390x/helper.c | 96 +++++-----
target-s390x/op_helper.c | 438 ++++++++++++++++++++++++++--------------------
2 files changed, 297 insertions(+), 237 deletions(-)
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index d0a1180..d98e6d9 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -74,7 +74,7 @@ S390CPU *cpu_s390x_init(const char *cpu_model)
{
S390CPU *cpu;
CPUS390XState *env;
- static int inited = 0;
+ static int inited;
cpu = S390_CPU(object_new(TYPE_S390_CPU));
env = &cpu->env;
@@ -91,25 +91,27 @@ S390CPU *cpu_s390x_init(const char *cpu_model)
#if defined(CONFIG_USER_ONLY)
-void do_interrupt (CPUS390XState *env)
+void do_interrupt(CPUS390XState *env)
{
env->exception_index = -1;
}
-int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw,
- int mmu_idx)
+int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong address,
+ int rw, int mmu_idx)
{
- /* fprintf(stderr,"%s: address 0x%lx rw %d mmu_idx %d\n",
- __FUNCTION__, address, rw, mmu_idx); */
+ /* fprintf(stderr, "%s: address 0x%lx rw %d mmu_idx %d\n",
+ __func__, address, rw, mmu_idx); */
env->exception_index = EXCP_ADDR;
- env->__excp_addr = address; /* FIXME: find out how this works on a real machine */
+ /* FIXME: find out how this works on a real machine */
+ env->__excp_addr = address;
return 1;
}
#else /* !CONFIG_USER_ONLY */
/* Ensure to exit the TB after this call! */
-static void trigger_pgm_exception(CPUS390XState *env, uint32_t code, uint32_t ilc)
+static void trigger_pgm_exception(CPUS390XState *env, uint32_t code,
+ uint32_t ilc)
{
env->exception_index = EXCP_PGM;
env->int_pgm_code = code;
@@ -138,19 +140,20 @@ static int trans_bits(CPUS390XState *env, uint64_t mode)
return bits;
}
-static void trigger_prot_fault(CPUS390XState *env, target_ulong vaddr, uint64_t mode)
+static void trigger_prot_fault(CPUS390XState *env, target_ulong vaddr,
+ uint64_t mode)
{
int ilc = ILC_LATER_INC_2;
int bits = trans_bits(env, mode) | 4;
- DPRINTF("%s: vaddr=%016" PRIx64 " bits=%d\n", __FUNCTION__, vaddr, bits);
+ DPRINTF("%s: vaddr=%016" PRIx64 " bits=%d\n", __func__, vaddr, bits);
stq_phys(env->psa + offsetof(LowCore, trans_exc_code), vaddr | bits);
trigger_pgm_exception(env, PGM_PROTECTION, ilc);
}
-static void trigger_page_fault(CPUS390XState *env, target_ulong vaddr, uint32_t type,
- uint64_t asc, int rw)
+static void trigger_page_fault(CPUS390XState *env, target_ulong vaddr,
+ uint32_t type, uint64_t asc, int rw)
{
int ilc = ILC_LATER;
int bits = trans_bits(env, asc);
@@ -160,26 +163,26 @@ static void trigger_page_fault(CPUS390XState *env, target_ulong vaddr, uint32_t
ilc = 2;
}
- DPRINTF("%s: vaddr=%016" PRIx64 " bits=%d\n", __FUNCTION__, vaddr, bits);
+ DPRINTF("%s: vaddr=%016" PRIx64 " bits=%d\n", __func__, vaddr, bits);
stq_phys(env->psa + offsetof(LowCore, trans_exc_code), vaddr | bits);
trigger_pgm_exception(env, type, ilc);
}
-static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, uint64_t asc,
- uint64_t asce, int level, target_ulong *raddr,
- int *flags, int rw)
+static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr,
+ uint64_t asc, uint64_t asce, int level,
+ target_ulong *raddr, int *flags, int rw)
{
uint64_t offs = 0;
uint64_t origin;
uint64_t new_asce;
- PTE_DPRINTF("%s: 0x%" PRIx64 "\n", __FUNCTION__, asce);
+ PTE_DPRINTF("%s: 0x%" PRIx64 "\n", __func__, asce);
if (((level != _ASCE_TYPE_SEGMENT) && (asce & _REGION_ENTRY_INV)) ||
((level == _ASCE_TYPE_SEGMENT) && (asce & _SEGMENT_ENTRY_INV))) {
/* XXX different regions have different faults */
- DPRINTF("%s: invalid region\n", __FUNCTION__);
+ DPRINTF("%s: invalid region\n", __func__);
trigger_page_fault(env, vaddr, PGM_SEGMENT_TRANS, asc, rw);
return -1;
}
@@ -222,7 +225,7 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, uint64_t a
new_asce = ldq_phys(origin + offs);
PTE_DPRINTF("%s: 0x%" PRIx64 " + 0x%" PRIx64 " => 0x%016" PRIx64 "\n",
- __FUNCTION__, origin, offs, new_asce);
+ __func__, origin, offs, new_asce);
if (level != _ASCE_TYPE_SEGMENT) {
/* yet another region */
@@ -232,7 +235,7 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, uint64_t a
/* PTE */
if (new_asce & _PAGE_INVALID) {
- DPRINTF("%s: PTE=0x%" PRIx64 " invalid\n", __FUNCTION__, new_asce);
+ DPRINTF("%s: PTE=0x%" PRIx64 " invalid\n", __func__, new_asce);
trigger_page_fault(env, vaddr, PGM_PAGE_TRANS, asc, rw);
return -1;
}
@@ -243,13 +246,14 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, uint64_t a
*raddr = new_asce & _ASCE_ORIGIN;
- PTE_DPRINTF("%s: PTE=0x%" PRIx64 "\n", __FUNCTION__, new_asce);
+ PTE_DPRINTF("%s: PTE=0x%" PRIx64 "\n", __func__, new_asce);
return 0;
}
-static int mmu_translate_asc(CPUS390XState *env, target_ulong vaddr, uint64_t asc,
- target_ulong *raddr, int *flags, int rw)
+static int mmu_translate_asc(CPUS390XState *env, target_ulong vaddr,
+ uint64_t asc, target_ulong *raddr, int *flags,
+ int rw)
{
uint64_t asce = 0;
int level, new_level;
@@ -257,15 +261,15 @@ static int mmu_translate_asc(CPUS390XState *env, target_ulong vaddr, uint64_t as
switch (asc) {
case PSW_ASC_PRIMARY:
- PTE_DPRINTF("%s: asc=primary\n", __FUNCTION__);
+ PTE_DPRINTF("%s: asc=primary\n", __func__);
asce = env->cregs[1];
break;
case PSW_ASC_SECONDARY:
- PTE_DPRINTF("%s: asc=secondary\n", __FUNCTION__);
+ PTE_DPRINTF("%s: asc=secondary\n", __func__);
asce = env->cregs[7];
break;
case PSW_ASC_HOME:
- PTE_DPRINTF("%s: asc=home\n", __FUNCTION__);
+ PTE_DPRINTF("%s: asc=home\n", __func__);
asce = env->cregs[13];
break;
}
@@ -276,8 +280,7 @@ static int mmu_translate_asc(CPUS390XState *env, target_ulong vaddr, uint64_t as
case _ASCE_TYPE_REGION2:
if (vaddr & 0xffe0000000000000ULL) {
DPRINTF("%s: vaddr doesn't fit 0x%16" PRIx64
- " 0xffe0000000000000ULL\n", __FUNCTION__,
- vaddr);
+ " 0xffe0000000000000ULL\n", __func__, vaddr);
trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw);
return -1;
}
@@ -285,8 +288,7 @@ static int mmu_translate_asc(CPUS390XState *env, target_ulong vaddr, uint64_t as
case _ASCE_TYPE_REGION3:
if (vaddr & 0xfffffc0000000000ULL) {
DPRINTF("%s: vaddr doesn't fit 0x%16" PRIx64
- " 0xfffffc0000000000ULL\n", __FUNCTION__,
- vaddr);
+ " 0xfffffc0000000000ULL\n", __func__, vaddr);
trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw);
return -1;
}
@@ -294,8 +296,7 @@ static int mmu_translate_asc(CPUS390XState *env, target_ulong vaddr, uint64_t as
case _ASCE_TYPE_SEGMENT:
if (vaddr & 0xffffffff80000000ULL) {
DPRINTF("%s: vaddr doesn't fit 0x%16" PRIx64
- " 0xffffffff80000000ULL\n", __FUNCTION__,
- vaddr);
+ " 0xffffffff80000000ULL\n", __func__, vaddr);
trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw);
return -1;
}
@@ -358,7 +359,7 @@ int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
break;
}
-out:
+ out:
/* Convert real address -> absolute address */
if (*raddr < 0x2000) {
*raddr = *raddr + env->psa;
@@ -378,18 +379,18 @@ out:
return r;
}
-int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong _vaddr, int rw,
- int mmu_idx)
+int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong orig_vaddr,
+ int rw, int mmu_idx)
{
uint64_t asc = env->psw.mask & PSW_MASK_ASC;
target_ulong vaddr, raddr;
int prot;
DPRINTF("%s: address 0x%" PRIx64 " rw %d mmu_idx %d\n",
- __FUNCTION__, _vaddr, rw, mmu_idx);
+ __func__, _vaddr, rw, mmu_idx);
- _vaddr &= TARGET_PAGE_MASK;
- vaddr = _vaddr;
+ orig_vaddr &= TARGET_PAGE_MASK;
+ vaddr = orig_vaddr;
/* 31-Bit mode */
if (!(env->psw.mask & PSW_MASK_64)) {
@@ -403,22 +404,23 @@ int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong _vaddr, int rw,
/* check out of RAM access */
if (raddr > (ram_size + virtio_size)) {
- DPRINTF("%s: aaddr %" PRIx64 " > ram_size %" PRIx64 "\n", __FUNCTION__,
+ DPRINTF("%s: aaddr %" PRIx64 " > ram_size %" PRIx64 "\n", __func__,
(uint64_t)aaddr, (uint64_t)ram_size);
trigger_pgm_exception(env, PGM_ADDRESSING, ILC_LATER);
return 1;
}
- DPRINTF("%s: set tlb %" PRIx64 " -> %" PRIx64 " (%x)\n", __FUNCTION__,
+ DPRINTF("%s: set tlb %" PRIx64 " -> %" PRIx64 " (%x)\n", __func__,
(uint64_t)vaddr, (uint64_t)raddr, prot);
- tlb_set_page(env, _vaddr, raddr, prot,
+ tlb_set_page(env, orig_vaddr, raddr, prot,
mmu_idx, TARGET_PAGE_SIZE);
return 0;
}
-target_phys_addr_t cpu_get_phys_page_debug(CPUS390XState *env, target_ulong vaddr)
+target_phys_addr_t cpu_get_phys_page_debug(CPUS390XState *env,
+ target_ulong vaddr)
{
target_ulong raddr;
int prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
@@ -509,7 +511,7 @@ static void do_program_interrupt(CPUS390XState *env)
break;
}
- qemu_log("%s: code=0x%x ilc=%d\n", __FUNCTION__, env->int_pgm_code, ilc);
+ qemu_log("%s: code=0x%x ilc=%d\n", __func__, env->int_pgm_code, ilc);
lowcore = cpu_physical_memory_map(env->psa, &len, 1);
@@ -522,7 +524,7 @@ static void do_program_interrupt(CPUS390XState *env)
cpu_physical_memory_unmap(lowcore, len, 1, len);
- DPRINTF("%s: %x %x %" PRIx64 " %" PRIx64 "\n", __FUNCTION__,
+ DPRINTF("%s: %x %x %" PRIx64 " %" PRIx64 "\n", __func__,
env->int_pgm_code, ilc, env->psw.mask,
env->psw.addr);
@@ -565,15 +567,15 @@ static void do_ext_interrupt(CPUS390XState *env)
env->pending_int &= ~INTERRUPT_EXT;
}
- DPRINTF("%s: %" PRIx64 " %" PRIx64 "\n", __FUNCTION__,
+ DPRINTF("%s: %" PRIx64 " %" PRIx64 "\n", __func__,
env->psw.mask, env->psw.addr);
load_psw(env, mask, addr);
}
-void do_interrupt (CPUS390XState *env)
+void do_interrupt(CPUS390XState *env)
{
- qemu_log("%s: %d at pc=%" PRIx64 "\n", __FUNCTION__, env->exception_index,
+ qemu_log("%s: %d at pc=%" PRIx64 "\n", __func__, env->exception_index,
env->psw.addr);
s390_add_running_cpu(env);
diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
index abc35dd..195e93e 100644
--- a/target-s390x/op_helper.c
+++ b/target-s390x/op_helper.c
@@ -31,13 +31,13 @@
#include <linux/kvm.h>
#endif
-#if !defined (CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
#include "sysemu.h"
#endif
/*****************************************************************************/
/* Softmmu support */
-#if !defined (CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
#define MMUSUFFIX _mmu
@@ -95,7 +95,7 @@ void tlb_fill(CPUS390XState *env1, target_ulong addr, int is_write, int mmu_idx,
/* raise an exception */
void HELPER(exception)(uint32_t excp)
{
- HELPER_LOG("%s: exception %d\n", __FUNCTION__, excp);
+ HELPER_LOG("%s: exception %d\n", __func__, excp);
env->exception_index = excp;
cpu_loop_exit(env);
}
@@ -164,7 +164,7 @@ uint32_t HELPER(nc)(uint32_t l, uint64_t dest, uint64_t src)
uint32_t cc = 0;
HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
- __FUNCTION__, l, dest, src);
+ __func__, l, dest, src);
for (i = 0; i <= l; i++) {
x = ldub(dest + i) & ldub(src + i);
if (x) {
@@ -183,7 +183,7 @@ uint32_t HELPER(xc)(uint32_t l, uint64_t dest, uint64_t src)
uint32_t cc = 0;
HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
- __FUNCTION__, l, dest, src);
+ __func__, l, dest, src);
#ifndef CONFIG_USER_ONLY
/* xor with itself is the same as memset(0) */
@@ -217,7 +217,7 @@ uint32_t HELPER(oc)(uint32_t l, uint64_t dest, uint64_t src)
uint32_t cc = 0;
HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
- __FUNCTION__, l, dest, src);
+ __func__, l, dest, src);
for (i = 0; i <= l; i++) {
x = ldub(dest + i) | ldub(src + i);
if (x) {
@@ -236,7 +236,7 @@ void HELPER(mvc)(uint32_t l, uint64_t dest, uint64_t src)
uint32_t l_64 = (l + 1) / 8;
HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
- __FUNCTION__, l, dest, src);
+ __func__, l, dest, src);
#ifndef CONFIG_USER_ONLY
if ((l > 32) &&
@@ -278,10 +278,11 @@ void HELPER(mvc)(uint32_t l, uint64_t dest, uint64_t src)
uint32_t HELPER(clc)(uint32_t l, uint64_t s1, uint64_t s2)
{
int i;
- unsigned char x,y;
+ unsigned char x, y;
uint32_t cc;
+
HELPER_LOG("%s l %d s1 %" PRIx64 " s2 %" PRIx64 "\n",
- __FUNCTION__, l, s1, s2);
+ __func__, l, s1, s2);
for (i = 0; i <= l; i++) {
x = ldub(s1 + i);
y = ldub(s2 + i);
@@ -295,7 +296,7 @@ uint32_t HELPER(clc)(uint32_t l, uint64_t s1, uint64_t s2)
}
}
cc = 0;
-done:
+ done:
HELPER_LOG("\n");
return cc;
}
@@ -303,9 +304,10 @@ done:
/* compare logical under mask */
uint32_t HELPER(clm)(uint32_t r1, uint32_t mask, uint64_t addr)
{
- uint8_t r,d;
+ uint8_t r, d;
uint32_t cc;
- HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%" PRIx64 "\n", __FUNCTION__, r1,
+
+ HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%" PRIx64 "\n", __func__, r1,
mask, addr);
cc = 0;
while (mask) {
@@ -313,7 +315,7 @@ uint32_t HELPER(clm)(uint32_t r1, uint32_t mask, uint64_t addr)
d = ldub(addr);
r = (r1 & 0xff000000UL) >> 24;
HELPER_LOG("mask 0x%x %02x/%02x (0x%" PRIx64 ") ", mask, r, d,
- addr);
+ addr);
if (r < d) {
cc = 1;
break;
@@ -334,7 +336,8 @@ uint32_t HELPER(clm)(uint32_t r1, uint32_t mask, uint64_t addr)
void HELPER(stcm)(uint32_t r1, uint32_t mask, uint64_t addr)
{
uint8_t r;
- HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%lx\n", __FUNCTION__, r1, mask,
+
+ HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%lx\n", __func__, r1, mask,
addr);
while (mask) {
if (mask & 8) {
@@ -355,6 +358,7 @@ void HELPER(mlg)(uint32_t r1, uint64_t v2)
#if HOST_LONG_BITS == 64 && defined(__GNUC__)
/* assuming 64-bit hosts have __uint128_t */
__uint128_t res = (__uint128_t)env->regs[r1 + 1];
+
res *= (__uint128_t)v2;
env->regs[r1] = (uint64_t)(res >> 64);
env->regs[r1 + 1] = (uint64_t)res;
@@ -370,18 +374,18 @@ void HELPER(dlg)(uint32_t r1, uint64_t v2)
if (!env->regs[r1]) {
/* 64 -> 64/64 case */
- env->regs[r1] = env->regs[r1+1] % divisor;
- env->regs[r1+1] = env->regs[r1+1] / divisor;
+ env->regs[r1] = env->regs[r1 + 1] % divisor;
+ env->regs[r1 + 1] = env->regs[r1 + 1] / divisor;
return;
} else {
-
#if HOST_LONG_BITS == 64 && defined(__GNUC__)
/* assuming 64-bit hosts have __uint128_t */
__uint128_t dividend = (((__uint128_t)env->regs[r1]) << 64) |
- (env->regs[r1+1]);
+ (env->regs[r1 + 1]);
__uint128_t quotient = dividend / divisor;
- env->regs[r1+1] = quotient;
__uint128_t remainder = dividend % divisor;
+
+ env->regs[r1 + 1] = quotient;
env->regs[r1] = remainder;
#else
/* 32-bit hosts would need special wrapper functionality - just abort if
@@ -431,7 +435,7 @@ uint32_t HELPER(srst)(uint32_t c, uint32_t r1, uint32_t r2)
uint64_t str = get_address_31fix(r2);
uint64_t end = get_address_31fix(r1);
- HELPER_LOG("%s: c %d *r1 0x%" PRIx64 " *r2 0x%" PRIx64 "\n", __FUNCTION__,
+ HELPER_LOG("%s: c %d *r1 0x%" PRIx64 " *r2 0x%" PRIx64 "\n", __func__,
c, env->regs[r1], env->regs[r2]);
for (i = str; i != end; i++) {
@@ -452,11 +456,12 @@ uint32_t HELPER(clst)(uint32_t c, uint32_t r1, uint32_t r2)
uint64_t s2 = get_address_31fix(r2);
uint8_t v1, v2;
uint32_t cc;
+
c = c & 0xff;
#ifdef CONFIG_USER_ONLY
if (!c) {
HELPER_LOG("%s: comparing '%s' and '%s'\n",
- __FUNCTION__, (char*)g2h(s1), (char*)g2h(s2));
+ __func__, (char *)g2h(s1), (char *)g2h(s2));
}
#endif
for (;;) {
@@ -501,10 +506,11 @@ void HELPER(mvst)(uint32_t c, uint32_t r1, uint32_t r2)
uint64_t dest = get_address_31fix(r1);
uint64_t src = get_address_31fix(r2);
uint8_t v;
+
c = c & 0xff;
#ifdef CONFIG_USER_ONLY
if (!c) {
- HELPER_LOG("%s: copy '%s' to 0x%lx\n", __FUNCTION__, (char*)g2h(src),
+ HELPER_LOG("%s: copy '%s' to 0x%lx\n", __func__, (char *)g2h(src),
dest);
}
#endif
@@ -526,6 +532,7 @@ uint32_t HELPER(csg)(uint32_t r1, uint64_t a2, uint32_t r3)
/* FIXME: locking? */
uint32_t cc;
uint64_t v2 = ldq(a2);
+
if (env->regs[r1] == v2) {
cc = 0;
stq(a2, env->regs[r3]);
@@ -564,8 +571,9 @@ uint32_t HELPER(cs)(uint32_t r1, uint64_t a2, uint32_t r3)
{
/* FIXME: locking? */
uint32_t cc;
- HELPER_LOG("%s: r1 %d a2 0x%lx r3 %d\n", __FUNCTION__, r1, a2, r3);
uint32_t v2 = ldl(a2);
+
+ HELPER_LOG("%s: r1 %d a2 0x%lx r3 %d\n", __func__, r1, a2, r3);
if (((uint32_t)env->regs[r1]) == v2) {
cc = 0;
stl(a2, (uint32_t)env->regs[r3]);
@@ -612,14 +620,16 @@ static uint32_t helper_icm(uint32_t r1, uint64_t address, uint32_t mask)
it does not change the program counter
in other words: tricky...
currently implemented by interpreting the cases it is most commonly used in
- */
+*/
uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
{
uint16_t insn = lduw_code(addr);
- HELPER_LOG("%s: v1 0x%lx addr 0x%lx insn 0x%x\n", __FUNCTION__, v1, addr,
- insn);
+
+ HELPER_LOG("%s: v1 0x%lx addr 0x%lx insn 0x%x\n", __func__, v1, addr,
+ insn);
if ((insn & 0xf0ff) == 0xd000) {
uint32_t l, insn2, b1, b2, d1, d2;
+
l = v1 & 0xff;
insn2 = ldl_code(addr + 2);
b1 = (insn2 >> 28) & 0xf;
@@ -645,13 +655,14 @@ uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
}
} else if ((insn & 0xff00) == 0x0a00) {
/* supervisor call */
- HELPER_LOG("%s: svc %ld via execute\n", __FUNCTION__, (insn|v1) & 0xff);
+ HELPER_LOG("%s: svc %ld via execute\n", __func__, (insn | v1) & 0xff);
env->psw.addr = ret - 4;
- env->int_svc_code = (insn|v1) & 0xff;
+ env->int_svc_code = (insn | v1) & 0xff;
env->int_svc_ilc = 4;
helper_exception(EXCP_SVC);
} else if ((insn & 0xff00) == 0xbf00) {
uint32_t insn2, r1, r3, b2, d2;
+
insn2 = ldl_code(addr + 2);
r1 = (insn2 >> 20) & 0xf;
r3 = (insn2 >> 16) & 0xf;
@@ -659,7 +670,7 @@ uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
d2 = insn2 & 0xfff;
cc = helper_icm(r1, get_address(0, b2, d2), r3);
} else {
-abort:
+ abort:
cpu_abort(env, "EXECUTE on instruction prefix 0x%x not implemented\n",
insn);
}
@@ -689,7 +700,7 @@ int32_t HELPER(nabs_i32)(int32_t val)
/* absolute value 64-bit */
uint64_t HELPER(abs_i64)(int64_t val)
{
- HELPER_LOG("%s: val 0x%" PRIx64 "\n", __FUNCTION__, val);
+ HELPER_LOG("%s: val 0x%" PRIx64 "\n", __func__, val);
if (val < 0) {
return -val;
@@ -774,9 +785,9 @@ void HELPER(ipm)(uint32_t cc, uint32_t r1)
uint64_t r = env->regs[r1];
r &= 0xffffffff00ffffffULL;
- r |= (cc << 28) | ( (env->psw.mask >> 40) & 0xf );
+ r |= (cc << 28) | ((env->psw.mask >> 40) & 0xf);
env->regs[r1] = r;
- HELPER_LOG("%s: cc %d psw.mask 0x%lx r1 0x%lx\n", __FUNCTION__,
+ HELPER_LOG("%s: cc %d psw.mask 0x%lx r1 0x%lx\n", __func__,
cc, env->psw.mask, r);
}
@@ -908,7 +919,7 @@ uint32_t HELPER(clcle)(uint32_t r1, uint64_t a2, uint32_t r3)
uint64_t srclen = env->regs[r3 + 1];
uint64_t src = get_address_31fix(r3);
uint8_t pad = a2 & 0xff;
- uint8_t v1 = 0,v2 = 0;
+ uint8_t v1 = 0, v2 = 0;
uint32_t cc = 0;
if (!(destlen || srclen)) {
@@ -1036,7 +1047,7 @@ static uint32_t set_cc_nz_f128(float128 v)
/* convert 32-bit int to 64-bit float */
void HELPER(cdfbr)(uint32_t f1, int32_t v2)
{
- HELPER_LOG("%s: converting %d to f%d\n", __FUNCTION__, v2, f1);
+ HELPER_LOG("%s: converting %d to f%d\n", __func__, v2, f1);
env->fregs[f1].d = int32_to_float64(v2, &env->fpu_status);
}
@@ -1044,6 +1055,7 @@ void HELPER(cdfbr)(uint32_t f1, int32_t v2)
void HELPER(cxfbr)(uint32_t f1, int32_t v2)
{
CPU_QuadU v1;
+
v1.q = int32_to_float128(v2, &env->fpu_status);
env->fregs[f1].ll = v1.ll.upper;
env->fregs[f1 + 2].ll = v1.ll.lower;
@@ -1052,14 +1064,14 @@ void HELPER(cxfbr)(uint32_t f1, int32_t v2)
/* convert 64-bit int to 32-bit float */
void HELPER(cegbr)(uint32_t f1, int64_t v2)
{
- HELPER_LOG("%s: converting %ld to f%d\n", __FUNCTION__, v2, f1);
+ HELPER_LOG("%s: converting %ld to f%d\n", __func__, v2, f1);
env->fregs[f1].l.upper = int64_to_float32(v2, &env->fpu_status);
}
/* convert 64-bit int to 64-bit float */
void HELPER(cdgbr)(uint32_t f1, int64_t v2)
{
- HELPER_LOG("%s: converting %ld to f%d\n", __FUNCTION__, v2, f1);
+ HELPER_LOG("%s: converting %ld to f%d\n", __func__, v2, f1);
env->fregs[f1].d = int64_to_float64(v2, &env->fpu_status);
}
@@ -1067,8 +1079,9 @@ void HELPER(cdgbr)(uint32_t f1, int64_t v2)
void HELPER(cxgbr)(uint32_t f1, int64_t v2)
{
CPU_QuadU x1;
+
x1.q = int64_to_float128(v2, &env->fpu_status);
- HELPER_LOG("%s: converted %ld to 0x%lx and 0x%lx\n", __FUNCTION__, v2,
+ HELPER_LOG("%s: converted %ld to 0x%lx and 0x%lx\n", __func__, v2,
x1.ll.upper, x1.ll.lower);
env->fregs[f1].ll = x1.ll.upper;
env->fregs[f1 + 2].ll = x1.ll.lower;
@@ -1078,7 +1091,7 @@ void HELPER(cxgbr)(uint32_t f1, int64_t v2)
void HELPER(cefbr)(uint32_t f1, int32_t v2)
{
env->fregs[f1].l.upper = int32_to_float32(v2, &env->fpu_status);
- HELPER_LOG("%s: converting %d to 0x%d in f%d\n", __FUNCTION__, v2,
+ HELPER_LOG("%s: converting %d to 0x%d in f%d\n", __func__, v2,
env->fregs[f1].l.upper, f1);
}
@@ -1088,7 +1101,7 @@ uint32_t HELPER(aebr)(uint32_t f1, uint32_t f2)
env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper,
env->fregs[f2].l.upper,
&env->fpu_status);
- HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __FUNCTION__,
+ HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __func__,
env->fregs[f2].l.upper, env->fregs[f1].l.upper, f1);
return set_cc_nz_f32(env->fregs[f1].l.upper);
@@ -1099,7 +1112,7 @@ uint32_t HELPER(adbr)(uint32_t f1, uint32_t f2)
{
env->fregs[f1].d = float64_add(env->fregs[f1].d, env->fregs[f2].d,
&env->fpu_status);
- HELPER_LOG("%s: adding 0x%ld resulting in 0x%ld in f%d\n", __FUNCTION__,
+ HELPER_LOG("%s: adding 0x%ld resulting in 0x%ld in f%d\n", __func__,
env->fregs[f2].d, env->fregs[f1].d, f1);
return set_cc_nz_f64(env->fregs[f1].d);
@@ -1111,7 +1124,7 @@ uint32_t HELPER(sebr)(uint32_t f1, uint32_t f2)
env->fregs[f1].l.upper = float32_sub(env->fregs[f1].l.upper,
env->fregs[f2].l.upper,
&env->fpu_status);
- HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __FUNCTION__,
+ HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __func__,
env->fregs[f2].l.upper, env->fregs[f1].l.upper, f1);
return set_cc_nz_f32(env->fregs[f1].l.upper);
@@ -1123,7 +1136,7 @@ uint32_t HELPER(sdbr)(uint32_t f1, uint32_t f2)
env->fregs[f1].d = float64_sub(env->fregs[f1].d, env->fregs[f2].d,
&env->fpu_status);
HELPER_LOG("%s: subtracting 0x%ld resulting in 0x%ld in f%d\n",
- __FUNCTION__, env->fregs[f2].d, env->fregs[f1].d, f1);
+ __func__, env->fregs[f2].d, env->fregs[f1].d, f1);
return set_cc_nz_f64(env->fregs[f1].d);
}
@@ -1140,12 +1153,13 @@ void HELPER(debr)(uint32_t f1, uint32_t f2)
void HELPER(dxbr)(uint32_t f1, uint32_t f2)
{
CPU_QuadU v1;
+ CPU_QuadU v2;
+ CPU_QuadU res;
+
v1.ll.upper = env->fregs[f1].ll;
v1.ll.lower = env->fregs[f1 + 2].ll;
- CPU_QuadU v2;
v2.ll.upper = env->fregs[f2].ll;
v2.ll.lower = env->fregs[f2 + 2].ll;
- CPU_QuadU res;
res.q = float128_div(v1.q, v2.q, &env->fpu_status);
env->fregs[f1].ll = res.ll.upper;
env->fregs[f1 + 2].ll = res.ll.lower;
@@ -1162,12 +1176,13 @@ void HELPER(mdbr)(uint32_t f1, uint32_t f2)
void HELPER(mxbr)(uint32_t f1, uint32_t f2)
{
CPU_QuadU v1;
+ CPU_QuadU v2;
+ CPU_QuadU res;
+
v1.ll.upper = env->fregs[f1].ll;
v1.ll.lower = env->fregs[f1 + 2].ll;
- CPU_QuadU v2;
v2.ll.upper = env->fregs[f2].ll;
v2.ll.lower = env->fregs[f2 + 2].ll;
- CPU_QuadU res;
res.q = float128_mul(v1.q, v2.q, &env->fpu_status);
env->fregs[f1].ll = res.ll.upper;
env->fregs[f1 + 2].ll = res.ll.lower;
@@ -1184,16 +1199,18 @@ void HELPER(ldebr)(uint32_t r1, uint32_t r2)
void HELPER(ldxbr)(uint32_t f1, uint32_t f2)
{
CPU_QuadU x2;
+
x2.ll.upper = env->fregs[f2].ll;
x2.ll.lower = env->fregs[f2 + 2].ll;
env->fregs[f1].d = float128_to_float64(x2.q, &env->fpu_status);
- HELPER_LOG("%s: to 0x%ld\n", __FUNCTION__, env->fregs[f1].d);
+ HELPER_LOG("%s: to 0x%ld\n", __func__, env->fregs[f1].d);
}
/* convert 64-bit float to 128-bit float */
void HELPER(lxdbr)(uint32_t f1, uint32_t f2)
{
CPU_QuadU res;
+
res.q = float64_to_float128(env->fregs[f2].d, &env->fpu_status);
env->fregs[f1].ll = res.ll.upper;
env->fregs[f1 + 2].ll = res.ll.lower;
@@ -1203,6 +1220,7 @@ void HELPER(lxdbr)(uint32_t f1, uint32_t f2)
void HELPER(ledbr)(uint32_t f1, uint32_t f2)
{
float64 d2 = env->fregs[f2].d;
+
env->fregs[f1].l.upper = float64_to_float32(d2, &env->fpu_status);
}
@@ -1210,10 +1228,11 @@ void HELPER(ledbr)(uint32_t f1, uint32_t f2)
void HELPER(lexbr)(uint32_t f1, uint32_t f2)
{
CPU_QuadU x2;
+
x2.ll.upper = env->fregs[f2].ll;
x2.ll.lower = env->fregs[f2 + 2].ll;
env->fregs[f1].l.upper = float128_to_float32(x2.q, &env->fpu_status);
- HELPER_LOG("%s: to 0x%d\n", __FUNCTION__, env->fregs[f1].l.upper);
+ HELPER_LOG("%s: to 0x%d\n", __func__, env->fregs[f1].l.upper);
}
/* absolute value of 32-bit float */
@@ -1221,6 +1240,7 @@ uint32_t HELPER(lpebr)(uint32_t f1, uint32_t f2)
{
float32 v1;
float32 v2 = env->fregs[f2].d;
+
v1 = float32_abs(v2);
env->fregs[f1].d = v1;
return set_cc_nz_f32(v1);
@@ -1231,6 +1251,7 @@ uint32_t HELPER(lpdbr)(uint32_t f1, uint32_t f2)
{
float64 v1;
float64 v2 = env->fregs[f2].d;
+
v1 = float64_abs(v2);
env->fregs[f1].d = v1;
return set_cc_nz_f64(v1);
@@ -1241,6 +1262,7 @@ uint32_t HELPER(lpxbr)(uint32_t f1, uint32_t f2)
{
CPU_QuadU v1;
CPU_QuadU v2;
+
v2.ll.upper = env->fregs[f2].ll;
v2.ll.lower = env->fregs[f2 + 2].ll;
v1.q = float128_abs(v2.q);
@@ -1267,6 +1289,7 @@ uint32_t HELPER(ltebr)(uint32_t f1, uint32_t f2)
uint32_t HELPER(ltxbr)(uint32_t f1, uint32_t f2)
{
CPU_QuadU x;
+
x.ll.upper = env->fregs[f2].ll;
x.ll.lower = env->fregs[f2 + 2].ll;
env->fregs[f1].ll = x.ll.upper;
@@ -1294,6 +1317,7 @@ uint32_t HELPER(lcdbr)(uint32_t f1, uint32_t f2)
uint32_t HELPER(lcxbr)(uint32_t f1, uint32_t f2)
{
CPU_QuadU x1, x2;
+
x2.ll.upper = env->fregs[f2].ll;
x2.ll.lower = env->fregs[f2 + 2].ll;
x1.q = float128_chs(x2.q);
@@ -1307,8 +1331,9 @@ void HELPER(aeb)(uint32_t f1, uint32_t val)
{
float32 v1 = env->fregs[f1].l.upper;
CPU_FloatU v2;
+
v2.l = val;
- HELPER_LOG("%s: adding 0x%d from f%d and 0x%d\n", __FUNCTION__,
+ HELPER_LOG("%s: adding 0x%d from f%d and 0x%d\n", __func__,
v1, f1, v2.f);
env->fregs[f1].l.upper = float32_add(v1, v2.f, &env->fpu_status);
}
@@ -1318,8 +1343,9 @@ void HELPER(deb)(uint32_t f1, uint32_t val)
{
float32 v1 = env->fregs[f1].l.upper;
CPU_FloatU v2;
+
v2.l = val;
- HELPER_LOG("%s: dividing 0x%d from f%d by 0x%d\n", __FUNCTION__,
+ HELPER_LOG("%s: dividing 0x%d from f%d by 0x%d\n", __func__,
v1, f1, v2.f);
env->fregs[f1].l.upper = float32_div(v1, v2.f, &env->fpu_status);
}
@@ -1329,8 +1355,9 @@ void HELPER(meeb)(uint32_t f1, uint32_t val)
{
float32 v1 = env->fregs[f1].l.upper;
CPU_FloatU v2;
+
v2.l = val;
- HELPER_LOG("%s: multiplying 0x%d from f%d and 0x%d\n", __FUNCTION__,
+ HELPER_LOG("%s: multiplying 0x%d from f%d and 0x%d\n", __func__,
v1, f1, v2.f);
env->fregs[f1].l.upper = float32_mul(v1, v2.f, &env->fpu_status);
}
@@ -1340,7 +1367,8 @@ uint32_t HELPER(cebr)(uint32_t f1, uint32_t f2)
{
float32 v1 = env->fregs[f1].l.upper;
float32 v2 = env->fregs[f2].l.upper;
- HELPER_LOG("%s: comparing 0x%d from f%d and 0x%d\n", __FUNCTION__,
+
+ HELPER_LOG("%s: comparing 0x%d from f%d and 0x%d\n", __func__,
v1, f1, v2);
return set_cc_f32(v1, v2);
}
@@ -1350,7 +1378,8 @@ uint32_t HELPER(cdbr)(uint32_t f1, uint32_t f2)
{
float64 v1 = env->fregs[f1].d;
float64 v2 = env->fregs[f2].d;
- HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%ld\n", __FUNCTION__,
+
+ HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%ld\n", __func__,
v1, f1, v2);
return set_cc_f64(v1, v2);
}
@@ -1359,14 +1388,15 @@ uint32_t HELPER(cdbr)(uint32_t f1, uint32_t f2)
uint32_t HELPER(cxbr)(uint32_t f1, uint32_t f2)
{
CPU_QuadU v1;
+ CPU_QuadU v2;
+
v1.ll.upper = env->fregs[f1].ll;
v1.ll.lower = env->fregs[f1 + 2].ll;
- CPU_QuadU v2;
v2.ll.upper = env->fregs[f2].ll;
v2.ll.lower = env->fregs[f2 + 2].ll;
return float_comp_to_cc(float128_compare_quiet(v1.q, v2.q,
- &env->fpu_status));
+ &env->fpu_status));
}
/* 64-bit FP compare RM */
@@ -1374,8 +1404,9 @@ uint32_t HELPER(cdb)(uint32_t f1, uint64_t a2)
{
float64 v1 = env->fregs[f1].d;
CPU_DoubleU v2;
+
v2.ll = ldq(a2);
- HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%lx\n", __FUNCTION__, v1,
+ HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%lx\n", __func__, v1,
f1, v2.d);
return set_cc_f64(v1, v2.d);
}
@@ -1385,8 +1416,9 @@ uint32_t HELPER(adb)(uint32_t f1, uint64_t a2)
{
float64 v1 = env->fregs[f1].d;
CPU_DoubleU v2;
+
v2.ll = ldq(a2);
- HELPER_LOG("%s: adding 0x%lx from f%d and 0x%lx\n", __FUNCTION__,
+ HELPER_LOG("%s: adding 0x%lx from f%d and 0x%lx\n", __func__,
v1, f1, v2.d);
env->fregs[f1].d = v1 = float64_add(v1, v2.d, &env->fpu_status);
return set_cc_nz_f64(v1);
@@ -1397,6 +1429,7 @@ void HELPER(seb)(uint32_t f1, uint32_t val)
{
float32 v1 = env->fregs[f1].l.upper;
CPU_FloatU v2;
+
v2.l = val;
env->fregs[f1].l.upper = float32_sub(v1, v2.f, &env->fpu_status);
}
@@ -1406,6 +1439,7 @@ uint32_t HELPER(sdb)(uint32_t f1, uint64_t a2)
{
float64 v1 = env->fregs[f1].d;
CPU_DoubleU v2;
+
v2.ll = ldq(a2);
env->fregs[f1].d = v1 = float64_sub(v1, v2.d, &env->fpu_status);
return set_cc_nz_f64(v1);
@@ -1416,8 +1450,9 @@ void HELPER(mdb)(uint32_t f1, uint64_t a2)
{
float64 v1 = env->fregs[f1].d;
CPU_DoubleU v2;
+
v2.ll = ldq(a2);
- HELPER_LOG("%s: multiplying 0x%lx from f%d and 0x%ld\n", __FUNCTION__,
+ HELPER_LOG("%s: multiplying 0x%lx from f%d and 0x%ld\n", __func__,
v1, f1, v2.d);
env->fregs[f1].d = float64_mul(v1, v2.d, &env->fpu_status);
}
@@ -1427,8 +1462,9 @@ void HELPER(ddb)(uint32_t f1, uint64_t a2)
{
float64 v1 = env->fregs[f1].d;
CPU_DoubleU v2;
+
v2.ll = ldq(a2);
- HELPER_LOG("%s: dividing 0x%lx from f%d by 0x%ld\n", __FUNCTION__,
+ HELPER_LOG("%s: dividing 0x%lx from f%d by 0x%ld\n", __func__,
v1, f1, v2.d);
env->fregs[f1].d = float64_div(v1, v2.d, &env->fpu_status);
}
@@ -1464,6 +1500,7 @@ static void set_round_mode(int m3)
uint32_t HELPER(cgebr)(uint32_t r1, uint32_t f2, uint32_t m3)
{
float32 v2 = env->fregs[f2].l.upper;
+
set_round_mode(m3);
env->regs[r1] = float32_to_int64(v2, &env->fpu_status);
return set_cc_nz_f32(v2);
@@ -1473,6 +1510,7 @@ uint32_t HELPER(cgebr)(uint32_t r1, uint32_t f2, uint32_t m3)
uint32_t HELPER(cgdbr)(uint32_t r1, uint32_t f2, uint32_t m3)
{
float64 v2 = env->fregs[f2].d;
+
set_round_mode(m3);
env->regs[r1] = float64_to_int64(v2, &env->fpu_status);
return set_cc_nz_f64(v2);
@@ -1482,6 +1520,7 @@ uint32_t HELPER(cgdbr)(uint32_t r1, uint32_t f2, uint32_t m3)
uint32_t HELPER(cgxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
{
CPU_QuadU v2;
+
v2.ll.upper = env->fregs[f2].ll;
v2.ll.lower = env->fregs[f2 + 2].ll;
set_round_mode(m3);
@@ -1501,9 +1540,10 @@ uint32_t HELPER(cgxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
uint32_t HELPER(cfebr)(uint32_t r1, uint32_t f2, uint32_t m3)
{
float32 v2 = env->fregs[f2].l.upper;
+
set_round_mode(m3);
env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
- float32_to_int32(v2, &env->fpu_status);
+ float32_to_int32(v2, &env->fpu_status);
return set_cc_nz_f32(v2);
}
@@ -1511,9 +1551,10 @@ uint32_t HELPER(cfebr)(uint32_t r1, uint32_t f2, uint32_t m3)
uint32_t HELPER(cfdbr)(uint32_t r1, uint32_t f2, uint32_t m3)
{
float64 v2 = env->fregs[f2].d;
+
set_round_mode(m3);
env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
- float64_to_int32(v2, &env->fpu_status);
+ float64_to_int32(v2, &env->fpu_status);
return set_cc_nz_f64(v2);
}
@@ -1521,10 +1562,11 @@ uint32_t HELPER(cfdbr)(uint32_t r1, uint32_t f2, uint32_t m3)
uint32_t HELPER(cfxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
{
CPU_QuadU v2;
+
v2.ll.upper = env->fregs[f2].ll;
v2.ll.lower = env->fregs[f2 + 2].ll;
env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
- float128_to_int32(v2.q, &env->fpu_status);
+ float128_to_int32(v2.q, &env->fpu_status);
return set_cc_nz_f128(v2.q);
}
@@ -1544,6 +1586,7 @@ void HELPER(lzdr)(uint32_t f1)
void HELPER(lzxr)(uint32_t f1)
{
CPU_QuadU x;
+
x.q = float64_to_float128(float64_zero, &env->fpu_status);
env->fregs[f1].ll = x.ll.upper;
env->fregs[f1 + 1].ll = x.ll.lower;
@@ -1553,12 +1596,13 @@ void HELPER(lzxr)(uint32_t f1)
uint32_t HELPER(sxbr)(uint32_t f1, uint32_t f2)
{
CPU_QuadU v1;
+ CPU_QuadU v2;
+ CPU_QuadU res;
+
v1.ll.upper = env->fregs[f1].ll;
v1.ll.lower = env->fregs[f1 + 2].ll;
- CPU_QuadU v2;
v2.ll.upper = env->fregs[f2].ll;
v2.ll.lower = env->fregs[f2 + 2].ll;
- CPU_QuadU res;
res.q = float128_sub(v1.q, v2.q, &env->fpu_status);
env->fregs[f1].ll = res.ll.upper;
env->fregs[f1 + 2].ll = res.ll.lower;
@@ -1569,12 +1613,13 @@ uint32_t HELPER(sxbr)(uint32_t f1, uint32_t f2)
uint32_t HELPER(axbr)(uint32_t f1, uint32_t f2)
{
CPU_QuadU v1;
+ CPU_QuadU v2;
+ CPU_QuadU res;
+
v1.ll.upper = env->fregs[f1].ll;
v1.ll.lower = env->fregs[f1 + 2].ll;
- CPU_QuadU v2;
v2.ll.upper = env->fregs[f2].ll;
v2.ll.lower = env->fregs[f2 + 2].ll;
- CPU_QuadU res;
res.q = float128_add(v1.q, v2.q, &env->fpu_status);
env->fregs[f1].ll = res.ll.upper;
env->fregs[f1 + 2].ll = res.ll.lower;
@@ -1599,8 +1644,9 @@ void HELPER(ddbr)(uint32_t f1, uint32_t f2)
/* 64-bit FP multiply and add RM */
void HELPER(madb)(uint32_t f1, uint64_t a2, uint32_t f3)
{
- HELPER_LOG("%s: f1 %d a2 0x%lx f3 %d\n", __FUNCTION__, f1, a2, f3);
CPU_DoubleU v2;
+
+ HELPER_LOG("%s: f1 %d a2 0x%lx f3 %d\n", __func__, f1, a2, f3);
v2.ll = ldq(a2);
env->fregs[f1].d = float64_add(env->fregs[f1].d,
float64_mul(v2.d, env->fregs[f3].d,
@@ -1611,7 +1657,7 @@ void HELPER(madb)(uint32_t f1, uint64_t a2, uint32_t f3)
/* 64-bit FP multiply and add RR */
void HELPER(madbr)(uint32_t f1, uint32_t f3, uint32_t f2)
{
- HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __FUNCTION__, f1, f2, f3);
+ HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __func__, f1, f2, f3);
env->fregs[f1].d = float64_add(float64_mul(env->fregs[f2].d,
env->fregs[f3].d,
&env->fpu_status),
@@ -1621,7 +1667,7 @@ void HELPER(madbr)(uint32_t f1, uint32_t f3, uint32_t f2)
/* 64-bit FP multiply and subtract RR */
void HELPER(msdbr)(uint32_t f1, uint32_t f3, uint32_t f2)
{
- HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __FUNCTION__, f1, f2, f3);
+ HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __func__, f1, f2, f3);
env->fregs[f1].d = float64_sub(float64_mul(env->fregs[f2].d,
env->fregs[f3].d,
&env->fpu_status),
@@ -1642,6 +1688,7 @@ void HELPER(maebr)(uint32_t f1, uint32_t f3, uint32_t f2)
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);
@@ -1651,8 +1698,9 @@ void HELPER(ldeb)(uint32_t f1, uint64_t a2)
void HELPER(lxdb)(uint32_t f1, uint64_t a2)
{
CPU_DoubleU v2;
- v2.ll = ldq(a2);
CPU_QuadU v1;
+
+ v2.ll = ldq(a2);
v1.q = float64_to_float128(v2.d, &env->fpu_status);
env->fregs[f1].ll = v1.ll.upper;
env->fregs[f1 + 2].ll = v1.ll.lower;
@@ -1665,7 +1713,7 @@ uint32_t HELPER(tceb)(uint32_t f1, uint64_t m2)
int neg = float32_is_neg(v1);
uint32_t cc = 0;
- HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __FUNCTION__, (long)v1, m2, neg);
+ HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __func__, (long)v1, m2, neg);
if ((float32_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
(float32_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
(float32_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
@@ -1687,7 +1735,7 @@ uint32_t HELPER(tcdb)(uint32_t f1, uint64_t m2)
int neg = float64_is_neg(v1);
uint32_t cc = 0;
- HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __FUNCTION__, v1, m2, neg);
+ HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __func__, v1, m2, neg);
if ((float64_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
(float64_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
(float64_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
@@ -1706,10 +1754,12 @@ uint32_t HELPER(tcxb)(uint32_t f1, uint64_t m2)
{
CPU_QuadU v1;
uint32_t cc = 0;
+ int neg;
+
v1.ll.upper = env->fregs[f1].ll;
v1.ll.lower = env->fregs[f1 + 2].ll;
- int neg = float128_is_neg(v1.q);
+ neg = float128_is_neg(v1.q);
if ((float128_is_zero(v1.q) && (m2 & (1 << (11-neg)))) ||
(float128_is_infinity(v1.q) && (m2 & (1 << (5-neg)))) ||
(float128_is_any_nan(v1.q) && (m2 & (1 << (3-neg)))) ||
@@ -1787,7 +1837,7 @@ void HELPER(cksm)(uint32_t r1, uint32_t r2)
/* store result */
env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
- ((uint32_t)cksm + (cksm >> 32));
+ ((uint32_t)cksm + (cksm >> 32));
}
static inline uint32_t cc_calc_ltgt_32(CPUS390XState *env, int32_t src,
@@ -1848,10 +1898,12 @@ static inline uint32_t cc_calc_ltugtu_64(CPUS390XState *env, uint64_t src,
}
}
-static inline uint32_t cc_calc_tm_32(CPUS390XState *env, uint32_t val, uint32_t mask)
+static inline uint32_t cc_calc_tm_32(CPUS390XState *env, uint32_t val,
+ uint32_t mask)
{
- HELPER_LOG("%s: val 0x%x mask 0x%x\n", __FUNCTION__, val, mask);
uint16_t r = val & mask;
+
+ HELPER_LOG("%s: val 0x%x mask 0x%x\n", __func__, val, mask);
if (r == 0 || mask == 0) {
return 0;
} else if (r == mask) {
@@ -1862,10 +1914,12 @@ static inline uint32_t cc_calc_tm_32(CPUS390XState *env, uint32_t val, uint32_t
}
/* set condition code for test under mask */
-static inline uint32_t cc_calc_tm_64(CPUS390XState *env, uint64_t val, uint32_t mask)
+static inline uint32_t cc_calc_tm_64(CPUS390XState *env, uint64_t val,
+ uint32_t mask)
{
uint16_t r = val & mask;
- HELPER_LOG("%s: val 0x%lx mask 0x%x r 0x%x\n", __FUNCTION__, val, mask, r);
+
+ HELPER_LOG("%s: val 0x%lx mask 0x%x r 0x%x\n", __func__, val, mask, r);
if (r == 0 || mask == 0) {
return 0;
} else if (r == mask) {
@@ -1888,8 +1942,8 @@ static inline uint32_t cc_calc_nz(CPUS390XState *env, uint64_t dst)
return !!dst;
}
-static inline uint32_t cc_calc_add_64(CPUS390XState *env, int64_t a1, int64_t a2,
- int64_t ar)
+static inline uint32_t cc_calc_add_64(CPUS390XState *env, int64_t a1,
+ int64_t a2, int64_t ar)
{
if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) {
return 3; /* overflow */
@@ -1904,8 +1958,8 @@ static inline uint32_t cc_calc_add_64(CPUS390XState *env, int64_t a1, int64_t a2
}
}
-static inline uint32_t cc_calc_addu_64(CPUS390XState *env, uint64_t a1, uint64_t a2,
- uint64_t ar)
+static inline uint32_t cc_calc_addu_64(CPUS390XState *env, uint64_t a1,
+ uint64_t a2, uint64_t ar)
{
if (ar == 0) {
if (a1) {
@@ -1915,15 +1969,15 @@ static inline uint32_t cc_calc_addu_64(CPUS390XState *env, uint64_t a1, uint64_t
}
} else {
if (ar < a1 || ar < a2) {
- return 3;
+ return 3;
} else {
- return 1;
+ return 1;
}
}
}
-static inline uint32_t cc_calc_sub_64(CPUS390XState *env, int64_t a1, int64_t a2,
- int64_t ar)
+static inline uint32_t cc_calc_sub_64(CPUS390XState *env, int64_t a1,
+ int64_t a2, int64_t ar)
{
if ((a1 > 0 && a2 < 0 && ar < 0) || (a1 < 0 && a2 > 0 && ar > 0)) {
return 3; /* overflow */
@@ -1938,8 +1992,8 @@ static inline uint32_t cc_calc_sub_64(CPUS390XState *env, int64_t a1, int64_t a2
}
}
-static inline uint32_t cc_calc_subu_64(CPUS390XState *env, uint64_t a1, uint64_t a2,
- uint64_t ar)
+static inline uint32_t cc_calc_subu_64(CPUS390XState *env, uint64_t a1,
+ uint64_t a2, uint64_t ar)
{
if (ar == 0) {
return 2;
@@ -1982,8 +2036,8 @@ static inline uint32_t cc_calc_comp_64(CPUS390XState *env, int64_t dst)
}
-static inline uint32_t cc_calc_add_32(CPUS390XState *env, int32_t a1, int32_t a2,
- int32_t ar)
+static inline uint32_t cc_calc_add_32(CPUS390XState *env, int32_t a1,
+ int32_t a2, int32_t ar)
{
if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) {
return 3; /* overflow */
@@ -1998,26 +2052,26 @@ static inline uint32_t cc_calc_add_32(CPUS390XState *env, int32_t a1, int32_t a2
}
}
-static inline uint32_t cc_calc_addu_32(CPUS390XState *env, uint32_t a1, uint32_t a2,
- uint32_t ar)
+static inline uint32_t cc_calc_addu_32(CPUS390XState *env, uint32_t a1,
+ uint32_t a2, uint32_t ar)
{
if (ar == 0) {
if (a1) {
- return 2;
+ return 2;
} else {
- return 0;
+ return 0;
}
} else {
if (ar < a1 || ar < a2) {
- return 3;
+ return 3;
} else {
- return 1;
+ return 1;
}
}
}
-static inline uint32_t cc_calc_sub_32(CPUS390XState *env, int32_t a1, int32_t a2,
- int32_t ar)
+static inline uint32_t cc_calc_sub_32(CPUS390XState *env, int32_t a1,
+ int32_t a2, int32_t ar)
{
if ((a1 > 0 && a2 < 0 && ar < 0) || (a1 < 0 && a2 > 0 && ar > 0)) {
return 3; /* overflow */
@@ -2032,8 +2086,8 @@ static inline uint32_t cc_calc_sub_32(CPUS390XState *env, int32_t a1, int32_t a2
}
}
-static inline uint32_t cc_calc_subu_32(CPUS390XState *env, uint32_t a1, uint32_t a2,
- uint32_t ar)
+static inline uint32_t cc_calc_subu_32(CPUS390XState *env, uint32_t a1,
+ uint32_t a2, uint32_t ar)
{
if (ar == 0) {
return 2;
@@ -2076,11 +2130,12 @@ static inline uint32_t cc_calc_comp_32(CPUS390XState *env, int32_t dst)
}
/* calculate condition code for insert character under mask insn */
-static inline uint32_t cc_calc_icm_32(CPUS390XState *env, uint32_t mask, uint32_t val)
+static inline uint32_t cc_calc_icm_32(CPUS390XState *env, uint32_t mask,
+ uint32_t val)
{
- HELPER_LOG("%s: mask 0x%x val %d\n", __FUNCTION__, mask, val);
uint32_t cc;
+ HELPER_LOG("%s: mask 0x%x val %d\n", __func__, mask, val);
if (mask == 0xf) {
if (!val) {
return 0;
@@ -2107,7 +2162,8 @@ static inline uint32_t cc_calc_icm_32(CPUS390XState *env, uint32_t mask, uint32_
return cc;
}
-static inline uint32_t cc_calc_slag(CPUS390XState *env, uint64_t src, uint64_t shift)
+static inline uint32_t cc_calc_slag(CPUS390XState *env, uint64_t src,
+ uint64_t shift)
{
uint64_t mask = ((1ULL << shift) - 1ULL) << (64 - shift);
uint64_t match, r;
@@ -2136,8 +2192,8 @@ static inline uint32_t cc_calc_slag(CPUS390XState *env, uint64_t src, uint64_t s
}
-static inline uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t src,
- uint64_t dst, uint64_t vr)
+static inline uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op,
+ uint64_t src, uint64_t dst, uint64_t vr)
{
uint32_t r = 0;
@@ -2244,7 +2300,7 @@ static inline uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t s
cpu_abort(env, "Unknown CC operation: %s\n", cc_name(cc_op));
}
- HELPER_LOG("%s: %15s 0x%016lx 0x%016lx 0x%016lx = %d\n", __FUNCTION__,
+ HELPER_LOG("%s: %15s 0x%016lx 0x%016lx 0x%016lx = %d\n", __func__,
cc_name(cc_op), src, dst, vr, r);
return r;
}
@@ -2334,6 +2390,7 @@ void HELPER(tr)(uint32_t len, uint64_t array, uint64_t trans)
for (i = 0; i <= len; i++) {
uint8_t byte = ldub(array + i);
uint8_t new_byte = ldub(trans + byte);
+
stb(array + i, new_byte);
}
}
@@ -2363,7 +2420,7 @@ static void program_interrupt(CPUS390XState *env, uint32_t code, int ilc)
}
/*
- * ret < 0 indicates program check, ret = 0,1,2,3 -> cc
+ * ret < 0 indicates program check, ret = 0, 1, 2, 3 -> cc
*/
int sclp_service_call(CPUS390XState *env, uint32_t sccb, uint64_t code)
{
@@ -2382,24 +2439,24 @@ int sclp_service_call(CPUS390XState *env, uint32_t sccb, uint64_t code)
return -PGM_SPECIFICATION;
}
- switch(code) {
- case SCLP_CMDW_READ_SCP_INFO:
- case SCLP_CMDW_READ_SCP_INFO_FORCED:
- while ((ram_size >> (20 + shift)) > 65535) {
- shift++;
- }
- stw_phys(sccb + SCP_MEM_CODE, ram_size >> (20 + shift));
- stb_phys(sccb + SCP_INCREMENT, 1 << shift);
- stw_phys(sccb + SCP_RESPONSE_CODE, 0x10);
+ switch (code) {
+ case SCLP_CMDW_READ_SCP_INFO:
+ case SCLP_CMDW_READ_SCP_INFO_FORCED:
+ while ((ram_size >> (20 + shift)) > 65535) {
+ shift++;
+ }
+ stw_phys(sccb + SCP_MEM_CODE, ram_size >> (20 + shift));
+ stb_phys(sccb + SCP_INCREMENT, 1 << shift);
+ stw_phys(sccb + SCP_RESPONSE_CODE, 0x10);
- s390_sclp_extint(sccb & ~3);
- break;
- default:
+ s390_sclp_extint(sccb & ~3);
+ break;
+ default:
#ifdef DEBUG_HELPER
- printf("KVM: invalid sclp call 0x%x / 0x%" PRIx64 "x\n", sccb, code);
+ printf("KVM: invalid sclp call 0x%x / 0x%" PRIx64 "x\n", sccb, code);
#endif
- r = 3;
- break;
+ r = 3;
+ break;
}
return r;
@@ -2479,7 +2536,7 @@ static inline uint64_t clock_value(CPUS390XState *env)
uint64_t time;
time = env->tod_offset +
- time2tod(qemu_get_clock_ns(vm_clock) - env->tod_basetime);
+ time2tod(qemu_get_clock_ns(vm_clock) - env->tod_basetime);
return time;
}
@@ -2503,7 +2560,6 @@ uint32_t HELPER(stcke)(uint64_t a1)
/* XXX programmable fields */
stw(a1 + 17, 0);
-
return 0;
}
@@ -2584,7 +2640,7 @@ uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1)
ebcdic_put(sysib.model, "QEMU ", 16);
ebcdic_put(sysib.sequence, "QEMU ", 16);
ebcdic_put(sysib.plant, "QEMU", 4);
- cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1);
+ cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
} else if ((sel1 == 2) && (sel2 == 1)) {
/* Basic Machine CPU */
struct sysib_121 sysib;
@@ -2594,7 +2650,7 @@ uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1)
ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
ebcdic_put(sysib.plant, "QEMU", 4);
stw_p(&sysib.cpu_addr, env->cpu_num);
- cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1);
+ cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
} else if ((sel1 == 2) && (sel2 == 2)) {
/* Basic Machine CPUs */
struct sysib_122 sysib;
@@ -2606,68 +2662,68 @@ uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1)
stw_p(&sysib.active_cpus, 1);
stw_p(&sysib.standby_cpus, 0);
stw_p(&sysib.reserved_cpus, 0);
- cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1);
+ cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
} else {
cc = 3;
}
break;
case STSI_LEVEL_2:
- {
- if ((sel1 == 2) && (sel2 == 1)) {
- /* LPAR CPU */
- struct sysib_221 sysib;
-
- memset(&sysib, 0, sizeof(sysib));
- /* XXX make different for different CPUs? */
- ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
- ebcdic_put(sysib.plant, "QEMU", 4);
- stw_p(&sysib.cpu_addr, env->cpu_num);
- stw_p(&sysib.cpu_id, 0);
- cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1);
- } else if ((sel1 == 2) && (sel2 == 2)) {
- /* LPAR CPUs */
- struct sysib_222 sysib;
-
- memset(&sysib, 0, sizeof(sysib));
- stw_p(&sysib.lpar_num, 0);
- sysib.lcpuc = 0;
- /* XXX change when SMP comes */
- stw_p(&sysib.total_cpus, 1);
- stw_p(&sysib.conf_cpus, 1);
- stw_p(&sysib.standby_cpus, 0);
- stw_p(&sysib.reserved_cpus, 0);
- ebcdic_put(sysib.name, "QEMU ", 8);
- stl_p(&sysib.caf, 1000);
- stw_p(&sysib.dedicated_cpus, 0);
- stw_p(&sysib.shared_cpus, 0);
- cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1);
- } else {
- cc = 3;
+ {
+ if ((sel1 == 2) && (sel2 == 1)) {
+ /* LPAR CPU */
+ struct sysib_221 sysib;
+
+ memset(&sysib, 0, sizeof(sysib));
+ /* XXX make different for different CPUs? */
+ ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
+ ebcdic_put(sysib.plant, "QEMU", 4);
+ stw_p(&sysib.cpu_addr, env->cpu_num);
+ stw_p(&sysib.cpu_id, 0);
+ cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
+ } else if ((sel1 == 2) && (sel2 == 2)) {
+ /* LPAR CPUs */
+ struct sysib_222 sysib;
+
+ memset(&sysib, 0, sizeof(sysib));
+ stw_p(&sysib.lpar_num, 0);
+ sysib.lcpuc = 0;
+ /* XXX change when SMP comes */
+ stw_p(&sysib.total_cpus, 1);
+ stw_p(&sysib.conf_cpus, 1);
+ stw_p(&sysib.standby_cpus, 0);
+ stw_p(&sysib.reserved_cpus, 0);
+ ebcdic_put(sysib.name, "QEMU ", 8);
+ stl_p(&sysib.caf, 1000);
+ stw_p(&sysib.dedicated_cpus, 0);
+ stw_p(&sysib.shared_cpus, 0);
+ cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
+ } else {
+ cc = 3;
+ }
+ break;
}
- break;
- }
case STSI_LEVEL_3:
- {
- if ((sel1 == 2) && (sel2 == 2)) {
- /* VM CPUs */
- struct sysib_322 sysib;
-
- memset(&sysib, 0, sizeof(sysib));
- sysib.count = 1;
- /* XXX change when SMP comes */
- stw_p(&sysib.vm[0].total_cpus, 1);
- stw_p(&sysib.vm[0].conf_cpus, 1);
- stw_p(&sysib.vm[0].standby_cpus, 0);
- stw_p(&sysib.vm[0].reserved_cpus, 0);
- ebcdic_put(sysib.vm[0].name, "KVMguest", 8);
- stl_p(&sysib.vm[0].caf, 1000);
- ebcdic_put(sysib.vm[0].cpi, "KVM/Linux ", 16);
- cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1);
- } else {
- cc = 3;
+ {
+ if ((sel1 == 2) && (sel2 == 2)) {
+ /* VM CPUs */
+ struct sysib_322 sysib;
+
+ memset(&sysib, 0, sizeof(sysib));
+ sysib.count = 1;
+ /* XXX change when SMP comes */
+ stw_p(&sysib.vm[0].total_cpus, 1);
+ stw_p(&sysib.vm[0].conf_cpus, 1);
+ stw_p(&sysib.vm[0].standby_cpus, 0);
+ stw_p(&sysib.vm[0].reserved_cpus, 0);
+ ebcdic_put(sysib.vm[0].name, "KVMguest", 8);
+ stl_p(&sysib.vm[0].caf, 1000);
+ ebcdic_put(sysib.vm[0].cpi, "KVM/Linux ", 16);
+ cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
+ } else {
+ cc = 3;
+ }
+ break;
}
- break;
- }
case STSI_LEVEL_CURRENT:
env->regs[0] = STSI_LEVEL_3;
break;
@@ -2781,6 +2837,7 @@ uint32_t HELPER(rrbe)(uint32_t r1, uint64_t r2)
{
uint8_t re;
uint8_t key;
+
if (r2 > ram_size) {
return 0;
}
@@ -2865,7 +2922,7 @@ static uint32_t mvc_asc(int64_t l, uint64_t a1, uint64_t mode1, uint64_t a2,
uint32_t HELPER(mvcs)(uint64_t l, uint64_t a1, uint64_t a2)
{
HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
- __FUNCTION__, l, a1, a2);
+ __func__, l, a1, a2);
return mvc_asc(l, a1, PSW_ASC_SECONDARY, a2, PSW_ASC_PRIMARY);
}
@@ -2873,7 +2930,7 @@ uint32_t HELPER(mvcs)(uint64_t l, uint64_t a1, uint64_t a2)
uint32_t HELPER(mvcp)(uint64_t l, uint64_t a1, uint64_t a2)
{
HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
- __FUNCTION__, l, a1, a2);
+ __func__, l, a1, a2);
return mvc_asc(l, a1, PSW_ASC_PRIMARY, a2, PSW_ASC_SECONDARY);
}
@@ -2883,9 +2940,9 @@ uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
int cc = 0;
HELPER_LOG("%s: %016" PRIx64 " %08x %016" PRIx64 "\n",
- __FUNCTION__, order_code, r1, cpu_addr);
+ __func__, order_code, r1, cpu_addr);
- /* Remember: Use "R1 or R1+1, whichever is the odd-numbered register"
+ /* Remember: Use "R1 or R1 + 1, whichever is the odd-numbered register"
as parameter (input). Status (output) is always R1. */
switch (order_code) {
@@ -2901,7 +2958,7 @@ 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)
+#if !defined(CONFIG_USER_ONLY)
case SIGP_RESTART:
qemu_system_reset_request();
cpu_loop_exit(env);
@@ -2922,7 +2979,7 @@ uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
void HELPER(sacf)(uint64_t a1)
{
- HELPER_LOG("%s: %16" PRIx64 "\n", __FUNCTION__, a1);
+ HELPER_LOG("%s: %16" PRIx64 "\n", __func__, a1);
switch (a1 & 0xf00) {
case 0x000:
@@ -2953,13 +3010,13 @@ void HELPER(ipte)(uint64_t pte_addr, uint64_t vaddr)
/* XXX broadcast to other CPUs */
/* XXX Linux is nice enough to give us the exact pte address.
- According to spec we'd have to find it out ourselves */
+ According to spec we'd have to find it out ourselves */
/* XXX Linux is fine with overwriting the pte, the spec requires
- us to only set the invalid bit */
+ us to only set the invalid bit */
stq_phys(pte_addr, pte | _PAGE_INVALID);
/* XXX we exploit the fact that Linux passes the exact virtual
- address here - it's not obliged to! */
+ address here - it's not obliged to! */
tlb_flush_page(env, page);
/* XXX 31-bit hack */
@@ -3008,7 +3065,8 @@ uint32_t HELPER(lra)(uint64_t addr, uint32_t r1)
env->exception_index = old_exc;
if (!(env->psw.mask & PSW_MASK_64)) {
- env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | (ret & 0xffffffffULL);
+ env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
+ (ret & 0xffffffffULL);
} else {
env->regs[r1] = ret;
}
--
1.6.0.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 02/12] target-s390x: split FPU ops
2012-09-10 11:40 [Qemu-devel] [PULL 00/12] s390 patch queue 2012-09-10 Alexander Graf
2012-09-10 11:40 ` [Qemu-devel] [PATCH 01/12] target-s390x: fix style Alexander Graf
@ 2012-09-10 11:40 ` Alexander Graf
2012-09-10 11:40 ` [Qemu-devel] [PATCH 03/12] target-s390x: split condition code helpers Alexander Graf
` (10 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Alexander Graf @ 2012-09-10 11:40 UTC (permalink / raw)
To: qemu-devel qemu-devel; +Cc: Blue Swirl, Aurelien Jarno
From: Blue Swirl <blauwirbel@gmail.com>
Move floating point instructions to fpu_helper.c.
While exporting some condition code helpers,
avoid duplicate identifier conflict with translate.c.
Remove unused set_cc_nz_f64() in translate.c.
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-s390x/Makefile.objs | 2 +
target-s390x/cpu.h | 6 +
target-s390x/fpu_helper.c | 836 ++++++++++++++++++++++++++++++++++++++++++++
target-s390x/op_helper.c | 802 ------------------------------------------
target-s390x/translate.c | 11 +-
5 files changed, 847 insertions(+), 810 deletions(-)
create mode 100644 target-s390x/fpu_helper.c
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index 80be3bb..23b3bd9 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -1,5 +1,7 @@
obj-y += translate.o op_helper.o helper.o cpu.o interrupt.o
+obj-y += fpu_helper.o
obj-$(CONFIG_SOFTMMU) += machine.o
obj-$(CONFIG_KVM) += kvm.o
$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+$(obj)/fpu_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 18ac6e3..b4620c5 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -999,4 +999,10 @@ static inline void cpu_pc_from_tb(CPUS390XState *env, TranslationBlock* tb)
env->psw.addr = tb->pc;
}
+/* fpu_helper.c */
+uint32_t set_cc_f32(float32 v1, float32 v2);
+uint32_t set_cc_f64(float64 v1, float64 v2);
+uint32_t set_cc_nz_f32(float32 v);
+uint32_t set_cc_nz_f64(float64 v);
+
#endif
diff --git a/target-s390x/fpu_helper.c b/target-s390x/fpu_helper.c
new file mode 100644
index 0000000..1389052
--- /dev/null
+++ b/target-s390x/fpu_helper.c
@@ -0,0 +1,836 @@
+/*
+ * S/390 FPU helper routines
+ *
+ * Copyright (c) 2009 Ulrich Hecht
+ * Copyright (c) 2009 Alexander Graf
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cpu.h"
+#include "dyngen-exec.h"
+#include "helper.h"
+
+#if !defined(CONFIG_USER_ONLY)
+#include "softmmu_exec.h"
+#endif
+
+/* #define DEBUG_HELPER */
+#ifdef DEBUG_HELPER
+#define HELPER_LOG(x...) qemu_log(x)
+#else
+#define HELPER_LOG(x...)
+#endif
+
+static inline int float_comp_to_cc(int float_compare)
+{
+ switch (float_compare) {
+ case float_relation_equal:
+ return 0;
+ case float_relation_less:
+ return 1;
+ case float_relation_greater:
+ return 2;
+ case float_relation_unordered:
+ return 3;
+ default:
+ cpu_abort(env, "unknown return value for float compare\n");
+ }
+}
+
+/* condition codes for binary FP ops */
+uint32_t set_cc_f32(float32 v1, float32 v2)
+{
+ return float_comp_to_cc(float32_compare_quiet(v1, v2, &env->fpu_status));
+}
+
+uint32_t set_cc_f64(float64 v1, float64 v2)
+{
+ return float_comp_to_cc(float64_compare_quiet(v1, v2, &env->fpu_status));
+}
+
+/* condition codes for unary FP ops */
+uint32_t set_cc_nz_f32(float32 v)
+{
+ if (float32_is_any_nan(v)) {
+ return 3;
+ } else if (float32_is_zero(v)) {
+ return 0;
+ } else if (float32_is_neg(v)) {
+ return 1;
+ } else {
+ return 2;
+ }
+}
+
+uint32_t set_cc_nz_f64(float64 v)
+{
+ if (float64_is_any_nan(v)) {
+ return 3;
+ } else if (float64_is_zero(v)) {
+ return 0;
+ } else if (float64_is_neg(v)) {
+ return 1;
+ } else {
+ return 2;
+ }
+}
+
+static uint32_t set_cc_nz_f128(float128 v)
+{
+ if (float128_is_any_nan(v)) {
+ return 3;
+ } else if (float128_is_zero(v)) {
+ return 0;
+ } else if (float128_is_neg(v)) {
+ return 1;
+ } else {
+ return 2;
+ }
+}
+
+/* convert 32-bit int to 64-bit float */
+void HELPER(cdfbr)(uint32_t f1, int32_t v2)
+{
+ HELPER_LOG("%s: converting %d to f%d\n", __func__, v2, f1);
+ env->fregs[f1].d = int32_to_float64(v2, &env->fpu_status);
+}
+
+/* convert 32-bit int to 128-bit float */
+void HELPER(cxfbr)(uint32_t f1, int32_t v2)
+{
+ CPU_QuadU v1;
+
+ v1.q = int32_to_float128(v2, &env->fpu_status);
+ env->fregs[f1].ll = v1.ll.upper;
+ env->fregs[f1 + 2].ll = v1.ll.lower;
+}
+
+/* convert 64-bit int to 32-bit float */
+void HELPER(cegbr)(uint32_t f1, int64_t v2)
+{
+ HELPER_LOG("%s: converting %ld to f%d\n", __func__, v2, f1);
+ env->fregs[f1].l.upper = int64_to_float32(v2, &env->fpu_status);
+}
+
+/* convert 64-bit int to 64-bit float */
+void HELPER(cdgbr)(uint32_t f1, int64_t v2)
+{
+ HELPER_LOG("%s: converting %ld to f%d\n", __func__, v2, f1);
+ env->fregs[f1].d = int64_to_float64(v2, &env->fpu_status);
+}
+
+/* convert 64-bit int to 128-bit float */
+void HELPER(cxgbr)(uint32_t f1, int64_t v2)
+{
+ CPU_QuadU x1;
+
+ x1.q = int64_to_float128(v2, &env->fpu_status);
+ HELPER_LOG("%s: converted %ld to 0x%lx and 0x%lx\n", __func__, v2,
+ x1.ll.upper, x1.ll.lower);
+ env->fregs[f1].ll = x1.ll.upper;
+ env->fregs[f1 + 2].ll = x1.ll.lower;
+}
+
+/* convert 32-bit int to 32-bit float */
+void HELPER(cefbr)(uint32_t f1, int32_t v2)
+{
+ env->fregs[f1].l.upper = int32_to_float32(v2, &env->fpu_status);
+ HELPER_LOG("%s: converting %d to 0x%d in f%d\n", __func__, v2,
+ env->fregs[f1].l.upper, f1);
+}
+
+/* 32-bit FP addition RR */
+uint32_t HELPER(aebr)(uint32_t f1, uint32_t f2)
+{
+ env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper,
+ env->fregs[f2].l.upper,
+ &env->fpu_status);
+ HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __func__,
+ env->fregs[f2].l.upper, env->fregs[f1].l.upper, f1);
+
+ return set_cc_nz_f32(env->fregs[f1].l.upper);
+}
+
+/* 64-bit FP addition RR */
+uint32_t HELPER(adbr)(uint32_t f1, uint32_t f2)
+{
+ env->fregs[f1].d = float64_add(env->fregs[f1].d, env->fregs[f2].d,
+ &env->fpu_status);
+ HELPER_LOG("%s: adding 0x%ld resulting in 0x%ld in f%d\n", __func__,
+ env->fregs[f2].d, env->fregs[f1].d, f1);
+
+ return set_cc_nz_f64(env->fregs[f1].d);
+}
+
+/* 32-bit FP subtraction RR */
+uint32_t HELPER(sebr)(uint32_t f1, uint32_t f2)
+{
+ env->fregs[f1].l.upper = float32_sub(env->fregs[f1].l.upper,
+ env->fregs[f2].l.upper,
+ &env->fpu_status);
+ HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __func__,
+ env->fregs[f2].l.upper, env->fregs[f1].l.upper, f1);
+
+ return set_cc_nz_f32(env->fregs[f1].l.upper);
+}
+
+/* 64-bit FP subtraction RR */
+uint32_t HELPER(sdbr)(uint32_t f1, uint32_t f2)
+{
+ env->fregs[f1].d = float64_sub(env->fregs[f1].d, env->fregs[f2].d,
+ &env->fpu_status);
+ HELPER_LOG("%s: subtracting 0x%ld resulting in 0x%ld in f%d\n",
+ __func__, env->fregs[f2].d, env->fregs[f1].d, f1);
+
+ return set_cc_nz_f64(env->fregs[f1].d);
+}
+
+/* 32-bit FP division RR */
+void HELPER(debr)(uint32_t f1, uint32_t f2)
+{
+ env->fregs[f1].l.upper = float32_div(env->fregs[f1].l.upper,
+ env->fregs[f2].l.upper,
+ &env->fpu_status);
+}
+
+/* 128-bit FP division RR */
+void HELPER(dxbr)(uint32_t f1, uint32_t f2)
+{
+ CPU_QuadU v1;
+ CPU_QuadU v2;
+ CPU_QuadU res;
+
+ v1.ll.upper = env->fregs[f1].ll;
+ v1.ll.lower = env->fregs[f1 + 2].ll;
+ v2.ll.upper = env->fregs[f2].ll;
+ v2.ll.lower = env->fregs[f2 + 2].ll;
+ res.q = float128_div(v1.q, v2.q, &env->fpu_status);
+ env->fregs[f1].ll = res.ll.upper;
+ env->fregs[f1 + 2].ll = res.ll.lower;
+}
+
+/* 64-bit FP multiplication RR */
+void HELPER(mdbr)(uint32_t f1, uint32_t f2)
+{
+ env->fregs[f1].d = float64_mul(env->fregs[f1].d, env->fregs[f2].d,
+ &env->fpu_status);
+}
+
+/* 128-bit FP multiplication RR */
+void HELPER(mxbr)(uint32_t f1, uint32_t f2)
+{
+ CPU_QuadU v1;
+ CPU_QuadU v2;
+ CPU_QuadU res;
+
+ v1.ll.upper = env->fregs[f1].ll;
+ v1.ll.lower = env->fregs[f1 + 2].ll;
+ v2.ll.upper = env->fregs[f2].ll;
+ v2.ll.lower = env->fregs[f2 + 2].ll;
+ res.q = float128_mul(v1.q, v2.q, &env->fpu_status);
+ env->fregs[f1].ll = res.ll.upper;
+ env->fregs[f1 + 2].ll = res.ll.lower;
+}
+
+/* convert 32-bit float to 64-bit float */
+void HELPER(ldebr)(uint32_t r1, uint32_t r2)
+{
+ env->fregs[r1].d = float32_to_float64(env->fregs[r2].l.upper,
+ &env->fpu_status);
+}
+
+/* convert 128-bit float to 64-bit float */
+void HELPER(ldxbr)(uint32_t f1, uint32_t f2)
+{
+ CPU_QuadU x2;
+
+ x2.ll.upper = env->fregs[f2].ll;
+ x2.ll.lower = env->fregs[f2 + 2].ll;
+ env->fregs[f1].d = float128_to_float64(x2.q, &env->fpu_status);
+ HELPER_LOG("%s: to 0x%ld\n", __func__, env->fregs[f1].d);
+}
+
+/* convert 64-bit float to 128-bit float */
+void HELPER(lxdbr)(uint32_t f1, uint32_t f2)
+{
+ CPU_QuadU res;
+
+ res.q = float64_to_float128(env->fregs[f2].d, &env->fpu_status);
+ env->fregs[f1].ll = res.ll.upper;
+ env->fregs[f1 + 2].ll = res.ll.lower;
+}
+
+/* convert 64-bit float to 32-bit float */
+void HELPER(ledbr)(uint32_t f1, uint32_t f2)
+{
+ float64 d2 = env->fregs[f2].d;
+
+ env->fregs[f1].l.upper = float64_to_float32(d2, &env->fpu_status);
+}
+
+/* convert 128-bit float to 32-bit float */
+void HELPER(lexbr)(uint32_t f1, uint32_t f2)
+{
+ CPU_QuadU x2;
+
+ x2.ll.upper = env->fregs[f2].ll;
+ x2.ll.lower = env->fregs[f2 + 2].ll;
+ env->fregs[f1].l.upper = float128_to_float32(x2.q, &env->fpu_status);
+ HELPER_LOG("%s: to 0x%d\n", __func__, env->fregs[f1].l.upper);
+}
+
+/* absolute value of 32-bit float */
+uint32_t HELPER(lpebr)(uint32_t f1, uint32_t f2)
+{
+ float32 v1;
+ float32 v2 = env->fregs[f2].d;
+
+ v1 = float32_abs(v2);
+ env->fregs[f1].d = v1;
+ return set_cc_nz_f32(v1);
+}
+
+/* absolute value of 64-bit float */
+uint32_t HELPER(lpdbr)(uint32_t f1, uint32_t f2)
+{
+ float64 v1;
+ float64 v2 = env->fregs[f2].d;
+
+ v1 = float64_abs(v2);
+ env->fregs[f1].d = v1;
+ return set_cc_nz_f64(v1);
+}
+
+/* absolute value of 128-bit float */
+uint32_t HELPER(lpxbr)(uint32_t f1, uint32_t f2)
+{
+ CPU_QuadU v1;
+ CPU_QuadU v2;
+
+ v2.ll.upper = env->fregs[f2].ll;
+ v2.ll.lower = env->fregs[f2 + 2].ll;
+ v1.q = float128_abs(v2.q);
+ env->fregs[f1].ll = v1.ll.upper;
+ env->fregs[f1 + 2].ll = v1.ll.lower;
+ return set_cc_nz_f128(v1.q);
+}
+
+/* load and test 64-bit float */
+uint32_t HELPER(ltdbr)(uint32_t f1, uint32_t f2)
+{
+ env->fregs[f1].d = env->fregs[f2].d;
+ return set_cc_nz_f64(env->fregs[f1].d);
+}
+
+/* load and test 32-bit float */
+uint32_t HELPER(ltebr)(uint32_t f1, uint32_t f2)
+{
+ env->fregs[f1].l.upper = env->fregs[f2].l.upper;
+ return set_cc_nz_f32(env->fregs[f1].l.upper);
+}
+
+/* load and test 128-bit float */
+uint32_t HELPER(ltxbr)(uint32_t f1, uint32_t f2)
+{
+ CPU_QuadU x;
+
+ x.ll.upper = env->fregs[f2].ll;
+ x.ll.lower = env->fregs[f2 + 2].ll;
+ env->fregs[f1].ll = x.ll.upper;
+ env->fregs[f1 + 2].ll = x.ll.lower;
+ return set_cc_nz_f128(x.q);
+}
+
+/* load complement of 32-bit float */
+uint32_t HELPER(lcebr)(uint32_t f1, uint32_t f2)
+{
+ env->fregs[f1].l.upper = float32_chs(env->fregs[f2].l.upper);
+
+ return set_cc_nz_f32(env->fregs[f1].l.upper);
+}
+
+/* load complement of 64-bit float */
+uint32_t HELPER(lcdbr)(uint32_t f1, uint32_t f2)
+{
+ env->fregs[f1].d = float64_chs(env->fregs[f2].d);
+
+ return set_cc_nz_f64(env->fregs[f1].d);
+}
+
+/* load complement of 128-bit float */
+uint32_t HELPER(lcxbr)(uint32_t f1, uint32_t f2)
+{
+ CPU_QuadU x1, x2;
+
+ x2.ll.upper = env->fregs[f2].ll;
+ x2.ll.lower = env->fregs[f2 + 2].ll;
+ x1.q = float128_chs(x2.q);
+ env->fregs[f1].ll = x1.ll.upper;
+ env->fregs[f1 + 2].ll = x1.ll.lower;
+ return set_cc_nz_f128(x1.q);
+}
+
+/* 32-bit FP addition RM */
+void HELPER(aeb)(uint32_t f1, uint32_t val)
+{
+ float32 v1 = env->fregs[f1].l.upper;
+ CPU_FloatU v2;
+
+ v2.l = val;
+ HELPER_LOG("%s: adding 0x%d from f%d and 0x%d\n", __func__,
+ v1, f1, v2.f);
+ env->fregs[f1].l.upper = float32_add(v1, v2.f, &env->fpu_status);
+}
+
+/* 32-bit FP division RM */
+void HELPER(deb)(uint32_t f1, uint32_t val)
+{
+ float32 v1 = env->fregs[f1].l.upper;
+ CPU_FloatU v2;
+
+ v2.l = val;
+ HELPER_LOG("%s: dividing 0x%d from f%d by 0x%d\n", __func__,
+ v1, f1, v2.f);
+ env->fregs[f1].l.upper = float32_div(v1, v2.f, &env->fpu_status);
+}
+
+/* 32-bit FP multiplication RM */
+void HELPER(meeb)(uint32_t f1, uint32_t val)
+{
+ float32 v1 = env->fregs[f1].l.upper;
+ CPU_FloatU v2;
+
+ v2.l = val;
+ HELPER_LOG("%s: multiplying 0x%d from f%d and 0x%d\n", __func__,
+ v1, f1, v2.f);
+ env->fregs[f1].l.upper = float32_mul(v1, v2.f, &env->fpu_status);
+}
+
+/* 32-bit FP compare RR */
+uint32_t HELPER(cebr)(uint32_t f1, uint32_t f2)
+{
+ float32 v1 = env->fregs[f1].l.upper;
+ float32 v2 = env->fregs[f2].l.upper;
+
+ HELPER_LOG("%s: comparing 0x%d from f%d and 0x%d\n", __func__,
+ v1, f1, v2);
+ return set_cc_f32(v1, v2);
+}
+
+/* 64-bit FP compare RR */
+uint32_t HELPER(cdbr)(uint32_t f1, uint32_t f2)
+{
+ float64 v1 = env->fregs[f1].d;
+ float64 v2 = env->fregs[f2].d;
+
+ HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%ld\n", __func__,
+ v1, f1, v2);
+ return set_cc_f64(v1, v2);
+}
+
+/* 128-bit FP compare RR */
+uint32_t HELPER(cxbr)(uint32_t f1, uint32_t f2)
+{
+ CPU_QuadU v1;
+ CPU_QuadU v2;
+
+ v1.ll.upper = env->fregs[f1].ll;
+ v1.ll.lower = env->fregs[f1 + 2].ll;
+ v2.ll.upper = env->fregs[f2].ll;
+ v2.ll.lower = env->fregs[f2 + 2].ll;
+
+ return float_comp_to_cc(float128_compare_quiet(v1.q, v2.q,
+ &env->fpu_status));
+}
+
+/* 64-bit FP compare RM */
+uint32_t HELPER(cdb)(uint32_t f1, uint64_t a2)
+{
+ float64 v1 = env->fregs[f1].d;
+ CPU_DoubleU v2;
+
+ v2.ll = ldq(a2);
+ HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%lx\n", __func__, v1,
+ f1, v2.d);
+ return set_cc_f64(v1, v2.d);
+}
+
+/* 64-bit FP addition RM */
+uint32_t HELPER(adb)(uint32_t f1, uint64_t a2)
+{
+ float64 v1 = env->fregs[f1].d;
+ CPU_DoubleU v2;
+
+ v2.ll = ldq(a2);
+ HELPER_LOG("%s: adding 0x%lx from f%d and 0x%lx\n", __func__,
+ v1, f1, v2.d);
+ env->fregs[f1].d = v1 = float64_add(v1, v2.d, &env->fpu_status);
+ return set_cc_nz_f64(v1);
+}
+
+/* 32-bit FP subtraction RM */
+void HELPER(seb)(uint32_t f1, uint32_t val)
+{
+ float32 v1 = env->fregs[f1].l.upper;
+ CPU_FloatU v2;
+
+ v2.l = val;
+ env->fregs[f1].l.upper = float32_sub(v1, v2.f, &env->fpu_status);
+}
+
+/* 64-bit FP subtraction RM */
+uint32_t HELPER(sdb)(uint32_t f1, uint64_t a2)
+{
+ float64 v1 = env->fregs[f1].d;
+ CPU_DoubleU v2;
+
+ v2.ll = ldq(a2);
+ env->fregs[f1].d = v1 = float64_sub(v1, v2.d, &env->fpu_status);
+ return set_cc_nz_f64(v1);
+}
+
+/* 64-bit FP multiplication RM */
+void HELPER(mdb)(uint32_t f1, uint64_t a2)
+{
+ float64 v1 = env->fregs[f1].d;
+ CPU_DoubleU v2;
+
+ v2.ll = ldq(a2);
+ HELPER_LOG("%s: multiplying 0x%lx from f%d and 0x%ld\n", __func__,
+ v1, f1, v2.d);
+ env->fregs[f1].d = float64_mul(v1, v2.d, &env->fpu_status);
+}
+
+/* 64-bit FP division RM */
+void HELPER(ddb)(uint32_t f1, uint64_t a2)
+{
+ float64 v1 = env->fregs[f1].d;
+ CPU_DoubleU v2;
+
+ v2.ll = ldq(a2);
+ HELPER_LOG("%s: dividing 0x%lx from f%d by 0x%ld\n", __func__,
+ v1, f1, v2.d);
+ env->fregs[f1].d = float64_div(v1, v2.d, &env->fpu_status);
+}
+
+static void set_round_mode(int m3)
+{
+ switch (m3) {
+ case 0:
+ /* current mode */
+ break;
+ case 1:
+ /* biased round no nearest */
+ case 4:
+ /* round to nearest */
+ set_float_rounding_mode(float_round_nearest_even, &env->fpu_status);
+ break;
+ case 5:
+ /* round to zero */
+ set_float_rounding_mode(float_round_to_zero, &env->fpu_status);
+ break;
+ case 6:
+ /* round to +inf */
+ set_float_rounding_mode(float_round_up, &env->fpu_status);
+ break;
+ case 7:
+ /* round to -inf */
+ set_float_rounding_mode(float_round_down, &env->fpu_status);
+ break;
+ }
+}
+
+/* convert 32-bit float to 64-bit int */
+uint32_t HELPER(cgebr)(uint32_t r1, uint32_t f2, uint32_t m3)
+{
+ float32 v2 = env->fregs[f2].l.upper;
+
+ set_round_mode(m3);
+ env->regs[r1] = float32_to_int64(v2, &env->fpu_status);
+ return set_cc_nz_f32(v2);
+}
+
+/* convert 64-bit float to 64-bit int */
+uint32_t HELPER(cgdbr)(uint32_t r1, uint32_t f2, uint32_t m3)
+{
+ float64 v2 = env->fregs[f2].d;
+
+ set_round_mode(m3);
+ env->regs[r1] = float64_to_int64(v2, &env->fpu_status);
+ return set_cc_nz_f64(v2);
+}
+
+/* convert 128-bit float to 64-bit int */
+uint32_t HELPER(cgxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
+{
+ CPU_QuadU v2;
+
+ v2.ll.upper = env->fregs[f2].ll;
+ v2.ll.lower = env->fregs[f2 + 2].ll;
+ set_round_mode(m3);
+ env->regs[r1] = float128_to_int64(v2.q, &env->fpu_status);
+ if (float128_is_any_nan(v2.q)) {
+ return 3;
+ } else if (float128_is_zero(v2.q)) {
+ return 0;
+ } else if (float128_is_neg(v2.q)) {
+ return 1;
+ } else {
+ return 2;
+ }
+}
+
+/* convert 32-bit float to 32-bit int */
+uint32_t HELPER(cfebr)(uint32_t r1, uint32_t f2, uint32_t m3)
+{
+ float32 v2 = env->fregs[f2].l.upper;
+
+ set_round_mode(m3);
+ env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
+ float32_to_int32(v2, &env->fpu_status);
+ return set_cc_nz_f32(v2);
+}
+
+/* convert 64-bit float to 32-bit int */
+uint32_t HELPER(cfdbr)(uint32_t r1, uint32_t f2, uint32_t m3)
+{
+ float64 v2 = env->fregs[f2].d;
+
+ set_round_mode(m3);
+ env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
+ float64_to_int32(v2, &env->fpu_status);
+ return set_cc_nz_f64(v2);
+}
+
+/* convert 128-bit float to 32-bit int */
+uint32_t HELPER(cfxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
+{
+ CPU_QuadU v2;
+
+ v2.ll.upper = env->fregs[f2].ll;
+ v2.ll.lower = env->fregs[f2 + 2].ll;
+ env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
+ float128_to_int32(v2.q, &env->fpu_status);
+ return set_cc_nz_f128(v2.q);
+}
+
+/* load 32-bit FP zero */
+void HELPER(lzer)(uint32_t f1)
+{
+ env->fregs[f1].l.upper = float32_zero;
+}
+
+/* load 64-bit FP zero */
+void HELPER(lzdr)(uint32_t f1)
+{
+ env->fregs[f1].d = float64_zero;
+}
+
+/* load 128-bit FP zero */
+void HELPER(lzxr)(uint32_t f1)
+{
+ CPU_QuadU x;
+
+ x.q = float64_to_float128(float64_zero, &env->fpu_status);
+ env->fregs[f1].ll = x.ll.upper;
+ env->fregs[f1 + 1].ll = x.ll.lower;
+}
+
+/* 128-bit FP subtraction RR */
+uint32_t HELPER(sxbr)(uint32_t f1, uint32_t f2)
+{
+ CPU_QuadU v1;
+ CPU_QuadU v2;
+ CPU_QuadU res;
+
+ v1.ll.upper = env->fregs[f1].ll;
+ v1.ll.lower = env->fregs[f1 + 2].ll;
+ v2.ll.upper = env->fregs[f2].ll;
+ v2.ll.lower = env->fregs[f2 + 2].ll;
+ res.q = float128_sub(v1.q, v2.q, &env->fpu_status);
+ env->fregs[f1].ll = res.ll.upper;
+ env->fregs[f1 + 2].ll = res.ll.lower;
+ return set_cc_nz_f128(res.q);
+}
+
+/* 128-bit FP addition RR */
+uint32_t HELPER(axbr)(uint32_t f1, uint32_t f2)
+{
+ CPU_QuadU v1;
+ CPU_QuadU v2;
+ CPU_QuadU res;
+
+ v1.ll.upper = env->fregs[f1].ll;
+ v1.ll.lower = env->fregs[f1 + 2].ll;
+ v2.ll.upper = env->fregs[f2].ll;
+ v2.ll.lower = env->fregs[f2 + 2].ll;
+ res.q = float128_add(v1.q, v2.q, &env->fpu_status);
+ env->fregs[f1].ll = res.ll.upper;
+ env->fregs[f1 + 2].ll = res.ll.lower;
+ return set_cc_nz_f128(res.q);
+}
+
+/* 32-bit FP multiplication RR */
+void HELPER(meebr)(uint32_t f1, uint32_t f2)
+{
+ env->fregs[f1].l.upper = float32_mul(env->fregs[f1].l.upper,
+ env->fregs[f2].l.upper,
+ &env->fpu_status);
+}
+
+/* 64-bit FP division RR */
+void HELPER(ddbr)(uint32_t f1, uint32_t f2)
+{
+ env->fregs[f1].d = float64_div(env->fregs[f1].d, env->fregs[f2].d,
+ &env->fpu_status);
+}
+
+/* 64-bit FP multiply and add RM */
+void HELPER(madb)(uint32_t f1, uint64_t a2, uint32_t f3)
+{
+ CPU_DoubleU v2;
+
+ HELPER_LOG("%s: f1 %d a2 0x%lx f3 %d\n", __func__, f1, a2, f3);
+ v2.ll = ldq(a2);
+ env->fregs[f1].d = float64_add(env->fregs[f1].d,
+ float64_mul(v2.d, env->fregs[f3].d,
+ &env->fpu_status),
+ &env->fpu_status);
+}
+
+/* 64-bit FP multiply and add RR */
+void HELPER(madbr)(uint32_t f1, uint32_t f3, uint32_t f2)
+{
+ HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __func__, f1, f2, f3);
+ env->fregs[f1].d = float64_add(float64_mul(env->fregs[f2].d,
+ env->fregs[f3].d,
+ &env->fpu_status),
+ env->fregs[f1].d, &env->fpu_status);
+}
+
+/* 64-bit FP multiply and subtract RR */
+void HELPER(msdbr)(uint32_t f1, uint32_t f3, uint32_t f2)
+{
+ HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __func__, f1, f2, f3);
+ env->fregs[f1].d = float64_sub(float64_mul(env->fregs[f2].d,
+ env->fregs[f3].d,
+ &env->fpu_status),
+ env->fregs[f1].d, &env->fpu_status);
+}
+
+/* 32-bit FP multiply and add RR */
+void HELPER(maebr)(uint32_t f1, uint32_t f3, uint32_t f2)
+{
+ env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper,
+ float32_mul(env->fregs[f2].l.upper,
+ env->fregs[f3].l.upper,
+ &env->fpu_status),
+ &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)
+{
+ CPU_DoubleU v2;
+ CPU_QuadU v1;
+
+ v2.ll = ldq(a2);
+ v1.q = float64_to_float128(v2.d, &env->fpu_status);
+ env->fregs[f1].ll = v1.ll.upper;
+ env->fregs[f1 + 2].ll = v1.ll.lower;
+}
+
+/* test data class 32-bit */
+uint32_t HELPER(tceb)(uint32_t f1, uint64_t m2)
+{
+ float32 v1 = env->fregs[f1].l.upper;
+ int neg = float32_is_neg(v1);
+ uint32_t cc = 0;
+
+ HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __func__, (long)v1, m2, neg);
+ if ((float32_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
+ (float32_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
+ (float32_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
+ (float32_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) {
+ cc = 1;
+ } else if (m2 & (1 << (9-neg))) {
+ /* assume normalized number */
+ cc = 1;
+ }
+
+ /* FIXME: denormalized? */
+ return cc;
+}
+
+/* test data class 64-bit */
+uint32_t HELPER(tcdb)(uint32_t f1, uint64_t m2)
+{
+ float64 v1 = env->fregs[f1].d;
+ int neg = float64_is_neg(v1);
+ uint32_t cc = 0;
+
+ HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __func__, v1, m2, neg);
+ if ((float64_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
+ (float64_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
+ (float64_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
+ (float64_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) {
+ cc = 1;
+ } else if (m2 & (1 << (9-neg))) {
+ /* assume normalized number */
+ cc = 1;
+ }
+ /* FIXME: denormalized? */
+ return cc;
+}
+
+/* test data class 128-bit */
+uint32_t HELPER(tcxb)(uint32_t f1, uint64_t m2)
+{
+ CPU_QuadU v1;
+ uint32_t cc = 0;
+ int neg;
+
+ v1.ll.upper = env->fregs[f1].ll;
+ v1.ll.lower = env->fregs[f1 + 2].ll;
+
+ neg = float128_is_neg(v1.q);
+ if ((float128_is_zero(v1.q) && (m2 & (1 << (11-neg)))) ||
+ (float128_is_infinity(v1.q) && (m2 & (1 << (5-neg)))) ||
+ (float128_is_any_nan(v1.q) && (m2 & (1 << (3-neg)))) ||
+ (float128_is_signaling_nan(v1.q) && (m2 & (1 << (1-neg))))) {
+ cc = 1;
+ } else if (m2 & (1 << (9-neg))) {
+ /* assume normalized number */
+ cc = 1;
+ }
+ /* FIXME: denormalized? */
+ return cc;
+}
+
+/* square root 64-bit RR */
+void HELPER(sqdbr)(uint32_t f1, uint32_t f2)
+{
+ env->fregs[f1].d = float64_sqrt(env->fregs[f2].d, &env->fpu_status);
+}
diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
index 195e93e..270bf14 100644
--- a/target-s390x/op_helper.c
+++ b/target-s390x/op_helper.c
@@ -977,802 +977,6 @@ uint32_t HELPER(slbg)(uint32_t cc, uint32_t r1, uint64_t v1, uint64_t v2)
}
}
-static inline int float_comp_to_cc(int float_compare)
-{
- switch (float_compare) {
- case float_relation_equal:
- return 0;
- case float_relation_less:
- return 1;
- case float_relation_greater:
- return 2;
- case float_relation_unordered:
- return 3;
- default:
- cpu_abort(env, "unknown return value for float compare\n");
- }
-}
-
-/* condition codes for binary FP ops */
-static uint32_t set_cc_f32(float32 v1, float32 v2)
-{
- return float_comp_to_cc(float32_compare_quiet(v1, v2, &env->fpu_status));
-}
-
-static uint32_t set_cc_f64(float64 v1, float64 v2)
-{
- return float_comp_to_cc(float64_compare_quiet(v1, v2, &env->fpu_status));
-}
-
-/* condition codes for unary FP ops */
-static uint32_t set_cc_nz_f32(float32 v)
-{
- if (float32_is_any_nan(v)) {
- return 3;
- } else if (float32_is_zero(v)) {
- return 0;
- } else if (float32_is_neg(v)) {
- return 1;
- } else {
- return 2;
- }
-}
-
-static uint32_t set_cc_nz_f64(float64 v)
-{
- if (float64_is_any_nan(v)) {
- return 3;
- } else if (float64_is_zero(v)) {
- return 0;
- } else if (float64_is_neg(v)) {
- return 1;
- } else {
- return 2;
- }
-}
-
-static uint32_t set_cc_nz_f128(float128 v)
-{
- if (float128_is_any_nan(v)) {
- return 3;
- } else if (float128_is_zero(v)) {
- return 0;
- } else if (float128_is_neg(v)) {
- return 1;
- } else {
- return 2;
- }
-}
-
-/* convert 32-bit int to 64-bit float */
-void HELPER(cdfbr)(uint32_t f1, int32_t v2)
-{
- HELPER_LOG("%s: converting %d to f%d\n", __func__, v2, f1);
- env->fregs[f1].d = int32_to_float64(v2, &env->fpu_status);
-}
-
-/* convert 32-bit int to 128-bit float */
-void HELPER(cxfbr)(uint32_t f1, int32_t v2)
-{
- CPU_QuadU v1;
-
- v1.q = int32_to_float128(v2, &env->fpu_status);
- env->fregs[f1].ll = v1.ll.upper;
- env->fregs[f1 + 2].ll = v1.ll.lower;
-}
-
-/* convert 64-bit int to 32-bit float */
-void HELPER(cegbr)(uint32_t f1, int64_t v2)
-{
- HELPER_LOG("%s: converting %ld to f%d\n", __func__, v2, f1);
- env->fregs[f1].l.upper = int64_to_float32(v2, &env->fpu_status);
-}
-
-/* convert 64-bit int to 64-bit float */
-void HELPER(cdgbr)(uint32_t f1, int64_t v2)
-{
- HELPER_LOG("%s: converting %ld to f%d\n", __func__, v2, f1);
- env->fregs[f1].d = int64_to_float64(v2, &env->fpu_status);
-}
-
-/* convert 64-bit int to 128-bit float */
-void HELPER(cxgbr)(uint32_t f1, int64_t v2)
-{
- CPU_QuadU x1;
-
- x1.q = int64_to_float128(v2, &env->fpu_status);
- HELPER_LOG("%s: converted %ld to 0x%lx and 0x%lx\n", __func__, v2,
- x1.ll.upper, x1.ll.lower);
- env->fregs[f1].ll = x1.ll.upper;
- env->fregs[f1 + 2].ll = x1.ll.lower;
-}
-
-/* convert 32-bit int to 32-bit float */
-void HELPER(cefbr)(uint32_t f1, int32_t v2)
-{
- env->fregs[f1].l.upper = int32_to_float32(v2, &env->fpu_status);
- HELPER_LOG("%s: converting %d to 0x%d in f%d\n", __func__, v2,
- env->fregs[f1].l.upper, f1);
-}
-
-/* 32-bit FP addition RR */
-uint32_t HELPER(aebr)(uint32_t f1, uint32_t f2)
-{
- env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper,
- env->fregs[f2].l.upper,
- &env->fpu_status);
- HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __func__,
- env->fregs[f2].l.upper, env->fregs[f1].l.upper, f1);
-
- return set_cc_nz_f32(env->fregs[f1].l.upper);
-}
-
-/* 64-bit FP addition RR */
-uint32_t HELPER(adbr)(uint32_t f1, uint32_t f2)
-{
- env->fregs[f1].d = float64_add(env->fregs[f1].d, env->fregs[f2].d,
- &env->fpu_status);
- HELPER_LOG("%s: adding 0x%ld resulting in 0x%ld in f%d\n", __func__,
- env->fregs[f2].d, env->fregs[f1].d, f1);
-
- return set_cc_nz_f64(env->fregs[f1].d);
-}
-
-/* 32-bit FP subtraction RR */
-uint32_t HELPER(sebr)(uint32_t f1, uint32_t f2)
-{
- env->fregs[f1].l.upper = float32_sub(env->fregs[f1].l.upper,
- env->fregs[f2].l.upper,
- &env->fpu_status);
- HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __func__,
- env->fregs[f2].l.upper, env->fregs[f1].l.upper, f1);
-
- return set_cc_nz_f32(env->fregs[f1].l.upper);
-}
-
-/* 64-bit FP subtraction RR */
-uint32_t HELPER(sdbr)(uint32_t f1, uint32_t f2)
-{
- env->fregs[f1].d = float64_sub(env->fregs[f1].d, env->fregs[f2].d,
- &env->fpu_status);
- HELPER_LOG("%s: subtracting 0x%ld resulting in 0x%ld in f%d\n",
- __func__, env->fregs[f2].d, env->fregs[f1].d, f1);
-
- return set_cc_nz_f64(env->fregs[f1].d);
-}
-
-/* 32-bit FP division RR */
-void HELPER(debr)(uint32_t f1, uint32_t f2)
-{
- env->fregs[f1].l.upper = float32_div(env->fregs[f1].l.upper,
- env->fregs[f2].l.upper,
- &env->fpu_status);
-}
-
-/* 128-bit FP division RR */
-void HELPER(dxbr)(uint32_t f1, uint32_t f2)
-{
- CPU_QuadU v1;
- CPU_QuadU v2;
- CPU_QuadU res;
-
- v1.ll.upper = env->fregs[f1].ll;
- v1.ll.lower = env->fregs[f1 + 2].ll;
- v2.ll.upper = env->fregs[f2].ll;
- v2.ll.lower = env->fregs[f2 + 2].ll;
- res.q = float128_div(v1.q, v2.q, &env->fpu_status);
- env->fregs[f1].ll = res.ll.upper;
- env->fregs[f1 + 2].ll = res.ll.lower;
-}
-
-/* 64-bit FP multiplication RR */
-void HELPER(mdbr)(uint32_t f1, uint32_t f2)
-{
- env->fregs[f1].d = float64_mul(env->fregs[f1].d, env->fregs[f2].d,
- &env->fpu_status);
-}
-
-/* 128-bit FP multiplication RR */
-void HELPER(mxbr)(uint32_t f1, uint32_t f2)
-{
- CPU_QuadU v1;
- CPU_QuadU v2;
- CPU_QuadU res;
-
- v1.ll.upper = env->fregs[f1].ll;
- v1.ll.lower = env->fregs[f1 + 2].ll;
- v2.ll.upper = env->fregs[f2].ll;
- v2.ll.lower = env->fregs[f2 + 2].ll;
- res.q = float128_mul(v1.q, v2.q, &env->fpu_status);
- env->fregs[f1].ll = res.ll.upper;
- env->fregs[f1 + 2].ll = res.ll.lower;
-}
-
-/* convert 32-bit float to 64-bit float */
-void HELPER(ldebr)(uint32_t r1, uint32_t r2)
-{
- env->fregs[r1].d = float32_to_float64(env->fregs[r2].l.upper,
- &env->fpu_status);
-}
-
-/* convert 128-bit float to 64-bit float */
-void HELPER(ldxbr)(uint32_t f1, uint32_t f2)
-{
- CPU_QuadU x2;
-
- x2.ll.upper = env->fregs[f2].ll;
- x2.ll.lower = env->fregs[f2 + 2].ll;
- env->fregs[f1].d = float128_to_float64(x2.q, &env->fpu_status);
- HELPER_LOG("%s: to 0x%ld\n", __func__, env->fregs[f1].d);
-}
-
-/* convert 64-bit float to 128-bit float */
-void HELPER(lxdbr)(uint32_t f1, uint32_t f2)
-{
- CPU_QuadU res;
-
- res.q = float64_to_float128(env->fregs[f2].d, &env->fpu_status);
- env->fregs[f1].ll = res.ll.upper;
- env->fregs[f1 + 2].ll = res.ll.lower;
-}
-
-/* convert 64-bit float to 32-bit float */
-void HELPER(ledbr)(uint32_t f1, uint32_t f2)
-{
- float64 d2 = env->fregs[f2].d;
-
- env->fregs[f1].l.upper = float64_to_float32(d2, &env->fpu_status);
-}
-
-/* convert 128-bit float to 32-bit float */
-void HELPER(lexbr)(uint32_t f1, uint32_t f2)
-{
- CPU_QuadU x2;
-
- x2.ll.upper = env->fregs[f2].ll;
- x2.ll.lower = env->fregs[f2 + 2].ll;
- env->fregs[f1].l.upper = float128_to_float32(x2.q, &env->fpu_status);
- HELPER_LOG("%s: to 0x%d\n", __func__, env->fregs[f1].l.upper);
-}
-
-/* absolute value of 32-bit float */
-uint32_t HELPER(lpebr)(uint32_t f1, uint32_t f2)
-{
- float32 v1;
- float32 v2 = env->fregs[f2].d;
-
- v1 = float32_abs(v2);
- env->fregs[f1].d = v1;
- return set_cc_nz_f32(v1);
-}
-
-/* absolute value of 64-bit float */
-uint32_t HELPER(lpdbr)(uint32_t f1, uint32_t f2)
-{
- float64 v1;
- float64 v2 = env->fregs[f2].d;
-
- v1 = float64_abs(v2);
- env->fregs[f1].d = v1;
- return set_cc_nz_f64(v1);
-}
-
-/* absolute value of 128-bit float */
-uint32_t HELPER(lpxbr)(uint32_t f1, uint32_t f2)
-{
- CPU_QuadU v1;
- CPU_QuadU v2;
-
- v2.ll.upper = env->fregs[f2].ll;
- v2.ll.lower = env->fregs[f2 + 2].ll;
- v1.q = float128_abs(v2.q);
- env->fregs[f1].ll = v1.ll.upper;
- env->fregs[f1 + 2].ll = v1.ll.lower;
- return set_cc_nz_f128(v1.q);
-}
-
-/* load and test 64-bit float */
-uint32_t HELPER(ltdbr)(uint32_t f1, uint32_t f2)
-{
- env->fregs[f1].d = env->fregs[f2].d;
- return set_cc_nz_f64(env->fregs[f1].d);
-}
-
-/* load and test 32-bit float */
-uint32_t HELPER(ltebr)(uint32_t f1, uint32_t f2)
-{
- env->fregs[f1].l.upper = env->fregs[f2].l.upper;
- return set_cc_nz_f32(env->fregs[f1].l.upper);
-}
-
-/* load and test 128-bit float */
-uint32_t HELPER(ltxbr)(uint32_t f1, uint32_t f2)
-{
- CPU_QuadU x;
-
- x.ll.upper = env->fregs[f2].ll;
- x.ll.lower = env->fregs[f2 + 2].ll;
- env->fregs[f1].ll = x.ll.upper;
- env->fregs[f1 + 2].ll = x.ll.lower;
- return set_cc_nz_f128(x.q);
-}
-
-/* load complement of 32-bit float */
-uint32_t HELPER(lcebr)(uint32_t f1, uint32_t f2)
-{
- env->fregs[f1].l.upper = float32_chs(env->fregs[f2].l.upper);
-
- return set_cc_nz_f32(env->fregs[f1].l.upper);
-}
-
-/* load complement of 64-bit float */
-uint32_t HELPER(lcdbr)(uint32_t f1, uint32_t f2)
-{
- env->fregs[f1].d = float64_chs(env->fregs[f2].d);
-
- return set_cc_nz_f64(env->fregs[f1].d);
-}
-
-/* load complement of 128-bit float */
-uint32_t HELPER(lcxbr)(uint32_t f1, uint32_t f2)
-{
- CPU_QuadU x1, x2;
-
- x2.ll.upper = env->fregs[f2].ll;
- x2.ll.lower = env->fregs[f2 + 2].ll;
- x1.q = float128_chs(x2.q);
- env->fregs[f1].ll = x1.ll.upper;
- env->fregs[f1 + 2].ll = x1.ll.lower;
- return set_cc_nz_f128(x1.q);
-}
-
-/* 32-bit FP addition RM */
-void HELPER(aeb)(uint32_t f1, uint32_t val)
-{
- float32 v1 = env->fregs[f1].l.upper;
- CPU_FloatU v2;
-
- v2.l = val;
- HELPER_LOG("%s: adding 0x%d from f%d and 0x%d\n", __func__,
- v1, f1, v2.f);
- env->fregs[f1].l.upper = float32_add(v1, v2.f, &env->fpu_status);
-}
-
-/* 32-bit FP division RM */
-void HELPER(deb)(uint32_t f1, uint32_t val)
-{
- float32 v1 = env->fregs[f1].l.upper;
- CPU_FloatU v2;
-
- v2.l = val;
- HELPER_LOG("%s: dividing 0x%d from f%d by 0x%d\n", __func__,
- v1, f1, v2.f);
- env->fregs[f1].l.upper = float32_div(v1, v2.f, &env->fpu_status);
-}
-
-/* 32-bit FP multiplication RM */
-void HELPER(meeb)(uint32_t f1, uint32_t val)
-{
- float32 v1 = env->fregs[f1].l.upper;
- CPU_FloatU v2;
-
- v2.l = val;
- HELPER_LOG("%s: multiplying 0x%d from f%d and 0x%d\n", __func__,
- v1, f1, v2.f);
- env->fregs[f1].l.upper = float32_mul(v1, v2.f, &env->fpu_status);
-}
-
-/* 32-bit FP compare RR */
-uint32_t HELPER(cebr)(uint32_t f1, uint32_t f2)
-{
- float32 v1 = env->fregs[f1].l.upper;
- float32 v2 = env->fregs[f2].l.upper;
-
- HELPER_LOG("%s: comparing 0x%d from f%d and 0x%d\n", __func__,
- v1, f1, v2);
- return set_cc_f32(v1, v2);
-}
-
-/* 64-bit FP compare RR */
-uint32_t HELPER(cdbr)(uint32_t f1, uint32_t f2)
-{
- float64 v1 = env->fregs[f1].d;
- float64 v2 = env->fregs[f2].d;
-
- HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%ld\n", __func__,
- v1, f1, v2);
- return set_cc_f64(v1, v2);
-}
-
-/* 128-bit FP compare RR */
-uint32_t HELPER(cxbr)(uint32_t f1, uint32_t f2)
-{
- CPU_QuadU v1;
- CPU_QuadU v2;
-
- v1.ll.upper = env->fregs[f1].ll;
- v1.ll.lower = env->fregs[f1 + 2].ll;
- v2.ll.upper = env->fregs[f2].ll;
- v2.ll.lower = env->fregs[f2 + 2].ll;
-
- return float_comp_to_cc(float128_compare_quiet(v1.q, v2.q,
- &env->fpu_status));
-}
-
-/* 64-bit FP compare RM */
-uint32_t HELPER(cdb)(uint32_t f1, uint64_t a2)
-{
- float64 v1 = env->fregs[f1].d;
- CPU_DoubleU v2;
-
- v2.ll = ldq(a2);
- HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%lx\n", __func__, v1,
- f1, v2.d);
- return set_cc_f64(v1, v2.d);
-}
-
-/* 64-bit FP addition RM */
-uint32_t HELPER(adb)(uint32_t f1, uint64_t a2)
-{
- float64 v1 = env->fregs[f1].d;
- CPU_DoubleU v2;
-
- v2.ll = ldq(a2);
- HELPER_LOG("%s: adding 0x%lx from f%d and 0x%lx\n", __func__,
- v1, f1, v2.d);
- env->fregs[f1].d = v1 = float64_add(v1, v2.d, &env->fpu_status);
- return set_cc_nz_f64(v1);
-}
-
-/* 32-bit FP subtraction RM */
-void HELPER(seb)(uint32_t f1, uint32_t val)
-{
- float32 v1 = env->fregs[f1].l.upper;
- CPU_FloatU v2;
-
- v2.l = val;
- env->fregs[f1].l.upper = float32_sub(v1, v2.f, &env->fpu_status);
-}
-
-/* 64-bit FP subtraction RM */
-uint32_t HELPER(sdb)(uint32_t f1, uint64_t a2)
-{
- float64 v1 = env->fregs[f1].d;
- CPU_DoubleU v2;
-
- v2.ll = ldq(a2);
- env->fregs[f1].d = v1 = float64_sub(v1, v2.d, &env->fpu_status);
- return set_cc_nz_f64(v1);
-}
-
-/* 64-bit FP multiplication RM */
-void HELPER(mdb)(uint32_t f1, uint64_t a2)
-{
- float64 v1 = env->fregs[f1].d;
- CPU_DoubleU v2;
-
- v2.ll = ldq(a2);
- HELPER_LOG("%s: multiplying 0x%lx from f%d and 0x%ld\n", __func__,
- v1, f1, v2.d);
- env->fregs[f1].d = float64_mul(v1, v2.d, &env->fpu_status);
-}
-
-/* 64-bit FP division RM */
-void HELPER(ddb)(uint32_t f1, uint64_t a2)
-{
- float64 v1 = env->fregs[f1].d;
- CPU_DoubleU v2;
-
- v2.ll = ldq(a2);
- HELPER_LOG("%s: dividing 0x%lx from f%d by 0x%ld\n", __func__,
- v1, f1, v2.d);
- env->fregs[f1].d = float64_div(v1, v2.d, &env->fpu_status);
-}
-
-static void set_round_mode(int m3)
-{
- switch (m3) {
- case 0:
- /* current mode */
- break;
- case 1:
- /* biased round no nearest */
- case 4:
- /* round to nearest */
- set_float_rounding_mode(float_round_nearest_even, &env->fpu_status);
- break;
- case 5:
- /* round to zero */
- set_float_rounding_mode(float_round_to_zero, &env->fpu_status);
- break;
- case 6:
- /* round to +inf */
- set_float_rounding_mode(float_round_up, &env->fpu_status);
- break;
- case 7:
- /* round to -inf */
- set_float_rounding_mode(float_round_down, &env->fpu_status);
- break;
- }
-}
-
-/* convert 32-bit float to 64-bit int */
-uint32_t HELPER(cgebr)(uint32_t r1, uint32_t f2, uint32_t m3)
-{
- float32 v2 = env->fregs[f2].l.upper;
-
- set_round_mode(m3);
- env->regs[r1] = float32_to_int64(v2, &env->fpu_status);
- return set_cc_nz_f32(v2);
-}
-
-/* convert 64-bit float to 64-bit int */
-uint32_t HELPER(cgdbr)(uint32_t r1, uint32_t f2, uint32_t m3)
-{
- float64 v2 = env->fregs[f2].d;
-
- set_round_mode(m3);
- env->regs[r1] = float64_to_int64(v2, &env->fpu_status);
- return set_cc_nz_f64(v2);
-}
-
-/* convert 128-bit float to 64-bit int */
-uint32_t HELPER(cgxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
-{
- CPU_QuadU v2;
-
- v2.ll.upper = env->fregs[f2].ll;
- v2.ll.lower = env->fregs[f2 + 2].ll;
- set_round_mode(m3);
- env->regs[r1] = float128_to_int64(v2.q, &env->fpu_status);
- if (float128_is_any_nan(v2.q)) {
- return 3;
- } else if (float128_is_zero(v2.q)) {
- return 0;
- } else if (float128_is_neg(v2.q)) {
- return 1;
- } else {
- return 2;
- }
-}
-
-/* convert 32-bit float to 32-bit int */
-uint32_t HELPER(cfebr)(uint32_t r1, uint32_t f2, uint32_t m3)
-{
- float32 v2 = env->fregs[f2].l.upper;
-
- set_round_mode(m3);
- env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
- float32_to_int32(v2, &env->fpu_status);
- return set_cc_nz_f32(v2);
-}
-
-/* convert 64-bit float to 32-bit int */
-uint32_t HELPER(cfdbr)(uint32_t r1, uint32_t f2, uint32_t m3)
-{
- float64 v2 = env->fregs[f2].d;
-
- set_round_mode(m3);
- env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
- float64_to_int32(v2, &env->fpu_status);
- return set_cc_nz_f64(v2);
-}
-
-/* convert 128-bit float to 32-bit int */
-uint32_t HELPER(cfxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
-{
- CPU_QuadU v2;
-
- v2.ll.upper = env->fregs[f2].ll;
- v2.ll.lower = env->fregs[f2 + 2].ll;
- env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
- float128_to_int32(v2.q, &env->fpu_status);
- return set_cc_nz_f128(v2.q);
-}
-
-/* load 32-bit FP zero */
-void HELPER(lzer)(uint32_t f1)
-{
- env->fregs[f1].l.upper = float32_zero;
-}
-
-/* load 64-bit FP zero */
-void HELPER(lzdr)(uint32_t f1)
-{
- env->fregs[f1].d = float64_zero;
-}
-
-/* load 128-bit FP zero */
-void HELPER(lzxr)(uint32_t f1)
-{
- CPU_QuadU x;
-
- x.q = float64_to_float128(float64_zero, &env->fpu_status);
- env->fregs[f1].ll = x.ll.upper;
- env->fregs[f1 + 1].ll = x.ll.lower;
-}
-
-/* 128-bit FP subtraction RR */
-uint32_t HELPER(sxbr)(uint32_t f1, uint32_t f2)
-{
- CPU_QuadU v1;
- CPU_QuadU v2;
- CPU_QuadU res;
-
- v1.ll.upper = env->fregs[f1].ll;
- v1.ll.lower = env->fregs[f1 + 2].ll;
- v2.ll.upper = env->fregs[f2].ll;
- v2.ll.lower = env->fregs[f2 + 2].ll;
- res.q = float128_sub(v1.q, v2.q, &env->fpu_status);
- env->fregs[f1].ll = res.ll.upper;
- env->fregs[f1 + 2].ll = res.ll.lower;
- return set_cc_nz_f128(res.q);
-}
-
-/* 128-bit FP addition RR */
-uint32_t HELPER(axbr)(uint32_t f1, uint32_t f2)
-{
- CPU_QuadU v1;
- CPU_QuadU v2;
- CPU_QuadU res;
-
- v1.ll.upper = env->fregs[f1].ll;
- v1.ll.lower = env->fregs[f1 + 2].ll;
- v2.ll.upper = env->fregs[f2].ll;
- v2.ll.lower = env->fregs[f2 + 2].ll;
- res.q = float128_add(v1.q, v2.q, &env->fpu_status);
- env->fregs[f1].ll = res.ll.upper;
- env->fregs[f1 + 2].ll = res.ll.lower;
- return set_cc_nz_f128(res.q);
-}
-
-/* 32-bit FP multiplication RR */
-void HELPER(meebr)(uint32_t f1, uint32_t f2)
-{
- env->fregs[f1].l.upper = float32_mul(env->fregs[f1].l.upper,
- env->fregs[f2].l.upper,
- &env->fpu_status);
-}
-
-/* 64-bit FP division RR */
-void HELPER(ddbr)(uint32_t f1, uint32_t f2)
-{
- env->fregs[f1].d = float64_div(env->fregs[f1].d, env->fregs[f2].d,
- &env->fpu_status);
-}
-
-/* 64-bit FP multiply and add RM */
-void HELPER(madb)(uint32_t f1, uint64_t a2, uint32_t f3)
-{
- CPU_DoubleU v2;
-
- HELPER_LOG("%s: f1 %d a2 0x%lx f3 %d\n", __func__, f1, a2, f3);
- v2.ll = ldq(a2);
- env->fregs[f1].d = float64_add(env->fregs[f1].d,
- float64_mul(v2.d, env->fregs[f3].d,
- &env->fpu_status),
- &env->fpu_status);
-}
-
-/* 64-bit FP multiply and add RR */
-void HELPER(madbr)(uint32_t f1, uint32_t f3, uint32_t f2)
-{
- HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __func__, f1, f2, f3);
- env->fregs[f1].d = float64_add(float64_mul(env->fregs[f2].d,
- env->fregs[f3].d,
- &env->fpu_status),
- env->fregs[f1].d, &env->fpu_status);
-}
-
-/* 64-bit FP multiply and subtract RR */
-void HELPER(msdbr)(uint32_t f1, uint32_t f3, uint32_t f2)
-{
- HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __func__, f1, f2, f3);
- env->fregs[f1].d = float64_sub(float64_mul(env->fregs[f2].d,
- env->fregs[f3].d,
- &env->fpu_status),
- env->fregs[f1].d, &env->fpu_status);
-}
-
-/* 32-bit FP multiply and add RR */
-void HELPER(maebr)(uint32_t f1, uint32_t f3, uint32_t f2)
-{
- env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper,
- float32_mul(env->fregs[f2].l.upper,
- env->fregs[f3].l.upper,
- &env->fpu_status),
- &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)
-{
- CPU_DoubleU v2;
- CPU_QuadU v1;
-
- v2.ll = ldq(a2);
- v1.q = float64_to_float128(v2.d, &env->fpu_status);
- env->fregs[f1].ll = v1.ll.upper;
- env->fregs[f1 + 2].ll = v1.ll.lower;
-}
-
-/* test data class 32-bit */
-uint32_t HELPER(tceb)(uint32_t f1, uint64_t m2)
-{
- float32 v1 = env->fregs[f1].l.upper;
- int neg = float32_is_neg(v1);
- uint32_t cc = 0;
-
- HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __func__, (long)v1, m2, neg);
- if ((float32_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
- (float32_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
- (float32_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
- (float32_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) {
- cc = 1;
- } else if (m2 & (1 << (9-neg))) {
- /* assume normalized number */
- cc = 1;
- }
-
- /* FIXME: denormalized? */
- return cc;
-}
-
-/* test data class 64-bit */
-uint32_t HELPER(tcdb)(uint32_t f1, uint64_t m2)
-{
- float64 v1 = env->fregs[f1].d;
- int neg = float64_is_neg(v1);
- uint32_t cc = 0;
-
- HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __func__, v1, m2, neg);
- if ((float64_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
- (float64_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
- (float64_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
- (float64_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) {
- cc = 1;
- } else if (m2 & (1 << (9-neg))) {
- /* assume normalized number */
- cc = 1;
- }
- /* FIXME: denormalized? */
- return cc;
-}
-
-/* test data class 128-bit */
-uint32_t HELPER(tcxb)(uint32_t f1, uint64_t m2)
-{
- CPU_QuadU v1;
- uint32_t cc = 0;
- int neg;
-
- v1.ll.upper = env->fregs[f1].ll;
- v1.ll.lower = env->fregs[f1 + 2].ll;
-
- neg = float128_is_neg(v1.q);
- if ((float128_is_zero(v1.q) && (m2 & (1 << (11-neg)))) ||
- (float128_is_infinity(v1.q) && (m2 & (1 << (5-neg)))) ||
- (float128_is_any_nan(v1.q) && (m2 & (1 << (3-neg)))) ||
- (float128_is_signaling_nan(v1.q) && (m2 & (1 << (1-neg))))) {
- cc = 1;
- } else if (m2 & (1 << (9-neg))) {
- /* assume normalized number */
- cc = 1;
- }
- /* FIXME: denormalized? */
- return cc;
-}
-
/* find leftmost one */
uint32_t HELPER(flogr)(uint32_t r1, uint64_t v2)
{
@@ -1795,12 +999,6 @@ uint32_t HELPER(flogr)(uint32_t r1, uint64_t v2)
}
}
-/* square root 64-bit RR */
-void HELPER(sqdbr)(uint32_t f1, uint32_t f2)
-{
- env->fregs[f1].d = float64_sqrt(env->fregs[f2].d, &env->fpu_status);
-}
-
/* checksum */
void HELPER(cksm)(uint32_t r1, uint32_t r2)
{
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index 1c1baf5..c370df3 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -667,16 +667,11 @@ static void set_cc_cmp_f32_i64(DisasContext *s, TCGv_i32 v1, TCGv_i64 v2)
s->cc_op = CC_OP_LTGT_F32;
}
-static void set_cc_nz_f32(DisasContext *s, TCGv_i32 v1)
+static void gen_set_cc_nz_f32(DisasContext *s, TCGv_i32 v1)
{
gen_op_update1_cc_i32(s, CC_OP_NZ_F32, v1);
}
-static inline void set_cc_nz_f64(DisasContext *s, TCGv_i64 v1)
-{
- gen_op_update1_cc_i64(s, CC_OP_NZ_F64, v1);
-}
-
/* CC value is in env->cc_op */
static inline void set_cc_static(DisasContext *s)
{
@@ -2235,7 +2230,7 @@ static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2,
tcg_temp_free_i32(tmp32);
tmp32 = load_freg32(r1);
- set_cc_nz_f32(s, tmp32);
+ gen_set_cc_nz_f32(s, tmp32);
tcg_temp_free_i32(tmp32);
break;
case 0xb: /* SEB R1,D2(X2,B2) [RXE] */
@@ -2248,7 +2243,7 @@ static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2,
tcg_temp_free_i32(tmp32);
tmp32 = load_freg32(r1);
- set_cc_nz_f32(s, tmp32);
+ gen_set_cc_nz_f32(s, tmp32);
tcg_temp_free_i32(tmp32);
break;
case 0xd: /* DEB R1,D2(X2,B2) [RXE] */
--
1.6.0.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 03/12] target-s390x: split condition code helpers
2012-09-10 11:40 [Qemu-devel] [PULL 00/12] s390 patch queue 2012-09-10 Alexander Graf
2012-09-10 11:40 ` [Qemu-devel] [PATCH 01/12] target-s390x: fix style Alexander Graf
2012-09-10 11:40 ` [Qemu-devel] [PATCH 02/12] target-s390x: split FPU ops Alexander Graf
@ 2012-09-10 11:40 ` Alexander Graf
2012-09-10 11:40 ` [Qemu-devel] [PATCH 04/12] target-s390x: split integer helpers Alexander Graf
` (9 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Alexander Graf @ 2012-09-10 11:40 UTC (permalink / raw)
To: qemu-devel qemu-devel; +Cc: Blue Swirl, Aurelien Jarno
From: Blue Swirl <blauwirbel@gmail.com>
Move condition code helpers to cc_helper.c.
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-s390x/Makefile.objs | 3 +-
target-s390x/cc_helper.c | 551 ++++++++++++++++++++++++++++++++++++++++++++
target-s390x/cpu.h | 3 +
target-s390x/op_helper.c | 522 +-----------------------------------------
4 files changed, 557 insertions(+), 522 deletions(-)
create mode 100644 target-s390x/cc_helper.c
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index 23b3bd9..f9437d6 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -1,7 +1,8 @@
obj-y += translate.o op_helper.o helper.o cpu.o interrupt.o
-obj-y += fpu_helper.o
+obj-y += fpu_helper.o cc_helper.o
obj-$(CONFIG_SOFTMMU) += machine.o
obj-$(CONFIG_KVM) += kvm.o
$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
$(obj)/fpu_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+$(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
diff --git a/target-s390x/cc_helper.c b/target-s390x/cc_helper.c
new file mode 100644
index 0000000..2ac1659
--- /dev/null
+++ b/target-s390x/cc_helper.c
@@ -0,0 +1,551 @@
+/*
+ * S/390 condition code helper routines
+ *
+ * Copyright (c) 2009 Ulrich Hecht
+ * Copyright (c) 2009 Alexander Graf
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cpu.h"
+#include "dyngen-exec.h"
+#include "helper.h"
+
+/* #define DEBUG_HELPER */
+#ifdef DEBUG_HELPER
+#define HELPER_LOG(x...) qemu_log(x)
+#else
+#define HELPER_LOG(x...)
+#endif
+
+static inline uint32_t cc_calc_ltgt_32(CPUS390XState *env, int32_t src,
+ int32_t dst)
+{
+ if (src == dst) {
+ return 0;
+ } else if (src < dst) {
+ return 1;
+ } else {
+ return 2;
+ }
+}
+
+static inline uint32_t cc_calc_ltgt0_32(CPUS390XState *env, int32_t dst)
+{
+ return cc_calc_ltgt_32(env, dst, 0);
+}
+
+static inline uint32_t cc_calc_ltgt_64(CPUS390XState *env, int64_t src,
+ int64_t dst)
+{
+ if (src == dst) {
+ return 0;
+ } else if (src < dst) {
+ return 1;
+ } else {
+ return 2;
+ }
+}
+
+static inline uint32_t cc_calc_ltgt0_64(CPUS390XState *env, int64_t dst)
+{
+ return cc_calc_ltgt_64(env, dst, 0);
+}
+
+static inline uint32_t cc_calc_ltugtu_32(CPUS390XState *env, uint32_t src,
+ uint32_t dst)
+{
+ if (src == dst) {
+ return 0;
+ } else if (src < dst) {
+ return 1;
+ } else {
+ return 2;
+ }
+}
+
+static inline uint32_t cc_calc_ltugtu_64(CPUS390XState *env, uint64_t src,
+ uint64_t dst)
+{
+ if (src == dst) {
+ return 0;
+ } else if (src < dst) {
+ return 1;
+ } else {
+ return 2;
+ }
+}
+
+static inline uint32_t cc_calc_tm_32(CPUS390XState *env, uint32_t val,
+ uint32_t mask)
+{
+ uint16_t r = val & mask;
+
+ HELPER_LOG("%s: val 0x%x mask 0x%x\n", __func__, val, mask);
+ if (r == 0 || mask == 0) {
+ return 0;
+ } else if (r == mask) {
+ return 3;
+ } else {
+ return 1;
+ }
+}
+
+/* set condition code for test under mask */
+static inline uint32_t cc_calc_tm_64(CPUS390XState *env, uint64_t val,
+ uint32_t mask)
+{
+ uint16_t r = val & mask;
+
+ HELPER_LOG("%s: val 0x%lx mask 0x%x r 0x%x\n", __func__, val, mask, r);
+ if (r == 0 || mask == 0) {
+ return 0;
+ } else if (r == mask) {
+ return 3;
+ } else {
+ while (!(mask & 0x8000)) {
+ mask <<= 1;
+ val <<= 1;
+ }
+ if (val & 0x8000) {
+ return 2;
+ } else {
+ return 1;
+ }
+ }
+}
+
+static inline uint32_t cc_calc_nz(CPUS390XState *env, uint64_t dst)
+{
+ return !!dst;
+}
+
+static inline uint32_t cc_calc_add_64(CPUS390XState *env, int64_t a1,
+ int64_t a2, int64_t ar)
+{
+ if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) {
+ return 3; /* overflow */
+ } else {
+ if (ar < 0) {
+ return 1;
+ } else if (ar > 0) {
+ return 2;
+ } else {
+ return 0;
+ }
+ }
+}
+
+static inline uint32_t cc_calc_addu_64(CPUS390XState *env, uint64_t a1,
+ uint64_t a2, uint64_t ar)
+{
+ if (ar == 0) {
+ if (a1) {
+ return 2;
+ } else {
+ return 0;
+ }
+ } else {
+ if (ar < a1 || ar < a2) {
+ return 3;
+ } else {
+ return 1;
+ }
+ }
+}
+
+static inline uint32_t cc_calc_sub_64(CPUS390XState *env, int64_t a1,
+ int64_t a2, int64_t ar)
+{
+ if ((a1 > 0 && a2 < 0 && ar < 0) || (a1 < 0 && a2 > 0 && ar > 0)) {
+ return 3; /* overflow */
+ } else {
+ if (ar < 0) {
+ return 1;
+ } else if (ar > 0) {
+ return 2;
+ } else {
+ return 0;
+ }
+ }
+}
+
+static inline uint32_t cc_calc_subu_64(CPUS390XState *env, uint64_t a1,
+ uint64_t a2, uint64_t ar)
+{
+ if (ar == 0) {
+ return 2;
+ } else {
+ if (a2 > a1) {
+ return 1;
+ } else {
+ return 3;
+ }
+ }
+}
+
+static inline uint32_t cc_calc_abs_64(CPUS390XState *env, int64_t dst)
+{
+ if ((uint64_t)dst == 0x8000000000000000ULL) {
+ return 3;
+ } else if (dst) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static inline uint32_t cc_calc_nabs_64(CPUS390XState *env, int64_t dst)
+{
+ return !!dst;
+}
+
+static inline uint32_t cc_calc_comp_64(CPUS390XState *env, int64_t dst)
+{
+ if ((uint64_t)dst == 0x8000000000000000ULL) {
+ return 3;
+ } else if (dst < 0) {
+ return 1;
+ } else if (dst > 0) {
+ return 2;
+ } else {
+ return 0;
+ }
+}
+
+
+static inline uint32_t cc_calc_add_32(CPUS390XState *env, int32_t a1,
+ int32_t a2, int32_t ar)
+{
+ if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) {
+ return 3; /* overflow */
+ } else {
+ if (ar < 0) {
+ return 1;
+ } else if (ar > 0) {
+ return 2;
+ } else {
+ return 0;
+ }
+ }
+}
+
+static inline uint32_t cc_calc_addu_32(CPUS390XState *env, uint32_t a1,
+ uint32_t a2, uint32_t ar)
+{
+ if (ar == 0) {
+ if (a1) {
+ return 2;
+ } else {
+ return 0;
+ }
+ } else {
+ if (ar < a1 || ar < a2) {
+ return 3;
+ } else {
+ return 1;
+ }
+ }
+}
+
+static inline uint32_t cc_calc_sub_32(CPUS390XState *env, int32_t a1,
+ int32_t a2, int32_t ar)
+{
+ if ((a1 > 0 && a2 < 0 && ar < 0) || (a1 < 0 && a2 > 0 && ar > 0)) {
+ return 3; /* overflow */
+ } else {
+ if (ar < 0) {
+ return 1;
+ } else if (ar > 0) {
+ return 2;
+ } else {
+ return 0;
+ }
+ }
+}
+
+static inline uint32_t cc_calc_subu_32(CPUS390XState *env, uint32_t a1,
+ uint32_t a2, uint32_t ar)
+{
+ if (ar == 0) {
+ return 2;
+ } else {
+ if (a2 > a1) {
+ return 1;
+ } else {
+ return 3;
+ }
+ }
+}
+
+static inline uint32_t cc_calc_abs_32(CPUS390XState *env, int32_t dst)
+{
+ if ((uint32_t)dst == 0x80000000UL) {
+ return 3;
+ } else if (dst) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static inline uint32_t cc_calc_nabs_32(CPUS390XState *env, int32_t dst)
+{
+ return !!dst;
+}
+
+static inline uint32_t cc_calc_comp_32(CPUS390XState *env, int32_t dst)
+{
+ if ((uint32_t)dst == 0x80000000UL) {
+ return 3;
+ } else if (dst < 0) {
+ return 1;
+ } else if (dst > 0) {
+ return 2;
+ } else {
+ return 0;
+ }
+}
+
+/* calculate condition code for insert character under mask insn */
+static inline uint32_t cc_calc_icm_32(CPUS390XState *env, uint32_t mask,
+ uint32_t val)
+{
+ uint32_t cc;
+
+ HELPER_LOG("%s: mask 0x%x val %d\n", __func__, mask, val);
+ if (mask == 0xf) {
+ if (!val) {
+ return 0;
+ } else if (val & 0x80000000) {
+ return 1;
+ } else {
+ return 2;
+ }
+ }
+
+ if (!val || !mask) {
+ cc = 0;
+ } else {
+ while (mask != 1) {
+ mask >>= 1;
+ val >>= 8;
+ }
+ if (val & 0x80) {
+ cc = 1;
+ } else {
+ cc = 2;
+ }
+ }
+ return cc;
+}
+
+static inline uint32_t cc_calc_slag(CPUS390XState *env, uint64_t src,
+ uint64_t shift)
+{
+ uint64_t mask = ((1ULL << shift) - 1ULL) << (64 - shift);
+ uint64_t match, r;
+
+ /* check if the sign bit stays the same */
+ if (src & (1ULL << 63)) {
+ match = mask;
+ } else {
+ match = 0;
+ }
+
+ if ((src & mask) != match) {
+ /* overflow */
+ return 3;
+ }
+
+ r = ((src << shift) & ((1ULL << 63) - 1)) | (src & (1ULL << 63));
+
+ if ((int64_t)r == 0) {
+ return 0;
+ } else if ((int64_t)r < 0) {
+ return 1;
+ }
+
+ return 2;
+}
+
+
+static inline uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op,
+ uint64_t src, uint64_t dst, uint64_t vr)
+{
+ uint32_t r = 0;
+
+ switch (cc_op) {
+ case CC_OP_CONST0:
+ case CC_OP_CONST1:
+ case CC_OP_CONST2:
+ case CC_OP_CONST3:
+ /* cc_op value _is_ cc */
+ r = cc_op;
+ break;
+ case CC_OP_LTGT0_32:
+ r = cc_calc_ltgt0_32(env, dst);
+ break;
+ case CC_OP_LTGT0_64:
+ r = cc_calc_ltgt0_64(env, dst);
+ break;
+ case CC_OP_LTGT_32:
+ r = cc_calc_ltgt_32(env, src, dst);
+ break;
+ case CC_OP_LTGT_64:
+ r = cc_calc_ltgt_64(env, src, dst);
+ break;
+ case CC_OP_LTUGTU_32:
+ r = cc_calc_ltugtu_32(env, src, dst);
+ break;
+ case CC_OP_LTUGTU_64:
+ r = cc_calc_ltugtu_64(env, src, dst);
+ break;
+ case CC_OP_TM_32:
+ r = cc_calc_tm_32(env, src, dst);
+ break;
+ case CC_OP_TM_64:
+ r = cc_calc_tm_64(env, src, dst);
+ break;
+ case CC_OP_NZ:
+ r = cc_calc_nz(env, dst);
+ break;
+ case CC_OP_ADD_64:
+ r = cc_calc_add_64(env, src, dst, vr);
+ break;
+ case CC_OP_ADDU_64:
+ r = cc_calc_addu_64(env, src, dst, vr);
+ break;
+ case CC_OP_SUB_64:
+ r = cc_calc_sub_64(env, src, dst, vr);
+ break;
+ case CC_OP_SUBU_64:
+ r = cc_calc_subu_64(env, src, dst, vr);
+ break;
+ case CC_OP_ABS_64:
+ r = cc_calc_abs_64(env, dst);
+ break;
+ case CC_OP_NABS_64:
+ r = cc_calc_nabs_64(env, dst);
+ break;
+ case CC_OP_COMP_64:
+ r = cc_calc_comp_64(env, dst);
+ break;
+
+ case CC_OP_ADD_32:
+ r = cc_calc_add_32(env, src, dst, vr);
+ break;
+ case CC_OP_ADDU_32:
+ r = cc_calc_addu_32(env, src, dst, vr);
+ break;
+ case CC_OP_SUB_32:
+ r = cc_calc_sub_32(env, src, dst, vr);
+ break;
+ case CC_OP_SUBU_32:
+ r = cc_calc_subu_32(env, src, dst, vr);
+ break;
+ case CC_OP_ABS_32:
+ r = cc_calc_abs_64(env, dst);
+ break;
+ case CC_OP_NABS_32:
+ r = cc_calc_nabs_64(env, dst);
+ break;
+ case CC_OP_COMP_32:
+ r = cc_calc_comp_32(env, dst);
+ break;
+
+ case CC_OP_ICM:
+ r = cc_calc_icm_32(env, src, dst);
+ break;
+ case CC_OP_SLAG:
+ r = cc_calc_slag(env, src, dst);
+ break;
+
+ case CC_OP_LTGT_F32:
+ r = set_cc_f32(src, dst);
+ break;
+ case CC_OP_LTGT_F64:
+ r = set_cc_f64(src, dst);
+ break;
+ case CC_OP_NZ_F32:
+ r = set_cc_nz_f32(dst);
+ break;
+ case CC_OP_NZ_F64:
+ r = set_cc_nz_f64(dst);
+ break;
+
+ default:
+ cpu_abort(env, "Unknown CC operation: %s\n", cc_name(cc_op));
+ }
+
+ HELPER_LOG("%s: %15s 0x%016lx 0x%016lx 0x%016lx = %d\n", __func__,
+ cc_name(cc_op), src, dst, vr, r);
+ return r;
+}
+
+uint32_t calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t src, uint64_t dst,
+ uint64_t vr)
+{
+ return do_calc_cc(env, cc_op, src, dst, vr);
+}
+
+uint32_t HELPER(calc_cc)(uint32_t cc_op, uint64_t src, uint64_t dst,
+ uint64_t vr)
+{
+ return do_calc_cc(env, cc_op, src, dst, vr);
+}
+
+/* insert psw mask and condition code into r1 */
+void HELPER(ipm)(uint32_t cc, uint32_t r1)
+{
+ uint64_t r = env->regs[r1];
+
+ r &= 0xffffffff00ffffffULL;
+ r |= (cc << 28) | ((env->psw.mask >> 40) & 0xf);
+ env->regs[r1] = r;
+ HELPER_LOG("%s: cc %d psw.mask 0x%lx r1 0x%lx\n", __func__,
+ cc, env->psw.mask, r);
+}
+
+#ifndef CONFIG_USER_ONLY
+void HELPER(load_psw)(uint64_t mask, uint64_t addr)
+{
+ load_psw(env, mask, addr);
+ cpu_loop_exit(env);
+}
+
+void HELPER(sacf)(uint64_t a1)
+{
+ HELPER_LOG("%s: %16" PRIx64 "\n", __func__, a1);
+
+ switch (a1 & 0xf00) {
+ case 0x000:
+ env->psw.mask &= ~PSW_MASK_ASC;
+ env->psw.mask |= PSW_ASC_PRIMARY;
+ break;
+ case 0x100:
+ env->psw.mask &= ~PSW_MASK_ASC;
+ env->psw.mask |= PSW_ASC_SECONDARY;
+ break;
+ case 0x300:
+ env->psw.mask &= ~PSW_MASK_ASC;
+ env->psw.mask |= PSW_ASC_HOME;
+ break;
+ default:
+ qemu_log("unknown sacf mode: %" PRIx64 "\n", a1);
+ program_interrupt(env, PGM_SPECIFICATION, 2);
+ break;
+ }
+}
+#endif
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index b4620c5..97fde5e 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -1005,4 +1005,7 @@ uint32_t set_cc_f64(float64 v1, float64 v2);
uint32_t set_cc_nz_f32(float32 v);
uint32_t set_cc_nz_f64(float64 v);
+/* op_helper.c */
+void program_interrupt(CPUS390XState *env, uint32_t code, int ilc);
+
#endif
diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
index 270bf14..eced890 100644
--- a/target-s390x/op_helper.c
+++ b/target-s390x/op_helper.c
@@ -779,18 +779,6 @@ uint32_t HELPER(icmh)(uint32_t r1, uint64_t address, uint32_t mask)
return cc;
}
-/* insert psw mask and condition code into r1 */
-void HELPER(ipm)(uint32_t cc, uint32_t r1)
-{
- uint64_t r = env->regs[r1];
-
- r &= 0xffffffff00ffffffULL;
- r |= (cc << 28) | ((env->psw.mask >> 40) & 0xf);
- env->regs[r1] = r;
- HELPER_LOG("%s: cc %d psw.mask 0x%lx r1 0x%lx\n", __func__,
- cc, env->psw.mask, r);
-}
-
/* load access registers r1 to r3 from memory at a2 */
void HELPER(lam)(uint32_t r1, uint64_t a2, uint32_t r3)
{
@@ -1038,483 +1026,6 @@ void HELPER(cksm)(uint32_t r1, uint32_t r2)
((uint32_t)cksm + (cksm >> 32));
}
-static inline uint32_t cc_calc_ltgt_32(CPUS390XState *env, int32_t src,
- int32_t dst)
-{
- if (src == dst) {
- return 0;
- } else if (src < dst) {
- return 1;
- } else {
- return 2;
- }
-}
-
-static inline uint32_t cc_calc_ltgt0_32(CPUS390XState *env, int32_t dst)
-{
- return cc_calc_ltgt_32(env, dst, 0);
-}
-
-static inline uint32_t cc_calc_ltgt_64(CPUS390XState *env, int64_t src,
- int64_t dst)
-{
- if (src == dst) {
- return 0;
- } else if (src < dst) {
- return 1;
- } else {
- return 2;
- }
-}
-
-static inline uint32_t cc_calc_ltgt0_64(CPUS390XState *env, int64_t dst)
-{
- return cc_calc_ltgt_64(env, dst, 0);
-}
-
-static inline uint32_t cc_calc_ltugtu_32(CPUS390XState *env, uint32_t src,
- uint32_t dst)
-{
- if (src == dst) {
- return 0;
- } else if (src < dst) {
- return 1;
- } else {
- return 2;
- }
-}
-
-static inline uint32_t cc_calc_ltugtu_64(CPUS390XState *env, uint64_t src,
- uint64_t dst)
-{
- if (src == dst) {
- return 0;
- } else if (src < dst) {
- return 1;
- } else {
- return 2;
- }
-}
-
-static inline uint32_t cc_calc_tm_32(CPUS390XState *env, uint32_t val,
- uint32_t mask)
-{
- uint16_t r = val & mask;
-
- HELPER_LOG("%s: val 0x%x mask 0x%x\n", __func__, val, mask);
- if (r == 0 || mask == 0) {
- return 0;
- } else if (r == mask) {
- return 3;
- } else {
- return 1;
- }
-}
-
-/* set condition code for test under mask */
-static inline uint32_t cc_calc_tm_64(CPUS390XState *env, uint64_t val,
- uint32_t mask)
-{
- uint16_t r = val & mask;
-
- HELPER_LOG("%s: val 0x%lx mask 0x%x r 0x%x\n", __func__, val, mask, r);
- if (r == 0 || mask == 0) {
- return 0;
- } else if (r == mask) {
- return 3;
- } else {
- while (!(mask & 0x8000)) {
- mask <<= 1;
- val <<= 1;
- }
- if (val & 0x8000) {
- return 2;
- } else {
- return 1;
- }
- }
-}
-
-static inline uint32_t cc_calc_nz(CPUS390XState *env, uint64_t dst)
-{
- return !!dst;
-}
-
-static inline uint32_t cc_calc_add_64(CPUS390XState *env, int64_t a1,
- int64_t a2, int64_t ar)
-{
- if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) {
- return 3; /* overflow */
- } else {
- if (ar < 0) {
- return 1;
- } else if (ar > 0) {
- return 2;
- } else {
- return 0;
- }
- }
-}
-
-static inline uint32_t cc_calc_addu_64(CPUS390XState *env, uint64_t a1,
- uint64_t a2, uint64_t ar)
-{
- if (ar == 0) {
- if (a1) {
- return 2;
- } else {
- return 0;
- }
- } else {
- if (ar < a1 || ar < a2) {
- return 3;
- } else {
- return 1;
- }
- }
-}
-
-static inline uint32_t cc_calc_sub_64(CPUS390XState *env, int64_t a1,
- int64_t a2, int64_t ar)
-{
- if ((a1 > 0 && a2 < 0 && ar < 0) || (a1 < 0 && a2 > 0 && ar > 0)) {
- return 3; /* overflow */
- } else {
- if (ar < 0) {
- return 1;
- } else if (ar > 0) {
- return 2;
- } else {
- return 0;
- }
- }
-}
-
-static inline uint32_t cc_calc_subu_64(CPUS390XState *env, uint64_t a1,
- uint64_t a2, uint64_t ar)
-{
- if (ar == 0) {
- return 2;
- } else {
- if (a2 > a1) {
- return 1;
- } else {
- return 3;
- }
- }
-}
-
-static inline uint32_t cc_calc_abs_64(CPUS390XState *env, int64_t dst)
-{
- if ((uint64_t)dst == 0x8000000000000000ULL) {
- return 3;
- } else if (dst) {
- return 1;
- } else {
- return 0;
- }
-}
-
-static inline uint32_t cc_calc_nabs_64(CPUS390XState *env, int64_t dst)
-{
- return !!dst;
-}
-
-static inline uint32_t cc_calc_comp_64(CPUS390XState *env, int64_t dst)
-{
- if ((uint64_t)dst == 0x8000000000000000ULL) {
- return 3;
- } else if (dst < 0) {
- return 1;
- } else if (dst > 0) {
- return 2;
- } else {
- return 0;
- }
-}
-
-
-static inline uint32_t cc_calc_add_32(CPUS390XState *env, int32_t a1,
- int32_t a2, int32_t ar)
-{
- if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) {
- return 3; /* overflow */
- } else {
- if (ar < 0) {
- return 1;
- } else if (ar > 0) {
- return 2;
- } else {
- return 0;
- }
- }
-}
-
-static inline uint32_t cc_calc_addu_32(CPUS390XState *env, uint32_t a1,
- uint32_t a2, uint32_t ar)
-{
- if (ar == 0) {
- if (a1) {
- return 2;
- } else {
- return 0;
- }
- } else {
- if (ar < a1 || ar < a2) {
- return 3;
- } else {
- return 1;
- }
- }
-}
-
-static inline uint32_t cc_calc_sub_32(CPUS390XState *env, int32_t a1,
- int32_t a2, int32_t ar)
-{
- if ((a1 > 0 && a2 < 0 && ar < 0) || (a1 < 0 && a2 > 0 && ar > 0)) {
- return 3; /* overflow */
- } else {
- if (ar < 0) {
- return 1;
- } else if (ar > 0) {
- return 2;
- } else {
- return 0;
- }
- }
-}
-
-static inline uint32_t cc_calc_subu_32(CPUS390XState *env, uint32_t a1,
- uint32_t a2, uint32_t ar)
-{
- if (ar == 0) {
- return 2;
- } else {
- if (a2 > a1) {
- return 1;
- } else {
- return 3;
- }
- }
-}
-
-static inline uint32_t cc_calc_abs_32(CPUS390XState *env, int32_t dst)
-{
- if ((uint32_t)dst == 0x80000000UL) {
- return 3;
- } else if (dst) {
- return 1;
- } else {
- return 0;
- }
-}
-
-static inline uint32_t cc_calc_nabs_32(CPUS390XState *env, int32_t dst)
-{
- return !!dst;
-}
-
-static inline uint32_t cc_calc_comp_32(CPUS390XState *env, int32_t dst)
-{
- if ((uint32_t)dst == 0x80000000UL) {
- return 3;
- } else if (dst < 0) {
- return 1;
- } else if (dst > 0) {
- return 2;
- } else {
- return 0;
- }
-}
-
-/* calculate condition code for insert character under mask insn */
-static inline uint32_t cc_calc_icm_32(CPUS390XState *env, uint32_t mask,
- uint32_t val)
-{
- uint32_t cc;
-
- HELPER_LOG("%s: mask 0x%x val %d\n", __func__, mask, val);
- if (mask == 0xf) {
- if (!val) {
- return 0;
- } else if (val & 0x80000000) {
- return 1;
- } else {
- return 2;
- }
- }
-
- if (!val || !mask) {
- cc = 0;
- } else {
- while (mask != 1) {
- mask >>= 1;
- val >>= 8;
- }
- if (val & 0x80) {
- cc = 1;
- } else {
- cc = 2;
- }
- }
- return cc;
-}
-
-static inline uint32_t cc_calc_slag(CPUS390XState *env, uint64_t src,
- uint64_t shift)
-{
- uint64_t mask = ((1ULL << shift) - 1ULL) << (64 - shift);
- uint64_t match, r;
-
- /* check if the sign bit stays the same */
- if (src & (1ULL << 63)) {
- match = mask;
- } else {
- match = 0;
- }
-
- if ((src & mask) != match) {
- /* overflow */
- return 3;
- }
-
- r = ((src << shift) & ((1ULL << 63) - 1)) | (src & (1ULL << 63));
-
- if ((int64_t)r == 0) {
- return 0;
- } else if ((int64_t)r < 0) {
- return 1;
- }
-
- return 2;
-}
-
-
-static inline uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op,
- uint64_t src, uint64_t dst, uint64_t vr)
-{
- uint32_t r = 0;
-
- switch (cc_op) {
- case CC_OP_CONST0:
- case CC_OP_CONST1:
- case CC_OP_CONST2:
- case CC_OP_CONST3:
- /* cc_op value _is_ cc */
- r = cc_op;
- break;
- case CC_OP_LTGT0_32:
- r = cc_calc_ltgt0_32(env, dst);
- break;
- case CC_OP_LTGT0_64:
- r = cc_calc_ltgt0_64(env, dst);
- break;
- case CC_OP_LTGT_32:
- r = cc_calc_ltgt_32(env, src, dst);
- break;
- case CC_OP_LTGT_64:
- r = cc_calc_ltgt_64(env, src, dst);
- break;
- case CC_OP_LTUGTU_32:
- r = cc_calc_ltugtu_32(env, src, dst);
- break;
- case CC_OP_LTUGTU_64:
- r = cc_calc_ltugtu_64(env, src, dst);
- break;
- case CC_OP_TM_32:
- r = cc_calc_tm_32(env, src, dst);
- break;
- case CC_OP_TM_64:
- r = cc_calc_tm_64(env, src, dst);
- break;
- case CC_OP_NZ:
- r = cc_calc_nz(env, dst);
- break;
- case CC_OP_ADD_64:
- r = cc_calc_add_64(env, src, dst, vr);
- break;
- case CC_OP_ADDU_64:
- r = cc_calc_addu_64(env, src, dst, vr);
- break;
- case CC_OP_SUB_64:
- r = cc_calc_sub_64(env, src, dst, vr);
- break;
- case CC_OP_SUBU_64:
- r = cc_calc_subu_64(env, src, dst, vr);
- break;
- case CC_OP_ABS_64:
- r = cc_calc_abs_64(env, dst);
- break;
- case CC_OP_NABS_64:
- r = cc_calc_nabs_64(env, dst);
- break;
- case CC_OP_COMP_64:
- r = cc_calc_comp_64(env, dst);
- break;
-
- case CC_OP_ADD_32:
- r = cc_calc_add_32(env, src, dst, vr);
- break;
- case CC_OP_ADDU_32:
- r = cc_calc_addu_32(env, src, dst, vr);
- break;
- case CC_OP_SUB_32:
- r = cc_calc_sub_32(env, src, dst, vr);
- break;
- case CC_OP_SUBU_32:
- r = cc_calc_subu_32(env, src, dst, vr);
- break;
- case CC_OP_ABS_32:
- r = cc_calc_abs_64(env, dst);
- break;
- case CC_OP_NABS_32:
- r = cc_calc_nabs_64(env, dst);
- break;
- case CC_OP_COMP_32:
- r = cc_calc_comp_32(env, dst);
- break;
-
- case CC_OP_ICM:
- r = cc_calc_icm_32(env, src, dst);
- break;
- case CC_OP_SLAG:
- r = cc_calc_slag(env, src, dst);
- break;
-
- case CC_OP_LTGT_F32:
- r = set_cc_f32(src, dst);
- break;
- case CC_OP_LTGT_F64:
- r = set_cc_f64(src, dst);
- break;
- case CC_OP_NZ_F32:
- r = set_cc_nz_f32(dst);
- break;
- case CC_OP_NZ_F64:
- r = set_cc_nz_f64(dst);
- break;
-
- default:
- cpu_abort(env, "Unknown CC operation: %s\n", cc_name(cc_op));
- }
-
- HELPER_LOG("%s: %15s 0x%016lx 0x%016lx 0x%016lx = %d\n", __func__,
- cc_name(cc_op), src, dst, vr, r);
- return r;
-}
-
-uint32_t calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t src, uint64_t dst,
- uint64_t vr)
-{
- return do_calc_cc(env, cc_op, src, dst, vr);
-}
-
-uint32_t HELPER(calc_cc)(uint32_t cc_op, uint64_t src, uint64_t dst,
- uint64_t vr)
-{
- return do_calc_cc(env, cc_op, src, dst, vr);
-}
-
uint64_t HELPER(cvd)(int32_t bin)
{
/* positive 0 */
@@ -1594,14 +1105,7 @@ void HELPER(tr)(uint32_t len, uint64_t array, uint64_t trans)
}
#ifndef CONFIG_USER_ONLY
-
-void HELPER(load_psw)(uint64_t mask, uint64_t addr)
-{
- load_psw(env, mask, addr);
- cpu_loop_exit(env);
-}
-
-static void program_interrupt(CPUS390XState *env, uint32_t code, int ilc)
+void program_interrupt(CPUS390XState *env, uint32_t code, int ilc)
{
qemu_log("program interrupt at %#" PRIx64 "\n", env->psw.addr);
@@ -2175,30 +1679,6 @@ uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
return cc;
}
-void HELPER(sacf)(uint64_t a1)
-{
- HELPER_LOG("%s: %16" PRIx64 "\n", __func__, a1);
-
- switch (a1 & 0xf00) {
- case 0x000:
- env->psw.mask &= ~PSW_MASK_ASC;
- env->psw.mask |= PSW_ASC_PRIMARY;
- break;
- case 0x100:
- env->psw.mask &= ~PSW_MASK_ASC;
- env->psw.mask |= PSW_ASC_SECONDARY;
- break;
- case 0x300:
- env->psw.mask &= ~PSW_MASK_ASC;
- env->psw.mask |= PSW_ASC_HOME;
- break;
- default:
- qemu_log("unknown sacf mode: %" PRIx64 "\n", a1);
- program_interrupt(env, PGM_SPECIFICATION, 2);
- break;
- }
-}
-
/* invalidate pte */
void HELPER(ipte)(uint64_t pte_addr, uint64_t vaddr)
{
--
1.6.0.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 04/12] target-s390x: split integer helpers
2012-09-10 11:40 [Qemu-devel] [PULL 00/12] s390 patch queue 2012-09-10 Alexander Graf
` (2 preceding siblings ...)
2012-09-10 11:40 ` [Qemu-devel] [PATCH 03/12] target-s390x: split condition code helpers Alexander Graf
@ 2012-09-10 11:40 ` Alexander Graf
2012-09-10 11:40 ` [Qemu-devel] [PATCH 05/12] target-s390x: split memory access helpers Alexander Graf
` (8 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Alexander Graf @ 2012-09-10 11:40 UTC (permalink / raw)
To: qemu-devel qemu-devel; +Cc: Blue Swirl, Aurelien Jarno
From: Blue Swirl <blauwirbel@gmail.com>
Move integer helpers to int_helper.c.
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-s390x/Makefile.objs | 3 +-
target-s390x/int_helper.c | 201 ++++++++++++++++++++++++++++++++++++++++++++
target-s390x/op_helper.c | 170 -------------------------------------
3 files changed, 203 insertions(+), 171 deletions(-)
create mode 100644 target-s390x/int_helper.c
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index f9437d6..e8f66e9 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -1,8 +1,9 @@
obj-y += translate.o op_helper.o helper.o cpu.o interrupt.o
-obj-y += fpu_helper.o cc_helper.o
+obj-y += int_helper.o fpu_helper.o cc_helper.o
obj-$(CONFIG_SOFTMMU) += machine.o
obj-$(CONFIG_KVM) += kvm.o
$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+$(obj)/int_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
$(obj)/fpu_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
$(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
diff --git a/target-s390x/int_helper.c b/target-s390x/int_helper.c
new file mode 100644
index 0000000..e2eeb07
--- /dev/null
+++ b/target-s390x/int_helper.c
@@ -0,0 +1,201 @@
+/*
+ * S/390 integer helper routines
+ *
+ * Copyright (c) 2009 Ulrich Hecht
+ * Copyright (c) 2009 Alexander Graf
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cpu.h"
+#include "dyngen-exec.h"
+#include "host-utils.h"
+#include "helper.h"
+
+/* #define DEBUG_HELPER */
+#ifdef DEBUG_HELPER
+#define HELPER_LOG(x...) qemu_log(x)
+#else
+#define HELPER_LOG(x...)
+#endif
+
+/* 64/64 -> 128 unsigned multiplication */
+void HELPER(mlg)(uint32_t r1, uint64_t v2)
+{
+#if HOST_LONG_BITS == 64 && defined(__GNUC__)
+ /* assuming 64-bit hosts have __uint128_t */
+ __uint128_t res = (__uint128_t)env->regs[r1 + 1];
+
+ res *= (__uint128_t)v2;
+ env->regs[r1] = (uint64_t)(res >> 64);
+ env->regs[r1 + 1] = (uint64_t)res;
+#else
+ mulu64(&env->regs[r1 + 1], &env->regs[r1], env->regs[r1 + 1], v2);
+#endif
+}
+
+/* 128 -> 64/64 unsigned division */
+void HELPER(dlg)(uint32_t r1, uint64_t v2)
+{
+ uint64_t divisor = v2;
+
+ if (!env->regs[r1]) {
+ /* 64 -> 64/64 case */
+ env->regs[r1] = env->regs[r1 + 1] % divisor;
+ env->regs[r1 + 1] = env->regs[r1 + 1] / divisor;
+ return;
+ } else {
+#if HOST_LONG_BITS == 64 && defined(__GNUC__)
+ /* assuming 64-bit hosts have __uint128_t */
+ __uint128_t dividend = (((__uint128_t)env->regs[r1]) << 64) |
+ (env->regs[r1 + 1]);
+ __uint128_t quotient = dividend / divisor;
+ __uint128_t remainder = dividend % divisor;
+
+ env->regs[r1 + 1] = quotient;
+ env->regs[r1] = remainder;
+#else
+ /* 32-bit hosts would need special wrapper functionality - just abort if
+ we encounter such a case; it's very unlikely anyways. */
+ cpu_abort(env, "128 -> 64/64 division not implemented\n");
+#endif
+ }
+}
+
+/* absolute value 32-bit */
+uint32_t HELPER(abs_i32)(int32_t val)
+{
+ if (val < 0) {
+ return -val;
+ } else {
+ return val;
+ }
+}
+
+/* negative absolute value 32-bit */
+int32_t HELPER(nabs_i32)(int32_t val)
+{
+ if (val < 0) {
+ return val;
+ } else {
+ return -val;
+ }
+}
+
+/* absolute value 64-bit */
+uint64_t HELPER(abs_i64)(int64_t val)
+{
+ HELPER_LOG("%s: val 0x%" PRIx64 "\n", __func__, val);
+
+ if (val < 0) {
+ return -val;
+ } else {
+ return val;
+ }
+}
+
+/* negative absolute value 64-bit */
+int64_t HELPER(nabs_i64)(int64_t val)
+{
+ if (val < 0) {
+ return val;
+ } else {
+ return -val;
+ }
+}
+
+/* add with carry 32-bit unsigned */
+uint32_t HELPER(addc_u32)(uint32_t cc, uint32_t v1, uint32_t v2)
+{
+ uint32_t res;
+
+ res = v1 + v2;
+ if (cc & 2) {
+ res++;
+ }
+
+ return res;
+}
+
+/* subtract unsigned v2 from v1 with borrow */
+uint32_t HELPER(slb)(uint32_t cc, uint32_t r1, uint32_t v2)
+{
+ uint32_t v1 = env->regs[r1];
+ uint32_t res = v1 + (~v2) + (cc >> 1);
+
+ env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | res;
+ if (cc & 2) {
+ /* borrow */
+ return v1 ? 1 : 0;
+ } else {
+ return v1 ? 3 : 2;
+ }
+}
+
+/* subtract unsigned v2 from v1 with borrow */
+uint32_t HELPER(slbg)(uint32_t cc, uint32_t r1, uint64_t v1, uint64_t v2)
+{
+ uint64_t res = v1 + (~v2) + (cc >> 1);
+
+ env->regs[r1] = res;
+ if (cc & 2) {
+ /* borrow */
+ return v1 ? 1 : 0;
+ } else {
+ return v1 ? 3 : 2;
+ }
+}
+
+/* find leftmost one */
+uint32_t HELPER(flogr)(uint32_t r1, uint64_t v2)
+{
+ uint64_t res = 0;
+ uint64_t ov2 = v2;
+
+ while (!(v2 & 0x8000000000000000ULL) && v2) {
+ v2 <<= 1;
+ res++;
+ }
+
+ if (!v2) {
+ env->regs[r1] = 64;
+ env->regs[r1 + 1] = 0;
+ return 0;
+ } else {
+ env->regs[r1] = res;
+ env->regs[r1 + 1] = ov2 & ~(0x8000000000000000ULL >> res);
+ return 2;
+ }
+}
+
+uint64_t HELPER(cvd)(int32_t bin)
+{
+ /* positive 0 */
+ uint64_t dec = 0x0c;
+ int shift = 4;
+
+ if (bin < 0) {
+ bin = -bin;
+ dec = 0x0d;
+ }
+
+ for (shift = 4; (shift < 64) && bin; shift += 4) {
+ int current_number = bin % 10;
+
+ dec |= (current_number) << shift;
+ bin /= 10;
+ }
+
+ return dec;
+}
diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
index eced890..3b8b997 100644
--- a/target-s390x/op_helper.c
+++ b/target-s390x/op_helper.c
@@ -352,49 +352,6 @@ void HELPER(stcm)(uint32_t r1, uint32_t mask, uint64_t addr)
HELPER_LOG("\n");
}
-/* 64/64 -> 128 unsigned multiplication */
-void HELPER(mlg)(uint32_t r1, uint64_t v2)
-{
-#if HOST_LONG_BITS == 64 && defined(__GNUC__)
- /* assuming 64-bit hosts have __uint128_t */
- __uint128_t res = (__uint128_t)env->regs[r1 + 1];
-
- res *= (__uint128_t)v2;
- env->regs[r1] = (uint64_t)(res >> 64);
- env->regs[r1 + 1] = (uint64_t)res;
-#else
- mulu64(&env->regs[r1 + 1], &env->regs[r1], env->regs[r1 + 1], v2);
-#endif
-}
-
-/* 128 -> 64/64 unsigned division */
-void HELPER(dlg)(uint32_t r1, uint64_t v2)
-{
- uint64_t divisor = v2;
-
- if (!env->regs[r1]) {
- /* 64 -> 64/64 case */
- env->regs[r1] = env->regs[r1 + 1] % divisor;
- env->regs[r1 + 1] = env->regs[r1 + 1] / divisor;
- return;
- } else {
-#if HOST_LONG_BITS == 64 && defined(__GNUC__)
- /* assuming 64-bit hosts have __uint128_t */
- __uint128_t dividend = (((__uint128_t)env->regs[r1]) << 64) |
- (env->regs[r1 + 1]);
- __uint128_t quotient = dividend / divisor;
- __uint128_t remainder = dividend % divisor;
-
- env->regs[r1 + 1] = quotient;
- env->regs[r1] = remainder;
-#else
- /* 32-bit hosts would need special wrapper functionality - just abort if
- we encounter such a case; it's very unlikely anyways. */
- cpu_abort(env, "128 -> 64/64 division not implemented\n");
-#endif
- }
-}
-
static inline uint64_t get_address(int x2, int b2, int d2)
{
uint64_t r = d2;
@@ -677,61 +634,6 @@ uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
return cc;
}
-/* absolute value 32-bit */
-uint32_t HELPER(abs_i32)(int32_t val)
-{
- if (val < 0) {
- return -val;
- } else {
- return val;
- }
-}
-
-/* negative absolute value 32-bit */
-int32_t HELPER(nabs_i32)(int32_t val)
-{
- if (val < 0) {
- return val;
- } else {
- return -val;
- }
-}
-
-/* absolute value 64-bit */
-uint64_t HELPER(abs_i64)(int64_t val)
-{
- HELPER_LOG("%s: val 0x%" PRIx64 "\n", __func__, val);
-
- if (val < 0) {
- return -val;
- } else {
- return val;
- }
-}
-
-/* negative absolute value 64-bit */
-int64_t HELPER(nabs_i64)(int64_t val)
-{
- if (val < 0) {
- return val;
- } else {
- return -val;
- }
-}
-
-/* add with carry 32-bit unsigned */
-uint32_t HELPER(addc_u32)(uint32_t cc, uint32_t v1, uint32_t v2)
-{
- uint32_t res;
-
- res = v1 + v2;
- if (cc & 2) {
- res++;
- }
-
- return res;
-}
-
/* store character under mask high operates on the upper half of r1 */
void HELPER(stcmh)(uint32_t r1, uint64_t address, uint32_t mask)
{
@@ -936,57 +838,6 @@ uint32_t HELPER(clcle)(uint32_t r1, uint64_t a2, uint32_t r3)
return cc;
}
-/* subtract unsigned v2 from v1 with borrow */
-uint32_t HELPER(slb)(uint32_t cc, uint32_t r1, uint32_t v2)
-{
- uint32_t v1 = env->regs[r1];
- uint32_t res = v1 + (~v2) + (cc >> 1);
-
- env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | res;
- if (cc & 2) {
- /* borrow */
- return v1 ? 1 : 0;
- } else {
- return v1 ? 3 : 2;
- }
-}
-
-/* subtract unsigned v2 from v1 with borrow */
-uint32_t HELPER(slbg)(uint32_t cc, uint32_t r1, uint64_t v1, uint64_t v2)
-{
- uint64_t res = v1 + (~v2) + (cc >> 1);
-
- env->regs[r1] = res;
- if (cc & 2) {
- /* borrow */
- return v1 ? 1 : 0;
- } else {
- return v1 ? 3 : 2;
- }
-}
-
-/* find leftmost one */
-uint32_t HELPER(flogr)(uint32_t r1, uint64_t v2)
-{
- uint64_t res = 0;
- uint64_t ov2 = v2;
-
- while (!(v2 & 0x8000000000000000ULL) && v2) {
- v2 <<= 1;
- res++;
- }
-
- if (!v2) {
- env->regs[r1] = 64;
- env->regs[r1 + 1] = 0;
- return 0;
- } else {
- env->regs[r1] = res;
- env->regs[r1 + 1] = ov2 & ~(0x8000000000000000ULL >> res);
- return 2;
- }
-}
-
/* checksum */
void HELPER(cksm)(uint32_t r1, uint32_t r2)
{
@@ -1026,27 +877,6 @@ void HELPER(cksm)(uint32_t r1, uint32_t r2)
((uint32_t)cksm + (cksm >> 32));
}
-uint64_t HELPER(cvd)(int32_t bin)
-{
- /* positive 0 */
- uint64_t dec = 0x0c;
- int shift = 4;
-
- if (bin < 0) {
- bin = -bin;
- dec = 0x0d;
- }
-
- for (shift = 4; (shift < 64) && bin; shift += 4) {
- int current_number = bin % 10;
-
- dec |= (current_number) << shift;
- bin /= 10;
- }
-
- return dec;
-}
-
void HELPER(unpk)(uint32_t len, uint64_t dest, uint64_t src)
{
int len_dest = len >> 4;
--
1.6.0.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 05/12] target-s390x: split memory access helpers
2012-09-10 11:40 [Qemu-devel] [PULL 00/12] s390 patch queue 2012-09-10 Alexander Graf
` (3 preceding siblings ...)
2012-09-10 11:40 ` [Qemu-devel] [PATCH 04/12] target-s390x: split integer helpers Alexander Graf
@ 2012-09-10 11:40 ` Alexander Graf
2012-09-10 11:40 ` [Qemu-devel] [PATCH 06/12] target-s390x: rename op_helper.c to misc_helper.c Alexander Graf
` (7 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Alexander Graf @ 2012-09-10 11:40 UTC (permalink / raw)
To: qemu-devel qemu-devel; +Cc: Blue Swirl, Aurelien Jarno
From: Blue Swirl <blauwirbel@gmail.com>
Move memory access helpers to mem_helper.c.
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
[agraf: fold softmmu include ifdefs together]
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-s390x/Makefile.objs | 3 +-
target-s390x/mem_helper.c | 1190 ++++++++++++++++++++++++++++++++++++++++++++
target-s390x/op_helper.c | 1159 +------------------------------------------
3 files changed, 1193 insertions(+), 1159 deletions(-)
create mode 100644 target-s390x/mem_helper.c
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index e8f66e9..b9b3061 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -1,5 +1,5 @@
obj-y += translate.o op_helper.o helper.o cpu.o interrupt.o
-obj-y += int_helper.o fpu_helper.o cc_helper.o
+obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o
obj-$(CONFIG_SOFTMMU) += machine.o
obj-$(CONFIG_KVM) += kvm.o
@@ -7,3 +7,4 @@ $(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
$(obj)/int_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
$(obj)/fpu_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
$(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+$(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c
new file mode 100644
index 0000000..ba05e65
--- /dev/null
+++ b/target-s390x/mem_helper.c
@@ -0,0 +1,1190 @@
+/*
+ * S/390 memory access helper routines
+ *
+ * Copyright (c) 2009 Ulrich Hecht
+ * Copyright (c) 2009 Alexander Graf
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cpu.h"
+#include "dyngen-exec.h"
+#include "helper.h"
+
+/*****************************************************************************/
+/* Softmmu support */
+#if !defined(CONFIG_USER_ONLY)
+#include "softmmu_exec.h"
+
+#define MMUSUFFIX _mmu
+
+#define SHIFT 0
+#include "softmmu_template.h"
+
+#define SHIFT 1
+#include "softmmu_template.h"
+
+#define SHIFT 2
+#include "softmmu_template.h"
+
+#define SHIFT 3
+#include "softmmu_template.h"
+
+/* try to fill the TLB and return an exception if error. If retaddr is
+ NULL, it means that the function was called in C code (i.e. not
+ from generated code or from helper.c) */
+/* XXX: fix it to restore all registers */
+void tlb_fill(CPUS390XState *env1, target_ulong addr, int is_write, int mmu_idx,
+ uintptr_t retaddr)
+{
+ TranslationBlock *tb;
+ CPUS390XState *saved_env;
+ int ret;
+
+ saved_env = env;
+ env = env1;
+ ret = cpu_s390x_handle_mmu_fault(env, addr, is_write, mmu_idx);
+ if (unlikely(ret != 0)) {
+ if (likely(retaddr)) {
+ /* now we have a real cpu fault */
+ tb = tb_find_pc(retaddr);
+ if (likely(tb)) {
+ /* the PC is inside the translated code. It means that we have
+ a virtual CPU fault */
+ cpu_restore_state(tb, env, retaddr);
+ }
+ }
+ cpu_loop_exit(env);
+ }
+ env = saved_env;
+}
+
+#endif
+
+/* #define DEBUG_HELPER */
+#ifdef DEBUG_HELPER
+#define HELPER_LOG(x...) qemu_log(x)
+#else
+#define HELPER_LOG(x...)
+#endif
+
+#ifndef CONFIG_USER_ONLY
+static void mvc_fast_memset(CPUS390XState *env, uint32_t l, uint64_t dest,
+ uint8_t byte)
+{
+ target_phys_addr_t dest_phys;
+ target_phys_addr_t len = l;
+ void *dest_p;
+ uint64_t asc = env->psw.mask & PSW_MASK_ASC;
+ int flags;
+
+ if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) {
+ stb(dest, byte);
+ cpu_abort(env, "should never reach here");
+ }
+ dest_phys |= dest & ~TARGET_PAGE_MASK;
+
+ dest_p = cpu_physical_memory_map(dest_phys, &len, 1);
+
+ memset(dest_p, byte, len);
+
+ cpu_physical_memory_unmap(dest_p, 1, len, len);
+}
+
+static void mvc_fast_memmove(CPUS390XState *env, uint32_t l, uint64_t dest,
+ uint64_t src)
+{
+ target_phys_addr_t dest_phys;
+ target_phys_addr_t src_phys;
+ target_phys_addr_t len = l;
+ void *dest_p;
+ void *src_p;
+ uint64_t asc = env->psw.mask & PSW_MASK_ASC;
+ int flags;
+
+ if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) {
+ stb(dest, 0);
+ cpu_abort(env, "should never reach here");
+ }
+ dest_phys |= dest & ~TARGET_PAGE_MASK;
+
+ if (mmu_translate(env, src, 0, asc, &src_phys, &flags)) {
+ ldub(src);
+ cpu_abort(env, "should never reach here");
+ }
+ src_phys |= src & ~TARGET_PAGE_MASK;
+
+ dest_p = cpu_physical_memory_map(dest_phys, &len, 1);
+ src_p = cpu_physical_memory_map(src_phys, &len, 0);
+
+ memmove(dest_p, src_p, len);
+
+ cpu_physical_memory_unmap(dest_p, 1, len, len);
+ cpu_physical_memory_unmap(src_p, 0, len, len);
+}
+#endif
+
+/* and on array */
+uint32_t HELPER(nc)(uint32_t l, uint64_t dest, uint64_t src)
+{
+ int i;
+ unsigned char x;
+ uint32_t cc = 0;
+
+ HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
+ __func__, l, dest, src);
+ for (i = 0; i <= l; i++) {
+ x = ldub(dest + i) & ldub(src + i);
+ if (x) {
+ cc = 1;
+ }
+ stb(dest + i, x);
+ }
+ return cc;
+}
+
+/* xor on array */
+uint32_t HELPER(xc)(uint32_t l, uint64_t dest, uint64_t src)
+{
+ int i;
+ unsigned char x;
+ uint32_t cc = 0;
+
+ HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
+ __func__, l, dest, src);
+
+#ifndef CONFIG_USER_ONLY
+ /* xor with itself is the same as memset(0) */
+ if ((l > 32) && (src == dest) &&
+ (src & TARGET_PAGE_MASK) == ((src + l) & TARGET_PAGE_MASK)) {
+ mvc_fast_memset(env, l + 1, dest, 0);
+ return 0;
+ }
+#else
+ if (src == dest) {
+ memset(g2h(dest), 0, l + 1);
+ return 0;
+ }
+#endif
+
+ for (i = 0; i <= l; i++) {
+ x = ldub(dest + i) ^ ldub(src + i);
+ if (x) {
+ cc = 1;
+ }
+ stb(dest + i, x);
+ }
+ return cc;
+}
+
+/* or on array */
+uint32_t HELPER(oc)(uint32_t l, uint64_t dest, uint64_t src)
+{
+ int i;
+ unsigned char x;
+ uint32_t cc = 0;
+
+ HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
+ __func__, l, dest, src);
+ for (i = 0; i <= l; i++) {
+ x = ldub(dest + i) | ldub(src + i);
+ if (x) {
+ cc = 1;
+ }
+ stb(dest + i, x);
+ }
+ return cc;
+}
+
+/* memmove */
+void HELPER(mvc)(uint32_t l, uint64_t dest, uint64_t src)
+{
+ int i = 0;
+ int x = 0;
+ uint32_t l_64 = (l + 1) / 8;
+
+ HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
+ __func__, l, dest, src);
+
+#ifndef CONFIG_USER_ONLY
+ if ((l > 32) &&
+ (src & TARGET_PAGE_MASK) == ((src + l) & TARGET_PAGE_MASK) &&
+ (dest & TARGET_PAGE_MASK) == ((dest + l) & TARGET_PAGE_MASK)) {
+ if (dest == (src + 1)) {
+ mvc_fast_memset(env, l + 1, dest, ldub(src));
+ return;
+ } else if ((src & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) {
+ mvc_fast_memmove(env, l + 1, dest, src);
+ return;
+ }
+ }
+#else
+ if (dest == (src + 1)) {
+ memset(g2h(dest), ldub(src), l + 1);
+ return;
+ } else {
+ memmove(g2h(dest), g2h(src), l + 1);
+ return;
+ }
+#endif
+
+ /* handle the parts that fit into 8-byte loads/stores */
+ if (dest != (src + 1)) {
+ for (i = 0; i < l_64; i++) {
+ stq(dest + x, ldq(src + x));
+ x += 8;
+ }
+ }
+
+ /* slow version crossing pages with byte accesses */
+ for (i = x; i <= l; i++) {
+ stb(dest + i, ldub(src + i));
+ }
+}
+
+/* compare unsigned byte arrays */
+uint32_t HELPER(clc)(uint32_t l, uint64_t s1, uint64_t s2)
+{
+ int i;
+ unsigned char x, y;
+ uint32_t cc;
+
+ HELPER_LOG("%s l %d s1 %" PRIx64 " s2 %" PRIx64 "\n",
+ __func__, l, s1, s2);
+ for (i = 0; i <= l; i++) {
+ x = ldub(s1 + i);
+ y = ldub(s2 + i);
+ HELPER_LOG("%02x (%c)/%02x (%c) ", x, x, y, y);
+ if (x < y) {
+ cc = 1;
+ goto done;
+ } else if (x > y) {
+ cc = 2;
+ goto done;
+ }
+ }
+ cc = 0;
+ done:
+ HELPER_LOG("\n");
+ return cc;
+}
+
+/* compare logical under mask */
+uint32_t HELPER(clm)(uint32_t r1, uint32_t mask, uint64_t addr)
+{
+ uint8_t r, d;
+ uint32_t cc;
+
+ HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%" PRIx64 "\n", __func__, r1,
+ mask, addr);
+ cc = 0;
+ while (mask) {
+ if (mask & 8) {
+ d = ldub(addr);
+ r = (r1 & 0xff000000UL) >> 24;
+ HELPER_LOG("mask 0x%x %02x/%02x (0x%" PRIx64 ") ", mask, r, d,
+ addr);
+ if (r < d) {
+ cc = 1;
+ break;
+ } else if (r > d) {
+ cc = 2;
+ break;
+ }
+ addr++;
+ }
+ mask = (mask << 1) & 0xf;
+ r1 <<= 8;
+ }
+ HELPER_LOG("\n");
+ return cc;
+}
+
+/* store character under mask */
+void HELPER(stcm)(uint32_t r1, uint32_t mask, uint64_t addr)
+{
+ uint8_t r;
+
+ HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%lx\n", __func__, r1, mask,
+ addr);
+ while (mask) {
+ if (mask & 8) {
+ r = (r1 & 0xff000000UL) >> 24;
+ stb(addr, r);
+ HELPER_LOG("mask 0x%x %02x (0x%lx) ", mask, r, addr);
+ addr++;
+ }
+ mask = (mask << 1) & 0xf;
+ r1 <<= 8;
+ }
+ HELPER_LOG("\n");
+}
+
+static inline uint64_t get_address(int x2, int b2, int d2)
+{
+ uint64_t r = d2;
+
+ if (x2) {
+ r += env->regs[x2];
+ }
+
+ if (b2) {
+ r += env->regs[b2];
+ }
+
+ /* 31-Bit mode */
+ if (!(env->psw.mask & PSW_MASK_64)) {
+ r &= 0x7fffffff;
+ }
+
+ return r;
+}
+
+static inline uint64_t get_address_31fix(int reg)
+{
+ uint64_t r = env->regs[reg];
+
+ /* 31-Bit mode */
+ if (!(env->psw.mask & PSW_MASK_64)) {
+ r &= 0x7fffffff;
+ }
+
+ return r;
+}
+
+/* search string (c is byte to search, r2 is string, r1 end of string) */
+uint32_t HELPER(srst)(uint32_t c, uint32_t r1, uint32_t r2)
+{
+ uint64_t i;
+ uint32_t cc = 2;
+ uint64_t str = get_address_31fix(r2);
+ uint64_t end = get_address_31fix(r1);
+
+ HELPER_LOG("%s: c %d *r1 0x%" PRIx64 " *r2 0x%" PRIx64 "\n", __func__,
+ c, env->regs[r1], env->regs[r2]);
+
+ for (i = str; i != end; i++) {
+ if (ldub(i) == c) {
+ env->regs[r1] = i;
+ cc = 1;
+ break;
+ }
+ }
+
+ return cc;
+}
+
+/* unsigned string compare (c is string terminator) */
+uint32_t HELPER(clst)(uint32_t c, uint32_t r1, uint32_t r2)
+{
+ uint64_t s1 = get_address_31fix(r1);
+ uint64_t s2 = get_address_31fix(r2);
+ uint8_t v1, v2;
+ uint32_t cc;
+
+ c = c & 0xff;
+#ifdef CONFIG_USER_ONLY
+ if (!c) {
+ HELPER_LOG("%s: comparing '%s' and '%s'\n",
+ __func__, (char *)g2h(s1), (char *)g2h(s2));
+ }
+#endif
+ for (;;) {
+ v1 = ldub(s1);
+ v2 = ldub(s2);
+ if ((v1 == c || v2 == c) || (v1 != v2)) {
+ break;
+ }
+ s1++;
+ s2++;
+ }
+
+ if (v1 == v2) {
+ cc = 0;
+ } else {
+ cc = (v1 < v2) ? 1 : 2;
+ /* FIXME: 31-bit mode! */
+ env->regs[r1] = s1;
+ env->regs[r2] = s2;
+ }
+ return cc;
+}
+
+/* move page */
+void HELPER(mvpg)(uint64_t r0, uint64_t r1, uint64_t r2)
+{
+ /* XXX missing r0 handling */
+#ifdef CONFIG_USER_ONLY
+ int i;
+
+ for (i = 0; i < TARGET_PAGE_SIZE; i++) {
+ stb(r1 + i, ldub(r2 + i));
+ }
+#else
+ mvc_fast_memmove(env, TARGET_PAGE_SIZE, r1, r2);
+#endif
+}
+
+/* string copy (c is string terminator) */
+void HELPER(mvst)(uint32_t c, uint32_t r1, uint32_t r2)
+{
+ uint64_t dest = get_address_31fix(r1);
+ uint64_t src = get_address_31fix(r2);
+ uint8_t v;
+
+ c = c & 0xff;
+#ifdef CONFIG_USER_ONLY
+ if (!c) {
+ HELPER_LOG("%s: copy '%s' to 0x%lx\n", __func__, (char *)g2h(src),
+ dest);
+ }
+#endif
+ for (;;) {
+ v = ldub(src);
+ stb(dest, v);
+ if (v == c) {
+ break;
+ }
+ src++;
+ dest++;
+ }
+ env->regs[r1] = dest; /* FIXME: 31-bit mode! */
+}
+
+/* compare and swap 64-bit */
+uint32_t HELPER(csg)(uint32_t r1, uint64_t a2, uint32_t r3)
+{
+ /* FIXME: locking? */
+ uint32_t cc;
+ uint64_t v2 = ldq(a2);
+
+ if (env->regs[r1] == v2) {
+ cc = 0;
+ stq(a2, env->regs[r3]);
+ } else {
+ cc = 1;
+ env->regs[r1] = v2;
+ }
+ return cc;
+}
+
+/* compare double and swap 64-bit */
+uint32_t HELPER(cdsg)(uint32_t r1, uint64_t a2, uint32_t r3)
+{
+ /* FIXME: locking? */
+ uint32_t cc;
+ uint64_t v2_hi = ldq(a2);
+ uint64_t v2_lo = ldq(a2 + 8);
+ uint64_t v1_hi = env->regs[r1];
+ uint64_t v1_lo = env->regs[r1 + 1];
+
+ if ((v1_hi == v2_hi) && (v1_lo == v2_lo)) {
+ cc = 0;
+ stq(a2, env->regs[r3]);
+ stq(a2 + 8, env->regs[r3 + 1]);
+ } else {
+ cc = 1;
+ env->regs[r1] = v2_hi;
+ env->regs[r1 + 1] = v2_lo;
+ }
+
+ return cc;
+}
+
+/* compare and swap 32-bit */
+uint32_t HELPER(cs)(uint32_t r1, uint64_t a2, uint32_t r3)
+{
+ /* FIXME: locking? */
+ uint32_t cc;
+ uint32_t v2 = ldl(a2);
+
+ HELPER_LOG("%s: r1 %d a2 0x%lx r3 %d\n", __func__, r1, a2, r3);
+ if (((uint32_t)env->regs[r1]) == v2) {
+ cc = 0;
+ stl(a2, (uint32_t)env->regs[r3]);
+ } else {
+ cc = 1;
+ env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | v2;
+ }
+ return cc;
+}
+
+static uint32_t helper_icm(uint32_t r1, uint64_t address, uint32_t mask)
+{
+ int pos = 24; /* top of the lower half of r1 */
+ uint64_t rmask = 0xff000000ULL;
+ uint8_t val = 0;
+ int ccd = 0;
+ uint32_t cc = 0;
+
+ while (mask) {
+ if (mask & 8) {
+ env->regs[r1] &= ~rmask;
+ val = ldub(address);
+ if ((val & 0x80) && !ccd) {
+ cc = 1;
+ }
+ ccd = 1;
+ if (val && cc == 0) {
+ cc = 2;
+ }
+ env->regs[r1] |= (uint64_t)val << pos;
+ address++;
+ }
+ mask = (mask << 1) & 0xf;
+ pos -= 8;
+ rmask >>= 8;
+ }
+
+ return cc;
+}
+
+/* execute instruction
+ this instruction executes an insn modified with the contents of r1
+ it does not change the executed instruction in memory
+ it does not change the program counter
+ in other words: tricky...
+ currently implemented by interpreting the cases it is most commonly used in
+*/
+uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
+{
+ uint16_t insn = lduw_code(addr);
+
+ HELPER_LOG("%s: v1 0x%lx addr 0x%lx insn 0x%x\n", __func__, v1, addr,
+ insn);
+ if ((insn & 0xf0ff) == 0xd000) {
+ uint32_t l, insn2, b1, b2, d1, d2;
+
+ l = v1 & 0xff;
+ insn2 = ldl_code(addr + 2);
+ b1 = (insn2 >> 28) & 0xf;
+ b2 = (insn2 >> 12) & 0xf;
+ d1 = (insn2 >> 16) & 0xfff;
+ d2 = insn2 & 0xfff;
+ switch (insn & 0xf00) {
+ case 0x200:
+ helper_mvc(l, get_address(0, b1, d1), get_address(0, b2, d2));
+ break;
+ case 0x500:
+ cc = helper_clc(l, get_address(0, b1, d1), get_address(0, b2, d2));
+ break;
+ case 0x700:
+ cc = helper_xc(l, get_address(0, b1, d1), get_address(0, b2, d2));
+ break;
+ case 0xc00:
+ helper_tr(l, get_address(0, b1, d1), get_address(0, b2, d2));
+ break;
+ default:
+ goto abort;
+ break;
+ }
+ } else if ((insn & 0xff00) == 0x0a00) {
+ /* supervisor call */
+ HELPER_LOG("%s: svc %ld via execute\n", __func__, (insn | v1) & 0xff);
+ env->psw.addr = ret - 4;
+ env->int_svc_code = (insn | v1) & 0xff;
+ env->int_svc_ilc = 4;
+ helper_exception(EXCP_SVC);
+ } else if ((insn & 0xff00) == 0xbf00) {
+ uint32_t insn2, r1, r3, b2, d2;
+
+ insn2 = ldl_code(addr + 2);
+ r1 = (insn2 >> 20) & 0xf;
+ r3 = (insn2 >> 16) & 0xf;
+ b2 = (insn2 >> 12) & 0xf;
+ d2 = insn2 & 0xfff;
+ cc = helper_icm(r1, get_address(0, b2, d2), r3);
+ } else {
+ abort:
+ cpu_abort(env, "EXECUTE on instruction prefix 0x%x not implemented\n",
+ insn);
+ }
+ return cc;
+}
+
+/* store character under mask high operates on the upper half of r1 */
+void HELPER(stcmh)(uint32_t r1, uint64_t address, uint32_t mask)
+{
+ int pos = 56; /* top of the upper half of r1 */
+
+ while (mask) {
+ if (mask & 8) {
+ stb(address, (env->regs[r1] >> pos) & 0xff);
+ address++;
+ }
+ mask = (mask << 1) & 0xf;
+ pos -= 8;
+ }
+}
+
+/* insert character under mask high; same as icm, but operates on the
+ upper half of r1 */
+uint32_t HELPER(icmh)(uint32_t r1, uint64_t address, uint32_t mask)
+{
+ int pos = 56; /* top of the upper half of r1 */
+ uint64_t rmask = 0xff00000000000000ULL;
+ uint8_t val = 0;
+ int ccd = 0;
+ uint32_t cc = 0;
+
+ while (mask) {
+ if (mask & 8) {
+ env->regs[r1] &= ~rmask;
+ val = ldub(address);
+ if ((val & 0x80) && !ccd) {
+ cc = 1;
+ }
+ ccd = 1;
+ if (val && cc == 0) {
+ cc = 2;
+ }
+ env->regs[r1] |= (uint64_t)val << pos;
+ address++;
+ }
+ mask = (mask << 1) & 0xf;
+ pos -= 8;
+ rmask >>= 8;
+ }
+
+ return cc;
+}
+
+/* load access registers r1 to r3 from memory at a2 */
+void HELPER(lam)(uint32_t r1, uint64_t a2, uint32_t r3)
+{
+ int i;
+
+ for (i = r1;; i = (i + 1) % 16) {
+ env->aregs[i] = ldl(a2);
+ a2 += 4;
+
+ if (i == r3) {
+ break;
+ }
+ }
+}
+
+/* store access registers r1 to r3 in memory at a2 */
+void HELPER(stam)(uint32_t r1, uint64_t a2, uint32_t r3)
+{
+ int i;
+
+ for (i = r1;; i = (i + 1) % 16) {
+ stl(a2, env->aregs[i]);
+ a2 += 4;
+
+ if (i == r3) {
+ break;
+ }
+ }
+}
+
+/* move long */
+uint32_t HELPER(mvcl)(uint32_t r1, uint32_t r2)
+{
+ uint64_t destlen = env->regs[r1 + 1] & 0xffffff;
+ uint64_t dest = get_address_31fix(r1);
+ uint64_t srclen = env->regs[r2 + 1] & 0xffffff;
+ uint64_t src = get_address_31fix(r2);
+ uint8_t pad = src >> 24;
+ uint8_t v;
+ uint32_t cc;
+
+ if (destlen == srclen) {
+ cc = 0;
+ } else if (destlen < srclen) {
+ cc = 1;
+ } else {
+ cc = 2;
+ }
+
+ if (srclen > destlen) {
+ srclen = destlen;
+ }
+
+ for (; destlen && srclen; src++, dest++, destlen--, srclen--) {
+ v = ldub(src);
+ stb(dest, v);
+ }
+
+ for (; destlen; dest++, destlen--) {
+ stb(dest, pad);
+ }
+
+ env->regs[r1 + 1] = destlen;
+ /* can't use srclen here, we trunc'ed it */
+ env->regs[r2 + 1] -= src - env->regs[r2];
+ env->regs[r1] = dest;
+ env->regs[r2] = src;
+
+ return cc;
+}
+
+/* move long extended another memcopy insn with more bells and whistles */
+uint32_t HELPER(mvcle)(uint32_t r1, uint64_t a2, uint32_t r3)
+{
+ uint64_t destlen = env->regs[r1 + 1];
+ uint64_t dest = env->regs[r1];
+ uint64_t srclen = env->regs[r3 + 1];
+ uint64_t src = env->regs[r3];
+ uint8_t pad = a2 & 0xff;
+ uint8_t v;
+ uint32_t cc;
+
+ if (!(env->psw.mask & PSW_MASK_64)) {
+ destlen = (uint32_t)destlen;
+ srclen = (uint32_t)srclen;
+ dest &= 0x7fffffff;
+ src &= 0x7fffffff;
+ }
+
+ if (destlen == srclen) {
+ cc = 0;
+ } else if (destlen < srclen) {
+ cc = 1;
+ } else {
+ cc = 2;
+ }
+
+ if (srclen > destlen) {
+ srclen = destlen;
+ }
+
+ for (; destlen && srclen; src++, dest++, destlen--, srclen--) {
+ v = ldub(src);
+ stb(dest, v);
+ }
+
+ for (; destlen; dest++, destlen--) {
+ stb(dest, pad);
+ }
+
+ env->regs[r1 + 1] = destlen;
+ /* can't use srclen here, we trunc'ed it */
+ /* FIXME: 31-bit mode! */
+ env->regs[r3 + 1] -= src - env->regs[r3];
+ env->regs[r1] = dest;
+ env->regs[r3] = src;
+
+ return cc;
+}
+
+/* compare logical long extended memcompare insn with padding */
+uint32_t HELPER(clcle)(uint32_t r1, uint64_t a2, uint32_t r3)
+{
+ uint64_t destlen = env->regs[r1 + 1];
+ uint64_t dest = get_address_31fix(r1);
+ uint64_t srclen = env->regs[r3 + 1];
+ uint64_t src = get_address_31fix(r3);
+ uint8_t pad = a2 & 0xff;
+ uint8_t v1 = 0, v2 = 0;
+ uint32_t cc = 0;
+
+ if (!(destlen || srclen)) {
+ return cc;
+ }
+
+ if (srclen > destlen) {
+ srclen = destlen;
+ }
+
+ for (; destlen || srclen; src++, dest++, destlen--, srclen--) {
+ v1 = srclen ? ldub(src) : pad;
+ v2 = destlen ? ldub(dest) : pad;
+ if (v1 != v2) {
+ cc = (v1 < v2) ? 1 : 2;
+ break;
+ }
+ }
+
+ env->regs[r1 + 1] = destlen;
+ /* can't use srclen here, we trunc'ed it */
+ env->regs[r3 + 1] -= src - env->regs[r3];
+ env->regs[r1] = dest;
+ env->regs[r3] = src;
+
+ return cc;
+}
+
+/* checksum */
+void HELPER(cksm)(uint32_t r1, uint32_t r2)
+{
+ uint64_t src = get_address_31fix(r2);
+ uint64_t src_len = env->regs[(r2 + 1) & 15];
+ uint64_t cksm = (uint32_t)env->regs[r1];
+
+ while (src_len >= 4) {
+ cksm += ldl(src);
+
+ /* move to next word */
+ src_len -= 4;
+ src += 4;
+ }
+
+ switch (src_len) {
+ case 0:
+ break;
+ case 1:
+ cksm += ldub(src) << 24;
+ break;
+ case 2:
+ cksm += lduw(src) << 16;
+ break;
+ case 3:
+ cksm += lduw(src) << 16;
+ cksm += ldub(src + 2) << 8;
+ break;
+ }
+
+ /* indicate we've processed everything */
+ env->regs[r2] = src + src_len;
+ env->regs[(r2 + 1) & 15] = 0;
+
+ /* store result */
+ env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
+ ((uint32_t)cksm + (cksm >> 32));
+}
+
+void HELPER(unpk)(uint32_t len, uint64_t dest, uint64_t src)
+{
+ int len_dest = len >> 4;
+ int len_src = len & 0xf;
+ uint8_t b;
+ int second_nibble = 0;
+
+ dest += len_dest;
+ src += len_src;
+
+ /* last byte is special, it only flips the nibbles */
+ b = ldub(src);
+ stb(dest, (b << 4) | (b >> 4));
+ src--;
+ len_src--;
+
+ /* now pad every nibble with 0xf0 */
+
+ while (len_dest > 0) {
+ uint8_t cur_byte = 0;
+
+ if (len_src > 0) {
+ cur_byte = ldub(src);
+ }
+
+ len_dest--;
+ dest--;
+
+ /* only advance one nibble at a time */
+ if (second_nibble) {
+ cur_byte >>= 4;
+ len_src--;
+ src--;
+ }
+ second_nibble = !second_nibble;
+
+ /* digit */
+ cur_byte = (cur_byte & 0xf);
+ /* zone bits */
+ cur_byte |= 0xf0;
+
+ stb(dest, cur_byte);
+ }
+}
+
+void HELPER(tr)(uint32_t len, uint64_t array, uint64_t trans)
+{
+ int i;
+
+ for (i = 0; i <= len; i++) {
+ uint8_t byte = ldub(array + i);
+ uint8_t new_byte = ldub(trans + byte);
+
+ stb(array + i, new_byte);
+ }
+}
+
+#if !defined(CONFIG_USER_ONLY)
+void HELPER(lctlg)(uint32_t r1, uint64_t a2, uint32_t r3)
+{
+ int i;
+ uint64_t src = a2;
+
+ for (i = r1;; i = (i + 1) % 16) {
+ env->cregs[i] = ldq(src);
+ HELPER_LOG("load ctl %d from 0x%" PRIx64 " == 0x%" PRIx64 "\n",
+ i, src, env->cregs[i]);
+ src += sizeof(uint64_t);
+
+ if (i == r3) {
+ break;
+ }
+ }
+
+ tlb_flush(env, 1);
+}
+
+void HELPER(lctl)(uint32_t r1, uint64_t a2, uint32_t r3)
+{
+ int i;
+ uint64_t src = a2;
+
+ for (i = r1;; i = (i + 1) % 16) {
+ env->cregs[i] = (env->cregs[i] & 0xFFFFFFFF00000000ULL) | ldl(src);
+ src += sizeof(uint32_t);
+
+ if (i == r3) {
+ break;
+ }
+ }
+
+ tlb_flush(env, 1);
+}
+
+void HELPER(stctg)(uint32_t r1, uint64_t a2, uint32_t r3)
+{
+ int i;
+ uint64_t dest = a2;
+
+ for (i = r1;; i = (i + 1) % 16) {
+ stq(dest, env->cregs[i]);
+ dest += sizeof(uint64_t);
+
+ if (i == r3) {
+ break;
+ }
+ }
+}
+
+void HELPER(stctl)(uint32_t r1, uint64_t a2, uint32_t r3)
+{
+ int i;
+ uint64_t dest = a2;
+
+ for (i = r1;; i = (i + 1) % 16) {
+ stl(dest, env->cregs[i]);
+ dest += sizeof(uint32_t);
+
+ if (i == r3) {
+ break;
+ }
+ }
+}
+
+uint32_t HELPER(tprot)(uint64_t a1, uint64_t a2)
+{
+ /* XXX implement */
+
+ return 0;
+}
+
+/* insert storage key extended */
+uint64_t HELPER(iske)(uint64_t r2)
+{
+ uint64_t addr = get_address(0, 0, r2);
+
+ if (addr > ram_size) {
+ return 0;
+ }
+
+ return env->storage_keys[addr / TARGET_PAGE_SIZE];
+}
+
+/* set storage key extended */
+void HELPER(sske)(uint32_t r1, uint64_t r2)
+{
+ uint64_t addr = get_address(0, 0, r2);
+
+ if (addr > ram_size) {
+ return;
+ }
+
+ env->storage_keys[addr / TARGET_PAGE_SIZE] = r1;
+}
+
+/* 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;
+ }
+
+ 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
+ *
+ * 0 Reference bit zero; change bit zero
+ * 1 Reference bit zero; change bit one
+ * 2 Reference bit one; change bit zero
+ * 3 Reference bit one; change bit one
+ */
+
+ return re >> 1;
+}
+
+/* compare and swap and purge */
+uint32_t HELPER(csp)(uint32_t r1, uint32_t r2)
+{
+ uint32_t cc;
+ uint32_t o1 = env->regs[r1];
+ uint64_t a2 = get_address_31fix(r2) & ~3ULL;
+ uint32_t o2 = ldl(a2);
+
+ if (o1 == o2) {
+ stl(a2, env->regs[(r1 + 1) & 15]);
+ if (env->regs[r2] & 0x3) {
+ /* flush TLB / ALB */
+ tlb_flush(env, 1);
+ }
+ cc = 0;
+ } else {
+ env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | o2;
+ cc = 1;
+ }
+
+ return cc;
+}
+
+static uint32_t mvc_asc(int64_t l, uint64_t a1, uint64_t mode1, uint64_t a2,
+ uint64_t mode2)
+{
+ target_ulong src, dest;
+ int flags, cc = 0, i;
+
+ if (!l) {
+ return 0;
+ } else if (l > 256) {
+ /* max 256 */
+ l = 256;
+ cc = 3;
+ }
+
+ if (mmu_translate(env, a1 & TARGET_PAGE_MASK, 1, mode1, &dest, &flags)) {
+ cpu_loop_exit(env);
+ }
+ dest |= a1 & ~TARGET_PAGE_MASK;
+
+ if (mmu_translate(env, a2 & TARGET_PAGE_MASK, 0, mode2, &src, &flags)) {
+ cpu_loop_exit(env);
+ }
+ src |= a2 & ~TARGET_PAGE_MASK;
+
+ /* XXX replace w/ memcpy */
+ for (i = 0; i < l; i++) {
+ /* XXX be more clever */
+ if ((((dest + i) & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) ||
+ (((src + i) & TARGET_PAGE_MASK) != (src & TARGET_PAGE_MASK))) {
+ mvc_asc(l - i, a1 + i, mode1, a2 + i, mode2);
+ break;
+ }
+ stb_phys(dest + i, ldub_phys(src + i));
+ }
+
+ return cc;
+}
+
+uint32_t HELPER(mvcs)(uint64_t l, uint64_t a1, uint64_t a2)
+{
+ HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
+ __func__, l, a1, a2);
+
+ return mvc_asc(l, a1, PSW_ASC_SECONDARY, a2, PSW_ASC_PRIMARY);
+}
+
+uint32_t HELPER(mvcp)(uint64_t l, uint64_t a1, uint64_t a2)
+{
+ HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
+ __func__, l, a1, a2);
+
+ return mvc_asc(l, a1, PSW_ASC_PRIMARY, a2, PSW_ASC_SECONDARY);
+}
+
+/* invalidate pte */
+void HELPER(ipte)(uint64_t pte_addr, uint64_t vaddr)
+{
+ uint64_t page = vaddr & TARGET_PAGE_MASK;
+ uint64_t pte = 0;
+
+ /* XXX broadcast to other CPUs */
+
+ /* XXX Linux is nice enough to give us the exact pte address.
+ According to spec we'd have to find it out ourselves */
+ /* XXX Linux is fine with overwriting the pte, the spec requires
+ us to only set the invalid bit */
+ stq_phys(pte_addr, pte | _PAGE_INVALID);
+
+ /* 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 */
+void HELPER(ptlb)(void)
+{
+ tlb_flush(env, 1);
+}
+
+/* store using real address */
+void HELPER(stura)(uint64_t addr, uint32_t v1)
+{
+ stw_phys(get_address(0, 0, addr), v1);
+}
+
+/* load real address */
+uint32_t HELPER(lra)(uint64_t addr, uint32_t r1)
+{
+ uint32_t cc = 0;
+ int old_exc = env->exception_index;
+ uint64_t asc = env->psw.mask & PSW_MASK_ASC;
+ uint64_t ret;
+ int flags;
+
+ /* XXX incomplete - has more corner cases */
+ if (!(env->psw.mask & PSW_MASK_64) && (addr >> 32)) {
+ program_interrupt(env, PGM_SPECIAL_OP, 2);
+ }
+
+ env->exception_index = old_exc;
+ if (mmu_translate(env, addr, 0, asc, &ret, &flags)) {
+ cc = 3;
+ }
+ if (env->exception_index == EXCP_PGM) {
+ ret = env->int_pgm_code | 0x80000000;
+ } else {
+ ret |= addr & ~TARGET_PAGE_MASK;
+ }
+ env->exception_index = old_exc;
+
+ if (!(env->psw.mask & PSW_MASK_64)) {
+ env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
+ (ret & 0xffffffffULL);
+ } else {
+ env->regs[r1] = ret;
+ }
+
+ return cc;
+}
+
+#endif
diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
index 3b8b997..bb8dbf5 100644
--- a/target-s390x/op_helper.c
+++ b/target-s390x/op_helper.c
@@ -32,57 +32,8 @@
#endif
#if !defined(CONFIG_USER_ONLY)
-#include "sysemu.h"
-#endif
-
-/*****************************************************************************/
-/* Softmmu support */
-#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
-
-#define MMUSUFFIX _mmu
-
-#define SHIFT 0
-#include "softmmu_template.h"
-
-#define SHIFT 1
-#include "softmmu_template.h"
-
-#define SHIFT 2
-#include "softmmu_template.h"
-
-#define SHIFT 3
-#include "softmmu_template.h"
-
-/* try to fill the TLB and return an exception if error. If retaddr is
- NULL, it means that the function was called in C code (i.e. not
- from generated code or from helper.c) */
-/* XXX: fix it to restore all registers */
-void tlb_fill(CPUS390XState *env1, target_ulong addr, int is_write, int mmu_idx,
- uintptr_t retaddr)
-{
- TranslationBlock *tb;
- CPUS390XState *saved_env;
- int ret;
-
- saved_env = env;
- env = env1;
- ret = cpu_s390x_handle_mmu_fault(env, addr, is_write, mmu_idx);
- if (unlikely(ret != 0)) {
- if (likely(retaddr)) {
- /* now we have a real cpu fault */
- tb = tb_find_pc(retaddr);
- if (likely(tb)) {
- /* the PC is inside the translated code. It means that we have
- a virtual CPU fault */
- cpu_restore_state(tb, env, retaddr);
- }
- }
- cpu_loop_exit(env);
- }
- env = saved_env;
-}
-
+#include "sysemu.h"
#endif
/* #define DEBUG_HELPER */
@@ -101,840 +52,6 @@ void HELPER(exception)(uint32_t excp)
}
#ifndef CONFIG_USER_ONLY
-static void mvc_fast_memset(CPUS390XState *env, uint32_t l, uint64_t dest,
- uint8_t byte)
-{
- target_phys_addr_t dest_phys;
- target_phys_addr_t len = l;
- void *dest_p;
- uint64_t asc = env->psw.mask & PSW_MASK_ASC;
- int flags;
-
- if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) {
- stb(dest, byte);
- cpu_abort(env, "should never reach here");
- }
- dest_phys |= dest & ~TARGET_PAGE_MASK;
-
- dest_p = cpu_physical_memory_map(dest_phys, &len, 1);
-
- memset(dest_p, byte, len);
-
- cpu_physical_memory_unmap(dest_p, 1, len, len);
-}
-
-static void mvc_fast_memmove(CPUS390XState *env, uint32_t l, uint64_t dest,
- uint64_t src)
-{
- target_phys_addr_t dest_phys;
- target_phys_addr_t src_phys;
- target_phys_addr_t len = l;
- void *dest_p;
- void *src_p;
- uint64_t asc = env->psw.mask & PSW_MASK_ASC;
- int flags;
-
- if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) {
- stb(dest, 0);
- cpu_abort(env, "should never reach here");
- }
- dest_phys |= dest & ~TARGET_PAGE_MASK;
-
- if (mmu_translate(env, src, 0, asc, &src_phys, &flags)) {
- ldub(src);
- cpu_abort(env, "should never reach here");
- }
- src_phys |= src & ~TARGET_PAGE_MASK;
-
- dest_p = cpu_physical_memory_map(dest_phys, &len, 1);
- src_p = cpu_physical_memory_map(src_phys, &len, 0);
-
- memmove(dest_p, src_p, len);
-
- cpu_physical_memory_unmap(dest_p, 1, len, len);
- cpu_physical_memory_unmap(src_p, 0, len, len);
-}
-#endif
-
-/* and on array */
-uint32_t HELPER(nc)(uint32_t l, uint64_t dest, uint64_t src)
-{
- int i;
- unsigned char x;
- uint32_t cc = 0;
-
- HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
- __func__, l, dest, src);
- for (i = 0; i <= l; i++) {
- x = ldub(dest + i) & ldub(src + i);
- if (x) {
- cc = 1;
- }
- stb(dest + i, x);
- }
- return cc;
-}
-
-/* xor on array */
-uint32_t HELPER(xc)(uint32_t l, uint64_t dest, uint64_t src)
-{
- int i;
- unsigned char x;
- uint32_t cc = 0;
-
- HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
- __func__, l, dest, src);
-
-#ifndef CONFIG_USER_ONLY
- /* xor with itself is the same as memset(0) */
- if ((l > 32) && (src == dest) &&
- (src & TARGET_PAGE_MASK) == ((src + l) & TARGET_PAGE_MASK)) {
- mvc_fast_memset(env, l + 1, dest, 0);
- return 0;
- }
-#else
- if (src == dest) {
- memset(g2h(dest), 0, l + 1);
- return 0;
- }
-#endif
-
- for (i = 0; i <= l; i++) {
- x = ldub(dest + i) ^ ldub(src + i);
- if (x) {
- cc = 1;
- }
- stb(dest + i, x);
- }
- return cc;
-}
-
-/* or on array */
-uint32_t HELPER(oc)(uint32_t l, uint64_t dest, uint64_t src)
-{
- int i;
- unsigned char x;
- uint32_t cc = 0;
-
- HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
- __func__, l, dest, src);
- for (i = 0; i <= l; i++) {
- x = ldub(dest + i) | ldub(src + i);
- if (x) {
- cc = 1;
- }
- stb(dest + i, x);
- }
- return cc;
-}
-
-/* memmove */
-void HELPER(mvc)(uint32_t l, uint64_t dest, uint64_t src)
-{
- int i = 0;
- int x = 0;
- uint32_t l_64 = (l + 1) / 8;
-
- HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
- __func__, l, dest, src);
-
-#ifndef CONFIG_USER_ONLY
- if ((l > 32) &&
- (src & TARGET_PAGE_MASK) == ((src + l) & TARGET_PAGE_MASK) &&
- (dest & TARGET_PAGE_MASK) == ((dest + l) & TARGET_PAGE_MASK)) {
- if (dest == (src + 1)) {
- mvc_fast_memset(env, l + 1, dest, ldub(src));
- return;
- } else if ((src & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) {
- mvc_fast_memmove(env, l + 1, dest, src);
- return;
- }
- }
-#else
- if (dest == (src + 1)) {
- memset(g2h(dest), ldub(src), l + 1);
- return;
- } else {
- memmove(g2h(dest), g2h(src), l + 1);
- return;
- }
-#endif
-
- /* handle the parts that fit into 8-byte loads/stores */
- if (dest != (src + 1)) {
- for (i = 0; i < l_64; i++) {
- stq(dest + x, ldq(src + x));
- x += 8;
- }
- }
-
- /* slow version crossing pages with byte accesses */
- for (i = x; i <= l; i++) {
- stb(dest + i, ldub(src + i));
- }
-}
-
-/* compare unsigned byte arrays */
-uint32_t HELPER(clc)(uint32_t l, uint64_t s1, uint64_t s2)
-{
- int i;
- unsigned char x, y;
- uint32_t cc;
-
- HELPER_LOG("%s l %d s1 %" PRIx64 " s2 %" PRIx64 "\n",
- __func__, l, s1, s2);
- for (i = 0; i <= l; i++) {
- x = ldub(s1 + i);
- y = ldub(s2 + i);
- HELPER_LOG("%02x (%c)/%02x (%c) ", x, x, y, y);
- if (x < y) {
- cc = 1;
- goto done;
- } else if (x > y) {
- cc = 2;
- goto done;
- }
- }
- cc = 0;
- done:
- HELPER_LOG("\n");
- return cc;
-}
-
-/* compare logical under mask */
-uint32_t HELPER(clm)(uint32_t r1, uint32_t mask, uint64_t addr)
-{
- uint8_t r, d;
- uint32_t cc;
-
- HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%" PRIx64 "\n", __func__, r1,
- mask, addr);
- cc = 0;
- while (mask) {
- if (mask & 8) {
- d = ldub(addr);
- r = (r1 & 0xff000000UL) >> 24;
- HELPER_LOG("mask 0x%x %02x/%02x (0x%" PRIx64 ") ", mask, r, d,
- addr);
- if (r < d) {
- cc = 1;
- break;
- } else if (r > d) {
- cc = 2;
- break;
- }
- addr++;
- }
- mask = (mask << 1) & 0xf;
- r1 <<= 8;
- }
- HELPER_LOG("\n");
- return cc;
-}
-
-/* store character under mask */
-void HELPER(stcm)(uint32_t r1, uint32_t mask, uint64_t addr)
-{
- uint8_t r;
-
- HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%lx\n", __func__, r1, mask,
- addr);
- while (mask) {
- if (mask & 8) {
- r = (r1 & 0xff000000UL) >> 24;
- stb(addr, r);
- HELPER_LOG("mask 0x%x %02x (0x%lx) ", mask, r, addr);
- addr++;
- }
- mask = (mask << 1) & 0xf;
- r1 <<= 8;
- }
- HELPER_LOG("\n");
-}
-
-static inline uint64_t get_address(int x2, int b2, int d2)
-{
- uint64_t r = d2;
-
- if (x2) {
- r += env->regs[x2];
- }
-
- if (b2) {
- r += env->regs[b2];
- }
-
- /* 31-Bit mode */
- if (!(env->psw.mask & PSW_MASK_64)) {
- r &= 0x7fffffff;
- }
-
- return r;
-}
-
-static inline uint64_t get_address_31fix(int reg)
-{
- uint64_t r = env->regs[reg];
-
- /* 31-Bit mode */
- if (!(env->psw.mask & PSW_MASK_64)) {
- r &= 0x7fffffff;
- }
-
- return r;
-}
-
-/* search string (c is byte to search, r2 is string, r1 end of string) */
-uint32_t HELPER(srst)(uint32_t c, uint32_t r1, uint32_t r2)
-{
- uint64_t i;
- uint32_t cc = 2;
- uint64_t str = get_address_31fix(r2);
- uint64_t end = get_address_31fix(r1);
-
- HELPER_LOG("%s: c %d *r1 0x%" PRIx64 " *r2 0x%" PRIx64 "\n", __func__,
- c, env->regs[r1], env->regs[r2]);
-
- for (i = str; i != end; i++) {
- if (ldub(i) == c) {
- env->regs[r1] = i;
- cc = 1;
- break;
- }
- }
-
- return cc;
-}
-
-/* unsigned string compare (c is string terminator) */
-uint32_t HELPER(clst)(uint32_t c, uint32_t r1, uint32_t r2)
-{
- uint64_t s1 = get_address_31fix(r1);
- uint64_t s2 = get_address_31fix(r2);
- uint8_t v1, v2;
- uint32_t cc;
-
- c = c & 0xff;
-#ifdef CONFIG_USER_ONLY
- if (!c) {
- HELPER_LOG("%s: comparing '%s' and '%s'\n",
- __func__, (char *)g2h(s1), (char *)g2h(s2));
- }
-#endif
- for (;;) {
- v1 = ldub(s1);
- v2 = ldub(s2);
- if ((v1 == c || v2 == c) || (v1 != v2)) {
- break;
- }
- s1++;
- s2++;
- }
-
- if (v1 == v2) {
- cc = 0;
- } else {
- cc = (v1 < v2) ? 1 : 2;
- /* FIXME: 31-bit mode! */
- env->regs[r1] = s1;
- env->regs[r2] = s2;
- }
- return cc;
-}
-
-/* move page */
-void HELPER(mvpg)(uint64_t r0, uint64_t r1, uint64_t r2)
-{
- /* XXX missing r0 handling */
-#ifdef CONFIG_USER_ONLY
- int i;
-
- for (i = 0; i < TARGET_PAGE_SIZE; i++) {
- stb(r1 + i, ldub(r2 + i));
- }
-#else
- mvc_fast_memmove(env, TARGET_PAGE_SIZE, r1, r2);
-#endif
-}
-
-/* string copy (c is string terminator) */
-void HELPER(mvst)(uint32_t c, uint32_t r1, uint32_t r2)
-{
- uint64_t dest = get_address_31fix(r1);
- uint64_t src = get_address_31fix(r2);
- uint8_t v;
-
- c = c & 0xff;
-#ifdef CONFIG_USER_ONLY
- if (!c) {
- HELPER_LOG("%s: copy '%s' to 0x%lx\n", __func__, (char *)g2h(src),
- dest);
- }
-#endif
- for (;;) {
- v = ldub(src);
- stb(dest, v);
- if (v == c) {
- break;
- }
- src++;
- dest++;
- }
- env->regs[r1] = dest; /* FIXME: 31-bit mode! */
-}
-
-/* compare and swap 64-bit */
-uint32_t HELPER(csg)(uint32_t r1, uint64_t a2, uint32_t r3)
-{
- /* FIXME: locking? */
- uint32_t cc;
- uint64_t v2 = ldq(a2);
-
- if (env->regs[r1] == v2) {
- cc = 0;
- stq(a2, env->regs[r3]);
- } else {
- cc = 1;
- env->regs[r1] = v2;
- }
- return cc;
-}
-
-/* compare double and swap 64-bit */
-uint32_t HELPER(cdsg)(uint32_t r1, uint64_t a2, uint32_t r3)
-{
- /* FIXME: locking? */
- uint32_t cc;
- uint64_t v2_hi = ldq(a2);
- uint64_t v2_lo = ldq(a2 + 8);
- uint64_t v1_hi = env->regs[r1];
- uint64_t v1_lo = env->regs[r1 + 1];
-
- if ((v1_hi == v2_hi) && (v1_lo == v2_lo)) {
- cc = 0;
- stq(a2, env->regs[r3]);
- stq(a2 + 8, env->regs[r3 + 1]);
- } else {
- cc = 1;
- env->regs[r1] = v2_hi;
- env->regs[r1 + 1] = v2_lo;
- }
-
- return cc;
-}
-
-/* compare and swap 32-bit */
-uint32_t HELPER(cs)(uint32_t r1, uint64_t a2, uint32_t r3)
-{
- /* FIXME: locking? */
- uint32_t cc;
- uint32_t v2 = ldl(a2);
-
- HELPER_LOG("%s: r1 %d a2 0x%lx r3 %d\n", __func__, r1, a2, r3);
- if (((uint32_t)env->regs[r1]) == v2) {
- cc = 0;
- stl(a2, (uint32_t)env->regs[r3]);
- } else {
- cc = 1;
- env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | v2;
- }
- return cc;
-}
-
-static uint32_t helper_icm(uint32_t r1, uint64_t address, uint32_t mask)
-{
- int pos = 24; /* top of the lower half of r1 */
- uint64_t rmask = 0xff000000ULL;
- uint8_t val = 0;
- int ccd = 0;
- uint32_t cc = 0;
-
- while (mask) {
- if (mask & 8) {
- env->regs[r1] &= ~rmask;
- val = ldub(address);
- if ((val & 0x80) && !ccd) {
- cc = 1;
- }
- ccd = 1;
- if (val && cc == 0) {
- cc = 2;
- }
- env->regs[r1] |= (uint64_t)val << pos;
- address++;
- }
- mask = (mask << 1) & 0xf;
- pos -= 8;
- rmask >>= 8;
- }
-
- return cc;
-}
-
-/* execute instruction
- this instruction executes an insn modified with the contents of r1
- it does not change the executed instruction in memory
- it does not change the program counter
- in other words: tricky...
- currently implemented by interpreting the cases it is most commonly used in
-*/
-uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
-{
- uint16_t insn = lduw_code(addr);
-
- HELPER_LOG("%s: v1 0x%lx addr 0x%lx insn 0x%x\n", __func__, v1, addr,
- insn);
- if ((insn & 0xf0ff) == 0xd000) {
- uint32_t l, insn2, b1, b2, d1, d2;
-
- l = v1 & 0xff;
- insn2 = ldl_code(addr + 2);
- b1 = (insn2 >> 28) & 0xf;
- b2 = (insn2 >> 12) & 0xf;
- d1 = (insn2 >> 16) & 0xfff;
- d2 = insn2 & 0xfff;
- switch (insn & 0xf00) {
- case 0x200:
- helper_mvc(l, get_address(0, b1, d1), get_address(0, b2, d2));
- break;
- case 0x500:
- cc = helper_clc(l, get_address(0, b1, d1), get_address(0, b2, d2));
- break;
- case 0x700:
- cc = helper_xc(l, get_address(0, b1, d1), get_address(0, b2, d2));
- break;
- case 0xc00:
- helper_tr(l, get_address(0, b1, d1), get_address(0, b2, d2));
- break;
- default:
- goto abort;
- break;
- }
- } else if ((insn & 0xff00) == 0x0a00) {
- /* supervisor call */
- HELPER_LOG("%s: svc %ld via execute\n", __func__, (insn | v1) & 0xff);
- env->psw.addr = ret - 4;
- env->int_svc_code = (insn | v1) & 0xff;
- env->int_svc_ilc = 4;
- helper_exception(EXCP_SVC);
- } else if ((insn & 0xff00) == 0xbf00) {
- uint32_t insn2, r1, r3, b2, d2;
-
- insn2 = ldl_code(addr + 2);
- r1 = (insn2 >> 20) & 0xf;
- r3 = (insn2 >> 16) & 0xf;
- b2 = (insn2 >> 12) & 0xf;
- d2 = insn2 & 0xfff;
- cc = helper_icm(r1, get_address(0, b2, d2), r3);
- } else {
- abort:
- cpu_abort(env, "EXECUTE on instruction prefix 0x%x not implemented\n",
- insn);
- }
- return cc;
-}
-
-/* store character under mask high operates on the upper half of r1 */
-void HELPER(stcmh)(uint32_t r1, uint64_t address, uint32_t mask)
-{
- int pos = 56; /* top of the upper half of r1 */
-
- while (mask) {
- if (mask & 8) {
- stb(address, (env->regs[r1] >> pos) & 0xff);
- address++;
- }
- mask = (mask << 1) & 0xf;
- pos -= 8;
- }
-}
-
-/* insert character under mask high; same as icm, but operates on the
- upper half of r1 */
-uint32_t HELPER(icmh)(uint32_t r1, uint64_t address, uint32_t mask)
-{
- int pos = 56; /* top of the upper half of r1 */
- uint64_t rmask = 0xff00000000000000ULL;
- uint8_t val = 0;
- int ccd = 0;
- uint32_t cc = 0;
-
- while (mask) {
- if (mask & 8) {
- env->regs[r1] &= ~rmask;
- val = ldub(address);
- if ((val & 0x80) && !ccd) {
- cc = 1;
- }
- ccd = 1;
- if (val && cc == 0) {
- cc = 2;
- }
- env->regs[r1] |= (uint64_t)val << pos;
- address++;
- }
- mask = (mask << 1) & 0xf;
- pos -= 8;
- rmask >>= 8;
- }
-
- return cc;
-}
-
-/* load access registers r1 to r3 from memory at a2 */
-void HELPER(lam)(uint32_t r1, uint64_t a2, uint32_t r3)
-{
- int i;
-
- for (i = r1;; i = (i + 1) % 16) {
- env->aregs[i] = ldl(a2);
- a2 += 4;
-
- if (i == r3) {
- break;
- }
- }
-}
-
-/* store access registers r1 to r3 in memory at a2 */
-void HELPER(stam)(uint32_t r1, uint64_t a2, uint32_t r3)
-{
- int i;
-
- for (i = r1;; i = (i + 1) % 16) {
- stl(a2, env->aregs[i]);
- a2 += 4;
-
- if (i == r3) {
- break;
- }
- }
-}
-
-/* move long */
-uint32_t HELPER(mvcl)(uint32_t r1, uint32_t r2)
-{
- uint64_t destlen = env->regs[r1 + 1] & 0xffffff;
- uint64_t dest = get_address_31fix(r1);
- uint64_t srclen = env->regs[r2 + 1] & 0xffffff;
- uint64_t src = get_address_31fix(r2);
- uint8_t pad = src >> 24;
- uint8_t v;
- uint32_t cc;
-
- if (destlen == srclen) {
- cc = 0;
- } else if (destlen < srclen) {
- cc = 1;
- } else {
- cc = 2;
- }
-
- if (srclen > destlen) {
- srclen = destlen;
- }
-
- for (; destlen && srclen; src++, dest++, destlen--, srclen--) {
- v = ldub(src);
- stb(dest, v);
- }
-
- for (; destlen; dest++, destlen--) {
- stb(dest, pad);
- }
-
- env->regs[r1 + 1] = destlen;
- /* can't use srclen here, we trunc'ed it */
- env->regs[r2 + 1] -= src - env->regs[r2];
- env->regs[r1] = dest;
- env->regs[r2] = src;
-
- return cc;
-}
-
-/* move long extended another memcopy insn with more bells and whistles */
-uint32_t HELPER(mvcle)(uint32_t r1, uint64_t a2, uint32_t r3)
-{
- uint64_t destlen = env->regs[r1 + 1];
- uint64_t dest = env->regs[r1];
- uint64_t srclen = env->regs[r3 + 1];
- uint64_t src = env->regs[r3];
- uint8_t pad = a2 & 0xff;
- uint8_t v;
- uint32_t cc;
-
- if (!(env->psw.mask & PSW_MASK_64)) {
- destlen = (uint32_t)destlen;
- srclen = (uint32_t)srclen;
- dest &= 0x7fffffff;
- src &= 0x7fffffff;
- }
-
- if (destlen == srclen) {
- cc = 0;
- } else if (destlen < srclen) {
- cc = 1;
- } else {
- cc = 2;
- }
-
- if (srclen > destlen) {
- srclen = destlen;
- }
-
- for (; destlen && srclen; src++, dest++, destlen--, srclen--) {
- v = ldub(src);
- stb(dest, v);
- }
-
- for (; destlen; dest++, destlen--) {
- stb(dest, pad);
- }
-
- env->regs[r1 + 1] = destlen;
- /* can't use srclen here, we trunc'ed it */
- /* FIXME: 31-bit mode! */
- env->regs[r3 + 1] -= src - env->regs[r3];
- env->regs[r1] = dest;
- env->regs[r3] = src;
-
- return cc;
-}
-
-/* compare logical long extended memcompare insn with padding */
-uint32_t HELPER(clcle)(uint32_t r1, uint64_t a2, uint32_t r3)
-{
- uint64_t destlen = env->regs[r1 + 1];
- uint64_t dest = get_address_31fix(r1);
- uint64_t srclen = env->regs[r3 + 1];
- uint64_t src = get_address_31fix(r3);
- uint8_t pad = a2 & 0xff;
- uint8_t v1 = 0, v2 = 0;
- uint32_t cc = 0;
-
- if (!(destlen || srclen)) {
- return cc;
- }
-
- if (srclen > destlen) {
- srclen = destlen;
- }
-
- for (; destlen || srclen; src++, dest++, destlen--, srclen--) {
- v1 = srclen ? ldub(src) : pad;
- v2 = destlen ? ldub(dest) : pad;
- if (v1 != v2) {
- cc = (v1 < v2) ? 1 : 2;
- break;
- }
- }
-
- env->regs[r1 + 1] = destlen;
- /* can't use srclen here, we trunc'ed it */
- env->regs[r3 + 1] -= src - env->regs[r3];
- env->regs[r1] = dest;
- env->regs[r3] = src;
-
- return cc;
-}
-
-/* checksum */
-void HELPER(cksm)(uint32_t r1, uint32_t r2)
-{
- uint64_t src = get_address_31fix(r2);
- uint64_t src_len = env->regs[(r2 + 1) & 15];
- uint64_t cksm = (uint32_t)env->regs[r1];
-
- while (src_len >= 4) {
- cksm += ldl(src);
-
- /* move to next word */
- src_len -= 4;
- src += 4;
- }
-
- switch (src_len) {
- case 0:
- break;
- case 1:
- cksm += ldub(src) << 24;
- break;
- case 2:
- cksm += lduw(src) << 16;
- break;
- case 3:
- cksm += lduw(src) << 16;
- cksm += ldub(src + 2) << 8;
- break;
- }
-
- /* indicate we've processed everything */
- env->regs[r2] = src + src_len;
- env->regs[(r2 + 1) & 15] = 0;
-
- /* store result */
- env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
- ((uint32_t)cksm + (cksm >> 32));
-}
-
-void HELPER(unpk)(uint32_t len, uint64_t dest, uint64_t src)
-{
- int len_dest = len >> 4;
- int len_src = len & 0xf;
- uint8_t b;
- int second_nibble = 0;
-
- dest += len_dest;
- src += len_src;
-
- /* last byte is special, it only flips the nibbles */
- b = ldub(src);
- stb(dest, (b << 4) | (b >> 4));
- src--;
- len_src--;
-
- /* now pad every nibble with 0xf0 */
-
- while (len_dest > 0) {
- uint8_t cur_byte = 0;
-
- if (len_src > 0) {
- cur_byte = ldub(src);
- }
-
- len_dest--;
- dest--;
-
- /* only advance one nibble at a time */
- if (second_nibble) {
- cur_byte >>= 4;
- len_src--;
- src--;
- }
- second_nibble = !second_nibble;
-
- /* digit */
- cur_byte = (cur_byte & 0xf);
- /* zone bits */
- cur_byte |= 0xf0;
-
- stb(dest, cur_byte);
- }
-}
-
-void HELPER(tr)(uint32_t len, uint64_t array, uint64_t trans)
-{
- int i;
-
- for (i = 0; i <= len; i++) {
- uint8_t byte = ldub(array + i);
- uint8_t new_byte = ldub(trans + byte);
-
- stb(array + i, new_byte);
- }
-}
-
-#ifndef CONFIG_USER_ONLY
void program_interrupt(CPUS390XState *env, uint32_t code, int ilc)
{
qemu_log("program interrupt at %#" PRIx64 "\n", env->psw.addr);
@@ -1267,206 +384,6 @@ uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1)
return cc;
}
-void HELPER(lctlg)(uint32_t r1, uint64_t a2, uint32_t r3)
-{
- int i;
- uint64_t src = a2;
-
- for (i = r1;; i = (i + 1) % 16) {
- env->cregs[i] = ldq(src);
- HELPER_LOG("load ctl %d from 0x%" PRIx64 " == 0x%" PRIx64 "\n",
- i, src, env->cregs[i]);
- src += sizeof(uint64_t);
-
- if (i == r3) {
- break;
- }
- }
-
- tlb_flush(env, 1);
-}
-
-void HELPER(lctl)(uint32_t r1, uint64_t a2, uint32_t r3)
-{
- int i;
- uint64_t src = a2;
-
- for (i = r1;; i = (i + 1) % 16) {
- env->cregs[i] = (env->cregs[i] & 0xFFFFFFFF00000000ULL) | ldl(src);
- src += sizeof(uint32_t);
-
- if (i == r3) {
- break;
- }
- }
-
- tlb_flush(env, 1);
-}
-
-void HELPER(stctg)(uint32_t r1, uint64_t a2, uint32_t r3)
-{
- int i;
- uint64_t dest = a2;
-
- for (i = r1;; i = (i + 1) % 16) {
- stq(dest, env->cregs[i]);
- dest += sizeof(uint64_t);
-
- if (i == r3) {
- break;
- }
- }
-}
-
-void HELPER(stctl)(uint32_t r1, uint64_t a2, uint32_t r3)
-{
- int i;
- uint64_t dest = a2;
-
- for (i = r1;; i = (i + 1) % 16) {
- stl(dest, env->cregs[i]);
- dest += sizeof(uint32_t);
-
- if (i == r3) {
- break;
- }
- }
-}
-
-uint32_t HELPER(tprot)(uint64_t a1, uint64_t a2)
-{
- /* XXX implement */
-
- return 0;
-}
-
-/* insert storage key extended */
-uint64_t HELPER(iske)(uint64_t r2)
-{
- uint64_t addr = get_address(0, 0, r2);
-
- if (addr > ram_size) {
- return 0;
- }
-
- return env->storage_keys[addr / TARGET_PAGE_SIZE];
-}
-
-/* set storage key extended */
-void HELPER(sske)(uint32_t r1, uint64_t r2)
-{
- uint64_t addr = get_address(0, 0, r2);
-
- if (addr > ram_size) {
- return;
- }
-
- env->storage_keys[addr / TARGET_PAGE_SIZE] = r1;
-}
-
-/* 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;
- }
-
- 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
- *
- * 0 Reference bit zero; change bit zero
- * 1 Reference bit zero; change bit one
- * 2 Reference bit one; change bit zero
- * 3 Reference bit one; change bit one
- */
-
- return re >> 1;
-}
-
-/* compare and swap and purge */
-uint32_t HELPER(csp)(uint32_t r1, uint32_t r2)
-{
- uint32_t cc;
- uint32_t o1 = env->regs[r1];
- uint64_t a2 = get_address_31fix(r2) & ~3ULL;
- uint32_t o2 = ldl(a2);
-
- if (o1 == o2) {
- stl(a2, env->regs[(r1 + 1) & 15]);
- if (env->regs[r2] & 0x3) {
- /* flush TLB / ALB */
- tlb_flush(env, 1);
- }
- cc = 0;
- } else {
- env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | o2;
- cc = 1;
- }
-
- return cc;
-}
-
-static uint32_t mvc_asc(int64_t l, uint64_t a1, uint64_t mode1, uint64_t a2,
- uint64_t mode2)
-{
- target_ulong src, dest;
- int flags, cc = 0, i;
-
- if (!l) {
- return 0;
- } else if (l > 256) {
- /* max 256 */
- l = 256;
- cc = 3;
- }
-
- if (mmu_translate(env, a1 & TARGET_PAGE_MASK, 1, mode1, &dest, &flags)) {
- cpu_loop_exit(env);
- }
- dest |= a1 & ~TARGET_PAGE_MASK;
-
- if (mmu_translate(env, a2 & TARGET_PAGE_MASK, 0, mode2, &src, &flags)) {
- cpu_loop_exit(env);
- }
- src |= a2 & ~TARGET_PAGE_MASK;
-
- /* XXX replace w/ memcpy */
- for (i = 0; i < l; i++) {
- /* XXX be more clever */
- if ((((dest + i) & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) ||
- (((src + i) & TARGET_PAGE_MASK) != (src & TARGET_PAGE_MASK))) {
- mvc_asc(l - i, a1 + i, mode1, a2 + i, mode2);
- break;
- }
- stb_phys(dest + i, ldub_phys(src + i));
- }
-
- return cc;
-}
-
-uint32_t HELPER(mvcs)(uint64_t l, uint64_t a1, uint64_t a2)
-{
- HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
- __func__, l, a1, a2);
-
- return mvc_asc(l, a1, PSW_ASC_SECONDARY, a2, PSW_ASC_PRIMARY);
-}
-
-uint32_t HELPER(mvcp)(uint64_t l, uint64_t a1, uint64_t a2)
-{
- HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
- __func__, l, a1, a2);
-
- return mvc_asc(l, a1, PSW_ASC_PRIMARY, a2, PSW_ASC_SECONDARY);
-}
-
uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
{
int cc = 0;
@@ -1508,78 +425,4 @@ uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
return cc;
}
-
-/* invalidate pte */
-void HELPER(ipte)(uint64_t pte_addr, uint64_t vaddr)
-{
- uint64_t page = vaddr & TARGET_PAGE_MASK;
- uint64_t pte = 0;
-
- /* XXX broadcast to other CPUs */
-
- /* XXX Linux is nice enough to give us the exact pte address.
- According to spec we'd have to find it out ourselves */
- /* XXX Linux is fine with overwriting the pte, the spec requires
- us to only set the invalid bit */
- stq_phys(pte_addr, pte | _PAGE_INVALID);
-
- /* 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 */
-void HELPER(ptlb)(void)
-{
- tlb_flush(env, 1);
-}
-
-/* store using real address */
-void HELPER(stura)(uint64_t addr, uint32_t v1)
-{
- stw_phys(get_address(0, 0, addr), v1);
-}
-
-/* load real address */
-uint32_t HELPER(lra)(uint64_t addr, uint32_t r1)
-{
- uint32_t cc = 0;
- int old_exc = env->exception_index;
- uint64_t asc = env->psw.mask & PSW_MASK_ASC;
- uint64_t ret;
- int flags;
-
- /* XXX incomplete - has more corner cases */
- if (!(env->psw.mask & PSW_MASK_64) && (addr >> 32)) {
- program_interrupt(env, PGM_SPECIAL_OP, 2);
- }
-
- env->exception_index = old_exc;
- if (mmu_translate(env, addr, 0, asc, &ret, &flags)) {
- cc = 3;
- }
- if (env->exception_index == EXCP_PGM) {
- ret = env->int_pgm_code | 0x80000000;
- } else {
- ret |= addr & ~TARGET_PAGE_MASK;
- }
- env->exception_index = old_exc;
-
- if (!(env->psw.mask & PSW_MASK_64)) {
- env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
- (ret & 0xffffffffULL);
- } else {
- env->regs[r1] = ret;
- }
-
- return cc;
-}
-
#endif
--
1.6.0.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 06/12] target-s390x: rename op_helper.c to misc_helper.c
2012-09-10 11:40 [Qemu-devel] [PULL 00/12] s390 patch queue 2012-09-10 Alexander Graf
` (4 preceding siblings ...)
2012-09-10 11:40 ` [Qemu-devel] [PATCH 05/12] target-s390x: split memory access helpers Alexander Graf
@ 2012-09-10 11:40 ` Alexander Graf
2012-09-10 11:40 ` [Qemu-devel] [PATCH 07/12] target-s390x: avoid AREG0 for FPU helpers Alexander Graf
` (6 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Alexander Graf @ 2012-09-10 11:40 UTC (permalink / raw)
To: qemu-devel qemu-devel; +Cc: Blue Swirl, Aurelien Jarno
From: Blue Swirl <blauwirbel@gmail.com>
Now op_helper.c contains miscellaneous helpers, rename
it to misc_helper.c.
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
[agraf: fix conflict]
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-s390x/Makefile.objs | 6 +++---
target-s390x/cpu.h | 2 +-
target-s390x/{op_helper.c => misc_helper.c} | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
rename target-s390x/{op_helper.c => misc_helper.c} (99%)
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index b9b3061..a87d26f 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -1,10 +1,10 @@
-obj-y += translate.o op_helper.o helper.o cpu.o interrupt.o
-obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o
+obj-y += translate.o helper.o cpu.o interrupt.o
+obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
obj-$(CONFIG_SOFTMMU) += machine.o
obj-$(CONFIG_KVM) += kvm.o
-$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
$(obj)/int_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
$(obj)/fpu_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
$(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
$(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+$(obj)/misc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 97fde5e..0ccb551 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -1005,7 +1005,7 @@ uint32_t set_cc_f64(float64 v1, float64 v2);
uint32_t set_cc_nz_f32(float32 v);
uint32_t set_cc_nz_f64(float64 v);
-/* op_helper.c */
+/* misc_helper.c */
void program_interrupt(CPUS390XState *env, uint32_t code, int ilc);
#endif
diff --git a/target-s390x/op_helper.c b/target-s390x/misc_helper.c
similarity index 99%
rename from target-s390x/op_helper.c
rename to target-s390x/misc_helper.c
index bb8dbf5..1d5137f 100644
--- a/target-s390x/op_helper.c
+++ b/target-s390x/misc_helper.c
@@ -1,5 +1,5 @@
/*
- * S/390 helper routines
+ * S/390 misc helper routines
*
* Copyright (c) 2009 Ulrich Hecht
* Copyright (c) 2009 Alexander Graf
--
1.6.0.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 07/12] target-s390x: avoid AREG0 for FPU helpers
2012-09-10 11:40 [Qemu-devel] [PULL 00/12] s390 patch queue 2012-09-10 Alexander Graf
` (5 preceding siblings ...)
2012-09-10 11:40 ` [Qemu-devel] [PATCH 06/12] target-s390x: rename op_helper.c to misc_helper.c Alexander Graf
@ 2012-09-10 11:40 ` Alexander Graf
2012-09-10 11:40 ` [Qemu-devel] [PATCH 08/12] target-s390x: avoid AREG0 for integer helpers Alexander Graf
` (5 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Alexander Graf @ 2012-09-10 11:40 UTC (permalink / raw)
To: qemu-devel qemu-devel; +Cc: Blue Swirl, Aurelien Jarno
From: Blue Swirl <blauwirbel@gmail.com>
Make FPU helpers take a parameter for CPUState instead
of relying on global env.
Introduce temporary wrappers for FPU load and store ops.
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-s390x/Makefile.objs | 1 -
target-s390x/cc_helper.c | 4 +-
target-s390x/cpu.h | 14 +++-
target-s390x/fpu_helper.c | 184 +++++++++++++++++++++++---------------------
target-s390x/helper.h | 126 +++++++++++++++---------------
target-s390x/mem_helper.c | 49 ++++++++++++
target-s390x/translate.c | 70 ++++++++--------
7 files changed, 257 insertions(+), 191 deletions(-)
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index a87d26f..7d965e9 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -4,7 +4,6 @@ obj-$(CONFIG_SOFTMMU) += machine.o
obj-$(CONFIG_KVM) += kvm.o
$(obj)/int_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
-$(obj)/fpu_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
$(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
$(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
$(obj)/misc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
diff --git a/target-s390x/cc_helper.c b/target-s390x/cc_helper.c
index 2ac1659..9c3a2c4 100644
--- a/target-s390x/cc_helper.c
+++ b/target-s390x/cc_helper.c
@@ -473,10 +473,10 @@ static inline uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op,
break;
case CC_OP_LTGT_F32:
- r = set_cc_f32(src, dst);
+ r = set_cc_f32(env, src, dst);
break;
case CC_OP_LTGT_F64:
- r = set_cc_f64(src, dst);
+ r = set_cc_f64(env, src, dst);
break;
case CC_OP_NZ_F32:
r = set_cc_nz_f32(dst);
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 0ccb551..9b7a2e3 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -1000,12 +1000,22 @@ static inline void cpu_pc_from_tb(CPUS390XState *env, TranslationBlock* tb)
}
/* fpu_helper.c */
-uint32_t set_cc_f32(float32 v1, float32 v2);
-uint32_t set_cc_f64(float64 v1, float64 v2);
+uint32_t set_cc_f32(CPUS390XState *env, float32 v1, float32 v2);
+uint32_t set_cc_f64(CPUS390XState *env, float64 v1, float64 v2);
uint32_t set_cc_nz_f32(float32 v);
uint32_t set_cc_nz_f64(float64 v);
/* misc_helper.c */
void program_interrupt(CPUS390XState *env, uint32_t code, int ilc);
+/* temporary wrappers */
+uint32_t cpu_ldub_data(CPUS390XState *env, target_ulong ptr);
+uint32_t cpu_lduw_data(CPUS390XState *env, target_ulong ptr);
+uint32_t cpu_ldl_data(CPUS390XState *env, target_ulong ptr);
+uint64_t cpu_ldq_data(CPUS390XState *env, target_ulong ptr);
+
+void cpu_stb_data(CPUS390XState *env, target_ulong ptr, uint32_t data);
+void cpu_stw_data(CPUS390XState *env, target_ulong ptr, uint32_t data);
+void cpu_stl_data(CPUS390XState *env, target_ulong ptr, uint32_t data);
+void cpu_stq_data(CPUS390XState *env, target_ulong ptr, uint64_t data);
#endif
diff --git a/target-s390x/fpu_helper.c b/target-s390x/fpu_helper.c
index 1389052..e235419 100644
--- a/target-s390x/fpu_helper.c
+++ b/target-s390x/fpu_helper.c
@@ -19,10 +19,10 @@
*/
#include "cpu.h"
-#include "dyngen-exec.h"
#include "helper.h"
-#if !defined(CONFIG_USER_ONLY)
+/* temporarily disabled due to wrapper use */
+#if 0 && !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
#endif
@@ -33,7 +33,7 @@
#define HELPER_LOG(x...)
#endif
-static inline int float_comp_to_cc(int float_compare)
+static inline int float_comp_to_cc(CPUS390XState *env, int float_compare)
{
switch (float_compare) {
case float_relation_equal:
@@ -50,14 +50,16 @@ static inline int float_comp_to_cc(int float_compare)
}
/* condition codes for binary FP ops */
-uint32_t set_cc_f32(float32 v1, float32 v2)
+uint32_t set_cc_f32(CPUS390XState *env, float32 v1, float32 v2)
{
- return float_comp_to_cc(float32_compare_quiet(v1, v2, &env->fpu_status));
+ return float_comp_to_cc(env, float32_compare_quiet(v1, v2,
+ &env->fpu_status));
}
-uint32_t set_cc_f64(float64 v1, float64 v2)
+uint32_t set_cc_f64(CPUS390XState *env, float64 v1, float64 v2)
{
- return float_comp_to_cc(float64_compare_quiet(v1, v2, &env->fpu_status));
+ return float_comp_to_cc(env, float64_compare_quiet(v1, v2,
+ &env->fpu_status));
}
/* condition codes for unary FP ops */
@@ -101,14 +103,14 @@ static uint32_t set_cc_nz_f128(float128 v)
}
/* convert 32-bit int to 64-bit float */
-void HELPER(cdfbr)(uint32_t f1, int32_t v2)
+void HELPER(cdfbr)(CPUS390XState *env, uint32_t f1, int32_t v2)
{
HELPER_LOG("%s: converting %d to f%d\n", __func__, v2, f1);
env->fregs[f1].d = int32_to_float64(v2, &env->fpu_status);
}
/* convert 32-bit int to 128-bit float */
-void HELPER(cxfbr)(uint32_t f1, int32_t v2)
+void HELPER(cxfbr)(CPUS390XState *env, uint32_t f1, int32_t v2)
{
CPU_QuadU v1;
@@ -118,21 +120,21 @@ void HELPER(cxfbr)(uint32_t f1, int32_t v2)
}
/* convert 64-bit int to 32-bit float */
-void HELPER(cegbr)(uint32_t f1, int64_t v2)
+void HELPER(cegbr)(CPUS390XState *env, uint32_t f1, int64_t v2)
{
HELPER_LOG("%s: converting %ld to f%d\n", __func__, v2, f1);
env->fregs[f1].l.upper = int64_to_float32(v2, &env->fpu_status);
}
/* convert 64-bit int to 64-bit float */
-void HELPER(cdgbr)(uint32_t f1, int64_t v2)
+void HELPER(cdgbr)(CPUS390XState *env, uint32_t f1, int64_t v2)
{
HELPER_LOG("%s: converting %ld to f%d\n", __func__, v2, f1);
env->fregs[f1].d = int64_to_float64(v2, &env->fpu_status);
}
/* convert 64-bit int to 128-bit float */
-void HELPER(cxgbr)(uint32_t f1, int64_t v2)
+void HELPER(cxgbr)(CPUS390XState *env, uint32_t f1, int64_t v2)
{
CPU_QuadU x1;
@@ -144,7 +146,7 @@ void HELPER(cxgbr)(uint32_t f1, int64_t v2)
}
/* convert 32-bit int to 32-bit float */
-void HELPER(cefbr)(uint32_t f1, int32_t v2)
+void HELPER(cefbr)(CPUS390XState *env, uint32_t f1, int32_t v2)
{
env->fregs[f1].l.upper = int32_to_float32(v2, &env->fpu_status);
HELPER_LOG("%s: converting %d to 0x%d in f%d\n", __func__, v2,
@@ -152,7 +154,7 @@ void HELPER(cefbr)(uint32_t f1, int32_t v2)
}
/* 32-bit FP addition RR */
-uint32_t HELPER(aebr)(uint32_t f1, uint32_t f2)
+uint32_t HELPER(aebr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper,
env->fregs[f2].l.upper,
@@ -164,7 +166,7 @@ uint32_t HELPER(aebr)(uint32_t f1, uint32_t f2)
}
/* 64-bit FP addition RR */
-uint32_t HELPER(adbr)(uint32_t f1, uint32_t f2)
+uint32_t HELPER(adbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
env->fregs[f1].d = float64_add(env->fregs[f1].d, env->fregs[f2].d,
&env->fpu_status);
@@ -175,7 +177,7 @@ uint32_t HELPER(adbr)(uint32_t f1, uint32_t f2)
}
/* 32-bit FP subtraction RR */
-uint32_t HELPER(sebr)(uint32_t f1, uint32_t f2)
+uint32_t HELPER(sebr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
env->fregs[f1].l.upper = float32_sub(env->fregs[f1].l.upper,
env->fregs[f2].l.upper,
@@ -187,7 +189,7 @@ uint32_t HELPER(sebr)(uint32_t f1, uint32_t f2)
}
/* 64-bit FP subtraction RR */
-uint32_t HELPER(sdbr)(uint32_t f1, uint32_t f2)
+uint32_t HELPER(sdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
env->fregs[f1].d = float64_sub(env->fregs[f1].d, env->fregs[f2].d,
&env->fpu_status);
@@ -198,7 +200,7 @@ uint32_t HELPER(sdbr)(uint32_t f1, uint32_t f2)
}
/* 32-bit FP division RR */
-void HELPER(debr)(uint32_t f1, uint32_t f2)
+void HELPER(debr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
env->fregs[f1].l.upper = float32_div(env->fregs[f1].l.upper,
env->fregs[f2].l.upper,
@@ -206,7 +208,7 @@ void HELPER(debr)(uint32_t f1, uint32_t f2)
}
/* 128-bit FP division RR */
-void HELPER(dxbr)(uint32_t f1, uint32_t f2)
+void HELPER(dxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
CPU_QuadU v1;
CPU_QuadU v2;
@@ -222,14 +224,14 @@ void HELPER(dxbr)(uint32_t f1, uint32_t f2)
}
/* 64-bit FP multiplication RR */
-void HELPER(mdbr)(uint32_t f1, uint32_t f2)
+void HELPER(mdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
env->fregs[f1].d = float64_mul(env->fregs[f1].d, env->fregs[f2].d,
&env->fpu_status);
}
/* 128-bit FP multiplication RR */
-void HELPER(mxbr)(uint32_t f1, uint32_t f2)
+void HELPER(mxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
CPU_QuadU v1;
CPU_QuadU v2;
@@ -245,14 +247,14 @@ void HELPER(mxbr)(uint32_t f1, uint32_t f2)
}
/* convert 32-bit float to 64-bit float */
-void HELPER(ldebr)(uint32_t r1, uint32_t r2)
+void HELPER(ldebr)(CPUS390XState *env, uint32_t r1, uint32_t r2)
{
env->fregs[r1].d = float32_to_float64(env->fregs[r2].l.upper,
&env->fpu_status);
}
/* convert 128-bit float to 64-bit float */
-void HELPER(ldxbr)(uint32_t f1, uint32_t f2)
+void HELPER(ldxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
CPU_QuadU x2;
@@ -263,7 +265,7 @@ void HELPER(ldxbr)(uint32_t f1, uint32_t f2)
}
/* convert 64-bit float to 128-bit float */
-void HELPER(lxdbr)(uint32_t f1, uint32_t f2)
+void HELPER(lxdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
CPU_QuadU res;
@@ -273,7 +275,7 @@ void HELPER(lxdbr)(uint32_t f1, uint32_t f2)
}
/* convert 64-bit float to 32-bit float */
-void HELPER(ledbr)(uint32_t f1, uint32_t f2)
+void HELPER(ledbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
float64 d2 = env->fregs[f2].d;
@@ -281,7 +283,7 @@ void HELPER(ledbr)(uint32_t f1, uint32_t f2)
}
/* convert 128-bit float to 32-bit float */
-void HELPER(lexbr)(uint32_t f1, uint32_t f2)
+void HELPER(lexbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
CPU_QuadU x2;
@@ -292,7 +294,7 @@ void HELPER(lexbr)(uint32_t f1, uint32_t f2)
}
/* absolute value of 32-bit float */
-uint32_t HELPER(lpebr)(uint32_t f1, uint32_t f2)
+uint32_t HELPER(lpebr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
float32 v1;
float32 v2 = env->fregs[f2].d;
@@ -303,7 +305,7 @@ uint32_t HELPER(lpebr)(uint32_t f1, uint32_t f2)
}
/* absolute value of 64-bit float */
-uint32_t HELPER(lpdbr)(uint32_t f1, uint32_t f2)
+uint32_t HELPER(lpdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
float64 v1;
float64 v2 = env->fregs[f2].d;
@@ -314,7 +316,7 @@ uint32_t HELPER(lpdbr)(uint32_t f1, uint32_t f2)
}
/* absolute value of 128-bit float */
-uint32_t HELPER(lpxbr)(uint32_t f1, uint32_t f2)
+uint32_t HELPER(lpxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
CPU_QuadU v1;
CPU_QuadU v2;
@@ -328,21 +330,21 @@ uint32_t HELPER(lpxbr)(uint32_t f1, uint32_t f2)
}
/* load and test 64-bit float */
-uint32_t HELPER(ltdbr)(uint32_t f1, uint32_t f2)
+uint32_t HELPER(ltdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
env->fregs[f1].d = env->fregs[f2].d;
return set_cc_nz_f64(env->fregs[f1].d);
}
/* load and test 32-bit float */
-uint32_t HELPER(ltebr)(uint32_t f1, uint32_t f2)
+uint32_t HELPER(ltebr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
env->fregs[f1].l.upper = env->fregs[f2].l.upper;
return set_cc_nz_f32(env->fregs[f1].l.upper);
}
/* load and test 128-bit float */
-uint32_t HELPER(ltxbr)(uint32_t f1, uint32_t f2)
+uint32_t HELPER(ltxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
CPU_QuadU x;
@@ -354,7 +356,7 @@ uint32_t HELPER(ltxbr)(uint32_t f1, uint32_t f2)
}
/* load complement of 32-bit float */
-uint32_t HELPER(lcebr)(uint32_t f1, uint32_t f2)
+uint32_t HELPER(lcebr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
env->fregs[f1].l.upper = float32_chs(env->fregs[f2].l.upper);
@@ -362,7 +364,7 @@ uint32_t HELPER(lcebr)(uint32_t f1, uint32_t f2)
}
/* load complement of 64-bit float */
-uint32_t HELPER(lcdbr)(uint32_t f1, uint32_t f2)
+uint32_t HELPER(lcdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
env->fregs[f1].d = float64_chs(env->fregs[f2].d);
@@ -370,7 +372,7 @@ uint32_t HELPER(lcdbr)(uint32_t f1, uint32_t f2)
}
/* load complement of 128-bit float */
-uint32_t HELPER(lcxbr)(uint32_t f1, uint32_t f2)
+uint32_t HELPER(lcxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
CPU_QuadU x1, x2;
@@ -383,7 +385,7 @@ uint32_t HELPER(lcxbr)(uint32_t f1, uint32_t f2)
}
/* 32-bit FP addition RM */
-void HELPER(aeb)(uint32_t f1, uint32_t val)
+void HELPER(aeb)(CPUS390XState *env, uint32_t f1, uint32_t val)
{
float32 v1 = env->fregs[f1].l.upper;
CPU_FloatU v2;
@@ -395,7 +397,7 @@ void HELPER(aeb)(uint32_t f1, uint32_t val)
}
/* 32-bit FP division RM */
-void HELPER(deb)(uint32_t f1, uint32_t val)
+void HELPER(deb)(CPUS390XState *env, uint32_t f1, uint32_t val)
{
float32 v1 = env->fregs[f1].l.upper;
CPU_FloatU v2;
@@ -407,7 +409,7 @@ void HELPER(deb)(uint32_t f1, uint32_t val)
}
/* 32-bit FP multiplication RM */
-void HELPER(meeb)(uint32_t f1, uint32_t val)
+void HELPER(meeb)(CPUS390XState *env, uint32_t f1, uint32_t val)
{
float32 v1 = env->fregs[f1].l.upper;
CPU_FloatU v2;
@@ -419,29 +421,29 @@ void HELPER(meeb)(uint32_t f1, uint32_t val)
}
/* 32-bit FP compare RR */
-uint32_t HELPER(cebr)(uint32_t f1, uint32_t f2)
+uint32_t HELPER(cebr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
float32 v1 = env->fregs[f1].l.upper;
float32 v2 = env->fregs[f2].l.upper;
HELPER_LOG("%s: comparing 0x%d from f%d and 0x%d\n", __func__,
v1, f1, v2);
- return set_cc_f32(v1, v2);
+ return set_cc_f32(env, v1, v2);
}
/* 64-bit FP compare RR */
-uint32_t HELPER(cdbr)(uint32_t f1, uint32_t f2)
+uint32_t HELPER(cdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
float64 v1 = env->fregs[f1].d;
float64 v2 = env->fregs[f2].d;
HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%ld\n", __func__,
v1, f1, v2);
- return set_cc_f64(v1, v2);
+ return set_cc_f64(env, v1, v2);
}
/* 128-bit FP compare RR */
-uint32_t HELPER(cxbr)(uint32_t f1, uint32_t f2)
+uint32_t HELPER(cxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
CPU_QuadU v1;
CPU_QuadU v2;
@@ -451,29 +453,29 @@ uint32_t HELPER(cxbr)(uint32_t f1, uint32_t f2)
v2.ll.upper = env->fregs[f2].ll;
v2.ll.lower = env->fregs[f2 + 2].ll;
- return float_comp_to_cc(float128_compare_quiet(v1.q, v2.q,
+ return float_comp_to_cc(env, float128_compare_quiet(v1.q, v2.q,
&env->fpu_status));
}
/* 64-bit FP compare RM */
-uint32_t HELPER(cdb)(uint32_t f1, uint64_t a2)
+uint32_t HELPER(cdb)(CPUS390XState *env, uint32_t f1, uint64_t a2)
{
float64 v1 = env->fregs[f1].d;
CPU_DoubleU v2;
- v2.ll = ldq(a2);
+ v2.ll = cpu_ldq_data(env, a2);
HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%lx\n", __func__, v1,
f1, v2.d);
- return set_cc_f64(v1, v2.d);
+ return set_cc_f64(env, v1, v2.d);
}
/* 64-bit FP addition RM */
-uint32_t HELPER(adb)(uint32_t f1, uint64_t a2)
+uint32_t HELPER(adb)(CPUS390XState *env, uint32_t f1, uint64_t a2)
{
float64 v1 = env->fregs[f1].d;
CPU_DoubleU v2;
- v2.ll = ldq(a2);
+ v2.ll = cpu_ldq_data(env, a2);
HELPER_LOG("%s: adding 0x%lx from f%d and 0x%lx\n", __func__,
v1, f1, v2.d);
env->fregs[f1].d = v1 = float64_add(v1, v2.d, &env->fpu_status);
@@ -481,7 +483,7 @@ uint32_t HELPER(adb)(uint32_t f1, uint64_t a2)
}
/* 32-bit FP subtraction RM */
-void HELPER(seb)(uint32_t f1, uint32_t val)
+void HELPER(seb)(CPUS390XState *env, uint32_t f1, uint32_t val)
{
float32 v1 = env->fregs[f1].l.upper;
CPU_FloatU v2;
@@ -491,41 +493,41 @@ void HELPER(seb)(uint32_t f1, uint32_t val)
}
/* 64-bit FP subtraction RM */
-uint32_t HELPER(sdb)(uint32_t f1, uint64_t a2)
+uint32_t HELPER(sdb)(CPUS390XState *env, uint32_t f1, uint64_t a2)
{
float64 v1 = env->fregs[f1].d;
CPU_DoubleU v2;
- v2.ll = ldq(a2);
+ v2.ll = cpu_ldq_data(env, a2);
env->fregs[f1].d = v1 = float64_sub(v1, v2.d, &env->fpu_status);
return set_cc_nz_f64(v1);
}
/* 64-bit FP multiplication RM */
-void HELPER(mdb)(uint32_t f1, uint64_t a2)
+void HELPER(mdb)(CPUS390XState *env, uint32_t f1, uint64_t a2)
{
float64 v1 = env->fregs[f1].d;
CPU_DoubleU v2;
- v2.ll = ldq(a2);
+ v2.ll = cpu_ldq_data(env, a2);
HELPER_LOG("%s: multiplying 0x%lx from f%d and 0x%ld\n", __func__,
v1, f1, v2.d);
env->fregs[f1].d = float64_mul(v1, v2.d, &env->fpu_status);
}
/* 64-bit FP division RM */
-void HELPER(ddb)(uint32_t f1, uint64_t a2)
+void HELPER(ddb)(CPUS390XState *env, uint32_t f1, uint64_t a2)
{
float64 v1 = env->fregs[f1].d;
CPU_DoubleU v2;
- v2.ll = ldq(a2);
+ v2.ll = cpu_ldq_data(env, a2);
HELPER_LOG("%s: dividing 0x%lx from f%d by 0x%ld\n", __func__,
v1, f1, v2.d);
env->fregs[f1].d = float64_div(v1, v2.d, &env->fpu_status);
}
-static void set_round_mode(int m3)
+static void set_round_mode(CPUS390XState *env, int m3)
{
switch (m3) {
case 0:
@@ -553,33 +555,36 @@ static void set_round_mode(int m3)
}
/* convert 32-bit float to 64-bit int */
-uint32_t HELPER(cgebr)(uint32_t r1, uint32_t f2, uint32_t m3)
+uint32_t HELPER(cgebr)(CPUS390XState *env, uint32_t r1, uint32_t f2,
+ uint32_t m3)
{
float32 v2 = env->fregs[f2].l.upper;
- set_round_mode(m3);
+ set_round_mode(env, m3);
env->regs[r1] = float32_to_int64(v2, &env->fpu_status);
return set_cc_nz_f32(v2);
}
/* convert 64-bit float to 64-bit int */
-uint32_t HELPER(cgdbr)(uint32_t r1, uint32_t f2, uint32_t m3)
+uint32_t HELPER(cgdbr)(CPUS390XState *env, uint32_t r1, uint32_t f2,
+ uint32_t m3)
{
float64 v2 = env->fregs[f2].d;
- set_round_mode(m3);
+ set_round_mode(env, m3);
env->regs[r1] = float64_to_int64(v2, &env->fpu_status);
return set_cc_nz_f64(v2);
}
/* convert 128-bit float to 64-bit int */
-uint32_t HELPER(cgxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
+uint32_t HELPER(cgxbr)(CPUS390XState *env, uint32_t r1, uint32_t f2,
+ uint32_t m3)
{
CPU_QuadU v2;
v2.ll.upper = env->fregs[f2].ll;
v2.ll.lower = env->fregs[f2 + 2].ll;
- set_round_mode(m3);
+ set_round_mode(env, m3);
env->regs[r1] = float128_to_int64(v2.q, &env->fpu_status);
if (float128_is_any_nan(v2.q)) {
return 3;
@@ -593,29 +598,32 @@ uint32_t HELPER(cgxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
}
/* convert 32-bit float to 32-bit int */
-uint32_t HELPER(cfebr)(uint32_t r1, uint32_t f2, uint32_t m3)
+uint32_t HELPER(cfebr)(CPUS390XState *env, uint32_t r1, uint32_t f2,
+ uint32_t m3)
{
float32 v2 = env->fregs[f2].l.upper;
- set_round_mode(m3);
+ set_round_mode(env, m3);
env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
float32_to_int32(v2, &env->fpu_status);
return set_cc_nz_f32(v2);
}
/* convert 64-bit float to 32-bit int */
-uint32_t HELPER(cfdbr)(uint32_t r1, uint32_t f2, uint32_t m3)
+uint32_t HELPER(cfdbr)(CPUS390XState *env, uint32_t r1, uint32_t f2,
+ uint32_t m3)
{
float64 v2 = env->fregs[f2].d;
- set_round_mode(m3);
+ set_round_mode(env, m3);
env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
float64_to_int32(v2, &env->fpu_status);
return set_cc_nz_f64(v2);
}
/* convert 128-bit float to 32-bit int */
-uint32_t HELPER(cfxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
+uint32_t HELPER(cfxbr)(CPUS390XState *env, uint32_t r1, uint32_t f2,
+ uint32_t m3)
{
CPU_QuadU v2;
@@ -627,19 +635,19 @@ uint32_t HELPER(cfxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
}
/* load 32-bit FP zero */
-void HELPER(lzer)(uint32_t f1)
+void HELPER(lzer)(CPUS390XState *env, uint32_t f1)
{
env->fregs[f1].l.upper = float32_zero;
}
/* load 64-bit FP zero */
-void HELPER(lzdr)(uint32_t f1)
+void HELPER(lzdr)(CPUS390XState *env, uint32_t f1)
{
env->fregs[f1].d = float64_zero;
}
/* load 128-bit FP zero */
-void HELPER(lzxr)(uint32_t f1)
+void HELPER(lzxr)(CPUS390XState *env, uint32_t f1)
{
CPU_QuadU x;
@@ -649,7 +657,7 @@ void HELPER(lzxr)(uint32_t f1)
}
/* 128-bit FP subtraction RR */
-uint32_t HELPER(sxbr)(uint32_t f1, uint32_t f2)
+uint32_t HELPER(sxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
CPU_QuadU v1;
CPU_QuadU v2;
@@ -666,7 +674,7 @@ uint32_t HELPER(sxbr)(uint32_t f1, uint32_t f2)
}
/* 128-bit FP addition RR */
-uint32_t HELPER(axbr)(uint32_t f1, uint32_t f2)
+uint32_t HELPER(axbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
CPU_QuadU v1;
CPU_QuadU v2;
@@ -683,7 +691,7 @@ uint32_t HELPER(axbr)(uint32_t f1, uint32_t f2)
}
/* 32-bit FP multiplication RR */
-void HELPER(meebr)(uint32_t f1, uint32_t f2)
+void HELPER(meebr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
env->fregs[f1].l.upper = float32_mul(env->fregs[f1].l.upper,
env->fregs[f2].l.upper,
@@ -691,19 +699,19 @@ void HELPER(meebr)(uint32_t f1, uint32_t f2)
}
/* 64-bit FP division RR */
-void HELPER(ddbr)(uint32_t f1, uint32_t f2)
+void HELPER(ddbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
env->fregs[f1].d = float64_div(env->fregs[f1].d, env->fregs[f2].d,
&env->fpu_status);
}
/* 64-bit FP multiply and add RM */
-void HELPER(madb)(uint32_t f1, uint64_t a2, uint32_t f3)
+void HELPER(madb)(CPUS390XState *env, uint32_t f1, uint64_t a2, uint32_t f3)
{
CPU_DoubleU v2;
HELPER_LOG("%s: f1 %d a2 0x%lx f3 %d\n", __func__, f1, a2, f3);
- v2.ll = ldq(a2);
+ v2.ll = cpu_ldq_data(env, a2);
env->fregs[f1].d = float64_add(env->fregs[f1].d,
float64_mul(v2.d, env->fregs[f3].d,
&env->fpu_status),
@@ -711,7 +719,7 @@ void HELPER(madb)(uint32_t f1, uint64_t a2, uint32_t f3)
}
/* 64-bit FP multiply and add RR */
-void HELPER(madbr)(uint32_t f1, uint32_t f3, uint32_t f2)
+void HELPER(madbr)(CPUS390XState *env, uint32_t f1, uint32_t f3, uint32_t f2)
{
HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __func__, f1, f2, f3);
env->fregs[f1].d = float64_add(float64_mul(env->fregs[f2].d,
@@ -721,7 +729,7 @@ void HELPER(madbr)(uint32_t f1, uint32_t f3, uint32_t f2)
}
/* 64-bit FP multiply and subtract RR */
-void HELPER(msdbr)(uint32_t f1, uint32_t f3, uint32_t f2)
+void HELPER(msdbr)(CPUS390XState *env, uint32_t f1, uint32_t f3, uint32_t f2)
{
HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __func__, f1, f2, f3);
env->fregs[f1].d = float64_sub(float64_mul(env->fregs[f2].d,
@@ -731,7 +739,7 @@ void HELPER(msdbr)(uint32_t f1, uint32_t f3, uint32_t f2)
}
/* 32-bit FP multiply and add RR */
-void HELPER(maebr)(uint32_t f1, uint32_t f3, uint32_t f2)
+void HELPER(maebr)(CPUS390XState *env, uint32_t f1, uint32_t f3, uint32_t f2)
{
env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper,
float32_mul(env->fregs[f2].l.upper,
@@ -741,29 +749,29 @@ void HELPER(maebr)(uint32_t f1, uint32_t f3, uint32_t f2)
}
/* convert 32-bit float to 64-bit float */
-void HELPER(ldeb)(uint32_t f1, uint64_t a2)
+void HELPER(ldeb)(CPUS390XState *env, uint32_t f1, uint64_t a2)
{
uint32_t v2;
- v2 = ldl(a2);
+ v2 = cpu_ldl_data(env, 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)
+void HELPER(lxdb)(CPUS390XState *env, uint32_t f1, uint64_t a2)
{
CPU_DoubleU v2;
CPU_QuadU v1;
- v2.ll = ldq(a2);
+ v2.ll = cpu_ldq_data(env, a2);
v1.q = float64_to_float128(v2.d, &env->fpu_status);
env->fregs[f1].ll = v1.ll.upper;
env->fregs[f1 + 2].ll = v1.ll.lower;
}
/* test data class 32-bit */
-uint32_t HELPER(tceb)(uint32_t f1, uint64_t m2)
+uint32_t HELPER(tceb)(CPUS390XState *env, uint32_t f1, uint64_t m2)
{
float32 v1 = env->fregs[f1].l.upper;
int neg = float32_is_neg(v1);
@@ -785,7 +793,7 @@ uint32_t HELPER(tceb)(uint32_t f1, uint64_t m2)
}
/* test data class 64-bit */
-uint32_t HELPER(tcdb)(uint32_t f1, uint64_t m2)
+uint32_t HELPER(tcdb)(CPUS390XState *env, uint32_t f1, uint64_t m2)
{
float64 v1 = env->fregs[f1].d;
int neg = float64_is_neg(v1);
@@ -806,7 +814,7 @@ uint32_t HELPER(tcdb)(uint32_t f1, uint64_t m2)
}
/* test data class 128-bit */
-uint32_t HELPER(tcxb)(uint32_t f1, uint64_t m2)
+uint32_t HELPER(tcxb)(CPUS390XState *env, uint32_t f1, uint64_t m2)
{
CPU_QuadU v1;
uint32_t cc = 0;
@@ -830,7 +838,7 @@ uint32_t HELPER(tcxb)(uint32_t f1, uint64_t m2)
}
/* square root 64-bit RR */
-void HELPER(sqdbr)(uint32_t f1, uint32_t f2)
+void HELPER(sqdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
{
env->fregs[f1].d = float64_sqrt(env->fregs[f2].d, &env->fpu_status);
}
diff --git a/target-s390x/helper.h b/target-s390x/helper.h
index 01c8d0e..af98773 100644
--- a/target-s390x/helper.h
+++ b/target-s390x/helper.h
@@ -45,70 +45,70 @@ DEF_HELPER_3(mvcle, i32, i32, i64, i32)
DEF_HELPER_3(clcle, i32, i32, i64, i32)
DEF_HELPER_3(slb, i32, i32, i32, i32)
DEF_HELPER_4(slbg, i32, i32, i32, i64, i64)
-DEF_HELPER_2(cefbr, void, i32, s32)
-DEF_HELPER_2(cdfbr, void, i32, s32)
-DEF_HELPER_2(cxfbr, void, i32, s32)
-DEF_HELPER_2(cegbr, void, i32, s64)
-DEF_HELPER_2(cdgbr, void, i32, s64)
-DEF_HELPER_2(cxgbr, void, i32, s64)
-DEF_HELPER_2(adbr, i32, i32, i32)
-DEF_HELPER_2(aebr, i32, i32, i32)
-DEF_HELPER_2(sebr, i32, i32, i32)
-DEF_HELPER_2(sdbr, i32, i32, i32)
-DEF_HELPER_2(debr, void, i32, i32)
-DEF_HELPER_2(dxbr, void, i32, i32)
-DEF_HELPER_2(mdbr, void, i32, i32)
-DEF_HELPER_2(mxbr, void, i32, i32)
-DEF_HELPER_2(ldebr, void, i32, i32)
-DEF_HELPER_2(ldxbr, void, i32, i32)
-DEF_HELPER_2(lxdbr, void, i32, i32)
-DEF_HELPER_2(ledbr, void, i32, i32)
-DEF_HELPER_2(lexbr, void, i32, i32)
-DEF_HELPER_2(lpebr, i32, i32, i32)
-DEF_HELPER_2(lpdbr, i32, i32, i32)
-DEF_HELPER_2(lpxbr, i32, i32, i32)
-DEF_HELPER_2(ltebr, i32, i32, i32)
-DEF_HELPER_2(ltdbr, i32, i32, i32)
-DEF_HELPER_2(ltxbr, i32, i32, i32)
-DEF_HELPER_2(lcebr, i32, i32, i32)
-DEF_HELPER_2(lcdbr, i32, i32, i32)
-DEF_HELPER_2(lcxbr, i32, i32, i32)
-DEF_HELPER_2(aeb, void, i32, i32)
-DEF_HELPER_2(deb, void, i32, i32)
-DEF_HELPER_2(meeb, void, i32, i32)
-DEF_HELPER_2(cdb, i32, i32, i64)
-DEF_HELPER_2(adb, i32, i32, i64)
-DEF_HELPER_2(seb, void, i32, i32)
-DEF_HELPER_2(sdb, i32, i32, i64)
-DEF_HELPER_2(mdb, void, i32, i64)
-DEF_HELPER_2(ddb, void, i32, i64)
-DEF_HELPER_FLAGS_2(cebr, TCG_CALL_PURE, i32, i32, i32)
-DEF_HELPER_FLAGS_2(cdbr, TCG_CALL_PURE, i32, i32, i32)
-DEF_HELPER_FLAGS_2(cxbr, TCG_CALL_PURE, i32, i32, i32)
-DEF_HELPER_3(cgebr, i32, i32, i32, i32)
-DEF_HELPER_3(cgdbr, i32, i32, i32, i32)
-DEF_HELPER_3(cgxbr, i32, i32, i32, i32)
-DEF_HELPER_1(lzer, void, i32)
-DEF_HELPER_1(lzdr, void, i32)
-DEF_HELPER_1(lzxr, void, i32)
-DEF_HELPER_3(cfebr, i32, i32, i32, i32)
-DEF_HELPER_3(cfdbr, i32, i32, i32, i32)
-DEF_HELPER_3(cfxbr, i32, i32, i32, i32)
-DEF_HELPER_2(axbr, i32, i32, i32)
-DEF_HELPER_2(sxbr, i32, i32, i32)
-DEF_HELPER_2(meebr, void, i32, i32)
-DEF_HELPER_2(ddbr, void, i32, i32)
-DEF_HELPER_3(madb, void, i32, i64, i32)
-DEF_HELPER_3(maebr, void, i32, i32, i32)
-DEF_HELPER_3(madbr, void, i32, i32, i32)
-DEF_HELPER_3(msdbr, void, i32, i32, i32)
-DEF_HELPER_2(ldeb, void, i32, i64)
-DEF_HELPER_2(lxdb, void, i32, i64)
-DEF_HELPER_FLAGS_2(tceb, TCG_CALL_PURE, i32, i32, i64)
-DEF_HELPER_FLAGS_2(tcdb, TCG_CALL_PURE, i32, i32, i64)
-DEF_HELPER_FLAGS_2(tcxb, TCG_CALL_PURE, i32, i32, i64)
+DEF_HELPER_3(cefbr, void, env, i32, s32)
+DEF_HELPER_3(cdfbr, void, env, i32, s32)
+DEF_HELPER_3(cxfbr, void, env, i32, s32)
+DEF_HELPER_3(cegbr, void, env, i32, s64)
+DEF_HELPER_3(cdgbr, void, env, i32, s64)
+DEF_HELPER_3(cxgbr, void, env, i32, s64)
+DEF_HELPER_3(adbr, i32, env, i32, i32)
+DEF_HELPER_3(aebr, i32, env, i32, i32)
+DEF_HELPER_3(sebr, i32, env, i32, i32)
+DEF_HELPER_3(sdbr, i32, env, i32, i32)
+DEF_HELPER_3(debr, void, env, i32, i32)
+DEF_HELPER_3(dxbr, void, env, i32, i32)
+DEF_HELPER_3(mdbr, void, env, i32, i32)
+DEF_HELPER_3(mxbr, void, env, i32, i32)
+DEF_HELPER_3(ldebr, void, env, i32, i32)
+DEF_HELPER_3(ldxbr, void, env, i32, i32)
+DEF_HELPER_3(lxdbr, void, env, i32, i32)
+DEF_HELPER_3(ledbr, void, env, i32, i32)
+DEF_HELPER_3(lexbr, void, env, i32, i32)
+DEF_HELPER_3(lpebr, i32, env, i32, i32)
+DEF_HELPER_3(lpdbr, i32, env, i32, i32)
+DEF_HELPER_3(lpxbr, i32, env, i32, i32)
+DEF_HELPER_3(ltebr, i32, env, i32, i32)
+DEF_HELPER_3(ltdbr, i32, env, i32, i32)
+DEF_HELPER_3(ltxbr, i32, env, i32, i32)
+DEF_HELPER_3(lcebr, i32, env, i32, i32)
+DEF_HELPER_3(lcdbr, i32, env, i32, i32)
+DEF_HELPER_3(lcxbr, i32, env, i32, i32)
+DEF_HELPER_3(aeb, void, env, i32, i32)
+DEF_HELPER_3(deb, void, env, i32, i32)
+DEF_HELPER_3(meeb, void, env, i32, i32)
+DEF_HELPER_3(cdb, i32, env, i32, i64)
+DEF_HELPER_3(adb, i32, env, i32, i64)
+DEF_HELPER_3(seb, void, env, i32, i32)
+DEF_HELPER_3(sdb, i32, env, i32, i64)
+DEF_HELPER_3(mdb, void, env, i32, i64)
+DEF_HELPER_3(ddb, void, env, i32, i64)
+DEF_HELPER_FLAGS_3(cebr, TCG_CALL_PURE, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(cdbr, TCG_CALL_PURE, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(cxbr, TCG_CALL_PURE, i32, env, i32, i32)
+DEF_HELPER_4(cgebr, i32, env, i32, i32, i32)
+DEF_HELPER_4(cgdbr, i32, env, i32, i32, i32)
+DEF_HELPER_4(cgxbr, i32, env, i32, i32, i32)
+DEF_HELPER_2(lzer, void, env, i32)
+DEF_HELPER_2(lzdr, void, env, i32)
+DEF_HELPER_2(lzxr, void, env, i32)
+DEF_HELPER_4(cfebr, i32, env, i32, i32, i32)
+DEF_HELPER_4(cfdbr, i32, env, i32, i32, i32)
+DEF_HELPER_4(cfxbr, i32, env, i32, i32, i32)
+DEF_HELPER_3(axbr, i32, env, i32, i32)
+DEF_HELPER_3(sxbr, i32, env, i32, i32)
+DEF_HELPER_3(meebr, void, env, i32, i32)
+DEF_HELPER_3(ddbr, void, env, i32, i32)
+DEF_HELPER_4(madb, void, env, i32, i64, i32)
+DEF_HELPER_4(maebr, void, env, i32, i32, i32)
+DEF_HELPER_4(madbr, void, env, i32, i32, i32)
+DEF_HELPER_4(msdbr, void, env, i32, i32, i32)
+DEF_HELPER_3(ldeb, void, env, i32, i64)
+DEF_HELPER_3(lxdb, void, env, i32, i64)
+DEF_HELPER_FLAGS_3(tceb, TCG_CALL_PURE, i32, env, i32, i64)
+DEF_HELPER_FLAGS_3(tcdb, TCG_CALL_PURE, i32, env, i32, i64)
+DEF_HELPER_FLAGS_3(tcxb, TCG_CALL_PURE, i32, env, i32, i64)
DEF_HELPER_2(flogr, i32, i32, i64)
-DEF_HELPER_2(sqdbr, void, i32, i32)
+DEF_HELPER_3(sqdbr, void, env, i32, i32)
DEF_HELPER_FLAGS_1(cvd, TCG_CALL_PURE|TCG_CALL_CONST, i64, s32)
DEF_HELPER_3(unpk, void, i32, i64, i64)
DEF_HELPER_3(tr, void, i32, i64, i64)
diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c
index ba05e65..3f8b3ba 100644
--- a/target-s390x/mem_helper.c
+++ b/target-s390x/mem_helper.c
@@ -1188,3 +1188,52 @@ uint32_t HELPER(lra)(uint64_t addr, uint32_t r1)
}
#endif
+
+/* temporary wrappers */
+#if defined(CONFIG_USER_ONLY)
+#define ldub_data(addr) ldub_raw(addr)
+#define lduw_data(addr) lduw_raw(addr)
+#define ldl_data(addr) ldl_raw(addr)
+#define ldq_data(addr) ldq_raw(addr)
+
+#define stb_data(addr, data) stb_raw(addr, data)
+#define stw_data(addr, data) stw_raw(addr, data)
+#define stl_data(addr, data) stl_raw(addr, data)
+#define stq_data(addr, data) stq_raw(addr, data)
+#endif
+
+#define WRAP_LD(rettype, fn) \
+ rettype cpu_ ## fn(CPUS390XState *env1, target_ulong addr) \
+ { \
+ CPUS390XState *saved_env; \
+ rettype ret; \
+ \
+ saved_env = env; \
+ env = env1; \
+ ret = fn(addr); \
+ env = saved_env; \
+ return ret; \
+ }
+
+WRAP_LD(uint32_t, ldub_data)
+WRAP_LD(uint32_t, lduw_data)
+WRAP_LD(uint32_t, ldl_data)
+WRAP_LD(uint64_t, ldq_data)
+#undef WRAP_LD
+
+#define WRAP_ST(datatype, fn) \
+ void cpu_ ## fn(CPUS390XState *env1, target_ulong addr, datatype val) \
+ { \
+ CPUS390XState *saved_env; \
+ \
+ saved_env = env; \
+ env = env1; \
+ fn(addr, val); \
+ env = saved_env; \
+ }
+
+WRAP_ST(uint32_t, stb_data)
+WRAP_ST(uint32_t, stw_data)
+WRAP_ST(uint32_t, stl_data)
+WRAP_ST(uint64_t, stq_data)
+#undef WRAP_ST
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index c370df3..b1f2071 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -2206,11 +2206,11 @@ static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2,
switch (op) {
case 0x4: /* LDEB R1,D2(X2,B2) [RXE] */
potential_page_fault(s);
- gen_helper_ldeb(tmp_r1, addr);
+ gen_helper_ldeb(cpu_env, tmp_r1, addr);
break;
case 0x5: /* LXDB R1,D2(X2,B2) [RXE] */
potential_page_fault(s);
- gen_helper_lxdb(tmp_r1, addr);
+ gen_helper_lxdb(cpu_env, tmp_r1, addr);
break;
case 0x9: /* CEB R1,D2(X2,B2) [RXE] */
tmp = tcg_temp_new_i64();
@@ -2225,7 +2225,7 @@ static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2,
tmp32 = tcg_temp_new_i32();
tcg_gen_qemu_ld32u(tmp, addr, get_mem_index(s));
tcg_gen_trunc_i64_i32(tmp32, tmp);
- gen_helper_aeb(tmp_r1, tmp32);
+ gen_helper_aeb(cpu_env, tmp_r1, tmp32);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32);
@@ -2238,7 +2238,7 @@ static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2,
tmp32 = tcg_temp_new_i32();
tcg_gen_qemu_ld32u(tmp, addr, get_mem_index(s));
tcg_gen_trunc_i64_i32(tmp32, tmp);
- gen_helper_seb(tmp_r1, tmp32);
+ gen_helper_seb(cpu_env, tmp_r1, tmp32);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32);
@@ -2251,23 +2251,23 @@ static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2,
tmp32 = tcg_temp_new_i32();
tcg_gen_qemu_ld32u(tmp, addr, get_mem_index(s));
tcg_gen_trunc_i64_i32(tmp32, tmp);
- gen_helper_deb(tmp_r1, tmp32);
+ gen_helper_deb(cpu_env, tmp_r1, tmp32);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32);
break;
case 0x10: /* TCEB R1,D2(X2,B2) [RXE] */
potential_page_fault(s);
- gen_helper_tceb(cc_op, tmp_r1, addr);
+ gen_helper_tceb(cc_op, cpu_env, tmp_r1, addr);
set_cc_static(s);
break;
case 0x11: /* TCDB R1,D2(X2,B2) [RXE] */
potential_page_fault(s);
- gen_helper_tcdb(cc_op, tmp_r1, addr);
+ gen_helper_tcdb(cc_op, cpu_env, tmp_r1, addr);
set_cc_static(s);
break;
case 0x12: /* TCXB R1,D2(X2,B2) [RXE] */
potential_page_fault(s);
- gen_helper_tcxb(cc_op, tmp_r1, addr);
+ gen_helper_tcxb(cc_op, cpu_env, tmp_r1, addr);
set_cc_static(s);
break;
case 0x17: /* MEEB R1,D2(X2,B2) [RXE] */
@@ -2275,38 +2275,38 @@ static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2,
tmp32 = tcg_temp_new_i32();
tcg_gen_qemu_ld32u(tmp, addr, get_mem_index(s));
tcg_gen_trunc_i64_i32(tmp32, tmp);
- gen_helper_meeb(tmp_r1, tmp32);
+ gen_helper_meeb(cpu_env, tmp_r1, tmp32);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32);
break;
case 0x19: /* CDB R1,D2(X2,B2) [RXE] */
potential_page_fault(s);
- gen_helper_cdb(cc_op, tmp_r1, addr);
+ gen_helper_cdb(cc_op, cpu_env, tmp_r1, addr);
set_cc_static(s);
break;
case 0x1a: /* ADB R1,D2(X2,B2) [RXE] */
potential_page_fault(s);
- gen_helper_adb(cc_op, tmp_r1, addr);
+ gen_helper_adb(cc_op, cpu_env, tmp_r1, addr);
set_cc_static(s);
break;
case 0x1b: /* SDB R1,D2(X2,B2) [RXE] */
potential_page_fault(s);
- gen_helper_sdb(cc_op, tmp_r1, addr);
+ gen_helper_sdb(cc_op, cpu_env, tmp_r1, addr);
set_cc_static(s);
break;
case 0x1c: /* MDB R1,D2(X2,B2) [RXE] */
potential_page_fault(s);
- gen_helper_mdb(tmp_r1, addr);
+ gen_helper_mdb(cpu_env, tmp_r1, addr);
break;
case 0x1d: /* DDB R1,D2(X2,B2) [RXE] */
potential_page_fault(s);
- gen_helper_ddb(tmp_r1, addr);
+ gen_helper_ddb(cpu_env, tmp_r1, addr);
break;
case 0x1e: /* MADB R1,R3,D2(X2,B2) [RXF] */
/* for RXF insns, r1 is R3 and r1b is R1 */
tmp32 = tcg_const_i32(r1b);
potential_page_fault(s);
- gen_helper_madb(tmp32, addr, tmp_r1);
+ gen_helper_madb(cpu_env, tmp32, addr, tmp_r1);
tcg_temp_free_i32(tmp32);
break;
default:
@@ -3001,14 +3001,14 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
#define FP_HELPER(i) \
tmp32_1 = tcg_const_i32(r1); \
tmp32_2 = tcg_const_i32(r2); \
- gen_helper_ ## i (tmp32_1, tmp32_2); \
+ gen_helper_ ## i(cpu_env, tmp32_1, tmp32_2); \
tcg_temp_free_i32(tmp32_1); \
tcg_temp_free_i32(tmp32_2);
#define FP_HELPER_CC(i) \
tmp32_1 = tcg_const_i32(r1); \
tmp32_2 = tcg_const_i32(r2); \
- gen_helper_ ## i (cc_op, tmp32_1, tmp32_2); \
+ gen_helper_ ## i(cc_op, cpu_env, tmp32_1, tmp32_2); \
set_cc_static(s); \
tcg_temp_free_i32(tmp32_1); \
tcg_temp_free_i32(tmp32_2);
@@ -3080,13 +3080,13 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
tmp32_3 = tcg_const_i32(r1);
switch (op) {
case 0xe:
- gen_helper_maebr(tmp32_1, tmp32_3, tmp32_2);
+ gen_helper_maebr(cpu_env, tmp32_1, tmp32_3, tmp32_2);
break;
case 0x1e:
- gen_helper_madbr(tmp32_1, tmp32_3, tmp32_2);
+ gen_helper_madbr(cpu_env, tmp32_1, tmp32_3, tmp32_2);
break;
case 0x1f:
- gen_helper_msdbr(tmp32_1, tmp32_3, tmp32_2);
+ gen_helper_msdbr(cpu_env, tmp32_1, tmp32_3, tmp32_2);
break;
default:
tcg_abort();
@@ -3138,17 +3138,17 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
break;
case 0x74: /* LZER R1 [RRE] */
tmp32_1 = tcg_const_i32(r1);
- gen_helper_lzer(tmp32_1);
+ gen_helper_lzer(cpu_env, tmp32_1);
tcg_temp_free_i32(tmp32_1);
break;
case 0x75: /* LZDR R1 [RRE] */
tmp32_1 = tcg_const_i32(r1);
- gen_helper_lzdr(tmp32_1);
+ gen_helper_lzdr(cpu_env, tmp32_1);
tcg_temp_free_i32(tmp32_1);
break;
case 0x76: /* LZXR R1 [RRE] */
tmp32_1 = tcg_const_i32(r1);
- gen_helper_lzxr(tmp32_1);
+ gen_helper_lzxr(cpu_env, tmp32_1);
tcg_temp_free_i32(tmp32_1);
break;
case 0x84: /* SFPC R1 [RRE] */
@@ -3169,13 +3169,13 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
tmp32_2 = load_reg32(r2);
switch (op) {
case 0x94:
- gen_helper_cefbr(tmp32_1, tmp32_2);
+ gen_helper_cefbr(cpu_env, tmp32_1, tmp32_2);
break;
case 0x95:
- gen_helper_cdfbr(tmp32_1, tmp32_2);
+ gen_helper_cdfbr(cpu_env, tmp32_1, tmp32_2);
break;
case 0x96:
- gen_helper_cxfbr(tmp32_1, tmp32_2);
+ gen_helper_cxfbr(cpu_env, tmp32_1, tmp32_2);
break;
default:
tcg_abort();
@@ -3191,13 +3191,13 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
tmp32_3 = tcg_const_i32(m3);
switch (op) {
case 0x98:
- gen_helper_cfebr(cc_op, tmp32_1, tmp32_2, tmp32_3);
+ gen_helper_cfebr(cc_op, cpu_env, tmp32_1, tmp32_2, tmp32_3);
break;
case 0x99:
- gen_helper_cfdbr(cc_op, tmp32_1, tmp32_2, tmp32_3);
+ gen_helper_cfdbr(cc_op, cpu_env, tmp32_1, tmp32_2, tmp32_3);
break;
case 0x9a:
- gen_helper_cfxbr(cc_op, tmp32_1, tmp32_2, tmp32_3);
+ gen_helper_cfxbr(cc_op, cpu_env, tmp32_1, tmp32_2, tmp32_3);
break;
default:
tcg_abort();
@@ -3213,10 +3213,10 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
tmp = load_reg(r2);
switch (op) {
case 0xa4:
- gen_helper_cegbr(tmp32_1, tmp);
+ gen_helper_cegbr(cpu_env, tmp32_1, tmp);
break;
case 0xa5:
- gen_helper_cdgbr(tmp32_1, tmp);
+ gen_helper_cdgbr(cpu_env, tmp32_1, tmp);
break;
default:
tcg_abort();
@@ -3227,7 +3227,7 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
case 0xa6: /* CXGBR R1,R2 [RRE] */
tmp32_1 = tcg_const_i32(r1);
tmp = load_reg(r2);
- gen_helper_cxgbr(tmp32_1, tmp);
+ gen_helper_cxgbr(cpu_env, tmp32_1, tmp);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i64(tmp);
break;
@@ -3235,7 +3235,7 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
tmp32_1 = tcg_const_i32(r1);
tmp32_2 = tcg_const_i32(r2);
tmp32_3 = tcg_const_i32(m3);
- gen_helper_cgebr(cc_op, tmp32_1, tmp32_2, tmp32_3);
+ gen_helper_cgebr(cc_op, cpu_env, tmp32_1, tmp32_2, tmp32_3);
set_cc_static(s);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
@@ -3245,7 +3245,7 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
tmp32_1 = tcg_const_i32(r1);
tmp32_2 = tcg_const_i32(r2);
tmp32_3 = tcg_const_i32(m3);
- gen_helper_cgdbr(cc_op, tmp32_1, tmp32_2, tmp32_3);
+ gen_helper_cgdbr(cc_op, cpu_env, tmp32_1, tmp32_2, tmp32_3);
set_cc_static(s);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
@@ -3255,7 +3255,7 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
tmp32_1 = tcg_const_i32(r1);
tmp32_2 = tcg_const_i32(r2);
tmp32_3 = tcg_const_i32(m3);
- gen_helper_cgxbr(cc_op, tmp32_1, tmp32_2, tmp32_3);
+ gen_helper_cgxbr(cc_op, cpu_env, tmp32_1, tmp32_2, tmp32_3);
set_cc_static(s);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 08/12] target-s390x: avoid AREG0 for integer helpers
2012-09-10 11:40 [Qemu-devel] [PULL 00/12] s390 patch queue 2012-09-10 Alexander Graf
` (6 preceding siblings ...)
2012-09-10 11:40 ` [Qemu-devel] [PATCH 07/12] target-s390x: avoid AREG0 for FPU helpers Alexander Graf
@ 2012-09-10 11:40 ` Alexander Graf
2012-09-10 11:40 ` [Qemu-devel] [PATCH 09/12] target-s390x: avoid AREG0 for condition code helpers Alexander Graf
` (4 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Alexander Graf @ 2012-09-10 11:40 UTC (permalink / raw)
To: qemu-devel qemu-devel; +Cc: Blue Swirl, Aurelien Jarno
From: Blue Swirl <blauwirbel@gmail.com>
Make integer helpers take a parameter for CPUState instead
of relying on global env.
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-s390x/Makefile.objs | 1 -
target-s390x/helper.h | 10 +++++-----
target-s390x/int_helper.c | 12 ++++++------
target-s390x/translate.c | 16 ++++++++--------
4 files changed, 19 insertions(+), 20 deletions(-)
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index 7d965e9..7b2c5c1 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -3,7 +3,6 @@ obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
obj-$(CONFIG_SOFTMMU) += machine.o
obj-$(CONFIG_KVM) += kvm.o
-$(obj)/int_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
$(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
$(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
$(obj)/misc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
diff --git a/target-s390x/helper.h b/target-s390x/helper.h
index af98773..c03cd59 100644
--- a/target-s390x/helper.h
+++ b/target-s390x/helper.h
@@ -12,8 +12,8 @@ DEF_HELPER_FLAGS_1(set_cc_comp_s64, TCG_CALL_PURE|TCG_CALL_CONST, i32, s64)
DEF_HELPER_FLAGS_2(set_cc_icm, TCG_CALL_PURE|TCG_CALL_CONST, i32, i32, i32)
DEF_HELPER_3(clm, i32, i32, i32, i64)
DEF_HELPER_3(stcm, void, i32, i32, i64)
-DEF_HELPER_2(mlg, void, i32, i64)
-DEF_HELPER_2(dlg, void, i32, i64)
+DEF_HELPER_3(mlg, void, env, i32, i64)
+DEF_HELPER_3(dlg, void, env, i32, i64)
DEF_HELPER_FLAGS_3(set_cc_add64, TCG_CALL_PURE|TCG_CALL_CONST, i32, s64, s64, s64)
DEF_HELPER_FLAGS_3(set_cc_addu64, TCG_CALL_PURE|TCG_CALL_CONST, i32, i64, i64, i64)
DEF_HELPER_FLAGS_3(set_cc_add32, TCG_CALL_PURE|TCG_CALL_CONST, i32, s32, s32, s32)
@@ -43,8 +43,8 @@ DEF_HELPER_3(stam, void, i32, i64, i32)
DEF_HELPER_3(lam, void, i32, i64, i32)
DEF_HELPER_3(mvcle, i32, i32, i64, i32)
DEF_HELPER_3(clcle, i32, i32, i64, i32)
-DEF_HELPER_3(slb, i32, i32, i32, i32)
-DEF_HELPER_4(slbg, i32, i32, i32, i64, i64)
+DEF_HELPER_4(slb, i32, env, i32, i32, i32)
+DEF_HELPER_5(slbg, i32, env, i32, i32, i64, i64)
DEF_HELPER_3(cefbr, void, env, i32, s32)
DEF_HELPER_3(cdfbr, void, env, i32, s32)
DEF_HELPER_3(cxfbr, void, env, i32, s32)
@@ -107,7 +107,7 @@ DEF_HELPER_3(lxdb, void, env, i32, i64)
DEF_HELPER_FLAGS_3(tceb, TCG_CALL_PURE, i32, env, i32, i64)
DEF_HELPER_FLAGS_3(tcdb, TCG_CALL_PURE, i32, env, i32, i64)
DEF_HELPER_FLAGS_3(tcxb, TCG_CALL_PURE, i32, env, i32, i64)
-DEF_HELPER_2(flogr, i32, i32, i64)
+DEF_HELPER_3(flogr, i32, env, i32, i64)
DEF_HELPER_3(sqdbr, void, env, i32, i32)
DEF_HELPER_FLAGS_1(cvd, TCG_CALL_PURE|TCG_CALL_CONST, i64, s32)
DEF_HELPER_3(unpk, void, i32, i64, i64)
diff --git a/target-s390x/int_helper.c b/target-s390x/int_helper.c
index e2eeb07..f202a7e 100644
--- a/target-s390x/int_helper.c
+++ b/target-s390x/int_helper.c
@@ -19,7 +19,6 @@
*/
#include "cpu.h"
-#include "dyngen-exec.h"
#include "host-utils.h"
#include "helper.h"
@@ -31,7 +30,7 @@
#endif
/* 64/64 -> 128 unsigned multiplication */
-void HELPER(mlg)(uint32_t r1, uint64_t v2)
+void HELPER(mlg)(CPUS390XState *env, uint32_t r1, uint64_t v2)
{
#if HOST_LONG_BITS == 64 && defined(__GNUC__)
/* assuming 64-bit hosts have __uint128_t */
@@ -46,7 +45,7 @@ void HELPER(mlg)(uint32_t r1, uint64_t v2)
}
/* 128 -> 64/64 unsigned division */
-void HELPER(dlg)(uint32_t r1, uint64_t v2)
+void HELPER(dlg)(CPUS390XState *env, uint32_t r1, uint64_t v2)
{
uint64_t divisor = v2;
@@ -129,7 +128,7 @@ uint32_t HELPER(addc_u32)(uint32_t cc, uint32_t v1, uint32_t v2)
}
/* subtract unsigned v2 from v1 with borrow */
-uint32_t HELPER(slb)(uint32_t cc, uint32_t r1, uint32_t v2)
+uint32_t HELPER(slb)(CPUS390XState *env, uint32_t cc, uint32_t r1, uint32_t v2)
{
uint32_t v1 = env->regs[r1];
uint32_t res = v1 + (~v2) + (cc >> 1);
@@ -144,7 +143,8 @@ uint32_t HELPER(slb)(uint32_t cc, uint32_t r1, uint32_t v2)
}
/* subtract unsigned v2 from v1 with borrow */
-uint32_t HELPER(slbg)(uint32_t cc, uint32_t r1, uint64_t v1, uint64_t v2)
+uint32_t HELPER(slbg)(CPUS390XState *env, uint32_t cc, uint32_t r1,
+ uint64_t v1, uint64_t v2)
{
uint64_t res = v1 + (~v2) + (cc >> 1);
@@ -158,7 +158,7 @@ uint32_t HELPER(slbg)(uint32_t cc, uint32_t r1, uint64_t v1, uint64_t v2)
}
/* find leftmost one */
-uint32_t HELPER(flogr)(uint32_t r1, uint64_t v2)
+uint32_t HELPER(flogr)(CPUS390XState *env, uint32_t r1, uint64_t v2)
{
uint64_t res = 0;
uint64_t ov2 = v2;
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index b1f2071..2a61e92 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -1803,7 +1803,7 @@ static void disas_e3(DisasContext* s, int op, int r1, int x2, int b2, int d2)
tmp2 = tcg_temp_new_i64();
tmp32_1 = tcg_const_i32(r1);
tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s));
- gen_helper_mlg(tmp32_1, tmp2);
+ gen_helper_mlg(cpu_env, tmp32_1, tmp2);
tcg_temp_free_i64(tmp2);
tcg_temp_free_i32(tmp32_1);
break;
@@ -1811,7 +1811,7 @@ static void disas_e3(DisasContext* s, int op, int r1, int x2, int b2, int d2)
tmp2 = tcg_temp_new_i64();
tmp32_1 = tcg_const_i32(r1);
tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s));
- gen_helper_dlg(tmp32_1, tmp2);
+ gen_helper_dlg(cpu_env, tmp32_1, tmp2);
tcg_temp_free_i64(tmp2);
tcg_temp_free_i32(tmp32_1);
break;
@@ -1837,7 +1837,7 @@ static void disas_e3(DisasContext* s, int op, int r1, int x2, int b2, int d2)
tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s));
/* XXX possible optimization point */
gen_op_calc_cc(s);
- gen_helper_slbg(cc_op, cc_op, tmp32_1, regs[r1], tmp2);
+ gen_helper_slbg(cc_op, cpu_env, cc_op, tmp32_1, regs[r1], tmp2);
set_cc_static(s);
tcg_temp_free_i64(tmp2);
tcg_temp_free_i32(tmp32_1);
@@ -1917,7 +1917,7 @@ static void disas_e3(DisasContext* s, int op, int r1, int x2, int b2, int d2)
tcg_gen_trunc_i64_i32(tmp32_2, tmp2);
/* XXX possible optimization point */
gen_op_calc_cc(s);
- gen_helper_slb(cc_op, cc_op, tmp32_1, tmp32_2);
+ gen_helper_slb(cc_op, cpu_env, cc_op, tmp32_1, tmp32_2);
set_cc_static(s);
tcg_temp_free_i64(tmp2);
tcg_temp_free_i32(tmp32_1);
@@ -3535,7 +3535,7 @@ static void disas_b9(DisasContext *s, int op, int r1, int r2)
case 0x83: /* FLOGR R1,R2 [RRE] */
tmp = load_reg(r2);
tmp32_1 = tcg_const_i32(r1);
- gen_helper_flogr(cc_op, tmp32_1, tmp);
+ gen_helper_flogr(cc_op, cpu_env, tmp32_1, tmp);
set_cc_static(s);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32_1);
@@ -3555,7 +3555,7 @@ static void disas_b9(DisasContext *s, int op, int r1, int r2)
case 0x87: /* DLGR R1,R2 [RRE] */
tmp32_1 = tcg_const_i32(r1);
tmp = load_reg(r2);
- gen_helper_dlg(tmp32_1, tmp);
+ gen_helper_dlg(cpu_env, tmp32_1, tmp);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32_1);
break;
@@ -3580,7 +3580,7 @@ static void disas_b9(DisasContext *s, int op, int r1, int r2)
tmp2 = load_reg(r2);
tmp32_1 = tcg_const_i32(r1);
gen_op_calc_cc(s);
- gen_helper_slbg(cc_op, cc_op, tmp32_1, tmp, tmp2);
+ gen_helper_slbg(cc_op, cpu_env, cc_op, tmp32_1, tmp, tmp2);
set_cc_static(s);
tcg_temp_free_i64(tmp);
tcg_temp_free_i64(tmp2);
@@ -3647,7 +3647,7 @@ static void disas_b9(DisasContext *s, int op, int r1, int r2)
tmp32_1 = load_reg32(r2);
tmp32_2 = tcg_const_i32(r1);
gen_op_calc_cc(s);
- gen_helper_slb(cc_op, cc_op, tmp32_2, tmp32_1);
+ gen_helper_slb(cc_op, cpu_env, cc_op, tmp32_2, tmp32_1);
set_cc_static(s);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 09/12] target-s390x: avoid AREG0 for condition code helpers
2012-09-10 11:40 [Qemu-devel] [PULL 00/12] s390 patch queue 2012-09-10 Alexander Graf
` (7 preceding siblings ...)
2012-09-10 11:40 ` [Qemu-devel] [PATCH 08/12] target-s390x: avoid AREG0 for integer helpers Alexander Graf
@ 2012-09-10 11:40 ` Alexander Graf
2012-09-10 11:40 ` [Qemu-devel] [PATCH 10/12] target-s390x: avoid AREG0 for misc helpers Alexander Graf
` (3 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Alexander Graf @ 2012-09-10 11:40 UTC (permalink / raw)
To: qemu-devel qemu-devel; +Cc: Blue Swirl, Aurelien Jarno
From: Blue Swirl <blauwirbel@gmail.com>
Make condition code helpers take a parameter for CPUState instead
of relying on global env.
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-s390x/Makefile.objs | 1 -
target-s390x/cc_helper.c | 11 +++++------
target-s390x/helper.h | 10 +++++-----
target-s390x/translate.c | 16 ++++++++--------
4 files changed, 18 insertions(+), 20 deletions(-)
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index 7b2c5c1..736cf33 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -3,6 +3,5 @@ obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
obj-$(CONFIG_SOFTMMU) += machine.o
obj-$(CONFIG_KVM) += kvm.o
-$(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
$(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
$(obj)/misc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
diff --git a/target-s390x/cc_helper.c b/target-s390x/cc_helper.c
index 9c3a2c4..19ef145 100644
--- a/target-s390x/cc_helper.c
+++ b/target-s390x/cc_helper.c
@@ -19,7 +19,6 @@
*/
#include "cpu.h"
-#include "dyngen-exec.h"
#include "helper.h"
/* #define DEBUG_HELPER */
@@ -500,14 +499,14 @@ uint32_t calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t src, uint64_t dst,
return do_calc_cc(env, cc_op, src, dst, vr);
}
-uint32_t HELPER(calc_cc)(uint32_t cc_op, uint64_t src, uint64_t dst,
- uint64_t vr)
+uint32_t HELPER(calc_cc)(CPUS390XState *env, uint32_t cc_op, uint64_t src,
+ uint64_t dst, uint64_t vr)
{
return do_calc_cc(env, cc_op, src, dst, vr);
}
/* insert psw mask and condition code into r1 */
-void HELPER(ipm)(uint32_t cc, uint32_t r1)
+void HELPER(ipm)(CPUS390XState *env, uint32_t cc, uint32_t r1)
{
uint64_t r = env->regs[r1];
@@ -519,13 +518,13 @@ void HELPER(ipm)(uint32_t cc, uint32_t r1)
}
#ifndef CONFIG_USER_ONLY
-void HELPER(load_psw)(uint64_t mask, uint64_t addr)
+void HELPER(load_psw)(CPUS390XState *env, uint64_t mask, uint64_t addr)
{
load_psw(env, mask, addr);
cpu_loop_exit(env);
}
-void HELPER(sacf)(uint64_t a1)
+void HELPER(sacf)(CPUS390XState *env, uint64_t a1)
{
HELPER_LOG("%s: %16" PRIx64 "\n", __func__, a1);
diff --git a/target-s390x/helper.h b/target-s390x/helper.h
index c03cd59..876b88e 100644
--- a/target-s390x/helper.h
+++ b/target-s390x/helper.h
@@ -36,7 +36,7 @@ DEF_HELPER_FLAGS_1(abs_i64, TCG_CALL_PURE|TCG_CALL_CONST, i64, s64)
DEF_HELPER_FLAGS_1(nabs_i64, TCG_CALL_PURE|TCG_CALL_CONST, s64, s64)
DEF_HELPER_3(stcmh, void, i32, i64, i32)
DEF_HELPER_3(icmh, i32, i32, i64, i32)
-DEF_HELPER_2(ipm, void, i32, i32)
+DEF_HELPER_3(ipm, void, env, i32, i32)
DEF_HELPER_FLAGS_3(addc_u32, TCG_CALL_PURE|TCG_CALL_CONST, i32, i32, i32, i32)
DEF_HELPER_FLAGS_3(set_cc_addc_u64, TCG_CALL_PURE|TCG_CALL_CONST, i32, i64, i64, i64)
DEF_HELPER_3(stam, void, i32, i64, i32)
@@ -115,7 +115,7 @@ DEF_HELPER_3(tr, void, i32, i64, i64)
DEF_HELPER_2(servc, i32, i32, i64)
DEF_HELPER_3(diag, i64, i32, i64, i64)
-DEF_HELPER_2(load_psw, void, i64, i64)
+DEF_HELPER_3(load_psw, void, env, i64, i64)
DEF_HELPER_1(program_interrupt, void, i32)
DEF_HELPER_FLAGS_1(stidp, TCG_CALL_CONST, void, i64)
DEF_HELPER_FLAGS_1(spx, TCG_CALL_CONST, void, i64)
@@ -139,14 +139,14 @@ DEF_HELPER_2(csp, i32, i32, i32)
DEF_HELPER_3(mvcs, i32, i64, i64, i64)
DEF_HELPER_3(mvcp, i32, i64, i64, i64)
DEF_HELPER_3(sigp, i32, i64, i32, i64)
-DEF_HELPER_1(sacf, void, i64)
+DEF_HELPER_2(sacf, void, env, i64)
DEF_HELPER_FLAGS_2(ipte, TCG_CALL_CONST, void, i64, i64)
DEF_HELPER_FLAGS_0(ptlb, TCG_CALL_CONST, void)
DEF_HELPER_2(lra, i32, i64, i32)
DEF_HELPER_2(stura, void, i64, i32)
DEF_HELPER_2(cksm, void, i32, i32)
-DEF_HELPER_FLAGS_4(calc_cc, TCG_CALL_PURE|TCG_CALL_CONST,
- i32, i32, i64, i64, i64)
+DEF_HELPER_FLAGS_5(calc_cc, TCG_CALL_PURE|TCG_CALL_CONST,
+ i32, env, i32, i64, i64, i64)
#include "def-helper.h"
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index 2a61e92..1d87272 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -722,7 +722,7 @@ static void gen_op_calc_cc(DisasContext *s)
case CC_OP_NZ_F32:
case CC_OP_NZ_F64:
/* 1 argument */
- gen_helper_calc_cc(cc_op, local_cc_op, dummy, cc_dst, dummy);
+ gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, dummy, cc_dst, dummy);
break;
case CC_OP_ICM:
case CC_OP_LTGT_32:
@@ -735,7 +735,7 @@ static void gen_op_calc_cc(DisasContext *s)
case CC_OP_LTGT_F64:
case CC_OP_SLAG:
/* 2 arguments */
- gen_helper_calc_cc(cc_op, local_cc_op, cc_src, cc_dst, dummy);
+ gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, cc_src, cc_dst, dummy);
break;
case CC_OP_ADD_64:
case CC_OP_ADDU_64:
@@ -746,11 +746,11 @@ static void gen_op_calc_cc(DisasContext *s)
case CC_OP_SUB_32:
case CC_OP_SUBU_32:
/* 3 arguments */
- gen_helper_calc_cc(cc_op, local_cc_op, cc_src, cc_dst, cc_vr);
+ gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, cc_src, cc_dst, cc_vr);
break;
case CC_OP_DYNAMIC:
/* unknown operation - assume 3 arguments and cc_op in env */
- gen_helper_calc_cc(cc_op, cc_op, cc_src, cc_dst, cc_vr);
+ gen_helper_calc_cc(cc_op, cpu_env, cc_op, cc_src, cc_dst, cc_vr);
break;
default:
tcg_abort();
@@ -2628,7 +2628,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
case 0x22: /* IPM R1 [RRE] */
tmp32_1 = tcg_const_i32(r1);
gen_op_calc_cc(s);
- gen_helper_ipm(cc_op, tmp32_1);
+ gen_helper_ipm(cpu_env, cc_op, tmp32_1);
tcg_temp_free_i32(tmp32_1);
break;
case 0x41: /* CKSM R1,R2 [RRE] */
@@ -2916,7 +2916,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
decode_rs(s, insn, &r1, &r3, &b2, &d2);
tmp = get_address(s, 0, b2, d2);
potential_page_fault(s);
- gen_helper_sacf(tmp);
+ gen_helper_sacf(cpu_env, tmp);
tcg_temp_free_i64(tmp);
/* addressing mode has changed, so end the block */
s->pc += ilc * 2;
@@ -2967,7 +2967,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
tcg_gen_qemu_ld64(tmp2, tmp, get_mem_index(s));
tcg_gen_addi_i64(tmp, tmp, 8);
tcg_gen_qemu_ld64(tmp3, tmp, get_mem_index(s));
- gen_helper_load_psw(tmp2, tmp3);
+ gen_helper_load_psw(cpu_env, tmp2, tmp3);
/* we need to keep cc_op intact */
s->is_jmp = DISAS_JUMP;
tcg_temp_free_i64(tmp);
@@ -4527,7 +4527,7 @@ static void disas_s390_insn(DisasContext *s)
tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s));
tcg_gen_addi_i64(tmp, tmp, 4);
tcg_gen_qemu_ld32u(tmp3, tmp, get_mem_index(s));
- gen_helper_load_psw(tmp2, tmp3);
+ gen_helper_load_psw(cpu_env, tmp2, tmp3);
tcg_temp_free_i64(tmp);
tcg_temp_free_i64(tmp2);
tcg_temp_free_i64(tmp3);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 10/12] target-s390x: avoid AREG0 for misc helpers
2012-09-10 11:40 [Qemu-devel] [PULL 00/12] s390 patch queue 2012-09-10 Alexander Graf
` (8 preceding siblings ...)
2012-09-10 11:40 ` [Qemu-devel] [PATCH 09/12] target-s390x: avoid AREG0 for condition code helpers Alexander Graf
@ 2012-09-10 11:40 ` Alexander Graf
2012-09-10 11:40 ` [Qemu-devel] [PATCH 11/12] target-s390x: switch to AREG0 free mode Alexander Graf
` (2 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Alexander Graf @ 2012-09-10 11:40 UTC (permalink / raw)
To: qemu-devel qemu-devel; +Cc: Blue Swirl, Aurelien Jarno
From: Blue Swirl <blauwirbel@gmail.com>
Make misc helpers take a parameter for CPUState instead
of relying on global env.
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
[agraf: fix conflict]
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-s390x/Makefile.objs | 1 -
target-s390x/helper.h | 26 ++++++++++----------
target-s390x/mem_helper.c | 2 +-
target-s390x/misc_helper.c | 55 ++++++++++++++++++++++++--------------------
target-s390x/translate.c | 32 ++++++++++++------------
5 files changed, 60 insertions(+), 56 deletions(-)
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index 736cf33..156d946 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -4,4 +4,3 @@ obj-$(CONFIG_SOFTMMU) += machine.o
obj-$(CONFIG_KVM) += kvm.o
$(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
-$(obj)/misc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
diff --git a/target-s390x/helper.h b/target-s390x/helper.h
index 876b88e..f4e0b37 100644
--- a/target-s390x/helper.h
+++ b/target-s390x/helper.h
@@ -1,6 +1,6 @@
#include "def-helper.h"
-DEF_HELPER_1(exception, void, i32)
+DEF_HELPER_2(exception, void, env, i32)
DEF_HELPER_3(nc, i32, i32, i64, i64)
DEF_HELPER_3(oc, i32, i32, i64, i64)
DEF_HELPER_3(xc, i32, i32, i64, i64)
@@ -113,20 +113,20 @@ DEF_HELPER_FLAGS_1(cvd, TCG_CALL_PURE|TCG_CALL_CONST, i64, s32)
DEF_HELPER_3(unpk, void, i32, i64, i64)
DEF_HELPER_3(tr, void, i32, i64, i64)
-DEF_HELPER_2(servc, i32, i32, i64)
-DEF_HELPER_3(diag, i64, i32, i64, i64)
+DEF_HELPER_3(servc, i32, env, i32, i64)
+DEF_HELPER_4(diag, i64, env, i32, i64, i64)
DEF_HELPER_3(load_psw, void, env, i64, i64)
DEF_HELPER_1(program_interrupt, void, i32)
-DEF_HELPER_FLAGS_1(stidp, TCG_CALL_CONST, void, i64)
-DEF_HELPER_FLAGS_1(spx, TCG_CALL_CONST, void, i64)
+DEF_HELPER_FLAGS_2(stidp, TCG_CALL_CONST, void, env, i64)
+DEF_HELPER_FLAGS_2(spx, TCG_CALL_CONST, void, env, i64)
DEF_HELPER_FLAGS_1(sck, TCG_CALL_CONST, i32, i64)
-DEF_HELPER_1(stck, i32, i64)
-DEF_HELPER_1(stcke, i32, i64)
-DEF_HELPER_FLAGS_1(sckc, TCG_CALL_CONST, void, i64)
-DEF_HELPER_FLAGS_1(stckc, TCG_CALL_CONST, void, i64)
-DEF_HELPER_FLAGS_1(spt, TCG_CALL_CONST, void, i64)
-DEF_HELPER_FLAGS_1(stpt, TCG_CALL_CONST, void, i64)
-DEF_HELPER_3(stsi, i32, i64, i32, i32)
+DEF_HELPER_2(stck, i32, env, i64)
+DEF_HELPER_2(stcke, i32, env, i64)
+DEF_HELPER_FLAGS_2(sckc, TCG_CALL_CONST, void, env, i64)
+DEF_HELPER_FLAGS_2(stckc, TCG_CALL_CONST, void, env, i64)
+DEF_HELPER_FLAGS_2(spt, TCG_CALL_CONST, void, env, i64)
+DEF_HELPER_FLAGS_2(stpt, TCG_CALL_CONST, void, env, i64)
+DEF_HELPER_4(stsi, i32, env, i64, i32, i32)
DEF_HELPER_3(lctl, void, i32, i64, i32)
DEF_HELPER_3(lctlg, void, i32, i64, i32)
DEF_HELPER_3(stctl, void, i32, i64, i32)
@@ -138,7 +138,7 @@ DEF_HELPER_FLAGS_2(rrbe, TCG_CALL_CONST, i32, i32, i64)
DEF_HELPER_2(csp, i32, i32, i32)
DEF_HELPER_3(mvcs, i32, i64, i64, i64)
DEF_HELPER_3(mvcp, i32, i64, i64, i64)
-DEF_HELPER_3(sigp, i32, i64, i32, i64)
+DEF_HELPER_4(sigp, i32, env, i64, i32, i64)
DEF_HELPER_2(sacf, void, env, i64)
DEF_HELPER_FLAGS_2(ipte, TCG_CALL_CONST, void, i64, i64)
DEF_HELPER_FLAGS_0(ptlb, TCG_CALL_CONST, void)
diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c
index 3f8b3ba..52f2602 100644
--- a/target-s390x/mem_helper.c
+++ b/target-s390x/mem_helper.c
@@ -595,7 +595,7 @@ uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
env->psw.addr = ret - 4;
env->int_svc_code = (insn | v1) & 0xff;
env->int_svc_ilc = 4;
- helper_exception(EXCP_SVC);
+ helper_exception(env, EXCP_SVC);
} else if ((insn & 0xff00) == 0xbf00) {
uint32_t insn2, r1, r3, b2, d2;
diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
index 1d5137f..ced26c6 100644
--- a/target-s390x/misc_helper.c
+++ b/target-s390x/misc_helper.c
@@ -21,7 +21,6 @@
#include "cpu.h"
#include "memory.h"
#include "cputlb.h"
-#include "dyngen-exec.h"
#include "host-utils.h"
#include "helper.h"
#include <string.h>
@@ -32,7 +31,10 @@
#endif
#if !defined(CONFIG_USER_ONLY)
+/* temporarily disabled due to wrapper use */
+#if 0
#include "softmmu_exec.h"
+#endif
#include "sysemu.h"
#endif
@@ -44,7 +46,7 @@
#endif
/* raise an exception */
-void HELPER(exception)(uint32_t excp)
+void HELPER(exception)(CPUS390XState *env, uint32_t excp)
{
HELPER_LOG("%s: exception %d\n", __func__, excp);
env->exception_index = excp;
@@ -112,7 +114,7 @@ int sclp_service_call(CPUS390XState *env, uint32_t sccb, uint64_t code)
}
/* SCLP service call */
-uint32_t HELPER(servc)(uint32_t r1, uint64_t r2)
+uint32_t HELPER(servc)(CPUS390XState *env, uint32_t r1, uint64_t r2)
{
int r;
@@ -125,7 +127,8 @@ uint32_t HELPER(servc)(uint32_t r1, uint64_t r2)
}
/* DIAG */
-uint64_t HELPER(diag)(uint32_t num, uint64_t mem, uint64_t code)
+uint64_t HELPER(diag)(CPUS390XState *env, uint32_t num, uint64_t mem,
+ uint64_t code)
{
uint64_t r;
@@ -155,17 +158,17 @@ uint64_t HELPER(diag)(uint32_t num, uint64_t mem, uint64_t code)
}
/* Store CPU ID */
-void HELPER(stidp)(uint64_t a1)
+void HELPER(stidp)(CPUS390XState *env, uint64_t a1)
{
- stq(a1, env->cpu_num);
+ cpu_stq_data(env, a1, env->cpu_num);
}
/* Set Prefix */
-void HELPER(spx)(uint64_t a1)
+void HELPER(spx)(CPUS390XState *env, uint64_t a1)
{
uint32_t prefix;
- prefix = ldl(a1);
+ prefix = cpu_ldl_data(env, a1);
env->psa = prefix & 0xfffff000;
qemu_log("prefix: %#x\n", prefix);
tlb_flush_page(env, 0);
@@ -191,31 +194,31 @@ static inline uint64_t clock_value(CPUS390XState *env)
}
/* Store Clock */
-uint32_t HELPER(stck)(uint64_t a1)
+uint32_t HELPER(stck)(CPUS390XState *env, uint64_t a1)
{
- stq(a1, clock_value(env));
+ cpu_stq_data(env, a1, clock_value(env));
return 0;
}
/* Store Clock Extended */
-uint32_t HELPER(stcke)(uint64_t a1)
+uint32_t HELPER(stcke)(CPUS390XState *env, uint64_t a1)
{
- stb(a1, 0);
+ cpu_stb_data(env, a1, 0);
/* basically the same value as stck */
- stq(a1 + 1, clock_value(env) | env->cpu_num);
+ cpu_stq_data(env, a1 + 1, clock_value(env) | env->cpu_num);
/* more fine grained than stck */
- stq(a1 + 9, 0);
+ cpu_stq_data(env, a1 + 9, 0);
/* XXX programmable fields */
- stw(a1 + 17, 0);
+ cpu_stw_data(env, a1 + 17, 0);
return 0;
}
/* Set Clock Comparator */
-void HELPER(sckc)(uint64_t a1)
+void HELPER(sckc)(CPUS390XState *env, uint64_t a1)
{
- uint64_t time = ldq(a1);
+ uint64_t time = cpu_ldq_data(env, a1);
if (time == -1ULL) {
return;
@@ -230,16 +233,16 @@ void HELPER(sckc)(uint64_t a1)
}
/* Store Clock Comparator */
-void HELPER(stckc)(uint64_t a1)
+void HELPER(stckc)(CPUS390XState *env, uint64_t a1)
{
/* XXX implement */
- stq(a1, 0);
+ cpu_stq_data(env, a1, 0);
}
/* Set CPU Timer */
-void HELPER(spt)(uint64_t a1)
+void HELPER(spt)(CPUS390XState *env, uint64_t a1)
{
- uint64_t time = ldq(a1);
+ uint64_t time = cpu_ldq_data(env, a1);
if (time == -1ULL) {
return;
@@ -252,14 +255,15 @@ void HELPER(spt)(uint64_t a1)
}
/* Store CPU Timer */
-void HELPER(stpt)(uint64_t a1)
+void HELPER(stpt)(CPUS390XState *env, uint64_t a1)
{
/* XXX implement */
- stq(a1, 0);
+ cpu_stq_data(env, a1, 0);
}
/* Store System Information */
-uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1)
+uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0, uint32_t r0,
+ uint32_t r1)
{
int cc = 0;
int sel1, sel2;
@@ -384,7 +388,8 @@ uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1)
return cc;
}
-uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
+uint32_t HELPER(sigp)(CPUS390XState *env, uint64_t order_code, uint32_t r1,
+ uint64_t cpu_addr)
{
int cc = 0;
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index 1d87272..0c61e63 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -312,7 +312,7 @@ static inline void gen_debug(DisasContext *s)
TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
update_psw_addr(s);
gen_op_calc_cc(s);
- gen_helper_exception(tmp);
+ gen_helper_exception(cpu_env, tmp);
tcg_temp_free_i32(tmp);
s->is_jmp = DISAS_EXCP;
}
@@ -324,7 +324,7 @@ static void gen_illegal_opcode(DisasContext *s, int ilc)
TCGv_i32 tmp = tcg_const_i32(EXCP_SPEC);
update_psw_addr(s);
gen_op_calc_cc(s);
- gen_helper_exception(tmp);
+ gen_helper_exception(cpu_env, tmp);
tcg_temp_free_i32(tmp);
s->is_jmp = DISAS_EXCP;
}
@@ -377,7 +377,7 @@ static void gen_program_exception(DisasContext *s, int ilc, int code)
/* trigger exception */
tmp = tcg_const_i32(EXCP_PGM);
- gen_helper_exception(tmp);
+ gen_helper_exception(cpu_env, tmp);
tcg_temp_free_i32(tmp);
/* end TB here */
@@ -2712,7 +2712,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
decode_rs(s, insn, &r1, &r3, &b2, &d2);
tmp = get_address(s, 0, b2, d2);
potential_page_fault(s);
- gen_helper_stidp(tmp);
+ gen_helper_stidp(cpu_env, tmp);
tcg_temp_free_i64(tmp);
break;
case 0x04: /* SCK D2(B2) [S] */
@@ -2730,7 +2730,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
decode_rs(s, insn, &r1, &r3, &b2, &d2);
tmp = get_address(s, 0, b2, d2);
potential_page_fault(s);
- gen_helper_stck(cc_op, tmp);
+ gen_helper_stck(cc_op, cpu_env, tmp);
set_cc_static(s);
tcg_temp_free_i64(tmp);
break;
@@ -2740,7 +2740,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
decode_rs(s, insn, &r1, &r3, &b2, &d2);
tmp = get_address(s, 0, b2, d2);
potential_page_fault(s);
- gen_helper_sckc(tmp);
+ gen_helper_sckc(cpu_env, tmp);
tcg_temp_free_i64(tmp);
break;
case 0x07: /* STCKC D2(B2) [S] */
@@ -2749,7 +2749,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
decode_rs(s, insn, &r1, &r3, &b2, &d2);
tmp = get_address(s, 0, b2, d2);
potential_page_fault(s);
- gen_helper_stckc(tmp);
+ gen_helper_stckc(cpu_env, tmp);
tcg_temp_free_i64(tmp);
break;
case 0x08: /* SPT D2(B2) [S] */
@@ -2758,7 +2758,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
decode_rs(s, insn, &r1, &r3, &b2, &d2);
tmp = get_address(s, 0, b2, d2);
potential_page_fault(s);
- gen_helper_spt(tmp);
+ gen_helper_spt(cpu_env, tmp);
tcg_temp_free_i64(tmp);
break;
case 0x09: /* STPT D2(B2) [S] */
@@ -2767,7 +2767,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
decode_rs(s, insn, &r1, &r3, &b2, &d2);
tmp = get_address(s, 0, b2, d2);
potential_page_fault(s);
- gen_helper_stpt(tmp);
+ gen_helper_stpt(cpu_env, tmp);
tcg_temp_free_i64(tmp);
break;
case 0x0a: /* SPKA D2(B2) [S] */
@@ -2793,7 +2793,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
decode_rs(s, insn, &r1, &r3, &b2, &d2);
tmp = get_address(s, 0, b2, d2);
potential_page_fault(s);
- gen_helper_spx(tmp);
+ gen_helper_spx(cpu_env, tmp);
tcg_temp_free_i64(tmp);
break;
case 0x11: /* STPX D2(B2) [S] */
@@ -2906,7 +2906,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
decode_rs(s, insn, &r1, &r3, &b2, &d2);
tmp = get_address(s, 0, b2, d2);
potential_page_fault(s);
- gen_helper_stcke(cc_op, tmp);
+ gen_helper_stcke(cc_op, cpu_env, tmp);
set_cc_static(s);
tcg_temp_free_i64(tmp);
break;
@@ -2930,7 +2930,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
tmp32_1 = load_reg32(0);
tmp32_2 = load_reg32(1);
potential_page_fault(s);
- gen_helper_stsi(cc_op, tmp, tmp32_1, tmp32_2);
+ gen_helper_stsi(cc_op, cpu_env, tmp, tmp32_1, tmp32_2);
set_cc_static(s);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32_1);
@@ -2980,7 +2980,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
potential_page_fault(s);
tmp32_1 = load_reg32(r2);
tmp = load_reg(r1);
- gen_helper_servc(cc_op, tmp32_1, tmp);
+ gen_helper_servc(cc_op, cpu_env, tmp32_1, tmp);
set_cc_static(s);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i64(tmp);
@@ -3926,7 +3926,7 @@ static void disas_s390_insn(DisasContext *s)
tmp32_3 = tcg_const_i32(EXCP_SVC);
tcg_gen_st_i32(tmp32_1, cpu_env, offsetof(CPUS390XState, int_svc_code));
tcg_gen_st_i32(tmp32_2, cpu_env, offsetof(CPUS390XState, int_svc_ilc));
- gen_helper_exception(tmp32_3);
+ gen_helper_exception(cpu_env, tmp32_3);
s->is_jmp = DISAS_EXCP;
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
@@ -4543,7 +4543,7 @@ static void disas_s390_insn(DisasContext *s)
tmp32_1 = tcg_const_i32(insn & 0xfff);
tmp2 = load_reg(2);
tmp3 = load_reg(1);
- gen_helper_diag(tmp2, tmp32_1, tmp2, tmp3);
+ gen_helper_diag(tmp2, cpu_env, tmp32_1, tmp2, tmp3);
store_reg(2, tmp2);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i64(tmp2);
@@ -4777,7 +4777,7 @@ static void disas_s390_insn(DisasContext *s)
tmp2 = load_reg(r3);
tmp32_1 = tcg_const_i32(r1);
potential_page_fault(s);
- gen_helper_sigp(cc_op, tmp, tmp32_1, tmp2);
+ gen_helper_sigp(cc_op, cpu_env, tmp, tmp32_1, tmp2);
set_cc_static(s);
tcg_temp_free_i64(tmp);
tcg_temp_free_i64(tmp2);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 11/12] target-s390x: switch to AREG0 free mode
2012-09-10 11:40 [Qemu-devel] [PULL 00/12] s390 patch queue 2012-09-10 Alexander Graf
` (9 preceding siblings ...)
2012-09-10 11:40 ` [Qemu-devel] [PATCH 10/12] target-s390x: avoid AREG0 for misc helpers Alexander Graf
@ 2012-09-10 11:40 ` Alexander Graf
2012-09-10 11:40 ` [Qemu-devel] [PATCH 12/12] tcg/s390: fix ld/st with CONFIG_TCG_PASS_AREG0 Alexander Graf
2012-09-10 13:16 ` [Qemu-devel] [PULL 00/12] s390 patch queue 2012-09-10 Aurelien Jarno
12 siblings, 0 replies; 14+ messages in thread
From: Alexander Graf @ 2012-09-10 11:40 UTC (permalink / raw)
To: qemu-devel qemu-devel; +Cc: Blue Swirl, Aurelien Jarno
From: Blue Swirl <blauwirbel@gmail.com>
Add an explicit CPUState parameter instead of relying on AREG0.
Remove temporary wrappers and switch to AREG0 free mode.
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
[agraf: fix conflicts]
Signed-off-by: Alexander Graf <agraf@suse.de>
---
configure | 2 +-
target-s390x/Makefile.objs | 2 -
target-s390x/cpu.h | 10 --
target-s390x/fpu_helper.c | 3 +-
target-s390x/helper.c | 6 +-
target-s390x/helper.h | 78 +++++-----
target-s390x/mem_helper.c | 338 ++++++++++++++++++++------------------------
target-s390x/misc_helper.c | 3 -
target-s390x/translate.c | 88 ++++++------
9 files changed, 239 insertions(+), 291 deletions(-)
diff --git a/configure b/configure
index d97fd81..a88a465 100755
--- a/configure
+++ b/configure
@@ -3829,7 +3829,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile"
case "$target_arch2" in
- alpha | i386 | or32 | sparc* | x86_64 | xtensa* | ppc*)
+ alpha | i386 | or32 | s390x | sparc* | x86_64 | xtensa* | ppc*)
echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
;;
esac
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index 156d946..e728abf 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -2,5 +2,3 @@ obj-y += translate.o helper.o cpu.o interrupt.o
obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
obj-$(CONFIG_SOFTMMU) += machine.o
obj-$(CONFIG_KVM) += kvm.o
-
-$(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 9b7a2e3..ed81af3 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -1008,14 +1008,4 @@ uint32_t set_cc_nz_f64(float64 v);
/* misc_helper.c */
void program_interrupt(CPUS390XState *env, uint32_t code, int ilc);
-/* temporary wrappers */
-uint32_t cpu_ldub_data(CPUS390XState *env, target_ulong ptr);
-uint32_t cpu_lduw_data(CPUS390XState *env, target_ulong ptr);
-uint32_t cpu_ldl_data(CPUS390XState *env, target_ulong ptr);
-uint64_t cpu_ldq_data(CPUS390XState *env, target_ulong ptr);
-
-void cpu_stb_data(CPUS390XState *env, target_ulong ptr, uint32_t data);
-void cpu_stw_data(CPUS390XState *env, target_ulong ptr, uint32_t data);
-void cpu_stl_data(CPUS390XState *env, target_ulong ptr, uint32_t data);
-void cpu_stq_data(CPUS390XState *env, target_ulong ptr, uint64_t data);
#endif
diff --git a/target-s390x/fpu_helper.c b/target-s390x/fpu_helper.c
index e235419..ee9420d 100644
--- a/target-s390x/fpu_helper.c
+++ b/target-s390x/fpu_helper.c
@@ -21,8 +21,7 @@
#include "cpu.h"
#include "helper.h"
-/* temporarily disabled due to wrapper use */
-#if 0 && !defined(CONFIG_USER_ONLY)
+#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
#endif
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index d98e6d9..a5741ec 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -499,14 +499,14 @@ static void do_program_interrupt(CPUS390XState *env)
switch (ilc) {
case ILC_LATER:
- ilc = get_ilc(ldub_code(env->psw.addr));
+ ilc = get_ilc(cpu_ldub_code(env, env->psw.addr));
break;
case ILC_LATER_INC:
- ilc = get_ilc(ldub_code(env->psw.addr));
+ ilc = get_ilc(cpu_ldub_code(env, env->psw.addr));
env->psw.addr += ilc * 2;
break;
case ILC_LATER_INC_2:
- ilc = get_ilc(ldub_code(env->psw.addr)) * 2;
+ ilc = get_ilc(cpu_ldub_code(env, env->psw.addr)) * 2;
env->psw.addr += ilc;
break;
}
diff --git a/target-s390x/helper.h b/target-s390x/helper.h
index f4e0b37..5419f37 100644
--- a/target-s390x/helper.h
+++ b/target-s390x/helper.h
@@ -1,17 +1,17 @@
#include "def-helper.h"
DEF_HELPER_2(exception, void, env, i32)
-DEF_HELPER_3(nc, i32, i32, i64, i64)
-DEF_HELPER_3(oc, i32, i32, i64, i64)
-DEF_HELPER_3(xc, i32, i32, i64, i64)
-DEF_HELPER_3(mvc, void, i32, i64, i64)
-DEF_HELPER_3(clc, i32, i32, i64, i64)
-DEF_HELPER_2(mvcl, i32, i32, i32)
+DEF_HELPER_4(nc, i32, env, i32, i64, i64)
+DEF_HELPER_4(oc, i32, env, i32, i64, i64)
+DEF_HELPER_4(xc, i32, env, i32, i64, i64)
+DEF_HELPER_4(mvc, void, env, i32, i64, i64)
+DEF_HELPER_4(clc, i32, env, i32, i64, i64)
+DEF_HELPER_3(mvcl, i32, env, i32, i32)
DEF_HELPER_FLAGS_1(set_cc_comp_s32, TCG_CALL_PURE|TCG_CALL_CONST, i32, s32)
DEF_HELPER_FLAGS_1(set_cc_comp_s64, TCG_CALL_PURE|TCG_CALL_CONST, i32, s64)
DEF_HELPER_FLAGS_2(set_cc_icm, TCG_CALL_PURE|TCG_CALL_CONST, i32, i32, i32)
-DEF_HELPER_3(clm, i32, i32, i32, i64)
-DEF_HELPER_3(stcm, void, i32, i32, i64)
+DEF_HELPER_4(clm, i32, env, i32, i32, i64)
+DEF_HELPER_4(stcm, void, env, i32, i32, i64)
DEF_HELPER_3(mlg, void, env, i32, i64)
DEF_HELPER_3(dlg, void, env, i32, i64)
DEF_HELPER_FLAGS_3(set_cc_add64, TCG_CALL_PURE|TCG_CALL_CONST, i32, s64, s64, s64)
@@ -22,27 +22,27 @@ DEF_HELPER_FLAGS_3(set_cc_sub64, TCG_CALL_PURE|TCG_CALL_CONST, i32, s64, s64, s6
DEF_HELPER_FLAGS_3(set_cc_subu64, TCG_CALL_PURE|TCG_CALL_CONST, i32, i64, i64, i64)
DEF_HELPER_FLAGS_3(set_cc_sub32, TCG_CALL_PURE|TCG_CALL_CONST, i32, s32, s32, s32)
DEF_HELPER_FLAGS_3(set_cc_subu32, TCG_CALL_PURE|TCG_CALL_CONST, i32, i32, i32, i32)
-DEF_HELPER_3(srst, i32, i32, i32, i32)
-DEF_HELPER_3(clst, i32, i32, i32, i32)
-DEF_HELPER_3(mvpg, void, i64, i64, i64)
-DEF_HELPER_3(mvst, void, i32, i32, i32)
-DEF_HELPER_3(csg, i32, i32, i64, i32)
-DEF_HELPER_3(cdsg, i32, i32, i64, i32)
-DEF_HELPER_3(cs, i32, i32, i64, i32)
-DEF_HELPER_4(ex, i32, i32, i64, i64, i64)
+DEF_HELPER_4(srst, i32, env, i32, i32, i32)
+DEF_HELPER_4(clst, i32, env, i32, i32, i32)
+DEF_HELPER_4(mvpg, void, env, i64, i64, i64)
+DEF_HELPER_4(mvst, void, env, i32, i32, i32)
+DEF_HELPER_4(csg, i32, env, i32, i64, i32)
+DEF_HELPER_4(cdsg, i32, env, i32, i64, i32)
+DEF_HELPER_4(cs, i32, env, i32, i64, i32)
+DEF_HELPER_5(ex, i32, env, i32, i64, i64, i64)
DEF_HELPER_FLAGS_1(abs_i32, TCG_CALL_PURE|TCG_CALL_CONST, i32, s32)
DEF_HELPER_FLAGS_1(nabs_i32, TCG_CALL_PURE|TCG_CALL_CONST, s32, s32)
DEF_HELPER_FLAGS_1(abs_i64, TCG_CALL_PURE|TCG_CALL_CONST, i64, s64)
DEF_HELPER_FLAGS_1(nabs_i64, TCG_CALL_PURE|TCG_CALL_CONST, s64, s64)
-DEF_HELPER_3(stcmh, void, i32, i64, i32)
-DEF_HELPER_3(icmh, i32, i32, i64, i32)
+DEF_HELPER_4(stcmh, void, env, i32, i64, i32)
+DEF_HELPER_4(icmh, i32, env, i32, i64, i32)
DEF_HELPER_3(ipm, void, env, i32, i32)
DEF_HELPER_FLAGS_3(addc_u32, TCG_CALL_PURE|TCG_CALL_CONST, i32, i32, i32, i32)
DEF_HELPER_FLAGS_3(set_cc_addc_u64, TCG_CALL_PURE|TCG_CALL_CONST, i32, i64, i64, i64)
-DEF_HELPER_3(stam, void, i32, i64, i32)
-DEF_HELPER_3(lam, void, i32, i64, i32)
-DEF_HELPER_3(mvcle, i32, i32, i64, i32)
-DEF_HELPER_3(clcle, i32, i32, i64, i32)
+DEF_HELPER_4(stam, void, env, i32, i64, i32)
+DEF_HELPER_4(lam, void, env, i32, i64, i32)
+DEF_HELPER_4(mvcle, i32, env, i32, i64, i32)
+DEF_HELPER_4(clcle, i32, env, i32, i64, i32)
DEF_HELPER_4(slb, i32, env, i32, i32, i32)
DEF_HELPER_5(slbg, i32, env, i32, i32, i64, i64)
DEF_HELPER_3(cefbr, void, env, i32, s32)
@@ -110,8 +110,8 @@ DEF_HELPER_FLAGS_3(tcxb, TCG_CALL_PURE, i32, env, i32, i64)
DEF_HELPER_3(flogr, i32, env, i32, i64)
DEF_HELPER_3(sqdbr, void, env, i32, i32)
DEF_HELPER_FLAGS_1(cvd, TCG_CALL_PURE|TCG_CALL_CONST, i64, s32)
-DEF_HELPER_3(unpk, void, i32, i64, i64)
-DEF_HELPER_3(tr, void, i32, i64, i64)
+DEF_HELPER_4(unpk, void, env, i32, i64, i64)
+DEF_HELPER_4(tr, void, env, i32, i64, i64)
DEF_HELPER_3(servc, i32, env, i32, i64)
DEF_HELPER_4(diag, i64, env, i32, i64, i64)
@@ -127,24 +127,24 @@ DEF_HELPER_FLAGS_2(stckc, TCG_CALL_CONST, void, env, i64)
DEF_HELPER_FLAGS_2(spt, TCG_CALL_CONST, void, env, i64)
DEF_HELPER_FLAGS_2(stpt, TCG_CALL_CONST, void, env, i64)
DEF_HELPER_4(stsi, i32, env, i64, i32, i32)
-DEF_HELPER_3(lctl, void, i32, i64, i32)
-DEF_HELPER_3(lctlg, void, i32, i64, i32)
-DEF_HELPER_3(stctl, void, i32, i64, i32)
-DEF_HELPER_3(stctg, void, i32, i64, i32)
+DEF_HELPER_4(lctl, void, env, i32, i64, i32)
+DEF_HELPER_4(lctlg, void, env, i32, i64, i32)
+DEF_HELPER_4(stctl, void, env, i32, i64, i32)
+DEF_HELPER_4(stctg, void, env, i32, i64, i32)
DEF_HELPER_FLAGS_2(tprot, TCG_CALL_CONST, i32, i64, i64)
-DEF_HELPER_FLAGS_1(iske, TCG_CALL_PURE|TCG_CALL_CONST, i64, i64)
-DEF_HELPER_FLAGS_2(sske, TCG_CALL_CONST, void, i32, i64)
-DEF_HELPER_FLAGS_2(rrbe, TCG_CALL_CONST, i32, i32, i64)
-DEF_HELPER_2(csp, i32, i32, i32)
-DEF_HELPER_3(mvcs, i32, i64, i64, i64)
-DEF_HELPER_3(mvcp, i32, i64, i64, i64)
+DEF_HELPER_FLAGS_2(iske, TCG_CALL_PURE|TCG_CALL_CONST, i64, env, i64)
+DEF_HELPER_FLAGS_3(sske, TCG_CALL_CONST, void, env, i32, i64)
+DEF_HELPER_FLAGS_3(rrbe, TCG_CALL_CONST, i32, env, i32, i64)
+DEF_HELPER_3(csp, i32, env, i32, i32)
+DEF_HELPER_4(mvcs, i32, env, i64, i64, i64)
+DEF_HELPER_4(mvcp, i32, env, i64, i64, i64)
DEF_HELPER_4(sigp, i32, env, i64, i32, i64)
DEF_HELPER_2(sacf, void, env, i64)
-DEF_HELPER_FLAGS_2(ipte, TCG_CALL_CONST, void, i64, i64)
-DEF_HELPER_FLAGS_0(ptlb, TCG_CALL_CONST, void)
-DEF_HELPER_2(lra, i32, i64, i32)
-DEF_HELPER_2(stura, void, i64, i32)
-DEF_HELPER_2(cksm, void, i32, i32)
+DEF_HELPER_FLAGS_3(ipte, TCG_CALL_CONST, void, env, i64, i64)
+DEF_HELPER_FLAGS_1(ptlb, TCG_CALL_CONST, void, env)
+DEF_HELPER_3(lra, i32, env, i64, i32)
+DEF_HELPER_3(stura, void, env, i64, i32)
+DEF_HELPER_3(cksm, void, env, i32, i32)
DEF_HELPER_FLAGS_5(calc_cc, TCG_CALL_PURE|TCG_CALL_CONST,
i32, env, i32, i64, i64, i64)
diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c
index 52f2602..b21b37c 100644
--- a/target-s390x/mem_helper.c
+++ b/target-s390x/mem_helper.c
@@ -19,7 +19,6 @@
*/
#include "cpu.h"
-#include "dyngen-exec.h"
#include "helper.h"
/*****************************************************************************/
@@ -45,15 +44,12 @@
NULL, it means that the function was called in C code (i.e. not
from generated code or from helper.c) */
/* XXX: fix it to restore all registers */
-void tlb_fill(CPUS390XState *env1, target_ulong addr, int is_write, int mmu_idx,
+void tlb_fill(CPUS390XState *env, target_ulong addr, int is_write, int mmu_idx,
uintptr_t retaddr)
{
TranslationBlock *tb;
- CPUS390XState *saved_env;
int ret;
- saved_env = env;
- env = env1;
ret = cpu_s390x_handle_mmu_fault(env, addr, is_write, mmu_idx);
if (unlikely(ret != 0)) {
if (likely(retaddr)) {
@@ -67,7 +63,6 @@ void tlb_fill(CPUS390XState *env1, target_ulong addr, int is_write, int mmu_idx,
}
cpu_loop_exit(env);
}
- env = saved_env;
}
#endif
@@ -90,7 +85,7 @@ static void mvc_fast_memset(CPUS390XState *env, uint32_t l, uint64_t dest,
int flags;
if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) {
- stb(dest, byte);
+ cpu_stb_data(env, dest, byte);
cpu_abort(env, "should never reach here");
}
dest_phys |= dest & ~TARGET_PAGE_MASK;
@@ -114,13 +109,13 @@ static void mvc_fast_memmove(CPUS390XState *env, uint32_t l, uint64_t dest,
int flags;
if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) {
- stb(dest, 0);
+ cpu_stb_data(env, dest, 0);
cpu_abort(env, "should never reach here");
}
dest_phys |= dest & ~TARGET_PAGE_MASK;
if (mmu_translate(env, src, 0, asc, &src_phys, &flags)) {
- ldub(src);
+ cpu_ldub_data(env, src);
cpu_abort(env, "should never reach here");
}
src_phys |= src & ~TARGET_PAGE_MASK;
@@ -136,7 +131,8 @@ static void mvc_fast_memmove(CPUS390XState *env, uint32_t l, uint64_t dest,
#endif
/* and on array */
-uint32_t HELPER(nc)(uint32_t l, uint64_t dest, uint64_t src)
+uint32_t HELPER(nc)(CPUS390XState *env, uint32_t l, uint64_t dest,
+ uint64_t src)
{
int i;
unsigned char x;
@@ -145,17 +141,18 @@ uint32_t HELPER(nc)(uint32_t l, uint64_t dest, uint64_t src)
HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
__func__, l, dest, src);
for (i = 0; i <= l; i++) {
- x = ldub(dest + i) & ldub(src + i);
+ x = cpu_ldub_data(env, dest + i) & cpu_ldub_data(env, src + i);
if (x) {
cc = 1;
}
- stb(dest + i, x);
+ cpu_stb_data(env, dest + i, x);
}
return cc;
}
/* xor on array */
-uint32_t HELPER(xc)(uint32_t l, uint64_t dest, uint64_t src)
+uint32_t HELPER(xc)(CPUS390XState *env, uint32_t l, uint64_t dest,
+ uint64_t src)
{
int i;
unsigned char x;
@@ -179,17 +176,18 @@ uint32_t HELPER(xc)(uint32_t l, uint64_t dest, uint64_t src)
#endif
for (i = 0; i <= l; i++) {
- x = ldub(dest + i) ^ ldub(src + i);
+ x = cpu_ldub_data(env, dest + i) ^ cpu_ldub_data(env, src + i);
if (x) {
cc = 1;
}
- stb(dest + i, x);
+ cpu_stb_data(env, dest + i, x);
}
return cc;
}
/* or on array */
-uint32_t HELPER(oc)(uint32_t l, uint64_t dest, uint64_t src)
+uint32_t HELPER(oc)(CPUS390XState *env, uint32_t l, uint64_t dest,
+ uint64_t src)
{
int i;
unsigned char x;
@@ -198,17 +196,17 @@ uint32_t HELPER(oc)(uint32_t l, uint64_t dest, uint64_t src)
HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
__func__, l, dest, src);
for (i = 0; i <= l; i++) {
- x = ldub(dest + i) | ldub(src + i);
+ x = cpu_ldub_data(env, dest + i) | cpu_ldub_data(env, src + i);
if (x) {
cc = 1;
}
- stb(dest + i, x);
+ cpu_stb_data(env, dest + i, x);
}
return cc;
}
/* memmove */
-void HELPER(mvc)(uint32_t l, uint64_t dest, uint64_t src)
+void HELPER(mvc)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
{
int i = 0;
int x = 0;
@@ -222,7 +220,7 @@ void HELPER(mvc)(uint32_t l, uint64_t dest, uint64_t src)
(src & TARGET_PAGE_MASK) == ((src + l) & TARGET_PAGE_MASK) &&
(dest & TARGET_PAGE_MASK) == ((dest + l) & TARGET_PAGE_MASK)) {
if (dest == (src + 1)) {
- mvc_fast_memset(env, l + 1, dest, ldub(src));
+ mvc_fast_memset(env, l + 1, dest, cpu_ldub_data(env, src));
return;
} else if ((src & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) {
mvc_fast_memmove(env, l + 1, dest, src);
@@ -231,7 +229,7 @@ void HELPER(mvc)(uint32_t l, uint64_t dest, uint64_t src)
}
#else
if (dest == (src + 1)) {
- memset(g2h(dest), ldub(src), l + 1);
+ memset(g2h(dest), cpu_ldub_data(env, src), l + 1);
return;
} else {
memmove(g2h(dest), g2h(src), l + 1);
@@ -242,19 +240,19 @@ void HELPER(mvc)(uint32_t l, uint64_t dest, uint64_t src)
/* handle the parts that fit into 8-byte loads/stores */
if (dest != (src + 1)) {
for (i = 0; i < l_64; i++) {
- stq(dest + x, ldq(src + x));
+ cpu_stq_data(env, dest + x, cpu_ldq_data(env, src + x));
x += 8;
}
}
/* slow version crossing pages with byte accesses */
for (i = x; i <= l; i++) {
- stb(dest + i, ldub(src + i));
+ cpu_stb_data(env, dest + i, cpu_ldub_data(env, src + i));
}
}
/* compare unsigned byte arrays */
-uint32_t HELPER(clc)(uint32_t l, uint64_t s1, uint64_t s2)
+uint32_t HELPER(clc)(CPUS390XState *env, uint32_t l, uint64_t s1, uint64_t s2)
{
int i;
unsigned char x, y;
@@ -263,8 +261,8 @@ uint32_t HELPER(clc)(uint32_t l, uint64_t s1, uint64_t s2)
HELPER_LOG("%s l %d s1 %" PRIx64 " s2 %" PRIx64 "\n",
__func__, l, s1, s2);
for (i = 0; i <= l; i++) {
- x = ldub(s1 + i);
- y = ldub(s2 + i);
+ x = cpu_ldub_data(env, s1 + i);
+ y = cpu_ldub_data(env, s2 + i);
HELPER_LOG("%02x (%c)/%02x (%c) ", x, x, y, y);
if (x < y) {
cc = 1;
@@ -281,7 +279,8 @@ uint32_t HELPER(clc)(uint32_t l, uint64_t s1, uint64_t s2)
}
/* compare logical under mask */
-uint32_t HELPER(clm)(uint32_t r1, uint32_t mask, uint64_t addr)
+uint32_t HELPER(clm)(CPUS390XState *env, uint32_t r1, uint32_t mask,
+ uint64_t addr)
{
uint8_t r, d;
uint32_t cc;
@@ -291,7 +290,7 @@ uint32_t HELPER(clm)(uint32_t r1, uint32_t mask, uint64_t addr)
cc = 0;
while (mask) {
if (mask & 8) {
- d = ldub(addr);
+ d = cpu_ldub_data(env, addr);
r = (r1 & 0xff000000UL) >> 24;
HELPER_LOG("mask 0x%x %02x/%02x (0x%" PRIx64 ") ", mask, r, d,
addr);
@@ -312,7 +311,8 @@ uint32_t HELPER(clm)(uint32_t r1, uint32_t mask, uint64_t addr)
}
/* store character under mask */
-void HELPER(stcm)(uint32_t r1, uint32_t mask, uint64_t addr)
+void HELPER(stcm)(CPUS390XState *env, uint32_t r1, uint32_t mask,
+ uint64_t addr)
{
uint8_t r;
@@ -321,7 +321,7 @@ void HELPER(stcm)(uint32_t r1, uint32_t mask, uint64_t addr)
while (mask) {
if (mask & 8) {
r = (r1 & 0xff000000UL) >> 24;
- stb(addr, r);
+ cpu_stb_data(env, addr, r);
HELPER_LOG("mask 0x%x %02x (0x%lx) ", mask, r, addr);
addr++;
}
@@ -331,7 +331,7 @@ void HELPER(stcm)(uint32_t r1, uint32_t mask, uint64_t addr)
HELPER_LOG("\n");
}
-static inline uint64_t get_address(int x2, int b2, int d2)
+static inline uint64_t get_address(CPUS390XState *env, int x2, int b2, int d2)
{
uint64_t r = d2;
@@ -351,7 +351,7 @@ static inline uint64_t get_address(int x2, int b2, int d2)
return r;
}
-static inline uint64_t get_address_31fix(int reg)
+static inline uint64_t get_address_31fix(CPUS390XState *env, int reg)
{
uint64_t r = env->regs[reg];
@@ -364,18 +364,18 @@ static inline uint64_t get_address_31fix(int reg)
}
/* search string (c is byte to search, r2 is string, r1 end of string) */
-uint32_t HELPER(srst)(uint32_t c, uint32_t r1, uint32_t r2)
+uint32_t HELPER(srst)(CPUS390XState *env, uint32_t c, uint32_t r1, uint32_t r2)
{
uint64_t i;
uint32_t cc = 2;
- uint64_t str = get_address_31fix(r2);
- uint64_t end = get_address_31fix(r1);
+ uint64_t str = get_address_31fix(env, r2);
+ uint64_t end = get_address_31fix(env, r1);
HELPER_LOG("%s: c %d *r1 0x%" PRIx64 " *r2 0x%" PRIx64 "\n", __func__,
c, env->regs[r1], env->regs[r2]);
for (i = str; i != end; i++) {
- if (ldub(i) == c) {
+ if (cpu_ldub_data(env, i) == c) {
env->regs[r1] = i;
cc = 1;
break;
@@ -386,10 +386,10 @@ uint32_t HELPER(srst)(uint32_t c, uint32_t r1, uint32_t r2)
}
/* unsigned string compare (c is string terminator) */
-uint32_t HELPER(clst)(uint32_t c, uint32_t r1, uint32_t r2)
+uint32_t HELPER(clst)(CPUS390XState *env, uint32_t c, uint32_t r1, uint32_t r2)
{
- uint64_t s1 = get_address_31fix(r1);
- uint64_t s2 = get_address_31fix(r2);
+ uint64_t s1 = get_address_31fix(env, r1);
+ uint64_t s2 = get_address_31fix(env, r2);
uint8_t v1, v2;
uint32_t cc;
@@ -401,8 +401,8 @@ uint32_t HELPER(clst)(uint32_t c, uint32_t r1, uint32_t r2)
}
#endif
for (;;) {
- v1 = ldub(s1);
- v2 = ldub(s2);
+ v1 = cpu_ldub_data(env, s1);
+ v2 = cpu_ldub_data(env, s2);
if ((v1 == c || v2 == c) || (v1 != v2)) {
break;
}
@@ -422,14 +422,14 @@ uint32_t HELPER(clst)(uint32_t c, uint32_t r1, uint32_t r2)
}
/* move page */
-void HELPER(mvpg)(uint64_t r0, uint64_t r1, uint64_t r2)
+void HELPER(mvpg)(CPUS390XState *env, uint64_t r0, uint64_t r1, uint64_t r2)
{
/* XXX missing r0 handling */
#ifdef CONFIG_USER_ONLY
int i;
for (i = 0; i < TARGET_PAGE_SIZE; i++) {
- stb(r1 + i, ldub(r2 + i));
+ cpu_stb_data(env, r1 + i, cpu_ldub_data(env, r2 + i));
}
#else
mvc_fast_memmove(env, TARGET_PAGE_SIZE, r1, r2);
@@ -437,10 +437,10 @@ void HELPER(mvpg)(uint64_t r0, uint64_t r1, uint64_t r2)
}
/* string copy (c is string terminator) */
-void HELPER(mvst)(uint32_t c, uint32_t r1, uint32_t r2)
+void HELPER(mvst)(CPUS390XState *env, uint32_t c, uint32_t r1, uint32_t r2)
{
- uint64_t dest = get_address_31fix(r1);
- uint64_t src = get_address_31fix(r2);
+ uint64_t dest = get_address_31fix(env, r1);
+ uint64_t src = get_address_31fix(env, r2);
uint8_t v;
c = c & 0xff;
@@ -451,8 +451,8 @@ void HELPER(mvst)(uint32_t c, uint32_t r1, uint32_t r2)
}
#endif
for (;;) {
- v = ldub(src);
- stb(dest, v);
+ v = cpu_ldub_data(env, src);
+ cpu_stb_data(env, dest, v);
if (v == c) {
break;
}
@@ -463,15 +463,15 @@ void HELPER(mvst)(uint32_t c, uint32_t r1, uint32_t r2)
}
/* compare and swap 64-bit */
-uint32_t HELPER(csg)(uint32_t r1, uint64_t a2, uint32_t r3)
+uint32_t HELPER(csg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
{
/* FIXME: locking? */
uint32_t cc;
- uint64_t v2 = ldq(a2);
+ uint64_t v2 = cpu_ldq_data(env, a2);
if (env->regs[r1] == v2) {
cc = 0;
- stq(a2, env->regs[r3]);
+ cpu_stq_data(env, a2, env->regs[r3]);
} else {
cc = 1;
env->regs[r1] = v2;
@@ -480,19 +480,19 @@ uint32_t HELPER(csg)(uint32_t r1, uint64_t a2, uint32_t r3)
}
/* compare double and swap 64-bit */
-uint32_t HELPER(cdsg)(uint32_t r1, uint64_t a2, uint32_t r3)
+uint32_t HELPER(cdsg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
{
/* FIXME: locking? */
uint32_t cc;
- uint64_t v2_hi = ldq(a2);
- uint64_t v2_lo = ldq(a2 + 8);
+ uint64_t v2_hi = cpu_ldq_data(env, a2);
+ uint64_t v2_lo = cpu_ldq_data(env, a2 + 8);
uint64_t v1_hi = env->regs[r1];
uint64_t v1_lo = env->regs[r1 + 1];
if ((v1_hi == v2_hi) && (v1_lo == v2_lo)) {
cc = 0;
- stq(a2, env->regs[r3]);
- stq(a2 + 8, env->regs[r3 + 1]);
+ cpu_stq_data(env, a2, env->regs[r3]);
+ cpu_stq_data(env, a2 + 8, env->regs[r3 + 1]);
} else {
cc = 1;
env->regs[r1] = v2_hi;
@@ -503,16 +503,16 @@ uint32_t HELPER(cdsg)(uint32_t r1, uint64_t a2, uint32_t r3)
}
/* compare and swap 32-bit */
-uint32_t HELPER(cs)(uint32_t r1, uint64_t a2, uint32_t r3)
+uint32_t HELPER(cs)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
{
/* FIXME: locking? */
uint32_t cc;
- uint32_t v2 = ldl(a2);
+ uint32_t v2 = cpu_ldl_data(env, a2);
HELPER_LOG("%s: r1 %d a2 0x%lx r3 %d\n", __func__, r1, a2, r3);
if (((uint32_t)env->regs[r1]) == v2) {
cc = 0;
- stl(a2, (uint32_t)env->regs[r3]);
+ cpu_stl_data(env, a2, (uint32_t)env->regs[r3]);
} else {
cc = 1;
env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | v2;
@@ -520,7 +520,8 @@ uint32_t HELPER(cs)(uint32_t r1, uint64_t a2, uint32_t r3)
return cc;
}
-static uint32_t helper_icm(uint32_t r1, uint64_t address, uint32_t mask)
+static uint32_t helper_icm(CPUS390XState *env, uint32_t r1, uint64_t address,
+ uint32_t mask)
{
int pos = 24; /* top of the lower half of r1 */
uint64_t rmask = 0xff000000ULL;
@@ -531,7 +532,7 @@ static uint32_t helper_icm(uint32_t r1, uint64_t address, uint32_t mask)
while (mask) {
if (mask & 8) {
env->regs[r1] &= ~rmask;
- val = ldub(address);
+ val = cpu_ldub_data(env, address);
if ((val & 0x80) && !ccd) {
cc = 1;
}
@@ -557,9 +558,10 @@ static uint32_t helper_icm(uint32_t r1, uint64_t address, uint32_t mask)
in other words: tricky...
currently implemented by interpreting the cases it is most commonly used in
*/
-uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
+uint32_t HELPER(ex)(CPUS390XState *env, uint32_t cc, uint64_t v1,
+ uint64_t addr, uint64_t ret)
{
- uint16_t insn = lduw_code(addr);
+ uint16_t insn = cpu_lduw_code(env, addr);
HELPER_LOG("%s: v1 0x%lx addr 0x%lx insn 0x%x\n", __func__, v1, addr,
insn);
@@ -567,23 +569,27 @@ uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
uint32_t l, insn2, b1, b2, d1, d2;
l = v1 & 0xff;
- insn2 = ldl_code(addr + 2);
+ insn2 = cpu_ldl_code(env, addr + 2);
b1 = (insn2 >> 28) & 0xf;
b2 = (insn2 >> 12) & 0xf;
d1 = (insn2 >> 16) & 0xfff;
d2 = insn2 & 0xfff;
switch (insn & 0xf00) {
case 0x200:
- helper_mvc(l, get_address(0, b1, d1), get_address(0, b2, d2));
+ helper_mvc(env, l, get_address(env, 0, b1, d1),
+ get_address(env, 0, b2, d2));
break;
case 0x500:
- cc = helper_clc(l, get_address(0, b1, d1), get_address(0, b2, d2));
+ cc = helper_clc(env, l, get_address(env, 0, b1, d1),
+ get_address(env, 0, b2, d2));
break;
case 0x700:
- cc = helper_xc(l, get_address(0, b1, d1), get_address(0, b2, d2));
+ cc = helper_xc(env, l, get_address(env, 0, b1, d1),
+ get_address(env, 0, b2, d2));
break;
case 0xc00:
- helper_tr(l, get_address(0, b1, d1), get_address(0, b2, d2));
+ helper_tr(env, l, get_address(env, 0, b1, d1),
+ get_address(env, 0, b2, d2));
break;
default:
goto abort;
@@ -599,12 +605,12 @@ uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
} else if ((insn & 0xff00) == 0xbf00) {
uint32_t insn2, r1, r3, b2, d2;
- insn2 = ldl_code(addr + 2);
+ insn2 = cpu_ldl_code(env, addr + 2);
r1 = (insn2 >> 20) & 0xf;
r3 = (insn2 >> 16) & 0xf;
b2 = (insn2 >> 12) & 0xf;
d2 = insn2 & 0xfff;
- cc = helper_icm(r1, get_address(0, b2, d2), r3);
+ cc = helper_icm(env, r1, get_address(env, 0, b2, d2), r3);
} else {
abort:
cpu_abort(env, "EXECUTE on instruction prefix 0x%x not implemented\n",
@@ -614,13 +620,14 @@ uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
}
/* store character under mask high operates on the upper half of r1 */
-void HELPER(stcmh)(uint32_t r1, uint64_t address, uint32_t mask)
+void HELPER(stcmh)(CPUS390XState *env, uint32_t r1, uint64_t address,
+ uint32_t mask)
{
int pos = 56; /* top of the upper half of r1 */
while (mask) {
if (mask & 8) {
- stb(address, (env->regs[r1] >> pos) & 0xff);
+ cpu_stb_data(env, address, (env->regs[r1] >> pos) & 0xff);
address++;
}
mask = (mask << 1) & 0xf;
@@ -630,7 +637,8 @@ void HELPER(stcmh)(uint32_t r1, uint64_t address, uint32_t mask)
/* insert character under mask high; same as icm, but operates on the
upper half of r1 */
-uint32_t HELPER(icmh)(uint32_t r1, uint64_t address, uint32_t mask)
+uint32_t HELPER(icmh)(CPUS390XState *env, uint32_t r1, uint64_t address,
+ uint32_t mask)
{
int pos = 56; /* top of the upper half of r1 */
uint64_t rmask = 0xff00000000000000ULL;
@@ -641,7 +649,7 @@ uint32_t HELPER(icmh)(uint32_t r1, uint64_t address, uint32_t mask)
while (mask) {
if (mask & 8) {
env->regs[r1] &= ~rmask;
- val = ldub(address);
+ val = cpu_ldub_data(env, address);
if ((val & 0x80) && !ccd) {
cc = 1;
}
@@ -661,12 +669,12 @@ uint32_t HELPER(icmh)(uint32_t r1, uint64_t address, uint32_t mask)
}
/* load access registers r1 to r3 from memory at a2 */
-void HELPER(lam)(uint32_t r1, uint64_t a2, uint32_t r3)
+void HELPER(lam)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
{
int i;
for (i = r1;; i = (i + 1) % 16) {
- env->aregs[i] = ldl(a2);
+ env->aregs[i] = cpu_ldl_data(env, a2);
a2 += 4;
if (i == r3) {
@@ -676,12 +684,12 @@ void HELPER(lam)(uint32_t r1, uint64_t a2, uint32_t r3)
}
/* store access registers r1 to r3 in memory at a2 */
-void HELPER(stam)(uint32_t r1, uint64_t a2, uint32_t r3)
+void HELPER(stam)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
{
int i;
for (i = r1;; i = (i + 1) % 16) {
- stl(a2, env->aregs[i]);
+ cpu_stl_data(env, a2, env->aregs[i]);
a2 += 4;
if (i == r3) {
@@ -691,12 +699,12 @@ void HELPER(stam)(uint32_t r1, uint64_t a2, uint32_t r3)
}
/* move long */
-uint32_t HELPER(mvcl)(uint32_t r1, uint32_t r2)
+uint32_t HELPER(mvcl)(CPUS390XState *env, uint32_t r1, uint32_t r2)
{
uint64_t destlen = env->regs[r1 + 1] & 0xffffff;
- uint64_t dest = get_address_31fix(r1);
+ uint64_t dest = get_address_31fix(env, r1);
uint64_t srclen = env->regs[r2 + 1] & 0xffffff;
- uint64_t src = get_address_31fix(r2);
+ uint64_t src = get_address_31fix(env, r2);
uint8_t pad = src >> 24;
uint8_t v;
uint32_t cc;
@@ -714,12 +722,12 @@ uint32_t HELPER(mvcl)(uint32_t r1, uint32_t r2)
}
for (; destlen && srclen; src++, dest++, destlen--, srclen--) {
- v = ldub(src);
- stb(dest, v);
+ v = cpu_ldub_data(env, src);
+ cpu_stb_data(env, dest, v);
}
for (; destlen; dest++, destlen--) {
- stb(dest, pad);
+ cpu_stb_data(env, dest, pad);
}
env->regs[r1 + 1] = destlen;
@@ -732,7 +740,8 @@ uint32_t HELPER(mvcl)(uint32_t r1, uint32_t r2)
}
/* move long extended another memcopy insn with more bells and whistles */
-uint32_t HELPER(mvcle)(uint32_t r1, uint64_t a2, uint32_t r3)
+uint32_t HELPER(mvcle)(CPUS390XState *env, uint32_t r1, uint64_t a2,
+ uint32_t r3)
{
uint64_t destlen = env->regs[r1 + 1];
uint64_t dest = env->regs[r1];
@@ -762,12 +771,12 @@ uint32_t HELPER(mvcle)(uint32_t r1, uint64_t a2, uint32_t r3)
}
for (; destlen && srclen; src++, dest++, destlen--, srclen--) {
- v = ldub(src);
- stb(dest, v);
+ v = cpu_ldub_data(env, src);
+ cpu_stb_data(env, dest, v);
}
for (; destlen; dest++, destlen--) {
- stb(dest, pad);
+ cpu_stb_data(env, dest, pad);
}
env->regs[r1 + 1] = destlen;
@@ -781,12 +790,13 @@ uint32_t HELPER(mvcle)(uint32_t r1, uint64_t a2, uint32_t r3)
}
/* compare logical long extended memcompare insn with padding */
-uint32_t HELPER(clcle)(uint32_t r1, uint64_t a2, uint32_t r3)
+uint32_t HELPER(clcle)(CPUS390XState *env, uint32_t r1, uint64_t a2,
+ uint32_t r3)
{
uint64_t destlen = env->regs[r1 + 1];
- uint64_t dest = get_address_31fix(r1);
+ uint64_t dest = get_address_31fix(env, r1);
uint64_t srclen = env->regs[r3 + 1];
- uint64_t src = get_address_31fix(r3);
+ uint64_t src = get_address_31fix(env, r3);
uint8_t pad = a2 & 0xff;
uint8_t v1 = 0, v2 = 0;
uint32_t cc = 0;
@@ -800,8 +810,8 @@ uint32_t HELPER(clcle)(uint32_t r1, uint64_t a2, uint32_t r3)
}
for (; destlen || srclen; src++, dest++, destlen--, srclen--) {
- v1 = srclen ? ldub(src) : pad;
- v2 = destlen ? ldub(dest) : pad;
+ v1 = srclen ? cpu_ldub_data(env, src) : pad;
+ v2 = destlen ? cpu_ldub_data(env, dest) : pad;
if (v1 != v2) {
cc = (v1 < v2) ? 1 : 2;
break;
@@ -818,14 +828,14 @@ uint32_t HELPER(clcle)(uint32_t r1, uint64_t a2, uint32_t r3)
}
/* checksum */
-void HELPER(cksm)(uint32_t r1, uint32_t r2)
+void HELPER(cksm)(CPUS390XState *env, uint32_t r1, uint32_t r2)
{
- uint64_t src = get_address_31fix(r2);
+ uint64_t src = get_address_31fix(env, r2);
uint64_t src_len = env->regs[(r2 + 1) & 15];
uint64_t cksm = (uint32_t)env->regs[r1];
while (src_len >= 4) {
- cksm += ldl(src);
+ cksm += cpu_ldl_data(env, src);
/* move to next word */
src_len -= 4;
@@ -836,14 +846,14 @@ void HELPER(cksm)(uint32_t r1, uint32_t r2)
case 0:
break;
case 1:
- cksm += ldub(src) << 24;
+ cksm += cpu_ldub_data(env, src) << 24;
break;
case 2:
- cksm += lduw(src) << 16;
+ cksm += cpu_lduw_data(env, src) << 16;
break;
case 3:
- cksm += lduw(src) << 16;
- cksm += ldub(src + 2) << 8;
+ cksm += cpu_lduw_data(env, src) << 16;
+ cksm += cpu_ldub_data(env, src + 2) << 8;
break;
}
@@ -856,7 +866,8 @@ void HELPER(cksm)(uint32_t r1, uint32_t r2)
((uint32_t)cksm + (cksm >> 32));
}
-void HELPER(unpk)(uint32_t len, uint64_t dest, uint64_t src)
+void HELPER(unpk)(CPUS390XState *env, uint32_t len, uint64_t dest,
+ uint64_t src)
{
int len_dest = len >> 4;
int len_src = len & 0xf;
@@ -867,8 +878,8 @@ void HELPER(unpk)(uint32_t len, uint64_t dest, uint64_t src)
src += len_src;
/* last byte is special, it only flips the nibbles */
- b = ldub(src);
- stb(dest, (b << 4) | (b >> 4));
+ b = cpu_ldub_data(env, src);
+ cpu_stb_data(env, dest, (b << 4) | (b >> 4));
src--;
len_src--;
@@ -878,7 +889,7 @@ void HELPER(unpk)(uint32_t len, uint64_t dest, uint64_t src)
uint8_t cur_byte = 0;
if (len_src > 0) {
- cur_byte = ldub(src);
+ cur_byte = cpu_ldub_data(env, src);
}
len_dest--;
@@ -897,30 +908,31 @@ void HELPER(unpk)(uint32_t len, uint64_t dest, uint64_t src)
/* zone bits */
cur_byte |= 0xf0;
- stb(dest, cur_byte);
+ cpu_stb_data(env, dest, cur_byte);
}
}
-void HELPER(tr)(uint32_t len, uint64_t array, uint64_t trans)
+void HELPER(tr)(CPUS390XState *env, uint32_t len, uint64_t array,
+ uint64_t trans)
{
int i;
for (i = 0; i <= len; i++) {
- uint8_t byte = ldub(array + i);
- uint8_t new_byte = ldub(trans + byte);
+ uint8_t byte = cpu_ldub_data(env, array + i);
+ uint8_t new_byte = cpu_ldub_data(env, trans + byte);
- stb(array + i, new_byte);
+ cpu_stb_data(env, array + i, new_byte);
}
}
#if !defined(CONFIG_USER_ONLY)
-void HELPER(lctlg)(uint32_t r1, uint64_t a2, uint32_t r3)
+void HELPER(lctlg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
{
int i;
uint64_t src = a2;
for (i = r1;; i = (i + 1) % 16) {
- env->cregs[i] = ldq(src);
+ env->cregs[i] = cpu_ldq_data(env, src);
HELPER_LOG("load ctl %d from 0x%" PRIx64 " == 0x%" PRIx64 "\n",
i, src, env->cregs[i]);
src += sizeof(uint64_t);
@@ -933,13 +945,14 @@ void HELPER(lctlg)(uint32_t r1, uint64_t a2, uint32_t r3)
tlb_flush(env, 1);
}
-void HELPER(lctl)(uint32_t r1, uint64_t a2, uint32_t r3)
+void HELPER(lctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
{
int i;
uint64_t src = a2;
for (i = r1;; i = (i + 1) % 16) {
- env->cregs[i] = (env->cregs[i] & 0xFFFFFFFF00000000ULL) | ldl(src);
+ env->cregs[i] = (env->cregs[i] & 0xFFFFFFFF00000000ULL) |
+ cpu_ldl_data(env, src);
src += sizeof(uint32_t);
if (i == r3) {
@@ -950,13 +963,13 @@ void HELPER(lctl)(uint32_t r1, uint64_t a2, uint32_t r3)
tlb_flush(env, 1);
}
-void HELPER(stctg)(uint32_t r1, uint64_t a2, uint32_t r3)
+void HELPER(stctg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
{
int i;
uint64_t dest = a2;
for (i = r1;; i = (i + 1) % 16) {
- stq(dest, env->cregs[i]);
+ cpu_stq_data(env, dest, env->cregs[i]);
dest += sizeof(uint64_t);
if (i == r3) {
@@ -965,13 +978,13 @@ void HELPER(stctg)(uint32_t r1, uint64_t a2, uint32_t r3)
}
}
-void HELPER(stctl)(uint32_t r1, uint64_t a2, uint32_t r3)
+void HELPER(stctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
{
int i;
uint64_t dest = a2;
for (i = r1;; i = (i + 1) % 16) {
- stl(dest, env->cregs[i]);
+ cpu_stl_data(env, dest, env->cregs[i]);
dest += sizeof(uint32_t);
if (i == r3) {
@@ -988,9 +1001,9 @@ uint32_t HELPER(tprot)(uint64_t a1, uint64_t a2)
}
/* insert storage key extended */
-uint64_t HELPER(iske)(uint64_t r2)
+uint64_t HELPER(iske)(CPUS390XState *env, uint64_t r2)
{
- uint64_t addr = get_address(0, 0, r2);
+ uint64_t addr = get_address(env, 0, 0, r2);
if (addr > ram_size) {
return 0;
@@ -1000,9 +1013,9 @@ uint64_t HELPER(iske)(uint64_t r2)
}
/* set storage key extended */
-void HELPER(sske)(uint32_t r1, uint64_t r2)
+void HELPER(sske)(CPUS390XState *env, uint32_t r1, uint64_t r2)
{
- uint64_t addr = get_address(0, 0, r2);
+ uint64_t addr = get_address(env, 0, 0, r2);
if (addr > ram_size) {
return;
@@ -1012,7 +1025,7 @@ void HELPER(sske)(uint32_t r1, uint64_t r2)
}
/* reset reference bit extended */
-uint32_t HELPER(rrbe)(uint32_t r1, uint64_t r2)
+uint32_t HELPER(rrbe)(CPUS390XState *env, uint32_t r1, uint64_t r2)
{
uint8_t re;
uint8_t key;
@@ -1038,15 +1051,15 @@ uint32_t HELPER(rrbe)(uint32_t r1, uint64_t r2)
}
/* compare and swap and purge */
-uint32_t HELPER(csp)(uint32_t r1, uint32_t r2)
+uint32_t HELPER(csp)(CPUS390XState *env, uint32_t r1, uint32_t r2)
{
uint32_t cc;
uint32_t o1 = env->regs[r1];
- uint64_t a2 = get_address_31fix(r2) & ~3ULL;
- uint32_t o2 = ldl(a2);
+ uint64_t a2 = get_address_31fix(env, r2) & ~3ULL;
+ uint32_t o2 = cpu_ldl_data(env, a2);
if (o1 == o2) {
- stl(a2, env->regs[(r1 + 1) & 15]);
+ cpu_stl_data(env, a2, env->regs[(r1 + 1) & 15]);
if (env->regs[r2] & 0x3) {
/* flush TLB / ALB */
tlb_flush(env, 1);
@@ -1060,8 +1073,8 @@ uint32_t HELPER(csp)(uint32_t r1, uint32_t r2)
return cc;
}
-static uint32_t mvc_asc(int64_t l, uint64_t a1, uint64_t mode1, uint64_t a2,
- uint64_t mode2)
+static uint32_t mvc_asc(CPUS390XState *env, int64_t l, uint64_t a1,
+ uint64_t mode1, uint64_t a2, uint64_t mode2)
{
target_ulong src, dest;
int flags, cc = 0, i;
@@ -1089,7 +1102,7 @@ static uint32_t mvc_asc(int64_t l, uint64_t a1, uint64_t mode1, uint64_t a2,
/* XXX be more clever */
if ((((dest + i) & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) ||
(((src + i) & TARGET_PAGE_MASK) != (src & TARGET_PAGE_MASK))) {
- mvc_asc(l - i, a1 + i, mode1, a2 + i, mode2);
+ mvc_asc(env, l - i, a1 + i, mode1, a2 + i, mode2);
break;
}
stb_phys(dest + i, ldub_phys(src + i));
@@ -1098,24 +1111,24 @@ static uint32_t mvc_asc(int64_t l, uint64_t a1, uint64_t mode1, uint64_t a2,
return cc;
}
-uint32_t HELPER(mvcs)(uint64_t l, uint64_t a1, uint64_t a2)
+uint32_t HELPER(mvcs)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2)
{
HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
__func__, l, a1, a2);
- return mvc_asc(l, a1, PSW_ASC_SECONDARY, a2, PSW_ASC_PRIMARY);
+ return mvc_asc(env, l, a1, PSW_ASC_SECONDARY, a2, PSW_ASC_PRIMARY);
}
-uint32_t HELPER(mvcp)(uint64_t l, uint64_t a1, uint64_t a2)
+uint32_t HELPER(mvcp)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2)
{
HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
__func__, l, a1, a2);
- return mvc_asc(l, a1, PSW_ASC_PRIMARY, a2, PSW_ASC_SECONDARY);
+ return mvc_asc(env, l, a1, PSW_ASC_PRIMARY, a2, PSW_ASC_SECONDARY);
}
/* invalidate pte */
-void HELPER(ipte)(uint64_t pte_addr, uint64_t vaddr)
+void HELPER(ipte)(CPUS390XState *env, uint64_t pte_addr, uint64_t vaddr)
{
uint64_t page = vaddr & TARGET_PAGE_MASK;
uint64_t pte = 0;
@@ -1141,19 +1154,19 @@ void HELPER(ipte)(uint64_t pte_addr, uint64_t vaddr)
}
/* flush local tlb */
-void HELPER(ptlb)(void)
+void HELPER(ptlb)(CPUS390XState *env)
{
tlb_flush(env, 1);
}
/* store using real address */
-void HELPER(stura)(uint64_t addr, uint32_t v1)
+void HELPER(stura)(CPUS390XState *env, uint64_t addr, uint32_t v1)
{
- stw_phys(get_address(0, 0, addr), v1);
+ stw_phys(get_address(env, 0, 0, addr), v1);
}
/* load real address */
-uint32_t HELPER(lra)(uint64_t addr, uint32_t r1)
+uint32_t HELPER(lra)(CPUS390XState *env, uint64_t addr, uint32_t r1)
{
uint32_t cc = 0;
int old_exc = env->exception_index;
@@ -1188,52 +1201,3 @@ uint32_t HELPER(lra)(uint64_t addr, uint32_t r1)
}
#endif
-
-/* temporary wrappers */
-#if defined(CONFIG_USER_ONLY)
-#define ldub_data(addr) ldub_raw(addr)
-#define lduw_data(addr) lduw_raw(addr)
-#define ldl_data(addr) ldl_raw(addr)
-#define ldq_data(addr) ldq_raw(addr)
-
-#define stb_data(addr, data) stb_raw(addr, data)
-#define stw_data(addr, data) stw_raw(addr, data)
-#define stl_data(addr, data) stl_raw(addr, data)
-#define stq_data(addr, data) stq_raw(addr, data)
-#endif
-
-#define WRAP_LD(rettype, fn) \
- rettype cpu_ ## fn(CPUS390XState *env1, target_ulong addr) \
- { \
- CPUS390XState *saved_env; \
- rettype ret; \
- \
- saved_env = env; \
- env = env1; \
- ret = fn(addr); \
- env = saved_env; \
- return ret; \
- }
-
-WRAP_LD(uint32_t, ldub_data)
-WRAP_LD(uint32_t, lduw_data)
-WRAP_LD(uint32_t, ldl_data)
-WRAP_LD(uint64_t, ldq_data)
-#undef WRAP_LD
-
-#define WRAP_ST(datatype, fn) \
- void cpu_ ## fn(CPUS390XState *env1, target_ulong addr, datatype val) \
- { \
- CPUS390XState *saved_env; \
- \
- saved_env = env; \
- env = env1; \
- fn(addr, val); \
- env = saved_env; \
- }
-
-WRAP_ST(uint32_t, stb_data)
-WRAP_ST(uint32_t, stw_data)
-WRAP_ST(uint32_t, stl_data)
-WRAP_ST(uint64_t, stq_data)
-#undef WRAP_ST
diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
index ced26c6..2938ac9 100644
--- a/target-s390x/misc_helper.c
+++ b/target-s390x/misc_helper.c
@@ -31,10 +31,7 @@
#endif
#if !defined(CONFIG_USER_ONLY)
-/* temporarily disabled due to wrapper use */
-#if 0
#include "softmmu_exec.h"
-#endif
#include "sysemu.h"
#endif
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index 0c61e63..66119cd 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -276,19 +276,19 @@ static inline void potential_page_fault(DisasContext *s)
static inline uint64_t ld_code2(uint64_t pc)
{
- return (uint64_t)lduw_code(pc);
+ return (uint64_t)cpu_lduw_code(cpu_single_env, pc);
}
static inline uint64_t ld_code4(uint64_t pc)
{
- return (uint64_t)ldl_code(pc);
+ return (uint64_t)cpu_ldl_code(cpu_single_env, pc);
}
static inline uint64_t ld_code6(uint64_t pc)
{
uint64_t opc;
- opc = (uint64_t)lduw_code(pc) << 32;
- opc |= (uint64_t)(uint32_t)ldl_code(pc+2);
+ opc = (uint64_t)cpu_lduw_code(cpu_single_env, pc) << 32;
+ opc |= (uint64_t)(uint32_t)cpu_ldl_code(cpu_single_env, pc + 2);
return opc;
}
@@ -1263,7 +1263,7 @@ static void gen_op_mvc(DisasContext *s, int l, TCGv_i64 s1, TCGv_i64 s2)
/* Fall back to helper */
vl = tcg_const_i32(l);
potential_page_fault(s);
- gen_helper_mvc(vl, s1, s2);
+ gen_helper_mvc(cpu_env, vl, s1, s2);
tcg_temp_free_i32(vl);
return;
}
@@ -1455,7 +1455,7 @@ static void gen_op_clc(DisasContext *s, int l, TCGv_i64 s1, TCGv_i64 s2)
potential_page_fault(s);
vl = tcg_const_i32(l);
- gen_helper_clc(cc_op, vl, s1, s2);
+ gen_helper_clc(cc_op, cpu_env, vl, s1, s2);
tcg_temp_free_i32(vl);
set_cc_static(s);
}
@@ -2094,7 +2094,7 @@ do_mh:
tmp32_1 = tcg_const_i32(r1);
tmp32_2 = tcg_const_i32(r3);
potential_page_fault(s);
- gen_helper_stcmh(tmp32_1, tmp, tmp32_2);
+ gen_helper_stcmh(cpu_env, tmp32_1, tmp, tmp32_2);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
@@ -2107,7 +2107,7 @@ do_mh:
tmp32_1 = tcg_const_i32(r1);
tmp32_2 = tcg_const_i32(r3);
potential_page_fault(s);
- gen_helper_lctlg(tmp32_1, tmp, tmp32_2);
+ gen_helper_lctlg(cpu_env, tmp32_1, tmp, tmp32_2);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
@@ -2119,7 +2119,7 @@ do_mh:
tmp32_1 = tcg_const_i32(r1);
tmp32_2 = tcg_const_i32(r3);
potential_page_fault(s);
- gen_helper_stctg(tmp32_1, tmp, tmp32_2);
+ gen_helper_stctg(cpu_env, tmp32_1, tmp, tmp32_2);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
@@ -2131,7 +2131,7 @@ do_mh:
tmp32_2 = tcg_const_i32(r3);
potential_page_fault(s);
/* XXX rewrite in tcg */
- gen_helper_csg(cc_op, tmp32_1, tmp, tmp32_2);
+ gen_helper_csg(cc_op, cpu_env, tmp32_1, tmp, tmp32_2);
set_cc_static(s);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32_1);
@@ -2143,7 +2143,7 @@ do_mh:
tmp32_2 = tcg_const_i32(r3);
potential_page_fault(s);
/* XXX rewrite in tcg */
- gen_helper_cdsg(cc_op, tmp32_1, tmp, tmp32_2);
+ gen_helper_cdsg(cc_op, cpu_env, tmp32_1, tmp, tmp32_2);
set_cc_static(s);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32_1);
@@ -2183,7 +2183,7 @@ do_mh:
tmp32_2 = tcg_const_i32(r3);
potential_page_fault(s);
/* XXX split CC calculation out */
- gen_helper_icmh(cc_op, tmp32_1, tmp, tmp32_2);
+ gen_helper_icmh(cc_op, cpu_env, tmp32_1, tmp, tmp32_2);
set_cc_static(s);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32_1);
@@ -2635,7 +2635,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
tmp32_1 = tcg_const_i32(r1);
tmp32_2 = tcg_const_i32(r2);
potential_page_fault(s);
- gen_helper_cksm(tmp32_1, tmp32_2);
+ gen_helper_cksm(cpu_env, tmp32_1, tmp32_2);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
gen_op_movi_cc(s, 0);
@@ -2664,7 +2664,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
tmp2 = load_reg(r1);
tmp3 = load_reg(r2);
potential_page_fault(s);
- gen_helper_mvpg(tmp, tmp2, tmp3);
+ gen_helper_mvpg(cpu_env, tmp, tmp2, tmp3);
tcg_temp_free_i64(tmp);
tcg_temp_free_i64(tmp2);
tcg_temp_free_i64(tmp3);
@@ -2676,7 +2676,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
tmp32_2 = tcg_const_i32(r1);
tmp32_3 = tcg_const_i32(r2);
potential_page_fault(s);
- gen_helper_mvst(tmp32_1, tmp32_2, tmp32_3);
+ gen_helper_mvst(cpu_env, tmp32_1, tmp32_2, tmp32_3);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
tcg_temp_free_i32(tmp32_3);
@@ -2687,7 +2687,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
tmp32_2 = tcg_const_i32(r1);
tmp32_3 = tcg_const_i32(r2);
potential_page_fault(s);
- gen_helper_clst(cc_op, tmp32_1, tmp32_2, tmp32_3);
+ gen_helper_clst(cc_op, cpu_env, tmp32_1, tmp32_2, tmp32_3);
set_cc_static(s);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
@@ -2698,7 +2698,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
tmp32_2 = tcg_const_i32(r1);
tmp32_3 = tcg_const_i32(r2);
potential_page_fault(s);
- gen_helper_srst(cc_op, tmp32_1, tmp32_2, tmp32_3);
+ gen_helper_srst(cc_op, cpu_env, tmp32_1, tmp32_2, tmp32_3);
set_cc_static(s);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
@@ -2785,7 +2785,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
case 0x0d: /* PTLB [S] */
/* Purge TLB */
check_privileged(s, ilc);
- gen_helper_ptlb();
+ gen_helper_ptlb(cpu_env);
break;
case 0x10: /* SPX D2(B2) [S] */
/* Set Prefix Register */
@@ -2828,7 +2828,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
r2 = insn & 0xf;
tmp = load_reg(r1);
tmp2 = load_reg(r2);
- gen_helper_ipte(tmp, tmp2);
+ gen_helper_ipte(cpu_env, tmp, tmp2);
tcg_temp_free_i64(tmp);
tcg_temp_free_i64(tmp2);
break;
@@ -2839,7 +2839,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
r2 = insn & 0xf;
tmp = load_reg(r2);
tmp2 = tcg_temp_new_i64();
- gen_helper_iske(tmp2, tmp);
+ gen_helper_iske(tmp2, cpu_env, tmp);
store_reg(r1, tmp2);
tcg_temp_free_i64(tmp);
tcg_temp_free_i64(tmp2);
@@ -2851,7 +2851,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
r2 = insn & 0xf;
tmp32_1 = load_reg32(r1);
tmp = load_reg(r2);
- gen_helper_rrbe(cc_op, tmp32_1, tmp);
+ gen_helper_rrbe(cc_op, cpu_env, tmp32_1, tmp);
set_cc_static(s);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i64(tmp);
@@ -2863,7 +2863,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
r2 = insn & 0xf;
tmp32_1 = load_reg32(r1);
tmp = load_reg(r2);
- gen_helper_sske(tmp32_1, tmp);
+ gen_helper_sske(cpu_env, tmp32_1, tmp);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i64(tmp);
break;
@@ -2880,7 +2880,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
tmp32_1 = load_reg32(r1);
tmp = load_reg(r2);
potential_page_fault(s);
- gen_helper_stura(tmp, tmp32_1);
+ gen_helper_stura(cpu_env, tmp, tmp32_1);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i64(tmp);
break;
@@ -2891,7 +2891,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
r2 = insn & 0xf;
tmp32_1 = tcg_const_i32(r1);
tmp32_2 = tcg_const_i32(r2);
- gen_helper_csp(cc_op, tmp32_1, tmp32_2);
+ gen_helper_csp(cc_op, cpu_env, tmp32_1, tmp32_2);
set_cc_static(s);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
@@ -3865,7 +3865,7 @@ static void disas_s390_insn(DisasContext *s)
int ilc;
int l1;
- opc = ldub_code(s->pc);
+ opc = cpu_ldub_code(cpu_single_env, s->pc);
LOG_DISAS("opc 0x%x\n", opc);
ilc = get_ilc(opc);
@@ -3951,7 +3951,7 @@ static void disas_s390_insn(DisasContext *s)
tmp32_1 = tcg_const_i32(r1);
tmp32_2 = tcg_const_i32(r2);
potential_page_fault(s);
- gen_helper_mvcl(cc_op, tmp32_1, tmp32_2);
+ gen_helper_mvcl(cc_op, cpu_env, tmp32_1, tmp32_2);
set_cc_static(s);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
@@ -4165,7 +4165,7 @@ static void disas_s390_insn(DisasContext *s)
tmp3 = tcg_const_i64(s->pc + 4);
update_psw_addr(s);
gen_op_calc_cc(s);
- gen_helper_ex(cc_op, cc_op, tmp2, tmp, tmp3);
+ gen_helper_ex(cc_op, cpu_env, cc_op, tmp2, tmp, tmp3);
set_cc_static(s);
tcg_temp_free_i64(tmp);
tcg_temp_free_i64(tmp2);
@@ -4694,7 +4694,7 @@ static void disas_s390_insn(DisasContext *s)
tmp32_1 = tcg_const_i32(r1);
tmp32_2 = tcg_const_i32(r3);
potential_page_fault(s);
- gen_helper_lam(tmp32_1, tmp, tmp32_2);
+ gen_helper_lam(cpu_env, tmp32_1, tmp, tmp32_2);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
@@ -4706,7 +4706,7 @@ static void disas_s390_insn(DisasContext *s)
tmp32_1 = tcg_const_i32(r1);
tmp32_2 = tcg_const_i32(r3);
potential_page_fault(s);
- gen_helper_stam(tmp32_1, tmp, tmp32_2);
+ gen_helper_stam(cpu_env, tmp32_1, tmp, tmp32_2);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
@@ -4732,7 +4732,7 @@ static void disas_s390_insn(DisasContext *s)
tmp32_1 = tcg_const_i32(r1);
tmp32_2 = tcg_const_i32(r3);
potential_page_fault(s);
- gen_helper_mvcle(cc_op, tmp32_1, tmp, tmp32_2);
+ gen_helper_mvcle(cc_op, cpu_env, tmp32_1, tmp, tmp32_2);
set_cc_static(s);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32_1);
@@ -4745,7 +4745,7 @@ static void disas_s390_insn(DisasContext *s)
tmp32_1 = tcg_const_i32(r1);
tmp32_2 = tcg_const_i32(r3);
potential_page_fault(s);
- gen_helper_clcle(cc_op, tmp32_1, tmp, tmp32_2);
+ gen_helper_clcle(cc_op, cpu_env, tmp32_1, tmp, tmp32_2);
set_cc_static(s);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32_1);
@@ -4789,7 +4789,7 @@ static void disas_s390_insn(DisasContext *s)
tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
tmp32_1 = tcg_const_i32(r1);
potential_page_fault(s);
- gen_helper_lra(cc_op, tmp, tmp32_1);
+ gen_helper_lra(cc_op, cpu_env, tmp, tmp32_1);
set_cc_static(s);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32_1);
@@ -4835,7 +4835,7 @@ static void disas_s390_insn(DisasContext *s)
tmp32_1 = tcg_const_i32(r1);
tmp32_2 = tcg_const_i32(r3);
potential_page_fault(s);
- gen_helper_stctl(tmp32_1, tmp, tmp32_2);
+ gen_helper_stctl(cpu_env, tmp32_1, tmp, tmp32_2);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
@@ -4849,7 +4849,7 @@ static void disas_s390_insn(DisasContext *s)
tmp32_1 = tcg_const_i32(r1);
tmp32_2 = tcg_const_i32(r3);
potential_page_fault(s);
- gen_helper_lctl(tmp32_1, tmp, tmp32_2);
+ gen_helper_lctl(cpu_env, tmp32_1, tmp, tmp32_2);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
@@ -4869,7 +4869,7 @@ static void disas_s390_insn(DisasContext *s)
tmp32_1 = tcg_const_i32(r1);
tmp32_2 = tcg_const_i32(r3);
potential_page_fault(s);
- gen_helper_cs(cc_op, tmp32_1, tmp, tmp32_2);
+ gen_helper_cs(cc_op, cpu_env, tmp32_1, tmp, tmp32_2);
set_cc_static(s);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32_1);
@@ -4882,7 +4882,7 @@ static void disas_s390_insn(DisasContext *s)
tmp32_1 = load_reg32(r1);
tmp32_2 = tcg_const_i32(r3);
potential_page_fault(s);
- gen_helper_clm(cc_op, tmp32_1, tmp32_2, tmp);
+ gen_helper_clm(cc_op, cpu_env, tmp32_1, tmp32_2, tmp);
set_cc_static(s);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32_1);
@@ -4895,7 +4895,7 @@ static void disas_s390_insn(DisasContext *s)
tmp32_1 = load_reg32(r1);
tmp32_2 = tcg_const_i32(r3);
potential_page_fault(s);
- gen_helper_stcm(tmp32_1, tmp32_2, tmp);
+ gen_helper_stcm(cpu_env, tmp32_1, tmp32_2, tmp);
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
@@ -4992,7 +4992,7 @@ static void disas_s390_insn(DisasContext *s)
break;
case 0xd4:
potential_page_fault(s);
- gen_helper_nc(cc_op, vl, tmp, tmp2);
+ gen_helper_nc(cc_op, cpu_env, vl, tmp, tmp2);
set_cc_static(s);
break;
case 0xd5:
@@ -5000,22 +5000,22 @@ static void disas_s390_insn(DisasContext *s)
break;
case 0xd6:
potential_page_fault(s);
- gen_helper_oc(cc_op, vl, tmp, tmp2);
+ gen_helper_oc(cc_op, cpu_env, vl, tmp, tmp2);
set_cc_static(s);
break;
case 0xd7:
potential_page_fault(s);
- gen_helper_xc(cc_op, vl, tmp, tmp2);
+ gen_helper_xc(cc_op, cpu_env, vl, tmp, tmp2);
set_cc_static(s);
break;
case 0xdc:
potential_page_fault(s);
- gen_helper_tr(vl, tmp, tmp2);
+ gen_helper_tr(cpu_env, vl, tmp, tmp2);
set_cc_static(s);
break;
case 0xf3:
potential_page_fault(s);
- gen_helper_unpk(vl, tmp, tmp2);
+ gen_helper_unpk(cpu_env, vl, tmp, tmp2);
break;
default:
tcg_abort();
@@ -5040,9 +5040,9 @@ static void disas_s390_insn(DisasContext *s)
tmp2 = get_address(s, 0, b1, d1);
tmp3 = get_address(s, 0, b2, d2);
if (opc == 0xda) {
- gen_helper_mvcp(cc_op, tmp, tmp2, tmp3);
+ gen_helper_mvcp(cc_op, cpu_env, tmp, tmp2, tmp3);
} else {
- gen_helper_mvcs(cc_op, tmp, tmp2, tmp3);
+ gen_helper_mvcs(cc_op, cpu_env, tmp, tmp2, tmp3);
}
set_cc_static(s);
tcg_temp_free_i64(tmp);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 12/12] tcg/s390: fix ld/st with CONFIG_TCG_PASS_AREG0
2012-09-10 11:40 [Qemu-devel] [PULL 00/12] s390 patch queue 2012-09-10 Alexander Graf
` (10 preceding siblings ...)
2012-09-10 11:40 ` [Qemu-devel] [PATCH 11/12] target-s390x: switch to AREG0 free mode Alexander Graf
@ 2012-09-10 11:40 ` Alexander Graf
2012-09-10 13:16 ` [Qemu-devel] [PULL 00/12] s390 patch queue 2012-09-10 Aurelien Jarno
12 siblings, 0 replies; 14+ messages in thread
From: Alexander Graf @ 2012-09-10 11:40 UTC (permalink / raw)
To: qemu-devel qemu-devel; +Cc: Blue Swirl, Aurelien Jarno
From: Aurelien Jarno <aurelien@aurel32.net>
The load/store slow path has been broken in e141ab52d:
- We need to move 4 registers for store functions and 3 registers for
load functions and not the reverse.
- According to the s390x calling convention the arguments of a function
should be zero extended. This means that the register shift should be
done with TCG_TYPE_I64 to ensure the higher word is correctly zero
extended when needed.
I am aware that CONFIG_TCG_PASS_AREG0 is being removed and thus that
this patch can be improved, but doing so means it can also be applied to
the 1.1 and 1.2 stable branches.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
tcg/s390/tcg-target.c | 14 +++++++-------
1 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
index 04662c1..99b5339 100644
--- a/tcg/s390/tcg-target.c
+++ b/tcg/s390/tcg-target.c
@@ -1509,11 +1509,13 @@ static void tcg_prepare_qemu_ldst(TCGContext* s, TCGReg data_reg,
tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R4, mem_index);
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal */
- tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
+ tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[3],
+ tcg_target_call_iarg_regs[2]);
+ tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
tcg_target_call_iarg_regs[1]);
- tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
+ tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[1],
tcg_target_call_iarg_regs[0]);
- tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
+ tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0],
TCG_AREG0);
#endif
tgen_calli(s, (tcg_target_ulong)qemu_st_helpers[s_bits]);
@@ -1521,13 +1523,11 @@ static void tcg_prepare_qemu_ldst(TCGContext* s, TCGReg data_reg,
tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal */
- tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
- tcg_target_call_iarg_regs[2]);
tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
tcg_target_call_iarg_regs[1]);
- tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
+ tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[1],
tcg_target_call_iarg_regs[0]);
- tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
+ tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0],
TCG_AREG0);
#endif
tgen_calli(s, (tcg_target_ulong)qemu_ld_helpers[s_bits]);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PULL 00/12] s390 patch queue 2012-09-10
2012-09-10 11:40 [Qemu-devel] [PULL 00/12] s390 patch queue 2012-09-10 Alexander Graf
` (11 preceding siblings ...)
2012-09-10 11:40 ` [Qemu-devel] [PATCH 12/12] tcg/s390: fix ld/st with CONFIG_TCG_PASS_AREG0 Alexander Graf
@ 2012-09-10 13:16 ` Aurelien Jarno
12 siblings, 0 replies; 14+ messages in thread
From: Aurelien Jarno @ 2012-09-10 13:16 UTC (permalink / raw)
To: Alexander Graf; +Cc: Blue Swirl, qemu-devel qemu-devel
On Mon, Sep 10, 2012 at 01:40:45PM +0200, Alexander Graf wrote:
> Hi Blue / Aurelien,
>
> This is my current patch queue for s390. Please pull.
>
> It contains:
>
> - tcg fix for s390 hosts
> - convert s390 target to be areg0 free
>
> Alex
>
>
> The following changes since commit 0c267217ca9985e6d118ec8368bebd382db7a099:
> Jan Kiszka (1):
> musicpal: Fix flash mapping
>
> are available in the git repository at:
>
> git://repo.or.cz/qemu/agraf.git s390-for-upstream
>
> Aurelien Jarno (1):
> tcg/s390: fix ld/st with CONFIG_TCG_PASS_AREG0
>
> Blue Swirl (11):
> target-s390x: fix style
> target-s390x: split FPU ops
> target-s390x: split condition code helpers
> target-s390x: split integer helpers
> target-s390x: split memory access helpers
> target-s390x: rename op_helper.c to misc_helper.c
> target-s390x: avoid AREG0 for FPU helpers
> target-s390x: avoid AREG0 for integer helpers
> target-s390x: avoid AREG0 for condition code helpers
> target-s390x: avoid AREG0 for misc helpers
> target-s390x: switch to AREG0 free mode
>
> configure | 2 +-
> target-s390x/Makefile.objs | 5 +-
> target-s390x/cc_helper.c | 550 ++++++++
> target-s390x/cpu.h | 9 +
> target-s390x/fpu_helper.c | 843 ++++++++++++
> target-s390x/helper.c | 102 +-
> target-s390x/helper.h | 250 ++--
> target-s390x/int_helper.c | 201 +++
> target-s390x/mem_helper.c | 1203 ++++++++++++++++++
> target-s390x/misc_helper.c | 430 +++++++
> target-s390x/op_helper.c | 3019 --------------------------------------------
> target-s390x/translate.c | 233 ++--
> tcg/s390/tcg-target.c | 14 +-
> 13 files changed, 3537 insertions(+), 3324 deletions(-)
> create mode 100644 target-s390x/cc_helper.c
> create mode 100644 target-s390x/fpu_helper.c
> create mode 100644 target-s390x/int_helper.c
> create mode 100644 target-s390x/mem_helper.c
> create mode 100644 target-s390x/misc_helper.c
> delete mode 100644 target-s390x/op_helper.c
>
Thanks, pulled.
--
Aurelien Jarno GPG: 1024D/F1BCDB73
aurelien@aurel32.net http://www.aurel32.net
^ permalink raw reply [flat|nested] 14+ messages in thread