changeset 6448:30fa347a47e6

8148783, PR3100: aarch64: SEGV running SpecJBB2013 Summary: Fix calculation of offset for adrp Reviewed-by: aph
author enevill
date Thu, 04 Feb 2016 16:24:28 +0000
parents bb1818a74170
children e174f34bc41c
files src/cpu/aarch64/vm/assembler_aarch64.cpp
diffstat 1 files changed, 10 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/aarch64/vm/assembler_aarch64.cpp	Mon May 23 15:39:13 2016 +0000
+++ b/src/cpu/aarch64/vm/assembler_aarch64.cpp	Thu Feb 04 16:24:28 2016 +0000
@@ -1632,7 +1632,10 @@
                      Instruction_aarch64::extract(insn2, 4, 0)) {
         // movk #imm16<<32
         Instruction_aarch64::patch(branch + 4, 20, 5, (uint64_t)target >> 32);
-        offset &= (1<<20)-1;
+        long dest = ((long)target & 0xffffffffL) | ((long)branch & 0xffff00000000L);
+        long pc_page = (long)branch >> 12;
+        long adr_page = (long)dest >> 12;
+        offset = adr_page - pc_page;
         instructions = 2;
       }
     }
@@ -4920,11 +4923,12 @@
   if (offset_high >= -(1<<20) && offset_low < (1<<20)) {
     _adrp(reg1, dest.target());
   } else {
-    unsigned long pc_page = (unsigned long)pc() >> 12;
-    long offset = dest_page - pc_page;
-    offset = (offset & ((1<<20)-1)) << 12;
-    _adrp(reg1, pc()+offset);
-    movk(reg1, ((unsigned long)dest.target() >> 32), 32);
+    unsigned long target = (unsigned long)dest.target();
+    unsigned long adrp_target
+      = (target & 0xffffffffUL) | ((unsigned long)pc() & 0xffff00000000UL);
+           
+    _adrp(reg1, (address)adrp_target);
+    movk(reg1, target >> 32, 32);
   }
   byte_offset = (unsigned long)dest.target() & 0xfff;
 }