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); | |
Yang
2012/12/27 14:41:53
Ditto, tests would be great.
| |
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 4303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5539 FixedArray::kHeaderSize - kPointerSize)); | 5549 FixedArray::kHeaderSize - kPointerSize)); |
5540 __ bind(&done); | 5550 __ bind(&done); |
5541 } | 5551 } |
5542 | 5552 |
5543 | 5553 |
5544 #undef __ | 5554 #undef __ |
5545 | 5555 |
5546 } } // namespace v8::internal | 5556 } } // namespace v8::internal |
5547 | 5557 |
5548 #endif // V8_TARGET_ARCH_X64 | 5558 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |