Skip to content

Commit 4c45cc2

Browse files
authored
Use assembler encodings, simplify pretty-printing (#11465)
While exploring the possibility of extending the set of x86 registers available to Cranelift, I noticed some opportunities for improvement: - this change uses on the assembler's `enc` modules for the "hardware encoding source of truth" instead of an older implementation in `cranelift-codegen` and/or raw integers. - this change uses the assembler's pretty printing instead of multiple implementations in `cranelift-codegen` With this in place, it should be more clear where to implement new registers.
1 parent 60a9799 commit 4c45cc2

File tree

3 files changed

+170
-257
lines changed

3 files changed

+170
-257
lines changed

cranelift/codegen/src/isa/x64/abi.rs

Lines changed: 87 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,14 +1110,15 @@ fn get_fltreg_for_retval(call_conv: CallConv, fltreg_idx: usize, is_last: bool)
11101110
}
11111111

11121112
fn is_callee_save_systemv(r: RealReg, enable_pinned_reg: bool) -> bool {
1113-
use regs::*;
1113+
use asm::gpr::enc::*;
1114+
11141115
match r.class() {
11151116
RegClass::Int => match r.hw_enc() {
1116-
ENC_RBX | ENC_RBP | ENC_R12 | ENC_R13 | ENC_R14 => true,
1117+
RBX | RBP | R12 | R13 | R14 => true,
11171118
// R15 is the pinned register; if we're using it that way,
11181119
// it is effectively globally-allocated, and is not
11191120
// callee-saved.
1120-
ENC_R15 => !enable_pinned_reg,
1121+
R15 => !enable_pinned_reg,
11211122
_ => false,
11221123
},
11231124
RegClass::Float => false,
@@ -1126,16 +1127,18 @@ fn is_callee_save_systemv(r: RealReg, enable_pinned_reg: bool) -> bool {
11261127
}
11271128

11281129
fn is_callee_save_fastcall(r: RealReg, enable_pinned_reg: bool) -> bool {
1129-
use regs::*;
1130+
use asm::gpr::enc::*;
1131+
use asm::xmm::enc::*;
1132+
11301133
match r.class() {
11311134
RegClass::Int => match r.hw_enc() {
1132-
ENC_RBX | ENC_RBP | ENC_RSI | ENC_RDI | ENC_R12 | ENC_R13 | ENC_R14 => true,
1135+
RBX | RBP | RSI | RDI | R12 | R13 | R14 => true,
11331136
// See above for SysV: we must treat the pinned reg specially.
1134-
ENC_R15 => !enable_pinned_reg,
1137+
R15 => !enable_pinned_reg,
11351138
_ => false,
11361139
},
11371140
RegClass::Float => match r.hw_enc() {
1138-
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 => true,
1141+
XMM6 | XMM7 | XMM8 | XMM9 | XMM10 | XMM11 | XMM12 | XMM13 | XMM14 | XMM15 => true,
11391142
_ => false,
11401143
},
11411144
RegClass::Vector => unreachable!(),
@@ -1164,84 +1167,93 @@ const SYSV_CLOBBERS: PRegSet = sysv_clobbers();
11641167
pub(crate) const ALL_CLOBBERS: PRegSet = all_clobbers();
11651168

11661169
const fn windows_clobbers() -> PRegSet {
1170+
use asm::gpr::enc::*;
1171+
use asm::xmm::enc::*;
1172+
11671173
PRegSet::empty()
1168-
.with(regs::gpr_preg(regs::ENC_RAX))
1169-
.with(regs::gpr_preg(regs::ENC_RCX))
1170-
.with(regs::gpr_preg(regs::ENC_RDX))
1171-
.with(regs::gpr_preg(regs::ENC_R8))
1172-
.with(regs::gpr_preg(regs::ENC_R9))
1173-
.with(regs::gpr_preg(regs::ENC_R10))
1174-
.with(regs::gpr_preg(regs::ENC_R11))
1175-
.with(regs::fpr_preg(0))
1176-
.with(regs::fpr_preg(1))
1177-
.with(regs::fpr_preg(2))
1178-
.with(regs::fpr_preg(3))
1179-
.with(regs::fpr_preg(4))
1180-
.with(regs::fpr_preg(5))
1174+
.with(regs::gpr_preg(RAX))
1175+
.with(regs::gpr_preg(RCX))
1176+
.with(regs::gpr_preg(RDX))
1177+
.with(regs::gpr_preg(R8))
1178+
.with(regs::gpr_preg(R9))
1179+
.with(regs::gpr_preg(R10))
1180+
.with(regs::gpr_preg(R11))
1181+
.with(regs::fpr_preg(XMM0))
1182+
.with(regs::fpr_preg(XMM1))
1183+
.with(regs::fpr_preg(XMM2))
1184+
.with(regs::fpr_preg(XMM3))
1185+
.with(regs::fpr_preg(XMM4))
1186+
.with(regs::fpr_preg(XMM5))
11811187
}
11821188

11831189
const fn sysv_clobbers() -> PRegSet {
1190+
use asm::gpr::enc::*;
1191+
use asm::xmm::enc::*;
1192+
11841193
PRegSet::empty()
1185-
.with(regs::gpr_preg(regs::ENC_RAX))
1186-
.with(regs::gpr_preg(regs::ENC_RCX))
1187-
.with(regs::gpr_preg(regs::ENC_RDX))
1188-
.with(regs::gpr_preg(regs::ENC_RSI))
1189-
.with(regs::gpr_preg(regs::ENC_RDI))
1190-
.with(regs::gpr_preg(regs::ENC_R8))
1191-
.with(regs::gpr_preg(regs::ENC_R9))
1192-
.with(regs::gpr_preg(regs::ENC_R10))
1193-
.with(regs::gpr_preg(regs::ENC_R11))
1194-
.with(regs::fpr_preg(0))
1195-
.with(regs::fpr_preg(1))
1196-
.with(regs::fpr_preg(2))
1197-
.with(regs::fpr_preg(3))
1198-
.with(regs::fpr_preg(4))
1199-
.with(regs::fpr_preg(5))
1200-
.with(regs::fpr_preg(6))
1201-
.with(regs::fpr_preg(7))
1202-
.with(regs::fpr_preg(8))
1203-
.with(regs::fpr_preg(9))
1204-
.with(regs::fpr_preg(10))
1205-
.with(regs::fpr_preg(11))
1206-
.with(regs::fpr_preg(12))
1207-
.with(regs::fpr_preg(13))
1208-
.with(regs::fpr_preg(14))
1209-
.with(regs::fpr_preg(15))
1194+
.with(regs::gpr_preg(RAX))
1195+
.with(regs::gpr_preg(RCX))
1196+
.with(regs::gpr_preg(RDX))
1197+
.with(regs::gpr_preg(RSI))
1198+
.with(regs::gpr_preg(RDI))
1199+
.with(regs::gpr_preg(R8))
1200+
.with(regs::gpr_preg(R9))
1201+
.with(regs::gpr_preg(R10))
1202+
.with(regs::gpr_preg(R11))
1203+
.with(regs::fpr_preg(XMM0))
1204+
.with(regs::fpr_preg(XMM1))
1205+
.with(regs::fpr_preg(XMM2))
1206+
.with(regs::fpr_preg(XMM3))
1207+
.with(regs::fpr_preg(XMM4))
1208+
.with(regs::fpr_preg(XMM5))
1209+
.with(regs::fpr_preg(XMM6))
1210+
.with(regs::fpr_preg(XMM7))
1211+
.with(regs::fpr_preg(XMM8))
1212+
.with(regs::fpr_preg(XMM9))
1213+
.with(regs::fpr_preg(XMM10))
1214+
.with(regs::fpr_preg(XMM11))
1215+
.with(regs::fpr_preg(XMM12))
1216+
.with(regs::fpr_preg(XMM13))
1217+
.with(regs::fpr_preg(XMM14))
1218+
.with(regs::fpr_preg(XMM15))
12101219
}
12111220

12121221
/// For calling conventions that clobber all registers.
12131222
const fn all_clobbers() -> PRegSet {
1223+
use asm::gpr::enc::*;
1224+
use asm::xmm::enc::*;
1225+
12141226
PRegSet::empty()
1215-
.with(regs::gpr_preg(regs::ENC_RAX))
1216-
.with(regs::gpr_preg(regs::ENC_RCX))
1217-
.with(regs::gpr_preg(regs::ENC_RDX))
1218-
.with(regs::gpr_preg(regs::ENC_RBX))
1219-
.with(regs::gpr_preg(regs::ENC_RSI))
1220-
.with(regs::gpr_preg(regs::ENC_RDI))
1221-
.with(regs::gpr_preg(regs::ENC_R8))
1222-
.with(regs::gpr_preg(regs::ENC_R9))
1223-
.with(regs::gpr_preg(regs::ENC_R10))
1224-
.with(regs::gpr_preg(regs::ENC_R11))
1225-
.with(regs::gpr_preg(regs::ENC_R12))
1226-
.with(regs::gpr_preg(regs::ENC_R13))
1227-
.with(regs::gpr_preg(regs::ENC_R14))
1228-
.with(regs::gpr_preg(regs::ENC_R15))
1229-
.with(regs::fpr_preg(0))
1230-
.with(regs::fpr_preg(1))
1231-
.with(regs::fpr_preg(2))
1232-
.with(regs::fpr_preg(3))
1233-
.with(regs::fpr_preg(4))
1234-
.with(regs::fpr_preg(5))
1235-
.with(regs::fpr_preg(6))
1236-
.with(regs::fpr_preg(7))
1237-
.with(regs::fpr_preg(8))
1238-
.with(regs::fpr_preg(9))
1239-
.with(regs::fpr_preg(10))
1240-
.with(regs::fpr_preg(11))
1241-
.with(regs::fpr_preg(12))
1242-
.with(regs::fpr_preg(13))
1243-
.with(regs::fpr_preg(14))
1244-
.with(regs::fpr_preg(15))
1227+
.with(regs::gpr_preg(RAX))
1228+
.with(regs::gpr_preg(RCX))
1229+
.with(regs::gpr_preg(RDX))
1230+
.with(regs::gpr_preg(RBX))
1231+
.with(regs::gpr_preg(RSI))
1232+
.with(regs::gpr_preg(RDI))
1233+
.with(regs::gpr_preg(R8))
1234+
.with(regs::gpr_preg(R9))
1235+
.with(regs::gpr_preg(R10))
1236+
.with(regs::gpr_preg(R11))
1237+
.with(regs::gpr_preg(R12))
1238+
.with(regs::gpr_preg(R13))
1239+
.with(regs::gpr_preg(R14))
1240+
.with(regs::gpr_preg(R15))
1241+
.with(regs::fpr_preg(XMM0))
1242+
.with(regs::fpr_preg(XMM1))
1243+
.with(regs::fpr_preg(XMM2))
1244+
.with(regs::fpr_preg(XMM3))
1245+
.with(regs::fpr_preg(XMM4))
1246+
.with(regs::fpr_preg(XMM5))
1247+
.with(regs::fpr_preg(XMM6))
1248+
.with(regs::fpr_preg(XMM7))
1249+
.with(regs::fpr_preg(XMM8))
1250+
.with(regs::fpr_preg(XMM9))
1251+
.with(regs::fpr_preg(XMM10))
1252+
.with(regs::fpr_preg(XMM11))
1253+
.with(regs::fpr_preg(XMM12))
1254+
.with(regs::fpr_preg(XMM13))
1255+
.with(regs::fpr_preg(XMM14))
1256+
.with(regs::fpr_preg(XMM15))
12451257
}
12461258

12471259
fn create_reg_env_systemv(enable_pinned_reg: bool) -> MachineEnv {

cranelift/codegen/src/isa/x64/inst/mod.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ pub use emit_state::EmitState;
55
use crate::binemit::{Addend, CodeOffset, Reloc};
66
use crate::ir::{ExternalName, LibCall, TrapCode, Type, types};
77
use crate::isa::x64::abi::X64ABIMachineSpec;
8-
use crate::isa::x64::inst::regs::{pretty_print_reg, show_ireg_sized};
8+
use crate::isa::x64::inst::regs::pretty_print_reg;
99
use crate::isa::x64::settings as x64_settings;
1010
use crate::isa::{CallConv, FunctionAlignment};
1111
use crate::{CodegenError, CodegenResult, settings};
@@ -522,7 +522,7 @@ impl PrettyPrint for Inst {
522522

523523
Inst::MovFromPReg { src, dst } => {
524524
let src: Reg = (*src).into();
525-
let src = regs::show_ireg_sized(src, 8);
525+
let src = pretty_print_reg(src, 8);
526526
let dst = pretty_print_reg(dst.to_reg().to_reg(), 8);
527527
let op = ljustify("movq".to_string());
528528
format!("{op} {src}, {dst}")
@@ -531,7 +531,7 @@ impl PrettyPrint for Inst {
531531
Inst::MovToPReg { src, dst } => {
532532
let src = pretty_print_reg(src.to_reg(), 8);
533533
let dst: Reg = (*dst).into();
534-
let dst = regs::show_ireg_sized(dst, 8);
534+
let dst = pretty_print_reg(dst, 8);
535535
let op = ljustify("movq".to_string());
536536
format!("{op} {src}, {dst}")
537537
}
@@ -606,7 +606,7 @@ impl PrettyPrint for Inst {
606606
let tmp = pretty_print_reg(tmp.to_reg().to_reg(), 8);
607607
let mut s = format!("return_call_known {dest:?} ({new_stack_arg_size}) tmp={tmp}");
608608
for ret in uses {
609-
let preg = regs::show_reg(ret.preg);
609+
let preg = pretty_print_reg(ret.preg, 8);
610610
let vreg = pretty_print_reg(ret.vreg, 8);
611611
write!(&mut s, " {vreg}={preg}").unwrap();
612612
}
@@ -625,7 +625,7 @@ impl PrettyPrint for Inst {
625625
let mut s =
626626
format!("return_call_unknown {callee} ({new_stack_arg_size}) tmp={tmp}");
627627
for ret in uses {
628-
let preg = regs::show_reg(ret.preg);
628+
let preg = pretty_print_reg(ret.preg, 8);
629629
let vreg = pretty_print_reg(ret.vreg, 8);
630630
write!(&mut s, " {vreg}={preg}").unwrap();
631631
}
@@ -635,7 +635,7 @@ impl PrettyPrint for Inst {
635635
Inst::Args { args } => {
636636
let mut s = "args".to_string();
637637
for arg in args {
638-
let preg = regs::show_reg(arg.preg);
638+
let preg = pretty_print_reg(arg.preg, 8);
639639
let def = pretty_print_reg(arg.vreg.to_reg(), 8);
640640
write!(&mut s, " {def}={preg}").unwrap();
641641
}
@@ -645,7 +645,7 @@ impl PrettyPrint for Inst {
645645
Inst::Rets { rets } => {
646646
let mut s = "rets".to_string();
647647
for ret in rets {
648-
let preg = regs::show_reg(ret.preg);
648+
let preg = pretty_print_reg(ret.preg, 8);
649649
let vreg = pretty_print_reg(ret.vreg, 8);
650650
write!(&mut s, " {vreg}={preg}").unwrap();
651651
}
@@ -808,7 +808,7 @@ impl PrettyPrint for Inst {
808808

809809
let mut s = format!("{dst} = coff_tls_get_addr {symbol:?}");
810810
if tmp.is_virtual() {
811-
let tmp = show_ireg_sized(tmp, 8);
811+
let tmp = pretty_print_reg(tmp, 8);
812812
write!(&mut s, ", {tmp}").unwrap();
813813
};
814814

@@ -1162,7 +1162,7 @@ fn x64_get_operands(inst: &mut Inst, collector: &mut impl OperandVisitor) {
11621162
// Windows) use different TLS strategies.
11631163
let mut clobbers =
11641164
X64ABIMachineSpec::get_regs_clobbered_by_call(CallConv::SystemV, false);
1165-
clobbers.remove(regs::gpr_preg(regs::ENC_RAX));
1165+
clobbers.remove(regs::gpr_preg(asm::gpr::enc::RAX));
11661166
collector.reg_clobbers(clobbers);
11671167
}
11681168

0 commit comments

Comments
 (0)