From 45aa9aa3b7730b38403553355b36a29f8905916a Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 16 Jun 2017 16:35:34 -0700 Subject: [PATCH] target/s390x: Implement load-on-condition-2 insns Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- target/s390x/insn-data.def | 9 +++++++++ target/s390x/insn-format.def | 1 + target/s390x/translate.c | 18 +++++++++++++++--- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def index aa4c5b255c..c8ad4da531 100644 --- a/target/s390x/insn-data.def +++ b/target/s390x/insn-data.def @@ -514,6 +514,13 @@ C(0xb9e2, LOCGR, RRF_c, LOC, r1, r2, r1, 0, loc, 0) C(0xebf2, LOC, RSY_b, LOC, r1, m2_32u, new, r1_32, loc, 0) C(0xebe2, LOCG, RSY_b, LOC, r1, m2_64, r1, 0, loc, 0) +/* LOAD HALFWORD IMMEDIATE ON CONDITION */ + C(0xec42, LOCHI, RIE_g, LOC2, r1, i2, new, r1_32, loc, 0) + C(0xec46, LOCGHI, RIE_g, LOC2, r1, i2, r1, 0, loc, 0) + C(0xec4e, LOCHHI, RIE_g, LOC2, r1_sr32, i2, new, r1_32h, loc, 0) +/* LOAD HIGH ON CONDITION */ + C(0xb9e0, LOCFHR, RRF_c, LOC2, r1_sr32, r2, new, r1_32h, loc, 0) + C(0xebe0, LOCFH, RSY_b, LOC2, r1_sr32, m2_32u, new, r1_32h, loc, 0) /* LOAD PAIR DISJOINT */ D(0xc804, LPD, SSF, ILA, 0, 0, new_P, r3_P32, lpd, 0, MO_TEUL) D(0xc805, LPDG, SSF, ILA, 0, 0, new_P, r3_P64, lpd, 0, MO_TEQ) @@ -779,6 +786,8 @@ /* STORE ON CONDITION */ D(0xebf3, STOC, RSY_b, LOC, 0, 0, 0, 0, soc, 0, 0) D(0xebe3, STOCG, RSY_b, LOC, 0, 0, 0, 0, soc, 0, 1) +/* STORE HIGH ON CONDITION */ + D(0xebe1, STOCFH, RSY_b, LOC2, 0, 0, 0, 0, soc, 0, 2) /* STORE REVERSED */ C(0xe33f, STRVH, RXY_a, Z, la2, r1_16u, new, m1_16, rev16, 0) C(0xe33e, STRV, RXY_a, Z, la2, r1_32u, new, m1_32, rev32, 0) diff --git a/target/s390x/insn-format.def b/target/s390x/insn-format.def index 0e898b90bd..a412d90fb7 100644 --- a/target/s390x/insn-format.def +++ b/target/s390x/insn-format.def @@ -11,6 +11,7 @@ F4(RIE_c, R(1, 8), I(2,32, 8), M(3,12), I(4,16,16)) F3(RIE_d, R(1, 8), I(2,16,16), R(3,12)) F3(RIE_e, R(1, 8), I(2,16,16), R(3,12)) F5(RIE_f, R(1, 8), R(2,12), I(3,16,8), I(4,24,8), I(5,32,8)) +F3(RIE_g, R(1, 8), I(2,16,16), M(3,12)) F2(RIL_a, R(1, 8), I(2,16,32)) F2(RIL_b, R(1, 8), I(2,16,32)) F2(RIL_c, M(1, 8), I(2,16,32)) diff --git a/target/s390x/translate.c b/target/s390x/translate.c index 802ccd9752..9932afb0f9 100644 --- a/target/s390x/translate.c +++ b/target/s390x/translate.c @@ -3641,7 +3641,7 @@ static ExitStatus op_sigp(DisasContext *s, DisasOps *o) static ExitStatus op_soc(DisasContext *s, DisasOps *o) { DisasCompare c; - TCGv_i64 a; + TCGv_i64 a, h; TCGLabel *lab; int r1; @@ -3661,10 +3661,21 @@ static ExitStatus op_soc(DisasContext *s, DisasOps *o) r1 = get_field(s->fields, r1); a = get_address(s, 0, get_field(s->fields, b2), get_field(s->fields, d2)); - if (s->insn->data) { + switch (s->insn->data) { + case 1: /* STOCG */ tcg_gen_qemu_st64(regs[r1], a, get_mem_index(s)); - } else { + break; + case 0: /* STOC */ tcg_gen_qemu_st32(regs[r1], a, get_mem_index(s)); + break; + case 2: /* STOCFH */ + h = tcg_temp_new_i64(); + tcg_gen_shri_i64(h, regs[r1], 32); + tcg_gen_qemu_st32(h, a, get_mem_index(s)); + tcg_temp_free_i64(h); + break; + default: + g_assert_not_reached(); } tcg_temp_free_i64(a); @@ -5416,6 +5427,7 @@ enum DisasInsnEnum { #define FAC_MIE S390_FEAT_STFLE_49 /* misc-instruction-extensions */ #define FAC_LAT S390_FEAT_STFLE_49 /* load-and-trap */ #define FAC_LOC S390_FEAT_STFLE_45 /* load/store on condition 1 */ +#define FAC_LOC2 S390_FEAT_STFLE_53 /* load/store on condition 2 */ #define FAC_LD S390_FEAT_LONG_DISPLACEMENT #define FAC_PC S390_FEAT_STFLE_45 /* population count */ #define FAC_SCF S390_FEAT_STORE_CLOCK_FAST