OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved.7 | 1 // Copyright 2012 the V8 project authors. All rights reserved.7 |
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 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1188 | 1188 |
1189 // This is computed in-place. | 1189 // This is computed in-place. |
1190 ASSERT(addend.is(ToDoubleRegister(instr->result()))); | 1190 ASSERT(addend.is(ToDoubleRegister(instr->result()))); |
1191 | 1191 |
1192 __ madd_d(addend, addend, multiplier, multiplicand); | 1192 __ madd_d(addend, addend, multiplier, multiplicand); |
1193 } | 1193 } |
1194 | 1194 |
1195 | 1195 |
1196 void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) { | 1196 void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) { |
1197 Register dividend = ToRegister(instr->dividend()); | 1197 Register dividend = ToRegister(instr->dividend()); |
| 1198 Register result = ToRegister(instr->result()); |
1198 int32_t divisor = instr->divisor(); | 1199 int32_t divisor = instr->divisor(); |
1199 ASSERT(dividend.is(ToRegister(instr->result()))); | |
1200 Register scratch = scratch0(); | 1200 Register scratch = scratch0(); |
| 1201 ASSERT(!scratch.is(dividend)); |
1201 | 1202 |
1202 // If the divisor is positive, things are easy: There can be no deopts and we | 1203 // If the divisor is positive, things are easy: There can be no deopts and we |
1203 // can simply do an arithmetic right shift. | 1204 // can simply do an arithmetic right shift. |
1204 if (divisor == 1) return; | 1205 if (divisor == 1) return; |
1205 uint16_t shift = WhichPowerOf2Abs(divisor); | 1206 uint16_t shift = WhichPowerOf2Abs(divisor); |
1206 if (divisor > 1) { | 1207 if (divisor > 1) { |
1207 __ sra(dividend, dividend, shift); | 1208 __ sra(result, dividend, shift); |
1208 return; | 1209 return; |
1209 } | 1210 } |
1210 | 1211 |
1211 // If the divisor is negative, we have to negate and handle edge cases. | 1212 // If the divisor is negative, we have to negate and handle edge cases. |
1212 Label not_kmin_int, done; | 1213 if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { |
1213 __ Subu(scratch, zero_reg, dividend); | 1214 __ Move(scratch, dividend); |
| 1215 } |
| 1216 __ Subu(result, zero_reg, dividend); |
1214 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1217 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
1215 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg)); | 1218 DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg)); |
1216 } | 1219 } |
1217 if (instr->hydrogen()->left()->RangeCanInclude(kMinInt)) { | 1220 if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { |
1218 // Note that we could emit branch-free code, but that would need one more | 1221 // Note that we could emit branch-free code, but that would need one more |
1219 // register. | 1222 // register. |
1220 __ Branch(¬_kmin_int, ne, dividend, Operand(kMinInt)); | 1223 |
| 1224 __ Xor(at, scratch, result); |
1221 if (divisor == -1) { | 1225 if (divisor == -1) { |
1222 DeoptimizeIf(al, instr->environment()); | 1226 DeoptimizeIf(ge, instr->environment(), at, Operand(zero_reg)); |
| 1227 __ sra(result, dividend, shift); |
1223 } else { | 1228 } else { |
1224 __ li(dividend, Operand(kMinInt / divisor)); | 1229 Label no_overflow, done; |
| 1230 __ Branch(&no_overflow, lt, at, Operand(zero_reg)); |
| 1231 __ li(result, Operand(kMinInt / divisor)); |
1225 __ Branch(&done); | 1232 __ Branch(&done); |
| 1233 __ bind(&no_overflow); |
| 1234 __ sra(result, dividend, shift); |
| 1235 __ bind(&done); |
1226 } | 1236 } |
| 1237 } else { |
| 1238 __ sra(result, dividend, shift); |
1227 } | 1239 } |
1228 __ bind(¬_kmin_int); | |
1229 __ sra(dividend, scratch, shift); | |
1230 __ bind(&done); | |
1231 } | 1240 } |
1232 | 1241 |
1233 | 1242 |
1234 void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { | 1243 void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { |
1235 Register dividend = ToRegister(instr->dividend()); | 1244 Register dividend = ToRegister(instr->dividend()); |
1236 int32_t divisor = instr->divisor(); | 1245 int32_t divisor = instr->divisor(); |
1237 Register result = ToRegister(instr->result()); | 1246 Register result = ToRegister(instr->result()); |
1238 ASSERT(!dividend.is(result)); | 1247 ASSERT(!dividend.is(result)); |
1239 | 1248 |
1240 if (divisor == 0) { | 1249 if (divisor == 0) { |
(...skipping 4484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5725 __ Subu(scratch, result, scratch); | 5734 __ Subu(scratch, result, scratch); |
5726 __ lw(result, FieldMemOperand(scratch, | 5735 __ lw(result, FieldMemOperand(scratch, |
5727 FixedArray::kHeaderSize - kPointerSize)); | 5736 FixedArray::kHeaderSize - kPointerSize)); |
5728 __ bind(&done); | 5737 __ bind(&done); |
5729 } | 5738 } |
5730 | 5739 |
5731 | 5740 |
5732 #undef __ | 5741 #undef __ |
5733 | 5742 |
5734 } } // namespace v8::internal | 5743 } } // namespace v8::internal |
OLD | NEW |