Add pshufw instruction, fix inconsistencies with pextrw instruction.
Current implementation of the pextrw instruction is the legacy SSE2 instruction in the assembler (66 0F C5), and SSE4 implementation(66 0F 3A 15) in disasm-x64.cc, this causes incorrect instruction encodings to be printed when using --print-code flag for debug, in this case, causes over flow of bytes, and subsequent instructions to be incorrectly disassembled. Fixing to use SSE4 encodings in the assembler cosistent with pextrb, pextrd. R=bbudge@chromium.org, mtrofin@chromium.org Review-Url: https://codereview.chromium.org/2771513002 Cr-Commit-Position: refs/heads/master@{#44047}
This commit is contained in:
parent
8d708c6593
commit
9d8d4dfa7d
@ -834,6 +834,23 @@ void Assembler::bsfq(Register dst, const Operand& src) {
|
||||
emit_operand(dst, src);
|
||||
}
|
||||
|
||||
void Assembler::pshufw(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
|
||||
EnsureSpace ensure_space(this);
|
||||
emit_optional_rex_32(dst, src);
|
||||
emit(0x0F);
|
||||
emit(0x70);
|
||||
emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
|
||||
emit(shuffle);
|
||||
}
|
||||
|
||||
void Assembler::pshufw(XMMRegister dst, const Operand& src, uint8_t shuffle) {
|
||||
EnsureSpace ensure_space(this);
|
||||
emit_optional_rex_32(dst, src);
|
||||
emit(0x0F);
|
||||
emit(0x70);
|
||||
emit_operand(dst.code(), src);
|
||||
emit(shuffle);
|
||||
}
|
||||
|
||||
void Assembler::call(Label* L) {
|
||||
EnsureSpace ensure_space(this);
|
||||
@ -2871,13 +2888,15 @@ void Assembler::pinsrw(XMMRegister dst, const Operand& src, int8_t imm8) {
|
||||
}
|
||||
|
||||
void Assembler::pextrw(Register dst, XMMRegister src, int8_t imm8) {
|
||||
DCHECK(IsEnabled(SSE4_1));
|
||||
DCHECK(is_uint8(imm8));
|
||||
EnsureSpace ensure_space(this);
|
||||
emit(0x66);
|
||||
emit_optional_rex_32(src, dst);
|
||||
emit_optional_rex_32(dst, src);
|
||||
emit(0x0F);
|
||||
emit(0xC5);
|
||||
emit_sse_operand(src, dst);
|
||||
emit(0x3A);
|
||||
emit(0x15);
|
||||
emit_sse_operand(dst, src);
|
||||
emit(imm8);
|
||||
}
|
||||
|
||||
|
@ -889,6 +889,9 @@ class Assembler : public AssemblerBase {
|
||||
void ud2();
|
||||
void setcc(Condition cc, Register reg);
|
||||
|
||||
void pshufw(XMMRegister dst, XMMRegister src, uint8_t shuffle);
|
||||
void pshufw(XMMRegister dst, const Operand& src, uint8_t shuffle);
|
||||
|
||||
// Label operations & relative jumps (PPUM Appendix D)
|
||||
//
|
||||
// Takes a branch opcode (cc) and a label (L) and generates
|
||||
|
@ -2133,7 +2133,13 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
|
||||
get_modrm(*current, &mod, ®op, &rm);
|
||||
AppendToBuffer("movmskps %s,", NameOfCPURegister(regop));
|
||||
current += PrintRightXMMOperand(current);
|
||||
|
||||
} else if (opcode == 0x70) {
|
||||
int mod, regop, rm;
|
||||
get_modrm(*current, &mod, ®op, &rm);
|
||||
AppendToBuffer("pshufw %s, ", NameOfXMMRegister(regop));
|
||||
current += PrintRightXMMOperand(current);
|
||||
AppendToBuffer(", %d", (*current) & 3);
|
||||
current += 1;
|
||||
} else if ((opcode & 0xF0) == 0x80) {
|
||||
// Jcc: Conditional jump (branch).
|
||||
current = data + JumpConditional(data);
|
||||
|
@ -266,6 +266,7 @@ TEST(DisasmX64) {
|
||||
__ xorq(rdx, Immediate(12345));
|
||||
__ xorq(rdx, Operand(rbx, rcx, times_8, 10000));
|
||||
__ bts(Operand(rbx, rcx, times_8, 10000), rdx);
|
||||
__ pshufw(xmm5, xmm1, 3);
|
||||
__ hlt();
|
||||
__ int3();
|
||||
__ ret(0);
|
||||
@ -519,6 +520,7 @@ TEST(DisasmX64) {
|
||||
CpuFeatureScope scope(&assm, SSE4_1);
|
||||
__ insertps(xmm5, xmm1, 123);
|
||||
__ extractps(rax, xmm1, 0);
|
||||
__ pextrw(rbx, xmm2, 1);
|
||||
__ pextrd(rbx, xmm15, 0);
|
||||
__ pextrd(r12, xmm0, 1);
|
||||
__ pinsrd(xmm9, r9, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user