OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <limits.h> // For LONG_MIN, LONG_MAX. | 5 #include <limits.h> // For LONG_MIN, LONG_MAX. |
6 | 6 |
7 #if V8_TARGET_ARCH_ARM | 7 #if V8_TARGET_ARCH_ARM |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/base/division-by-constant.h" | 10 #include "src/base/division-by-constant.h" |
(...skipping 1218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1229 | 1229 |
1230 | 1230 |
1231 // On ARM this is just a synonym to make the purpose clear. | 1231 // On ARM this is just a synonym to make the purpose clear. |
1232 void MacroAssembler::MovFromFloatParameter(DwVfpRegister dst) { | 1232 void MacroAssembler::MovFromFloatParameter(DwVfpRegister dst) { |
1233 MovFromFloatResult(dst); | 1233 MovFromFloatResult(dst); |
1234 } | 1234 } |
1235 | 1235 |
1236 | 1236 |
1237 void MacroAssembler::InvokePrologue(const ParameterCount& expected, | 1237 void MacroAssembler::InvokePrologue(const ParameterCount& expected, |
1238 const ParameterCount& actual, | 1238 const ParameterCount& actual, |
1239 Handle<Code> code_constant, | |
1240 Register code_reg, | |
1241 Label* done, | 1239 Label* done, |
1242 bool* definitely_mismatches, | 1240 bool* definitely_mismatches, |
1243 InvokeFlag flag, | 1241 InvokeFlag flag, |
1244 const CallWrapper& call_wrapper) { | 1242 const CallWrapper& call_wrapper) { |
1245 bool definitely_matches = false; | 1243 bool definitely_matches = false; |
1246 *definitely_mismatches = false; | 1244 *definitely_mismatches = false; |
1247 Label regular_invoke; | 1245 Label regular_invoke; |
1248 | 1246 |
1249 // Check whether the expected and actual arguments count match. If not, | 1247 // Check whether the expected and actual arguments count match. If not, |
1250 // setup registers according to contract with ArgumentsAdaptorTrampoline: | 1248 // setup registers according to contract with ArgumentsAdaptorTrampoline: |
1251 // r0: actual arguments count | 1249 // r0: actual arguments count |
1252 // r1: function (passed through to callee) | 1250 // r1: function (passed through to callee) |
1253 // r2: expected arguments count | 1251 // r2: expected arguments count |
1254 | 1252 |
1255 // The code below is made a lot easier because the calling code already sets | 1253 // The code below is made a lot easier because the calling code already sets |
1256 // up actual and expected registers according to the contract if values are | 1254 // up actual and expected registers according to the contract if values are |
1257 // passed in registers. | 1255 // passed in registers. |
1258 DCHECK(actual.is_immediate() || actual.reg().is(r0)); | 1256 DCHECK(actual.is_immediate() || actual.reg().is(r0)); |
1259 DCHECK(expected.is_immediate() || expected.reg().is(r2)); | 1257 DCHECK(expected.is_immediate() || expected.reg().is(r2)); |
1260 DCHECK((!code_constant.is_null() && code_reg.is(no_reg)) || code_reg.is(r3)); | |
1261 | 1258 |
1262 if (expected.is_immediate()) { | 1259 if (expected.is_immediate()) { |
1263 DCHECK(actual.is_immediate()); | 1260 DCHECK(actual.is_immediate()); |
1264 mov(r0, Operand(actual.immediate())); | 1261 mov(r0, Operand(actual.immediate())); |
1265 if (expected.immediate() == actual.immediate()) { | 1262 if (expected.immediate() == actual.immediate()) { |
1266 definitely_matches = true; | 1263 definitely_matches = true; |
1267 } else { | 1264 } else { |
1268 const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel; | 1265 const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel; |
1269 if (expected.immediate() == sentinel) { | 1266 if (expected.immediate() == sentinel) { |
1270 // Don't worry about adapting arguments for builtins that | 1267 // Don't worry about adapting arguments for builtins that |
(...skipping 11 matching lines...) Expand all Loading... |
1282 mov(r0, Operand(actual.immediate())); | 1279 mov(r0, Operand(actual.immediate())); |
1283 cmp(expected.reg(), Operand(actual.immediate())); | 1280 cmp(expected.reg(), Operand(actual.immediate())); |
1284 b(eq, ®ular_invoke); | 1281 b(eq, ®ular_invoke); |
1285 } else { | 1282 } else { |
1286 cmp(expected.reg(), Operand(actual.reg())); | 1283 cmp(expected.reg(), Operand(actual.reg())); |
1287 b(eq, ®ular_invoke); | 1284 b(eq, ®ular_invoke); |
1288 } | 1285 } |
1289 } | 1286 } |
1290 | 1287 |
1291 if (!definitely_matches) { | 1288 if (!definitely_matches) { |
1292 if (!code_constant.is_null()) { | |
1293 mov(r3, Operand(code_constant)); | |
1294 add(r3, r3, Operand(Code::kHeaderSize - kHeapObjectTag)); | |
1295 } | |
1296 | |
1297 Handle<Code> adaptor = | 1289 Handle<Code> adaptor = |
1298 isolate()->builtins()->ArgumentsAdaptorTrampoline(); | 1290 isolate()->builtins()->ArgumentsAdaptorTrampoline(); |
1299 if (flag == CALL_FUNCTION) { | 1291 if (flag == CALL_FUNCTION) { |
1300 call_wrapper.BeforeCall(CallSize(adaptor)); | 1292 call_wrapper.BeforeCall(CallSize(adaptor)); |
1301 Call(adaptor); | 1293 Call(adaptor); |
1302 call_wrapper.AfterCall(); | 1294 call_wrapper.AfterCall(); |
1303 if (!*definitely_mismatches) { | 1295 if (!*definitely_mismatches) { |
1304 b(done); | 1296 b(done); |
1305 } | 1297 } |
1306 } else { | 1298 } else { |
1307 Jump(adaptor, RelocInfo::CODE_TARGET); | 1299 Jump(adaptor, RelocInfo::CODE_TARGET); |
1308 } | 1300 } |
1309 bind(®ular_invoke); | 1301 bind(®ular_invoke); |
1310 } | 1302 } |
1311 } | 1303 } |
1312 | 1304 |
1313 | 1305 |
1314 void MacroAssembler::InvokeCode(Register code, | 1306 void MacroAssembler::InvokeCode(Register code, |
1315 const ParameterCount& expected, | 1307 const ParameterCount& expected, |
1316 const ParameterCount& actual, | 1308 const ParameterCount& actual, |
1317 InvokeFlag flag, | 1309 InvokeFlag flag, |
1318 const CallWrapper& call_wrapper) { | 1310 const CallWrapper& call_wrapper) { |
1319 // You can't call a function without a valid frame. | 1311 // You can't call a function without a valid frame. |
1320 DCHECK(flag == JUMP_FUNCTION || has_frame()); | 1312 DCHECK(flag == JUMP_FUNCTION || has_frame()); |
1321 | 1313 |
1322 Label done; | 1314 Label done; |
1323 bool definitely_mismatches = false; | 1315 bool definitely_mismatches = false; |
1324 InvokePrologue(expected, actual, Handle<Code>::null(), code, | 1316 InvokePrologue(expected, actual, &done, &definitely_mismatches, flag, |
1325 &done, &definitely_mismatches, flag, | |
1326 call_wrapper); | 1317 call_wrapper); |
1327 if (!definitely_mismatches) { | 1318 if (!definitely_mismatches) { |
1328 if (flag == CALL_FUNCTION) { | 1319 if (flag == CALL_FUNCTION) { |
1329 call_wrapper.BeforeCall(CallSize(code)); | 1320 call_wrapper.BeforeCall(CallSize(code)); |
1330 Call(code); | 1321 Call(code); |
1331 call_wrapper.AfterCall(); | 1322 call_wrapper.AfterCall(); |
1332 } else { | 1323 } else { |
1333 DCHECK(flag == JUMP_FUNCTION); | 1324 DCHECK(flag == JUMP_FUNCTION); |
1334 Jump(code); | 1325 Jump(code); |
1335 } | 1326 } |
(...skipping 2387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3723 } | 3714 } |
3724 } | 3715 } |
3725 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); | 3716 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); |
3726 add(result, result, Operand(dividend, LSR, 31)); | 3717 add(result, result, Operand(dividend, LSR, 31)); |
3727 } | 3718 } |
3728 | 3719 |
3729 } // namespace internal | 3720 } // namespace internal |
3730 } // namespace v8 | 3721 } // namespace v8 |
3731 | 3722 |
3732 #endif // V8_TARGET_ARCH_ARM | 3723 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |