| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 break; | 233 break; |
| 234 } else { | 234 } else { |
| 235 // Use sscanf to parse the individual parts of the command line. At the | 235 // Use sscanf to parse the individual parts of the command line. At the |
| 236 // moment no command expects more than two parameters. | 236 // moment no command expects more than two parameters. |
| 237 int args = SScanF(line, | 237 int args = SScanF(line, |
| 238 "%" XSTR(COMMAND_SIZE) "s " | 238 "%" XSTR(COMMAND_SIZE) "s " |
| 239 "%" XSTR(ARG_SIZE) "s " | 239 "%" XSTR(ARG_SIZE) "s " |
| 240 "%" XSTR(ARG_SIZE) "s", | 240 "%" XSTR(ARG_SIZE) "s", |
| 241 cmd, arg1, arg2); | 241 cmd, arg1, arg2); |
| 242 if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) { | 242 if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) { |
| 243 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); | 243 sim_->InstructionDecode(sim_->get_pc()); |
| 244 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) { | 244 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) { |
| 245 // Execute the one instruction we broke at with breakpoints disabled. | 245 // Execute the one instruction we broke at with breakpoints disabled. |
| 246 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); | 246 sim_->InstructionDecode(sim_->get_pc()); |
| 247 // Leave the debugger shell. | 247 // Leave the debugger shell. |
| 248 done = true; | 248 done = true; |
| 249 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) { | 249 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) { |
| 250 if (args == 2) { | 250 if (args == 2) { |
| 251 int32_t value; | 251 int32_t value; |
| 252 if (strcmp(arg1, "all") == 0) { | 252 if (strcmp(arg1, "all") == 0) { |
| 253 for (int i = 0; i < kNumRegisters; i++) { | 253 for (int i = 0; i < kNumRegisters; i++) { |
| 254 value = GetRegisterValue(i); | 254 value = GetRegisterValue(i); |
| 255 PrintF("%3s: 0x%08x %10d\n", Registers::Name(i), value, value); | 255 PrintF("%3s: 0x%08x %10d\n", Registers::Name(i), value, value); |
| 256 } | 256 } |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 397 RedoBreakpoints(); | 397 RedoBreakpoints(); |
| 398 | 398 |
| 399 #undef COMMAND_SIZE | 399 #undef COMMAND_SIZE |
| 400 #undef ARG_SIZE | 400 #undef ARG_SIZE |
| 401 | 401 |
| 402 #undef STR | 402 #undef STR |
| 403 #undef XSTR | 403 #undef XSTR |
| 404 } | 404 } |
| 405 | 405 |
| 406 | 406 |
| 407 |
| 408 InstrThumb2::InstrThumb2(byte* pc) |
| 409 : pc_(pc) { |
| 410 instr0_ = *reinterpret_cast<uint16_t*>(Address()); |
| 411 if (instr0_ > kMax16BitThumbOpcode) { |
| 412 instr1_ = *reinterpret_cast<uint16_t*>( |
| 413 reinterpret_cast<uint32_t>(Address() + 2)); |
| 414 size_ = 4; |
| 415 Decode32(); |
| 416 } else { |
| 417 size_ = 2; |
| 418 Decode16(); |
| 419 } |
| 420 } |
| 421 |
| 422 void InstrThumb2::Decode16() { |
| 423 switch (instr0_ & 0xff80) { // bits 15 - 11 |
| 424 case B13: |
| 425 Decode16_Rdn3Imm8(OP_CMP, VARIANT_IMMEDIATE); |
| 426 break; |
| 427 case B13 | B12: |
| 428 Decode16_Rdn3Imm8(OP_ADD, VARIANT_IMMEDIATE); |
| 429 break; |
| 430 case B15 | B13 | B11: |
| 431 Decode16_Rdn3Imm8(OP_ADD, VARIANT_SP_PLUS_IMMEDIATE); |
| 432 break; |
| 433 case B15 | B14 | B13: |
| 434 Decode16_Imm11(OP_B, VARIANT_REGISTER); |
| 435 break; |
| 436 case B15 | B14 | B13 | B12 | B11: |
| 437 Decode16_Imm11(OP_BL, VARIANT_IMMEDIATE); |
| 438 break; |
| 439 default: |
| 440 UnsupportedInstruction(); |
| 441 } |
| 442 } |
| 443 |
| 444 void InstrThumb2::Decode32() { |
| 445 switch (instr0_ & (0xff * B5)) { |
| 446 case B11 | B9: // 01010000 * B5 |
| 447 Decode32_SRn4XImm3Rd4Imm2Type2Rm4(OP_AND, VARIANT_REGISTER); |
| 448 DecodeImmShift(); |
| 449 break; |
| 450 case B11 | B9 | B8: // 01011000 * B5 |
| 451 Decode32_SRn4XImm3Rd4Imm2Type2Rm4(OP_ADD, VARIANT_REGISTER); |
| 452 DecodeImmShift(); |
| 453 break; |
| 454 case B12 | B8 | B7 | B5: // 10x01101 * B5; |
| 455 case B12 | B10 | B8 | B7 | B5: // B10 is part of Imm. |
| 456 Decode32_ImmX5SRn4XImm3Rd4Imm8(OP_SUB, VARIANT_IMMEDIATE); |
| 457 ThumbExpandImm(); |
| 458 break; |
| 459 |
| 460 default: |
| 461 UnsupportedInstruction(); |
| 462 } |
| 463 } |
| 464 |
| 465 void InstrThumb2::UnsupportedInstruction() { |
| 466 if (size_ == 2) { |
| 467 PrintF("Unsupported 16bit instruction %x\n", instr0_); |
| 468 } else { |
| 469 PrintF("Unsupported 32bit instruction %x:%x\n", instr0_, instr1_); |
| 470 } |
| 471 op_ = OP_UNSUPPORTED; |
| 472 } |
| 473 |
| 474 void InstrThumb2::Decode16_Rdn3Imm8(Operation op, OpVariant variant) { |
| 475 op_ = op; |
| 476 variant_ = variant; |
| 477 s_ = AUTO; |
| 478 |
| 479 imm_ = Bits0(7, 0); |
| 480 rd_ = rn_ = Bits0(10, 8); |
| 481 } |
| 482 |
| 483 void InstrThumb2::Decode16_Imm11(Operation op, OpVariant variant) { |
| 484 op_ = op; |
| 485 variant_ = variant; |
| 486 s_ = AUTO; |
| 487 |
| 488 imm_ = Bits0(10, 0); |
| 489 } |
| 490 |
| 491 void InstrThumb2::Decode32_SRn4XImm3Rd4Imm2Type2Rm4(Operation op, |
| 492 OpVariant variant) { |
| 493 op_ = op; |
| 494 variant_ = variant; |
| 495 |
| 496 s_ = Bit0(4); |
| 497 rn_ = Bits0(3, 0); |
| 498 imm_ = Bits1(14, 12) * B2 | Bits1(7, 6); |
| 499 rd_ = Bits1(11, 8); |
| 500 type_ = Bits1(5, 4); |
| 501 rm_ = Bits1(3, 0); |
| 502 } |
| 503 |
| 504 void InstrThumb2::Decode32_ImmX5SRn4XImm3Rd4Imm8(Operation op, |
| 505 OpVariant variant) { |
| 506 op_ = op; |
| 507 variant_ = variant; |
| 508 |
| 509 s_ = Bit0(4); |
| 510 imm_ = Bit0(10) * B11 | Bits1(14, 12) * B8 | Bits1(7, 0); |
| 511 rn_ = Bits0(3, 0); |
| 512 rd_ = Bits1(11, 8); |
| 513 } |
| 514 |
| 515 void InstrThumb2::DecodeImmShift() { |
| 516 if (imm_ == 0) { |
| 517 switch (type_) { |
| 518 case LSL: |
| 519 type_ = no_shift; |
| 520 break; |
| 521 case ASR: |
| 522 case LSR: |
| 523 imm_ = 32; |
| 524 break; |
| 525 case ROR: |
| 526 type_ = RRX; |
| 527 imm_ = 1; |
| 528 break; |
| 529 default: |
| 530 UnsupportedInstruction(); |
| 531 } |
| 532 } |
| 533 } |
| 534 |
| 535 void InstrThumb2::ThumbExpandImm() { |
| 536 if (imm_ > 255) { |
| 537 // TODO(haustein) Support thumb2 immediate shift here.. |
| 538 UnsupportedInstruction(); |
| 539 } |
| 540 } |
| 541 |
| 542 |
| 407 // Create one simulator per thread and keep it in thread local storage. | 543 // Create one simulator per thread and keep it in thread local storage. |
| 408 static v8::internal::Thread::LocalStorageKey simulator_key; | 544 static v8::internal::Thread::LocalStorageKey simulator_key; |
| 409 | 545 |
| 410 | 546 |
| 411 bool Simulator::initialized_ = false; | 547 bool Simulator::initialized_ = false; |
| 412 | 548 |
| 413 | 549 |
| 414 void Simulator::Initialize() { | 550 void Simulator::Initialize() { |
| 415 if (initialized_) return; | 551 if (initialized_) return; |
| 416 simulator_key = v8::internal::Thread::CreateThreadLocalKey(); | 552 simulator_key = v8::internal::Thread::CreateThreadLocalKey(); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 inexact_vfp_flag_ = false; | 595 inexact_vfp_flag_ = false; |
| 460 | 596 |
| 461 // The sp is initialized to point to the bottom (high address) of the | 597 // The sp is initialized to point to the bottom (high address) of the |
| 462 // allocated stack area. To be safe in potential stack underflows we leave | 598 // allocated stack area. To be safe in potential stack underflows we leave |
| 463 // some buffer below. | 599 // some buffer below. |
| 464 registers_[sp] = reinterpret_cast<int32_t>(stack_) + stack_size - 64; | 600 registers_[sp] = reinterpret_cast<int32_t>(stack_) + stack_size - 64; |
| 465 // The lr and pc are initialized to a known bad value that will cause an | 601 // The lr and pc are initialized to a known bad value that will cause an |
| 466 // access violation if the simulator ever tries to execute it. | 602 // access violation if the simulator ever tries to execute it. |
| 467 registers_[pc] = bad_lr; | 603 registers_[pc] = bad_lr; |
| 468 registers_[lr] = bad_lr; | 604 registers_[lr] = bad_lr; |
| 605 |
| 469 InitializeCoverage(); | 606 InitializeCoverage(); |
| 470 } | 607 } |
| 471 | 608 |
| 472 | 609 |
| 473 // When the generated code calls an external reference we need to catch that in | 610 // When the generated code calls an external reference we need to catch that in |
| 474 // the simulator. The external reference will be a function compiled for the | 611 // the simulator. The external reference will be a function compiled for the |
| 475 // host architecture. We need to call that function instead of trying to | 612 // host architecture. We need to call that function instead of trying to |
| 476 // execute it with the simulator. We do that by redirecting the external | 613 // execute it with the simulator. We do that by redirecting the external |
| 477 // reference to a swi (software-interrupt) instruction that is handled by | 614 // reference to a swi (software-interrupt) instruction that is handled by |
| 478 // the simulator. We write the original destination of the jump just at a known | 615 // the simulator. We write the original destination of the jump just at a known |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 pc_modified_ = true; | 687 pc_modified_ = true; |
| 551 } | 688 } |
| 552 registers_[reg] = value; | 689 registers_[reg] = value; |
| 553 } | 690 } |
| 554 | 691 |
| 555 | 692 |
| 556 // Get the register from the architecture state. This function does handle | 693 // Get the register from the architecture state. This function does handle |
| 557 // the special case of accessing the PC register. | 694 // the special case of accessing the PC register. |
| 558 int32_t Simulator::get_register(int reg) const { | 695 int32_t Simulator::get_register(int reg) const { |
| 559 ASSERT((reg >= 0) && (reg < num_registers)); | 696 ASSERT((reg >= 0) && (reg < num_registers)); |
| 560 return registers_[reg] + ((reg == pc) ? Instr::kPCReadOffset : 0); | 697 if (reg == pc) { |
| 698 return registers_[reg] + (InThumbMode() ? Instr::kPCReadOffsetThumb |
| 699 : Instr::kPCReadOffset); |
| 700 } |
| 701 return registers_[reg]; |
| 561 } | 702 } |
| 562 | 703 |
| 563 | 704 |
| 564 // Raw access to the PC register. | 705 // Raw access to the PC register. |
| 565 void Simulator::set_pc(int32_t value) { | 706 void Simulator::set_pc(int32_t value) { |
| 566 pc_modified_ = true; | 707 pc_modified_ = true; |
| 567 registers_[pc] = value; | 708 registers_[pc] = value; |
| 568 } | 709 } |
| 569 | 710 |
| 570 | 711 |
| (...skipping 1532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2103 break; | 2244 break; |
| 2104 } | 2245 } |
| 2105 default: | 2246 default: |
| 2106 UNIMPLEMENTED(); // Not used by V8. | 2247 UNIMPLEMENTED(); // Not used by V8. |
| 2107 break; | 2248 break; |
| 2108 } | 2249 } |
| 2109 } | 2250 } |
| 2110 } | 2251 } |
| 2111 | 2252 |
| 2112 | 2253 |
| 2113 // Executes the current instruction. | 2254 void Simulator::InstructionDecode(int32_t adr) { |
| 2114 void Simulator::InstructionDecode(Instr* instr) { | |
| 2115 pc_modified_ = false; | |
| 2116 if (::v8::internal::FLAG_trace_sim) { | 2255 if (::v8::internal::FLAG_trace_sim) { |
| 2117 disasm::NameConverter converter; | 2256 disasm::NameConverter converter; |
| 2118 disasm::Disassembler dasm(converter); | 2257 disasm::Disassembler dasm(converter); |
| 2119 // use a reasonably large buffer | 2258 // use a reasonably large buffer |
| 2120 v8::internal::EmbeddedVector<char, 256> buffer; | 2259 v8::internal::EmbeddedVector<char, 256> buffer; |
| 2121 dasm.InstructionDecode(buffer, | 2260 dasm.InstructionDecode(buffer, |
| 2122 reinterpret_cast<byte*>(instr)); | 2261 reinterpret_cast<byte*>(adr)); |
| 2123 PrintF(" 0x%08x %s\n", instr, buffer.start()); | 2262 PrintF(" 0x%08x %s\n", adr, buffer.start()); |
| 2124 } | 2263 } |
| 2264 if ((adr & 1) == 1) { |
| 2265 InstructionDecodeThumb2(reinterpret_cast<byte*>(adr)); |
| 2266 } else { |
| 2267 InstructionDecodeArm(reinterpret_cast<Instr*>(adr)); |
| 2268 } |
| 2269 } |
| 2270 |
| 2271 int32_t Simulator::GetOperand2(const InstrThumb2& instr, bool* carry_out) { |
| 2272 switch (instr.Variant()) { |
| 2273 case VARIANT_IMMEDIATE: |
| 2274 return instr.Imm(); |
| 2275 |
| 2276 case VARIANT_REGISTER: |
| 2277 return GetRmShiftImm(instr, carry_out); |
| 2278 |
| 2279 default: |
| 2280 UNIMPLEMENTED(); |
| 2281 return -1; |
| 2282 } |
| 2283 } |
| 2284 |
| 2285 int32_t Simulator::GetRmShiftImm(const InstrThumb2& instr, bool* carry_out) { |
| 2286 Shift shift = (Shift) instr.Type(); |
| 2287 int shift_amount = instr.Imm(); |
| 2288 int32_t result = get_register(instr.Rm()); |
| 2289 |
| 2290 switch (shift) { |
| 2291 case no_shift: |
| 2292 break; |
| 2293 |
| 2294 case ASR: { |
| 2295 ASSERT(shift_amount > 0); |
| 2296 result >>= (shift_amount - 1); |
| 2297 *carry_out = (result & 1) == 1; |
| 2298 result >>= 1; |
| 2299 break; |
| 2300 } |
| 2301 |
| 2302 case LSL: { |
| 2303 ASSERT(shift_amount > 0); |
| 2304 result <<= (shift_amount - 1); |
| 2305 *carry_out = (result < 0); |
| 2306 result <<= 1; |
| 2307 break; |
| 2308 } |
| 2309 |
| 2310 case LSR: { |
| 2311 uint32_t uresult = static_cast<uint32_t>(result); |
| 2312 ASSERT(shift_amount > 0); |
| 2313 uresult >>= (shift_amount - 1); |
| 2314 *carry_out = (uresult & 1) == 1; |
| 2315 uresult >>= 1; |
| 2316 result = static_cast<int32_t>(uresult); |
| 2317 break; |
| 2318 } |
| 2319 |
| 2320 case RRX: |
| 2321 case ROR: { |
| 2322 UNIMPLEMENTED(); |
| 2323 break; |
| 2324 } |
| 2325 |
| 2326 default: { |
| 2327 UNREACHABLE(); |
| 2328 break; |
| 2329 } |
| 2330 } |
| 2331 return result; |
| 2332 } |
| 2333 |
| 2334 |
| 2335 |
| 2336 void Simulator::InstructionDecodeThumb2(byte* adr) { |
| 2337 pc_modified_ = false; |
| 2338 InstrThumb2 instr(adr); |
| 2339 bool shifter_carry_out = 0; |
| 2340 int32_t alu_out; |
| 2341 int32_t operand2; |
| 2342 |
| 2343 int32_t rn_val = get_register(instr.Rn()); |
| 2344 switch (instr.Op()) { |
| 2345 case OP_AND: |
| 2346 alu_out = rn_val & GetOperand2(instr, &shifter_carry_out); |
| 2347 set_register(instr.Rd(), alu_out); |
| 2348 if (instr.HasS()) { |
| 2349 SetNZFlags(alu_out); |
| 2350 SetCFlag(shifter_carry_out); |
| 2351 } |
| 2352 break; |
| 2353 case OP_ADD: |
| 2354 operand2 = GetOperand2(instr, &shifter_carry_out); |
| 2355 alu_out = rn_val + operand2; |
| 2356 set_register(instr.Rd(), alu_out); |
| 2357 if (instr.HasS()) { |
| 2358 SetNZFlags(alu_out); |
| 2359 SetCFlag(CarryFrom(rn_val, operand2)); |
| 2360 SetVFlag(OverflowFrom(alu_out, rn_val, operand2, true)); |
| 2361 } |
| 2362 break; |
| 2363 |
| 2364 case OP_SUB: |
| 2365 operand2 = GetOperand2(instr, &shifter_carry_out); |
| 2366 alu_out = rn_val - operand2; |
| 2367 set_register(instr.Rd(), alu_out); |
| 2368 if (instr.HasS()) { |
| 2369 SetNZFlags(alu_out); |
| 2370 SetCFlag(!BorrowFrom(rn_val, operand2)); |
| 2371 SetVFlag(OverflowFrom(alu_out, rn_val, operand2, false)); |
| 2372 } |
| 2373 break; |
| 2374 |
| 2375 default: |
| 2376 PrintF("Unrecogized Thumb Instruction"); |
| 2377 UNIMPLEMENTED(); |
| 2378 } |
| 2379 if (!pc_modified_) { |
| 2380 set_register(pc, reinterpret_cast<int32_t>(adr) + instr.Size()); |
| 2381 } |
| 2382 } |
| 2383 |
| 2384 // Executes the current instruction. |
| 2385 void Simulator::InstructionDecodeArm(Instr* instr) { |
| 2386 pc_modified_ = false; |
| 2125 if (instr->ConditionField() == special_condition) { | 2387 if (instr->ConditionField() == special_condition) { |
| 2126 DecodeUnconditional(instr); | 2388 DecodeUnconditional(instr); |
| 2127 } else if (ConditionallyExecute(instr)) { | 2389 } else if (ConditionallyExecute(instr)) { |
| 2128 switch (instr->TypeField()) { | 2390 switch (instr->TypeField()) { |
| 2129 case 0: | 2391 case 0: |
| 2130 case 1: { | 2392 case 1: { |
| 2131 DecodeType01(instr); | 2393 DecodeType01(instr); |
| 2132 break; | 2394 break; |
| 2133 } | 2395 } |
| 2134 case 2: { | 2396 case 2: { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2169 | 2431 |
| 2170 void Simulator::Execute() { | 2432 void Simulator::Execute() { |
| 2171 // Get the PC to simulate. Cannot use the accessor here as we need the | 2433 // Get the PC to simulate. Cannot use the accessor here as we need the |
| 2172 // raw PC value and not the one used as input to arithmetic instructions. | 2434 // raw PC value and not the one used as input to arithmetic instructions. |
| 2173 int program_counter = get_pc(); | 2435 int program_counter = get_pc(); |
| 2174 | 2436 |
| 2175 if (::v8::internal::FLAG_stop_sim_at == 0) { | 2437 if (::v8::internal::FLAG_stop_sim_at == 0) { |
| 2176 // Fast version of the dispatch loop without checking whether the simulator | 2438 // Fast version of the dispatch loop without checking whether the simulator |
| 2177 // should be stopping at a particular executed instruction. | 2439 // should be stopping at a particular executed instruction. |
| 2178 while (program_counter != end_sim_pc) { | 2440 while (program_counter != end_sim_pc) { |
| 2179 Instr* instr = reinterpret_cast<Instr*>(program_counter); | |
| 2180 icount_++; | 2441 icount_++; |
| 2181 InstructionDecode(instr); | 2442 InstructionDecode(program_counter); |
| 2182 program_counter = get_pc(); | 2443 program_counter = get_pc(); |
| 2183 } | 2444 } |
| 2184 } else { | 2445 } else { |
| 2185 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when | 2446 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when |
| 2186 // we reach the particular instuction count. | 2447 // we reach the particular instuction count. |
| 2187 while (program_counter != end_sim_pc) { | 2448 while (program_counter != end_sim_pc) { |
| 2188 Instr* instr = reinterpret_cast<Instr*>(program_counter); | |
| 2189 icount_++; | 2449 icount_++; |
| 2190 if (icount_ == ::v8::internal::FLAG_stop_sim_at) { | 2450 if (icount_ == ::v8::internal::FLAG_stop_sim_at) { |
| 2191 Debugger dbg(this); | 2451 Debugger dbg(this); |
| 2192 dbg.Debug(); | 2452 dbg.Debug(); |
| 2193 } else { | 2453 } else { |
| 2194 InstructionDecode(instr); | 2454 InstructionDecode(program_counter); |
| 2195 } | 2455 } |
| 2196 program_counter = get_pc(); | 2456 program_counter = get_pc(); |
| 2197 } | 2457 } |
| 2198 } | 2458 } |
| 2199 } | 2459 } |
| 2200 | 2460 |
| 2201 | 2461 |
| 2202 int32_t Simulator::Call(byte* entry, int argument_count, ...) { | 2462 int32_t Simulator::Call(byte* entry, int argument_count, ...) { |
| 2203 va_list parameters; | 2463 va_list parameters; |
| 2204 va_start(parameters, argument_count); | 2464 va_start(parameters, argument_count); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2303 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); | 2563 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); |
| 2304 uintptr_t address = *stack_slot; | 2564 uintptr_t address = *stack_slot; |
| 2305 set_register(sp, current_sp + sizeof(uintptr_t)); | 2565 set_register(sp, current_sp + sizeof(uintptr_t)); |
| 2306 return address; | 2566 return address; |
| 2307 } | 2567 } |
| 2308 | 2568 |
| 2309 | 2569 |
| 2310 } } // namespace assembler::arm | 2570 } } // namespace assembler::arm |
| 2311 | 2571 |
| 2312 #endif // !defined(__arm__) | 2572 #endif // !defined(__arm__) |
| OLD | NEW |