Auto merge of #101069 - zhaixiaojuan:loongarch64-inline-asm, r=Amanieu
Add loongarch64 asm! support
This commit is contained in:
commit
999e6e5afb
6 changed files with 380 additions and 1 deletions
|
@ -593,6 +593,8 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister {
|
|||
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w",
|
||||
InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => "f",
|
||||
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => "a",
|
||||
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => "d",
|
||||
|
@ -667,6 +669,8 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
|
|||
InlineAsmRegClass::Avr(_) => unimplemented!(),
|
||||
InlineAsmRegClass::Bpf(_) => unimplemented!(),
|
||||
InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => cx.type_i32(),
|
||||
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(),
|
||||
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => cx.type_f32(),
|
||||
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(),
|
||||
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(),
|
||||
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => cx.type_i32(),
|
||||
|
@ -804,6 +808,7 @@ fn modifier_to_gcc(arch: InlineAsmArch, reg: InlineAsmRegClass, modifier: Option
|
|||
}
|
||||
}
|
||||
InlineAsmRegClass::Hexagon(_) => None,
|
||||
InlineAsmRegClass::LoongArch(_) => None,
|
||||
InlineAsmRegClass::Mips(_) => None,
|
||||
InlineAsmRegClass::Nvptx(_) => None,
|
||||
InlineAsmRegClass::PowerPC(_) => None,
|
||||
|
|
|
@ -236,6 +236,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
|||
InlineAsmArch::Nvptx64 => {}
|
||||
InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {}
|
||||
InlineAsmArch::Hexagon => {}
|
||||
InlineAsmArch::LoongArch64 => {}
|
||||
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {}
|
||||
InlineAsmArch::S390x => {}
|
||||
InlineAsmArch::SpirV => {}
|
||||
|
@ -633,6 +634,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
|
|||
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)
|
||||
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg) => "w",
|
||||
InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => "f",
|
||||
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => "r",
|
||||
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => "f",
|
||||
InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => "h",
|
||||
|
@ -719,6 +722,7 @@ fn modifier_to_llvm(
|
|||
}
|
||||
}
|
||||
InlineAsmRegClass::Hexagon(_) => None,
|
||||
InlineAsmRegClass::LoongArch(_) => None,
|
||||
InlineAsmRegClass::Mips(_) => None,
|
||||
InlineAsmRegClass::Nvptx(_) => None,
|
||||
InlineAsmRegClass::PowerPC(_) => None,
|
||||
|
@ -803,6 +807,8 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
|
|||
cx.type_vector(cx.type_i64(), 2)
|
||||
}
|
||||
InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => cx.type_i32(),
|
||||
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(),
|
||||
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => cx.type_f32(),
|
||||
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(),
|
||||
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => cx.type_f32(),
|
||||
InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => cx.type_i16(),
|
||||
|
|
131
compiler/rustc_target/src/asm/loongarch.rs
Normal file
131
compiler/rustc_target/src/asm/loongarch.rs
Normal file
|
@ -0,0 +1,131 @@
|
|||
use super::{InlineAsmArch, InlineAsmType};
|
||||
use rustc_macros::HashStable_Generic;
|
||||
use rustc_span::Symbol;
|
||||
use std::fmt;
|
||||
|
||||
def_reg_class! {
|
||||
LoongArch LoongArchInlineAsmRegClass {
|
||||
reg,
|
||||
freg,
|
||||
}
|
||||
}
|
||||
|
||||
impl LoongArchInlineAsmRegClass {
|
||||
pub fn valid_modifiers(self, _arch: super::InlineAsmArch) -> &'static [char] {
|
||||
&[]
|
||||
}
|
||||
|
||||
pub fn suggest_class(self, _arch: InlineAsmArch, _ty: InlineAsmType) -> Option<Self> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn suggest_modifier(
|
||||
self,
|
||||
_arch: InlineAsmArch,
|
||||
_ty: InlineAsmType,
|
||||
) -> Option<(char, &'static str)> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn supported_types(
|
||||
self,
|
||||
arch: InlineAsmArch,
|
||||
) -> &'static [(InlineAsmType, Option<Symbol>)] {
|
||||
match (self, arch) {
|
||||
(Self::reg, InlineAsmArch::LoongArch64) => types! { _: I8, I16, I32, I64, F32, F64; },
|
||||
(Self::reg, _) => types! { _: I8, I16, I32, F32; },
|
||||
(Self::freg, _) => types! { _: F32, F64; },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The reserved registers are taken from <https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.cpp#79>
|
||||
def_regs! {
|
||||
LoongArch LoongArchInlineAsmReg LoongArchInlineAsmRegClass {
|
||||
r1: reg = ["$r1","$ra"],
|
||||
r4: reg = ["$r4","$a0"],
|
||||
r5: reg = ["$r5","$a1"],
|
||||
r6: reg = ["$r6","$a2"],
|
||||
r7: reg = ["$r7","$a3"],
|
||||
r8: reg = ["$r8","$a4"],
|
||||
r9: reg = ["$r9","$a5"],
|
||||
r10: reg = ["$r10","$a6"],
|
||||
r11: reg = ["$r11","$a7"],
|
||||
r12: reg = ["$r12","$t0"],
|
||||
r13: reg = ["$r13","$t1"],
|
||||
r14: reg = ["$r14","$t2"],
|
||||
r15: reg = ["$r15","$t3"],
|
||||
r16: reg = ["$r16","$t4"],
|
||||
r17: reg = ["$r17","$t5"],
|
||||
r18: reg = ["$r18","$t6"],
|
||||
r19: reg = ["$r19","$t7"],
|
||||
r20: reg = ["$r20","$t8"],
|
||||
r23: reg = ["$r23","$s0"],
|
||||
r24: reg = ["$r24","$s1"],
|
||||
r25: reg = ["$r25","$s2"],
|
||||
r26: reg = ["$r26","$s3"],
|
||||
r27: reg = ["$r27","$s4"],
|
||||
r28: reg = ["$r28","$s5"],
|
||||
r29: reg = ["$r29","$s6"],
|
||||
r30: reg = ["$r30","$s7"],
|
||||
f0: freg = ["$f0","$fa0"],
|
||||
f1: freg = ["$f1","$fa1"],
|
||||
f2: freg = ["$f2","$fa2"],
|
||||
f3: freg = ["$f3","$fa3"],
|
||||
f4: freg = ["$f4","$fa4"],
|
||||
f5: freg = ["$f5","$fa5"],
|
||||
f6: freg = ["$f6","$fa6"],
|
||||
f7: freg = ["$f7","$fa7"],
|
||||
f8: freg = ["$f8","$ft0"],
|
||||
f9: freg = ["$f9","$ft1"],
|
||||
f10: freg = ["$f10","$ft2"],
|
||||
f11: freg = ["$f11","$ft3"],
|
||||
f12: freg = ["$f12","$ft4"],
|
||||
f13: freg = ["$f13","$ft5"],
|
||||
f14: freg = ["$f14","$ft6"],
|
||||
f15: freg = ["$f15","$ft7"],
|
||||
f16: freg = ["$f16","$ft8"],
|
||||
f17: freg = ["$f17","$ft9"],
|
||||
f18: freg = ["$f18","$ft10"],
|
||||
f19: freg = ["$f19","$ft11"],
|
||||
f20: freg = ["$f20","$ft12"],
|
||||
f21: freg = ["$f21","$ft13"],
|
||||
f22: freg = ["$f22","$ft14"],
|
||||
f23: freg = ["$f23","$ft15"],
|
||||
f24: freg = ["$f24","$fs0"],
|
||||
f25: freg = ["$f25","$fs1"],
|
||||
f26: freg = ["$f26","$fs2"],
|
||||
f27: freg = ["$f27","$fs3"],
|
||||
f28: freg = ["$f28","$fs4"],
|
||||
f29: freg = ["$f29","$fs5"],
|
||||
f30: freg = ["$f30","$fs6"],
|
||||
f31: freg = ["$f31","$fs7"],
|
||||
#error = ["$r0","$zero"] =>
|
||||
"constant zero cannot be used as an operand for inline asm",
|
||||
#error = ["$r2","$tp"] =>
|
||||
"reserved for TLS",
|
||||
#error = ["$r3","$sp"] =>
|
||||
"the stack pointer cannot be used as an operand for inline asm",
|
||||
#error = ["$r21"] =>
|
||||
"reserved by the ABI",
|
||||
#error = ["$r22","$fp"] =>
|
||||
"the frame pointer cannot be used as an operand for inline asm",
|
||||
#error = ["$r31","$s8"] =>
|
||||
"$r31 is used internally by LLVM and cannot be used as an operand for inline asm",
|
||||
}
|
||||
}
|
||||
|
||||
impl LoongArchInlineAsmReg {
|
||||
pub fn emit(
|
||||
self,
|
||||
out: &mut dyn fmt::Write,
|
||||
_arch: InlineAsmArch,
|
||||
_modifier: Option<char>,
|
||||
) -> fmt::Result {
|
||||
out.write_str(self.name())
|
||||
}
|
||||
}
|
|
@ -168,6 +168,7 @@ mod arm;
|
|||
mod avr;
|
||||
mod bpf;
|
||||
mod hexagon;
|
||||
mod loongarch;
|
||||
mod m68k;
|
||||
mod mips;
|
||||
mod msp430;
|
||||
|
@ -184,6 +185,7 @@ pub use arm::{ArmInlineAsmReg, ArmInlineAsmRegClass};
|
|||
pub use avr::{AvrInlineAsmReg, AvrInlineAsmRegClass};
|
||||
pub use bpf::{BpfInlineAsmReg, BpfInlineAsmRegClass};
|
||||
pub use hexagon::{HexagonInlineAsmReg, HexagonInlineAsmRegClass};
|
||||
pub use loongarch::{LoongArchInlineAsmReg, LoongArchInlineAsmRegClass};
|
||||
pub use m68k::{M68kInlineAsmReg, M68kInlineAsmRegClass};
|
||||
pub use mips::{MipsInlineAsmReg, MipsInlineAsmRegClass};
|
||||
pub use msp430::{Msp430InlineAsmReg, Msp430InlineAsmRegClass};
|
||||
|
@ -205,6 +207,7 @@ pub enum InlineAsmArch {
|
|||
RiscV64,
|
||||
Nvptx64,
|
||||
Hexagon,
|
||||
LoongArch64,
|
||||
Mips,
|
||||
Mips64,
|
||||
PowerPC,
|
||||
|
@ -234,6 +237,7 @@ impl FromStr for InlineAsmArch {
|
|||
"powerpc" => Ok(Self::PowerPC),
|
||||
"powerpc64" => Ok(Self::PowerPC64),
|
||||
"hexagon" => Ok(Self::Hexagon),
|
||||
"loongarch64" => Ok(Self::LoongArch64),
|
||||
"mips" => Ok(Self::Mips),
|
||||
"mips64" => Ok(Self::Mips64),
|
||||
"s390x" => Ok(Self::S390x),
|
||||
|
@ -259,6 +263,7 @@ pub enum InlineAsmReg {
|
|||
Nvptx(NvptxInlineAsmReg),
|
||||
PowerPC(PowerPCInlineAsmReg),
|
||||
Hexagon(HexagonInlineAsmReg),
|
||||
LoongArch(LoongArchInlineAsmReg),
|
||||
Mips(MipsInlineAsmReg),
|
||||
S390x(S390xInlineAsmReg),
|
||||
SpirV(SpirVInlineAsmReg),
|
||||
|
@ -280,6 +285,7 @@ impl InlineAsmReg {
|
|||
Self::RiscV(r) => r.name(),
|
||||
Self::PowerPC(r) => r.name(),
|
||||
Self::Hexagon(r) => r.name(),
|
||||
Self::LoongArch(r) => r.name(),
|
||||
Self::Mips(r) => r.name(),
|
||||
Self::S390x(r) => r.name(),
|
||||
Self::Bpf(r) => r.name(),
|
||||
|
@ -298,6 +304,7 @@ impl InlineAsmReg {
|
|||
Self::RiscV(r) => InlineAsmRegClass::RiscV(r.reg_class()),
|
||||
Self::PowerPC(r) => InlineAsmRegClass::PowerPC(r.reg_class()),
|
||||
Self::Hexagon(r) => InlineAsmRegClass::Hexagon(r.reg_class()),
|
||||
Self::LoongArch(r) => InlineAsmRegClass::LoongArch(r.reg_class()),
|
||||
Self::Mips(r) => InlineAsmRegClass::Mips(r.reg_class()),
|
||||
Self::S390x(r) => InlineAsmRegClass::S390x(r.reg_class()),
|
||||
Self::Bpf(r) => InlineAsmRegClass::Bpf(r.reg_class()),
|
||||
|
@ -324,6 +331,7 @@ impl InlineAsmReg {
|
|||
Self::PowerPC(PowerPCInlineAsmReg::parse(name)?)
|
||||
}
|
||||
InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmReg::parse(name)?),
|
||||
InlineAsmArch::LoongArch64 => Self::LoongArch(LoongArchInlineAsmReg::parse(name)?),
|
||||
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
|
||||
Self::Mips(MipsInlineAsmReg::parse(name)?)
|
||||
}
|
||||
|
@ -354,6 +362,9 @@ impl InlineAsmReg {
|
|||
Self::RiscV(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
|
||||
Self::PowerPC(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
|
||||
Self::Hexagon(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
|
||||
Self::LoongArch(r) => {
|
||||
r.validate(arch, reloc_model, target_features, target, is_clobber)
|
||||
}
|
||||
Self::Mips(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
|
||||
Self::S390x(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
|
||||
Self::Bpf(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
|
||||
|
@ -379,6 +390,7 @@ impl InlineAsmReg {
|
|||
Self::RiscV(r) => r.emit(out, arch, modifier),
|
||||
Self::PowerPC(r) => r.emit(out, arch, modifier),
|
||||
Self::Hexagon(r) => r.emit(out, arch, modifier),
|
||||
Self::LoongArch(r) => r.emit(out, arch, modifier),
|
||||
Self::Mips(r) => r.emit(out, arch, modifier),
|
||||
Self::S390x(r) => r.emit(out, arch, modifier),
|
||||
Self::Bpf(r) => r.emit(out, arch, modifier),
|
||||
|
@ -397,6 +409,7 @@ impl InlineAsmReg {
|
|||
Self::RiscV(_) => cb(self),
|
||||
Self::PowerPC(r) => r.overlapping_regs(|r| cb(Self::PowerPC(r))),
|
||||
Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))),
|
||||
Self::LoongArch(_) => cb(self),
|
||||
Self::Mips(_) => cb(self),
|
||||
Self::S390x(_) => cb(self),
|
||||
Self::Bpf(r) => r.overlapping_regs(|r| cb(Self::Bpf(r))),
|
||||
|
@ -418,6 +431,7 @@ pub enum InlineAsmRegClass {
|
|||
Nvptx(NvptxInlineAsmRegClass),
|
||||
PowerPC(PowerPCInlineAsmRegClass),
|
||||
Hexagon(HexagonInlineAsmRegClass),
|
||||
LoongArch(LoongArchInlineAsmRegClass),
|
||||
Mips(MipsInlineAsmRegClass),
|
||||
S390x(S390xInlineAsmRegClass),
|
||||
SpirV(SpirVInlineAsmRegClass),
|
||||
|
@ -440,6 +454,7 @@ impl InlineAsmRegClass {
|
|||
Self::Nvptx(r) => r.name(),
|
||||
Self::PowerPC(r) => r.name(),
|
||||
Self::Hexagon(r) => r.name(),
|
||||
Self::LoongArch(r) => r.name(),
|
||||
Self::Mips(r) => r.name(),
|
||||
Self::S390x(r) => r.name(),
|
||||
Self::SpirV(r) => r.name(),
|
||||
|
@ -464,6 +479,7 @@ impl InlineAsmRegClass {
|
|||
Self::Nvptx(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Nvptx),
|
||||
Self::PowerPC(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::PowerPC),
|
||||
Self::Hexagon(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Hexagon),
|
||||
Self::LoongArch(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::LoongArch),
|
||||
Self::Mips(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Mips),
|
||||
Self::S390x(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::S390x),
|
||||
Self::SpirV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::SpirV),
|
||||
|
@ -495,6 +511,7 @@ impl InlineAsmRegClass {
|
|||
Self::Nvptx(r) => r.suggest_modifier(arch, ty),
|
||||
Self::PowerPC(r) => r.suggest_modifier(arch, ty),
|
||||
Self::Hexagon(r) => r.suggest_modifier(arch, ty),
|
||||
Self::LoongArch(r) => r.suggest_modifier(arch, ty),
|
||||
Self::Mips(r) => r.suggest_modifier(arch, ty),
|
||||
Self::S390x(r) => r.suggest_modifier(arch, ty),
|
||||
Self::SpirV(r) => r.suggest_modifier(arch, ty),
|
||||
|
@ -522,6 +539,7 @@ impl InlineAsmRegClass {
|
|||
Self::Nvptx(r) => r.default_modifier(arch),
|
||||
Self::PowerPC(r) => r.default_modifier(arch),
|
||||
Self::Hexagon(r) => r.default_modifier(arch),
|
||||
Self::LoongArch(r) => r.default_modifier(arch),
|
||||
Self::Mips(r) => r.default_modifier(arch),
|
||||
Self::S390x(r) => r.default_modifier(arch),
|
||||
Self::SpirV(r) => r.default_modifier(arch),
|
||||
|
@ -548,6 +566,7 @@ impl InlineAsmRegClass {
|
|||
Self::Nvptx(r) => r.supported_types(arch),
|
||||
Self::PowerPC(r) => r.supported_types(arch),
|
||||
Self::Hexagon(r) => r.supported_types(arch),
|
||||
Self::LoongArch(r) => r.supported_types(arch),
|
||||
Self::Mips(r) => r.supported_types(arch),
|
||||
Self::S390x(r) => r.supported_types(arch),
|
||||
Self::SpirV(r) => r.supported_types(arch),
|
||||
|
@ -575,6 +594,7 @@ impl InlineAsmRegClass {
|
|||
Self::PowerPC(PowerPCInlineAsmRegClass::parse(name)?)
|
||||
}
|
||||
InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmRegClass::parse(name)?),
|
||||
InlineAsmArch::LoongArch64 => Self::LoongArch(LoongArchInlineAsmRegClass::parse(name)?),
|
||||
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
|
||||
Self::Mips(MipsInlineAsmRegClass::parse(name)?)
|
||||
}
|
||||
|
@ -601,6 +621,7 @@ impl InlineAsmRegClass {
|
|||
Self::Nvptx(r) => r.valid_modifiers(arch),
|
||||
Self::PowerPC(r) => r.valid_modifiers(arch),
|
||||
Self::Hexagon(r) => r.valid_modifiers(arch),
|
||||
Self::LoongArch(r) => r.valid_modifiers(arch),
|
||||
Self::Mips(r) => r.valid_modifiers(arch),
|
||||
Self::S390x(r) => r.valid_modifiers(arch),
|
||||
Self::SpirV(r) => r.valid_modifiers(arch),
|
||||
|
@ -760,6 +781,11 @@ pub fn allocatable_registers(
|
|||
hexagon::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
|
||||
map
|
||||
}
|
||||
InlineAsmArch::LoongArch64 => {
|
||||
let mut map = loongarch::regclass_map();
|
||||
loongarch::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
|
||||
map
|
||||
}
|
||||
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
|
||||
let mut map = mips::regclass_map();
|
||||
mips::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue