Infer REX prefixes for SIMD load_extend
This commit is contained in:
@@ -1945,15 +1945,8 @@ fn define_simd(
|
||||
for recipe in &[rec_fld, rec_fldDisp8, rec_fldDisp32] {
|
||||
let inst = *inst;
|
||||
let template = recipe.opcodes(*opcodes);
|
||||
e.enc32_maybe_isap(inst.clone().bind(I32), template.clone(), isap);
|
||||
// REX-less encoding must come after REX encoding so we don't use it by
|
||||
// default. Otherwise reg-alloc would never use r8 and up.
|
||||
e.enc64_maybe_isap(inst.clone().bind(I32), template.clone().rex(), isap);
|
||||
e.enc64_maybe_isap(inst.clone().bind(I32), template.clone(), isap);
|
||||
// Similar to above; TODO some of this duplication can be cleaned up by infer_rex()
|
||||
// tracked in https://github.com/bytecodealliance/cranelift/issues/1090
|
||||
e.enc64_maybe_isap(inst.clone().bind(I64), template.clone().rex(), isap);
|
||||
e.enc64_maybe_isap(inst.bind(I64), template, isap);
|
||||
e.enc_both_inferred_maybe_isap(inst.clone().bind(I32), template.clone(), isap);
|
||||
e.enc64_maybe_isap(inst.bind(I64), template.infer_rex(), isap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2087,7 +2087,7 @@ pub(crate) fn define<'shared>(
|
||||
);
|
||||
|
||||
// XX /r float load with 8-bit offset.
|
||||
recipes.add_template_recipe(
|
||||
recipes.add_template_inferred(
|
||||
EncodingRecipeBuilder::new("fldDisp8", &formats.load, 2)
|
||||
.operands_in(vec![gpr])
|
||||
.operands_out(vec![fpr])
|
||||
@@ -2110,6 +2110,7 @@ pub(crate) fn define<'shared>(
|
||||
sink.put1(offset as u8);
|
||||
"#,
|
||||
),
|
||||
"size_plus_maybe_sib_for_inreg_0_plus_rex_prefix_for_inreg0_outreg0",
|
||||
);
|
||||
|
||||
let has_big_offset =
|
||||
@@ -2142,7 +2143,7 @@ pub(crate) fn define<'shared>(
|
||||
);
|
||||
|
||||
// XX /r float load with 32-bit offset.
|
||||
recipes.add_template_recipe(
|
||||
recipes.add_template_inferred(
|
||||
EncodingRecipeBuilder::new("fldDisp32", &formats.load, 5)
|
||||
.operands_in(vec![gpr])
|
||||
.operands_out(vec![fpr])
|
||||
@@ -2165,6 +2166,7 @@ pub(crate) fn define<'shared>(
|
||||
sink.put4(offset as u32);
|
||||
"#,
|
||||
),
|
||||
"size_plus_maybe_sib_for_inreg_0_plus_rex_prefix_for_inreg0_outreg0",
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -156,6 +156,22 @@ fn size_plus_maybe_sib_or_offset_for_inreg_0_plus_rex_prefix_for_inreg0_outreg0(
|
||||
+ if needs_rex { 1 } else { 0 }
|
||||
}
|
||||
|
||||
/// Calculates the size while inferring if the first input register (inreg0) and first output
|
||||
/// register (outreg0) require a dynamic REX and if the first input register (inreg0) requires a
|
||||
/// SIB.
|
||||
fn size_plus_maybe_sib_for_inreg_0_plus_rex_prefix_for_inreg0_outreg0(
|
||||
sizing: &RecipeSizing,
|
||||
enc: Encoding,
|
||||
inst: Inst,
|
||||
divert: &RegDiversions,
|
||||
func: &Function,
|
||||
) -> u8 {
|
||||
let needs_rex = (EncodingBits::from(enc.bits()).rex_w() != 0)
|
||||
|| test_input(0, inst, divert, func, is_extended_reg)
|
||||
|| test_result(0, inst, divert, func, is_extended_reg);
|
||||
size_plus_maybe_sib_for_inreg_0(sizing, enc, inst, divert, func) + if needs_rex { 1 } else { 0 }
|
||||
}
|
||||
|
||||
/// Infers whether a dynamic REX prefix will be emitted, for use with one input reg.
|
||||
///
|
||||
/// A REX prefix is known to be emitted if either:
|
||||
|
||||
Reference in New Issue
Block a user