[aarch64-port-dev ] Fix overflow in ADRP

Andrew Haley aph at redhat.com
Thu Aug 22 11:04:37 PDT 2013


I came across a case where ADRP couldn't reach its target.  I fixed this
by allowing the ADRP macro to generate a full 64-bit address if needs be.

Andrew.


comparing with ssh://hg.openjdk.java.net/aarch64-port/jdk8//hotspot
searching for changes
remote: X11 forwarding request failed on channel 0
changeset:   4865:b0a65a4a6094
tag:         tip
user:        aph
date:        Thu Aug 22 19:02:06 2013 +0100
summary:     Allow adrp macro to handle full 64-bit offsets.

diff -r 3fc92a2940e6 -r b0a65a4a6094 src/cpu/aarch64/vm/assembler_aarch64.cpp
--- a/src/cpu/aarch64/vm/assembler_aarch64.cpp	Wed Aug 21 18:26:08 2013 +0100
+++ b/src/cpu/aarch64/vm/assembler_aarch64.cpp	Thu Aug 22 19:02:06 2013 +0100
@@ -1286,10 +1286,7 @@
 }

 void Assembler::adrp(Register reg1, const Address &dest, unsigned long &byte_offset) {
-  InstructionMark im(this);
-  code_section()->relocate(inst_mark(), dest.rspec());
-  byte_offset = (uint64_t)dest.target() & 0xfff;
-  _adrp(reg1, dest.target());
+  ShouldNotReachHere();
 }

 #undef __
diff -r 3fc92a2940e6 -r b0a65a4a6094 src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Wed Aug 21 18:26:08 2013 +0100
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Thu Aug 22 19:02:06 2013 +0100
@@ -2575,3 +2575,18 @@
   ldrw(zr, Address(r, off));
   return inst_mark();
 }
+
+void MacroAssembler::adrp(Register reg1, const Address &dest, unsigned long &byte_offset) {
+  if (labs(pc() - dest.target()) >= (1LL << 32)) {
+    // Out of range.  This doesn't happen very often, but we have to
+    // handle it
+    mov(reg1, dest);
+    byte_offset = 0;
+  } else {
+    InstructionMark im(this);
+    code_section()->relocate(inst_mark(), dest.rspec());
+    byte_offset = (uint64_t)dest.target() & 0xfff;
+    _adrp(reg1, dest.target());
+  }
+}
+
diff -r 3fc92a2940e6 -r b0a65a4a6094 src/cpu/aarch64/vm/macroAssembler_aarch64.hpp
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Wed Aug 21 18:26:08 2013 +0100
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Thu Aug 22 19:02:06 2013 +0100
@@ -1281,6 +1281,8 @@
   void add(Register Rd, Register Rn, RegisterOrConstant increment);
   void addw(Register Rd, Register Rn, RegisterOrConstant increment);

+  void adrp(Register reg1, const Address &dest, unsigned long &byte_offset);
+
   void tableswitch(Register index, jint lowbound, jint highbound,
 		   Label &jumptable, Label &jumptable_end) {
     adr(rscratch1, jumptable);
diff -r 3fc92a2940e6 -r b0a65a4a6094 src/cpu/aarch64/vm/nativeInst_aarch64.cpp
--- a/src/cpu/aarch64/vm/nativeInst_aarch64.cpp	Wed Aug 21 18:26:08 2013 +0100
+++ b/src/cpu/aarch64/vm/nativeInst_aarch64.cpp	Thu Aug 22 19:02:06 2013 +0100
@@ -180,8 +180,23 @@
 };

 bool NativeInstruction::is_safepoint_poll() {
-  address addr = addr_at(-4);
-  return os::is_poll_address(MacroAssembler::pd_call_destination(addr));
+  /* We expect a safepoint poll to be either
+
+     adrp(reg, polling_page);
+     ldr(reg, offset);
+
+     or
+
+     mov(reg, polling_page);
+     ldr(reg, Address(reg, 0));
+  */
+
+  if (is_adrp_at(addr_at(-4))) {
+    address addr = addr_at(-4);
+    return os::is_poll_address(MacroAssembler::pd_call_destination(addr));
+  } else {
+    return os::is_poll_address(MacroAssembler::pd_call_destination(addr_at(-16)));
+  }
 }

 bool NativeInstruction::is_adrp_at(address instr) {




More information about the aarch64-port-dev mailing list