[turbofan] IA: Float64ToUint32 supports mem operand
BUG= R=titzer@chromium.org Review URL: https://codereview.chromium.org/582713002 Patch from Weiliang Lin <weiliang.lin@intel.com>. git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24092 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
2d3b7f20b1
commit
8892385565
@ -303,8 +303,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
||||
case kSSEFloat64ToUint32: {
|
||||
XMMRegister scratch = xmm0;
|
||||
__ Move(scratch, -2147483648.0);
|
||||
// TODO(turbofan): IA32 SSE subsd() should take an operand.
|
||||
__ addsd(scratch, i.InputDoubleRegister(0));
|
||||
__ addsd(scratch, i.InputOperand(0));
|
||||
__ cvttsd2si(i.OutputRegister(), scratch);
|
||||
__ add(i.OutputRegister(), Immediate(0x80000000));
|
||||
break;
|
||||
|
@ -376,9 +376,7 @@ void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {
|
||||
|
||||
void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) {
|
||||
IA32OperandGenerator g(this);
|
||||
// TODO(turbofan): IA32 SSE subsd() should take an operand.
|
||||
Emit(kSSEFloat64ToUint32, g.DefineAsRegister(node),
|
||||
g.UseRegister(node->InputAt(0)));
|
||||
Emit(kSSEFloat64ToUint32, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
|
||||
}
|
||||
|
||||
|
||||
|
@ -469,8 +469,12 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
||||
break;
|
||||
}
|
||||
case kSSEFloat64ToUint32: {
|
||||
// TODO(turbofan): X64 SSE cvttsd2siq should support operands.
|
||||
__ cvttsd2siq(i.OutputRegister(), i.InputDoubleRegister(0));
|
||||
RegisterOrOperand input = i.InputRegisterOrOperand(0);
|
||||
if (input.type == kDoubleRegister) {
|
||||
__ cvttsd2siq(i.OutputRegister(), input.double_reg);
|
||||
} else {
|
||||
__ cvttsd2siq(i.OutputRegister(), input.operand);
|
||||
}
|
||||
__ andl(i.OutputRegister(), i.OutputRegister()); // clear upper bits.
|
||||
// TODO(turbofan): generated code should not look at the upper 32 bits
|
||||
// of the result, but those bits could escape to the outside world.
|
||||
|
@ -500,9 +500,7 @@ void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {
|
||||
|
||||
void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) {
|
||||
X64OperandGenerator g(this);
|
||||
// TODO(turbofan): X64 SSE cvttsd2siq should support operands.
|
||||
Emit(kSSEFloat64ToUint32, g.DefineAsRegister(node),
|
||||
g.UseRegister(node->InputAt(0)));
|
||||
Emit(kSSEFloat64ToUint32, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
|
||||
}
|
||||
|
||||
|
||||
|
@ -2014,6 +2014,15 @@ void Assembler::subsd(XMMRegister dst, XMMRegister src) {
|
||||
}
|
||||
|
||||
|
||||
void Assembler::subsd(XMMRegister dst, const Operand& src) {
|
||||
EnsureSpace ensure_space(this);
|
||||
EMIT(0xF2);
|
||||
EMIT(0x0F);
|
||||
EMIT(0x5C);
|
||||
emit_sse_operand(dst, src);
|
||||
}
|
||||
|
||||
|
||||
void Assembler::divsd(XMMRegister dst, XMMRegister src) {
|
||||
EnsureSpace ensure_space(this);
|
||||
EMIT(0xF2);
|
||||
|
@ -956,6 +956,7 @@ class Assembler : public AssemblerBase {
|
||||
void addsd(XMMRegister dst, XMMRegister src);
|
||||
void addsd(XMMRegister dst, const Operand& src);
|
||||
void subsd(XMMRegister dst, XMMRegister src);
|
||||
void subsd(XMMRegister dst, const Operand& src);
|
||||
void mulsd(XMMRegister dst, XMMRegister src);
|
||||
void mulsd(XMMRegister dst, const Operand& src);
|
||||
void divsd(XMMRegister dst, XMMRegister src);
|
||||
|
@ -2629,6 +2629,16 @@ void Assembler::cvttsd2siq(Register dst, XMMRegister src) {
|
||||
}
|
||||
|
||||
|
||||
void Assembler::cvttsd2siq(Register dst, const Operand& src) {
|
||||
EnsureSpace ensure_space(this);
|
||||
emit(0xF2);
|
||||
emit_rex_64(dst, src);
|
||||
emit(0x0F);
|
||||
emit(0x2C);
|
||||
emit_sse_operand(dst, src);
|
||||
}
|
||||
|
||||
|
||||
void Assembler::cvtlsi2sd(XMMRegister dst, const Operand& src) {
|
||||
EnsureSpace ensure_space(this);
|
||||
emit(0xF2);
|
||||
@ -2900,6 +2910,12 @@ void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
|
||||
}
|
||||
|
||||
|
||||
void Assembler::emit_sse_operand(Register reg, const Operand& adr) {
|
||||
Register ireg = {reg.code()};
|
||||
emit_operand(ireg, adr);
|
||||
}
|
||||
|
||||
|
||||
void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
|
||||
emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
|
||||
}
|
||||
|
@ -1048,6 +1048,7 @@ class Assembler : public AssemblerBase {
|
||||
void cvttsd2si(Register dst, const Operand& src);
|
||||
void cvttsd2si(Register dst, XMMRegister src);
|
||||
void cvttsd2siq(Register dst, XMMRegister src);
|
||||
void cvttsd2siq(Register dst, const Operand& src);
|
||||
|
||||
void cvtlsi2sd(XMMRegister dst, const Operand& src);
|
||||
void cvtlsi2sd(XMMRegister dst, Register src);
|
||||
@ -1316,6 +1317,7 @@ class Assembler : public AssemblerBase {
|
||||
// The first argument is the reg field, the second argument is the r/m field.
|
||||
void emit_sse_operand(XMMRegister dst, XMMRegister src);
|
||||
void emit_sse_operand(XMMRegister reg, const Operand& adr);
|
||||
void emit_sse_operand(Register reg, const Operand& adr);
|
||||
void emit_sse_operand(XMMRegister dst, Register src);
|
||||
void emit_sse_operand(Register dst, XMMRegister src);
|
||||
|
||||
|
@ -3232,6 +3232,46 @@ TEST(RunChangeFloat64ToInt32_spilled) {
|
||||
}
|
||||
|
||||
|
||||
TEST(RunChangeFloat64ToUint32_spilled) {
|
||||
RawMachineAssemblerTester<uint32_t> m;
|
||||
const int kNumInputs = 32;
|
||||
int32_t magic = 0x786234;
|
||||
double input[kNumInputs];
|
||||
uint32_t result[kNumInputs];
|
||||
Node* input_node[kNumInputs];
|
||||
|
||||
for (int i = 0; i < kNumInputs; i++) {
|
||||
input_node[i] =
|
||||
m.Load(kMachFloat64, m.PointerConstant(&input), m.Int32Constant(i * 8));
|
||||
}
|
||||
|
||||
for (int i = 0; i < kNumInputs; i++) {
|
||||
m.Store(kMachUint32, m.PointerConstant(&result), m.Int32Constant(i * 4),
|
||||
m.ChangeFloat64ToUint32(input_node[i]));
|
||||
}
|
||||
|
||||
m.Return(m.Int32Constant(magic));
|
||||
|
||||
for (int i = 0; i < kNumInputs; i++) {
|
||||
if (i % 2) {
|
||||
input[i] = 100 + i + 2147483648;
|
||||
} else {
|
||||
input[i] = 100 + i;
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_EQ(magic, m.Call());
|
||||
|
||||
for (int i = 0; i < kNumInputs; i++) {
|
||||
if (i % 2) {
|
||||
CHECK_EQ(result[i], 100 + i + 2147483648);
|
||||
} else {
|
||||
CHECK_EQ(result[i], 100 + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(RunDeadChangeFloat64ToInt32) {
|
||||
RawMachineAssemblerTester<int32_t> m;
|
||||
const int magic = 0x88abcda4;
|
||||
|
@ -416,6 +416,7 @@ TEST(DisasmIa320) {
|
||||
__ addsd(xmm1, xmm0);
|
||||
__ mulsd(xmm1, xmm0);
|
||||
__ subsd(xmm1, xmm0);
|
||||
__ subsd(xmm1, Operand(ebx, ecx, times_4, 10000));
|
||||
__ divsd(xmm1, xmm0);
|
||||
__ ucomisd(xmm0, xmm1);
|
||||
__ cmpltsd(xmm0, xmm1);
|
||||
|
@ -378,6 +378,7 @@ TEST(DisasmX64) {
|
||||
__ cvttsd2si(rdx, Operand(rbx, rcx, times_4, 10000));
|
||||
__ cvttsd2si(rdx, xmm1);
|
||||
__ cvttsd2siq(rdx, xmm1);
|
||||
__ cvttsd2siq(rdx, Operand(rbx, rcx, times_4, 10000));
|
||||
__ movsd(xmm1, Operand(rbx, rcx, times_4, 10000));
|
||||
__ movsd(Operand(rbx, rcx, times_4, 10000), xmm1);
|
||||
// 128 bit move instructions.
|
||||
|
Loading…
Reference in New Issue
Block a user