]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
s390: support RISBLG/RISBHG, MVCIN, LDE/LDER
authorChristian Borntraeger <borntraeger@de.ibm.com>
Fri, 7 Oct 2016 07:07:10 +0000 (07:07 +0000)
committerChristian Borntraeger <borntraeger@de.ibm.com>
Fri, 7 Oct 2016 07:07:10 +0000 (07:07 +0000)
patch by Andreas Arnez

git-svn-id: svn://svn.valgrind.org/vex/trunk@3259

VEX/priv/guest_s390_toIR.c

index a587d2e939843e05d07a310ef1e50fc09d3eb396..59cddfd7b32ce7442686cebcf3d32ced1f1146e8 100644 (file)
@@ -3830,6 +3830,16 @@ s390_irgen_BRCT(UChar r1, UShort i2)
    return "brct";
 }
 
+static const HChar *
+s390_irgen_BRCTH(UChar r1, UInt i2)
+{
+   put_gpr_w0(r1, binop(Iop_Sub32, get_gpr_w0(r1), mkU32(1)));
+   if_condition_goto(binop(Iop_CmpNE32, get_gpr_w0(r1), mkU32(0)),
+                     guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
+
+   return "brcth";
+}
+
 static const HChar *
 s390_irgen_BRCTG(UChar r1, UShort i2)
 {
@@ -7633,6 +7643,65 @@ s390_irgen_RISBGN(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
    return s390_irgen_RISBGx(r1, r2, i3, i4, i5, False);
 }
 
+static IRExpr *
+s390_irgen_RISBxG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5,
+                  Bool high)
+{
+   UChar from;
+   UChar to;
+   UChar rot;
+   UChar z_bit;
+   UInt mask;
+   UInt maskc;
+   IRTemp op2 = newTemp(Ity_I32);
+
+   from = i3 & 31;
+   to = i4 & 31;
+   rot = i5 & 63;
+   z_bit = i4 & 128;
+   if (rot == 0) {
+      assign(op2, high ? get_gpr_w0(r2) : get_gpr_w1(r2));
+   } else if (rot == 32) {
+      assign(op2, high ? get_gpr_w1(r2) : get_gpr_w0(r2));
+   } else {
+      assign(op2,
+             unop(high ? Iop_64HIto32 : Iop_64to32,
+                  binop(Iop_Or64,
+                        binop(Iop_Shl64, get_gpr_dw0(r2), mkU8(rot)),
+                        binop(Iop_Shr64, get_gpr_dw0(r2), mkU8(64 - rot)))));
+   }
+   if (from <= to) {
+      mask = ~0U;
+      mask = (mask >> from) & (mask << (31 - to));
+      maskc = ~mask;
+   } else {
+      maskc = ~0U;
+      maskc = (maskc >> (to + 1)) & (maskc << (32 - from));
+      mask = ~maskc;
+   }
+   if (z_bit) {
+      return binop(Iop_And32, mkexpr(op2), mkU32(mask));
+   }
+   return binop(Iop_Or32,
+                binop(Iop_And32, high ? get_gpr_w0(r1) : get_gpr_w1(r1),
+                      mkU32(maskc)),
+                binop(Iop_And32, mkexpr(op2), mkU32(mask)));
+}
+
+static const HChar *
+s390_irgen_RISBHG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
+{
+   put_gpr_w0(r1, s390_irgen_RISBxG(r1, r2, i3, i4, i5, True));
+   return "risbhg";
+}
+
+static const HChar *
+s390_irgen_RISBLG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
+{
+   put_gpr_w1(r1, s390_irgen_RISBxG(r1, r2, i3, i4, i5, False));
+   return "risblg";
+}
+
 static const HChar *
 s390_irgen_SAR(UChar r1, UChar r2)
 {
@@ -8769,6 +8838,15 @@ s390_irgen_LDR(UChar r1, UChar r2)
    return "ldr";
 }
 
+static const HChar *
+s390_irgen_LDER(UChar r1, UChar r2)
+{
+   put_fpr_dw0(r1, mkF64i(0x0));
+   put_fpr_w0(r1, get_fpr_w0(r2));
+
+   return "lder";
+}
+
 static const HChar *
 s390_irgen_LXR(UChar r1, UChar r2)
 {
@@ -8794,6 +8872,15 @@ s390_irgen_LD(UChar r1, IRTemp op2addr)
    return "ld";
 }
 
+static const HChar *
+s390_irgen_LDE(UChar r1, IRTemp op2addr)
+{
+   put_fpr_dw0(r1, mkF64i(0x0));
+   put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
+
+   return "lde";
+}
+
 static const HChar *
 s390_irgen_LEY(UChar r1, IRTemp op2addr)
 {
@@ -10910,6 +10997,22 @@ s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
    put_counter_dw0(mkU64(0));
 }
 
+static void
+s390_irgen_MVCIN_EX(IRTemp length, IRTemp start1, IRTemp start2)
+{
+   IRTemp counter = newTemp(Ity_I64);
+
+   assign(counter, get_counter_dw0());
+
+   store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
+         load(Ity_I8, binop(Iop_Sub64, mkexpr(start2), mkexpr(counter))));
+
+   /* Check for end of field */
+   put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
+   iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
+   put_counter_dw0(mkU64(0));
+}
+
 static void
 s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
 {
@@ -11043,6 +11146,11 @@ s390_irgen_EX(UChar r1, IRTemp addr2)
       s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
       return "ex@tr";
 
+   case 0xe800000000000000ULL:
+      /* special case MVCIN */
+      s390_irgen_EX_SS(r1, addr2, s390_irgen_MVCIN_EX, 64);
+      return "ex@mvcin";
+
    default:
    {
       /* everything else will get a self checking prefix that also checks the
@@ -11486,6 +11594,17 @@ s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
    return "mvc";
 }
 
+static const HChar *
+s390_irgen_MVCIN(UChar length, IRTemp start1, IRTemp start2)
+{
+   IRTemp len = newTemp(Ity_I64);
+
+   assign(len, mkU64(length));
+   s390_irgen_MVCIN_EX(len, start1, start2);
+
+   return "mvcin";
+}
+
 static const HChar *
 s390_irgen_MVCL(UChar r1, UChar r2)
 {
@@ -14560,7 +14679,8 @@ s390_decode_4byte_and_irgen(const UChar *bytes)
                                      ovl.fmt.RRF.r3, ovl.fmt.RRF.r2);  goto ok;
    case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
                                      ovl.fmt.RRF.r3, ovl.fmt.RRF.r2);  goto ok;
-   case 0xb324: /* LDER */ goto unimplemented;
+   case 0xb324: s390_format_RRE_FF(s390_irgen_LDER, ovl.fmt.RRE.r1,
+                                   ovl.fmt.RRE.r2); goto ok;
    case 0xb325: /* LXDR */ goto unimplemented;
    case 0xb326: /* LXER */ goto unimplemented;
    case 0xb32e: /* MAER */ goto unimplemented;
@@ -16046,7 +16166,13 @@ s390_decode_6byte_and_irgen(const UChar *bytes)
    case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
                                                ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
                                                goto ok;
-   case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
+   case 0xec0000000051ULL: s390_format_RIE_RRUUU(s390_irgen_RISBLG,
+                                                 ovl.fmt.RIE_RRUUU.r1,
+                                                 ovl.fmt.RIE_RRUUU.r2,
+                                                 ovl.fmt.RIE_RRUUU.i3,
+                                                 ovl.fmt.RIE_RRUUU.i4,
+                                                 ovl.fmt.RIE_RRUUU.i5);
+                                                 goto ok;
    case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
                                                  ovl.fmt.RIE_RRUUU.r1,
                                                  ovl.fmt.RIE_RRUUU.r2,
@@ -16082,7 +16208,13 @@ s390_decode_6byte_and_irgen(const UChar *bytes)
                                                  ovl.fmt.RIE_RRUUU.i4,
                                                  ovl.fmt.RIE_RRUUU.i5);
                                                  goto ok;
-   case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
+   case 0xec000000005dULL: s390_format_RIE_RRUUU(s390_irgen_RISBHG,
+                                                 ovl.fmt.RIE_RRUUU.r1,
+                                                 ovl.fmt.RIE_RRUUU.r2,
+                                                 ovl.fmt.RIE_RRUUU.i3,
+                                                 ovl.fmt.RIE_RRUUU.i4,
+                                                 ovl.fmt.RIE_RRUUU.i5);
+                                                 goto ok;
    case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
                                                 ovl.fmt.RIE_RRPU.r1,
                                                 ovl.fmt.RIE_RRPU.r2,
@@ -16245,7 +16377,10 @@ s390_decode_6byte_and_irgen(const UChar *bytes)
                                                  ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
                                                  ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
                                                  ovl.fmt.RXF.r1);  goto ok;
