Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(124)

Side by Side Diff: src/arm/assembler-arm.cc

Issue 11185052: Put more constants in movw/movt instructions (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/assembler-arm.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 801 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 #endif // def DEBUG 812 #endif // def DEBUG
813 if (assembler != NULL && assembler->predictable_code_size()) return true; 813 if (assembler != NULL && assembler->predictable_code_size()) return true;
814 return Serializer::enabled(); 814 return Serializer::enabled();
815 } else if (rmode_ == RelocInfo::NONE) { 815 } else if (rmode_ == RelocInfo::NONE) {
816 return false; 816 return false;
817 } 817 }
818 return true; 818 return true;
819 } 819 }
820 820
821 821
822 static bool use_movw_movt(const Operand& x, const Assembler* assembler) {
823 if (Assembler::use_immediate_constant_pool_loads(assembler)) {
824 return true;
825 }
826 if (x.must_output_reloc_info(assembler)) {
827 return false;
828 }
829 return CpuFeatures::IsSupported(ARMv7);
830 }
831
832
822 bool Operand::is_single_instruction(const Assembler* assembler, 833 bool Operand::is_single_instruction(const Assembler* assembler,
823 Instr instr) const { 834 Instr instr) const {
824 if (rm_.is_valid()) return true; 835 if (rm_.is_valid()) return true;
825 uint32_t dummy1, dummy2; 836 uint32_t dummy1, dummy2;
826 if (must_output_reloc_info(assembler) || 837 if (must_output_reloc_info(assembler) ||
827 !fits_shifter(imm32_, &dummy1, &dummy2, &instr)) { 838 !fits_shifter(imm32_, &dummy1, &dummy2, &instr)) {
828 // The immediate operand cannot be encoded as a shifter operand, or use of 839 // The immediate operand cannot be encoded as a shifter operand, or use of
829 // constant pool is required. For a mov instruction not setting the 840 // constant pool is required. For a mov instruction not setting the
830 // condition code additional instruction conventions can be used. 841 // condition code additional instruction conventions can be used.
831 if ((instr & ~kCondMask) == 13*B21) { // mov, S not set 842 if ((instr & ~kCondMask) == 13*B21) { // mov, S not set
832 #ifdef USE_BLX 843 return !use_movw_movt(*this, assembler);
833 // When using BLX, there are two things that must be true for the address
834 // load to be longer than a single instruction. First, immediate loads
835 // using movw/movt must be supported (and fast) on the target ARM
836 // architecture. Second, the reloc mode must be something other than NONE,
837 // since NONE is a used whenever the constant pool cannot be used for
838 // technical reasons, e.g. back-patching calls site in optimized code with
839 // a call to a lazy deopt routine.
840 return !Assembler::allow_immediate_constant_pool_loads(assembler) &&
841 rmode_ != RelocInfo::NONE;
842 #else
843 // It's not possible to use immediate loads to the pc to do a call, (the
844 // pc would be inconsistent half-way through the load), so loading the
845 // destination address without USE_BLX is always a single instruction of
846 // the form ldr pc, [pc + #xxx].
847 return true;
848 #endif
849 } else { 844 } else {
850 // If this is not a mov or mvn instruction there will always an additional 845 // If this is not a mov or mvn instruction there will always an additional
851 // instructions - either mov or ldr. The mov might actually be two 846 // instructions - either mov or ldr. The mov might actually be two
852 // instructions mov or movw followed by movt so including the actual 847 // instructions mov or movw followed by movt so including the actual
853 // instruction two or three instructions will be generated. 848 // instruction two or three instructions will be generated.
854 return false; 849 return false;
855 } 850 }
856 } else { 851 } else {
857 // No use of constant pool and the immediate operand can be encoded as a 852 // No use of constant pool and the immediate operand can be encoded as a
858 // shifter operand. 853 // shifter operand.
859 return true; 854 return true;
860 } 855 }
861 } 856 }
862 857
863 858
864 void Assembler::move_32_bit_immediate(Condition cond, 859 void Assembler::move_32_bit_immediate(Condition cond,
865 Register rd, 860 Register rd,
866 SBit s, 861 SBit s,
867 const Operand& x) { 862 const Operand& x) {
868 if (rd.code() != pc.code() && s == LeaveCC) { 863 if (rd.code() != pc.code() && s == LeaveCC) {
869 // Candidate for immediate load. 864 if (use_movw_movt(x, this)) {
870 if (x.must_output_reloc_info(this)) { 865 if (x.must_output_reloc_info(this)) {
871 if (!Assembler::allow_immediate_constant_pool_loads(this)) { 866 RecordRelocInfo(x.rmode_, x.imm32_, DONT_USE_CONSTANT_POOL);
872 RecordRelocInfo(x.rmode_, x.imm32_, USE_CONSTANT_POOL); 867 // Make sure the movw/movt doesn't get separated.
873 ldr(rd, MemOperand(pc, 0), cond); 868 BlockConstPoolFor(2);
874 return;
875 } 869 }
876 RecordRelocInfo(x.rmode_, x.imm32_, DONT_USE_CONSTANT_POOL); 870 emit(cond | 0x30*B20 | rd.code()*B12 |
877 // Make sure the movw/movt doesn't get separated. 871 EncodeMovwImmediate(x.imm32_ & 0xffff));
878 BlockConstPoolFor(2); 872 movt(rd, static_cast<uint32_t>(x.imm32_) >> 16, cond);
873 return;
879 } 874 }
875 }
880 876
881 // Emit a real movw/movt pair. 877 RecordRelocInfo(x.rmode_, x.imm32_, USE_CONSTANT_POOL);
882 emit(cond | 0x30*B20 | rd.code()*B12 | 878 ldr(rd, MemOperand(pc, 0), cond);
883 EncodeMovwImmediate(x.imm32_ & 0xffff));
884 movt(rd, static_cast<uint32_t>(x.imm32_) >> 16, cond);
885 } else {
886 RecordRelocInfo(x.rmode_, x.imm32_, USE_CONSTANT_POOL);
887 ldr(rd, MemOperand(pc, 0), cond);
888 }
889 } 879 }
890 880
891 881
892 void Assembler::addrmod1(Instr instr, 882 void Assembler::addrmod1(Instr instr,
893 Register rn, 883 Register rn,
894 Register rd, 884 Register rd,
895 const Operand& x) { 885 const Operand& x) {
896 CheckBuffer(); 886 CheckBuffer();
897 ASSERT((instr & ~(kCondMask | kOpCodeMask | S)) == 0); 887 ASSERT((instr & ~(kCondMask | kOpCodeMask | S)) == 0);
898 if (!x.rm_.is_valid()) { 888 if (!x.rm_.is_valid()) {
(...skipping 10 matching lines...) Expand all
909 Condition cond = Instruction::ConditionField(instr); 899 Condition cond = Instruction::ConditionField(instr);
910 if ((instr & ~kCondMask) == 13*B21) { // mov, S not set 900 if ((instr & ~kCondMask) == 13*B21) { // mov, S not set
911 move_32_bit_immediate(cond, rd, LeaveCC, x); 901 move_32_bit_immediate(cond, rd, LeaveCC, x);
912 } else { 902 } else {
913 // If this is not a mov or mvn instruction we may still be able to avoid 903 // If this is not a mov or mvn instruction we may still be able to avoid
914 // a constant pool entry by using mvn or movw. 904 // a constant pool entry by using mvn or movw.
915 if (!x.must_output_reloc_info(this) && 905 if (!x.must_output_reloc_info(this) &&
916 (instr & kMovMvnMask) != kMovMvnPattern) { 906 (instr & kMovMvnMask) != kMovMvnPattern) {
917 mov(ip, x, LeaveCC, cond); 907 mov(ip, x, LeaveCC, cond);
918 } else { 908 } else {
919 move_32_bit_immediate(cond, ip, 909 move_32_bit_immediate(cond, ip, LeaveCC, x);
920 static_cast<SBit>(instr & (1 << 20)), x);
921 } 910 }
922 addrmod1(instr, rn, rd, Operand(ip)); 911 addrmod1(instr, rn, rd, Operand(ip));
923 } 912 }
924 return; 913 return;
925 } 914 }
926 instr |= I | rotate_imm*B8 | immed_8; 915 instr |= I | rotate_imm*B8 | immed_8;
927 } else if (!x.rs_.is_valid()) { 916 } else if (!x.rs_.is_valid()) {
928 // Immediate shift. 917 // Immediate shift.
929 instr |= x.shift_imm_*B7 | x.shift_op_ | x.rm_.code(); 918 instr |= x.shift_imm_*B7 | x.shift_op_ | x.rm_.code();
930 } else { 919 } else {
(...skipping 1848 matching lines...) Expand 10 before | Expand all | Expand 10 after
2779 2768
2780 // Since a constant pool was just emitted, move the check offset forward by 2769 // Since a constant pool was just emitted, move the check offset forward by
2781 // the standard interval. 2770 // the standard interval.
2782 next_buffer_check_ = pc_offset() + kCheckPoolInterval; 2771 next_buffer_check_ = pc_offset() + kCheckPoolInterval;
2783 } 2772 }
2784 2773
2785 2774
2786 } } // namespace v8::internal 2775 } } // namespace v8::internal
2787 2776
2788 #endif // V8_TARGET_ARCH_ARM 2777 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698