mirror of https://github.com/xemu-project/xemu.git
target-s390: Convert AND, OR, XOR, INSERT IMMEDIATE
Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
parent
b9bca3e57a
commit
facfc86487
|
@ -49,6 +49,13 @@
|
|||
C(0xb980, NGR, RRE, Z, r1, r2, r1, 0, and, nz64)
|
||||
C(0xb9e4, NGRK, RRF_a, DO, r2, r3, r1, 0, and, nz64)
|
||||
C(0xe380, NG, RXY_a, Z, r1, m2_64, r1, 0, and, nz64)
|
||||
/* AND IMMEDIATE */
|
||||
D(0xc00a, NIHF, RIL_a, EI, r1_o, i2_32u, r1, 0, andi, 0, 0x2020)
|
||||
D(0xc00b, NILF, RIL_a, EI, r1_o, i2_32u, r1, 0, andi, 0, 0x2000)
|
||||
D(0xa504, NIHH, RI_a, Z, r1_o, i2_16u, r1, 0, andi, 0, 0x1030)
|
||||
D(0xa505, NIHL, RI_a, Z, r1_o, i2_16u, r1, 0, andi, 0, 0x1020)
|
||||
D(0xa506, NILH, RI_a, Z, r1_o, i2_16u, r1, 0, andi, 0, 0x1010)
|
||||
D(0xa507, NILL, RI_a, Z, r1_o, i2_16u, r1, 0, andi, 0, 0x1000)
|
||||
|
||||
/* COMPARE */
|
||||
C(0x1900, CR, RR_a, Z, r1_o, r2_o, 0, 0, 0, cmps32)
|
||||
|
@ -106,6 +113,17 @@
|
|||
C(0xb982, XGR, RRE, Z, r1, r2, r1, 0, xor, nz64)
|
||||
C(0xb9e7, XGRK, RRF_a, DO, r2, r3, r1, 0, xor, nz64)
|
||||
C(0xe382, XG, RXY_a, Z, r1, m2_64, r1, 0, xor, nz64)
|
||||
/* EXCLUSIVE OR IMMEDIATE */
|
||||
D(0xc006, XIHF, RIL_a, EI, r1_o, i2_32u, r1, 0, xori, 0, 0x2020)
|
||||
D(0xc007, XILF, RIL_a, EI, r1_o, i2_32u, r1, 0, xori, 0, 0x2000)
|
||||
|
||||
/* INSERT IMMEDIATE */
|
||||
D(0xc008, IIHF, RIL_a, EI, r1_o, i2_32u, r1, 0, insi, 0, 0x2020)
|
||||
D(0xc009, IILF, RIL_a, EI, r1_o, i2_32u, r1, 0, insi, 0, 0x2000)
|
||||
D(0xa500, IIHH, RI_a, Z, r1_o, i2_16u, r1, 0, insi, 0, 0x1030)
|
||||
D(0xa501, IIHL, RI_a, Z, r1_o, i2_16u, r1, 0, insi, 0, 0x1020)
|
||||
D(0xa502, IILH, RI_a, Z, r1_o, i2_16u, r1, 0, insi, 0, 0x1010)
|
||||
D(0xa503, IILL, RI_a, Z, r1_o, i2_16u, r1, 0, insi, 0, 0x1000)
|
||||
|
||||
/* LOAD */
|
||||
C(0x1800, LR, RR_a, Z, 0, r2_o, 0, cond_r1r2_32, mov2, 0)
|
||||
|
@ -223,6 +241,13 @@
|
|||
C(0xb981, OGR, RRE, Z, r1, r2, r1, 0, or, nz64)
|
||||
C(0xb9e6, OGRK, RRF_a, DO, r2, r3, r1, 0, or, nz64)
|
||||
C(0xe381, OG, RXY_a, Z, r1, m2_64, r1, 0, or, nz64)
|
||||
/* OR IMMEDIATE */
|
||||
D(0xc00c, OIHF, RIL_a, EI, r1_o, i2_32u, r1, 0, ori, 0, 0x2020)
|
||||
D(0xc00d, OILF, RIL_a, EI, r1_o, i2_32u, r1, 0, ori, 0, 0x2000)
|
||||
D(0xa508, OIHH, RI_a, Z, r1_o, i2_16u, r1, 0, ori, 0, 0x1030)
|
||||
D(0xa509, OIHL, RI_a, Z, r1_o, i2_16u, r1, 0, ori, 0, 0x1020)
|
||||
D(0xa50a, OILH, RI_a, Z, r1_o, i2_16u, r1, 0, ori, 0, 0x1010)
|
||||
D(0xa50b, OILL, RI_a, Z, r1_o, i2_16u, r1, 0, ori, 0, 0x1000)
|
||||
|
||||
/* SUBTRACT */
|
||||
C(0x1b00, SR, RR_a, Z, r1, r2, new, r1_32, sub, subs32)
|
||||
|
|
|
@ -1875,141 +1875,6 @@ static void disas_ed(CPUS390XState *env, DisasContext *s, int op, int r1,
|
|||
tcg_temp_free_i64(addr);
|
||||
}
|
||||
|
||||
static void disas_a5(CPUS390XState *env, DisasContext *s, int op, int r1,
|
||||
int i2)
|
||||
{
|
||||
TCGv_i64 tmp, tmp2;
|
||||
TCGv_i32 tmp32;
|
||||
LOG_DISAS("disas_a5: op 0x%x r1 %d i2 0x%x\n", op, r1, i2);
|
||||
switch (op) {
|
||||
case 0x0: /* IIHH R1,I2 [RI] */
|
||||
tmp = tcg_const_i64(i2);
|
||||
tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 48, 16);
|
||||
tcg_temp_free_i64(tmp);
|
||||
break;
|
||||
case 0x1: /* IIHL R1,I2 [RI] */
|
||||
tmp = tcg_const_i64(i2);
|
||||
tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 32, 16);
|
||||
tcg_temp_free_i64(tmp);
|
||||
break;
|
||||
case 0x2: /* IILH R1,I2 [RI] */
|
||||
tmp = tcg_const_i64(i2);
|
||||
tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 16, 16);
|
||||
tcg_temp_free_i64(tmp);
|
||||
break;
|
||||
case 0x3: /* IILL R1,I2 [RI] */
|
||||
tmp = tcg_const_i64(i2);
|
||||
tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 0, 16);
|
||||
tcg_temp_free_i64(tmp);
|
||||
break;
|
||||
case 0x4: /* NIHH R1,I2 [RI] */
|
||||
case 0x8: /* OIHH R1,I2 [RI] */
|
||||
tmp = load_reg(r1);
|
||||
tmp32 = tcg_temp_new_i32();
|
||||
switch (op) {
|
||||
case 0x4:
|
||||
tmp2 = tcg_const_i64((((uint64_t)i2) << 48)
|
||||
| 0x0000ffffffffffffULL);
|
||||
tcg_gen_and_i64(tmp, tmp, tmp2);
|
||||
break;
|
||||
case 0x8:
|
||||
tmp2 = tcg_const_i64(((uint64_t)i2) << 48);
|
||||
tcg_gen_or_i64(tmp, tmp, tmp2);
|
||||
break;
|
||||
default:
|
||||
tcg_abort();
|
||||
}
|
||||
store_reg(r1, tmp);
|
||||
tcg_gen_shri_i64(tmp2, tmp, 48);
|
||||
tcg_gen_trunc_i64_i32(tmp32, tmp2);
|
||||
set_cc_nz_u32(s, tmp32);
|
||||
tcg_temp_free_i64(tmp2);
|
||||
tcg_temp_free_i32(tmp32);
|
||||
tcg_temp_free_i64(tmp);
|
||||
break;
|
||||
case 0x5: /* NIHL R1,I2 [RI] */
|
||||
case 0x9: /* OIHL R1,I2 [RI] */
|
||||
tmp = load_reg(r1);
|
||||
tmp32 = tcg_temp_new_i32();
|
||||
switch (op) {
|
||||
case 0x5:
|
||||
tmp2 = tcg_const_i64((((uint64_t)i2) << 32)
|
||||
| 0xffff0000ffffffffULL);
|
||||
tcg_gen_and_i64(tmp, tmp, tmp2);
|
||||
break;
|
||||
case 0x9:
|
||||
tmp2 = tcg_const_i64(((uint64_t)i2) << 32);
|
||||
tcg_gen_or_i64(tmp, tmp, tmp2);
|
||||
break;
|
||||
default:
|
||||
tcg_abort();
|
||||
}
|
||||
store_reg(r1, tmp);
|
||||
tcg_gen_shri_i64(tmp2, tmp, 32);
|
||||
tcg_gen_trunc_i64_i32(tmp32, tmp2);
|
||||
tcg_gen_andi_i32(tmp32, tmp32, 0xffff);
|
||||
set_cc_nz_u32(s, tmp32);
|
||||
tcg_temp_free_i64(tmp2);
|
||||
tcg_temp_free_i32(tmp32);
|
||||
tcg_temp_free_i64(tmp);
|
||||
break;
|
||||
case 0x6: /* NILH R1,I2 [RI] */
|
||||
case 0xa: /* OILH R1,I2 [RI] */
|
||||
tmp = load_reg(r1);
|
||||
tmp32 = tcg_temp_new_i32();
|
||||
switch (op) {
|
||||
case 0x6:
|
||||
tmp2 = tcg_const_i64((((uint64_t)i2) << 16)
|
||||
| 0xffffffff0000ffffULL);
|
||||
tcg_gen_and_i64(tmp, tmp, tmp2);
|
||||
break;
|
||||
case 0xa:
|
||||
tmp2 = tcg_const_i64(((uint64_t)i2) << 16);
|
||||
tcg_gen_or_i64(tmp, tmp, tmp2);
|
||||
break;
|
||||
default:
|
||||
tcg_abort();
|
||||
}
|
||||
store_reg(r1, tmp);
|
||||
tcg_gen_shri_i64(tmp, tmp, 16);
|
||||
tcg_gen_trunc_i64_i32(tmp32, tmp);
|
||||
tcg_gen_andi_i32(tmp32, tmp32, 0xffff);
|
||||
set_cc_nz_u32(s, tmp32);
|
||||
tcg_temp_free_i64(tmp2);
|
||||
tcg_temp_free_i32(tmp32);
|
||||
tcg_temp_free_i64(tmp);
|
||||
break;
|
||||
case 0x7: /* NILL R1,I2 [RI] */
|
||||
case 0xb: /* OILL R1,I2 [RI] */
|
||||
tmp = load_reg(r1);
|
||||
tmp32 = tcg_temp_new_i32();
|
||||
switch (op) {
|
||||
case 0x7:
|
||||
tmp2 = tcg_const_i64(i2 | 0xffffffffffff0000ULL);
|
||||
tcg_gen_and_i64(tmp, tmp, tmp2);
|
||||
break;
|
||||
case 0xb:
|
||||
tmp2 = tcg_const_i64(i2);
|
||||
tcg_gen_or_i64(tmp, tmp, tmp2);
|
||||
break;
|
||||
default:
|
||||
tcg_abort();
|
||||
}
|
||||
store_reg(r1, tmp);
|
||||
tcg_gen_trunc_i64_i32(tmp32, tmp);
|
||||
tcg_gen_andi_i32(tmp32, tmp32, 0xffff);
|
||||
set_cc_nz_u32(s, tmp32); /* signedness should not matter here */
|
||||
tcg_temp_free_i64(tmp2);
|
||||
tcg_temp_free_i32(tmp32);
|
||||
tcg_temp_free_i64(tmp);
|
||||
break;
|
||||
default:
|
||||
LOG_DISAS("illegal a5 operation 0x%x\n", op);
|
||||
gen_illegal_opcode(s);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void disas_a7(CPUS390XState *env, DisasContext *s, int op, int r1,
|
||||
int i2)
|
||||
{
|
||||
|
@ -2918,44 +2783,6 @@ static void disas_c0(CPUS390XState *env, DisasContext *s, int op, int r1, int i2
|
|||
gen_goto_tb(s, 0, target);
|
||||
s->is_jmp = DISAS_TB_JUMP;
|
||||
break;
|
||||
case 0x7: /* XILF R1,I2 [RIL] */
|
||||
case 0xb: /* NILF R1,I2 [RIL] */
|
||||
case 0xd: /* OILF R1,I2 [RIL] */
|
||||
tmp32_1 = load_reg32(r1);
|
||||
switch (op) {
|
||||
case 0x7:
|
||||
tcg_gen_xori_i32(tmp32_1, tmp32_1, (uint32_t)i2);
|
||||
break;
|
||||
case 0xb:
|
||||
tcg_gen_andi_i32(tmp32_1, tmp32_1, (uint32_t)i2);
|
||||
break;
|
||||
case 0xd:
|
||||
tcg_gen_ori_i32(tmp32_1, tmp32_1, (uint32_t)i2);
|
||||
break;
|
||||
default:
|
||||
tcg_abort();
|
||||
}
|
||||
store_reg32(r1, tmp32_1);
|
||||
set_cc_nz_u32(s, tmp32_1);
|
||||
tcg_temp_free_i32(tmp32_1);
|
||||
break;
|
||||
case 0x9: /* IILF R1,I2 [RIL] */
|
||||
tmp32_1 = tcg_const_i32((uint32_t)i2);
|
||||
store_reg32(r1, tmp32_1);
|
||||
tcg_temp_free_i32(tmp32_1);
|
||||
break;
|
||||
case 0xa: /* NIHF R1,I2 [RIL] */
|
||||
tmp = load_reg(r1);
|
||||
tmp32_1 = tcg_temp_new_i32();
|
||||
tcg_gen_andi_i64(tmp, tmp, (((uint64_t)((uint32_t)i2)) << 32)
|
||||
| 0xffffffffULL);
|
||||
store_reg(r1, tmp);
|
||||
tcg_gen_shri_i64(tmp, tmp, 32);
|
||||
tcg_gen_trunc_i64_i32(tmp32_1, tmp);
|
||||
set_cc_nz_u32(s, tmp32_1);
|
||||
tcg_temp_free_i64(tmp);
|
||||
tcg_temp_free_i32(tmp32_1);
|
||||
break;
|
||||
default:
|
||||
LOG_DISAS("illegal c0 operation 0x%x\n", op);
|
||||
gen_illegal_opcode(s);
|
||||
|
@ -3487,13 +3314,6 @@ static void disas_s390_insn(CPUS390XState *env, DisasContext *s)
|
|||
tcg_temp_free_i32(tmp32_1);
|
||||
tcg_temp_free_i32(tmp32_2);
|
||||
break;
|
||||
case 0xa5:
|
||||
insn = ld_code4(env, s->pc);
|
||||
r1 = (insn >> 20) & 0xf;
|
||||
op = (insn >> 16) & 0xf;
|
||||
i2 = insn & 0xffff;
|
||||
disas_a5(env, s, op, r1, i2);
|
||||
break;
|
||||
case 0xa7:
|
||||
insn = ld_code4(env, s->pc);
|
||||
r1 = (insn >> 20) & 0xf;
|
||||
|
@ -4112,6 +3932,31 @@ static ExitStatus op_and(DisasContext *s, DisasOps *o)
|
|||
return NO_EXIT;
|
||||
}
|
||||
|
||||
static ExitStatus op_andi(DisasContext *s, DisasOps *o)
|
||||
{
|
||||
int shift = s->insn->data & 0xff;
|
||||
int size = s->insn->data >> 8;
|
||||
uint64_t mask = ((1ull << size) - 1) << shift;
|
||||
|
||||
assert(!o->g_in2);
|
||||
tcg_gen_shli_i64(o->in2, o->in2, shift);
|
||||
tcg_gen_ori_i64(o->in2, o->in2, ~mask);
|
||||
tcg_gen_and_i64(o->out, o->in1, o->in2);
|
||||
|
||||
/* Produce the CC from only the bits manipulated. */
|
||||
tcg_gen_andi_i64(cc_dst, o->out, mask);
|
||||
set_cc_nz_u64(s, cc_dst);
|
||||
return NO_EXIT;
|
||||
}
|
||||
|
||||
static ExitStatus op_insi(DisasContext *s, DisasOps *o)
|
||||
{
|
||||
int shift = s->insn->data & 0xff;
|
||||
int size = s->insn->data >> 8;
|
||||
tcg_gen_deposit_i64(o->out, o->in1, o->in2, shift, size);
|
||||
return NO_EXIT;
|
||||
}
|
||||
|
||||
static ExitStatus op_ld8s(DisasContext *s, DisasOps *o)
|
||||
{
|
||||
tcg_gen_qemu_ld8s(o->out, o->in2, get_mem_index(s));
|
||||
|
@ -4194,6 +4039,22 @@ static ExitStatus op_or(DisasContext *s, DisasOps *o)
|
|||
return NO_EXIT;
|
||||
}
|
||||
|
||||
static ExitStatus op_ori(DisasContext *s, DisasOps *o)
|
||||
{
|
||||
int shift = s->insn->data & 0xff;
|
||||
int size = s->insn->data >> 8;
|
||||
uint64_t mask = ((1ull << size) - 1) << shift;
|
||||
|
||||
assert(!o->g_in2);
|
||||
tcg_gen_shli_i64(o->in2, o->in2, shift);
|
||||
tcg_gen_or_i64(o->out, o->in1, o->in2);
|
||||
|
||||
/* Produce the CC from only the bits manipulated. */
|
||||
tcg_gen_andi_i64(cc_dst, o->out, mask);
|
||||
set_cc_nz_u64(s, cc_dst);
|
||||
return NO_EXIT;
|
||||
}
|
||||
|
||||
static ExitStatus op_sub(DisasContext *s, DisasOps *o)
|
||||
{
|
||||
tcg_gen_sub_i64(o->out, o->in1, o->in2);
|
||||
|
@ -4206,6 +4067,22 @@ static ExitStatus op_xor(DisasContext *s, DisasOps *o)
|
|||
return NO_EXIT;
|
||||
}
|
||||
|
||||
static ExitStatus op_xori(DisasContext *s, DisasOps *o)
|
||||
{
|
||||
int shift = s->insn->data & 0xff;
|
||||
int size = s->insn->data >> 8;
|
||||
uint64_t mask = ((1ull << size) - 1) << shift;
|
||||
|
||||
assert(!o->g_in2);
|
||||
tcg_gen_shli_i64(o->in2, o->in2, shift);
|
||||
tcg_gen_xor_i64(o->out, o->in1, o->in2);
|
||||
|
||||
/* Produce the CC from only the bits manipulated. */
|
||||
tcg_gen_andi_i64(cc_dst, o->out, mask);
|
||||
set_cc_nz_u64(s, cc_dst);
|
||||
return NO_EXIT;
|
||||
}
|
||||
|
||||
/* ====================================================================== */
|
||||
/* The "Cc OUTput" generators. Given the generated output (and in some cases
|
||||
the original inputs), update the various cc data structures in order to
|
||||
|
|
Loading…
Reference in New Issue