| 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 901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 912 } | 912 } |
| 913 | 913 |
| 914 | 914 |
| 915 void Simulator::set_dw_register(int dreg, const int* dbl) { | 915 void Simulator::set_dw_register(int dreg, const int* dbl) { |
| 916 ASSERT((dreg >= 0) && (dreg < num_d_registers)); | 916 ASSERT((dreg >= 0) && (dreg < num_d_registers)); |
| 917 registers_[dreg] = dbl[0]; | 917 registers_[dreg] = dbl[0]; |
| 918 registers_[dreg + 1] = dbl[1]; | 918 registers_[dreg + 1] = dbl[1]; |
| 919 } | 919 } |
| 920 | 920 |
| 921 | 921 |
| 922 void Simulator::get_d_register(int dreg, uint64_t* value) { |
| 923 ASSERT((dreg >= 0) && (dreg < DwVfpRegister::NumRegisters())); |
| 924 memcpy(value, vfp_registers_ + dreg * 2, sizeof(*value)); |
| 925 } |
| 926 |
| 927 |
| 928 void Simulator::set_d_register(int dreg, const uint64_t* value) { |
| 929 ASSERT((dreg >= 0) && (dreg < DwVfpRegister::NumRegisters())); |
| 930 memcpy(vfp_registers_ + dreg * 2, value, sizeof(*value)); |
| 931 } |
| 932 |
| 933 |
| 934 void Simulator::get_d_register(int dreg, uint32_t* value) { |
| 935 ASSERT((dreg >= 0) && (dreg < DwVfpRegister::NumRegisters())); |
| 936 memcpy(value, vfp_registers_ + dreg * 2, sizeof(*value) * 2); |
| 937 } |
| 938 |
| 939 |
| 940 void Simulator::set_d_register(int dreg, const uint32_t* value) { |
| 941 ASSERT((dreg >= 0) && (dreg < DwVfpRegister::NumRegisters())); |
| 942 memcpy(vfp_registers_ + dreg * 2, value, sizeof(*value) * 2); |
| 943 } |
| 944 |
| 945 |
| 946 void Simulator::get_q_register(int qreg, uint64_t* value) { |
| 947 ASSERT((qreg >= 0) && (qreg < num_q_registers)); |
| 948 memcpy(value, vfp_registers_ + qreg * 4, sizeof(*value) * 2); |
| 949 } |
| 950 |
| 951 |
| 952 void Simulator::set_q_register(int qreg, const uint64_t* value) { |
| 953 ASSERT((qreg >= 0) && (qreg < num_q_registers)); |
| 954 memcpy(vfp_registers_ + qreg * 4, value, sizeof(*value) * 2); |
| 955 } |
| 956 |
| 957 |
| 958 void Simulator::get_q_register(int qreg, uint32_t* value) { |
| 959 ASSERT((qreg >= 0) && (qreg < num_q_registers)); |
| 960 memcpy(value, vfp_registers_ + qreg * 4, sizeof(*value) * 4); |
| 961 } |
| 962 |
| 963 |
| 964 void Simulator::set_q_register(int qreg, const uint32_t* value) { |
| 965 ASSERT((qreg >= 0) && (qreg < num_q_registers)); |
| 966 memcpy(vfp_registers_ + qreg * 4, value, sizeof(*value) * 4); |
| 967 } |
| 968 |
| 969 |
| 922 // Raw access to the PC register. | 970 // Raw access to the PC register. |
| 923 void Simulator::set_pc(int32_t value) { | 971 void Simulator::set_pc(int32_t value) { |
| 924 pc_modified_ = true; | 972 pc_modified_ = true; |
| 925 registers_[pc] = value; | 973 registers_[pc] = value; |
| 926 } | 974 } |
| 927 | 975 |
| 928 | 976 |
| 929 bool Simulator::has_bad_pc() const { | 977 bool Simulator::has_bad_pc() const { |
| 930 return ((registers_[pc] == bad_lr) || (registers_[pc] == end_sim_pc)); | 978 return ((registers_[pc] == bad_lr) || (registers_[pc] == end_sim_pc)); |
| 931 } | 979 } |
| (...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1479 while (bit_vector != 0) { | 1527 while (bit_vector != 0) { |
| 1480 if ((bit_vector & 1) != 0) { | 1528 if ((bit_vector & 1) != 0) { |
| 1481 count++; | 1529 count++; |
| 1482 } | 1530 } |
| 1483 bit_vector >>= 1; | 1531 bit_vector >>= 1; |
| 1484 } | 1532 } |
| 1485 return count; | 1533 return count; |
| 1486 } | 1534 } |
| 1487 | 1535 |
| 1488 | 1536 |
| 1489 void Simulator::ProcessPUW(Instruction* instr, | 1537 int32_t Simulator::ProcessPU(Instruction* instr, |
| 1490 int num_regs, | 1538 int num_regs, |
| 1491 int reg_size, | 1539 int reg_size, |
| 1492 intptr_t* start_address, | 1540 intptr_t* start_address, |
| 1493 intptr_t* end_address) { | 1541 intptr_t* end_address) { |
| 1494 int rn = instr->RnValue(); | 1542 int rn = instr->RnValue(); |
| 1495 int32_t rn_val = get_register(rn); | 1543 int32_t rn_val = get_register(rn); |
| 1496 switch (instr->PUField()) { | 1544 switch (instr->PUField()) { |
| 1497 case da_x: { | 1545 case da_x: { |
| 1498 UNIMPLEMENTED(); | 1546 UNIMPLEMENTED(); |
| 1499 break; | 1547 break; |
| 1500 } | 1548 } |
| 1501 case ia_x: { | 1549 case ia_x: { |
| 1502 *start_address = rn_val; | 1550 *start_address = rn_val; |
| 1503 *end_address = rn_val + (num_regs * reg_size) - reg_size; | 1551 *end_address = rn_val + (num_regs * reg_size) - reg_size; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1514 *start_address = rn_val + reg_size; | 1562 *start_address = rn_val + reg_size; |
| 1515 *end_address = rn_val + (num_regs * reg_size); | 1563 *end_address = rn_val + (num_regs * reg_size); |
| 1516 rn_val = *end_address; | 1564 rn_val = *end_address; |
| 1517 break; | 1565 break; |
| 1518 } | 1566 } |
| 1519 default: { | 1567 default: { |
| 1520 UNREACHABLE(); | 1568 UNREACHABLE(); |
| 1521 break; | 1569 break; |
| 1522 } | 1570 } |
| 1523 } | 1571 } |
| 1524 if (instr->HasW()) { | 1572 return rn_val; |
| 1525 set_register(rn, rn_val); | |
| 1526 } | |
| 1527 } | 1573 } |
| 1528 | 1574 |
| 1529 | 1575 |
| 1530 // Addressing Mode 4 - Load and Store Multiple | 1576 // Addressing Mode 4 - Load and Store Multiple |
| 1531 void Simulator::HandleRList(Instruction* instr, bool load) { | 1577 void Simulator::HandleRList(Instruction* instr, bool load) { |
| 1532 int rlist = instr->RlistValue(); | 1578 int rlist = instr->RlistValue(); |
| 1533 int num_regs = count_bits(rlist); | 1579 int num_regs = count_bits(rlist); |
| 1534 | 1580 |
| 1535 intptr_t start_address = 0; | 1581 intptr_t start_address = 0; |
| 1536 intptr_t end_address = 0; | 1582 intptr_t end_address = 0; |
| 1537 ProcessPUW(instr, num_regs, kPointerSize, &start_address, &end_address); | 1583 int32_t rn_val = |
| 1584 ProcessPU(instr, num_regs, kPointerSize, &start_address, &end_address); |
| 1538 | 1585 |
| 1539 intptr_t* address = reinterpret_cast<intptr_t*>(start_address); | 1586 intptr_t* address = reinterpret_cast<intptr_t*>(start_address); |
| 1540 // Catch null pointers a little earlier. | 1587 // Catch null pointers a little earlier. |
| 1541 ASSERT(start_address > 8191 || start_address < 0); | 1588 ASSERT(start_address > 8191 || start_address < 0); |
| 1542 int reg = 0; | 1589 int reg = 0; |
| 1543 while (rlist != 0) { | 1590 while (rlist != 0) { |
| 1544 if ((rlist & 1) != 0) { | 1591 if ((rlist & 1) != 0) { |
| 1545 if (load) { | 1592 if (load) { |
| 1546 set_register(reg, *address); | 1593 set_register(reg, *address); |
| 1547 } else { | 1594 } else { |
| 1548 *address = get_register(reg); | 1595 *address = get_register(reg); |
| 1549 } | 1596 } |
| 1550 address += 1; | 1597 address += 1; |
| 1551 } | 1598 } |
| 1552 reg++; | 1599 reg++; |
| 1553 rlist >>= 1; | 1600 rlist >>= 1; |
| 1554 } | 1601 } |
| 1555 ASSERT(end_address == ((intptr_t)address) - 4); | 1602 ASSERT(end_address == ((intptr_t)address) - 4); |
| 1603 if (instr->HasW()) { |
| 1604 set_register(instr->RnValue(), rn_val); |
| 1605 } |
| 1556 } | 1606 } |
| 1557 | 1607 |
| 1558 | 1608 |
| 1559 // Addressing Mode 6 - Load and Store Multiple Coprocessor registers. | 1609 // Addressing Mode 6 - Load and Store Multiple Coprocessor registers. |
| 1560 void Simulator::HandleVList(Instruction* instr) { | 1610 void Simulator::HandleVList(Instruction* instr) { |
| 1561 VFPRegPrecision precision = | 1611 VFPRegPrecision precision = |
| 1562 (instr->SzValue() == 0) ? kSinglePrecision : kDoublePrecision; | 1612 (instr->SzValue() == 0) ? kSinglePrecision : kDoublePrecision; |
| 1563 int operand_size = (precision == kSinglePrecision) ? 4 : 8; | 1613 int operand_size = (precision == kSinglePrecision) ? 4 : 8; |
| 1564 | 1614 |
| 1565 bool load = (instr->VLValue() == 0x1); | 1615 bool load = (instr->VLValue() == 0x1); |
| 1566 | 1616 |
| 1567 int vd; | 1617 int vd; |
| 1568 int num_regs; | 1618 int num_regs; |
| 1569 vd = instr->VFPDRegValue(precision); | 1619 vd = instr->VFPDRegValue(precision); |
| 1570 if (precision == kSinglePrecision) { | 1620 if (precision == kSinglePrecision) { |
| 1571 num_regs = instr->Immed8Value(); | 1621 num_regs = instr->Immed8Value(); |
| 1572 } else { | 1622 } else { |
| 1573 num_regs = instr->Immed8Value() / 2; | 1623 num_regs = instr->Immed8Value() / 2; |
| 1574 } | 1624 } |
| 1575 | 1625 |
| 1576 intptr_t start_address = 0; | 1626 intptr_t start_address = 0; |
| 1577 intptr_t end_address = 0; | 1627 intptr_t end_address = 0; |
| 1578 ProcessPUW(instr, num_regs, operand_size, &start_address, &end_address); | 1628 int32_t rn_val = |
| 1629 ProcessPU(instr, num_regs, operand_size, &start_address, &end_address); |
| 1579 | 1630 |
| 1580 intptr_t* address = reinterpret_cast<intptr_t*>(start_address); | 1631 intptr_t* address = reinterpret_cast<intptr_t*>(start_address); |
| 1581 for (int reg = vd; reg < vd + num_regs; reg++) { | 1632 for (int reg = vd; reg < vd + num_regs; reg++) { |
| 1582 if (precision == kSinglePrecision) { | 1633 if (precision == kSinglePrecision) { |
| 1583 if (load) { | 1634 if (load) { |
| 1584 set_s_register_from_sinteger( | 1635 set_s_register_from_sinteger( |
| 1585 reg, ReadW(reinterpret_cast<int32_t>(address), instr)); | 1636 reg, ReadW(reinterpret_cast<int32_t>(address), instr)); |
| 1586 } else { | 1637 } else { |
| 1587 WriteW(reinterpret_cast<int32_t>(address), | 1638 WriteW(reinterpret_cast<int32_t>(address), |
| 1588 get_sinteger_from_s_register(reg), instr); | 1639 get_sinteger_from_s_register(reg), instr); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1601 int32_t data[2]; | 1652 int32_t data[2]; |
| 1602 double d = get_double_from_d_register(reg); | 1653 double d = get_double_from_d_register(reg); |
| 1603 OS::MemCopy(data, &d, 8); | 1654 OS::MemCopy(data, &d, 8); |
| 1604 WriteW(reinterpret_cast<int32_t>(address), data[0], instr); | 1655 WriteW(reinterpret_cast<int32_t>(address), data[0], instr); |
| 1605 WriteW(reinterpret_cast<int32_t>(address + 1), data[1], instr); | 1656 WriteW(reinterpret_cast<int32_t>(address + 1), data[1], instr); |
| 1606 } | 1657 } |
| 1607 address += 2; | 1658 address += 2; |
| 1608 } | 1659 } |
| 1609 } | 1660 } |
| 1610 ASSERT(reinterpret_cast<intptr_t>(address) - operand_size == end_address); | 1661 ASSERT(reinterpret_cast<intptr_t>(address) - operand_size == end_address); |
| 1662 if (instr->HasW()) { |
| 1663 set_register(instr->RnValue(), rn_val); |
| 1664 } |
| 1611 } | 1665 } |
| 1612 | 1666 |
| 1613 | 1667 |
| 1614 // Calls into the V8 runtime are based on this very simple interface. | 1668 // Calls into the V8 runtime are based on this very simple interface. |
| 1615 // Note: To be able to return two values from some calls the code in runtime.cc | 1669 // Note: To be able to return two values from some calls the code in runtime.cc |
| 1616 // uses the ObjectPair which is essentially two 32-bit values stuffed into a | 1670 // uses the ObjectPair which is essentially two 32-bit values stuffed into a |
| 1617 // 64-bit value. With the code below we assume that all runtime calls return | 1671 // 64-bit value. With the code below we assume that all runtime calls return |
| 1618 // 64 bits of result. If they don't, the r1 result register contains a bogus | 1672 // 64 bits of result. If they don't, the r1 result register contains a bogus |
| 1619 // value, which is fine because it is caller-saved. | 1673 // value, which is fine because it is caller-saved. |
| 1620 typedef int64_t (*SimulatorRuntimeCall)(int32_t arg0, | 1674 typedef int64_t (*SimulatorRuntimeCall)(int32_t arg0, |
| (...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2592 int32_t shifter_operand = GetShiftRm(instr, &shifter_carry_out); | 2646 int32_t shifter_operand = GetShiftRm(instr, &shifter_carry_out); |
| 2593 int32_t addr = 0; | 2647 int32_t addr = 0; |
| 2594 switch (instr->PUField()) { | 2648 switch (instr->PUField()) { |
| 2595 case da_x: { | 2649 case da_x: { |
| 2596 ASSERT(!instr->HasW()); | 2650 ASSERT(!instr->HasW()); |
| 2597 Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm"); | 2651 Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm"); |
| 2598 UNIMPLEMENTED(); | 2652 UNIMPLEMENTED(); |
| 2599 break; | 2653 break; |
| 2600 } | 2654 } |
| 2601 case ia_x: { | 2655 case ia_x: { |
| 2602 if (instr->HasW()) { | 2656 if (instr->Bit(4) == 0) { |
| 2603 ASSERT(instr->Bits(5, 4) == 0x1); | 2657 // Memop. |
| 2604 | 2658 } else { |
| 2605 if (instr->Bit(22) == 0x1) { // USAT. | 2659 if (instr->Bit(5) == 0) { |
| 2606 int32_t sat_pos = instr->Bits(20, 16); | 2660 switch (instr->Bits(22, 21)) { |
| 2607 int32_t sat_val = (1 << sat_pos) - 1; | 2661 case 0: |
| 2608 int32_t shift = instr->Bits(11, 7); | 2662 if (instr->Bit(20) == 0) { |
| 2609 int32_t shift_type = instr->Bit(6); | 2663 if (instr->Bit(6) == 0) { |
| 2610 int32_t rm_val = get_register(instr->RmValue()); | 2664 // Pkhbt. |
| 2611 if (shift_type == 0) { // LSL | 2665 uint32_t rn_val = get_register(rn); |
| 2612 rm_val <<= shift; | 2666 uint32_t rm_val = get_register(instr->RmValue()); |
| 2613 } else { // ASR | 2667 int32_t shift = instr->Bits(11, 7); |
| 2614 rm_val >>= shift; | 2668 rm_val <<= shift; |
| 2669 set_register(rd, (rn_val & 0xFFFF) | (rm_val & 0xFFFF0000U)); |
| 2670 } else { |
| 2671 // Pkhtb. |
| 2672 uint32_t rn_val = get_register(rn); |
| 2673 int32_t rm_val = get_register(instr->RmValue()); |
| 2674 int32_t shift = instr->Bits(11, 7); |
| 2675 if (shift == 0) { |
| 2676 shift = 32; |
| 2677 } |
| 2678 rm_val >>= shift; |
| 2679 set_register(rd, (rn_val & 0xFFFF0000U) | (rm_val & 0xFFFF)); |
| 2680 } |
| 2681 } else { |
| 2682 UNIMPLEMENTED(); |
| 2683 } |
| 2684 break; |
| 2685 case 1: |
| 2686 UNIMPLEMENTED(); |
| 2687 break; |
| 2688 case 2: |
| 2689 UNIMPLEMENTED(); |
| 2690 break; |
| 2691 case 3: { |
| 2692 // Usat. |
| 2693 int32_t sat_pos = instr->Bits(20, 16); |
| 2694 int32_t sat_val = (1 << sat_pos) - 1; |
| 2695 int32_t shift = instr->Bits(11, 7); |
| 2696 int32_t shift_type = instr->Bit(6); |
| 2697 int32_t rm_val = get_register(instr->RmValue()); |
| 2698 if (shift_type == 0) { // LSL |
| 2699 rm_val <<= shift; |
| 2700 } else { // ASR |
| 2701 rm_val >>= shift; |
| 2702 } |
| 2703 // If saturation occurs, the Q flag should be set in the CPSR. |
| 2704 // There is no Q flag yet, and no instruction (MRS) to read the |
| 2705 // CPSR directly. |
| 2706 if (rm_val > sat_val) { |
| 2707 rm_val = sat_val; |
| 2708 } else if (rm_val < 0) { |
| 2709 rm_val = 0; |
| 2710 } |
| 2711 set_register(rd, rm_val); |
| 2712 break; |
| 2713 } |
| 2615 } | 2714 } |
| 2616 // If saturation occurs, the Q flag should be set in the CPSR. | 2715 } else { |
| 2617 // There is no Q flag yet, and no instruction (MRS) to read the | 2716 switch (instr->Bits(22, 21)) { |
| 2618 // CPSR directly. | 2717 case 0: |
| 2619 if (rm_val > sat_val) { | 2718 UNIMPLEMENTED(); |
| 2620 rm_val = sat_val; | 2719 break; |
| 2621 } else if (rm_val < 0) { | 2720 case 1: |
| 2622 rm_val = 0; | 2721 UNIMPLEMENTED(); |
| 2722 break; |
| 2723 case 2: |
| 2724 if ((instr->Bit(20) == 0) && (instr->Bits(9, 6) == 1)) { |
| 2725 if (instr->Bits(19, 16) == 0xF) { |
| 2726 // Uxtb16. |
| 2727 uint32_t rm_val = get_register(instr->RmValue()); |
| 2728 int32_t rotate = instr->Bits(11, 10); |
| 2729 switch (rotate) { |
| 2730 case 0: |
| 2731 break; |
| 2732 case 1: |
| 2733 rm_val = (rm_val >> 8) | (rm_val << 24); |
| 2734 break; |
| 2735 case 2: |
| 2736 rm_val = (rm_val >> 16) | (rm_val << 16); |
| 2737 break; |
| 2738 case 3: |
| 2739 rm_val = (rm_val >> 24) | (rm_val << 8); |
| 2740 break; |
| 2741 } |
| 2742 set_register(rd, |
| 2743 (rm_val & 0xFF) | (rm_val & 0xFF0000)); |
| 2744 } else { |
| 2745 UNIMPLEMENTED(); |
| 2746 } |
| 2747 } else { |
| 2748 UNIMPLEMENTED(); |
| 2749 } |
| 2750 break; |
| 2751 case 3: |
| 2752 if ((instr->Bit(20) == 0) && (instr->Bits(9, 6) == 1)) { |
| 2753 if (instr->Bits(19, 16) == 0xF) { |
| 2754 // Uxtb. |
| 2755 uint32_t rm_val = get_register(instr->RmValue()); |
| 2756 int32_t rotate = instr->Bits(11, 10); |
| 2757 switch (rotate) { |
| 2758 case 0: |
| 2759 break; |
| 2760 case 1: |
| 2761 rm_val = (rm_val >> 8) | (rm_val << 24); |
| 2762 break; |
| 2763 case 2: |
| 2764 rm_val = (rm_val >> 16) | (rm_val << 16); |
| 2765 break; |
| 2766 case 3: |
| 2767 rm_val = (rm_val >> 24) | (rm_val << 8); |
| 2768 break; |
| 2769 } |
| 2770 set_register(rd, (rm_val & 0xFF)); |
| 2771 } else { |
| 2772 // Uxtab. |
| 2773 uint32_t rn_val = get_register(rn); |
| 2774 uint32_t rm_val = get_register(instr->RmValue()); |
| 2775 int32_t rotate = instr->Bits(11, 10); |
| 2776 switch (rotate) { |
| 2777 case 0: |
| 2778 break; |
| 2779 case 1: |
| 2780 rm_val = (rm_val >> 8) | (rm_val << 24); |
| 2781 break; |
| 2782 case 2: |
| 2783 rm_val = (rm_val >> 16) | (rm_val << 16); |
| 2784 break; |
| 2785 case 3: |
| 2786 rm_val = (rm_val >> 24) | (rm_val << 8); |
| 2787 break; |
| 2788 } |
| 2789 set_register(rd, rn_val + (rm_val & 0xFF)); |
| 2790 } |
| 2791 } else { |
| 2792 UNIMPLEMENTED(); |
| 2793 } |
| 2794 break; |
| 2623 } | 2795 } |
| 2624 set_register(rd, rm_val); | |
| 2625 } else { // SSAT. | |
| 2626 UNIMPLEMENTED(); | |
| 2627 } | 2796 } |
| 2628 return; | 2797 return; |
| 2629 } else { | |
| 2630 Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm"); | |
| 2631 UNIMPLEMENTED(); | |
| 2632 } | 2798 } |
| 2633 break; | 2799 break; |
| 2634 } | 2800 } |
| 2635 case db_x: { | 2801 case db_x: { |
| 2636 if (FLAG_enable_sudiv) { | 2802 if (FLAG_enable_sudiv) { |
| 2637 if (!instr->HasW()) { | 2803 if (!instr->HasW()) { |
| 2638 if (instr->Bits(5, 4) == 0x1) { | 2804 if (instr->Bits(5, 4) == 0x1) { |
| 2639 if ((instr->Bit(22) == 0x0) && (instr->Bit(20) == 0x1)) { | 2805 if ((instr->Bit(22) == 0x0) && (instr->Bit(20) == 0x1)) { |
| 2640 // sdiv (in V8 notation matching ARM ISA format) rn = rm/rs | 2806 // sdiv (in V8 notation matching ARM ISA format) rn = rm/rs |
| 2641 // Format(instr, "'sdiv'cond'b 'rn, 'rm, 'rs); | 2807 // Format(instr, "'sdiv'cond'b 'rn, 'rm, 'rs); |
| (...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3345 break; | 3511 break; |
| 3346 default: | 3512 default: |
| 3347 UNIMPLEMENTED(); // Not used by V8. | 3513 UNIMPLEMENTED(); // Not used by V8. |
| 3348 } | 3514 } |
| 3349 } else { | 3515 } else { |
| 3350 UNIMPLEMENTED(); // Not used by V8. | 3516 UNIMPLEMENTED(); // Not used by V8. |
| 3351 } | 3517 } |
| 3352 } | 3518 } |
| 3353 | 3519 |
| 3354 | 3520 |
| 3521 void Simulator::DecodeSpecialCondition(Instruction* instr) { |
| 3522 switch (instr->SpecialValue()) { |
| 3523 case 5: |
| 3524 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && |
| 3525 (instr->Bit(4) == 1)) { |
| 3526 // vmovl signed |
| 3527 int Vd = (instr->Bit(22) << 4) | instr->VdValue(); |
| 3528 int Vm = (instr->Bit(5) << 4) | instr->VmValue(); |
| 3529 int imm3 = instr->Bits(21, 19); |
| 3530 if ((imm3 != 1) && (imm3 != 2) && (imm3 != 4)) UNIMPLEMENTED(); |
| 3531 int esize = 8 * imm3; |
| 3532 int elements = 64 / esize; |
| 3533 int8_t from[8]; |
| 3534 get_d_register(Vm, reinterpret_cast<uint64_t*>(from)); |
| 3535 int16_t to[8]; |
| 3536 int e = 0; |
| 3537 while (e < elements) { |
| 3538 to[e] = from[e]; |
| 3539 e++; |
| 3540 } |
| 3541 set_q_register(Vd, reinterpret_cast<uint64_t*>(to)); |
| 3542 } else { |
| 3543 UNIMPLEMENTED(); |
| 3544 } |
| 3545 break; |
| 3546 case 7: |
| 3547 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && |
| 3548 (instr->Bit(4) == 1)) { |
| 3549 // vmovl unsigned |
| 3550 int Vd = (instr->Bit(22) << 4) | instr->VdValue(); |
| 3551 int Vm = (instr->Bit(5) << 4) | instr->VmValue(); |
| 3552 int imm3 = instr->Bits(21, 19); |
| 3553 if ((imm3 != 1) && (imm3 != 2) && (imm3 != 4)) UNIMPLEMENTED(); |
| 3554 int esize = 8 * imm3; |
| 3555 int elements = 64 / esize; |
| 3556 uint8_t from[8]; |
| 3557 get_d_register(Vm, reinterpret_cast<uint64_t*>(from)); |
| 3558 uint16_t to[8]; |
| 3559 int e = 0; |
| 3560 while (e < elements) { |
| 3561 to[e] = from[e]; |
| 3562 e++; |
| 3563 } |
| 3564 set_q_register(Vd, reinterpret_cast<uint64_t*>(to)); |
| 3565 } else { |
| 3566 UNIMPLEMENTED(); |
| 3567 } |
| 3568 break; |
| 3569 case 8: |
| 3570 if (instr->Bits(21, 20) == 0) { |
| 3571 // vst1 |
| 3572 int Vd = (instr->Bit(22) << 4) | instr->VdValue(); |
| 3573 int Rn = instr->VnValue(); |
| 3574 int type = instr->Bits(11, 8); |
| 3575 int Rm = instr->VmValue(); |
| 3576 int32_t address = get_register(Rn); |
| 3577 int regs = 0; |
| 3578 switch (type) { |
| 3579 case nlt_1: |
| 3580 regs = 1; |
| 3581 break; |
| 3582 case nlt_2: |
| 3583 regs = 2; |
| 3584 break; |
| 3585 case nlt_3: |
| 3586 regs = 3; |
| 3587 break; |
| 3588 case nlt_4: |
| 3589 regs = 4; |
| 3590 break; |
| 3591 default: |
| 3592 UNIMPLEMENTED(); |
| 3593 break; |
| 3594 } |
| 3595 int r = 0; |
| 3596 while (r < regs) { |
| 3597 uint32_t data[2]; |
| 3598 get_d_register(Vd + r, data); |
| 3599 WriteW(address, data[0], instr); |
| 3600 WriteW(address + 4, data[1], instr); |
| 3601 address += 8; |
| 3602 r++; |
| 3603 } |
| 3604 if (Rm != 15) { |
| 3605 if (Rm == 13) { |
| 3606 set_register(Rn, address); |
| 3607 } else { |
| 3608 set_register(Rn, get_register(Rn) + get_register(Rm)); |
| 3609 } |
| 3610 } |
| 3611 } else if (instr->Bits(21, 20) == 2) { |
| 3612 // vld1 |
| 3613 int Vd = (instr->Bit(22) << 4) | instr->VdValue(); |
| 3614 int Rn = instr->VnValue(); |
| 3615 int type = instr->Bits(11, 8); |
| 3616 int Rm = instr->VmValue(); |
| 3617 int32_t address = get_register(Rn); |
| 3618 int regs = 0; |
| 3619 switch (type) { |
| 3620 case nlt_1: |
| 3621 regs = 1; |
| 3622 break; |
| 3623 case nlt_2: |
| 3624 regs = 2; |
| 3625 break; |
| 3626 case nlt_3: |
| 3627 regs = 3; |
| 3628 break; |
| 3629 case nlt_4: |
| 3630 regs = 4; |
| 3631 break; |
| 3632 default: |
| 3633 UNIMPLEMENTED(); |
| 3634 break; |
| 3635 } |
| 3636 int r = 0; |
| 3637 while (r < regs) { |
| 3638 uint32_t data[2]; |
| 3639 data[0] = ReadW(address, instr); |
| 3640 data[1] = ReadW(address + 4, instr); |
| 3641 set_d_register(Vd + r, data); |
| 3642 address += 8; |
| 3643 r++; |
| 3644 } |
| 3645 if (Rm != 15) { |
| 3646 if (Rm == 13) { |
| 3647 set_register(Rn, address); |
| 3648 } else { |
| 3649 set_register(Rn, get_register(Rn) + get_register(Rm)); |
| 3650 } |
| 3651 } |
| 3652 } else { |
| 3653 UNIMPLEMENTED(); |
| 3654 } |
| 3655 break; |
| 3656 case 0xA: |
| 3657 case 0xB: |
| 3658 if ((instr->Bits(22, 20) == 5) && (instr->Bits(15, 12) == 0xf)) { |
| 3659 // pld: ignore instruction. |
| 3660 } else { |
| 3661 UNIMPLEMENTED(); |
| 3662 } |
| 3663 break; |
| 3664 default: |
| 3665 UNIMPLEMENTED(); |
| 3666 break; |
| 3667 } |
| 3668 } |
| 3669 |
| 3670 |
| 3355 // Executes the current instruction. | 3671 // Executes the current instruction. |
| 3356 void Simulator::InstructionDecode(Instruction* instr) { | 3672 void Simulator::InstructionDecode(Instruction* instr) { |
| 3357 if (v8::internal::FLAG_check_icache) { | 3673 if (v8::internal::FLAG_check_icache) { |
| 3358 CheckICache(isolate_->simulator_i_cache(), instr); | 3674 CheckICache(isolate_->simulator_i_cache(), instr); |
| 3359 } | 3675 } |
| 3360 pc_modified_ = false; | 3676 pc_modified_ = false; |
| 3361 if (::v8::internal::FLAG_trace_sim) { | 3677 if (::v8::internal::FLAG_trace_sim) { |
| 3362 disasm::NameConverter converter; | 3678 disasm::NameConverter converter; |
| 3363 disasm::Disassembler dasm(converter); | 3679 disasm::Disassembler dasm(converter); |
| 3364 // use a reasonably large buffer | 3680 // use a reasonably large buffer |
| 3365 v8::internal::EmbeddedVector<char, 256> buffer; | 3681 v8::internal::EmbeddedVector<char, 256> buffer; |
| 3366 dasm.InstructionDecode(buffer, | 3682 dasm.InstructionDecode(buffer, |
| 3367 reinterpret_cast<byte*>(instr)); | 3683 reinterpret_cast<byte*>(instr)); |
| 3368 PrintF(" 0x%08x %s\n", reinterpret_cast<intptr_t>(instr), buffer.start()); | 3684 PrintF(" 0x%08x %s\n", reinterpret_cast<intptr_t>(instr), buffer.start()); |
| 3369 } | 3685 } |
| 3370 if (instr->ConditionField() == kSpecialCondition) { | 3686 if (instr->ConditionField() == kSpecialCondition) { |
| 3371 UNIMPLEMENTED(); | 3687 DecodeSpecialCondition(instr); |
| 3372 } else if (ConditionallyExecute(instr)) { | 3688 } else if (ConditionallyExecute(instr)) { |
| 3373 switch (instr->TypeValue()) { | 3689 switch (instr->TypeValue()) { |
| 3374 case 0: | 3690 case 0: |
| 3375 case 1: { | 3691 case 1: { |
| 3376 DecodeType01(instr); | 3692 DecodeType01(instr); |
| 3377 break; | 3693 break; |
| 3378 } | 3694 } |
| 3379 case 2: { | 3695 case 2: { |
| 3380 DecodeType2(instr); | 3696 DecodeType2(instr); |
| 3381 break; | 3697 break; |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3580 uintptr_t address = *stack_slot; | 3896 uintptr_t address = *stack_slot; |
| 3581 set_register(sp, current_sp + sizeof(uintptr_t)); | 3897 set_register(sp, current_sp + sizeof(uintptr_t)); |
| 3582 return address; | 3898 return address; |
| 3583 } | 3899 } |
| 3584 | 3900 |
| 3585 } } // namespace v8::internal | 3901 } } // namespace v8::internal |
| 3586 | 3902 |
| 3587 #endif // USE_SIMULATOR | 3903 #endif // USE_SIMULATOR |
| 3588 | 3904 |
| 3589 #endif // V8_TARGET_ARCH_ARM | 3905 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |