Revision: 19704
Author: [email protected]
Date: Fri Mar 7 09:05:10 2014 UTC
Log: Introduce intrinsics for double values in Javascript.
[email protected]
Review URL: https://codereview.chromium.org/178583006
http://code.google.com/p/v8/source/detail?r=19704
Added:
/branches/bleeding_edge/test/mjsunit/double-intrinsics.js
Modified:
/branches/bleeding_edge/src/a64/lithium-a64.cc
/branches/bleeding_edge/src/a64/lithium-a64.h
/branches/bleeding_edge/src/a64/lithium-codegen-a64.cc
/branches/bleeding_edge/src/arm/lithium-arm.cc
/branches/bleeding_edge/src/arm/lithium-arm.h
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/full-codegen.cc
/branches/bleeding_edge/src/hydrogen-instructions.h
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-ia32.h
/branches/bleeding_edge/src/runtime.cc
/branches/bleeding_edge/src/runtime.h
/branches/bleeding_edge/src/x64/assembler-x64.cc
/branches/bleeding_edge/src/x64/assembler-x64.h
/branches/bleeding_edge/src/x64/disasm-x64.cc
/branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
/branches/bleeding_edge/src/x64/lithium-x64.cc
/branches/bleeding_edge/src/x64/lithium-x64.h
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/double-intrinsics.js Fri Mar 7
09:05:10 2014 UTC
@@ -0,0 +1,37 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+function assertDoubleBits(hi, lo, x) {
+ hi = hi | 0;
+ lo = lo | 0;
+ assertEquals(x, %_ConstructDouble(hi, lo));
+ assertEquals(hi, %_DoubleHi(x));
+ assertEquals(lo, %_DoubleLo(x));
+ assertEquals(x, %_ConstructDouble(%_DoubleHi(x), %_DoubleLo(x)));
+}
+
+
+var tests = [0x7ff80000, 0x00000000, NaN,
+ 0x7ff00000, 0x00000000, Infinity,
+ 0xfff00000, 0x00000000, -Infinity,
+ 0x80000000, 0x00000000, -0,
+ 0x400921fb, 0x54442d18, Math.PI,
+ 0xc00921fb, 0x54442d18, -Math.PI,
+ 0x4005bf0a, 0x8b145769, Math.E,
+ 0xc005bf0a, 0x8b145769, -Math.E,
+ 0xbfe80000, 0x00000000, -0.75];
+
+
+for (var i = 0; i < tests.length; i += 3) {
+ assertDoubleBits(tests[i], tests[i + 1], tests[i + 2]);
+}
+
+%OptimizeFunctionOnNextCall(assertDoubleBits);
+
+for (var i = 0; i < tests.length; i += 3) {
+ assertDoubleBits(tests[i], tests[i + 1], tests[i + 2]);
+ assertOptimized(assertDoubleBits);
+}
=======================================
--- /branches/bleeding_edge/src/a64/lithium-a64.cc Tue Mar 4 12:48:17 2014
UTC
+++ /branches/bleeding_edge/src/a64/lithium-a64.cc Fri Mar 7 09:05:10 2014
UTC
@@ -1867,6 +1867,21 @@
return MarkAsCall(
DefineFixed(new(zone()) LRegExpLiteral(context), x0), instr);
}
+
+
+LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) {
+ HValue* value = instr->value();
+ ASSERT(value->representation().IsDouble());
+ return DefineAsRegister(new(zone()) LDoubleBits(UseRegister(value)));
+}
+
+
+LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) {
+ LOperand* lo = UseRegister(instr->lo());
+ LOperand* hi = UseRegister(instr->hi());
+ LOperand* temp = TempRegister();
+ return DefineAsRegister(new(zone()) LConstructDouble(hi, lo, temp));
+}
LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
=======================================
--- /branches/bleeding_edge/src/a64/lithium-a64.h Thu Feb 20 11:22:33 2014
UTC
+++ /branches/bleeding_edge/src/a64/lithium-a64.h Fri Mar 7 09:05:10 2014
UTC
@@ -84,12 +84,14 @@
V(ConstantI) \
V(ConstantS) \
V(ConstantT) \
+ V(ConstructDouble) \
V(Context) \
V(DateField) \
V(DebugBreak) \
V(DeclareGlobals) \
V(Deoptimize) \
V(DivI) \
+ V(DoubleBits) \
V(DoubleToIntOrSmi) \
V(Drop) \
V(Dummy) \
@@ -1011,6 +1013,35 @@
};
+class LDoubleBits V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LDoubleBits(LOperand* value) {
+ inputs_[0] = value;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(DoubleBits, "double-bits")
+ DECLARE_HYDROGEN_ACCESSOR(DoubleBits)
+};
+
+
+class LConstructDouble V8_FINAL : public LTemplateInstruction<1, 2, 1> {
+ public:
+ LConstructDouble(LOperand* hi, LOperand* lo, LOperand* temp) {
+ inputs_[0] = hi;
+ inputs_[1] = lo;
+ temps_[0] = temp;
+ }
+
+ LOperand* hi() { return inputs_[0]; }
+ LOperand* lo() { return inputs_[1]; }
+ LOperand* temp() { return temps_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(ConstructDouble, "construct-double")
+};
+
+
class LClassOfTestAndBranch V8_FINAL : public LControlInstruction<1, 2> {
public:
LClassOfTestAndBranch(LOperand* value, LOperand* temp1, LOperand* temp2)
{
=======================================
--- /branches/bleeding_edge/src/a64/lithium-codegen-a64.cc Thu Mar 6
13:07:51 2014 UTC
+++ /branches/bleeding_edge/src/a64/lithium-codegen-a64.cc Fri Mar 7
09:05:10 2014 UTC
@@ -2221,6 +2221,30 @@
__ Bind(&done);
}
+
+
+void LCodeGen::DoDoubleBits(LDoubleBits* instr) {
+ DoubleRegister value_reg = ToDoubleRegister(instr->value());
+ Register result_reg = ToRegister(instr->result());
+ if (instr->hydrogen()->bits() == HDoubleBits::HIGH) {
+ __ Fmov(result_reg, value_reg);
+ __ Mov(result_reg, Operand(result_reg, LSR, 32));
+ } else {
+ __ Fmov(result_reg.W(), value_reg.S());
+ }
+}
+
+
+void LCodeGen::DoConstructDouble(LConstructDouble* instr) {
+ Register hi_reg = ToRegister(instr->hi());
+ Register lo_reg = ToRegister(instr->lo());
+ Register temp = ToRegister(instr->temp());
+ DoubleRegister result_reg = ToDoubleRegister(instr->result());
+
+ __ And(temp, lo_reg, Operand(0xffffffff));
+ __ Orr(temp, temp, Operand(hi_reg, LSL, 32));
+ __ Fmov(result_reg, temp);
+}
void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc Tue Mar 4 12:48:17 2014
UTC
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc Fri Mar 7 09:05:10 2014
UTC
@@ -1937,6 +1937,20 @@
return AssignEnvironment(DefineAsRegister(result));
}
}
+
+
+LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) {
+ HValue* value = instr->value();
+ ASSERT(value->representation().IsDouble());
+ return DefineAsRegister(new(zone()) LDoubleBits(UseRegister(value)));
+}
+
+
+LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) {
+ LOperand* lo = UseRegister(instr->lo());
+ LOperand* hi = UseRegister(instr->hi());
+ return DefineAsRegister(new(zone()) LConstructDouble(hi, lo));
+}
LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.h Tue Mar 4 12:45:00 2014
UTC
+++ /branches/bleeding_edge/src/arm/lithium-arm.h Fri Mar 7 09:05:10 2014
UTC
@@ -80,12 +80,14 @@
V(ConstantI) \
V(ConstantS) \
V(ConstantT) \
+ V(ConstructDouble) \
V(Context) \
V(DateField) \
V(DebugBreak) \
V(DeclareGlobals) \
V(Deoptimize) \
V(DivI) \
+ V(DoubleBits) \
V(DoubleToI) \
V(DoubleToSmi) \
V(Drop) \
@@ -2386,6 +2388,33 @@
};
+class LDoubleBits V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LDoubleBits(LOperand* value) {
+ inputs_[0] = value;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(DoubleBits, "double-bits")
+ DECLARE_HYDROGEN_ACCESSOR(DoubleBits)
+};
+
+
+class LConstructDouble V8_FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+ LConstructDouble(LOperand* hi, LOperand* lo) {
+ inputs_[0] = hi;
+ inputs_[1] = lo;
+ }
+
+ LOperand* hi() { return inputs_[0]; }
+ LOperand* lo() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(ConstructDouble, "construct-double")
+};
+
+
class LAllocate V8_FINAL : public LTemplateInstruction<1, 2, 2> {
public:
LAllocate(LOperand* context,
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Thu Mar 6
13:07:51 2014 UTC
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Fri Mar 7
09:05:10 2014 UTC
@@ -5224,6 +5224,26 @@
__ bind(&done);
}
+
+
+void LCodeGen::DoDoubleBits(LDoubleBits* instr) {
+ DwVfpRegister value_reg = ToDoubleRegister(instr->value());
+ Register result_reg = ToRegister(instr->result());
+ if (instr->hydrogen()->bits() == HDoubleBits::HIGH) {
+ __ VmovHigh(result_reg, value_reg);
+ } else {
+ __ VmovLow(result_reg, value_reg);
+ }
+}
+
+
+void LCodeGen::DoConstructDouble(LConstructDouble* instr) {
+ Register hi_reg = ToRegister(instr->hi());
+ Register lo_reg = ToRegister(instr->lo());
+ DwVfpRegister result_reg = ToDoubleRegister(instr->result());
+ __ VmovHigh(result_reg, hi_reg);
+ __ VmovLow(result_reg, lo_reg);
+}
void LCodeGen::DoAllocate(LAllocate* instr) {
=======================================
--- /branches/bleeding_edge/src/full-codegen.cc Fri Mar 7 08:49:02 2014 UTC
+++ /branches/bleeding_edge/src/full-codegen.cc Fri Mar 7 09:05:10 2014 UTC
@@ -947,6 +947,34 @@
void FullCodeGenerator::EmitDebugBreakInOptimizedCode(CallRuntime* expr) {
context()->Plug(handle(Smi::FromInt(0), isolate()));
}
+
+
+void FullCodeGenerator::EmitDoubleHi(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ ASSERT(args->length() == 1);
+ VisitForStackValue(args->at(0));
+ masm()->CallRuntime(Runtime::kDoubleHi, 1);
+ context()->Plug(result_register());
+}
+
+
+void FullCodeGenerator::EmitDoubleLo(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ ASSERT(args->length() == 1);
+ VisitForStackValue(args->at(0));
+ masm()->CallRuntime(Runtime::kDoubleLo, 1);
+ context()->Plug(result_register());
+}
+
+
+void FullCodeGenerator::EmitConstructDouble(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ ASSERT(args->length() == 2);
+ VisitForStackValue(args->at(0));
+ VisitForStackValue(args->at(1));
+ masm()->CallRuntime(Runtime::kConstructDouble, 2);
+ context()->Plug(result_register());
+}
void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Thu Mar 6 12:13:49
2014 UTC
+++ /branches/bleeding_edge/src/hydrogen-instructions.h Fri Mar 7 09:05:10
2014 UTC
@@ -102,12 +102,14 @@
V(CompareObjectEqAndBranch) \
V(CompareMap) \
V(Constant) \
+ V(ConstructDouble) \
V(Context) \
V(DateField) \
V(DebugBreak) \
V(DeclareGlobals) \
V(Deoptimize) \
V(Div) \
+ V(DoubleBits) \
V(DummyUse) \
V(EnterInlined) \
V(EnvironmentMarker) \
@@ -1814,6 +1816,65 @@
set_representation(Representation::Integer32());
SetFlag(kAllowUndefinedAsNaN);
SetFlag(kUseGVN);
+ }
+
+ virtual bool IsDeletable() const V8_OVERRIDE { return true; }
+};
+
+
+class HDoubleBits V8_FINAL : public HUnaryOperation {
+ public:
+ enum Bits { HIGH, LOW };
+ DECLARE_INSTRUCTION_FACTORY_P2(HDoubleBits, HValue*, Bits);
+
+ virtual Representation RequiredInputRepresentation(int index)
V8_OVERRIDE {
+ return Representation::Double();
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(DoubleBits)
+
+ Bits bits() { return bits_; }
+
+ protected:
+ virtual bool DataEquals(HValue* other) V8_OVERRIDE {
+ return other->IsDoubleBits() && HDoubleBits::cast(other)->bits() ==
bits();
+ }
+
+ private:
+ HDoubleBits(HValue* value, Bits bits)
+ : HUnaryOperation(value), bits_(bits) {
+ set_representation(Representation::Integer32());
+ SetFlag(kUseGVN);
+ }
+
+ virtual bool IsDeletable() const V8_OVERRIDE { return true; }
+
+ Bits bits_;
+};
+
+
+class HConstructDouble V8_FINAL : public HTemplateInstruction<2> {
+ public:
+ DECLARE_INSTRUCTION_FACTORY_P2(HConstructDouble, HValue*, HValue*);
+
+ virtual Representation RequiredInputRepresentation(int index)
V8_OVERRIDE {
+ return Representation::Integer32();
+ }
+
+ DECLARE_CONCRETE_INSTRUCTION(ConstructDouble)
+
+ HValue* hi() { return OperandAt(0); }
+ HValue* lo() { return OperandAt(1); }
+
+ protected:
+ virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; }
+
+ private:
+ explicit HConstructDouble(HValue* hi, HValue* lo) {
+ set_representation(Representation::Double());
+ SetFlag(kUseGVN);
+ SetOperandAt(0, hi);
+ SetOperandAt(1, lo);
}
virtual bool IsDeletable() const V8_OVERRIDE { return true; }
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Fri Mar 7 08:49:02 2014 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc Fri Mar 7 09:05:10 2014 UTC
@@ -10500,6 +10500,35 @@
HCallStub* result = New<HCallStub>(CodeStub::RegExpExec, 4);
return ast_context()->ReturnInstruction(result, call->id());
}
+
+
+void HOptimizedGraphBuilder::GenerateDoubleLo(CallRuntime* call) {
+ ASSERT_EQ(1, call->arguments()->length());
+ CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+ HValue* value = Pop();
+ HInstruction* result = NewUncasted<HDoubleBits>(value, HDoubleBits::LOW);
+ return ast_context()->ReturnInstruction(result, call->id());
+}
+
+
+void HOptimizedGraphBuilder::GenerateDoubleHi(CallRuntime* call) {
+ ASSERT_EQ(1, call->arguments()->length());
+ CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+ HValue* value = Pop();
+ HInstruction* result = NewUncasted<HDoubleBits>(value,
HDoubleBits::HIGH);
+ return ast_context()->ReturnInstruction(result, call->id());
+}
+
+
+void HOptimizedGraphBuilder::GenerateConstructDouble(CallRuntime* call) {
+ ASSERT_EQ(2, call->arguments()->length());
+ CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+ CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
+ HValue* lo = Pop();
+ HValue* hi = Pop();
+ HInstruction* result = NewUncasted<HConstructDouble>(hi, lo);
+ return ast_context()->ReturnInstruction(result, call->id());
+}
// Construct a RegExp exec result with two in-object properties.
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Fri Mar 7
08:36:13 2014 UTC
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Fri Mar 7
09:05:10 2014 UTC
@@ -5757,6 +5757,45 @@
__ ClampUint8(result_reg);
__ bind(&done);
}
+
+
+void LCodeGen::DoDoubleBits(LDoubleBits* instr) {
+ CpuFeatureScope scope(masm(), SSE2);
+ XMMRegister value_reg = ToDoubleRegister(instr->value());
+ Register result_reg = ToRegister(instr->result());
+ if (instr->hydrogen()->bits() == HDoubleBits::HIGH) {
+ if (CpuFeatures::IsSupported(SSE4_1)) {
+ CpuFeatureScope scope2(masm(), SSE4_1);
+ __ pextrd(result_reg, value_reg, 1);
+ } else {
+ XMMRegister xmm_scratch = double_scratch0();
+ __ pshufd(xmm_scratch, value_reg, 1);
+ __ movd(result_reg, xmm_scratch);
+ }
+ } else {
+ __ movd(result_reg, value_reg);
+ }
+}
+
+
+void LCodeGen::DoConstructDouble(LConstructDouble* instr) {
+ Register hi_reg = ToRegister(instr->hi());
+ Register lo_reg = ToRegister(instr->lo());
+ XMMRegister result_reg = ToDoubleRegister(instr->result());
+ CpuFeatureScope scope(masm(), SSE2);
+
+ if (CpuFeatures::IsSupported(SSE4_1)) {
+ CpuFeatureScope scope2(masm(), SSE4_1);
+ __ movd(result_reg, lo_reg);
+ __ pinsrd(result_reg, hi_reg, 1);
+ } else {
+ XMMRegister xmm_scratch = double_scratch0();
+ __ movd(result_reg, hi_reg);
+ __ psllq(result_reg, 32);
+ __ movd(xmm_scratch, lo_reg);
+ __ orps(result_reg, xmm_scratch);
+ }
+}
void LCodeGen::DoAllocate(LAllocate* instr) {
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Tue Mar 4 12:48:17
2014 UTC
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Fri Mar 7 09:05:10
2014 UTC
@@ -1972,6 +1972,20 @@
}
}
}
+
+
+LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) {
+ HValue* value = instr->value();
+ ASSERT(value->representation().IsDouble());
+ return DefineAsRegister(new(zone()) LDoubleBits(UseRegister(value)));
+}
+
+
+LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) {
+ LOperand* lo = UseRegister(instr->lo());
+ LOperand* hi = UseRegister(instr->hi());
+ return DefineAsRegister(new(zone()) LConstructDouble(hi, lo));
+}
LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.h Tue Mar 4 12:45:00
2014 UTC
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.h Fri Mar 7 09:05:10
2014 UTC
@@ -82,12 +82,14 @@
V(ConstantI) \
V(ConstantS) \
V(ConstantT) \
+ V(ConstructDouble) \
V(Context) \
V(DateField) \
V(DebugBreak) \
V(DeclareGlobals) \
V(Deoptimize) \
V(DivI) \
+ V(DoubleBits) \
V(DoubleToI) \
V(DoubleToSmi) \
V(Drop) \
@@ -2408,6 +2410,33 @@
};
+class LDoubleBits V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LDoubleBits(LOperand* value) {
+ inputs_[0] = value;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(DoubleBits, "double-bits")
+ DECLARE_HYDROGEN_ACCESSOR(DoubleBits)
+};
+
+
+class LConstructDouble V8_FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+ LConstructDouble(LOperand* hi, LOperand* lo) {
+ inputs_[0] = hi;
+ inputs_[1] = lo;
+ }
+
+ LOperand* hi() { return inputs_[0]; }
+ LOperand* lo() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(ConstructDouble, "construct-double")
+};
+
+
class LAllocate V8_FINAL : public LTemplateInstruction<1, 2, 1> {
public:
LAllocate(LOperand* context, LOperand* size, LOperand* temp) {
=======================================
--- /branches/bleeding_edge/src/runtime.cc Fri Mar 7 08:49:02 2014 UTC
+++ /branches/bleeding_edge/src/runtime.cc Fri Mar 7 09:05:10 2014 UTC
@@ -7664,6 +7664,34 @@
#undef RUNTIME_UNARY_MATH
+RUNTIME_FUNCTION(MaybeObject*, Runtime_DoubleHi) {
+ SealHandleScope shs(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+ return isolate->heap()->NumberFromDouble(
+ static_cast<int32_t>(double_to_uint64(x) >> 32));
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_DoubleLo) {
+ SealHandleScope shs(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+ return isolate->heap()->NumberFromDouble(
+ static_cast<int32_t>(double_to_uint64(x) & 0xFFFFFFFFu));
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ConstructDouble) {
+ SealHandleScope shs(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_NUMBER_CHECKED(uint32_t, hi, Uint32, args[0]);
+ CONVERT_NUMBER_CHECKED(uint32_t, lo, Uint32, args[1]);
+ uint64_t result = (static_cast<uint64_t>(hi) << 32) | lo;
+ return isolate->heap()->AllocateHeapNumber(uint64_to_double(result));
+}
+
+
// Cube root approximation, refer to: http://metamerist.com/cbrt/cbrt.htm
// Using initial approximation adapted from Kahan's cbrt and 4 iterations
// of Newton's method.
=======================================
--- /branches/bleeding_edge/src/runtime.h Fri Mar 7 08:49:02 2014 UTC
+++ /branches/bleeding_edge/src/runtime.h Fri Mar 7 09:05:10 2014 UTC
@@ -655,7 +655,10 @@
F(RegExpExec, 4,
1) \
F(RegExpConstructResult, 3,
1) \
F(GetFromCache, 2,
1) \
- F(NumberToString, 1, 1)
+ F(NumberToString, 1,
1) \
+ F(DoubleHi, 1,
1) \
+ F(DoubleLo, 1,
1) \
+ F(ConstructDouble, 2, 1)
//---------------------------------------------------------------------------
=======================================
--- /branches/bleeding_edge/src/x64/assembler-x64.cc Wed Feb 19 13:51:49
2014 UTC
+++ /branches/bleeding_edge/src/x64/assembler-x64.cc Fri Mar 7 09:05:10
2014 UTC
@@ -2796,6 +2796,16 @@
emit(0x11); // store
emit_sse_operand(dst, src);
}
+
+
+void Assembler::psllq(XMMRegister reg, byte imm8) {
+ EnsureSpace ensure_space(this);
+ emit(0x66);
+ emit(0x0F);
+ emit(0x73);
+ emit_sse_operand(rsi, reg); // rsi == 6
+ emit(imm8);
+}
void Assembler::cvttss2si(Register dst, const Operand& src) {
=======================================
--- /branches/bleeding_edge/src/x64/assembler-x64.h Wed Feb 19 13:51:49
2014 UTC
+++ /branches/bleeding_edge/src/x64/assembler-x64.h Fri Mar 7 09:05:10
2014 UTC
@@ -1381,6 +1381,8 @@
void movapd(XMMRegister dst, XMMRegister src);
+ void psllq(XMMRegister reg, byte imm8);
+
void cvttsd2si(Register dst, const Operand& src);
void cvttsd2si(Register dst, XMMRegister src);
void cvttsd2siq(Register dst, XMMRegister src);
=======================================
--- /branches/bleeding_edge/src/x64/disasm-x64.cc Wed Mar 5 09:28:26 2014
UTC
+++ /branches/bleeding_edge/src/x64/disasm-x64.cc Fri Mar 7 09:05:10 2014
UTC
@@ -1089,6 +1089,11 @@
} else if (opcode == 0x50) {
AppendToBuffer("movmskpd %s,", NameOfCPURegister(regop));
current += PrintRightXMMOperand(current);
+ } else if (opcode == 0x73) {
+ current += 1;
+ ASSERT(regop == 6);
+ AppendToBuffer("psllq,%s,%d", NameOfXMMRegister(rm), *current &
0x7f);
+ current += 1;
} else {
const char* mnemonic = "?";
if (opcode == 0x54) {
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Thu Mar 6
16:22:47 2014 UTC
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Fri Mar 7
09:05:10 2014 UTC
@@ -5055,6 +5055,30 @@
__ bind(&done);
}
+
+
+void LCodeGen::DoDoubleBits(LDoubleBits* instr) {
+ XMMRegister value_reg = ToDoubleRegister(instr->value());
+ Register result_reg = ToRegister(instr->result());
+ if (instr->hydrogen()->bits() == HDoubleBits::HIGH) {
+ __ movq(result_reg, value_reg);
+ __ shr(result_reg, Immediate(32));
+ } else {
+ __ movd(result_reg, value_reg);
+ }
+}
+
+
+void LCodeGen::DoConstructDouble(LConstructDouble* instr) {
+ Register hi_reg = ToRegister(instr->hi());
+ Register lo_reg = ToRegister(instr->lo());
+ XMMRegister result_reg = ToDoubleRegister(instr->result());
+ XMMRegister xmm_scratch = double_scratch0();
+ __ movd(result_reg, hi_reg);
+ __ psllq(result_reg, 32);
+ __ movd(xmm_scratch, lo_reg);
+ __ orps(result_reg, xmm_scratch);
+}
void LCodeGen::DoAllocate(LAllocate* instr) {
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc Wed Mar 5 09:49:07 2014
UTC
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc Fri Mar 7 09:05:10 2014
UTC
@@ -1847,6 +1847,20 @@
return AssignEnvironment(DefineSameAsFirst(result));
}
}
+
+
+LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) {
+ HValue* value = instr->value();
+ ASSERT(value->representation().IsDouble());
+ return DefineAsRegister(new(zone()) LDoubleBits(UseRegister(value)));
+}
+
+
+LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) {
+ LOperand* lo = UseRegister(instr->lo());
+ LOperand* hi = UseRegister(instr->hi());
+ return DefineAsRegister(new(zone()) LConstructDouble(hi, lo));
+}
LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h Tue Mar 4 12:45:00 2014
UTC
+++ /branches/bleeding_edge/src/x64/lithium-x64.h Fri Mar 7 09:05:10 2014
UTC
@@ -80,12 +80,14 @@
V(ConstantI) \
V(ConstantS) \
V(ConstantT) \
+ V(ConstructDouble) \
V(Context) \
V(DateField) \
V(DebugBreak) \
V(DeclareGlobals) \
V(Deoptimize) \
V(DivI) \
+ V(DoubleBits) \
V(DoubleToI) \
V(DoubleToSmi) \
V(Drop) \
@@ -2313,6 +2315,33 @@
};
+class LDoubleBits V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LDoubleBits(LOperand* value) {
+ inputs_[0] = value;
+ }
+
+ LOperand* value() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(DoubleBits, "double-bits")
+ DECLARE_HYDROGEN_ACCESSOR(DoubleBits)
+};
+
+
+class LConstructDouble V8_FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+ LConstructDouble(LOperand* hi, LOperand* lo) {
+ inputs_[0] = hi;
+ inputs_[1] = lo;
+ }
+
+ LOperand* hi() { return inputs_[0]; }
+ LOperand* lo() { return inputs_[1]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(ConstructDouble, "construct-double")
+};
+
+
class LAllocate V8_FINAL : public LTemplateInstruction<1, 2, 1> {
public:
LAllocate(LOperand* context, LOperand* size, LOperand* temp) {
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.