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

Side by Side Diff: src/arm/assembler-thumb2.h

Issue 601028: Forking disassembler and simulator for Thumb2 support;... Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 10 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') | src/arm/assembler-thumb2-inl.h » ('j') | 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 12 matching lines...) Expand all
23 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 23 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 24 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 28 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31 // OF THE POSSIBILITY OF SUCH DAMAGE. 31 // OF THE POSSIBILITY OF SUCH DAMAGE.
32 32
33 // The original source code covered by the above license above has been modified 33 // The original source code covered by the above license has been modified
34 // significantly by Google Inc. 34 // significantly by Google Inc.
35 // Copyright 2006-2008 the V8 project authors. All rights reserved. 35 // Copyright 2010 the V8 project authors. All rights reserved.
36 36
37 // A light-weight ARM Assembler 37 // A light-weight ARM Assembler
38 // Generates user mode instructions for the ARM architecture up to version 5 38 // Generates user mode instructions for the ARM architecture up to version 5
39 39
40 #ifndef V8_ARM_ASSEMBLER_THUMB2_H_ 40 #ifndef V8_ARM_ASSEMBLER_THUMB2_H_
41 #define V8_ARM_ASSEMBLER_THUMB2_H_ 41 #define V8_ARM_ASSEMBLER_THUMB2_H_
42 #include <stdio.h> 42 #include <stdio.h>
43 #include "assembler.h" 43 #include "assembler.h"
44 #include "serialize.h" 44 #include "serialize.h"
45 45
46 namespace v8 { 46 namespace v8 {
47 namespace internal { 47 namespace internal {
48 48
49 // The beginning of this file contains some enum declarations that are
50 // redundant with declarations in constants-arm.h, but in a different namespace
51 // Please keep the order and values consistent, so we can merge the files
52 // later easily.
53
54 // Opcodes for Data-processing instructions (instructions with a type 0 and 1)
55 // as defined in section A3.4
56 enum Opcode {
57 no_operand = -1,
58 AND = 0, // Logical AND
59 EOR = 1, // Logical Exclusive OR
60 SUB = 2, // Subtract
61 RSB = 3, // Reverse Subtract
62 ADD = 4, // Add
63 ADC = 5, // Add with Carry
64 SBC = 6, // Subtract with Carry
65 RSC = 7, // Reverse Subtract with Carry
66 TST = 8, // Test
67 TEQ = 9, // Test Equivalence
68 CMP = 10, // Compare
69 CMN = 11, // Compare Negated
70 ORR = 12, // Logical (inclusive) OR
71 MOV = 13, // Move
72 BIC = 14, // Bit Clear
73 MVN = 15, // Move Not
74 max_operand = 16
75 };
76
77 enum BitPositions {
78 B0 = 1 << 0,
79 B1 = 1 << 1,
80 B2 = 1 << 2,
81 B3 = 1 << 3,
82 B4 = 1 << 4,
83 B5 = 1 << 5,
84 B6 = 1 << 6,
85 B7 = 1 << 7,
86 B8 = 1 << 8,
87 B9 = 1 << 9,
88 B10 = 1 << 10,
89 B11 = 1 << 11,
90 B12 = 1 << 12,
91 B16 = 1 << 16,
92 B18 = 1 << 18,
93 B19 = 1 << 19,
94 B20 = 1 << 20,
95 B21 = 1 << 21,
96 B22 = 1 << 22,
97 B23 = 1 << 23,
98 B24 = 1 << 24,
99 B25 = 1 << 25,
100 B26 = 1 << 26,
101 B27 = 1 << 27
102 };
103
104 enum Bits1 {
105 b0 = 0x0,
106 b1 = 0x1
107 };
108
109 enum Bits2 {
110 b00 = 0x0,
111 b01 = 0x1,
112 b10 = 0x2,
113 b11 = 0x3
114 };
115
116 enum Bits3 {
117 b000 = 0x0,
118 b001 = 0x1,
119 b010 = 0x2,
120 b011 = 0x3,
121 b100 = 0x4,
122 b101 = 0x5,
123 b110 = 0x6,
124 b111 = 0x7
125 };
126
127 enum Bits4 {
128 b0000 = 0x0,
129 b0001 = 0x1,
130 b0010 = 0x2,
131 b0011 = 0x3,
132 b0100 = 0x4,
133 b0101 = 0x5,
134 b0110 = 0x6,
135 b0111 = 0x7,
136 b1000 = 0x8,
137 b1001 = 0x9,
138 b1010 = 0xa,
139 b1011 = 0xb,
140 b1100 = 0xc,
141 b1101 = 0xd,
142 b1110 = 0xe,
143 b1111 = 0xf
144 };
145
146 enum Bits5 {
147 b00000 = 0x00,
148 b00001 = 0x01,
149 b00010 = 0x02,
150 b00011 = 0x03,
151 b00100 = 0x04,
152 b00101 = 0x05,
153 b00110 = 0x06,
154 b00111 = 0x07,
155 b01000 = 0x08,
156 b01001 = 0x09,
157 b01010 = 0x0a,
158 b01011 = 0x0b,
159 b01100 = 0x0c,
160 b01101 = 0x0d,
161 b01110 = 0x0e,
162 b01111 = 0x0f,
163 b10000 = 0x10,
164 b10001 = 0x11,
165 b10010 = 0x12,
166 b10011 = 0x13,
167 b10100 = 0x14,
168 b10101 = 0x15,
169 b10110 = 0x16,
170 b10111 = 0x17,
171 b11000 = 0x18,
172 b11001 = 0x19,
173 b11010 = 0x1a,
174 b11011 = 0x1b,
175 b11100 = 0x1c,
176 b11101 = 0x1d,
177 b11110 = 0x1e,
178 b11111 = 0x1f
179 };
180
49 // CPU Registers. 181 // CPU Registers.
50 // 182 //
51 // 1) We would prefer to use an enum, but enum values are assignment- 183 // 1) We would prefer to use an enum, but enum values are assignment-
52 // compatible with int, which has caused code-generation bugs. 184 // compatible with int, which has caused code-generation bugs.
53 // 185 //
54 // 2) We would prefer to use a class instead of a struct but we don't like 186 // 2) We would prefer to use a class instead of a struct but we don't like
55 // the register initialization to depend on the particular initialization 187 // the register initialization to depend on the particular initialization
56 // order (which appears to be different on OS X, Linux, and Windows for the 188 // order (which appears to be different on OS X, Linux, and Windows for the
57 // installed versions of C++ we tried). Using a struct permits C-style 189 // installed versions of C++ we tried). Using a struct permits C-style
58 // "initialization". Also, the Register objects cannot be const as this 190 // "initialization". Also, the Register objects cannot be const as this
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 p9 = 9, 375 p9 = 9,
244 p10 = 10, 376 p10 = 10,
245 p11 = 11, 377 p11 = 11,
246 p12 = 12, 378 p12 = 12,
247 p13 = 13, 379 p13 = 13,
248 p14 = 14, 380 p14 = 14,
249 p15 = 15 381 p15 = 15
250 }; 382 };
251 383
252 384
253 // Condition field in instructions 385 // Condition field in instructions.
254 enum Condition { 386 enum Condition {
255 eq = 0 << 28, // Z set equal. 387 eq = 0 << 28, // Z set equal.
256 ne = 1 << 28, // Z clear not equal. 388 ne = 1 << 28, // Z clear not equal.
257 nz = 1 << 28, // Z clear not zero. 389 nz = 1 << 28, // Z clear not zero.
258 cs = 2 << 28, // C set carry set. 390 cs = 2 << 28, // C set carry set.
259 hs = 2 << 28, // C set unsigned higher or same. 391 hs = 2 << 28, // C set unsigned higher or same.
260 cc = 3 << 28, // C clear carry clear. 392 cc = 3 << 28, // C clear carry clear.
261 lo = 3 << 28, // C clear unsigned lower. 393 lo = 3 << 28, // C clear unsigned lower.
262 mi = 4 << 28, // N set negative. 394 mi = 4 << 28, // N set negative.
263 pl = 5 << 28, // N clear positive or zero. 395 pl = 5 << 28, // N clear positive or zero.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 441
310 // Hints are not used on the arm. Negating is trivial. 442 // Hints are not used on the arm. Negating is trivial.
311 inline Hint NegateHint(Hint ignored) { return no_hint; } 443 inline Hint NegateHint(Hint ignored) { return no_hint; }
312 444
313 445
314 // ----------------------------------------------------------------------------- 446 // -----------------------------------------------------------------------------
315 // Addressing modes and instruction variants 447 // Addressing modes and instruction variants
316 448
317 // Shifter operand shift operation 449 // Shifter operand shift operation
318 enum ShiftOp { 450 enum ShiftOp {
319 LSL = 0 << 5, 451 LSL = 0,
320 LSR = 1 << 5, 452 LSR = 1,
321 ASR = 2 << 5, 453 ASR = 2,
322 ROR = 3 << 5, 454 ROR = 3,
323 RRX = -1 455 RRX = -1
324 }; 456 };
325 457
326 458
327 // Condition code updating mode 459 // Condition code updating mode
328 enum SBit { 460 enum SBit {
329 SetCC = 1 << 20, // set condition code 461 SetCC = 1 << 20, // set condition code
330 LeaveCC = 0 << 20 // leave condition code unchanged 462 LeaveCC = 0 << 20 // leave condition code unchanged
331 }; 463 };
332 464
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 explicit Scope(CpuFeature f) {} 631 explicit Scope(CpuFeature f) {}
500 #endif 632 #endif
501 }; 633 };
502 634
503 private: 635 private:
504 static unsigned supported_; 636 static unsigned supported_;
505 static unsigned enabled_; 637 static unsigned enabled_;
506 static unsigned found_by_runtime_probing_; 638 static unsigned found_by_runtime_probing_;
507 }; 639 };
508 640
641 typedef int32_t InstrArm;
642 typedef int16_t InstrThumb;
509 643
510 typedef int32_t Instr; 644 // hack to keep the code patcher happy for now
645 typedef InstrArm Instr;
511 646
512 647 extern const InstrArm kMovLrPc;
513 extern const Instr kMovLrPc; 648 extern const InstrArm kLdrPCPattern;
514 extern const Instr kLdrPCPattern;
515 649
516 650
517 class Assembler : public Malloced { 651 class Assembler : public Malloced {
518 public: 652 public:
519 // Create an assembler. Instructions and relocation information are emitted 653 // Create an assembler. Instructions and relocation information are emitted
520 // into a buffer, with the instructions starting from the beginning and the 654 // into a buffer, with the instructions starting from the beginning and the
521 // relocation information starting from the end of the buffer. See CodeDesc 655 // relocation information starting from the end of the buffer. See CodeDesc
522 // for a detailed comment on the layout (globals.h). 656 // for a detailed comment on the layout (globals.h).
523 // 657 //
524 // If the provided buffer is NULL, the assembler allocates and grows its own 658 // If the provided buffer is NULL, the assembler allocates and grows its own
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 set_target_at(constant_pool_entry, target); 716 set_target_at(constant_pool_entry, target);
583 } 717 }
584 718
585 // Here we are patching the address in the constant pool, not the actual call 719 // Here we are patching the address in the constant pool, not the actual call
586 // instruction. The address in the constant pool is the same size as a 720 // instruction. The address in the constant pool is the same size as a
587 // pointer. 721 // pointer.
588 static const int kCallTargetSize = kPointerSize; 722 static const int kCallTargetSize = kPointerSize;
589 static const int kExternalTargetSize = kPointerSize; 723 static const int kExternalTargetSize = kPointerSize;
590 724
591 // Size of an instruction. 725 // Size of an instruction.
726 static const int kInstrArmSize = sizeof(InstrArm);
727 static const int kInstrThumbSize = sizeof(InstrThumb);
728 // Keep the code generator happy for now.
592 static const int kInstrSize = sizeof(Instr); 729 static const int kInstrSize = sizeof(Instr);
593 730
731
594 // Distance between the instruction referring to the address of the call 732 // Distance between the instruction referring to the address of the call
595 // target (ldr pc, [target addr in const pool]) and the return address 733 // target (ldr pc, [target addr in const pool]) and the return address
596 static const int kCallTargetAddressOffset = kInstrSize; 734 static const int kCallTargetAddressOffset = kInstrArmSize;
597 735
598 // Distance between start of patched return sequence and the emitted address 736 // Distance between start of patched return sequence and the emitted address
599 // to jump to. 737 // to jump to.
600 static const int kPatchReturnSequenceAddressOffset = kInstrSize; 738 static const int kPatchReturnSequenceAddressOffset = kInstrArmSize;
601 739
602 // Difference between address of current opcode and value read from pc 740 // Difference between address of current opcode and value read from pc
603 // register. 741 // register.
604 static const int kPcLoadDelta = 8; 742 static const int kPcLoadDelta = 8;
605 743
606 static const int kJSReturnSequenceLength = 4; 744 static const int kJSReturnSequenceLength = 4;
607 745
608 // --------------------------------------------------------------------------- 746 // ---------------------------------------------------------------------------
609 // Code generation 747 // Code generation
610 748
(...skipping 12 matching lines...) Expand all
623 // Convenience branch instructions using labels 761 // Convenience branch instructions using labels
624 void b(Label* L, Condition cond = al) { 762 void b(Label* L, Condition cond = al) {
625 b(branch_offset(L, cond == al), cond); 763 b(branch_offset(L, cond == al), cond);
626 } 764 }
627 void b(Condition cond, Label* L) { b(branch_offset(L, cond == al), cond); } 765 void b(Condition cond, Label* L) { b(branch_offset(L, cond == al), cond); }
628 void bl(Label* L, Condition cond = al) { bl(branch_offset(L, false), cond); } 766 void bl(Label* L, Condition cond = al) { bl(branch_offset(L, false), cond); }
629 void bl(Condition cond, Label* L) { bl(branch_offset(L, false), cond); } 767 void bl(Condition cond, Label* L) { bl(branch_offset(L, false), cond); }
630 void blx(Label* L) { blx(branch_offset(L, false)); } // v5 and above 768 void blx(Label* L) { blx(branch_offset(L, false)); } // v5 and above
631 769
632 // Data-processing instructions 770 // Data-processing instructions
771 void ubfx(Register dst, Register src1, const Operand& src2,
772 const Operand& src3, Condition cond = al);
773
633 void and_(Register dst, Register src1, const Operand& src2, 774 void and_(Register dst, Register src1, const Operand& src2,
634 SBit s = LeaveCC, Condition cond = al); 775 SBit s = LeaveCC, Condition cond = al);
635 776
636 void eor(Register dst, Register src1, const Operand& src2, 777 void eor(Register dst, Register src1, const Operand& src2,
637 SBit s = LeaveCC, Condition cond = al); 778 SBit s = LeaveCC, Condition cond = al);
638 779
639 void sub(Register dst, Register src1, const Operand& src2, 780 void sub(Register dst, Register src1, const Operand& src2,
640 SBit s = LeaveCC, Condition cond = al); 781 SBit s = LeaveCC, Condition cond = al);
641 void sub(Register dst, Register src1, Register src2, 782 void sub(Register dst, Register src1, Register src2,
642 SBit s = LeaveCC, Condition cond = al) { 783 SBit s = LeaveCC, Condition cond = al) {
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 LFlag l = Short); // v5 and above 930 LFlag l = Short); // v5 and above
790 void stc2(Coprocessor coproc, CRegister crd, Register base, int option, 931 void stc2(Coprocessor coproc, CRegister crd, Register base, int option,
791 LFlag l = Short); // v5 and above 932 LFlag l = Short); // v5 and above
792 933
793 // Support for VFP. 934 // Support for VFP.
794 // All these APIs support S0 to S31 and D0 to D15. 935 // All these APIs support S0 to S31 and D0 to D15.
795 // Currently these APIs do not support extended D registers, i.e, D16 to D31. 936 // Currently these APIs do not support extended D registers, i.e, D16 to D31.
796 // However, some simple modifications can allow 937 // However, some simple modifications can allow
797 // these APIs to support D16 to D31. 938 // these APIs to support D16 to D31.
798 939
940 void vldr(const DwVfpRegister dst,
941 const Register base,
942 int offset, // Offset must be a multiple of 4.
943 const Condition cond = al);
944 void vstr(const DwVfpRegister src,
945 const Register base,
946 int offset, // Offset must be a multiple of 4.
947 const Condition cond = al);
799 void vmov(const DwVfpRegister dst, 948 void vmov(const DwVfpRegister dst,
800 const Register src1, 949 const Register src1,
801 const Register src2, 950 const Register src2,
802 const Condition cond = al); 951 const Condition cond = al);
803 void vmov(const Register dst1, 952 void vmov(const Register dst1,
804 const Register dst2, 953 const Register dst2,
805 const DwVfpRegister src, 954 const DwVfpRegister src,
806 const Condition cond = al); 955 const Condition cond = al);
807 void vmov(const SwVfpRegister dst, 956 void vmov(const SwVfpRegister dst,
808 const Register src, 957 const Register src,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
857 1006
858 // Load effective address of memory operand x into register dst 1007 // Load effective address of memory operand x into register dst
859 void lea(Register dst, const MemOperand& x, 1008 void lea(Register dst, const MemOperand& x,
860 SBit s = LeaveCC, Condition cond = al); 1009 SBit s = LeaveCC, Condition cond = al);
861 1010
862 // Jump unconditionally to given label. 1011 // Jump unconditionally to given label.
863 void jmp(Label* L) { b(L, al); } 1012 void jmp(Label* L) { b(L, al); }
864 1013
865 // Check the code size generated from label to here. 1014 // Check the code size generated from label to here.
866 int InstructionsGeneratedSince(Label* l) { 1015 int InstructionsGeneratedSince(Label* l) {
867 return (pc_offset() - l->pos()) / kInstrSize; 1016 return (pc_offset() - l->pos()) / kInstrArmSize;
868 } 1017 }
869 1018
870 // Check whether an immediate fits an addressing mode 1 instruction. 1019 // Check whether an immediate fits an addressing mode 1 instruction.
871 bool ImmediateFitsAddrMode1Instruction(int32_t imm32); 1020 bool ImmediateFitsAddrMode1Instruction(int32_t imm32);
872 1021
873 // Postpone the generation of the constant pool for the specified number of 1022 // Postpone the generation of the constant pool for the specified number of
874 // instructions. 1023 // instructions.
875 void BlockConstPoolFor(int instructions); 1024 void BlockConstPoolFor(int instructions);
876 1025
877 // Debugging 1026 // Debugging
(...skipping 10 matching lines...) Expand all
888 void WriteRecordedPositions(); 1037 void WriteRecordedPositions();
889 1038
890 int pc_offset() const { return pc_ - buffer_; } 1039 int pc_offset() const { return pc_ - buffer_; }
891 int current_position() const { return current_position_; } 1040 int current_position() const { return current_position_; }
892 int current_statement_position() const { return current_position_; } 1041 int current_statement_position() const { return current_position_; }
893 1042
894 protected: 1043 protected:
895 int buffer_space() const { return reloc_info_writer.pos() - pc_; } 1044 int buffer_space() const { return reloc_info_writer.pos() - pc_; }
896 1045
897 // Read/patch instructions 1046 // Read/patch instructions
898 static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); } 1047 static InstrArm instr_arm_at(byte* pc) {
899 void instr_at_put(byte* pc, Instr instr) { 1048 return *reinterpret_cast<InstrArm*>(pc);
900 *reinterpret_cast<Instr*>(pc) = instr;
901 } 1049 }
902 Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } 1050
903 void instr_at_put(int pos, Instr instr) { 1051 void instr_arm_at_put(byte* pc, InstrArm instr) {
904 *reinterpret_cast<Instr*>(buffer_ + pos) = instr; 1052 *reinterpret_cast<InstrArm*>(pc) = instr;
1053 }
1054
1055 InstrArm instr_arm_at(int pos) {
1056 return *reinterpret_cast<InstrArm*>(buffer_ + pos);
1057 }
1058
1059 void instr_arm_at_put(int pos, InstrArm instr) {
1060 *reinterpret_cast<InstrArm*>(buffer_ + pos) = instr;
905 } 1061 }
906 1062
907 // Decode branch instruction at pos and return branch target pos 1063 // Decode branch instruction at pos and return branch target pos
908 int target_at(int pos); 1064 int target_at(int pos);
909 1065
910 // Patch branch instruction at pos to branch to given branch target pos 1066 // Patch branch instruction at pos to branch to given branch target pos
911 void target_at_put(int pos, int target_pos); 1067 void target_at_put(int pos, int target_pos);
912 1068
913 // Check if is time to emit a constant pool for pending reloc info entries 1069 // Check if is time to emit a constant pool for pending reloc info entries
914 void CheckConstPool(bool force_emit, bool require_jump); 1070 void CheckConstPool(bool force_emit, bool require_jump);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 // location it is accessed from. In this case, we emit a jump over the emitted 1103 // location it is accessed from. In this case, we emit a jump over the emitted
948 // constant pool. 1104 // constant pool.
949 // Constants in the pool may be addresses of functions that gets relocated; 1105 // Constants in the pool may be addresses of functions that gets relocated;
950 // if so, a relocation info entry is associated to the constant pool entry. 1106 // if so, a relocation info entry is associated to the constant pool entry.
951 1107
952 // Repeated checking whether the constant pool should be emitted is rather 1108 // Repeated checking whether the constant pool should be emitted is rather
953 // expensive. By default we only check again once a number of instructions 1109 // expensive. By default we only check again once a number of instructions
954 // has been generated. That also means that the sizing of the buffers is not 1110 // has been generated. That also means that the sizing of the buffers is not
955 // an exact science, and that we rely on some slop to not overrun buffers. 1111 // an exact science, and that we rely on some slop to not overrun buffers.
956 static const int kCheckConstIntervalInst = 32; 1112 static const int kCheckConstIntervalInst = 32;
957 static const int kCheckConstInterval = kCheckConstIntervalInst * kInstrSize; 1113 static const int kCheckConstInterval =
1114 kCheckConstIntervalInst * kInstrArmSize;
958 1115
959 1116
960 // Pools are emitted after function return and in dead code at (more or less) 1117 // Pools are emitted after function return and in dead code at (more or less)
961 // regular intervals of kDistBetweenPools bytes 1118 // regular intervals of kDistBetweenPools bytes
962 static const int kDistBetweenPools = 1*KB; 1119 static const int kDistBetweenPools = 1*KB;
963 1120
964 // Constants in pools are accessed via pc relative addressing, which can 1121 // Constants in pools are accessed via pc relative addressing, which can
965 // reach +/-4KB thereby defining a maximum distance between the instruction 1122 // reach +/-4KB thereby defining a maximum distance between the instruction
966 // and the accessed constant. We satisfy this constraint by limiting the 1123 // and the accessed constant. We satisfy this constraint by limiting the
967 // distance between pools. 1124 // distance between pools.
968 static const int kMaxDistBetweenPools = 4*KB - 2*kBufferCheckInterval; 1125 static const int kMaxDistBetweenPools = 4*KB - 2*kBufferCheckInterval;
969 1126
970 // Emission of the constant pool may be blocked in some code sequences 1127 // Emission of the constant pool may be blocked in some code sequences
971 int no_const_pool_before_; // block emission before this pc offset 1128 int no_const_pool_before_; // block emission before this pc offset
972 1129
973 // Keep track of the last emitted pool to guarantee a maximal distance 1130 // Keep track of the last emitted pool to guarantee a maximal distance
974 int last_const_pool_end_; // pc offset following the last constant pool 1131 int last_const_pool_end_; // pc offset following the last constant pool
975 1132
976 // Relocation info generation 1133 // Relocation info generation
977 // Each relocation is encoded as a variable size value 1134 // Each relocation is encoded as a variable size value
978 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; 1135 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
979 RelocInfoWriter reloc_info_writer; 1136 RelocInfoWriter reloc_info_writer;
980 // Relocation info records are also used during code generation as temporary 1137 // Relocation info records are also used during code generation as temporary
981 // containers for constants and code target addresses until they are emitted 1138 // containers for constants and code target addresses until they are emitted
982 // to the constant pool. These pending relocation info records are temporarily 1139 // to the constant pool. These pending relocation info records are temporarily
983 // stored in a separate buffer until a constant pool is emitted. 1140 // stored in a separate buffer until a constant pool is emitted.
984 // If every instruction in a long sequence is accessing the pool, we need one 1141 // If every instruction in a long sequence is accessing the pool, we need one
985 // pending relocation entry per instruction. 1142 // pending relocation entry per instruction.
986 static const int kMaxNumPRInfo = kMaxDistBetweenPools/kInstrSize; 1143 static const int kMaxNumPRInfo = kMaxDistBetweenPools/kInstrArmSize;
987 RelocInfo prinfo_[kMaxNumPRInfo]; // the buffer of pending relocation info 1144 RelocInfo prinfo_[kMaxNumPRInfo]; // the buffer of pending relocation info
988 int num_prinfo_; // number of pending reloc info entries in the buffer 1145 int num_prinfo_; // number of pending reloc info entries in the buffer
989 1146
990 // The bound position, before this we cannot do instruction elimination. 1147 // The bound position, before this we cannot do instruction elimination.
991 int last_bound_pos_; 1148 int last_bound_pos_;
992 1149
993 // source position information 1150 // source position information
994 int current_position_; 1151 int current_position_;
995 int current_statement_position_; 1152 int current_statement_position_;
996 int written_position_; 1153 int written_position_;
997 int written_statement_position_; 1154 int written_statement_position_;
1155 bool thumb_mode_;
1156
998 1157
999 // Code emission 1158 // Code emission
1000 inline void CheckBuffer(); 1159 inline void CheckBuffer();
1160 inline void EnsureThumbMode();
1161 inline void EnsureArmMode();
1001 void GrowBuffer(); 1162 void GrowBuffer();
1002 inline void emit(Instr x); 1163 inline void emit_thumb(InstrThumb x);
1164 inline void emit_arm(InstrArm x);
1165 inline void emit_int32(int32_t x);
1003 1166
1004 // Instruction generation 1167 // ARM Instruction generation
1005 void addrmod1(Instr instr, Register rn, Register rd, const Operand& x); 1168 void addrmod1(InstrArm instr, Register rn, Register rd, const Operand& x);
1006 void addrmod2(Instr instr, Register rd, const MemOperand& x); 1169 void addrmod2(InstrArm instr, Register rd, const MemOperand& x);
1007 void addrmod3(Instr instr, Register rd, const MemOperand& x); 1170 void addrmod3(InstrArm instr, Register rd, const MemOperand& x);
1008 void addrmod4(Instr instr, Register rn, RegList rl); 1171 void addrmod4(InstrArm instr, Register rn, RegList rl);
1009 void addrmod5(Instr instr, CRegister crd, const MemOperand& x); 1172 void addrmod5(InstrArm instr, CRegister crd, const MemOperand& x);
1173
1174 // Thumb2 Instruction generation
1175 void DataProcessing(Condition cond, Opcode op, SBit s,
1176 Register rn, Register rd, const Operand& x);
1177 void DataProcessingReg(Opcode op, SBit s, Register rn, Register rd,
1178 Register rm, ShiftOp shiftOp, int shiftBy);
1179 void DataProcessingImm(Opcode op, SBit s, Register rn, Register rd, int imm);
1010 1180
1011 // Labels 1181 // Labels
1012 void print(Label* L); 1182 void print(Label* L);
1013 void bind_to(Label* L, int pos); 1183 void bind_to(Label* L, int pos);
1014 void link_to(Label* L, Label* appendix); 1184 void link_to(Label* L, Label* appendix);
1015 void next(Label* L); 1185 void next(Label* L);
1016 1186
1017 // Record reloc info for current pc_ 1187 // Record reloc info for current pc_
1018 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 1188 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1019 1189
1020 friend class RegExpMacroAssemblerARM; 1190 friend class RegExpMacroAssemblerARM;
1021 friend class RelocInfo; 1191 friend class RelocInfo;
1022 friend class CodePatcher; 1192 friend class CodePatcher;
1023 }; 1193 };
1024 1194
1025 } } // namespace v8::internal 1195 } } // namespace v8::internal
1026 1196
1027 #endif // V8_ARM_ASSEMBLER_THUMB2_H_ 1197 #endif // V8_ARM_ASSEMBLER_THUMB2_H_
OLDNEW
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/assembler-thumb2-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698