| Index: src/x64/lithium-x64.cc
|
| ===================================================================
|
| --- src/x64/lithium-x64.cc (revision 6859)
|
| +++ src/x64/lithium-x64.cc (working copy)
|
| @@ -1318,8 +1318,32 @@
|
|
|
|
|
| LInstruction* LChunkBuilder::DoMod(HMod* instr) {
|
| - Abort("Unimplemented: %s", "DoMod");
|
| - return NULL;
|
| + if (instr->representation().IsInteger32()) {
|
| + ASSERT(instr->left()->representation().IsInteger32());
|
| + ASSERT(instr->right()->representation().IsInteger32());
|
| + // The temporary operand is necessary to ensure that right is not allocated
|
| + // into edx.
|
| + LOperand* temp = FixedTemp(rdx);
|
| + LOperand* value = UseFixed(instr->left(), rax);
|
| + LOperand* divisor = UseRegister(instr->right());
|
| + LModI* mod = new LModI(value, divisor, temp);
|
| + LInstruction* result = DefineFixed(mod, rdx);
|
| + return (instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
|
| + instr->CheckFlag(HValue::kCanBeDivByZero))
|
| + ? AssignEnvironment(result)
|
| + : result;
|
| + } else if (instr->representation().IsTagged()) {
|
| + return DoArithmeticT(Token::MOD, instr);
|
| + } else {
|
| + ASSERT(instr->representation().IsDouble());
|
| + // We call a C function for double modulo. It can't trigger a GC.
|
| + // We need to use fixed result register for the call.
|
| + // TODO(fschneider): Allow any register as input registers.
|
| + LOperand* left = UseFixedDouble(instr->left(), xmm1);
|
| + LOperand* right = UseFixedDouble(instr->right(), xmm2);
|
| + LArithmeticD* result = new LArithmeticD(Token::MOD, left, right);
|
| + return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
|
| + }
|
| }
|
|
|
|
|
|
|