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 1147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1158 __ bind(&done); | 1158 __ bind(&done); |
1159 return; | 1159 return; |
1160 } | 1160 } |
1161 | 1161 |
1162 // These registers hold untagged 32 bit values. | 1162 // These registers hold untagged 32 bit values. |
1163 Register left = ToRegister(instr->left()); | 1163 Register left = ToRegister(instr->left()); |
1164 Register right = ToRegister(instr->right()); | 1164 Register right = ToRegister(instr->right()); |
1165 Register result = ToRegister(instr->result()); | 1165 Register result = ToRegister(instr->result()); |
1166 Label done; | 1166 Label done; |
1167 | 1167 |
| 1168 // Check for x % 0. |
| 1169 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { |
| 1170 __ cmp(right, Operand::Zero()); |
| 1171 DeoptimizeIf(eq, instr->environment()); |
| 1172 } |
| 1173 |
1168 if (CpuFeatures::IsSupported(SUDIV)) { | 1174 if (CpuFeatures::IsSupported(SUDIV)) { |
1169 CpuFeatureScope scope(masm(), SUDIV); | 1175 CpuFeatureScope scope(masm(), SUDIV); |
1170 // Check for x % 0. | |
1171 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { | |
1172 __ cmp(right, Operand::Zero()); | |
1173 DeoptimizeIf(eq, instr->environment()); | |
1174 } | |
1175 | |
1176 // Check for (kMinInt % -1). | 1176 // Check for (kMinInt % -1). |
1177 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 1177 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
1178 Label left_not_min_int; | 1178 Label left_not_min_int; |
1179 __ cmp(left, Operand(kMinInt)); | 1179 __ cmp(left, Operand(kMinInt)); |
1180 __ b(ne, &left_not_min_int); | 1180 __ b(ne, &left_not_min_int); |
1181 __ cmp(right, Operand(-1)); | 1181 __ cmp(right, Operand(-1)); |
1182 DeoptimizeIf(eq, instr->environment()); | 1182 DeoptimizeIf(eq, instr->environment()); |
1183 __ bind(&left_not_min_int); | 1183 __ bind(&left_not_min_int); |
1184 } | 1184 } |
1185 | 1185 |
1186 // For r3 = r1 % r2; we can have the following ARM code | 1186 // For r3 = r1 % r2; we can have the following ARM code |
1187 // sdiv r3, r1, r2 | 1187 // sdiv r3, r1, r2 |
1188 // mls r3, r3, r2, r1 | 1188 // mls r3, r3, r2, r1 |
1189 | 1189 |
1190 __ sdiv(result, left, right); | 1190 __ sdiv(result, left, right); |
1191 __ mls(result, result, right, left); | 1191 __ mls(result, result, right, left); |
1192 __ cmp(result, Operand::Zero()); | |
1193 __ b(ne, &done); | |
1194 | 1192 |
1195 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1193 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
1196 __ cmp(left, Operand::Zero()); | 1194 __ cmp(result, Operand::Zero()); |
1197 DeoptimizeIf(lt, instr->environment()); | 1195 __ b(ne, &done); |
| 1196 __ cmp(left, Operand::Zero()); |
| 1197 DeoptimizeIf(lt, instr->environment()); |
1198 } | 1198 } |
1199 } else { | 1199 } else { |
1200 Register scratch = scratch0(); | 1200 Register scratch = scratch0(); |
1201 Register scratch2 = ToRegister(instr->temp()); | 1201 Register scratch2 = ToRegister(instr->temp()); |
1202 DwVfpRegister dividend = ToDoubleRegister(instr->temp2()); | 1202 DwVfpRegister dividend = ToDoubleRegister(instr->temp2()); |
1203 DwVfpRegister divisor = ToDoubleRegister(instr->temp3()); | 1203 DwVfpRegister divisor = ToDoubleRegister(instr->temp3()); |
1204 DwVfpRegister quotient = double_scratch0(); | 1204 DwVfpRegister quotient = double_scratch0(); |
1205 | 1205 |
1206 ASSERT(!dividend.is(divisor)); | 1206 ASSERT(!dividend.is(divisor)); |
1207 ASSERT(!dividend.is(quotient)); | 1207 ASSERT(!dividend.is(quotient)); |
1208 ASSERT(!divisor.is(quotient)); | 1208 ASSERT(!divisor.is(quotient)); |
1209 ASSERT(!scratch.is(left)); | 1209 ASSERT(!scratch.is(left)); |
1210 ASSERT(!scratch.is(right)); | 1210 ASSERT(!scratch.is(right)); |
1211 ASSERT(!scratch.is(result)); | 1211 ASSERT(!scratch.is(result)); |
1212 | 1212 |
1213 Label vfp_modulo, both_positive, right_negative; | 1213 Label vfp_modulo, right_negative; |
1214 | |
1215 // Check for x % 0. | |
1216 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { | |
1217 __ cmp(right, Operand::Zero()); | |
1218 DeoptimizeIf(eq, instr->environment()); | |
1219 } | |
1220 | 1214 |
1221 __ Move(result, left); | 1215 __ Move(result, left); |
1222 | 1216 |
1223 // (0 % x) must yield 0 (if x is finite, which is the case here). | 1217 // (0 % x) must yield 0 (if x is finite, which is the case here). |
1224 __ cmp(left, Operand::Zero()); | 1218 __ cmp(left, Operand::Zero()); |
1225 __ b(eq, &done); | 1219 __ b(eq, &done); |
1226 // Preload right in a vfp register. | 1220 // Preload right in a vfp register. |
1227 __ vmov(divisor.low(), right); | 1221 __ vmov(divisor.low(), right); |
1228 __ b(lt, &vfp_modulo); | 1222 __ b(lt, &vfp_modulo); |
1229 | 1223 |
1230 __ cmp(left, Operand(right)); | 1224 __ cmp(left, Operand(right)); |
1231 __ b(lt, &done); | 1225 __ b(lt, &done); |
1232 | 1226 |
1233 // Check for (positive) power of two on the right hand side. | 1227 // Check for (positive) power of two on the right hand side. |
1234 __ JumpIfNotPowerOfTwoOrZeroAndNeg(right, | 1228 __ JumpIfNotPowerOfTwoOrZeroAndNeg(right, |
1235 scratch, | 1229 scratch, |
1236 &right_negative, | 1230 &right_negative, |
1237 &both_positive); | 1231 &vfp_modulo); |
1238 // Perform modulo operation (scratch contains right - 1). | 1232 // Perform modulo operation (scratch contains right - 1). |
1239 __ and_(result, scratch, Operand(left)); | 1233 __ and_(result, scratch, Operand(left)); |
1240 __ b(&done); | 1234 __ b(&done); |
1241 | 1235 |
1242 __ bind(&right_negative); | 1236 __ bind(&right_negative); |
1243 // Negate right. The sign of the divisor does not matter. | 1237 // Negate right. The sign of the divisor does not matter. |
1244 __ rsb(right, right, Operand::Zero()); | 1238 __ rsb(right, right, Operand::Zero()); |
1245 | 1239 |
1246 __ bind(&both_positive); | |
1247 const int kUnfolds = 3; | |
1248 // If the right hand side is smaller than the (nonnegative) | |
1249 // left hand side, the left hand side is the result. | |
1250 // Else try a few subtractions of the left hand side. | |
1251 __ mov(scratch, left); | |
1252 for (int i = 0; i < kUnfolds; i++) { | |
1253 // Check if the left hand side is less or equal than the | |
1254 // the right hand side. | |
1255 __ cmp(scratch, Operand(right)); | |
1256 __ mov(result, scratch, LeaveCC, lt); | |
1257 __ b(lt, &done); | |
1258 // If not, reduce the left hand side by the right hand | |
1259 // side and check again. | |
1260 if (i < kUnfolds - 1) __ sub(scratch, scratch, right); | |
1261 } | |
1262 | |
1263 __ bind(&vfp_modulo); | 1240 __ bind(&vfp_modulo); |
1264 // Load the arguments in VFP registers. | 1241 // Load the arguments in VFP registers. |
1265 // The divisor value is preloaded before. Be careful that 'right' | 1242 // The divisor value is preloaded before. Be careful that 'right' |
1266 // is only live on entry. | 1243 // is only live on entry. |
1267 __ vmov(dividend.low(), left); | 1244 __ vmov(dividend.low(), left); |
1268 // From here on don't use right as it may have been reallocated | 1245 // From here on don't use right as it may have been reallocated |
1269 // (for example to scratch2). | 1246 // (for example to scratch2). |
1270 right = no_reg; | 1247 right = no_reg; |
1271 | 1248 |
1272 __ vcvt_f64_s32(dividend, dividend.low()); | 1249 __ vcvt_f64_s32(dividend, dividend.low()); |
(...skipping 4791 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6064 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); | 6041 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); |
6065 __ ldr(result, FieldMemOperand(scratch, | 6042 __ ldr(result, FieldMemOperand(scratch, |
6066 FixedArray::kHeaderSize - kPointerSize)); | 6043 FixedArray::kHeaderSize - kPointerSize)); |
6067 __ bind(&done); | 6044 __ bind(&done); |
6068 } | 6045 } |
6069 | 6046 |
6070 | 6047 |
6071 #undef __ | 6048 #undef __ |
6072 | 6049 |
6073 } } // namespace v8::internal | 6050 } } // namespace v8::internal |
OLD | NEW |