| 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 1089 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1100 __ mfhi(result); | 1100 __ mfhi(result); |
| 1101 | 1101 |
| 1102 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1102 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1103 DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg)); | 1103 DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg)); |
| 1104 } | 1104 } |
| 1105 } | 1105 } |
| 1106 __ bind(&done); | 1106 __ bind(&done); |
| 1107 } | 1107 } |
| 1108 | 1108 |
| 1109 | 1109 |
| 1110 void LCodeGen::EmitSignedIntegerDivisionByConstant( |
| 1111 Register result, |
| 1112 Register dividend, |
| 1113 int32_t divisor, |
| 1114 Register remainder, |
| 1115 Register scratch, |
| 1116 LEnvironment* environment) { |
| 1117 ASSERT(!AreAliased(dividend, scratch, at, no_reg)); |
| 1118 |
| 1119 uint32_t divisor_abs = abs(divisor); |
| 1120 |
| 1121 int32_t power_of_2_factor = |
| 1122 CompilerIntrinsics::CountTrailingZeros(divisor_abs); |
| 1123 |
| 1124 switch (divisor_abs) { |
| 1125 case 0: |
| 1126 DeoptimizeIf(al, environment); |
| 1127 return; |
| 1128 |
| 1129 case 1: |
| 1130 if (divisor > 0) { |
| 1131 __ Move(result, dividend); |
| 1132 } else { |
| 1133 __ SubuAndCheckForOverflow(result, zero_reg, dividend, scratch); |
| 1134 DeoptimizeIf(lt, environment, scratch, Operand(zero_reg)); |
| 1135 } |
| 1136 // Compute the remainder. |
| 1137 __ Move(remainder, zero_reg); |
| 1138 return; |
| 1139 |
| 1140 default: |
| 1141 if (IsPowerOf2(divisor_abs)) { |
| 1142 // Branch and condition free code for integer division by a power |
| 1143 // of two. |
| 1144 int32_t power = WhichPowerOf2(divisor_abs); |
| 1145 if (power > 1) { |
| 1146 __ sra(scratch, dividend, power - 1); |
| 1147 } |
| 1148 __ srl(scratch, scratch, 32 - power); |
| 1149 __ Addu(scratch, dividend, Operand(scratch)); |
| 1150 __ sra(result, scratch, power); |
| 1151 // Negate if necessary. |
| 1152 // We don't need to check for overflow because the case '-1' is |
| 1153 // handled separately. |
| 1154 if (divisor < 0) { |
| 1155 ASSERT(divisor != -1); |
| 1156 __ Subu(result, zero_reg, Operand(result)); |
| 1157 } |
| 1158 // Compute the remainder. |
| 1159 if (divisor > 0) { |
| 1160 __ sll(scratch, result, power); |
| 1161 __ Subu(remainder, dividend, Operand(scratch)); |
| 1162 } else { |
| 1163 __ sll(scratch, result, power); |
| 1164 __ Addu(remainder, dividend, Operand(scratch)); |
| 1165 } |
| 1166 return; |
| 1167 } else if (LChunkBuilder::HasMagicNumberForDivisor(divisor)) { |
| 1168 // Use magic numbers for a few specific divisors. |
| 1169 // Details and proofs can be found in: |
| 1170 // - Hacker's Delight, Henry S. Warren, Jr. |
| 1171 // - The PowerPC Compiler Writer's Guide |
| 1172 // and probably many others. |
| 1173 // |
| 1174 // We handle |
| 1175 // <divisor with magic numbers> * <power of 2> |
| 1176 // but not |
| 1177 // <divisor with magic numbers> * <other divisor with magic numbers> |
| 1178 DivMagicNumbers magic_numbers = |
| 1179 DivMagicNumberFor(divisor_abs >> power_of_2_factor); |
| 1180 // Branch and condition free code for integer division by a power |
| 1181 // of two. |
| 1182 const int32_t M = magic_numbers.M; |
| 1183 const int32_t s = magic_numbers.s + power_of_2_factor; |
| 1184 |
| 1185 __ li(scratch, Operand(M)); |
| 1186 __ mult(dividend, scratch); |
| 1187 __ mfhi(scratch); |
| 1188 if (M < 0) { |
| 1189 __ Addu(scratch, scratch, Operand(dividend)); |
| 1190 } |
| 1191 if (s > 0) { |
| 1192 __ sra(scratch, scratch, s); |
| 1193 __ mov(scratch, scratch); |
| 1194 } |
| 1195 __ srl(at, dividend, 31); |
| 1196 __ Addu(result, scratch, Operand(at)); |
| 1197 if (divisor < 0) __ Subu(result, zero_reg, Operand(result)); |
| 1198 // Compute the remainder. |
| 1199 __ li(scratch, Operand(divisor)); |
| 1200 // This sequence could be replaced with 'mls' when |
| 1201 // it gets implemented. |
| 1202 __ Mul(scratch, result, Operand(scratch)); |
| 1203 __ Subu(remainder, dividend, Operand(scratch)); |
| 1204 } else { |
| 1205 __ li(scratch, Operand(divisor)); |
| 1206 __ div(dividend, scratch); |
| 1207 __ mfhi(remainder); |
| 1208 __ mflo(result); |
| 1209 } |
| 1210 } |
| 1211 } |
| 1212 |
| 1213 |
| 1110 void LCodeGen::DoDivI(LDivI* instr) { | 1214 void LCodeGen::DoDivI(LDivI* instr) { |
| 1111 const Register left = ToRegister(instr->left()); | 1215 const Register left = ToRegister(instr->left()); |
| 1112 const Register right = ToRegister(instr->right()); | 1216 const Register right = ToRegister(instr->right()); |
| 1113 const Register result = ToRegister(instr->result()); | 1217 const Register result = ToRegister(instr->result()); |
| 1114 | 1218 |
| 1115 // On MIPS div is asynchronous - it will run in the background while we | 1219 // On MIPS div is asynchronous - it will run in the background while we |
| 1116 // check for special cases. | 1220 // check for special cases. |
| 1117 __ div(left, right); | 1221 __ div(left, right); |
| 1118 | 1222 |
| 1119 // Check for x / 0. | 1223 // Check for x / 0. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1148 DoubleRegister multiplier = ToDoubleRegister(instr->multiplier()); | 1252 DoubleRegister multiplier = ToDoubleRegister(instr->multiplier()); |
| 1149 DoubleRegister multiplicand = ToDoubleRegister(instr->multiplicand()); | 1253 DoubleRegister multiplicand = ToDoubleRegister(instr->multiplicand()); |
| 1150 | 1254 |
| 1151 // This is computed in-place. | 1255 // This is computed in-place. |
| 1152 ASSERT(addend.is(ToDoubleRegister(instr->result()))); | 1256 ASSERT(addend.is(ToDoubleRegister(instr->result()))); |
| 1153 | 1257 |
| 1154 __ madd_d(addend, addend, multiplier, multiplicand); | 1258 __ madd_d(addend, addend, multiplier, multiplicand); |
| 1155 } | 1259 } |
| 1156 | 1260 |
| 1157 | 1261 |
| 1262 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) { |
| 1263 const Register result = ToRegister(instr->result()); |
| 1264 const Register left = ToRegister(instr->left()); |
| 1265 const Register remainder = ToRegister(instr->temp()); |
| 1266 const Register scratch = scratch0(); |
| 1267 |
| 1268 Label done; |
| 1269 // We only optimize this for division by constants, because the standard |
| 1270 // integer division routine is usually slower than transitionning to FPU. |
| 1271 ASSERT(instr->right()->IsConstantOperand()); |
| 1272 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right())); |
| 1273 if (divisor < 0) { |
| 1274 DeoptimizeIf(eq, instr->environment(), left, Operand(zero_reg)); |
| 1275 } |
| 1276 EmitSignedIntegerDivisionByConstant(result, |
| 1277 left, |
| 1278 divisor, |
| 1279 remainder, |
| 1280 scratch, |
| 1281 instr->environment()); |
| 1282 // We operated a truncating division. Correct the result if necessary. |
| 1283 __ Branch(&done, eq, remainder, Operand(zero_reg), USE_DELAY_SLOT); |
| 1284 __ Xor(scratch , remainder, Operand(divisor)); |
| 1285 __ Branch(&done, ge, scratch, Operand(zero_reg)); |
| 1286 __ Subu(result, result, Operand(1)); |
| 1287 __ bind(&done); |
| 1288 } |
| 1289 |
| 1290 |
| 1158 void LCodeGen::DoMulI(LMulI* instr) { | 1291 void LCodeGen::DoMulI(LMulI* instr) { |
| 1159 Register scratch = scratch0(); | 1292 Register scratch = scratch0(); |
| 1160 Register result = ToRegister(instr->result()); | 1293 Register result = ToRegister(instr->result()); |
| 1161 // Note that result may alias left. | 1294 // Note that result may alias left. |
| 1162 Register left = ToRegister(instr->left()); | 1295 Register left = ToRegister(instr->left()); |
| 1163 LOperand* right_op = instr->right(); | 1296 LOperand* right_op = instr->right(); |
| 1164 | 1297 |
| 1165 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 1298 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
| 1166 bool bailout_on_minus_zero = | 1299 bool bailout_on_minus_zero = |
| 1167 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); | 1300 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); |
| (...skipping 4639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5807 __ Subu(scratch, result, scratch); | 5940 __ Subu(scratch, result, scratch); |
| 5808 __ lw(result, FieldMemOperand(scratch, | 5941 __ lw(result, FieldMemOperand(scratch, |
| 5809 FixedArray::kHeaderSize - kPointerSize)); | 5942 FixedArray::kHeaderSize - kPointerSize)); |
| 5810 __ bind(&done); | 5943 __ bind(&done); |
| 5811 } | 5944 } |
| 5812 | 5945 |
| 5813 | 5946 |
| 5814 #undef __ | 5947 #undef __ |
| 5815 | 5948 |
| 5816 } } // namespace v8::internal | 5949 } } // namespace v8::internal |
| OLD | NEW |