From facfc8648728b5c5554b3269355a4c13824e664b Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 17 Aug 2012 15:01:36 -0700 Subject: [PATCH] target-s390: Convert AND, OR, XOR, INSERT IMMEDIATE Signed-off-by: Richard Henderson --- target-s390x/insn-data.def | 25 +++++ target-s390x/translate.c | 237 +++++++++++---------------------------------- 2 files changed, 82 insertions(+), 180 deletions(-) diff --git a/target-s390x/insn-data.def b/target-s390x/insn-data.def index 9507262..705b655 100644 --- a/target-s390x/insn-data.def +++ b/target-s390x/insn-data.def @@ -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) diff --git a/target-s390x/translate.c b/target-s390x/translate.c index 2da94f5..06db4c5 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -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 -- 2.7.4