xref: /llvm-project/lld/test/MachO/loh-adrp-ldr-got-ldr.s (revision 75cdab6dc2453a508157a9c383b93373a93078d6)
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