diff mbox

[PULL,24/34] target-s390x: implement TRANSLATE AND TEST instruction

Message ID 1433461324-23584-25-git-send-email-agraf@suse.de
State New
Headers show

Commit Message

Alexander Graf June 4, 2015, 11:41 p.m. UTC
From: Aurelien Jarno <aurelien@aurel32.net>

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      |  1 +
 target-s390x/insn-data.def |  2 ++
 target-s390x/mem_helper.c  | 24 ++++++++++++++++++++++++
 target-s390x/translate.c   | 10 ++++++++++
 4 files changed, 37 insertions(+)

Comments

Paolo Bonzini June 20, 2015, 9:06 p.m. UTC | #1
On 05/06/2015 01:41, Alexander Graf wrote:
> From: Aurelien Jarno <aurelien@aurel32.net>
> 
> 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      |  1 +
>  target-s390x/insn-data.def |  2 ++
>  target-s390x/mem_helper.c  | 24 ++++++++++++++++++++++++
>  target-s390x/translate.c   | 10 ++++++++++
>  4 files changed, 37 insertions(+)
> 
> diff --git a/target-s390x/helper.h b/target-s390x/helper.h
> index cb0b421..48b015e 100644
> --- a/target-s390x/helper.h
> +++ b/target-s390x/helper.h
> @@ -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)
> diff --git a/target-s390x/insn-data.def b/target-s390x/insn-data.def
> index a12939d..e401754 100644
> --- a/target-s390x/insn-data.def
> +++ b/target-s390x/insn-data.def
> @@ -759,6 +759,8 @@
>  
>  /* 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
> diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c
> index 0e8cd0f..e19e1aa 100644
> --- a/target-s390x/mem_helper.c
> +++ b/target-s390x/mem_helper.c
> @@ -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));

Missing break here.

Paolo

> +        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)
>  {
> diff --git a/target-s390x/translate.c b/target-s390x/translate.c
> index b0dbfe8..003598d 100644
> --- a/target-s390x/translate.c
> +++ b/target-s390x/translate.c
> @@ -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));
>
Aurelien Jarno June 21, 2015, 2:24 p.m. UTC | #2
On 2015-06-20 23:06, Paolo Bonzini wrote:
> 
> 
> On 05/06/2015 01:41, Alexander Graf wrote:
> > From: Aurelien Jarno <aurelien@aurel32.net>
> > 
> > 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      |  1 +
> >  target-s390x/insn-data.def |  2 ++
> >  target-s390x/mem_helper.c  | 24 ++++++++++++++++++++++++
> >  target-s390x/translate.c   | 10 ++++++++++
> >  4 files changed, 37 insertions(+)
> > 
> > diff --git a/target-s390x/helper.h b/target-s390x/helper.h
> > index cb0b421..48b015e 100644
> > --- a/target-s390x/helper.h
> > +++ b/target-s390x/helper.h
> > @@ -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)
> > diff --git a/target-s390x/insn-data.def b/target-s390x/insn-data.def
> > index a12939d..e401754 100644
> > --- a/target-s390x/insn-data.def
> > +++ b/target-s390x/insn-data.def
> > @@ -759,6 +759,8 @@
> >  
> >  /* 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
> > diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c
> > index 0e8cd0f..e19e1aa 100644
> > --- a/target-s390x/mem_helper.c
> > +++ b/target-s390x/mem_helper.c
> > @@ -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));
> 
> Missing break here.

Good catch, I'll send a patch to fix that. Thanks.

Aurelien
diff mbox

Patch

diff --git a/target-s390x/helper.h b/target-s390x/helper.h
index cb0b421..48b015e 100644
--- a/target-s390x/helper.h
+++ b/target-s390x/helper.h
@@ -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)
diff --git a/target-s390x/insn-data.def b/target-s390x/insn-data.def
index a12939d..e401754 100644
--- a/target-s390x/insn-data.def
+++ b/target-s390x/insn-data.def
@@ -759,6 +759,8 @@ 
 
 /* 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
diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c
index 0e8cd0f..e19e1aa 100644
--- a/target-s390x/mem_helper.c
+++ b/target-s390x/mem_helper.c
@@ -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)
 {
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index b0dbfe8..003598d 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -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));