From: Julian Seward Date: Tue, 19 Jul 2016 07:05:34 +0000 (+0000) Subject: Implement CLREX. Fixes #359838. X-Git-Tag: svn/VALGRIND_3_12_0^2~39 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fe574f61c7f9af2dcdff44f7afcd6bfe1eb540b9;p=thirdparty%2Fvalgrind.git Implement CLREX. Fixes #359838. git-svn-id: svn://svn.valgrind.org/vex/trunk@3227 --- diff --git a/VEX/priv/guest_arm64_toIR.c b/VEX/priv/guest_arm64_toIR.c index bc6b9a818d..b0a1d66fa1 100644 --- a/VEX/priv/guest_arm64_toIR.c +++ b/VEX/priv/guest_arm64_toIR.c @@ -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 diff --git a/VEX/priv/host_arm64_defs.c b/VEX/priv/host_arm64_defs.c index 82f658ee87..cc7c832f37 100644 --- a/VEX/priv/host_arm64_defs.c +++ b/VEX/priv/host_arm64_defs.c @@ -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] diff --git a/VEX/priv/host_arm64_defs.h b/VEX/priv/host_arm64_defs.h index d74f8a1318..62b25fd74a 100644 --- a/VEX/priv/host_arm64_defs.h +++ b/VEX/priv/host_arm64_defs.h @@ -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, diff --git a/VEX/priv/host_arm64_isel.c b/VEX/priv/host_arm64_isel.c index a57240891e..9aadcce944 100644 --- a/VEX/priv/host_arm64_isel.c +++ b/VEX/priv/host_arm64_isel.c @@ -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; }