Changeset 62419 in webkit for trunk/JavaScriptCore/assembler/ARMv7Assembler.h
- Timestamp:
- Jul 2, 2010, 5:28:12 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/assembler/ARMv7Assembler.h
r62306 r62419 446 446 }; 447 447 448 449 /*450 Some features of the Thumb instruction set are deprecated in ARMv7. Deprecated features affecting451 instructions supported by ARMv7-M are as follows:452 • use of the PC as <Rd> or <Rm> in a 16-bit ADD (SP plus register) instruction453 • use of the SP as <Rm> in a 16-bit ADD (SP plus register) instruction454 • use of the SP as <Rm> in a 16-bit CMP (register) instruction455 • use of MOV (register) instructions in which <Rd> is the SP or PC and <Rm> is also the SP or PC.456 • use of <Rn> as the lowest-numbered register in the register list of a 16-bit STM instruction with base457 register writeback458 */459 448 460 449 class ARMv7Assembler { … … 624 613 OP_SUB_S_reg_T2 = 0xEBB0, 625 614 OP_CMP_reg_T2 = 0xEBB0, 615 OP_VSTR = 0xED00, 616 OP_VLDR = 0xED10, 617 OP_VMOV_StoC = 0xEE00, 618 OP_VMOV_CtoS = 0xEE10, 619 OP_VMUL_T2 = 0xEE20, 620 OP_VADD_T2 = 0xEE30, 621 OP_VSUB_T2 = 0xEE30, 622 OP_VDIV = 0xEE80, 623 OP_VCMP_T1 = 0xEEB0, 624 OP_VCVT_FPIVFP = 0xEEB0, 625 OP_VMOV_IMM_T2 = 0xEEB0, 626 OP_VMRS = 0xEEB0, 626 627 OP_B_T4a = 0xF000, 627 628 OP_AND_imm_T1 = 0xF000, … … 663 664 664 665 typedef enum { 666 OP_VADD_T2b = 0x0A00, 667 OP_VDIVb = 0x0A00, 668 OP_VLDRb = 0x0A00, 669 OP_VMOV_IMM_T2b = 0x0A00, 670 OP_VMUL_T2b = 0x0A00, 671 OP_VSTRb = 0x0A00, 672 OP_VMOV_CtoSb = 0x0A10, 673 OP_VMOV_StoCb = 0x0A10, 674 OP_VMRSb = 0x0A10, 675 OP_VCMP_T1b = 0x0A40, 676 OP_VCVT_FPIVFPb = 0x0A40, 677 OP_VSUB_T2b = 0x0A40, 678 OP_NOP_T2b = 0x8000, 665 679 OP_B_T4b = 0x9000, 666 OP_NOP_T2b = 0x8000,667 680 } OpcodeID2; 668 681 … … 1496 1509 void vadd_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) 1497 1510 { 1498 m_formatter.vfpOp( 0x0b00ee30 | doubleRegisterMask(rd, 6, 28) | doubleRegisterMask(rn, 23, 0) | doubleRegisterMask(rm, 21, 16));1511 m_formatter.vfpOp(OP_VADD_T2, OP_VADD_T2b, true, rn, rd, rm); 1499 1512 } 1500 1513 1501 1514 void vcmp_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rm) 1502 1515 { 1503 m_formatter.vfpOp( 0x0bc0eeb4 | doubleRegisterMask(rd, 6, 28) | doubleRegisterMask(rm, 21, 16));1516 m_formatter.vfpOp(OP_VCMP_T1, OP_VCMP_T1b, true, VFPOperand(4), rd, rm); 1504 1517 } 1505 1518 1506 1519 void vcvt_F64_S32(FPDoubleRegisterID rd, FPSingleRegisterID rm) 1507 1520 { 1508 vcvt(doubleRegisterMask(rd, 6, 28), singleRegisterMask(rm, 16, 21), false, false, false, true); 1521 // boolean values are 64bit (toInt, unsigned, roundZero) 1522 m_formatter.vfpOp(OP_VCVT_FPIVFP, OP_VCVT_FPIVFPb, true, vcvtOp(false, false, false), rd, rm); 1509 1523 } 1510 1524 1511 1525 void vcvtr_S32_F64(FPSingleRegisterID rd, FPDoubleRegisterID rm) 1512 1526 { 1513 vcvt(singleRegisterMask(rd, 6, 28), doubleRegisterMask(rm, 16, 21), true, false, true, true); 1527 // boolean values are 64bit (toInt, unsigned, roundZero) 1528 m_formatter.vfpOp(OP_VCVT_FPIVFP, OP_VCVT_FPIVFPb, true, vcvtOp(true, false, true), rd, rm); 1514 1529 } 1515 1530 1516 1531 void vdiv_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) 1517 1532 { 1518 m_formatter.vfpOp( 0x0b00ee80 | doubleRegisterMask(rd, 6, 28) | doubleRegisterMask(rn, 23, 0) | doubleRegisterMask(rm, 21, 16));1533 m_formatter.vfpOp(OP_VDIV, OP_VDIVb, true, rn, rd, rm); 1519 1534 } 1520 1535 1521 1536 void vldr(FPDoubleRegisterID rd, RegisterID rn, int32_t imm) 1522 1537 { 1523 vmem(rd, rn, imm, true);1538 m_formatter.vfpMemOp(OP_VLDR, OP_VLDRb, true, rn, rd, imm); 1524 1539 } 1525 1540 1526 1541 void vmov_F64_0(FPDoubleRegisterID rd) 1527 1542 { 1528 m_formatter.vfpOp(0x0b00eeb0 | doubleRegisterMask(rd, 28, 6)); 1529 } 1530 1531 void vmov(RegisterID rd, FPSingleRegisterID sn) 1532 { 1533 m_formatter.vfpOp(0x0a10ee10 | (rd << 28) | singleRegisterMask(sn, 0, 23)); 1534 } 1535 1536 void vmov(FPSingleRegisterID sn, RegisterID rd) 1537 { 1538 m_formatter.vfpOp(0x0a10ee00 | (rd << 28) | singleRegisterMask(sn, 0, 23)); 1539 } 1540 1541 // move FPSCR flags to APSR. 1542 void vmrs_APSR_nzcv_FPSCR() 1543 { 1544 m_formatter.vfpOp(0xfa10eef1); 1543 m_formatter.vfpOp(OP_VMOV_IMM_T2, OP_VMOV_IMM_T2b, true, VFPOperand(0), rd, VFPOperand(0)); 1544 } 1545 1546 void vmov(RegisterID rd, FPSingleRegisterID rn) 1547 { 1548 ASSERT(!BadReg(rd)); 1549 m_formatter.vfpOp(OP_VMOV_CtoS, OP_VMOV_CtoSb, false, rn, rd, VFPOperand(0)); 1550 } 1551 1552 void vmov(FPSingleRegisterID rd, RegisterID rn) 1553 { 1554 ASSERT(!BadReg(rn)); 1555 m_formatter.vfpOp(OP_VMOV_StoC, OP_VMOV_StoCb, false, rd, rn, VFPOperand(0)); 1556 } 1557 1558 void vmrs(RegisterID reg = ARMRegisters::pc) 1559 { 1560 ASSERT(reg != ARMRegisters::sp); 1561 m_formatter.vfpOp(OP_VMRS, OP_VMRSb, false, VFPOperand(1), VFPOperand(0x10 | reg), VFPOperand(0)); 1545 1562 } 1546 1563 1547 1564 void vmul_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) 1548 1565 { 1549 m_formatter.vfpOp( 0x0b00ee20 | doubleRegisterMask(rd, 6, 28) | doubleRegisterMask(rn, 23, 0) | doubleRegisterMask(rm, 21, 16));1566 m_formatter.vfpOp(OP_VMUL_T2, OP_VMUL_T2b, true, rn, rd, rm); 1550 1567 } 1551 1568 1552 1569 void vstr(FPDoubleRegisterID rd, RegisterID rn, int32_t imm) 1553 1570 { 1554 vmem(rd, rn, imm, false);1571 m_formatter.vfpMemOp(OP_VSTR, OP_VSTRb, true, rn, rd, imm); 1555 1572 } 1556 1573 1557 1574 void vsub_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) 1558 1575 { 1559 m_formatter.vfpOp(0x0b40ee30 | doubleRegisterMask(rd, 6, 28) | doubleRegisterMask(rn, 23, 0) | doubleRegisterMask(rm, 21, 16)); 1560 } 1561 1576 m_formatter.vfpOp(OP_VSUB_T2, OP_VSUB_T2b, true, rn, rd, rm); 1577 } 1562 1578 1563 1579 JmpDst label() … … 1721 1737 1722 1738 private: 1723 1724 void vcvt(uint32_t rdMask, uint32_t rmMask, bool toInteger, bool isUnsigned, bool isRoundZero, bool isDouble) 1739 // VFP operations commonly take one or more 5-bit operands, typically representing a 1740 // floating point register number. This will commonly be encoded in the instruction 1741 // in two parts, with one single bit field, and one 4-bit field. In the case of 1742 // double precision operands the high bit of the register number will be encoded 1743 // separately, and for single precision operands the high bit of the register number 1744 // will be encoded individually. 1745 // VFPOperand encapsulates a 5-bit VFP operand, with bits 0..3 containing the 4-bit 1746 // field to be encoded together in the instruction (the low 4-bits of a double 1747 // register number, or the high 4-bits of a single register number), and bit 4 1748 // contains the bit value to be encoded individually. 1749 struct VFPOperand { 1750 explicit VFPOperand(uint32_t value) 1751 : m_value(value) 1752 { 1753 ASSERT(!(m_value & ~0x1f)); 1754 } 1755 1756 VFPOperand(FPDoubleRegisterID reg) 1757 : m_value(reg) 1758 { 1759 } 1760 1761 VFPOperand(RegisterID reg) 1762 : m_value(reg) 1763 { 1764 } 1765 1766 VFPOperand(FPSingleRegisterID reg) 1767 : m_value(((reg & 1) << 4) | (reg >> 1)) // rotate the lowest bit of 'reg' to the top. 1768 { 1769 } 1770 1771 uint32_t bits1() 1772 { 1773 return m_value >> 4; 1774 } 1775 1776 uint32_t bits4() 1777 { 1778 return m_value & 0xf; 1779 } 1780 1781 uint32_t m_value; 1782 }; 1783 1784 VFPOperand vcvtOp(bool toInteger, bool isUnsigned, bool isRoundZero) 1725 1785 { 1726 1786 // Cannot specify rounding when converting to float. 1727 1787 ASSERT(toInteger || !isRoundZero); 1728 1788 1729 // 'sz' field 1730 int op = isDouble ? 0x0b40eeb8 : 0x0a40eeb8; 1731 1789 uint32_t op = 0x8; 1732 1790 if (toInteger) { 1733 1791 // opc2 indicates both toInteger & isUnsigned. 1734 op |= isUnsigned ? 0x 00000004 : 0x00000005;1792 op |= isUnsigned ? 0x4 : 0x5; 1735 1793 // 'op' field in instruction is isRoundZero 1736 1794 if (isRoundZero) 1737 op |= 0x 00800000;1795 op |= 0x10; 1738 1796 } else { 1739 1797 // 'op' field in instruction is isUnsigned 1740 1798 if (!isUnsigned) 1741 op |= 0x00800000; 1742 } 1743 m_formatter.vfpOp(op | rdMask | rmMask); 1744 } 1745 1746 // Arm vfp addresses can be offset by a 9-bit ones-comp immediate, left shifted by 2. 1747 // (i.e. +/-(0..255) 32-bit words) 1748 void vmem(FPDoubleRegisterID rd, RegisterID rn, int32_t imm, bool isLoad) 1749 { 1750 bool up; 1751 uint32_t offset; 1752 if (imm < 0) { 1753 offset = -imm; 1754 up = false; 1755 } else { 1756 offset = imm; 1757 up = true; 1758 } 1759 1760 // offset is effectively leftshifted by 2 already (the bottom two bits are zero, and not 1761 // reperesented in the instruction. Left shift by 14, to mov it into position 0x00AA0000. 1762 ASSERT((offset & ~(0xff << 2)) == 0); 1763 offset <<= 14; 1764 1765 m_formatter.vfpOp(0x0b00ed00 | offset | (up << 7) | (isLoad << 4) | doubleRegisterMask(rd, 6, 28) | rn); 1799 op |= 0x10; 1800 } 1801 return VFPOperand(op); 1766 1802 } 1767 1803 … … 1953 1989 } 1954 1990 1955 void vfpOp(int32_t op) 1956 { 1957 m_buffer.putInt(op); 1958 } 1959 1991 // Formats up instructions of the pattern: 1992 // 111111111B11aaaa:bbbb222SA2C2cccc 1993 // Where 1s in the pattern come from op1, 2s in the pattern come from op2, S is the provided size bit. 1994 // Operands provide 5 bit values of the form Aaaaa, Bbbbb, Ccccc. 1995 void vfpOp(OpcodeID1 op1, OpcodeID2 op2, bool size, VFPOperand a, VFPOperand b, VFPOperand c) 1996 { 1997 ASSERT(!(op1 & 0x004f)); 1998 ASSERT(!(op2 & 0xf1af)); 1999 m_buffer.putShort(op1 | b.bits1() << 6 | a.bits4()); 2000 m_buffer.putShort(op2 | b.bits4() << 12 | size << 8 | a.bits1() << 7 | c.bits1() << 5 | c.bits4()); 2001 } 2002 2003 // Arm vfp addresses can be offset by a 9-bit ones-comp immediate, left shifted by 2. 2004 // (i.e. +/-(0..255) 32-bit words) 2005 void vfpMemOp(OpcodeID1 op1, OpcodeID2 op2, bool size, RegisterID rn, VFPOperand rd, int32_t imm) 2006 { 2007 bool up = true; 2008 if (imm < 0) { 2009 imm = -imm; 2010 up = false; 2011 } 2012 2013 uint32_t offset = imm; 2014 ASSERT(!(offset & ~0x3fc)); 2015 offset >>= 2; 2016 2017 m_buffer.putShort(op1 | (up << 7) | rd.bits1() << 6 | rn); 2018 m_buffer.putShort(op2 | rd.bits4() << 12 | size << 8 | offset); 2019 } 1960 2020 1961 2021 // Administrative methods:
Note:
See TracChangeset
for help on using the changeset viewer.