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

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

Issue 6794050: Revert "[Arguments] Merge (7442,7496] from bleeding_edge." (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/arguments
Patch Set: Created 9 years, 8 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/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 26 matching lines...) Expand all
37 #include "v8.h" 37 #include "v8.h"
38 38
39 #if defined(V8_TARGET_ARCH_ARM) 39 #if defined(V8_TARGET_ARCH_ARM)
40 40
41 #include "arm/assembler-arm-inl.h" 41 #include "arm/assembler-arm-inl.h"
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 CpuFeatures::CpuFeatures()
48 bool CpuFeatures::initialized_ = false; 48 : supported_(0),
49 #endif 49 enabled_(0),
50 unsigned CpuFeatures::supported_ = 0; 50 found_by_runtime_probing_(0) {
51 unsigned CpuFeatures::found_by_runtime_probing_ = 0; 51 }
52
53 52
54 #ifdef __arm__ 53 #ifdef __arm__
55 static uint64_t CpuFeaturesImpliedByCompiler() { 54 static uint64_t CpuFeaturesImpliedByCompiler() {
56 uint64_t answer = 0; 55 uint64_t answer = 0;
57 #ifdef CAN_USE_ARMV7_INSTRUCTIONS 56 #ifdef CAN_USE_ARMV7_INSTRUCTIONS
58 answer |= 1u << ARMv7; 57 answer |= 1u << ARMv7;
59 #endif // def CAN_USE_ARMV7_INSTRUCTIONS 58 #endif // def CAN_USE_ARMV7_INSTRUCTIONS
60 // If the compiler is allowed to use VFP then we can use VFP too in our code 59 // If the compiler is allowed to use VFP then we can use VFP too in our code
61 // generation even when generating snapshots. This won't work for cross 60 // generation even when generating snapshots. This won't work for cross
62 // compilation. 61 // compilation.
63 #if defined(__VFP_FP__) && !defined(__SOFTFP__) 62 #if defined(__VFP_FP__) && !defined(__SOFTFP__)
64 answer |= 1u << VFP3; 63 answer |= 1u << VFP3;
65 #endif // defined(__VFP_FP__) && !defined(__SOFTFP__) 64 #endif // defined(__VFP_FP__) && !defined(__SOFTFP__)
66 #ifdef CAN_USE_VFP_INSTRUCTIONS 65 #ifdef CAN_USE_VFP_INSTRUCTIONS
67 answer |= 1u << VFP3; 66 answer |= 1u << VFP3;
68 #endif // def CAN_USE_VFP_INSTRUCTIONS 67 #endif // def CAN_USE_VFP_INSTRUCTIONS
69 return answer; 68 return answer;
70 } 69 }
71 #endif // def __arm__ 70 #endif // def __arm__
72 71
73 72
74 void CpuFeatures::Probe() { 73 void CpuFeatures::Probe(bool portable) {
75 ASSERT(!initialized_);
76 #ifdef DEBUG
77 initialized_ = true;
78 #endif
79 #ifndef __arm__ 74 #ifndef __arm__
80 // For the simulator=arm build, use VFP when FLAG_enable_vfp3 is enabled. 75 // For the simulator=arm build, use VFP when FLAG_enable_vfp3 is enabled.
81 if (FLAG_enable_vfp3) { 76 if (FLAG_enable_vfp3) {
82 supported_ |= 1u << VFP3; 77 supported_ |= 1u << VFP3;
83 } 78 }
84 // For the simulator=arm build, use ARMv7 when FLAG_enable_armv7 is enabled 79 // For the simulator=arm build, use ARMv7 when FLAG_enable_armv7 is enabled
85 if (FLAG_enable_armv7) { 80 if (FLAG_enable_armv7) {
86 supported_ |= 1u << ARMv7; 81 supported_ |= 1u << ARMv7;
87 } 82 }
88 #else // def __arm__ 83 #else // def __arm__
89 if (Serializer::enabled()) { 84 if (portable && Serializer::enabled()) {
90 supported_ |= OS::CpuFeaturesImpliedByPlatform(); 85 supported_ |= OS::CpuFeaturesImpliedByPlatform();
91 supported_ |= CpuFeaturesImpliedByCompiler(); 86 supported_ |= CpuFeaturesImpliedByCompiler();
92 return; // No features if we might serialize. 87 return; // No features if we might serialize.
93 } 88 }
94 89
95 if (OS::ArmCpuHasFeature(VFP3)) { 90 if (OS::ArmCpuHasFeature(VFP3)) {
96 // This implementation also sets the VFP flags if 91 // This implementation also sets the VFP flags if
97 // runtime detection of VFP returns true. 92 // runtime detection of VFP returns true.
98 supported_ |= 1u << VFP3; 93 supported_ |= 1u << VFP3;
99 found_by_runtime_probing_ |= 1u << VFP3; 94 found_by_runtime_probing_ |= 1u << VFP3;
100 } 95 }
101 96
102 if (OS::ArmCpuHasFeature(ARMv7)) { 97 if (OS::ArmCpuHasFeature(ARMv7)) {
103 supported_ |= 1u << ARMv7; 98 supported_ |= 1u << ARMv7;
104 found_by_runtime_probing_ |= 1u << ARMv7; 99 found_by_runtime_probing_ |= 1u << ARMv7;
105 } 100 }
101
102 if (!portable) found_by_runtime_probing_ = 0;
106 #endif 103 #endif
107 } 104 }
108 105
109 106
110 // ----------------------------------------------------------------------------- 107 // -----------------------------------------------------------------------------
111 // Implementation of RelocInfo 108 // Implementation of RelocInfo
112 109
113 const int RelocInfo::kApplyMask = 0; 110 const int RelocInfo::kApplyMask = 0;
114 111
115 112
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 al | B26 | NegOffset | fp.code() * B16; 261 al | B26 | NegOffset | fp.code() * B16;
265 const Instr kLdrStrInstrTypeMask = 0xffff0000; 262 const Instr kLdrStrInstrTypeMask = 0xffff0000;
266 const Instr kLdrStrInstrArgumentMask = 0x0000ffff; 263 const Instr kLdrStrInstrArgumentMask = 0x0000ffff;
267 const Instr kLdrStrOffsetMask = 0x00000fff; 264 const Instr kLdrStrOffsetMask = 0x00000fff;
268 265
269 266
270 // Spare buffer. 267 // Spare buffer.
271 static const int kMinimalBufferSize = 4*KB; 268 static const int kMinimalBufferSize = 4*KB;
272 269
273 270
274 Assembler::Assembler(Isolate* arg_isolate, void* buffer, int buffer_size) 271 Assembler::Assembler(void* buffer, int buffer_size)
275 : AssemblerBase(arg_isolate), 272 : AssemblerBase(Isolate::Current()),
276 positions_recorder_(this), 273 positions_recorder_(this),
277 allow_peephole_optimization_(false), 274 allow_peephole_optimization_(false),
278 emit_debug_code_(FLAG_debug_code) { 275 emit_debug_code_(FLAG_debug_code) {
279 allow_peephole_optimization_ = FLAG_peephole_optimization; 276 allow_peephole_optimization_ = FLAG_peephole_optimization;
280 if (buffer == NULL) { 277 if (buffer == NULL) {
281 // Do our own buffer management. 278 // Do our own buffer management.
282 if (buffer_size <= kMinimalBufferSize) { 279 if (buffer_size <= kMinimalBufferSize) {
283 buffer_size = kMinimalBufferSize; 280 buffer_size = kMinimalBufferSize;
284 281
285 if (isolate()->assembler_spare_buffer() != NULL) { 282 if (isolate()->assembler_spare_buffer() != NULL) {
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 } 708 }
712 } 709 }
713 // If the opcode is one with a complementary version and the complementary 710 // If the opcode is one with a complementary version and the complementary
714 // immediate fits, change the opcode. 711 // immediate fits, change the opcode.
715 if (instr != NULL) { 712 if (instr != NULL) {
716 if ((*instr & kMovMvnMask) == kMovMvnPattern) { 713 if ((*instr & kMovMvnMask) == kMovMvnPattern) {
717 if (fits_shifter(~imm32, rotate_imm, immed_8, NULL)) { 714 if (fits_shifter(~imm32, rotate_imm, immed_8, NULL)) {
718 *instr ^= kMovMvnFlip; 715 *instr ^= kMovMvnFlip;
719 return true; 716 return true;
720 } else if ((*instr & kMovLeaveCCMask) == kMovLeaveCCPattern) { 717 } else if ((*instr & kMovLeaveCCMask) == kMovLeaveCCPattern) {
721 if (CpuFeatures::IsSupported(ARMv7)) { 718 if (Isolate::Current()->cpu_features()->IsSupported(ARMv7)) {
722 if (imm32 < 0x10000) { 719 if (imm32 < 0x10000) {
723 *instr ^= kMovwLeaveCCFlip; 720 *instr ^= kMovwLeaveCCFlip;
724 *instr |= EncodeMovwImmediate(imm32); 721 *instr |= EncodeMovwImmediate(imm32);
725 *rotate_imm = *immed_8 = 0; // Not used for movw. 722 *rotate_imm = *immed_8 = 0; // Not used for movw.
726 return true; 723 return true;
727 } 724 }
728 } 725 }
729 } 726 }
730 } else if ((*instr & kCmpCmnMask) == kCmpCmnPattern) { 727 } else if ((*instr & kCmpCmnMask) == kCmpCmnPattern) {
731 if (fits_shifter(-imm32, rotate_imm, immed_8, NULL)) { 728 if (fits_shifter(-imm32, rotate_imm, immed_8, NULL)) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 bool Operand::is_single_instruction(Instr instr) const { 772 bool Operand::is_single_instruction(Instr instr) const {
776 if (rm_.is_valid()) return true; 773 if (rm_.is_valid()) return true;
777 uint32_t dummy1, dummy2; 774 uint32_t dummy1, dummy2;
778 if (must_use_constant_pool() || 775 if (must_use_constant_pool() ||
779 !fits_shifter(imm32_, &dummy1, &dummy2, &instr)) { 776 !fits_shifter(imm32_, &dummy1, &dummy2, &instr)) {
780 // The immediate operand cannot be encoded as a shifter operand, or use of 777 // The immediate operand cannot be encoded as a shifter operand, or use of
781 // constant pool is required. For a mov instruction not setting the 778 // constant pool is required. For a mov instruction not setting the
782 // condition code additional instruction conventions can be used. 779 // condition code additional instruction conventions can be used.
783 if ((instr & ~kCondMask) == 13*B21) { // mov, S not set 780 if ((instr & ~kCondMask) == 13*B21) { // mov, S not set
784 if (must_use_constant_pool() || 781 if (must_use_constant_pool() ||
785 !CpuFeatures::IsSupported(ARMv7)) { 782 !Isolate::Current()->cpu_features()->IsSupported(ARMv7)) {
786 // mov instruction will be an ldr from constant pool (one instruction). 783 // mov instruction will be an ldr from constant pool (one instruction).
787 return true; 784 return true;
788 } else { 785 } else {
789 // mov instruction will be a mov or movw followed by movt (two 786 // mov instruction will be a mov or movw followed by movt (two
790 // instructions). 787 // instructions).
791 return false; 788 return false;
792 } 789 }
793 } else { 790 } else {
794 // If this is not a mov or mvn instruction there will always an additional 791 // If this is not a mov or mvn instruction there will always an additional
795 // instructions - either mov or ldr. The mov might actually be two 792 // instructions - either mov or ldr. The mov might actually be two
(...skipping 22 matching lines...) Expand all
818 if (x.must_use_constant_pool() || 815 if (x.must_use_constant_pool() ||
819 !fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) { 816 !fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) {
820 // The immediate operand cannot be encoded as a shifter operand, so load 817 // The immediate operand cannot be encoded as a shifter operand, so load
821 // it first to register ip and change the original instruction to use ip. 818 // it first to register ip and change the original instruction to use ip.
822 // However, if the original instruction is a 'mov rd, x' (not setting the 819 // However, if the original instruction is a 'mov rd, x' (not setting the
823 // condition code), then replace it with a 'ldr rd, [pc]'. 820 // condition code), then replace it with a 'ldr rd, [pc]'.
824 CHECK(!rn.is(ip)); // rn should never be ip, or will be trashed 821 CHECK(!rn.is(ip)); // rn should never be ip, or will be trashed
825 Condition cond = Instruction::ConditionField(instr); 822 Condition cond = Instruction::ConditionField(instr);
826 if ((instr & ~kCondMask) == 13*B21) { // mov, S not set 823 if ((instr & ~kCondMask) == 13*B21) { // mov, S not set
827 if (x.must_use_constant_pool() || 824 if (x.must_use_constant_pool() ||
828 !CpuFeatures::IsSupported(ARMv7)) { 825 !isolate()->cpu_features()->IsSupported(ARMv7)) {
829 RecordRelocInfo(x.rmode_, x.imm32_); 826 RecordRelocInfo(x.rmode_, x.imm32_);
830 ldr(rd, MemOperand(pc, 0), cond); 827 ldr(rd, MemOperand(pc, 0), cond);
831 } else { 828 } else {
832 // Will probably use movw, will certainly not use constant pool. 829 // Will probably use movw, will certainly not use constant pool.
833 mov(rd, Operand(x.imm32_ & 0xffff), LeaveCC, cond); 830 mov(rd, Operand(x.imm32_ & 0xffff), LeaveCC, cond);
834 movt(rd, static_cast<uint32_t>(x.imm32_) >> 16, cond); 831 movt(rd, static_cast<uint32_t>(x.imm32_) >> 16, cond);
835 } 832 }
836 } else { 833 } else {
837 // If this is not a mov or mvn instruction we may still be able to avoid 834 // If this is not a mov or mvn instruction we may still be able to avoid
838 // a constant pool entry by using mvn or movw. 835 // a constant pool entry by using mvn or movw.
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
1261 1258
1262 1259
1263 // Saturating instructions. 1260 // Saturating instructions.
1264 1261
1265 // Unsigned saturate. 1262 // Unsigned saturate.
1266 void Assembler::usat(Register dst, 1263 void Assembler::usat(Register dst,
1267 int satpos, 1264 int satpos,
1268 const Operand& src, 1265 const Operand& src,
1269 Condition cond) { 1266 Condition cond) {
1270 // v6 and above. 1267 // v6 and above.
1271 ASSERT(CpuFeatures::IsSupported(ARMv7)); 1268 ASSERT(isolate()->cpu_features()->IsSupported(ARMv7));
1272 ASSERT(!dst.is(pc) && !src.rm_.is(pc)); 1269 ASSERT(!dst.is(pc) && !src.rm_.is(pc));
1273 ASSERT((satpos >= 0) && (satpos <= 31)); 1270 ASSERT((satpos >= 0) && (satpos <= 31));
1274 ASSERT((src.shift_op_ == ASR) || (src.shift_op_ == LSL)); 1271 ASSERT((src.shift_op_ == ASR) || (src.shift_op_ == LSL));
1275 ASSERT(src.rs_.is(no_reg)); 1272 ASSERT(src.rs_.is(no_reg));
1276 1273
1277 int sh = 0; 1274 int sh = 0;
1278 if (src.shift_op_ == ASR) { 1275 if (src.shift_op_ == ASR) {
1279 sh = 1; 1276 sh = 1;
1280 } 1277 }
1281 1278
1282 emit(cond | 0x6*B24 | 0xe*B20 | satpos*B16 | dst.code()*B12 | 1279 emit(cond | 0x6*B24 | 0xe*B20 | satpos*B16 | dst.code()*B12 |
1283 src.shift_imm_*B7 | sh*B6 | 0x1*B4 | src.rm_.code()); 1280 src.shift_imm_*B7 | sh*B6 | 0x1*B4 | src.rm_.code());
1284 } 1281 }
1285 1282
1286 1283
1287 // Bitfield manipulation instructions. 1284 // Bitfield manipulation instructions.
1288 1285
1289 // Unsigned bit field extract. 1286 // Unsigned bit field extract.
1290 // Extracts #width adjacent bits from position #lsb in a register, and 1287 // Extracts #width adjacent bits from position #lsb in a register, and
1291 // writes them to the low bits of a destination register. 1288 // writes them to the low bits of a destination register.
1292 // ubfx dst, src, #lsb, #width 1289 // ubfx dst, src, #lsb, #width
1293 void Assembler::ubfx(Register dst, 1290 void Assembler::ubfx(Register dst,
1294 Register src, 1291 Register src,
1295 int lsb, 1292 int lsb,
1296 int width, 1293 int width,
1297 Condition cond) { 1294 Condition cond) {
1298 // v7 and above. 1295 // v7 and above.
1299 ASSERT(CpuFeatures::IsSupported(ARMv7)); 1296 ASSERT(isolate()->cpu_features()->IsSupported(ARMv7));
1300 ASSERT(!dst.is(pc) && !src.is(pc)); 1297 ASSERT(!dst.is(pc) && !src.is(pc));
1301 ASSERT((lsb >= 0) && (lsb <= 31)); 1298 ASSERT((lsb >= 0) && (lsb <= 31));
1302 ASSERT((width >= 1) && (width <= (32 - lsb))); 1299 ASSERT((width >= 1) && (width <= (32 - lsb)));
1303 emit(cond | 0xf*B23 | B22 | B21 | (width - 1)*B16 | dst.code()*B12 | 1300 emit(cond | 0xf*B23 | B22 | B21 | (width - 1)*B16 | dst.code()*B12 |
1304 lsb*B7 | B6 | B4 | src.code()); 1301 lsb*B7 | B6 | B4 | src.code());
1305 } 1302 }
1306 1303
1307 1304
1308 // Signed bit field extract. 1305 // Signed bit field extract.
1309 // Extracts #width adjacent bits from position #lsb in a register, and 1306 // Extracts #width adjacent bits from position #lsb in a register, and
1310 // writes them to the low bits of a destination register. The extracted 1307 // writes them to the low bits of a destination register. The extracted
1311 // value is sign extended to fill the destination register. 1308 // value is sign extended to fill the destination register.
1312 // sbfx dst, src, #lsb, #width 1309 // sbfx dst, src, #lsb, #width
1313 void Assembler::sbfx(Register dst, 1310 void Assembler::sbfx(Register dst,
1314 Register src, 1311 Register src,
1315 int lsb, 1312 int lsb,
1316 int width, 1313 int width,
1317 Condition cond) { 1314 Condition cond) {
1318 // v7 and above. 1315 // v7 and above.
1319 ASSERT(CpuFeatures::IsSupported(ARMv7)); 1316 ASSERT(isolate()->cpu_features()->IsSupported(ARMv7));
1320 ASSERT(!dst.is(pc) && !src.is(pc)); 1317 ASSERT(!dst.is(pc) && !src.is(pc));
1321 ASSERT((lsb >= 0) && (lsb <= 31)); 1318 ASSERT((lsb >= 0) && (lsb <= 31));
1322 ASSERT((width >= 1) && (width <= (32 - lsb))); 1319 ASSERT((width >= 1) && (width <= (32 - lsb)));
1323 emit(cond | 0xf*B23 | B21 | (width - 1)*B16 | dst.code()*B12 | 1320 emit(cond | 0xf*B23 | B21 | (width - 1)*B16 | dst.code()*B12 |
1324 lsb*B7 | B6 | B4 | src.code()); 1321 lsb*B7 | B6 | B4 | src.code());
1325 } 1322 }
1326 1323
1327 1324
1328 // Bit field clear. 1325 // Bit field clear.
1329 // Sets #width adjacent bits at position #lsb in the destination register 1326 // Sets #width adjacent bits at position #lsb in the destination register
1330 // to zero, preserving the value of the other bits. 1327 // to zero, preserving the value of the other bits.
1331 // bfc dst, #lsb, #width 1328 // bfc dst, #lsb, #width
1332 void Assembler::bfc(Register dst, int lsb, int width, Condition cond) { 1329 void Assembler::bfc(Register dst, int lsb, int width, Condition cond) {
1333 // v7 and above. 1330 // v7 and above.
1334 ASSERT(CpuFeatures::IsSupported(ARMv7)); 1331 ASSERT(isolate()->cpu_features()->IsSupported(ARMv7));
1335 ASSERT(!dst.is(pc)); 1332 ASSERT(!dst.is(pc));
1336 ASSERT((lsb >= 0) && (lsb <= 31)); 1333 ASSERT((lsb >= 0) && (lsb <= 31));
1337 ASSERT((width >= 1) && (width <= (32 - lsb))); 1334 ASSERT((width >= 1) && (width <= (32 - lsb)));
1338 int msb = lsb + width - 1; 1335 int msb = lsb + width - 1;
1339 emit(cond | 0x1f*B22 | msb*B16 | dst.code()*B12 | lsb*B7 | B4 | 0xf); 1336 emit(cond | 0x1f*B22 | msb*B16 | dst.code()*B12 | lsb*B7 | B4 | 0xf);
1340 } 1337 }
1341 1338
1342 1339
1343 // Bit field insert. 1340 // Bit field insert.
1344 // Inserts #width adjacent bits from the low bits of the source register 1341 // Inserts #width adjacent bits from the low bits of the source register
1345 // into position #lsb of the destination register. 1342 // into position #lsb of the destination register.
1346 // bfi dst, src, #lsb, #width 1343 // bfi dst, src, #lsb, #width
1347 void Assembler::bfi(Register dst, 1344 void Assembler::bfi(Register dst,
1348 Register src, 1345 Register src,
1349 int lsb, 1346 int lsb,
1350 int width, 1347 int width,
1351 Condition cond) { 1348 Condition cond) {
1352 // v7 and above. 1349 // v7 and above.
1353 ASSERT(CpuFeatures::IsSupported(ARMv7)); 1350 ASSERT(isolate()->cpu_features()->IsSupported(ARMv7));
1354 ASSERT(!dst.is(pc) && !src.is(pc)); 1351 ASSERT(!dst.is(pc) && !src.is(pc));
1355 ASSERT((lsb >= 0) && (lsb <= 31)); 1352 ASSERT((lsb >= 0) && (lsb <= 31));
1356 ASSERT((width >= 1) && (width <= (32 - lsb))); 1353 ASSERT((width >= 1) && (width <= (32 - lsb)));
1357 int msb = lsb + width - 1; 1354 int msb = lsb + width - 1;
1358 emit(cond | 0x1f*B22 | msb*B16 | dst.code()*B12 | lsb*B7 | B4 | 1355 emit(cond | 0x1f*B22 | msb*B16 | dst.code()*B12 | lsb*B7 | B4 |
1359 src.code()); 1356 src.code());
1360 } 1357 }
1361 1358
1362 1359
1363 // Status register access instructions. 1360 // Status register access instructions.
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
1615 } 1612 }
1616 1613
1617 1614
1618 void Assembler::ldrsh(Register dst, const MemOperand& src, Condition cond) { 1615 void Assembler::ldrsh(Register dst, const MemOperand& src, Condition cond) {
1619 addrmod3(cond | L | B7 | S6 | H | B4, dst, src); 1616 addrmod3(cond | L | B7 | S6 | H | B4, dst, src);
1620 } 1617 }
1621 1618
1622 1619
1623 void Assembler::ldrd(Register dst1, Register dst2, 1620 void Assembler::ldrd(Register dst1, Register dst2,
1624 const MemOperand& src, Condition cond) { 1621 const MemOperand& src, Condition cond) {
1625 ASSERT(CpuFeatures::IsEnabled(ARMv7)); 1622 ASSERT(isolate()->cpu_features()->IsEnabled(ARMv7));
1626 ASSERT(src.rm().is(no_reg)); 1623 ASSERT(src.rm().is(no_reg));
1627 ASSERT(!dst1.is(lr)); // r14. 1624 ASSERT(!dst1.is(lr)); // r14.
1628 ASSERT_EQ(0, dst1.code() % 2); 1625 ASSERT_EQ(0, dst1.code() % 2);
1629 ASSERT_EQ(dst1.code() + 1, dst2.code()); 1626 ASSERT_EQ(dst1.code() + 1, dst2.code());
1630 addrmod3(cond | B7 | B6 | B4, dst1, src); 1627 addrmod3(cond | B7 | B6 | B4, dst1, src);
1631 } 1628 }
1632 1629
1633 1630
1634 void Assembler::strd(Register src1, Register src2, 1631 void Assembler::strd(Register src1, Register src2,
1635 const MemOperand& dst, Condition cond) { 1632 const MemOperand& dst, Condition cond) {
1636 ASSERT(dst.rm().is(no_reg)); 1633 ASSERT(dst.rm().is(no_reg));
1637 ASSERT(!src1.is(lr)); // r14. 1634 ASSERT(!src1.is(lr)); // r14.
1638 ASSERT_EQ(0, src1.code() % 2); 1635 ASSERT_EQ(0, src1.code() % 2);
1639 ASSERT_EQ(src1.code() + 1, src2.code()); 1636 ASSERT_EQ(src1.code() + 1, src2.code());
1640 ASSERT(CpuFeatures::IsEnabled(ARMv7)); 1637 ASSERT(isolate()->cpu_features()->IsEnabled(ARMv7));
1641 addrmod3(cond | B7 | B6 | B5 | B4, src1, dst); 1638 addrmod3(cond | B7 | B6 | B5 | B4, src1, dst);
1642 } 1639 }
1643 1640
1644 // Load/Store multiple instructions. 1641 // Load/Store multiple instructions.
1645 void Assembler::ldm(BlockAddrMode am, 1642 void Assembler::ldm(BlockAddrMode am,
1646 Register base, 1643 Register base,
1647 RegList dst, 1644 RegList dst,
1648 Condition cond) { 1645 Condition cond) {
1649 // ABI stack constraint: ldmxx base, {..sp..} base != sp is not restartable. 1646 // ABI stack constraint: ldmxx base, {..sp..} base != sp is not restartable.
1650 ASSERT(base.is(sp) || (dst & sp.bit()) == 0); 1647 ASSERT(base.is(sp) || (dst & sp.bit()) == 0);
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
1866 // Support for VFP. 1863 // Support for VFP.
1867 1864
1868 void Assembler::vldr(const DwVfpRegister dst, 1865 void Assembler::vldr(const DwVfpRegister dst,
1869 const Register base, 1866 const Register base,
1870 int offset, 1867 int offset,
1871 const Condition cond) { 1868 const Condition cond) {
1872 // Ddst = MEM(Rbase + offset). 1869 // Ddst = MEM(Rbase + offset).
1873 // Instruction details available in ARM DDI 0406A, A8-628. 1870 // Instruction details available in ARM DDI 0406A, A8-628.
1874 // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) | 1871 // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) |
1875 // Vdst(15-12) | 1011(11-8) | offset 1872 // Vdst(15-12) | 1011(11-8) | offset
1876 ASSERT(CpuFeatures::IsEnabled(VFP3)); 1873 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
1877 int u = 1; 1874 int u = 1;
1878 if (offset < 0) { 1875 if (offset < 0) {
1879 offset = -offset; 1876 offset = -offset;
1880 u = 0; 1877 u = 0;
1881 } 1878 }
1882 1879
1883 ASSERT(offset >= 0); 1880 ASSERT(offset >= 0);
1884 if ((offset % 4) == 0 && (offset / 4) < 256) { 1881 if ((offset % 4) == 0 && (offset / 4) < 256) {
1885 emit(cond | u*B23 | 0xD1*B20 | base.code()*B16 | dst.code()*B12 | 1882 emit(cond | u*B23 | 0xD1*B20 | base.code()*B16 | dst.code()*B12 |
1886 0xB*B8 | ((offset / 4) & 255)); 1883 0xB*B8 | ((offset / 4) & 255));
(...skipping 21 matching lines...) Expand all
1908 1905
1909 1906
1910 void Assembler::vldr(const SwVfpRegister dst, 1907 void Assembler::vldr(const SwVfpRegister dst,
1911 const Register base, 1908 const Register base,
1912 int offset, 1909 int offset,
1913 const Condition cond) { 1910 const Condition cond) {
1914 // Sdst = MEM(Rbase + offset). 1911 // Sdst = MEM(Rbase + offset).
1915 // Instruction details available in ARM DDI 0406A, A8-628. 1912 // Instruction details available in ARM DDI 0406A, A8-628.
1916 // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) | 1913 // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) |
1917 // Vdst(15-12) | 1010(11-8) | offset 1914 // Vdst(15-12) | 1010(11-8) | offset
1918 ASSERT(CpuFeatures::IsEnabled(VFP3)); 1915 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
1919 int u = 1; 1916 int u = 1;
1920 if (offset < 0) { 1917 if (offset < 0) {
1921 offset = -offset; 1918 offset = -offset;
1922 u = 0; 1919 u = 0;
1923 } 1920 }
1924 int sd, d; 1921 int sd, d;
1925 dst.split_code(&sd, &d); 1922 dst.split_code(&sd, &d);
1926 ASSERT(offset >= 0); 1923 ASSERT(offset >= 0);
1927 1924
1928 if ((offset % 4) == 0 && (offset / 4) < 256) { 1925 if ((offset % 4) == 0 && (offset / 4) < 256) {
(...skipping 23 matching lines...) Expand all
1952 1949
1953 1950
1954 void Assembler::vstr(const DwVfpRegister src, 1951 void Assembler::vstr(const DwVfpRegister src,
1955 const Register base, 1952 const Register base,
1956 int offset, 1953 int offset,
1957 const Condition cond) { 1954 const Condition cond) {
1958 // MEM(Rbase + offset) = Dsrc. 1955 // MEM(Rbase + offset) = Dsrc.
1959 // Instruction details available in ARM DDI 0406A, A8-786. 1956 // Instruction details available in ARM DDI 0406A, A8-786.
1960 // cond(31-28) | 1101(27-24)| U000(23-20) | | Rbase(19-16) | 1957 // cond(31-28) | 1101(27-24)| U000(23-20) | | Rbase(19-16) |
1961 // Vsrc(15-12) | 1011(11-8) | (offset/4) 1958 // Vsrc(15-12) | 1011(11-8) | (offset/4)
1962 ASSERT(CpuFeatures::IsEnabled(VFP3)); 1959 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
1963 int u = 1; 1960 int u = 1;
1964 if (offset < 0) { 1961 if (offset < 0) {
1965 offset = -offset; 1962 offset = -offset;
1966 u = 0; 1963 u = 0;
1967 } 1964 }
1968 ASSERT(offset >= 0); 1965 ASSERT(offset >= 0);
1969 if ((offset % 4) == 0 && (offset / 4) < 256) { 1966 if ((offset % 4) == 0 && (offset / 4) < 256) {
1970 emit(cond | u*B23 | 0xD0*B20 | base.code()*B16 | src.code()*B12 | 1967 emit(cond | u*B23 | 0xD0*B20 | base.code()*B16 | src.code()*B12 |
1971 0xB*B8 | ((offset / 4) & 255)); 1968 0xB*B8 | ((offset / 4) & 255));
1972 } else { 1969 } else {
(...skipping 20 matching lines...) Expand all
1993 1990
1994 1991
1995 void Assembler::vstr(const SwVfpRegister src, 1992 void Assembler::vstr(const SwVfpRegister src,
1996 const Register base, 1993 const Register base,
1997 int offset, 1994 int offset,
1998 const Condition cond) { 1995 const Condition cond) {
1999 // MEM(Rbase + offset) = SSrc. 1996 // MEM(Rbase + offset) = SSrc.
2000 // Instruction details available in ARM DDI 0406A, A8-786. 1997 // Instruction details available in ARM DDI 0406A, A8-786.
2001 // cond(31-28) | 1101(27-24)| U000(23-20) | Rbase(19-16) | 1998 // cond(31-28) | 1101(27-24)| U000(23-20) | Rbase(19-16) |
2002 // Vdst(15-12) | 1010(11-8) | (offset/4) 1999 // Vdst(15-12) | 1010(11-8) | (offset/4)
2003 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2000 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2004 int u = 1; 2001 int u = 1;
2005 if (offset < 0) { 2002 if (offset < 0) {
2006 offset = -offset; 2003 offset = -offset;
2007 u = 0; 2004 u = 0;
2008 } 2005 }
2009 int sd, d; 2006 int sd, d;
2010 src.split_code(&sd, &d); 2007 src.split_code(&sd, &d);
2011 ASSERT(offset >= 0); 2008 ASSERT(offset >= 0);
2012 if ((offset % 4) == 0 && (offset / 4) < 256) { 2009 if ((offset % 4) == 0 && (offset / 4) < 256) {
2013 emit(cond | u*B23 | d*B22 | 0xD0*B20 | base.code()*B16 | sd*B12 | 2010 emit(cond | u*B23 | d*B22 | 0xD0*B20 | base.code()*B16 | sd*B12 |
(...skipping 25 matching lines...) Expand all
2039 uint64_t i; 2036 uint64_t i;
2040 memcpy(&i, &d, 8); 2037 memcpy(&i, &d, 8);
2041 2038
2042 *lo = i & 0xffffffff; 2039 *lo = i & 0xffffffff;
2043 *hi = i >> 32; 2040 *hi = i >> 32;
2044 } 2041 }
2045 2042
2046 // Only works for little endian floating point formats. 2043 // Only works for little endian floating point formats.
2047 // We don't support VFP on the mixed endian floating point platform. 2044 // We don't support VFP on the mixed endian floating point platform.
2048 static bool FitsVMOVDoubleImmediate(double d, uint32_t *encoding) { 2045 static bool FitsVMOVDoubleImmediate(double d, uint32_t *encoding) {
2049 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2046 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3));
2050 2047
2051 // VMOV can accept an immediate of the form: 2048 // VMOV can accept an immediate of the form:
2052 // 2049 //
2053 // +/- m * 2^(-n) where 16 <= m <= 31 and 0 <= n <= 7 2050 // +/- m * 2^(-n) where 16 <= m <= 31 and 0 <= n <= 7
2054 // 2051 //
2055 // The immediate is encoded using an 8-bit quantity, comprised of two 2052 // The immediate is encoded using an 8-bit quantity, comprised of two
2056 // 4-bit fields. For an 8-bit immediate of the form: 2053 // 4-bit fields. For an 8-bit immediate of the form:
2057 // 2054 //
2058 // [abcdefgh] 2055 // [abcdefgh]
2059 // 2056 //
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2092 2089
2093 return true; 2090 return true;
2094 } 2091 }
2095 2092
2096 2093
2097 void Assembler::vmov(const DwVfpRegister dst, 2094 void Assembler::vmov(const DwVfpRegister dst,
2098 double imm, 2095 double imm,
2099 const Condition cond) { 2096 const Condition cond) {
2100 // Dd = immediate 2097 // Dd = immediate
2101 // Instruction details available in ARM DDI 0406B, A8-640. 2098 // Instruction details available in ARM DDI 0406B, A8-640.
2102 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2099 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2103 2100
2104 uint32_t enc; 2101 uint32_t enc;
2105 if (FitsVMOVDoubleImmediate(imm, &enc)) { 2102 if (FitsVMOVDoubleImmediate(imm, &enc)) {
2106 // The double can be encoded in the instruction. 2103 // The double can be encoded in the instruction.
2107 emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 | 0xB*B8 | enc); 2104 emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 | 0xB*B8 | enc);
2108 } else { 2105 } else {
2109 // Synthesise the double from ARM immediates. This could be implemented 2106 // Synthesise the double from ARM immediates. This could be implemented
2110 // using vldr from a constant pool. 2107 // using vldr from a constant pool.
2111 uint32_t lo, hi; 2108 uint32_t lo, hi;
2112 DoubleAsTwoUInt32(imm, &lo, &hi); 2109 DoubleAsTwoUInt32(imm, &lo, &hi);
(...skipping 16 matching lines...) Expand all
2129 } 2126 }
2130 } 2127 }
2131 } 2128 }
2132 2129
2133 2130
2134 void Assembler::vmov(const SwVfpRegister dst, 2131 void Assembler::vmov(const SwVfpRegister dst,
2135 const SwVfpRegister src, 2132 const SwVfpRegister src,
2136 const Condition cond) { 2133 const Condition cond) {
2137 // Sd = Sm 2134 // Sd = Sm
2138 // Instruction details available in ARM DDI 0406B, A8-642. 2135 // Instruction details available in ARM DDI 0406B, A8-642.
2139 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2136 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2140 int sd, d, sm, m; 2137 int sd, d, sm, m;
2141 dst.split_code(&sd, &d); 2138 dst.split_code(&sd, &d);
2142 src.split_code(&sm, &m); 2139 src.split_code(&sm, &m);
2143 emit(cond | 0xE*B24 | d*B22 | 0xB*B20 | sd*B12 | 0xA*B8 | B6 | m*B5 | sm); 2140 emit(cond | 0xE*B24 | d*B22 | 0xB*B20 | sd*B12 | 0xA*B8 | B6 | m*B5 | sm);
2144 } 2141 }
2145 2142
2146 2143
2147 void Assembler::vmov(const DwVfpRegister dst, 2144 void Assembler::vmov(const DwVfpRegister dst,
2148 const DwVfpRegister src, 2145 const DwVfpRegister src,
2149 const Condition cond) { 2146 const Condition cond) {
2150 // Dd = Dm 2147 // Dd = Dm
2151 // Instruction details available in ARM DDI 0406B, A8-642. 2148 // Instruction details available in ARM DDI 0406B, A8-642.
2152 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2149 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2153 emit(cond | 0xE*B24 | 0xB*B20 | 2150 emit(cond | 0xE*B24 | 0xB*B20 |
2154 dst.code()*B12 | 0x5*B9 | B8 | B6 | src.code()); 2151 dst.code()*B12 | 0x5*B9 | B8 | B6 | src.code());
2155 } 2152 }
2156 2153
2157 2154
2158 void Assembler::vmov(const DwVfpRegister dst, 2155 void Assembler::vmov(const DwVfpRegister dst,
2159 const Register src1, 2156 const Register src1,
2160 const Register src2, 2157 const Register src2,
2161 const Condition cond) { 2158 const Condition cond) {
2162 // Dm = <Rt,Rt2>. 2159 // Dm = <Rt,Rt2>.
2163 // Instruction details available in ARM DDI 0406A, A8-646. 2160 // Instruction details available in ARM DDI 0406A, A8-646.
2164 // cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) | 2161 // cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) |
2165 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm 2162 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm
2166 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2163 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2167 ASSERT(!src1.is(pc) && !src2.is(pc)); 2164 ASSERT(!src1.is(pc) && !src2.is(pc));
2168 emit(cond | 0xC*B24 | B22 | src2.code()*B16 | 2165 emit(cond | 0xC*B24 | B22 | src2.code()*B16 |
2169 src1.code()*B12 | 0xB*B8 | B4 | dst.code()); 2166 src1.code()*B12 | 0xB*B8 | B4 | dst.code());
2170 } 2167 }
2171 2168
2172 2169
2173 void Assembler::vmov(const Register dst1, 2170 void Assembler::vmov(const Register dst1,
2174 const Register dst2, 2171 const Register dst2,
2175 const DwVfpRegister src, 2172 const DwVfpRegister src,
2176 const Condition cond) { 2173 const Condition cond) {
2177 // <Rt,Rt2> = Dm. 2174 // <Rt,Rt2> = Dm.
2178 // Instruction details available in ARM DDI 0406A, A8-646. 2175 // Instruction details available in ARM DDI 0406A, A8-646.
2179 // cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) | 2176 // cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) |
2180 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm 2177 // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm
2181 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2178 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2182 ASSERT(!dst1.is(pc) && !dst2.is(pc)); 2179 ASSERT(!dst1.is(pc) && !dst2.is(pc));
2183 emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 | 2180 emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 |
2184 dst1.code()*B12 | 0xB*B8 | B4 | src.code()); 2181 dst1.code()*B12 | 0xB*B8 | B4 | src.code());
2185 } 2182 }
2186 2183
2187 2184
2188 void Assembler::vmov(const SwVfpRegister dst, 2185 void Assembler::vmov(const SwVfpRegister dst,
2189 const Register src, 2186 const Register src,
2190 const Condition cond) { 2187 const Condition cond) {
2191 // Sn = Rt. 2188 // Sn = Rt.
2192 // Instruction details available in ARM DDI 0406A, A8-642. 2189 // Instruction details available in ARM DDI 0406A, A8-642.
2193 // cond(31-28) | 1110(27-24)| 000(23-21) | op=0(20) | Vn(19-16) | 2190 // cond(31-28) | 1110(27-24)| 000(23-21) | op=0(20) | Vn(19-16) |
2194 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) 2191 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0)
2195 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2192 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2196 ASSERT(!src.is(pc)); 2193 ASSERT(!src.is(pc));
2197 int sn, n; 2194 int sn, n;
2198 dst.split_code(&sn, &n); 2195 dst.split_code(&sn, &n);
2199 emit(cond | 0xE*B24 | sn*B16 | src.code()*B12 | 0xA*B8 | n*B7 | B4); 2196 emit(cond | 0xE*B24 | sn*B16 | src.code()*B12 | 0xA*B8 | n*B7 | B4);
2200 } 2197 }
2201 2198
2202 2199
2203 void Assembler::vmov(const Register dst, 2200 void Assembler::vmov(const Register dst,
2204 const SwVfpRegister src, 2201 const SwVfpRegister src,
2205 const Condition cond) { 2202 const Condition cond) {
2206 // Rt = Sn. 2203 // Rt = Sn.
2207 // Instruction details available in ARM DDI 0406A, A8-642. 2204 // Instruction details available in ARM DDI 0406A, A8-642.
2208 // cond(31-28) | 1110(27-24)| 000(23-21) | op=1(20) | Vn(19-16) | 2205 // cond(31-28) | 1110(27-24)| 000(23-21) | op=1(20) | Vn(19-16) |
2209 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) 2206 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0)
2210 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2207 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2211 ASSERT(!dst.is(pc)); 2208 ASSERT(!dst.is(pc));
2212 int sn, n; 2209 int sn, n;
2213 src.split_code(&sn, &n); 2210 src.split_code(&sn, &n);
2214 emit(cond | 0xE*B24 | B20 | sn*B16 | dst.code()*B12 | 0xA*B8 | n*B7 | B4); 2211 emit(cond | 0xE*B24 | B20 | sn*B16 | dst.code()*B12 | 0xA*B8 | n*B7 | B4);
2215 } 2212 }
2216 2213
2217 2214
2218 // Type of data to read from or write to VFP register. 2215 // Type of data to read from or write to VFP register.
2219 // Used as specifier in generic vcvt instruction. 2216 // Used as specifier in generic vcvt instruction.
2220 enum VFPType { S32, U32, F32, F64 }; 2217 enum VFPType { S32, U32, F32, F64 };
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
2325 return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | 0x7*B16 | 2322 return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | 0x7*B16 |
2326 Vd*B12 | 0x5*B9 | sz*B8 | B7 | B6 | M*B5 | Vm); 2323 Vd*B12 | 0x5*B9 | sz*B8 | B7 | B6 | M*B5 | Vm);
2327 } 2324 }
2328 } 2325 }
2329 2326
2330 2327
2331 void Assembler::vcvt_f64_s32(const DwVfpRegister dst, 2328 void Assembler::vcvt_f64_s32(const DwVfpRegister dst,
2332 const SwVfpRegister src, 2329 const SwVfpRegister src,
2333 VFPConversionMode mode, 2330 VFPConversionMode mode,
2334 const Condition cond) { 2331 const Condition cond) {
2335 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2332 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2336 emit(EncodeVCVT(F64, dst.code(), S32, src.code(), mode, cond)); 2333 emit(EncodeVCVT(F64, dst.code(), S32, src.code(), mode, cond));
2337 } 2334 }
2338 2335
2339 2336
2340 void Assembler::vcvt_f32_s32(const SwVfpRegister dst, 2337 void Assembler::vcvt_f32_s32(const SwVfpRegister dst,
2341 const SwVfpRegister src, 2338 const SwVfpRegister src,
2342 VFPConversionMode mode, 2339 VFPConversionMode mode,
2343 const Condition cond) { 2340 const Condition cond) {
2344 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2341 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2345 emit(EncodeVCVT(F32, dst.code(), S32, src.code(), mode, cond)); 2342 emit(EncodeVCVT(F32, dst.code(), S32, src.code(), mode, cond));
2346 } 2343 }
2347 2344
2348 2345
2349 void Assembler::vcvt_f64_u32(const DwVfpRegister dst, 2346 void Assembler::vcvt_f64_u32(const DwVfpRegister dst,
2350 const SwVfpRegister src, 2347 const SwVfpRegister src,
2351 VFPConversionMode mode, 2348 VFPConversionMode mode,
2352 const Condition cond) { 2349 const Condition cond) {
2353 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2350 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2354 emit(EncodeVCVT(F64, dst.code(), U32, src.code(), mode, cond)); 2351 emit(EncodeVCVT(F64, dst.code(), U32, src.code(), mode, cond));
2355 } 2352 }
2356 2353
2357 2354
2358 void Assembler::vcvt_s32_f64(const SwVfpRegister dst, 2355 void Assembler::vcvt_s32_f64(const SwVfpRegister dst,
2359 const DwVfpRegister src, 2356 const DwVfpRegister src,
2360 VFPConversionMode mode, 2357 VFPConversionMode mode,
2361 const Condition cond) { 2358 const Condition cond) {
2362 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2359 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2363 emit(EncodeVCVT(S32, dst.code(), F64, src.code(), mode, cond)); 2360 emit(EncodeVCVT(S32, dst.code(), F64, src.code(), mode, cond));
2364 } 2361 }
2365 2362
2366 2363
2367 void Assembler::vcvt_u32_f64(const SwVfpRegister dst, 2364 void Assembler::vcvt_u32_f64(const SwVfpRegister dst,
2368 const DwVfpRegister src, 2365 const DwVfpRegister src,
2369 VFPConversionMode mode, 2366 VFPConversionMode mode,
2370 const Condition cond) { 2367 const Condition cond) {
2371 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2368 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2372 emit(EncodeVCVT(U32, dst.code(), F64, src.code(), mode, cond)); 2369 emit(EncodeVCVT(U32, dst.code(), F64, src.code(), mode, cond));
2373 } 2370 }
2374 2371
2375 2372
2376 void Assembler::vcvt_f64_f32(const DwVfpRegister dst, 2373 void Assembler::vcvt_f64_f32(const DwVfpRegister dst,
2377 const SwVfpRegister src, 2374 const SwVfpRegister src,
2378 VFPConversionMode mode, 2375 VFPConversionMode mode,
2379 const Condition cond) { 2376 const Condition cond) {
2380 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2377 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2381 emit(EncodeVCVT(F64, dst.code(), F32, src.code(), mode, cond)); 2378 emit(EncodeVCVT(F64, dst.code(), F32, src.code(), mode, cond));
2382 } 2379 }
2383 2380
2384 2381
2385 void Assembler::vcvt_f32_f64(const SwVfpRegister dst, 2382 void Assembler::vcvt_f32_f64(const SwVfpRegister dst,
2386 const DwVfpRegister src, 2383 const DwVfpRegister src,
2387 VFPConversionMode mode, 2384 VFPConversionMode mode,
2388 const Condition cond) { 2385 const Condition cond) {
2389 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2386 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2390 emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond)); 2387 emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond));
2391 } 2388 }
2392 2389
2393 2390
2394 void Assembler::vneg(const DwVfpRegister dst, 2391 void Assembler::vneg(const DwVfpRegister dst,
2395 const DwVfpRegister src, 2392 const DwVfpRegister src,
2396 const Condition cond) { 2393 const Condition cond) {
2397 emit(cond | 0xE*B24 | 0xB*B20 | B16 | dst.code()*B12 | 2394 emit(cond | 0xE*B24 | 0xB*B20 | B16 | dst.code()*B12 |
2398 0x5*B9 | B8 | B6 | src.code()); 2395 0x5*B9 | B8 | B6 | src.code());
2399 } 2396 }
2400 2397
2401 2398
2402 void Assembler::vabs(const DwVfpRegister dst, 2399 void Assembler::vabs(const DwVfpRegister dst,
2403 const DwVfpRegister src, 2400 const DwVfpRegister src,
2404 const Condition cond) { 2401 const Condition cond) {
2405 emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 | 2402 emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 |
2406 0x5*B9 | B8 | 0x3*B6 | src.code()); 2403 0x5*B9 | B8 | 0x3*B6 | src.code());
2407 } 2404 }
2408 2405
2409 2406
2410 void Assembler::vadd(const DwVfpRegister dst, 2407 void Assembler::vadd(const DwVfpRegister dst,
2411 const DwVfpRegister src1, 2408 const DwVfpRegister src1,
2412 const DwVfpRegister src2, 2409 const DwVfpRegister src2,
2413 const Condition cond) { 2410 const Condition cond) {
2414 // Dd = vadd(Dn, Dm) double precision floating point addition. 2411 // Dd = vadd(Dn, Dm) double precision floating point addition.
2415 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. 2412 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
2416 // Instruction details available in ARM DDI 0406A, A8-536. 2413 // Instruction details available in ARM DDI 0406A, A8-536.
2417 // cond(31-28) | 11100(27-23)| D=?(22) | 11(21-20) | Vn(19-16) | 2414 // cond(31-28) | 11100(27-23)| D=?(22) | 11(21-20) | Vn(19-16) |
2418 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 0(6) | M=?(5) | 0(4) | Vm(3-0) 2415 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 0(6) | M=?(5) | 0(4) | Vm(3-0)
2419 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2416 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2420 emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | 2417 emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 |
2421 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); 2418 dst.code()*B12 | 0x5*B9 | B8 | src2.code());
2422 } 2419 }
2423 2420
2424 2421
2425 void Assembler::vsub(const DwVfpRegister dst, 2422 void Assembler::vsub(const DwVfpRegister dst,
2426 const DwVfpRegister src1, 2423 const DwVfpRegister src1,
2427 const DwVfpRegister src2, 2424 const DwVfpRegister src2,
2428 const Condition cond) { 2425 const Condition cond) {
2429 // Dd = vsub(Dn, Dm) double precision floating point subtraction. 2426 // Dd = vsub(Dn, Dm) double precision floating point subtraction.
2430 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. 2427 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
2431 // Instruction details available in ARM DDI 0406A, A8-784. 2428 // Instruction details available in ARM DDI 0406A, A8-784.
2432 // cond(31-28) | 11100(27-23)| D=?(22) | 11(21-20) | Vn(19-16) | 2429 // cond(31-28) | 11100(27-23)| D=?(22) | 11(21-20) | Vn(19-16) |
2433 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 1(6) | M=?(5) | 0(4) | Vm(3-0) 2430 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 1(6) | M=?(5) | 0(4) | Vm(3-0)
2434 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2431 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2435 emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | 2432 emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 |
2436 dst.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); 2433 dst.code()*B12 | 0x5*B9 | B8 | B6 | src2.code());
2437 } 2434 }
2438 2435
2439 2436
2440 void Assembler::vmul(const DwVfpRegister dst, 2437 void Assembler::vmul(const DwVfpRegister dst,
2441 const DwVfpRegister src1, 2438 const DwVfpRegister src1,
2442 const DwVfpRegister src2, 2439 const DwVfpRegister src2,
2443 const Condition cond) { 2440 const Condition cond) {
2444 // Dd = vmul(Dn, Dm) double precision floating point multiplication. 2441 // Dd = vmul(Dn, Dm) double precision floating point multiplication.
2445 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. 2442 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
2446 // Instruction details available in ARM DDI 0406A, A8-784. 2443 // Instruction details available in ARM DDI 0406A, A8-784.
2447 // cond(31-28) | 11100(27-23)| D=?(22) | 10(21-20) | Vn(19-16) | 2444 // cond(31-28) | 11100(27-23)| D=?(22) | 10(21-20) | Vn(19-16) |
2448 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 0(6) | M=?(5) | 0(4) | Vm(3-0) 2445 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 0(6) | M=?(5) | 0(4) | Vm(3-0)
2449 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2446 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2450 emit(cond | 0xE*B24 | 0x2*B20 | src1.code()*B16 | 2447 emit(cond | 0xE*B24 | 0x2*B20 | src1.code()*B16 |
2451 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); 2448 dst.code()*B12 | 0x5*B9 | B8 | src2.code());
2452 } 2449 }
2453 2450
2454 2451
2455 void Assembler::vdiv(const DwVfpRegister dst, 2452 void Assembler::vdiv(const DwVfpRegister dst,
2456 const DwVfpRegister src1, 2453 const DwVfpRegister src1,
2457 const DwVfpRegister src2, 2454 const DwVfpRegister src2,
2458 const Condition cond) { 2455 const Condition cond) {
2459 // Dd = vdiv(Dn, Dm) double precision floating point division. 2456 // Dd = vdiv(Dn, Dm) double precision floating point division.
2460 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. 2457 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm.
2461 // Instruction details available in ARM DDI 0406A, A8-584. 2458 // Instruction details available in ARM DDI 0406A, A8-584.
2462 // cond(31-28) | 11101(27-23)| D=?(22) | 00(21-20) | Vn(19-16) | 2459 // cond(31-28) | 11101(27-23)| D=?(22) | 00(21-20) | Vn(19-16) |
2463 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=? | 0(6) | M=?(5) | 0(4) | Vm(3-0) 2460 // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=? | 0(6) | M=?(5) | 0(4) | Vm(3-0)
2464 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2461 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2465 emit(cond | 0xE*B24 | B23 | src1.code()*B16 | 2462 emit(cond | 0xE*B24 | B23 | src1.code()*B16 |
2466 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); 2463 dst.code()*B12 | 0x5*B9 | B8 | src2.code());
2467 } 2464 }
2468 2465
2469 2466
2470 void Assembler::vcmp(const DwVfpRegister src1, 2467 void Assembler::vcmp(const DwVfpRegister src1,
2471 const DwVfpRegister src2, 2468 const DwVfpRegister src2,
2472 const Condition cond) { 2469 const Condition cond) {
2473 // vcmp(Dd, Dm) double precision floating point comparison. 2470 // vcmp(Dd, Dm) double precision floating point comparison.
2474 // Instruction details available in ARM DDI 0406A, A8-570. 2471 // Instruction details available in ARM DDI 0406A, A8-570.
2475 // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0100 (19-16) | 2472 // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0100 (19-16) |
2476 // Vd(15-12) | 101(11-9) | sz(8)=1 | E(7)=0 | 1(6) | M(5)=? | 0(4) | Vm(3-0) 2473 // Vd(15-12) | 101(11-9) | sz(8)=1 | E(7)=0 | 1(6) | M(5)=? | 0(4) | Vm(3-0)
2477 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2474 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2478 emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | 2475 emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 |
2479 src1.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); 2476 src1.code()*B12 | 0x5*B9 | B8 | B6 | src2.code());
2480 } 2477 }
2481 2478
2482 2479
2483 void Assembler::vcmp(const DwVfpRegister src1, 2480 void Assembler::vcmp(const DwVfpRegister src1,
2484 const double src2, 2481 const double src2,
2485 const Condition cond) { 2482 const Condition cond) {
2486 // vcmp(Dd, Dm) double precision floating point comparison. 2483 // vcmp(Dd, Dm) double precision floating point comparison.
2487 // Instruction details available in ARM DDI 0406A, A8-570. 2484 // Instruction details available in ARM DDI 0406A, A8-570.
2488 // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0101 (19-16) | 2485 // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0101 (19-16) |
2489 // Vd(15-12) | 101(11-9) | sz(8)=1 | E(7)=0 | 1(6) | M(5)=? | 0(4) | 0000(3-0) 2486 // Vd(15-12) | 101(11-9) | sz(8)=1 | E(7)=0 | 1(6) | M(5)=? | 0(4) | 0000(3-0)
2490 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2487 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2491 ASSERT(src2 == 0.0); 2488 ASSERT(src2 == 0.0);
2492 emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | B16 | 2489 emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | B16 |
2493 src1.code()*B12 | 0x5*B9 | B8 | B6); 2490 src1.code()*B12 | 0x5*B9 | B8 | B6);
2494 } 2491 }
2495 2492
2496 2493
2497 void Assembler::vmsr(Register dst, Condition cond) { 2494 void Assembler::vmsr(Register dst, Condition cond) {
2498 // Instruction details available in ARM DDI 0406A, A8-652. 2495 // Instruction details available in ARM DDI 0406A, A8-652.
2499 // cond(31-28) | 1110 (27-24) | 1110(23-20)| 0001 (19-16) | 2496 // cond(31-28) | 1110 (27-24) | 1110(23-20)| 0001 (19-16) |
2500 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) 2497 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0)
2501 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2498 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2502 emit(cond | 0xE*B24 | 0xE*B20 | B16 | 2499 emit(cond | 0xE*B24 | 0xE*B20 | B16 |
2503 dst.code()*B12 | 0xA*B8 | B4); 2500 dst.code()*B12 | 0xA*B8 | B4);
2504 } 2501 }
2505 2502
2506 2503
2507 void Assembler::vmrs(Register dst, Condition cond) { 2504 void Assembler::vmrs(Register dst, Condition cond) {
2508 // Instruction details available in ARM DDI 0406A, A8-652. 2505 // Instruction details available in ARM DDI 0406A, A8-652.
2509 // cond(31-28) | 1110 (27-24) | 1111(23-20)| 0001 (19-16) | 2506 // cond(31-28) | 1110 (27-24) | 1111(23-20)| 0001 (19-16) |
2510 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) 2507 // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0)
2511 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2508 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2512 emit(cond | 0xE*B24 | 0xF*B20 | B16 | 2509 emit(cond | 0xE*B24 | 0xF*B20 | B16 |
2513 dst.code()*B12 | 0xA*B8 | B4); 2510 dst.code()*B12 | 0xA*B8 | B4);
2514 } 2511 }
2515 2512
2516 2513
2517 void Assembler::vsqrt(const DwVfpRegister dst, 2514 void Assembler::vsqrt(const DwVfpRegister dst,
2518 const DwVfpRegister src, 2515 const DwVfpRegister src,
2519 const Condition cond) { 2516 const Condition cond) {
2520 // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0001 (19-16) | 2517 // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0001 (19-16) |
2521 // Vd(15-12) | 101(11-9) | sz(8)=1 | 11 (7-6) | M(5)=? | 0(4) | Vm(3-0) 2518 // Vd(15-12) | 101(11-9) | sz(8)=1 | 11 (7-6) | M(5)=? | 0(4) | Vm(3-0)
2522 ASSERT(CpuFeatures::IsEnabled(VFP3)); 2519 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3));
2523 emit(cond | 0xE*B24 | B23 | 0x3*B20 | B16 | 2520 emit(cond | 0xE*B24 | B23 | 0x3*B20 | B16 |
2524 dst.code()*B12 | 0x5*B9 | B8 | 3*B6 | src.code()); 2521 dst.code()*B12 | 0x5*B9 | B8 | 3*B6 | src.code());
2525 } 2522 }
2526 2523
2527 2524
2528 // Pseudo instructions. 2525 // Pseudo instructions.
2529 void Assembler::nop(int type) { 2526 void Assembler::nop(int type) {
2530 // This is mov rx, rx. 2527 // This is mov rx, rx.
2531 ASSERT(0 <= type && type <= 14); // mov pc, pc is not a nop. 2528 ASSERT(0 <= type && type <= 14); // mov pc, pc is not a nop.
2532 emit(al | 13*B21 | type*B12 | type); 2529 emit(al | 13*B21 | type*B12 | type);
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
2786 2783
2787 // Since a constant pool was just emitted, move the check offset forward by 2784 // Since a constant pool was just emitted, move the check offset forward by
2788 // the standard interval. 2785 // the standard interval.
2789 next_buffer_check_ = pc_offset() + kCheckConstInterval; 2786 next_buffer_check_ = pc_offset() + kCheckConstInterval;
2790 } 2787 }
2791 2788
2792 2789
2793 } } // namespace v8::internal 2790 } } // namespace v8::internal
2794 2791
2795 #endif // V8_TARGET_ARCH_ARM 2792 #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