Skip to content

Commit 999e6e5

Browse files
committed
Auto merge of #101069 - zhaixiaojuan:loongarch64-inline-asm, r=Amanieu
Add loongarch64 asm! support
2 parents 91b61a4 + 5f2fa4c commit 999e6e5

File tree

6 files changed

+380
-1
lines changed

6 files changed

+380
-1
lines changed

Diff for: compiler/rustc_codegen_gcc/src/asm.rs

+5
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,8 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister {
593593
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r",
594594
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w",
595595
InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => "r",
596+
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => "r",
597+
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => "f",
596598
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => "r",
597599
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => "a",
598600
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => "d",
@@ -667,6 +669,8 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
667669
InlineAsmRegClass::Avr(_) => unimplemented!(),
668670
InlineAsmRegClass::Bpf(_) => unimplemented!(),
669671
InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => cx.type_i32(),
672+
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(),
673+
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => cx.type_f32(),
670674
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(),
671675
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(),
672676
InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => cx.type_i32(),
@@ -804,6 +808,7 @@ fn modifier_to_gcc(arch: InlineAsmArch, reg: InlineAsmRegClass, modifier: Option
804808
}
805809
}
806810
InlineAsmRegClass::Hexagon(_) => None,
811+
InlineAsmRegClass::LoongArch(_) => None,
807812
InlineAsmRegClass::Mips(_) => None,
808813
InlineAsmRegClass::Nvptx(_) => None,
809814
InlineAsmRegClass::PowerPC(_) => None,

Diff for: compiler/rustc_codegen_llvm/src/asm.rs

+6
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
236236
InlineAsmArch::Nvptx64 => {}
237237
InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {}
238238
InlineAsmArch::Hexagon => {}
239+
InlineAsmArch::LoongArch64 => {}
239240
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {}
240241
InlineAsmArch::S390x => {}
241242
InlineAsmArch::SpirV => {}
@@ -633,6 +634,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
633634
InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)
634635
| InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg) => "w",
635636
InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => "r",
637+
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => "r",
638+
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => "f",
636639
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => "r",
637640
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => "f",
638641
InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => "h",
@@ -719,6 +722,7 @@ fn modifier_to_llvm(
719722
}
720723
}
721724
InlineAsmRegClass::Hexagon(_) => None,
725+
InlineAsmRegClass::LoongArch(_) => None,
722726
InlineAsmRegClass::Mips(_) => None,
723727
InlineAsmRegClass::Nvptx(_) => None,
724728
InlineAsmRegClass::PowerPC(_) => None,
@@ -803,6 +807,8 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
803807
cx.type_vector(cx.type_i64(), 2)
804808
}
805809
InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => cx.type_i32(),
810+
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(),
811+
InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => cx.type_f32(),
806812
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(),
807813
InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => cx.type_f32(),
808814
InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => cx.type_i16(),

