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 are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // 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 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 // Machine instruction Immediates | 176 // Machine instruction Immediates |
177 | 177 |
178 class Immediate BASE_EMBEDDED { | 178 class Immediate BASE_EMBEDDED { |
179 public: | 179 public: |
180 inline explicit Immediate(int x); | 180 inline explicit Immediate(int x); |
181 inline explicit Immediate(const char* s); | 181 inline explicit Immediate(const char* s); |
182 inline explicit Immediate(const ExternalReference& ext); | 182 inline explicit Immediate(const ExternalReference& ext); |
183 inline explicit Immediate(Handle<Object> handle); | 183 inline explicit Immediate(Handle<Object> handle); |
184 inline explicit Immediate(Smi* value); | 184 inline explicit Immediate(Smi* value); |
185 | 185 |
186 bool is_zero() const { return x_ == 0 && rmode_ == no_reloc; } | 186 bool is_zero() const { return x_ == 0 && rmode_ == RelocInfo::NONE; } |
187 bool is_int8() const { return -128 <= x_ && x_ < 128 && rmode_ == no_reloc; } | 187 bool is_int8() const { |
| 188 return -128 <= x_ && x_ < 128 && rmode_ == RelocInfo::NONE; |
| 189 } |
188 | 190 |
189 private: | 191 private: |
190 int x_; | 192 int x_; |
191 RelocMode rmode_; | 193 RelocInfo::Mode rmode_; |
192 | 194 |
193 friend class Assembler; | 195 friend class Assembler; |
194 }; | 196 }; |
195 | 197 |
196 | 198 |
197 // ----------------------------------------------------------------------------- | 199 // ----------------------------------------------------------------------------- |
198 // Machine instruction Operands | 200 // Machine instruction Operands |
199 | 201 |
200 enum ScaleFactor { | 202 enum ScaleFactor { |
201 times_1 = 0, | 203 times_1 = 0, |
202 times_2 = 1, | 204 times_2 = 1, |
203 times_4 = 2, | 205 times_4 = 2, |
204 times_8 = 3 | 206 times_8 = 3 |
205 }; | 207 }; |
206 | 208 |
207 | 209 |
208 class Operand BASE_EMBEDDED { | 210 class Operand BASE_EMBEDDED { |
209 public: | 211 public: |
210 // reg | 212 // reg |
211 INLINE(explicit Operand(Register reg)); | 213 INLINE(explicit Operand(Register reg)); |
212 | 214 |
213 // [disp/r] | 215 // [disp/r] |
214 INLINE(explicit Operand(int32_t disp, RelocMode rmode)); | 216 INLINE(explicit Operand(int32_t disp, RelocInfo::Mode rmode)); |
215 // disp only must always be relocated | 217 // disp only must always be relocated |
216 | 218 |
217 // [base + disp/r] | 219 // [base + disp/r] |
218 explicit Operand(Register base, int32_t disp, RelocMode rmode = no_reloc); | 220 explicit Operand(Register base, int32_t disp, |
| 221 RelocInfo::Mode rmode = RelocInfo::NONE); |
219 | 222 |
220 // [base + index*scale + disp/r] | 223 // [base + index*scale + disp/r] |
221 explicit Operand(Register base, | 224 explicit Operand(Register base, |
222 Register index, | 225 Register index, |
223 ScaleFactor scale, | 226 ScaleFactor scale, |
224 int32_t disp, | 227 int32_t disp, |
225 RelocMode rmode = no_reloc); | 228 RelocInfo::Mode rmode = RelocInfo::NONE); |
226 | 229 |
227 // [index*scale + disp/r] | 230 // [index*scale + disp/r] |
228 explicit Operand(Register index, | 231 explicit Operand(Register index, |
229 ScaleFactor scale, | 232 ScaleFactor scale, |
230 int32_t disp, | 233 int32_t disp, |
231 RelocMode rmode = no_reloc); | 234 RelocInfo::Mode rmode = RelocInfo::NONE); |
232 | 235 |
233 static Operand StaticVariable(const ExternalReference& ext) { | 236 static Operand StaticVariable(const ExternalReference& ext) { |
234 return Operand(reinterpret_cast<int32_t>(ext.address()), | 237 return Operand(reinterpret_cast<int32_t>(ext.address()), |
235 external_reference); | 238 RelocInfo::EXTERNAL_REFERENCE); |
236 } | 239 } |
237 | 240 |
238 static Operand StaticArray(Register index, | 241 static Operand StaticArray(Register index, |
239 ScaleFactor scale, | 242 ScaleFactor scale, |
240 const ExternalReference& arr) { | 243 const ExternalReference& arr) { |
241 return Operand(index, scale, reinterpret_cast<int32_t>(arr.address()), | 244 return Operand(index, scale, reinterpret_cast<int32_t>(arr.address()), |
242 external_reference); | 245 RelocInfo::EXTERNAL_REFERENCE); |
243 } | 246 } |
244 | 247 |
245 // Returns true if this Operand is a wrapper for the specified register. | 248 // Returns true if this Operand is a wrapper for the specified register. |
246 bool is_reg(Register reg) const; | 249 bool is_reg(Register reg) const; |
247 | 250 |
248 private: | 251 private: |
249 // Mutable because reg in ModR/M byte is set by Assembler via set_reg(). | 252 // Mutable because reg in ModR/M byte is set by Assembler via set_reg(). |
250 mutable byte buf_[6]; | 253 mutable byte buf_[6]; |
251 // The number of bytes in buf_. | 254 // The number of bytes in buf_. |
252 unsigned int len_; | 255 unsigned int len_; |
253 // Only valid if len_ > 4. | 256 // Only valid if len_ > 4. |
254 RelocMode rmode_; | 257 RelocInfo::Mode rmode_; |
255 | 258 |
256 inline void set_modrm(int mod, // reg == 0 | 259 inline void set_modrm(int mod, // reg == 0 |
257 Register rm); | 260 Register rm); |
258 inline void set_sib(ScaleFactor scale, Register index, Register base); | 261 inline void set_sib(ScaleFactor scale, Register index, Register base); |
259 inline void set_disp8(int8_t disp); | 262 inline void set_disp8(int8_t disp); |
260 inline void set_dispr(int32_t disp, RelocMode rmode); | 263 inline void set_dispr(int32_t disp, RelocInfo::Mode rmode); |
261 inline void set_reg(Register reg) const; | 264 inline void set_reg(Register reg) const; |
262 | 265 |
263 friend class Assembler; | 266 friend class Assembler; |
264 }; | 267 }; |
265 | 268 |
266 | 269 |
267 // ----------------------------------------------------------------------------- | 270 // ----------------------------------------------------------------------------- |
268 // A Displacement describes the 32bit immediate field of an instruction which | 271 // A Displacement describes the 32bit immediate field of an instruction which |
269 // may be used together with a Label in order to refer to a yet unknown code | 272 // may be used together with a Label in order to refer to a yet unknown code |
270 // position. Displacements stored in the instruction stream are used to describe | 273 // position. Displacements stored in the instruction stream are used to describe |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 // j(cc, &L); // backward branch to bound label | 570 // j(cc, &L); // backward branch to bound label |
568 // bind(&L); // illegal: a label may be bound only once | 571 // bind(&L); // illegal: a label may be bound only once |
569 // | 572 // |
570 // Note: The same Label can be used for forward and backward branches | 573 // Note: The same Label can be used for forward and backward branches |
571 // but it may be bound only once. | 574 // but it may be bound only once. |
572 | 575 |
573 void bind(Label* L); // binds an unbound label L to the current code position | 576 void bind(Label* L); // binds an unbound label L to the current code position |
574 | 577 |
575 // Calls | 578 // Calls |
576 void call(Label* L); | 579 void call(Label* L); |
577 void call(byte* entry, RelocMode rmode); | 580 void call(byte* entry, RelocInfo::Mode rmode); |
578 void call(const Operand& adr); | 581 void call(const Operand& adr); |
579 void call(Handle<Code> code, RelocMode rmode); | 582 void call(Handle<Code> code, RelocInfo::Mode rmode); |
580 | 583 |
581 // Jumps | 584 // Jumps |
582 void jmp(Label* L); // unconditional jump to L | 585 void jmp(Label* L); // unconditional jump to L |
583 void jmp(byte* entry, RelocMode rmode); | 586 void jmp(byte* entry, RelocInfo::Mode rmode); |
584 void jmp(const Operand& adr); | 587 void jmp(const Operand& adr); |
585 void jmp(Handle<Code> code, RelocMode rmode); | 588 void jmp(Handle<Code> code, RelocInfo::Mode rmode); |
586 | 589 |
587 // Conditional jumps | 590 // Conditional jumps |
588 void j(Condition cc, Label* L, Hint hint = no_hint); | 591 void j(Condition cc, Label* L, Hint hint = no_hint); |
589 void j(Condition cc, byte* entry, RelocMode rmode, Hint hint = no_hint); | 592 void j(Condition cc, byte* entry, RelocInfo::Mode rmode, Hint hint = no_hint); |
590 void j(Condition cc, Handle<Code> code, Hint hint = no_hint); | 593 void j(Condition cc, Handle<Code> code, Hint hint = no_hint); |
591 | 594 |
592 // Floating-point operations | 595 // Floating-point operations |
593 void fld(int i); | 596 void fld(int i); |
594 | 597 |
595 void fld1(); | 598 void fld1(); |
596 void fldz(); | 599 void fldz(); |
597 | 600 |
598 void fld_s(const Operand& adr); | 601 void fld_s(const Operand& adr); |
599 void fld_d(const Operand& adr); | 602 void fld_d(const Operand& adr); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
671 // Record a comment relocation entry that can be used by a disassembler. | 674 // Record a comment relocation entry that can be used by a disassembler. |
672 // Use --debug_code to enable. | 675 // Use --debug_code to enable. |
673 void RecordComment(const char* msg); | 676 void RecordComment(const char* msg); |
674 | 677 |
675 void RecordPosition(int pos); | 678 void RecordPosition(int pos); |
676 void RecordStatementPosition(int pos); | 679 void RecordStatementPosition(int pos); |
677 void WriteRecordedPositions(); | 680 void WriteRecordedPositions(); |
678 | 681 |
679 // Writes a single word of data in the code stream. | 682 // Writes a single word of data in the code stream. |
680 // Used for inline tables, e.g., jump-tables. | 683 // Used for inline tables, e.g., jump-tables. |
681 void dd(uint32_t data, RelocMode reloc_info); | 684 void dd(uint32_t data, RelocInfo::Mode reloc_info); |
682 | 685 |
683 // Writes the absolute address of a bound label at the given position in | 686 // Writes the absolute address of a bound label at the given position in |
684 // the generated code. That positions should have the relocation mode | 687 // the generated code. That positions should have the relocation mode |
685 // internal_reference! | 688 // internal_reference! |
686 void WriteInternalReference(int position, const Label& bound_label); | 689 void WriteInternalReference(int position, const Label& bound_label); |
687 | 690 |
688 int pc_offset() const { return pc_ - buffer_; } | 691 int pc_offset() const { return pc_ - buffer_; } |
689 int last_statement_position() const { return last_statement_position_; } | 692 int last_statement_position() const { return last_statement_position_; } |
690 int last_position() const { return last_position_; } | 693 int last_position() const { return last_position_; } |
691 | 694 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
742 return *reinterpret_cast<uint32_t*>(addr_at(pos)); | 745 return *reinterpret_cast<uint32_t*>(addr_at(pos)); |
743 } | 746 } |
744 void long_at_put(int pos, uint32_t x) { | 747 void long_at_put(int pos, uint32_t x) { |
745 *reinterpret_cast<uint32_t*>(addr_at(pos)) = x; | 748 *reinterpret_cast<uint32_t*>(addr_at(pos)) = x; |
746 } | 749 } |
747 | 750 |
748 // code emission | 751 // code emission |
749 void GrowBuffer(); | 752 void GrowBuffer(); |
750 inline void emit(uint32_t x); | 753 inline void emit(uint32_t x); |
751 inline void emit(Handle<Object> handle); | 754 inline void emit(Handle<Object> handle); |
752 inline void emit(uint32_t x, RelocMode rmode); | 755 inline void emit(uint32_t x, RelocInfo::Mode rmode); |
753 inline void emit(const Immediate& x); | 756 inline void emit(const Immediate& x); |
754 | 757 |
755 // instruction generation | 758 // instruction generation |
756 void emit_arith_b(int op1, int op2, Register dst, int imm8); | 759 void emit_arith_b(int op1, int op2, Register dst, int imm8); |
757 | 760 |
758 // Emit a basic arithmetic instruction (i.e. first byte of the family is 0x81) | 761 // Emit a basic arithmetic instruction (i.e. first byte of the family is 0x81) |
759 // with a given destination expression and an immediate operand. It attempts | 762 // with a given destination expression and an immediate operand. It attempts |
760 // to use the shortest encoding possible. | 763 // to use the shortest encoding possible. |
761 // sel specifies the /n in the modrm byte (see the Intel PRM). | 764 // sel specifies the /n in the modrm byte (see the Intel PRM). |
762 void emit_arith(int sel, Operand dst, const Immediate& x); | 765 void emit_arith(int sel, Operand dst, const Immediate& x); |
763 | 766 |
764 void emit_operand(Register reg, const Operand& adr); | 767 void emit_operand(Register reg, const Operand& adr); |
765 void emit_operand(const Operand& adr, Register reg); | 768 void emit_operand(const Operand& adr, Register reg); |
766 | 769 |
767 void emit_farith(int b1, int b2, int i); | 770 void emit_farith(int b1, int b2, int i); |
768 | 771 |
769 // labels | 772 // labels |
770 void print(Label* L); | 773 void print(Label* L); |
771 void bind_to(Label* L, int pos); | 774 void bind_to(Label* L, int pos); |
772 void link_to(Label* L, Label* appendix); | 775 void link_to(Label* L, Label* appendix); |
773 | 776 |
774 // displacements | 777 // displacements |
775 inline Displacement disp_at(Label* L); | 778 inline Displacement disp_at(Label* L); |
776 inline void disp_at_put(Label* L, Displacement disp); | 779 inline void disp_at_put(Label* L, Displacement disp); |
777 inline void emit_disp(Label* L, Displacement::Type type); | 780 inline void emit_disp(Label* L, Displacement::Type type); |
778 | 781 |
779 // record reloc info for current pc_ | 782 // record reloc info for current pc_ |
780 void RecordRelocInfo(RelocMode rmode, intptr_t data = 0); | 783 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); |
781 | 784 |
782 friend class CodePatcher; | 785 friend class CodePatcher; |
783 friend class EnsureSpace; | 786 friend class EnsureSpace; |
784 }; | 787 }; |
785 | 788 |
786 | 789 |
787 // Helper class that ensures that there is enough space for generating | 790 // Helper class that ensures that there is enough space for generating |
788 // instructions and relocation information. The constructor makes | 791 // instructions and relocation information. The constructor makes |
789 // sure that there is enough space and (in debug mode) the destructor | 792 // sure that there is enough space and (in debug mode) the destructor |
790 // checks that we did not generate too much. | 793 // checks that we did not generate too much. |
(...skipping 16 matching lines...) Expand all Loading... |
807 private: | 810 private: |
808 Assembler* assembler_; | 811 Assembler* assembler_; |
809 #ifdef DEBUG | 812 #ifdef DEBUG |
810 int space_before_; | 813 int space_before_; |
811 #endif | 814 #endif |
812 }; | 815 }; |
813 | 816 |
814 } } // namespace v8::internal | 817 } } // namespace v8::internal |
815 | 818 |
816 #endif // V8_ASSEMBLER_IA32_H_ | 819 #endif // V8_ASSEMBLER_IA32_H_ |
OLD | NEW |