| 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 |