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 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 | 269 |
270 | 270 |
271 Assembler::Assembler(void* buffer, int buffer_size) | 271 Assembler::Assembler(void* buffer, int buffer_size) |
272 : positions_recorder_(this), | 272 : AssemblerBase(Isolate::Current()), |
| 273 positions_recorder_(this), |
273 allow_peephole_optimization_(false), | 274 allow_peephole_optimization_(false), |
274 emit_debug_code_(FLAG_debug_code) { | 275 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 (isolate->assembler_spare_buffer() != NULL) { | 282 if (isolate()->assembler_spare_buffer() != NULL) { |
283 buffer = isolate->assembler_spare_buffer(); | 283 buffer = isolate()->assembler_spare_buffer(); |
284 isolate->set_assembler_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(); | |
318 ASSERT(const_pool_blocked_nesting_ == 0); | 317 ASSERT(const_pool_blocked_nesting_ == 0); |
319 if (own_buffer_) { | 318 if (own_buffer_) { |
320 if (isolate->assembler_spare_buffer() == NULL && | 319 if (isolate()->assembler_spare_buffer() == NULL && |
321 buffer_size_ == kMinimalBufferSize) { | 320 buffer_size_ == kMinimalBufferSize) { |
322 isolate->set_assembler_spare_buffer(buffer_); | 321 isolate()->set_assembler_spare_buffer(buffer_); |
323 } else { | 322 } else { |
324 DeleteArray(buffer_); | 323 DeleteArray(buffer_); |
325 } | 324 } |
326 } | 325 } |
327 } | 326 } |
328 | 327 |
329 | 328 |
330 void Assembler::GetCode(CodeDesc* desc) { | 329 void Assembler::GetCode(CodeDesc* desc) { |
331 // Emit constant pool if necessary. | 330 // Emit constant pool if necessary. |
332 CheckConstPool(true, false); | 331 CheckConstPool(true, false); |
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
816 if (x.must_use_constant_pool() || | 815 if (x.must_use_constant_pool() || |
817 !fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) { | 816 !fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) { |
818 // 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 |
819 // 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. |
820 // 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 |
821 // condition code), then replace it with a 'ldr rd, [pc]'. | 820 // condition code), then replace it with a 'ldr rd, [pc]'. |
822 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 |
823 Condition cond = Instruction::ConditionField(instr); | 822 Condition cond = Instruction::ConditionField(instr); |
824 if ((instr & ~kCondMask) == 13*B21) { // mov, S not set | 823 if ((instr & ~kCondMask) == 13*B21) { // mov, S not set |
825 if (x.must_use_constant_pool() || | 824 if (x.must_use_constant_pool() || |
826 !Isolate::Current()->cpu_features()->IsSupported(ARMv7)) { | 825 !isolate()->cpu_features()->IsSupported(ARMv7)) { |
827 RecordRelocInfo(x.rmode_, x.imm32_); | 826 RecordRelocInfo(x.rmode_, x.imm32_); |
828 ldr(rd, MemOperand(pc, 0), cond); | 827 ldr(rd, MemOperand(pc, 0), cond); |
829 } else { | 828 } else { |
830 // Will probably use movw, will certainly not use constant pool. | 829 // Will probably use movw, will certainly not use constant pool. |
831 mov(rd, Operand(x.imm32_ & 0xffff), LeaveCC, cond); | 830 mov(rd, Operand(x.imm32_ & 0xffff), LeaveCC, cond); |
832 movt(rd, static_cast<uint32_t>(x.imm32_) >> 16, cond); | 831 movt(rd, static_cast<uint32_t>(x.imm32_) >> 16, cond); |
833 } | 832 } |
834 } else { | 833 } else { |
835 // 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 |
836 // 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... |
1259 | 1258 |
1260 | 1259 |
1261 // Saturating instructions. | 1260 // Saturating instructions. |
1262 | 1261 |
1263 // Unsigned saturate. | 1262 // Unsigned saturate. |
1264 void Assembler::usat(Register dst, | 1263 void Assembler::usat(Register dst, |
1265 int satpos, | 1264 int satpos, |
1266 const Operand& src, | 1265 const Operand& src, |
1267 Condition cond) { | 1266 Condition cond) { |
1268 // v6 and above. | 1267 // v6 and above. |
1269 ASSERT(Isolate::Current()->cpu_features()->IsSupported(ARMv7)); | 1268 ASSERT(isolate()->cpu_features()->IsSupported(ARMv7)); |
1270 ASSERT(!dst.is(pc) && !src.rm_.is(pc)); | 1269 ASSERT(!dst.is(pc) && !src.rm_.is(pc)); |
1271 ASSERT((satpos >= 0) && (satpos <= 31)); | 1270 ASSERT((satpos >= 0) && (satpos <= 31)); |
1272 ASSERT((src.shift_op_ == ASR) || (src.shift_op_ == LSL)); | 1271 ASSERT((src.shift_op_ == ASR) || (src.shift_op_ == LSL)); |
1273 ASSERT(src.rs_.is(no_reg)); | 1272 ASSERT(src.rs_.is(no_reg)); |
1274 | 1273 |
1275 int sh = 0; | 1274 int sh = 0; |
1276 if (src.shift_op_ == ASR) { | 1275 if (src.shift_op_ == ASR) { |
1277 sh = 1; | 1276 sh = 1; |
1278 } | 1277 } |
1279 | 1278 |
1280 emit(cond | 0x6*B24 | 0xe*B20 | satpos*B16 | dst.code()*B12 | | 1279 emit(cond | 0x6*B24 | 0xe*B20 | satpos*B16 | dst.code()*B12 | |
1281 src.shift_imm_*B7 | sh*B6 | 0x1*B4 | src.rm_.code()); | 1280 src.shift_imm_*B7 | sh*B6 | 0x1*B4 | src.rm_.code()); |
1282 } | 1281 } |
1283 | 1282 |
1284 | 1283 |
1285 // Bitfield manipulation instructions. | 1284 // Bitfield manipulation instructions. |
1286 | 1285 |
1287 // Unsigned bit field extract. | 1286 // Unsigned bit field extract. |
1288 // Extracts #width adjacent bits from position #lsb in a register, and | 1287 // Extracts #width adjacent bits from position #lsb in a register, and |
1289 // writes them to the low bits of a destination register. | 1288 // writes them to the low bits of a destination register. |
1290 // ubfx dst, src, #lsb, #width | 1289 // ubfx dst, src, #lsb, #width |
1291 void Assembler::ubfx(Register dst, | 1290 void Assembler::ubfx(Register dst, |
1292 Register src, | 1291 Register src, |
1293 int lsb, | 1292 int lsb, |
1294 int width, | 1293 int width, |
1295 Condition cond) { | 1294 Condition cond) { |
1296 // v7 and above. | 1295 // v7 and above. |
1297 ASSERT(Isolate::Current()->cpu_features()->IsSupported(ARMv7)); | 1296 ASSERT(isolate()->cpu_features()->IsSupported(ARMv7)); |
1298 ASSERT(!dst.is(pc) && !src.is(pc)); | 1297 ASSERT(!dst.is(pc) && !src.is(pc)); |
1299 ASSERT((lsb >= 0) && (lsb <= 31)); | 1298 ASSERT((lsb >= 0) && (lsb <= 31)); |
1300 ASSERT((width >= 1) && (width <= (32 - lsb))); | 1299 ASSERT((width >= 1) && (width <= (32 - lsb))); |
1301 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 | |
1302 lsb*B7 | B6 | B4 | src.code()); | 1301 lsb*B7 | B6 | B4 | src.code()); |
1303 } | 1302 } |
1304 | 1303 |
1305 | 1304 |
1306 // Signed bit field extract. | 1305 // Signed bit field extract. |
1307 // Extracts #width adjacent bits from position #lsb in a register, and | 1306 // Extracts #width adjacent bits from position #lsb in a register, and |
1308 // 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 |
1309 // value is sign extended to fill the destination register. | 1308 // value is sign extended to fill the destination register. |
1310 // sbfx dst, src, #lsb, #width | 1309 // sbfx dst, src, #lsb, #width |
1311 void Assembler::sbfx(Register dst, | 1310 void Assembler::sbfx(Register dst, |
1312 Register src, | 1311 Register src, |
1313 int lsb, | 1312 int lsb, |
1314 int width, | 1313 int width, |
1315 Condition cond) { | 1314 Condition cond) { |
1316 // v7 and above. | 1315 // v7 and above. |
1317 ASSERT(Isolate::Current()->cpu_features()->IsSupported(ARMv7)); | 1316 ASSERT(isolate()->cpu_features()->IsSupported(ARMv7)); |
1318 ASSERT(!dst.is(pc) && !src.is(pc)); | 1317 ASSERT(!dst.is(pc) && !src.is(pc)); |
1319 ASSERT((lsb >= 0) && (lsb <= 31)); | 1318 ASSERT((lsb >= 0) && (lsb <= 31)); |
1320 ASSERT((width >= 1) && (width <= (32 - lsb))); | 1319 ASSERT((width >= 1) && (width <= (32 - lsb))); |
1321 emit(cond | 0xf*B23 | B21 | (width - 1)*B16 | dst.code()*B12 | | 1320 emit(cond | 0xf*B23 | B21 | (width - 1)*B16 | dst.code()*B12 | |
1322 lsb*B7 | B6 | B4 | src.code()); | 1321 lsb*B7 | B6 | B4 | src.code()); |
1323 } | 1322 } |
1324 | 1323 |
1325 | 1324 |
1326 // Bit field clear. | 1325 // Bit field clear. |
1327 // Sets #width adjacent bits at position #lsb in the destination register | 1326 // Sets #width adjacent bits at position #lsb in the destination register |
1328 // to zero, preserving the value of the other bits. | 1327 // to zero, preserving the value of the other bits. |
1329 // bfc dst, #lsb, #width | 1328 // bfc dst, #lsb, #width |
1330 void Assembler::bfc(Register dst, int lsb, int width, Condition cond) { | 1329 void Assembler::bfc(Register dst, int lsb, int width, Condition cond) { |
1331 // v7 and above. | 1330 // v7 and above. |
1332 ASSERT(Isolate::Current()->cpu_features()->IsSupported(ARMv7)); | 1331 ASSERT(isolate()->cpu_features()->IsSupported(ARMv7)); |
1333 ASSERT(!dst.is(pc)); | 1332 ASSERT(!dst.is(pc)); |
1334 ASSERT((lsb >= 0) && (lsb <= 31)); | 1333 ASSERT((lsb >= 0) && (lsb <= 31)); |
1335 ASSERT((width >= 1) && (width <= (32 - lsb))); | 1334 ASSERT((width >= 1) && (width <= (32 - lsb))); |
1336 int msb = lsb + width - 1; | 1335 int msb = lsb + width - 1; |
1337 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); |
1338 } | 1337 } |
1339 | 1338 |
1340 | 1339 |
1341 // Bit field insert. | 1340 // Bit field insert. |
1342 // 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 |
1343 // into position #lsb of the destination register. | 1342 // into position #lsb of the destination register. |
1344 // bfi dst, src, #lsb, #width | 1343 // bfi dst, src, #lsb, #width |
1345 void Assembler::bfi(Register dst, | 1344 void Assembler::bfi(Register dst, |
1346 Register src, | 1345 Register src, |
1347 int lsb, | 1346 int lsb, |
1348 int width, | 1347 int width, |
1349 Condition cond) { | 1348 Condition cond) { |
1350 // v7 and above. | 1349 // v7 and above. |
1351 ASSERT(Isolate::Current()->cpu_features()->IsSupported(ARMv7)); | 1350 ASSERT(isolate()->cpu_features()->IsSupported(ARMv7)); |
1352 ASSERT(!dst.is(pc) && !src.is(pc)); | 1351 ASSERT(!dst.is(pc) && !src.is(pc)); |
1353 ASSERT((lsb >= 0) && (lsb <= 31)); | 1352 ASSERT((lsb >= 0) && (lsb <= 31)); |
1354 ASSERT((width >= 1) && (width <= (32 - lsb))); | 1353 ASSERT((width >= 1) && (width <= (32 - lsb))); |
1355 int msb = lsb + width - 1; | 1354 int msb = lsb + width - 1; |
1356 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 | |
1357 src.code()); | 1356 src.code()); |
1358 } | 1357 } |
1359 | 1358 |
1360 | 1359 |
1361 // Status register access instructions. | 1360 // Status register access instructions. |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1613 } | 1612 } |
1614 | 1613 |
1615 | 1614 |
1616 void Assembler::ldrsh(Register dst, const MemOperand& src, Condition cond) { | 1615 void Assembler::ldrsh(Register dst, const MemOperand& src, Condition cond) { |
1617 addrmod3(cond | L | B7 | S6 | H | B4, dst, src); | 1616 addrmod3(cond | L | B7 | S6 | H | B4, dst, src); |
1618 } | 1617 } |
1619 | 1618 |
1620 | 1619 |
1621 void Assembler::ldrd(Register dst1, Register dst2, | 1620 void Assembler::ldrd(Register dst1, Register dst2, |
1622 const MemOperand& src, Condition cond) { | 1621 const MemOperand& src, Condition cond) { |
1623 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(ARMv7)); | 1622 ASSERT(isolate()->cpu_features()->IsEnabled(ARMv7)); |
1624 ASSERT(src.rm().is(no_reg)); | 1623 ASSERT(src.rm().is(no_reg)); |
1625 ASSERT(!dst1.is(lr)); // r14. | 1624 ASSERT(!dst1.is(lr)); // r14. |
1626 ASSERT_EQ(0, dst1.code() % 2); | 1625 ASSERT_EQ(0, dst1.code() % 2); |
1627 ASSERT_EQ(dst1.code() + 1, dst2.code()); | 1626 ASSERT_EQ(dst1.code() + 1, dst2.code()); |
1628 addrmod3(cond | B7 | B6 | B4, dst1, src); | 1627 addrmod3(cond | B7 | B6 | B4, dst1, src); |
1629 } | 1628 } |
1630 | 1629 |
1631 | 1630 |
1632 void Assembler::strd(Register src1, Register src2, | 1631 void Assembler::strd(Register src1, Register src2, |
1633 const MemOperand& dst, Condition cond) { | 1632 const MemOperand& dst, Condition cond) { |
1634 ASSERT(dst.rm().is(no_reg)); | 1633 ASSERT(dst.rm().is(no_reg)); |
1635 ASSERT(!src1.is(lr)); // r14. | 1634 ASSERT(!src1.is(lr)); // r14. |
1636 ASSERT_EQ(0, src1.code() % 2); | 1635 ASSERT_EQ(0, src1.code() % 2); |
1637 ASSERT_EQ(src1.code() + 1, src2.code()); | 1636 ASSERT_EQ(src1.code() + 1, src2.code()); |
1638 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(ARMv7)); | 1637 ASSERT(isolate()->cpu_features()->IsEnabled(ARMv7)); |
1639 addrmod3(cond | B7 | B6 | B5 | B4, src1, dst); | 1638 addrmod3(cond | B7 | B6 | B5 | B4, src1, dst); |
1640 } | 1639 } |
1641 | 1640 |
1642 // Load/Store multiple instructions. | 1641 // Load/Store multiple instructions. |
1643 void Assembler::ldm(BlockAddrMode am, | 1642 void Assembler::ldm(BlockAddrMode am, |
1644 Register base, | 1643 Register base, |
1645 RegList dst, | 1644 RegList dst, |
1646 Condition cond) { | 1645 Condition cond) { |
1647 // ABI stack constraint: ldmxx base, {..sp..} base != sp is not restartable. | 1646 // ABI stack constraint: ldmxx base, {..sp..} base != sp is not restartable. |
1648 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... |
1864 // Support for VFP. | 1863 // Support for VFP. |
1865 | 1864 |
1866 void Assembler::vldr(const DwVfpRegister dst, | 1865 void Assembler::vldr(const DwVfpRegister dst, |
1867 const Register base, | 1866 const Register base, |
1868 int offset, | 1867 int offset, |
1869 const Condition cond) { | 1868 const Condition cond) { |
1870 // Ddst = MEM(Rbase + offset). | 1869 // Ddst = MEM(Rbase + offset). |
1871 // Instruction details available in ARM DDI 0406A, A8-628. | 1870 // Instruction details available in ARM DDI 0406A, A8-628. |
1872 // 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) | |
1873 // Vdst(15-12) | 1011(11-8) | offset | 1872 // Vdst(15-12) | 1011(11-8) | offset |
1874 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 1873 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
1875 int u = 1; | 1874 int u = 1; |
1876 if (offset < 0) { | 1875 if (offset < 0) { |
1877 offset = -offset; | 1876 offset = -offset; |
1878 u = 0; | 1877 u = 0; |
1879 } | 1878 } |
1880 | 1879 |
1881 ASSERT(offset >= 0); | 1880 ASSERT(offset >= 0); |
1882 if ((offset % 4) == 0 && (offset / 4) < 256) { | 1881 if ((offset % 4) == 0 && (offset / 4) < 256) { |
1883 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 | |
1884 0xB*B8 | ((offset / 4) & 255)); | 1883 0xB*B8 | ((offset / 4) & 255)); |
(...skipping 21 matching lines...) Expand all Loading... |
1906 | 1905 |
1907 | 1906 |
1908 void Assembler::vldr(const SwVfpRegister dst, | 1907 void Assembler::vldr(const SwVfpRegister dst, |
1909 const Register base, | 1908 const Register base, |
1910 int offset, | 1909 int offset, |
1911 const Condition cond) { | 1910 const Condition cond) { |
1912 // Sdst = MEM(Rbase + offset). | 1911 // Sdst = MEM(Rbase + offset). |
1913 // Instruction details available in ARM DDI 0406A, A8-628. | 1912 // Instruction details available in ARM DDI 0406A, A8-628. |
1914 // 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) | |
1915 // Vdst(15-12) | 1010(11-8) | offset | 1914 // Vdst(15-12) | 1010(11-8) | offset |
1916 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 1915 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
1917 int u = 1; | 1916 int u = 1; |
1918 if (offset < 0) { | 1917 if (offset < 0) { |
1919 offset = -offset; | 1918 offset = -offset; |
1920 u = 0; | 1919 u = 0; |
1921 } | 1920 } |
1922 int sd, d; | 1921 int sd, d; |
1923 dst.split_code(&sd, &d); | 1922 dst.split_code(&sd, &d); |
1924 ASSERT(offset >= 0); | 1923 ASSERT(offset >= 0); |
1925 | 1924 |
1926 if ((offset % 4) == 0 && (offset / 4) < 256) { | 1925 if ((offset % 4) == 0 && (offset / 4) < 256) { |
(...skipping 23 matching lines...) Expand all Loading... |
1950 | 1949 |
1951 | 1950 |
1952 void Assembler::vstr(const DwVfpRegister src, | 1951 void Assembler::vstr(const DwVfpRegister src, |
1953 const Register base, | 1952 const Register base, |
1954 int offset, | 1953 int offset, |
1955 const Condition cond) { | 1954 const Condition cond) { |
1956 // MEM(Rbase + offset) = Dsrc. | 1955 // MEM(Rbase + offset) = Dsrc. |
1957 // Instruction details available in ARM DDI 0406A, A8-786. | 1956 // Instruction details available in ARM DDI 0406A, A8-786. |
1958 // 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) | |
1959 // Vsrc(15-12) | 1011(11-8) | (offset/4) | 1958 // Vsrc(15-12) | 1011(11-8) | (offset/4) |
1960 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 1959 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
1961 int u = 1; | 1960 int u = 1; |
1962 if (offset < 0) { | 1961 if (offset < 0) { |
1963 offset = -offset; | 1962 offset = -offset; |
1964 u = 0; | 1963 u = 0; |
1965 } | 1964 } |
1966 ASSERT(offset >= 0); | 1965 ASSERT(offset >= 0); |
1967 if ((offset % 4) == 0 && (offset / 4) < 256) { | 1966 if ((offset % 4) == 0 && (offset / 4) < 256) { |
1968 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 | |
1969 0xB*B8 | ((offset / 4) & 255)); | 1968 0xB*B8 | ((offset / 4) & 255)); |
1970 } else { | 1969 } else { |
(...skipping 20 matching lines...) Expand all Loading... |
1991 | 1990 |
1992 | 1991 |
1993 void Assembler::vstr(const SwVfpRegister src, | 1992 void Assembler::vstr(const SwVfpRegister src, |
1994 const Register base, | 1993 const Register base, |
1995 int offset, | 1994 int offset, |
1996 const Condition cond) { | 1995 const Condition cond) { |
1997 // MEM(Rbase + offset) = SSrc. | 1996 // MEM(Rbase + offset) = SSrc. |
1998 // Instruction details available in ARM DDI 0406A, A8-786. | 1997 // Instruction details available in ARM DDI 0406A, A8-786. |
1999 // 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) | |
2000 // Vdst(15-12) | 1010(11-8) | (offset/4) | 1999 // Vdst(15-12) | 1010(11-8) | (offset/4) |
2001 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2000 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2002 int u = 1; | 2001 int u = 1; |
2003 if (offset < 0) { | 2002 if (offset < 0) { |
2004 offset = -offset; | 2003 offset = -offset; |
2005 u = 0; | 2004 u = 0; |
2006 } | 2005 } |
2007 int sd, d; | 2006 int sd, d; |
2008 src.split_code(&sd, &d); | 2007 src.split_code(&sd, &d); |
2009 ASSERT(offset >= 0); | 2008 ASSERT(offset >= 0); |
2010 if ((offset % 4) == 0 && (offset / 4) < 256) { | 2009 if ((offset % 4) == 0 && (offset / 4) < 256) { |
2011 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 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2090 | 2089 |
2091 return true; | 2090 return true; |
2092 } | 2091 } |
2093 | 2092 |
2094 | 2093 |
2095 void Assembler::vmov(const DwVfpRegister dst, | 2094 void Assembler::vmov(const DwVfpRegister dst, |
2096 double imm, | 2095 double imm, |
2097 const Condition cond) { | 2096 const Condition cond) { |
2098 // Dd = immediate | 2097 // Dd = immediate |
2099 // Instruction details available in ARM DDI 0406B, A8-640. | 2098 // Instruction details available in ARM DDI 0406B, A8-640. |
2100 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2099 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2101 | 2100 |
2102 uint32_t enc; | 2101 uint32_t enc; |
2103 if (FitsVMOVDoubleImmediate(imm, &enc)) { | 2102 if (FitsVMOVDoubleImmediate(imm, &enc)) { |
2104 // The double can be encoded in the instruction. | 2103 // The double can be encoded in the instruction. |
2105 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); |
2106 } else { | 2105 } else { |
2107 // Synthesise the double from ARM immediates. This could be implemented | 2106 // Synthesise the double from ARM immediates. This could be implemented |
2108 // using vldr from a constant pool. | 2107 // using vldr from a constant pool. |
2109 uint32_t lo, hi; | 2108 uint32_t lo, hi; |
2110 DoubleAsTwoUInt32(imm, &lo, &hi); | 2109 DoubleAsTwoUInt32(imm, &lo, &hi); |
(...skipping 16 matching lines...) Expand all Loading... |
2127 } | 2126 } |
2128 } | 2127 } |
2129 } | 2128 } |
2130 | 2129 |
2131 | 2130 |
2132 void Assembler::vmov(const SwVfpRegister dst, | 2131 void Assembler::vmov(const SwVfpRegister dst, |
2133 const SwVfpRegister src, | 2132 const SwVfpRegister src, |
2134 const Condition cond) { | 2133 const Condition cond) { |
2135 // Sd = Sm | 2134 // Sd = Sm |
2136 // Instruction details available in ARM DDI 0406B, A8-642. | 2135 // Instruction details available in ARM DDI 0406B, A8-642. |
2137 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2136 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2138 int sd, d, sm, m; | 2137 int sd, d, sm, m; |
2139 dst.split_code(&sd, &d); | 2138 dst.split_code(&sd, &d); |
2140 src.split_code(&sm, &m); | 2139 src.split_code(&sm, &m); |
2141 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); |
2142 } | 2141 } |
2143 | 2142 |
2144 | 2143 |
2145 void Assembler::vmov(const DwVfpRegister dst, | 2144 void Assembler::vmov(const DwVfpRegister dst, |
2146 const DwVfpRegister src, | 2145 const DwVfpRegister src, |
2147 const Condition cond) { | 2146 const Condition cond) { |
2148 // Dd = Dm | 2147 // Dd = Dm |
2149 // Instruction details available in ARM DDI 0406B, A8-642. | 2148 // Instruction details available in ARM DDI 0406B, A8-642. |
2150 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2149 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2151 emit(cond | 0xE*B24 | 0xB*B20 | | 2150 emit(cond | 0xE*B24 | 0xB*B20 | |
2152 dst.code()*B12 | 0x5*B9 | B8 | B6 | src.code()); | 2151 dst.code()*B12 | 0x5*B9 | B8 | B6 | src.code()); |
2153 } | 2152 } |
2154 | 2153 |
2155 | 2154 |
2156 void Assembler::vmov(const DwVfpRegister dst, | 2155 void Assembler::vmov(const DwVfpRegister dst, |
2157 const Register src1, | 2156 const Register src1, |
2158 const Register src2, | 2157 const Register src2, |
2159 const Condition cond) { | 2158 const Condition cond) { |
2160 // Dm = <Rt,Rt2>. | 2159 // Dm = <Rt,Rt2>. |
2161 // Instruction details available in ARM DDI 0406A, A8-646. | 2160 // Instruction details available in ARM DDI 0406A, A8-646. |
2162 // 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) | |
2163 // 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 |
2164 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2163 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2165 ASSERT(!src1.is(pc) && !src2.is(pc)); | 2164 ASSERT(!src1.is(pc) && !src2.is(pc)); |
2166 emit(cond | 0xC*B24 | B22 | src2.code()*B16 | | 2165 emit(cond | 0xC*B24 | B22 | src2.code()*B16 | |
2167 src1.code()*B12 | 0xB*B8 | B4 | dst.code()); | 2166 src1.code()*B12 | 0xB*B8 | B4 | dst.code()); |
2168 } | 2167 } |
2169 | 2168 |
2170 | 2169 |
2171 void Assembler::vmov(const Register dst1, | 2170 void Assembler::vmov(const Register dst1, |
2172 const Register dst2, | 2171 const Register dst2, |
2173 const DwVfpRegister src, | 2172 const DwVfpRegister src, |
2174 const Condition cond) { | 2173 const Condition cond) { |
2175 // <Rt,Rt2> = Dm. | 2174 // <Rt,Rt2> = Dm. |
2176 // Instruction details available in ARM DDI 0406A, A8-646. | 2175 // Instruction details available in ARM DDI 0406A, A8-646. |
2177 // 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) | |
2178 // 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 |
2179 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2178 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2180 ASSERT(!dst1.is(pc) && !dst2.is(pc)); | 2179 ASSERT(!dst1.is(pc) && !dst2.is(pc)); |
2181 emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 | | 2180 emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 | |
2182 dst1.code()*B12 | 0xB*B8 | B4 | src.code()); | 2181 dst1.code()*B12 | 0xB*B8 | B4 | src.code()); |
2183 } | 2182 } |
2184 | 2183 |
2185 | 2184 |
2186 void Assembler::vmov(const SwVfpRegister dst, | 2185 void Assembler::vmov(const SwVfpRegister dst, |
2187 const Register src, | 2186 const Register src, |
2188 const Condition cond) { | 2187 const Condition cond) { |
2189 // Sn = Rt. | 2188 // Sn = Rt. |
2190 // Instruction details available in ARM DDI 0406A, A8-642. | 2189 // Instruction details available in ARM DDI 0406A, A8-642. |
2191 // 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) | |
2192 // 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) |
2193 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2192 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2194 ASSERT(!src.is(pc)); | 2193 ASSERT(!src.is(pc)); |
2195 int sn, n; | 2194 int sn, n; |
2196 dst.split_code(&sn, &n); | 2195 dst.split_code(&sn, &n); |
2197 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); |
2198 } | 2197 } |
2199 | 2198 |
2200 | 2199 |
2201 void Assembler::vmov(const Register dst, | 2200 void Assembler::vmov(const Register dst, |
2202 const SwVfpRegister src, | 2201 const SwVfpRegister src, |
2203 const Condition cond) { | 2202 const Condition cond) { |
2204 // Rt = Sn. | 2203 // Rt = Sn. |
2205 // Instruction details available in ARM DDI 0406A, A8-642. | 2204 // Instruction details available in ARM DDI 0406A, A8-642. |
2206 // 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) | |
2207 // 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) |
2208 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2207 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2209 ASSERT(!dst.is(pc)); | 2208 ASSERT(!dst.is(pc)); |
2210 int sn, n; | 2209 int sn, n; |
2211 src.split_code(&sn, &n); | 2210 src.split_code(&sn, &n); |
2212 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); |
2213 } | 2212 } |
2214 | 2213 |
2215 | 2214 |
2216 // Type of data to read from or write to VFP register. | 2215 // Type of data to read from or write to VFP register. |
2217 // Used as specifier in generic vcvt instruction. | 2216 // Used as specifier in generic vcvt instruction. |
2218 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... |
2323 return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | 0x7*B16 | | 2322 return (cond | 0xE*B24 | B23 | D*B22 | 0x3*B20 | 0x7*B16 | |
2324 Vd*B12 | 0x5*B9 | sz*B8 | B7 | B6 | M*B5 | Vm); | 2323 Vd*B12 | 0x5*B9 | sz*B8 | B7 | B6 | M*B5 | Vm); |
2325 } | 2324 } |
2326 } | 2325 } |
2327 | 2326 |
2328 | 2327 |
2329 void Assembler::vcvt_f64_s32(const DwVfpRegister dst, | 2328 void Assembler::vcvt_f64_s32(const DwVfpRegister dst, |
2330 const SwVfpRegister src, | 2329 const SwVfpRegister src, |
2331 VFPConversionMode mode, | 2330 VFPConversionMode mode, |
2332 const Condition cond) { | 2331 const Condition cond) { |
2333 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2332 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2334 emit(EncodeVCVT(F64, dst.code(), S32, src.code(), mode, cond)); | 2333 emit(EncodeVCVT(F64, dst.code(), S32, src.code(), mode, cond)); |
2335 } | 2334 } |
2336 | 2335 |
2337 | 2336 |
2338 void Assembler::vcvt_f32_s32(const SwVfpRegister dst, | 2337 void Assembler::vcvt_f32_s32(const SwVfpRegister dst, |
2339 const SwVfpRegister src, | 2338 const SwVfpRegister src, |
2340 VFPConversionMode mode, | 2339 VFPConversionMode mode, |
2341 const Condition cond) { | 2340 const Condition cond) { |
2342 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2341 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2343 emit(EncodeVCVT(F32, dst.code(), S32, src.code(), mode, cond)); | 2342 emit(EncodeVCVT(F32, dst.code(), S32, src.code(), mode, cond)); |
2344 } | 2343 } |
2345 | 2344 |
2346 | 2345 |
2347 void Assembler::vcvt_f64_u32(const DwVfpRegister dst, | 2346 void Assembler::vcvt_f64_u32(const DwVfpRegister dst, |
2348 const SwVfpRegister src, | 2347 const SwVfpRegister src, |
2349 VFPConversionMode mode, | 2348 VFPConversionMode mode, |
2350 const Condition cond) { | 2349 const Condition cond) { |
2351 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2350 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2352 emit(EncodeVCVT(F64, dst.code(), U32, src.code(), mode, cond)); | 2351 emit(EncodeVCVT(F64, dst.code(), U32, src.code(), mode, cond)); |
2353 } | 2352 } |
2354 | 2353 |
2355 | 2354 |
2356 void Assembler::vcvt_s32_f64(const SwVfpRegister dst, | 2355 void Assembler::vcvt_s32_f64(const SwVfpRegister dst, |
2357 const DwVfpRegister src, | 2356 const DwVfpRegister src, |
2358 VFPConversionMode mode, | 2357 VFPConversionMode mode, |
2359 const Condition cond) { | 2358 const Condition cond) { |
2360 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2359 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2361 emit(EncodeVCVT(S32, dst.code(), F64, src.code(), mode, cond)); | 2360 emit(EncodeVCVT(S32, dst.code(), F64, src.code(), mode, cond)); |
2362 } | 2361 } |
2363 | 2362 |
2364 | 2363 |
2365 void Assembler::vcvt_u32_f64(const SwVfpRegister dst, | 2364 void Assembler::vcvt_u32_f64(const SwVfpRegister dst, |
2366 const DwVfpRegister src, | 2365 const DwVfpRegister src, |
2367 VFPConversionMode mode, | 2366 VFPConversionMode mode, |
2368 const Condition cond) { | 2367 const Condition cond) { |
2369 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2368 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2370 emit(EncodeVCVT(U32, dst.code(), F64, src.code(), mode, cond)); | 2369 emit(EncodeVCVT(U32, dst.code(), F64, src.code(), mode, cond)); |
2371 } | 2370 } |
2372 | 2371 |
2373 | 2372 |
2374 void Assembler::vcvt_f64_f32(const DwVfpRegister dst, | 2373 void Assembler::vcvt_f64_f32(const DwVfpRegister dst, |
2375 const SwVfpRegister src, | 2374 const SwVfpRegister src, |
2376 VFPConversionMode mode, | 2375 VFPConversionMode mode, |
2377 const Condition cond) { | 2376 const Condition cond) { |
2378 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2377 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2379 emit(EncodeVCVT(F64, dst.code(), F32, src.code(), mode, cond)); | 2378 emit(EncodeVCVT(F64, dst.code(), F32, src.code(), mode, cond)); |
2380 } | 2379 } |
2381 | 2380 |
2382 | 2381 |
2383 void Assembler::vcvt_f32_f64(const SwVfpRegister dst, | 2382 void Assembler::vcvt_f32_f64(const SwVfpRegister dst, |
2384 const DwVfpRegister src, | 2383 const DwVfpRegister src, |
2385 VFPConversionMode mode, | 2384 VFPConversionMode mode, |
2386 const Condition cond) { | 2385 const Condition cond) { |
2387 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2386 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2388 emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond)); | 2387 emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond)); |
2389 } | 2388 } |
2390 | 2389 |
2391 | 2390 |
2392 void Assembler::vneg(const DwVfpRegister dst, | 2391 void Assembler::vneg(const DwVfpRegister dst, |
2393 const DwVfpRegister src, | 2392 const DwVfpRegister src, |
2394 const Condition cond) { | 2393 const Condition cond) { |
2395 emit(cond | 0xE*B24 | 0xB*B20 | B16 | dst.code()*B12 | | 2394 emit(cond | 0xE*B24 | 0xB*B20 | B16 | dst.code()*B12 | |
2396 0x5*B9 | B8 | B6 | src.code()); | 2395 0x5*B9 | B8 | B6 | src.code()); |
2397 } | 2396 } |
2398 | 2397 |
2399 | 2398 |
2400 void Assembler::vabs(const DwVfpRegister dst, | 2399 void Assembler::vabs(const DwVfpRegister dst, |
2401 const DwVfpRegister src, | 2400 const DwVfpRegister src, |
2402 const Condition cond) { | 2401 const Condition cond) { |
2403 emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 | | 2402 emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 | |
2404 0x5*B9 | B8 | 0x3*B6 | src.code()); | 2403 0x5*B9 | B8 | 0x3*B6 | src.code()); |
2405 } | 2404 } |
2406 | 2405 |
2407 | 2406 |
2408 void Assembler::vadd(const DwVfpRegister dst, | 2407 void Assembler::vadd(const DwVfpRegister dst, |
2409 const DwVfpRegister src1, | 2408 const DwVfpRegister src1, |
2410 const DwVfpRegister src2, | 2409 const DwVfpRegister src2, |
2411 const Condition cond) { | 2410 const Condition cond) { |
2412 // Dd = vadd(Dn, Dm) double precision floating point addition. | 2411 // Dd = vadd(Dn, Dm) double precision floating point addition. |
2413 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2412 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
2414 // Instruction details available in ARM DDI 0406A, A8-536. | 2413 // Instruction details available in ARM DDI 0406A, A8-536. |
2415 // 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) | |
2416 // 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) |
2417 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2416 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2418 emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | | 2417 emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | |
2419 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); | 2418 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); |
2420 } | 2419 } |
2421 | 2420 |
2422 | 2421 |
2423 void Assembler::vsub(const DwVfpRegister dst, | 2422 void Assembler::vsub(const DwVfpRegister dst, |
2424 const DwVfpRegister src1, | 2423 const DwVfpRegister src1, |
2425 const DwVfpRegister src2, | 2424 const DwVfpRegister src2, |
2426 const Condition cond) { | 2425 const Condition cond) { |
2427 // Dd = vsub(Dn, Dm) double precision floating point subtraction. | 2426 // Dd = vsub(Dn, Dm) double precision floating point subtraction. |
2428 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2427 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
2429 // Instruction details available in ARM DDI 0406A, A8-784. | 2428 // Instruction details available in ARM DDI 0406A, A8-784. |
2430 // 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) | |
2431 // 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) |
2432 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2431 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2433 emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | | 2432 emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | |
2434 dst.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); | 2433 dst.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); |
2435 } | 2434 } |
2436 | 2435 |
2437 | 2436 |
2438 void Assembler::vmul(const DwVfpRegister dst, | 2437 void Assembler::vmul(const DwVfpRegister dst, |
2439 const DwVfpRegister src1, | 2438 const DwVfpRegister src1, |
2440 const DwVfpRegister src2, | 2439 const DwVfpRegister src2, |
2441 const Condition cond) { | 2440 const Condition cond) { |
2442 // Dd = vmul(Dn, Dm) double precision floating point multiplication. | 2441 // Dd = vmul(Dn, Dm) double precision floating point multiplication. |
2443 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2442 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
2444 // Instruction details available in ARM DDI 0406A, A8-784. | 2443 // Instruction details available in ARM DDI 0406A, A8-784. |
2445 // 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) | |
2446 // 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) |
2447 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2446 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2448 emit(cond | 0xE*B24 | 0x2*B20 | src1.code()*B16 | | 2447 emit(cond | 0xE*B24 | 0x2*B20 | src1.code()*B16 | |
2449 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); | 2448 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); |
2450 } | 2449 } |
2451 | 2450 |
2452 | 2451 |
2453 void Assembler::vdiv(const DwVfpRegister dst, | 2452 void Assembler::vdiv(const DwVfpRegister dst, |
2454 const DwVfpRegister src1, | 2453 const DwVfpRegister src1, |
2455 const DwVfpRegister src2, | 2454 const DwVfpRegister src2, |
2456 const Condition cond) { | 2455 const Condition cond) { |
2457 // Dd = vdiv(Dn, Dm) double precision floating point division. | 2456 // Dd = vdiv(Dn, Dm) double precision floating point division. |
2458 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. | 2457 // Dd = D:Vd; Dm=M:Vm; Dn=N:Vm. |
2459 // Instruction details available in ARM DDI 0406A, A8-584. | 2458 // Instruction details available in ARM DDI 0406A, A8-584. |
2460 // 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) | |
2461 // 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) |
2462 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2461 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2463 emit(cond | 0xE*B24 | B23 | src1.code()*B16 | | 2462 emit(cond | 0xE*B24 | B23 | src1.code()*B16 | |
2464 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); | 2463 dst.code()*B12 | 0x5*B9 | B8 | src2.code()); |
2465 } | 2464 } |
2466 | 2465 |
2467 | 2466 |
2468 void Assembler::vcmp(const DwVfpRegister src1, | 2467 void Assembler::vcmp(const DwVfpRegister src1, |
2469 const DwVfpRegister src2, | 2468 const DwVfpRegister src2, |
2470 const Condition cond) { | 2469 const Condition cond) { |
2471 // vcmp(Dd, Dm) double precision floating point comparison. | 2470 // vcmp(Dd, Dm) double precision floating point comparison. |
2472 // Instruction details available in ARM DDI 0406A, A8-570. | 2471 // Instruction details available in ARM DDI 0406A, A8-570. |
2473 // 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) | |
2474 // 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) |
2475 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2474 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2476 emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | | 2475 emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | |
2477 src1.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); | 2476 src1.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); |
2478 } | 2477 } |
2479 | 2478 |
2480 | 2479 |
2481 void Assembler::vcmp(const DwVfpRegister src1, | 2480 void Assembler::vcmp(const DwVfpRegister src1, |
2482 const double src2, | 2481 const double src2, |
2483 const Condition cond) { | 2482 const Condition cond) { |
2484 // vcmp(Dd, Dm) double precision floating point comparison. | 2483 // vcmp(Dd, Dm) double precision floating point comparison. |
2485 // Instruction details available in ARM DDI 0406A, A8-570. | 2484 // Instruction details available in ARM DDI 0406A, A8-570. |
2486 // 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) | |
2487 // 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) |
2488 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2487 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2489 ASSERT(src2 == 0.0); | 2488 ASSERT(src2 == 0.0); |
2490 emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | B16 | | 2489 emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | B16 | |
2491 src1.code()*B12 | 0x5*B9 | B8 | B6); | 2490 src1.code()*B12 | 0x5*B9 | B8 | B6); |
2492 } | 2491 } |
2493 | 2492 |
2494 | 2493 |
2495 void Assembler::vmsr(Register dst, Condition cond) { | 2494 void Assembler::vmsr(Register dst, Condition cond) { |
2496 // Instruction details available in ARM DDI 0406A, A8-652. | 2495 // Instruction details available in ARM DDI 0406A, A8-652. |
2497 // 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) | |
2498 // 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) |
2499 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2498 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2500 emit(cond | 0xE*B24 | 0xE*B20 | B16 | | 2499 emit(cond | 0xE*B24 | 0xE*B20 | B16 | |
2501 dst.code()*B12 | 0xA*B8 | B4); | 2500 dst.code()*B12 | 0xA*B8 | B4); |
2502 } | 2501 } |
2503 | 2502 |
2504 | 2503 |
2505 void Assembler::vmrs(Register dst, Condition cond) { | 2504 void Assembler::vmrs(Register dst, Condition cond) { |
2506 // Instruction details available in ARM DDI 0406A, A8-652. | 2505 // Instruction details available in ARM DDI 0406A, A8-652. |
2507 // 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) | |
2508 // 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) |
2509 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2508 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2510 emit(cond | 0xE*B24 | 0xF*B20 | B16 | | 2509 emit(cond | 0xE*B24 | 0xF*B20 | B16 | |
2511 dst.code()*B12 | 0xA*B8 | B4); | 2510 dst.code()*B12 | 0xA*B8 | B4); |
2512 } | 2511 } |
2513 | 2512 |
2514 | 2513 |
2515 void Assembler::vsqrt(const DwVfpRegister dst, | 2514 void Assembler::vsqrt(const DwVfpRegister dst, |
2516 const DwVfpRegister src, | 2515 const DwVfpRegister src, |
2517 const Condition cond) { | 2516 const Condition cond) { |
2518 // 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) | |
2519 // 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) |
2520 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3)); | 2519 ASSERT(isolate()->cpu_features()->IsEnabled(VFP3)); |
2521 emit(cond | 0xE*B24 | B23 | 0x3*B20 | B16 | | 2520 emit(cond | 0xE*B24 | B23 | 0x3*B20 | B16 | |
2522 dst.code()*B12 | 0x5*B9 | B8 | 3*B6 | src.code()); | 2521 dst.code()*B12 | 0x5*B9 | B8 | 3*B6 | src.code()); |
2523 } | 2522 } |
2524 | 2523 |
2525 | 2524 |
2526 // Pseudo instructions. | 2525 // Pseudo instructions. |
2527 void Assembler::nop(int type) { | 2526 void Assembler::nop(int type) { |
2528 // This is mov rx, rx. | 2527 // This is mov rx, rx. |
2529 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. |
2530 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... |
2784 | 2783 |
2785 // 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 |
2786 // the standard interval. | 2785 // the standard interval. |
2787 next_buffer_check_ = pc_offset() + kCheckConstInterval; | 2786 next_buffer_check_ = pc_offset() + kCheckConstInterval; |
2788 } | 2787 } |
2789 | 2788 |
2790 | 2789 |
2791 } } // namespace v8::internal | 2790 } } // namespace v8::internal |
2792 | 2791 |
2793 #endif // V8_TARGET_ARCH_ARM | 2792 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |