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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 // 3) By not using an enum, we are possibly preventing the compiler from | 56 // 3) By not using an enum, we are possibly preventing the compiler from |
57 // doing certain constant folds, which may significantly reduce the | 57 // doing certain constant folds, which may significantly reduce the |
58 // code generated for some assembly instructions (because they boil down | 58 // code generated for some assembly instructions (because they boil down |
59 // to a few constants). If this is a problem, we could change the code | 59 // to a few constants). If this is a problem, we could change the code |
60 // such that we use an enum in optimized mode, and the struct in debug | 60 // such that we use an enum in optimized mode, and the struct in debug |
61 // mode. This way we get the compile-time error checking in debug mode | 61 // mode. This way we get the compile-time error checking in debug mode |
62 // and best performance in optimized code. | 62 // and best performance in optimized code. |
63 // | 63 // |
64 | 64 |
65 struct Register { | 65 struct Register { |
| 66 static Register toRegister(int code) { |
| 67 Register r = {code}; |
| 68 return r; |
| 69 } |
66 bool is_valid() const { return 0 <= code_ && code_ < 16; } | 70 bool is_valid() const { return 0 <= code_ && code_ < 16; } |
67 bool is(Register reg) const { return code_ == reg.code_; } | 71 bool is(Register reg) const { return code_ == reg.code_; } |
68 // The byte-register distinction of ai32 has dissapeared. | 72 // The byte-register distinction of ai32 has dissapeared. |
69 bool is_byte_register() const { return false; } | 73 bool is_byte_register() const { return false; } |
70 int code() const { | 74 int code() const { |
71 ASSERT(is_valid()); | 75 ASSERT(is_valid()); |
72 return code_; | 76 return code_; |
73 } | 77 } |
74 int bit() const { | 78 int bit() const { |
75 UNIMPLEMENTED(); | 79 UNIMPLEMENTED(); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 ? no_hint | 204 ? no_hint |
201 : ((hint == not_taken) ? taken : not_taken); | 205 : ((hint == not_taken) ? taken : not_taken); |
202 } | 206 } |
203 | 207 |
204 | 208 |
205 // ----------------------------------------------------------------------------- | 209 // ----------------------------------------------------------------------------- |
206 // Machine instruction Immediates | 210 // Machine instruction Immediates |
207 | 211 |
208 class Immediate BASE_EMBEDDED { | 212 class Immediate BASE_EMBEDDED { |
209 public: | 213 public: |
210 inline explicit Immediate(int64_t x); | 214 explicit Immediate(int32_t value) : value_(value) {} |
211 inline explicit Immediate(const char* s); | |
212 inline explicit Immediate(const ExternalReference& ext); | |
213 inline explicit Immediate(Handle<Object> handle); | |
214 inline explicit Immediate(Smi* value); | 215 inline explicit Immediate(Smi* value); |
215 | 216 |
216 static Immediate CodeRelativeOffset(Label* label) { | |
217 return Immediate(label); | |
218 } | |
219 | |
220 bool is_zero() const { return x_ == 0 && rmode_ == RelocInfo::NONE; } | |
221 bool is_int8() const { | |
222 return -128 <= x_ && x_ < 128 && rmode_ == RelocInfo::NONE; | |
223 } | |
224 bool is_int16() const { | |
225 return -32768 <= x_ && x_ < 32768 && rmode_ == RelocInfo::NONE; | |
226 } | |
227 bool is_int32() const { | |
228 return V8_INT64_C(-2147483648) <= x_ | |
229 && x_ < V8_INT64_C(2147483648) | |
230 && rmode_ == RelocInfo::NONE; | |
231 } | |
232 | |
233 private: | 217 private: |
234 inline explicit Immediate(Label* value) { UNIMPLEMENTED(); } | 218 int32_t value_; |
235 | |
236 int64_t x_; | |
237 RelocInfo::Mode rmode_; | |
238 | 219 |
239 friend class Assembler; | 220 friend class Assembler; |
240 }; | 221 }; |
241 | 222 |
242 | 223 |
243 // ----------------------------------------------------------------------------- | 224 // ----------------------------------------------------------------------------- |
244 // Machine instruction Operands | 225 // Machine instruction Operands |
245 | 226 |
246 enum ScaleFactor { | 227 enum ScaleFactor { |
247 times_1 = 0, | 228 times_1 = 0, |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 void push(const Operand& src); | 396 void push(const Operand& src); |
416 void push(Label* label, RelocInfo::Mode relocation_mode); | 397 void push(Label* label, RelocInfo::Mode relocation_mode); |
417 | 398 |
418 void pop(Register dst); | 399 void pop(Register dst); |
419 void pop(const Operand& dst); | 400 void pop(const Operand& dst); |
420 | 401 |
421 void enter(const Immediate& size); | 402 void enter(const Immediate& size); |
422 void leave(); | 403 void leave(); |
423 | 404 |
424 // Moves | 405 // Moves |
425 void mov_b(Register dst, const Operand& src); | 406 void movb(Register dst, const Operand& src); |
426 void mov_b(const Operand& dst, int8_t imm8); | 407 void movb(const Operand& dst, int8_t imm8); |
427 void mov_b(const Operand& dst, Register src); | 408 void movb(const Operand& dst, Register src); |
428 | 409 |
429 void mov_w(Register dst, const Operand& src); | 410 void movq(Register dst, int32_t imm32); |
430 void mov_w(const Operand& dst, Register src); | 411 void movq(Register dst, Immediate x); |
| 412 void movq(Register dst, const Operand& src); |
| 413 void movq(Register dst, Register src); |
| 414 void movq(const Operand& dst, const Immediate& x); |
| 415 void movq(const Operand& dst, Register src); |
431 | 416 |
432 void mov(Register dst, int32_t imm32); | 417 // New x64 instructions to load a 64-bit immediate into a register. |
433 void mov(Register dst, const Immediate& x); | 418 // All 64-bit immediates must have a relocation mode. |
434 void mov(Register dst, Handle<Object> handle); | 419 void movq(Register dst, void* ptr, RelocInfo::Mode rmode); |
435 void mov(Register dst, const Operand& src); | 420 void movq(Register dst, int64_t value, RelocInfo::Mode rmode); |
436 void mov(Register dst, Register src); | 421 void movq(Register dst, const char* s, RelocInfo::Mode rmode); |
437 void mov(const Operand& dst, const Immediate& x); | 422 void movq(Register dst, const ExternalReference& ext, RelocInfo::Mode rmode); |
438 void mov(const Operand& dst, Handle<Object> handle); | 423 void movq(Register dst, Handle<Object> handle, RelocInfo::Mode rmode); |
439 void mov(const Operand& dst, Register src); | 424 |
| 425 // New x64 instruction to load from an immediate 64-bit pointer into RAX. |
| 426 void load_rax(void* ptr, RelocInfo::Mode rmode); |
440 | 427 |
441 void movsx_b(Register dst, const Operand& src); | 428 void movsx_b(Register dst, const Operand& src); |
442 | 429 |
443 void movsx_w(Register dst, const Operand& src); | 430 void movsx_w(Register dst, const Operand& src); |
444 | 431 |
445 void movzx_b(Register dst, const Operand& src); | 432 void movzx_b(Register dst, const Operand& src); |
446 | 433 |
447 void movzx_w(Register dst, const Operand& src); | 434 void movzx_w(Register dst, const Operand& src); |
448 | 435 |
449 // Conditional moves | 436 // Conditional moves |
450 void cmov(Condition cc, Register dst, int32_t imm32); | 437 void cmov(Condition cc, Register dst, int32_t imm32); |
451 void cmov(Condition cc, Register dst, Handle<Object> handle); | 438 void cmov(Condition cc, Register dst, Handle<Object> handle); |
452 void cmov(Condition cc, Register dst, const Operand& src); | 439 void cmov(Condition cc, Register dst, const Operand& src); |
453 | 440 |
454 // Exchange two registers | 441 // Exchange two registers |
455 void xchg(Register dst, Register src); | 442 void xchg(Register dst, Register src); |
456 | 443 |
457 // Arithmetics | 444 // Arithmetics |
458 void adc(Register dst, int32_t imm32); | 445 void add(Register dst, Register src) { |
459 void adc(Register dst, const Operand& src); | 446 arithmetic_op(0x03, dst, src); |
| 447 } |
460 | 448 |
461 void add(Register dst, Register src); | 449 void add(Register dst, const Operand& src) { |
462 void add(Register dst, const Operand& src); | 450 arithmetic_op(0x03, dst, src); |
463 void add(const Operand& dst, const Immediate& x); | 451 } |
| 452 |
| 453 void add(const Operand& dst, Register src) { |
| 454 arithmetic_op(0x01, src, dst); |
| 455 } |
| 456 |
| 457 void add(Register dst, Immediate src) { |
| 458 immediate_arithmetic_op(0x0, dst, src); |
| 459 } |
| 460 |
| 461 void add(const Operand& dst, Immediate src) { |
| 462 immediate_arithmetic_op(0x0, dst, src); |
| 463 } |
| 464 |
| 465 void cmp(Register dst, Register src) { |
| 466 arithmetic_op(0x3B, dst, src); |
| 467 } |
| 468 |
| 469 void cmp(Register dst, const Operand& src) { |
| 470 arithmetic_op(0x3B, dst, src); |
| 471 } |
| 472 |
| 473 void cmp(const Operand& dst, Register src) { |
| 474 arithmetic_op(0x39, src, dst); |
| 475 } |
| 476 |
| 477 void cmp(Register dst, Immediate src) { |
| 478 immediate_arithmetic_op(0x7, dst, src); |
| 479 } |
| 480 |
| 481 void cmp(const Operand& dst, Immediate src) { |
| 482 immediate_arithmetic_op(0x7, dst, src); |
| 483 } |
| 484 |
464 | 485 |
465 void and_(Register dst, int32_t imm32); | 486 void and_(Register dst, int32_t imm32); |
466 void and_(Register dst, const Operand& src); | 487 void and_(Register dst, const Operand& src); |
467 void and_(const Operand& src, Register dst); | 488 void and_(const Operand& src, Register dst); |
468 void and_(const Operand& dst, const Immediate& x); | 489 void and_(const Operand& dst, const Immediate& x); |
469 | 490 |
470 void cmpb(const Operand& op, int8_t imm8); | 491 void cmpb(const Operand& op, int8_t imm8); |
471 void cmpb_al(const Operand& op); | 492 void cmpb_al(const Operand& op); |
472 void cmpw_ax(const Operand& op); | 493 void cmpw_ax(const Operand& op); |
473 void cmpw(const Operand& op, Immediate imm16); | 494 void cmpw(const Operand& op, Immediate imm16); |
474 void cmp(Register reg, int32_t imm32); | |
475 void cmp(Register reg, Handle<Object> handle); | |
476 void cmp(Register reg, const Operand& op); | |
477 void cmp(const Operand& op, const Immediate& imm); | |
478 | 495 |
479 void dec_b(Register dst); | 496 void dec_b(Register dst); |
480 | 497 |
481 void dec(Register dst); | 498 void dec(Register dst); |
482 void dec(const Operand& dst); | 499 void dec(const Operand& dst); |
483 | 500 |
484 void cdq(); | 501 void cdq(); |
485 | 502 |
486 void idiv(Register src); | 503 void idiv(Register src); |
487 | 504 |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
709 byte byte_at(int pos) { return buffer_[pos]; } | 726 byte byte_at(int pos) { return buffer_[pos]; } |
710 uint32_t long_at(int pos) { | 727 uint32_t long_at(int pos) { |
711 return *reinterpret_cast<uint32_t*>(addr_at(pos)); | 728 return *reinterpret_cast<uint32_t*>(addr_at(pos)); |
712 } | 729 } |
713 void long_at_put(int pos, uint32_t x) { | 730 void long_at_put(int pos, uint32_t x) { |
714 *reinterpret_cast<uint32_t*>(addr_at(pos)) = x; | 731 *reinterpret_cast<uint32_t*>(addr_at(pos)) = x; |
715 } | 732 } |
716 | 733 |
717 // code emission | 734 // code emission |
718 void GrowBuffer(); | 735 void GrowBuffer(); |
719 inline void emit(uint32_t x); | 736 inline void emitl(uint32_t x); |
720 inline void emit(Handle<Object> handle); | 737 inline void emit(Handle<Object> handle); |
721 inline void emit(uint32_t x, RelocInfo::Mode rmode); | 738 inline void emitq(uint64_t x, RelocInfo::Mode rmode); |
722 inline void emit(const Immediate& x); | 739 void emit(Immediate x) { emitl(x.value_); } |
723 inline void emit_w(const Immediate& x); | |
724 | 740 |
725 // Emits a REX prefix that encodes a 64-bit operand size and | 741 // Emits a REX prefix that encodes a 64-bit operand size and |
726 // the top bit of both register codes. | 742 // the top bit of both register codes. |
| 743 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. |
| 744 // REX.W is set. |
727 inline void emit_rex_64(Register reg, Register rm_reg); | 745 inline void emit_rex_64(Register reg, Register rm_reg); |
728 | 746 |
729 // Emits a REX prefix that encodes a 64-bit operand size and | 747 // Emits a REX prefix that encodes a 64-bit operand size and |
730 // the top bit of the destination, index, and base register codes. | 748 // the top bit of the destination, index, and base register codes. |
| 749 // The high bit of reg is used for REX.R, the high bit of op's base |
| 750 // register is used for REX.B, and the high bit of op's index register |
| 751 // is used for REX.X. REX.W is set. |
731 inline void emit_rex_64(Register reg, const Operand& op); | 752 inline void emit_rex_64(Register reg, const Operand& op); |
732 | 753 |
733 // Emit the code-object-relative offset of the label's position | 754 // Emit the code-object-relative offset of the label's position |
734 inline void emit_code_relative_offset(Label* label); | 755 inline void emit_code_relative_offset(Label* label); |
735 | 756 |
736 // instruction generation | 757 // instruction generation |
737 void emit_arith_b(int op1, int op2, Register dst, int imm8); | 758 void emit_arith_b(int op1, int op2, Register dst, int imm8); |
738 | 759 |
739 // Emit a basic arithmetic instruction (i.e. first byte of the family is 0x81) | 760 // Emit a basic arithmetic instruction (i.e. first byte of the family is 0x81) |
740 // with a given destination expression and an immediate operand. It attempts | 761 // with a given destination expression and an immediate operand. It attempts |
741 // to use the shortest encoding possible. | 762 // to use the shortest encoding possible. |
742 // sel specifies the /n in the modrm byte (see the Intel PRM). | 763 // sel specifies the /n in the modrm byte (see the Intel PRM). |
| 764 void arithmetic_op(byte opcode, Register dst, Register src); |
| 765 void arithmetic_op(byte opcode, Register reg, const Operand& op); |
| 766 void immediate_arithmetic_op(byte subcode, Register dst, Immediate src); |
| 767 void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src); |
| 768 |
743 void emit_arith(int sel, Operand dst, const Immediate& x); | 769 void emit_arith(int sel, Operand dst, const Immediate& x); |
744 | 770 |
745 void emit_operand(Register reg, const Operand& adr); | 771 void emit_operand(Register reg, const Operand& adr); |
746 | 772 |
747 void emit_farith(int b1, int b2, int i); | 773 void emit_farith(int b1, int b2, int i); |
748 | 774 |
749 // labels | 775 // labels |
750 void print(Label* L); | 776 void print(Label* L); |
751 void bind_to(Label* L, int pos); | 777 void bind_to(Label* L, int pos); |
752 void link_to(Label* L, Label* appendix); | 778 void link_to(Label* L, Label* appendix); |
753 | 779 |
754 // record reloc info for current pc_ | 780 // record reloc info for current pc_ |
755 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); | 781 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0) { |
| 782 UNIMPLEMENTED(); |
| 783 } |
756 | 784 |
757 friend class CodePatcher; | 785 friend class CodePatcher; |
758 friend class EnsureSpace; | 786 friend class EnsureSpace; |
759 | 787 |
760 // Code buffer: | 788 // Code buffer: |
761 // The buffer into which code and relocation info are generated. | 789 // The buffer into which code and relocation info are generated. |
762 byte* buffer_; | 790 byte* buffer_; |
763 int buffer_size_; | 791 int buffer_size_; |
764 // True if the assembler owns the buffer, false if buffer is external. | 792 // True if the assembler owns the buffer, false if buffer is external. |
765 bool own_buffer_; | 793 bool own_buffer_; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
804 private: | 832 private: |
805 Assembler* assembler_; | 833 Assembler* assembler_; |
806 #ifdef DEBUG | 834 #ifdef DEBUG |
807 int space_before_; | 835 int space_before_; |
808 #endif | 836 #endif |
809 }; | 837 }; |
810 | 838 |
811 } } // namespace v8::internal | 839 } } // namespace v8::internal |
812 | 840 |
813 #endif // V8_X64_ASSEMBLER_X64_H_ | 841 #endif // V8_X64_ASSEMBLER_X64_H_ |
OLD | NEW |