@@ -125,7 +125,8 @@ fn prefix_and_suffix<'tcx>(
125125 // the alignment from a `#[repr(align(<n>))]` is used if it specifies a higher alignment.
126126 // if no alignment is specified, an alignment of 4 bytes is used.
127127 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 ) ;
129130
130131 // In particular, `.arm` can also be written `.code 32` and `.thumb` as `.code 16`.
131132 let ( arch_prefix, arch_suffix) = if is_arm {
@@ -157,12 +158,16 @@ fn prefix_and_suffix<'tcx>(
157158 }
158159 Linkage :: LinkOnceAny | Linkage :: LinkOnceODR | Linkage :: WeakAny | Linkage :: WeakODR => {
159160 match asm_binary_format {
160- BinaryFormat :: Elf
161- | BinaryFormat :: Coff
162- | BinaryFormat :: Wasm
163- | BinaryFormat :: Xcoff => {
161+ BinaryFormat :: Elf | BinaryFormat :: Coff | BinaryFormat :: Wasm => {
164162 writeln ! ( w, ".weak {asm_name}" ) ?;
165163 }
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+ }
166171 BinaryFormat :: MachO => {
167172 writeln ! ( w, ".globl {asm_name}" ) ?;
168173 writeln ! ( w, ".weak_definition {asm_name}" ) ?;
@@ -189,7 +194,7 @@ fn prefix_and_suffix<'tcx>(
189194 let mut begin = String :: new ( ) ;
190195 let mut end = String :: new ( ) ;
191196 match asm_binary_format {
192- BinaryFormat :: Elf | BinaryFormat :: Xcoff => {
197+ BinaryFormat :: Elf => {
193198 let section = link_section. unwrap_or ( format ! ( ".text.{asm_name}" ) ) ;
194199
195200 let progbits = match is_arm {
@@ -203,7 +208,7 @@ fn prefix_and_suffix<'tcx>(
203208 } ;
204209
205210 writeln ! ( begin, ".pushsection {section},\" ax\" , {progbits}" ) . unwrap ( ) ;
206- writeln ! ( begin, ".balign {align }" ) . unwrap ( ) ;
211+ writeln ! ( begin, ".balign {align_bytes }" ) . unwrap ( ) ;
207212 write_linkage ( & mut begin) . unwrap ( ) ;
208213 if let Visibility :: Hidden = item_data. visibility {
209214 writeln ! ( begin, ".hidden {asm_name}" ) . unwrap ( ) ;
@@ -224,7 +229,7 @@ fn prefix_and_suffix<'tcx>(
224229 BinaryFormat :: MachO => {
225230 let section = link_section. unwrap_or ( "__TEXT,__text" . to_string ( ) ) ;
226231 writeln ! ( begin, ".pushsection {},regular,pure_instructions" , section) . unwrap ( ) ;
227- writeln ! ( begin, ".balign {align }" ) . unwrap ( ) ;
232+ writeln ! ( begin, ".balign {align_bytes }" ) . unwrap ( ) ;
228233 write_linkage ( & mut begin) . unwrap ( ) ;
229234 if let Visibility :: Hidden = item_data. visibility {
230235 writeln ! ( begin, ".private_extern {asm_name}" ) . unwrap ( ) ;
@@ -240,7 +245,7 @@ fn prefix_and_suffix<'tcx>(
240245 BinaryFormat :: Coff => {
241246 let section = link_section. unwrap_or ( format ! ( ".text.{asm_name}" ) ) ;
242247 writeln ! ( begin, ".pushsection {},\" xr\" " , section) . unwrap ( ) ;
243- writeln ! ( begin, ".balign {align }" ) . unwrap ( ) ;
248+ writeln ! ( begin, ".balign {align_bytes }" ) . unwrap ( ) ;
244249 write_linkage ( & mut begin) . unwrap ( ) ;
245250 writeln ! ( begin, ".def {asm_name}" ) . unwrap ( ) ;
246251 writeln ! ( begin, ".scl 2" ) . unwrap ( ) ;
@@ -279,6 +284,33 @@ fn prefix_and_suffix<'tcx>(
279284 // .size is ignored for function symbols, so we can skip it
280285 writeln ! ( end, "end_function" ) . unwrap ( ) ;
281286 }
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+ }
282314 }
283315
284316 ( begin, end)
0 commit comments