__ cvtss2sd(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;
case kSSECvtsd2ss:
- __ cvtsd2ss(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+ __ cvtsd2ss(i.OutputDoubleRegister(), i.InputOperand(0));
break;
case kSSEFloat64ToInt32:
__ cvttsd2si(i.OutputRegister(), i.InputOperand(0));
void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
IA32OperandGenerator g(this);
- // TODO(turbofan): IA32 SSE conversions should take an operand.
- Emit(kSSECvtsd2ss, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+ Emit(kSSECvtsd2ss, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
}
__ cvtss2sd(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;
case kSSECvtsd2ss:
- __ cvtsd2ss(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+ if (instr->InputAt(0)->IsDoubleRegister()) {
+ __ cvtsd2ss(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+ } else {
+ __ cvtsd2ss(i.OutputDoubleRegister(), i.InputOperand(0));
+ }
break;
case kSSEFloat64ToInt32:
if (instr->InputAt(0)->IsDoubleRegister()) {
void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
X64OperandGenerator g(this);
- // TODO(turbofan): X64 SSE conversions should take an operand.
- Emit(kSSECvtsd2ss, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+ Emit(kSSECvtsd2ss, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
}
}
-void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
+void Assembler::cvtsd2ss(XMMRegister dst, const Operand& src) {
EnsureSpace ensure_space(this);
EMIT(0xF2);
EMIT(0x0F);
void cvtsi2sd(XMMRegister dst, Register src) { cvtsi2sd(dst, Operand(src)); }
void cvtsi2sd(XMMRegister dst, const Operand& src);
void cvtss2sd(XMMRegister dst, XMMRegister src);
- void cvtsd2ss(XMMRegister dst, XMMRegister src);
+ void cvtsd2ss(XMMRegister dst, const Operand& src);
+ void cvtsd2ss(XMMRegister dst, XMMRegister src) {
+ cvtsd2ss(dst, Operand(src));
+ }
void addsd(XMMRegister dst, XMMRegister src);
void addsd(XMMRegister dst, const Operand& src);
}
+void Assembler::cvtsd2ss(XMMRegister dst, const Operand& src) {
+ EnsureSpace ensure_space(this);
+ emit(0xF2);
+ emit_optional_rex_32(dst, src);
+ emit(0x0F);
+ emit(0x5A);
+ emit_sse_operand(dst, src);
+}
+
+
void Assembler::cvtsd2si(Register dst, XMMRegister src) {
EnsureSpace ensure_space(this);
emit(0xF2);
void cvtss2sd(XMMRegister dst, XMMRegister src);
void cvtss2sd(XMMRegister dst, const Operand& src);
void cvtsd2ss(XMMRegister dst, XMMRegister src);
+ void cvtsd2ss(XMMRegister dst, const Operand& src);
void cvtsd2si(Register dst, XMMRegister src);
void cvtsd2siq(Register dst, XMMRegister src);
}
+TEST(RunTruncateFloat64ToFloat32_spilled) {
+ RawMachineAssemblerTester<uint32_t> m;
+ const int kNumInputs = 32;
+ int32_t magic = 0x786234;
+ double input[kNumInputs];
+ float 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(kMachFloat32, m.PointerConstant(&result), m.Int32Constant(i * 4),
+ m.TruncateFloat64ToFloat32(input_node[i]));
+ }
+
+ m.Return(m.Int32Constant(magic));
+
+ for (int i = 0; i < kNumInputs; i++) {
+ input[i] = 0.1 + i;
+ }
+
+ CHECK_EQ(magic, m.Call());
+
+ for (int i = 0; i < kNumInputs; i++) {
+ CHECK_EQ(result[i], DoubleToFloat32(input[i]));
+ }
+}
+
+
TEST(RunDeadChangeFloat64ToInt32) {
RawMachineAssemblerTester<int32_t> m;
const int magic = 0x88abcda4;
// Move operation
__ movaps(xmm0, xmm1);
__ shufps(xmm0, xmm0, 0x0);
+ __ cvtsd2ss(xmm0, xmm1);
+ __ cvtsd2ss(xmm0, Operand(ebx, ecx, times_4, 10000));
// logic operation
__ andps(xmm0, xmm1);
// Move operation
__ cvttss2si(rdx, Operand(rbx, rcx, times_4, 10000));
__ cvttss2si(rdx, xmm1);
+ __ cvtsd2ss(xmm0, xmm1);
+ __ cvtsd2ss(xmm0, Operand(rbx, rcx, times_4, 10000));
__ movaps(xmm0, xmm1);
// logic operation