Index: src/ia32/lithium-ia32.cc |
=================================================================== |
--- src/ia32/lithium-ia32.cc (revision 11883) |
+++ src/ia32/lithium-ia32.cc (working copy) |
@@ -1347,12 +1347,57 @@ |
} |
-LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { |
- UNIMPLEMENTED(); |
+HValue* LChunkBuilder::SimplifiedDividendForMathFloorOfDiv(HValue* dividend) { |
+ // A value with an integer representation does not need to be transformed. |
+ if (dividend->representation().IsInteger32()) { |
+ return dividend; |
+ // A change from an integer32 can be replaced by the integer32 value. |
+ } else if (dividend->IsChange() && |
+ HChange::cast(dividend)->from().IsInteger32()) { |
+ return HChange::cast(dividend)->value(); |
+ } |
return NULL; |
} |
+HValue* LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(HValue* divisor) { |
+ if (divisor->IsConstant() && |
+ HConstant::cast(divisor)->HasInteger32Value()) { |
+ HConstant* constant_val = HConstant::cast(divisor); |
+ return constant_val->CopyToRepresentation(Representation::Integer32(), |
+ divisor->block()->zone()); |
+ } |
+ return NULL; |
+} |
+ |
+ |
+LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { |
+ HValue* right = instr->right(); |
+ ASSERT(right->IsConstant() && HConstant::cast(right)->HasInteger32Value()); |
+ LOperand* divisor = chunk_->DefineConstantOperand(HConstant::cast(right)); |
+ int32_t divisor_si = HConstant::cast(right)->Integer32Value(); |
+ if (divisor_si == 0) { |
+ LOperand* dividend = UseRegister(instr->left()); |
+ return AssignEnvironment(DefineAsRegister( |
+ new(zone()) LMathFloorOfDiv(dividend, divisor, NULL))); |
+ } else if (IsPowerOf2(abs(divisor_si))) { |
+ // use dividend as temp if divisor < 0 && divisor != -1 |
+ LOperand* dividend = divisor_si < -1 ? UseTempRegister(instr->left()) : |
+ UseRegisterAtStart(instr->left()); |
+ LInstruction* result = DefineAsRegister( |
+ new(zone()) LMathFloorOfDiv(dividend, divisor, NULL)); |
+ return divisor_si < 0 ? AssignEnvironment(result) : result; |
+ } else { |
+ // needs edx:eax, plus a temp |
+ LOperand* dividend = UseFixed(instr->left(), eax); |
+ LOperand* temp = TempRegister(); |
+ LInstruction* result = DefineFixed( |
+ new(zone()) LMathFloorOfDiv(dividend, divisor, temp), edx); |
+ return divisor_si < 0 ? AssignEnvironment(result) : result; |
+ } |
+} |
+ |
+ |
LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
if (instr->representation().IsInteger32()) { |
ASSERT(instr->left()->representation().IsInteger32()); |