target-s390: Convert TEST UNDER MASK

Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
Richard Henderson 2012-08-20 16:20:58 -07:00
parent b4e2bd3563
commit 00d2dc192f
3 changed files with 27 additions and 80 deletions

View File

@ -20,6 +20,7 @@
#include "cpu.h"
#include "helper.h"
#include "qemu/host-utils.h"
/* #define 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,
uint32_t mask)
static uint32_t cc_calc_tm_32(CPUS390XState *env, uint32_t val, 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 || mask == 0) {
if (r == 0) {
return 0;
} else if (r == mask) {
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 inline uint32_t cc_calc_tm_64(CPUS390XState *env, uint64_t val,
uint32_t mask)
static uint32_t cc_calc_tm_64(CPUS390XState *env, uint64_t val, uint64_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 || mask == 0) {
if (r == 0) {
return 0;
} else if (r == mask) {
return 3;
} else {
while (!(mask & 0x8000)) {
mask <<= 1;
val <<= 1;
}
if (val & 0x8000) {
int top = clz64(mask);
if ((int64_t)(val << top) < 0) {
return 2;
} else {
return 1;

View File

@ -336,3 +336,11 @@
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(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)

View File

@ -1514,16 +1514,6 @@ do_mh:
tcg_temp_free_i32(tmp32_1);
tcg_temp_free_i32(tmp32_2);
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] */
tmp = get_address(s, 0, b2, d2); /* SIY -> this is the destination */
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);
}
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,
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(tmp4);
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] */
insn = ld_code4(env, s->pc);
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_2);
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] */
insn = ld_code4(env, s->pc);
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);
}
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
with the TCG register to which we will write. Used in combination with