Skip to content

Commit 469479a

Browse files
authored
x64: use Rust types for assembler immediates (#10302)
Previously we used `AssemblerImm*` and `AssemblerSimm*` throughout the x64 ISLE to indicate the type of immediate an instruction would receive. Alex has noted previously that this is unnecessary; it does after all create more ties between the `cranelift-codegen` ISLE and `cranelift-assembler-x64` that could possibly break in the future. This change removes those ties by using Rust types in ISLE (e.g., `u8`, `i8`, `u16`, etc.) and converting to the expected assembler type in the ISLE glue layer.
1 parent 575e5a6 commit 469479a

File tree

4 files changed

+48
-139
lines changed

4 files changed

+48
-139
lines changed

cranelift/assembler-x64/meta/src/generate.rs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,23 +52,6 @@ pub fn isle_macro(f: &mut Formatter, insts: &[dsl::Inst]) {
5252
/// Generate the ISLE definitions that match the `isle_assembler_methods!` macro
5353
/// above.
5454
pub fn isle_definitions(f: &mut Formatter, insts: &[dsl::Inst]) {
55-
f.line("(type AssemblerImm8 extern (enum))", None);
56-
f.line("(type AssemblerSimm8 extern (enum))", None);
57-
f.line("(type AssemblerImm16 extern (enum))", None);
58-
f.line("(type AssemblerSimm16 extern (enum))", None);
59-
f.line("(type AssemblerImm32 extern (enum))", None);
60-
f.line("(type AssemblerSimm32 extern (enum))", None);
61-
f.line("(type AssemblerReadGpr extern (enum))", None);
62-
f.line("(type AssemblerReadWriteGpr extern (enum))", None);
63-
f.line("(type AssemblerReadGprMem extern (enum))", None);
64-
f.line("(type AssemblerReadWriteGprMem extern (enum))", None);
65-
f.line("(type AssemblerInst extern (enum))", None);
66-
f.line("(type AssemblerReadXmm extern (enum))", None);
67-
f.line("(type AssemblerReadWriteXmm extern (enum))", None);
68-
f.line("(type AssemblerReadXmmMem extern (enum))", None);
69-
f.line("(type AssemblerReadWriteXmmMem extern (enum))", None);
70-
f.empty_line();
71-
7255
f.line("(type AssemblerOutputs (enum", None);
7356
f.line(" ;; Used for instructions that have ISLE `SideEffect`s (memory stores, traps,", None);
7457
f.line(" ;; etc.) and do not return a `Value`.", None);

cranelift/assembler-x64/meta/src/generate/operand.rs

Lines changed: 28 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -26,45 +26,16 @@ impl dsl::Operand {
2626
}
2727
}
2828

29-
#[must_use]
30-
pub fn generate_mut_ty(&self, read_ty: &str, read_write_ty: &str) -> Option<String> {
31-
use dsl::Mutability::*;
32-
use dsl::OperandKind::*;
33-
let pick_ty = match self.mutability {
34-
Read => read_ty,
35-
ReadWrite => read_write_ty,
36-
};
37-
match self.location.kind() {
38-
FixedReg(_) => None,
39-
Imm(loc) => {
40-
let bits = loc.bits();
41-
if self.extension.is_sign_extended() {
42-
Some(format!("Simm{bits}"))
43-
} else {
44-
Some(format!("Imm{bits}"))
45-
}
46-
}
47-
Reg(r) => match r.bits() {
48-
128 => Some(format!("Xmm<{pick_ty}>")),
49-
_ => Some(format!("Gpr<{pick_ty}>")),
50-
},
51-
RegMem(rm) => match rm.bits() {
52-
128 => Some(format!("XmmMem<{pick_ty}, Gpr>")),
53-
_ => Some(format!("GprMem<{pick_ty}, {read_ty}>")),
54-
},
55-
}
56-
}
57-
58-
/// Returns the type of this operand in ISLE as part of the
59-
/// `IsleConstructorRaw` variants.
29+
/// Returns the type of this operand in ISLE as a part of the ISLE "raw"
30+
/// constructors.
6031
pub fn isle_param_raw(&self) -> String {
6132
match self.location.kind() {
6233
OperandKind::Imm(loc) => {
6334
let bits = loc.bits();
6435
if self.extension.is_sign_extended() {
65-
format!("AssemblerSimm{bits}")
36+
format!("i{bits}")
6637
} else {
67-
format!("AssemblerImm{bits}")
38+
format!("u{bits}")
6839
}
6940
}
7041
OperandKind::Reg(r) => match r.bits() {
@@ -104,9 +75,9 @@ impl dsl::Operand {
10475
OperandKind::Imm(loc) => {
10576
let bits = loc.bits();
10677
if self.extension.is_sign_extended() {
107-
format!("&cranelift_assembler_x64::Simm{bits}")
78+
format!("i{bits}")
10879
} else {
109-
format!("&cranelift_assembler_x64::Imm{bits}")
80+
format!("u{bits}")
11081
}
11182
}
11283
OperandKind::RegMem(rm) => match rm.bits() {
@@ -126,52 +97,33 @@ impl dsl::Operand {
12697
/// Effectively converts `self.rust_param_raw()` to the assembler type.
12798
pub fn rust_convert_isle_to_assembler(&self) -> Option<&'static str> {
12899
match self.location.kind() {
129-
OperandKind::Reg(r) => match r.bits() {
130-
128 => Some(match self.mutability {
131-
Mutability::Read => "cranelift_assembler_x64::Xmm::new",
132-
Mutability::ReadWrite => "self.convert_xmm_to_assembler_read_write_xmm",
133-
}),
134-
_ => Some(match self.mutability {
135-
Mutability::Read => "cranelift_assembler_x64::Gpr::new",
136-
Mutability::ReadWrite => "self.convert_gpr_to_assembler_read_write_gpr",
137-
}),
138-
},
139-
OperandKind::RegMem(rm) => match rm.bits() {
140-
128 => Some(match self.mutability {
141-
Mutability::Read => "self.convert_xmm_mem_to_assembler_read_xmm_mem",
142-
Mutability::ReadWrite => "self.convert_xmm_mem_to_assembler_read_write_xmm_mem",
143-
}),
144-
_ => Some(match self.mutability {
145-
Mutability::Read => "self.convert_gpr_mem_to_assembler_read_gpr_mem",
146-
Mutability::ReadWrite => "self.convert_gpr_mem_to_assembler_read_write_gpr_mem",
147-
}),
100+
OperandKind::Reg(r) => Some(match (r.bits(), self.mutability) {
101+
(128, Mutability::Read) => "cranelift_assembler_x64::Xmm::new",
102+
(128, Mutability::ReadWrite) => "self.convert_xmm_to_assembler_read_write_xmm",
103+
(_, Mutability::Read) => "cranelift_assembler_x64::Gpr::new",
104+
(_, Mutability::ReadWrite) => "self.convert_gpr_to_assembler_read_write_gpr",
105+
}),
106+
OperandKind::RegMem(r) => Some(match (r.bits(), self.mutability) {
107+
(128, Mutability::Read) => "self.convert_xmm_mem_to_assembler_read_xmm_mem",
108+
(128, Mutability::ReadWrite) => "self.convert_xmm_mem_to_assembler_read_write_xmm_mem",
109+
(_, Mutability::Read) => "self.convert_gpr_mem_to_assembler_read_gpr_mem",
110+
(_, Mutability::ReadWrite) => "self.convert_gpr_mem_to_assembler_read_write_gpr_mem",
111+
}),
112+
OperandKind::Imm(loc) => match (self.extension.is_sign_extended(), loc.bits()) {
113+
(true, 8) => Some("cranelift_assembler_x64::Simm8::new"),
114+
(true, 16) => Some("cranelift_assembler_x64::Simm16::new"),
115+
(true, 32) => Some("cranelift_assembler_x64::Simm32::new"),
116+
(false, 8) => Some("cranelift_assembler_x64::Imm8::new"),
117+
(false, 16) => Some("cranelift_assembler_x64::Imm16::new"),
118+
(false, 32) => Some("cranelift_assembler_x64::Imm32::new"),
119+
_ => None,
148120
},
149-
OperandKind::FixedReg(_) | OperandKind::Imm(_) => None,
121+
OperandKind::FixedReg(_) => None,
150122
}
151123
}
152124
}
153125

154126
impl dsl::Location {
155-
/// `<operand type>`, if the operand has a type (i.e., not fixed registers).
156-
#[must_use]
157-
pub fn generate_type(&self, generic: Option<String>) -> Option<String> {
158-
use dsl::Location::*;
159-
let generic = match generic {
160-
Some(ty) => format!("<{ty}>"),
161-
None => String::new(),
162-
};
163-
match self {
164-
al | ax | eax | rax | cl => None,
165-
imm8 => Some("Imm8".into()),
166-
imm16 => Some("Imm16".into()),
167-
imm32 => Some("Imm32".into()),
168-
r8 | r16 | r32 | r64 => Some(format!("Gpr{generic}")),
169-
rm8 | rm16 | rm32 | rm64 => Some(format!("GprMem{generic}")),
170-
xmm => Some(format!("Xmm{generic}")),
171-
rm128 => Some(format!("XmmMem{generic}")),
172-
}
173-
}
174-
175127
/// `self.<operand>.to_string(...)`
176128
#[must_use]
177129
pub fn generate_to_string(&self, extension: dsl::Extension) -> String {
@@ -200,7 +152,7 @@ impl dsl::Location {
200152

201153
/// `Size::<operand size>`
202154
#[must_use]
203-
pub fn generate_size(&self) -> Option<&str> {
155+
fn generate_size(&self) -> Option<&str> {
204156
use dsl::Location::*;
205157
match self {
206158
al | ax | eax | rax | cl | imm8 | imm16 | imm32 => None,

cranelift/codegen/src/isa/x64/inst.isle

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,8 @@
827827
;; An instruction assembled outside of cranelift-codegen.
828828
(External (inst AssemblerInst))))
829829

830+
(type AssemblerInst extern (enum))
831+
830832
(type OperandSize extern
831833
(enum Size8
832834
Size16
@@ -2946,17 +2948,17 @@
29462948
dst_lo)))
29472949

29482950
;; Helpers for matching operands, extracting them into their assembler types.
2949-
(decl is_imm8 (AssemblerImm8) GprMemImm)
2951+
(decl is_imm8 (u8) GprMemImm)
29502952
(extern extractor is_imm8 is_imm8)
2951-
(decl is_simm8 (AssemblerSimm8) GprMemImm)
2953+
(decl is_simm8 (i8) GprMemImm)
29522954
(extern extractor is_simm8 is_simm8)
2953-
(decl is_imm16 (AssemblerImm16) GprMemImm)
2955+
(decl is_imm16 (u16) GprMemImm)
29542956
(extern extractor is_imm16 is_imm16)
2955-
(decl is_simm16 (AssemblerSimm16) GprMemImm)
2957+
(decl is_simm16 (i16) GprMemImm)
29562958
(extern extractor is_simm16 is_simm16)
2957-
(decl is_imm32 (AssemblerImm32) GprMemImm)
2959+
(decl is_imm32 (u32) GprMemImm)
29582960
(extern extractor is_imm32 is_imm32)
2959-
(decl is_simm32 (AssemblerSimm32) GprMemImm)
2961+
(decl is_simm32 (i32) GprMemImm)
29602962
(extern extractor is_simm32 is_simm32)
29612963
(decl is_gpr (Gpr) GprMemImm)
29622964
(extern extractor is_gpr is_gpr)
@@ -2967,12 +2969,6 @@
29672969
(decl is_xmm (Xmm) XmmMem)
29682970
(extern extractor is_xmm is_xmm)
29692971

2970-
;; Helpers to auto-convert to and from assembler types.
2971-
2972-
(decl u8_to_assembler_imm8 (u8) AssemblerImm8)
2973-
(extern constructor u8_to_assembler_imm8 u8_to_assembler_imm8)
2974-
(convert u8 AssemblerImm8 u8_to_assembler_imm8)
2975-
29762972
;; Helper for emitting `and` instructions.
29772973
(decl x64_and (Type Gpr GprMemImm) Gpr)
29782974

cranelift/codegen/src/isa/x64/lower/isle.rs

Lines changed: 12 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,6 @@ type BoxSyntheticAmode = Box<SyntheticAmode>;
4242
/// When interacting with the external assembler (see `external.rs`), we
4343
/// need to fix the types we'll use.
4444
type AssemblerInst = asm::Inst<CraneliftRegisters>;
45-
type AssemblerImm8 = asm::Imm8;
46-
type AssemblerSimm8 = asm::Simm8;
47-
type AssemblerImm16 = asm::Imm16;
48-
type AssemblerSimm16 = asm::Simm16;
49-
type AssemblerImm32 = asm::Imm32;
50-
type AssemblerSimm32 = asm::Simm32;
5145

5246
pub struct SinkableLoad {
5347
inst: Inst,
@@ -958,56 +952,44 @@ impl Context for IsleContext<'_, '_, MInst, X64Backend> {
958952
///// External assembler methods.
959953
////////////////////////////////////////////////////////////////////////////
960954

961-
fn is_imm8(&mut self, src: &GprMemImm) -> Option<AssemblerImm8> {
955+
fn is_imm8(&mut self, src: &GprMemImm) -> Option<u8> {
962956
match src.clone().to_reg_mem_imm() {
963-
RegMemImm::Imm { simm32 } => {
964-
let imm = u8::try_from(simm32).ok()?;
965-
Some(AssemblerImm8::new(imm))
966-
}
957+
RegMemImm::Imm { simm32 } => Some(u8::try_from(simm32).ok()?),
967958
_ => None,
968959
}
969960
}
970961

971-
fn is_simm8(&mut self, src: &GprMemImm) -> Option<AssemblerSimm8> {
962+
fn is_simm8(&mut self, src: &GprMemImm) -> Option<i8> {
972963
match src.clone().to_reg_mem_imm() {
973-
RegMemImm::Imm { simm32 } => {
974-
let imm = i8::try_from(simm32).ok()?;
975-
Some(AssemblerSimm8::new(imm))
976-
}
964+
RegMemImm::Imm { simm32 } => Some(i8::try_from(simm32).ok()?),
977965
_ => None,
978966
}
979967
}
980968

981-
fn is_imm16(&mut self, src: &GprMemImm) -> Option<AssemblerImm16> {
969+
fn is_imm16(&mut self, src: &GprMemImm) -> Option<u16> {
982970
match src.clone().to_reg_mem_imm() {
983-
RegMemImm::Imm { simm32 } => {
984-
let imm = u16::try_from(simm32).ok()?;
985-
Some(AssemblerImm16::new(imm))
986-
}
971+
RegMemImm::Imm { simm32 } => Some(u16::try_from(simm32).ok()?),
987972
_ => None,
988973
}
989974
}
990975

991-
fn is_simm16(&mut self, src: &GprMemImm) -> Option<AssemblerSimm16> {
976+
fn is_simm16(&mut self, src: &GprMemImm) -> Option<i16> {
992977
match src.clone().to_reg_mem_imm() {
993-
RegMemImm::Imm { simm32 } => {
994-
let imm = i16::try_from(simm32).ok()?;
995-
Some(AssemblerSimm16::new(imm))
996-
}
978+
RegMemImm::Imm { simm32 } => Some(i16::try_from(simm32).ok()?),
997979
_ => None,
998980
}
999981
}
1000982

1001-
fn is_imm32(&mut self, src: &GprMemImm) -> Option<AssemblerImm32> {
983+
fn is_imm32(&mut self, src: &GprMemImm) -> Option<u32> {
1002984
match src.clone().to_reg_mem_imm() {
1003-
RegMemImm::Imm { simm32 } => Some(AssemblerImm32::new(simm32)),
985+
RegMemImm::Imm { simm32 } => Some(simm32),
1004986
_ => None,
1005987
}
1006988
}
1007989

1008-
fn is_simm32(&mut self, src: &GprMemImm) -> Option<AssemblerSimm32> {
990+
fn is_simm32(&mut self, src: &GprMemImm) -> Option<i32> {
1009991
match src.clone().to_reg_mem_imm() {
1010-
RegMemImm::Imm { simm32 } => Some(AssemblerSimm32::new(simm32 as i32)),
992+
RegMemImm::Imm { simm32 } => Some(simm32 as i32),
1011993
_ => None,
1012994
}
1013995
}
@@ -1040,10 +1022,6 @@ impl Context for IsleContext<'_, '_, MInst, X64Backend> {
10401022
RegMem::Mem { addr } => XmmMem::new(RegMem::Mem { addr }),
10411023
}
10421024
}
1043-
1044-
fn u8_to_assembler_imm8(&mut self, val: u8) -> AssemblerImm8 {
1045-
AssemblerImm8::new(val)
1046-
}
10471025
}
10481026

10491027
impl IsleContext<'_, '_, MInst, X64Backend> {

0 commit comments

Comments
 (0)