Diff for: compiler/rustc_target/src/asm/loongarch.rs

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
use super::{InlineAsmArch, InlineAsmType};
2+
use rustc_macros::HashStable_Generic;
3+
use rustc_span::Symbol;
4+
use std::fmt;
5+
6+
def_reg_class! {
7+
LoongArch LoongArchInlineAsmRegClass {
8+
reg,
9+
freg,
10+
}
11+
}
12+
13+
impl LoongArchInlineAsmRegClass {
14+
pub fn valid_modifiers(self, _arch: super::InlineAsmArch) -> &'static [char] {
15+
&[]
16+
}
17+
18+
pub fn suggest_class(self, _arch: InlineAsmArch, _ty: InlineAsmType) -> Option<Self> {
19+
None
20+
}
21+
22+
pub fn suggest_modifier(
23+
self,
24+
_arch: InlineAsmArch,
25+
_ty: InlineAsmType,
26+
) -> Option<(char, &'static str)> {
27+
None
28+
}
29+
30+
pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
31+
None
32+
}
33+
34+
pub fn supported_types(
35+
self,
36+
arch: InlineAsmArch,
37+
) -> &'static [(InlineAsmType, Option<Symbol>)] {
38+
match (self, arch) {
39+
(Self::reg, InlineAsmArch::LoongArch64) => types! { _: I8, I16, I32, I64, F32, F64; },
40+
(Self::reg, _) => types! { _: I8, I16, I32, F32; },
41+
(Self::freg, _) => types! { _: F32, F64; },
42+
}
43+
}
44+
}
45+
46+
// The reserved registers are taken from <https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.cpp#79>
47+
def_regs! {
48+
LoongArch LoongArchInlineAsmReg LoongArchInlineAsmRegClass {
49+
r1: reg = ["$r1","$ra"],
50+
r4: reg = ["$r4","$a0"],
51+
r5: reg = ["$r5","$a1"],
52+
r6: reg = ["$r6","$a2"],
53+
r7: reg = ["$r7","$a3"],
54+
r8: reg = ["$r8","$a4"],
55+
r9: reg = ["$r9","$a5"],
56+
r10: reg = ["$r10","$a6"],
57+
r11: reg = ["$r11","$a7"],
58+
r12: reg = ["$r12","$t0"],
59+
r13: reg = ["$r13","$t1"],
60+
r14: reg = ["$r14","$t2"],
61+
r15: reg = ["$r15","$t3"],
62+
r16: reg = ["$r16","$t4"],
63+
r17: reg = ["$r17","$t5"],
64+
r18: reg = ["$r18","$t6"],
65+
r19: reg = ["$r19","$t7"],
66+
r20: reg = ["$r20","$t8"],
67+
r23: reg = ["$r23","$s0"],
68+
r24: reg = ["$r24","$s1"],
69+
r25: reg = ["$r25","$s2"],
70+
r26: reg = ["$r26","$s3"],
71+
r27: reg = ["$r27","$s4"],
72+
r28: reg = ["$r28","$s5"],
73+
r29: reg = ["$r29","$s6"],
74+
r30: reg = ["$r30","$s7"],
75+
f0: freg = ["$f0","$fa0"],
76+
f1: freg = ["$f1","$fa1"],
77+
f2: freg = ["$f2","$fa2"],
78+
f3: freg = ["$f3","$fa3"],
79+
f4: freg = ["$f4","$fa4"],
80+
f5: freg = ["$f5","$fa5"],
81+
f6: freg = ["$f6","$fa6"],
82+
f7: freg = ["$f7","$fa7"],
83+
f8: freg = ["$f8","$ft0"],
84+
f9: freg = ["$f9","$ft1"],
85+
f10: freg = ["$f10","$ft2"],
86+
f11: freg = ["$f11","$ft3"],
87+
f12: freg = ["$f12","$ft4"],
88+
f13: freg = ["$f13","$ft5"],
89+
f14: freg = ["$f14","$ft6"],
90+
f15: freg = ["$f15","$ft7"],
91+
f16: freg = ["$f16","$ft8"],
92+
f17: freg = ["$f17","$ft9"],
93+
f18: freg = ["$f18","$ft10"],
94+
f19: freg = ["$f19","$ft11"],
95+
f20: freg = ["$f20","$ft12"],
96+
f21: freg = ["$f21","$ft13"],
97+
f22: freg = ["$f22","$ft14"],
98+
f23: freg = ["$f23","$ft15"],
99+
f24: freg = ["$f24","$fs0"],
100+
f25: freg = ["$f25","$fs1"],
101+
f26: freg = ["$f26","$fs2"],
102+
f27: freg = ["$f27","$fs3"],
103+
f28: freg = ["$f28","$fs4"],
104+
f29: freg = ["$f29","$fs5"],
105+
f30: freg = ["$f30","$fs6"],
106+
f31: freg = ["$f31","$fs7"],
107+
#error = ["$r0","$zero"] =>
108+
"constant zero cannot be used as an operand for inline asm",
109+
#error = ["$r2","$tp"] =>
110+
"reserved for TLS",
111+
#error = ["$r3","$sp"] =>
112+
"the stack pointer cannot be used as an operand for inline asm",
113+
#error = ["$r21"] =>
114+
"reserved by the ABI",
115+
#error = ["$r22","$fp"] =>
116+
"the frame pointer cannot be used as an operand for inline asm",
117+
#error = ["$r31","$s8"] =>
118+
"$r31 is used internally by LLVM and cannot be used as an operand for inline asm",
119+
}
120+
}
121+
122+
impl LoongArchInlineAsmReg {
123+
pub fn emit(
124+
self,
125+
out: &mut dyn fmt::Write,
126+
_arch: InlineAsmArch,
127+
_modifier: Option<char>,
128+
) -> fmt::Result {
129+
out.write_str(self.name())
130+
}
131+
}

Diff for: compiler/rustc_target/src/asm/mod.rs

