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