rustc_target/asm/
loongarch.rs

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