]>
Commit | Line | Data |
---|---|---|
1 | use std::fmt; | |
2 | ||
3 | use rustc_span::Symbol; | |
4 | ||
5 | use super::{InlineAsmArch, InlineAsmType, ModifierInfo}; | |
6 | ||
7 | def_reg_class! { | |
8 | PowerPC PowerPCInlineAsmRegClass { | |
9 | reg, | |
10 | reg_nonzero, | |
11 | freg, | |
12 | cr, | |
13 | xer, | |
14 | } | |
15 | } | |
16 | ||
17 | impl PowerPCInlineAsmRegClass { | |
18 | pub fn valid_modifiers(self, _arch: super::InlineAsmArch) -> &'static [char] { | |
19 | &[] | |
20 | } | |
21 | ||
22 | pub fn suggest_class(self, _arch: InlineAsmArch, _ty: InlineAsmType) -> Option<Self> { | |
23 | None | |
24 | } | |
25 | ||
26 | pub fn suggest_modifier( | |
27 | self, | |
28 | _arch: InlineAsmArch, | |
29 | _ty: InlineAsmType, | |
30 | ) -> Option<ModifierInfo> { | |
31 | None | |
32 | } | |
33 | ||
34 | pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<ModifierInfo> { | |
35 | None | |
36 | } | |
37 | ||
38 | pub fn supported_types( | |
39 | self, | |
40 | arch: InlineAsmArch, | |
41 | ) -> &'static [(InlineAsmType, Option<Symbol>)] { | |
42 | match self { | |
43 | Self::reg | Self::reg_nonzero => { | |
44 | if arch == InlineAsmArch::PowerPC { | |
45 | types! { _: I8, I16, I32; } | |
46 | } else { | |
47 | types! { _: I8, I16, I32, I64; } | |
48 | } | |
49 | } | |
50 | Self::freg => types! { _: F32, F64; }, | |
51 | Self::cr | Self::xer => &[], | |
52 | } | |
53 | } | |
54 | } | |
55 | ||
56 | def_regs! { | |
57 | PowerPC PowerPCInlineAsmReg PowerPCInlineAsmRegClass { | |
58 | r0: reg = ["r0", "0"], | |
59 | r3: reg, reg_nonzero = ["r3", "3"], | |
60 | r4: reg, reg_nonzero = ["r4", "4"], | |
61 | r5: reg, reg_nonzero = ["r5", "5"], | |
62 | r6: reg, reg_nonzero = ["r6", "6"], | |
63 | r7: reg, reg_nonzero = ["r7", "7"], | |
64 | r8: reg, reg_nonzero = ["r8", "8"], | |
65 | r9: reg, reg_nonzero = ["r9", "9"], | |
66 | r10: reg, reg_nonzero = ["r10", "10"], | |
67 | r11: reg, reg_nonzero = ["r11", "11"], | |
68 | r12: reg, reg_nonzero = ["r12", "12"], | |
69 | r14: reg, reg_nonzero = ["r14", "14"], | |
70 | r15: reg, reg_nonzero = ["r15", "15"], | |
71 | r16: reg, reg_nonzero = ["r16", "16"], | |
72 | r17: reg, reg_nonzero = ["r17", "17"], | |
73 | r18: reg, reg_nonzero = ["r18", "18"], | |
74 | r19: reg, reg_nonzero = ["r19", "19"], | |
75 | r20: reg, reg_nonzero = ["r20", "20"], | |
76 | r21: reg, reg_nonzero = ["r21", "21"], | |
77 | r22: reg, reg_nonzero = ["r22", "22"], | |
78 | r23: reg, reg_nonzero = ["r23", "23"], | |
79 | r24: reg, reg_nonzero = ["r24", "24"], | |
80 | r25: reg, reg_nonzero = ["r25", "25"], | |
81 | r26: reg, reg_nonzero = ["r26", "26"], | |
82 | r27: reg, reg_nonzero = ["r27", "27"], | |
83 | r28: reg, reg_nonzero = ["r28", "28"], | |
84 | f0: freg = ["f0", "fr0"], | |
85 | f1: freg = ["f1", "fr1"], | |
86 | f2: freg = ["f2", "fr2"], | |
87 | f3: freg = ["f3", "fr3"], | |
88 | f4: freg = ["f4", "fr4"], | |
89 | f5: freg = ["f5", "fr5"], | |
90 | f6: freg = ["f6", "fr6"], | |
91 | f7: freg = ["f7", "fr7"], | |
92 | f8: freg = ["f8", "fr8"], | |
93 | f9: freg = ["f9", "fr9"], | |
94 | f10: freg = ["f10", "fr10"], | |
95 | f11: freg = ["f11", "fr11"], | |
96 | f12: freg = ["f12", "fr12"], | |
97 | f13: freg = ["f13", "fr13"], | |
98 | f14: freg = ["f14", "fr14"], | |
99 | f15: freg = ["f15", "fr15"], | |
100 | f16: freg = ["f16", "fr16"], | |
101 | f17: freg = ["f17", "fr17"], | |
102 | f18: freg = ["f18", "fr18"], | |
103 | f19: freg = ["f19", "fr19"], | |
104 | f20: freg = ["f20", "fr20"], | |
105 | f21: freg = ["f21", "fr21"], | |
106 | f22: freg = ["f22", "fr22"], | |
107 | f23: freg = ["f23", "fr23"], | |
108 | f24: freg = ["f24", "fr24"], | |
109 | f25: freg = ["f25", "fr25"], | |
110 | f26: freg = ["f26", "fr26"], | |
111 | f27: freg = ["f27", "fr27"], | |
112 | f28: freg = ["f28", "fr28"], | |
113 | f29: freg = ["f29", "fr29"], | |
114 | f30: freg = ["f30", "fr30"], | |
115 | f31: freg = ["f31", "fr31"], | |
116 | cr: cr = ["cr"], | |
117 | cr0: cr = ["cr0"], | |
118 | cr1: cr = ["cr1"], | |
119 | cr2: cr = ["cr2"], | |
120 | cr3: cr = ["cr3"], | |
121 | cr4: cr = ["cr4"], | |
122 | cr5: cr = ["cr5"], | |
123 | cr6: cr = ["cr6"], | |
124 | cr7: cr = ["cr7"], | |
125 | xer: xer = ["xer"], | |
126 | #error = ["r1", "1", "sp"] => | |
127 | "the stack pointer cannot be used as an operand for inline asm", | |
128 | #error = ["r2", "2"] => | |
129 | "r2 is a system reserved register and cannot be used as an operand for inline asm", | |
130 | #error = ["r13", "13"] => | |
131 | "r13 is a system reserved register and cannot be used as an operand for inline asm", | |
132 | #error = ["r29", "29"] => | |
133 | "r29 is used internally by LLVM and cannot be used as an operand for inline asm", | |
134 | #error = ["r30", "30"] => | |
135 | "r30 is used internally by LLVM and cannot be used as an operand for inline asm", | |
136 | #error = ["r31", "31", "fp"] => | |
137 | "the frame pointer cannot be used as an operand for inline asm", | |
138 | #error = ["lr"] => | |
139 | "the link register cannot be used as an operand for inline asm", | |
140 | #error = ["ctr"] => | |
141 | "the counter register cannot be used as an operand for inline asm", | |
142 | #error = ["vrsave"] => | |
143 | "the vrsave register cannot be used as an operand for inline asm", | |
144 | } | |
145 | } | |
146 | ||
147 | impl PowerPCInlineAsmReg { | |
148 | pub fn emit( | |
149 | self, | |
150 | out: &mut dyn fmt::Write, | |
151 | _arch: InlineAsmArch, | |
152 | _modifier: Option<char>, | |
153 | ) -> fmt::Result { | |
154 | macro_rules! do_emit { | |
155 | ( | |
156 | $($(($reg:ident, $value:literal)),*;)* | |
157 | ) => { | |
158 | out.write_str(match self { | |
159 | $($(Self::$reg => $value,)*)* | |
160 | }) | |
161 | }; | |
162 | } | |
163 | // Strip off the leading prefix. | |
164 | do_emit! { | |
165 | (r0, "0"), (r3, "3"), (r4, "4"), (r5, "5"), (r6, "6"), (r7, "7"); | |
166 | (r8, "8"), (r9, "9"), (r10, "10"), (r11, "11"), (r12, "12"), (r14, "14"), (r15, "15"); | |
167 | (r16, "16"), (r17, "17"), (r18, "18"), (r19, "19"), (r20, "20"), (r21, "21"), (r22, "22"), (r23, "23"); | |
168 | (r24, "24"), (r25, "25"), (r26, "26"), (r27, "27"), (r28, "28"); | |
169 | (f0, "0"), (f1, "1"), (f2, "2"), (f3, "3"), (f4, "4"), (f5, "5"), (f6, "6"), (f7, "7"); | |
170 | (f8, "8"), (f9, "9"), (f10, "10"), (f11, "11"), (f12, "12"), (f13, "13"), (f14, "14"), (f15, "15"); | |
171 | (f16, "16"), (f17, "17"), (f18, "18"), (f19, "19"), (f20, "20"), (f21, "21"), (f22, "22"), (f23, "23"); | |
172 | (f24, "24"), (f25, "25"), (f26, "26"), (f27, "27"), (f28, "28"), (f29, "29"), (f30, "30"), (f31, "31"); | |
173 | (cr, "cr"); | |
174 | (cr0, "0"), (cr1, "1"), (cr2, "2"), (cr3, "3"), (cr4, "4"), (cr5, "5"), (cr6, "6"), (cr7, "7"); | |
175 | (xer, "xer"); | |
176 | } | |
177 | } | |
178 | ||
179 | pub fn overlapping_regs(self, mut cb: impl FnMut(PowerPCInlineAsmReg)) { | |
180 | macro_rules! reg_conflicts { | |
181 | ( | |
182 | $( | |
183 | $full:ident : $($field:ident)* | |
184 | ),*; | |
185 | ) => { | |
186 | match self { | |
187 | $( | |
188 | Self::$full => { | |
189 | cb(Self::$full); | |
190 | $(cb(Self::$field);)* | |
191 | } | |
192 | $(Self::$field)|* => { | |
193 | cb(Self::$full); | |
194 | cb(self); | |
195 | } | |
196 | )* | |
197 | r => cb(r), | |
198 | } | |
199 | }; | |
200 | } | |
201 | reg_conflicts! { | |
202 | cr : cr0 cr1 cr2 cr3 cr4 cr5 cr6 cr7; | |
203 | } | |
204 | } | |
205 | } |