+26
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ mod arm;
168168
mod avr;
169169
mod bpf;
170170
mod hexagon;
171+
mod loongarch;
171172
mod m68k;
172173
mod mips;
173174
mod msp430;
@@ -184,6 +185,7 @@ pub use arm::{ArmInlineAsmReg, ArmInlineAsmRegClass};
184185
pub use avr::{AvrInlineAsmReg, AvrInlineAsmRegClass};
185186
pub use bpf::{BpfInlineAsmReg, BpfInlineAsmRegClass};
186187
pub use hexagon::{HexagonInlineAsmReg, HexagonInlineAsmRegClass};
188+
pub use loongarch::{LoongArchInlineAsmReg, LoongArchInlineAsmRegClass};
187189
pub use m68k::{M68kInlineAsmReg, M68kInlineAsmRegClass};
188190
pub use mips::{MipsInlineAsmReg, MipsInlineAsmRegClass};
189191
pub use msp430::{Msp430InlineAsmReg, Msp430InlineAsmRegClass};
@@ -205,6 +207,7 @@ pub enum InlineAsmArch {
205207
RiscV64,
206208
Nvptx64,
207209
Hexagon,
210+
LoongArch64,
208211
Mips,
209212
Mips64,
210213
PowerPC,
@@ -234,6 +237,7 @@ impl FromStr for InlineAsmArch {
234237
"powerpc" => Ok(Self::PowerPC),
235238
"powerpc64" => Ok(Self::PowerPC64),
236239
"hexagon" => Ok(Self::Hexagon),
240+
"loongarch64" => Ok(Self::LoongArch64),
237241
"mips" => Ok(Self::Mips),
238242
"mips64" => Ok(Self::Mips64),
239243
"s390x" => Ok(Self::S390x),
@@ -259,6 +263,7 @@ pub enum InlineAsmReg {
259263
Nvptx(NvptxInlineAsmReg),
260264
PowerPC(PowerPCInlineAsmReg),
261265
Hexagon(HexagonInlineAsmReg),
266+
LoongArch(LoongArchInlineAsmReg),
262267
Mips(MipsInlineAsmReg),
263268
S390x(S390xInlineAsmReg),
264269
SpirV(SpirVInlineAsmReg),
@@ -280,6 +285,7 @@ impl InlineAsmReg {
280285
Self::RiscV(r) => r.name(),
281286
Self::PowerPC(r) => r.name(),
282287
Self::Hexagon(r) => r.name(),
288+
Self::LoongArch(r) => r.name(),
283289
Self::Mips(r) => r.name(),
284290
Self::S390x(r) => r.name(),
285291
Self::Bpf(r) => r.name(),
@@ -298,6 +304,7 @@ impl InlineAsmReg {
298304
Self::RiscV(r) => InlineAsmRegClass::RiscV(r.reg_class()),
299305
Self::PowerPC(r) => InlineAsmRegClass::PowerPC(r.reg_class()),
300306
Self::Hexagon(r) => InlineAsmRegClass::Hexagon(r.reg_class()),
307+
Self::LoongArch(r) => InlineAsmRegClass::LoongArch(r.reg_class()),
301308
Self::Mips(r) => InlineAsmRegClass::Mips(r.reg_class()),
302309
Self::S390x(r) => InlineAsmRegClass::S390x(r.reg_class()),
303310
Self::Bpf(r) => InlineAsmRegClass::Bpf(r.reg_class()),
@@ -324,6 +331,7 @@ impl InlineAsmReg {
324331
Self::PowerPC(PowerPCInlineAsmReg::parse(name)?)
325332
}
326333
InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmReg::parse(name)?),
334+
InlineAsmArch::LoongArch64 => Self::LoongArch(LoongArchInlineAsmReg::parse(name)?),
327335
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
328336
Self::Mips(MipsInlineAsmReg::parse(name)?)
329337
}
@@ -354,6 +362,9 @@ impl InlineAsmReg {
354362
Self::RiscV(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
355363
Self::PowerPC(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
356364
Self::Hexagon(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
365+
Self::LoongArch(r) => {
366+
r.validate(arch, reloc_model, target_features, target, is_clobber)
367+
}
357368
Self::Mips(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
358369
Self::S390x(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
359370
Self::Bpf(r) => r.validate(arch, reloc_model, target_features, target, is_clobber),
@@ -379,6 +390,7 @@ impl InlineAsmReg {
379390
Self::RiscV(r) => r.emit(out, arch, modifier),
380391
Self::PowerPC(r) => r.emit(out, arch, modifier),
381392
Self::Hexagon(r) => r.emit(out, arch, modifier),
393+
Self::LoongArch(r) => r.emit(out, arch, modifier),
382394
Self::Mips(r) => r.emit(out, arch, modifier),
383395
Self::S390x(r) => r.emit(out, arch, modifier),
384396
Self::Bpf(r) => r.emit(out, arch, modifier),
@@ -397,6 +409,7 @@ impl InlineAsmReg {
397409
Self::RiscV(_) => cb(self),
398410
Self::PowerPC(r) => r.overlapping_regs(|r| cb(Self::PowerPC(r))),
399411
Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))),
412+
Self::LoongArch(_) => cb(self),
400413
Self::Mips(_) => cb(self),
401414
Self::S390x(_) => cb(self),
402415
Self::Bpf(r) => r.overlapping_regs(|r| cb(Self::Bpf(r))),
@@ -418,6 +431,7 @@ pub enum InlineAsmRegClass {
418431
Nvptx(NvptxInlineAsmRegClass),
419432
PowerPC(PowerPCInlineAsmRegClass),
420433
Hexagon(HexagonInlineAsmRegClass),
434+
LoongArch(LoongArchInlineAsmRegClass),
421435
Mips(MipsInlineAsmRegClass),
422436
S390x(S390xInlineAsmRegClass),
423437
SpirV(SpirVInlineAsmRegClass),
@@ -440,6 +454,7 @@ impl InlineAsmRegClass {
440454
Self::Nvptx(r) => r.name(),
441455
Self::PowerPC(r) => r.name(),
442456
Self::Hexagon(r) => r.name(),
457+
Self::LoongArch(r) => r.name(),
443458
Self::Mips(r) => r.name(),
444459
Self::S390x(r) => r.name(),
445460
Self::SpirV(r) => r.name(),
@@ -464,6 +479,7 @@ impl InlineAsmRegClass {
464479
Self::Nvptx(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Nvptx),
465480
Self::PowerPC(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::PowerPC),
466481
Self::Hexagon(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Hexagon),
482+
Self::LoongArch(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::LoongArch),
467483
Self::Mips(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Mips),
468484
Self::S390x(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::S390x),
469485
Self::SpirV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::SpirV),
@@ -495,6 +511,7 @@ impl InlineAsmRegClass {
495511
Self::Nvptx(r) => r.suggest_modifier(arch, ty),
496512
Self::PowerPC(r) => r.suggest_modifier(arch, ty),
497513
Self::Hexagon(r) => r.suggest_modifier(arch, ty),
514+
Self::LoongArch(r) => r.suggest_modifier(arch, ty),
498515
Self::Mips(r) => r.suggest_modifier(arch, ty),
499516
Self::S390x(r) => r.suggest_modifier(arch, ty),
500517
Self::SpirV(r) => r.suggest_modifier(arch, ty),
@@ -522,6 +539,7 @@ impl InlineAsmRegClass {
522539
Self::Nvptx(r) => r.default_modifier(arch),
523540
Self::PowerPC(r) => r.default_modifier(arch),
524541
Self::Hexagon(r) => r.default_modifier(arch),
542+
Self::LoongArch(r) => r.default_modifier(arch),
525543
Self::Mips(r) => r.default_modifier(arch),
526544
Self::S390x(r) => r.default_modifier(arch),
527545
Self::SpirV(r) => r.default_modifier(arch),
@@ -548,6 +566,7 @@ impl InlineAsmRegClass {
548566
Self::Nvptx(r) => r.supported_types(arch),
549567
Self::PowerPC(r) => r.supported_types(arch),
550568
Self::Hexagon(r) => r.supported_types(arch),
569+
Self::LoongArch(r) => r.supported_types(arch),
551570
Self::Mips(r) => r.supported_types(arch),
552571
Self::S390x(r) => r.supported_types(arch),
553572
Self::SpirV(r) => r.supported_types(arch),
@@ -575,6 +594,7 @@ impl InlineAsmRegClass {
575594
Self::PowerPC(PowerPCInlineAsmRegClass::parse(name)?)
576595
}
577596
InlineAsmArch::Hexagon => Self::Hexagon(HexagonInlineAsmRegClass::parse(name)?),
597+
InlineAsmArch::LoongArch64 => Self::LoongArch(LoongArchInlineAsmRegClass::parse(name)?),
578598
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
579599
Self::Mips(MipsInlineAsmRegClass::parse(name)?)
580600
}
@@ -601,6 +621,7 @@ impl InlineAsmRegClass {
601621
Self::Nvptx(r) => r.valid_modifiers(arch),
602622
Self::PowerPC(r) => r.valid_modifiers(arch),
603623
Self::Hexagon(r) => r.valid_modifiers(arch),
624+
Self::LoongArch(r) => r.valid_modifiers(arch),
604625
Self::Mips(r) => r.valid_modifiers(arch),
605626
Self::S390x(r) => r.valid_modifiers(arch),
606627
Self::SpirV(r) => r.valid_modifiers(arch),
@@ -760,6 +781,11 @@ pub fn allocatable_registers(
760781
hexagon::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
761782
map
762783
}
784+
InlineAsmArch::LoongArch64 => {
785+
let mut map = loongarch::regclass_map();
786+
loongarch::fill_reg_map(arch, reloc_model, target_features, target, &mut map);
787+
map
788+
}
763789
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
764790
let mut map = mips::regclass_map();
765791
mips::fill_reg_map(arch, reloc_model, target_features, target, &mut map);

0 commit comments

Comments
 (0)