]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Implement CLREX. Fixes #359838.
authorJulian Seward <jseward@acm.org>
Tue, 19 Jul 2016 07:05:34 +0000 (07:05 +0000)
committerJulian Seward <jseward@acm.org>
Tue, 19 Jul 2016 07:05:34 +0000 (07:05 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@3227

VEX/priv/guest_arm64_toIR.c
VEX/priv/host_arm64_defs.c
VEX/priv/host_arm64_defs.h
VEX/priv/host_arm64_isel.c

index bc6b9a818d79041502441684cc9c310b4c471dc4..b0a1d66fa1da6137e3bd529ed8ab8e5322d187d2 100644 (file)
@@ -6952,7 +6952,21 @@ Bool dis_ARM64_branch_etc(/*MB_OUT*/DisResult* dres, UInt insn,
       return True;
    }
 
-  //fail:
+   /* ------------------- CLREX ------------------ */
+   /* 31        23        15   11 7
+      1101 0101 0000 0011 0011 m  0101 1111  CLREX CRm
+      CRm is apparently ignored.
+   */
+   if ((INSN(31,0) & 0xFFFFF0FF) == 0xD503305F) {
+      UInt mm = INSN(11,8);
+      /* AFAICS, this simply cancels a (all?) reservations made by a
+         (any?) preceding LDREX(es).  Arrange to hand it through to
+         the back end. */
+      stmt( IRStmt_MBE(Imbe_CancelReservation) );
+      DIP("clrex #%u\n", mm);
+      return True;
+   }
+
    vex_printf("ARM64 front end: branch_etc\n");
    return False;
 #  undef INSN
index 82f658ee87146a437f6258f3630cc2e12ebfe4bb..cc7c832f37fa4eae822e2ff674ffab51dbc895a5 100644 (file)
@@ -1010,6 +1010,11 @@ ARM64Instr* ARM64Instr_MFence ( void ) {
    i->tag        = ARM64in_MFence;
    return i;
 }
+ARM64Instr* ARM64Instr_ClrEX ( void ) {
+   ARM64Instr* i = LibVEX_Alloc_inline(sizeof(ARM64Instr));
+   i->tag        = ARM64in_ClrEX;
+   return i;
+}
 ARM64Instr* ARM64Instr_VLdStH ( Bool isLoad, HReg sD, HReg rN, UInt uimm12 ) {
    ARM64Instr* i = LibVEX_Alloc_inline(sizeof(ARM64Instr));
    i->tag                   = ARM64in_VLdStH;
@@ -1567,6 +1572,9 @@ void ppARM64Instr ( const ARM64Instr* i ) {
       case ARM64in_MFence:
          vex_printf("(mfence) dsb sy; dmb sy; isb");
          return;
+      case ARM64in_ClrEX:
+         vex_printf("clrex #15");
+         return;
       case ARM64in_VLdStH:
          if (i->ARM64in.VLdStH.isLoad) {
             vex_printf("ldr    ");
@@ -2058,6 +2066,8 @@ void getRegUsage_ARM64Instr ( HRegUsage* u, const ARM64Instr* i, Bool mode64 )
          return;
       case ARM64in_MFence:
          return;
+      case ARM64in_ClrEX:
+         return;
       case ARM64in_VLdStH:
          addHRegUse(u, HRmRead, i->ARM64in.VLdStH.rN);
          if (i->ARM64in.VLdStH.isLoad) {
@@ -2318,6 +2328,8 @@ void mapRegs_ARM64Instr ( HRegRemap* m, ARM64Instr* i, Bool mode64 )
          return;
       case ARM64in_MFence:
          return;
+      case ARM64in_ClrEX:
+         return;
       case ARM64in_VLdStH:
          i->ARM64in.VLdStH.hD = lookupHRegRemap(m, i->ARM64in.VLdStH.hD);
          i->ARM64in.VLdStH.rN = lookupHRegRemap(m, i->ARM64in.VLdStH.rN);
@@ -3797,12 +3809,10 @@ Int emit_ARM64Instr ( /*MB_MOD*/Bool* is_profInc,
          *p++ = 0xD5033FDF; /* ISB */
          goto done;
       }
-      //case ARM64in_CLREX: {
-      //   //ATC, but believed to be correct
-      //   goto bad;
-      //   *p++ = 0xD5033F5F; /* clrex */
-      //   goto done;
-      //}
+      case ARM64in_ClrEX: {
+         *p++ = 0xD5033F5F; /* clrex #15 */
+         goto done;
+      }
       case ARM64in_VLdStH: {
          /* 01 111101 01 imm12 n t   LDR Ht, [Xn|SP, #imm12 * 2]
             01 111101 00 imm12 n t   STR Ht, [Xn|SP, #imm12 * 2]
index d74f8a131846426c458e31828e4683cf22a28feb..62b25fd74aa9b509e471562bfc8822e670db4874 100644 (file)
@@ -482,6 +482,7 @@ typedef
       ARM64in_LdrEX,
       ARM64in_StrEX,
       ARM64in_MFence,
+      ARM64in_ClrEX,
       /* ARM64in_V*: scalar ops involving vector registers */
       ARM64in_VLdStH,   /* ld/st to/from low 16 bits of vec reg, imm offset */
       ARM64in_VLdStS,   /* ld/st to/from low 32 bits of vec reg, imm offset */
@@ -673,6 +674,9 @@ typedef
             total nuclear overkill, but better safe than sorry. */
          struct {
          } MFence;
+         /* A CLREX instruction. */
+         struct {
+         } ClrEX;
          /* --- INSTRUCTIONS INVOLVING VECTOR REGISTERS --- */
          /* ld/st to/from low 16 bits of vec reg, imm offset */
          struct {
@@ -909,6 +913,7 @@ extern ARM64Instr* ARM64Instr_Mul     ( HReg dst, HReg argL, HReg argR,
 extern ARM64Instr* ARM64Instr_LdrEX   ( Int szB );
 extern ARM64Instr* ARM64Instr_StrEX   ( Int szB );
 extern ARM64Instr* ARM64Instr_MFence  ( void );
+extern ARM64Instr* ARM64Instr_ClrEX   ( void );
 extern ARM64Instr* ARM64Instr_VLdStH  ( Bool isLoad, HReg sD, HReg rN,
                                         UInt uimm12 /* 0 .. 8190, 0 % 2 */ );
 extern ARM64Instr* ARM64Instr_VLdStS  ( Bool isLoad, HReg sD, HReg rN,
index a57240891e3f5d2bbef35d34b8ffdc01736ab386..9aadcce944d6ef9d1b02df8e85176f4bd79396d5 100644 (file)
@@ -3839,6 +3839,9 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt )
          case Imbe_Fence:
             addInstr(env, ARM64Instr_MFence());
             return;
+         case Imbe_CancelReservation:
+            addInstr(env, ARM64Instr_ClrEX());
+            return;
          default:
             break;
       }