1use std::fmt;
2
3use rustc_data_structures::fx::FxIndexSet;
4use rustc_span::Symbol;
5
6use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
7use crate::spec::{RelocModel, Target};
8
9def_reg_class! {
10 Sparc SparcInlineAsmRegClass {
11 reg,
12 yreg,
13 }
14}
15
16impl SparcInlineAsmRegClass {
17 pub fn valid_modifiers(self, _arch: super::InlineAsmArch) -> &'static [char] {
18 &[]
19 }
20
21 pub fn suggest_class(self, _arch: InlineAsmArch, _ty: InlineAsmType) -> Option<Self> {
22 None
23 }
24
25 pub fn suggest_modifier(
26 self,
27 _arch: InlineAsmArch,
28 _ty: InlineAsmType,
29 ) -> Option<ModifierInfo> {
30 None
31 }
32
33 pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> {
34 None
35 }
36
37 pub fn supported_types(
38 self,
39 arch: InlineAsmArch,
40 ) -> &'static [(InlineAsmType, Option<Symbol>)] {
41 match self {
42 Self::reg => {
43 if arch == InlineAsmArch::Sparc {
44 types! {
45 _: I8, I16, I32;
46 }
50 } else {
51 types! { _: I8, I16, I32, I64; }
52 }
53 }
54 Self::yreg => &[],
55 }
56 }
57}
58
59fn reserved_g5(
60 arch: InlineAsmArch,
61 _reloc_model: RelocModel,
62 _target_features: &FxIndexSet<Symbol>,
63 _target: &Target,
64 _is_clobber: bool,
65) -> Result<(), &'static str> {
66 if arch == InlineAsmArch::Sparc {
67 Err("g5 is reserved for system on SPARC32")
73 } else {
74 Ok(())
75 }
76}
77
78def_regs! {
79 Sparc SparcInlineAsmReg SparcInlineAsmRegClass {
80 r2: reg = ["r2", "g2"], r3: reg = ["r3", "g3"], r4: reg = ["r4", "g4"], r5: reg = ["r5", "g5"] % reserved_g5,
89 r8: reg = ["r8", "o0"], r9: reg = ["r9", "o1"], r10: reg = ["r10", "o2"], r11: reg = ["r11", "o3"], r12: reg = ["r12", "o4"], r13: reg = ["r13", "o5"], r15: reg = ["r15", "o7"], r16: reg = ["r16", "l0"], r17: reg = ["r17", "l1"], r18: reg = ["r18", "l2"], r19: reg = ["r19", "l3"], r20: reg = ["r20", "l4"], r21: reg = ["r21", "l5"], r22: reg = ["r22", "l6"], r23: reg = ["r23", "l7"], r24: reg = ["r24", "i0"], r25: reg = ["r25", "i1"], r26: reg = ["r26", "i2"], r27: reg = ["r27", "i3"], r28: reg = ["r28", "i4"], r29: reg = ["r29", "i5"], y: yreg = ["y"],
111 #error = ["r0", "g0"] =>
112 "g0 is always zero and cannot be used as an operand for inline asm",
113 #error = ["r1", "g1"] =>
117 "reserved by LLVM and cannot be used as an operand for inline asm",
118 #error = ["r6", "g6", "r7", "g7"] =>
119 "reserved for system and cannot be used as an operand for inline asm",
120 #error = ["sp", "r14", "o6"] =>
121 "the stack pointer cannot be used as an operand for inline asm",
122 #error = ["fp", "r30", "i6"] =>
123 "the frame pointer cannot be used as an operand for inline asm",
124 #error = ["r31", "i7"] =>
125 "the return address register cannot be used as an operand for inline asm",
126 }
127}
128
129impl SparcInlineAsmReg {
130 pub fn emit(
131 self,
132 out: &mut dyn fmt::Write,
133 _arch: InlineAsmArch,
134 _modifier: Option<char>,
135 ) -> fmt::Result {
136 write!(out, "%{}", self.name())
137 }
138}