]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
arm64: implement "mrs Xt, cntvct_el0" by pass-through to the host.
authorJulian Seward <jseward@acm.org>
Mon, 14 Jul 2014 20:39:23 +0000 (20:39 +0000)
committerJulian Seward <jseward@acm.org>
Mon, 14 Jul 2014 20:39:23 +0000 (20:39 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@2900

VEX/priv/guest_arm64_defs.h
VEX/priv/guest_arm64_helpers.c
VEX/priv/guest_arm64_toIR.c

index 342312e834871cc879c77297df125d9e3e850dee..b8eb1ff9492f3a9c3a87a87f68467ef50f34a96f 100644 (file)
@@ -110,6 +110,11 @@ ULong arm64g_calculate_condition ( /* ARM64Condcode << 4 | cc_op */
 //ZZ                               UInt resR1, UInt resR2 );
 
 
+/* --- DIRTY HELPERS --- */
+
+extern ULong arm64g_dirtyhelper_MRS_CNTVCT_EL0 ( void );
+
+
 /*---------------------------------------------------------*/
 /*--- Condition code stuff                              ---*/
 /*---------------------------------------------------------*/
index eaa8d6fb84b0f9f5ffdfb5cb57caba671e40821d..5d2080e6ed5dc0425314f9eacf3a80d850c6b633 100644 (file)
@@ -677,6 +677,21 @@ ULong arm64g_calculate_condition ( /* ARM64Condcode << 4 | cc_op */
 }
 
 
+/* CALLED FROM GENERATED CODE */
+/* DIRTY HELPER (non-referentially-transparent) */
+/* Horrible hack.  On non-arm64 platforms, return 0. */
+ULong arm64g_dirtyhelper_MRS_CNTVCT_EL0 ( void )
+{
+#  if defined(__aarch64__) && !defined(__arm__)
+   ULong w = 0x5555555555555555ULL; /* overwritten */
+   __asm__ __volatile__("mrs %0, cntvct_el0" : "=r"(w));
+   return w;
+#  else
+   return 0ULL;
+#  endif
+}
+
+
 /*---------------------------------------------------------------*/
 /*--- Flag-helpers translation-time function specialisers.    ---*/
 /*--- These help iropt specialise calls the above run-time    ---*/
index 871c6a4182a0487b0cfbff2b6d6afe0a533c5f9d..60ef7ea6e73d39406f4b25d923302c482445d0b4 100644 (file)
@@ -5050,7 +5050,7 @@ Bool dis_ARM64_branch_etc(/*MB_OUT*/DisResult* dres, UInt insn,
    }
 
    /* ------------------ M{SR,RS} ------------------ */
-   /* Only handles the case where the system register is TPIDR_EL0.
+   /* ---- Cases for TPIDR_EL0 ----
       0xD51BD0 010 Rt   MSR tpidr_el0, rT
       0xD53BD0 010 Rt   MRS rT, tpidr_el0
    */
@@ -5067,7 +5067,7 @@ Bool dis_ARM64_branch_etc(/*MB_OUT*/DisResult* dres, UInt insn,
       }
       return True;
    }
-   /* Cases for FPCR 
+   /* ---- Cases for FPCR ----
       0xD51B44 000 Rt  MSR fpcr, rT
       0xD53B44 000 Rt  MSR rT, fpcr
    */
@@ -5084,7 +5084,7 @@ Bool dis_ARM64_branch_etc(/*MB_OUT*/DisResult* dres, UInt insn,
       }
       return True;
    }
-   /* Cases for FPSR 
+   /* ---- Cases for FPSR ----
       0xD51B44 001 Rt  MSR fpsr, rT
       0xD53B44 001 Rt  MSR rT, fpsr
       The only part of this we model is FPSR.QC.  All other bits
@@ -5122,7 +5122,7 @@ Bool dis_ARM64_branch_etc(/*MB_OUT*/DisResult* dres, UInt insn,
       }
       return True;
    }
-   /* Cases for NZCV
+   /* ---- Cases for NZCV ----
       D51B42 000 Rt  MSR nzcv, rT
       D53B42 000 Rt  MRS rT, nzcv
       The only parts of NZCV that actually exist are bits 31:28, which 
@@ -5146,7 +5146,7 @@ Bool dis_ARM64_branch_etc(/*MB_OUT*/DisResult* dres, UInt insn,
       }
       return True;
    }
-   /* Cases for DCZID_EL0
+   /* ---- Cases for DCZID_EL0 ----
       Don't support arbitrary reads and writes to this register.  Just
       return the value 16, which indicates that the DC ZVA instruction
       is not permitted, so we don't have to emulate it.
@@ -5158,7 +5158,7 @@ Bool dis_ARM64_branch_etc(/*MB_OUT*/DisResult* dres, UInt insn,
       DIP("mrs %s, dczid_el0 (FAKED)\n", nameIReg64orZR(tt));
       return True;
    }
-   /* Cases for CTR_EL0
+   /* ---- Cases for CTR_EL0 ----
       We just handle reads, and make up a value from the D and I line
       sizes in the VexArchInfo we are given, and patch in the following
       fields that the Foundation model gives ("natively"):
@@ -5184,6 +5184,28 @@ Bool dis_ARM64_branch_etc(/*MB_OUT*/DisResult* dres, UInt insn,
       DIP("mrs %s, ctr_el0\n", nameIReg64orZR(tt));
       return True;
    }
+   /* ---- Cases for CNTVCT_EL0 ----
+      This is a timestamp counter of some sort.  Support reads of it only
+      by passing through to the host.
+      D5 3B E0 010 Rt  MRS Xt, cntvct_el0
+   */
+   if ((INSN(31,0) & 0xFFFFFFE0) == 0xD53BE040) {
+      UInt     tt   = INSN(4,0);
+      IRTemp   val  = newTemp(Ity_I64);
+      IRExpr** args = mkIRExprVec_0();
+      IRDirty* d    = unsafeIRDirty_1_N ( 
+                         val, 
+                         0/*regparms*/, 
+                         "arm64g_dirtyhelper_MRS_CNTVCT_EL0",
+                         &arm64g_dirtyhelper_MRS_CNTVCT_EL0,
+                         args 
+                      );
+      /* execute the dirty call, dumping the result in val. */
+      stmt( IRStmt_Dirty(d) );
+      putIReg64orZR(tt, mkexpr(val));
+      DIP("mrs %s, cntvct_el0\n", nameIReg64orZR(tt));
+      return True;
+   }   
 
    /* ------------------ IC_IVAU ------------------ */
    /* D5 0B 75 001 Rt  ic ivau, rT