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

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

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