File: loh-adrp-ldr-got-ldr.s

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (263 lines) | stat: -rw-r--r-- 6,238 bytes parent folder | download | duplicates (14)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# REQUIRES: aarch64

# RUN: rm -rf %t; split-file %s %t
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin %t/lib.s -o %t/lib.o
# RUN: %lld -arch arm64 -dylib -o %t/lib.dylib %t/lib.o
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin %t/external.s -o %t/near-got.o
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin %t/external.s -defsym=PADDING=1 -o %t/far-got.o
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin %t/local.s -o %t/local.o
# RUN: %lld -arch arm64 %t/near-got.o %t/lib.dylib -o %t/NearGot
# RUN: %lld -arch arm64 %t/far-got.o %t/lib.dylib -o %t/FarGot
# RUN: %lld -arch arm64 %t/local.o -o %t/Local
# RUN: llvm-objdump --no-print-imm-hex -d --macho %t/NearGot | FileCheck %s -check-prefix=NEAR-GOT
# RUN: llvm-objdump --no-print-imm-hex -d --macho %t/FarGot | FileCheck %s -check-prefix=FAR-GOT
# RUN: llvm-objdump --no-print-imm-hex -d --macho %t/Local | FileCheck %s -check-prefix=LOCAL

#--- external.s
.text
.align 2
.globl _main
_main:

## Basic test
L1: adrp x0, _external@GOTPAGE
L2: ldr  x1, [x0, _external@GOTPAGEOFF]
L3: ldr  x2, [x1]
# NEAR-GOT-LABEL: _main:
# NEAR-GOT-NEXT: nop
# NEAR-GOT-NEXT: ldr x1, #{{.*}} ; literal pool symbol address: _external
# NEAR-GOT-NEXT: ldr x2, [x1]
# FAR-GOT-LABEL: _main:
# FAR-GOT-NEXT:  adrp x0
# FAR-GOT-NEXT:  ldr x1
# FAR-GOT-NEXT:  ldr x2, [x1]

