arm64: implement "mrs Xt, cntvct_el0" by pass-through to the host.
git-svn-id: svn://svn.valgrind.org/vex/trunk@2900 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/priv/guest_arm64_defs.h b/priv/guest_arm64_defs.h
index 342312e..b8eb1ff 100644
--- a/priv/guest_arm64_defs.h
+++ b/priv/guest_arm64_defs.h
@@ -110,6 +110,11 @@
//ZZ UInt resR1, UInt resR2 );
+/* --- DIRTY HELPERS --- */
+
+extern ULong arm64g_dirtyhelper_MRS_CNTVCT_EL0 ( void );
+
+
/*---------------------------------------------------------*/
/*--- Condition code stuff ---*/
/*---------------------------------------------------------*/
diff --git a/priv/guest_arm64_helpers.c b/priv/guest_arm64_helpers.c
index eaa8d6f..5d2080e 100644
--- a/priv/guest_arm64_helpers.c
+++ b/priv/guest_arm64_helpers.c
@@ -677,6 +677,21 @@
}
+/* 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 ---*/
diff --git a/priv/guest_arm64_toIR.c b/priv/guest_arm64_toIR.c
index 871c6a4..60ef7ea 100644
--- a/priv/guest_arm64_toIR.c
+++ b/priv/guest_arm64_toIR.c
@@ -5050,7 +5050,7 @@
}
/* ------------------ 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 @@
}
return True;
}
- /* Cases for FPCR
+ /* ---- Cases for FPCR ----
0xD51B44 000 Rt MSR fpcr, rT
0xD53B44 000 Rt MSR rT, fpcr
*/
@@ -5084,7 +5084,7 @@
}
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 @@
}
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 @@
}
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 @@
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 @@
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