[x64] Add movlps and movhps to assembler

These instructions will be used for prototyping Wasm SIMD's store lane
later on, separated the implementation for assembler and disassembler
into this patch to make things smaller.

Curiously, movhps and movlhps seems to have the same encoding, 0f 16, so
I'm not sure not sure how to differentiate them in the disassembler
besides using the mod field, since movlhps only takes xmm registers,
whereas movhps always take 1 operand.

Bug: v8:10975
Change-Id: I8be9a31b1c9a5515038f9c8c55ef30d1ba063ea7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2471977
Reviewed-by: Bill Budge <bbudge@chromium.org>
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70520}
This commit is contained in:
Ng Zhi An 2020-10-14 09:33:41 -07:00 committed by Commit Bot
parent 8a4194ddad
commit 944dad59c8
5 changed files with 144 additions and 5 deletions

View File

@ -2994,6 +2994,42 @@ void Assembler::movss(Operand src, XMMRegister dst) {
emit_sse_operand(dst, src);
}
void Assembler::movlps(XMMRegister dst, Operand src) {
DCHECK(!IsEnabled(AVX));
EnsureSpace ensure_space(this);
emit_optional_rex_32(dst, src);
emit(0x0F);
emit(0x12);
emit_sse_operand(dst, src);
}
void Assembler::movlps(Operand src, XMMRegister dst) {
DCHECK(!IsEnabled(AVX));
EnsureSpace ensure_space(this);
emit_optional_rex_32(dst, src);
emit(0x0F);
emit(0x13);
emit_sse_operand(dst, src);
}
void Assembler::movhps(XMMRegister dst, Operand src) {
DCHECK(!IsEnabled(AVX));
EnsureSpace ensure_space(this);
emit_optional_rex_32(dst, src);
emit(0x0F);
emit(0x16);
emit_sse_operand(dst, src);
}
void Assembler::movhps(Operand src, XMMRegister dst) {
DCHECK(!IsEnabled(AVX));
EnsureSpace ensure_space(this);
emit_optional_rex_32(dst, src);
emit(0x0F);
emit(0x17);
emit_sse_operand(dst, src);
}
void Assembler::cmpps(XMMRegister dst, XMMRegister src, int8_t cmp) {
EnsureSpace ensure_space(this);
emit_optional_rex_32(dst, src);
@ -3467,6 +3503,38 @@ void Assembler::vmovdqu(Operand dst, XMMRegister src) {
emit_sse_operand(src, dst);
}
void Assembler::vmovlps(XMMRegister dst, XMMRegister src1, Operand src2) {
DCHECK(IsEnabled(AVX));
EnsureSpace ensure_space(this);
emit_vex_prefix(dst, src1, src2, kL128, kNone, k0F, kWIG);
emit(0x12);
emit_sse_operand(dst, src2);
}
void Assembler::vmovlps(Operand dst, XMMRegister src) {
DCHECK(IsEnabled(AVX));
EnsureSpace ensure_space(this);
emit_vex_prefix(src, xmm0, dst, kL128, kNone, k0F, kWIG);
emit(0x13);
emit_sse_operand(src, dst);
}
void Assembler::vmovhps(XMMRegister dst, XMMRegister src1, Operand src2) {
DCHECK(IsEnabled(AVX));
EnsureSpace ensure_space(this);
emit_vex_prefix(dst, src1, src2, kL128, kNone, k0F, kWIG);
emit(0x16);
emit_sse_operand(dst, src2);
}
void Assembler::vmovhps(Operand dst, XMMRegister src) {
DCHECK(IsEnabled(AVX));
EnsureSpace ensure_space(this);
emit_vex_prefix(src, xmm0, dst, kL128, kNone, k0F, kWIG);
emit(0x17);
emit_sse_operand(src, dst);
}
void Assembler::vinstr(byte op, XMMRegister dst, XMMRegister src1,
XMMRegister src2, SIMDPrefix pp, LeadingOpcode m,
VexW w) {

View File

@ -929,6 +929,13 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void movss(XMMRegister dst, Operand src);
void movss(Operand dst, XMMRegister src);
void movlps(XMMRegister dst, Operand src);
void movlps(Operand dst, XMMRegister src);
void movhps(XMMRegister dst, Operand src);
void movhps(Operand dst, XMMRegister src);
void shufps(XMMRegister dst, XMMRegister src, byte imm8);
void cvttss2si(Register dst, Operand src);
@ -1305,6 +1312,12 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void vmovdqu(XMMRegister dst, Operand src);
void vmovdqu(Operand dst, XMMRegister src);
void vmovlps(XMMRegister dst, XMMRegister src1, Operand src2);
void vmovlps(Operand dst, XMMRegister src);
void vmovhps(XMMRegister dst, XMMRegister src1, Operand src2);
void vmovhps(Operand dst, XMMRegister src);
#define AVX_SSE_UNOP(instr, escape, opcode) \
void v##instr(XMMRegister dst, XMMRegister src2) { \
vps(0x##opcode, dst, xmm0, src2); \

View File

@ -145,6 +145,8 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
AVX_OP(Movss, movss)
AVX_OP(Movsd, movsd)
AVX_OP(Movdqu, movdqu)
AVX_OP(Movlps, movlps)
AVX_OP(Movhps, movhps)
AVX_OP(Pcmpeqb, pcmpeqb)
AVX_OP(Pcmpeqw, pcmpeqw)
AVX_OP(Pcmpeqd, pcmpeqd)

View File

@ -1335,11 +1335,32 @@ int DisassemblerX64::AVXInstruction(byte* data) {
current += PrintRightXMMOperand(current);
AppendToBuffer(",%s", NameOfXMMRegister(regop));
break;
case 0x16:
AppendToBuffer("vmovlhps %s,%s,", NameOfXMMRegister(regop),
case 0x12:
AppendToBuffer("vmovlps %s,%s,", NameOfXMMRegister(regop),
NameOfXMMRegister(vvvv));
current += PrintRightXMMOperand(current);
break;
case 0x13:
AppendToBuffer("vmovlps ");
current += PrintRightXMMOperand(current);
AppendToBuffer(",%s", NameOfXMMRegister(regop));
break;
case 0x16:
if (mod == 0b11) {
AppendToBuffer("vmovlhps %s,%s,", NameOfXMMRegister(regop),
NameOfXMMRegister(vvvv));
current += PrintRightXMMOperand(current);
} else {
AppendToBuffer("vmovhps %s,%s,", NameOfXMMRegister(regop),
NameOfXMMRegister(vvvv));
current += PrintRightXMMOperand(current);
}
break;
case 0x17:
AppendToBuffer("vmovhps ");
current += PrintRightXMMOperand(current);
AppendToBuffer(",%s", NameOfXMMRegister(regop));
break;
case 0x28:
AppendToBuffer("vmovaps %s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(current);
@ -2351,12 +2372,38 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
AppendToBuffer("%s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(current);
}
} else if (opcode == 0x16) {
// movlhps xmm1, xmm2
} else if (opcode == 0x12) {
// movlps xmm1, m64
int mod, regop, rm;
get_modrm(*current, &mod, &regop, &rm);
AppendToBuffer("movlhps %s,", NameOfXMMRegister(regop));
AppendToBuffer("movlps %s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(current);
} else if (opcode == 0x13) {
// movlps m64, xmm1
int mod, regop, rm;
get_modrm(*current, &mod, &regop, &rm);
AppendToBuffer("movlps ");
current += PrintRightXMMOperand(current);
AppendToBuffer(",%s", NameOfXMMRegister(regop));
} else if (opcode == 0x16) {
// movlhps xmm1, xmm2
// movhps xmm1, m64
int mod, regop, rm;
get_modrm(*current, &mod, &regop, &rm);
if (mod == 0b11) {
AppendToBuffer("movlhps ");
} else {
AppendToBuffer("movhps ");
}
AppendToBuffer("%s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(current);
} else if (opcode == 0x17) {
// movhps m64, xmm1
int mod, regop, rm;
get_modrm(*current, &mod, &regop, &rm);
AppendToBuffer("movhps ");
current += PrintRightXMMOperand(current);
AppendToBuffer(",%s", NameOfXMMRegister(regop));
} else if (opcode == 0x1F) {
// NOP
int mod, regop, rm;

View File

@ -401,6 +401,10 @@ TEST(DisasmX64) {
__ movdqu(xmm0, Operand(rsp, 12));
__ movdqu(Operand(rsp, 12), xmm0);
__ movdqu(xmm1, xmm0);
__ movlps(xmm8, Operand(rbx, rcx, times_4, 10000));
__ movlps(Operand(rbx, rcx, times_4, 10000), xmm9);
__ movhps(xmm8, Operand(rbx, rcx, times_4, 10000));
__ movhps(Operand(rbx, rcx, times_4, 10000), xmm9);
__ shufps(xmm0, xmm9, 0x0);
__ ucomiss(xmm0, xmm1);
@ -651,6 +655,11 @@ TEST(DisasmX64) {
__ vmovdqu(xmm9, Operand(rbx, rcx, times_4, 10000));
__ vmovdqu(Operand(rbx, rcx, times_4, 10000), xmm0);
__ vmovlps(xmm8, xmm9, Operand(rbx, rcx, times_4, 10000));
__ vmovlps(Operand(rbx, rcx, times_4, 10000), xmm9);
__ vmovhps(xmm8, xmm9, Operand(rbx, rcx, times_4, 10000));
__ vmovhps(Operand(rbx, rcx, times_4, 10000), xmm12);
__ vroundps(xmm9, xmm2, kRoundUp);
__ vroundpd(xmm9, xmm2, kRoundToNearest);
__ vroundss(xmm9, xmm1, xmm2, kRoundDown);