Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: src/arm/simulator-arm.cc

Issue 173567: ARM native regexps. (Closed)
Patch Set: Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include <stdlib.h> 28 #include <stdlib.h>
29 29 #include <cstdarg>
30 #include "v8.h" 30 #include "v8.h"
31 31
32 #include "disasm.h" 32 #include "disasm.h"
33 #include "assembler.h" 33 #include "assembler.h"
34 #include "arm/constants-arm.h" 34 #include "arm/constants-arm.h"
35 #include "arm/simulator-arm.h" 35 #include "arm/simulator-arm.h"
36 36
37 #if !defined(__arm__) 37 #if !defined(__arm__)
38 38
39 // Only build the simulator if not compiling for real ARM hardware. 39 // Only build the simulator if not compiling for real ARM hardware.
(...skipping 1369 matching lines...) Expand 10 before | Expand all | Expand 10 after
1409 SetCFlag(!BorrowFrom(rn_val, shifter_operand)); 1409 SetCFlag(!BorrowFrom(rn_val, shifter_operand));
1410 SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false)); 1410 SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, false));
1411 } else { 1411 } else {
1412 UNIMPLEMENTED(); 1412 UNIMPLEMENTED();
1413 } 1413 }
1414 break; 1414 break;
1415 } 1415 }
1416 1416
1417 case CMN: { 1417 case CMN: {
1418 if (instr->HasS()) { 1418 if (instr->HasS()) {
1419 Format(instr, "cmn'cond 'rn, 'shift_rm"); 1419 // Format(instr, "cmn'cond 'rn, 'shift_rm");
1420 Format(instr, "cmn'cond 'rn, 'imm"); 1420 // Format(instr, "cmn'cond 'rn, 'imm");
1421 alu_out = rn_val + shifter_operand;
1422 SetNZFlags(alu_out);
1423 SetCFlag(!CarryFrom(rn_val, shifter_operand));
1424 SetVFlag(OverflowFrom(alu_out, rn_val, shifter_operand, true));
1421 } else { 1425 } else {
1422 ASSERT(type == 0); 1426 ASSERT(type == 0);
1423 int rm = instr->RmField(); 1427 int rm = instr->RmField();
1424 int rd = instr->RdField(); 1428 int rd = instr->RdField();
1425 switch (instr->Bits(7, 4)) { 1429 switch (instr->Bits(7, 4)) {
1426 case CLZ: { 1430 case CLZ: {
1427 uint32_t bits = get_register(rm); 1431 uint32_t bits = get_register(rm);
1428 int leading_zeros = 0; 1432 int leading_zeros = 0;
1429 if (bits == 0) { 1433 if (bits == 0) {
1430 leading_zeros = 32; 1434 leading_zeros = 32;
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1559 if (instr->HasL()) { 1563 if (instr->HasL()) {
1560 set_register(rd, ReadW(addr, instr)); 1564 set_register(rd, ReadW(addr, instr));
1561 } else { 1565 } else {
1562 WriteW(addr, get_register(rd), instr); 1566 WriteW(addr, get_register(rd), instr);
1563 } 1567 }
1564 } 1568 }
1565 } 1569 }
1566 1570
1567 1571
1568 void Simulator::DecodeType3(Instr* instr) { 1572 void Simulator::DecodeType3(Instr* instr) {
1573 ASSERT(instr->Bit(4) == 0);
1569 int rd = instr->RdField(); 1574 int rd = instr->RdField();
1570 int rn = instr->RnField(); 1575 int rn = instr->RnField();
1571 int32_t rn_val = get_register(rn); 1576 int32_t rn_val = get_register(rn);
1572 bool shifter_carry_out = 0; 1577 bool shifter_carry_out = 0;
1573 int32_t shifter_operand = GetShiftRm(instr, &shifter_carry_out); 1578 int32_t shifter_operand = GetShiftRm(instr, &shifter_carry_out);
1574 int32_t addr = 0; 1579 int32_t addr = 0;
1575 switch (instr->PUField()) { 1580 switch (instr->PUField()) {
1576 case 0: { 1581 case 0: {
1577 ASSERT(!instr->HasW()); 1582 ASSERT(!instr->HasW());
1578 Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm"); 1583 Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm");
(...skipping 19 matching lines...) Expand all
1598 set_register(rn, addr); 1603 set_register(rn, addr);
1599 } 1604 }
1600 break; 1605 break;
1601 } 1606 }
1602 default: { 1607 default: {
1603 UNREACHABLE(); 1608 UNREACHABLE();
1604 break; 1609 break;
1605 } 1610 }
1606 } 1611 }
1607 if (instr->HasB()) { 1612 if (instr->HasB()) {
1608 UNIMPLEMENTED(); 1613 if (instr->HasL()) {
1614 uint8_t byte = ReadB(addr);
1615 set_register(rd, byte);
1616 } else {
1617 UNIMPLEMENTED();
1618 }
1609 } else { 1619 } else {
1610 if (instr->HasL()) { 1620 if (instr->HasL()) {
1611 set_register(rd, ReadW(addr, instr)); 1621 set_register(rd, ReadW(addr, instr));
1612 } else { 1622 } else {
1613 WriteW(addr, get_register(rd), instr); 1623 WriteW(addr, get_register(rd), instr);
1614 } 1624 }
1615 } 1625 }
1616 } 1626 }
1617 1627
1618 1628
(...skipping 28 matching lines...) Expand all
1647 void Simulator::DecodeType7(Instr* instr) { 1657 void Simulator::DecodeType7(Instr* instr) {
1648 if (instr->Bit(24) == 1) { 1658 if (instr->Bit(24) == 1) {
1649 // Format(instr, "swi 'swi"); 1659 // Format(instr, "swi 'swi");
1650 SoftwareInterrupt(instr); 1660 SoftwareInterrupt(instr);
1651 } else { 1661 } else {
1652 UNIMPLEMENTED(); 1662 UNIMPLEMENTED();
1653 } 1663 }
1654 } 1664 }
1655 1665
1656 1666
1667 void Simulator::DecodeUnconditional(Instr* instr) {
1668 if (instr->Bits(7, 4) == 0x0B && instr->Bits(27, 25) == 0 && instr->HasL()) {
1669 // Load halfword instruction, either register or immediate offset.
1670 int rd = instr->RdField();
1671 int rn = instr->RnField();
1672 int32_t rn_val = get_register(rn);
1673 int32_t addr = 0;
1674 int32_t offset;
1675 if (instr->Bit(22) == 0) {
1676 // Register offset.
1677 int rm = instr->RmField();
1678 offset = get_register(rm);
1679 } else {
1680 // Immediate offset
1681 offset = instr->Bits(3, 0) + (instr->Bits(11, 8) << 4);
1682 }
1683 switch (instr->PUField()) {
1684 case 0: {
1685 // Post index, negative.
1686 ASSERT(!instr->HasW());
1687 addr = rn_val;
1688 rn_val -= offset;
1689 set_register(rn, rn_val);
1690 break;
1691 }
1692 case 1: {
1693 // Post index, positive.
1694 ASSERT(!instr->HasW());
1695 addr = rn_val;
1696 rn_val += offset;
1697 set_register(rn, rn_val);
1698 break;
1699 }
1700 case 2: {
1701 // Pre index or offset, negative.
1702 rn_val -= offset;
1703 addr = rn_val;
1704 if (instr->HasW()) {
1705 set_register(rn, rn_val);
1706 }
1707 break;
1708 }
1709 case 3: {
1710 // Pre index or offset, positive.
1711 rn_val += offset;
1712 addr = rn_val;
1713 if (instr->HasW()) {
1714 set_register(rn, rn_val);
1715 }
1716 break;
1717 }
1718 default: {
1719 // The PU field is a 2-bit field.
1720 UNREACHABLE();
1721 break;
1722 }
1723 }
1724 // Not sign extending, so load as unsigned.
1725 uint16_t halfword = ReadH(addr, instr);
1726 set_register(rd, halfword);
1727 } else {
1728 UNIMPLEMENTED();
1729 }
1730 }
1731
1732
1657 // Executes the current instruction. 1733 // Executes the current instruction.
1658 void Simulator::InstructionDecode(Instr* instr) { 1734 void Simulator::InstructionDecode(Instr* instr) {
1659 pc_modified_ = false; 1735 pc_modified_ = false;
1660 if (instr->ConditionField() == special_condition) {
1661 Debugger dbg(this);
1662 dbg.Stop(instr);
1663 return;
1664 }
1665 if (::v8::internal::FLAG_trace_sim) { 1736 if (::v8::internal::FLAG_trace_sim) {
1666 disasm::NameConverter converter; 1737 disasm::NameConverter converter;
1667 disasm::Disassembler dasm(converter); 1738 disasm::Disassembler dasm(converter);
1668 // use a reasonably large buffer 1739 // use a reasonably large buffer
1669 v8::internal::EmbeddedVector<char, 256> buffer; 1740 v8::internal::EmbeddedVector<char, 256> buffer;
1670 dasm.InstructionDecode(buffer, 1741 dasm.InstructionDecode(buffer,
1671 reinterpret_cast<byte*>(instr)); 1742 reinterpret_cast<byte*>(instr));
1672 PrintF(" 0x%x %s\n", instr, buffer.start()); 1743 PrintF(" 0x%x %s\n", instr, buffer.start());
1673 } 1744 }
1674 if (ConditionallyExecute(instr)) { 1745 if (instr->ConditionField() == special_condition) {
1746 DecodeUnconditional(instr);
1747 } else if (ConditionallyExecute(instr)) {
1675 switch (instr->TypeField()) { 1748 switch (instr->TypeField()) {
1676 case 0: 1749 case 0:
1677 case 1: { 1750 case 1: {
1678 DecodeType01(instr); 1751 DecodeType01(instr);
1679 break; 1752 break;
1680 } 1753 }
1681 case 2: { 1754 case 2: {
1682 DecodeType2(instr); 1755 DecodeType2(instr);
1683 break; 1756 break;
1684 } 1757 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1740 dbg.Debug(); 1813 dbg.Debug();
1741 } else { 1814 } else {
1742 InstructionDecode(instr); 1815 InstructionDecode(instr);
1743 } 1816 }
1744 program_counter = get_pc(); 1817 program_counter = get_pc();
1745 } 1818 }
1746 } 1819 }
1747 } 1820 }
1748 1821
1749 1822
1750 Object* Simulator::Call(int32_t entry, int32_t p0, int32_t p1, int32_t p2, 1823 int32_t Simulator::Call(byte* entry, int argument_count, ...) {
1751 int32_t p3, int32_t p4) { 1824 va_list parameters;
1752 // Setup parameters 1825 va_start(parameters, argument_count);
1753 set_register(r0, p0); 1826 // Setup arguments
1754 set_register(r1, p1); 1827
1755 set_register(r2, p2); 1828 // First four arguments passed in registers.
1756 set_register(r3, p3); 1829 ASSERT(argument_count >= 4);
1757 intptr_t* stack_pointer = reinterpret_cast<intptr_t*>(get_register(sp)); 1830 set_register(r0, va_arg(parameters, int32_t));
1758 *(--stack_pointer) = p4; 1831 set_register(r1, va_arg(parameters, int32_t));
1759 set_register(sp, reinterpret_cast<int32_t>(stack_pointer)); 1832 set_register(r2, va_arg(parameters, int32_t));
1833 set_register(r3, va_arg(parameters, int32_t));
1834
1835 // Remaining arguments passed on stack.
1836 int original_stack = get_register(sp);
1837 // Compute position of stack on entry to generated code.
1838 int entry_stack = (original_stack - (argument_count - 4) * sizeof(int32_t));
1839 if (OS::ActivationFrameAlignment() != 0) {
1840 entry_stack &= -OS::ActivationFrameAlignment();
1841 }
1842 // Store remaining arguments on stack, from low to high memory.
1843 intptr_t* stack_argument = reinterpret_cast<intptr_t*>(entry_stack);
1844 for (int i = 4; i < argument_count; i++) {
1845 stack_argument[i - 4] = va_arg(parameters, int32_t);
1846 }
1847 va_end(parameters);
1848 set_register(sp, entry_stack);
1760 1849
1761 // Prepare to execute the code at entry 1850 // Prepare to execute the code at entry
1762 set_register(pc, entry); 1851 set_register(pc, reinterpret_cast<int32_t>(entry));
1763 // Put down marker for end of simulation. The simulator will stop simulation 1852 // Put down marker for end of simulation. The simulator will stop simulation
1764 // when the PC reaches this value. By saving the "end simulation" value into 1853 // when the PC reaches this value. By saving the "end simulation" value into
1765 // the LR the simulation stops when returning to this call point. 1854 // the LR the simulation stops when returning to this call point.
1766 set_register(lr, end_sim_pc); 1855 set_register(lr, end_sim_pc);
1767 1856
1768 // Remember the values of callee-saved registers. 1857 // Remember the values of callee-saved registers.
1769 // The code below assumes that r9 is not used as sb (static base) in 1858 // The code below assumes that r9 is not used as sb (static base) in
1770 // simulator code and therefore is regarded as a callee-saved register. 1859 // simulator code and therefore is regarded as a callee-saved register.
1771 int32_t r4_val = get_register(r4); 1860 int32_t r4_val = get_register(r4);
1772 int32_t r5_val = get_register(r5); 1861 int32_t r5_val = get_register(r5);
(...skipping 13 matching lines...) Expand all
1786 set_register(r7, callee_saved_value); 1875 set_register(r7, callee_saved_value);
1787 set_register(r8, callee_saved_value); 1876 set_register(r8, callee_saved_value);
1788 set_register(r9, callee_saved_value); 1877 set_register(r9, callee_saved_value);
1789 set_register(r10, callee_saved_value); 1878 set_register(r10, callee_saved_value);
1790 set_register(r11, callee_saved_value); 1879 set_register(r11, callee_saved_value);
1791 1880
1792 // Start the simulation 1881 // Start the simulation
1793 Execute(); 1882 Execute();
1794 1883
1795 // Check that the callee-saved registers have been preserved. 1884 // Check that the callee-saved registers have been preserved.
1796 CHECK_EQ(get_register(r4), callee_saved_value); 1885 CHECK_EQ(callee_saved_value, get_register(r4));
1797 CHECK_EQ(get_register(r5), callee_saved_value); 1886 CHECK_EQ(callee_saved_value, get_register(r5));
1798 CHECK_EQ(get_register(r6), callee_saved_value); 1887 CHECK_EQ(callee_saved_value, get_register(r6));
1799 CHECK_EQ(get_register(r7), callee_saved_value); 1888 CHECK_EQ(callee_saved_value, get_register(r7));
1800 CHECK_EQ(get_register(r8), callee_saved_value); 1889 CHECK_EQ(callee_saved_value, get_register(r8));
1801 CHECK_EQ(get_register(r9), callee_saved_value); 1890 CHECK_EQ(callee_saved_value, get_register(r9));
1802 CHECK_EQ(get_register(r10), callee_saved_value); 1891 CHECK_EQ(callee_saved_value, get_register(r10));
1803 CHECK_EQ(get_register(r11), callee_saved_value); 1892 CHECK_EQ(callee_saved_value, get_register(r11));
1804 1893
1805 // Restore callee-saved registers with the original value. 1894 // Restore callee-saved registers with the original value.
1806 set_register(r4, r4_val); 1895 set_register(r4, r4_val);
1807 set_register(r5, r5_val); 1896 set_register(r5, r5_val);
1808 set_register(r6, r6_val); 1897 set_register(r6, r6_val);
1809 set_register(r7, r7_val); 1898 set_register(r7, r7_val);
1810 set_register(r8, r8_val); 1899 set_register(r8, r8_val);
1811 set_register(r9, r9_val); 1900 set_register(r9, r9_val);
1812 set_register(r10, r10_val); 1901 set_register(r10, r10_val);
1813 set_register(r11, r11_val); 1902 set_register(r11, r11_val);
1814 1903
1815 int result = get_register(r0); 1904 // Pop stack passed arguments.
1816 return reinterpret_cast<Object*>(result); 1905 CHECK_EQ(entry_stack, get_register(sp));
1906 set_register(sp, original_stack);
1907
1908 int32_t result = get_register(r0);
1909 return result;
1817 } 1910 }
1818 1911
1819 } } // namespace assembler::arm 1912 } } // namespace assembler::arm
1820 1913
1821 #endif // !defined(__arm__) 1914 #endif // !defined(__arm__)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698