OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 } | 335 } |
336 } else if (strcmp(cmd, "del") == 0) { | 336 } else if (strcmp(cmd, "del") == 0) { |
337 if (!DeleteBreakpoint(NULL)) { | 337 if (!DeleteBreakpoint(NULL)) { |
338 PrintF("deleting breakpoint failed\n"); | 338 PrintF("deleting breakpoint failed\n"); |
339 } | 339 } |
340 } else if (strcmp(cmd, "flags") == 0) { | 340 } else if (strcmp(cmd, "flags") == 0) { |
341 PrintF("N flag: %d; ", sim_->n_flag_); | 341 PrintF("N flag: %d; ", sim_->n_flag_); |
342 PrintF("Z flag: %d; ", sim_->z_flag_); | 342 PrintF("Z flag: %d; ", sim_->z_flag_); |
343 PrintF("C flag: %d; ", sim_->c_flag_); | 343 PrintF("C flag: %d; ", sim_->c_flag_); |
344 PrintF("V flag: %d\n", sim_->v_flag_); | 344 PrintF("V flag: %d\n", sim_->v_flag_); |
| 345 PrintF("INVALID OP flag: %d; ", sim_->inv_op_vfp_flag_); |
| 346 PrintF("DIV BY ZERO flag: %d; ", sim_->div_zero_vfp_flag_); |
| 347 PrintF("OVERFLOW flag: %d; ", sim_->overflow_vfp_flag_); |
| 348 PrintF("UNDERFLOW flag: %d; ", sim_->underflow_vfp_flag_); |
| 349 PrintF("INEXACT flag: %d; ", sim_->inexact_vfp_flag_); |
345 } else if (strcmp(cmd, "unstop") == 0) { | 350 } else if (strcmp(cmd, "unstop") == 0) { |
346 intptr_t stop_pc = sim_->get_pc() - Instr::kInstrSize; | 351 intptr_t stop_pc = sim_->get_pc() - Instr::kInstrSize; |
347 Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc); | 352 Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc); |
348 if (stop_instr->ConditionField() == special_condition) { | 353 if (stop_instr->ConditionField() == special_condition) { |
349 stop_instr->SetInstructionBits(kNopInstr); | 354 stop_instr->SetInstructionBits(kNopInstr); |
350 } else { | 355 } else { |
351 PrintF("Not at debugger stop."); | 356 PrintF("Not at debugger stop."); |
352 } | 357 } |
353 } else if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) { | 358 } else if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) { |
354 PrintF("cont\n"); | 359 PrintF("cont\n"); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 // Setup architecture state. | 427 // Setup architecture state. |
423 // All registers are initialized to zero to start with. | 428 // All registers are initialized to zero to start with. |
424 for (int i = 0; i < num_registers; i++) { | 429 for (int i = 0; i < num_registers; i++) { |
425 registers_[i] = 0; | 430 registers_[i] = 0; |
426 } | 431 } |
427 n_flag_ = false; | 432 n_flag_ = false; |
428 z_flag_ = false; | 433 z_flag_ = false; |
429 c_flag_ = false; | 434 c_flag_ = false; |
430 v_flag_ = false; | 435 v_flag_ = false; |
431 | 436 |
| 437 // Initializing VFP registers. |
| 438 // All registers are initialized to zero to start with. |
| 439 // even though s_registers_ & d_registers_ share the same |
| 440 // physical registers in the target |
| 441 for (int i = 0; i < num_s_registers; i++) { |
| 442 vfp_register[i] = 0; |
| 443 } |
| 444 n_flag_FPSCR_ = false; |
| 445 z_flag_FPSCR_ = false; |
| 446 c_flag_FPSCR_ = false; |
| 447 v_flag_FPSCR_ = false; |
| 448 |
| 449 inv_op_vfp_flag_ = false; |
| 450 div_zero_vfp_flag_ = false; |
| 451 overflow_vfp_flag_ = false; |
| 452 underflow_vfp_flag_ = false; |
| 453 inexact_vfp_flag_ = false; |
| 454 |
432 // The sp is initialized to point to the bottom (high address) of the | 455 // The sp is initialized to point to the bottom (high address) of the |
433 // allocated stack area. To be safe in potential stack underflows we leave | 456 // allocated stack area. To be safe in potential stack underflows we leave |
434 // some buffer below. | 457 // some buffer below. |
435 registers_[sp] = reinterpret_cast<int32_t>(stack_) + stack_size - 64; | 458 registers_[sp] = reinterpret_cast<int32_t>(stack_) + stack_size - 64; |
436 // The lr and pc are initialized to a known bad value that will cause an | 459 // The lr and pc are initialized to a known bad value that will cause an |
437 // access violation if the simulator ever tries to execute it. | 460 // access violation if the simulator ever tries to execute it. |
438 registers_[pc] = bad_lr; | 461 registers_[pc] = bad_lr; |
439 registers_[lr] = bad_lr; | 462 registers_[lr] = bad_lr; |
440 InitializeCoverage(); | 463 InitializeCoverage(); |
441 } | 464 } |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
537 pc_modified_ = true; | 560 pc_modified_ = true; |
538 registers_[pc] = value; | 561 registers_[pc] = value; |
539 } | 562 } |
540 | 563 |
541 | 564 |
542 // Raw access to the PC register without the special adjustment when reading. | 565 // Raw access to the PC register without the special adjustment when reading. |
543 int32_t Simulator::get_pc() const { | 566 int32_t Simulator::get_pc() const { |
544 return registers_[pc]; | 567 return registers_[pc]; |
545 } | 568 } |
546 | 569 |
| 570 // Getting from and setting into VFP registers. |
| 571 void Simulator::set_s_register(int sreg, unsigned int value) { |
| 572 ASSERT((sreg >= 0) && (sreg < num_s_registers)); |
| 573 vfp_register[sreg] = value; |
| 574 } |
| 575 |
| 576 unsigned int Simulator::get_s_register(int sreg) const { |
| 577 ASSERT((sreg >= 0) && (sreg < num_s_registers)); |
| 578 return vfp_register[sreg]; |
| 579 } |
| 580 |
| 581 void Simulator::set_s_register_from_float(int sreg, const float flt) { |
| 582 ASSERT((sreg >= 0) && (sreg < num_s_registers)); |
| 583 // Read the bits from the single precision floating point value |
| 584 // into the unsigned integer element of vfp_register[] given by index=sreg. |
| 585 char buffer[sizeof(vfp_register[0])]; |
| 586 memcpy(buffer, &flt, sizeof(vfp_register[0])); |
| 587 memcpy(&vfp_register[sreg], buffer, sizeof(vfp_register[0])); |
| 588 } |
| 589 |
| 590 void Simulator::set_s_register_from_sinteger(int sreg, const int sint) { |
| 591 ASSERT((sreg >= 0) && (sreg < num_s_registers)); |
| 592 // Read the bits from the integer value |
| 593 // into the unsigned integer element of vfp_register[] given by index=sreg. |
| 594 char buffer[sizeof(vfp_register[0])]; |
| 595 memcpy(buffer, &sint, sizeof(vfp_register[0])); |
| 596 memcpy(&vfp_register[sreg], buffer, sizeof(vfp_register[0])); |
| 597 } |
| 598 |
| 599 void Simulator::set_d_register_from_double(int dreg, const double& dbl) { |
| 600 ASSERT((dreg >= 0) && (dreg < num_d_registers)); |
| 601 // Read the bits from the double precision floating point value |
| 602 // into the two consecutive unsigned integer elements of vfp_register[] |
| 603 // given by index 2*sreg and 2*sreg+1. |
| 604 char buffer[2 * sizeof(vfp_register[0])]; |
| 605 memcpy(buffer, &dbl, 2 * sizeof(vfp_register[0])); |
| 606 #ifndef BIG_ENDIAN_FLOATING_POINT |
| 607 memcpy(&vfp_register[dreg * 2], buffer, 2 * sizeof(vfp_register[0])); |
| 608 #else |
| 609 memcpy(&vfp_register[dreg * 2], &buffer[4], sizeof(vfp_register[0])); |
| 610 memcpy(&vfp_register[dreg * 2 + 1], &buffer[0], sizeof(vfp_register[0])); |
| 611 #endif |
| 612 } |
| 613 |
| 614 float Simulator::get_float_from_s_register(int sreg) { |
| 615 ASSERT((sreg >= 0) && (sreg < num_s_registers)); |
| 616 |
| 617 float sm_val = 0.0; |
| 618 // Read the bits from the unsigned integer vfp_register[] array |
| 619 // into the single precision floating point value and return it. |
| 620 char buffer[sizeof(vfp_register[0])]; |
| 621 memcpy(buffer, &vfp_register[sreg], sizeof(vfp_register[0])); |
| 622 memcpy(&sm_val, buffer, sizeof(vfp_register[0])); |
| 623 return(sm_val); |
| 624 } |
| 625 |
| 626 int Simulator::get_sinteger_from_s_register(int sreg) { |
| 627 ASSERT((sreg >= 0) && (sreg < num_s_registers)); |
| 628 |
| 629 int sm_val = 0; |
| 630 // Read the bits from the unsigned integer vfp_register[] array |
| 631 // into the single precision floating point value and return it. |
| 632 char buffer[sizeof(vfp_register[0])]; |
| 633 memcpy(buffer, &vfp_register[sreg], sizeof(vfp_register[0])); |
| 634 memcpy(&sm_val, buffer, sizeof(vfp_register[0])); |
| 635 return(sm_val); |
| 636 } |
| 637 |
| 638 double Simulator::get_double_from_d_register(int dreg) { |
| 639 ASSERT((dreg >= 0) && (dreg < num_d_registers)); |
| 640 |
| 641 double dm_val = 0.0; |
| 642 // Read the bits from the unsigned integer vfp_register[] array |
| 643 // into the double precision floating point value and return it. |
| 644 char buffer[2 * sizeof(vfp_register[0])]; |
| 645 #ifndef BIG_ENDIAN_FLOATING_POINT |
| 646 memcpy(buffer, &vfp_register[2 * dreg], 2 * sizeof(vfp_register[0])); |
| 647 #else |
| 648 memcpy(&buffer[0], &vfp_register[2 * dreg + 1], sizeof(vfp_register[0])); |
| 649 memcpy(&buffer[4], &vfp_register[2 * dreg], sizeof(vfp_register[0])); |
| 650 #endif |
| 651 memcpy(&dm_val, buffer, 2 * sizeof(vfp_register[0])); |
| 652 return(dm_val); |
| 653 } |
| 654 |
547 | 655 |
548 // For use in calls that take two double values, constructed from r0, r1, r2 | 656 // For use in calls that take two double values, constructed from r0, r1, r2 |
549 // and r3. | 657 // and r3. |
550 void Simulator::GetFpArgs(double* x, double* y) { | 658 void Simulator::GetFpArgs(double* x, double* y) { |
551 // We use a char buffer to get around the strict-aliasing rules which | 659 // We use a char buffer to get around the strict-aliasing rules which |
552 // otherwise allow the compiler to optimize away the copy. | 660 // otherwise allow the compiler to optimize away the copy. |
553 char buffer[2 * sizeof(registers_[0])]; | 661 char buffer[2 * sizeof(registers_[0])]; |
554 // Registers 0 and 1 -> x. | 662 // Registers 0 and 1 -> x. |
555 memcpy(buffer, registers_, sizeof(buffer)); | 663 memcpy(buffer, registers_, sizeof(buffer)); |
556 memcpy(x, buffer, sizeof(buffer)); | 664 memcpy(x, buffer, sizeof(buffer)); |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
764 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); | 872 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); |
765 } else { | 873 } else { |
766 // operands have different signs | 874 // operands have different signs |
767 overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0)) | 875 overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0)) |
768 // and first operand and result have different signs | 876 // and first operand and result have different signs |
769 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); | 877 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); |
770 } | 878 } |
771 return overflow; | 879 return overflow; |
772 } | 880 } |
773 | 881 |
| 882 // Support for VFP comparisons. |
| 883 void Simulator::Compute_FPSCR_Flags(double val1, double val2) { |
| 884 // All Non-Nan cases |
| 885 if (val1 == val2) { |
| 886 n_flag_FPSCR_ = false; |
| 887 z_flag_FPSCR_ = true; |
| 888 c_flag_FPSCR_ = true; |
| 889 v_flag_FPSCR_ = false; |
| 890 } else if (val1 < val2) { |
| 891 n_flag_FPSCR_ = true; |
| 892 z_flag_FPSCR_ = false; |
| 893 c_flag_FPSCR_ = false; |
| 894 v_flag_FPSCR_ = false; |
| 895 } else { |
| 896 // Case when (val1 > val2). |
| 897 n_flag_FPSCR_ = false; |
| 898 z_flag_FPSCR_ = false; |
| 899 c_flag_FPSCR_ = true; |
| 900 v_flag_FPSCR_ = false; |
| 901 } |
| 902 } |
| 903 |
| 904 |
| 905 void Simulator::Copy_FPSCR_to_APSR() { |
| 906 n_flag_ = n_flag_FPSCR_; |
| 907 z_flag_ = z_flag_FPSCR_; |
| 908 c_flag_ = c_flag_FPSCR_; |
| 909 v_flag_ = v_flag_FPSCR_; |
| 910 } |
| 911 |
| 912 |
774 | 913 |
775 // Addressing Mode 1 - Data-processing operands: | 914 // Addressing Mode 1 - Data-processing operands: |
776 // Get the value based on the shifter_operand with register. | 915 // Get the value based on the shifter_operand with register. |
777 int32_t Simulator::GetShiftRm(Instr* instr, bool* carry_out) { | 916 int32_t Simulator::GetShiftRm(Instr* instr, bool* carry_out) { |
778 Shift shift = instr->ShiftField(); | 917 Shift shift = instr->ShiftField(); |
779 int shift_amount = instr->ShiftAmountField(); | 918 int shift_amount = instr->ShiftAmountField(); |
780 int32_t result = get_register(instr->RmField()); | 919 int32_t result = get_register(instr->RmField()); |
781 if (instr->Bit(4) == 0) { | 920 if (instr->Bit(4) == 0) { |
782 // by immediate | 921 // by immediate |
783 if ((shift == ROR) && (shift_amount == 0)) { | 922 if ((shift == ROR) && (shift_amount == 0)) { |
(...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1657 intptr_t pc_address = get_pc(); | 1796 intptr_t pc_address = get_pc(); |
1658 if (instr->HasLink()) { | 1797 if (instr->HasLink()) { |
1659 set_register(lr, pc_address + Instr::kInstrSize); | 1798 set_register(lr, pc_address + Instr::kInstrSize); |
1660 } | 1799 } |
1661 int pc_reg = get_register(pc); | 1800 int pc_reg = get_register(pc); |
1662 set_pc(pc_reg + off); | 1801 set_pc(pc_reg + off); |
1663 } | 1802 } |
1664 | 1803 |
1665 | 1804 |
1666 void Simulator::DecodeType6(Instr* instr) { | 1805 void Simulator::DecodeType6(Instr* instr) { |
1667 UNIMPLEMENTED(); | 1806 DecodeType6CoprocessorIns(instr); |
1668 } | 1807 } |
1669 | 1808 |
1670 | 1809 |
1671 void Simulator::DecodeType7(Instr* instr) { | 1810 void Simulator::DecodeType7(Instr* instr) { |
1672 if (instr->Bit(24) == 1) { | 1811 if (instr->Bit(24) == 1) { |
1673 // Format(instr, "swi 'swi"); | |
1674 SoftwareInterrupt(instr); | 1812 SoftwareInterrupt(instr); |
1675 } else { | 1813 } else { |
1676 UNIMPLEMENTED(); | 1814 DecodeTypeVFP(instr); |
1677 } | 1815 } |
1678 } | 1816 } |
1679 | 1817 |
1680 | 1818 |
1681 void Simulator::DecodeUnconditional(Instr* instr) { | 1819 void Simulator::DecodeUnconditional(Instr* instr) { |
1682 if (instr->Bits(7, 4) == 0x0B && instr->Bits(27, 25) == 0 && instr->HasL()) { | 1820 if (instr->Bits(7, 4) == 0x0B && instr->Bits(27, 25) == 0 && instr->HasL()) { |
1683 // Load halfword instruction, either register or immediate offset. | 1821 // Load halfword instruction, either register or immediate offset. |
1684 int rd = instr->RdField(); | 1822 int rd = instr->RdField(); |
1685 int rn = instr->RnField(); | 1823 int rn = instr->RnField(); |
1686 int32_t rn_val = get_register(rn); | 1824 int32_t rn_val = get_register(rn); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1738 // Not sign extending, so load as unsigned. | 1876 // Not sign extending, so load as unsigned. |
1739 uint16_t halfword = ReadH(addr, instr); | 1877 uint16_t halfword = ReadH(addr, instr); |
1740 set_register(rd, halfword); | 1878 set_register(rd, halfword); |
1741 } else { | 1879 } else { |
1742 Debugger dbg(this); | 1880 Debugger dbg(this); |
1743 dbg.Stop(instr); | 1881 dbg.Stop(instr); |
1744 } | 1882 } |
1745 } | 1883 } |
1746 | 1884 |
1747 | 1885 |
| 1886 // void Simulator::DecodeTypeVFP(Instr* instr) |
| 1887 // The Following ARMv7 VFPv instructions are currently supported. |
| 1888 // fmsr :Sn = Rt |
| 1889 // fmrs :Rt = Sn |
| 1890 // fsitod: Dd = Sm |
| 1891 // ftosid: Sd = Dm |
| 1892 // Dd = faddd(Dn, Dm) |
| 1893 // Dd = fsubd(Dn, Dm) |
| 1894 // Dd = fmuld(Dn, Dm) |
| 1895 // Dd = fdivd(Dn, Dm) |
| 1896 // vcmp(Dd, Dm) |
| 1897 // VMRS |
| 1898 void Simulator::DecodeTypeVFP(Instr* instr) { |
| 1899 ASSERT((instr->TypeField() == 7) && (instr->Bit(24) == 0x0) ); |
| 1900 |
| 1901 int rt = instr->RtField(); |
| 1902 int vm = instr->VmField(); |
| 1903 int vn = instr->VnField(); |
| 1904 int vd = instr->VdField(); |
| 1905 |
| 1906 if (instr->Bit(23) == 1) { |
| 1907 if ((instr->Bits(21, 19) == 0x7) && |
| 1908 (instr->Bits(18, 16) == 0x5) && |
| 1909 (instr->Bits(11, 9) == 0x5) && |
| 1910 (instr->Bit(8) == 1) && |
| 1911 (instr->Bit(6) == 1) && |
| 1912 (instr->Bit(4) == 0)) { |
| 1913 double dm_val = get_double_from_d_register(vm); |
| 1914 int32_t int_value = static_cast<int32_t>(dm_val); |
| 1915 set_s_register_from_sinteger(((vd<<1) | instr->DField()), int_value); |
| 1916 } else if ((instr->Bits(21, 19) == 0x7) && |
| 1917 (instr->Bits(18, 16) == 0x0) && |
| 1918 (instr->Bits(11, 9) == 0x5) && |
| 1919 (instr->Bit(8) == 1) && |
| 1920 (instr->Bit(7) == 1) && |
| 1921 (instr->Bit(6) == 1) && |
| 1922 (instr->Bit(4) == 0)) { |
| 1923 int32_t int_value = get_sinteger_from_s_register(((vm<<1) | |
| 1924 instr->MField())); |
| 1925 double dbl_value = static_cast<double>(int_value); |
| 1926 set_d_register_from_double(vd, dbl_value); |
| 1927 } else if ((instr->Bit(21) == 0x0) && |
| 1928 (instr->Bit(20) == 0x0) && |
| 1929 (instr->Bits(11, 9) == 0x5) && |
| 1930 (instr->Bit(8) == 1) && |
| 1931 (instr->Bit(6) == 0) && |
| 1932 (instr->Bit(4) == 0)) { |
| 1933 double dn_value = get_double_from_d_register(vn); |
| 1934 double dm_value = get_double_from_d_register(vm); |
| 1935 double dd_value = dn_value / dm_value; |
| 1936 set_d_register_from_double(vd, dd_value); |
| 1937 } else if ((instr->Bits(21, 20) == 0x3) && |
| 1938 (instr->Bits(19, 16) == 0x4) && |
| 1939 (instr->Bits(11, 9) == 0x5) && |
| 1940 (instr->Bit(8) == 0x1) && |
| 1941 (instr->Bit(6) == 0x1) && |
| 1942 (instr->Bit(4) == 0x0)) { |
| 1943 double dd_value = get_double_from_d_register(vd); |
| 1944 double dm_value = get_double_from_d_register(vm); |
| 1945 Compute_FPSCR_Flags(dd_value, dm_value); |
| 1946 } else if ((instr->Bits(23, 20) == 0xF) && |
| 1947 (instr->Bits(19, 16) == 0x1) && |
| 1948 (instr->Bits(11, 8) == 0xA) && |
| 1949 (instr->Bits(7, 5) == 0x0) && |
| 1950 (instr->Bit(4) == 0x1) && |
| 1951 (instr->Bits(3, 0) == 0x0)) { |
| 1952 if (instr->Bits(15, 12) == 0xF) |
| 1953 Copy_FPSCR_to_APSR(); |
| 1954 else |
| 1955 UNIMPLEMENTED(); // not used by V8 now |
| 1956 } else { |
| 1957 UNIMPLEMENTED(); // not used by V8 now |
| 1958 } |
| 1959 } else if (instr->Bit(21) == 1) { |
| 1960 if ((instr->Bit(20) == 0x1) && |
| 1961 (instr->Bits(11, 9) == 0x5) && |
| 1962 (instr->Bit(8) == 0x1) && |
| 1963 (instr->Bit(6) == 0) && |
| 1964 (instr->Bit(4) == 0)) { |
| 1965 double dn_value = get_double_from_d_register(vn); |
| 1966 double dm_value = get_double_from_d_register(vm); |
| 1967 double dd_value = dn_value + dm_value; |
| 1968 set_d_register_from_double(vd, dd_value); |
| 1969 } else if ((instr->Bit(20) == 0x1) && |
| 1970 (instr->Bits(11, 9) == 0x5) && |
| 1971 (instr->Bit(8) == 0x1) && |
| 1972 (instr->Bit(6) == 1) && |
| 1973 (instr->Bit(4) == 0)) { |
| 1974 double dn_value = get_double_from_d_register(vn); |
| 1975 double dm_value = get_double_from_d_register(vm); |
| 1976 double dd_value = dn_value - dm_value; |
| 1977 set_d_register_from_double(vd, dd_value); |
| 1978 } else if ((instr->Bit(20) == 0x0) && |
| 1979 (instr->Bits(11, 9) == 0x5) && |
| 1980 (instr->Bit(8) == 0x1) && |
| 1981 (instr->Bit(6) == 0) && |
| 1982 (instr->Bit(4) == 0)) { |
| 1983 double dn_value = get_double_from_d_register(vn); |
| 1984 double dm_value = get_double_from_d_register(vm); |
| 1985 double dd_value = dn_value * dm_value; |
| 1986 set_d_register_from_double(vd, dd_value); |
| 1987 } else { |
| 1988 UNIMPLEMENTED(); // not used by V8 now |
| 1989 } |
| 1990 } else { |
| 1991 if ((instr->Bit(20) == 0x0) && |
| 1992 (instr->Bits(11, 8) == 0xA) && |
| 1993 (instr->Bits(6, 5) == 0x0) && |
| 1994 (instr->Bit(4) == 1) && |
| 1995 (instr->Bits(3, 0) == 0x0)) { |
| 1996 int32_t rs_val = get_register(rt); |
| 1997 set_s_register_from_sinteger(((vn<<1) | instr->NField()), rs_val); |
| 1998 } else if ((instr->Bit(20) == 0x1) && |
| 1999 (instr->Bits(11, 8) == 0xA) && |
| 2000 (instr->Bits(6, 5) == 0x0) && |
| 2001 (instr->Bit(4) == 1) && |
| 2002 (instr->Bits(3, 0) == 0x0)) { |
| 2003 int32_t int_value = get_sinteger_from_s_register(((vn<<1) | |
| 2004 instr->NField())); |
| 2005 set_register(rt, int_value); |
| 2006 } else { |
| 2007 UNIMPLEMENTED(); // not used by V8 now |
| 2008 } |
| 2009 } |
| 2010 } |
| 2011 |
| 2012 |
| 2013 |
| 2014 // void Simulator::DecodeType6CoprocessorIns(Instr* instr) |
| 2015 // Decode Type 6 coprocessor instructions |
| 2016 // Dm = fmdrr(Rt, Rt2) |
| 2017 // <Rt, Rt2> = fmrrd(Dm) |
| 2018 void Simulator::DecodeType6CoprocessorIns(Instr* instr) { |
| 2019 ASSERT((instr->TypeField() == 6)); |
| 2020 |
| 2021 int rt = instr->RtField(); |
| 2022 int rn = instr->RnField(); |
| 2023 int vm = instr->VmField(); |
| 2024 |
| 2025 if (instr->Bit(23) == 1) { |
| 2026 UNIMPLEMENTED(); |
| 2027 } else if (instr->Bit(22) == 1) { |
| 2028 if ((instr->Bits(27, 24) == 0xC) && |
| 2029 (instr->Bit(22) == 1) && |
| 2030 (instr->Bits(11, 8) == 0xB) && |
| 2031 (instr->Bits(7, 6) == 0x0) && |
| 2032 (instr->Bit(4) == 1)) { |
| 2033 if (instr->Bit(20) == 0) { |
| 2034 int32_t rs_val = get_register(rt); |
| 2035 int32_t rn_val = get_register(rn); |
| 2036 |
| 2037 set_s_register_from_sinteger(2*vm, rs_val); |
| 2038 set_s_register_from_sinteger((2*vm+1), rn_val); |
| 2039 |
| 2040 } else if (instr->Bit(20) == 1) { |
| 2041 int32_t rt_int_value = get_sinteger_from_s_register(2*vm); |
| 2042 int32_t rn_int_value = get_sinteger_from_s_register(2*vm+1); |
| 2043 |
| 2044 set_register(rt, rt_int_value); |
| 2045 set_register(rn, rn_int_value); |
| 2046 } |
| 2047 } else { |
| 2048 UNIMPLEMENTED(); |
| 2049 } |
| 2050 } else if (instr->Bit(21) == 1) { |
| 2051 UNIMPLEMENTED(); |
| 2052 } else { |
| 2053 UNIMPLEMENTED(); |
| 2054 } |
| 2055 } |
| 2056 |
| 2057 |
1748 // Executes the current instruction. | 2058 // Executes the current instruction. |
1749 void Simulator::InstructionDecode(Instr* instr) { | 2059 void Simulator::InstructionDecode(Instr* instr) { |
1750 pc_modified_ = false; | 2060 pc_modified_ = false; |
1751 if (::v8::internal::FLAG_trace_sim) { | 2061 if (::v8::internal::FLAG_trace_sim) { |
1752 disasm::NameConverter converter; | 2062 disasm::NameConverter converter; |
1753 disasm::Disassembler dasm(converter); | 2063 disasm::Disassembler dasm(converter); |
1754 // use a reasonably large buffer | 2064 // use a reasonably large buffer |
1755 v8::internal::EmbeddedVector<char, 256> buffer; | 2065 v8::internal::EmbeddedVector<char, 256> buffer; |
1756 dasm.InstructionDecode(buffer, | 2066 dasm.InstructionDecode(buffer, |
1757 reinterpret_cast<byte*>(instr)); | 2067 reinterpret_cast<byte*>(instr)); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1795 break; | 2105 break; |
1796 } | 2106 } |
1797 } | 2107 } |
1798 } | 2108 } |
1799 if (!pc_modified_) { | 2109 if (!pc_modified_) { |
1800 set_register(pc, reinterpret_cast<int32_t>(instr) + Instr::kInstrSize); | 2110 set_register(pc, reinterpret_cast<int32_t>(instr) + Instr::kInstrSize); |
1801 } | 2111 } |
1802 } | 2112 } |
1803 | 2113 |
1804 | 2114 |
1805 // | |
1806 void Simulator::Execute() { | 2115 void Simulator::Execute() { |
1807 // Get the PC to simulate. Cannot use the accessor here as we need the | 2116 // Get the PC to simulate. Cannot use the accessor here as we need the |
1808 // raw PC value and not the one used as input to arithmetic instructions. | 2117 // raw PC value and not the one used as input to arithmetic instructions. |
1809 int program_counter = get_pc(); | 2118 int program_counter = get_pc(); |
1810 | 2119 |
1811 if (::v8::internal::FLAG_stop_sim_at == 0) { | 2120 if (::v8::internal::FLAG_stop_sim_at == 0) { |
1812 // Fast version of the dispatch loop without checking whether the simulator | 2121 // Fast version of the dispatch loop without checking whether the simulator |
1813 // should be stopping at a particular executed instruction. | 2122 // should be stopping at a particular executed instruction. |
1814 while (program_counter != end_sim_pc) { | 2123 while (program_counter != end_sim_pc) { |
1815 Instr* instr = reinterpret_cast<Instr*>(program_counter); | 2124 Instr* instr = reinterpret_cast<Instr*>(program_counter); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1920 CHECK_EQ(entry_stack, get_register(sp)); | 2229 CHECK_EQ(entry_stack, get_register(sp)); |
1921 set_register(sp, original_stack); | 2230 set_register(sp, original_stack); |
1922 | 2231 |
1923 int32_t result = get_register(r0); | 2232 int32_t result = get_register(r0); |
1924 return result; | 2233 return result; |
1925 } | 2234 } |
1926 | 2235 |
1927 } } // namespace assembler::arm | 2236 } } // namespace assembler::arm |
1928 | 2237 |
1929 #endif // !defined(__arm__) | 2238 #endif // !defined(__arm__) |
OLD | NEW |