Implement unchainXDirect_ARM64.
git-svn-id: svn://svn.valgrind.org/vex/trunk@2822 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/priv/host_arm64_defs.c b/priv/host_arm64_defs.c
index 21e1281..44773b3 100644
--- a/priv/host_arm64_defs.c
+++ b/priv/host_arm64_defs.c
@@ -6264,6 +6264,7 @@
vassert(is_imm64_to_iregNo_EXACTLY4(
p, /*x*/9, Ptr_to_ULong(disp_cp_chain_me_EXPECTED)));
vassert(p[4] == 0xD63F0120);
+
/* And what we want to change it to is:
movw x9, place_to_jump_to[15:0]
movk x9, place_to_jump_to[31:15], lsl 16
@@ -6276,7 +6277,6 @@
The replacement has the same length as the original.
*/
-
(void)imm64_to_iregNo_EXACTLY4(
p, /*x*/9, Ptr_to_ULong(place_to_jump_to));
p[4] = 0xD61F0120;
@@ -6286,67 +6286,47 @@
}
-//ZZ /* NB: what goes on here has to be very closely coordinated with the
-//ZZ emitInstr case for XDirect, above. */
-//ZZ VexInvalRange unchainXDirect_ARM ( void* place_to_unchain,
-//ZZ void* place_to_jump_to_EXPECTED,
-//ZZ void* disp_cp_chain_me )
-//ZZ {
-//ZZ /* What we're expecting to see is:
-//ZZ (general case)
-//ZZ movw r12, lo16(place_to_jump_to_EXPECTED)
-//ZZ movt r12, lo16(place_to_jump_to_EXPECTED)
-//ZZ bx r12
-//ZZ viz
-//ZZ <8 bytes generated by imm32_to_iregNo_EXACTLY2>
-//ZZ E1 2F FF 1C
-//ZZ ---OR---
-//ZZ in the case where the displacement falls within 26 bits
-//ZZ b disp24; undef; undef
-//ZZ viz
-//ZZ EA <3 bytes == disp24>
-//ZZ FF 00 00 00
-//ZZ FF 00 00 00
-//ZZ */
-//ZZ UInt* p = (UInt*)place_to_unchain;
-//ZZ vassert(0 == (3 & (HWord)p));
-//ZZ
-//ZZ Bool valid = False;
-//ZZ if (is_imm32_to_iregNo_EXACTLY2(
-//ZZ p, /*r*/12, (UInt)Ptr_to_ULong(place_to_jump_to_EXPECTED))
-//ZZ && p[2] == 0xE12FFF1C) {
-//ZZ valid = True; /* it's the long form */
-//ZZ if (0)
-//ZZ vex_printf("QQQ unchainXDirect_ARM: found long form\n");
-//ZZ } else
-//ZZ if ((p[0] >> 24) == 0xEA && p[1] == 0xFF000000 && p[2] == 0xFF000000) {
-//ZZ /* It's the short form. Check the displacement is right. */
-//ZZ Int simm24 = p[0] & 0x00FFFFFF;
-//ZZ simm24 <<= 8; simm24 >>= 8;
-//ZZ if ((UChar*)p + (simm24 << 2) + 8 == (UChar*)place_to_jump_to_EXPECTED) {
-//ZZ valid = True;
-//ZZ if (0)
-//ZZ vex_printf("QQQ unchainXDirect_ARM: found short form\n");
-//ZZ }
-//ZZ }
-//ZZ vassert(valid);
-//ZZ
-//ZZ /* And what we want to change it to is:
-//ZZ movw r12, lo16(disp_cp_chain_me)
-//ZZ movt r12, hi16(disp_cp_chain_me)
-//ZZ blx r12
-//ZZ viz
-//ZZ <8 bytes generated by imm32_to_iregNo_EXACTLY2>
-//ZZ E1 2F FF 3C
-//ZZ */
-//ZZ (void)imm32_to_iregNo_EXACTLY2(
-//ZZ p, /*r*/12, (UInt)Ptr_to_ULong(disp_cp_chain_me));
-//ZZ p[2] = 0xE12FFF3C;
-//ZZ VexInvalRange vir = {(HWord)p, 12};
-//ZZ return vir;
-//ZZ }
-//ZZ
-//ZZ
+/* NB: what goes on here has to be very closely coordinated with the
+ emitInstr case for XDirect, above. */
+VexInvalRange unchainXDirect_ARM64 ( void* place_to_unchain,
+ void* place_to_jump_to_EXPECTED,
+ void* disp_cp_chain_me )
+{
+ /* What we're expecting to see is:
+ movw x9, place_to_jump_to_EXPECTED[15:0]
+ movk x9, place_to_jump_to_EXPECTED[31:15], lsl 16
+ movk x9, place_to_jump_to_EXPECTED[47:32], lsl 32
+ movk x9, place_to_jump_to_EXPECTED[63:48], lsl 48
+ br x9
+ viz
+ <16 bytes generated by imm64_to_iregNo_EXACTLY4>
+ D6 1F 01 20
+ */
+ UInt* p = (UInt*)place_to_unchain;
+ vassert(0 == (3 & (HWord)p));
+ vassert(is_imm64_to_iregNo_EXACTLY4(
+ p, /*x*/9, Ptr_to_ULong(place_to_jump_to_EXPECTED)));
+ vassert(p[4] == 0xD61F0120);
+
+ /* And what we want to change it to is:
+ movw x9, disp_cp_chain_me_to[15:0]
+ movk x9, disp_cp_chain_me_to[31:15], lsl 16
+ movk x9, disp_cp_chain_me_to[47:32], lsl 32
+ movk x9, disp_cp_chain_me_to[63:48], lsl 48
+ blr x9
+ viz
+ <16 bytes generated by imm64_to_iregNo_EXACTLY4>
+ D6 3F 01 20
+ */
+ (void)imm64_to_iregNo_EXACTLY4(
+ p, /*x*/9, Ptr_to_ULong(disp_cp_chain_me));
+ p[4] = 0xD63F0120;
+
+ VexInvalRange vir = {(HWord)p, 20};
+ return vir;
+}
+
+
//ZZ /* Patch the counter address into a profile inc point, as previously
//ZZ created by the ARMin_ProfInc case for emit_ARMInstr. */
//ZZ VexInvalRange patchProfInc_ARM ( void* place_to_patch,
diff --git a/priv/host_arm64_defs.h b/priv/host_arm64_defs.h
index b6e4da8..c841171 100644
--- a/priv/host_arm64_defs.h
+++ b/priv/host_arm64_defs.h
@@ -1116,10 +1116,10 @@
void* disp_cp_chain_me_EXPECTED,
void* place_to_jump_to );
-//ZZ extern VexInvalRange unchainXDirect_ARM ( void* place_to_unchain,
-//ZZ void* place_to_jump_to_EXPECTED,
-//ZZ void* disp_cp_chain_me );
-//ZZ
+extern VexInvalRange unchainXDirect_ARM64 ( void* place_to_unchain,
+ void* place_to_jump_to_EXPECTED,
+ void* disp_cp_chain_me );
+
//ZZ /* Patch the counter location into an existing ProfInc point. */
//ZZ extern VexInvalRange patchProfInc_ARM ( void* place_to_patch,
//ZZ ULong* location_of_counter );
diff --git a/priv/main_main.c b/priv/main_main.c
index 2ca1df1..93ca478 100644
--- a/priv/main_main.c
+++ b/priv/main_main.c
@@ -1048,6 +1048,8 @@
unchainXDirect = unchainXDirect_AMD64; break;
case VexArchARM:
unchainXDirect = unchainXDirect_ARM; break;
+ case VexArchARM64:
+ unchainXDirect = unchainXDirect_ARM64; break;
case VexArchS390X:
unchainXDirect = unchainXDirect_S390; break;
case VexArchPPC32: