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 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 ScaleFactor scale, | 263 ScaleFactor scale, |
264 int32_t disp); | 264 int32_t disp); |
265 | 265 |
266 private: | 266 private: |
267 byte rex_; | 267 byte rex_; |
268 byte buf_[10]; | 268 byte buf_[10]; |
269 // The number of bytes in buf_. | 269 // The number of bytes in buf_. |
270 unsigned int len_; | 270 unsigned int len_; |
271 RelocInfo::Mode rmode_; | 271 RelocInfo::Mode rmode_; |
272 | 272 |
273 // Set the ModRM byte without an encoded 'reg' register. The | 273 // Set the ModR/M byte without an encoded 'reg' register. The |
274 // register is encoded later as part of the emit_operand operation. | 274 // register is encoded later as part of the emit_operand operation. |
275 // set_modrm can be called before or after set_sib and set_disp*. | 275 // set_modrm can be called before or after set_sib and set_disp*. |
276 inline void set_modrm(int mod, Register rm); | 276 inline void set_modrm(int mod, Register rm); |
277 | 277 |
278 // Set the SIB byte if one is needed. Sets the length to 2 rather than 1. | 278 // Set the SIB byte if one is needed. Sets the length to 2 rather than 1. |
279 inline void set_sib(ScaleFactor scale, Register index, Register base); | 279 inline void set_sib(ScaleFactor scale, Register index, Register base); |
280 | 280 |
281 // Adds operand displacement fields (offsets added to the memory address). | 281 // Adds operand displacement fields (offsets added to the memory address). |
282 // Needs to be called after set_sib, not before it. | 282 // Needs to be called after set_sib, not before it. |
283 inline void set_disp8(int disp); | 283 inline void set_disp8(int disp); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 void push(Label* label, RelocInfo::Mode relocation_mode); | 410 void push(Label* label, RelocInfo::Mode relocation_mode); |
411 | 411 |
412 void pop(Register dst); | 412 void pop(Register dst); |
413 void pop(const Operand& dst); | 413 void pop(const Operand& dst); |
414 | 414 |
415 void enter(Immediate size); | 415 void enter(Immediate size); |
416 void leave(); | 416 void leave(); |
417 | 417 |
418 // Moves | 418 // Moves |
419 void movb(Register dst, const Operand& src); | 419 void movb(Register dst, const Operand& src); |
420 void movb(const Operand& dst, int8_t imm8); | 420 void movb(Register dst, Immediate imm); |
421 void movb(const Operand& dst, Register src); | 421 void movb(const Operand& dst, Register src); |
422 | 422 |
423 void movl(Register dst, Register src); | 423 void movl(Register dst, Register src); |
424 void movl(Register dst, const Operand& src); | 424 void movl(Register dst, const Operand& src); |
425 void movl(const Operand& dst, Register src); | 425 void movl(const Operand& dst, Register src); |
426 // Load a 32-bit immediate value, zero-extended to 64 bits. | 426 // Load a 32-bit immediate value, zero-extended to 64 bits. |
427 void movl(Register dst, Immediate imm32); | 427 void movl(Register dst, Immediate imm32); |
428 | 428 |
429 void movq(Register dst, int32_t imm32); | 429 void movq(Register dst, int32_t imm32); |
430 void movq(Register dst, const Operand& src); | 430 void movq(Register dst, const Operand& src); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 void cmpw(const Operand& op, Immediate imm16); | 531 void cmpw(const Operand& op, Immediate imm16); |
532 | 532 |
533 void dec_b(Register dst); | 533 void dec_b(Register dst); |
534 | 534 |
535 void dec(Register dst); | 535 void dec(Register dst); |
536 void dec(const Operand& dst); | 536 void dec(const Operand& dst); |
537 | 537 |
538 // Sign-extends rax into rdx:rax. | 538 // Sign-extends rax into rdx:rax. |
539 void cqo(); | 539 void cqo(); |
540 | 540 |
| 541 // Divide rdx:rax by src. Quotient in rax, remainder in rdx. |
541 void idiv(Register src); | 542 void idiv(Register src); |
542 | 543 |
| 544 void imul(Register dst, Register src); |
543 void imul(Register dst, const Operand& src); | 545 void imul(Register dst, const Operand& src); |
544 void imul(Register dst, Register src, int32_t imm32); | 546 // Performs the operation dst = src * imm. |
| 547 void imul(Register dst, Register src, Immediate imm); |
545 | 548 |
546 void inc(Register dst); | 549 void inc(Register dst); |
547 void inc(const Operand& dst); | 550 void inc(const Operand& dst); |
548 | 551 |
549 void lea(Register dst, const Operand& src); | 552 void lea(Register dst, const Operand& src); |
550 | 553 |
| 554 // Multiply rax by src, put the result in rdx:rax. |
551 void mul(Register src); | 555 void mul(Register src); |
552 | 556 |
553 void neg(Register dst); | 557 void neg(Register dst); |
554 void neg(const Operand& dst); | 558 void neg(const Operand& dst); |
555 | 559 |
556 void not_(Register dst); | 560 void not_(Register dst); |
557 void not_(const Operand& dst); | 561 void not_(const Operand& dst); |
558 | 562 |
559 void or_(Register dst, Register src) { | 563 void or_(Register dst, Register src) { |
560 arithmetic_op(0x0B, dst, src); | 564 arithmetic_op(0x0B, dst, src); |
(...skipping 11 matching lines...) Expand all Loading... |
572 immediate_arithmetic_op(0x1, dst, src); | 576 immediate_arithmetic_op(0x1, dst, src); |
573 } | 577 } |
574 | 578 |
575 void or_(const Operand& dst, Immediate src) { | 579 void or_(const Operand& dst, Immediate src) { |
576 immediate_arithmetic_op(0x1, dst, src); | 580 immediate_arithmetic_op(0x1, dst, src); |
577 } | 581 } |
578 | 582 |
579 | 583 |
580 void rcl(Register dst, uint8_t imm8); | 584 void rcl(Register dst, uint8_t imm8); |
581 | 585 |
582 void sbb(Register dst, const Operand& src); | 586 // Shifts dst:src left by cl bits, affecting only dst. |
| 587 void shld(Register dst, Register src); |
583 | 588 |
584 void shld(Register dst, const Operand& src); | 589 // Shifts src:dst right by cl bits, affecting only dst. |
585 | 590 void shrd(Register dst, Register src); |
586 void shrd(Register dst, const Operand& src); | |
587 | 591 |
588 // Shifts dst right, duplicating sign bit, by shift_amount bits. | 592 // Shifts dst right, duplicating sign bit, by shift_amount bits. |
589 // Shifting by 1 is handled efficiently. | 593 // Shifting by 1 is handled efficiently. |
590 void sar(Register dst, Immediate shift_amount) { | 594 void sar(Register dst, Immediate shift_amount) { |
591 shift(dst, shift_amount, 0x7); | 595 shift(dst, shift_amount, 0x7); |
592 } | 596 } |
593 | 597 |
594 // Shifts dst right, duplicating sign bit, by cl % 64 bits. | 598 // Shifts dst right, duplicating sign bit, by cl % 64 bits. |
595 void sar(Register dst) { | 599 void sar(Register dst) { |
596 shift(dst, 0x7); | 600 shift(dst, 0x7); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 } | 633 } |
630 | 634 |
631 void sub(const Operand& dst, Immediate src) { | 635 void sub(const Operand& dst, Immediate src) { |
632 immediate_arithmetic_op(0x5, dst, src); | 636 immediate_arithmetic_op(0x5, dst, src); |
633 } | 637 } |
634 | 638 |
635 void testb(Register reg, Immediate mask); | 639 void testb(Register reg, Immediate mask); |
636 void testb(const Operand& op, Immediate mask); | 640 void testb(const Operand& op, Immediate mask); |
637 void testl(Register reg, Immediate mask); | 641 void testl(Register reg, Immediate mask); |
638 void testl(const Operand& op, Immediate mask); | 642 void testl(const Operand& op, Immediate mask); |
| 643 void testq(const Operand& op, Register reg); |
| 644 void testq(Register dst, Register src); |
639 | 645 |
640 void xor_(Register dst, Register src) { | 646 void xor_(Register dst, Register src) { |
641 arithmetic_op(0x33, dst, src); | 647 arithmetic_op(0x33, dst, src); |
642 } | 648 } |
643 | 649 |
644 void xor_(Register dst, const Operand& src) { | 650 void xor_(Register dst, const Operand& src) { |
645 arithmetic_op(0x33, dst, src); | 651 arithmetic_op(0x33, dst, src); |
646 } | 652 } |
647 | 653 |
648 void xor_(const Operand& dst, Register src) { | 654 void xor_(const Operand& dst, Register src) { |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
891 // register is used for REX.B, and the high bit of op's index register | 897 // register is used for REX.B, and the high bit of op's index register |
892 // is used for REX.X. REX.W is cleared. | 898 // is used for REX.X. REX.W is cleared. |
893 inline void emit_rex_32(Register reg, const Operand& op); | 899 inline void emit_rex_32(Register reg, const Operand& op); |
894 | 900 |
895 // High bit of rm_reg goes to REX.B. | 901 // High bit of rm_reg goes to REX.B. |
896 // REX.W, REX.R and REX.X are clear. | 902 // REX.W, REX.R and REX.X are clear. |
897 inline void emit_rex_32(Register rm_reg); | 903 inline void emit_rex_32(Register rm_reg); |
898 | 904 |
899 // High bit of base goes to REX.B and high bit of index to REX.X. | 905 // High bit of base goes to REX.B and high bit of index to REX.X. |
900 // REX.W and REX.R are clear. | 906 // REX.W and REX.R are clear. |
901 inline void emit_rex_32(const Operand &); | 907 inline void emit_rex_32(const Operand& op); |
902 | 908 |
903 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. | 909 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. |
904 // REX.W is cleared. If no REX bits are set, no byte is emitted. | 910 // REX.W is cleared. If no REX bits are set, no byte is emitted. |
905 inline void emit_optional_rex_32(Register reg, Register rm_reg); | 911 inline void emit_optional_rex_32(Register reg, Register rm_reg); |
906 | 912 |
907 // The high bit of reg is used for REX.R, the high bit of op's base | 913 // The high bit of reg is used for REX.R, the high bit of op's base |
908 // register is used for REX.B, and the high bit of op's index register | 914 // register is used for REX.B, and the high bit of op's index register |
909 // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing | 915 // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing |
910 // is emitted. | 916 // is emitted. |
911 inline void emit_optional_rex_32(Register reg, const Operand& op); | 917 inline void emit_optional_rex_32(Register reg, const Operand& op); |
912 | 918 |
913 // Optionally do as emit_rex_32(Register) if the register number has | 919 // Optionally do as emit_rex_32(Register) if the register number has |
914 // the high bit set. | 920 // the high bit set. |
915 inline void emit_optional_rex_32(Register rm_reg); | 921 inline void emit_optional_rex_32(Register rm_reg); |
916 | 922 |
917 // Optionally do as emit_rex_32(const Operand&) if the operand register | 923 // Optionally do as emit_rex_32(const Operand&) if the operand register |
918 // numbers have a high bit set. | 924 // numbers have a high bit set. |
919 inline void emit_optional_rex_32(const Operand& op); | 925 inline void emit_optional_rex_32(const Operand& op); |
920 | 926 |
921 | 927 |
922 // Emit the Mod/RM byte, and optionally the SIB byte and | 928 // Emit the ModR/M byte, and optionally the SIB byte and |
923 // 1- or 4-byte offset for a memory operand. Also encodes | 929 // 1- or 4-byte offset for a memory operand. Also encodes |
924 // the second operand of the operation, a register or operation | 930 // the second operand of the operation, a register or operation |
925 // subcode, into the Mod/RM byte. | 931 // subcode, into the reg field of the ModR/M byte. |
926 void emit_operand(Register reg, const Operand& adr) { | 932 void emit_operand(Register reg, const Operand& adr) { |
927 emit_operand(reg.code() & 0x07, adr); | 933 emit_operand(reg.code() & 0x07, adr); |
928 } | 934 } |
929 | 935 |
930 // Emit the Mod/RM byte, and optionally the SIB byte and | 936 // Emit the ModR/M byte, and optionally the SIB byte and |
931 // 1- or 4-byte offset for a memory operand. Also used to encode | 937 // 1- or 4-byte offset for a memory operand. Also used to encode |
932 // a three-byte opcode extension into the Mod/RM byte. | 938 // a three-bit opcode extension into the ModR/M byte. |
933 void emit_operand(int rm, const Operand& adr); | 939 void emit_operand(int rm, const Operand& adr); |
934 | 940 |
| 941 // Emit a ModR/M byte with registers coded in the reg and rm_reg fields. |
| 942 void emit_modrm(Register reg, Register rm_reg) { |
| 943 emit(0xC0 | (reg.code() & 0x7) << 3 | (rm_reg.code() & 0x7)); |
| 944 } |
| 945 |
| 946 // Emit a ModR/M byte with an operation subcode in the reg field and |
| 947 // a register in the rm_reg field. |
| 948 void emit_modrm(int code, Register rm_reg) { |
| 949 ASSERT((code & ~0x7) == 0); |
| 950 emit(0xC0 | (code & 0x7) << 3 | (rm_reg.code() & 0x7)); |
| 951 } |
| 952 |
935 // Emit the code-object-relative offset of the label's position | 953 // Emit the code-object-relative offset of the label's position |
936 inline void emit_code_relative_offset(Label* label); | 954 inline void emit_code_relative_offset(Label* label); |
937 | 955 |
938 // Emit machine code for one of the operations ADD, ADC, SUB, SBC, | 956 // Emit machine code for one of the operations ADD, ADC, SUB, SBC, |
939 // AND, OR, XOR, or CMP. The encodings of these operations are all | 957 // AND, OR, XOR, or CMP. The encodings of these operations are all |
940 // similar, differing just in the opcode or in the reg field of the | 958 // similar, differing just in the opcode or in the reg field of the |
941 // Mod/RM byte. | 959 // ModR/M byte. |
942 void arithmetic_op(byte opcode, Register dst, Register src); | 960 void arithmetic_op(byte opcode, Register dst, Register src); |
943 void arithmetic_op(byte opcode, Register reg, const Operand& op); | 961 void arithmetic_op(byte opcode, Register reg, const Operand& op); |
944 void immediate_arithmetic_op(byte subcode, Register dst, Immediate src); | 962 void immediate_arithmetic_op(byte subcode, Register dst, Immediate src); |
945 void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src); | 963 void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src); |
946 // Emit machine code for a shift operation. | 964 // Emit machine code for a shift operation. |
947 void shift(Register dst, Immediate shift_amount, int subcode); | 965 void shift(Register dst, Immediate shift_amount, int subcode); |
948 // Shift dst by cl % 64 bits. | 966 // Shift dst by cl % 64 bits. |
949 void shift(Register dst, int subcode); | 967 void shift(Register dst, int subcode); |
950 | 968 |
951 void emit_farith(int b1, int b2, int i); | 969 void emit_farith(int b1, int b2, int i); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1008 private: | 1026 private: |
1009 Assembler* assembler_; | 1027 Assembler* assembler_; |
1010 #ifdef DEBUG | 1028 #ifdef DEBUG |
1011 int space_before_; | 1029 int space_before_; |
1012 #endif | 1030 #endif |
1013 }; | 1031 }; |
1014 | 1032 |
1015 } } // namespace v8::internal | 1033 } } // namespace v8::internal |
1016 | 1034 |
1017 #endif // V8_X64_ASSEMBLER_X64_H_ | 1035 #endif // V8_X64_ASSEMBLER_X64_H_ |
OLD | NEW |