Commit 944dad59 authored by Ng Zhi An's avatar Ng Zhi An Committed by Commit Bot

[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/+/2471977Reviewed-by: 's avatarBill Budge <bbudge@chromium.org>
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70520}
parent 8a4194dd
......@@ -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) {
......
......@@ -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); \
......
......@@ -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)
......
......@@ -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 == 0x12) {
// movlps xmm1, m64
int mod, regop, rm;
get_modrm(*current, &mod, &regop, &rm);
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);
AppendToBuffer("movlhps %s,", NameOfXMMRegister(regop));
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;
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment