| 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 19 matching lines...) Expand all Loading... |
| 30 | 30 |
| 31 // The original source code covered by the above license above has been | 31 // The original source code covered by the above license above has been |
| 32 // modified significantly by Google Inc. | 32 // modified significantly by Google Inc. |
| 33 // Copyright 2011 the V8 project authors. All rights reserved. | 33 // Copyright 2011 the V8 project authors. All rights reserved. |
| 34 | 34 |
| 35 // A light-weight IA32 Assembler. | 35 // A light-weight IA32 Assembler. |
| 36 | 36 |
| 37 #ifndef V8_X87_ASSEMBLER_X87_H_ | 37 #ifndef V8_X87_ASSEMBLER_X87_H_ |
| 38 #define V8_X87_ASSEMBLER_X87_H_ | 38 #define V8_X87_ASSEMBLER_X87_H_ |
| 39 | 39 |
| 40 #include <deque> |
| 41 |
| 40 #include "src/assembler.h" | 42 #include "src/assembler.h" |
| 41 #include "src/isolate.h" | 43 #include "src/isolate.h" |
| 42 #include "src/serialize.h" | 44 #include "src/serialize.h" |
| 43 | 45 |
| 44 namespace v8 { | 46 namespace v8 { |
| 45 namespace internal { | 47 namespace internal { |
| 46 | 48 |
| 47 // CPU Registers. | 49 // CPU Registers. |
| 48 // | 50 // |
| 49 // 1) We would prefer to use an enum, but enum values are assignment- | 51 // 1) We would prefer to use an enum, but enum values are assignment- |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 ScaleFactor scale, | 344 ScaleFactor scale, |
| 343 int32_t disp, | 345 int32_t disp, |
| 344 RelocInfo::Mode rmode = RelocInfo::NONE32); | 346 RelocInfo::Mode rmode = RelocInfo::NONE32); |
| 345 | 347 |
| 346 // [index*scale + disp/r] | 348 // [index*scale + disp/r] |
| 347 explicit Operand(Register index, | 349 explicit Operand(Register index, |
| 348 ScaleFactor scale, | 350 ScaleFactor scale, |
| 349 int32_t disp, | 351 int32_t disp, |
| 350 RelocInfo::Mode rmode = RelocInfo::NONE32); | 352 RelocInfo::Mode rmode = RelocInfo::NONE32); |
| 351 | 353 |
| 354 static Operand JumpTable(Register index, ScaleFactor scale, Label* table) { |
| 355 return Operand(index, scale, reinterpret_cast<int32_t>(table), |
| 356 RelocInfo::INTERNAL_REFERENCE); |
| 357 } |
| 358 |
| 352 static Operand StaticVariable(const ExternalReference& ext) { | 359 static Operand StaticVariable(const ExternalReference& ext) { |
| 353 return Operand(reinterpret_cast<int32_t>(ext.address()), | 360 return Operand(reinterpret_cast<int32_t>(ext.address()), |
| 354 RelocInfo::EXTERNAL_REFERENCE); | 361 RelocInfo::EXTERNAL_REFERENCE); |
| 355 } | 362 } |
| 356 | 363 |
| 357 static Operand StaticArray(Register index, | 364 static Operand StaticArray(Register index, |
| 358 ScaleFactor scale, | 365 ScaleFactor scale, |
| 359 const ExternalReference& arr) { | 366 const ExternalReference& arr) { |
| 360 return Operand(index, scale, reinterpret_cast<int32_t>(arr.address()), | 367 return Operand(index, scale, reinterpret_cast<int32_t>(arr.address()), |
| 361 RelocInfo::EXTERNAL_REFERENCE); | 368 RelocInfo::EXTERNAL_REFERENCE); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 // be no displacement at position zero, because there is always at least one | 422 // be no displacement at position zero, because there is always at least one |
| 416 // instruction byte before the displacement). | 423 // instruction byte before the displacement). |
| 417 // | 424 // |
| 418 // Displacement _data field layout | 425 // Displacement _data field layout |
| 419 // | 426 // |
| 420 // |31.....2|1......0| | 427 // |31.....2|1......0| |
| 421 // [ next | type | | 428 // [ next | type | |
| 422 | 429 |
| 423 class Displacement BASE_EMBEDDED { | 430 class Displacement BASE_EMBEDDED { |
| 424 public: | 431 public: |
| 425 enum Type { | 432 enum Type { UNCONDITIONAL_JUMP, CODE_RELATIVE, OTHER, CODE_ABSOLUTE }; |
| 426 UNCONDITIONAL_JUMP, | |
| 427 CODE_RELATIVE, | |
| 428 OTHER | |
| 429 }; | |
| 430 | 433 |
| 431 int data() const { return data_; } | 434 int data() const { return data_; } |
| 432 Type type() const { return TypeField::decode(data_); } | 435 Type type() const { return TypeField::decode(data_); } |
| 433 void next(Label* L) const { | 436 void next(Label* L) const { |
| 434 int n = NextField::decode(data_); | 437 int n = NextField::decode(data_); |
| 435 n > 0 ? L->link_to(n) : L->Unuse(); | 438 n > 0 ? L->link_to(n) : L->Unuse(); |
| 436 } | 439 } |
| 437 void link_to(Label* L) { init(L, type()); } | 440 void link_to(Label* L) { init(L, type()); } |
| 438 | 441 |
| 439 explicit Displacement(int data) { data_ = data; } | 442 explicit Displacement(int data) { data_ = data; } |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 781 void bts(Register dst, Register src) { bts(Operand(dst), src); } | 784 void bts(Register dst, Register src) { bts(Operand(dst), src); } |
| 782 void bts(const Operand& dst, Register src); | 785 void bts(const Operand& dst, Register src); |
| 783 void bsr(Register dst, Register src) { bsr(dst, Operand(src)); } | 786 void bsr(Register dst, Register src) { bsr(dst, Operand(src)); } |
| 784 void bsr(Register dst, const Operand& src); | 787 void bsr(Register dst, const Operand& src); |
| 785 | 788 |
| 786 // Miscellaneous | 789 // Miscellaneous |
| 787 void hlt(); | 790 void hlt(); |
| 788 void int3(); | 791 void int3(); |
| 789 void nop(); | 792 void nop(); |
| 790 void ret(int imm16); | 793 void ret(int imm16); |
| 794 void ud2(); |
| 791 | 795 |
| 792 // Label operations & relative jumps (PPUM Appendix D) | 796 // Label operations & relative jumps (PPUM Appendix D) |
| 793 // | 797 // |
| 794 // Takes a branch opcode (cc) and a label (L) and generates | 798 // Takes a branch opcode (cc) and a label (L) and generates |
| 795 // either a backward branch or a forward branch and links it | 799 // either a backward branch or a forward branch and links it |
| 796 // to the label fixup chain. Usage: | 800 // to the label fixup chain. Usage: |
| 797 // | 801 // |
| 798 // Label L; // unbound label | 802 // Label L; // unbound label |
| 799 // j(cc, &L); // forward branch to unbound label | 803 // j(cc, &L); // forward branch to unbound label |
| 800 // bind(&L); // bind label to the current pc | 804 // bind(&L); // bind label to the current pc |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 936 void RecordComment(const char* msg); | 940 void RecordComment(const char* msg); |
| 937 | 941 |
| 938 // Record a deoptimization reason that can be used by a log or cpu profiler. | 942 // Record a deoptimization reason that can be used by a log or cpu profiler. |
| 939 // Use --trace-deopt to enable. | 943 // Use --trace-deopt to enable. |
| 940 void RecordDeoptReason(const int reason, const int raw_position); | 944 void RecordDeoptReason(const int reason, const int raw_position); |
| 941 | 945 |
| 942 // Writes a single byte or word of data in the code stream. Used for | 946 // Writes a single byte or word of data in the code stream. Used for |
| 943 // inline tables, e.g., jump-tables. | 947 // inline tables, e.g., jump-tables. |
| 944 void db(uint8_t data); | 948 void db(uint8_t data); |
| 945 void dd(uint32_t data); | 949 void dd(uint32_t data); |
| 950 void dd(Label* label); |
| 946 | 951 |
| 947 // Check if there is less than kGap bytes available in the buffer. | 952 // Check if there is less than kGap bytes available in the buffer. |
| 948 // If this is the case, we need to grow the buffer before emitting | 953 // If this is the case, we need to grow the buffer before emitting |
| 949 // an instruction or relocation information. | 954 // an instruction or relocation information. |
| 950 inline bool buffer_overflow() const { | 955 inline bool buffer_overflow() const { |
| 951 return pc_ >= reloc_info_writer.pos() - kGap; | 956 return pc_ >= reloc_info_writer.pos() - kGap; |
| 952 } | 957 } |
| 953 | 958 |
| 954 // Get the number of bytes available in the buffer. | 959 // Get the number of bytes available in the buffer. |
| 955 inline int available_space() const { return reloc_info_writer.pos() - pc_; } | 960 inline int available_space() const { return reloc_info_writer.pos() - pc_; } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1006 void emit_arith_b(int op1, int op2, Register dst, int imm8); | 1011 void emit_arith_b(int op1, int op2, Register dst, int imm8); |
| 1007 | 1012 |
| 1008 // Emit a basic arithmetic instruction (i.e. first byte of the family is 0x81) | 1013 // Emit a basic arithmetic instruction (i.e. first byte of the family is 0x81) |
| 1009 // with a given destination expression and an immediate operand. It attempts | 1014 // with a given destination expression and an immediate operand. It attempts |
| 1010 // to use the shortest encoding possible. | 1015 // to use the shortest encoding possible. |
| 1011 // sel specifies the /n in the modrm byte (see the Intel PRM). | 1016 // sel specifies the /n in the modrm byte (see the Intel PRM). |
| 1012 void emit_arith(int sel, Operand dst, const Immediate& x); | 1017 void emit_arith(int sel, Operand dst, const Immediate& x); |
| 1013 | 1018 |
| 1014 void emit_operand(Register reg, const Operand& adr); | 1019 void emit_operand(Register reg, const Operand& adr); |
| 1015 | 1020 |
| 1021 void emit_label(Label* label); |
| 1022 |
| 1016 void emit_farith(int b1, int b2, int i); | 1023 void emit_farith(int b1, int b2, int i); |
| 1017 | 1024 |
| 1018 // labels | 1025 // labels |
| 1019 void print(Label* L); | 1026 void print(Label* L); |
| 1020 void bind_to(Label* L, int pos); | 1027 void bind_to(Label* L, int pos); |
| 1021 | 1028 |
| 1022 // displacements | 1029 // displacements |
| 1023 inline Displacement disp_at(Label* L); | 1030 inline Displacement disp_at(Label* L); |
| 1024 inline void disp_at_put(Label* L, Displacement disp); | 1031 inline void disp_at_put(Label* L, Displacement disp); |
| 1025 inline void emit_disp(Label* L, Displacement::Type type); | 1032 inline void emit_disp(Label* L, Displacement::Type type); |
| 1026 inline void emit_near_disp(Label* L); | 1033 inline void emit_near_disp(Label* L); |
| 1027 | 1034 |
| 1028 // record reloc info for current pc_ | 1035 // record reloc info for current pc_ |
| 1029 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); | 1036 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); |
| 1030 | 1037 |
| 1031 friend class CodePatcher; | 1038 friend class CodePatcher; |
| 1032 friend class EnsureSpace; | 1039 friend class EnsureSpace; |
| 1033 | 1040 |
| 1041 // Internal reference positions, required for (potential) patching in |
| 1042 // GrowBuffer(); contains only those internal references whose labels |
| 1043 // are already bound. |
| 1044 std::deque<int> internal_reference_positions_; |
| 1045 |
| 1034 // code generation | 1046 // code generation |
| 1035 RelocInfoWriter reloc_info_writer; | 1047 RelocInfoWriter reloc_info_writer; |
| 1036 | 1048 |
| 1037 PositionsRecorder positions_recorder_; | 1049 PositionsRecorder positions_recorder_; |
| 1038 friend class PositionsRecorder; | 1050 friend class PositionsRecorder; |
| 1039 }; | 1051 }; |
| 1040 | 1052 |
| 1041 | 1053 |
| 1042 // Helper class that ensures that there is enough space for generating | 1054 // Helper class that ensures that there is enough space for generating |
| 1043 // instructions and relocation information. The constructor makes | 1055 // instructions and relocation information. The constructor makes |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1062 private: | 1074 private: |
| 1063 Assembler* assembler_; | 1075 Assembler* assembler_; |
| 1064 #ifdef DEBUG | 1076 #ifdef DEBUG |
| 1065 int space_before_; | 1077 int space_before_; |
| 1066 #endif | 1078 #endif |
| 1067 }; | 1079 }; |
| 1068 | 1080 |
| 1069 } } // namespace v8::internal | 1081 } } // namespace v8::internal |
| 1070 | 1082 |
| 1071 #endif // V8_X87_ASSEMBLER_X87_H_ | 1083 #endif // V8_X87_ASSEMBLER_X87_H_ |
| OLD | NEW |