## The second load has an offset
L4: adrp x0, _external@GOTPAGE
L5: ldr  x1, [x0, _external@GOTPAGEOFF]
L6: ldr  q2, [x1, #16]
# NEAR-GOT-NEXT: nop
# NEAR-GOT-NEXT: ldr x1, #{{.*}} ; literal pool symbol address: _external
# NEAR-GOT-NEXT: ldr q2, [x1, #16]
# FAR-GOT-NEXT:  adrp x0
# FAR-GOT-NEXT:  ldr x1
# FAR-GOT-NEXT:  ldr q2, [x1, #16]

### Tests for invalid inputs
.ifndef PADDING
## Registers don't match
L7: adrp x0, _external@GOTPAGE
L8: ldr  x1, [x1, _external@GOTPAGEOFF]
L9: ldr  x2, [x1]
# NEAR-GOT-NEXT: adrp x0
# NEAR-GOT-NEXT: ldr x1
# NEAR-GOT-NEXT: ldr x2, [x1]

## Registers don't match
L10: adrp x0, _external@GOTPAGE
L11: ldr  x1, [x0, _external@GOTPAGEOFF]
L12: ldr  x2, [x0]
# NEAR-GOT-NEXT: adrp x0
# NEAR-GOT-NEXT: ldr x1
# NEAR-GOT-NEXT: ldr x2, [x0]

## Not an LDR (immediate)
L13: adrp x0, _external@GOTPAGE
L14: ldr  x1, 0
L15: ldr  x2, [x1]
# NEAR-GOT-NEXT: adrp x0
# NEAR-GOT-NEXT: ldr x1
# NEAR-GOT-NEXT: ldr x2, [x1]

.loh AdrpLdrGotLdr L7, L8, L9
.loh AdrpLdrGotLdr L10, L11, L12
.loh AdrpLdrGotLdr L13, L14, L15
.endif

.loh AdrpLdrGotLdr L1, L2, L3
.loh AdrpLdrGotLdr L4, L5, L6

.ifdef PADDING
.space 1048576
.endif
.data


#--- lib.s
.data
.align 4
.globl _external
_external:
    .zero 32

#--- local.s
.text
.align 2
.globl _main
_main:

### Transformation to a literal LDR
## Basic case
L1: adrp x0, _close@GOTPAGE
L2: ldr  x1, [x0, _close@GOTPAGEOFF]
L3: ldr  x2, [x1]
# LOCAL-LABEL: _main:
# LOCAL-NEXT: nop
# LOCAL-NEXT: nop
# LOCAL-NEXT: ldr x2

## Load with offset
L4: adrp x0, _close@GOTPAGE
L5: ldr  x1, [x0, _close@GOTPAGEOFF]
L6: ldr  x2, [x1, #8]
# LOCAL-NEXT: nop
# LOCAL-NEXT: nop
# LOCAL-NEXT: ldr x2

## 32 bit load
L7: adrp x0, _close@GOTPAGE
L8: ldr  x1, [x0, _close@GOTPAGEOFF]
L9: ldr  w1, [x1]
# LOCAL-NEXT: nop
# LOCAL-NEXT: nop
# LOCAL-NEXT: ldr w1, _close

## Floating point
L10: adrp x0, _close@GOTPAGE
L11: ldr  x1, [x0, _close@GOTPAGEOFF]
L12: ldr  s1, [x1]
# LOCAL-NEXT: nop
# LOCAL-NEXT: nop
# LOCAL-NEXT: ldr s1, _close

L13: adrp x0, _close@GOTPAGE
L14: ldr  x1, [x0, _close@GOTPAGEOFF]
L15: ldr  d1, [x1, #8]
# LOCAL-NEXT: nop
# LOCAL-NEXT: nop
# LOCAL-NEXT: ldr d1, _close8

L16: adrp x0, _close@GOTPAGE
L17: ldr  x1, [x0, _close@GOTPAGEOFF]
L18: ldr  q0, [x1]
# LOCAL-NEXT: nop
# LOCAL-NEXT: nop
# LOCAL-NEXT: ldr q0, _close


### Transformation to ADR+LDR
## 1 byte floating point load
L19: adrp x0, _close@GOTPAGE
L20: ldr  x1, [x0, _close@GOTPAGEOFF]
L21: ldr  b2, [x1]
# LOCAL-NEXT: adr x1
# LOCAL-NEXT: nop
# LOCAL-NEXT: ldr b2, [x1]

## 1 byte GPR load, zero extend
L22: adrp x0, _close@GOTPAGE
L23: ldr  x1, [x0, _close@GOTPAGEOFF]
L24: ldrb w2, [x1]
# LOCAL-NEXT: adr x1
# LOCAL-NEXT: nop
# LOCAL-NEXT: ldrb w2, [x1]

## 1 byte GPR load, sign extend
L25: adrp  x0, _close@GOTPAGE
L26: ldr   x1, [x0, _close@GOTPAGEOFF]
L27: ldrsb x2, [x1]
# LOCAL-NEXT: adr x1
# LOCAL-NEXT: nop
# LOCAL-NEXT: ldrsb x2, [x1]

## Unaligned
L28: adrp x0, _unaligned@GOTPAGE
L29: ldr  x1, [x0, _unaligned@GOTPAGEOFF]
L30: ldr  x2, [x1]
# LOCAL-NEXT: adr x1
# LOCAL-NEXT: nop
# LOCAL-NEXT: ldr x2, [x1]


### Transformation to ADRP + immediate LDR
## Basic test: target is far
L31: adrp x0, _far@GOTPAGE
L32: ldr  x1, [x0, _far@GOTPAGEOFF]
L33: ldr  x2, [x1]
# LOCAL-NEXT: adrp x0
# LOCAL-NEXT: nop
# LOCAL-NEXT: ldr x2

## With offset
L34: adrp x0, _far@GOTPAGE
L35: ldr  x1, [x0, _far@GOTPAGEOFF]
L36: ldr  x2, [x1, #8]
# LOCAL-NEXT: adrp x0
# LOCAL-NEXT: nop
# LOCAL-NEXT: ldr x2

### No changes other than GOT relaxation
## Far and unaligned
L37: adrp x0, _far_unaligned@GOTPAGE
L38: ldr  x1, [x0, _far_unaligned@GOTPAGEOFF]
L39: ldr  x2, [x1]
# LOCAL-NEXT: adrp x0
# LOCAL-NEXT: add x1, x0
# LOCAL-NEXT: ldr x2, [x1]

## Far with large offset (_far_offset@GOTPAGEOFF + #255 > 4095)
L40: adrp x0, _far_offset@GOTPAGE
L41: ldr  x1, [x0, _far_offset@GOTPAGEOFF]
L42: ldrb w2, [x1, #255]
# LOCAL-NEXT: adrp x0
# LOCAL-NEXT: add x1, x0
# LOCAL-NEXT: ldrb w2, [x1, #255]

### Tests for invalid inputs, only GOT relaxation should happen
## Registers don't match
L43: adrp x0, _far@GOTPAGE
L44: ldr  x1, [x0, _far@GOTPAGEOFF]
L45: ldr  x2, [x2]
# LOCAL-NEXT: adrp x0
# LOCAL-NEXT: add x1, x0
# LOCAL-NEXT: ldr x2, [x2]

.data
.align 4
    .quad 0
_close:
    .quad 0
_close8:
    .quad 0
    .byte 0
_unaligned:
    .quad 0

.space 1048576
.align 12
    .quad 0
_far:
     .quad 0
    .byte 0
_far_unaligned:
    .quad 0
.space 4000
_far_offset:
    .byte 0


.loh AdrpLdrGotLdr L1, L2, L3
.loh AdrpLdrGotLdr L4, L5, L6
.loh AdrpLdrGotLdr L7, L8, L9
.loh AdrpLdrGotLdr L10, L11, L12
.loh AdrpLdrGotLdr L13, L14, L15
.loh AdrpLdrGotLdr L16, L17, L18
.loh AdrpLdrGotLdr L19, L20, L21
.loh AdrpLdrGotLdr L22, L23, L24
.loh AdrpLdrGotLdr L25, L26, L27
.loh AdrpLdrGotLdr L28, L29, L30
.loh AdrpLdrGotLdr L31, L32, L33
.loh AdrpLdrGotLdr L34, L35, L36
.loh AdrpLdrGotLdr L37, L38, L39
.loh AdrpLdrGotLdr L40, L41, L42
.loh AdrpLdrGotLdr L43, L44, L45