[turbofan] IA: Uint32ToFloat64 supports mem operand.
BUG= R=dcarney@chromium.org Review URL: https://codereview.chromium.org/583963002 Patch from Jing Bao <jing.bao@intel.com>. git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24318 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
51a2f97d80
commit
49ffb141d9
@ -370,8 +370,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
||||
__ cvtsi2sd(i.OutputDoubleRegister(), i.InputOperand(0));
|
||||
break;
|
||||
case kSSEUint32ToFloat64:
|
||||
// TODO(turbofan): IA32 SSE LoadUint32() should take an operand.
|
||||
__ LoadUint32(i.OutputDoubleRegister(), i.InputRegister(0));
|
||||
__ LoadUint32(i.OutputDoubleRegister(), i.InputOperand(0));
|
||||
break;
|
||||
case kIA32Movsxbl:
|
||||
__ movsx_b(i.OutputRegister(), i.MemoryOperand());
|
||||
|
@ -133,6 +133,18 @@ TEST_F(InstructionSelectorTest, BetterLeftOperandTestMulBinop) {
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Conversions.
|
||||
|
||||
TEST_F(InstructionSelectorTest, ChangeUint32ToFloat64WithParameter) {
|
||||
StreamBuilder m(this, kMachFloat64, kMachUint32);
|
||||
m.Return(m.ChangeUint32ToFloat64(m.Parameter(0)));
|
||||
Stream s = m.Build();
|
||||
ASSERT_EQ(1U, s.size());
|
||||
EXPECT_EQ(kSSEUint32ToFloat64, s[0]->arch_opcode());
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Loads and stores
|
||||
|
||||
|
@ -459,9 +459,7 @@ void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
|
||||
|
||||
void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) {
|
||||
IA32OperandGenerator g(this);
|
||||
// TODO(turbofan): IA32 SSE LoadUint32() should take an operand.
|
||||
Emit(kSSEUint32ToFloat64, g.DefineAsRegister(node),
|
||||
g.UseRegister(node->InputAt(0)));
|
||||
Emit(kSSEUint32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
|
||||
}
|
||||
|
||||
|
||||
|
@ -424,8 +424,11 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
||||
}
|
||||
break;
|
||||
case kSSEUint32ToFloat64:
|
||||
// TODO(turbofan): X64 SSE cvtqsi2sd should support operands.
|
||||
__ cvtqsi2sd(i.OutputDoubleRegister(), i.InputRegister(0));
|
||||
if (instr->InputAt(0)->IsRegister()) {
|
||||
__ cvtqsi2sd(i.OutputDoubleRegister(), i.InputRegister(0));
|
||||
} else {
|
||||
__ cvtqsi2sd(i.OutputDoubleRegister(), i.InputOperand(0));
|
||||
}
|
||||
break;
|
||||
case kX64Movsxbl:
|
||||
__ movsxbl(i.OutputRegister(), i.MemoryOperand());
|
||||
|
@ -33,6 +33,15 @@ TEST_F(InstructionSelectorTest, ChangeInt32ToInt64WithParameter) {
|
||||
}
|
||||
|
||||
|
||||
TEST_F(InstructionSelectorTest, ChangeUint32ToFloat64WithParameter) {
|
||||
StreamBuilder m(this, kMachFloat64, kMachUint32);
|
||||
m.Return(m.ChangeUint32ToFloat64(m.Parameter(0)));
|
||||
Stream s = m.Build();
|
||||
ASSERT_EQ(1U, s.size());
|
||||
EXPECT_EQ(kSSEUint32ToFloat64, s[0]->arch_opcode());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(InstructionSelectorTest, ChangeUint32ToUint64WithParameter) {
|
||||
StreamBuilder m(this, kMachUint64, kMachUint32);
|
||||
m.Return(m.ChangeUint32ToUint64(m.Parameter(0)));
|
||||
|
@ -600,9 +600,7 @@ void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
|
||||
|
||||
void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) {
|
||||
X64OperandGenerator g(this);
|
||||
// TODO(turbofan): X64 SSE cvtqsi2sd should support operands.
|
||||
Emit(kSSEUint32ToFloat64, g.DefineAsRegister(node),
|
||||
g.UseRegister(node->InputAt(0)));
|
||||
Emit(kSSEUint32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
|
||||
}
|
||||
|
||||
|
||||
|
@ -345,12 +345,10 @@ void MacroAssembler::TruncateHeapNumberToI(Register result_reg,
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::LoadUint32(XMMRegister dst,
|
||||
Register src) {
|
||||
void MacroAssembler::LoadUint32(XMMRegister dst, const Operand& src) {
|
||||
Label done;
|
||||
cmp(src, Immediate(0));
|
||||
ExternalReference uint32_bias =
|
||||
ExternalReference::address_of_uint32_bias();
|
||||
ExternalReference uint32_bias = ExternalReference::address_of_uint32_bias();
|
||||
Cvtsi2sd(dst, src);
|
||||
j(not_sign, &done, Label::kNear);
|
||||
addsd(dst, Operand::StaticVariable(uint32_bias));
|
||||
|
@ -486,7 +486,10 @@ class MacroAssembler: public Assembler {
|
||||
j(not_carry, is_smi);
|
||||
}
|
||||
|
||||
void LoadUint32(XMMRegister dst, Register src);
|
||||
void LoadUint32(XMMRegister dst, Register src) {
|
||||
LoadUint32(dst, Operand(src));
|
||||
}
|
||||
void LoadUint32(XMMRegister dst, const Operand& src);
|
||||
|
||||
// Jump the register contains a smi.
|
||||
inline void JumpIfSmi(Register value,
|
||||
|
@ -2683,6 +2683,16 @@ void Assembler::cvtlsi2ss(XMMRegister dst, Register src) {
|
||||
}
|
||||
|
||||
|
||||
void Assembler::cvtqsi2sd(XMMRegister dst, const Operand& src) {
|
||||
EnsureSpace ensure_space(this);
|
||||
emit(0xF2);
|
||||
emit_rex_64(dst, src);
|
||||
emit(0x0F);
|
||||
emit(0x2A);
|
||||
emit_sse_operand(dst, src);
|
||||
}
|
||||
|
||||
|
||||
void Assembler::cvtqsi2sd(XMMRegister dst, Register src) {
|
||||
EnsureSpace ensure_space(this);
|
||||
emit(0xF2);
|
||||
|
@ -3102,6 +3102,38 @@ TEST(RunChangeUint32ToFloat64_B) {
|
||||
}
|
||||
|
||||
|
||||
TEST(RunChangeUint32ToFloat64_spilled) {
|
||||
RawMachineAssemblerTester<int32_t> m;
|
||||
const int kNumInputs = 32;
|
||||
int32_t magic = 0x786234;
|
||||
uint32_t input[kNumInputs];
|
||||
double result[kNumInputs];
|
||||
Node* input_node[kNumInputs];
|
||||
|
||||
for (int i = 0; i < kNumInputs; i++) {
|
||||
input_node[i] =
|
||||
m.Load(kMachUint32, m.PointerConstant(&input), m.Int32Constant(i * 4));
|
||||
}
|
||||
|
||||
for (int i = 0; i < kNumInputs; i++) {
|
||||
m.Store(kMachFloat64, m.PointerConstant(&result), m.Int32Constant(i * 8),
|
||||
m.ChangeUint32ToFloat64(input_node[i]));
|
||||
}
|
||||
|
||||
m.Return(m.Int32Constant(magic));
|
||||
|
||||
for (int i = 0; i < kNumInputs; i++) {
|
||||
input[i] = 100 + i;
|
||||
}
|
||||
|
||||
CHECK_EQ(magic, m.Call());
|
||||
|
||||
for (int i = 0; i < kNumInputs; i++) {
|
||||
CHECK_EQ(result[i], static_cast<double>(100 + i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(RunChangeFloat64ToInt32_A) {
|
||||
RawMachineAssemblerTester<int32_t> m;
|
||||
int32_t magic = 0x786234;
|
||||
|
@ -380,6 +380,8 @@ TEST(DisasmX64) {
|
||||
__ cvttsd2si(rdx, xmm1);
|
||||
__ cvttsd2siq(rdx, xmm1);
|
||||
__ cvttsd2siq(rdx, Operand(rbx, rcx, times_4, 10000));
|
||||
__ cvtqsi2sd(xmm1, Operand(rbx, rcx, times_4, 10000));
|
||||
__ cvtqsi2sd(xmm1, rdx);
|
||||
__ 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