| 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 |