| 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 |