summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2012-08-17 10:27:29 -0700
committerRichard Henderson <rth@twiddle.net>2013-01-05 12:00:28 -0800
commitc698d8768756c66dd0dd55ea884c69c2212d59f9 (patch)
tree9aaa8ba31c9df844d622bb6a3bae29aedce4bb1b
parentaedec19d628dacf4f04ee7258ac2c5c9e47b5a7e (diff)
downloadqemu-c698d8768756c66dd0dd55ea884c69c2212d59f9.zip
target-s390: Convert LOAD (LOGICAL) BYTE, CHARACTER, HALFWORD
Signed-off-by: Richard Henderson <rth@twiddle.net>
-rw-r--r--target-s390x/insn-data.def30
-rw-r--r--target-s390x/translate.c157
2 files changed, 78 insertions, 109 deletions
diff --git a/target-s390x/insn-data.def b/target-s390x/insn-data.def
index f0dcea617c..796185f002 100644
--- a/target-s390x/insn-data.def
+++ b/target-s390x/insn-data.def
@@ -126,11 +126,41 @@
C(0xe371, LAY, RXY_a, LD, 0, a2, 0, r1, mov2, 0)
/* LOAD ADDRESS RELATIVE LONG */
C(0xc000, LARL, RIL_b, Z, 0, ri2, 0, r1, mov2, 0)
+/* LOAD BYTE */
+ C(0xb926, LBR, RRE, EI, 0, r2_8s, 0, r1_32, mov2, 0)
+ C(0xb906, LGBR, RRE, EI, 0, r2_8s, 0, r1, mov2, 0)
+ C(0xe376, LB, RXY_a, LD, 0, a2, new, r1_32, ld8s, 0)
+ C(0xe377, LGB, RXY_a, LD, 0, a2, r1, 0, ld8s, 0)
+/* LOAD HALFWORD */
+ C(0xb927, LHR, RRE, EI, 0, r2_16s, 0, r1_32, mov2, 0)
+ C(0xb907, LGHR, RRE, EI, 0, r2_16s, 0, r1, mov2, 0)
+ C(0x4800, LH, RX_a, Z, 0, a2, new, r1_32, ld16s, 0)
+ C(0xe378, LHY, RXY_a, LD, 0, a2, new, r1_32, ld16s, 0)
+ C(0xe315, LGH, RXY_a, Z, 0, a2, r1, 0, ld16s, 0)
+/* LOAD HALFWORD IMMEDIATE */
+ C(0xa708, LHI, RI_a, Z, 0, i2, 0, r1_32, mov2, 0)
+ C(0xa709, LGHI, RI_a, Z, 0, i2, 0, r1, mov2, 0)
+/* LOAD HALFWORD RELATIVE LONG */
+ C(0xc405, LHRL, RIL_b, GIE, 0, ri2, new, r1_32, ld16s, 0)
+ C(0xc404, LGHRL, RIL_b, GIE, 0, ri2, r1, 0, ld16s, 0)
/* LOAD LOGICAL */
C(0xb916, LLGFR, RRE, Z, 0, r2_32u, 0, r1, mov2, 0)
C(0xe316, LLGF, RXY_a, Z, 0, a2, r1, 0, ld32u, 0)
/* LOAD LOGICAL RELATIVE LONG */
C(0xc40e, LLGFRL, RIL_b, GIE, 0, ri2, r1, 0, ld32u, 0)
+/* LOAD LOGICAL CHARACTER */
+ C(0xb994, LLCR, RRE, EI, 0, r2_8u, 0, r1_32, mov2, 0)
+ C(0xb984, LLGCR, RRE, EI, 0, r2_8u, 0, r1, mov2, 0)
+ C(0xe394, LLC, RXY_a, EI, 0, a2, new, r1_32, ld8u, 0)
+ C(0xe390, LLGC, RXY_a, Z, 0, a2, r1, 0, ld8u, 0)
+/* LOAD LOGICAL HALFWORD */
+ C(0xb995, LLHR, RRE, EI, 0, r2_16u, 0, r1_32, mov2, 0)
+ C(0xb985, LLGHR, RRE, EI, 0, r2_16u, 0, r1, mov2, 0)
+ C(0xe395, LLH, RXY_a, EI, 0, a2, new, r1_32, ld16u, 0)
+ C(0xe391, LLGH, RXY_a, Z, 0, a2, r1, 0, ld16u, 0)
+/* LOAD LOGICAL HALFWORD RELATIVE LONG */
+ C(0xc402, LLHRL, RIL_b, GIE, 0, ri2, new, r1_32, ld16u, 0)
+ C(0xc406, LLGHRL, RIL_b, GIE, 0, ri2, r1, 0, ld16u, 0)
/* MULTIPLY */
C(0x1c00, MR, RR_a, Z, r1p1_32s, r2_32s, new, r1_D32, mul, 0)
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index 0cf090262f..840bd6e3a0 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -1391,12 +1391,6 @@ static void disas_e3(CPUS390XState *env, DisasContext* s, int op, int r1,
store_reg(r1, tmp2);
tcg_temp_free_i64(tmp2);
break;
- case 0x15: /* LGH R1,D2(X2,B2) [RXY] */
- tmp2 = tcg_temp_new_i64();
- tcg_gen_qemu_ld16s(tmp2, addr, get_mem_index(s));
- store_reg(r1, tmp2);
- tcg_temp_free_i64(tmp2);
- break;
case 0x17: /* LLGT R1,D2(X2,B2) [RXY] */
tmp2 = tcg_temp_new_i64();
tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s));
@@ -1458,30 +1452,6 @@ static void disas_e3(CPUS390XState *env, DisasContext* s, int op, int r1,
store_reg8(r1, tmp3);
tcg_temp_free_i64(tmp3);
break;
- case 0x76: /* LB R1,D2(X2,B2) [RXY] */
- case 0x77: /* LGB R1,D2(X2,B2) [RXY] */
- tmp2 = tcg_temp_new_i64();
- tcg_gen_qemu_ld8s(tmp2, addr, get_mem_index(s));
- switch (op) {
- case 0x76:
- tcg_gen_ext8s_i64(tmp2, tmp2);
- store_reg32_i64(r1, tmp2);
- break;
- case 0x77:
- tcg_gen_ext8s_i64(tmp2, tmp2);
- store_reg(r1, tmp2);
- break;
- default:
- tcg_abort();
- }
- tcg_temp_free_i64(tmp2);
- break;
- case 0x78: /* LHY R1,D2(X2,B2) [RXY] */
- tmp2 = tcg_temp_new_i64();
- tcg_gen_qemu_ld16s(tmp2, addr, get_mem_index(s));
- store_reg32_i64(r1, tmp2);
- tcg_temp_free_i64(tmp2);
- break;
case 0x87: /* DLG R1,D2(X2,B2) [RXY] */
tmp2 = tcg_temp_new_i64();
tmp32_1 = tcg_const_i32(r1);
@@ -1517,24 +1487,6 @@ static void disas_e3(CPUS390XState *env, DisasContext* s, int op, int r1,
tcg_temp_free_i64(tmp2);
tcg_temp_free_i32(tmp32_1);
break;
- case 0x90: /* LLGC R1,D2(X2,B2) [RXY] */
- tcg_gen_qemu_ld8u(regs[r1], addr, get_mem_index(s));
- break;
- case 0x91: /* LLGH R1,D2(X2,B2) [RXY] */
- tcg_gen_qemu_ld16u(regs[r1], addr, get_mem_index(s));
- break;
- case 0x94: /* LLC R1,D2(X2,B2) [RXY] */
- tmp2 = tcg_temp_new_i64();
- tcg_gen_qemu_ld8u(tmp2, addr, get_mem_index(s));
- store_reg32_i64(r1, tmp2);
- tcg_temp_free_i64(tmp2);
- break;
- case 0x95: /* LLH R1,D2(X2,B2) [RXY] */
- tmp2 = tcg_temp_new_i64();
- tcg_gen_qemu_ld16u(tmp2, addr, get_mem_index(s));
- store_reg32_i64(r1, tmp2);
- tcg_temp_free_i64(tmp2);
- break;
case 0x97: /* DL R1,D2(X2,B2) [RXY] */
/* reg(r1) = reg(r1, r1+1) % ld32(addr) */
/* reg(r1+1) = reg(r1, r1+1) / ld32(addr) */
@@ -2194,16 +2146,6 @@ static void disas_a7(CPUS390XState *env, DisasContext *s, int op, int r1,
s->is_jmp = DISAS_TB_JUMP;
tcg_temp_free_i64(tmp);
break;
- case 0x8: /* lhi r1, i2 */
- tmp32_1 = tcg_const_i32(i2);
- store_reg32(r1, tmp32_1);
- tcg_temp_free_i32(tmp32_1);
- break;
- case 0x9: /* lghi r1, i2 */
- tmp = tcg_const_i64(i2);
- store_reg(r1, tmp);
- tcg_temp_free_i64(tmp);
- break;
default:
LOG_DISAS("illegal a7 operation 0x%x\n", op);
gen_illegal_opcode(s);
@@ -2911,12 +2853,6 @@ static void disas_b9(CPUS390XState *env, DisasContext *s, int op, int r1,
}
tcg_temp_free_i64(tmp);
break;
- case 0x6: /* LGBR R1,R2 [RRE] */
- tmp2 = load_reg(r2);
- tcg_gen_ext8s_i64(tmp2, tmp2);
- store_reg(r1, tmp2);
- tcg_temp_free_i64(tmp2);
- break;
case 0xd: /* DSGR R1,R2 [RRE] */
case 0x1d: /* DSGFR R1,R2 [RRE] */
tmp = load_reg(r1 + 1);
@@ -2955,18 +2891,6 @@ static void disas_b9(CPUS390XState *env, DisasContext *s, int op, int r1,
store_reg32(r1, tmp32_1);
tcg_temp_free_i32(tmp32_1);
break;
- case 0x26: /* LBR R1,R2 [RRE] */
- tmp32_1 = load_reg32(r2);
- tcg_gen_ext8s_i32(tmp32_1, tmp32_1);
- store_reg32(r1, tmp32_1);
- tcg_temp_free_i32(tmp32_1);
- break;
- case 0x27: /* LHR R1,R2 [RRE] */
- tmp32_1 = load_reg32(r2);
- tcg_gen_ext16s_i32(tmp32_1, tmp32_1);
- store_reg32(r1, tmp32_1);
- tcg_temp_free_i32(tmp32_1);
- break;
case 0x83: /* FLOGR R1,R2 [RRE] */
tmp = load_reg(r2);
tmp32_1 = tcg_const_i32(r1);
@@ -2975,18 +2899,6 @@ static void disas_b9(CPUS390XState *env, DisasContext *s, int op, int r1,
tcg_temp_free_i64(tmp);
tcg_temp_free_i32(tmp32_1);
break;
- case 0x84: /* LLGCR R1,R2 [RRE] */
- tmp = load_reg(r2);
- tcg_gen_andi_i64(tmp, tmp, 0xff);
- store_reg(r1, tmp);
- tcg_temp_free_i64(tmp);
- break;
- case 0x85: /* LLGHR R1,R2 [RRE] */
- tmp = load_reg(r2);
- tcg_gen_andi_i64(tmp, tmp, 0xffff);
- store_reg(r1, tmp);
- tcg_temp_free_i64(tmp);
- break;
case 0x87: /* DLGR R1,R2 [RRE] */
tmp32_1 = tcg_const_i32(r1);
tmp = load_reg(r2);
@@ -3021,18 +2933,6 @@ static void disas_b9(CPUS390XState *env, DisasContext *s, int op, int r1,
tcg_temp_free_i64(tmp2);
tcg_temp_free_i32(tmp32_1);
break;
- case 0x94: /* LLCR R1,R2 [RRE] */
- tmp32_1 = load_reg32(r2);
- tcg_gen_andi_i32(tmp32_1, tmp32_1, 0xff);
- store_reg32(r1, tmp32_1);
- tcg_temp_free_i32(tmp32_1);
- break;
- case 0x95: /* LLHR R1,R2 [RRE] */
- tmp32_1 = load_reg32(r2);
- tcg_gen_andi_i32(tmp32_1, tmp32_1, 0xffff);
- store_reg32(r1, tmp32_1);
- tcg_temp_free_i32(tmp32_1);
- break;
case 0x97: /* DLR R1,R2 [RRE] */
/* reg(r1) = reg(r1, r1+1) % reg(r2) */
/* reg(r1+1) = reg(r1, r1+1) / reg(r2) */
@@ -3429,15 +3329,6 @@ static void disas_s390_insn(CPUS390XState *env, DisasContext *s)
tcg_temp_free_i64(tmp);
s->is_jmp = DISAS_TB_JUMP;
break;
- case 0x48: /* LH R1,D2(X2,B2) [RX] */
- insn = ld_code4(env, s->pc);
- tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
- tmp2 = tcg_temp_new_i64();
- tcg_gen_qemu_ld16s(tmp2, tmp, get_mem_index(s));
- store_reg32_i64(r1, tmp2);
- tcg_temp_free_i64(tmp);
- tcg_temp_free_i64(tmp2);
- break;
case 0x4d: /* BAS R1,D2(X2,B2) [RX] */
insn = ld_code4(env, s->pc);
tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
@@ -4366,6 +4257,30 @@ static ExitStatus op_and(DisasContext *s, DisasOps *o)
return NO_EXIT;
}
+static ExitStatus op_ld8s(DisasContext *s, DisasOps *o)
+{
+ tcg_gen_qemu_ld8s(o->out, o->in2, get_mem_index(s));
+ return NO_EXIT;
+}
+
+static ExitStatus op_ld8u(DisasContext *s, DisasOps *o)
+{
+ tcg_gen_qemu_ld8u(o->out, o->in2, get_mem_index(s));
+ return NO_EXIT;
+}
+
+static ExitStatus op_ld16s(DisasContext *s, DisasOps *o)
+{
+ tcg_gen_qemu_ld16s(o->out, o->in2, get_mem_index(s));
+ return NO_EXIT;
+}
+
+static ExitStatus op_ld16u(DisasContext *s, DisasOps *o)
+{
+ tcg_gen_qemu_ld16u(o->out, o->in2, get_mem_index(s));
+ return NO_EXIT;
+}
+
static ExitStatus op_ld32s(DisasContext *s, DisasOps *o)
{
tcg_gen_qemu_ld32s(o->out, o->in2, get_mem_index(s));
@@ -4676,6 +4591,30 @@ static void in2_r2_o(DisasContext *s, DisasFields *f, DisasOps *o)
o->g_in2 = true;
}
+static void in2_r2_8s(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+ o->in2 = tcg_temp_new_i64();
+ tcg_gen_ext8s_i64(o->in2, regs[get_field(f, r2)]);
+}
+
+static void in2_r2_8u(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+ o->in2 = tcg_temp_new_i64();
+ tcg_gen_ext8u_i64(o->in2, regs[get_field(f, r2)]);
+}
+
+static void in2_r2_16s(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+ o->in2 = tcg_temp_new_i64();
+ tcg_gen_ext16s_i64(o->in2, regs[get_field(f, r2)]);
+}
+
+static void in2_r2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+ o->in2 = tcg_temp_new_i64();
+ tcg_gen_ext16u_i64(o->in2, regs[get_field(f, r2)]);
+}
+
static void in2_r3(DisasContext *s, DisasFields *f, DisasOps *o)
{
o->in2 = load_reg(get_field(f, r3));