OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1137 // Result just fit in r64, because it's int32 * uint32. | 1137 // Result just fit in r64, because it's int32 * uint32. |
1138 __ imul(reg2, reg1); | 1138 __ imul(reg2, reg1); |
1139 | 1139 |
1140 __ addq(reg2, Immediate(1 << 30)); | 1140 __ addq(reg2, Immediate(1 << 30)); |
1141 __ sar(reg2, Immediate(shift)); | 1141 __ sar(reg2, Immediate(shift)); |
1142 } | 1142 } |
1143 } | 1143 } |
1144 | 1144 |
1145 | 1145 |
1146 void LCodeGen::DoDivI(LDivI* instr) { | 1146 void LCodeGen::DoDivI(LDivI* instr) { |
1147 if (instr->hydrogen()->HasPowerOf2Divisor()) { | 1147 if (!instr->is_flooring() && instr->hydrogen()->HasPowerOf2Divisor()) { |
1148 Register dividend = ToRegister(instr->left()); | 1148 Register dividend = ToRegister(instr->left()); |
1149 int32_t divisor = | 1149 int32_t divisor = |
1150 HConstant::cast(instr->hydrogen()->right())->Integer32Value(); | 1150 HConstant::cast(instr->hydrogen()->right())->Integer32Value(); |
1151 int32_t test_value = 0; | 1151 int32_t test_value = 0; |
1152 int32_t power = 0; | 1152 int32_t power = 0; |
1153 | 1153 |
1154 if (divisor > 0) { | 1154 if (divisor > 0) { |
1155 test_value = divisor - 1; | 1155 test_value = divisor - 1; |
1156 power = WhichPowerOf2(divisor); | 1156 power = WhichPowerOf2(divisor); |
1157 } else { | 1157 } else { |
(...skipping 26 matching lines...) Expand all Loading... |
1184 LOperand* right = instr->right(); | 1184 LOperand* right = instr->right(); |
1185 ASSERT(ToRegister(instr->result()).is(rax)); | 1185 ASSERT(ToRegister(instr->result()).is(rax)); |
1186 ASSERT(ToRegister(instr->left()).is(rax)); | 1186 ASSERT(ToRegister(instr->left()).is(rax)); |
1187 ASSERT(!ToRegister(instr->right()).is(rax)); | 1187 ASSERT(!ToRegister(instr->right()).is(rax)); |
1188 ASSERT(!ToRegister(instr->right()).is(rdx)); | 1188 ASSERT(!ToRegister(instr->right()).is(rdx)); |
1189 | 1189 |
1190 Register left_reg = rax; | 1190 Register left_reg = rax; |
1191 | 1191 |
1192 // Check for x / 0. | 1192 // Check for x / 0. |
1193 Register right_reg = ToRegister(right); | 1193 Register right_reg = ToRegister(right); |
1194 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { | 1194 if (instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) { |
1195 __ testl(right_reg, right_reg); | 1195 __ testl(right_reg, right_reg); |
1196 DeoptimizeIf(zero, instr->environment()); | 1196 DeoptimizeIf(zero, instr->environment()); |
1197 } | 1197 } |
1198 | 1198 |
1199 // Check for (0 / -x) that will produce negative zero. | 1199 // Check for (0 / -x) that will produce negative zero. |
1200 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1200 if (instr->hydrogen_value()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
1201 Label left_not_zero; | 1201 Label left_not_zero; |
1202 __ testl(left_reg, left_reg); | 1202 __ testl(left_reg, left_reg); |
1203 __ j(not_zero, &left_not_zero, Label::kNear); | 1203 __ j(not_zero, &left_not_zero, Label::kNear); |
1204 __ testl(right_reg, right_reg); | 1204 __ testl(right_reg, right_reg); |
1205 DeoptimizeIf(sign, instr->environment()); | 1205 DeoptimizeIf(sign, instr->environment()); |
1206 __ bind(&left_not_zero); | 1206 __ bind(&left_not_zero); |
1207 } | 1207 } |
1208 | 1208 |
1209 // Check for (kMinInt / -1). | 1209 // Check for (kMinInt / -1). |
1210 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 1210 if (instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)) { |
1211 Label left_not_min_int; | 1211 Label left_not_min_int; |
1212 __ cmpl(left_reg, Immediate(kMinInt)); | 1212 __ cmpl(left_reg, Immediate(kMinInt)); |
1213 __ j(not_zero, &left_not_min_int, Label::kNear); | 1213 __ j(not_zero, &left_not_min_int, Label::kNear); |
1214 __ cmpl(right_reg, Immediate(-1)); | 1214 __ cmpl(right_reg, Immediate(-1)); |
1215 DeoptimizeIf(zero, instr->environment()); | 1215 DeoptimizeIf(zero, instr->environment()); |
1216 __ bind(&left_not_min_int); | 1216 __ bind(&left_not_min_int); |
1217 } | 1217 } |
1218 | 1218 |
1219 // Sign extend to rdx. | 1219 // Sign extend to rdx. |
1220 __ cdq(); | 1220 __ cdq(); |
1221 __ idivl(right_reg); | 1221 __ idivl(right_reg); |
1222 | 1222 |
1223 // Deoptimize if remainder is not 0. | 1223 if (!instr->is_flooring()) { |
1224 __ testl(rdx, rdx); | 1224 // Deoptimize if remainder is not 0. |
1225 DeoptimizeIf(not_zero, instr->environment()); | 1225 __ testl(rdx, rdx); |
| 1226 DeoptimizeIf(not_zero, instr->environment()); |
| 1227 } else { |
| 1228 Label done; |
| 1229 __ testl(rdx, rdx); |
| 1230 __ j(zero, &done, Label::kNear); |
| 1231 __ xorl(rdx, right_reg); |
| 1232 __ sarl(rdx, Immediate(31)); |
| 1233 __ addl(rax, rdx); |
| 1234 __ bind(&done); |
| 1235 } |
1226 } | 1236 } |
1227 | 1237 |
1228 | 1238 |
1229 void LCodeGen::DoMulI(LMulI* instr) { | 1239 void LCodeGen::DoMulI(LMulI* instr) { |
1230 Register left = ToRegister(instr->left()); | 1240 Register left = ToRegister(instr->left()); |
1231 LOperand* right = instr->right(); | 1241 LOperand* right = instr->right(); |
1232 | 1242 |
1233 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1243 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
1234 __ movl(kScratchRegister, left); | 1244 __ movl(kScratchRegister, left); |
1235 } | 1245 } |
(...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1705 __ addsd(left, right); | 1715 __ addsd(left, right); |
1706 break; | 1716 break; |
1707 case Token::SUB: | 1717 case Token::SUB: |
1708 __ subsd(left, right); | 1718 __ subsd(left, right); |
1709 break; | 1719 break; |
1710 case Token::MUL: | 1720 case Token::MUL: |
1711 __ mulsd(left, right); | 1721 __ mulsd(left, right); |
1712 break; | 1722 break; |
1713 case Token::DIV: | 1723 case Token::DIV: |
1714 __ divsd(left, right); | 1724 __ divsd(left, right); |
| 1725 __ movaps(left, left); |
1715 break; | 1726 break; |
1716 case Token::MOD: | 1727 case Token::MOD: |
1717 __ PrepareCallCFunction(2); | 1728 __ PrepareCallCFunction(2); |
1718 __ movaps(xmm0, left); | 1729 __ movaps(xmm0, left); |
1719 ASSERT(right.is(xmm1)); | 1730 ASSERT(right.is(xmm1)); |
1720 __ CallCFunction( | 1731 __ CallCFunction( |
1721 ExternalReference::double_fp_operation(Token::MOD, isolate()), 2); | 1732 ExternalReference::double_fp_operation(Token::MOD, isolate()), 2); |
1722 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 1733 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
1723 __ movaps(result, xmm0); | 1734 __ movaps(result, xmm0); |
1724 break; | 1735 break; |
(...skipping 3814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5539 FixedArray::kHeaderSize - kPointerSize)); | 5550 FixedArray::kHeaderSize - kPointerSize)); |
5540 __ bind(&done); | 5551 __ bind(&done); |
5541 } | 5552 } |
5542 | 5553 |
5543 | 5554 |
5544 #undef __ | 5555 #undef __ |
5545 | 5556 |
5546 } } // namespace v8::internal | 5557 } } // namespace v8::internal |
5547 | 5558 |
5548 #endif // V8_TARGET_ARCH_X64 | 5559 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |