Rollup merge of #146949 - pmur:murp/improve-ppc-inline-asm, r=Amanieu
Add vsx register support for ppc inline asm, and implement preserves_flag option This should address the last(?) missing pieces of inline asm for ppc: * Explicit VSX register support. ISA 2.06 (POWER7) added a 64x128b register overlay extending the fpr's to 128b, and unifies them with the vmx (altivec) registers. Implementations details within gcc/llvm percolate up, and require using the `x` template modifier. I have updated the inline asm to implicitly include this for vsx arguments which do not specify it. ~~Support for the gcc codegen backend is still a todo.~~ * Implement the `preserves_flags` option. All ABI's, and all ISAs store their flags in `cr`, and the carry bit lives inside `xer`. The other status registers hold sticky bits or control bits which do not affect branch instructions. There is some interest in the e500 (powerpcspe) port. Architecturally, it has a very different FP ISA, and includes a simd extension called SPR (which is not IBM's cell SPE). Notably, it does not have altivec/fpr/vsx registers. It also has an SPE accumulator register which its ABI marks as volatile, but I am not sure if the compiler uses it.
This commit is contained in:
@@ -546,9 +546,16 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||
}
|
||||
|
||||
if !options.contains(InlineAsmOptions::PRESERVES_FLAGS) {
|
||||
// TODO(@Commeownist): I'm not 100% sure this one clobber is sufficient
|
||||
// on all architectures. For instance, what about FP stack?
|
||||
extended_asm.add_clobber("cc");
|
||||
match asm_arch {
|
||||
InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {
|
||||
// "cc" is cr0 on powerpc.
|
||||
}
|
||||
// TODO(@Commeownist): I'm not 100% sure this one clobber is sufficient
|
||||
// on all architectures. For instance, what about FP stack?
|
||||
_ => {
|
||||
extended_asm.add_clobber("cc");
|
||||
}
|
||||
}
|
||||
}
|
||||
if !options.contains(InlineAsmOptions::NOMEM) {
|
||||
extended_asm.add_clobber("memory");
|
||||
@@ -698,6 +705,7 @@ fn reg_class_to_gcc(reg_class: InlineAsmRegClass) -> &'static str {
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b",
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => "f",
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => "v",
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vsreg) => "wa",
|
||||
InlineAsmRegClass::PowerPC(
|
||||
PowerPCInlineAsmRegClass::cr
|
||||
| PowerPCInlineAsmRegClass::ctr
|
||||
@@ -778,9 +786,9 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => cx.type_i32(),
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => cx.type_i32(),
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => cx.type_f64(),
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => {
|
||||
cx.type_vector(cx.type_i32(), 4)
|
||||
}
|
||||
InlineAsmRegClass::PowerPC(
|
||||
PowerPCInlineAsmRegClass::vreg | PowerPCInlineAsmRegClass::vsreg,
|
||||
) => cx.type_vector(cx.type_i32(), 4),
|
||||
InlineAsmRegClass::PowerPC(
|
||||
PowerPCInlineAsmRegClass::cr
|
||||
| PowerPCInlineAsmRegClass::ctr
|
||||
@@ -957,6 +965,13 @@ fn modifier_to_gcc(
|
||||
InlineAsmRegClass::LoongArch(_) => None,
|
||||
InlineAsmRegClass::Mips(_) => None,
|
||||
InlineAsmRegClass::Nvptx(_) => None,
|
||||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vsreg) => {
|
||||
if modifier.is_none() {
|
||||
Some('x')
|
||||
} else {
|
||||
modifier
|
||||
}
|
||||
}
|
||||
InlineAsmRegClass::PowerPC(_) => None,
|
||||
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg)
|
||||
| InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => None,
|
||||
|
||||
Reference in New Issue
Block a user