[aarch64-port-dev ] Fix off-by-one error in offset calculation for branches

Andrew Haley aph at redhat.com
Tue Dec 31 04:51:36 PST 2013


The last patch of 2013!  This is an error in the branch displacement
that only occurs if teh code cache is very large.

Andrew.


# HG changeset patch
# User aph
# Date 1388494100 0
# Node ID 970ff006b665f02059728ad0ae41ba2ed49ec88a
# Parent  95878f303a4614d45117420765b31667a34ce1a9
Fix off-by-one error in offset calculation for branches.

diff -r 95878f303a46 -r 970ff006b665 src/cpu/aarch64/vm/assembler_aarch64.cpp
--- a/src/cpu/aarch64/vm/assembler_aarch64.cpp	Tue Dec 31 12:47:20 2013 +0000
+++ b/src/cpu/aarch64/vm/assembler_aarch64.cpp	Tue Dec 31 12:48:20 2013 +0000
@@ -1192,20 +1192,16 @@

 #ifndef PRODUCT
   {
-    Label l, loop, empty;
-    address a = __ pc();
-    __ adr(r3, l);
-    __ bl(empty);
-    __ movz(r0, 0);
-    __ BIND(loop);
-    __ subs(r0, r0, 10);
-    __ br(Assembler::NE, l);
-    __ add(r0, r0, 1u);
-    __ adr(r3, loop);
-    __ br(Assembler::AL, loop);
-    __ BIND(l);
-    __ BIND(empty);
-    __ ret(lr);
+    address PC = __ pc();
+    __ bl(__ pc()+(1<<27)-4);
+    NativeCall* call = nativeCall_at(PC);
+    ptrdiff_t offset = call->destination()-PC;
+    assert(offset == (1<<27)-4, "broken branch coding");
+    PC = __ pc();
+    __ bl(__ pc()-(1<<27));
+    call = nativeCall_at(PC);
+    offset = call->destination()-PC;
+    assert(offset == -(1<<27), "broken branch coding");
   }


diff -r 95878f303a46 -r 970ff006b665 src/cpu/aarch64/vm/nativeInst_aarch64.hpp
--- a/src/cpu/aarch64/vm/nativeInst_aarch64.hpp	Tue Dec 31 12:47:20 2013 +0000
+++ b/src/cpu/aarch64/vm/nativeInst_aarch64.hpp	Tue Dec 31 12:48:20 2013 +0000
@@ -128,7 +128,7 @@
   enum { cache_line_size = BytesPerWord };  // conservative estimate!
   address instruction_address() const       { return addr_at(instruction_offset); }
   address next_instruction_address() const  { return addr_at(return_address_offset); }
-  int   displacement() const                { return (int_at(displacement_offset) << 7) >> 5; }
+  int   displacement() const                { return (int_at(displacement_offset) << 6) >> 4; }
   address displacement_address() const      { return addr_at(displacement_offset); }
   address return_address() const            { return addr_at(return_address_offset); }
   address destination() const;


More information about the aarch64-port-dev mailing list