Skip to content

Commit 757eac4

Browse files
committed
Fix 16-bit x86_pextr encoding
The x86 ISA has (at least) two encodings for PEXTRW: 1. in the SSE2 opcode (66 0f c5) the XMM operand uses r/m and the GPR operand uses reg 2. in the SSE4.1 opcode (66 0f 3a 15) the XMM operand uses reg and the GPR operand uses r/m This changes the 16-bit x86_pextr encoding from #1 to #2 to match the other PEXTR* implementations (all #2 style).
1 parent 93e646f commit 757eac4

2 files changed

Lines changed: 10 additions & 10 deletions

File tree

cranelift-codegen/meta/src/isa/x86/encodings.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1909,23 +1909,23 @@ pub(crate) fn define(
19091909
}
19101910

19111911
// SIMD extractlane
1912-
let mut x86_pextr_mapping: HashMap<u64, (Vec<u8>, Option<SettingPredicateNumber>)> =
1913-
HashMap::new();
1914-
x86_pextr_mapping.insert(8, (vec![0x66, 0x0f, 0x3a, 0x14], Some(use_sse41_simd))); // PEXTRB
1915-
x86_pextr_mapping.insert(16, (vec![0x66, 0x0f, 0xc5], None)); // PEXTRW from SSE2, SSE4.1 has a PEXTRW that can move to reg/m16 but the opcode is four bytes
1916-
x86_pextr_mapping.insert(32, (vec![0x66, 0x0f, 0x3a, 0x16], Some(use_sse41_simd))); // PEXTRD
1917-
x86_pextr_mapping.insert(64, (vec![0x66, 0x0f, 0x3a, 0x16], Some(use_sse41_simd))); // PEXTRQ, only x86_64
1912+
let mut x86_pextr_mapping: HashMap<u64, Vec<u8>> = HashMap::new();
1913+
x86_pextr_mapping.insert(8, vec![0x66, 0x0f, 0x3a, 0x14]); // PEXTRB
1914+
x86_pextr_mapping.insert(16, vec![0x66, 0x0f, 0x3a, 0x15]); // PEXTRW from SSE4.1, SSE2 has a
1915+
// PEXTRW that can move to reg/m16 but the ModR/M assignment is backwards
1916+
x86_pextr_mapping.insert(32, vec![0x66, 0x0f, 0x3a, 0x16]); // PEXTRD
1917+
x86_pextr_mapping.insert(64, vec![0x66, 0x0f, 0x3a, 0x16]); // PEXTRQ, only x86_64
19181918

19191919
for ty in ValueType::all_lane_types().filter(allowed_simd_type) {
1920-
if let Some((opcode, isap)) = x86_pextr_mapping.get(&ty.lane_bits()) {
1920+
if let Some(opcode) = x86_pextr_mapping.get(&ty.lane_bits()) {
19211921
let instruction = x86_pextr.bind_vector_from_lane(ty, sse_vector_size);
19221922
let template = rec_r_ib_unsigned_gpr.opcodes(opcode.clone());
19231923
if ty.lane_bits() < 64 {
1924-
e.enc_32_64_maybe_isap(instruction, template.nonrex(), isap.clone());
1924+
e.enc_32_64_maybe_isap(instruction, template.nonrex(), Some(use_sse41_simd));
19251925
} else {
19261926
// It turns out the 64-bit widths have REX/W encodings and only are available on
19271927
// x86_64.
1928-
e.enc64_maybe_isap(instruction, template.rex().w(), isap.clone());
1928+
e.enc64_maybe_isap(instruction, template.rex().w(), Some(use_sse41_simd));
19291929
}
19301930
}
19311931
}

filetests/isa/x86/extractlane-binemit.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ function %test_extractlane_i16() {
1717
ebb0:
1818
[-, %rax] v0 = iconst.i16 4
1919
[-, %xmm1] v1 = splat.i16x8 v0
20-
[-, %rax] v2 = x86_pextr v1, 4 ; bin: 66 0f c5 c8 04
20+
[-, %rax] v2 = x86_pextr v1, 4 ; bin: 66 0f 3a 15 c8 04
2121
return
2222
}
2323

0 commit comments

Comments
 (0)