rustc_target/asm/
s390x.rs

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                    // non-clobber-only vector register support is unstable.
49                    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        // The left halves of v0-v15 are aliased to f0-f15.
190        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}