target-s390x: implement TRANSLATE AND TEST instruction
authorAurelien Jarno <aurelien@aurel32.net>
Wed, 3 Jun 2015 21:09:47 +0000 (23:09 +0200)
committerAlexander Graf <agraf@suse.de>
Thu, 4 Jun 2015 23:37:59 +0000 (01:37 +0200)
It is part of the basic zArchitecture instructions. Allow it to be call
from EXECUTE.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
target-s390x/helper.h
target-s390x/insn-data.def
target-s390x/mem_helper.c
target-s390x/translate.c

index cb0b421cd876097f6ce8376e5e5ea5ed98739488..48b015eab32672c577adf4f7e250760a6ee69c55 100644 (file)
@@ -77,6 +77,7 @@ DEF_HELPER_FLAGS_3(sqxb, TCG_CALL_NO_WG, i64, env, i64, i64)
 DEF_HELPER_FLAGS_1(cvd, TCG_CALL_NO_RWG_SE, i64, s32)
 DEF_HELPER_FLAGS_4(unpk, TCG_CALL_NO_WG, void, env, i32, i64, i64)
 DEF_HELPER_FLAGS_4(tr, TCG_CALL_NO_WG, void, env, i32, i64, i64)
+DEF_HELPER_4(trt, i32, env, i32, i64, i64)
 DEF_HELPER_4(cksm, i64, env, i64, i64, i64)
 DEF_HELPER_FLAGS_5(calc_cc, TCG_CALL_NO_RWG_SE, i32, env, i32, i64, i64, i64)
 DEF_HELPER_FLAGS_2(sfpc, TCG_CALL_NO_RWG, void, env, i64)
index a12939de669b2636c54c12bff78c3c8401898247..e401754046286238fba09206e496450847fe8327 100644 (file)
 
 /* TRANSLATE */
     C(0xdc00, TR,      SS_a,  Z,   la1, a2, 0, 0, tr, 0)
+/* TRANSLATE AND TEST */
+    C(0xdd00, TRT,     SS_a,  Z,   la1, a2, 0, 0, trt, 0)
 
 /* UNPACK */
     /* Really format SS_b, but we pack both lengths into one argument
index 0e8cd0f4895cb1c377d69f75b38b27a1baf7d147..e19e1aa961e08de4b4c252cfe0ddffcd5e34ce0c 100644 (file)
@@ -509,6 +509,9 @@ uint32_t HELPER(ex)(CPUS390XState *env, uint32_t cc, uint64_t v1,
         case 0xc00:
             helper_tr(env, l, get_address(env, 0, b1, d1),
                       get_address(env, 0, b2, d2));
+        case 0xd00:
+            cc = helper_trt(env, l, get_address(env, 0, b1, d1),
+                            get_address(env, 0, b2, d2));
             break;
         default:
             goto abort;
@@ -801,6 +804,27 @@ void HELPER(tr)(CPUS390XState *env, uint32_t len, uint64_t array,
     }
 }
 
+uint32_t HELPER(trt)(CPUS390XState *env, uint32_t len, uint64_t array,
+                     uint64_t trans)
+{
+    uint32_t cc = 0;
+    int i;
+
+    for (i = 0; i <= len; i++) {
+        uint8_t byte = cpu_ldub_data(env, array + i);
+        uint8_t sbyte = cpu_ldub_data(env, trans + byte);
+
+        if (sbyte != 0) {
+            env->regs[1] = array + i;
+            env->regs[2] = (env->regs[2] & ~0xff) | sbyte;
+            cc = (i == len) ? 2 : 1;
+            break;
+        }
+    }
+
+    return cc;
+}
+
 #if !defined(CONFIG_USER_ONLY)
 void HELPER(lctlg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
 {
index b0dbfe8da705543ab366d9771861b9cfd6fa4b93..003598df6be9d7e2c17905da264667b5e4b0c90c 100644 (file)
@@ -3787,6 +3787,16 @@ static ExitStatus op_tr(DisasContext *s, DisasOps *o)
     return NO_EXIT;
 }
 
+static ExitStatus op_trt(DisasContext *s, DisasOps *o)
+{
+    TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
+    potential_page_fault(s);
+    gen_helper_trt(cc_op, cpu_env, l, o->addr1, o->in2);
+    tcg_temp_free_i32(l);
+    set_cc_static(s);
+    return NO_EXIT;
+}
+
 static ExitStatus op_unpk(DisasContext *s, DisasOps *o)
 {
     TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));