extern ULong arm64g_dirtyhelper_MRS_ID_AA64MMFR1_EL1 ( void );
extern ULong arm64g_dirtyhelper_MRS_ID_AA64ISAR0_EL1 ( void );
+extern ULong arm64g_dirtyhelper_MRS_ID_AA64ISAR1_EL1 ( void );
extern void arm64g_dirtyhelper_PMULLQ ( /*OUT*/V128* res,
ULong arg1, ULong arg2 );
# endif
}
+/* CALLED FROM GENERATED CODE */
+/* DIRTY HELPER (non-referentially-transparent) */
+/* Horrible hack. On non-arm64 platforms, return 0. */
+ULong arm64g_dirtyhelper_MRS_ID_AA64ISAR1_EL1 ( void )
+{
+# if defined(__aarch64__) && !defined(__arm__)
+ ULong w = 0x5555555555555555ULL; /* overwritten */
+ __asm__ __volatile__("mrs %0, id_aa64isar1_el1" : "=r"(w));
+
+ // only nibble 0 DBP
+ w &= 0xF;
+ /* No dc cvadp only dc cvap */
+ if ( w & 0x2 ) {
+ w ^= 0x2;
+ w |= 0x1;
+ }
+
+ return w;
+# else
+ return 0ULL;
+# endif
+}
void arm64g_dirtyhelper_PMULLQ ( /*OUT*/V128* res, ULong arg1, ULong arg2 )
{
*/
if ((INSN(31,0) & 0xFFFFFFE0) == 0xD5380620 /*MRS*/) {
UInt tt = INSN(4,0);
- putIReg64orZR(tt, mkU64(0x0));
+ IRTemp val = newTemp(Ity_I64);
+ IRExpr** args = mkIRExprVec_0();
+ IRDirty* d = unsafeIRDirty_1_N (
+ val,
+ 0/*regparms*/,
+ "arm64g_dirtyhelper_MRS_ID_AA64ISAR1_EL1",
+ &arm64g_dirtyhelper_MRS_ID_AA64ISAR1_EL1,
+ args
+ );
+ /* execute the dirty call, dumping the result in val. */
+ stmt( IRStmt_Dirty(d) );
+ putIReg64orZR(tt, mkexpr(val));
DIP("mrs %s, id_aa64isar1_el1 (FAKED)\n", nameIReg64orZR(tt));
return True;
}
/* ------------------ DC_CVAU ------------------ */
/* D5 0B 7B 001 Rt dc cvau, rT
D5 0B 7E 001 Rt dc civac, rT
+ D5 0B 7A 001 Rt dc cvac, rT
+ D5 0B 7C 001 Rt dc cvap, rT
*/
if ( (INSN(31,0) & 0xFFFFFFE0) == 0xD50B7B20
- || (INSN(31,0) & 0xFFFFFFE0) == 0xD50B7E20) {
+ || (INSN(31,0) & 0xFFFFFFE0) == 0xD50B7E20
+ || ((INSN(31,0) & 0xFFFFFFE0) == 0xD50B7A20)
+ || ((INSN(31,0) & 0xFFFFFFE0) == 0xD50B7C20)) {
/* Exactly the same scheme as for IC IVAU, except we observe the
dMinLine size, and request an Ijk_FlushDCache instead of
Ijk_InvalICache. */