OLD | NEW |
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
2 // All Rights Reserved. | 2 // All Rights Reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
6 // are met: | 6 // are met: |
7 // | 7 // |
8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
10 // | 10 // |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 #endif | 306 #endif |
307 | 307 |
308 printf("target%s%s %s%s%s %s\n", | 308 printf("target%s%s %s%s%s %s\n", |
309 arm_target_type, arm_no_probe, arm_arch, arm_fpu, arm_thumb, | 309 arm_target_type, arm_no_probe, arm_arch, arm_fpu, arm_thumb, |
310 arm_float_abi); | 310 arm_float_abi); |
311 } | 311 } |
312 | 312 |
313 | 313 |
314 void CpuFeatures::PrintFeatures() { | 314 void CpuFeatures::PrintFeatures() { |
315 printf( | 315 printf( |
316 "ARMv8=%d ARMv7=%d VFP3=%d VFP32DREGS=%d NEON=%d SUDIV=%d " | 316 "ARMv8=%d ARMv7=%d VFPv3=%d VFP32DREGS=%d NEON=%d SUDIV=%d " |
317 "MOVW_MOVT_IMMEDIATE_LOADS=%d", | 317 "MOVW_MOVT_IMMEDIATE_LOADS=%d", |
318 CpuFeatures::IsSupported(ARMv8), CpuFeatures::IsSupported(ARMv7), | 318 CpuFeatures::IsSupported(ARMv8), CpuFeatures::IsSupported(ARMv7), |
319 CpuFeatures::IsSupported(VFP3), CpuFeatures::IsSupported(VFP32DREGS), | 319 CpuFeatures::IsSupported(VFPv3), CpuFeatures::IsSupported(VFP32DREGS), |
320 CpuFeatures::IsSupported(NEON), CpuFeatures::IsSupported(SUDIV), | 320 CpuFeatures::IsSupported(NEON), CpuFeatures::IsSupported(SUDIV), |
321 CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS)); | 321 CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS)); |
322 #ifdef __arm__ | 322 #ifdef __arm__ |
323 bool eabi_hardfloat = base::OS::ArmUsingHardFloat(); | 323 bool eabi_hardfloat = base::OS::ArmUsingHardFloat(); |
324 #elif USE_EABI_HARDFLOAT | 324 #elif USE_EABI_HARDFLOAT |
325 bool eabi_hardfloat = true; | 325 bool eabi_hardfloat = true; |
326 #else | 326 #else |
327 bool eabi_hardfloat = false; | 327 bool eabi_hardfloat = false; |
328 #endif | 328 #endif |
329 printf(" USE_EABI_HARDFLOAT=%d\n", eabi_hardfloat); | 329 printf(" USE_EABI_HARDFLOAT=%d\n", eabi_hardfloat); |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 pending_32_bit_constants_.reserve(kMinNumPendingConstants); | 591 pending_32_bit_constants_.reserve(kMinNumPendingConstants); |
592 pending_64_bit_constants_.reserve(kMinNumPendingConstants); | 592 pending_64_bit_constants_.reserve(kMinNumPendingConstants); |
593 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); | 593 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_); |
594 next_buffer_check_ = 0; | 594 next_buffer_check_ = 0; |
595 const_pool_blocked_nesting_ = 0; | 595 const_pool_blocked_nesting_ = 0; |
596 no_const_pool_before_ = 0; | 596 no_const_pool_before_ = 0; |
597 first_const_pool_32_use_ = -1; | 597 first_const_pool_32_use_ = -1; |
598 first_const_pool_64_use_ = -1; | 598 first_const_pool_64_use_ = -1; |
599 last_bound_pos_ = 0; | 599 last_bound_pos_ = 0; |
600 ClearRecordedAstId(); | 600 ClearRecordedAstId(); |
| 601 if (CpuFeatures::IsSupported(VFP32DREGS)) { |
| 602 // Register objects tend to be abstracted and survive between scopes, so |
| 603 // it's awkward to use CpuFeatures::VFP32DREGS with CpuFeatureScope. To make |
| 604 // its use consistent with other features, we always enable it if we can. |
| 605 EnableCpuFeature(VFP32DREGS); |
| 606 } |
601 } | 607 } |
602 | 608 |
603 | 609 |
604 Assembler::~Assembler() { | 610 Assembler::~Assembler() { |
605 DCHECK(const_pool_blocked_nesting_ == 0); | 611 DCHECK(const_pool_blocked_nesting_ == 0); |
606 } | 612 } |
607 | 613 |
608 | 614 |
609 void Assembler::GetCode(CodeDesc* desc) { | 615 void Assembler::GetCode(CodeDesc* desc) { |
610 // Emit constant pool if necessary. | 616 // Emit constant pool if necessary. |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
970 CodePatcher::DONT_FLUSH); | 976 CodePatcher::DONT_FLUSH); |
971 patcher.masm()->mov(dst, Operand(target24)); | 977 patcher.masm()->mov(dst, Operand(target24)); |
972 } else { | 978 } else { |
973 uint16_t target16_0 = target24 & kImm16Mask; | 979 uint16_t target16_0 = target24 & kImm16Mask; |
974 uint16_t target16_1 = target24 >> 16; | 980 uint16_t target16_1 = target24 >> 16; |
975 if (CpuFeatures::IsSupported(ARMv7)) { | 981 if (CpuFeatures::IsSupported(ARMv7)) { |
976 // Patch with movw/movt. | 982 // Patch with movw/movt. |
977 if (target16_1 == 0) { | 983 if (target16_1 == 0) { |
978 CodePatcher patcher(isolate(), reinterpret_cast<byte*>(buffer_ + pos), | 984 CodePatcher patcher(isolate(), reinterpret_cast<byte*>(buffer_ + pos), |
979 1, CodePatcher::DONT_FLUSH); | 985 1, CodePatcher::DONT_FLUSH); |
| 986 CpuFeatureScope scope(patcher.masm(), ARMv7); |
980 patcher.masm()->movw(dst, target16_0); | 987 patcher.masm()->movw(dst, target16_0); |
981 } else { | 988 } else { |
982 CodePatcher patcher(isolate(), reinterpret_cast<byte*>(buffer_ + pos), | 989 CodePatcher patcher(isolate(), reinterpret_cast<byte*>(buffer_ + pos), |
983 2, CodePatcher::DONT_FLUSH); | 990 2, CodePatcher::DONT_FLUSH); |
| 991 CpuFeatureScope scope(patcher.masm(), ARMv7); |
984 patcher.masm()->movw(dst, target16_0); | 992 patcher.masm()->movw(dst, target16_0); |
985 patcher.masm()->movt(dst, target16_1); | 993 patcher.masm()->movt(dst, target16_1); |
986 } | 994 } |
987 } else { | 995 } else { |
988 // Patch with a sequence of mov/orr/orr instructions. | 996 // Patch with a sequence of mov/orr/orr instructions. |
989 uint8_t target8_0 = target16_0 & kImm8Mask; | 997 uint8_t target8_0 = target16_0 & kImm8Mask; |
990 uint8_t target8_1 = target16_0 >> 8; | 998 uint8_t target8_1 = target16_0 >> 8; |
991 uint8_t target8_2 = target16_1 & kImm8Mask; | 999 uint8_t target8_2 = target16_1 & kImm8Mask; |
992 if (target8_2 == 0) { | 1000 if (target8_2 == 0) { |
993 CodePatcher patcher(isolate(), reinterpret_cast<byte*>(buffer_ + pos), | 1001 CodePatcher patcher(isolate(), reinterpret_cast<byte*>(buffer_ + pos), |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1250 const Operand& x, | 1258 const Operand& x, |
1251 Condition cond) { | 1259 Condition cond) { |
1252 uint32_t imm32 = static_cast<uint32_t>(x.imm32_); | 1260 uint32_t imm32 = static_cast<uint32_t>(x.imm32_); |
1253 if (x.must_output_reloc_info(this)) { | 1261 if (x.must_output_reloc_info(this)) { |
1254 RecordRelocInfo(x.rmode_); | 1262 RecordRelocInfo(x.rmode_); |
1255 } | 1263 } |
1256 | 1264 |
1257 if (use_mov_immediate_load(x, this)) { | 1265 if (use_mov_immediate_load(x, this)) { |
1258 Register target = rd.code() == pc.code() ? ip : rd; | 1266 Register target = rd.code() == pc.code() ? ip : rd; |
1259 if (CpuFeatures::IsSupported(ARMv7)) { | 1267 if (CpuFeatures::IsSupported(ARMv7)) { |
| 1268 CpuFeatureScope scope(this, ARMv7); |
1260 if (!FLAG_enable_embedded_constant_pool && | 1269 if (!FLAG_enable_embedded_constant_pool && |
1261 x.must_output_reloc_info(this)) { | 1270 x.must_output_reloc_info(this)) { |
1262 // Make sure the movw/movt doesn't get separated. | 1271 // Make sure the movw/movt doesn't get separated. |
1263 BlockConstPoolFor(2); | 1272 BlockConstPoolFor(2); |
1264 } | 1273 } |
1265 movw(target, imm32 & 0xffff, cond); | 1274 movw(target, imm32 & 0xffff, cond); |
1266 movt(target, imm32 >> 16, cond); | 1275 movt(target, imm32 >> 16, cond); |
1267 } else { | 1276 } else { |
1268 DCHECK(FLAG_enable_embedded_constant_pool); | 1277 DCHECK(FLAG_enable_embedded_constant_pool); |
1269 mov(target, Operand(imm32 & kImm8Mask), LeaveCC, cond); | 1278 mov(target, Operand(imm32 & kImm8Mask), LeaveCC, cond); |
1270 orr(target, target, Operand(imm32 & (kImm8Mask << 8)), LeaveCC, cond); | 1279 orr(target, target, Operand(imm32 & (kImm8Mask << 8)), LeaveCC, cond); |
1271 orr(target, target, Operand(imm32 & (kImm8Mask << 16)), LeaveCC, cond); | 1280 orr(target, target, Operand(imm32 & (kImm8Mask << 16)), LeaveCC, cond); |
1272 orr(target, target, Operand(imm32 & (kImm8Mask << 24)), LeaveCC, cond); | 1281 orr(target, target, Operand(imm32 & (kImm8Mask << 24)), LeaveCC, cond); |
1273 } | 1282 } |
1274 if (target.code() != rd.code()) { | 1283 if (target.code() != rd.code()) { |
1275 mov(rd, target, LeaveCC, cond); | 1284 mov(rd, target, LeaveCC, cond); |
1276 } | 1285 } |
1277 } else { | 1286 } else { |
1278 DCHECK(!FLAG_enable_embedded_constant_pool || is_constant_pool_available()); | 1287 DCHECK(!FLAG_enable_embedded_constant_pool || is_constant_pool_available()); |
1279 ConstantPoolEntry::Access access = | 1288 ConstantPoolEntry::Access access = |
1280 ConstantPoolAddEntry(pc_offset(), x.rmode_, x.imm32_); | 1289 ConstantPoolAddEntry(pc_offset(), x.rmode_, x.imm32_); |
1281 if (access == ConstantPoolEntry::OVERFLOWED) { | 1290 if (access == ConstantPoolEntry::OVERFLOWED) { |
1282 DCHECK(FLAG_enable_embedded_constant_pool); | 1291 DCHECK(FLAG_enable_embedded_constant_pool); |
1283 Register target = rd.code() == pc.code() ? ip : rd; | 1292 Register target = rd.code() == pc.code() ? ip : rd; |
1284 // Emit instructions to load constant pool offset. | 1293 // Emit instructions to load constant pool offset. |
1285 if (CpuFeatures::IsSupported(ARMv7)) { | 1294 if (CpuFeatures::IsSupported(ARMv7)) { |
| 1295 CpuFeatureScope scope(this, ARMv7); |
1286 movw(target, 0, cond); | 1296 movw(target, 0, cond); |
1287 movt(target, 0, cond); | 1297 movt(target, 0, cond); |
1288 } else { | 1298 } else { |
1289 mov(target, Operand(0), LeaveCC, cond); | 1299 mov(target, Operand(0), LeaveCC, cond); |
1290 orr(target, target, Operand(0), LeaveCC, cond); | 1300 orr(target, target, Operand(0), LeaveCC, cond); |
1291 orr(target, target, Operand(0), LeaveCC, cond); | 1301 orr(target, target, Operand(0), LeaveCC, cond); |
1292 orr(target, target, Operand(0), LeaveCC, cond); | 1302 orr(target, target, Operand(0), LeaveCC, cond); |
1293 } | 1303 } |
1294 // Load from constant pool at offset. | 1304 // Load from constant pool at offset. |
1295 ldr(rd, MemOperand(pp, target), cond); | 1305 ldr(rd, MemOperand(pp, target), cond); |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1486 } | 1496 } |
1487 | 1497 |
1488 | 1498 |
1489 void Assembler::bl(int branch_offset, Condition cond) { | 1499 void Assembler::bl(int branch_offset, Condition cond) { |
1490 DCHECK((branch_offset & 3) == 0); | 1500 DCHECK((branch_offset & 3) == 0); |
1491 int imm24 = branch_offset >> 2; | 1501 int imm24 = branch_offset >> 2; |
1492 CHECK(is_int24(imm24)); | 1502 CHECK(is_int24(imm24)); |
1493 emit(cond | B27 | B25 | B24 | (imm24 & kImm24Mask)); | 1503 emit(cond | B27 | B25 | B24 | (imm24 & kImm24Mask)); |
1494 } | 1504 } |
1495 | 1505 |
1496 | 1506 void Assembler::blx(int branch_offset) { |
1497 void Assembler::blx(int branch_offset) { // v5 and above | |
1498 DCHECK((branch_offset & 1) == 0); | 1507 DCHECK((branch_offset & 1) == 0); |
1499 int h = ((branch_offset & 2) >> 1)*B24; | 1508 int h = ((branch_offset & 2) >> 1)*B24; |
1500 int imm24 = branch_offset >> 2; | 1509 int imm24 = branch_offset >> 2; |
1501 CHECK(is_int24(imm24)); | 1510 CHECK(is_int24(imm24)); |
1502 emit(kSpecialCondition | B27 | B25 | h | (imm24 & kImm24Mask)); | 1511 emit(kSpecialCondition | B27 | B25 | h | (imm24 & kImm24Mask)); |
1503 } | 1512 } |
1504 | 1513 |
1505 | 1514 void Assembler::blx(Register target, Condition cond) { |
1506 void Assembler::blx(Register target, Condition cond) { // v5 and above | |
1507 DCHECK(!target.is(pc)); | 1515 DCHECK(!target.is(pc)); |
1508 emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BLX | target.code()); | 1516 emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BLX | target.code()); |
1509 } | 1517 } |
1510 | 1518 |
1511 | 1519 void Assembler::bx(Register target, Condition cond) { |
1512 void Assembler::bx(Register target, Condition cond) { // v5 and above, plus v4t | |
1513 DCHECK(!target.is(pc)); // use of pc is actually allowed, but discouraged | 1520 DCHECK(!target.is(pc)); // use of pc is actually allowed, but discouraged |
1514 emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BX | target.code()); | 1521 emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BX | target.code()); |
1515 } | 1522 } |
1516 | 1523 |
1517 | 1524 |
1518 void Assembler::b(Label* L, Condition cond) { | 1525 void Assembler::b(Label* L, Condition cond) { |
1519 CheckBuffer(); | 1526 CheckBuffer(); |
1520 b(branch_offset(L), cond); | 1527 b(branch_offset(L), cond); |
1521 } | 1528 } |
1522 | 1529 |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1658 emit(link); | 1665 emit(link); |
1659 nop(dst.code()); | 1666 nop(dst.code()); |
1660 if (!CpuFeatures::IsSupported(ARMv7)) { | 1667 if (!CpuFeatures::IsSupported(ARMv7)) { |
1661 nop(dst.code()); | 1668 nop(dst.code()); |
1662 } | 1669 } |
1663 } | 1670 } |
1664 } | 1671 } |
1665 | 1672 |
1666 | 1673 |
1667 void Assembler::movw(Register reg, uint32_t immediate, Condition cond) { | 1674 void Assembler::movw(Register reg, uint32_t immediate, Condition cond) { |
1668 DCHECK(CpuFeatures::IsSupported(ARMv7)); | 1675 DCHECK(IsEnabled(ARMv7)); |
1669 emit(cond | 0x30*B20 | reg.code()*B12 | EncodeMovwImmediate(immediate)); | 1676 emit(cond | 0x30*B20 | reg.code()*B12 | EncodeMovwImmediate(immediate)); |
1670 } | 1677 } |
1671 | 1678 |
1672 | 1679 |
1673 void Assembler::movt(Register reg, uint32_t immediate, Condition cond) { | 1680 void Assembler::movt(Register reg, uint32_t immediate, Condition cond) { |
1674 DCHECK(CpuFeatures::IsSupported(ARMv7)); | 1681 DCHECK(IsEnabled(ARMv7)); |
1675 emit(cond | 0x34*B20 | reg.code()*B12 | EncodeMovwImmediate(immediate)); | 1682 emit(cond | 0x34*B20 | reg.code()*B12 | EncodeMovwImmediate(immediate)); |
1676 } | 1683 } |
1677 | 1684 |
1678 | 1685 |
1679 void Assembler::bic(Register dst, Register src1, const Operand& src2, | 1686 void Assembler::bic(Register dst, Register src1, const Operand& src2, |
1680 SBit s, Condition cond) { | 1687 SBit s, Condition cond) { |
1681 addrmod1(cond | BIC | s, src1, dst, src2); | 1688 addrmod1(cond | BIC | s, src1, dst, src2); |
1682 } | 1689 } |
1683 | 1690 |
1684 | 1691 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1794 Condition cond) { | 1801 Condition cond) { |
1795 DCHECK(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc)); | 1802 DCHECK(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc)); |
1796 DCHECK(!dstL.is(dstH)); | 1803 DCHECK(!dstL.is(dstH)); |
1797 emit(cond | B23 | s | dstH.code()*B16 | dstL.code()*B12 | | 1804 emit(cond | B23 | s | dstH.code()*B16 | dstL.code()*B12 | |
1798 src2.code()*B8 | B7 | B4 | src1.code()); | 1805 src2.code()*B8 | B7 | B4 | src1.code()); |
1799 } | 1806 } |
1800 | 1807 |
1801 | 1808 |
1802 // Miscellaneous arithmetic instructions. | 1809 // Miscellaneous arithmetic instructions. |
1803 void Assembler::clz(Register dst, Register src, Condition cond) { | 1810 void Assembler::clz(Register dst, Register src, Condition cond) { |
1804 // v5 and above. | |
1805 DCHECK(!dst.is(pc) && !src.is(pc)); | 1811 DCHECK(!dst.is(pc) && !src.is(pc)); |
1806 emit(cond | B24 | B22 | B21 | 15*B16 | dst.code()*B12 | | 1812 emit(cond | B24 | B22 | B21 | 15*B16 | dst.code()*B12 | |
1807 15*B8 | CLZ | src.code()); | 1813 15*B8 | CLZ | src.code()); |
1808 } | 1814 } |
1809 | 1815 |
1810 | 1816 |
1811 // Saturating instructions. | 1817 // Saturating instructions. |
1812 | 1818 |
1813 // Unsigned saturate. | 1819 // Unsigned saturate. |
1814 void Assembler::usat(Register dst, | 1820 void Assembler::usat(Register dst, |
(...skipping 19 matching lines...) Expand all Loading... |
1834 | 1840 |
1835 // Unsigned bit field extract. | 1841 // Unsigned bit field extract. |
1836 // Extracts #width adjacent bits from position #lsb in a register, and | 1842 // Extracts #width adjacent bits from position #lsb in a register, and |
1837 // writes them to the low bits of a destination register. | 1843 // writes them to the low bits of a destination register. |
1838 // ubfx dst, src, #lsb, #width | 1844 // ubfx dst, src, #lsb, #width |
1839 void Assembler::ubfx(Register dst, | 1845 void Assembler::ubfx(Register dst, |
1840 Register src, | 1846 Register src, |
1841 int lsb, | 1847 int lsb, |
1842 int width, | 1848 int width, |
1843 Condition cond) { | 1849 Condition cond) { |
1844 // v7 and above. | 1850 DCHECK(IsEnabled(ARMv7)); |
1845 DCHECK(CpuFeatures::IsSupported(ARMv7)); | |
1846 DCHECK(!dst.is(pc) && !src.is(pc)); | 1851 DCHECK(!dst.is(pc) && !src.is(pc)); |
1847 DCHECK((lsb >= 0) && (lsb <= 31)); | 1852 DCHECK((lsb >= 0) && (lsb <= 31)); |
1848 DCHECK((width >= 1) && (width <= (32 - lsb))); | 1853 DCHECK((width >= 1) && (width <= (32 - lsb))); |
1849 emit(cond | 0xf*B23 | B22 | B21 | (width - 1)*B16 | dst.code()*B12 | | 1854 emit(cond | 0xf*B23 | B22 | B21 | (width - 1)*B16 | dst.code()*B12 | |
1850 lsb*B7 | B6 | B4 | src.code()); | 1855 lsb*B7 | B6 | B4 | src.code()); |
1851 } | 1856 } |
1852 | 1857 |
1853 | 1858 |
1854 // Signed bit field extract. | 1859 // Signed bit field extract. |
1855 // Extracts #width adjacent bits from position #lsb in a register, and | 1860 // Extracts #width adjacent bits from position #lsb in a register, and |
1856 // writes them to the low bits of a destination register. The extracted | 1861 // writes them to the low bits of a destination register. The extracted |
1857 // value is sign extended to fill the destination register. | 1862 // value is sign extended to fill the destination register. |
1858 // sbfx dst, src, #lsb, #width | 1863 // sbfx dst, src, #lsb, #width |
1859 void Assembler::sbfx(Register dst, | 1864 void Assembler::sbfx(Register dst, |
1860 Register src, | 1865 Register src, |
1861 int lsb, | 1866 int lsb, |
1862 int width, | 1867 int width, |
1863 Condition cond) { | 1868 Condition cond) { |
1864 // v7 and above. | 1869 DCHECK(IsEnabled(ARMv7)); |
1865 DCHECK(CpuFeatures::IsSupported(ARMv7)); | |
1866 DCHECK(!dst.is(pc) && !src.is(pc)); | 1870 DCHECK(!dst.is(pc) && !src.is(pc)); |
1867 DCHECK((lsb >= 0) && (lsb <= 31)); | 1871 DCHECK((lsb >= 0) && (lsb <= 31)); |
1868 DCHECK((width >= 1) && (width <= (32 - lsb))); | 1872 DCHECK((width >= 1) && (width <= (32 - lsb))); |
1869 emit(cond | 0xf*B23 | B21 | (width - 1)*B16 | dst.code()*B12 | | 1873 emit(cond | 0xf*B23 | B21 | (width - 1)*B16 | dst.code()*B12 | |
1870 lsb*B7 | B6 | B4 | src.code()); | 1874 lsb*B7 | B6 | B4 | src.code()); |
1871 } | 1875 } |
1872 | 1876 |
1873 | 1877 |
1874 // Bit field clear. | 1878 // Bit field clear. |
1875 // Sets #width adjacent bits at position #lsb in the destination register | 1879 // Sets #width adjacent bits at position #lsb in the destination register |
1876 // to zero, preserving the value of the other bits. | 1880 // to zero, preserving the value of the other bits. |
1877 // bfc dst, #lsb, #width | 1881 // bfc dst, #lsb, #width |
1878 void Assembler::bfc(Register dst, int lsb, int width, Condition cond) { | 1882 void Assembler::bfc(Register dst, int lsb, int width, Condition cond) { |
1879 // v7 and above. | 1883 DCHECK(IsEnabled(ARMv7)); |
1880 DCHECK(CpuFeatures::IsSupported(ARMv7)); | |
1881 DCHECK(!dst.is(pc)); | 1884 DCHECK(!dst.is(pc)); |
1882 DCHECK((lsb >= 0) && (lsb <= 31)); | 1885 DCHECK((lsb >= 0) && (lsb <= 31)); |
1883 DCHECK((width >= 1) && (width <= (32 - lsb))); | 1886 DCHECK((width >= 1) && (width <= (32 - lsb))); |
1884 int msb = lsb + width - 1; | 1887 int msb = lsb + width - 1; |
1885 emit(cond | 0x1f*B22 | msb*B16 | dst.code()*B12 | lsb*B7 | B4 | 0xf); | 1888 emit(cond | 0x1f*B22 | msb*B16 | dst.code()*B12 | lsb*B7 | B4 | 0xf); |
1886 } | 1889 } |
1887 | 1890 |
1888 | 1891 |
1889 // Bit field insert. | 1892 // Bit field insert. |
1890 // Inserts #width adjacent bits from the low bits of the source register | 1893 // Inserts #width adjacent bits from the low bits of the source register |
1891 // into position #lsb of the destination register. | 1894 // into position #lsb of the destination register. |
1892 // bfi dst, src, #lsb, #width | 1895 // bfi dst, src, #lsb, #width |
1893 void Assembler::bfi(Register dst, | 1896 void Assembler::bfi(Register dst, |
1894 Register src, | 1897 Register src, |
1895 int lsb, | 1898 int lsb, |
1896 int width, | 1899 int width, |
1897 Condition cond) { | 1900 Condition cond) { |
1898 // v7 and above. | 1901 DCHECK(IsEnabled(ARMv7)); |
1899 DCHECK(CpuFeatures::IsSupported(ARMv7)); | |
1900 DCHECK(!dst.is(pc) && !src.is(pc)); | 1902 DCHECK(!dst.is(pc) && !src.is(pc)); |
1901 DCHECK((lsb >= 0) && (lsb <= 31)); | 1903 DCHECK((lsb >= 0) && (lsb <= 31)); |
1902 DCHECK((width >= 1) && (width <= (32 - lsb))); | 1904 DCHECK((width >= 1) && (width <= (32 - lsb))); |
1903 int msb = lsb + width - 1; | 1905 int msb = lsb + width - 1; |
1904 emit(cond | 0x1f*B22 | msb*B16 | dst.code()*B12 | lsb*B7 | B4 | | 1906 emit(cond | 0x1f*B22 | msb*B16 | dst.code()*B12 | lsb*B7 | B4 | |
1905 src.code()); | 1907 src.code()); |
1906 } | 1908 } |
1907 | 1909 |
1908 | 1910 |
1909 void Assembler::pkhbt(Register dst, | 1911 void Assembler::pkhbt(Register dst, |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2286 Label skip; | 2288 Label skip; |
2287 b(&skip, NegateCondition(cond)); | 2289 b(&skip, NegateCondition(cond)); |
2288 bkpt(0); | 2290 bkpt(0); |
2289 bind(&skip); | 2291 bind(&skip); |
2290 } else { | 2292 } else { |
2291 bkpt(0); | 2293 bkpt(0); |
2292 } | 2294 } |
2293 #endif // def __arm__ | 2295 #endif // def __arm__ |
2294 } | 2296 } |
2295 | 2297 |
2296 | 2298 void Assembler::bkpt(uint32_t imm16) { |
2297 void Assembler::bkpt(uint32_t imm16) { // v5 and above | |
2298 DCHECK(is_uint16(imm16)); | 2299 DCHECK(is_uint16(imm16)); |
2299 emit(al | B24 | B21 | (imm16 >> 4)*B8 | BKPT | (imm16 & 0xf)); | 2300 emit(al | B24 | B21 | (imm16 >> 4)*B8 | BKPT | (imm16 & 0xf)); |
2300 } | 2301 } |
2301 | 2302 |
2302 | 2303 |
2303 void Assembler::svc(uint32_t imm24, Condition cond) { | 2304 void Assembler::svc(uint32_t imm24, Condition cond) { |
2304 DCHECK(is_uint24(imm24)); | 2305 DCHECK(is_uint24(imm24)); |
2305 emit(cond | 15*B24 | imm24); | 2306 emit(cond | 15*B24 | imm24); |
2306 } | 2307 } |
2307 | 2308 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2348 CRegister crd, | 2349 CRegister crd, |
2349 CRegister crn, | 2350 CRegister crn, |
2350 CRegister crm, | 2351 CRegister crm, |
2351 int opcode_2, | 2352 int opcode_2, |
2352 Condition cond) { | 2353 Condition cond) { |
2353 DCHECK(is_uint4(opcode_1) && is_uint3(opcode_2)); | 2354 DCHECK(is_uint4(opcode_1) && is_uint3(opcode_2)); |
2354 emit(cond | B27 | B26 | B25 | (opcode_1 & 15)*B20 | crn.code()*B16 | | 2355 emit(cond | B27 | B26 | B25 | (opcode_1 & 15)*B20 | crn.code()*B16 | |
2355 crd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | crm.code()); | 2356 crd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | crm.code()); |
2356 } | 2357 } |
2357 | 2358 |
2358 | 2359 void Assembler::cdp2(Coprocessor coproc, int opcode_1, CRegister crd, |
2359 void Assembler::cdp2(Coprocessor coproc, | 2360 CRegister crn, CRegister crm, int opcode_2) { |
2360 int opcode_1, | |
2361 CRegister crd, | |
2362 CRegister crn, | |
2363 CRegister crm, | |
2364 int opcode_2) { // v5 and above | |
2365 cdp(coproc, opcode_1, crd, crn, crm, opcode_2, kSpecialCondition); | 2361 cdp(coproc, opcode_1, crd, crn, crm, opcode_2, kSpecialCondition); |
2366 } | 2362 } |
2367 | 2363 |
2368 | 2364 |
2369 void Assembler::mcr(Coprocessor coproc, | 2365 void Assembler::mcr(Coprocessor coproc, |
2370 int opcode_1, | 2366 int opcode_1, |
2371 Register rd, | 2367 Register rd, |
2372 CRegister crn, | 2368 CRegister crn, |
2373 CRegister crm, | 2369 CRegister crm, |
2374 int opcode_2, | 2370 int opcode_2, |
2375 Condition cond) { | 2371 Condition cond) { |
2376 DCHECK(is_uint3(opcode_1) && is_uint3(opcode_2)); | 2372 DCHECK(is_uint3(opcode_1) && is_uint3(opcode_2)); |
2377 emit(cond | B27 | B26 | B25 | (opcode_1 & 7)*B21 | crn.code()*B16 | | 2373 emit(cond | B27 | B26 | B25 | (opcode_1 & 7)*B21 | crn.code()*B16 | |
2378 rd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | B4 | crm.code()); | 2374 rd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | B4 | crm.code()); |
2379 } | 2375 } |
2380 | 2376 |
2381 | 2377 void Assembler::mcr2(Coprocessor coproc, int opcode_1, Register rd, |
2382 void Assembler::mcr2(Coprocessor coproc, | 2378 CRegister crn, CRegister crm, int opcode_2) { |
2383 int opcode_1, | |
2384 Register rd, | |
2385 CRegister crn, | |
2386 CRegister crm, | |
2387 int opcode_2) { // v5 and above | |
2388 mcr(coproc, opcode_1, rd, crn, crm, opcode_2, kSpecialCondition); | 2379 mcr(coproc, opcode_1, rd, crn, crm, opcode_2, kSpecialCondition); |
2389 } | 2380 } |
2390 | 2381 |
2391 | 2382 |
2392 void Assembler::mrc(Coprocessor coproc, | 2383 void Assembler::mrc(Coprocessor coproc, |
2393 int opcode_1, | 2384 int opcode_1, |
2394 Register rd, | 2385 Register rd, |
2395 CRegister crn, | 2386 CRegister crn, |
2396 CRegister crm, | 2387 CRegister crm, |
2397 int opcode_2, | 2388 int opcode_2, |
2398 Condition cond) { | 2389 Condition cond) { |
2399 DCHECK(is_uint3(opcode_1) && is_uint3(opcode_2)); | 2390 DCHECK(is_uint3(opcode_1) && is_uint3(opcode_2)); |
2400 emit(cond | B27 | B26 | B25 | (opcode_1 & 7)*B21 | L | crn.code()*B16 | | 2391 emit(cond | B27 | B26 | B25 | (opcode_1 & 7)*B21 | L | crn.code()*B16 | |
2401 rd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | B4 | crm.code()); | 2392 rd.code()*B12 | coproc*B8 | (opcode_2 & 7)*B5 | B4 | crm.code()); |
2402 } | 2393 } |
2403 | 2394 |
2404 | 2395 void Assembler::mrc2(Coprocessor coproc, int opcode_1, Register rd, |
2405 void Assembler::mrc2(Coprocessor coproc, | 2396 CRegister crn, CRegister crm, int opcode_2) { |
2406 int opcode_1, | |
2407 Register rd, | |
2408 CRegister crn, | |
2409 CRegister crm, | |
2410 int opcode_2) { // v5 and above | |
2411 mrc(coproc, opcode_1, rd, crn, crm, opcode_2, kSpecialCondition); | 2397 mrc(coproc, opcode_1, rd, crn, crm, opcode_2, kSpecialCondition); |
2412 } | 2398 } |
2413 | 2399 |
2414 | 2400 |
2415 void Assembler::ldc(Coprocessor coproc, | 2401 void Assembler::ldc(Coprocessor coproc, |
2416 CRegister crd, | 2402 CRegister crd, |
2417 const MemOperand& src, | 2403 const MemOperand& src, |
2418 LFlag l, | 2404 LFlag l, |
2419 Condition cond) { | 2405 Condition cond) { |
2420 addrmod5(cond | B27 | B26 | l | L | coproc*B8, crd, src); | 2406 addrmod5(cond | B27 | B26 | l | L | coproc*B8, crd, src); |
2421 } | 2407 } |
2422 | 2408 |
2423 | 2409 |
2424 void Assembler::ldc(Coprocessor coproc, | 2410 void Assembler::ldc(Coprocessor coproc, |
2425 CRegister crd, | 2411 CRegister crd, |
2426 Register rn, | 2412 Register rn, |
2427 int option, | 2413 int option, |
2428 LFlag l, | 2414 LFlag l, |
2429 Condition cond) { | 2415 Condition cond) { |
2430 // Unindexed addressing. | 2416 // Unindexed addressing. |
2431 DCHECK(is_uint8(option)); | 2417 DCHECK(is_uint8(option)); |
2432 emit(cond | B27 | B26 | U | l | L | rn.code()*B16 | crd.code()*B12 | | 2418 emit(cond | B27 | B26 | U | l | L | rn.code()*B16 | crd.code()*B12 | |
2433 coproc*B8 | (option & 255)); | 2419 coproc*B8 | (option & 255)); |
2434 } | 2420 } |
2435 | 2421 |
2436 | 2422 void Assembler::ldc2(Coprocessor coproc, CRegister crd, const MemOperand& src, |
2437 void Assembler::ldc2(Coprocessor coproc, | 2423 LFlag l) { |
2438 CRegister crd, | |
2439 const MemOperand& src, | |
2440 LFlag l) { // v5 and above | |
2441 ldc(coproc, crd, src, l, kSpecialCondition); | 2424 ldc(coproc, crd, src, l, kSpecialCondition); |
2442 } | 2425 } |
2443 | 2426 |
2444 | 2427 void Assembler::ldc2(Coprocessor coproc, CRegister crd, Register rn, int option, |
2445 void Assembler::ldc2(Coprocessor coproc, | 2428 LFlag l) { |
2446 CRegister crd, | |
2447 Register rn, | |
2448 int option, | |
2449 LFlag l) { // v5 and above | |
2450 ldc(coproc, crd, rn, option, l, kSpecialCondition); | 2429 ldc(coproc, crd, rn, option, l, kSpecialCondition); |
2451 } | 2430 } |
2452 | 2431 |
2453 | 2432 |
2454 // Support for VFP. | 2433 // Support for VFP. |
2455 | 2434 |
2456 void Assembler::vldr(const DwVfpRegister dst, | 2435 void Assembler::vldr(const DwVfpRegister dst, |
2457 const Register base, | 2436 const Register base, |
2458 int offset, | 2437 int offset, |
2459 const Condition cond) { | 2438 const Condition cond) { |
2460 // Ddst = MEM(Rbase + offset). | 2439 // Ddst = MEM(Rbase + offset). |
2461 // Instruction details available in ARM DDI 0406C.b, A8-924. | 2440 // Instruction details available in ARM DDI 0406C.b, A8-924. |
2462 // cond(31-28) | 1101(27-24)| U(23) | D(22) | 01(21-20) | Rbase(19-16) | | 2441 // cond(31-28) | 1101(27-24)| U(23) | D(22) | 01(21-20) | Rbase(19-16) | |
2463 // Vd(15-12) | 1011(11-8) | offset | 2442 // Vd(15-12) | 1011(11-8) | offset |
| 2443 DCHECK(VfpRegisterIsAvailable(dst)); |
2464 int u = 1; | 2444 int u = 1; |
2465 if (offset < 0) { | 2445 if (offset < 0) { |
2466 CHECK(offset != kMinInt); | 2446 CHECK(offset != kMinInt); |
2467 offset = -offset; | 2447 offset = -offset; |
2468 u = 0; | 2448 u = 0; |
2469 } | 2449 } |
2470 int vd, d; | 2450 int vd, d; |
2471 dst.split_code(&vd, &d); | 2451 dst.split_code(&vd, &d); |
2472 | 2452 |
2473 DCHECK(offset >= 0); | 2453 DCHECK(offset >= 0); |
(...skipping 10 matching lines...) Expand all Loading... |
2484 sub(ip, base, Operand(offset)); | 2464 sub(ip, base, Operand(offset)); |
2485 } | 2465 } |
2486 emit(cond | 0xD*B24 | d*B22 | B20 | ip.code()*B16 | vd*B12 | 0xB*B8); | 2466 emit(cond | 0xD*B24 | d*B22 | B20 | ip.code()*B16 | vd*B12 | 0xB*B8); |
2487 } | 2467 } |
2488 } | 2468 } |
2489 | 2469 |
2490 | 2470 |
2491 void Assembler::vldr(const DwVfpRegister dst, | 2471 void Assembler::vldr(const DwVfpRegister dst, |
2492 const MemOperand& operand, | 2472 const MemOperand& operand, |
2493 const Condition cond) { | 2473 const Condition cond) { |
| 2474 DCHECK(VfpRegisterIsAvailable(dst)); |
2494 DCHECK(operand.am_ == Offset); | 2475 DCHECK(operand.am_ == Offset); |
2495 if (operand.rm().is_valid()) { | 2476 if (operand.rm().is_valid()) { |
2496 add(ip, operand.rn(), | 2477 add(ip, operand.rn(), |
2497 Operand(operand.rm(), operand.shift_op_, operand.shift_imm_)); | 2478 Operand(operand.rm(), operand.shift_op_, operand.shift_imm_)); |
2498 vldr(dst, ip, 0, cond); | 2479 vldr(dst, ip, 0, cond); |
2499 } else { | 2480 } else { |
2500 vldr(dst, operand.rn(), operand.offset(), cond); | 2481 vldr(dst, operand.rn(), operand.offset(), cond); |
2501 } | 2482 } |
2502 } | 2483 } |
2503 | 2484 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2551 | 2532 |
2552 | 2533 |
2553 void Assembler::vstr(const DwVfpRegister src, | 2534 void Assembler::vstr(const DwVfpRegister src, |
2554 const Register base, | 2535 const Register base, |
2555 int offset, | 2536 int offset, |
2556 const Condition cond) { | 2537 const Condition cond) { |
2557 // MEM(Rbase + offset) = Dsrc. | 2538 // MEM(Rbase + offset) = Dsrc. |
2558 // Instruction details available in ARM DDI 0406C.b, A8-1082. | 2539 // Instruction details available in ARM DDI 0406C.b, A8-1082. |
2559 // cond(31-28) | 1101(27-24)| U(23) | D(22) | 00(21-20) | Rbase(19-16) | | 2540 // cond(31-28) | 1101(27-24)| U(23) | D(22) | 00(21-20) | Rbase(19-16) | |
2560 // Vd(15-12) | 1011(11-8) | (offset/4) | 2541 // Vd(15-12) | 1011(11-8) | (offset/4) |
| 2542 DCHECK(VfpRegisterIsAvailable(src)); |
2561 int u = 1; | 2543 int u = 1; |
2562 if (offset < 0) { | 2544 if (offset < 0) { |
2563 CHECK(offset != kMinInt); | 2545 CHECK(offset != kMinInt); |
2564 offset = -offset; | 2546 offset = -offset; |
2565 u = 0; | 2547 u = 0; |
2566 } | 2548 } |
2567 DCHECK(offset >= 0); | 2549 DCHECK(offset >= 0); |
2568 int vd, d; | 2550 int vd, d; |
2569 src.split_code(&vd, &d); | 2551 src.split_code(&vd, &d); |
2570 | 2552 |
(...skipping 10 matching lines...) Expand all Loading... |
2581 sub(ip, base, Operand(offset)); | 2563 sub(ip, base, Operand(offset)); |
2582 } | 2564 } |
2583 emit(cond | 0xD*B24 | d*B22 | ip.code()*B16 | vd*B12 | 0xB*B8); | 2565 emit(cond | 0xD*B24 | d*B22 | ip.code()*B16 | vd*B12 | 0xB*B8); |
2584 } | 2566 } |
2585 } | 2567 } |
2586 | 2568 |
2587 | 2569 |
2588 void Assembler::vstr(const DwVfpRegister src, | 2570 void Assembler::vstr(const DwVfpRegister src, |
2589 const MemOperand& operand, | 2571 const MemOperand& operand, |
2590 const Condition cond) { | 2572 const Condition cond) { |
| 2573 DCHECK(VfpRegisterIsAvailable(src)); |
2591 DCHECK(operand.am_ == Offset); | 2574 DCHECK(operand.am_ == Offset); |
2592 if (operand.rm().is_valid()) { | 2575 if (operand.rm().is_valid()) { |
2593 add(ip, operand.rn(), | 2576 add(ip, operand.rn(), |
2594 Operand(operand.rm(), operand.shift_op_, operand.shift_imm_)); | 2577 Operand(operand.rm(), operand.shift_op_, operand.shift_imm_)); |
2595 vstr(src, ip, 0, cond); | 2578 vstr(src, ip, 0, cond); |
2596 } else { | 2579 } else { |
2597 vstr(src, operand.rn(), operand.offset(), cond); | 2580 vstr(src, operand.rn(), operand.offset(), cond); |
2598 } | 2581 } |
2599 } | 2582 } |
2600 | 2583 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2639 DCHECK(operand.am_ == Offset); | 2622 DCHECK(operand.am_ == Offset); |
2640 if (operand.rm().is_valid()) { | 2623 if (operand.rm().is_valid()) { |
2641 add(ip, operand.rn(), | 2624 add(ip, operand.rn(), |
2642 Operand(operand.rm(), operand.shift_op_, operand.shift_imm_)); | 2625 Operand(operand.rm(), operand.shift_op_, operand.shift_imm_)); |
2643 vstr(src, ip, 0, cond); | 2626 vstr(src, ip, 0, cond); |
2644 } else { | 2627 } else { |
2645 vstr(src, operand.rn(), operand.offset(), cond); | 2628 vstr(src, operand.rn(), operand.offset(), cond); |
2646 } | 2629 } |
2647 } | 2630 } |
2648 | 2631 |
2649 | 2632 void Assembler::vldm(BlockAddrMode am, Register base, DwVfpRegister first, |
2650 void Assembler::vldm(BlockAddrMode am, | 2633 DwVfpRegister last, Condition cond) { |
2651 Register base, | |
2652 DwVfpRegister first, | |
2653 DwVfpRegister last, | |
2654 Condition cond) { | |
2655 // Instruction details available in ARM DDI 0406C.b, A8-922. | 2634 // Instruction details available in ARM DDI 0406C.b, A8-922. |
2656 // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) | | 2635 // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) | |
2657 // first(15-12) | 1011(11-8) | (count * 2) | 2636 // first(15-12) | 1011(11-8) | (count * 2) |
2658 DCHECK_LE(first.code(), last.code()); | 2637 DCHECK_LE(first.code(), last.code()); |
| 2638 DCHECK(VfpRegisterIsAvailable(last)); |
2659 DCHECK(am == ia || am == ia_w || am == db_w); | 2639 DCHECK(am == ia || am == ia_w || am == db_w); |
2660 DCHECK(!base.is(pc)); | 2640 DCHECK(!base.is(pc)); |
2661 | 2641 |
2662 int sd, d; | 2642 int sd, d; |
2663 first.split_code(&sd, &d); | 2643 first.split_code(&sd, &d); |
2664 int count = last.code() - first.code() + 1; | 2644 int count = last.code() - first.code() + 1; |
2665 DCHECK(count <= 16); | 2645 DCHECK(count <= 16); |
2666 emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 | | 2646 emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 | |
2667 0xB*B8 | count*2); | 2647 0xB*B8 | count*2); |
2668 } | 2648 } |
2669 | 2649 |
2670 | 2650 void Assembler::vstm(BlockAddrMode am, Register base, DwVfpRegister first, |
2671 void Assembler::vstm(BlockAddrMode am, | 2651 DwVfpRegister last, Condition cond) { |
2672 Register base, | |
2673 DwVfpRegister first, | |
2674 DwVfpRegister last, | |
2675 Condition cond) { | |
2676 // Instruction details available in ARM DDI 0406C.b, A8-1080. | 2652 // Instruction details available in ARM DDI 0406C.b, A8-1080. |
2677 // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) | | 2653 // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) | |
2678 // first(15-12) | 1011(11-8) | (count * 2) | 2654 // first(15-12) | 1011(11-8) | (count * 2) |
2679 DCHECK_LE(first.code(), last.code()); | 2655 DCHECK_LE(first.code(), last.code()); |
| 2656 DCHECK(VfpRegisterIsAvailable(last)); |
2680 DCHECK(am == ia || am == ia_w || am == db_w); | 2657 DCHECK(am == ia || am == ia_w || am == db_w); |
2681 DCHECK(!base.is(pc)); | 2658 DCHECK(!base.is(pc)); |
2682 | 2659 |
2683 int sd, d; | 2660 int sd, d; |
2684 first.split_code(&sd, &d); | 2661 first.split_code(&sd, &d); |
2685 int count = last.code() - first.code() + 1; | 2662 int count = last.code() - first.code() + 1; |
2686 DCHECK(count <= 16); | 2663 DCHECK(count <= 16); |
2687 emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 | | 2664 emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 | |
2688 0xB*B8 | count*2); | 2665 0xB*B8 | count*2); |
2689 } | 2666 } |
2690 | 2667 |
2691 void Assembler::vldm(BlockAddrMode am, | 2668 void Assembler::vldm(BlockAddrMode am, Register base, SwVfpRegister first, |
2692 Register base, | 2669 SwVfpRegister last, Condition cond) { |
2693 SwVfpRegister first, | |
2694 SwVfpRegister last, | |
2695 Condition cond) { | |
2696 // Instruction details available in ARM DDI 0406A, A8-626. | 2670 // Instruction details available in ARM DDI 0406A, A8-626. |
2697 // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) | | 2671 // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) | |
2698 // first(15-12) | 1010(11-8) | (count/2) | 2672 // first(15-12) | 1010(11-8) | (count/2) |
2699 DCHECK_LE(first.code(), last.code()); | 2673 DCHECK_LE(first.code(), last.code()); |
2700 DCHECK(am == ia || am == ia_w || am == db_w); | 2674 DCHECK(am == ia || am == ia_w || am == db_w); |
2701 DCHECK(!base.is(pc)); | 2675 DCHECK(!base.is(pc)); |
2702 | 2676 |
2703 int sd, d; | 2677 int sd, d; |
2704 first.split_code(&sd, &d); | 2678 first.split_code(&sd, &d); |
2705 int count = last.code() - first.code() + 1; | 2679 int count = last.code() - first.code() + 1; |
2706 emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 | | 2680 emit(cond | B27 | B26 | am | d*B22 | B20 | base.code()*B16 | sd*B12 | |
2707 0xA*B8 | count); | 2681 0xA*B8 | count); |
2708 } | 2682 } |
2709 | 2683 |
2710 | 2684 void Assembler::vstm(BlockAddrMode am, Register base, SwVfpRegister first, |
2711 void Assembler::vstm(BlockAddrMode am, | 2685 SwVfpRegister last, Condition cond) { |
2712 Register base, | |
2713 SwVfpRegister first, | |
2714 SwVfpRegister last, | |
2715 Condition cond) { | |
2716 // Instruction details available in ARM DDI 0406A, A8-784. | 2686 // Instruction details available in ARM DDI 0406A, A8-784. |
2717 // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) | | 2687 // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) | |
2718 // first(15-12) | 1011(11-8) | (count/2) | 2688 // first(15-12) | 1011(11-8) | (count/2) |
2719 DCHECK_LE(first.code(), last.code()); | 2689 DCHECK_LE(first.code(), last.code()); |
2720 DCHECK(am == ia || am == ia_w || am == db_w); | 2690 DCHECK(am == ia || am == ia_w || am == db_w); |
2721 DCHECK(!base.is(pc)); | 2691 DCHECK(!base.is(pc)); |
2722 | 2692 |
2723 int sd, d; | 2693 int sd, d; |
2724 first.split_code(&sd, &d); | 2694 first.split_code(&sd, &d); |
2725 int count = last.code() - first.code() + 1; | 2695 int count = last.code() - first.code() + 1; |
2726 emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 | | 2696 emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 | |
2727 0xA*B8 | count); | 2697 0xA*B8 | count); |
2728 } | 2698 } |
2729 | 2699 |
2730 | 2700 |
2731 static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) { | 2701 static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) { |
2732 uint64_t i; | 2702 uint64_t i; |
2733 memcpy(&i, &d, 8); | 2703 memcpy(&i, &d, 8); |
2734 | 2704 |
2735 *lo = i & 0xffffffff; | 2705 *lo = i & 0xffffffff; |
2736 *hi = i >> 32; | 2706 *hi = i >> 32; |
2737 } | 2707 } |
2738 | 2708 |
2739 | 2709 |
2740 // Only works for little endian floating point formats. | 2710 // Only works for little endian floating point formats. |
2741 // We don't support VFP on the mixed endian floating point platform. | 2711 // We don't support VFP on the mixed endian floating point platform. |
2742 static bool FitsVmovFPImmediate(double d, uint32_t* encoding) { | 2712 static bool FitsVmovFPImmediate(double d, uint32_t* encoding) { |
2743 DCHECK(CpuFeatures::IsSupported(VFP3)); | |
2744 | |
2745 // VMOV can accept an immediate of the form: | 2713 // VMOV can accept an immediate of the form: |
2746 // | 2714 // |
2747 // +/- m * 2^(-n) where 16 <= m <= 31 and 0 <= n <= 7 | 2715 // +/- m * 2^(-n) where 16 <= m <= 31 and 0 <= n <= 7 |
2748 // | 2716 // |
2749 // The immediate is encoded using an 8-bit quantity, comprised of two | 2717 // The immediate is encoded using an 8-bit quantity, comprised of two |
2750 // 4-bit fields. For an 8-bit immediate of the form: | 2718 // 4-bit fields. For an 8-bit immediate of the form: |
2751 // | 2719 // |
2752 // [abcdefgh] | 2720 // [abcdefgh] |
2753 // | 2721 // |
2754 // where a is the MSB and h is the LSB, an immediate 64-bit double can be | 2722 // where a is the MSB and h is the LSB, an immediate 64-bit double can be |
(...skipping 28 matching lines...) Expand all Loading... |
2783 *encoding = (hi >> 16) & 0xf; // Low nybble. | 2751 *encoding = (hi >> 16) & 0xf; // Low nybble. |
2784 *encoding |= (hi >> 4) & 0x70000; // Low three bits of the high nybble. | 2752 *encoding |= (hi >> 4) & 0x70000; // Low three bits of the high nybble. |
2785 *encoding |= (hi >> 12) & 0x80000; // Top bit of the high nybble. | 2753 *encoding |= (hi >> 12) & 0x80000; // Top bit of the high nybble. |
2786 | 2754 |
2787 return true; | 2755 return true; |
2788 } | 2756 } |
2789 | 2757 |
2790 | 2758 |
2791 void Assembler::vmov(const SwVfpRegister dst, float imm) { | 2759 void Assembler::vmov(const SwVfpRegister dst, float imm) { |
2792 uint32_t enc; | 2760 uint32_t enc; |
2793 if (CpuFeatures::IsSupported(VFP3) && FitsVmovFPImmediate(imm, &enc)) { | 2761 if (CpuFeatures::IsSupported(VFPv3) && FitsVmovFPImmediate(imm, &enc)) { |
| 2762 CpuFeatureScope scope(this, VFPv3); |
2794 // The float can be encoded in the instruction. | 2763 // The float can be encoded in the instruction. |
2795 // | 2764 // |
2796 // Sd = immediate | 2765 // Sd = immediate |
2797 // Instruction details available in ARM DDI 0406C.b, A8-936. | 2766 // Instruction details available in ARM DDI 0406C.b, A8-936. |
2798 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | imm4H(19-16) | | 2767 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | imm4H(19-16) | |
2799 // Vd(15-12) | 101(11-9) | sz=0(8) | imm4L(3-0) | 2768 // Vd(15-12) | 101(11-9) | sz=0(8) | imm4L(3-0) |
2800 int vd, d; | 2769 int vd, d; |
2801 dst.split_code(&vd, &d); | 2770 dst.split_code(&vd, &d); |
2802 emit(al | 0x1D * B23 | d * B22 | 0x3 * B20 | vd * B12 | 0x5 * B9 | enc); | 2771 emit(al | 0x1D * B23 | d * B22 | 0x3 * B20 | vd * B12 | 0x5 * B9 | enc); |
2803 } else { | 2772 } else { |
2804 mov(ip, Operand(bit_cast<int32_t>(imm))); | 2773 mov(ip, Operand(bit_cast<int32_t>(imm))); |
2805 vmov(dst, ip); | 2774 vmov(dst, ip); |
2806 } | 2775 } |
2807 } | 2776 } |
2808 | 2777 |
2809 | 2778 |
2810 void Assembler::vmov(const DwVfpRegister dst, | 2779 void Assembler::vmov(const DwVfpRegister dst, |
2811 double imm, | 2780 double imm, |
2812 const Register scratch) { | 2781 const Register scratch) { |
| 2782 DCHECK(VfpRegisterIsAvailable(dst)); |
| 2783 DCHECK(!scratch.is(ip)); |
2813 uint32_t enc; | 2784 uint32_t enc; |
2814 // If the embedded constant pool is disabled, we can use the normal, inline | 2785 // If the embedded constant pool is disabled, we can use the normal, inline |
2815 // constant pool. If the embedded constant pool is enabled (via | 2786 // constant pool. If the embedded constant pool is enabled (via |
2816 // FLAG_enable_embedded_constant_pool), we can only use it where the pool | 2787 // FLAG_enable_embedded_constant_pool), we can only use it where the pool |
2817 // pointer (pp) is valid. | 2788 // pointer (pp) is valid. |
2818 bool can_use_pool = | 2789 bool can_use_pool = |
2819 !FLAG_enable_embedded_constant_pool || is_constant_pool_available(); | 2790 !FLAG_enable_embedded_constant_pool || is_constant_pool_available(); |
2820 if (CpuFeatures::IsSupported(VFP3) && FitsVmovFPImmediate(imm, &enc)) { | 2791 if (CpuFeatures::IsSupported(VFPv3) && FitsVmovFPImmediate(imm, &enc)) { |
| 2792 CpuFeatureScope scope(this, VFPv3); |
2821 // The double can be encoded in the instruction. | 2793 // The double can be encoded in the instruction. |
2822 // | 2794 // |
2823 // Dd = immediate | 2795 // Dd = immediate |
2824 // Instruction details available in ARM DDI 0406C.b, A8-936. | 2796 // Instruction details available in ARM DDI 0406C.b, A8-936. |
2825 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | imm4H(19-16) | | 2797 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | imm4H(19-16) | |
2826 // Vd(15-12) | 101(11-9) | sz=1(8) | imm4L(3-0) | 2798 // Vd(15-12) | 101(11-9) | sz=1(8) | imm4L(3-0) |
2827 int vd, d; | 2799 int vd, d; |
2828 dst.split_code(&vd, &d); | 2800 dst.split_code(&vd, &d); |
2829 emit(al | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | enc); | 2801 emit(al | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | enc); |
2830 } else if (FLAG_enable_vldr_imm && can_use_pool) { | 2802 } else if (CpuFeatures::IsSupported(ARMv7) && FLAG_enable_vldr_imm && |
| 2803 can_use_pool) { |
| 2804 CpuFeatureScope scope(this, ARMv7); |
2831 // TODO(jfb) Temporarily turned off until we have constant blinding or | 2805 // TODO(jfb) Temporarily turned off until we have constant blinding or |
2832 // some equivalent mitigation: an attacker can otherwise control | 2806 // some equivalent mitigation: an attacker can otherwise control |
2833 // generated data which also happens to be executable, a Very Bad | 2807 // generated data which also happens to be executable, a Very Bad |
2834 // Thing indeed. | 2808 // Thing indeed. |
2835 // Blinding gets tricky because we don't have xor, we probably | 2809 // Blinding gets tricky because we don't have xor, we probably |
2836 // need to add/subtract without losing precision, which requires a | 2810 // need to add/subtract without losing precision, which requires a |
2837 // cookie value that Lithium is probably better positioned to | 2811 // cookie value that Lithium is probably better positioned to |
2838 // choose. | 2812 // choose. |
2839 // We could also add a few peepholes here like detecting 0.0 and | 2813 // We could also add a few peepholes here like detecting 0.0 and |
2840 // -0.0 and doing a vmov from the sequestered d14, forcing denorms | 2814 // -0.0 and doing a vmov from the sequestered d14, forcing denorms |
(...skipping 22 matching lines...) Expand all Loading... |
2863 if (lo == hi) { | 2837 if (lo == hi) { |
2864 // Move the low and high parts of the double to a D register in one | 2838 // Move the low and high parts of the double to a D register in one |
2865 // instruction. | 2839 // instruction. |
2866 mov(ip, Operand(lo)); | 2840 mov(ip, Operand(lo)); |
2867 vmov(dst, ip, ip); | 2841 vmov(dst, ip, ip); |
2868 } else if (scratch.is(no_reg)) { | 2842 } else if (scratch.is(no_reg)) { |
2869 mov(ip, Operand(lo)); | 2843 mov(ip, Operand(lo)); |
2870 vmov(dst, VmovIndexLo, ip); | 2844 vmov(dst, VmovIndexLo, ip); |
2871 if (((lo & 0xffff) == (hi & 0xffff)) && | 2845 if (((lo & 0xffff) == (hi & 0xffff)) && |
2872 CpuFeatures::IsSupported(ARMv7)) { | 2846 CpuFeatures::IsSupported(ARMv7)) { |
| 2847 CpuFeatureScope scope(this, ARMv7); |
2873 movt(ip, hi >> 16); | 2848 movt(ip, hi >> 16); |
2874 } else { | 2849 } else { |
2875 mov(ip, Operand(hi)); | 2850 mov(ip, Operand(hi)); |
2876 } | 2851 } |
2877 vmov(dst, VmovIndexHi, ip); | 2852 vmov(dst, VmovIndexHi, ip); |
2878 } else { | 2853 } else { |
2879 // Move the low and high parts of the double to a D register in one | 2854 // Move the low and high parts of the double to a D register in one |
2880 // instruction. | 2855 // instruction. |
2881 mov(ip, Operand(lo)); | 2856 mov(ip, Operand(lo)); |
2882 mov(scratch, Operand(hi)); | 2857 mov(scratch, Operand(hi)); |
(...skipping 15 matching lines...) Expand all Loading... |
2898 } | 2873 } |
2899 | 2874 |
2900 | 2875 |
2901 void Assembler::vmov(const DwVfpRegister dst, | 2876 void Assembler::vmov(const DwVfpRegister dst, |
2902 const DwVfpRegister src, | 2877 const DwVfpRegister src, |
2903 const Condition cond) { | 2878 const Condition cond) { |
2904 // Dd = Dm | 2879 // Dd = Dm |
2905 // Instruction details available in ARM DDI 0406C.b, A8-938. | 2880 // Instruction details available in ARM DDI 0406C.b, A8-938. |
2906 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) | | 2881 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) | |
2907 // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) | 2882 // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
| 2883 DCHECK(VfpRegisterIsAvailable(dst)); |
| 2884 DCHECK(VfpRegisterIsAvailable(src)); |
2908 int vd, d; | 2885 int vd, d; |
2909 dst.split_code(&vd, &d); | 2886 dst.split_code(&vd, &d); |
2910 int vm, m; | 2887 int vm, m; |
2911 src.split_code(&vm, &m); | 2888 src.split_code(&vm, &m); |
2912 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B6 | m*B5 | | 2889 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B6 | m*B5 | |
2913 vm); | 2890 vm); |
2914 } | 2891 } |
2915 | 2892 |
2916 | 2893 |
2917 void Assembler::vmov(const DwVfpRegister dst, | 2894 void Assembler::vmov(const DwVfpRegister dst, |
2918 const VmovIndex index, | 2895 const VmovIndex index, |
2919 const Register src, | 2896 const Register src, |
2920 const Condition cond) { | 2897 const Condition cond) { |
2921 // Dd[index] = Rt | 2898 // Dd[index] = Rt |
2922 // Instruction details available in ARM DDI 0406C.b, A8-940. | 2899 // Instruction details available in ARM DDI 0406C.b, A8-940. |
2923 // cond(31-28) | 1110(27-24) | 0(23) | opc1=0index(22-21) | 0(20) | | 2900 // cond(31-28) | 1110(27-24) | 0(23) | opc1=0index(22-21) | 0(20) | |
2924 // Vd(19-16) | Rt(15-12) | 1011(11-8) | D(7) | opc2=00(6-5) | 1(4) | 0000(3-0) | 2901 // Vd(19-16) | Rt(15-12) | 1011(11-8) | D(7) | opc2=00(6-5) | 1(4) | 0000(3-0) |
| 2902 DCHECK(VfpRegisterIsAvailable(dst)); |
2925 DCHECK(index.index == 0 || index.index == 1); | 2903 DCHECK(index.index == 0 || index.index == 1); |
2926 int vd, d; | 2904 int vd, d; |
2927 dst.split_code(&vd, &d); | 2905 dst.split_code(&vd, &d); |
2928 emit(cond | 0xE*B24 | index.index*B21 | vd*B16 | src.code()*B12 | 0xB*B8 | | 2906 emit(cond | 0xE*B24 | index.index*B21 | vd*B16 | src.code()*B12 | 0xB*B8 | |
2929 d*B7 | B4); | 2907 d*B7 | B4); |
2930 } | 2908 } |
2931 | 2909 |
2932 | 2910 |
2933 void Assembler::vmov(const Register dst, | 2911 void Assembler::vmov(const Register dst, |
2934 const VmovIndex index, | 2912 const VmovIndex index, |
2935 const DwVfpRegister src, | 2913 const DwVfpRegister src, |
2936 const Condition cond) { | 2914 const Condition cond) { |
2937 // Dd[index] = Rt | 2915 // Dd[index] = Rt |
2938 // Instruction details available in ARM DDI 0406C.b, A8.8.342. | 2916 // Instruction details available in ARM DDI 0406C.b, A8.8.342. |
2939 // cond(31-28) | 1110(27-24) | U=0(23) | opc1=0index(22-21) | 1(20) | | 2917 // cond(31-28) | 1110(27-24) | U=0(23) | opc1=0index(22-21) | 1(20) | |
2940 // Vn(19-16) | Rt(15-12) | 1011(11-8) | N(7) | opc2=00(6-5) | 1(4) | 0000(3-0) | 2918 // Vn(19-16) | Rt(15-12) | 1011(11-8) | N(7) | opc2=00(6-5) | 1(4) | 0000(3-0) |
| 2919 DCHECK(VfpRegisterIsAvailable(src)); |
2941 DCHECK(index.index == 0 || index.index == 1); | 2920 DCHECK(index.index == 0 || index.index == 1); |
2942 int vn, n; | 2921 int vn, n; |
2943 src.split_code(&vn, &n); | 2922 src.split_code(&vn, &n); |
2944 emit(cond | 0xE*B24 | index.index*B21 | B20 | vn*B16 | dst.code()*B12 | | 2923 emit(cond | 0xE*B24 | index.index*B21 | B20 | vn*B16 | dst.code()*B12 | |
2945 0xB*B8 | n*B7 | B4); | 2924 0xB*B8 | n*B7 | B4); |
2946 } | 2925 } |
2947 | 2926 |
2948 | 2927 |
2949 void Assembler::vmov(const DwVfpRegister dst, | 2928 void Assembler::vmov(const DwVfpRegister dst, |
2950 const Register src1, | 2929 const Register src1, |
2951 const Register src2, | 2930 const Register src2, |
2952 const Condition cond) { | 2931 const Condition cond) { |
2953 // Dm = <Rt,Rt2>. | 2932 // Dm = <Rt,Rt2>. |
2954 // Instruction details available in ARM DDI 0406C.b, A8-948. | 2933 // Instruction details available in ARM DDI 0406C.b, A8-948. |
2955 // cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) | | 2934 // cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) | |
2956 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm | 2935 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm |
| 2936 DCHECK(VfpRegisterIsAvailable(dst)); |
2957 DCHECK(!src1.is(pc) && !src2.is(pc)); | 2937 DCHECK(!src1.is(pc) && !src2.is(pc)); |
2958 int vm, m; | 2938 int vm, m; |
2959 dst.split_code(&vm, &m); | 2939 dst.split_code(&vm, &m); |
2960 emit(cond | 0xC*B24 | B22 | src2.code()*B16 | | 2940 emit(cond | 0xC*B24 | B22 | src2.code()*B16 | |
2961 src1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm); | 2941 src1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm); |
2962 } | 2942 } |
2963 | 2943 |
2964 | 2944 |
2965 void Assembler::vmov(const Register dst1, | 2945 void Assembler::vmov(const Register dst1, |
2966 const Register dst2, | 2946 const Register dst2, |
2967 const DwVfpRegister src, | 2947 const DwVfpRegister src, |
2968 const Condition cond) { | 2948 const Condition cond) { |
2969 // <Rt,Rt2> = Dm. | 2949 // <Rt,Rt2> = Dm. |
2970 // Instruction details available in ARM DDI 0406C.b, A8-948. | 2950 // Instruction details available in ARM DDI 0406C.b, A8-948. |
2971 // cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) | | 2951 // cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) | |
2972 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm | 2952 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm |
| 2953 DCHECK(VfpRegisterIsAvailable(src)); |
2973 DCHECK(!dst1.is(pc) && !dst2.is(pc)); | 2954 DCHECK(!dst1.is(pc) && !dst2.is(pc)); |
2974 int vm, m; | 2955 int vm, m; |
2975 src.split_code(&vm, &m); | 2956 src.split_code(&vm, &m); |
2976 emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 | | 2957 emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 | |
2977 dst1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm); | 2958 dst1.code()*B12 | 0xB*B8 | m*B5 | B4 | vm); |
2978 } | 2959 } |
2979 | 2960 |
2980 | 2961 |
2981 void Assembler::vmov(const SwVfpRegister dst, | 2962 void Assembler::vmov(const SwVfpRegister dst, |
2982 const Register src, | 2963 const Register src, |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3116 return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | 0x7*B16 | | 3097 return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | 0x7*B16 | |
3117 Vd*B12 | 0x5*B9 | sz*B8 | B7 | B6 | M*B5 | Vm); | 3098 Vd*B12 | 0x5*B9 | sz*B8 | B7 | B6 | M*B5 | Vm); |
3118 } | 3099 } |
3119 } | 3100 } |
3120 | 3101 |
3121 | 3102 |
3122 void Assembler::vcvt_f64_s32(const DwVfpRegister dst, | 3103 void Assembler::vcvt_f64_s32(const DwVfpRegister dst, |
3123 const SwVfpRegister src, | 3104 const SwVfpRegister src, |
3124 VFPConversionMode mode, | 3105 VFPConversionMode mode, |
3125 const Condition cond) { | 3106 const Condition cond) { |
| 3107 DCHECK(VfpRegisterIsAvailable(dst)); |
3126 emit(EncodeVCVT(F64, dst.code(), S32, src.code(), mode, cond)); | 3108 emit(EncodeVCVT(F64, dst.code(), S32, src.code(), mode, cond)); |
3127 } | 3109 } |
3128 | 3110 |
3129 | 3111 |
3130 void Assembler::vcvt_f32_s32(const SwVfpRegister dst, | 3112 void Assembler::vcvt_f32_s32(const SwVfpRegister dst, |
3131 const SwVfpRegister src, | 3113 const SwVfpRegister src, |
3132 VFPConversionMode mode, | 3114 VFPConversionMode mode, |
3133 const Condition cond) { | 3115 const Condition cond) { |
3134 emit(EncodeVCVT(F32, dst.code(), S32, src.code(), mode, cond)); | 3116 emit(EncodeVCVT(F32, dst.code(), S32, src.code(), mode, cond)); |
3135 } | 3117 } |
3136 | 3118 |
3137 | 3119 |
3138 void Assembler::vcvt_f64_u32(const DwVfpRegister dst, | 3120 void Assembler::vcvt_f64_u32(const DwVfpRegister dst, |
3139 const SwVfpRegister src, | 3121 const SwVfpRegister src, |
3140 VFPConversionMode mode, | 3122 VFPConversionMode mode, |
3141 const Condition cond) { | 3123 const Condition cond) { |
| 3124 DCHECK(VfpRegisterIsAvailable(dst)); |
3142 emit(EncodeVCVT(F64, dst.code(), U32, src.code(), mode, cond)); | 3125 emit(EncodeVCVT(F64, dst.code(), U32, src.code(), mode, cond)); |
3143 } | 3126 } |
3144 | 3127 |
3145 | 3128 |
3146 void Assembler::vcvt_f32_u32(const SwVfpRegister dst, const SwVfpRegister src, | 3129 void Assembler::vcvt_f32_u32(const SwVfpRegister dst, const SwVfpRegister src, |
3147 VFPConversionMode mode, const Condition cond) { | 3130 VFPConversionMode mode, const Condition cond) { |
3148 emit(EncodeVCVT(F32, dst.code(), U32, src.code(), mode, cond)); | 3131 emit(EncodeVCVT(F32, dst.code(), U32, src.code(), mode, cond)); |
3149 } | 3132 } |
3150 | 3133 |
3151 | 3134 |
3152 void Assembler::vcvt_s32_f32(const SwVfpRegister dst, const SwVfpRegister src, | 3135 void Assembler::vcvt_s32_f32(const SwVfpRegister dst, const SwVfpRegister src, |
3153 VFPConversionMode mode, const Condition cond) { | 3136 VFPConversionMode mode, const Condition cond) { |
3154 emit(EncodeVCVT(S32, dst.code(), F32, src.code(), mode, cond)); | 3137 emit(EncodeVCVT(S32, dst.code(), F32, src.code(), mode, cond)); |
3155 } | 3138 } |
3156 | 3139 |
3157 | 3140 |
3158 void Assembler::vcvt_u32_f32(const SwVfpRegister dst, const SwVfpRegister src, | 3141 void Assembler::vcvt_u32_f32(const SwVfpRegister dst, const SwVfpRegister src, |
3159 VFPConversionMode mode, const Condition cond) { | 3142 VFPConversionMode mode, const Condition cond) { |
3160 emit(EncodeVCVT(U32, dst.code(), F32, src.code(), mode, cond)); | 3143 emit(EncodeVCVT(U32, dst.code(), F32, src.code(), mode, cond)); |
3161 } | 3144 } |
3162 | 3145 |
3163 | 3146 |
3164 void Assembler::vcvt_s32_f64(const SwVfpRegister dst, | 3147 void Assembler::vcvt_s32_f64(const SwVfpRegister dst, |
3165 const DwVfpRegister src, | 3148 const DwVfpRegister src, |
3166 VFPConversionMode mode, | 3149 VFPConversionMode mode, |
3167 const Condition cond) { | 3150 const Condition cond) { |
| 3151 DCHECK(VfpRegisterIsAvailable(src)); |
3168 emit(EncodeVCVT(S32, dst.code(), F64, src.code(), mode, cond)); | 3152 emit(EncodeVCVT(S32, dst.code(), F64, src.code(), mode, cond)); |
3169 } | 3153 } |
3170 | 3154 |
3171 | 3155 |
3172 void Assembler::vcvt_u32_f64(const SwVfpRegister dst, | 3156 void Assembler::vcvt_u32_f64(const SwVfpRegister dst, |
3173 const DwVfpRegister src, | 3157 const DwVfpRegister src, |
3174 VFPConversionMode mode, | 3158 VFPConversionMode mode, |
3175 const Condition cond) { | 3159 const Condition cond) { |
| 3160 DCHECK(VfpRegisterIsAvailable(src)); |
3176 emit(EncodeVCVT(U32, dst.code(), F64, src.code(), mode, cond)); | 3161 emit(EncodeVCVT(U32, dst.code(), F64, src.code(), mode, cond)); |
3177 } | 3162 } |
3178 | 3163 |
3179 | 3164 |
3180 void Assembler::vcvt_f64_f32(const DwVfpRegister dst, | 3165 void Assembler::vcvt_f64_f32(const DwVfpRegister dst, |
3181 const SwVfpRegister src, | 3166 const SwVfpRegister src, |
3182 VFPConversionMode mode, | 3167 VFPConversionMode mode, |
3183 const Condition cond) { | 3168 const Condition cond) { |
| 3169 DCHECK(VfpRegisterIsAvailable(dst)); |
3184 emit(EncodeVCVT(F64, dst.code(), F32, src.code(), mode, cond)); | 3170 emit(EncodeVCVT(F64, dst.code(), F32, src.code(), mode, cond)); |
3185 } | 3171 } |
3186 | 3172 |
3187 | 3173 |
3188 void Assembler::vcvt_f32_f64(const SwVfpRegister dst, | 3174 void Assembler::vcvt_f32_f64(const SwVfpRegister dst, |
3189 const DwVfpRegister src, | 3175 const DwVfpRegister src, |
3190 VFPConversionMode mode, | 3176 VFPConversionMode mode, |
3191 const Condition cond) { | 3177 const Condition cond) { |
| 3178 DCHECK(VfpRegisterIsAvailable(src)); |
3192 emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond)); | 3179 emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond)); |
3193 } | 3180 } |
3194 | 3181 |
3195 | 3182 |
3196 void Assembler::vcvt_f64_s32(const DwVfpRegister dst, | 3183 void Assembler::vcvt_f64_s32(const DwVfpRegister dst, |
3197 int fraction_bits, | 3184 int fraction_bits, |
3198 const Condition cond) { | 3185 const Condition cond) { |
3199 // Instruction details available in ARM DDI 0406C.b, A8-874. | 3186 // Instruction details available in ARM DDI 0406C.b, A8-874. |
3200 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 1010(19-16) | Vd(15-12) | | 3187 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 1010(19-16) | Vd(15-12) | |
3201 // 101(11-9) | sf=1(8) | sx=1(7) | 1(6) | i(5) | 0(4) | imm4(3-0) | 3188 // 101(11-9) | sf=1(8) | sx=1(7) | 1(6) | i(5) | 0(4) | imm4(3-0) |
| 3189 DCHECK(IsEnabled(VFPv3)); |
| 3190 DCHECK(VfpRegisterIsAvailable(dst)); |
3202 DCHECK(fraction_bits > 0 && fraction_bits <= 32); | 3191 DCHECK(fraction_bits > 0 && fraction_bits <= 32); |
3203 DCHECK(CpuFeatures::IsSupported(VFP3)); | |
3204 int vd, d; | 3192 int vd, d; |
3205 dst.split_code(&vd, &d); | 3193 dst.split_code(&vd, &d); |
3206 int imm5 = 32 - fraction_bits; | 3194 int imm5 = 32 - fraction_bits; |
3207 int i = imm5 & 1; | 3195 int i = imm5 & 1; |
3208 int imm4 = (imm5 >> 1) & 0xf; | 3196 int imm4 = (imm5 >> 1) & 0xf; |
3209 emit(cond | 0xE*B24 | B23 | d*B22 | 0x3*B20 | B19 | 0x2*B16 | | 3197 emit(cond | 0xE*B24 | B23 | d*B22 | 0x3*B20 | B19 | 0x2*B16 | |
3210 vd*B12 | 0x5*B9 | B8 | B7 | B6 | i*B5 | imm4); | 3198 vd*B12 | 0x5*B9 | B8 | B7 | B6 | i*B5 | imm4); |
3211 } | 3199 } |
3212 | 3200 |
3213 | 3201 |
3214 void Assembler::vneg(const DwVfpRegister dst, | 3202 void Assembler::vneg(const DwVfpRegister dst, |
3215 const DwVfpRegister src, | 3203 const DwVfpRegister src, |
3216 const Condition cond) { | 3204 const Condition cond) { |
3217 // Instruction details available in ARM DDI 0406C.b, A8-968. | 3205 // Instruction details available in ARM DDI 0406C.b, A8-968. |
3218 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0001(19-16) | Vd(15-12) | | 3206 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0001(19-16) | Vd(15-12) | |
3219 // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) | 3207 // 101(11-9) | sz=1(8) | 0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
| 3208 DCHECK(VfpRegisterIsAvailable(dst)); |
| 3209 DCHECK(VfpRegisterIsAvailable(src)); |
3220 int vd, d; | 3210 int vd, d; |
3221 dst.split_code(&vd, &d); | 3211 dst.split_code(&vd, &d); |
3222 int vm, m; | 3212 int vm, m; |
3223 src.split_code(&vm, &m); | 3213 src.split_code(&vm, &m); |
3224 | 3214 |
3225 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | B6 | | 3215 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | B6 | |
3226 m*B5 | vm); | 3216 m*B5 | vm); |
3227 } | 3217 } |
3228 | 3218 |
3229 | 3219 |
(...skipping 11 matching lines...) Expand all Loading... |
3241 B6 | m * B5 | vm); | 3231 B6 | m * B5 | vm); |
3242 } | 3232 } |
3243 | 3233 |
3244 | 3234 |
3245 void Assembler::vabs(const DwVfpRegister dst, | 3235 void Assembler::vabs(const DwVfpRegister dst, |
3246 const DwVfpRegister src, | 3236 const DwVfpRegister src, |
3247 const Condition cond) { | 3237 const Condition cond) { |
3248 // Instruction details available in ARM DDI 0406C.b, A8-524. | 3238 // Instruction details available in ARM DDI 0406C.b, A8-524. |
3249 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) | | 3239 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | 0000(19-16) | Vd(15-12) | |
3250 // 101(11-9) | sz=1(8) | 1(7) | 1(6) | M(5) | 0(4) | Vm(3-0) | 3240 // 101(11-9) | sz=1(8) | 1(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
| 3241 DCHECK(VfpRegisterIsAvailable(dst)); |
| 3242 DCHECK(VfpRegisterIsAvailable(src)); |
3251 int vd, d; | 3243 int vd, d; |
3252 dst.split_code(&vd, &d); | 3244 dst.split_code(&vd, &d); |
3253 int vm, m; | 3245 int vm, m; |
3254 src.split_code(&vm, &m); | 3246 src.split_code(&vm, &m); |
3255 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B7 | B6 | | 3247 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | B7 | B6 | |
3256 m*B5 | vm); | 3248 m*B5 | vm); |
3257 } | 3249 } |
3258 | 3250 |
3259 | 3251 |
3260 void Assembler::vabs(const SwVfpRegister dst, const SwVfpRegister src, | 3252 void Assembler::vabs(const SwVfpRegister dst, const SwVfpRegister src, |
(...skipping 12 matching lines...) Expand all Loading... |
3273 | 3265 |
3274 void Assembler::vadd(const DwVfpRegister dst, | 3266 void Assembler::vadd(const DwVfpRegister dst, |
3275 const DwVfpRegister src1, | 3267 const DwVfpRegister src1, |
3276 const DwVfpRegister src2, | 3268 const DwVfpRegister src2, |
3277 const Condition cond) { | 3269 const Condition cond) { |
3278 // Dd = vadd(Dn, Dm) double precision floating point addition. | 3270 // Dd = vadd(Dn, Dm) double precision floating point addition. |
3279 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 3271 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
3280 // Instruction details available in ARM DDI 0406C.b, A8-830. | 3272 // Instruction details available in ARM DDI 0406C.b, A8-830. |
3281 // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) | | 3273 // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) | |
3282 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) | 3274 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) |
| 3275 DCHECK(VfpRegisterIsAvailable(dst)); |
| 3276 DCHECK(VfpRegisterIsAvailable(src1)); |
| 3277 DCHECK(VfpRegisterIsAvailable(src2)); |
3283 int vd, d; | 3278 int vd, d; |
3284 dst.split_code(&vd, &d); | 3279 dst.split_code(&vd, &d); |
3285 int vn, n; | 3280 int vn, n; |
3286 src1.split_code(&vn, &n); | 3281 src1.split_code(&vn, &n); |
3287 int vm, m; | 3282 int vm, m; |
3288 src2.split_code(&vm, &m); | 3283 src2.split_code(&vm, &m); |
3289 emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | | 3284 emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | |
3290 n*B7 | m*B5 | vm); | 3285 n*B7 | m*B5 | vm); |
3291 } | 3286 } |
3292 | 3287 |
(...skipping 18 matching lines...) Expand all Loading... |
3311 | 3306 |
3312 void Assembler::vsub(const DwVfpRegister dst, | 3307 void Assembler::vsub(const DwVfpRegister dst, |
3313 const DwVfpRegister src1, | 3308 const DwVfpRegister src1, |
3314 const DwVfpRegister src2, | 3309 const DwVfpRegister src2, |
3315 const Condition cond) { | 3310 const Condition cond) { |
3316 // Dd = vsub(Dn, Dm) double precision floating point subtraction. | 3311 // Dd = vsub(Dn, Dm) double precision floating point subtraction. |
3317 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 3312 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
3318 // Instruction details available in ARM DDI 0406C.b, A8-1086. | 3313 // Instruction details available in ARM DDI 0406C.b, A8-1086. |
3319 // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) | | 3314 // cond(31-28) | 11100(27-23)| D(22) | 11(21-20) | Vn(19-16) | |
3320 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 1(6) | M(5) | 0(4) | Vm(3-0) | 3315 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
| 3316 DCHECK(VfpRegisterIsAvailable(dst)); |
| 3317 DCHECK(VfpRegisterIsAvailable(src1)); |
| 3318 DCHECK(VfpRegisterIsAvailable(src2)); |
3321 int vd, d; | 3319 int vd, d; |
3322 dst.split_code(&vd, &d); | 3320 dst.split_code(&vd, &d); |
3323 int vn, n; | 3321 int vn, n; |
3324 src1.split_code(&vn, &n); | 3322 src1.split_code(&vn, &n); |
3325 int vm, m; | 3323 int vm, m; |
3326 src2.split_code(&vm, &m); | 3324 src2.split_code(&vm, &m); |
3327 emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | | 3325 emit(cond | 0x1C*B23 | d*B22 | 0x3*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | |
3328 n*B7 | B6 | m*B5 | vm); | 3326 n*B7 | B6 | m*B5 | vm); |
3329 } | 3327 } |
3330 | 3328 |
(...skipping 18 matching lines...) Expand all Loading... |
3349 | 3347 |
3350 void Assembler::vmul(const DwVfpRegister dst, | 3348 void Assembler::vmul(const DwVfpRegister dst, |
3351 const DwVfpRegister src1, | 3349 const DwVfpRegister src1, |
3352 const DwVfpRegister src2, | 3350 const DwVfpRegister src2, |
3353 const Condition cond) { | 3351 const Condition cond) { |
3354 // Dd = vmul(Dn, Dm) double precision floating point multiplication. | 3352 // Dd = vmul(Dn, Dm) double precision floating point multiplication. |
3355 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 3353 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
3356 // Instruction details available in ARM DDI 0406C.b, A8-960. | 3354 // Instruction details available in ARM DDI 0406C.b, A8-960. |
3357 // cond(31-28) | 11100(27-23)| D(22) | 10(21-20) | Vn(19-16) | | 3355 // cond(31-28) | 11100(27-23)| D(22) | 10(21-20) | Vn(19-16) | |
3358 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) | 3356 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) |
| 3357 DCHECK(VfpRegisterIsAvailable(dst)); |
| 3358 DCHECK(VfpRegisterIsAvailable(src1)); |
| 3359 DCHECK(VfpRegisterIsAvailable(src2)); |
3359 int vd, d; | 3360 int vd, d; |
3360 dst.split_code(&vd, &d); | 3361 dst.split_code(&vd, &d); |
3361 int vn, n; | 3362 int vn, n; |
3362 src1.split_code(&vn, &n); | 3363 src1.split_code(&vn, &n); |
3363 int vm, m; | 3364 int vm, m; |
3364 src2.split_code(&vm, &m); | 3365 src2.split_code(&vm, &m); |
3365 emit(cond | 0x1C*B23 | d*B22 | 0x2*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | | 3366 emit(cond | 0x1C*B23 | d*B22 | 0x2*B20 | vn*B16 | vd*B12 | 0x5*B9 | B8 | |
3366 n*B7 | m*B5 | vm); | 3367 n*B7 | m*B5 | vm); |
3367 } | 3368 } |
3368 | 3369 |
(...skipping 16 matching lines...) Expand all Loading... |
3385 } | 3386 } |
3386 | 3387 |
3387 | 3388 |
3388 void Assembler::vmla(const DwVfpRegister dst, | 3389 void Assembler::vmla(const DwVfpRegister dst, |
3389 const DwVfpRegister src1, | 3390 const DwVfpRegister src1, |
3390 const DwVfpRegister src2, | 3391 const DwVfpRegister src2, |
3391 const Condition cond) { | 3392 const Condition cond) { |
3392 // Instruction details available in ARM DDI 0406C.b, A8-932. | 3393 // Instruction details available in ARM DDI 0406C.b, A8-932. |
3393 // cond(31-28) | 11100(27-23) | D(22) | 00(21-20) | Vn(19-16) | | 3394 // cond(31-28) | 11100(27-23) | D(22) | 00(21-20) | Vn(19-16) | |
3394 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | op=0(6) | M(5) | 0(4) | Vm(3-0) | 3395 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | op=0(6) | M(5) | 0(4) | Vm(3-0) |
| 3396 DCHECK(VfpRegisterIsAvailable(dst)); |
| 3397 DCHECK(VfpRegisterIsAvailable(src1)); |
| 3398 DCHECK(VfpRegisterIsAvailable(src2)); |
3395 int vd, d; | 3399 int vd, d; |
3396 dst.split_code(&vd, &d); | 3400 dst.split_code(&vd, &d); |
3397 int vn, n; | 3401 int vn, n; |
3398 src1.split_code(&vn, &n); | 3402 src1.split_code(&vn, &n); |
3399 int vm, m; | 3403 int vm, m; |
3400 src2.split_code(&vm, &m); | 3404 src2.split_code(&vm, &m); |
3401 emit(cond | 0x1C*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | m*B5 | | 3405 emit(cond | 0x1C*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | m*B5 | |
3402 vm); | 3406 vm); |
3403 } | 3407 } |
3404 | 3408 |
(...skipping 14 matching lines...) Expand all Loading... |
3419 } | 3423 } |
3420 | 3424 |
3421 | 3425 |
3422 void Assembler::vmls(const DwVfpRegister dst, | 3426 void Assembler::vmls(const DwVfpRegister dst, |
3423 const DwVfpRegister src1, | 3427 const DwVfpRegister src1, |
3424 const DwVfpRegister src2, | 3428 const DwVfpRegister src2, |
3425 const Condition cond) { | 3429 const Condition cond) { |
3426 // Instruction details available in ARM DDI 0406C.b, A8-932. | 3430 // Instruction details available in ARM DDI 0406C.b, A8-932. |
3427 // cond(31-28) | 11100(27-23) | D(22) | 00(21-20) | Vn(19-16) | | 3431 // cond(31-28) | 11100(27-23) | D(22) | 00(21-20) | Vn(19-16) | |
3428 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | op=1(6) | M(5) | 0(4) | Vm(3-0) | 3432 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | op=1(6) | M(5) | 0(4) | Vm(3-0) |
| 3433 DCHECK(VfpRegisterIsAvailable(dst)); |
| 3434 DCHECK(VfpRegisterIsAvailable(src1)); |
| 3435 DCHECK(VfpRegisterIsAvailable(src2)); |
3429 int vd, d; | 3436 int vd, d; |
3430 dst.split_code(&vd, &d); | 3437 dst.split_code(&vd, &d); |
3431 int vn, n; | 3438 int vn, n; |
3432 src1.split_code(&vn, &n); | 3439 src1.split_code(&vn, &n); |
3433 int vm, m; | 3440 int vm, m; |
3434 src2.split_code(&vm, &m); | 3441 src2.split_code(&vm, &m); |
3435 emit(cond | 0x1C*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | B6 | | 3442 emit(cond | 0x1C*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | B6 | |
3436 m*B5 | vm); | 3443 m*B5 | vm); |
3437 } | 3444 } |
3438 | 3445 |
(...skipping 16 matching lines...) Expand all Loading... |
3455 | 3462 |
3456 void Assembler::vdiv(const DwVfpRegister dst, | 3463 void Assembler::vdiv(const DwVfpRegister dst, |
3457 const DwVfpRegister src1, | 3464 const DwVfpRegister src1, |
3458 const DwVfpRegister src2, | 3465 const DwVfpRegister src2, |
3459 const Condition cond) { | 3466 const Condition cond) { |
3460 // Dd = vdiv(Dn, Dm) double precision floating point division. | 3467 // Dd = vdiv(Dn, Dm) double precision floating point division. |
3461 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 3468 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
3462 // Instruction details available in ARM DDI 0406C.b, A8-882. | 3469 // Instruction details available in ARM DDI 0406C.b, A8-882. |
3463 // cond(31-28) | 11101(27-23)| D(22) | 00(21-20) | Vn(19-16) | | 3470 // cond(31-28) | 11101(27-23)| D(22) | 00(21-20) | Vn(19-16) | |
3464 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) | 3471 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) |
| 3472 DCHECK(VfpRegisterIsAvailable(dst)); |
| 3473 DCHECK(VfpRegisterIsAvailable(src1)); |
| 3474 DCHECK(VfpRegisterIsAvailable(src2)); |
3465 int vd, d; | 3475 int vd, d; |
3466 dst.split_code(&vd, &d); | 3476 dst.split_code(&vd, &d); |
3467 int vn, n; | 3477 int vn, n; |
3468 src1.split_code(&vn, &n); | 3478 src1.split_code(&vn, &n); |
3469 int vm, m; | 3479 int vm, m; |
3470 src2.split_code(&vm, &m); | 3480 src2.split_code(&vm, &m); |
3471 emit(cond | 0x1D*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | m*B5 | | 3481 emit(cond | 0x1D*B23 | d*B22 | vn*B16 | vd*B12 | 0x5*B9 | B8 | n*B7 | m*B5 | |
3472 vm); | 3482 vm); |
3473 } | 3483 } |
3474 | 3484 |
(...skipping 16 matching lines...) Expand all Loading... |
3491 } | 3501 } |
3492 | 3502 |
3493 | 3503 |
3494 void Assembler::vcmp(const DwVfpRegister src1, | 3504 void Assembler::vcmp(const DwVfpRegister src1, |
3495 const DwVfpRegister src2, | 3505 const DwVfpRegister src2, |
3496 const Condition cond) { | 3506 const Condition cond) { |
3497 // vcmp(Dd, Dm) double precision floating point comparison. | 3507 // vcmp(Dd, Dm) double precision floating point comparison. |
3498 // Instruction details available in ARM DDI 0406C.b, A8-864. | 3508 // Instruction details available in ARM DDI 0406C.b, A8-864. |
3499 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0100(19-16) | | 3509 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0100(19-16) | |
3500 // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) | 3510 // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
| 3511 DCHECK(VfpRegisterIsAvailable(src1)); |
| 3512 DCHECK(VfpRegisterIsAvailable(src2)); |
3501 int vd, d; | 3513 int vd, d; |
3502 src1.split_code(&vd, &d); | 3514 src1.split_code(&vd, &d); |
3503 int vm, m; | 3515 int vm, m; |
3504 src2.split_code(&vm, &m); | 3516 src2.split_code(&vm, &m); |
3505 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x4*B16 | vd*B12 | 0x5*B9 | B8 | B6 | | 3517 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x4*B16 | vd*B12 | 0x5*B9 | B8 | B6 | |
3506 m*B5 | vm); | 3518 m*B5 | vm); |
3507 } | 3519 } |
3508 | 3520 |
3509 | 3521 |
3510 void Assembler::vcmp(const SwVfpRegister src1, const SwVfpRegister src2, | 3522 void Assembler::vcmp(const SwVfpRegister src1, const SwVfpRegister src2, |
(...skipping 11 matching lines...) Expand all Loading... |
3522 } | 3534 } |
3523 | 3535 |
3524 | 3536 |
3525 void Assembler::vcmp(const DwVfpRegister src1, | 3537 void Assembler::vcmp(const DwVfpRegister src1, |
3526 const double src2, | 3538 const double src2, |
3527 const Condition cond) { | 3539 const Condition cond) { |
3528 // vcmp(Dd, #0.0) double precision floating point comparison. | 3540 // vcmp(Dd, #0.0) double precision floating point comparison. |
3529 // Instruction details available in ARM DDI 0406C.b, A8-864. | 3541 // Instruction details available in ARM DDI 0406C.b, A8-864. |
3530 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0101(19-16) | | 3542 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0101(19-16) | |
3531 // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | 0(5) | 0(4) | 0000(3-0) | 3543 // Vd(15-12) | 101(11-9) | sz=1(8) | E=0(7) | 1(6) | 0(5) | 0(4) | 0000(3-0) |
| 3544 DCHECK(VfpRegisterIsAvailable(src1)); |
3532 DCHECK(src2 == 0.0); | 3545 DCHECK(src2 == 0.0); |
3533 int vd, d; | 3546 int vd, d; |
3534 src1.split_code(&vd, &d); | 3547 src1.split_code(&vd, &d); |
3535 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x5*B16 | vd*B12 | 0x5*B9 | B8 | B6); | 3548 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | 0x5*B16 | vd*B12 | 0x5*B9 | B8 | B6); |
3536 } | 3549 } |
3537 | 3550 |
3538 | 3551 |
3539 void Assembler::vcmp(const SwVfpRegister src1, const float src2, | 3552 void Assembler::vcmp(const SwVfpRegister src1, const float src2, |
3540 const Condition cond) { | 3553 const Condition cond) { |
3541 // vcmp(Sd, #0.0) single precision floating point comparison. | 3554 // vcmp(Sd, #0.0) single precision floating point comparison. |
3542 // Instruction details available in ARM DDI 0406C.b, A8-864. | 3555 // Instruction details available in ARM DDI 0406C.b, A8-864. |
3543 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0101(19-16) | | 3556 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0101(19-16) | |
3544 // Vd(15-12) | 101(11-9) | sz=0(8) | E=0(7) | 1(6) | 0(5) | 0(4) | 0000(3-0) | 3557 // Vd(15-12) | 101(11-9) | sz=0(8) | E=0(7) | 1(6) | 0(5) | 0(4) | 0000(3-0) |
3545 DCHECK(src2 == 0.0); | 3558 DCHECK(src2 == 0.0); |
3546 int vd, d; | 3559 int vd, d; |
3547 src1.split_code(&vd, &d); | 3560 src1.split_code(&vd, &d); |
3548 emit(cond | 0x1D * B23 | d * B22 | 0x3 * B20 | 0x5 * B16 | vd * B12 | | 3561 emit(cond | 0x1D * B23 | d * B22 | 0x3 * B20 | 0x5 * B16 | vd * B12 | |
3549 0x5 * B9 | B6); | 3562 0x5 * B9 | B6); |
3550 } | 3563 } |
3551 | 3564 |
3552 void Assembler::vmaxnm(const DwVfpRegister dst, const DwVfpRegister src1, | 3565 void Assembler::vmaxnm(const DwVfpRegister dst, const DwVfpRegister src1, |
3553 const DwVfpRegister src2) { | 3566 const DwVfpRegister src2) { |
3554 // kSpecialCondition(31-28) | 11101(27-23) | D(22) | 00(21-20) | Vn(19-16) | | 3567 // kSpecialCondition(31-28) | 11101(27-23) | D(22) | 00(21-20) | Vn(19-16) | |
3555 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) | 3568 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) |
3556 DCHECK(CpuFeatures::IsSupported(ARMv8)); | 3569 DCHECK(IsEnabled(ARMv8)); |
3557 int vd, d; | 3570 int vd, d; |
3558 dst.split_code(&vd, &d); | 3571 dst.split_code(&vd, &d); |
3559 int vn, n; | 3572 int vn, n; |
3560 src1.split_code(&vn, &n); | 3573 src1.split_code(&vn, &n); |
3561 int vm, m; | 3574 int vm, m; |
3562 src2.split_code(&vm, &m); | 3575 src2.split_code(&vm, &m); |
3563 | 3576 |
3564 emit(kSpecialCondition | 0x1D * B23 | d * B22 | vn * B16 | vd * B12 | | 3577 emit(kSpecialCondition | 0x1D * B23 | d * B22 | vn * B16 | vd * B12 | |
3565 0x5 * B9 | B8 | n * B7 | m * B5 | vm); | 3578 0x5 * B9 | B8 | n * B7 | m * B5 | vm); |
3566 } | 3579 } |
3567 | 3580 |
3568 void Assembler::vmaxnm(const SwVfpRegister dst, const SwVfpRegister src1, | 3581 void Assembler::vmaxnm(const SwVfpRegister dst, const SwVfpRegister src1, |
3569 const SwVfpRegister src2) { | 3582 const SwVfpRegister src2) { |
3570 // kSpecialCondition(31-28) | 11101(27-23) | D(22) | 00(21-20) | Vn(19-16) | | 3583 // kSpecialCondition(31-28) | 11101(27-23) | D(22) | 00(21-20) | Vn(19-16) | |
3571 // Vd(15-12) | 101(11-9) | sz=0(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) | 3584 // Vd(15-12) | 101(11-9) | sz=0(8) | N(7) | 0(6) | M(5) | 0(4) | Vm(3-0) |
3572 DCHECK(CpuFeatures::IsSupported(ARMv8)); | 3585 DCHECK(IsEnabled(ARMv8)); |
3573 int vd, d; | 3586 int vd, d; |
3574 dst.split_code(&vd, &d); | 3587 dst.split_code(&vd, &d); |
3575 int vn, n; | 3588 int vn, n; |
3576 src1.split_code(&vn, &n); | 3589 src1.split_code(&vn, &n); |
3577 int vm, m; | 3590 int vm, m; |
3578 src2.split_code(&vm, &m); | 3591 src2.split_code(&vm, &m); |
3579 | 3592 |
3580 emit(kSpecialCondition | 0x1D * B23 | d * B22 | vn * B16 | vd * B12 | | 3593 emit(kSpecialCondition | 0x1D * B23 | d * B22 | vn * B16 | vd * B12 | |
3581 0x5 * B9 | n * B7 | m * B5 | vm); | 3594 0x5 * B9 | n * B7 | m * B5 | vm); |
3582 } | 3595 } |
3583 | 3596 |
3584 void Assembler::vminnm(const DwVfpRegister dst, const DwVfpRegister src1, | 3597 void Assembler::vminnm(const DwVfpRegister dst, const DwVfpRegister src1, |
3585 const DwVfpRegister src2) { | 3598 const DwVfpRegister src2) { |
3586 // kSpecialCondition(31-28) | 11101(27-23) | D(22) | 00(21-20) | Vn(19-16) | | 3599 // kSpecialCondition(31-28) | 11101(27-23) | D(22) | 00(21-20) | Vn(19-16) | |
3587 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 1(6) | M(5) | 0(4) | Vm(3-0) | 3600 // Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
3588 DCHECK(CpuFeatures::IsSupported(ARMv8)); | 3601 DCHECK(IsEnabled(ARMv8)); |
3589 int vd, d; | 3602 int vd, d; |
3590 dst.split_code(&vd, &d); | 3603 dst.split_code(&vd, &d); |
3591 int vn, n; | 3604 int vn, n; |
3592 src1.split_code(&vn, &n); | 3605 src1.split_code(&vn, &n); |
3593 int vm, m; | 3606 int vm, m; |
3594 src2.split_code(&vm, &m); | 3607 src2.split_code(&vm, &m); |
3595 | 3608 |
3596 emit(kSpecialCondition | 0x1D * B23 | d * B22 | vn * B16 | vd * B12 | | 3609 emit(kSpecialCondition | 0x1D * B23 | d * B22 | vn * B16 | vd * B12 | |
3597 0x5 * B9 | B8 | n * B7 | B6 | m * B5 | vm); | 3610 0x5 * B9 | B8 | n * B7 | B6 | m * B5 | vm); |
3598 } | 3611 } |
3599 | 3612 |
3600 void Assembler::vminnm(const SwVfpRegister dst, const SwVfpRegister src1, | 3613 void Assembler::vminnm(const SwVfpRegister dst, const SwVfpRegister src1, |
3601 const SwVfpRegister src2) { | 3614 const SwVfpRegister src2) { |
3602 // kSpecialCondition(31-28) | 11101(27-23) | D(22) | 00(21-20) | Vn(19-16) | | 3615 // kSpecialCondition(31-28) | 11101(27-23) | D(22) | 00(21-20) | Vn(19-16) | |
3603 // Vd(15-12) | 101(11-9) | sz=0(8) | N(7) | 1(6) | M(5) | 0(4) | Vm(3-0) | 3616 // Vd(15-12) | 101(11-9) | sz=0(8) | N(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
3604 DCHECK(CpuFeatures::IsSupported(ARMv8)); | 3617 DCHECK(IsEnabled(ARMv8)); |
3605 int vd, d; | 3618 int vd, d; |
3606 dst.split_code(&vd, &d); | 3619 dst.split_code(&vd, &d); |
3607 int vn, n; | 3620 int vn, n; |
3608 src1.split_code(&vn, &n); | 3621 src1.split_code(&vn, &n); |
3609 int vm, m; | 3622 int vm, m; |
3610 src2.split_code(&vm, &m); | 3623 src2.split_code(&vm, &m); |
3611 | 3624 |
3612 emit(kSpecialCondition | 0x1D * B23 | d * B22 | vn * B16 | vd * B12 | | 3625 emit(kSpecialCondition | 0x1D * B23 | d * B22 | vn * B16 | vd * B12 | |
3613 0x5 * B9 | n * B7 | B6 | m * B5 | vm); | 3626 0x5 * B9 | n * B7 | B6 | m * B5 | vm); |
3614 } | 3627 } |
3615 | 3628 |
3616 void Assembler::vsel(Condition cond, const DwVfpRegister dst, | 3629 void Assembler::vsel(Condition cond, const DwVfpRegister dst, |
3617 const DwVfpRegister src1, const DwVfpRegister src2) { | 3630 const DwVfpRegister src1, const DwVfpRegister src2) { |
3618 // cond=kSpecialCondition(31-28) | 11100(27-23) | D(22) | | 3631 // cond=kSpecialCondition(31-28) | 11100(27-23) | D(22) | |
3619 // vsel_cond=XX(21-20) | Vn(19-16) | Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | | 3632 // vsel_cond=XX(21-20) | Vn(19-16) | Vd(15-12) | 101(11-9) | sz=1(8) | N(7) | |
3620 // 0(6) | M(5) | 0(4) | Vm(3-0) | 3633 // 0(6) | M(5) | 0(4) | Vm(3-0) |
3621 DCHECK(CpuFeatures::IsSupported(ARMv8)); | 3634 DCHECK(IsEnabled(ARMv8)); |
3622 int vd, d; | 3635 int vd, d; |
3623 dst.split_code(&vd, &d); | 3636 dst.split_code(&vd, &d); |
3624 int vn, n; | 3637 int vn, n; |
3625 src1.split_code(&vn, &n); | 3638 src1.split_code(&vn, &n); |
3626 int vm, m; | 3639 int vm, m; |
3627 src2.split_code(&vm, &m); | 3640 src2.split_code(&vm, &m); |
3628 int sz = 1; | 3641 int sz = 1; |
3629 | 3642 |
3630 // VSEL has a special (restricted) condition encoding. | 3643 // VSEL has a special (restricted) condition encoding. |
3631 // eq(0b0000)... -> 0b00 | 3644 // eq(0b0000)... -> 0b00 |
(...skipping 11 matching lines...) Expand all Loading... |
3643 | 3656 |
3644 emit(kSpecialCondition | 0x1C * B23 | d * B22 | vsel_cond * B20 | vn * B16 | | 3657 emit(kSpecialCondition | 0x1C * B23 | d * B22 | vsel_cond * B20 | vn * B16 | |
3645 vd * B12 | 0x5 * B9 | sz * B8 | n * B7 | m * B5 | vm); | 3658 vd * B12 | 0x5 * B9 | sz * B8 | n * B7 | m * B5 | vm); |
3646 } | 3659 } |
3647 | 3660 |
3648 void Assembler::vsel(Condition cond, const SwVfpRegister dst, | 3661 void Assembler::vsel(Condition cond, const SwVfpRegister dst, |
3649 const SwVfpRegister src1, const SwVfpRegister src2) { | 3662 const SwVfpRegister src1, const SwVfpRegister src2) { |
3650 // cond=kSpecialCondition(31-28) | 11100(27-23) | D(22) | | 3663 // cond=kSpecialCondition(31-28) | 11100(27-23) | D(22) | |
3651 // vsel_cond=XX(21-20) | Vn(19-16) | Vd(15-12) | 101(11-9) | sz=0(8) | N(7) | | 3664 // vsel_cond=XX(21-20) | Vn(19-16) | Vd(15-12) | 101(11-9) | sz=0(8) | N(7) | |
3652 // 0(6) | M(5) | 0(4) | Vm(3-0) | 3665 // 0(6) | M(5) | 0(4) | Vm(3-0) |
3653 DCHECK(CpuFeatures::IsSupported(ARMv8)); | 3666 DCHECK(IsEnabled(ARMv8)); |
3654 int vd, d; | 3667 int vd, d; |
3655 dst.split_code(&vd, &d); | 3668 dst.split_code(&vd, &d); |
3656 int vn, n; | 3669 int vn, n; |
3657 src1.split_code(&vn, &n); | 3670 src1.split_code(&vn, &n); |
3658 int vm, m; | 3671 int vm, m; |
3659 src2.split_code(&vm, &m); | 3672 src2.split_code(&vm, &m); |
3660 int sz = 0; | 3673 int sz = 0; |
3661 | 3674 |
3662 // VSEL has a special (restricted) condition encoding. | 3675 // VSEL has a special (restricted) condition encoding. |
3663 // eq(0b0000)... -> 0b00 | 3676 // eq(0b0000)... -> 0b00 |
(...skipping 12 matching lines...) Expand all Loading... |
3676 emit(kSpecialCondition | 0x1C * B23 | d * B22 | vsel_cond * B20 | vn * B16 | | 3689 emit(kSpecialCondition | 0x1C * B23 | d * B22 | vsel_cond * B20 | vn * B16 | |
3677 vd * B12 | 0x5 * B9 | sz * B8 | n * B7 | m * B5 | vm); | 3690 vd * B12 | 0x5 * B9 | sz * B8 | n * B7 | m * B5 | vm); |
3678 } | 3691 } |
3679 | 3692 |
3680 void Assembler::vsqrt(const DwVfpRegister dst, | 3693 void Assembler::vsqrt(const DwVfpRegister dst, |
3681 const DwVfpRegister src, | 3694 const DwVfpRegister src, |
3682 const Condition cond) { | 3695 const Condition cond) { |
3683 // Instruction details available in ARM DDI 0406C.b, A8-1058. | 3696 // Instruction details available in ARM DDI 0406C.b, A8-1058. |
3684 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0001(19-16) | | 3697 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 0001(19-16) | |
3685 // Vd(15-12) | 101(11-9) | sz=1(8) | 11(7-6) | M(5) | 0(4) | Vm(3-0) | 3698 // Vd(15-12) | 101(11-9) | sz=1(8) | 11(7-6) | M(5) | 0(4) | Vm(3-0) |
| 3699 DCHECK(VfpRegisterIsAvailable(dst)); |
| 3700 DCHECK(VfpRegisterIsAvailable(src)); |
3686 int vd, d; | 3701 int vd, d; |
3687 dst.split_code(&vd, &d); | 3702 dst.split_code(&vd, &d); |
3688 int vm, m; | 3703 int vm, m; |
3689 src.split_code(&vm, &m); | 3704 src.split_code(&vm, &m); |
3690 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | 0x3*B6 | | 3705 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | 0x3*B6 | |
3691 m*B5 | vm); | 3706 m*B5 | vm); |
3692 } | 3707 } |
3693 | 3708 |
3694 | 3709 |
3695 void Assembler::vsqrt(const SwVfpRegister dst, const SwVfpRegister src, | 3710 void Assembler::vsqrt(const SwVfpRegister dst, const SwVfpRegister src, |
(...skipping 23 matching lines...) Expand all Loading... |
3719 // cond(31-28) | 1110 (27-24) | 1111(23-20)| 0001 (19-16) | | 3734 // cond(31-28) | 1110 (27-24) | 1111(23-20)| 0001 (19-16) | |
3720 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) | 3735 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) |
3721 emit(cond | 0xE * B24 | 0xF * B20 | B16 | dst.code() * B12 | 0xA * B8 | B4); | 3736 emit(cond | 0xE * B24 | 0xF * B20 | B16 | dst.code() * B12 | 0xA * B8 | B4); |
3722 } | 3737 } |
3723 | 3738 |
3724 | 3739 |
3725 void Assembler::vrinta(const SwVfpRegister dst, const SwVfpRegister src) { | 3740 void Assembler::vrinta(const SwVfpRegister dst, const SwVfpRegister src) { |
3726 // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) | | 3741 // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) | |
3727 // 10(19-18) | RM=00(17-16) | Vd(15-12) | 101(11-9) | sz=0(8) | 01(7-6) | | 3742 // 10(19-18) | RM=00(17-16) | Vd(15-12) | 101(11-9) | sz=0(8) | 01(7-6) | |
3728 // M(5) | 0(4) | Vm(3-0) | 3743 // M(5) | 0(4) | Vm(3-0) |
3729 DCHECK(CpuFeatures::IsSupported(ARMv8)); | 3744 DCHECK(IsEnabled(ARMv8)); |
3730 int vd, d; | 3745 int vd, d; |
3731 dst.split_code(&vd, &d); | 3746 dst.split_code(&vd, &d); |
3732 int vm, m; | 3747 int vm, m; |
3733 src.split_code(&vm, &m); | 3748 src.split_code(&vm, &m); |
3734 emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | vd * B12 | | 3749 emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | vd * B12 | |
3735 0x5 * B9 | B6 | m * B5 | vm); | 3750 0x5 * B9 | B6 | m * B5 | vm); |
3736 } | 3751 } |
3737 | 3752 |
3738 | 3753 |
3739 void Assembler::vrinta(const DwVfpRegister dst, const DwVfpRegister src) { | 3754 void Assembler::vrinta(const DwVfpRegister dst, const DwVfpRegister src) { |
3740 // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) | | 3755 // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) | |
3741 // 10(19-18) | RM=00(17-16) | Vd(15-12) | 101(11-9) | sz=1(8) | 01(7-6) | | 3756 // 10(19-18) | RM=00(17-16) | Vd(15-12) | 101(11-9) | sz=1(8) | 01(7-6) | |
3742 // M(5) | 0(4) | Vm(3-0) | 3757 // M(5) | 0(4) | Vm(3-0) |
3743 DCHECK(CpuFeatures::IsSupported(ARMv8)); | 3758 DCHECK(IsEnabled(ARMv8)); |
3744 int vd, d; | 3759 int vd, d; |
3745 dst.split_code(&vd, &d); | 3760 dst.split_code(&vd, &d); |
3746 int vm, m; | 3761 int vm, m; |
3747 src.split_code(&vm, &m); | 3762 src.split_code(&vm, &m); |
3748 emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | vd * B12 | | 3763 emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | vd * B12 | |
3749 0x5 * B9 | B8 | B6 | m * B5 | vm); | 3764 0x5 * B9 | B8 | B6 | m * B5 | vm); |
3750 } | 3765 } |
3751 | 3766 |
3752 | 3767 |
3753 void Assembler::vrintn(const SwVfpRegister dst, const SwVfpRegister src) { | 3768 void Assembler::vrintn(const SwVfpRegister dst, const SwVfpRegister src) { |
3754 // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) | | 3769 // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) | |
3755 // 10(19-18) | RM=01(17-16) | Vd(15-12) | 101(11-9) | sz=0(8) | 01(7-6) | | 3770 // 10(19-18) | RM=01(17-16) | Vd(15-12) | 101(11-9) | sz=0(8) | 01(7-6) | |
3756 // M(5) | 0(4) | Vm(3-0) | 3771 // M(5) | 0(4) | Vm(3-0) |
3757 DCHECK(CpuFeatures::IsSupported(ARMv8)); | 3772 DCHECK(IsEnabled(ARMv8)); |
3758 int vd, d; | 3773 int vd, d; |
3759 dst.split_code(&vd, &d); | 3774 dst.split_code(&vd, &d); |
3760 int vm, m; | 3775 int vm, m; |
3761 src.split_code(&vm, &m); | 3776 src.split_code(&vm, &m); |
3762 emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | 0x1 * B16 | | 3777 emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | 0x1 * B16 | |
3763 vd * B12 | 0x5 * B9 | B6 | m * B5 | vm); | 3778 vd * B12 | 0x5 * B9 | B6 | m * B5 | vm); |
3764 } | 3779 } |
3765 | 3780 |
3766 | 3781 |
3767 void Assembler::vrintn(const DwVfpRegister dst, const DwVfpRegister src) { | 3782 void Assembler::vrintn(const DwVfpRegister dst, const DwVfpRegister src) { |
3768 // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) | | 3783 // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) | |
3769 // 10(19-18) | RM=01(17-16) | Vd(15-12) | 101(11-9) | sz=1(8) | 01(7-6) | | 3784 // 10(19-18) | RM=01(17-16) | Vd(15-12) | 101(11-9) | sz=1(8) | 01(7-6) | |
3770 // M(5) | 0(4) | Vm(3-0) | 3785 // M(5) | 0(4) | Vm(3-0) |
3771 DCHECK(CpuFeatures::IsSupported(ARMv8)); | 3786 DCHECK(IsEnabled(ARMv8)); |
3772 int vd, d; | 3787 int vd, d; |
3773 dst.split_code(&vd, &d); | 3788 dst.split_code(&vd, &d); |
3774 int vm, m; | 3789 int vm, m; |
3775 src.split_code(&vm, &m); | 3790 src.split_code(&vm, &m); |
3776 emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | 0x1 * B16 | | 3791 emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | 0x1 * B16 | |
3777 vd * B12 | 0x5 * B9 | B8 | B6 | m * B5 | vm); | 3792 vd * B12 | 0x5 * B9 | B8 | B6 | m * B5 | vm); |
3778 } | 3793 } |
3779 | 3794 |
3780 | 3795 |
3781 void Assembler::vrintp(const SwVfpRegister dst, const SwVfpRegister src) { | 3796 void Assembler::vrintp(const SwVfpRegister dst, const SwVfpRegister src) { |
3782 // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) | | 3797 // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) | |
3783 // 10(19-18) | RM=10(17-16) | Vd(15-12) | 101(11-9) | sz=0(8) | 01(7-6) | | 3798 // 10(19-18) | RM=10(17-16) | Vd(15-12) | 101(11-9) | sz=0(8) | 01(7-6) | |
3784 // M(5) | 0(4) | Vm(3-0) | 3799 // M(5) | 0(4) | Vm(3-0) |
3785 DCHECK(CpuFeatures::IsSupported(ARMv8)); | 3800 DCHECK(IsEnabled(ARMv8)); |
3786 int vd, d; | 3801 int vd, d; |
3787 dst.split_code(&vd, &d); | 3802 dst.split_code(&vd, &d); |
3788 int vm, m; | 3803 int vm, m; |
3789 src.split_code(&vm, &m); | 3804 src.split_code(&vm, &m); |
3790 emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | 0x2 * B16 | | 3805 emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | 0x2 * B16 | |
3791 vd * B12 | 0x5 * B9 | B6 | m * B5 | vm); | 3806 vd * B12 | 0x5 * B9 | B6 | m * B5 | vm); |
3792 } | 3807 } |
3793 | 3808 |
3794 | 3809 |
3795 void Assembler::vrintp(const DwVfpRegister dst, const DwVfpRegister src) { | 3810 void Assembler::vrintp(const DwVfpRegister dst, const DwVfpRegister src) { |
3796 // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) | | 3811 // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) | |
3797 // 10(19-18) | RM=10(17-16) | Vd(15-12) | 101(11-9) | sz=1(8) | 01(7-6) | | 3812 // 10(19-18) | RM=10(17-16) | Vd(15-12) | 101(11-9) | sz=1(8) | 01(7-6) | |
3798 // M(5) | 0(4) | Vm(3-0) | 3813 // M(5) | 0(4) | Vm(3-0) |
3799 DCHECK(CpuFeatures::IsSupported(ARMv8)); | 3814 DCHECK(IsEnabled(ARMv8)); |
3800 int vd, d; | 3815 int vd, d; |
3801 dst.split_code(&vd, &d); | 3816 dst.split_code(&vd, &d); |
3802 int vm, m; | 3817 int vm, m; |
3803 src.split_code(&vm, &m); | 3818 src.split_code(&vm, &m); |
3804 emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | 0x2 * B16 | | 3819 emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | 0x2 * B16 | |
3805 vd * B12 | 0x5 * B9 | B8 | B6 | m * B5 | vm); | 3820 vd * B12 | 0x5 * B9 | B8 | B6 | m * B5 | vm); |
3806 } | 3821 } |
3807 | 3822 |
3808 | 3823 |
3809 void Assembler::vrintm(const SwVfpRegister dst, const SwVfpRegister src) { | 3824 void Assembler::vrintm(const SwVfpRegister dst, const SwVfpRegister src) { |
3810 // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) | | 3825 // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) | |
3811 // 10(19-18) | RM=11(17-16) | Vd(15-12) | 101(11-9) | sz=0(8) | 01(7-6) | | 3826 // 10(19-18) | RM=11(17-16) | Vd(15-12) | 101(11-9) | sz=0(8) | 01(7-6) | |
3812 // M(5) | 0(4) | Vm(3-0) | 3827 // M(5) | 0(4) | Vm(3-0) |
3813 DCHECK(CpuFeatures::IsSupported(ARMv8)); | 3828 DCHECK(IsEnabled(ARMv8)); |
3814 int vd, d; | 3829 int vd, d; |
3815 dst.split_code(&vd, &d); | 3830 dst.split_code(&vd, &d); |
3816 int vm, m; | 3831 int vm, m; |
3817 src.split_code(&vm, &m); | 3832 src.split_code(&vm, &m); |
3818 emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | 0x3 * B16 | | 3833 emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | 0x3 * B16 | |
3819 vd * B12 | 0x5 * B9 | B6 | m * B5 | vm); | 3834 vd * B12 | 0x5 * B9 | B6 | m * B5 | vm); |
3820 } | 3835 } |
3821 | 3836 |
3822 | 3837 |
3823 void Assembler::vrintm(const DwVfpRegister dst, const DwVfpRegister src) { | 3838 void Assembler::vrintm(const DwVfpRegister dst, const DwVfpRegister src) { |
3824 // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) | | 3839 // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) | |
3825 // 10(19-18) | RM=11(17-16) | Vd(15-12) | 101(11-9) | sz=1(8) | 01(7-6) | | 3840 // 10(19-18) | RM=11(17-16) | Vd(15-12) | 101(11-9) | sz=1(8) | 01(7-6) | |
3826 // M(5) | 0(4) | Vm(3-0) | 3841 // M(5) | 0(4) | Vm(3-0) |
3827 DCHECK(CpuFeatures::IsSupported(ARMv8)); | 3842 DCHECK(IsEnabled(ARMv8)); |
3828 int vd, d; | 3843 int vd, d; |
3829 dst.split_code(&vd, &d); | 3844 dst.split_code(&vd, &d); |
3830 int vm, m; | 3845 int vm, m; |
3831 src.split_code(&vm, &m); | 3846 src.split_code(&vm, &m); |
3832 emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | 0x3 * B16 | | 3847 emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | 0x3 * B16 | |
3833 vd * B12 | 0x5 * B9 | B8 | B6 | m * B5 | vm); | 3848 vd * B12 | 0x5 * B9 | B8 | B6 | m * B5 | vm); |
3834 } | 3849 } |
3835 | 3850 |
3836 | 3851 |
3837 void Assembler::vrintz(const SwVfpRegister dst, const SwVfpRegister src, | 3852 void Assembler::vrintz(const SwVfpRegister dst, const SwVfpRegister src, |
3838 const Condition cond) { | 3853 const Condition cond) { |
3839 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 011(19-17) | 0(16) | | 3854 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 011(19-17) | 0(16) | |
3840 // Vd(15-12) | 101(11-9) | sz=0(8) | op=1(7) | 1(6) | M(5) | 0(4) | Vm(3-0) | 3855 // Vd(15-12) | 101(11-9) | sz=0(8) | op=1(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
3841 DCHECK(CpuFeatures::IsSupported(ARMv8)); | 3856 DCHECK(IsEnabled(ARMv8)); |
3842 int vd, d; | 3857 int vd, d; |
3843 dst.split_code(&vd, &d); | 3858 dst.split_code(&vd, &d); |
3844 int vm, m; | 3859 int vm, m; |
3845 src.split_code(&vm, &m); | 3860 src.split_code(&vm, &m); |
3846 emit(cond | 0x1D * B23 | d * B22 | 0x3 * B20 | 0x3 * B17 | vd * B12 | | 3861 emit(cond | 0x1D * B23 | d * B22 | 0x3 * B20 | 0x3 * B17 | vd * B12 | |
3847 0x5 * B9 | B7 | B6 | m * B5 | vm); | 3862 0x5 * B9 | B7 | B6 | m * B5 | vm); |
3848 } | 3863 } |
3849 | 3864 |
3850 | 3865 |
3851 void Assembler::vrintz(const DwVfpRegister dst, const DwVfpRegister src, | 3866 void Assembler::vrintz(const DwVfpRegister dst, const DwVfpRegister src, |
3852 const Condition cond) { | 3867 const Condition cond) { |
3853 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 011(19-17) | 0(16) | | 3868 // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 011(19-17) | 0(16) | |
3854 // Vd(15-12) | 101(11-9) | sz=1(8) | op=1(7) | 1(6) | M(5) | 0(4) | Vm(3-0) | 3869 // Vd(15-12) | 101(11-9) | sz=1(8) | op=1(7) | 1(6) | M(5) | 0(4) | Vm(3-0) |
3855 DCHECK(CpuFeatures::IsSupported(ARMv8)); | 3870 DCHECK(IsEnabled(ARMv8)); |
3856 int vd, d; | 3871 int vd, d; |
3857 dst.split_code(&vd, &d); | 3872 dst.split_code(&vd, &d); |
3858 int vm, m; | 3873 int vm, m; |
3859 src.split_code(&vm, &m); | 3874 src.split_code(&vm, &m); |
3860 emit(cond | 0x1D * B23 | d * B22 | 0x3 * B20 | 0x3 * B17 | vd * B12 | | 3875 emit(cond | 0x1D * B23 | d * B22 | 0x3 * B20 | 0x3 * B17 | vd * B12 | |
3861 0x5 * B9 | B8 | B7 | B6 | m * B5 | vm); | 3876 0x5 * B9 | B8 | B7 | B6 | m * B5 | vm); |
3862 } | 3877 } |
3863 | 3878 |
3864 | 3879 |
3865 // Support for NEON. | 3880 // Support for NEON. |
3866 | 3881 |
3867 void Assembler::vld1(NeonSize size, | 3882 void Assembler::vld1(NeonSize size, |
3868 const NeonListOperand& dst, | 3883 const NeonListOperand& dst, |
3869 const NeonMemOperand& src) { | 3884 const NeonMemOperand& src) { |
3870 // Instruction details available in ARM DDI 0406C.b, A8.8.320. | 3885 // Instruction details available in ARM DDI 0406C.b, A8.8.320. |
3871 // 1111(31-28) | 01000(27-23) | D(22) | 10(21-20) | Rn(19-16) | | 3886 // 1111(31-28) | 01000(27-23) | D(22) | 10(21-20) | Rn(19-16) | |
3872 // Vd(15-12) | type(11-8) | size(7-6) | align(5-4) | Rm(3-0) | 3887 // Vd(15-12) | type(11-8) | size(7-6) | align(5-4) | Rm(3-0) |
3873 DCHECK(CpuFeatures::IsSupported(NEON)); | 3888 DCHECK(IsEnabled(NEON)); |
3874 int vd, d; | 3889 int vd, d; |
3875 dst.base().split_code(&vd, &d); | 3890 dst.base().split_code(&vd, &d); |
3876 emit(0xFU*B28 | 4*B24 | d*B22 | 2*B20 | src.rn().code()*B16 | vd*B12 | | 3891 emit(0xFU*B28 | 4*B24 | d*B22 | 2*B20 | src.rn().code()*B16 | vd*B12 | |
3877 dst.type()*B8 | size*B6 | src.align()*B4 | src.rm().code()); | 3892 dst.type()*B8 | size*B6 | src.align()*B4 | src.rm().code()); |
3878 } | 3893 } |
3879 | 3894 |
3880 | 3895 |
3881 void Assembler::vst1(NeonSize size, | 3896 void Assembler::vst1(NeonSize size, |
3882 const NeonListOperand& src, | 3897 const NeonListOperand& src, |
3883 const NeonMemOperand& dst) { | 3898 const NeonMemOperand& dst) { |
3884 // Instruction details available in ARM DDI 0406C.b, A8.8.404. | 3899 // Instruction details available in ARM DDI 0406C.b, A8.8.404. |
3885 // 1111(31-28) | 01000(27-23) | D(22) | 00(21-20) | Rn(19-16) | | 3900 // 1111(31-28) | 01000(27-23) | D(22) | 00(21-20) | Rn(19-16) | |
3886 // Vd(15-12) | type(11-8) | size(7-6) | align(5-4) | Rm(3-0) | 3901 // Vd(15-12) | type(11-8) | size(7-6) | align(5-4) | Rm(3-0) |
3887 DCHECK(CpuFeatures::IsSupported(NEON)); | 3902 DCHECK(IsEnabled(NEON)); |
3888 int vd, d; | 3903 int vd, d; |
3889 src.base().split_code(&vd, &d); | 3904 src.base().split_code(&vd, &d); |
3890 emit(0xFU*B28 | 4*B24 | d*B22 | dst.rn().code()*B16 | vd*B12 | src.type()*B8 | | 3905 emit(0xFU*B28 | 4*B24 | d*B22 | dst.rn().code()*B16 | vd*B12 | src.type()*B8 | |
3891 size*B6 | dst.align()*B4 | dst.rm().code()); | 3906 size*B6 | dst.align()*B4 | dst.rm().code()); |
3892 } | 3907 } |
3893 | 3908 |
3894 | 3909 |
3895 void Assembler::vmovl(NeonDataType dt, QwNeonRegister dst, DwVfpRegister src) { | 3910 void Assembler::vmovl(NeonDataType dt, QwNeonRegister dst, DwVfpRegister src) { |
3896 // Instruction details available in ARM DDI 0406C.b, A8.8.346. | 3911 // Instruction details available in ARM DDI 0406C.b, A8.8.346. |
3897 // 1111(31-28) | 001(27-25) | U(24) | 1(23) | D(22) | imm3(21-19) | | 3912 // 1111(31-28) | 001(27-25) | U(24) | 1(23) | D(22) | imm3(21-19) | |
3898 // 000(18-16) | Vd(15-12) | 101000(11-6) | M(5) | 1(4) | Vm(3-0) | 3913 // 000(18-16) | Vd(15-12) | 101000(11-6) | M(5) | 1(4) | Vm(3-0) |
3899 DCHECK(CpuFeatures::IsSupported(NEON)); | 3914 DCHECK(IsEnabled(NEON)); |
3900 int vd, d; | 3915 int vd, d; |
3901 dst.split_code(&vd, &d); | 3916 dst.split_code(&vd, &d); |
3902 int vm, m; | 3917 int vm, m; |
3903 src.split_code(&vm, &m); | 3918 src.split_code(&vm, &m); |
3904 emit(0xFU*B28 | B25 | (dt & NeonDataTypeUMask) | B23 | d*B22 | | 3919 emit(0xFU*B28 | B25 | (dt & NeonDataTypeUMask) | B23 | d*B22 | |
3905 (dt & NeonDataTypeSizeMask)*B19 | vd*B12 | 0xA*B8 | m*B5 | B4 | vm); | 3920 (dt & NeonDataTypeSizeMask)*B19 | vd*B12 | 0xA*B8 | m*B5 | B4 | vm); |
3906 } | 3921 } |
3907 | 3922 |
3908 void Assembler::vswp(DwVfpRegister srcdst0, DwVfpRegister srcdst1) { | 3923 void Assembler::vswp(DwVfpRegister srcdst0, DwVfpRegister srcdst1) { |
| 3924 DCHECK(VfpRegisterIsAvailable(srcdst0)); |
| 3925 DCHECK(VfpRegisterIsAvailable(srcdst1)); |
3909 DCHECK(!srcdst0.is(kScratchDoubleReg)); | 3926 DCHECK(!srcdst0.is(kScratchDoubleReg)); |
3910 DCHECK(!srcdst1.is(kScratchDoubleReg)); | 3927 DCHECK(!srcdst1.is(kScratchDoubleReg)); |
3911 | 3928 |
3912 if (srcdst0.is(srcdst1)) return; // Swapping aliased registers emits nothing. | 3929 if (srcdst0.is(srcdst1)) return; // Swapping aliased registers emits nothing. |
3913 | 3930 |
3914 if (CpuFeatures::IsSupported(NEON)) { | 3931 if (CpuFeatures::IsSupported(NEON)) { |
3915 // Instruction details available in ARM DDI 0406C.b, A8.8.418. | 3932 // Instruction details available in ARM DDI 0406C.b, A8.8.418. |
3916 // 1111(31-28) | 00111(27-23) | D(22) | 110010(21-16) | | 3933 // 1111(31-28) | 00111(27-23) | D(22) | 110010(21-16) | |
3917 // Vd(15-12) | 000000(11-6) | M(5) | 0(4) | Vm(3-0) | 3934 // Vd(15-12) | 000000(11-6) | M(5) | 0(4) | Vm(3-0) |
3918 int vd, d; | 3935 int vd, d; |
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4424 void Assembler::PatchConstantPoolAccessInstruction( | 4441 void Assembler::PatchConstantPoolAccessInstruction( |
4425 int pc_offset, int offset, ConstantPoolEntry::Access access, | 4442 int pc_offset, int offset, ConstantPoolEntry::Access access, |
4426 ConstantPoolEntry::Type type) { | 4443 ConstantPoolEntry::Type type) { |
4427 DCHECK(FLAG_enable_embedded_constant_pool); | 4444 DCHECK(FLAG_enable_embedded_constant_pool); |
4428 Address pc = buffer_ + pc_offset; | 4445 Address pc = buffer_ + pc_offset; |
4429 | 4446 |
4430 // Patch vldr/ldr instruction with correct offset. | 4447 // Patch vldr/ldr instruction with correct offset. |
4431 Instr instr = instr_at(pc); | 4448 Instr instr = instr_at(pc); |
4432 if (access == ConstantPoolEntry::OVERFLOWED) { | 4449 if (access == ConstantPoolEntry::OVERFLOWED) { |
4433 if (CpuFeatures::IsSupported(ARMv7)) { | 4450 if (CpuFeatures::IsSupported(ARMv7)) { |
| 4451 CpuFeatureScope scope(this, ARMv7); |
4434 // Instructions to patch must be 'movw rd, [#0]' and 'movt rd, [#0]. | 4452 // Instructions to patch must be 'movw rd, [#0]' and 'movt rd, [#0]. |
4435 Instr next_instr = instr_at(pc + kInstrSize); | 4453 Instr next_instr = instr_at(pc + kInstrSize); |
4436 DCHECK((IsMovW(instr) && Instruction::ImmedMovwMovtValue(instr) == 0)); | 4454 DCHECK((IsMovW(instr) && Instruction::ImmedMovwMovtValue(instr) == 0)); |
4437 DCHECK((IsMovT(next_instr) && | 4455 DCHECK((IsMovT(next_instr) && |
4438 Instruction::ImmedMovwMovtValue(next_instr) == 0)); | 4456 Instruction::ImmedMovwMovtValue(next_instr) == 0)); |
4439 instr_at_put(pc, PatchMovwImmediate(instr, offset & 0xffff)); | 4457 instr_at_put(pc, PatchMovwImmediate(instr, offset & 0xffff)); |
4440 instr_at_put(pc + kInstrSize, | 4458 instr_at_put(pc + kInstrSize, |
4441 PatchMovwImmediate(next_instr, offset >> 16)); | 4459 PatchMovwImmediate(next_instr, offset >> 16)); |
4442 } else { | 4460 } else { |
4443 // Instructions to patch must be 'mov rd, [#0]' and 'orr rd, rd, [#0]. | 4461 // Instructions to patch must be 'mov rd, [#0]' and 'orr rd, rd, [#0]. |
(...skipping 28 matching lines...) Expand all Loading... |
4472 DCHECK(is_uint12(offset)); | 4490 DCHECK(is_uint12(offset)); |
4473 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset)); | 4491 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset)); |
4474 } | 4492 } |
4475 } | 4493 } |
4476 | 4494 |
4477 | 4495 |
4478 } // namespace internal | 4496 } // namespace internal |
4479 } // namespace v8 | 4497 } // namespace v8 |
4480 | 4498 |
4481 #endif // V8_TARGET_ARCH_ARM | 4499 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |