]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_target/src/asm/aarch64.rs
New upstream version 1.60.0+dfsg1
[rustc.git] / compiler / rustc_target / src / asm / aarch64.rs
CommitLineData
f9f354fc 1use super::{InlineAsmArch, InlineAsmType};
a2a8927a 2use crate::spec::Target;
5099ac24 3use rustc_data_structures::stable_set::FxHashSet;
f9f354fc 4use rustc_macros::HashStable_Generic;
5099ac24 5use rustc_span::Symbol;
f9f354fc
XL
6use std::fmt;
7
8def_reg_class! {
9 AArch64 AArch64InlineAsmRegClass {
10 reg,
11 vreg,
12 vreg_low16,
136023e0 13 preg,
f9f354fc
XL
14 }
15}
16
17impl AArch64InlineAsmRegClass {
18 pub fn valid_modifiers(self, _arch: super::InlineAsmArch) -> &'static [char] {
19 match self {
20 Self::reg => &['w', 'x'],
21 Self::vreg | Self::vreg_low16 => &['b', 'h', 's', 'd', 'q', 'v'],
136023e0 22 Self::preg => &[],
f9f354fc
XL
23 }
24 }
25
26 pub fn suggest_class(self, _arch: InlineAsmArch, _ty: InlineAsmType) -> Option<Self> {
27 None
28 }
29
30 pub fn suggest_modifier(
31 self,
32 _arch: InlineAsmArch,
33 ty: InlineAsmType,
34 ) -> Option<(char, &'static str)> {
35 match self {
36 Self::reg => match ty.size().bits() {
37 64 => None,
38 _ => Some(('w', "w0")),
39 },
40 Self::vreg | Self::vreg_low16 => match ty.size().bits() {
41 8 => Some(('b', "b0")),
42 16 => Some(('h', "h0")),
43 32 => Some(('s', "s0")),
44 64 => Some(('d', "d0")),
45 128 => Some(('q', "q0")),
46 _ => None,
47 },
136023e0 48 Self::preg => None,
f9f354fc
XL
49 }
50 }
51
52 pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
53 match self {
54 Self::reg => Some(('x', "x0")),
55 Self::vreg | Self::vreg_low16 => Some(('v', "v0")),
136023e0 56 Self::preg => None,
f9f354fc
XL
57 }
58 }
59
60 pub fn supported_types(
61 self,
62 _arch: InlineAsmArch,
5099ac24 63 ) -> &'static [(InlineAsmType, Option<Symbol>)] {
f9f354fc
XL
64 match self {
65 Self::reg => types! { _: I8, I16, I32, I64, F32, F64; },
66 Self::vreg | Self::vreg_low16 => types! {
5099ac24 67 fp: I8, I16, I32, I64, F32, F64,
f9f354fc
XL
68 VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2), VecF64(1),
69 VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2);
70 },
136023e0 71 Self::preg => &[],
f9f354fc
XL
72 }
73 }
74}
75
a2a8927a
XL
76pub fn reserved_x18(
77 _arch: InlineAsmArch,
5099ac24 78 _target_features: &FxHashSet<Symbol>,
a2a8927a 79 target: &Target,
5099ac24 80 _is_clobber: bool,
a2a8927a
XL
81) -> Result<(), &'static str> {
82 if target.os == "android"
83 || target.is_like_fuchsia
84 || target.is_like_osx
85 || target.is_like_windows
86 {
87 Err("x18 is a reserved register on this target")
88 } else {
89 Ok(())
90 }
91}
92
f9f354fc
XL
93def_regs! {
94 AArch64 AArch64InlineAsmReg AArch64InlineAsmRegClass {
95 x0: reg = ["x0", "w0"],
96 x1: reg = ["x1", "w1"],
97 x2: reg = ["x2", "w2"],
98 x3: reg = ["x3", "w3"],
99 x4: reg = ["x4", "w4"],
100 x5: reg = ["x5", "w5"],
101 x6: reg = ["x6", "w6"],
102 x7: reg = ["x7", "w7"],
103 x8: reg = ["x8", "w8"],
104 x9: reg = ["x9", "w9"],
105 x10: reg = ["x10", "w10"],
106 x11: reg = ["x11", "w11"],
107 x12: reg = ["x12", "w12"],
108 x13: reg = ["x13", "w13"],
109 x14: reg = ["x14", "w14"],
110 x15: reg = ["x15", "w15"],
111 x16: reg = ["x16", "w16"],
112 x17: reg = ["x17", "w17"],
a2a8927a 113 x18: reg = ["x18", "w18"] % reserved_x18,
f9f354fc
XL
114 x20: reg = ["x20", "w20"],
115 x21: reg = ["x21", "w21"],
116 x22: reg = ["x22", "w22"],
117 x23: reg = ["x23", "w23"],
118 x24: reg = ["x24", "w24"],
119 x25: reg = ["x25", "w25"],
120 x26: reg = ["x26", "w26"],
121 x27: reg = ["x27", "w27"],
122 x28: reg = ["x28", "w28"],
17df50a5 123 x30: reg = ["x30", "w30", "lr", "wlr"],
136023e0
XL
124 v0: vreg, vreg_low16 = ["v0", "b0", "h0", "s0", "d0", "q0", "z0"],
125 v1: vreg, vreg_low16 = ["v1", "b1", "h1", "s1", "d1", "q1", "z1"],
126 v2: vreg, vreg_low16 = ["v2", "b2", "h2", "s2", "d2", "q2", "z2"],
127 v3: vreg, vreg_low16 = ["v3", "b3", "h3", "s3", "d3", "q3", "z3"],
128 v4: vreg, vreg_low16 = ["v4", "b4", "h4", "s4", "d4", "q4", "z4"],
129 v5: vreg, vreg_low16 = ["v5", "b5", "h5", "s5", "d5", "q5", "z5"],
130 v6: vreg, vreg_low16 = ["v6", "b6", "h6", "s6", "d6", "q6", "z6"],
131 v7: vreg, vreg_low16 = ["v7", "b7", "h7", "s7", "d7", "q7", "z7"],
132 v8: vreg, vreg_low16 = ["v8", "b8", "h8", "s8", "d8", "q8", "z8"],
133 v9: vreg, vreg_low16 = ["v9", "b9", "h9", "s9", "d9", "q9", "z9"],
134 v10: vreg, vreg_low16 = ["v10", "b10", "h10", "s10", "d10", "q10", "z10"],
135 v11: vreg, vreg_low16 = ["v11", "b11", "h11", "s11", "d11", "q11", "z11"],
136 v12: vreg, vreg_low16 = ["v12", "b12", "h12", "s12", "d12", "q12", "z12"],
137 v13: vreg, vreg_low16 = ["v13", "b13", "h13", "s13", "d13", "q13", "z13"],
138 v14: vreg, vreg_low16 = ["v14", "b14", "h14", "s14", "d14", "q14", "z14"],
139 v15: vreg, vreg_low16 = ["v15", "b15", "h15", "s15", "d15", "q15", "z15"],
140 v16: vreg = ["v16", "b16", "h16", "s16", "d16", "q16", "z16"],
141 v17: vreg = ["v17", "b17", "h17", "s17", "d17", "q17", "z17"],
142 v18: vreg = ["v18", "b18", "h18", "s18", "d18", "q18", "z18"],
143 v19: vreg = ["v19", "b19", "h19", "s19", "d19", "q19", "z19"],
144 v20: vreg = ["v20", "b20", "h20", "s20", "d20", "q20", "z20"],
145 v21: vreg = ["v21", "b21", "h21", "s21", "d21", "q21", "z21"],
146 v22: vreg = ["v22", "b22", "h22", "s22", "d22", "q22", "z22"],
147 v23: vreg = ["v23", "b23", "h23", "s23", "d23", "q23", "z23"],
148 v24: vreg = ["v24", "b24", "h24", "s24", "d24", "q24", "z24"],
149 v25: vreg = ["v25", "b25", "h25", "s25", "d25", "q25", "z25"],
150 v26: vreg = ["v26", "b26", "h26", "s26", "d26", "q26", "z26"],
151 v27: vreg = ["v27", "b27", "h27", "s27", "d27", "q27", "z27"],
152 v28: vreg = ["v28", "b28", "h28", "s28", "d28", "q28", "z28"],
153 v29: vreg = ["v29", "b29", "h29", "s29", "d29", "q29", "z29"],
154 v30: vreg = ["v30", "b30", "h30", "s30", "d30", "q30", "z30"],
155 v31: vreg = ["v31", "b31", "h31", "s31", "d31", "q31", "z31"],
156 p0: preg = ["p0"],
157 p1: preg = ["p1"],
158 p2: preg = ["p2"],
159 p3: preg = ["p3"],
160 p4: preg = ["p4"],
161 p5: preg = ["p5"],
162 p6: preg = ["p6"],
163 p7: preg = ["p7"],
164 p8: preg = ["p8"],
165 p9: preg = ["p9"],
166 p10: preg = ["p10"],
167 p11: preg = ["p11"],
168 p12: preg = ["p12"],
169 p13: preg = ["p13"],
170 p14: preg = ["p14"],
171 p15: preg = ["p15"],
172 ffr: preg = ["ffr"],
17df50a5
XL
173 #error = ["x19", "w19"] =>
174 "x19 is used internally by LLVM and cannot be used as an operand for inline asm",
175 #error = ["x29", "w29", "fp", "wfp"] =>
f9f354fc
XL
176 "the frame pointer cannot be used as an operand for inline asm",
177 #error = ["sp", "wsp"] =>
178 "the stack pointer cannot be used as an operand for inline asm",
179 #error = ["xzr", "wzr"] =>
180 "the zero register cannot be used as an operand for inline asm",
181 }
182}
183
184impl AArch64InlineAsmReg {
185 pub fn emit(
186 self,
187 out: &mut dyn fmt::Write,
188 _arch: InlineAsmArch,
189 modifier: Option<char>,
190 ) -> fmt::Result {
191 let (prefix, index) = if (self as u32) < Self::v0 as u32 {
192 (modifier.unwrap_or('x'), self as u32 - Self::x0 as u32)
193 } else {
194 (modifier.unwrap_or('v'), self as u32 - Self::v0 as u32)
195 };
196 assert!(index < 32);
197 write!(out, "{}{}", prefix, index)
198 }
199}