-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
attempt to support BinaryFormat::Xcoff
in naked_asm!
#137816
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -125,7 +125,8 @@ fn prefix_and_suffix<'tcx>( | |
// the alignment from a `#[repr(align(<n>))]` is used if it specifies a higher alignment. | ||
// if no alignment is specified, an alignment of 4 bytes is used. | ||
let min_function_alignment = tcx.sess.opts.unstable_opts.min_function_alignment; | ||
let align = Ord::max(min_function_alignment, attrs.alignment).map(|a| a.bytes()).unwrap_or(4); | ||
let align_bytes = | ||
Ord::max(min_function_alignment, attrs.alignment).map(|a| a.bytes()).unwrap_or(4); | ||
|
||
// In particular, `.arm` can also be written `.code 32` and `.thumb` as `.code 16`. | ||
let (arch_prefix, arch_suffix) = if is_arm { | ||
|
@@ -157,12 +158,16 @@ fn prefix_and_suffix<'tcx>( | |
} | ||
Linkage::LinkOnceAny | Linkage::LinkOnceODR | Linkage::WeakAny | Linkage::WeakODR => { | ||
match asm_binary_format { | ||
BinaryFormat::Elf | ||
| BinaryFormat::Coff | ||
| BinaryFormat::Wasm | ||
| BinaryFormat::Xcoff => { | ||
BinaryFormat::Elf | BinaryFormat::Coff | BinaryFormat::Wasm => { | ||
writeln!(w, ".weak {asm_name}")?; | ||
} | ||
BinaryFormat::Xcoff => { | ||
// FIXME: there is currently no way of defining a weak symbol in inline assembly | ||
// for AIX. See https://github.com/llvm/llvm-project/issues/130269 | ||
emit_fatal( | ||
"cannot create weak symbols from inline assembly for this target", | ||
) | ||
} | ||
BinaryFormat::MachO => { | ||
writeln!(w, ".globl {asm_name}")?; | ||
writeln!(w, ".weak_definition {asm_name}")?; | ||
|
@@ -189,7 +194,7 @@ fn prefix_and_suffix<'tcx>( | |
let mut begin = String::new(); | ||
let mut end = String::new(); | ||
match asm_binary_format { | ||
BinaryFormat::Elf | BinaryFormat::Xcoff => { | ||
BinaryFormat::Elf => { | ||
let section = link_section.unwrap_or(format!(".text.{asm_name}")); | ||
|
||
let progbits = match is_arm { | ||
|
@@ -203,7 +208,7 @@ fn prefix_and_suffix<'tcx>( | |
}; | ||
|
||
writeln!(begin, ".pushsection {section},\"ax\", {progbits}").unwrap(); | ||
writeln!(begin, ".balign {align}").unwrap(); | ||
writeln!(begin, ".balign {align_bytes}").unwrap(); | ||
write_linkage(&mut begin).unwrap(); | ||
if let Visibility::Hidden = item_data.visibility { | ||
writeln!(begin, ".hidden {asm_name}").unwrap(); | ||
|
@@ -224,7 +229,7 @@ fn prefix_and_suffix<'tcx>( | |
BinaryFormat::MachO => { | ||
let section = link_section.unwrap_or("__TEXT,__text".to_string()); | ||
writeln!(begin, ".pushsection {},regular,pure_instructions", section).unwrap(); | ||
writeln!(begin, ".balign {align}").unwrap(); | ||
writeln!(begin, ".balign {align_bytes}").unwrap(); | ||
write_linkage(&mut begin).unwrap(); | ||
if let Visibility::Hidden = item_data.visibility { | ||
writeln!(begin, ".private_extern {asm_name}").unwrap(); | ||
|
@@ -240,7 +245,7 @@ fn prefix_and_suffix<'tcx>( | |
BinaryFormat::Coff => { | ||
let section = link_section.unwrap_or(format!(".text.{asm_name}")); | ||
writeln!(begin, ".pushsection {},\"xr\"", section).unwrap(); | ||
writeln!(begin, ".balign {align}").unwrap(); | ||
writeln!(begin, ".balign {align_bytes}").unwrap(); | ||
write_linkage(&mut begin).unwrap(); | ||
writeln!(begin, ".def {asm_name}").unwrap(); | ||
writeln!(begin, ".scl 2").unwrap(); | ||
|
@@ -279,6 +284,33 @@ fn prefix_and_suffix<'tcx>( | |
// .size is ignored for function symbols, so we can skip it | ||
writeln!(end, "end_function").unwrap(); | ||
} | ||
BinaryFormat::Xcoff => { | ||
// the LLVM XCOFFAsmParser is extremely incomplete and does not implement many of the | ||
// documented directives. | ||
// | ||
// - https://github.com/llvm/llvm-project/blob/1b25c0c4da968fe78921ce77736e5baef4db75e3/llvm/lib/MC/MCParser/XCOFFAsmParser.cpp | ||
// - https://www.ibm.com/docs/en/ssw_aix_71/assembler/assembler_pdf.pdf | ||
// | ||
// Consequently, we try our best here but cannot do as good a job as for other binary | ||
// formats. | ||
|
||
// FIXME: start a section. `.csect` is not currently implemented in LLVM | ||
|
||
// fun fact: according to the assembler documentation, .align takes an exponent, | ||
// but LLVM only accepts powers of 2 (but does emit the exponent) | ||
// so when we hand `.align 32` to LLVM, the assembly output will contain `.align 5` | ||
writeln!(begin, ".align {}", align_bytes).unwrap(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. note: Yeah, this is a fun dialect difference of AIX assembly that we don't handle well |
||
|
||
write_linkage(&mut begin).unwrap(); | ||
if let Visibility::Hidden = item_data.visibility { | ||
// FIXME apparently `.globl {asm_name}, hidden` is valid | ||
// but due to limitations with `.weak` (see above) we can't really use that in general yet | ||
} | ||
writeln!(begin, "{asm_name}:").unwrap(); | ||
|
||
writeln!(end).unwrap(); | ||
// FIXME: end the section? | ||
} | ||
} | ||
|
||
(begin, end) | ||
|
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
//@ revisions: elfv1-be aix | ||
//@ add-core-stubs | ||
//@ assembly-output: emit-asm | ||
// | ||
//@[elfv1-be] compile-flags: --target powerpc64-unknown-linux-gnu | ||
//@[elfv1-be] needs-llvm-components: powerpc | ||
// | ||
//@[aix] compile-flags: --target powerpc64-ibm-aix | ||
//@[aix] needs-llvm-components: powerpc | ||
|
||
#![crate_type = "lib"] | ||
#![feature(no_core, naked_functions, asm_experimental_arch, f128, linkage, fn_align)] | ||
#![no_core] | ||
|
||
// tests that naked functions work for the `powerpc64-ibm-aix` target. | ||
// | ||
// This target is special because it uses the XCOFF binary format | ||
// It is tested alongside an elf powerpc target to pin down commonalities and differences. | ||
// | ||
// https://doc.rust-lang.org/rustc/platform-support/aix.html | ||
// https://www.ibm.com/docs/en/aix/7.2?topic=formats-xcoff-object-file-format | ||
|
||
extern crate minicore; | ||
use minicore::*; | ||
|
||
// elfv1-be: .p2align 2 | ||
// aix: .align 2 | ||
// CHECK: .globl blr | ||
// CHECK-LABEL: blr: | ||
// CHECK: blr | ||
#[no_mangle] | ||
#[naked] | ||
unsafe extern "C" fn blr() { | ||
naked_asm!("blr") | ||
} |
File renamed without changes.
File renamed without changes.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, we modelled the CSect as MCSections in the LLVM backend (XCOFF doesn't really have arbitrary sections, so that works well enought). So for the assembly writing the
.csect
directive is written when we switch to section.With that in mind I wonder if
.section
works for the parser? Otherwise, it's not clear to me which.csect
this ends up in? (Without-ffunction-sections
we typical have a catch all..text..[PR]
, if it's that one seems fine)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't look like it https://godbolt.org/z/4zfvahexs, neither
.section
or.pushsection
is recognized.