1# REQUIRES: aarch64 2 3# RUN: rm -rf %t; split-file %s %t 4# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin %t/lib.s -o %t/lib.o 5# RUN: %lld -arch arm64 -dylib -o %t/lib.dylib %t/lib.o 6# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin %t/external.s -o %t/near-got.o 7# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin %t/external.s -defsym=PADDING=1 -o %t/far-got.o 8# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin %t/local.s -o %t/local.o 9# RUN: %lld -arch arm64 %t/near-got.o %t/lib.dylib -o %t/NearGot 10# RUN: %lld -arch arm64 %t/far-got.o %t/lib.dylib -o %t/FarGot 11# RUN: %lld -arch arm64 %t/local.o -o %t/Local 12# RUN: llvm-objdump --no-print-imm-hex -d --macho %t/NearGot | FileCheck %s -check-prefix=NEAR-GOT 13# RUN: llvm-objdump --no-print-imm-hex -d --macho %t/FarGot | FileCheck %s -check-prefix=FAR-GOT 14# RUN: llvm-objdump --no-print-imm-hex -d --macho %t/Local | FileCheck %s -check-prefix=LOCAL 15 16#--- external.s 17.text 18.align 2 19.globl _main 20_main: 21 22## Basic test 23L1: adrp x0, _external@GOTPAGE 24L2: ldr x1, [x0, _external@GOTPAGEOFF] 25L3: ldr x2, [x1] 26# NEAR-GOT-LABEL: _main: 27# NEAR-GOT-NEXT: nop 28# NEAR-GOT-NEXT: ldr x1, #{{.*}} ; literal pool symbol address: _external 29# NEAR-GOT-NEXT: ldr x2, [x1] 30# FAR-GOT-LABEL: _main: 31# FAR-GOT-NEXT: adrp x0 32# FAR-GOT-NEXT: ldr x1 33# FAR-GOT-NEXT: ldr x2, [x1] 34 35## The second load has an offset 36L4: adrp x0, _external@GOTPAGE 37L5: ldr x1, [x0, _external@GOTPAGEOFF] 38L6: ldr q2, [x1, #16] 39# NEAR-GOT-NEXT: nop 40# NEAR-GOT-NEXT: ldr x1, #{{.*}} ; literal pool symbol address: _external 41# NEAR-GOT-NEXT: ldr q2, [x1, #16] 42# FAR-GOT-NEXT: adrp x0 43# FAR-GOT-NEXT: ldr x1 44# FAR-GOT-NEXT: ldr q2, [x1, #16] 45 46### Tests for invalid inputs 47.ifndef PADDING 48## Registers don't match 49L7: adrp x0, _external@GOTPAGE 50L8: ldr x1, [x1, _external@GOTPAGEOFF] 51L9: ldr x2, [x1] 52# NEAR-GOT-NEXT: adrp x0 53# NEAR-GOT-NEXT: ldr x1 54# NEAR-GOT-NEXT: ldr x2, [x1] 55 56## Registers don't match 57L10: adrp x0, _external@GOTPAGE 58L11: ldr x1, [x0, _external@GOTPAGEOFF] 59L12: ldr x2, [x0] 60# NEAR-GOT-NEXT: adrp x0 61# NEAR-GOT-NEXT: ldr x1 62# NEAR-GOT-NEXT: ldr x2, [x0] 63 64## Not an LDR (immediate) 65L13: adrp x0, _external@GOTPAGE 66L14: ldr x1, 0 67L15: ldr x2, [x1] 68# NEAR-GOT-NEXT: adrp x0 69# NEAR-GOT-NEXT: ldr x1 70# NEAR-GOT-NEXT: ldr x2, [x1] 71 72.loh AdrpLdrGotLdr L7, L8, L9 73.loh AdrpLdrGotLdr L10, L11, L12 74.loh AdrpLdrGotLdr L13, L14, L15 75.endif 76 77.loh AdrpLdrGotLdr L1, L2, L3 78.loh AdrpLdrGotLdr L4, L5, L6 79 80.ifdef PADDING 81.space 1048576 82.endif 83.data 84 85 86#--- lib.s 87.data 88.align 4 89.globl _external 90_external: 91 .zero 32 92 93#--- local.s 94.text 95.align 2 96.globl _main 97_main: 98 99### Transformation to a literal LDR 100## Basic case 101L1: adrp x0, _close@GOTPAGE 102L2: ldr x1, [x0, _close@GOTPAGEOFF] 103L3: ldr x2, [x1] 104# LOCAL-LABEL: _main: 105# LOCAL-NEXT: nop 106# LOCAL-NEXT: nop 107# LOCAL-NEXT: ldr x2 108 109## Load with offset 110L4: adrp x0, _close@GOTPAGE 111L5: ldr x1, [x0, _close@GOTPAGEOFF] 112L6: ldr x2, [x1, #8] 113# LOCAL-NEXT: nop 114# LOCAL-NEXT: nop 115# LOCAL-NEXT: ldr x2 116 117## 32 bit load 118L7: adrp x0, _close@GOTPAGE 119L8: ldr x1, [x0, _close@GOTPAGEOFF] 120L9: ldr w1, [x1] 121# LOCAL-NEXT: nop 122# LOCAL-NEXT: nop 123# LOCAL-NEXT: ldr w1, _close 124 125## Floating point 126L10: adrp x0, _close@GOTPAGE 127L11: ldr x1, [x0, _close@GOTPAGEOFF] 128L12: ldr s1, [x1] 129# LOCAL-NEXT: nop 130# LOCAL-NEXT: nop 131# LOCAL-NEXT: ldr s1, _close 132 133L13: adrp x0, _close@GOTPAGE 134L14: ldr x1, [x0, _close@GOTPAGEOFF] 135L15: ldr d1, [x1, #8] 136# LOCAL-NEXT: nop 137# LOCAL-NEXT: nop 138# LOCAL-NEXT: ldr d1, _close8 139 140L16: adrp x0, _close@GOTPAGE 141L17: ldr x1, [x0, _close@GOTPAGEOFF] 142L18: ldr q0, [x1] 143# LOCAL-NEXT: nop 144# LOCAL-NEXT: nop 145# LOCAL-NEXT: ldr q0, _close 146 147 148### Transformation to ADR+LDR 149## 1 byte floating point load 150L19: adrp x0, _close@GOTPAGE 151L20: ldr x1, [x0, _close@GOTPAGEOFF] 152L21: ldr b2, [x1] 153# LOCAL-NEXT: adr x1 154# LOCAL-NEXT: nop 155# LOCAL-NEXT: ldr b2, [x1] 156 157## 1 byte GPR load, zero extend 158L22: adrp x0, _close@GOTPAGE 159L23: ldr x1, [x0, _close@GOTPAGEOFF] 160L24: ldrb w2, [x1] 161# LOCAL-NEXT: adr x1 162# LOCAL-NEXT: nop 163# LOCAL-NEXT: ldrb w2, [x1] 164 165## 1 byte GPR load, sign extend 166L25: adrp x0, _close@GOTPAGE 167L26: ldr x1, [x0, _close@GOTPAGEOFF] 168L27: ldrsb x2, [x1] 169# LOCAL-NEXT: adr x1 170# LOCAL-NEXT: nop 171# LOCAL-NEXT: ldrsb x2, [x1] 172 173## Unaligned 174L28: adrp x0, _unaligned@GOTPAGE 175L29: ldr x1, [x0, _unaligned@GOTPAGEOFF] 176L30: ldr x2, [x1] 177# LOCAL-NEXT: adr x1 178# LOCAL-NEXT: nop 179# LOCAL-NEXT: ldr x2, [x1] 180 181 182### Transformation to ADRP + immediate LDR 183## Basic test: target is far 184L31: adrp x0, _far@GOTPAGE 185L32: ldr x1, [x0, _far@GOTPAGEOFF] 186L33: ldr x2, [x1] 187# LOCAL-NEXT: adrp x0 188# LOCAL-NEXT: nop 189# LOCAL-NEXT: ldr x2 190 191## With offset 192L34: adrp x0, _far@GOTPAGE 193L35: ldr x1, [x0, _far@GOTPAGEOFF] 194L36: ldr x2, [x1, #8] 195# LOCAL-NEXT: adrp x0 196# LOCAL-NEXT: nop 197# LOCAL-NEXT: ldr x2 198 199### No changes other than GOT relaxation 200## Far and unaligned 201L37: adrp x0, _far_unaligned@GOTPAGE 202L38: ldr x1, [x0, _far_unaligned@GOTPAGEOFF] 203L39: ldr x2, [x1] 204# LOCAL-NEXT: adrp x0 205# LOCAL-NEXT: add x1, x0 206# LOCAL-NEXT: ldr x2, [x1] 207 208## Far with large offset (_far_offset@GOTPAGEOFF + #255 > 4095) 209L40: adrp x0, _far_offset@GOTPAGE 210L41: ldr x1, [x0, _far_offset@GOTPAGEOFF] 211L42: ldrb w2, [x1, #255] 212# LOCAL-NEXT: adrp x0 213# LOCAL-NEXT: add x1, x0 214# LOCAL-NEXT: ldrb w2, [x1, #255] 215 216### Tests for invalid inputs, only GOT relaxation should happen 217## Registers don't match 218L43: adrp x0, _far@GOTPAGE 219L44: ldr x1, [x0, _far@GOTPAGEOFF] 220L45: ldr x2, [x2] 221# LOCAL-NEXT: adrp x0 222# LOCAL-NEXT: add x1, x0 223# LOCAL-NEXT: ldr x2, [x2] 224 225.data 226.align 4 227 .quad 0 228_close: 229 .quad 0 230_close8: 231 .quad 0 232 .byte 0 233_unaligned: 234 .quad 0 235 236.space 1048576 237.align 12 238 .quad 0 239_far: 240 .quad 0 241 .byte 0 242_far_unaligned: 243 .quad 0 244.space 4000 245_far_offset: 246 .byte 0 247 248 249.loh AdrpLdrGotLdr L1, L2, L3 250.loh AdrpLdrGotLdr L4, L5, L6 251.loh AdrpLdrGotLdr L7, L8, L9 252.loh AdrpLdrGotLdr L10, L11, L12 253.loh AdrpLdrGotLdr L13, L14, L15 254.loh AdrpLdrGotLdr L16, L17, L18 255.loh AdrpLdrGotLdr L19, L20, L21 256.loh AdrpLdrGotLdr L22, L23, L24 257.loh AdrpLdrGotLdr L25, L26, L27 258.loh AdrpLdrGotLdr L28, L29, L30 259.loh AdrpLdrGotLdr L31, L32, L33 260.loh AdrpLdrGotLdr L34, L35, L36 261.loh AdrpLdrGotLdr L37, L38, L39 262.loh AdrpLdrGotLdr L40, L41, L42 263.loh AdrpLdrGotLdr L43, L44, L45 264