Chromium Code Reviews| Index: src/a64/lithium-codegen-a64.cc |
| diff --git a/src/a64/lithium-codegen-a64.cc b/src/a64/lithium-codegen-a64.cc |
| index 534db081d8d22f90e41c83e17d700d1e61b59b2d..43b24ca57c010509784f8cc300dc761711aa148d 100644 |
| --- a/src/a64/lithium-codegen-a64.cc |
| +++ b/src/a64/lithium-codegen-a64.cc |
| @@ -3589,6 +3589,49 @@ void LCodeGen::DoMathFloor(LMathFloor* instr) { |
| } |
| +void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) { |
| + const Register result = ToRegister32(instr->result()); |
| + const Register left = ToRegister32(instr->left()); |
| + const Register right = ToRegister32(instr->right()); |
| + const Register remainder = ToRegister32(instr->temp()); |
|
jbramley
2014/01/23 14:15:13
We don't usually declare these as 'const'. If we'r
|
| + |
| + // Check for x / 0. |
| + DeoptimizeIfZero(right, instr->environment()); |
| + |
| + // Check for (kMinInt / -1). |
| + if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
| + __ Cmp(left, kMinInt); |
|
jbramley
2014/01/23 14:15:13
This will generate two instructions because cmp ca
|
| + __ Ccmp(right, -1, ZFlag, eq); |
| + DeoptimizeIf(eq, instr->environment()); |
| + } |
| + |
| + // Check for (0 / -x) that will produce negative zero. |
| + if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| + __ Cmp(right, 0); |
| + __ Ccmp(left, 0, ZFlag, mi); |
| + // "right" can't be null because the code would have already been |
| + // deoptimized. The Z flag is set only if (right < 0) and (left == 0). |
| + // In this case we need to deoptimize to produce a -0. |
| + DeoptimizeIf(eq, instr->environment()); |
| + } |
| + |
| + Label done; |
| + __ Sdiv(result, left, right); |
|
jbramley
2014/01/23 14:15:13
This can't cause an exception on ARM, so it can go
|
| + // If both operands have the same sign then we are done. |
| + __ Eor(remainder, left, Operand(right)); |
|
jbramley
2014/01/23 14:15:13
We have an implicit constructor for Operand (for s
|
| + __ Tbz(remainder, kWSignBit, &done); |
| + |
| + // Check if the result needs to be corrected. |
| + __ Mul(remainder, result, right); |
| + __ Sub(remainder, remainder, left); |
|
jbramley
2014/01/23 14:15:13
You can use Msub here instead of Mul and Sub:
__ M
|
| + __ Cmp(remainder, 0); |
|
baptiste.afsa1
2014/01/23 13:54:19
You can merge this two instructions into a Cbz.
|
| + __ B(eq, &done); |
| + __ Sub(result, result, Operand(1)); |
|
jbramley
2014/01/23 14:15:13
We have an implicit constructor for Operand (for s
|
| + |
| + __ Bind(&done); |
| +} |
| + |
| + |
| void LCodeGen::DoMathLog(LMathLog* instr) { |
| ASSERT(ToDoubleRegister(instr->result()).is(d0)); |
| TranscendentalCacheStub stub(TranscendentalCache::LOG, |