Remove FPR32; fixes #1303
Until #1306 is resolved (some spilling/regalloc issue with larger FPR register banks), this removes FPR32 support. Only Wasm's `i64x2.mul` was using this register class and that instruction is predicated on AVX512 support; for the time being, that instruction will have to make do with the 16 FPR registers.
This commit is contained in:
@@ -143,19 +143,18 @@ fn replace_nonrex_constraints(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn replace_evex_constraints(
|
fn replace_evex_constraints(
|
||||||
regs: &IsaRegs,
|
_: &IsaRegs,
|
||||||
constraints: Vec<OperandConstraint>,
|
constraints: Vec<OperandConstraint>,
|
||||||
) -> Vec<OperandConstraint> {
|
) -> Vec<OperandConstraint> {
|
||||||
constraints
|
constraints
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|constraint| match constraint {
|
.map(|constraint| match constraint {
|
||||||
OperandConstraint::RegClass(rc_index) => {
|
OperandConstraint::RegClass(rc_index) => {
|
||||||
let new_rc_index = if rc_index == regs.class_by_name("FPR") {
|
// FIXME(#1306) this should be able to upgrade the register class to FPR32 as in
|
||||||
regs.class_by_name("FPR32")
|
// `replace_nonrex_constraints` above, e.g. When FPR32 is re-added, add back in the
|
||||||
} else {
|
// rc_index conversion to FPR32. In the meantime, this is effectively a no-op
|
||||||
rc_index
|
// conversion--the register class stays the same.
|
||||||
};
|
OperandConstraint::RegClass(rc_index)
|
||||||
OperandConstraint::RegClass(new_rc_index)
|
|
||||||
}
|
}
|
||||||
_ => constraint,
|
_ => constraint,
|
||||||
})
|
})
|
||||||
@@ -419,7 +418,6 @@ pub(crate) fn define<'shared>(
|
|||||||
let abcd = regs.class_by_name("ABCD");
|
let abcd = regs.class_by_name("ABCD");
|
||||||
let gpr = regs.class_by_name("GPR");
|
let gpr = regs.class_by_name("GPR");
|
||||||
let fpr = regs.class_by_name("FPR");
|
let fpr = regs.class_by_name("FPR");
|
||||||
let fpr32 = regs.class_by_name("FPR32");
|
|
||||||
let flag = regs.class_by_name("FLAG");
|
let flag = regs.class_by_name("FLAG");
|
||||||
|
|
||||||
// Operand constraints shorthands.
|
// Operand constraints shorthands.
|
||||||
@@ -3364,8 +3362,8 @@ pub(crate) fn define<'shared>(
|
|||||||
recipes.add_template(
|
recipes.add_template(
|
||||||
Template::new(
|
Template::new(
|
||||||
EncodingRecipeBuilder::new("evex_reg_vvvv_rm_128", &formats.binary, 1)
|
EncodingRecipeBuilder::new("evex_reg_vvvv_rm_128", &formats.binary, 1)
|
||||||
.operands_in(vec![fpr32, fpr32])
|
.operands_in(vec![fpr, fpr])
|
||||||
.operands_out(vec![fpr32])
|
.operands_out(vec![fpr])
|
||||||
.emit(
|
.emit(
|
||||||
r#"
|
r#"
|
||||||
// instruction encoding operands: reg (op1, w), vvvv (op2, r), rm (op3, r)
|
// instruction encoding operands: reg (op1, w), vvvv (op2, r), rm (op3, r)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ pub(crate) fn define() -> IsaRegs {
|
|||||||
let mut regs = IsaRegsBuilder::new();
|
let mut regs = IsaRegsBuilder::new();
|
||||||
|
|
||||||
let builder = RegBankBuilder::new("FloatRegs", "xmm")
|
let builder = RegBankBuilder::new("FloatRegs", "xmm")
|
||||||
.units(32)
|
.units(16)
|
||||||
.track_pressure(true);
|
.track_pressure(true);
|
||||||
let float_regs = regs.add_bank(builder);
|
let float_regs = regs.add_bank(builder);
|
||||||
|
|
||||||
@@ -24,10 +24,7 @@ pub(crate) fn define() -> IsaRegs {
|
|||||||
let builder = RegClassBuilder::new_toplevel("GPR", int_regs);
|
let builder = RegClassBuilder::new_toplevel("GPR", int_regs);
|
||||||
let gpr = regs.add_class(builder);
|
let gpr = regs.add_class(builder);
|
||||||
|
|
||||||
let builder = RegClassBuilder::new_toplevel("FPR32", float_regs);
|
let builder = RegClassBuilder::new_toplevel("FPR", float_regs);
|
||||||
let fpr32 = regs.add_class(builder);
|
|
||||||
|
|
||||||
let builder = RegClassBuilder::subclass_of("FPR", fpr32, 0, 16);
|
|
||||||
let fpr = regs.add_class(builder);
|
let fpr = regs.add_class(builder);
|
||||||
|
|
||||||
let builder = RegClassBuilder::new_toplevel("FLAG", flag_reg);
|
let builder = RegClassBuilder::new_toplevel("FLAG", flag_reg);
|
||||||
|
|||||||
@@ -33,11 +33,12 @@ mod tests {
|
|||||||
assert_eq!(INFO.parse_regunit("xmm0"), fpr(0));
|
assert_eq!(INFO.parse_regunit("xmm0"), fpr(0));
|
||||||
assert_eq!(INFO.parse_regunit("xmm15"), fpr(15));
|
assert_eq!(INFO.parse_regunit("xmm15"), fpr(15));
|
||||||
|
|
||||||
fn fpr32(unit: usize) -> Option<u16> {
|
// FIXME(#1306) Add these tests back in when FPR32 is re-added.
|
||||||
Some(FPR32.unit(unit))
|
// fn fpr32(unit: usize) -> Option<u16> {
|
||||||
}
|
// Some(FPR32.unit(unit))
|
||||||
assert_eq!(INFO.parse_regunit("xmm0"), fpr32(0));
|
// }
|
||||||
assert_eq!(INFO.parse_regunit("xmm31"), fpr32(31));
|
// assert_eq!(INFO.parse_regunit("xmm0"), fpr32(0));
|
||||||
|
// assert_eq!(INFO.parse_regunit("xmm31"), fpr32(31));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -62,11 +63,12 @@ mod tests {
|
|||||||
assert_eq!(fpr(0), "%xmm0");
|
assert_eq!(fpr(0), "%xmm0");
|
||||||
assert_eq!(fpr(15), "%xmm15");
|
assert_eq!(fpr(15), "%xmm15");
|
||||||
|
|
||||||
fn fpr32(ru: RegUnit) -> String {
|
// FIXME(#1306) Add these tests back in when FPR32 is re-added.
|
||||||
INFO.display_regunit(FPR32.first + ru).to_string()
|
// fn fpr32(ru: RegUnit) -> String {
|
||||||
}
|
// INFO.display_regunit(FPR32.first + ru).to_string()
|
||||||
assert_eq!(fpr32(0), "%xmm0");
|
// }
|
||||||
assert_eq!(fpr32(31), "%xmm31");
|
// assert_eq!(fpr32(0), "%xmm0");
|
||||||
|
// assert_eq!(fpr32(31), "%xmm31");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ function %imul_i64x2() {
|
|||||||
block0:
|
block0:
|
||||||
[-, %xmm1] v0 = vconst.i64x2 [1 2]
|
[-, %xmm1] v0 = vconst.i64x2 [1 2]
|
||||||
[-, %xmm2] v1 = vconst.i64x2 [2 2]
|
[-, %xmm2] v1 = vconst.i64x2 [2 2]
|
||||||
[-, %xmm19] v2 = imul v0, v1 ; bin: 62 e2 f5 08 40 da
|
[-, %xmm14] v2 = imul v0, v1 ; bin: 62 72 f5 08 40 f2
|
||||||
; 62, mandatory EVEX prefix
|
; 62, mandatory EVEX prefix
|
||||||
; e2 = 1110 0010, R, X, B are unset (inverted) while R' is set (MSB in %xmm19); mm is set to 0F38
|
; 72 = 0111 0010, R is set (MSB in %xmm14) while X, B, and R' are unset (note these are all inverted); mm is set to 0F38
|
||||||
; f5 = 1111 0101, W is set (64-bit op), vvvv set to 1 (inverted), bit 2 always set, pp set to 01
|
; f5 = 1111 0101, W is set (64-bit op), vvvv set to 1 (inverted), bit 2 always set, pp set to 01
|
||||||
; 08 = 0000 1000, everything, LL' indicates 128-bit, V' is unset (inverted, %xmm1 has MSB of 0)
|
; 08 = 0000 1000, everything, LL' indicates 128-bit, V' is unset (inverted, %xmm1 has MSB of 0)
|
||||||
; 40, opcode (correct)
|
; 40, opcode (correct)
|
||||||
; da = 1100 1010, ModR/M byte using 0b011 from %xmm19 in reg and 0b010 from %xmm2 in r/m
|
; f2 = 1111 0010, ModR/M byte using 0b110 from %xmm14 in reg and 0b010 from %xmm2 in r/m
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,14 +166,11 @@ impl Compiler {
|
|||||||
if trampolines.contains_key(&index) {
|
if trampolines.contains_key(&index) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// FIXME(#1303) we should be generating a trampoline for all
|
// FIXME(#1322) we should be generating a trampoline for all
|
||||||
// functions in a module, not just those with less than 40
|
// functions in a module, not just those with less than 40
|
||||||
// arguments. Currently though cranelift dies in spec tests when one
|
// arguments. Currently there is no relocation support for
|
||||||
// function has 100 arguments. This looks to be a cranelift bug, so
|
// trampoline compilation; when that is added this check can
|
||||||
// let's work around it for now by skipping generating a trampoline
|
// go away.
|
||||||
// for that massive function. The trampoline isn't actually needed
|
|
||||||
// at this time, and we'll hopefully get the cranelift bug fixed
|
|
||||||
// soon enough to remove this condition.
|
|
||||||
if sig.params.len() > 40 {
|
if sig.params.len() > 40 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
5
tests/misc_testsuite/export-large-signature.wast
Normal file
5
tests/misc_testsuite/export-large-signature.wast
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
(module
|
||||||
|
(func (export "many_params")
|
||||||
|
(param f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32)
|
||||||
|
)
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user