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 |