-   case 0xed0000000024ULL: /* LDE */ goto unimplemented;
+   case 0xed0000000024ULL: s390_format_RXE_FRRD(s390_irgen_LDE,
+                                                ovl.fmt.RXE.r1, ovl.fmt.RXE.x2,
+                                                ovl.fmt.RXE.b2,
+                                                ovl.fmt.RXE.d2); goto ok;
    case 0xed0000000025ULL: /* LXD */ goto unimplemented;
    case 0xed0000000026ULL: /* LXE */ goto unimplemented;
    case 0xed000000002eULL: /* MAE */ goto unimplemented;
@@ -16421,7 +16556,8 @@ s390_decode_6byte_and_irgen(const UChar *bytes)
    case 0xc802ULL: /* CSST */ goto unimplemented;
    case 0xc804ULL: /* LPD */ goto unimplemented;
    case 0xc805ULL: /* LPDG */ goto unimplemented;
-   case 0xcc06ULL: /* BRCTH */ goto unimplemented;
+   case 0xcc06ULL:  s390_format_RIL_RP(s390_irgen_BRCTH, ovl.fmt.RIL.r1,
+                                       ovl.fmt.RIL.i2);  goto ok;
    case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
                                       ovl.fmt.RIL.i2);  goto ok;
    case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
@@ -16471,7 +16607,9 @@ s390_decode_6byte_and_irgen(const UChar *bytes)
    case 0xdfULL: /* EDMK */ goto unimplemented;
    case 0xe1ULL: /* PKU */ goto unimplemented;
    case 0xe2ULL: /* UNPKU */ goto unimplemented;
-   case 0xe8ULL: /* MVCIN */ goto unimplemented;
+   case 0xe8ULL: s390_format_SS_L0RDRD(s390_irgen_MVCIN, ovl.fmt.SS.l,
+                                       ovl.fmt.SS.b1, ovl.fmt.SS.d1,
+                                       ovl.fmt.SS.b2, ovl.fmt.SS.d2);  goto ok;
    case 0xe9ULL: /* PKA */ goto unimplemented;
    case 0xeaULL: /* UNPKA */ goto unimplemented;
    case 0xeeULL: /* PLO */ goto unimplemented;