| Index: src/x87/lithium-x87.cc
|
| diff --git a/src/x87/lithium-x87.cc b/src/x87/lithium-x87.cc
|
| index 02037c3b0861752d066ce75689ad920e4ce1e9a0..c3ff7424297d75853eae7b668e618c6ad988081b 100644
|
| --- a/src/x87/lithium-x87.cc
|
| +++ b/src/x87/lithium-x87.cc
|
| @@ -484,6 +484,12 @@ LUnallocated* LChunkBuilder::ToUnallocated(Register reg) {
|
| }
|
|
|
|
|
| +LUnallocated* LChunkBuilder::ToUnallocated(X87Register reg) {
|
| + return new(zone()) LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER,
|
| + X87Register::ToAllocationIndex(reg));
|
| +}
|
| +
|
| +
|
| LOperand* LChunkBuilder::UseFixed(HValue* value, Register fixed_register) {
|
| return Use(value, ToUnallocated(fixed_register));
|
| }
|
| @@ -616,6 +622,12 @@ LInstruction* LChunkBuilder::DefineFixed(LTemplateResultInstruction<1>* instr,
|
| }
|
|
|
|
|
| +LInstruction* LChunkBuilder::DefineFixed(LTemplateResultInstruction<1>* instr,
|
| + X87Register reg) {
|
| + return Define(instr, ToUnallocated(reg));
|
| +}
|
| +
|
| +
|
| LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
|
| HEnvironment* hydrogen_env = current_block_->last_environment();
|
| int argument_index_accumulator = 0;
|
| @@ -872,6 +884,14 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
|
| if (current->IsControlInstruction() &&
|
| HControlInstruction::cast(current)->KnownSuccessorBlock(&successor) &&
|
| successor != NULL) {
|
| + // Always insert a fpu register barrier here when branch is optimized to
|
| + // be a direct goto.
|
| + // TODO(weiliang): require a better solution.
|
| + if (!current->IsGoto()) {
|
| + LClobberDoubles* clobber = new(zone()) LClobberDoubles(isolate());
|
| + clobber->set_hydrogen_value(current);
|
| + chunk_->AddInstruction(clobber, current_block_);
|
| + }
|
| instr = new(zone()) LGoto(successor);
|
| } else {
|
| instr = current->CompileToLithium(this);
|
| @@ -931,7 +951,8 @@ void LChunkBuilder::AddInstruction(LInstruction* instr,
|
| if (FLAG_stress_environments && !instr->HasEnvironment()) {
|
| instr = AssignEnvironment(instr);
|
| }
|
| - if (instr->IsGoto() && LGoto::cast(instr)->jumps_to_join()) {
|
| + if (instr->IsGoto() &&
|
| + (LGoto::cast(instr)->jumps_to_join() || next_block_->is_osr_entry())) {
|
| // TODO(olivf) Since phis of spilled values are joined as registers
|
| // (not in the stack slot), we need to allow the goto gaps to keep one
|
| // x87 register alive. To ensure all other values are still spilled, we
|
| @@ -979,7 +1000,9 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
|
| bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() ||
|
| type.IsJSArray() || type.IsHeapNumber() || type.IsString();
|
| LOperand* temp = !easy_case && expected.NeedsMap() ? TempRegister() : NULL;
|
| - LInstruction* branch = new(zone()) LBranch(UseRegister(value), temp);
|
| + LInstruction* branch = temp != NULL
|
| + ? new(zone()) LBranch(UseRegister(value), temp)
|
| + : new(zone()) LBranch(UseRegisterAtStart(value), temp);
|
| if (!easy_case &&
|
| ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) ||
|
| !expected.IsGeneric())) {
|
| @@ -1182,16 +1205,16 @@ LInstruction* LChunkBuilder::DoMathFloor(HUnaryMathOperation* instr) {
|
|
|
|
|
| LInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) {
|
| - // Crankshaft is turned off for nosse2.
|
| - UNREACHABLE();
|
| - return NULL;
|
| + LOperand* input = UseRegisterAtStart(instr->value());
|
| + LInstruction* result = DefineAsRegister(new(zone()) LMathRound(input));
|
| + return AssignEnvironment(result);
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoMathFround(HUnaryMathOperation* instr) {
|
| - LOperand* input = UseRegisterAtStart(instr->value());
|
| + LOperand* input = UseRegister(instr->value());
|
| LMathFround* result = new (zone()) LMathFround(input);
|
| - return AssignEnvironment(DefineAsRegister(result));
|
| + return DefineSameAsFirst(result);
|
| }
|
|
|
|
|
| @@ -1225,11 +1248,11 @@ LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) {
|
| LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) {
|
| DCHECK(instr->representation().IsDouble());
|
| DCHECK(instr->value()->representation().IsDouble());
|
| - LOperand* value = UseTempRegister(instr->value());
|
| - LOperand* temp1 = TempRegister();
|
| - LOperand* temp2 = TempRegister();
|
| + LOperand* value = UseRegisterAtStart(instr->value());
|
| + LOperand* temp1 = FixedTemp(ecx);
|
| + LOperand* temp2 = FixedTemp(edx);
|
| LMathExp* result = new(zone()) LMathExp(value, temp1, temp2);
|
| - return DefineAsRegister(result);
|
| + return MarkAsCall(DefineSameAsFirst(result), instr);
|
| }
|
|
|
|
|
| @@ -1242,8 +1265,7 @@ LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) {
|
|
|
| LInstruction* LChunkBuilder::DoMathPowHalf(HUnaryMathOperation* instr) {
|
| LOperand* input = UseRegisterAtStart(instr->value());
|
| - LOperand* temp = TempRegister();
|
| - LMathPowHalf* result = new(zone()) LMathPowHalf(input, temp);
|
| + LMathPowHalf* result = new(zone()) LMathPowHalf(input);
|
| return DefineSameAsFirst(result);
|
| }
|
|
|
| @@ -1615,6 +1637,8 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
|
| LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) {
|
| LOperand* left = NULL;
|
| LOperand* right = NULL;
|
| + LOperand* scratch = TempRegister();
|
| +
|
| if (instr->representation().IsSmiOrInteger32()) {
|
| DCHECK(instr->left()->representation().Equals(instr->representation()));
|
| DCHECK(instr->right()->representation().Equals(instr->representation()));
|
| @@ -1627,15 +1651,19 @@ LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) {
|
| left = UseRegisterAtStart(instr->left());
|
| right = UseRegisterAtStart(instr->right());
|
| }
|
| - LMathMinMax* minmax = new(zone()) LMathMinMax(left, right);
|
| + LMathMinMax* minmax = new(zone()) LMathMinMax(left, right, scratch);
|
| return DefineSameAsFirst(minmax);
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoPower(HPower* instr) {
|
| - // Crankshaft is turned off for nosse2.
|
| - UNREACHABLE();
|
| - return NULL;
|
| + // Unlike ia32, we don't have a MathPowStub and directly call c function.
|
| + DCHECK(instr->representation().IsDouble());
|
| + DCHECK(instr->left()->representation().IsDouble());
|
| + LOperand* left = UseRegisterAtStart(instr->left());
|
| + LOperand* right = UseRegisterAtStart(instr->right());
|
| + LPower* result = new(zone()) LPower(left, right);
|
| + return MarkAsCall(DefineSameAsFirst(result), instr);
|
| }
|
|
|
|
|
| @@ -1697,9 +1725,8 @@ LInstruction* LChunkBuilder::DoCompareHoleAndBranch(
|
|
|
| LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch(
|
| HCompareMinusZeroAndBranch* instr) {
|
| - LOperand* value = UseRegister(instr->value());
|
| - LOperand* scratch = TempRegister();
|
| - return new(zone()) LCompareMinusZeroAndBranch(value, scratch);
|
| + LOperand* value = UseRegisterAtStart(instr->value());
|
| + return new(zone()) LCompareMinusZeroAndBranch(value);
|
| }
|
|
|
|
|
| @@ -2022,8 +2049,8 @@ LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
|
| HValue* value = instr->value();
|
| Representation input_rep = value->representation();
|
| if (input_rep.IsDouble()) {
|
| - UNREACHABLE();
|
| - return NULL;
|
| + LOperand* reg = UseRegister(value);
|
| + return DefineFixed(new(zone()) LClampDToUint8(reg), eax);
|
| } else if (input_rep.IsInteger32()) {
|
| LOperand* reg = UseFixed(value, eax);
|
| return DefineFixed(new(zone()) LClampIToUint8(reg), eax);
|
| @@ -2067,7 +2094,7 @@ LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
|
| } else if (r.IsInteger32()) {
|
| return DefineAsRegister(new(zone()) LConstantI);
|
| } else if (r.IsDouble()) {
|
| - return DefineAsRegister(new (zone()) LConstantD);
|
| + return DefineAsRegister(new(zone()) LConstantD);
|
| } else if (r.IsExternal()) {
|
| return DefineAsRegister(new(zone()) LConstantE);
|
| } else if (r.IsTagged()) {
|
|
|