1use std::fmt;
2
3use rustc_span::Symbol;
4
5use super::{InlineAsmArch, InlineAsmType, ModifierInfo};
6
7def_reg_class! {
8 S390x S390xInlineAsmRegClass {
9 reg,
10 reg_addr,
11 freg,
12 vreg,
13 areg,
14 }
15}
16
17impl S390xInlineAsmRegClass {
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 allow_experimental_reg: bool,
42 ) -> &'static [(InlineAsmType, Option<Symbol>)] {
43 match self {
44 Self::reg | Self::reg_addr => types! { _: I8, I16, I32, I64; },
45 Self::freg => types! { _: F32, F64; },
46 Self::vreg => {
47 if allow_experimental_reg {
48 types! {
50 vector: I32, F32, I64, F64, I128, F128,
51 VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2);
52 }
53 } else {
54 &[]
55 }
56 }
57 Self::areg => &[],
58 }
59 }
60}
61
62def_regs! {
63 S390x S390xInlineAsmReg S390xInlineAsmRegClass {
64 r0: reg = ["r0"],
65 r1: reg, reg_addr = ["r1"],
66 r2: reg, reg_addr = ["r2"],
67 r3: reg, reg_addr = ["r3"],
68 r4: reg, reg_addr = ["r4"],
69 r5: reg, reg_addr = ["r5"],
70 r6: reg, reg_addr = ["r6"],
71 r7: reg, reg_addr = ["r7"],
72 r8: reg, reg_addr = ["r8"],
73 r9: reg, reg_addr = ["r9"],
74 r10: reg, reg_addr = ["r10"],
75 r12: reg, reg_addr = ["r12"],
76 r13: reg, reg_addr = ["r13"],
77 r14: reg, reg_addr = ["r14"],
78 f0: freg = ["f0"],
79 f1: freg = ["f1"],
80 f2: freg = ["f2"],
81 f3: freg = ["f3"],
82 f4: freg = ["f4"],
83 f5: freg = ["f5"],
84 f6: freg = ["f6"],
85 f7: freg = ["f7"],
86 f8: freg = ["f8"],
87 f9: freg = ["f9"],
88 f10: freg = ["f10"],
89 f11: freg = ["f11"],
90 f12: freg = ["f12"],
91 f13: freg = ["f13"],
92 f14: freg = ["f14"],
93 f15: freg = ["f15"],
94 v0: vreg = ["v0"],
95 v1: vreg = ["v1"],
96 v2: vreg = ["v2"],
97 v3: vreg = ["v3"],
98 v4: vreg = ["v4"],
99 v5: vreg = ["v5"],
100 v6: vreg = ["v6"],
101 v7: vreg = ["v7"],
102 v8: vreg = ["v8"],
103 v9: vreg = ["v9"],
104 v10: vreg = ["v10"],
105 v11: vreg = ["v11"],
106 v12: vreg = ["v12"],
107 v13: vreg = ["v13"],
108 v14: vreg = ["v14"],
109 v15: vreg = ["v15"],
110 v16: vreg = ["v16"],
111 v17: vreg = ["v17"],
112 v18: vreg = ["v18"],
113 v19: vreg = ["v19"],
114 v20: vreg = ["v20"],
115 v21: vreg = ["v21"],
116 v22: vreg = ["v22"],
117 v23: vreg = ["v23"],
118 v24: vreg = ["v24"],
119 v25: vreg = ["v25"],
120 v26: vreg = ["v26"],
121 v27: vreg = ["v27"],
122 v28: vreg = ["v28"],
123 v29: vreg = ["v29"],
124 v30: vreg = ["v30"],
125 v31: vreg = ["v31"],
126 a2: areg = ["a2"],
127 a3: areg = ["a3"],
128 a4: areg = ["a4"],
129 a5: areg = ["a5"],
130 a6: areg = ["a6"],
131 a7: areg = ["a7"],
132 a8: areg = ["a8"],
133 a9: areg = ["a9"],
134 a10: areg = ["a10"],
135 a11: areg = ["a11"],
136 a12: areg = ["a12"],
137 a13: areg = ["a13"],
138 a14: areg = ["a14"],
139 a15: areg = ["a15"],
140 #error = ["r11"] =>
141 "The frame pointer cannot be used as an operand for inline asm",
142 #error = ["r15"] =>
143 "The stack pointer cannot be used as an operand for inline asm",
144 #error = [
145 "c0", "c1", "c2", "c3",
146 "c4", "c5", "c6", "c7",
147 "c8", "c9", "c10", "c11",
148 "c12", "c13", "c14", "c15"
149 ] =>
150 "control registers are reserved by the kernel and cannot be used as operands for inline asm",
151 #error = ["a0", "a1"] =>
152 "a0 and a1 are reserved for system use and cannot be used as operands for inline asm",
153 }
154}
155
156impl S390xInlineAsmReg {
157 pub fn emit(
158 self,
159 out: &mut dyn fmt::Write,
160 _arch: InlineAsmArch,
161 _modifier: Option<char>,
162 ) -> fmt::Result {
163 write!(out, "%{}", self.name())
164 }
165
166 pub fn overlapping_regs(self, mut cb: impl FnMut(S390xInlineAsmReg)) {
167 macro_rules! reg_conflicts {
168 (
169 $(
170 $full:ident : $($field:ident)*
171 ),*;
172 ) => {
173 match self {
174 $(
175 Self::$full => {
176 cb(Self::$full);
177 $(cb(Self::$field);)*
178 }
179 $(Self::$field)|* => {
180 cb(Self::$full);
181 cb(self);
182 }
183 )*
184 r => cb(r),
185 }
186 };
187 }
188
189 reg_conflicts! {
191 v0 : f0,
192 v1 : f1,
193 v2 : f2,
194 v3 : f3,
195 v4 : f4,
196 v5 : f5,
197 v6 : f6,
198 v7 : f7,
199 v8 : f8,
200 v9 : f9,
201 v10 : f10,
202 v11 : f11,
203 v12 : f12,
204 v13 : f13,
205 v14 : f14,
206 v15 : f15;
207 }
208 }
209}