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
23 L1
: adrp x0
, _external@GOTPAGE
24 L2
: ldr x1
, [x0
, _external@GOTPAGEOFF
]
26 # NEAR-GOT-LABEL: _main:
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]
35 ## The second load has an offset
36 L4
: adrp x0
, _external@GOTPAGE
37 L5
: ldr x1
, [x0
, _external@GOTPAGEOFF
]
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]
46 ### Tests for invalid inputs
48 ## Registers don't match
49 L7
: adrp x0
, _external@GOTPAGE
50 L8
: ldr x1
, [x1
, _external@GOTPAGEOFF
]
52 # NEAR-GOT-NEXT: adrp x0
53 # NEAR-GOT-NEXT: ldr x1
54 # NEAR-GOT-NEXT: ldr x2, [x1]
56 ## Registers don't match
57 L10
: adrp x0
, _external@GOTPAGE
58 L11
: ldr x1
, [x0
, _external@GOTPAGEOFF
]
60 # NEAR-GOT-NEXT: adrp x0
61 # NEAR-GOT-NEXT: ldr x1
62 # NEAR-GOT-NEXT: ldr x2, [x0]
64 ## Not an LDR (immediate)
65 L13
: adrp x0
, _external@GOTPAGE
68 # NEAR-GOT-NEXT: adrp x0
69 # NEAR-GOT-NEXT: ldr x1
70 # NEAR-GOT-NEXT: ldr x2, [x1]
72 .loh AdrpLdrGotLdr L7, L8, L9
73 .loh AdrpLdrGotLdr L10, L11, L12
74 .loh AdrpLdrGotLdr L13, L14, L15
77 .loh AdrpLdrGotLdr L1, L2, L3
78 .loh AdrpLdrGotLdr L4, L5, L6
99 ### Transformation to a literal LDR
101 L1
: adrp x0
, _close@GOTPAGE
102 L2
: ldr x1
, [x0
, _close@GOTPAGEOFF
]
104 # LOCAL-LABEL: _main:
110 L4
: adrp x0
, _close@GOTPAGE
111 L5
: ldr x1
, [x0
, _close@GOTPAGEOFF
]
118 L7
: adrp x0
, _close@GOTPAGE
119 L8
: ldr x1
, [x0
, _close@GOTPAGEOFF
]
123 # LOCAL-NEXT: ldr w1, _close
126 L10
: adrp x0
, _close@GOTPAGE
127 L11
: ldr x1
, [x0
, _close@GOTPAGEOFF
]
131 # LOCAL-NEXT: ldr s1, _close
133 L13
: adrp x0
, _close@GOTPAGE
134 L14
: ldr x1
, [x0
, _close@GOTPAGEOFF
]
135 L15
: ldr d1
, [x1
, #8]
138 # LOCAL-NEXT: ldr d1, _close8
140 L16
: adrp x0
, _close@GOTPAGE
141 L17
: ldr x1
, [x0
, _close@GOTPAGEOFF
]
145 # LOCAL-NEXT: ldr q0, _close
148 ### Transformation to ADR+LDR
149 ## 1 byte floating point load
150 L19
: adrp x0
, _close@GOTPAGE
151 L20
: ldr x1
, [x0
, _close@GOTPAGEOFF
]
155 # LOCAL-NEXT: ldr b2, [x1]
157 ## 1 byte GPR load, zero extend
158 L22
: adrp x0
, _close@GOTPAGE
159 L23
: ldr x1
, [x0
, _close@GOTPAGEOFF
]
163 # LOCAL-NEXT: ldrb w2, [x1]
165 ## 1 byte GPR load, sign extend
166 L25
: adrp x0
, _close@GOTPAGE
167 L26
: ldr x1
, [x0
, _close@GOTPAGEOFF
]
171 # LOCAL-NEXT: ldrsb x2, [x1]
174 L28
: adrp x0
, _unaligned@GOTPAGE
175 L29
: ldr x1
, [x0
, _unaligned@GOTPAGEOFF
]
179 # LOCAL-NEXT: ldr x2, [x1]
182 ### Transformation to ADRP + immediate LDR
183 ## Basic test: target is far
184 L31
: adrp x0
, _far@GOTPAGE
185 L32
: ldr x1
, [x0
, _far@GOTPAGEOFF
]
187 # LOCAL-NEXT: adrp x0
192 L34
: adrp x0
, _far@GOTPAGE
193 L35
: ldr x1
, [x0
, _far@GOTPAGEOFF
]
194 L36
: ldr x2
, [x1
, #8]
195 # LOCAL-NEXT: adrp x0
199 ### No changes other than GOT relaxation
201 L37
: adrp x0
, _far_unaligned@GOTPAGE
202 L38
: ldr x1
, [x0
, _far_unaligned@GOTPAGEOFF
]
204 # LOCAL-NEXT: adrp x0
205 # LOCAL-NEXT: add x1, x0
206 # LOCAL-NEXT: ldr x2, [x1]
208 ## Far with large offset (_far_offset@GOTPAGEOFF + #255 > 4095)
209 L40
: adrp x0
, _far_offset@GOTPAGE
210 L41
: ldr x1
, [x0
, _far_offset@GOTPAGEOFF
]
211 L42
: ldrb w2
, [x1
, #255]
212 # LOCAL-NEXT: adrp x0
213 # LOCAL-NEXT: add x1, x0
214 # LOCAL-NEXT: ldrb w2, [x1, #255]
216 ### Tests for invalid inputs, only GOT relaxation should happen
217 ## Registers don't match
218 L43
: adrp x0
, _far@GOTPAGE
219 L44
: ldr x1
, [x0
, _far@GOTPAGEOFF
]
221 # LOCAL-NEXT: adrp x0
222 # LOCAL-NEXT: add x1, x0
223 # LOCAL-NEXT: ldr x2, [x2]
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