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