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

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

Issue 148153010: Synchronize with r15701. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/codegen-arm.cc » ('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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 #include "serialize.h" 42 #include "serialize.h"
43 43
44 namespace v8 { 44 namespace v8 {
45 namespace internal { 45 namespace internal {
46 46
47 #ifdef DEBUG 47 #ifdef DEBUG
48 bool CpuFeatures::initialized_ = false; 48 bool CpuFeatures::initialized_ = false;
49 #endif 49 #endif
50 unsigned CpuFeatures::supported_ = 0; 50 unsigned CpuFeatures::supported_ = 0;
51 unsigned CpuFeatures::found_by_runtime_probing_only_ = 0; 51 unsigned CpuFeatures::found_by_runtime_probing_only_ = 0;
52 unsigned CpuFeatures::cache_line_size_ = 64;
52 53
53 54
54 ExternalReference ExternalReference::cpu_features() { 55 ExternalReference ExternalReference::cpu_features() {
55 ASSERT(CpuFeatures::initialized_); 56 ASSERT(CpuFeatures::initialized_);
56 return ExternalReference(&CpuFeatures::supported_); 57 return ExternalReference(&CpuFeatures::supported_);
57 } 58 }
58 59
59 60
60 // Get the CPU features enabled by the build. For cross compilation the 61 // Get the CPU features enabled by the build. For cross compilation the
61 // preprocessor symbols CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP3_INSTRUCTIONS 62 // preprocessor symbols CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP3_INSTRUCTIONS
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 } 119 }
119 120
120 #ifndef __arm__ 121 #ifndef __arm__
121 // For the simulator=arm build, use VFP when FLAG_enable_vfp3 is 122 // For the simulator=arm build, use VFP when FLAG_enable_vfp3 is
122 // enabled. VFPv3 implies ARMv7, see ARM DDI 0406B, page A1-6. 123 // enabled. VFPv3 implies ARMv7, see ARM DDI 0406B, page A1-6.
123 if (FLAG_enable_vfp3) { 124 if (FLAG_enable_vfp3) {
124 supported_ |= 125 supported_ |=
125 static_cast<uint64_t>(1) << VFP3 | 126 static_cast<uint64_t>(1) << VFP3 |
126 static_cast<uint64_t>(1) << ARMv7; 127 static_cast<uint64_t>(1) << ARMv7;
127 } 128 }
129 if (FLAG_enable_neon) {
130 supported_ |= 1u << NEON;
131 }
128 // For the simulator=arm build, use ARMv7 when FLAG_enable_armv7 is enabled 132 // For the simulator=arm build, use ARMv7 when FLAG_enable_armv7 is enabled
129 if (FLAG_enable_armv7) { 133 if (FLAG_enable_armv7) {
130 supported_ |= static_cast<uint64_t>(1) << ARMv7; 134 supported_ |= static_cast<uint64_t>(1) << ARMv7;
131 } 135 }
132 136
133 if (FLAG_enable_sudiv) { 137 if (FLAG_enable_sudiv) {
134 supported_ |= static_cast<uint64_t>(1) << SUDIV; 138 supported_ |= static_cast<uint64_t>(1) << SUDIV;
135 } 139 }
136 140
137 if (FLAG_enable_movw_movt) { 141 if (FLAG_enable_movw_movt) {
(...skipping 12 matching lines...) Expand all
150 // Probe for additional features not already known to be available. 154 // Probe for additional features not already known to be available.
151 if (!IsSupported(VFP3) && FLAG_enable_vfp3 && OS::ArmCpuHasFeature(VFP3)) { 155 if (!IsSupported(VFP3) && FLAG_enable_vfp3 && OS::ArmCpuHasFeature(VFP3)) {
152 // This implementation also sets the VFP flags if runtime 156 // This implementation also sets the VFP flags if runtime
153 // detection of VFP returns true. VFPv3 implies ARMv7, see ARM DDI 157 // detection of VFP returns true. VFPv3 implies ARMv7, see ARM DDI
154 // 0406B, page A1-6. 158 // 0406B, page A1-6.
155 found_by_runtime_probing_only_ |= 159 found_by_runtime_probing_only_ |=
156 static_cast<uint64_t>(1) << VFP3 | 160 static_cast<uint64_t>(1) << VFP3 |
157 static_cast<uint64_t>(1) << ARMv7; 161 static_cast<uint64_t>(1) << ARMv7;
158 } 162 }
159 163
164 if (!IsSupported(NEON) && FLAG_enable_neon && OS::ArmCpuHasFeature(NEON)) {
165 found_by_runtime_probing_only_ |= 1u << NEON;
166 }
167
160 if (!IsSupported(ARMv7) && FLAG_enable_armv7 && OS::ArmCpuHasFeature(ARMv7)) { 168 if (!IsSupported(ARMv7) && FLAG_enable_armv7 && OS::ArmCpuHasFeature(ARMv7)) {
161 found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << ARMv7; 169 found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << ARMv7;
162 } 170 }
163 171
164 if (!IsSupported(SUDIV) && FLAG_enable_sudiv && OS::ArmCpuHasFeature(SUDIV)) { 172 if (!IsSupported(SUDIV) && FLAG_enable_sudiv && OS::ArmCpuHasFeature(SUDIV)) {
165 found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << SUDIV; 173 found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << SUDIV;
166 } 174 }
167 175
168 if (!IsSupported(UNALIGNED_ACCESSES) && FLAG_enable_unaligned_accesses 176 if (!IsSupported(UNALIGNED_ACCESSES) && FLAG_enable_unaligned_accesses
169 && OS::ArmCpuHasFeature(ARMv7)) { 177 && OS::ArmCpuHasFeature(ARMv7)) {
170 found_by_runtime_probing_only_ |= 178 found_by_runtime_probing_only_ |=
171 static_cast<uint64_t>(1) << UNALIGNED_ACCESSES; 179 static_cast<uint64_t>(1) << UNALIGNED_ACCESSES;
172 } 180 }
173 181
174 if (OS::GetCpuImplementer() == QUALCOMM_IMPLEMENTER && 182 CpuImplementer implementer = OS::GetCpuImplementer();
183 if (implementer == QUALCOMM_IMPLEMENTER &&
175 FLAG_enable_movw_movt && OS::ArmCpuHasFeature(ARMv7)) { 184 FLAG_enable_movw_movt && OS::ArmCpuHasFeature(ARMv7)) {
176 found_by_runtime_probing_only_ |= 185 found_by_runtime_probing_only_ |=
177 static_cast<uint64_t>(1) << MOVW_MOVT_IMMEDIATE_LOADS; 186 static_cast<uint64_t>(1) << MOVW_MOVT_IMMEDIATE_LOADS;
178 } 187 }
179 188
189 CpuPart part = OS::GetCpuPart(implementer);
190 if ((part == CORTEX_A9) || (part == CORTEX_A5)) {
191 cache_line_size_ = 32;
192 }
193
180 if (!IsSupported(VFP32DREGS) && FLAG_enable_32dregs 194 if (!IsSupported(VFP32DREGS) && FLAG_enable_32dregs
181 && OS::ArmCpuHasFeature(VFP32DREGS)) { 195 && OS::ArmCpuHasFeature(VFP32DREGS)) {
182 found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << VFP32DREGS; 196 found_by_runtime_probing_only_ |= static_cast<uint64_t>(1) << VFP32DREGS;
183 } 197 }
184 198
185 supported_ |= found_by_runtime_probing_only_; 199 supported_ |= found_by_runtime_probing_only_;
186 #endif 200 #endif
187 201
188 // Assert that VFP3 implies ARMv7. 202 // Assert that VFP3 implies ARMv7.
189 ASSERT(!IsSupported(VFP3) || IsSupported(ARMv7)); 203 ASSERT(!IsSupported(VFP3) || IsSupported(ARMv7));
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 254
241 #endif // __arm__ 255 #endif // __arm__
242 256
243 printf("target%s %s%s%s %s\n", 257 printf("target%s %s%s%s %s\n",
244 arm_test, arm_arch, arm_fpu, arm_thumb, arm_float_abi); 258 arm_test, arm_arch, arm_fpu, arm_thumb, arm_float_abi);
245 } 259 }
246 260
247 261
248 void CpuFeatures::PrintFeatures() { 262 void CpuFeatures::PrintFeatures() {
249 printf( 263 printf(
250 "ARMv7=%d VFP3=%d VFP32DREGS=%d SUDIV=%d UNALIGNED_ACCESSES=%d " 264 "ARMv7=%d VFP3=%d VFP32DREGS=%d NEON=%d SUDIV=%d UNALIGNED_ACCESSES=%d "
251 "MOVW_MOVT_IMMEDIATE_LOADS=%d", 265 "MOVW_MOVT_IMMEDIATE_LOADS=%d",
252 CpuFeatures::IsSupported(ARMv7), 266 CpuFeatures::IsSupported(ARMv7),
253 CpuFeatures::IsSupported(VFP3), 267 CpuFeatures::IsSupported(VFP3),
254 CpuFeatures::IsSupported(VFP32DREGS), 268 CpuFeatures::IsSupported(VFP32DREGS),
269 CpuFeatures::IsSupported(NEON),
255 CpuFeatures::IsSupported(SUDIV), 270 CpuFeatures::IsSupported(SUDIV),
256 CpuFeatures::IsSupported(UNALIGNED_ACCESSES), 271 CpuFeatures::IsSupported(UNALIGNED_ACCESSES),
257 CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS)); 272 CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS));
258 #ifdef __arm__ 273 #ifdef __arm__
259 bool eabi_hardfloat = OS::ArmUsingHardFloat(); 274 bool eabi_hardfloat = OS::ArmUsingHardFloat();
260 #elif USE_EABI_HARDFLOAT 275 #elif USE_EABI_HARDFLOAT
261 bool eabi_hardfloat = true; 276 bool eabi_hardfloat = true;
262 #else 277 #else
263 bool eabi_hardfloat = false; 278 bool eabi_hardfloat = false;
264 #endif 279 #endif
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 ShiftOp shift_op, int shift_imm, AddrMode am) { 386 ShiftOp shift_op, int shift_imm, AddrMode am) {
372 ASSERT(is_uint5(shift_imm)); 387 ASSERT(is_uint5(shift_imm));
373 rn_ = rn; 388 rn_ = rn;
374 rm_ = rm; 389 rm_ = rm;
375 shift_op_ = shift_op; 390 shift_op_ = shift_op;
376 shift_imm_ = shift_imm & 31; 391 shift_imm_ = shift_imm & 31;
377 am_ = am; 392 am_ = am;
378 } 393 }
379 394
380 395
396 NeonMemOperand::NeonMemOperand(Register rn, AddrMode am, int align) {
397 ASSERT((am == Offset) || (am == PostIndex));
398 rn_ = rn;
399 rm_ = (am == Offset) ? pc : sp;
400 SetAlignment(align);
401 }
402
403
404 NeonMemOperand::NeonMemOperand(Register rn, Register rm, int align) {
405 rn_ = rn;
406 rm_ = rm;
407 SetAlignment(align);
408 }
409
410
411 void NeonMemOperand::SetAlignment(int align) {
412 switch (align) {
413 case 0:
414 align_ = 0;
415 break;
416 case 64:
417 align_ = 1;
418 break;
419 case 128:
420 align_ = 2;
421 break;
422 case 256:
423 align_ = 3;
424 break;
425 default:
426 UNREACHABLE();
427 align_ = 0;
428 break;
429 }
430 }
431
432
433 NeonListOperand::NeonListOperand(DoubleRegister base, int registers_count) {
434 base_ = base;
435 switch (registers_count) {
436 case 1:
437 type_ = nlt_1;
438 break;
439 case 2:
440 type_ = nlt_2;
441 break;
442 case 3:
443 type_ = nlt_3;
444 break;
445 case 4:
446 type_ = nlt_4;
447 break;
448 default:
449 UNREACHABLE();
450 type_ = nlt_1;
451 break;
452 }
453 }
454
455
381 // ----------------------------------------------------------------------------- 456 // -----------------------------------------------------------------------------
382 // Specific instructions, constants, and masks. 457 // Specific instructions, constants, and masks.
383 458
384 // add(sp, sp, 4) instruction (aka Pop()) 459 // add(sp, sp, 4) instruction (aka Pop())
385 const Instr kPopInstruction = 460 const Instr kPopInstruction =
386 al | PostIndex | 4 | LeaveCC | I | kRegister_sp_Code * B16 | 461 al | PostIndex | 4 | LeaveCC | I | kRegister_sp_Code * B16 |
387 kRegister_sp_Code * B12; 462 kRegister_sp_Code * B12;
388 // str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r)) 463 // str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r))
389 // register r is not encoded. 464 // register r is not encoded.
390 const Instr kPushRegPattern = 465 const Instr kPushRegPattern =
(...skipping 1148 matching lines...) Expand 10 before | Expand all | Expand 10 after
1539 ASSERT(CpuFeatures::IsSupported(ARMv7)); 1614 ASSERT(CpuFeatures::IsSupported(ARMv7));
1540 ASSERT(!dst.is(pc) && !src.is(pc)); 1615 ASSERT(!dst.is(pc) && !src.is(pc));
1541 ASSERT((lsb >= 0) && (lsb <= 31)); 1616 ASSERT((lsb >= 0) && (lsb <= 31));
1542 ASSERT((width >= 1) && (width <= (32 - lsb))); 1617 ASSERT((width >= 1) && (width <= (32 - lsb)));
1543 int msb = lsb + width - 1; 1618 int msb = lsb + width - 1;
1544 emit(cond | 0x1f*B22 | msb*B16 | dst.code()*B12 | lsb*B7 | B4 | 1619 emit(cond | 0x1f*B22 | msb*B16 | dst.code()*B12 | lsb*B7 | B4 |
1545 src.code()); 1620 src.code());
1546 } 1621 }
1547 1622
1548 1623
1624 void Assembler::pkhbt(Register dst,
1625 Register src1,
1626 const Operand& src2,
1627 Condition cond ) {
1628 // Instruction details available in ARM DDI 0406C.b, A8.8.125.
1629 // cond(31-28) | 01101000(27-20) | Rn(19-16) |
1630 // Rd(15-12) | imm5(11-7) | 0(6) | 01(5-4) | Rm(3-0)
1631 ASSERT(!dst.is(pc));
1632 ASSERT(!src1.is(pc));
1633 ASSERT(!src2.rm().is(pc));
1634 ASSERT(!src2.rm().is(no_reg));
1635 ASSERT(src2.rs().is(no_reg));
1636 ASSERT((src2.shift_imm_ >= 0) && (src2.shift_imm_ <= 31));
1637 ASSERT(src2.shift_op() == LSL);
1638 emit(cond | 0x68*B20 | src1.code()*B16 | dst.code()*B12 |
1639 src2.shift_imm_*B7 | B4 | src2.rm().code());
1640 }
1641
1642
1643 void Assembler::pkhtb(Register dst,
1644 Register src1,
1645 const Operand& src2,
1646 Condition cond) {
1647 // Instruction details available in ARM DDI 0406C.b, A8.8.125.
1648 // cond(31-28) | 01101000(27-20) | Rn(19-16) |
1649 // Rd(15-12) | imm5(11-7) | 1(6) | 01(5-4) | Rm(3-0)
1650 ASSERT(!dst.is(pc));
1651 ASSERT(!src1.is(pc));
1652 ASSERT(!src2.rm().is(pc));
1653 ASSERT(!src2.rm().is(no_reg));
1654 ASSERT(src2.rs().is(no_reg));
1655 ASSERT((src2.shift_imm_ >= 1) && (src2.shift_imm_ <= 32));
1656 ASSERT(src2.shift_op() == ASR);
1657 int asr = (src2.shift_imm_ == 32) ? 0 : src2.shift_imm_;
1658 emit(cond | 0x68*B20 | src1.code()*B16 | dst.code()*B12 |
1659 asr*B7 | B6 | B4 | src2.rm().code());
1660 }
1661
1662
1663 void Assembler::uxtb(Register dst,
1664 const Operand& src,
1665 Condition cond) {
1666 // Instruction details available in ARM DDI 0406C.b, A8.8.274.
1667 // cond(31-28) | 01101110(27-20) | 1111(19-16) |
1668 // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
1669 ASSERT(!dst.is(pc));
1670 ASSERT(!src.rm().is(pc));
1671 ASSERT(!src.rm().is(no_reg));
1672 ASSERT(src.rs().is(no_reg));
1673 ASSERT((src.shift_imm_ == 0) ||
1674 (src.shift_imm_ == 8) ||
1675 (src.shift_imm_ == 16) ||
1676 (src.shift_imm_ == 24));
1677 ASSERT(src.shift_op() == ROR);
1678 emit(cond | 0x6E*B20 | 0xF*B16 | dst.code()*B12 |
1679 ((src.shift_imm_ >> 1)&0xC)*B8 | 7*B4 | src.rm().code());
1680 }
1681
1682
1683 void Assembler::uxtab(Register dst,
1684 Register src1,
1685 const Operand& src2,
1686 Condition cond) {
1687 // Instruction details available in ARM DDI 0406C.b, A8.8.271.
1688 // cond(31-28) | 01101110(27-20) | Rn(19-16) |
1689 // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
1690 ASSERT(!dst.is(pc));
1691 ASSERT(!src1.is(pc));
1692 ASSERT(!src2.rm().is(pc));
1693 ASSERT(!src2.rm().is(no_reg));
1694 ASSERT(src2.rs().is(no_reg));
1695 ASSERT((src2.shift_imm_ == 0) ||
1696 (src2.shift_imm_ == 8) ||
1697 (src2.shift_imm_ == 16) ||
1698 (src2.shift_imm_ == 24));
1699 ASSERT(src2.shift_op() == ROR);
1700 emit(cond | 0x6E*B20 | src1.code()*B16 | dst.code()*B12 |
1701 ((src2.shift_imm_ >> 1) &0xC)*B8 | 7*B4 | src2.rm().code());
1702 }
1703
1704
1705 void Assembler::uxtb16(Register dst,
1706 const Operand& src,
1707 Condition cond) {
1708 // Instruction details available in ARM DDI 0406C.b, A8.8.275.
1709 // cond(31-28) | 01101100(27-20) | 1111(19-16) |
1710 // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
1711 ASSERT(!dst.is(pc));
1712 ASSERT(!src.rm().is(pc));
1713 ASSERT(!src.rm().is(no_reg));
1714 ASSERT(src.rs().is(no_reg));
1715 ASSERT((src.shift_imm_ == 0) ||
1716 (src.shift_imm_ == 8) ||
1717 (src.shift_imm_ == 16) ||
1718 (src.shift_imm_ == 24));
1719 ASSERT(src.shift_op() == ROR);
1720 emit(cond | 0x6C*B20 | 0xF*B16 | dst.code()*B12 |
1721 ((src.shift_imm_ >> 1)&0xC)*B8 | 7*B4 | src.rm().code());
1722 }
1723
1724
1549 // Status register access instructions. 1725 // Status register access instructions.
1550 void Assembler::mrs(Register dst, SRegister s, Condition cond) { 1726 void Assembler::mrs(Register dst, SRegister s, Condition cond) {
1551 ASSERT(!dst.is(pc)); 1727 ASSERT(!dst.is(pc));
1552 emit(cond | B24 | s | 15*B16 | dst.code()*B12); 1728 emit(cond | B24 | s | 15*B16 | dst.code()*B12);
1553 } 1729 }
1554 1730
1555 1731
1556 void Assembler::msr(SRegisterFieldMask fields, const Operand& src, 1732 void Assembler::msr(SRegisterFieldMask fields, const Operand& src,
1557 Condition cond) { 1733 Condition cond) {
1558 ASSERT(fields >= B16 && fields < B20); // at least one field set 1734 ASSERT(fields >= B16 && fields < B20); // at least one field set
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1637 const MemOperand& dst, Condition cond) { 1813 const MemOperand& dst, Condition cond) {
1638 ASSERT(dst.rm().is(no_reg)); 1814 ASSERT(dst.rm().is(no_reg));
1639 ASSERT(!src1.is(lr)); // r14. 1815 ASSERT(!src1.is(lr)); // r14.
1640 ASSERT_EQ(0, src1.code() % 2); 1816 ASSERT_EQ(0, src1.code() % 2);
1641 ASSERT_EQ(src1.code() + 1, src2.code()); 1817 ASSERT_EQ(src1.code() + 1, src2.code());
1642 ASSERT(IsEnabled(ARMv7)); 1818 ASSERT(IsEnabled(ARMv7));
1643 addrmod3(cond | B7 | B6 | B5 | B4, src1, dst); 1819 addrmod3(cond | B7 | B6 | B5 | B4, src1, dst);
1644 } 1820 }
1645 1821
1646 1822
1823 // Preload instructions.
1824 void Assembler::pld(const MemOperand& address) {
1825 // Instruction details available in ARM DDI 0406C.b, A8.8.128.
1826 // 1111(31-28) | 0111(27-24) | U(23) | R(22) | 01(21-20) | Rn(19-16) |
1827 // 1111(15-12) | imm5(11-07) | type(6-5) | 0(4)| Rm(3-0) |
1828 ASSERT(address.rm().is(no_reg));
1829 ASSERT(address.am() == Offset);
1830 int U = B23;
1831 int offset = address.offset();
1832 if (offset < 0) {
1833 offset = -offset;
1834 U = 0;
1835 }
1836 ASSERT(offset < 4096);
1837 emit(kSpecialCondition | B26 | B24 | U | B22 | B20 | address.rn().code()*B16 |
1838 0xf*B12 | offset);
1839 }
1840
1841
1647 // Load/Store multiple instructions. 1842 // Load/Store multiple instructions.
1648 void Assembler::ldm(BlockAddrMode am, 1843 void Assembler::ldm(BlockAddrMode am,
1649 Register base, 1844 Register base,
1650 RegList dst, 1845 RegList dst,
1651 Condition cond) { 1846 Condition cond) {
1652 // ABI stack constraint: ldmxx base, {..sp..} base != sp is not restartable. 1847 // ABI stack constraint: ldmxx base, {..sp..} base != sp is not restartable.
1653 ASSERT(base.is(sp) || (dst & sp.bit()) == 0); 1848 ASSERT(base.is(sp) || (dst & sp.bit()) == 0);
1654 1849
1655 addrmod4(cond | B27 | am | L, base, dst); 1850 addrmod4(cond | B27 | am | L, base, dst);
1656 1851
(...skipping 1043 matching lines...) Expand 10 before | Expand all | Expand 10 after
2700 // Vd(15-12) | 101(11-9) | sz=1(8) | 11(7-6) | M(5) | 0(4) | Vm(3-0) 2895 // Vd(15-12) | 101(11-9) | sz=1(8) | 11(7-6) | M(5) | 0(4) | Vm(3-0)
2701 int vd, d; 2896 int vd, d;
2702 dst.split_code(&vd, &d); 2897 dst.split_code(&vd, &d);
2703 int vm, m; 2898 int vm, m;
2704 src.split_code(&vm, &m); 2899 src.split_code(&vm, &m);
2705 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | 0x3*B6 | 2900 emit(cond | 0x1D*B23 | d*B22 | 0x3*B20 | B16 | vd*B12 | 0x5*B9 | B8 | 0x3*B6 |
2706 m*B5 | vm); 2901 m*B5 | vm);
2707 } 2902 }
2708 2903
2709 2904
2905 // Support for NEON.
2906
2907 void Assembler::vld1(NeonSize size,
2908 const NeonListOperand& dst,
2909 const NeonMemOperand& src) {
2910 // Instruction details available in ARM DDI 0406C.b, A8.8.320.
2911 // 1111(31-28) | 01000(27-23) | D(22) | 10(21-20) | Rn(19-16) |
2912 // Vd(15-12) | type(11-8) | size(7-6) | align(5-4) | Rm(3-0)
2913 ASSERT(CpuFeatures::IsSupported(NEON));
2914 int vd, d;
2915 dst.base().split_code(&vd, &d);
2916 emit(0xFU*B28 | 4*B24 | d*B22 | 2*B20 | src.rn().code()*B16 | vd*B12 |
2917 dst.type()*B8 | size*B6 | src.align()*B4 | src.rm().code());
2918 }
2919
2920
2921 void Assembler::vst1(NeonSize size,
2922 const NeonListOperand& src,
2923 const NeonMemOperand& dst) {
2924 // Instruction details available in ARM DDI 0406C.b, A8.8.404.
2925 // 1111(31-28) | 01000(27-23) | D(22) | 00(21-20) | Rn(19-16) |
2926 // Vd(15-12) | type(11-8) | size(7-6) | align(5-4) | Rm(3-0)
2927 ASSERT(CpuFeatures::IsSupported(NEON));
2928 int vd, d;
2929 src.base().split_code(&vd, &d);
2930 emit(0xFU*B28 | 4*B24 | d*B22 | dst.rn().code()*B16 | vd*B12 | src.type()*B8 |
2931 size*B6 | dst.align()*B4 | dst.rm().code());
2932 }
2933
2934
2935 void Assembler::vmovl(NeonDataType dt, QwNeonRegister dst, DwVfpRegister src) {
2936 // Instruction details available in ARM DDI 0406C.b, A8.8.346.
2937 // 1111(31-28) | 001(27-25) | U(24) | 1(23) | D(22) | imm3(21-19) |
2938 // 000(18-16) | Vd(15-12) | 101000(11-6) | M(5) | 1(4) | Vm(3-0)
2939 ASSERT(CpuFeatures::IsSupported(NEON));
2940 int vd, d;
2941 dst.split_code(&vd, &d);
2942 int vm, m;
2943 src.split_code(&vm, &m);
2944 emit(0xFU*B28 | B25 | (dt & NeonDataTypeUMask) | B23 | d*B22 |
2945 (dt & NeonDataTypeSizeMask)*B19 | vd*B12 | 0xA*B8 | m*B5 | B4 | vm);
2946 }
2947
2948
2710 // Pseudo instructions. 2949 // Pseudo instructions.
2711 void Assembler::nop(int type) { 2950 void Assembler::nop(int type) {
2712 // ARMv6{K/T2} and v7 have an actual NOP instruction but it serializes 2951 // ARMv6{K/T2} and v7 have an actual NOP instruction but it serializes
2713 // some of the CPU's pipeline and has to issue. Older ARM chips simply used 2952 // some of the CPU's pipeline and has to issue. Older ARM chips simply used
2714 // MOV Rx, Rx as NOP and it performs better even in newer CPUs. 2953 // MOV Rx, Rx as NOP and it performs better even in newer CPUs.
2715 // We therefore use MOV Rx, Rx, even on newer CPUs, and use Rx to encode 2954 // We therefore use MOV Rx, Rx, even on newer CPUs, and use Rx to encode
2716 // a type. 2955 // a type.
2717 ASSERT(0 <= type && type <= 14); // mov pc, pc isn't a nop. 2956 ASSERT(0 <= type && type <= 14); // mov pc, pc isn't a nop.
2718 emit(al | 13*B21 | type*B12 | type); 2957 emit(al | 13*B21 | type*B12 | type);
2719 } 2958 }
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
3110 3349
3111 // Since a constant pool was just emitted, move the check offset forward by 3350 // Since a constant pool was just emitted, move the check offset forward by
3112 // the standard interval. 3351 // the standard interval.
3113 next_buffer_check_ = pc_offset() + kCheckPoolInterval; 3352 next_buffer_check_ = pc_offset() + kCheckPoolInterval;
3114 } 3353 }
3115 3354
3116 3355
3117 } } // namespace v8::internal 3356 } } // namespace v8::internal
3118 3357
3119 #endif // V8_TARGET_ARCH_ARM 3358 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698