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 |