mirror of
https://git.proxmox.com/git/qemu
synced 2025-08-07 16:52:06 +00:00
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(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)
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user