Skip to content
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

Add asm clobbers for PPC / PPC64 #111335

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion compiler/rustc_codegen_gcc/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,8 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister {
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b",
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => "f",
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => "v",
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)//should this not be either x or y ?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are explicitly making these clobber-only for now. We can always revisit this later if needed.

| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => {
unreachable!("clobber-only")
},
Expand Down Expand Up @@ -683,6 +684,7 @@ 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_i64(), 2),
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => {
unreachable!("clobber-only")
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_codegen_llvm/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,7 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b",
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => "f",
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => "v",
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => {
unreachable!("clobber-only")
Expand Down Expand Up @@ -817,6 +818,12 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
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_i64(), 2)
} //no clue if this is right :D
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is correct if the tests accept it! You'll need to extend the tests in tests/assembly/asm to include tests for vector regisers. Have a look at the AArch64/x86 tests for examples.

// IBM doc: All PPC vreg's are 128-bits wide.
//Each vreg can hold sixteen 8-bit elements, eight 16-bit elements, or four 32-bit elements.
// LLVM doc: For 4 x f32 or 4 x f64 types, a 128-bit altivec vector
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)
| InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => {
unreachable!("clobber-only")
Expand Down
20 changes: 20 additions & 0 deletions compiler/rustc_target/src/asm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,7 @@ pub enum InlineAsmClobberAbi {
AArch64NoX18,
RiscV,
LoongArch,
PowerPC,
}

impl InlineAsmClobberAbi {
Expand Down Expand Up @@ -885,6 +886,10 @@ impl InlineAsmClobberAbi {
"C" | "system" | "efiapi" => Ok(InlineAsmClobberAbi::LoongArch),
_ => Err(&["C", "system", "efiapi"]),
},
InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => match name {
"C" | "system" | "efiapi" => Ok(InlineAsmClobberAbi::PowerPC),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not include efiapi.

_ => Err(&["C", "system", "efiapi"]),
},
_ => Err(&[]),
}
}
Expand Down Expand Up @@ -1042,6 +1047,21 @@ impl InlineAsmClobberAbi {
f16, f17, f18, f19, f20, f21, f22, f23,
}
},
InlineAsmClobberAbi::PowerPC => clobbered_regs! {
PowerPC PowerPCInlineAsmReg {
// ra
r0,
r3, r4, r5, r6, r7, r8, r9, r10, r11, r12,
// float
f0, f1, f2, f3, f4, f5, f6, f7, f8, f9,
f10, f11, f12, f13,

// VMX capable only
v0, v1, v2, v3, v4, v5, v6, v7, v8, v9,
v10, v11, v12, v13, v14, v15, v16, v17,
v18, v19,
}
},
}
}
}
38 changes: 38 additions & 0 deletions compiler/rustc_target/src/asm/powerpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ def_reg_class! {
reg,
reg_nonzero,
freg,
vreg,
cr,
xer,
}
Expand Down Expand Up @@ -47,6 +48,7 @@ impl PowerPCInlineAsmRegClass {
}
}
Self::freg => types! { _: F32, F64; },
Self::vreg => todo!(), //not quite sure :)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be something like:

types! {
    vsx: I8, I16, I32, I64, F32, F64,
    altivec: VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2);
}

Altivec allows 128-bit vector types, and VSX allows using scalars in vector registers.

However this should be verified by writing asm tests that checks that LLVM is able to generate the correct code for these.

Self::cr | Self::xer => &[],
}
}
Expand Down Expand Up @@ -112,6 +114,38 @@ def_regs! {
f29: freg = ["f29", "fr29"],
f30: freg = ["f30", "fr30"],
f31: freg = ["f31", "fr31"],
v0: vreg = ["v0"],
v1: vreg = ["v1"],
v2: vreg = ["v2"],
v3: vreg = ["v3"],
v4: vreg = ["v4"],
v5: vreg = ["v5"],
v6: vreg = ["v6"],
v7: vreg = ["v7"],
v8: vreg = ["v8"],
v9: vreg = ["v9"],
v10: vreg = ["v10"],
v11: vreg = ["v11"],
v12: vreg = ["v12"],
v13: vreg = ["v13"],
v14: vreg = ["v14"],
v15: vreg = ["v15"],
v16: vreg = ["v16"],
v17: vreg = ["v17"],
v18: vreg = ["v18"],
v19: vreg = ["v19"],
v20: vreg = ["v20"],
v21: vreg = ["v21"],
v22: vreg = ["v22"],
v23: vreg = ["v23"],
v24: vreg = ["v24"],
v25: vreg = ["v25"],
v26: vreg = ["v26"],
v27: vreg = ["v27"],
v28: vreg = ["v28"],
v29: vreg = ["v29"],
v30: vreg = ["v30"],
v31: vreg = ["v31"],
cr: cr = ["cr"],
cr0: cr = ["cr0"],
cr1: cr = ["cr1"],
Expand Down Expand Up @@ -169,6 +203,10 @@ impl PowerPCInlineAsmReg {
(f8, "8"), (f9, "9"), (f10, "10"), (f11, "11"), (f12, "12"), (f13, "13"), (f14, "14"), (f15, "15");
(f16, "16"), (f17, "17"), (f18, "18"), (f19, "19"), (f20, "20"), (f21, "21"), (f22, "22"), (f23, "23");
(f24, "24"), (f25, "25"), (f26, "26"), (f27, "27"), (f28, "28"), (f29, "29"), (f30, "30"), (f31, "31");
(v0, "0"), (v1, "1"), (v2, "2"), (v3, "3"), (v4, "4"), (v5, "5"), (v6, "6"), (v7, "7");
(v8, "8"), (v9, "9"), (v10, "10"), (v11, "11"), (v12, "12"), (v13, "13"), (v14, "14"), (v15, "15");
(v16, "16"), (v17, "17"), (v18, "18"), (v19, "19"), (v20, "20"), (v21, "21"), (v22, "22"), (v23, "23");
(v24, "24"), (v25, "25"), (v26, "26"), (v27, "27"), (v28, "28"), (v29, "29"), (v30, "30"), (v31, "31");
(cr, "cr");
(cr0, "0"), (cr1, "1"), (cr2, "2"), (cr3, "3"), (cr4, "4"), (cr5, "5"), (cr6, "6"), (cr7, "7");
(xer, "xer");
Expand Down