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()) { |