target-s390: Convert EXECUTE
authorRichard Henderson <rth@twiddle.net>
Tue, 21 Aug 2012 20:48:38 +0000 (13:48 -0700)
committerRichard Henderson <rth@twiddle.net>
Sat, 5 Jan 2013 20:18:38 +0000 (12:18 -0800)
Signed-off-by: Richard Henderson <rth@twiddle.net>
target-s390x/insn-data.def
target-s390x/translate.c

index 38a93e31115e39a05d1b249c018ccd8b5d1bbe6d..0768849266d2452b8d1ee39dfd7d11773861ee45 100644 (file)
     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)
 
+/* EXECUTE */
+    C(0x4400, EX,      RX_a,  Z,   r1_o, a2, 0, 0, ex, 0)
+/* EXECUTE RELATIVE LONG */
+    C(0xc600, EXRL,    RIL_b, EE,  r1_o, ri2, 0, 0, ex, 0)
+
 /* INSERT CHARACTER */
     C(0x4300, IC,      RX_a,  Z,   0, m2_8u, 0, r1_8, mov2, 0)
     C(0xe373, ICY,     RXY_a, LD,  0, m2_8u, 0, r1_8, mov2, 0)
index 36d8cdd102da721cbdb3b553c65ca2b54dc24d80..bece7c56d860a77e07fab84246fd43caa3883dfb 100644 (file)
@@ -2355,19 +2355,6 @@ static void disas_s390_insn(CPUS390XState *env, DisasContext *s)
     LOG_DISAS("opc 0x%x\n", opc);
 
     switch (opc) {
-    case 0x44: /* EX     R1,D2(X2,B2)     [RX] */
-        insn = ld_code4(env, s->pc);
-        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
-        tmp2 = load_reg(r1);
-        tmp3 = tcg_const_i64(s->pc + 4);
-        update_psw_addr(s);
-        gen_op_calc_cc(s);
-        gen_helper_ex(cc_op, cpu_env, cc_op, tmp2, tmp, tmp3);
-        set_cc_static(s);
-        tcg_temp_free_i64(tmp);
-        tcg_temp_free_i64(tmp2);
-        tcg_temp_free_i64(tmp3);
-        break;
     case 0x4e: /* CVD    R1,D2(X2,B2)     [RX] */
         insn = ld_code4(env, s->pc);
         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
@@ -3423,6 +3410,32 @@ static ExitStatus op_divu64(DisasContext *s, DisasOps *o)
     return NO_EXIT;
 }
 
+static ExitStatus op_ex(DisasContext *s, DisasOps *o)
+{
+    /* ??? Perhaps a better way to implement EXECUTE is to set a bit in
+       tb->flags, (ab)use the tb->cs_base field as the address of
+       the template in memory, and grab 8 bits of tb->flags/cflags for
+       the contents of the register.  We would then recognize all this
+       in gen_intermediate_code_internal, generating code for exactly
+       one instruction.  This new TB then gets executed normally.
+
+       On the other hand, this seems to be mostly used for modifying
+       MVC inside of memcpy, which needs a helper call anyway.  So
+       perhaps this doesn't bear thinking about any further.  */
+
+    TCGv_i64 tmp;
+
+    update_psw_addr(s);
+    gen_op_calc_cc(s);
+
+    tmp = tcg_const_i64(s->next_pc);
+    gen_helper_ex(cc_op, cpu_env, cc_op, o->in1, o->in2, tmp);
+    tcg_temp_free_i64(tmp);
+
+    set_cc_static(s);
+    return NO_EXIT;
+}
+
 static ExitStatus op_icm(DisasContext *s, DisasOps *o)
 {
     int m3 = get_field(s->fields, m3);