summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_target/src/asm
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /compiler/rustc_target/src/asm
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_target/src/asm')
-rw-r--r--compiler/rustc_target/src/asm/loongarch.rs130
-rw-r--r--compiler/rustc_target/src/asm/mod.rs46
2 files changed, 176 insertions, 0 deletions
diff --git a/compiler/rustc_target/src/asm/loongarch.rs b/compiler/rustc_target/src/asm/loongarch.rs
new file mode 100644
index 000000000..9d1a4f3ee
--- /dev/null
+++ b/compiler/rustc_target/src/asm/loongarch.rs
@@ -0,0 +1,130 @@
+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 {
+ Self::reg => types! { _: I8, I16, I32, I64, F32, F64; },
+ 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())
+ }
+}
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index 3f9c850b3..e60b8e78e 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -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);
@@ -813,6 +839,7 @@ pub enum InlineAsmClobberAbi {
AArch64,
AArch64NoX18,
RiscV,
+ LoongArch,
}
impl InlineAsmClobberAbi {
@@ -854,6 +881,10 @@ impl InlineAsmClobberAbi {
"C" | "system" | "efiapi" => Ok(InlineAsmClobberAbi::RiscV),
_ => Err(&["C", "system", "efiapi"]),
},
+ InlineAsmArch::LoongArch64 => match name {
+ "C" | "system" => Ok(InlineAsmClobberAbi::LoongArch),
+ _ => Err(&["C", "system"]),
+ },
_ => Err(&[]),
}
}
@@ -996,6 +1027,21 @@ impl InlineAsmClobberAbi {
v24, v25, v26, v27, v28, v29, v30, v31,
}
},
+ InlineAsmClobberAbi::LoongArch => clobbered_regs! {
+ LoongArch LoongArchInlineAsmReg {
+ // ra
+ r1,
+ // a0-a7
+ r4, r5, r6, r7, r8, r9, r10, r11,
+ // t0-t8
+ r12, r13, r14, r15, r16, r17, r18, r19, r20,
+ // fa0-fa7
+ f0, f1, f2, f3, f4, f5, f6, f7,
+ // ft0-ft15
+ f8, f9, f10, f11, f12, f13, f14, f15,
+ f16, f17, f18, f19, f20, f21, f22, f23,
+ }
+ },
}
}
}