Changeset 62306 in webkit for trunk/JavaScriptCore/assembler/ARMv7Assembler.h
- Timestamp:
- Jul 1, 2010, 3:56:58 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/assembler/ARMv7Assembler.h
r59037 r62306 57 57 } RegisterID; 58 58 59 // s0 == d0 == q060 // s4 == d2 == q161 // etc62 59 typedef enum { 63 s0 = 0, 64 s1 = 1, 65 s2 = 2, 66 s3 = 3, 67 s4 = 4, 68 s5 = 5, 69 s6 = 6, 70 s7 = 7, 71 s8 = 8, 72 s9 = 9, 73 s10 = 10, 74 s11 = 11, 75 s12 = 12, 76 s13 = 13, 77 s14 = 14, 78 s15 = 15, 79 s16 = 16, 80 s17 = 17, 81 s18 = 18, 82 s19 = 19, 83 s20 = 20, 84 s21 = 21, 85 s22 = 22, 86 s23 = 23, 87 s24 = 24, 88 s25 = 25, 89 s26 = 26, 90 s27 = 27, 91 s28 = 28, 92 s29 = 29, 93 s30 = 30, 94 s31 = 31, 95 d0 = 0 << 1, 96 d1 = 1 << 1, 97 d2 = 2 << 1, 98 d3 = 3 << 1, 99 d4 = 4 << 1, 100 d5 = 5 << 1, 101 d6 = 6 << 1, 102 d7 = 7 << 1, 103 d8 = 8 << 1, 104 d9 = 9 << 1, 105 d10 = 10 << 1, 106 d11 = 11 << 1, 107 d12 = 12 << 1, 108 d13 = 13 << 1, 109 d14 = 14 << 1, 110 d15 = 15 << 1, 111 d16 = 16 << 1, 112 d17 = 17 << 1, 113 d18 = 18 << 1, 114 d19 = 19 << 1, 115 d20 = 20 << 1, 116 d21 = 21 << 1, 117 d22 = 22 << 1, 118 d23 = 23 << 1, 119 d24 = 24 << 1, 120 d25 = 25 << 1, 121 d26 = 26 << 1, 122 d27 = 27 << 1, 123 d28 = 28 << 1, 124 d29 = 29 << 1, 125 d30 = 30 << 1, 126 d31 = 31 << 1, 127 q0 = 0 << 2, 128 q1 = 1 << 2, 129 q2 = 2 << 2, 130 q3 = 3 << 2, 131 q4 = 4 << 2, 132 q5 = 5 << 2, 133 q6 = 6 << 2, 134 q7 = 7 << 2, 135 q8 = 8 << 2, 136 q9 = 9 << 2, 137 q10 = 10 << 2, 138 q11 = 11 << 2, 139 q12 = 12 << 2, 140 q13 = 13 << 2, 141 q14 = 14 << 2, 142 q15 = 15 << 2, 143 q16 = 16 << 2, 144 q17 = 17 << 2, 145 q18 = 18 << 2, 146 q19 = 19 << 2, 147 q20 = 20 << 2, 148 q21 = 21 << 2, 149 q22 = 22 << 2, 150 q23 = 23 << 2, 151 q24 = 24 << 2, 152 q25 = 25 << 2, 153 q26 = 26 << 2, 154 q27 = 27 << 2, 155 q28 = 28 << 2, 156 q29 = 29 << 2, 157 q30 = 30 << 2, 158 q31 = 31 << 2, 159 } FPRegisterID; 60 s0, 61 s1, 62 s2, 63 s3, 64 s4, 65 s5, 66 s6, 67 s7, 68 s8, 69 s9, 70 s10, 71 s11, 72 s12, 73 s13, 74 s14, 75 s15, 76 s16, 77 s17, 78 s18, 79 s19, 80 s20, 81 s21, 82 s22, 83 s23, 84 s24, 85 s25, 86 s26, 87 s27, 88 s28, 89 s29, 90 s30, 91 s31, 92 } FPSingleRegisterID; 93 94 typedef enum { 95 d0, 96 d1, 97 d2, 98 d3, 99 d4, 100 d5, 101 d6, 102 d7, 103 d8, 104 d9, 105 d10, 106 d11, 107 d12, 108 d13, 109 d14, 110 d15, 111 d16, 112 d17, 113 d18, 114 d19, 115 d20, 116 d21, 117 d22, 118 d23, 119 d24, 120 d25, 121 d26, 122 d27, 123 d28, 124 d29, 125 d30, 126 d31, 127 } FPDoubleRegisterID; 128 129 typedef enum { 130 q0, 131 q1, 132 q2, 133 q3, 134 q4, 135 q5, 136 q6, 137 q7, 138 q8, 139 q9, 140 q10, 141 q11, 142 q12, 143 q13, 144 q14, 145 q15, 146 q16, 147 q17, 148 q18, 149 q19, 150 q20, 151 q21, 152 q22, 153 q23, 154 q24, 155 q25, 156 q26, 157 q27, 158 q28, 159 q29, 160 q30, 161 q31, 162 } FPQuadRegisterID; 163 164 inline FPSingleRegisterID asSingle(FPDoubleRegisterID reg) 165 { 166 ASSERT(reg < d16); 167 return (FPSingleRegisterID)(reg << 1); 168 } 169 170 inline FPDoubleRegisterID asDouble(FPSingleRegisterID reg) 171 { 172 ASSERT(!(reg & 1)); 173 return (FPDoubleRegisterID)(reg >> 1); 174 } 160 175 } 161 176 … … 355 370 }; 356 371 372 class VFPImmediate { 373 public: 374 VFPImmediate(double d) 375 : m_value(-1) 376 { 377 union { 378 uint64_t i; 379 double d; 380 } u; 381 382 u.d = d; 383 384 int sign = (u.i >> 63); 385 int exponent = (u.i >> 52) & 0x7ff; 386 uint64_t mantissa = u.i & 0x000fffffffffffffull; 387 388 if ((exponent >= 0x3fc) && (exponent <= 0x403) && !(mantissa & 0x0000ffffffffffffull)) 389 m_value = (sign << 7) | ((exponent & 7) << 4) | (int)(mantissa >> 48); 390 } 391 392 bool isValid() 393 { 394 return m_value != -1; 395 } 396 397 uint8_t value() 398 { 399 return (uint8_t)m_value; 400 } 401 402 private: 403 int m_value; 404 }; 357 405 358 406 typedef enum { … … 418 466 419 467 typedef ARMRegisters::RegisterID RegisterID; 420 typedef ARMRegisters::FPRegisterID FPRegisterID; 468 typedef ARMRegisters::FPSingleRegisterID FPSingleRegisterID; 469 typedef ARMRegisters::FPDoubleRegisterID FPDoubleRegisterID; 470 typedef ARMRegisters::FPQuadRegisterID FPQuadRegisterID; 421 471 422 472 // (HS, LO, HI, LS) -> (AE, B, A, BE) … … 504 554 } 505 555 506 bool isSingleRegister(FPRegisterID reg) 507 { 508 // Check that the high bit isn't set (q16+), and that the low bit isn't (s1, s3, etc). 509 return !(reg & ~31); 510 } 511 512 bool isDoubleRegister(FPRegisterID reg) 513 { 514 // Check that the high bit isn't set (q16+), and that the low bit isn't (s1, s3, etc). 515 return !(reg & ~(31 << 1)); 516 } 517 518 bool isQuadRegister(FPRegisterID reg) 519 { 520 return !(reg & ~(31 << 2)); 521 } 522 523 uint32_t singleRegisterNum(FPRegisterID reg) 524 { 525 ASSERT(isSingleRegister(reg)); 526 return reg; 527 } 528 529 uint32_t doubleRegisterNum(FPRegisterID reg) 530 { 531 ASSERT(isDoubleRegister(reg)); 532 return reg >> 1; 533 } 534 535 uint32_t quadRegisterNum(FPRegisterID reg) 536 { 537 ASSERT(isQuadRegister(reg)); 538 return reg >> 2; 539 } 540 541 uint32_t singleRegisterMask(FPRegisterID rd, int highBitsShift, int lowBitShift) 542 { 543 uint32_t rdNum = singleRegisterNum(rd); 556 uint32_t singleRegisterMask(FPSingleRegisterID rdNum, int highBitsShift, int lowBitShift) 557 { 544 558 uint32_t rdMask = (rdNum >> 1) << highBitsShift; 545 559 if (rdNum & 1) … … 548 562 } 549 563 550 uint32_t doubleRegisterMask(FPRegisterID rd, int highBitShift, int lowBitsShift) 551 { 552 uint32_t rdNum = doubleRegisterNum(rd); 564 uint32_t doubleRegisterMask(FPDoubleRegisterID rdNum, int highBitShift, int lowBitsShift) 565 { 553 566 uint32_t rdMask = (rdNum & 0xf) << lowBitsShift; 554 567 if (rdNum & 16) … … 559 572 typedef enum { 560 573 OP_ADD_reg_T1 = 0x1800, 561 OP_ADD_S_reg_T1 = 0x1800,562 574 OP_SUB_reg_T1 = 0x1A00, 563 OP_SUB_S_reg_T1 = 0x1A00,564 575 OP_ADD_imm_T1 = 0x1C00, 565 OP_ADD_S_imm_T1 = 0x1C00,566 576 OP_SUB_imm_T1 = 0x1E00, 567 OP_SUB_S_imm_T1 = 0x1E00,568 577 OP_MOV_imm_T1 = 0x2000, 569 578 OP_CMP_imm_T1 = 0x2800, 570 579 OP_ADD_imm_T2 = 0x3000, 571 OP_ADD_S_imm_T2 = 0x3000,572 580 OP_SUB_imm_T2 = 0x3800, 573 OP_SUB_S_imm_T2 = 0x3800,574 581 OP_AND_reg_T1 = 0x4000, 575 582 OP_EOR_reg_T1 = 0x4040, 576 583 OP_TST_reg_T1 = 0x4200, 584 OP_RSB_imm_T1 = 0x4240, 577 585 OP_CMP_reg_T1 = 0x4280, 578 586 OP_ORR_reg_T1 = 0x4300, … … 604 612 OP_TST_reg_T2 = 0xEA10, 605 613 OP_ORR_reg_T2 = 0xEA40, 614 OP_ORR_S_reg_T2 = 0xEA50, 606 615 OP_ASR_imm_T1 = 0xEA4F, 607 616 OP_LSL_imm_T1 = 0xEA4F, … … 628 637 OP_SUB_S_imm_T3 = 0xF1B0, 629 638 OP_CMP_imm_T2 = 0xF1B0, 639 OP_RSB_imm_T2 = 0xF1C0, 630 640 OP_ADD_imm_T4 = 0xF200, 631 641 OP_MOV_imm_T3 = 0xF240, … … 785 795 if (!((rd | rn) & 8)) { 786 796 if (imm.isUInt3()) { 787 m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_ S_imm_T1, (RegisterID)imm.getUInt3(), rn, rd);797 m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_imm_T1, (RegisterID)imm.getUInt3(), rn, rd); 788 798 return; 789 799 } else if ((rd == rn) && imm.isUInt8()) { 790 m_formatter.oneWordOp5Reg3Imm8(OP_ADD_ S_imm_T2, rd, imm.getUInt8());800 m_formatter.oneWordOp5Reg3Imm8(OP_ADD_imm_T2, rd, imm.getUInt8()); 791 801 return; 792 802 } … … 810 820 { 811 821 if (!((rd | rn | rm) & 8)) 812 m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_ S_reg_T1, rm, rn, rd);822 m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_reg_T1, rm, rn, rd); 813 823 else 814 824 add_S(rd, rn, rm, ShiftTypeAndAmount()); … … 1220 1230 } 1221 1231 1232 void neg(RegisterID rd, RegisterID rm) 1233 { 1234 ARMThumbImmediate zero = ARMThumbImmediate::makeUInt12(0); 1235 sub(rd, zero, rm); 1236 } 1237 1222 1238 void orr(RegisterID rd, RegisterID rn, ARMThumbImmediate imm) 1223 1239 { … … 1244 1260 else 1245 1261 orr(rd, rn, rm, ShiftTypeAndAmount()); 1262 } 1263 1264 void orr_S(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift) 1265 { 1266 ASSERT(!BadReg(rd)); 1267 ASSERT(!BadReg(rn)); 1268 ASSERT(!BadReg(rm)); 1269 m_formatter.twoWordOp12Reg4FourFours(OP_ORR_S_reg_T2, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm)); 1270 } 1271 1272 void orr_S(RegisterID rd, RegisterID rn, RegisterID rm) 1273 { 1274 if ((rd == rn) && !((rd | rm) & 8)) 1275 m_formatter.oneWordOp10Reg3Reg3(OP_ORR_reg_T1, rm, rd); 1276 else if ((rd == rm) && !((rd | rn) & 8)) 1277 m_formatter.oneWordOp10Reg3Reg3(OP_ORR_reg_T1, rn, rd); 1278 else 1279 orr_S(rd, rn, rm, ShiftTypeAndAmount()); 1246 1280 } 1247 1281 … … 1362 1396 } 1363 1397 1398 void sub(RegisterID rd, ARMThumbImmediate imm, RegisterID rn) 1399 { 1400 ASSERT(rd != ARMRegisters::pc); 1401 ASSERT(rn != ARMRegisters::pc); 1402 ASSERT(imm.isValid()); 1403 ASSERT(imm.isUInt12()); 1404 1405 if (!((rd | rn) & 8) && !imm.getUInt12()) 1406 m_formatter.oneWordOp10Reg3Reg3(OP_RSB_imm_T1, rn, rd); 1407 else 1408 m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_RSB_imm_T2, rn, rd, imm); 1409 } 1410 1364 1411 void sub(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift) 1365 1412 { … … 1394 1441 } else if (!((rd | rn) & 8)) { 1395 1442 if (imm.isUInt3()) { 1396 m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_ S_imm_T1, (RegisterID)imm.getUInt3(), rn, rd);1443 m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_imm_T1, (RegisterID)imm.getUInt3(), rn, rd); 1397 1444 return; 1398 1445 } else if ((rd == rn) && imm.isUInt8()) { 1399 m_formatter.oneWordOp5Reg3Imm8(OP_SUB_ S_imm_T2, rd, imm.getUInt8());1446 m_formatter.oneWordOp5Reg3Imm8(OP_SUB_imm_T2, rd, imm.getUInt8()); 1400 1447 return; 1401 1448 } … … 1419 1466 { 1420 1467 if (!((rd | rn | rm) & 8)) 1421 m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_ S_reg_T1, rm, rn, rd);1468 m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_reg_T1, rm, rn, rd); 1422 1469 else 1423 1470 sub_S(rd, rn, rm, ShiftTypeAndAmount()); … … 1447 1494 } 1448 1495 1449 void vadd_F64(FP RegisterID rd, FPRegisterID rn, FPRegisterID rm)1496 void vadd_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) 1450 1497 { 1451 1498 m_formatter.vfpOp(0x0b00ee30 | doubleRegisterMask(rd, 6, 28) | doubleRegisterMask(rn, 23, 0) | doubleRegisterMask(rm, 21, 16)); 1452 1499 } 1453 1500 1454 void vcmp_F64(FP RegisterID rd, FPRegisterID rm)1501 void vcmp_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rm) 1455 1502 { 1456 1503 m_formatter.vfpOp(0x0bc0eeb4 | doubleRegisterMask(rd, 6, 28) | doubleRegisterMask(rm, 21, 16)); 1457 1504 } 1458 1505 1459 void vcvt_F64_S32(FPRegisterID fd, FPRegisterID sm) 1460 { 1461 m_formatter.vfpOp(0x0bc0eeb8 | doubleRegisterMask(fd, 6, 28) | singleRegisterMask(sm, 16, 21)); 1462 } 1463 1464 void vcvt_S32_F64(FPRegisterID sd, FPRegisterID fm) 1465 { 1466 m_formatter.vfpOp(0x0bc0eebd | singleRegisterMask(sd, 28, 6) | doubleRegisterMask(fm, 21, 16)); 1467 } 1468 1469 void vldr(FPRegisterID rd, RegisterID rn, int32_t imm) 1506 void vcvt_F64_S32(FPDoubleRegisterID rd, FPSingleRegisterID rm) 1507 { 1508 vcvt(doubleRegisterMask(rd, 6, 28), singleRegisterMask(rm, 16, 21), false, false, false, true); 1509 } 1510 1511 void vcvtr_S32_F64(FPSingleRegisterID rd, FPDoubleRegisterID rm) 1512 { 1513 vcvt(singleRegisterMask(rd, 6, 28), doubleRegisterMask(rm, 16, 21), true, false, true, true); 1514 } 1515 1516 void vdiv_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) 1517 { 1518 m_formatter.vfpOp(0x0b00ee80 | doubleRegisterMask(rd, 6, 28) | doubleRegisterMask(rn, 23, 0) | doubleRegisterMask(rm, 21, 16)); 1519 } 1520 1521 void vldr(FPDoubleRegisterID rd, RegisterID rn, int32_t imm) 1470 1522 { 1471 1523 vmem(rd, rn, imm, true); 1472 1524 } 1473 1525 1474 void vmov(RegisterID rd, FPRegisterID sn) 1526 void vmov_F64_0(FPDoubleRegisterID rd) 1527 { 1528 m_formatter.vfpOp(0x0b00eeb0 | doubleRegisterMask(rd, 28, 6)); 1529 } 1530 1531 void vmov(RegisterID rd, FPSingleRegisterID sn) 1475 1532 { 1476 1533 m_formatter.vfpOp(0x0a10ee10 | (rd << 28) | singleRegisterMask(sn, 0, 23)); 1477 1534 } 1478 1535 1479 void vmov(FP RegisterID sn, RegisterID rd)1536 void vmov(FPSingleRegisterID sn, RegisterID rd) 1480 1537 { 1481 1538 m_formatter.vfpOp(0x0a10ee00 | (rd << 28) | singleRegisterMask(sn, 0, 23)); … … 1488 1545 } 1489 1546 1490 void vmul_F64(FP RegisterID rd, FPRegisterID rn, FPRegisterID rm)1547 void vmul_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) 1491 1548 { 1492 1549 m_formatter.vfpOp(0x0b00ee20 | doubleRegisterMask(rd, 6, 28) | doubleRegisterMask(rn, 23, 0) | doubleRegisterMask(rm, 21, 16)); 1493 1550 } 1494 1551 1495 void vstr(FP RegisterID rd, RegisterID rn, int32_t imm)1552 void vstr(FPDoubleRegisterID rd, RegisterID rn, int32_t imm) 1496 1553 { 1497 1554 vmem(rd, rn, imm, false); 1498 1555 } 1499 1556 1500 void vsub_F64(FP RegisterID rd, FPRegisterID rn, FPRegisterID rm)1557 void vsub_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) 1501 1558 { 1502 1559 m_formatter.vfpOp(0x0b40ee30 | doubleRegisterMask(rd, 6, 28) | doubleRegisterMask(rn, 23, 0) | doubleRegisterMask(rm, 21, 16)); … … 1665 1722 private: 1666 1723 1724 void vcvt(uint32_t rdMask, uint32_t rmMask, bool toInteger, bool isUnsigned, bool isRoundZero, bool isDouble) 1725 { 1726 // Cannot specify rounding when converting to float. 1727 ASSERT(toInteger || !isRoundZero); 1728 1729 // 'sz' field 1730 int op = isDouble ? 0x0b40eeb8 : 0x0a40eeb8; 1731 1732 if (toInteger) { 1733 // opc2 indicates both toInteger & isUnsigned. 1734 op |= isUnsigned ? 0x00000004 : 0x00000005; 1735 // 'op' field in instruction is isRoundZero 1736 if (isRoundZero) 1737 op |= 0x00800000; 1738 } else { 1739 // 'op' field in instruction is isUnsigned 1740 if (!isUnsigned) 1741 op |= 0x00800000; 1742 } 1743 m_formatter.vfpOp(op | rdMask | rmMask); 1744 } 1745 1667 1746 // Arm vfp addresses can be offset by a 9-bit ones-comp immediate, left shifted by 2. 1668 1747 // (i.e. +/-(0..255) 32-bit words) 1669 void vmem(FP RegisterID rd, RegisterID rn, int32_t imm, bool isLoad)1748 void vmem(FPDoubleRegisterID rd, RegisterID rn, int32_t imm, bool isLoad) 1670 1749 { 1671 1750 bool up;
Note:
See TracChangeset
for help on using the changeset viewer.