Infer REX prefixes for SIMD load and store with displacement

This commit is contained in:
Andrew Brown
2020-04-01 10:06:12 -07:00
parent dc874a5b3b
commit e425bfcebd
4 changed files with 44 additions and 10 deletions

View File

@@ -1866,8 +1866,8 @@ fn define_simd(
// Store
let bound_store = store.bind(vector(ty, sse_vector_size)).bind(Any);
e.enc_both_inferred(bound_store.clone(), rec_fst.opcodes(&MOVUPS_STORE));
e.enc_both(bound_store.clone(), rec_fstDisp8.opcodes(&MOVUPS_STORE));
e.enc_both(bound_store, rec_fstDisp32.opcodes(&MOVUPS_STORE));
e.enc_both_inferred(bound_store.clone(), rec_fstDisp8.opcodes(&MOVUPS_STORE));
e.enc_both_inferred(bound_store, rec_fstDisp32.opcodes(&MOVUPS_STORE));
// Store complex
let bound_store_complex = store_complex.bind(vector(ty, sse_vector_size));
@@ -1887,8 +1887,8 @@ fn define_simd(
// Load
let bound_load = load.bind(vector(ty, sse_vector_size)).bind(Any);
e.enc_both_inferred(bound_load.clone(), rec_fld.opcodes(&MOVUPS_LOAD));
e.enc_both(bound_load.clone(), rec_fldDisp8.opcodes(&MOVUPS_LOAD));
e.enc_both(bound_load, rec_fldDisp32.opcodes(&MOVUPS_LOAD));
e.enc_both_inferred(bound_load.clone(), rec_fldDisp8.opcodes(&MOVUPS_LOAD));
e.enc_both_inferred(bound_load, rec_fldDisp32.opcodes(&MOVUPS_LOAD));
// Load complex
let bound_load_complex = load_complex.bind(vector(ty, sse_vector_size));

View File

@@ -1604,7 +1604,7 @@ pub(crate) fn define<'shared>(
);
// XX /r register-indirect store with 8-bit offset of FPR.
recipes.add_template_recipe(
recipes.add_template_inferred(
EncodingRecipeBuilder::new("fstDisp8", &formats.store, 2)
.operands_in(vec![fpr, gpr])
.inst_predicate(has_small_offset)
@@ -1626,6 +1626,7 @@ pub(crate) fn define<'shared>(
sink.put1(offset as u8);
"#,
),
"size_plus_maybe_sib_inreg1_plus_rex_prefix_for_inreg0_inreg1",
);
// XX /r register-indirect store with 32-bit offset.
@@ -1682,7 +1683,7 @@ pub(crate) fn define<'shared>(
);
// XX /r register-indirect store with 32-bit offset of FPR.
recipes.add_template_recipe(
recipes.add_template_inferred(
EncodingRecipeBuilder::new("fstDisp32", &formats.store, 5)
.operands_in(vec![fpr, gpr])
.clobbers_flags(false)
@@ -1703,6 +1704,7 @@ pub(crate) fn define<'shared>(
sink.put4(offset as u32);
"#,
),
"size_plus_maybe_sib_inreg1_plus_rex_prefix_for_inreg0_inreg1",
);
}

View File

@@ -139,6 +139,21 @@ fn size_plus_maybe_sib_or_offset_inreg1_plus_rex_prefix_for_inreg0_inreg1(
+ if needs_rex { 1 } else { 0 }
}
/// Calculates the size while inferring if the first and second input registers (inreg0, inreg1)
/// require a dynamic REX prefix and if the second input register (inreg1) requires a SIB.
fn size_plus_maybe_sib_inreg1_plus_rex_prefix_for_inreg0_inreg1(
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_input(1, inst, divert, func, is_extended_reg);
size_plus_maybe_sib_for_inreg_1(sizing, enc, inst, divert, func) + 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 or offset.