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

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

Issue 2360243002: [arm] Clean up use of IsSupported and IsEnabled. (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/assembler-arm-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/assembler-arm-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698