|
| 1 | +use super::{InlineAsmArch, InlineAsmType}; |
| 2 | +use rustc_macros::HashStable_Generic; |
| 3 | +use std::fmt; |
| 4 | + |
| 5 | +def_reg_class! { |
| 6 | + AArch64 AArch64InlineAsmRegClass { |
| 7 | + reg, |
| 8 | + vreg, |
| 9 | + vreg_low16, |
| 10 | + } |
| 11 | +} |
| 12 | + |
| 13 | +impl AArch64InlineAsmRegClass { |
| 14 | + pub fn valid_modifiers(self, _arch: super::InlineAsmArch) -> &'static [char] { |
| 15 | + match self { |
| 16 | + Self::reg => &['w', 'x'], |
| 17 | + Self::vreg | Self::vreg_low16 => &['b', 'h', 's', 'd', 'q', 'v'], |
| 18 | + } |
| 19 | + } |
| 20 | + |
| 21 | + pub fn suggest_modifier( |
| 22 | + self, |
| 23 | + _arch: InlineAsmArch, |
| 24 | + ty: InlineAsmType, |
| 25 | + ) -> Option<(char, &'static str, Option<&'static str>)> { |
| 26 | + match self { |
| 27 | + Self::reg => { |
| 28 | + if ty.size().bits() <= 32 { |
| 29 | + Some(('w', "w0", None)) |
| 30 | + } else { |
| 31 | + None |
| 32 | + } |
| 33 | + } |
| 34 | + Self::vreg | Self::vreg_low16 => match ty.size().bits() { |
| 35 | + 8 => Some(('b', "b0", None)), |
| 36 | + 16 => Some(('h', "h0", None)), |
| 37 | + 32 => Some(('s', "s0", None)), |
| 38 | + 64 => Some(('d', "d0", None)), |
| 39 | + 128 => Some(('q', "q0", None)), |
| 40 | + _ => None, |
| 41 | + }, |
| 42 | + } |
| 43 | + } |
| 44 | + |
| 45 | + pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> { |
| 46 | + match self { |
| 47 | + Self::reg => Some(('x', "x0")), |
| 48 | + Self::vreg | Self::vreg_low16 => Some(('v', "v0")), |
| 49 | + } |
| 50 | + } |
| 51 | + |
| 52 | + pub fn supported_types( |
| 53 | + self, |
| 54 | + _arch: InlineAsmArch, |
| 55 | + ) -> &'static [(InlineAsmType, Option<&'static str>)] { |
| 56 | + match self { |
| 57 | + Self::reg => types! { _: I8, I16, I32, I64, F32, F64; }, |
| 58 | + Self::vreg | Self::vreg_low16 => types! { |
| 59 | + "fp": I8, I16, I32, I64, F32, F64, |
| 60 | + VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2), VecF64(1), |
| 61 | + VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2); |
| 62 | + }, |
| 63 | + } |
| 64 | + } |
| 65 | +} |
| 66 | + |
| 67 | +def_regs! { |
| 68 | + AArch64 AArch64InlineAsmReg AArch64InlineAsmRegClass { |
| 69 | + x0: reg = ["x0", "w0"], |
| 70 | + x1: reg = ["x1", "w1"], |
| 71 | + x2: reg = ["x2", "w2"], |
| 72 | + x3: reg = ["x3", "w3"], |
| 73 | + x4: reg = ["x4", "w4"], |
| 74 | + x5: reg = ["x5", "w5"], |
| 75 | + x6: reg = ["x6", "w6"], |
| 76 | + x7: reg = ["x7", "w7"], |
| 77 | + x8: reg = ["x8", "w8"], |
| 78 | + x9: reg = ["x9", "w9"], |
| 79 | + x10: reg = ["x10", "w10"], |
| 80 | + x11: reg = ["x11", "w11"], |
| 81 | + x12: reg = ["x12", "w12"], |
| 82 | + x13: reg = ["x13", "w13"], |
| 83 | + x14: reg = ["x14", "w14"], |
| 84 | + x15: reg = ["x15", "w15"], |
| 85 | + x16: reg = ["x16", "w16"], |
| 86 | + x17: reg = ["x17", "w17"], |
| 87 | + x18: reg = ["x18", "w18"], |
| 88 | + x19: reg = ["x19", "w19"], |
| 89 | + x20: reg = ["x20", "w20"], |
| 90 | + x21: reg = ["x21", "w21"], |
| 91 | + x22: reg = ["x22", "w22"], |
| 92 | + x23: reg = ["x23", "w23"], |
| 93 | + x24: reg = ["x24", "w24"], |
| 94 | + x25: reg = ["x25", "w25"], |
| 95 | + x26: reg = ["x26", "w26"], |
| 96 | + x27: reg = ["x27", "w27"], |
| 97 | + x28: reg = ["x28", "w28"], |
| 98 | + x30: reg = ["x30", "w30", "lr"], |
| 99 | + v0: vreg, vreg_low16 = ["v0", "b0", "h0", "s0", "d0", "q0"], |
| 100 | + v1: vreg, vreg_low16 = ["v1", "b1", "h1", "s1", "d1", "q1"], |
| 101 | + v2: vreg, vreg_low16 = ["v2", "b2", "h2", "s2", "d2", "q2"], |
| 102 | + v3: vreg, vreg_low16 = ["v3", "b3", "h3", "s3", "d3", "q3"], |
| 103 | + v4: vreg, vreg_low16 = ["v4", "b4", "h4", "s4", "d4", "q4"], |
| 104 | + v5: vreg, vreg_low16 = ["v5", "b5", "h5", "s5", "d5", "q5"], |
| 105 | + v6: vreg, vreg_low16 = ["v6", "b6", "h6", "s6", "d6", "q6"], |
| 106 | + v7: vreg, vreg_low16 = ["v7", "b7", "h7", "s7", "d7", "q7"], |
| 107 | + v8: vreg, vreg_low16 = ["v8", "b8", "h8", "s8", "d8", "q8"], |
| 108 | + v9: vreg, vreg_low16 = ["v9", "b9", "h9", "s9", "d9", "q9"], |
| 109 | + v10: vreg, vreg_low16 = ["v10", "b10", "h10", "s10", "d10", "q10"], |
| 110 | + v11: vreg, vreg_low16 = ["v11", "b11", "h11", "s11", "d11", "q11"], |
| 111 | + v12: vreg, vreg_low16 = ["v12", "b12", "h12", "s12", "d12", "q12"], |
| 112 | + v13: vreg, vreg_low16 = ["v13", "b13", "h13", "s13", "d13", "q13"], |
| 113 | + v14: vreg, vreg_low16 = ["v14", "b14", "h14", "s14", "d14", "q14"], |
| 114 | + v15: vreg, vreg_low16 = ["v15", "b15", "h15", "s15", "d15", "q15"], |
| 115 | + v16: vreg = ["v16", "b16", "h16", "s16", "d16", "q16"], |
| 116 | + v17: vreg = ["v17", "b17", "h17", "s17", "d17", "q17"], |
| 117 | + v18: vreg = ["v18", "b18", "h18", "s18", "d18", "q18"], |
| 118 | + v19: vreg = ["v19", "b19", "h19", "s19", "d19", "q19"], |
| 119 | + v20: vreg = ["v20", "b20", "h20", "s20", "d20", "q20"], |
| 120 | + v21: vreg = ["v21", "b21", "h21", "s21", "d21", "q21"], |
| 121 | + v22: vreg = ["v22", "b22", "h22", "s22", "d22", "q22"], |
| 122 | + v23: vreg = ["v23", "b23", "h23", "s23", "d23", "q23"], |
| 123 | + v24: vreg = ["v24", "b24", "h24", "s24", "d24", "q24"], |
| 124 | + v25: vreg = ["v25", "b25", "h25", "s25", "d25", "q25"], |
| 125 | + v26: vreg = ["v26", "b26", "h26", "s26", "d26", "q26"], |
| 126 | + v27: vreg = ["v27", "b27", "h27", "s27", "d27", "q27"], |
| 127 | + v28: vreg = ["v28", "b28", "h28", "s28", "d28", "q28"], |
| 128 | + v29: vreg = ["v29", "b29", "h29", "s29", "d29", "q29"], |
| 129 | + v30: vreg = ["v30", "b30", "h30", "s30", "d30", "q30"], |
| 130 | + v31: vreg = ["v31", "b31", "h31", "s31", "d31", "q31"], |
| 131 | + "the frame pointer cannot be used as an operand for inline asm" = |
| 132 | + ["x29", "fp"], |
| 133 | + "the stack pointer cannot be used as an operand for inline asm" = |
| 134 | + ["sp", "wsp"], |
| 135 | + "the zero register cannot be used as an operand for inline asm" = |
| 136 | + ["xzr", "wzr"], |
| 137 | + } |
| 138 | +} |
| 139 | + |
| 140 | +impl AArch64InlineAsmReg { |
| 141 | + pub fn emit( |
| 142 | + self, |
| 143 | + out: &mut dyn fmt::Write, |
| 144 | + _arch: InlineAsmArch, |
| 145 | + modifier: Option<char>, |
| 146 | + ) -> fmt::Result { |
| 147 | + let (prefix, index) = if (self as u32) < Self::v0 as u32 { |
| 148 | + (modifier.unwrap_or('x'), self as u32 - Self::x0 as u32) |
| 149 | + } else { |
| 150 | + (modifier.unwrap_or('v'), self as u32 - Self::v0 as u32) |
| 151 | + }; |
| 152 | + assert!(index < 32); |
| 153 | + write!(out, "{}{}", prefix, index) |
| 154 | + } |
| 155 | +} |
0 commit comments