Fixed bug in extractps instruction on ia32 and x64

This is a fixed version of https://codereview.chromium.org/27097002/
which was originally written by weiliang.lin@intel.com.

R=bmeurer@chromium.org

Review URL: https://codereview.chromium.org/27301003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17217 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 3769a2d2
...@@ -2347,7 +2347,7 @@ void Assembler::extractps(Register dst, XMMRegister src, byte imm8) { ...@@ -2347,7 +2347,7 @@ void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
EMIT(0x0F); EMIT(0x0F);
EMIT(0x3A); EMIT(0x3A);
EMIT(0x17); EMIT(0x17);
emit_sse_operand(dst, src); emit_sse_operand(src, dst);
EMIT(imm8); EMIT(imm8);
} }
...@@ -2486,6 +2486,11 @@ void Assembler::emit_sse_operand(Register dst, XMMRegister src) { ...@@ -2486,6 +2486,11 @@ void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
} }
void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
EMIT(0xC0 | (dst.code() << 3) | src.code());
}
void Assembler::Print() { void Assembler::Print() {
Disassembler::Decode(isolate(), stdout, buffer_, pc_); Disassembler::Decode(isolate(), stdout, buffer_, pc_);
} }
......
...@@ -1168,6 +1168,7 @@ class Assembler : public AssemblerBase { ...@@ -1168,6 +1168,7 @@ class Assembler : public AssemblerBase {
void emit_sse_operand(XMMRegister reg, const Operand& adr); void emit_sse_operand(XMMRegister reg, const Operand& adr);
void emit_sse_operand(XMMRegister dst, XMMRegister src); void emit_sse_operand(XMMRegister dst, XMMRegister src);
void emit_sse_operand(Register dst, XMMRegister src); void emit_sse_operand(Register dst, XMMRegister src);
void emit_sse_operand(XMMRegister dst, Register src);
byte* addr_at(int pos) { return buffer_ + pos; } byte* addr_at(int pos) { return buffer_ + pos; }
......
...@@ -942,13 +942,13 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer, ...@@ -942,13 +942,13 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer,
case SHORT_IMMEDIATE_INSTR: { case SHORT_IMMEDIATE_INSTR: {
byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1)); byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1));
AppendToBuffer("%s eax, %s", idesc.mnem, NameOfAddress(addr)); AppendToBuffer("%s eax,%s", idesc.mnem, NameOfAddress(addr));
data += 5; data += 5;
break; break;
} }
case BYTE_IMMEDIATE_INSTR: { case BYTE_IMMEDIATE_INSTR: {
AppendToBuffer("%s al, 0x%x", idesc.mnem, data[1]); AppendToBuffer("%s al,0x%x", idesc.mnem, data[1]);
data += 2; data += 2;
break; break;
} }
...@@ -1239,8 +1239,8 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer, ...@@ -1239,8 +1239,8 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer,
get_modrm(*data, &mod, &regop, &rm); get_modrm(*data, &mod, &regop, &rm);
int8_t imm8 = static_cast<int8_t>(data[1]); int8_t imm8 = static_cast<int8_t>(data[1]);
AppendToBuffer("extractps %s,%s,%d", AppendToBuffer("extractps %s,%s,%d",
NameOfCPURegister(regop), NameOfCPURegister(rm),
NameOfXMMRegister(rm), NameOfXMMRegister(regop),
static_cast<int>(imm8)); static_cast<int>(imm8));
data += 2; data += 2;
} else if (*data == 0x22) { } else if (*data == 0x22) {
......
...@@ -2554,15 +2554,15 @@ void Assembler::movdqu(XMMRegister dst, const Operand& src) { ...@@ -2554,15 +2554,15 @@ void Assembler::movdqu(XMMRegister dst, const Operand& src) {
void Assembler::extractps(Register dst, XMMRegister src, byte imm8) { void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
ASSERT(CpuFeatures::IsSupported(SSE4_1)); ASSERT(IsEnabled(SSE4_1));
ASSERT(is_uint8(imm8)); ASSERT(is_uint8(imm8));
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
emit(0x66); emit(0x66);
emit_optional_rex_32(dst, src); emit_optional_rex_32(src, dst);
emit(0x0F); emit(0x0F);
emit(0x3A); emit(0x3A);
emit(0x17); emit(0x17);
emit_sse_operand(dst, src); emit_sse_operand(src, dst);
emit(imm8); emit(imm8);
} }
......
...@@ -1036,14 +1036,14 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) { ...@@ -1036,14 +1036,14 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
get_modrm(*current, &mod, &regop, &rm); get_modrm(*current, &mod, &regop, &rm);
AppendToBuffer("extractps "); // reg/m32, xmm, imm8 AppendToBuffer("extractps "); // reg/m32, xmm, imm8
current += PrintRightOperand(current); current += PrintRightOperand(current);
AppendToBuffer(", %s, %d", NameOfCPURegister(regop), (*current) & 3); AppendToBuffer(",%s,%d", NameOfXMMRegister(regop), (*current) & 3);
current += 1; current += 1;
} else if (third_byte == 0x0b) { } else if (third_byte == 0x0b) {
get_modrm(*current, &mod, &regop, &rm); get_modrm(*current, &mod, &regop, &rm);
// roundsd xmm, xmm/m64, imm8 // roundsd xmm, xmm/m64, imm8
AppendToBuffer("roundsd %s, ", NameOfCPURegister(regop)); AppendToBuffer("roundsd %s,", NameOfXMMRegister(regop));
current += PrintRightOperand(current); current += PrintRightXMMOperand(current);
AppendToBuffer(", %d", (*current) & 3); AppendToBuffer(",%d", (*current) & 3);
current += 1; current += 1;
} else { } else {
UnimplementedInstruction(); UnimplementedInstruction();
...@@ -1062,12 +1062,12 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) { ...@@ -1062,12 +1062,12 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
} // else no immediate displacement. } // else no immediate displacement.
AppendToBuffer("nop"); AppendToBuffer("nop");
} else if (opcode == 0x28) { } else if (opcode == 0x28) {
AppendToBuffer("movapd %s, ", NameOfXMMRegister(regop)); AppendToBuffer("movapd %s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(current); current += PrintRightXMMOperand(current);
} else if (opcode == 0x29) { } else if (opcode == 0x29) {
AppendToBuffer("movapd "); AppendToBuffer("movapd ");
current += PrintRightXMMOperand(current); current += PrintRightXMMOperand(current);
AppendToBuffer(", %s", NameOfXMMRegister(regop)); AppendToBuffer(",%s", NameOfXMMRegister(regop));
} else if (opcode == 0x6E) { } else if (opcode == 0x6E) {
AppendToBuffer("mov%c %s,", AppendToBuffer("mov%c %s,",
rex_w() ? 'q' : 'd', rex_w() ? 'q' : 'd',
...@@ -1081,15 +1081,15 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) { ...@@ -1081,15 +1081,15 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
AppendToBuffer("mov%c ", AppendToBuffer("mov%c ",
rex_w() ? 'q' : 'd'); rex_w() ? 'q' : 'd');
current += PrintRightOperand(current); current += PrintRightOperand(current);
AppendToBuffer(", %s", NameOfXMMRegister(regop)); AppendToBuffer(",%s", NameOfXMMRegister(regop));
} else if (opcode == 0x7F) { } else if (opcode == 0x7F) {
AppendToBuffer("movdqa "); AppendToBuffer("movdqa ");
current += PrintRightXMMOperand(current); current += PrintRightXMMOperand(current);
AppendToBuffer(", %s", NameOfXMMRegister(regop)); AppendToBuffer(",%s", NameOfXMMRegister(regop));
} else if (opcode == 0xD6) { } else if (opcode == 0xD6) {
AppendToBuffer("movq "); AppendToBuffer("movq ");
current += PrintRightXMMOperand(current); current += PrintRightXMMOperand(current);
AppendToBuffer(", %s", NameOfXMMRegister(regop)); AppendToBuffer(",%s", NameOfXMMRegister(regop));
} else if (opcode == 0x50) { } else if (opcode == 0x50) {
AppendToBuffer("movmskpd %s,", NameOfCPURegister(regop)); AppendToBuffer("movmskpd %s,", NameOfCPURegister(regop));
current += PrintRightXMMOperand(current); current += PrintRightXMMOperand(current);
...@@ -1214,7 +1214,7 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) { ...@@ -1214,7 +1214,7 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
} else if (opcode == 0x7E) { } else if (opcode == 0x7E) {
int mod, regop, rm; int mod, regop, rm;
get_modrm(*current, &mod, &regop, &rm); get_modrm(*current, &mod, &regop, &rm);
AppendToBuffer("movq %s, ", NameOfXMMRegister(regop)); AppendToBuffer("movq %s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(current); current += PrintRightXMMOperand(current);
} else { } else {
UnimplementedInstruction(); UnimplementedInstruction();
...@@ -1238,7 +1238,7 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) { ...@@ -1238,7 +1238,7 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
// movaps xmm, xmm/m128 // movaps xmm, xmm/m128
int mod, regop, rm; int mod, regop, rm;
get_modrm(*current, &mod, &regop, &rm); get_modrm(*current, &mod, &regop, &rm);
AppendToBuffer("movaps %s, ", NameOfXMMRegister(regop)); AppendToBuffer("movaps %s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(current); current += PrintRightXMMOperand(current);
} else if (opcode == 0x29) { } else if (opcode == 0x29) {
...@@ -1247,7 +1247,7 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) { ...@@ -1247,7 +1247,7 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
get_modrm(*current, &mod, &regop, &rm); get_modrm(*current, &mod, &regop, &rm);
AppendToBuffer("movaps "); AppendToBuffer("movaps ");
current += PrintRightXMMOperand(current); current += PrintRightXMMOperand(current);
AppendToBuffer(", %s", NameOfXMMRegister(regop)); AppendToBuffer(",%s", NameOfXMMRegister(regop));
} else if (opcode == 0xA2) { } else if (opcode == 0xA2) {
// CPUID // CPUID
...@@ -1264,14 +1264,14 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) { ...@@ -1264,14 +1264,14 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
// xorps xmm, xmm/m128 // xorps xmm, xmm/m128
int mod, regop, rm; int mod, regop, rm;
get_modrm(*current, &mod, &regop, &rm); get_modrm(*current, &mod, &regop, &rm);
AppendToBuffer("xorps %s, ", NameOfXMMRegister(regop)); AppendToBuffer("xorps %s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(current); current += PrintRightXMMOperand(current);
} else if (opcode == 0x50) { } else if (opcode == 0x50) {
// movmskps reg, xmm // movmskps reg, xmm
int mod, regop, rm; int mod, regop, rm;
get_modrm(*current, &mod, &regop, &rm); get_modrm(*current, &mod, &regop, &rm);
AppendToBuffer("movmskps %s, ", NameOfCPURegister(regop)); AppendToBuffer("movmskps %s,", NameOfCPURegister(regop));
current += PrintRightXMMOperand(current); current += PrintRightXMMOperand(current);
} else if ((opcode & 0xF0) == 0x80) { } else if ((opcode & 0xF0) == 0x80) {
...@@ -1450,7 +1450,7 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer, ...@@ -1450,7 +1450,7 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer,
case SHORT_IMMEDIATE_INSTR: { case SHORT_IMMEDIATE_INSTR: {
byte* addr = byte* addr =
reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1)); reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1));
AppendToBuffer("%s rax, %s", idesc.mnem, NameOfAddress(addr)); AppendToBuffer("%s rax,%s", idesc.mnem, NameOfAddress(addr));
data += 5; data += 5;
break; break;
} }
...@@ -1599,7 +1599,7 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer, ...@@ -1599,7 +1599,7 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer,
if (reg == 0) { if (reg == 0) {
AppendToBuffer("nop"); // Common name for xchg rax,rax. AppendToBuffer("nop"); // Common name for xchg rax,rax.
} else { } else {
AppendToBuffer("xchg%c rax, %s", AppendToBuffer("xchg%c rax,%s",
operand_size_code(), operand_size_code(),
NameOfCPURegister(reg)); NameOfCPURegister(reg));
} }
...@@ -1628,12 +1628,12 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer, ...@@ -1628,12 +1628,12 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer,
bool is_32bit = (opcode >= 0xB8); bool is_32bit = (opcode >= 0xB8);
int reg = (opcode & 0x7) | (rex_b() ? 8 : 0); int reg = (opcode & 0x7) | (rex_b() ? 8 : 0);
if (is_32bit) { if (is_32bit) {
AppendToBuffer("mov%c %s, ", AppendToBuffer("mov%c %s,",
operand_size_code(), operand_size_code(),
NameOfCPURegister(reg)); NameOfCPURegister(reg));
data += PrintImmediate(data, OPERAND_DOUBLEWORD_SIZE); data += PrintImmediate(data, OPERAND_DOUBLEWORD_SIZE);
} else { } else {
AppendToBuffer("movb %s, ", AppendToBuffer("movb %s,",
NameOfByteCPURegister(reg)); NameOfByteCPURegister(reg));
data += PrintImmediate(data, OPERAND_BYTE_SIZE); data += PrintImmediate(data, OPERAND_BYTE_SIZE);
} }
...@@ -1755,7 +1755,7 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer, ...@@ -1755,7 +1755,7 @@ int DisassemblerX64::InstructionDecode(v8::internal::Vector<char> out_buffer,
break; break;
case 0x3C: case 0x3C:
AppendToBuffer("cmp al, 0x%x", *reinterpret_cast<int8_t*>(data + 1)); AppendToBuffer("cmp al,0x%x", *reinterpret_cast<int8_t*>(data + 1));
data +=2; data +=2;
break; break;
......
...@@ -564,4 +564,35 @@ TEST(StackAlignmentForSSE2) { ...@@ -564,4 +564,35 @@ TEST(StackAlignmentForSSE2) {
#endif // __GNUC__ #endif // __GNUC__
TEST(AssemblerIa32Extractps) {
CcTest::InitializeVM();
if (!CpuFeatures::IsSupported(SSE4_1)) return;
Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
HandleScope scope(isolate);
v8::internal::byte buffer[256];
MacroAssembler assm(isolate, buffer, sizeof buffer);
{ CpuFeatureScope fscope2(&assm, SSE2);
CpuFeatureScope fscope41(&assm, SSE4_1);
__ movdbl(xmm1, Operand(esp, 4));
__ extractps(eax, xmm1, 0x1);
__ ret(0);
}
CodeDesc desc;
assm.GetCode(&desc);
Code* code = Code::cast(isolate->heap()->CreateCode(
desc,
Code::ComputeFlags(Code::STUB),
Handle<Code>())->ToObjectChecked());
CHECK(code->IsCode());
#ifdef OBJECT_PRINT
Code::cast(code)->Print();
#endif
F4 f = FUNCTION_CAST<F4>(Code::cast(code)->entry());
CHECK_EQ(0x7FF80000, f(OS::nan_value()));
}
#undef __ #undef __
...@@ -35,34 +35,7 @@ ...@@ -35,34 +35,7 @@
#include "serialize.h" #include "serialize.h"
#include "cctest.h" #include "cctest.h"
using v8::internal::Assembler; using namespace v8::internal;
using v8::internal::Code;
using v8::internal::CodeDesc;
using v8::internal::FUNCTION_CAST;
using v8::internal::Immediate;
using v8::internal::Isolate;
using v8::internal::Label;
using v8::internal::OS;
using v8::internal::Operand;
using v8::internal::byte;
using v8::internal::greater;
using v8::internal::less_equal;
using v8::internal::equal;
using v8::internal::not_equal;
using v8::internal::r13;
using v8::internal::r15;
using v8::internal::r8;
using v8::internal::r9;
using v8::internal::rax;
using v8::internal::rbx;
using v8::internal::rbp;
using v8::internal::rcx;
using v8::internal::rdi;
using v8::internal::rdx;
using v8::internal::rsi;
using v8::internal::rsp;
using v8::internal::times_1;
using v8::internal::xmm0;
// Test the x64 assembler by compiling some simple functions into // Test the x64 assembler by compiling some simple functions into
// a buffer and executing them. These tests do not initialize the // a buffer and executing them. These tests do not initialize the
...@@ -77,13 +50,14 @@ using v8::internal::xmm0; ...@@ -77,13 +50,14 @@ using v8::internal::xmm0;
typedef int (*F0)(); typedef int (*F0)();
typedef int (*F1)(int64_t x); typedef int (*F1)(int64_t x);
typedef int (*F2)(int64_t x, int64_t y); typedef int (*F2)(int64_t x, int64_t y);
typedef int (*F3)(double x);
#ifdef _WIN64 #ifdef _WIN64
static const v8::internal::Register arg1 = rcx; static const Register arg1 = rcx;
static const v8::internal::Register arg2 = rdx; static const Register arg2 = rdx;
#else #else
static const v8::internal::Register arg1 = rdi; static const Register arg1 = rdi;
static const v8::internal::Register arg2 = rsi; static const Register arg2 = rsi;
#endif #endif
#define __ assm. #define __ assm.
...@@ -366,7 +340,7 @@ TEST(AssemblerX64LabelChaining) { ...@@ -366,7 +340,7 @@ TEST(AssemblerX64LabelChaining) {
TEST(AssemblerMultiByteNop) { TEST(AssemblerMultiByteNop) {
CcTest::InitializeVM(); CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate()); v8::HandleScope scope(CcTest::isolate());
v8::internal::byte buffer[1024]; byte buffer[1024];
Isolate* isolate = CcTest::i_isolate(); Isolate* isolate = CcTest::i_isolate();
Assembler assm(isolate, buffer, sizeof(buffer)); Assembler assm(isolate, buffer, sizeof(buffer));
__ push(rbx); __ push(rbx);
...@@ -420,7 +394,7 @@ TEST(AssemblerMultiByteNop) { ...@@ -420,7 +394,7 @@ TEST(AssemblerMultiByteNop) {
Code* code = Code::cast(isolate->heap()->CreateCode( Code* code = Code::cast(isolate->heap()->CreateCode(
desc, desc,
Code::ComputeFlags(Code::STUB), Code::ComputeFlags(Code::STUB),
v8::internal::Handle<Code>())->ToObjectChecked()); Handle<Code>())->ToObjectChecked());
CHECK(code->IsCode()); CHECK(code->IsCode());
F0 f = FUNCTION_CAST<F0>(code->entry()); F0 f = FUNCTION_CAST<F0>(code->entry());
...@@ -434,7 +408,7 @@ TEST(AssemblerMultiByteNop) { ...@@ -434,7 +408,7 @@ TEST(AssemblerMultiByteNop) {
void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) { void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope scope(CcTest::isolate()); v8::HandleScope scope(CcTest::isolate());
v8::internal::byte buffer[1024]; byte buffer[1024];
CHECK(args[0]->IsArray()); CHECK(args[0]->IsArray());
v8::Local<v8::Array> vec = v8::Local<v8::Array>::Cast(args[0]); v8::Local<v8::Array> vec = v8::Local<v8::Array>::Cast(args[0]);
...@@ -472,7 +446,7 @@ void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -472,7 +446,7 @@ void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) {
Code* code = Code::cast(isolate->heap()->CreateCode( Code* code = Code::cast(isolate->heap()->CreateCode(
desc, desc,
Code::ComputeFlags(Code::STUB), Code::ComputeFlags(Code::STUB),
v8::internal::Handle<Code>())->ToObjectChecked()); Handle<Code>())->ToObjectChecked());
CHECK(code->IsCode()); CHECK(code->IsCode());
F0 f = FUNCTION_CAST<F0>(code->entry()); F0 f = FUNCTION_CAST<F0>(code->entry());
...@@ -517,4 +491,33 @@ TEST(StackAlignmentForSSE2) { ...@@ -517,4 +491,33 @@ TEST(StackAlignmentForSSE2) {
#endif // __GNUC__ #endif // __GNUC__
TEST(AssemblerX64Extractps) {
CcTest::InitializeVM();
if (!CpuFeatures::IsSupported(SSE4_1)) return;
v8::HandleScope scope(CcTest::isolate());
byte buffer[256];
Isolate* isolate = CcTest::i_isolate();
Assembler assm(isolate, buffer, sizeof(buffer));
{ CpuFeatureScope fscope2(&assm, SSE4_1);
__ extractps(rax, xmm0, 0x1);
__ ret(0);
}
CodeDesc desc;
assm.GetCode(&desc);
Code* code = Code::cast(isolate->heap()->CreateCode(
desc,
Code::ComputeFlags(Code::STUB),
Handle<Code>())->ToObjectChecked());
CHECK(code->IsCode());
#ifdef OBJECT_PRINT
Code::cast(code)->Print();
#endif
F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry());
CHECK_EQ(0x7FF80000, f(OS::nan_value()));
}
#undef __ #undef __
...@@ -429,6 +429,7 @@ TEST(DisasmIa320) { ...@@ -429,6 +429,7 @@ TEST(DisasmIa320) {
CpuFeatureScope scope(&assm, SSE4_1); CpuFeatureScope scope(&assm, SSE4_1);
__ pextrd(eax, xmm0, 1); __ pextrd(eax, xmm0, 1);
__ pinsrd(xmm1, eax, 0); __ pinsrd(xmm1, eax, 0);
__ extractps(eax, xmm1, 0);
} }
} }
......
...@@ -392,6 +392,13 @@ TEST(DisasmX64) { ...@@ -392,6 +392,13 @@ TEST(DisasmX64) {
} }
} }
{
if (CpuFeatures::IsSupported(SSE4_1)) {
CpuFeatureScope scope(&assm, SSE4_1);
__ extractps(rax, xmm1, 0);
}
}
// Nop instructions // Nop instructions
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
__ Nop(i); __ Nop(i);
......
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