@@ -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,17 @@ 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: .weak_definition is accepted by the assembly parser, but is not
166
+ // documented https://www.ibm.com/docs/en/ssw_aix_71/assembler/assembler_pdf.pdf
167
+ // For all I know, it might just be ignored.
168
+ //
169
+ // On the other hand `.weak` is documented, but rejected as an "unknown directive".
170
+ writeln ! ( w, ".weak_definition {asm_name}" ) ?;
171
+ }
166
172
BinaryFormat :: MachO => {
167
173
writeln ! ( w, ".globl {asm_name}" ) ?;
168
174
writeln ! ( w, ".weak_definition {asm_name}" ) ?;
@@ -189,7 +195,7 @@ fn prefix_and_suffix<'tcx>(
189
195
let mut begin = String :: new ( ) ;
190
196
let mut end = String :: new ( ) ;
191
197
match asm_binary_format {
192
- BinaryFormat :: Elf | BinaryFormat :: Xcoff => {
198
+ BinaryFormat :: Elf => {
193
199
let section = link_section. unwrap_or ( format ! ( ".text.{asm_name}" ) ) ;
194
200
195
201
let progbits = match is_arm {
@@ -203,7 +209,7 @@ fn prefix_and_suffix<'tcx>(
203
209
} ;
204
210
205
211
writeln ! ( begin, ".pushsection {section},\" ax\" , {progbits}" ) . unwrap ( ) ;
206
- writeln ! ( begin, ".balign {align }" ) . unwrap ( ) ;
212
+ writeln ! ( begin, ".balign {align_bytes }" ) . unwrap ( ) ;
207
213
write_linkage ( & mut begin) . unwrap ( ) ;
208
214
if let Visibility :: Hidden = item_data. visibility {
209
215
writeln ! ( begin, ".hidden {asm_name}" ) . unwrap ( ) ;
@@ -224,7 +230,7 @@ fn prefix_and_suffix<'tcx>(
224
230
BinaryFormat :: MachO => {
225
231
let section = link_section. unwrap_or ( "__TEXT,__text" . to_string ( ) ) ;
226
232
writeln ! ( begin, ".pushsection {},regular,pure_instructions" , section) . unwrap ( ) ;
227
- writeln ! ( begin, ".balign {align }" ) . unwrap ( ) ;
233
+ writeln ! ( begin, ".balign {align_bytes }" ) . unwrap ( ) ;
228
234
write_linkage ( & mut begin) . unwrap ( ) ;
229
235
if let Visibility :: Hidden = item_data. visibility {
230
236
writeln ! ( begin, ".private_extern {asm_name}" ) . unwrap ( ) ;
@@ -240,7 +246,7 @@ fn prefix_and_suffix<'tcx>(
240
246
BinaryFormat :: Coff => {
241
247
let section = link_section. unwrap_or ( format ! ( ".text.{asm_name}" ) ) ;
242
248
writeln ! ( begin, ".pushsection {},\" xr\" " , section) . unwrap ( ) ;
243
- writeln ! ( begin, ".balign {align }" ) . unwrap ( ) ;
249
+ writeln ! ( begin, ".balign {align_bytes }" ) . unwrap ( ) ;
244
250
write_linkage ( & mut begin) . unwrap ( ) ;
245
251
writeln ! ( begin, ".def {asm_name}" ) . unwrap ( ) ;
246
252
writeln ! ( begin, ".scl 2" ) . unwrap ( ) ;
@@ -279,6 +285,32 @@ fn prefix_and_suffix<'tcx>(
279
285
// .size is ignored for function symbols, so we can skip it
280
286
writeln ! ( end, "end_function" ) . unwrap ( ) ;
281
287
}
288
+ BinaryFormat :: Xcoff => {
289
+ // the LLVM XCOFFAsmParser extremely is incomplete.
290
+ //
291
+ // https://github.com./llvm/llvm-project/blob/1b25c0c4da968fe78921ce77736e5baef4db75e3/llvm/lib/MC/MCParser/XCOFFAsmParser.cpp
292
+ //
293
+ // and does not implement many of the documented directives from https://www.ibm.com/docs/en/ssw_aix_71/assembler/assembler_pdf.pdf
294
+ //
295
+ // Consequently, we try our best here but cannot do as good a job as for other targets.
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