LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
switch (instr->op()) {
- case kMathFloor: return DoMathFloor(instr);
- case kMathRound: return DoMathRound(instr);
- case kMathAbs: return DoMathAbs(instr);
- case kMathLog: return DoMathLog(instr);
- case kMathExp: return DoMathExp(instr);
- case kMathSqrt: return DoMathSqrt(instr);
- case kMathPowHalf: return DoMathPowHalf(instr);
- case kMathClz32: return DoMathClz32(instr);
+ case kMathFloor:
+ return DoMathFloor(instr);
+ case kMathRound:
+ return DoMathRound(instr);
+ case kMathFround:
+ return DoMathFround(instr);
+ case kMathAbs:
+ return DoMathAbs(instr);
+ case kMathLog:
+ return DoMathLog(instr);
+ case kMathExp:
+ return DoMathExp(instr);
+ case kMathSqrt:
+ return DoMathSqrt(instr);
+ case kMathPowHalf:
+ return DoMathPowHalf(instr);
+ case kMathClz32:
+ return DoMathClz32(instr);
default:
UNREACHABLE();
return NULL;
}
+LInstruction* LChunkBuilder::DoMathFround(HUnaryMathOperation* instr) {
+ LOperand* input = UseRegister(instr->value());
+ LMathFround* result = new (zone()) LMathFround(input);
+ return DefineAsRegister(result);
+}
+
+
LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) {
Representation r = instr->value()->representation();
LOperand* context = (r.IsDouble() || r.IsSmiOrInteger32())
// Forward declarations.
class LCodeGen;
-#define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \
- V(AccessArgumentsAt) \
- V(AddI) \
- V(Allocate) \
- V(AllocateBlockContext) \
- V(ApplyArguments) \
- V(ArgumentsElements) \
- V(ArgumentsLength) \
- V(ArithmeticD) \
- V(ArithmeticT) \
- V(BitI) \
- V(BoundsCheck) \
- V(Branch) \
- V(CallJSFunction) \
- V(CallWithDescriptor) \
- V(CallFunction) \
- V(CallNew) \
- V(CallNewArray) \
- V(CallRuntime) \
- V(CallStub) \
- V(CheckInstanceType) \
- V(CheckNonSmi) \
- V(CheckMaps) \
- V(CheckMapValue) \
- V(CheckSmi) \
- V(CheckValue) \
- V(ClampDToUint8) \
- V(ClampIToUint8) \
- V(ClampTToUint8) \
- V(ClassOfTestAndBranch) \
- V(CompareMinusZeroAndBranch) \
- V(CompareNumericAndBranch) \
- V(CmpObjectEqAndBranch) \
- V(CmpHoleAndBranch) \
- V(CmpMapAndBranch) \
- V(CmpT) \
- V(ConstantD) \
- V(ConstantE) \
- V(ConstantI) \
- V(ConstantS) \
- V(ConstantT) \
- V(ConstructDouble) \
- V(Context) \
- V(DateField) \
- V(DebugBreak) \
- V(DeclareGlobals) \
- V(Deoptimize) \
- V(DivByConstI) \
- V(DivByPowerOf2I) \
- V(DivI) \
- V(DoubleBits) \
- V(DoubleToI) \
- V(DoubleToSmi) \
- V(Drop) \
- V(Dummy) \
- V(DummyUse) \
- V(FlooringDivByConstI) \
- V(FlooringDivByPowerOf2I) \
- V(FlooringDivI) \
- V(ForInCacheArray) \
- V(ForInPrepareMap) \
- V(FunctionLiteral) \
- V(GetCachedArrayIndex) \
- V(Goto) \
- V(HasCachedArrayIndexAndBranch) \
- V(HasInstanceTypeAndBranch) \
- V(InnerAllocatedObject) \
- V(InstanceOf) \
- V(InstanceOfKnownGlobal) \
- V(InstructionGap) \
- V(Integer32ToDouble) \
- V(InvokeFunction) \
- V(IsConstructCallAndBranch) \
- V(IsObjectAndBranch) \
- V(IsStringAndBranch) \
- V(IsSmiAndBranch) \
- V(IsUndetectableAndBranch) \
- V(Label) \
- V(LazyBailout) \
- V(LoadContextSlot) \
- V(LoadRoot) \
- V(LoadFieldByIndex) \
- V(LoadFunctionPrototype) \
- V(LoadGlobalCell) \
- V(LoadGlobalGeneric) \
- V(LoadKeyed) \
- V(LoadKeyedGeneric) \
- V(LoadNamedField) \
- V(LoadNamedGeneric) \
- V(MapEnumLength) \
- V(MathAbs) \
- V(MathClz32) \
- V(MathExp) \
- V(MathFloor) \
- V(MathLog) \
- V(MathMinMax) \
- V(MathPowHalf) \
- V(MathRound) \
- V(MathSqrt) \
- V(ModByConstI) \
- V(ModByPowerOf2I) \
- V(ModI) \
- V(MulI) \
- V(MultiplyAddD) \
- V(MultiplySubD) \
- V(NumberTagD) \
- V(NumberTagI) \
- V(NumberTagU) \
- V(NumberUntagD) \
- V(OsrEntry) \
- V(Parameter) \
- V(Power) \
- V(PushArgument) \
- V(RegExpLiteral) \
- V(Return) \
- V(SeqStringGetChar) \
- V(SeqStringSetChar) \
- V(ShiftI) \
- V(SmiTag) \
- V(SmiUntag) \
- V(StackCheck) \
- V(StoreCodeEntry) \
- V(StoreContextSlot) \
- V(StoreFrameContext) \
- V(StoreGlobalCell) \
- V(StoreKeyed) \
- V(StoreKeyedGeneric) \
- V(StoreNamedField) \
- V(StoreNamedGeneric) \
- V(StringAdd) \
- V(StringCharCodeAt) \
- V(StringCharFromCode) \
- V(StringCompareAndBranch) \
- V(SubI) \
- V(RSubI) \
- V(TaggedToI) \
- V(ThisFunction) \
- V(ToFastProperties) \
- V(TransitionElementsKind) \
- V(TrapAllocationMemento) \
- V(Typeof) \
- V(TypeofIsAndBranch) \
- V(Uint32ToDouble) \
- V(UnknownOSRValue) \
+#define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \
+ V(AccessArgumentsAt) \
+ V(AddI) \
+ V(Allocate) \
+ V(AllocateBlockContext) \
+ V(ApplyArguments) \
+ V(ArgumentsElements) \
+ V(ArgumentsLength) \
+ V(ArithmeticD) \
+ V(ArithmeticT) \
+ V(BitI) \
+ V(BoundsCheck) \
+ V(Branch) \
+ V(CallJSFunction) \
+ V(CallWithDescriptor) \
+ V(CallFunction) \
+ V(CallNew) \
+ V(CallNewArray) \
+ V(CallRuntime) \
+ V(CallStub) \
+ V(CheckInstanceType) \
+ V(CheckNonSmi) \
+ V(CheckMaps) \
+ V(CheckMapValue) \
+ V(CheckSmi) \
+ V(CheckValue) \
+ V(ClampDToUint8) \
+ V(ClampIToUint8) \
+ V(ClampTToUint8) \
+ V(ClassOfTestAndBranch) \
+ V(CompareMinusZeroAndBranch) \
+ V(CompareNumericAndBranch) \
+ V(CmpObjectEqAndBranch) \
+ V(CmpHoleAndBranch) \
+ V(CmpMapAndBranch) \
+ V(CmpT) \
+ V(ConstantD) \
+ V(ConstantE) \
+ V(ConstantI) \
+ V(ConstantS) \
+ V(ConstantT) \
+ V(ConstructDouble) \
+ V(Context) \
+ V(DateField) \
+ V(DebugBreak) \
+ V(DeclareGlobals) \
+ V(Deoptimize) \
+ V(DivByConstI) \
+ V(DivByPowerOf2I) \
+ V(DivI) \
+ V(DoubleBits) \
+ V(DoubleToI) \
+ V(DoubleToSmi) \
+ V(Drop) \
+ V(Dummy) \
+ V(DummyUse) \
+ V(FlooringDivByConstI) \
+ V(FlooringDivByPowerOf2I) \
+ V(FlooringDivI) \
+ V(ForInCacheArray) \
+ V(ForInPrepareMap) \
+ V(FunctionLiteral) \
+ V(GetCachedArrayIndex) \
+ V(Goto) \
+ V(HasCachedArrayIndexAndBranch) \
+ V(HasInstanceTypeAndBranch) \
+ V(InnerAllocatedObject) \
+ V(InstanceOf) \
+ V(InstanceOfKnownGlobal) \
+ V(InstructionGap) \
+ V(Integer32ToDouble) \
+ V(InvokeFunction) \
+ V(IsConstructCallAndBranch) \
+ V(IsObjectAndBranch) \
+ V(IsStringAndBranch) \
+ V(IsSmiAndBranch) \
+ V(IsUndetectableAndBranch) \
+ V(Label) \
+ V(LazyBailout) \
+ V(LoadContextSlot) \
+ V(LoadRoot) \
+ V(LoadFieldByIndex) \
+ V(LoadFunctionPrototype) \
+ V(LoadGlobalCell) \
+ V(LoadGlobalGeneric) \
+ V(LoadKeyed) \
+ V(LoadKeyedGeneric) \
+ V(LoadNamedField) \
+ V(LoadNamedGeneric) \
+ V(MapEnumLength) \
+ V(MathAbs) \
+ V(MathClz32) \
+ V(MathExp) \
+ V(MathFloor) \
+ V(MathFround) \
+ V(MathLog) \
+ V(MathMinMax) \
+ V(MathPowHalf) \
+ V(MathRound) \
+ V(MathSqrt) \
+ V(ModByConstI) \
+ V(ModByPowerOf2I) \
+ V(ModI) \
+ V(MulI) \
+ V(MultiplyAddD) \
+ V(MultiplySubD) \
+ V(NumberTagD) \
+ V(NumberTagI) \
+ V(NumberTagU) \
+ V(NumberUntagD) \
+ V(OsrEntry) \
+ V(Parameter) \
+ V(Power) \
+ V(PushArgument) \
+ V(RegExpLiteral) \
+ V(Return) \
+ V(SeqStringGetChar) \
+ V(SeqStringSetChar) \
+ V(ShiftI) \
+ V(SmiTag) \
+ V(SmiUntag) \
+ V(StackCheck) \
+ V(StoreCodeEntry) \
+ V(StoreContextSlot) \
+ V(StoreFrameContext) \
+ V(StoreGlobalCell) \
+ V(StoreKeyed) \
+ V(StoreKeyedGeneric) \
+ V(StoreNamedField) \
+ V(StoreNamedGeneric) \
+ V(StringAdd) \
+ V(StringCharCodeAt) \
+ V(StringCharFromCode) \
+ V(StringCompareAndBranch) \
+ V(SubI) \
+ V(RSubI) \
+ V(TaggedToI) \
+ V(ThisFunction) \
+ V(ToFastProperties) \
+ V(TransitionElementsKind) \
+ V(TrapAllocationMemento) \
+ V(Typeof) \
+ V(TypeofIsAndBranch) \
+ V(Uint32ToDouble) \
+ V(UnknownOSRValue) \
V(WrapReceiver)
};
+class LMathFround V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LMathFround(LOperand* value) { inputs_[0] = value; }
+
+ LOperand* value() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(MathRound, "math-fround")
+};
+
+
class LMathAbs V8_FINAL : public LTemplateInstruction<1, 2, 0> {
public:
LMathAbs(LOperand* context, LOperand* value) {
LInstruction* DoMathFloor(HUnaryMathOperation* instr);
LInstruction* DoMathRound(HUnaryMathOperation* instr);
+ LInstruction* DoMathFround(HUnaryMathOperation* instr);
LInstruction* DoMathAbs(HUnaryMathOperation* instr);
LInstruction* DoMathLog(HUnaryMathOperation* instr);
LInstruction* DoMathExp(HUnaryMathOperation* instr);
}
+void LCodeGen::DoMathFround(LMathFround* instr) {
+ DwVfpRegister input_reg = ToDoubleRegister(instr->value());
+ DwVfpRegister output_reg = ToDoubleRegister(instr->result());
+ LowDwVfpRegister scratch = double_scratch0();
+ __ vcvt_f32_f64(scratch.low(), input_reg);
+ __ vcvt_f64_f32(output_reg, scratch.low());
+}
+
+
void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
DwVfpRegister input = ToDoubleRegister(instr->value());
DwVfpRegister result = ToDoubleRegister(instr->result());
return DefineAsRegister(result);
}
}
+ case kMathFround: {
+ ASSERT(instr->value()->representation().IsDouble());
+ LOperand* input = UseRegister(instr->value());
+ LMathFround* result = new (zone()) LMathFround(input);
+ return DefineAsRegister(result);
+ }
case kMathSqrt: {
ASSERT(instr->representation().IsDouble());
ASSERT(instr->value()->representation().IsDouble());
// Forward declarations.
class LCodeGen;
-#define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \
- V(AccessArgumentsAt) \
- V(AddE) \
- V(AddI) \
- V(AddS) \
- V(Allocate) \
- V(AllocateBlockContext) \
- V(ApplyArguments) \
- V(ArgumentsElements) \
- V(ArgumentsLength) \
- V(ArithmeticD) \
- V(ArithmeticT) \
- V(BitI) \
- V(BitS) \
- V(BoundsCheck) \
- V(Branch) \
- V(CallFunction) \
- V(CallJSFunction) \
- V(CallNew) \
- V(CallNewArray) \
- V(CallRuntime) \
- V(CallStub) \
- V(CallWithDescriptor) \
- V(CheckInstanceType) \
- V(CheckMapValue) \
- V(CheckMaps) \
- V(CheckNonSmi) \
- V(CheckSmi) \
- V(CheckValue) \
- V(ClampDToUint8) \
- V(ClampIToUint8) \
- V(ClampTToUint8) \
- V(ClassOfTestAndBranch) \
- V(CmpHoleAndBranchD) \
- V(CmpHoleAndBranchT) \
- V(CmpMapAndBranch) \
- V(CmpObjectEqAndBranch) \
- V(CmpT) \
- V(CompareMinusZeroAndBranch) \
- V(CompareNumericAndBranch) \
- V(ConstantD) \
- V(ConstantE) \
- V(ConstantI) \
- V(ConstantS) \
- V(ConstantT) \
- V(ConstructDouble) \
- V(Context) \
- V(DateField) \
- V(DebugBreak) \
- V(DeclareGlobals) \
- V(Deoptimize) \
- V(DivByConstI) \
- V(DivByPowerOf2I) \
- V(DivI) \
- V(DoubleBits) \
- V(DoubleToIntOrSmi) \
- V(Drop) \
- V(Dummy) \
- V(DummyUse) \
- V(FlooringDivByConstI) \
- V(FlooringDivByPowerOf2I) \
- V(FlooringDivI) \
- V(ForInCacheArray) \
- V(ForInPrepareMap) \
- V(FunctionLiteral) \
- V(GetCachedArrayIndex) \
- V(Goto) \
- V(HasCachedArrayIndexAndBranch) \
- V(HasInstanceTypeAndBranch) \
- V(InnerAllocatedObject) \
- V(InstanceOf) \
- V(InstanceOfKnownGlobal) \
- V(InstructionGap) \
- V(Integer32ToDouble) \
- V(InvokeFunction) \
- V(IsConstructCallAndBranch) \
- V(IsObjectAndBranch) \
- V(IsSmiAndBranch) \
- V(IsStringAndBranch) \
- V(IsUndetectableAndBranch) \
- V(Label) \
- V(LazyBailout) \
- V(LoadContextSlot) \
- V(LoadFieldByIndex) \
- V(LoadFunctionPrototype) \
- V(LoadGlobalCell) \
- V(LoadGlobalGeneric) \
- V(LoadKeyedExternal) \
- V(LoadKeyedFixed) \
- V(LoadKeyedFixedDouble) \
- V(LoadKeyedGeneric) \
- V(LoadNamedField) \
- V(LoadNamedGeneric) \
- V(LoadRoot) \
- V(MapEnumLength) \
- V(MathAbs) \
- V(MathAbsTagged) \
- V(MathClz32) \
- V(MathExp) \
- V(MathFloorD) \
- V(MathFloorI) \
- V(MathLog) \
- V(MathMinMax) \
- V(MathPowHalf) \
- V(MathRoundD) \
- V(MathRoundI) \
- V(MathSqrt) \
- V(ModByConstI) \
- V(ModByPowerOf2I) \
- V(ModI) \
- V(MulConstIS) \
- V(MulI) \
- V(MulS) \
- V(NumberTagD) \
- V(NumberTagU) \
- V(NumberUntagD) \
- V(OsrEntry) \
- V(Parameter) \
- V(Power) \
- V(PreparePushArguments) \
- V(PushArguments) \
- V(RegExpLiteral) \
- V(Return) \
- V(SeqStringGetChar) \
- V(SeqStringSetChar) \
- V(ShiftI) \
- V(ShiftS) \
- V(SmiTag) \
- V(SmiUntag) \
- V(StackCheck) \
- V(StoreCodeEntry) \
- V(StoreContextSlot) \
- V(StoreFrameContext) \
- V(StoreGlobalCell) \
- V(StoreKeyedExternal) \
- V(StoreKeyedFixed) \
- V(StoreKeyedFixedDouble) \
- V(StoreKeyedGeneric) \
- V(StoreNamedField) \
- V(StoreNamedGeneric) \
- V(StringAdd) \
- V(StringCharCodeAt) \
- V(StringCharFromCode) \
- V(StringCompareAndBranch) \
- V(SubI) \
- V(SubS) \
- V(TaggedToI) \
- V(ThisFunction) \
- V(ToFastProperties) \
- V(TransitionElementsKind) \
- V(TrapAllocationMemento) \
- V(TruncateDoubleToIntOrSmi) \
- V(Typeof) \
- V(TypeofIsAndBranch) \
- V(Uint32ToDouble) \
- V(UnknownOSRValue) \
+#define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \
+ V(AccessArgumentsAt) \
+ V(AddE) \
+ V(AddI) \
+ V(AddS) \
+ V(Allocate) \
+ V(AllocateBlockContext) \
+ V(ApplyArguments) \
+ V(ArgumentsElements) \
+ V(ArgumentsLength) \
+ V(ArithmeticD) \
+ V(ArithmeticT) \
+ V(BitI) \
+ V(BitS) \
+ V(BoundsCheck) \
+ V(Branch) \
+ V(CallFunction) \
+ V(CallJSFunction) \
+ V(CallNew) \
+ V(CallNewArray) \
+ V(CallRuntime) \
+ V(CallStub) \
+ V(CallWithDescriptor) \
+ V(CheckInstanceType) \
+ V(CheckMapValue) \
+ V(CheckMaps) \
+ V(CheckNonSmi) \
+ V(CheckSmi) \
+ V(CheckValue) \
+ V(ClampDToUint8) \
+ V(ClampIToUint8) \
+ V(ClampTToUint8) \
+ V(ClassOfTestAndBranch) \
+ V(CmpHoleAndBranchD) \
+ V(CmpHoleAndBranchT) \
+ V(CmpMapAndBranch) \
+ V(CmpObjectEqAndBranch) \
+ V(CmpT) \
+ V(CompareMinusZeroAndBranch) \
+ V(CompareNumericAndBranch) \
+ V(ConstantD) \
+ V(ConstantE) \
+ V(ConstantI) \
+ V(ConstantS) \
+ V(ConstantT) \
+ V(ConstructDouble) \
+ V(Context) \
+ V(DateField) \
+ V(DebugBreak) \
+ V(DeclareGlobals) \
+ V(Deoptimize) \
+ V(DivByConstI) \
+ V(DivByPowerOf2I) \
+ V(DivI) \
+ V(DoubleBits) \
+ V(DoubleToIntOrSmi) \
+ V(Drop) \
+ V(Dummy) \
+ V(DummyUse) \
+ V(FlooringDivByConstI) \
+ V(FlooringDivByPowerOf2I) \
+ V(FlooringDivI) \
+ V(ForInCacheArray) \
+ V(ForInPrepareMap) \
+ V(FunctionLiteral) \
+ V(GetCachedArrayIndex) \
+ V(Goto) \
+ V(HasCachedArrayIndexAndBranch) \
+ V(HasInstanceTypeAndBranch) \
+ V(InnerAllocatedObject) \
+ V(InstanceOf) \
+ V(InstanceOfKnownGlobal) \
+ V(InstructionGap) \
+ V(Integer32ToDouble) \
+ V(InvokeFunction) \
+ V(IsConstructCallAndBranch) \
+ V(IsObjectAndBranch) \
+ V(IsSmiAndBranch) \
+ V(IsStringAndBranch) \
+ V(IsUndetectableAndBranch) \
+ V(Label) \
+ V(LazyBailout) \
+ V(LoadContextSlot) \
+ V(LoadFieldByIndex) \
+ V(LoadFunctionPrototype) \
+ V(LoadGlobalCell) \
+ V(LoadGlobalGeneric) \
+ V(LoadKeyedExternal) \
+ V(LoadKeyedFixed) \
+ V(LoadKeyedFixedDouble) \
+ V(LoadKeyedGeneric) \
+ V(LoadNamedField) \
+ V(LoadNamedGeneric) \
+ V(LoadRoot) \
+ V(MapEnumLength) \
+ V(MathAbs) \
+ V(MathAbsTagged) \
+ V(MathClz32) \
+ V(MathExp) \
+ V(MathFloorD) \
+ V(MathFloorI) \
+ V(MathFround) \
+ V(MathLog) \
+ V(MathMinMax) \
+ V(MathPowHalf) \
+ V(MathRoundD) \
+ V(MathRoundI) \
+ V(MathSqrt) \
+ V(ModByConstI) \
+ V(ModByPowerOf2I) \
+ V(ModI) \
+ V(MulConstIS) \
+ V(MulI) \
+ V(MulS) \
+ V(NumberTagD) \
+ V(NumberTagU) \
+ V(NumberUntagD) \
+ V(OsrEntry) \
+ V(Parameter) \
+ V(Power) \
+ V(PreparePushArguments) \
+ V(PushArguments) \
+ V(RegExpLiteral) \
+ V(Return) \
+ V(SeqStringGetChar) \
+ V(SeqStringSetChar) \
+ V(ShiftI) \
+ V(ShiftS) \
+ V(SmiTag) \
+ V(SmiUntag) \
+ V(StackCheck) \
+ V(StoreCodeEntry) \
+ V(StoreContextSlot) \
+ V(StoreFrameContext) \
+ V(StoreGlobalCell) \
+ V(StoreKeyedExternal) \
+ V(StoreKeyedFixed) \
+ V(StoreKeyedFixedDouble) \
+ V(StoreKeyedGeneric) \
+ V(StoreNamedField) \
+ V(StoreNamedGeneric) \
+ V(StringAdd) \
+ V(StringCharCodeAt) \
+ V(StringCharFromCode) \
+ V(StringCompareAndBranch) \
+ V(SubI) \
+ V(SubS) \
+ V(TaggedToI) \
+ V(ThisFunction) \
+ V(ToFastProperties) \
+ V(TransitionElementsKind) \
+ V(TrapAllocationMemento) \
+ V(TruncateDoubleToIntOrSmi) \
+ V(Typeof) \
+ V(TypeofIsAndBranch) \
+ V(Uint32ToDouble) \
+ V(UnknownOSRValue) \
V(WrapReceiver)
};
+class LMathFround V8_FINAL : public LUnaryMathOperation<0> {
+ public:
+ explicit LMathFround(LOperand* value) : LUnaryMathOperation<0>(value) {}
+
+ DECLARE_CONCRETE_INSTRUCTION(MathFround, "math-fround")
+};
+
+
class LMathSqrt V8_FINAL : public LUnaryMathOperation<0> {
public:
explicit LMathSqrt(LOperand* value) : LUnaryMathOperation<0>(value) { }
}
+void LCodeGen::DoMathFround(LMathFround* instr) {
+ DoubleRegister input = ToDoubleRegister(instr->value());
+ DoubleRegister result = ToDoubleRegister(instr->result());
+ __ Fcvt(result.S(), input);
+ __ Fcvt(result, result.S());
+}
+
+
void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
DoubleRegister input = ToDoubleRegister(instr->value());
DoubleRegister result = ToDoubleRegister(instr->result());
const char* HUnaryMathOperation::OpName() const {
switch (op()) {
- case kMathFloor: return "floor";
- case kMathRound: return "round";
- case kMathAbs: return "abs";
- case kMathLog: return "log";
- case kMathExp: return "exp";
- case kMathSqrt: return "sqrt";
- case kMathPowHalf: return "pow-half";
- case kMathClz32: return "clz32";
+ case kMathFloor:
+ return "floor";
+ case kMathFround:
+ return "fround";
+ case kMathRound:
+ return "round";
+ case kMathAbs:
+ return "abs";
+ case kMathLog:
+ return "log";
+ case kMathExp:
+ return "exp";
+ case kMathSqrt:
+ return "sqrt";
+ case kMathPowHalf:
+ return "pow-half";
+ case kMathClz32:
+ return "clz32";
default:
UNREACHABLE();
return NULL;
case kMathAbs:
return H_CONSTANT_DOUBLE((d > 0.0) ? d : -d);
case kMathRound:
+ case kMathFround:
case kMathFloor:
return H_CONSTANT_DOUBLE(d);
case kMathClz32:
// Exponent is not negative, the double value is already an integer.
if (Double(d).Exponent() >= 0) return H_CONSTANT_DOUBLE(d);
return H_CONSTANT_DOUBLE(std::floor(d + 0.5));
+ case kMathFround:
+ return H_CONSTANT_DOUBLE(static_cast<double>(static_cast<float>(d)));
case kMathFloor:
return H_CONSTANT_DOUBLE(std::floor(d));
case kMathClz32: {
switch (op_) {
case kMathFloor:
case kMathRound:
+ case kMathFround:
case kMathSqrt:
case kMathPowHalf:
case kMathLog:
// is tagged, and not when it is an unboxed double or unboxed integer.
SetChangesFlag(kNewSpacePromotion);
break;
+ case kMathFround:
case kMathLog:
case kMathExp:
case kMathSqrt:
if (!FLAG_fast_math) break;
// Fall through if FLAG_fast_math.
case kMathRound:
+ case kMathFround:
case kMathFloor:
case kMathAbs:
case kMathSqrt:
if (!FLAG_fast_math) break;
// Fall through if FLAG_fast_math.
case kMathRound:
+ case kMathFround:
case kMathFloor:
case kMathAbs:
case kMathSqrt:
}
+void LCodeGen::DoMathFround(LMathFround* instr) {
+ XMMRegister input_reg = ToDoubleRegister(instr->value());
+ XMMRegister output_reg = ToDoubleRegister(instr->result());
+ __ cvtsd2ss(output_reg, input_reg);
+ __ cvtss2sd(output_reg, output_reg);
+}
+
+
void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
Operand input = ToOperand(instr->value());
XMMRegister output = ToDoubleRegister(instr->result());
LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
switch (instr->op()) {
- case kMathFloor: return DoMathFloor(instr);
- case kMathRound: return DoMathRound(instr);
- case kMathAbs: return DoMathAbs(instr);
- case kMathLog: return DoMathLog(instr);
- case kMathExp: return DoMathExp(instr);
- case kMathSqrt: return DoMathSqrt(instr);
- case kMathPowHalf: return DoMathPowHalf(instr);
- case kMathClz32: return DoMathClz32(instr);
+ case kMathFloor:
+ return DoMathFloor(instr);
+ case kMathRound:
+ return DoMathRound(instr);
+ case kMathFround:
+ return DoMathFround(instr);
+ case kMathAbs:
+ return DoMathAbs(instr);
+ case kMathLog:
+ return DoMathLog(instr);
+ case kMathExp:
+ return DoMathExp(instr);
+ case kMathSqrt:
+ return DoMathSqrt(instr);
+ case kMathPowHalf:
+ return DoMathPowHalf(instr);
+ case kMathClz32:
+ return DoMathClz32(instr);
default:
UNREACHABLE();
return NULL;
}
+LInstruction* LChunkBuilder::DoMathFround(HUnaryMathOperation* instr) {
+ LOperand* input = UseRegister(instr->value());
+ LMathFround* result = new (zone()) LMathFround(input);
+ return DefineAsRegister(result);
+}
+
+
LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) {
LOperand* context = UseAny(instr->context()); // Deferred use.
LOperand* input = UseRegisterAtStart(instr->value());
// Forward declarations.
class LCodeGen;
-#define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \
- V(AccessArgumentsAt) \
- V(AddI) \
- V(AllocateBlockContext) \
- V(Allocate) \
- V(ApplyArguments) \
- V(ArgumentsElements) \
- V(ArgumentsLength) \
- V(ArithmeticD) \
- V(ArithmeticT) \
- V(BitI) \
- V(BoundsCheck) \
- V(Branch) \
- V(CallJSFunction) \
- V(CallWithDescriptor) \
- V(CallFunction) \
- V(CallNew) \
- V(CallNewArray) \
- V(CallRuntime) \
- V(CallStub) \
- V(CheckInstanceType) \
- V(CheckMaps) \
- V(CheckMapValue) \
- V(CheckNonSmi) \
- V(CheckSmi) \
- V(CheckValue) \
- V(ClampDToUint8) \
- V(ClampIToUint8) \
- V(ClampTToUint8) \
- V(ClassOfTestAndBranch) \
- V(CompareMinusZeroAndBranch) \
- V(CompareNumericAndBranch) \
- V(CmpObjectEqAndBranch) \
- V(CmpHoleAndBranch) \
- V(CmpMapAndBranch) \
- V(CmpT) \
- V(ConstantD) \
- V(ConstantE) \
- V(ConstantI) \
- V(ConstantS) \
- V(ConstantT) \
- V(ConstructDouble) \
- V(Context) \
- V(DateField) \
- V(DebugBreak) \
- V(DeclareGlobals) \
- V(Deoptimize) \
- V(DivByConstI) \
- V(DivByPowerOf2I) \
- V(DivI) \
- V(DoubleBits) \
- V(DoubleToI) \
- V(DoubleToSmi) \
- V(Drop) \
- V(Dummy) \
- V(DummyUse) \
- V(FlooringDivByConstI) \
- V(FlooringDivByPowerOf2I) \
- V(FlooringDivI) \
- V(ForInCacheArray) \
- V(ForInPrepareMap) \
- V(FunctionLiteral) \
- V(GetCachedArrayIndex) \
- V(Goto) \
- V(HasCachedArrayIndexAndBranch) \
- V(HasInstanceTypeAndBranch) \
- V(InnerAllocatedObject) \
- V(InstanceOf) \
- V(InstanceOfKnownGlobal) \
- V(InstructionGap) \
- V(Integer32ToDouble) \
- V(InvokeFunction) \
- V(IsConstructCallAndBranch) \
- V(IsObjectAndBranch) \
- V(IsStringAndBranch) \
- V(IsSmiAndBranch) \
- V(IsUndetectableAndBranch) \
- V(Label) \
- V(LazyBailout) \
- V(LoadContextSlot) \
- V(LoadFieldByIndex) \
- V(LoadFunctionPrototype) \
- V(LoadGlobalCell) \
- V(LoadGlobalGeneric) \
- V(LoadKeyed) \
- V(LoadKeyedGeneric) \
- V(LoadNamedField) \
- V(LoadNamedGeneric) \
- V(LoadRoot) \
- V(MapEnumLength) \
- V(MathAbs) \
- V(MathClz32) \
- V(MathExp) \
- V(MathFloor) \
- V(MathLog) \
- V(MathMinMax) \
- V(MathPowHalf) \
- V(MathRound) \
- V(MathSqrt) \
- V(ModByConstI) \
- V(ModByPowerOf2I) \
- V(ModI) \
- V(MulI) \
- V(NumberTagD) \
- V(NumberTagI) \
- V(NumberTagU) \
- V(NumberUntagD) \
- V(OsrEntry) \
- V(Parameter) \
- V(Power) \
- V(PushArgument) \
- V(RegExpLiteral) \
- V(Return) \
- V(SeqStringGetChar) \
- V(SeqStringSetChar) \
- V(ShiftI) \
- V(SmiTag) \
- V(SmiUntag) \
- V(StackCheck) \
- V(StoreCodeEntry) \
- V(StoreContextSlot) \
- V(StoreFrameContext) \
- V(StoreGlobalCell) \
- V(StoreKeyed) \
- V(StoreKeyedGeneric) \
- V(StoreNamedField) \
- V(StoreNamedGeneric) \
- V(StringAdd) \
- V(StringCharCodeAt) \
- V(StringCharFromCode) \
- V(StringCompareAndBranch) \
- V(SubI) \
- V(TaggedToI) \
- V(ThisFunction) \
- V(ToFastProperties) \
- V(TransitionElementsKind) \
- V(TrapAllocationMemento) \
- V(Typeof) \
- V(TypeofIsAndBranch) \
- V(Uint32ToDouble) \
- V(UnknownOSRValue) \
+#define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \
+ V(AccessArgumentsAt) \
+ V(AddI) \
+ V(AllocateBlockContext) \
+ V(Allocate) \
+ V(ApplyArguments) \
+ V(ArgumentsElements) \
+ V(ArgumentsLength) \
+ V(ArithmeticD) \
+ V(ArithmeticT) \
+ V(BitI) \
+ V(BoundsCheck) \
+ V(Branch) \
+ V(CallJSFunction) \
+ V(CallWithDescriptor) \
+ V(CallFunction) \
+ V(CallNew) \
+ V(CallNewArray) \
+ V(CallRuntime) \
+ V(CallStub) \
+ V(CheckInstanceType) \
+ V(CheckMaps) \
+ V(CheckMapValue) \
+ V(CheckNonSmi) \
+ V(CheckSmi) \
+ V(CheckValue) \
+ V(ClampDToUint8) \
+ V(ClampIToUint8) \
+ V(ClampTToUint8) \
+ V(ClassOfTestAndBranch) \
+ V(CompareMinusZeroAndBranch) \
+ V(CompareNumericAndBranch) \
+ V(CmpObjectEqAndBranch) \
+ V(CmpHoleAndBranch) \
+ V(CmpMapAndBranch) \
+ V(CmpT) \
+ V(ConstantD) \
+ V(ConstantE) \
+ V(ConstantI) \
+ V(ConstantS) \
+ V(ConstantT) \
+ V(ConstructDouble) \
+ V(Context) \
+ V(DateField) \
+ V(DebugBreak) \
+ V(DeclareGlobals) \
+ V(Deoptimize) \
+ V(DivByConstI) \
+ V(DivByPowerOf2I) \
+ V(DivI) \
+ V(DoubleBits) \
+ V(DoubleToI) \
+ V(DoubleToSmi) \
+ V(Drop) \
+ V(Dummy) \
+ V(DummyUse) \
+ V(FlooringDivByConstI) \
+ V(FlooringDivByPowerOf2I) \
+ V(FlooringDivI) \
+ V(ForInCacheArray) \
+ V(ForInPrepareMap) \
+ V(FunctionLiteral) \
+ V(GetCachedArrayIndex) \
+ V(Goto) \
+ V(HasCachedArrayIndexAndBranch) \
+ V(HasInstanceTypeAndBranch) \
+ V(InnerAllocatedObject) \
+ V(InstanceOf) \
+ V(InstanceOfKnownGlobal) \
+ V(InstructionGap) \
+ V(Integer32ToDouble) \
+ V(InvokeFunction) \
+ V(IsConstructCallAndBranch) \
+ V(IsObjectAndBranch) \
+ V(IsStringAndBranch) \
+ V(IsSmiAndBranch) \
+ V(IsUndetectableAndBranch) \
+ V(Label) \
+ V(LazyBailout) \
+ V(LoadContextSlot) \
+ V(LoadFieldByIndex) \
+ V(LoadFunctionPrototype) \
+ V(LoadGlobalCell) \
+ V(LoadGlobalGeneric) \
+ V(LoadKeyed) \
+ V(LoadKeyedGeneric) \
+ V(LoadNamedField) \
+ V(LoadNamedGeneric) \
+ V(LoadRoot) \
+ V(MapEnumLength) \
+ V(MathAbs) \
+ V(MathClz32) \
+ V(MathExp) \
+ V(MathFloor) \
+ V(MathFround) \
+ V(MathLog) \
+ V(MathMinMax) \
+ V(MathPowHalf) \
+ V(MathRound) \
+ V(MathSqrt) \
+ V(ModByConstI) \
+ V(ModByPowerOf2I) \
+ V(ModI) \
+ V(MulI) \
+ V(NumberTagD) \
+ V(NumberTagI) \
+ V(NumberTagU) \
+ V(NumberUntagD) \
+ V(OsrEntry) \
+ V(Parameter) \
+ V(Power) \
+ V(PushArgument) \
+ V(RegExpLiteral) \
+ V(Return) \
+ V(SeqStringGetChar) \
+ V(SeqStringSetChar) \
+ V(ShiftI) \
+ V(SmiTag) \
+ V(SmiUntag) \
+ V(StackCheck) \
+ V(StoreCodeEntry) \
+ V(StoreContextSlot) \
+ V(StoreFrameContext) \
+ V(StoreGlobalCell) \
+ V(StoreKeyed) \
+ V(StoreKeyedGeneric) \
+ V(StoreNamedField) \
+ V(StoreNamedGeneric) \
+ V(StringAdd) \
+ V(StringCharCodeAt) \
+ V(StringCharFromCode) \
+ V(StringCompareAndBranch) \
+ V(SubI) \
+ V(TaggedToI) \
+ V(ThisFunction) \
+ V(ToFastProperties) \
+ V(TransitionElementsKind) \
+ V(TrapAllocationMemento) \
+ V(Typeof) \
+ V(TypeofIsAndBranch) \
+ V(Uint32ToDouble) \
+ V(UnknownOSRValue) \
V(WrapReceiver)
temps_[0] = temp;
}
- LOperand* value() { return inputs_[0]; }
LOperand* temp() { return temps_[0]; }
+ LOperand* value() { return inputs_[0]; }
DECLARE_CONCRETE_INSTRUCTION(MathRound, "math-round")
DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
};
+class LMathFround V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LMathFround(LOperand* value) { inputs_[0] = value; }
+
+ LOperand* value() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(MathRound, "math-fround")
+};
+
+
class LMathAbs V8_FINAL : public LTemplateInstruction<1, 2, 0> {
public:
LMathAbs(LOperand* context, LOperand* value) {
LInstruction* DoMathFloor(HUnaryMathOperation* instr);
LInstruction* DoMathRound(HUnaryMathOperation* instr);
+ LInstruction* DoMathFround(HUnaryMathOperation* instr);
LInstruction* DoMathAbs(HUnaryMathOperation* instr);
LInstruction* DoMathLog(HUnaryMathOperation* instr);
LInstruction* DoMathExp(HUnaryMathOperation* instr);
V(Math, max, MathMax) \
V(Math, min, MathMin) \
V(Math, imul, MathImul) \
- V(Math, clz32, MathClz32)
+ V(Math, clz32, MathClz32) \
+ V(Math, fround, MathFround)
enum BuiltinFunctionId {
kArrayCode,
}
+void LCodeGen::DoMathFround(LMathFround* instr) {
+ XMMRegister input_reg = ToDoubleRegister(instr->value());
+ XMMRegister output_reg = ToDoubleRegister(instr->result());
+ __ cvtsd2ss(output_reg, input_reg);
+ __ cvtss2sd(output_reg, output_reg);
+}
+
+
void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
XMMRegister output = ToDoubleRegister(instr->result());
if (instr->value()->IsDoubleRegister()) {
LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
switch (instr->op()) {
- case kMathFloor: return DoMathFloor(instr);
- case kMathRound: return DoMathRound(instr);
- case kMathAbs: return DoMathAbs(instr);
- case kMathLog: return DoMathLog(instr);
- case kMathExp: return DoMathExp(instr);
- case kMathSqrt: return DoMathSqrt(instr);
- case kMathPowHalf: return DoMathPowHalf(instr);
- case kMathClz32: return DoMathClz32(instr);
+ case kMathFloor:
+ return DoMathFloor(instr);
+ case kMathRound:
+ return DoMathRound(instr);
+ case kMathFround:
+ return DoMathFround(instr);
+ case kMathAbs:
+ return DoMathAbs(instr);
+ case kMathLog:
+ return DoMathLog(instr);
+ case kMathExp:
+ return DoMathExp(instr);
+ case kMathSqrt:
+ return DoMathSqrt(instr);
+ case kMathPowHalf:
+ return DoMathPowHalf(instr);
+ case kMathClz32:
+ return DoMathClz32(instr);
default:
UNREACHABLE();
return NULL;
}
+LInstruction* LChunkBuilder::DoMathFround(HUnaryMathOperation* instr) {
+ LOperand* input = UseRegister(instr->value());
+ LMathFround* result = new (zone()) LMathFround(input);
+ return DefineAsRegister(result);
+}
+
+
LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) {
LOperand* context = UseAny(instr->context());
LOperand* input = UseRegisterAtStart(instr->value());
// Forward declarations.
class LCodeGen;
-#define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \
- V(AccessArgumentsAt) \
- V(AddI) \
- V(Allocate) \
- V(AllocateBlockContext) \
- V(ApplyArguments) \
- V(ArgumentsElements) \
- V(ArgumentsLength) \
- V(ArithmeticD) \
- V(ArithmeticT) \
- V(BitI) \
- V(BoundsCheck) \
- V(Branch) \
- V(CallJSFunction) \
- V(CallWithDescriptor) \
- V(CallFunction) \
- V(CallNew) \
- V(CallNewArray) \
- V(CallRuntime) \
- V(CallStub) \
- V(CheckInstanceType) \
- V(CheckMaps) \
- V(CheckMapValue) \
- V(CheckNonSmi) \
- V(CheckSmi) \
- V(CheckValue) \
- V(ClampDToUint8) \
- V(ClampIToUint8) \
- V(ClampTToUint8) \
- V(ClassOfTestAndBranch) \
- V(CompareMinusZeroAndBranch) \
- V(CompareNumericAndBranch) \
- V(CmpObjectEqAndBranch) \
- V(CmpHoleAndBranch) \
- V(CmpMapAndBranch) \
- V(CmpT) \
- V(ConstantD) \
- V(ConstantE) \
- V(ConstantI) \
- V(ConstantS) \
- V(ConstantT) \
- V(ConstructDouble) \
- V(Context) \
- V(DateField) \
- V(DebugBreak) \
- V(DeclareGlobals) \
- V(Deoptimize) \
- V(DivByConstI) \
- V(DivByPowerOf2I) \
- V(DivI) \
- V(DoubleBits) \
- V(DoubleToI) \
- V(DoubleToSmi) \
- V(Drop) \
- V(DummyUse) \
- V(Dummy) \
- V(FlooringDivByConstI) \
- V(FlooringDivByPowerOf2I) \
- V(FlooringDivI) \
- V(ForInCacheArray) \
- V(ForInPrepareMap) \
- V(FunctionLiteral) \
- V(GetCachedArrayIndex) \
- V(Goto) \
- V(HasCachedArrayIndexAndBranch) \
- V(HasInstanceTypeAndBranch) \
- V(InnerAllocatedObject) \
- V(InstanceOf) \
- V(InstanceOfKnownGlobal) \
- V(InstructionGap) \
- V(Integer32ToDouble) \
- V(InvokeFunction) \
- V(IsConstructCallAndBranch) \
- V(IsObjectAndBranch) \
- V(IsStringAndBranch) \
- V(IsSmiAndBranch) \
- V(IsUndetectableAndBranch) \
- V(Label) \
- V(LazyBailout) \
- V(LoadContextSlot) \
- V(LoadRoot) \
- V(LoadFieldByIndex) \
- V(LoadFunctionPrototype) \
- V(LoadGlobalCell) \
- V(LoadGlobalGeneric) \
- V(LoadKeyed) \
- V(LoadKeyedGeneric) \
- V(LoadNamedField) \
- V(LoadNamedGeneric) \
- V(MapEnumLength) \
- V(MathAbs) \
- V(MathClz32) \
- V(MathExp) \
- V(MathFloor) \
- V(MathLog) \
- V(MathMinMax) \
- V(MathPowHalf) \
- V(MathRound) \
- V(MathSqrt) \
- V(ModByConstI) \
- V(ModByPowerOf2I) \
- V(ModI) \
- V(MulI) \
- V(NumberTagD) \
- V(NumberTagI) \
- V(NumberTagU) \
- V(NumberUntagD) \
- V(OsrEntry) \
- V(Parameter) \
- V(Power) \
- V(PushArgument) \
- V(RegExpLiteral) \
- V(Return) \
- V(SeqStringGetChar) \
- V(SeqStringSetChar) \
- V(ShiftI) \
- V(SmiTag) \
- V(SmiUntag) \
- V(StackCheck) \
- V(StoreCodeEntry) \
- V(StoreContextSlot) \
- V(StoreFrameContext) \
- V(StoreGlobalCell) \
- V(StoreKeyed) \
- V(StoreKeyedGeneric) \
- V(StoreNamedField) \
- V(StoreNamedGeneric) \
- V(StringAdd) \
- V(StringCharCodeAt) \
- V(StringCharFromCode) \
- V(StringCompareAndBranch) \
- V(SubI) \
- V(TaggedToI) \
- V(ThisFunction) \
- V(ToFastProperties) \
- V(TransitionElementsKind) \
- V(TrapAllocationMemento) \
- V(Typeof) \
- V(TypeofIsAndBranch) \
- V(Uint32ToDouble) \
- V(UnknownOSRValue) \
+#define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \
+ V(AccessArgumentsAt) \
+ V(AddI) \
+ V(Allocate) \
+ V(AllocateBlockContext) \
+ V(ApplyArguments) \
+ V(ArgumentsElements) \
+ V(ArgumentsLength) \
+ V(ArithmeticD) \
+ V(ArithmeticT) \
+ V(BitI) \
+ V(BoundsCheck) \
+ V(Branch) \
+ V(CallJSFunction) \
+ V(CallWithDescriptor) \
+ V(CallFunction) \
+ V(CallNew) \
+ V(CallNewArray) \
+ V(CallRuntime) \
+ V(CallStub) \
+ V(CheckInstanceType) \
+ V(CheckMaps) \
+ V(CheckMapValue) \
+ V(CheckNonSmi) \
+ V(CheckSmi) \
+ V(CheckValue) \
+ V(ClampDToUint8) \
+ V(ClampIToUint8) \
+ V(ClampTToUint8) \
+ V(ClassOfTestAndBranch) \
+ V(CompareMinusZeroAndBranch) \
+ V(CompareNumericAndBranch) \
+ V(CmpObjectEqAndBranch) \
+ V(CmpHoleAndBranch) \
+ V(CmpMapAndBranch) \
+ V(CmpT) \
+ V(ConstantD) \
+ V(ConstantE) \
+ V(ConstantI) \
+ V(ConstantS) \
+ V(ConstantT) \
+ V(ConstructDouble) \
+ V(Context) \
+ V(DateField) \
+ V(DebugBreak) \
+ V(DeclareGlobals) \
+ V(Deoptimize) \
+ V(DivByConstI) \
+ V(DivByPowerOf2I) \
+ V(DivI) \
+ V(DoubleBits) \
+ V(DoubleToI) \
+ V(DoubleToSmi) \
+ V(Drop) \
+ V(DummyUse) \
+ V(Dummy) \
+ V(FlooringDivByConstI) \
+ V(FlooringDivByPowerOf2I) \
+ V(FlooringDivI) \
+ V(ForInCacheArray) \
+ V(ForInPrepareMap) \
+ V(FunctionLiteral) \
+ V(GetCachedArrayIndex) \
+ V(Goto) \
+ V(HasCachedArrayIndexAndBranch) \
+ V(HasInstanceTypeAndBranch) \
+ V(InnerAllocatedObject) \
+ V(InstanceOf) \
+ V(InstanceOfKnownGlobal) \
+ V(InstructionGap) \
+ V(Integer32ToDouble) \
+ V(InvokeFunction) \
+ V(IsConstructCallAndBranch) \
+ V(IsObjectAndBranch) \
+ V(IsStringAndBranch) \
+ V(IsSmiAndBranch) \
+ V(IsUndetectableAndBranch) \
+ V(Label) \
+ V(LazyBailout) \
+ V(LoadContextSlot) \
+ V(LoadRoot) \
+ V(LoadFieldByIndex) \
+ V(LoadFunctionPrototype) \
+ V(LoadGlobalCell) \
+ V(LoadGlobalGeneric) \
+ V(LoadKeyed) \
+ V(LoadKeyedGeneric) \
+ V(LoadNamedField) \
+ V(LoadNamedGeneric) \
+ V(MapEnumLength) \
+ V(MathAbs) \
+ V(MathClz32) \
+ V(MathExp) \
+ V(MathFloor) \
+ V(MathFround) \
+ V(MathLog) \
+ V(MathMinMax) \
+ V(MathPowHalf) \
+ V(MathRound) \
+ V(MathSqrt) \
+ V(ModByConstI) \
+ V(ModByPowerOf2I) \
+ V(ModI) \
+ V(MulI) \
+ V(NumberTagD) \
+ V(NumberTagI) \
+ V(NumberTagU) \
+ V(NumberUntagD) \
+ V(OsrEntry) \
+ V(Parameter) \
+ V(Power) \
+ V(PushArgument) \
+ V(RegExpLiteral) \
+ V(Return) \
+ V(SeqStringGetChar) \
+ V(SeqStringSetChar) \
+ V(ShiftI) \
+ V(SmiTag) \
+ V(SmiUntag) \
+ V(StackCheck) \
+ V(StoreCodeEntry) \
+ V(StoreContextSlot) \
+ V(StoreFrameContext) \
+ V(StoreGlobalCell) \
+ V(StoreKeyed) \
+ V(StoreKeyedGeneric) \
+ V(StoreNamedField) \
+ V(StoreNamedGeneric) \
+ V(StringAdd) \
+ V(StringCharCodeAt) \
+ V(StringCharFromCode) \
+ V(StringCompareAndBranch) \
+ V(SubI) \
+ V(TaggedToI) \
+ V(ThisFunction) \
+ V(ToFastProperties) \
+ V(TransitionElementsKind) \
+ V(TrapAllocationMemento) \
+ V(Typeof) \
+ V(TypeofIsAndBranch) \
+ V(Uint32ToDouble) \
+ V(UnknownOSRValue) \
V(WrapReceiver)
class LMathRound V8_FINAL : public LTemplateInstruction<1, 1, 1> {
public:
- explicit LMathRound(LOperand* value, LOperand* temp) {
+ LMathRound(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp;
}
};
+class LMathFround V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+ explicit LMathFround(LOperand* value) { inputs_[0] = value; }
+
+ LOperand* value() { return inputs_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(MathRound, "math-fround")
+};
+
+
class LMathAbs V8_FINAL : public LTemplateInstruction<1, 2, 0> {
public:
explicit LMathAbs(LOperand* context, LOperand* value) {
LInstruction* DoMathFloor(HUnaryMathOperation* instr);
LInstruction* DoMathRound(HUnaryMathOperation* instr);
+ LInstruction* DoMathFround(HUnaryMathOperation* instr);
LInstruction* DoMathAbs(HUnaryMathOperation* instr);
LInstruction* DoMathLog(HUnaryMathOperation* instr);
LInstruction* DoMathExp(HUnaryMathOperation* instr);
assertEquals(Math.pow(2, 52) + 1, Math.round(Math.pow(2, 52) + 1));
});
+test(function mathFround() {
+ assertTrue(isNaN(Math.fround(NaN)));
+ assertEquals("Infinity", String(1/Math.fround(0)));
+ assertEquals("-Infinity", String(1/Math.fround(-0)));
+ assertEquals("Infinity", String(Math.fround(Infinity)));
+ assertEquals("-Infinity", String(Math.fround(-Infinity)));
+ assertEquals("Infinity", String(Math.fround(1E200)));
+ assertEquals("-Infinity", String(Math.fround(-1E200)));
+ assertEquals(3.1415927410125732, Math.fround(Math.PI));
+});
+
test(function mathFloor() {
assertEquals(1, Math.floor(1.5));
assertEquals(-2, Math.floor(-1.5));
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// Flags: --allow-natives-syntax
+
// Monkey-patch Float32Array.
Float32Array = function(x) { this[0] = 0; };
assertTrue(isNaN(Math.fround(function() {})));
assertTrue(isNaN(Math.fround({ toString: function() { return NaN; } })));
assertTrue(isNaN(Math.fround({ valueOf: function() { return "abc"; } })));
-assertEquals("Infinity", String(1/Math.fround(0)));
-assertEquals("-Infinity", String(1/Math.fround(-0)));
-assertEquals("Infinity", String(Math.fround(Infinity)));
-assertEquals("-Infinity", String(Math.fround(-Infinity)));
+assertTrue(isNaN(Math.fround(NaN)));
+assertTrue(isNaN(Math.fround(function() {})));
+assertTrue(isNaN(Math.fround({ toString: function() { return NaN; } })));
+assertTrue(isNaN(Math.fround({ valueOf: function() { return "abc"; } })));
-assertEquals("Infinity", String(Math.fround(1E200)));
-assertEquals("-Infinity", String(Math.fround(-1E200)));
-assertEquals("Infinity", String(1/Math.fround(1E-300)));
-assertEquals("-Infinity", String(1/Math.fround(-1E-300)));
+function unopt(x) { return Math.fround(x); }
+function opt(y) { return Math.fround(y); }
+
+opt(0.1);
+opt(0.1);
+unopt(0.1);
+%NeverOptimizeFunction(unopt);
+%OptimizeFunctionOnNextCall(opt);
+
+function test(f) {
+ assertEquals("Infinity", String(1/f(0)));
+ assertEquals("-Infinity", String(1/f(-0)));
+ assertEquals("Infinity", String(f(Infinity)));
+ assertEquals("-Infinity", String(f(-Infinity)));
+ assertEquals("Infinity", String(f(1E200)));
+ assertEquals("-Infinity", String(f(-1E200)));
+ assertEquals("Infinity", String(1/f(1E-300)));
+ assertEquals("-Infinity", String(1/f(-1E-300)));
+}
+
+test(opt);
+test(unopt);
mantissa_23_shift = Math.pow(2, -23);
mantissa_29_shift = Math.pow(2, -23-29);
var pi = new ieee754float(0, 0x400, 0x490fda, 0x14442d18);
-assertEquals(pi.toSingle(), Math.fround(pi.toDouble()));
+assertEquals(pi.toSingle(), opt(pi.toDouble()));
+assertEquals(pi.toSingle(), unopt(pi.toDouble()));
+
function fuzz_mantissa(sign, exp, m1inc, m2inc) {
for (var m1 = 0; m1 < (1 << 23); m1 += m1inc) {
for (var m2 = 0; m2 < (1 << 29); m2 += m2inc) {
var float = new ieee754float(sign, exp, m1, m2);
- assertEquals(float.toSingle(), Math.fround(float.toDouble()));
+ assertEquals(float.toSingle(), unopt(float.toDouble()));
+ assertEquals(float.toSingle(), opt(float.toDouble()));
}
}
}