@@ -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