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

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

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

Powered by Google App Engine
This is Rietveld 408576698