| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |