Fixes #1091: Use match statements instead of HashMaps in x86 encodings;
This commit is contained in:
committed by
Andrew Brown
parent
d8967bb58a
commit
0d50462a93
@@ -1759,24 +1759,22 @@ pub(crate) fn define(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SIMD insertlane
|
// SIMD insertlane
|
||||||
let mut x86_pinsr_mapping: HashMap<u64, (&'static [u8], Option<SettingPredicateNumber>)> =
|
|
||||||
HashMap::new();
|
|
||||||
x86_pinsr_mapping.insert(8, (&PINSRB, Some(use_sse41_simd)));
|
|
||||||
x86_pinsr_mapping.insert(16, (&PINSRW, None));
|
|
||||||
x86_pinsr_mapping.insert(32, (&PINSR, Some(use_sse41_simd)));
|
|
||||||
x86_pinsr_mapping.insert(64, (&PINSR, Some(use_sse41_simd)));
|
|
||||||
|
|
||||||
for ty in ValueType::all_lane_types().filter(allowed_simd_type) {
|
for ty in ValueType::all_lane_types().filter(allowed_simd_type) {
|
||||||
if let Some((opcode, isap)) = x86_pinsr_mapping.get(&ty.lane_bits()) {
|
let (opcode, isap): (&[_], _) = match ty.lane_bits() {
|
||||||
let instruction = x86_pinsr.bind_vector_from_lane(ty, sse_vector_size);
|
8 => (&PINSRB, Some(use_sse41_simd)),
|
||||||
let template = rec_r_ib_unsigned_r.opcodes(opcode);
|
16 => (&PINSRW, None),
|
||||||
if ty.lane_bits() < 64 {
|
32 | 64 => (&PINSR, Some(use_sse41_simd)),
|
||||||
e.enc_32_64_maybe_isap(instruction, template.nonrex(), isap.clone());
|
_ => panic!("invalid size for SIMD insertlane"),
|
||||||
} else {
|
};
|
||||||
// It turns out the 64-bit widths have REX/W encodings and only are available on
|
|
||||||
// x86_64.
|
let instruction = x86_pinsr.bind_vector_from_lane(ty, sse_vector_size);
|
||||||
e.enc64_maybe_isap(instruction, template.rex().w(), isap.clone());
|
let template = rec_r_ib_unsigned_r.opcodes(opcode);
|
||||||
}
|
if ty.lane_bits() < 64 {
|
||||||
|
e.enc_32_64_maybe_isap(instruction, template.nonrex(), isap);
|
||||||
|
} else {
|
||||||
|
// It turns out the 64-bit widths have REX/W encodings and only are available on
|
||||||
|
// x86_64.
|
||||||
|
e.enc64_maybe_isap(instruction, template.rex().w(), isap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1802,23 +1800,22 @@ pub(crate) fn define(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SIMD extractlane
|
// SIMD extractlane
|
||||||
let mut x86_pextr_mapping: HashMap<u64, &'static [u8]> = HashMap::new();
|
|
||||||
x86_pextr_mapping.insert(8, &PEXTRB);
|
|
||||||
x86_pextr_mapping.insert(16, &PEXTRW);
|
|
||||||
x86_pextr_mapping.insert(32, &PEXTR);
|
|
||||||
x86_pextr_mapping.insert(64, &PEXTR);
|
|
||||||
|
|
||||||
for ty in ValueType::all_lane_types().filter(allowed_simd_type) {
|
for ty in ValueType::all_lane_types().filter(allowed_simd_type) {
|
||||||
if let Some(opcode) = x86_pextr_mapping.get(&ty.lane_bits()) {
|
let opcode = match ty.lane_bits() {
|
||||||
let instruction = x86_pextr.bind_vector_from_lane(ty, sse_vector_size);
|
8 => &PEXTRB,
|
||||||
let template = rec_r_ib_unsigned_gpr.opcodes(opcode);
|
16 => &PEXTRW,
|
||||||
if ty.lane_bits() < 64 {
|
32 | 64 => &PEXTR,
|
||||||
e.enc_32_64_maybe_isap(instruction, template.nonrex(), Some(use_sse41_simd));
|
_ => panic!("invalid size for SIMD extractlane"),
|
||||||
} else {
|
};
|
||||||
// It turns out the 64-bit widths have REX/W encodings and only are available on
|
|
||||||
// x86_64.
|
let instruction = x86_pextr.bind_vector_from_lane(ty, sse_vector_size);
|
||||||
e.enc64_maybe_isap(instruction, template.rex().w(), Some(use_sse41_simd));
|
let template = rec_r_ib_unsigned_gpr.opcodes(opcode);
|
||||||
}
|
if ty.lane_bits() < 64 {
|
||||||
|
e.enc_32_64_maybe_isap(instruction, template.nonrex(), Some(use_sse41_simd));
|
||||||
|
} else {
|
||||||
|
// It turns out the 64-bit widths have REX/W encodings and only are available on
|
||||||
|
// x86_64.
|
||||||
|
e.enc64_maybe_isap(instruction, template.rex().w(), Some(use_sse41_simd));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1996,27 +1993,28 @@ pub(crate) fn define(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SIMD icmp using PCMPEQ*
|
// SIMD icmp using PCMPEQ*
|
||||||
let mut pcmpeq_mapping: HashMap<u64, (&[u8], Option<SettingPredicateNumber>)> = HashMap::new();
|
|
||||||
pcmpeq_mapping.insert(8, (&PCMPEQB, None));
|
|
||||||
pcmpeq_mapping.insert(16, (&PCMPEQW, None));
|
|
||||||
pcmpeq_mapping.insert(32, (&PCMPEQD, None));
|
|
||||||
pcmpeq_mapping.insert(64, (&PCMPEQQ, Some(use_sse41_simd)));
|
|
||||||
for ty in ValueType::all_lane_types().filter(|t| t.is_int() && allowed_simd_type(t)) {
|
for ty in ValueType::all_lane_types().filter(|t| t.is_int() && allowed_simd_type(t)) {
|
||||||
if let Some((opcodes, isa_predicate)) = pcmpeq_mapping.get(&ty.lane_bits()) {
|
let (opcodes, isa_predicate): (&[_], _) = match ty.lane_bits() {
|
||||||
let instruction = icmp.bind_vector_from_lane(ty, sse_vector_size);
|
8 => (&PCMPEQB, None),
|
||||||
let f_int_compare = formats.get(formats.by_name("IntCompare"));
|
16 => (&PCMPEQW, None),
|
||||||
let has_eq_condition_code =
|
32 => (&PCMPEQD, None),
|
||||||
InstructionPredicate::new_has_condition_code(f_int_compare, IntCC::Equal, "cond");
|
64 => (&PCMPEQQ, Some(use_sse41_simd)),
|
||||||
let template = rec_icscc_fpr.nonrex().opcodes(*opcodes);
|
_ => panic!("invalid size for SIMD icmp"),
|
||||||
e.enc_32_64_func(instruction, template, |builder| {
|
};
|
||||||
let builder = builder.inst_predicate(has_eq_condition_code);
|
|
||||||
if let Some(p) = isa_predicate {
|
let instruction = icmp.bind_vector_from_lane(ty, sse_vector_size);
|
||||||
builder.isa_predicate(*p)
|
let f_int_compare = formats.get(formats.by_name("IntCompare"));
|
||||||
} else {
|
let has_eq_condition_code =
|
||||||
builder
|
InstructionPredicate::new_has_condition_code(f_int_compare, IntCC::Equal, "cond");
|
||||||
}
|
let template = rec_icscc_fpr.nonrex().opcodes(opcodes);
|
||||||
});
|
e.enc_32_64_func(instruction, template, |builder| {
|
||||||
}
|
let builder = builder.inst_predicate(has_eq_condition_code);
|
||||||
|
if let Some(p) = isa_predicate {
|
||||||
|
builder.isa_predicate(p)
|
||||||
|
} else {
|
||||||
|
builder
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reference type instructions
|
// Reference type instructions
|
||||||
|
|||||||
Reference in New Issue
Block a user