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