[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