summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--target-s390x/insn-data.def19
-rw-r--r--target-s390x/translate.c28
2 files changed, 47 insertions, 0 deletions
diff --git a/target-s390x/insn-data.def b/target-s390x/insn-data.def
index 8b89ce6217..4478d1c8cf 100644
--- a/target-s390x/insn-data.def
+++ b/target-s390x/insn-data.def
@@ -166,6 +166,25 @@
/* COMPARE LOGICAL STRING */
C(0xb25d, CLST, RRE, Z, r1_o, r2_o, 0, 0, clst, 0)
+/* COMPARE AND BRANCH */
+ D(0xecf6, CRB, RRS, GIE, r1_32s, r2_32s, 0, 0, cj, 0, 0)
+ D(0xece4, CGRB, RRS, GIE, r1_o, r2_o, 0, 0, cj, 0, 0)
+ D(0xec76, CRJ, RIE_b, GIE, r1_32s, r2_32s, 0, 0, cj, 0, 0)
+ D(0xec64, CGRJ, RIE_b, GIE, r1_o, r2_o, 0, 0, cj, 0, 0)
+ D(0xecfe, CIB, RIS, GIE, r1_32s, i2, 0, 0, cj, 0, 0)
+ D(0xecfc, CGIB, RIS, GIE, r1_o, i2, 0, 0, cj, 0, 0)
+ D(0xec7e, CIJ, RIE_c, GIE, r1_32s, i2, 0, 0, cj, 0, 0)
+ D(0xec7c, CGIJ, RIE_c, GIE, r1_o, i2, 0, 0, cj, 0, 0)
+/* COMPARE LOGICAL AND BRANCH */
+ D(0xecf7, CLRB, RRS, GIE, r1_32u, r2_32u, 0, 0, cj, 0, 1)
+ D(0xece5, CLGRB, RRS, GIE, r1_o, r2_o, 0, 0, cj, 0, 1)
+ D(0xec77, CLRJ, RIE_b, GIE, r1_32u, r2_32u, 0, 0, cj, 0, 1)
+ D(0xec65, CLGRJ, RIE_b, GIE, r1_o, r2_o, 0, 0, cj, 0, 1)
+ D(0xecff, CLIB, RIS, GIE, r1_32u, i2_8u, 0, 0, cj, 0, 1)
+ D(0xecfd, CLGIB, RIS, GIE, r1_o, i2_8u, 0, 0, cj, 0, 1)
+ D(0xec7f, CLIJ, RIE_c, GIE, r1_32u, i2_8u, 0, 0, cj, 0, 1)
+ D(0xec7d, CLGIJ, RIE_c, GIE, r1_o, i2_8u, 0, 0, cj, 0, 1)
+
/* COMPARE AND SWAP */
C(0xba00, CS, RS_a, Z, r1_o, a2, new, r1_32, cs, 0)
C(0xeb14, CSY, RSY_a, LD, r1_o, a2, new, r1_32, cs, 0)
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index c87d97ffe2..d6f7121a2e 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -1427,6 +1427,34 @@ static ExitStatus op_bx64(DisasContext *s, DisasOps *o)
return help_branch(s, &c, is_imm, imm, o->in2);
}
+static ExitStatus op_cj(DisasContext *s, DisasOps *o)
+{
+ int imm, m3 = get_field(s->fields, m3);
+ bool is_imm;
+ DisasCompare c;
+
+ /* Bit 3 of the m3 field is reserved and should be zero.
+ Choose to ignore it wrt the ltgt_cond table above. */
+ c.cond = ltgt_cond[m3 & 14];
+ if (s->insn->data) {
+ c.cond = tcg_unsigned_cond(c.cond);
+ }
+ c.is_64 = c.g1 = c.g2 = true;
+ c.u.s64.a = o->in1;
+ c.u.s64.b = o->in2;
+
+ is_imm = have_field(s->fields, i4);
+ if (is_imm) {
+ imm = get_field(s->fields, i4);
+ } else {
+ imm = 0;
+ o->out = get_address(s, 0, get_field(s->fields, b4),
+ get_field(s->fields, d4));
+ }
+
+ return help_branch(s, &c, is_imm, imm, o->out);
+}
+
static ExitStatus op_ceb(DisasContext *s, DisasOps *o)
{
gen_helper_ceb(cc_op, cpu_env, o->in1, o->in2);