Chromium Code Reviews| 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 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 716 int link = target_at(L->pos()); | 716 int link = target_at(L->pos()); |
| 717 if (link == kEndOfChain) { | 717 if (link == kEndOfChain) { |
| 718 L->Unuse(); | 718 L->Unuse(); |
| 719 } else { | 719 } else { |
| 720 ASSERT(link >= 0); | 720 ASSERT(link >= 0); |
| 721 L->link_to(link); | 721 L->link_to(link); |
| 722 } | 722 } |
| 723 } | 723 } |
| 724 | 724 |
| 725 | 725 |
| 726 static Instr EncodeMovwImmediate(uint32_t immediate) { | |
| 727 ASSERT(immediate < 0x10000); | |
| 728 return ((immediate & 0xf000) << 4) | (immediate & 0xfff); | |
| 729 } | |
| 730 | |
| 731 | |
| 732 // Low-level code emission routines depending on the addressing mode. | 726 // Low-level code emission routines depending on the addressing mode. |
| 733 // If this returns true then you have to use the rotate_imm and immed_8 | 727 // If this returns true then you have to use the rotate_imm and immed_8 |
| 734 // that it returns, because it may have already changed the instruction | 728 // that it returns, because it may have already changed the instruction |
| 735 // to match them! | 729 // to match them! |
| 736 static bool fits_shifter(uint32_t imm32, | 730 static bool fits_shifter(uint32_t imm32, |
| 737 uint32_t* rotate_imm, | 731 uint32_t* rotate_imm, |
| 738 uint32_t* immed_8, | 732 uint32_t* immed_8, |
| 739 Instr* instr) { | 733 Instr* instr) { |
| 740 // imm32 must be unsigned. | 734 // imm32 must be unsigned. |
| 741 for (int rot = 0; rot < 16; rot++) { | 735 for (int rot = 0; rot < 16; rot++) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 786 } | 780 } |
| 787 } | 781 } |
| 788 return false; | 782 return false; |
| 789 } | 783 } |
| 790 | 784 |
| 791 | 785 |
| 792 // We have to use the temporary register for things that can be relocated even | 786 // We have to use the temporary register for things that can be relocated even |
| 793 // if they can be encoded in the ARM's 12 bits of immediate-offset instruction | 787 // if they can be encoded in the ARM's 12 bits of immediate-offset instruction |
| 794 // space. There is no guarantee that the relocated location can be similarly | 788 // space. There is no guarantee that the relocated location can be similarly |
| 795 // encoded. | 789 // encoded. |
| 796 bool Operand::must_use_constant_pool(const Assembler* assembler) const { | 790 bool Operand::must_output_reloc_info(const Assembler* assembler) const { |
| 797 if (rmode_ == RelocInfo::EXTERNAL_REFERENCE) { | 791 if (rmode_ == RelocInfo::EXTERNAL_REFERENCE) { |
| 798 #ifdef DEBUG | 792 #ifdef DEBUG |
| 799 if (!Serializer::enabled()) { | 793 if (!Serializer::enabled()) { |
| 800 Serializer::TooLateToEnableNow(); | 794 Serializer::TooLateToEnableNow(); |
| 801 } | 795 } |
| 802 #endif // def DEBUG | 796 #endif // def DEBUG |
| 803 if (assembler != NULL && assembler->predictable_code_size()) return true; | 797 if (assembler != NULL && assembler->predictable_code_size()) return true; |
| 804 return Serializer::enabled(); | 798 return Serializer::enabled(); |
| 805 } else if (rmode_ == RelocInfo::NONE) { | 799 } else if (rmode_ == RelocInfo::NONE) { |
| 806 return false; | 800 return false; |
| 807 } | 801 } |
| 808 return true; | 802 return true; |
| 809 } | 803 } |
| 810 | 804 |
| 811 | 805 |
| 812 bool Operand::is_single_instruction(const Assembler* assembler, | 806 bool Operand::is_single_instruction(const Assembler* assembler, |
| 813 Instr instr) const { | 807 Instr instr) const { |
| 814 if (rm_.is_valid()) return true; | 808 if (rm_.is_valid()) return true; |
| 815 uint32_t dummy1, dummy2; | 809 uint32_t dummy1, dummy2; |
| 816 if (must_use_constant_pool(assembler) || | 810 if (must_output_reloc_info(assembler) || |
| 817 !fits_shifter(imm32_, &dummy1, &dummy2, &instr)) { | 811 !fits_shifter(imm32_, &dummy1, &dummy2, &instr)) { |
| 818 // The immediate operand cannot be encoded as a shifter operand, or use of | 812 // The immediate operand cannot be encoded as a shifter operand, or use of |
| 819 // constant pool is required. For a mov instruction not setting the | 813 // constant pool is required. For a mov instruction not setting the |
| 820 // condition code additional instruction conventions can be used. | 814 // condition code additional instruction conventions can be used. |
| 821 if ((instr & ~kCondMask) == 13*B21) { // mov, S not set | 815 if ((instr & ~kCondMask) == 13*B21) { // mov, S not set |
| 822 if (must_use_constant_pool(assembler) || | 816 #ifdef USE_BLX |
| 823 !CpuFeatures::IsSupported(ARMv7)) { | 817 return !Assembler::allow_immediate_constant_pool_loads(assembler); |
| 824 // mov instruction will be an ldr from constant pool (one instruction). | 818 #else |
| 825 return true; | 819 return true; |
|
Michael Starzinger
2012/10/10 14:19:29
Indentation is off.
danno
2012/10/17 10:04:44
Done.
danno
2012/10/17 10:04:44
Done.
| |
| 826 } else { | 820 #endif |
| 827 // mov instruction will be a mov or movw followed by movt (two | |
| 828 // instructions). | |
| 829 return false; | |
| 830 } | |
| 831 } else { | 821 } else { |
| 832 // If this is not a mov or mvn instruction there will always an additional | 822 // If this is not a mov or mvn instruction there will always an additional |
| 833 // instructions - either mov or ldr. The mov might actually be two | 823 // instructions - either mov or ldr. The mov might actually be two |
| 834 // instructions mov or movw followed by movt so including the actual | 824 // instructions mov or movw followed by movt so including the actual |
| 835 // instruction two or three instructions will be generated. | 825 // instruction two or three instructions will be generated. |
| 836 return false; | 826 return false; |
| 837 } | 827 } |
| 838 } else { | 828 } else { |
| 839 // No use of constant pool and the immediate operand can be encoded as a | 829 // No use of constant pool and the immediate operand can be encoded as a |
| 840 // shifter operand. | 830 // shifter operand. |
| 841 return true; | 831 return true; |
| 842 } | 832 } |
| 843 } | 833 } |
| 844 | 834 |
| 845 | 835 |
| 836 void Assembler::move_32_bit_immediate(Condition cond, | |
| 837 Register rd, | |
| 838 SBit s, | |
| 839 const Operand& x) { | |
| 840 if (Assembler::allow_immediate_constant_pool_loads(this) && | |
| 841 rd.code() != pc.code() && | |
| 842 s == LeaveCC) { | |
|
Please use jfb - chromium.org
2012/10/10 13:56:52
In this case we're emitting 2 instructions, and wh
danno
2012/10/17 10:04:44
I solved this a little differently. Embedded objec
| |
| 843 if (x.must_output_reloc_info(this)) { | |
| 844 RecordRelocInfo(x.rmode_, x.imm32_, DONT_USE_CONSTANT_POOL); | |
|
Please use jfb - chromium.org
2012/10/10 13:56:52
As before, if there's relocinfo then it's code (ri
Michael Starzinger
2012/10/10 14:34:29
I am not sure about this. We also have RelocInfos
danno
2012/10/17 10:04:44
For object pointers, the address is not aligned, s
| |
| 845 } | |
| 846 BlockConstPoolFor(2); | |
| 847 | |
| 848 // Emit a "real" movw | |
| 849 emit(cond | 0x30*B20 | rd.code()*B12 | | |
| 850 EncodeMovwImmediate(x.imm32_ & 0xffff)); | |
| 851 movt(rd, static_cast<uint32_t>(x.imm32_) >> 16, cond); | |
| 852 } else { | |
| 853 RecordRelocInfo(x.rmode_, x.imm32_); | |
| 854 ldr(rd, MemOperand(pc, 0), cond); | |
| 855 } | |
| 856 } | |
| 857 | |
| 858 | |
| 846 void Assembler::addrmod1(Instr instr, | 859 void Assembler::addrmod1(Instr instr, |
| 847 Register rn, | 860 Register rn, |
| 848 Register rd, | 861 Register rd, |
| 849 const Operand& x) { | 862 const Operand& x) { |
| 850 CheckBuffer(); | 863 CheckBuffer(); |
| 851 ASSERT((instr & ~(kCondMask | kOpCodeMask | S)) == 0); | 864 ASSERT((instr & ~(kCondMask | kOpCodeMask | S)) == 0); |
| 852 if (!x.rm_.is_valid()) { | 865 if (!x.rm_.is_valid()) { |
| 853 // Immediate. | 866 // Immediate. |
| 854 uint32_t rotate_imm; | 867 uint32_t rotate_imm; |
| 855 uint32_t immed_8; | 868 uint32_t immed_8; |
| 856 if (x.must_use_constant_pool(this) || | 869 if (x.must_output_reloc_info(this) || |
| 857 !fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) { | 870 !fits_shifter(x.imm32_, &rotate_imm, &immed_8, &instr)) { |
| 858 // The immediate operand cannot be encoded as a shifter operand, so load | 871 // The immediate operand cannot be encoded as a shifter operand, so load |
| 859 // it first to register ip and change the original instruction to use ip. | 872 // it first to register ip and change the original instruction to use ip. |
| 860 // However, if the original instruction is a 'mov rd, x' (not setting the | 873 // However, if the original instruction is a 'mov rd, x' (not setting the |
| 861 // condition code), then replace it with a 'ldr rd, [pc]'. | 874 // condition code), then replace it with a 'ldr rd, [pc]'. |
| 862 CHECK(!rn.is(ip)); // rn should never be ip, or will be trashed | 875 CHECK(!rn.is(ip)); // rn should never be ip, or will be trashed |
| 863 Condition cond = Instruction::ConditionField(instr); | 876 Condition cond = Instruction::ConditionField(instr); |
| 864 if ((instr & ~kCondMask) == 13*B21) { // mov, S not set | 877 if ((instr & ~kCondMask) == 13*B21) { // mov, S not set |
| 865 if (x.must_use_constant_pool(this) || | 878 move_32_bit_immediate(cond, rd, LeaveCC, x); |
| 866 !CpuFeatures::IsSupported(ARMv7)) { | |
| 867 RecordRelocInfo(x.rmode_, x.imm32_); | |
| 868 ldr(rd, MemOperand(pc, 0), cond); | |
| 869 } else { | |
| 870 // Will probably use movw, will certainly not use constant pool. | |
| 871 mov(rd, Operand(x.imm32_ & 0xffff), LeaveCC, cond); | |
| 872 movt(rd, static_cast<uint32_t>(x.imm32_) >> 16, cond); | |
| 873 } | |
| 874 } else { | 879 } else { |
| 875 // If this is not a mov or mvn instruction we may still be able to avoid | 880 // If this is not a mov or mvn instruction we may still be able to avoid |
| 876 // a constant pool entry by using mvn or movw. | 881 // a constant pool entry by using mvn or movw. |
| 877 if (!x.must_use_constant_pool(this) && | 882 if (!x.must_output_reloc_info(this) && |
| 878 (instr & kMovMvnMask) != kMovMvnPattern) { | 883 (instr & kMovMvnMask) != kMovMvnPattern) { |
| 879 mov(ip, x, LeaveCC, cond); | 884 mov(ip, x, LeaveCC, cond); |
| 880 } else { | 885 } else { |
| 881 RecordRelocInfo(x.rmode_, x.imm32_); | 886 move_32_bit_immediate(cond, ip, |
| 882 ldr(ip, MemOperand(pc, 0), cond); | 887 static_cast<SBit>(instr & (1 << 20)), x); |
| 883 } | 888 } |
| 884 addrmod1(instr, rn, rd, Operand(ip)); | 889 addrmod1(instr, rn, rd, Operand(ip)); |
| 885 } | 890 } |
| 886 return; | 891 return; |
| 887 } | 892 } |
| 888 instr |= I | rotate_imm*B8 | immed_8; | 893 instr |= I | rotate_imm*B8 | immed_8; |
| 889 } else if (!x.rs_.is_valid()) { | 894 } else if (!x.rs_.is_valid()) { |
| 890 // Immediate shift. | 895 // Immediate shift. |
| 891 instr |= x.shift_imm_*B7 | x.shift_op_ | x.rm_.code(); | 896 instr |= x.shift_imm_*B7 | x.shift_op_ | x.rm_.code(); |
| 892 } else { | 897 } else { |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1179 // Don't allow nop instructions in the form mov rn, rn to be generated using | 1184 // Don't allow nop instructions in the form mov rn, rn to be generated using |
| 1180 // the mov instruction. They must be generated using nop(int/NopMarkerTypes) | 1185 // the mov instruction. They must be generated using nop(int/NopMarkerTypes) |
| 1181 // or MarkCode(int/NopMarkerTypes) pseudo instructions. | 1186 // or MarkCode(int/NopMarkerTypes) pseudo instructions. |
| 1182 ASSERT(!(src.is_reg() && src.rm().is(dst) && s == LeaveCC && cond == al)); | 1187 ASSERT(!(src.is_reg() && src.rm().is(dst) && s == LeaveCC && cond == al)); |
| 1183 addrmod1(cond | MOV | s, r0, dst, src); | 1188 addrmod1(cond | MOV | s, r0, dst, src); |
| 1184 } | 1189 } |
| 1185 | 1190 |
| 1186 | 1191 |
| 1187 void Assembler::movw(Register reg, uint32_t immediate, Condition cond) { | 1192 void Assembler::movw(Register reg, uint32_t immediate, Condition cond) { |
| 1188 ASSERT(immediate < 0x10000); | 1193 ASSERT(immediate < 0x10000); |
| 1194 // May use movw if supported, but on unsupported platforms will try to use | |
| 1195 // equivalent rotated immed_8 value and other tricks before falling back to a | |
| 1196 // constant pool load. | |
| 1189 mov(reg, Operand(immediate), LeaveCC, cond); | 1197 mov(reg, Operand(immediate), LeaveCC, cond); |
| 1190 } | 1198 } |
| 1191 | 1199 |
| 1192 | 1200 |
| 1193 void Assembler::movt(Register reg, uint32_t immediate, Condition cond) { | 1201 void Assembler::movt(Register reg, uint32_t immediate, Condition cond) { |
| 1194 emit(cond | 0x34*B20 | reg.code()*B12 | EncodeMovwImmediate(immediate)); | 1202 emit(cond | 0x34*B20 | reg.code()*B12 | EncodeMovwImmediate(immediate)); |
| 1195 } | 1203 } |
| 1196 | 1204 |
| 1197 | 1205 |
| 1198 void Assembler::bic(Register dst, Register src1, const Operand& src2, | 1206 void Assembler::bic(Register dst, Register src1, const Operand& src2, |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1408 | 1416 |
| 1409 | 1417 |
| 1410 void Assembler::msr(SRegisterFieldMask fields, const Operand& src, | 1418 void Assembler::msr(SRegisterFieldMask fields, const Operand& src, |
| 1411 Condition cond) { | 1419 Condition cond) { |
| 1412 ASSERT(fields >= B16 && fields < B20); // at least one field set | 1420 ASSERT(fields >= B16 && fields < B20); // at least one field set |
| 1413 Instr instr; | 1421 Instr instr; |
| 1414 if (!src.rm_.is_valid()) { | 1422 if (!src.rm_.is_valid()) { |
| 1415 // Immediate. | 1423 // Immediate. |
| 1416 uint32_t rotate_imm; | 1424 uint32_t rotate_imm; |
| 1417 uint32_t immed_8; | 1425 uint32_t immed_8; |
| 1418 if (src.must_use_constant_pool(this) || | 1426 if (src.must_output_reloc_info(this) || |
| 1419 !fits_shifter(src.imm32_, &rotate_imm, &immed_8, NULL)) { | 1427 !fits_shifter(src.imm32_, &rotate_imm, &immed_8, NULL)) { |
| 1420 // Immediate operand cannot be encoded, load it first to register ip. | 1428 // Immediate operand cannot be encoded, load it first to register ip. |
| 1421 RecordRelocInfo(src.rmode_, src.imm32_); | 1429 RecordRelocInfo(src.rmode_, src.imm32_); |
| 1422 ldr(ip, MemOperand(pc, 0), cond); | 1430 ldr(ip, MemOperand(pc, 0), cond); |
| 1423 msr(fields, Operand(ip), cond); | 1431 msr(fields, Operand(ip), cond); |
| 1424 return; | 1432 return; |
| 1425 } | 1433 } |
| 1426 instr = I | rotate_imm*B8 | immed_8; | 1434 instr = I | rotate_imm*B8 | immed_8; |
| 1427 } else { | 1435 } else { |
| 1428 ASSERT(!src.rs_.is_valid() && src.shift_imm_ == 0); // only rm allowed | 1436 ASSERT(!src.rs_.is_valid() && src.shift_imm_ == 0); // only rm allowed |
| (...skipping 1003 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2432 | 2440 |
| 2433 | 2441 |
| 2434 // Pseudo instructions. | 2442 // Pseudo instructions. |
| 2435 void Assembler::nop(int type) { | 2443 void Assembler::nop(int type) { |
| 2436 // This is mov rx, rx. | 2444 // This is mov rx, rx. |
| 2437 ASSERT(0 <= type && type <= 14); // mov pc, pc is not a nop. | 2445 ASSERT(0 <= type && type <= 14); // mov pc, pc is not a nop. |
| 2438 emit(al | 13*B21 | type*B12 | type); | 2446 emit(al | 13*B21 | type*B12 | type); |
| 2439 } | 2447 } |
| 2440 | 2448 |
| 2441 | 2449 |
| 2450 bool Assembler::IsMovT(Instr instr) { | |
| 2451 instr &= ~(((kNumberOfConditions - 1) << 28) | // Mask off conditions | |
| 2452 ((kNumRegisters-1)*B12) | // mask out register | |
| 2453 EncodeMovwImmediate(0xFFFF)); // mask out immediate value | |
| 2454 return instr == 0x34*B20; | |
| 2455 } | |
| 2456 | |
| 2457 | |
| 2458 bool Assembler::IsMovW(Instr instr) { | |
| 2459 instr &= ~(((kNumberOfConditions - 1) << 28) | // Mask off conditions | |
| 2460 ((kNumRegisters-1)*B12) | // mask out destination | |
| 2461 EncodeMovwImmediate(0xFFFF)); // mask out immediate value | |
| 2462 return instr == 0x30*B20; | |
| 2463 } | |
| 2464 | |
| 2465 | |
| 2442 bool Assembler::IsNop(Instr instr, int type) { | 2466 bool Assembler::IsNop(Instr instr, int type) { |
| 2443 // Check for mov rx, rx where x = type. | 2467 // Check for mov rx, rx where x = type. |
| 2444 ASSERT(0 <= type && type <= 14); // mov pc, pc is not a nop. | 2468 ASSERT(0 <= type && type <= 14); // mov pc, pc is not a nop. |
| 2445 return instr == (al | 13*B21 | type*B12 | type); | 2469 return instr == (al | 13*B21 | type*B12 | type); |
| 2446 } | 2470 } |
| 2447 | 2471 |
| 2448 | 2472 |
| 2449 bool Assembler::ImmediateFitsAddrMode1Instruction(int32_t imm32) { | 2473 bool Assembler::ImmediateFitsAddrMode1Instruction(int32_t imm32) { |
| 2450 uint32_t dummy1; | 2474 uint32_t dummy1; |
| 2451 uint32_t dummy2; | 2475 uint32_t dummy2; |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2550 // No relocation info should be pending while using dd. dd is used | 2574 // No relocation info should be pending while using dd. dd is used |
| 2551 // to write pure data with no pointers and the constant pool should | 2575 // to write pure data with no pointers and the constant pool should |
| 2552 // be emitted before using dd. | 2576 // be emitted before using dd. |
| 2553 ASSERT(num_pending_reloc_info_ == 0); | 2577 ASSERT(num_pending_reloc_info_ == 0); |
| 2554 CheckBuffer(); | 2578 CheckBuffer(); |
| 2555 *reinterpret_cast<uint32_t*>(pc_) = data; | 2579 *reinterpret_cast<uint32_t*>(pc_) = data; |
| 2556 pc_ += sizeof(uint32_t); | 2580 pc_ += sizeof(uint32_t); |
| 2557 } | 2581 } |
| 2558 | 2582 |
| 2559 | 2583 |
| 2560 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { | 2584 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data, |
| 2585 UseConstantPoolMode mode) { | |
| 2561 // We do not try to reuse pool constants. | 2586 // We do not try to reuse pool constants. |
| 2562 RelocInfo rinfo(pc_, rmode, data, NULL); | 2587 RelocInfo rinfo(pc_, rmode, data, NULL); |
| 2563 if (((rmode >= RelocInfo::JS_RETURN) && | 2588 if (((rmode >= RelocInfo::JS_RETURN) && |
| 2564 (rmode <= RelocInfo::DEBUG_BREAK_SLOT)) || | 2589 (rmode <= RelocInfo::DEBUG_BREAK_SLOT)) || |
| 2565 (rmode == RelocInfo::CONST_POOL)) { | 2590 (rmode == RelocInfo::CONST_POOL) || |
| 2591 mode == DONT_USE_CONSTANT_POOL) { | |
| 2566 // Adjust code for new modes. | 2592 // Adjust code for new modes. |
| 2567 ASSERT(RelocInfo::IsDebugBreakSlot(rmode) | 2593 ASSERT(RelocInfo::IsDebugBreakSlot(rmode) |
| 2568 || RelocInfo::IsJSReturn(rmode) | 2594 || RelocInfo::IsJSReturn(rmode) |
| 2569 || RelocInfo::IsComment(rmode) | 2595 || RelocInfo::IsComment(rmode) |
| 2570 || RelocInfo::IsPosition(rmode) | 2596 || RelocInfo::IsPosition(rmode) |
| 2571 || RelocInfo::IsConstPool(rmode)); | 2597 || RelocInfo::IsConstPool(rmode) |
| 2598 || mode == DONT_USE_CONSTANT_POOL); | |
| 2572 // These modes do not need an entry in the constant pool. | 2599 // These modes do not need an entry in the constant pool. |
| 2573 } else { | 2600 } else { |
| 2574 ASSERT(num_pending_reloc_info_ < kMaxNumPendingRelocInfo); | 2601 ASSERT(num_pending_reloc_info_ < kMaxNumPendingRelocInfo); |
| 2575 if (num_pending_reloc_info_ == 0) { | 2602 if (num_pending_reloc_info_ == 0) { |
| 2576 first_const_pool_use_ = pc_offset(); | 2603 first_const_pool_use_ = pc_offset(); |
| 2577 } | 2604 } |
| 2578 pending_reloc_info_[num_pending_reloc_info_++] = rinfo; | 2605 pending_reloc_info_[num_pending_reloc_info_++] = rinfo; |
| 2579 // Make sure the constant pool is not emitted in place of the next | 2606 // Make sure the constant pool is not emitted in place of the next |
| 2580 // instruction for which we just recorded relocation info. | 2607 // instruction for which we just recorded relocation info. |
| 2581 BlockConstPoolFor(1); | 2608 BlockConstPoolFor(1); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2680 // Emit constant pool entries. | 2707 // Emit constant pool entries. |
| 2681 for (int i = 0; i < num_pending_reloc_info_; i++) { | 2708 for (int i = 0; i < num_pending_reloc_info_; i++) { |
| 2682 RelocInfo& rinfo = pending_reloc_info_[i]; | 2709 RelocInfo& rinfo = pending_reloc_info_[i]; |
| 2683 ASSERT(rinfo.rmode() != RelocInfo::COMMENT && | 2710 ASSERT(rinfo.rmode() != RelocInfo::COMMENT && |
| 2684 rinfo.rmode() != RelocInfo::POSITION && | 2711 rinfo.rmode() != RelocInfo::POSITION && |
| 2685 rinfo.rmode() != RelocInfo::STATEMENT_POSITION && | 2712 rinfo.rmode() != RelocInfo::STATEMENT_POSITION && |
| 2686 rinfo.rmode() != RelocInfo::CONST_POOL); | 2713 rinfo.rmode() != RelocInfo::CONST_POOL); |
| 2687 | 2714 |
| 2688 Instr instr = instr_at(rinfo.pc()); | 2715 Instr instr = instr_at(rinfo.pc()); |
| 2689 // Instruction to patch must be 'ldr rd, [pc, #offset]' with offset == 0. | 2716 // Instruction to patch must be 'ldr rd, [pc, #offset]' with offset == 0. |
| 2690 ASSERT(IsLdrPcImmediateOffset(instr) && | 2717 if (IsLdrPcImmediateOffset(instr) && |
| 2691 GetLdrRegisterImmediateOffset(instr) == 0); | 2718 GetLdrRegisterImmediateOffset(instr) == 0) { |
| 2719 int delta = pc_ - rinfo.pc() - kPcLoadDelta; | |
| 2720 // 0 is the smallest delta: | |
| 2721 // ldr rd, [pc, #0] | |
| 2722 // constant pool marker | |
| 2723 // data | |
| 2724 ASSERT(is_uint12(delta)); | |
| 2692 | 2725 |
| 2693 int delta = pc_ - rinfo.pc() - kPcLoadDelta; | 2726 instr_at_put(rinfo.pc(), SetLdrRegisterImmediateOffset(instr, delta)); |
| 2694 // 0 is the smallest delta: | 2727 } else { |
| 2695 // ldr rd, [pc, #0] | 2728 ASSERT(IsMovW(instr)); |
| 2696 // constant pool marker | 2729 } |
| 2697 // data | |
| 2698 ASSERT(is_uint12(delta)); | |
| 2699 | |
| 2700 instr_at_put(rinfo.pc(), SetLdrRegisterImmediateOffset(instr, delta)); | |
| 2701 emit(rinfo.data()); | 2730 emit(rinfo.data()); |
| 2702 } | 2731 } |
| 2703 | 2732 |
| 2704 num_pending_reloc_info_ = 0; | 2733 num_pending_reloc_info_ = 0; |
| 2705 first_const_pool_use_ = -1; | 2734 first_const_pool_use_ = -1; |
| 2706 | 2735 |
| 2707 RecordComment("]"); | 2736 RecordComment("]"); |
| 2708 | 2737 |
| 2709 if (after_pool.is_linked()) { | 2738 if (after_pool.is_linked()) { |
| 2710 bind(&after_pool); | 2739 bind(&after_pool); |
| 2711 } | 2740 } |
| 2712 } | 2741 } |
| 2713 | 2742 |
| 2714 // Since a constant pool was just emitted, move the check offset forward by | 2743 // Since a constant pool was just emitted, move the check offset forward by |
| 2715 // the standard interval. | 2744 // the standard interval. |
| 2716 next_buffer_check_ = pc_offset() + kCheckPoolInterval; | 2745 next_buffer_check_ = pc_offset() + kCheckPoolInterval; |
| 2717 } | 2746 } |
| 2718 | 2747 |
| 2719 | 2748 |
| 2720 } } // namespace v8::internal | 2749 } } // namespace v8::internal |
| 2721 | 2750 |
| 2722 #endif // V8_TARGET_ARCH_ARM | 2751 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |