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:
gdeepti 2017-03-22 13:49:27 -07:00 committed by Commit bot
parent 8d708c6593
commit 9d8d4dfa7d
4 changed files with 34 additions and 4 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -2133,7 +2133,13 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
get_modrm(*current, &mod, &regop, &rm);
AppendToBuffer("movmskps %s,", NameOfCPURegister(regop));
current += PrintRightXMMOperand(current);
} else if (opcode == 0x70) {
int mod, regop, rm;
get_modrm(*current, &mod, &regop, &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);

View File

@ -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);