mirror of https://github.com/proxmox/mirror_qemu
target-s390: Convert TEST UNDER MASK
Signed-off-by: Richard Henderson <rth@twiddle.net>master
parent
b4e2bd3563
commit
00d2dc192f
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "helper.h"
|
#include "helper.h"
|
||||||
|
#include "qemu/host-utils.h"
|
||||||
|
|
||||||
/* #define DEBUG_HELPER */
|
/* #define DEBUG_HELPER */
|
||||||
#ifdef DEBUG_HELPER
|
#ifdef DEBUG_HELPER
|
||||||
|
@ -86,13 +87,11 @@ 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,
|
static uint32_t cc_calc_tm_32(CPUS390XState *env, uint32_t val, uint32_t mask)
|
||||||
uint32_t mask)
|
|
||||||
{
|
{
|
||||||
uint16_t r = val & mask;
|
uint32_t r = val & mask;
|
||||||
|
|
||||||
HELPER_LOG("%s: val 0x%x mask 0x%x\n", __func__, val, mask);
|
if (r == 0) {
|
||||||
if (r == 0 || mask == 0) {
|
|
||||||
return 0;
|
return 0;
|
||||||
} else if (r == mask) {
|
} else if (r == mask) {
|
||||||
return 3;
|
return 3;
|
||||||
|
@ -101,23 +100,17 @@ static inline uint32_t cc_calc_tm_32(CPUS390XState *env, uint32_t val,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set condition code for test under mask */
|
static uint32_t cc_calc_tm_64(CPUS390XState *env, uint64_t val, uint64_t mask)
|
||||||
static inline uint32_t cc_calc_tm_64(CPUS390XState *env, uint64_t val,
|
|
||||||
uint32_t mask)
|
|
||||||
{
|
{
|
||||||
uint16_t r = val & mask;
|
uint64_t r = val & mask;
|
||||||
|
|
||||||
HELPER_LOG("%s: val 0x%lx mask 0x%x r 0x%x\n", __func__, val, mask, r);
|
if (r == 0) {
|
||||||
if (r == 0 || mask == 0) {
|
|
||||||
return 0;
|
return 0;
|
||||||
} else if (r == mask) {
|
} else if (r == mask) {
|
||||||
return 3;
|
return 3;
|
||||||
} else {
|
} else {
|
||||||
while (!(mask & 0x8000)) {
|
int top = clz64(mask);
|
||||||
mask <<= 1;
|
if ((int64_t)(val << top) < 0) {
|
||||||
val <<= 1;
|
|
||||||
}
|
|
||||||
if (val & 0x8000) {
|
|
||||||
return 2;
|
return 2;
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -336,3 +336,11 @@
|
||||||
C(0xb989, SLBGR, RRE, Z, r1, r2, r1, 0, subb, subb64)
|
C(0xb989, SLBGR, RRE, Z, r1, r2, r1, 0, subb, subb64)
|
||||||
C(0xe399, SLB, RXY_a, Z, r1, m2_32u, new, r1_32, subb, subb32)
|
C(0xe399, SLB, RXY_a, Z, r1, m2_32u, new, r1_32, subb, subb32)
|
||||||
C(0xe389, SLBG, RXY_a, Z, r1, m2_64, r1, 0, subb, subb64)
|
C(0xe389, SLBG, RXY_a, Z, r1, m2_64, r1, 0, subb, subb64)
|
||||||
|
|
||||||
|
/* TEST UNDER MASK */
|
||||||
|
C(0x9100, TM, SI, Z, m1_8u, i2_8u, 0, 0, 0, tm32)
|
||||||
|
C(0xeb51, TMY, SIY, LD, m1_8u, i2_8u, 0, 0, 0, tm32)
|
||||||
|
D(0xa702, TMHH, RI_a, Z, r1_o, i2_16u_shl, 0, 0, 0, tm64, 48)
|
||||||
|
D(0xa703, TMHL, RI_a, Z, r1_o, i2_16u_shl, 0, 0, 0, tm64, 32)
|
||||||
|
D(0xa700, TMLH, RI_a, Z, r1_o, i2_16u_shl, 0, 0, 0, tm64, 16)
|
||||||
|
D(0xa701, TMLL, RI_a, Z, r1_o, i2_16u_shl, 0, 0, 0, tm64, 0)
|
||||||
|
|
|
@ -1514,16 +1514,6 @@ do_mh:
|
||||||
tcg_temp_free_i32(tmp32_1);
|
tcg_temp_free_i32(tmp32_1);
|
||||||
tcg_temp_free_i32(tmp32_2);
|
tcg_temp_free_i32(tmp32_2);
|
||||||
break;
|
break;
|
||||||
case 0x51: /* TMY D1(B1),I2 [SIY] */
|
|
||||||
tmp = get_address(s, 0, b2, d2); /* SIY -> this is the destination */
|
|
||||||
tmp2 = tcg_const_i64((r1 << 4) | r3);
|
|
||||||
tcg_gen_qemu_ld8u(tmp, tmp, get_mem_index(s));
|
|
||||||
/* yes, this is a 32 bit operation with 64 bit tcg registers, because
|
|
||||||
that incurs less conversions */
|
|
||||||
cmp_64(s, tmp, tmp2, CC_OP_TM_32);
|
|
||||||
tcg_temp_free_i64(tmp);
|
|
||||||
tcg_temp_free_i64(tmp2);
|
|
||||||
break;
|
|
||||||
case 0x52: /* MVIY D1(B1),I2 [SIY] */
|
case 0x52: /* MVIY D1(B1),I2 [SIY] */
|
||||||
tmp = get_address(s, 0, b2, d2); /* SIY -> this is the destination */
|
tmp = get_address(s, 0, b2, d2); /* SIY -> this is the destination */
|
||||||
tmp2 = tcg_const_i64((r1 << 4) | r3);
|
tmp2 = tcg_const_i64((r1 << 4) | r3);
|
||||||
|
@ -1672,44 +1662,6 @@ static void disas_ed(CPUS390XState *env, DisasContext *s, int op, int r1,
|
||||||
tcg_temp_free_i64(addr);
|
tcg_temp_free_i64(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disas_a7(CPUS390XState *env, DisasContext *s, int op, int r1,
|
|
||||||
int i2)
|
|
||||||
{
|
|
||||||
TCGv_i64 tmp, tmp2;
|
|
||||||
|
|
||||||
LOG_DISAS("disas_a7: op 0x%x r1 %d i2 0x%x\n", op, r1, i2);
|
|
||||||
switch (op) {
|
|
||||||
case 0x0: /* TMLH or TMH R1,I2 [RI] */
|
|
||||||
case 0x1: /* TMLL or TML R1,I2 [RI] */
|
|
||||||
case 0x2: /* TMHH R1,I2 [RI] */
|
|
||||||
case 0x3: /* TMHL R1,I2 [RI] */
|
|
||||||
tmp = load_reg(r1);
|
|
||||||
tmp2 = tcg_const_i64((uint16_t)i2);
|
|
||||||
switch (op) {
|
|
||||||
case 0x0:
|
|
||||||
tcg_gen_shri_i64(tmp, tmp, 16);
|
|
||||||
break;
|
|
||||||
case 0x1:
|
|
||||||
break;
|
|
||||||
case 0x2:
|
|
||||||
tcg_gen_shri_i64(tmp, tmp, 48);
|
|
||||||
break;
|
|
||||||
case 0x3:
|
|
||||||
tcg_gen_shri_i64(tmp, tmp, 32);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tcg_gen_andi_i64(tmp, tmp, 0xffff);
|
|
||||||
cmp_64(s, tmp, tmp2, CC_OP_TM_64);
|
|
||||||
tcg_temp_free_i64(tmp);
|
|
||||||
tcg_temp_free_i64(tmp2);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG_DISAS("illegal a7 operation 0x%x\n", op);
|
|
||||||
gen_illegal_opcode(s);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void disas_b2(CPUS390XState *env, DisasContext *s, int op,
|
static void disas_b2(CPUS390XState *env, DisasContext *s, int op,
|
||||||
uint32_t insn)
|
uint32_t insn)
|
||||||
{
|
{
|
||||||
|
@ -2678,15 +2630,6 @@ static void disas_s390_insn(CPUS390XState *env, DisasContext *s)
|
||||||
tcg_temp_free_i64(tmp3);
|
tcg_temp_free_i64(tmp3);
|
||||||
tcg_temp_free_i64(tmp4);
|
tcg_temp_free_i64(tmp4);
|
||||||
break;
|
break;
|
||||||
case 0x91: /* TM D1(B1),I2 [SI] */
|
|
||||||
insn = ld_code4(env, s->pc);
|
|
||||||
tmp = decode_si(s, insn, &i2, &b1, &d1);
|
|
||||||
tmp2 = tcg_const_i64(i2);
|
|
||||||
tcg_gen_qemu_ld8u(tmp, tmp, get_mem_index(s));
|
|
||||||
cmp_64(s, tmp, tmp2, CC_OP_TM_32);
|
|
||||||
tcg_temp_free_i64(tmp);
|
|
||||||
tcg_temp_free_i64(tmp2);
|
|
||||||
break;
|
|
||||||
case 0x92: /* MVI D1(B1),I2 [SI] */
|
case 0x92: /* MVI D1(B1),I2 [SI] */
|
||||||
insn = ld_code4(env, s->pc);
|
insn = ld_code4(env, s->pc);
|
||||||
tmp = decode_si(s, insn, &i2, &b1, &d1);
|
tmp = decode_si(s, insn, &i2, &b1, &d1);
|
||||||
|
@ -2744,13 +2687,6 @@ static void disas_s390_insn(CPUS390XState *env, DisasContext *s)
|
||||||
tcg_temp_free_i32(tmp32_1);
|
tcg_temp_free_i32(tmp32_1);
|
||||||
tcg_temp_free_i32(tmp32_2);
|
tcg_temp_free_i32(tmp32_2);
|
||||||
break;
|
break;
|
||||||
case 0xa7:
|
|
||||||
insn = ld_code4(env, s->pc);
|
|
||||||
r1 = (insn >> 20) & 0xf;
|
|
||||||
op = (insn >> 16) & 0xf;
|
|
||||||
i2 = (short)insn;
|
|
||||||
disas_a7(env, s, op, r1, i2);
|
|
||||||
break;
|
|
||||||
case 0xa8: /* MVCLE R1,R3,D2(B2) [RS] */
|
case 0xa8: /* MVCLE R1,R3,D2(B2) [RS] */
|
||||||
insn = ld_code4(env, s->pc);
|
insn = ld_code4(env, s->pc);
|
||||||
decode_rs(s, insn, &r1, &r3, &b2, &d2);
|
decode_rs(s, insn, &r1, &r3, &b2, &d2);
|
||||||
|
@ -3945,6 +3881,16 @@ static void cout_subb64(DisasContext *s, DisasOps *o)
|
||||||
gen_op_update3_cc_i64(s, CC_OP_SUBB_64, o->in1, o->in2, o->out);
|
gen_op_update3_cc_i64(s, CC_OP_SUBB_64, o->in1, o->in2, o->out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cout_tm32(DisasContext *s, DisasOps *o)
|
||||||
|
{
|
||||||
|
gen_op_update2_cc_i64(s, CC_OP_TM_32, o->in1, o->in2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cout_tm64(DisasContext *s, DisasOps *o)
|
||||||
|
{
|
||||||
|
gen_op_update2_cc_i64(s, CC_OP_TM_64, o->in1, o->in2);
|
||||||
|
}
|
||||||
|
|
||||||
/* ====================================================================== */
|
/* ====================================================================== */
|
||||||
/* The "PREPeration" generators. These initialize the DisasOps.OUT fields
|
/* The "PREPeration" generators. These initialize the DisasOps.OUT fields
|
||||||
with the TCG register to which we will write. Used in combination with
|
with the TCG register to which we will write. Used in combination with
|
||||||
|
|
Loading…
Reference in New Issue