@@ -64,6 +64,7 @@ impl AArch64InlineAsmRegClass {
64
64
neon: I8 , I16 , I32 , I64 , F16 , F32 , F64 , F128 ,
65
65
VecI8 ( 8 ) , VecI16 ( 4 ) , VecI32 ( 2 ) , VecI64 ( 1 ) , VecF16 ( 4 ) , VecF32 ( 2 ) , VecF64 ( 1 ) ,
66
66
VecI8 ( 16 ) , VecI16 ( 8 ) , VecI32 ( 4 ) , VecI64 ( 2 ) , VecF16 ( 8 ) , VecF32 ( 4 ) , VecF64 ( 2 ) ;
67
+ // Note: When adding support for SVE vector types, they must be rejected for Arm64EC.
67
68
} ,
68
69
Self :: preg => & [ ] ,
69
70
}
@@ -96,7 +97,7 @@ fn restricted_for_arm64ec(
96
97
_is_clobber : bool ,
97
98
) -> Result < ( ) , & ' static str > {
98
99
if arch == InlineAsmArch :: Arm64EC {
99
- Err ( "x13, x14, x23, x24, x28, v16-v31 cannot be used for Arm64EC" )
100
+ Err ( "x13, x14, x23, x24, x28, v16-v31, p*, ffr cannot be used for Arm64EC" )
100
101
} else {
101
102
Ok ( ( ) )
102
103
}
@@ -165,23 +166,23 @@ def_regs! {
165
166
v29: vreg = [ "v29" , "b29" , "h29" , "s29" , "d29" , "q29" , "z29" ] % restricted_for_arm64ec,
166
167
v30: vreg = [ "v30" , "b30" , "h30" , "s30" , "d30" , "q30" , "z30" ] % restricted_for_arm64ec,
167
168
v31: vreg = [ "v31" , "b31" , "h31" , "s31" , "d31" , "q31" , "z31" ] % restricted_for_arm64ec,
168
- p0: preg = [ "p0" ] ,
169
- p1: preg = [ "p1" ] ,
170
- p2: preg = [ "p2" ] ,
171
- p3: preg = [ "p3" ] ,
172
- p4: preg = [ "p4" ] ,
173
- p5: preg = [ "p5" ] ,
174
- p6: preg = [ "p6" ] ,
175
- p7: preg = [ "p7" ] ,
176
- p8: preg = [ "p8" ] ,
177
- p9: preg = [ "p9" ] ,
178
- p10: preg = [ "p10" ] ,
179
- p11: preg = [ "p11" ] ,
180
- p12: preg = [ "p12" ] ,
181
- p13: preg = [ "p13" ] ,
182
- p14: preg = [ "p14" ] ,
183
- p15: preg = [ "p15" ] ,
184
- ffr: preg = [ "ffr" ] ,
169
+ p0: preg = [ "p0" ] % restricted_for_arm64ec ,
170
+ p1: preg = [ "p1" ] % restricted_for_arm64ec ,
171
+ p2: preg = [ "p2" ] % restricted_for_arm64ec ,
172
+ p3: preg = [ "p3" ] % restricted_for_arm64ec ,
173
+ p4: preg = [ "p4" ] % restricted_for_arm64ec ,
174
+ p5: preg = [ "p5" ] % restricted_for_arm64ec ,
175
+ p6: preg = [ "p6" ] % restricted_for_arm64ec ,
176
+ p7: preg = [ "p7" ] % restricted_for_arm64ec ,
177
+ p8: preg = [ "p8" ] % restricted_for_arm64ec ,
178
+ p9: preg = [ "p9" ] % restricted_for_arm64ec ,
179
+ p10: preg = [ "p10" ] % restricted_for_arm64ec ,
180
+ p11: preg = [ "p11" ] % restricted_for_arm64ec ,
181
+ p12: preg = [ "p12" ] % restricted_for_arm64ec ,
182
+ p13: preg = [ "p13" ] % restricted_for_arm64ec ,
183
+ p14: preg = [ "p14" ] % restricted_for_arm64ec ,
184
+ p15: preg = [ "p15" ] % restricted_for_arm64ec ,
185
+ ffr: preg = [ "ffr" ] % restricted_for_arm64ec ,
185
186
#error = [ "x19" , "w19" ] =>
186
187
"x19 is used internally by LLVM and cannot be used as an operand for inline asm" ,
187
188
#error = [ "x29" , "w29" , "fp" , "wfp" ] =>
@@ -200,12 +201,66 @@ impl AArch64InlineAsmReg {
200
201
_arch : InlineAsmArch ,
201
202
modifier : Option < char > ,
202
203
) -> fmt:: Result {
203
- let ( prefix, index) = if ( self as u32 ) < Self :: v0 as u32 {
204
- ( modifier. unwrap_or ( 'x' ) , self as u32 - Self :: x0 as u32 )
204
+ let ( prefix, index) = if let Some ( index) = self . reg_index ( ) {
205
+ ( modifier. unwrap_or ( 'x' ) , index)
206
+ } else if let Some ( index) = self . vreg_index ( ) {
207
+ ( modifier. unwrap_or ( 'v' ) , index)
205
208
} else {
206
- ( modifier . unwrap_or ( 'v' ) , self as u32 - Self :: v0 as u32 )
209
+ return out . write_str ( self . name ( ) ) ;
207
210
} ;
208
211
assert ! ( index < 32 ) ;
209
212
write ! ( out, "{prefix}{index}" )
210
213
}
214
+
215
+ /// If the register is an integer register then return its index.
216
+ pub fn reg_index ( self ) -> Option < u32 > {
217
+ // Unlike `vreg_index`, we can't subtract `x0` to get the u32 because
218
+ // `x19` and `x29` are missing and the integer constants for the
219
+ // `x0`..`x30` enum variants don't all match the register number. E.g. the
220
+ // integer constant for `x18` is 18, but the constant for `x20` is 19.
221
+ use AArch64InlineAsmReg :: * ;
222
+ Some ( match self {
223
+ x0 => 0 ,
224
+ x1 => 1 ,
225
+ x2 => 2 ,
226
+ x3 => 3 ,
227
+ x4 => 4 ,
228
+ x5 => 5 ,
229
+ x6 => 6 ,
230
+ x7 => 7 ,
231
+ x8 => 8 ,
232
+ x9 => 9 ,
233
+ x10 => 10 ,
234
+ x11 => 11 ,
235
+ x12 => 12 ,
236
+ x13 => 13 ,
237
+ x14 => 14 ,
238
+ x15 => 15 ,
239
+ x16 => 16 ,
240
+ x17 => 17 ,
241
+ x18 => 18 ,
242
+ // x19 is reserved
243
+ x20 => 20 ,
244
+ x21 => 21 ,
245
+ x22 => 22 ,
246
+ x23 => 23 ,
247
+ x24 => 24 ,
248
+ x25 => 25 ,
249
+ x26 => 26 ,
250
+ x27 => 27 ,
251
+ x28 => 28 ,
252
+ // x29 is reserved
253
+ x30 => 30 ,
254
+ _ => return None ,
255
+ } )
256
+ }
257
+
258
+ /// If the register is a vector register then return its index.
259
+ pub fn vreg_index ( self ) -> Option < u32 > {
260
+ use AArch64InlineAsmReg :: * ;
261
+ if self as u32 >= v0 as u32 && self as u32 <= v31 as u32 {
262
+ return Some ( self as u32 - v0 as u32 ) ;
263
+ }
264
+ None
265
+ }
211
266
}
0 commit comments