target-s390: Convert AND, OR, XOR, INSERT IMMEDIATE

Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
Richard Henderson 2012-08-17 15:01:36 -07:00
parent b9bca3e57a
commit facfc86487
2 changed files with 82 additions and 180 deletions

View File

@ -49,6 +49,13 @@
C(0xb980, NGR, RRE, Z, r1, r2, r1, 0, and, nz64) C(0xb980, NGR, RRE, Z, r1, r2, r1, 0, and, nz64)
C(0xb9e4, NGRK, RRF_a, DO, r2, r3, 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) 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 */ /* COMPARE */
C(0x1900, CR, RR_a, Z, r1_o, r2_o, 0, 0, 0, cmps32) 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(0xb982, XGR, RRE, Z, r1, r2, r1, 0, xor, nz64)
C(0xb9e7, XGRK, RRF_a, DO, r2, r3, 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) 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 */ /* LOAD */
C(0x1800, LR, RR_a, Z, 0, r2_o, 0, cond_r1r2_32, mov2, 0) 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(0xb981, OGR, RRE, Z, r1, r2, r1, 0, or, nz64)
C(0xb9e6, OGRK, RRF_a, DO, r2, r3, 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) 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 */ /* SUBTRACT */
C(0x1b00, SR, RR_a, Z, r1, r2, new, r1_32, sub, subs32) C(0x1b00, SR, RR_a, Z, r1, r2, new, r1_32, sub, subs32)

View File

@ -1875,141 +1875,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_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, static void disas_a7(CPUS390XState *env, DisasContext *s, int op, int r1,
int i2) 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); gen_goto_tb(s, 0, target);
s->is_jmp = DISAS_TB_JUMP; s->is_jmp = DISAS_TB_JUMP;
break; 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: default:
LOG_DISAS("illegal c0 operation 0x%x\n", op); LOG_DISAS("illegal c0 operation 0x%x\n", op);
gen_illegal_opcode(s); 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_1);
tcg_temp_free_i32(tmp32_2); tcg_temp_free_i32(tmp32_2);
break; 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: case 0xa7:
insn = ld_code4(env, s->pc); insn = ld_code4(env, s->pc);
r1 = (insn >> 20) & 0xf; r1 = (insn >> 20) & 0xf;
@ -4112,6 +3932,31 @@ static ExitStatus op_and(DisasContext *s, DisasOps *o)
return NO_EXIT; 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) static ExitStatus op_ld8s(DisasContext *s, DisasOps *o)
{ {
tcg_gen_qemu_ld8s(o->out, o->in2, get_mem_index(s)); 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; 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) static ExitStatus op_sub(DisasContext *s, DisasOps *o)
{ {
tcg_gen_sub_i64(o->out, o->in1, o->in2); 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; 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 "Cc OUTput" generators. Given the generated output (and in some cases
the original inputs), update the various cc data structures in order to the original inputs), update the various cc data structures in order to