@@ -125,7 +125,8 @@ fn prefix_and_suffix<'tcx>(
125
125
// the alignment from a `#[repr(align(<n>))]` is used if it specifies a higher alignment.
126
126
// if no alignment is specified, an alignment of 4 bytes is used.
127
127
let min_function_alignment = tcx. sess . opts . unstable_opts . min_function_alignment ;
128
- let align = Ord :: max ( min_function_alignment, attrs. alignment ) . map ( |a| a. bytes ( ) ) . unwrap_or ( 4 ) ;
128
+ let align_bytes =
129
+ Ord :: max ( min_function_alignment, attrs. alignment ) . map ( |a| a. bytes ( ) ) . unwrap_or ( 4 ) ;
129
130
130
131
// In particular, `.arm` can also be written `.code 32` and `.thumb` as `.code 16`.
131
132
let ( arch_prefix, arch_suffix) = if is_arm {
@@ -157,12 +158,16 @@ fn prefix_and_suffix<'tcx>(
157
158
}
158
159
Linkage :: LinkOnceAny | Linkage :: LinkOnceODR | Linkage :: WeakAny | Linkage :: WeakODR => {
159
160
match asm_binary_format {
160
- BinaryFormat :: Elf
161
- | BinaryFormat :: Coff
162
- | BinaryFormat :: Wasm
163
- | BinaryFormat :: Xcoff => {
161
+ BinaryFormat :: Elf | BinaryFormat :: Coff | BinaryFormat :: Wasm => {
164
162
writeln ! ( w, ".weak {asm_name}" ) ?;
165
163
}
164
+ BinaryFormat :: Xcoff => {
165
+ // FIXME: there is currently no way of defining a weak symbol in inline assembly
166
+ // for AIX. See https://github.com/llvm/llvm-project/issues/130269
167
+ emit_fatal (
168
+ "cannot create weak symbols from inline assembly for this target" ,
169
+ )
170
+ }
166
171
BinaryFormat :: MachO => {
167
172
writeln ! ( w, ".globl {asm_name}" ) ?;
168
173
writeln ! ( w, ".weak_definition {asm_name}" ) ?;
@@ -189,7 +194,7 @@ fn prefix_and_suffix<'tcx>(
189
194
let mut begin = String :: new ( ) ;
190
195
let mut end = String :: new ( ) ;
191
196
match asm_binary_format {
192
- BinaryFormat :: Elf | BinaryFormat :: Xcoff => {
197
+ BinaryFormat :: Elf => {
193
198
let section = link_section. unwrap_or ( format ! ( ".text.{asm_name}" ) ) ;
194
199
195
200
let progbits = match is_arm {
@@ -203,7 +208,7 @@ fn prefix_and_suffix<'tcx>(
203
208
} ;
204
209
205
210
writeln ! ( begin, ".pushsection {section},\" ax\" , {progbits}" ) . unwrap ( ) ;
206
- writeln ! ( begin, ".balign {align }" ) . unwrap ( ) ;
211
+ writeln ! ( begin, ".balign {align_bytes }" ) . unwrap ( ) ;
207
212
write_linkage ( & mut begin) . unwrap ( ) ;
208
213
if let Visibility :: Hidden = item_data. visibility {
209
214
writeln ! ( begin, ".hidden {asm_name}" ) . unwrap ( ) ;
@@ -224,7 +229,7 @@ fn prefix_and_suffix<'tcx>(
224
229
BinaryFormat :: MachO => {
225
230
let section = link_section. unwrap_or ( "__TEXT,__text" . to_string ( ) ) ;
226
231
writeln ! ( begin, ".pushsection {},regular,pure_instructions" , section) . unwrap ( ) ;
227
- writeln ! ( begin, ".balign {align }" ) . unwrap ( ) ;
232
+ writeln ! ( begin, ".balign {align_bytes }" ) . unwrap ( ) ;
228
233
write_linkage ( & mut begin) . unwrap ( ) ;
229
234
if let Visibility :: Hidden = item_data. visibility {
230
235
writeln ! ( begin, ".private_extern {asm_name}" ) . unwrap ( ) ;
@@ -240,7 +245,7 @@ fn prefix_and_suffix<'tcx>(
240
245
BinaryFormat :: Coff => {
241
246
let section = link_section. unwrap_or ( format ! ( ".text.{asm_name}" ) ) ;
242
247
writeln ! ( begin, ".pushsection {},\" xr\" " , section) . unwrap ( ) ;
243
- writeln ! ( begin, ".balign {align }" ) . unwrap ( ) ;
248
+ writeln ! ( begin, ".balign {align_bytes }" ) . unwrap ( ) ;
244
249
write_linkage ( & mut begin) . unwrap ( ) ;
245
250
writeln ! ( begin, ".def {asm_name}" ) . unwrap ( ) ;
246
251
writeln ! ( begin, ".scl 2" ) . unwrap ( ) ;
@@ -279,6 +284,33 @@ fn prefix_and_suffix<'tcx>(
279
284
// .size is ignored for function symbols, so we can skip it
280
285
writeln ! ( end, "end_function" ) . unwrap ( ) ;
281
286
}
287
+ BinaryFormat :: Xcoff => {
288
+ // the LLVM XCOFFAsmParser is extremely incomplete and does not implement many of the
289
+ // documented directives.
290
+ //
291
+ // - https://github.com/llvm/llvm-project/blob/1b25c0c4da968fe78921ce77736e5baef4db75e3/llvm/lib/MC/MCParser/XCOFFAsmParser.cpp
292
+ // - https://www.ibm.com/docs/en/ssw_aix_71/assembler/assembler_pdf.pdf
293
+ //
294
+ // Consequently, we try our best here but cannot do as good a job as for other binary
295
+ // formats.
296
+
297
+ // FIXME: start a section. `.csect` is not currently implemented in LLVM
298
+
299
+ // fun fact: according to the assembler documentation, .align takes an exponent,
300
+ // but LLVM only accepts powers of 2 (but does emit the exponent)
301
+ // so when we hand `.align 32` to LLVM, the assembly output will contain `.align 5`
302
+ writeln ! ( begin, ".align {}" , align_bytes) . unwrap ( ) ;
303
+
304
+ write_linkage ( & mut begin) . unwrap ( ) ;
305
+ if let Visibility :: Hidden = item_data. visibility {
306
+ // FIXME apparently `.globl {asm_name}, hidden` is valid
307
+ // but due to limitations with `.weak` (see above) we can't really use that in general yet
308
+ }
309
+ writeln ! ( begin, "{asm_name}:" ) . unwrap ( ) ;
310
+
311
+ writeln ! ( end) . unwrap ( ) ;
312
+ // FIXME: end the section?
313
+ }
282
314
}
283
315
284
316
( begin, end)
0 commit comments