| 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 1077 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1088 } | 1088 } |
| 1089 | 1089 |
| 1090 __ bind(÷nd_is_not_negative); | 1090 __ bind(÷nd_is_not_negative); |
| 1091 __ And(dividend, dividend, Operand(mask)); | 1091 __ And(dividend, dividend, Operand(mask)); |
| 1092 __ bind(&done); | 1092 __ bind(&done); |
| 1093 } | 1093 } |
| 1094 | 1094 |
| 1095 | 1095 |
| 1096 void LCodeGen::DoModI(LModI* instr) { | 1096 void LCodeGen::DoModI(LModI* instr) { |
| 1097 HMod* hmod = instr->hydrogen(); | 1097 HMod* hmod = instr->hydrogen(); |
| 1098 HValue* left = hmod->left(); | |
| 1099 HValue* right = hmod->right(); | |
| 1100 const Register left_reg = ToRegister(instr->left()); | 1098 const Register left_reg = ToRegister(instr->left()); |
| 1101 const Register right_reg = ToRegister(instr->right()); | 1099 const Register right_reg = ToRegister(instr->right()); |
| 1102 const Register result_reg = ToRegister(instr->result()); | 1100 const Register result_reg = ToRegister(instr->result()); |
| 1103 | 1101 |
| 1104 // div runs in the background while we check for special cases. | 1102 // div runs in the background while we check for special cases. |
| 1105 __ div(left_reg, right_reg); | 1103 __ div(left_reg, right_reg); |
| 1106 | 1104 |
| 1107 Label done; | 1105 Label done; |
| 1108 // Check for x % 0, we have to deopt in this case because we can't return a | 1106 // Check for x % 0, we have to deopt in this case because we can't return a |
| 1109 // NaN. | 1107 // NaN. |
| 1110 if (right->CanBeZero()) { | 1108 if (hmod->CheckFlag(HValue::kCanBeDivByZero)) { |
| 1111 DeoptimizeIf(eq, instr->environment(), right_reg, Operand(zero_reg)); | 1109 DeoptimizeIf(eq, instr->environment(), right_reg, Operand(zero_reg)); |
| 1112 } | 1110 } |
| 1113 | 1111 |
| 1114 // Check for kMinInt % -1, we have to deopt if we care about -0, because we | 1112 // Check for kMinInt % -1, div will return kMinInt, which is not what we |
| 1115 // can't return that. | 1113 // want. We have to deopt if we care about -0, because we can't return that. |
| 1116 if (left->RangeCanInclude(kMinInt) && right->RangeCanInclude(-1)) { | 1114 if (hmod->CheckFlag(HValue::kCanOverflow)) { |
| 1117 Label left_not_min_int; | 1115 Label no_overflow_possible; |
| 1118 __ Branch(&left_not_min_int, ne, left_reg, Operand(kMinInt)); | 1116 __ Branch(&no_overflow_possible, ne, left_reg, Operand(kMinInt)); |
| 1119 // TODO(svenpanne) Don't deopt when we don't care about -0. | 1117 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1120 DeoptimizeIf(eq, instr->environment(), right_reg, Operand(-1)); | 1118 DeoptimizeIf(eq, instr->environment(), right_reg, Operand(-1)); |
| 1121 __ bind(&left_not_min_int); | 1119 } else { |
| 1120 __ Branch(&no_overflow_possible, ne, right_reg, Operand(-1)); |
| 1121 __ Branch(USE_DELAY_SLOT, &done); |
| 1122 __ mov(result_reg, zero_reg); |
| 1123 } |
| 1124 __ bind(&no_overflow_possible); |
| 1122 } | 1125 } |
| 1123 | 1126 |
| 1124 // TODO(svenpanne) Only emit the test/deopt if we have to. | 1127 // If we care about -0, test if the dividend is <0 and the result is 0. |
| 1125 __ Branch(USE_DELAY_SLOT, &done, ge, left_reg, Operand(zero_reg)); | 1128 __ Branch(USE_DELAY_SLOT, &done, ge, left_reg, Operand(zero_reg)); |
| 1126 __ mfhi(result_reg); | 1129 __ mfhi(result_reg); |
| 1127 | |
| 1128 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1130 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1129 DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg)); | 1131 DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg)); |
| 1130 } | 1132 } |
| 1131 __ bind(&done); | 1133 __ bind(&done); |
| 1132 } | 1134 } |
| 1133 | 1135 |
| 1134 | 1136 |
| 1135 void LCodeGen::DoDivI(LDivI* instr) { | 1137 void LCodeGen::DoDivI(LDivI* instr) { |
| 1138 HBinaryOperation* hdiv = instr->hydrogen(); |
| 1136 const Register left = ToRegister(instr->left()); | 1139 const Register left = ToRegister(instr->left()); |
| 1137 const Register right = ToRegister(instr->right()); | 1140 const Register right = ToRegister(instr->right()); |
| 1138 const Register result = ToRegister(instr->result()); | 1141 const Register result = ToRegister(instr->result()); |
| 1139 | 1142 |
| 1140 // On MIPS div is asynchronous - it will run in the background while we | 1143 // On MIPS div is asynchronous - it will run in the background while we |
| 1141 // check for special cases. | 1144 // check for special cases. |
| 1142 __ div(left, right); | 1145 __ div(left, right); |
| 1143 | 1146 |
| 1144 // Check for x / 0. | 1147 // Check for x / 0. |
| 1145 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { | 1148 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { |
| 1146 DeoptimizeIf(eq, instr->environment(), right, Operand(zero_reg)); | 1149 DeoptimizeIf(eq, instr->environment(), right, Operand(zero_reg)); |
| 1147 } | 1150 } |
| 1148 | 1151 |
| 1149 // Check for (0 / -x) that will produce negative zero. | 1152 // Check for (0 / -x) that will produce negative zero. |
| 1150 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1153 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1151 Label left_not_zero; | 1154 Label left_not_zero; |
| 1152 __ Branch(&left_not_zero, ne, left, Operand(zero_reg)); | 1155 __ Branch(&left_not_zero, ne, left, Operand(zero_reg)); |
| 1153 DeoptimizeIf(lt, instr->environment(), right, Operand(zero_reg)); | 1156 DeoptimizeIf(lt, instr->environment(), right, Operand(zero_reg)); |
| 1154 __ bind(&left_not_zero); | 1157 __ bind(&left_not_zero); |
| 1155 } | 1158 } |
| 1156 | 1159 |
| 1157 // Check for (kMinInt / -1). | 1160 // Check for (kMinInt / -1). |
| 1158 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 1161 if (hdiv->CheckFlag(HValue::kCanOverflow) && |
| 1162 !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { |
| 1159 Label left_not_min_int; | 1163 Label left_not_min_int; |
| 1160 __ Branch(&left_not_min_int, ne, left, Operand(kMinInt)); | 1164 __ Branch(&left_not_min_int, ne, left, Operand(kMinInt)); |
| 1161 DeoptimizeIf(eq, instr->environment(), right, Operand(-1)); | 1165 DeoptimizeIf(eq, instr->environment(), right, Operand(-1)); |
| 1162 __ bind(&left_not_min_int); | 1166 __ bind(&left_not_min_int); |
| 1163 } | 1167 } |
| 1164 | 1168 |
| 1165 if (!instr->hydrogen()->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { | 1169 if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { |
| 1166 __ mfhi(result); | 1170 __ mfhi(result); |
| 1167 DeoptimizeIf(ne, instr->environment(), result, Operand(zero_reg)); | 1171 DeoptimizeIf(ne, instr->environment(), result, Operand(zero_reg)); |
| 1168 } | 1172 } |
| 1169 __ mflo(result); | 1173 __ mflo(result); |
| 1170 } | 1174 } |
| 1171 | 1175 |
| 1172 | 1176 |
| 1173 void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) { | 1177 void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) { |
| 1174 DoubleRegister addend = ToDoubleRegister(instr->addend()); | 1178 DoubleRegister addend = ToDoubleRegister(instr->addend()); |
| 1175 DoubleRegister multiplier = ToDoubleRegister(instr->multiplier()); | 1179 DoubleRegister multiplier = ToDoubleRegister(instr->multiplier()); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1226 Register result = ToRegister(instr->result()); | 1230 Register result = ToRegister(instr->result()); |
| 1227 ASSERT(!dividend.is(result)); | 1231 ASSERT(!dividend.is(result)); |
| 1228 | 1232 |
| 1229 if (divisor == 0) { | 1233 if (divisor == 0) { |
| 1230 DeoptimizeIf(al, instr->environment()); | 1234 DeoptimizeIf(al, instr->environment()); |
| 1231 return; | 1235 return; |
| 1232 } | 1236 } |
| 1233 | 1237 |
| 1234 // Check for (0 / -x) that will produce negative zero. | 1238 // Check for (0 / -x) that will produce negative zero. |
| 1235 HMathFloorOfDiv* hdiv = instr->hydrogen(); | 1239 HMathFloorOfDiv* hdiv = instr->hydrogen(); |
| 1236 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && | 1240 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { |
| 1237 hdiv->left()->RangeCanInclude(0) && divisor < 0) { | |
| 1238 DeoptimizeIf(eq, instr->environment(), dividend, Operand(zero_reg)); | 1241 DeoptimizeIf(eq, instr->environment(), dividend, Operand(zero_reg)); |
| 1239 } | 1242 } |
| 1240 | 1243 |
| 1241 __ FlooringDiv(result, dividend, divisor); | 1244 __ FlooringDiv(result, dividend, divisor); |
| 1242 } | 1245 } |
| 1243 | 1246 |
| 1244 | 1247 |
| 1245 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) { | 1248 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) { |
| 1246 const Register result = ToRegister(instr->result()); | 1249 const Register result = ToRegister(instr->result()); |
| 1247 const Register left = ToRegister(instr->left()); | 1250 const Register left = ToRegister(instr->left()); |
| (...skipping 4468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5716 __ Subu(scratch, result, scratch); | 5719 __ Subu(scratch, result, scratch); |
| 5717 __ lw(result, FieldMemOperand(scratch, | 5720 __ lw(result, FieldMemOperand(scratch, |
| 5718 FixedArray::kHeaderSize - kPointerSize)); | 5721 FixedArray::kHeaderSize - kPointerSize)); |
| 5719 __ bind(&done); | 5722 __ bind(&done); |
| 5720 } | 5723 } |
| 5721 | 5724 |
| 5722 | 5725 |
| 5723 #undef __ | 5726 #undef __ |
| 5724 | 5727 |
| 5725 } } // namespace v8::internal | 5728 } } // namespace v8::internal |
| OLD | NEW |