| 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 // The non-allocatable registers are: | 91 // The non-allocatable registers are: |
| 92 // rsp - stack pointer | 92 // rsp - stack pointer |
| 93 // rbp - frame pointer | 93 // rbp - frame pointer |
| 94 // rsi - context register | 94 // rsi - context register |
| 95 // r10 - fixed scratch register | 95 // r10 - fixed scratch register |
| 96 // r13 - root register | 96 // r13 - root register |
| 97 // r15 - smi constant register | 97 // r15 - smi constant register |
| 98 static const int kNumRegisters = 16; | 98 static const int kNumRegisters = 16; |
| 99 static const int kNumAllocatableRegisters = 10; | 99 static const int kNumAllocatableRegisters = 10; |
| 100 | 100 |
| 101 static int ToAllocationIndex(Register reg) { |
| 102 return allocationIndexByRegisterCode[reg.code()]; |
| 103 } |
| 104 |
| 105 static Register FromAllocationIndex(int index) { |
| 106 ASSERT(index >= 0 && index < kNumAllocatableRegisters); |
| 107 Register result = { registerCodeByAllocationIndex[index] }; |
| 108 return result; |
| 109 } |
| 110 |
| 101 static const char* AllocationIndexToString(int index) { | 111 static const char* AllocationIndexToString(int index) { |
| 102 ASSERT(index >= 0 && index < kNumAllocatableRegisters); | 112 ASSERT(index >= 0 && index < kNumAllocatableRegisters); |
| 103 const char* const names[] = { | 113 const char* const names[] = { |
| 104 "rax", | 114 "rax", |
| 115 "rbx", |
| 116 "rdx", |
| 105 "rcx", | 117 "rcx", |
| 106 "rdx", | |
| 107 "rbx", | |
| 108 "rdi", | 118 "rdi", |
| 109 "r8", | 119 "r8", |
| 110 "r9", | 120 "r9", |
| 111 "r11", | 121 "r11", |
| 112 "r12", | 122 "r14", |
| 113 "r14" | 123 "r12" |
| 114 }; | 124 }; |
| 115 return names[index]; | 125 return names[index]; |
| 116 } | 126 } |
| 117 | 127 |
| 118 static Register toRegister(int code) { | 128 static Register toRegister(int code) { |
| 119 Register r = { code }; | 129 Register r = { code }; |
| 120 return r; | 130 return r; |
| 121 } | 131 } |
| 122 bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } | 132 bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } |
| 123 bool is(Register reg) const { return code_ == reg.code_; } | 133 bool is(Register reg) const { return code_ == reg.code_; } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 136 } | 146 } |
| 137 // Return the 3 low bits of the register code. Used when encoding registers | 147 // Return the 3 low bits of the register code. Used when encoding registers |
| 138 // in modR/M, SIB, and opcode bytes. | 148 // in modR/M, SIB, and opcode bytes. |
| 139 int low_bits() const { | 149 int low_bits() const { |
| 140 return code_ & 0x7; | 150 return code_ & 0x7; |
| 141 } | 151 } |
| 142 | 152 |
| 143 // Unfortunately we can't make this private in a struct when initializing | 153 // Unfortunately we can't make this private in a struct when initializing |
| 144 // by assignment. | 154 // by assignment. |
| 145 int code_; | 155 int code_; |
| 156 |
| 157 private: |
| 158 static const int registerCodeByAllocationIndex[kNumAllocatableRegisters]; |
| 159 static const int allocationIndexByRegisterCode[kNumRegisters]; |
| 146 }; | 160 }; |
| 147 | 161 |
| 148 const Register rax = { 0 }; | 162 const Register rax = { 0 }; |
| 149 const Register rcx = { 1 }; | 163 const Register rcx = { 1 }; |
| 150 const Register rdx = { 2 }; | 164 const Register rdx = { 2 }; |
| 151 const Register rbx = { 3 }; | 165 const Register rbx = { 3 }; |
| 152 const Register rsp = { 4 }; | 166 const Register rsp = { 4 }; |
| 153 const Register rbp = { 5 }; | 167 const Register rbp = { 5 }; |
| 154 const Register rsi = { 6 }; | 168 const Register rsi = { 6 }; |
| 155 const Register rdi = { 7 }; | 169 const Register rdi = { 7 }; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 166 | 180 |
| 167 struct XMMRegister { | 181 struct XMMRegister { |
| 168 static const int kNumRegisters = 16; | 182 static const int kNumRegisters = 16; |
| 169 static const int kNumAllocatableRegisters = 15; | 183 static const int kNumAllocatableRegisters = 15; |
| 170 | 184 |
| 171 static int ToAllocationIndex(XMMRegister reg) { | 185 static int ToAllocationIndex(XMMRegister reg) { |
| 172 ASSERT(reg.code() != 0); | 186 ASSERT(reg.code() != 0); |
| 173 return reg.code() - 1; | 187 return reg.code() - 1; |
| 174 } | 188 } |
| 175 | 189 |
| 190 static XMMRegister FromAllocationIndex(int index) { |
| 191 ASSERT(0 <= index && index < kNumAllocatableRegisters); |
| 192 XMMRegister result = { index + 1 }; |
| 193 return result; |
| 194 } |
| 195 |
| 176 static const char* AllocationIndexToString(int index) { | 196 static const char* AllocationIndexToString(int index) { |
| 177 ASSERT(index >= 0 && index < kNumAllocatableRegisters); | 197 ASSERT(index >= 0 && index < kNumAllocatableRegisters); |
| 178 const char* const names[] = { | 198 const char* const names[] = { |
| 179 "xmm1", | 199 "xmm1", |
| 180 "xmm2", | 200 "xmm2", |
| 181 "xmm3", | 201 "xmm3", |
| 182 "xmm4", | 202 "xmm4", |
| 183 "xmm5", | 203 "xmm5", |
| 184 "xmm6", | 204 "xmm6", |
| 185 "xmm7", | 205 "xmm7", |
| 186 "xmm8", | 206 "xmm8", |
| 187 "xmm9", | 207 "xmm9", |
| 188 "xmm10", | 208 "xmm10", |
| 189 "xmm11", | 209 "xmm11", |
| 190 "xmm12", | 210 "xmm12", |
| 191 "xmm13", | 211 "xmm13", |
| 192 "xmm14", | 212 "xmm14", |
| 193 "xmm15" | 213 "xmm15" |
| 194 }; | 214 }; |
| 195 return names[index]; | 215 return names[index]; |
| 196 } | 216 } |
| 197 | 217 |
| 198 static XMMRegister from_code(int code) { | 218 static XMMRegister from_code(int code) { |
| 199 ASSERT(code >= 0); | 219 ASSERT(code >= 0); |
| 200 ASSERT(code < kNumRegisters); | 220 ASSERT(code < kNumRegisters); |
| 201 XMMRegister r = { code }; | 221 XMMRegister r = { code }; |
| 202 return r; | 222 return r; |
| 203 } | 223 } |
| 204 bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } | 224 bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } |
| 225 bool is(XMMRegister reg) const { return code_ == reg.code_; } |
| 205 int code() const { | 226 int code() const { |
| 206 ASSERT(is_valid()); | 227 ASSERT(is_valid()); |
| 207 return code_; | 228 return code_; |
| 208 } | 229 } |
| 209 | 230 |
| 210 // Return the high bit of the register code as a 0 or 1. Used often | 231 // Return the high bit of the register code as a 0 or 1. Used often |
| 211 // when constructing the REX prefix byte. | 232 // when constructing the REX prefix byte. |
| 212 int high_bit() const { | 233 int high_bit() const { |
| 213 return code_ >> 3; | 234 return code_ >> 3; |
| 214 } | 235 } |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 // [index*scale + disp/r] | 390 // [index*scale + disp/r] |
| 370 Operand(Register index, | 391 Operand(Register index, |
| 371 ScaleFactor scale, | 392 ScaleFactor scale, |
| 372 int32_t disp); | 393 int32_t disp); |
| 373 | 394 |
| 374 // Offset from existing memory operand. | 395 // Offset from existing memory operand. |
| 375 // Offset is added to existing displacement as 32-bit signed values and | 396 // Offset is added to existing displacement as 32-bit signed values and |
| 376 // this must not overflow. | 397 // this must not overflow. |
| 377 Operand(const Operand& base, int32_t offset); | 398 Operand(const Operand& base, int32_t offset); |
| 378 | 399 |
| 400 // Checks whether either base or index register is the given register. |
| 401 // Does not check the "reg" part of the Operand. |
| 402 bool AddressUsesRegister(Register reg) const; |
| 403 |
| 379 private: | 404 private: |
| 380 byte rex_; | 405 byte rex_; |
| 381 byte buf_[6]; | 406 byte buf_[6]; |
| 382 // The number of bytes in buf_. | 407 // The number of bytes of buf_ in use. |
| 383 unsigned int len_; | 408 byte len_; |
| 384 | 409 |
| 385 // Set the ModR/M byte without an encoded 'reg' register. The | 410 // Set the ModR/M byte without an encoded 'reg' register. The |
| 386 // register is encoded later as part of the emit_operand operation. | 411 // register is encoded later as part of the emit_operand operation. |
| 387 // set_modrm can be called before or after set_sib and set_disp*. | 412 // set_modrm can be called before or after set_sib and set_disp*. |
| 388 inline void set_modrm(int mod, Register rm); | 413 inline void set_modrm(int mod, Register rm); |
| 389 | 414 |
| 390 // Set the SIB byte if one is needed. Sets the length to 2 rather than 1. | 415 // Set the SIB byte if one is needed. Sets the length to 2 rather than 1. |
| 391 inline void set_sib(ScaleFactor scale, Register index, Register base); | 416 inline void set_sib(ScaleFactor scale, Register index, Register base); |
| 392 | 417 |
| 393 // Adds operand displacement fields (offsets added to the memory address). | 418 // Adds operand displacement fields (offsets added to the memory address). |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 // Should equal Debug::kX64JSReturnSequenceLength - kCallTargetAddressOffset; | 552 // Should equal Debug::kX64JSReturnSequenceLength - kCallTargetAddressOffset; |
| 528 static const int kPatchReturnSequenceAddressOffset = 13 - 4; | 553 static const int kPatchReturnSequenceAddressOffset = 13 - 4; |
| 529 // Distance between start of patched debug break slot and where the | 554 // Distance between start of patched debug break slot and where the |
| 530 // 32-bit displacement of a near call would be, relative to the pushed | 555 // 32-bit displacement of a near call would be, relative to the pushed |
| 531 // return address. TODO: Use return sequence length instead. | 556 // return address. TODO: Use return sequence length instead. |
| 532 // Should equal Debug::kX64JSReturnSequenceLength - kCallTargetAddressOffset; | 557 // Should equal Debug::kX64JSReturnSequenceLength - kCallTargetAddressOffset; |
| 533 static const int kPatchDebugBreakSlotAddressOffset = 13 - 4; | 558 static const int kPatchDebugBreakSlotAddressOffset = 13 - 4; |
| 534 // TODO(X64): Rename this, removing the "Real", after changing the above. | 559 // TODO(X64): Rename this, removing the "Real", after changing the above. |
| 535 static const int kRealPatchReturnSequenceAddressOffset = 2; | 560 static const int kRealPatchReturnSequenceAddressOffset = 2; |
| 536 | 561 |
| 537 // The x64 JS return sequence is padded with int3 to make it large | 562 // Some x64 JS code is padded with int3 to make it large |
| 538 // enough to hold a call instruction when the debugger patches it. | 563 // enough to hold an instruction when the debugger patches it. |
| 564 static const int kJumpInstructionLength = 13; |
| 539 static const int kCallInstructionLength = 13; | 565 static const int kCallInstructionLength = 13; |
| 540 static const int kJSReturnSequenceLength = 13; | 566 static const int kJSReturnSequenceLength = 13; |
| 567 static const int kShortCallInstructionLength = 5; |
| 541 | 568 |
| 542 // The debug break slot must be able to contain a call instruction. | 569 // The debug break slot must be able to contain a call instruction. |
| 543 static const int kDebugBreakSlotLength = kCallInstructionLength; | 570 static const int kDebugBreakSlotLength = kCallInstructionLength; |
| 544 | 571 |
| 545 // One byte opcode for test eax,0xXXXXXXXX. | 572 // One byte opcode for test eax,0xXXXXXXXX. |
| 546 static const byte kTestEaxByte = 0xA9; | 573 static const byte kTestEaxByte = 0xA9; |
| 574 // One byte opcode for test al, 0xXX. |
| 575 static const byte kTestAlByte = 0xA8; |
| 576 // One byte opcode for nop. |
| 577 static const byte kNopByte = 0x90; |
| 578 |
| 579 // One byte prefix for a short conditional jump. |
| 580 static const byte kJccShortPrefix = 0x70; |
| 581 static const byte kJncShortOpcode = kJccShortPrefix | not_carry; |
| 582 static const byte kJcShortOpcode = kJccShortPrefix | carry; |
| 583 |
| 584 |
| 547 | 585 |
| 548 // --------------------------------------------------------------------------- | 586 // --------------------------------------------------------------------------- |
| 549 // Code generation | 587 // Code generation |
| 550 // | 588 // |
| 551 // Function names correspond one-to-one to x64 instruction mnemonics. | 589 // Function names correspond one-to-one to x64 instruction mnemonics. |
| 552 // Unless specified otherwise, instructions operate on 64-bit operands. | 590 // Unless specified otherwise, instructions operate on 64-bit operands. |
| 553 // | 591 // |
| 554 // If we need versions of an assembly instruction that operate on different | 592 // If we need versions of an assembly instruction that operate on different |
| 555 // width arguments, we add a single-letter suffix specifying the width. | 593 // width arguments, we add a single-letter suffix specifying the width. |
| 556 // This is done for the following instructions: mov, cmp, inc, dec, | 594 // This is done for the following instructions: mov, cmp, inc, dec, |
| 557 // add, sub, and test. | 595 // add, sub, and test. |
| 558 // There are no versions of these instructions without the suffix. | 596 // There are no versions of these instructions without the suffix. |
| 559 // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'. | 597 // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'. |
| 560 // - Instructions on 16-bit (word) operands/registers have a trailing 'w'. | 598 // - Instructions on 16-bit (word) operands/registers have a trailing 'w'. |
| 561 // - Instructions on 32-bit (doubleword) operands/registers use 'l'. | 599 // - Instructions on 32-bit (doubleword) operands/registers use 'l'. |
| 562 // - Instructions on 64-bit (quadword) operands/registers use 'q'. | 600 // - Instructions on 64-bit (quadword) operands/registers use 'q'. |
| 563 // | 601 // |
| 564 // Some mnemonics, such as "and", are the same as C++ keywords. | 602 // Some mnemonics, such as "and", are the same as C++ keywords. |
| 565 // Naming conflicts with C++ keywords are resolved by adding a trailing '_'. | 603 // Naming conflicts with C++ keywords are resolved by adding a trailing '_'. |
| 566 | 604 |
| 567 // Insert the smallest number of nop instructions | 605 // Insert the smallest number of nop instructions |
| 568 // possible to align the pc offset to a multiple | 606 // possible to align the pc offset to a multiple |
| 569 // of m. m must be a power of 2. | 607 // of m, where m must be a power of 2. |
| 570 void Align(int m); | 608 void Align(int m); |
| 571 // Aligns code to something that's optimal for a jump target for the platform. | 609 // Aligns code to something that's optimal for a jump target for the platform. |
| 572 void CodeTargetAlign(); | 610 void CodeTargetAlign(); |
| 573 | 611 |
| 574 // Stack | 612 // Stack |
| 575 void pushfq(); | 613 void pushfq(); |
| 576 void popfq(); | 614 void popfq(); |
| 577 | 615 |
| 578 void push(Immediate value); | 616 void push(Immediate value); |
| 617 // Push a 32 bit integer, and guarantee that it is actually pushed as a |
| 618 // 32 bit value, the normal push will optimize the 8 bit case. |
| 619 void push_imm32(int32_t imm32); |
| 579 void push(Register src); | 620 void push(Register src); |
| 580 void push(const Operand& src); | 621 void push(const Operand& src); |
| 581 | 622 |
| 582 void pop(Register dst); | 623 void pop(Register dst); |
| 583 void pop(const Operand& dst); | 624 void pop(const Operand& dst); |
| 584 | 625 |
| 585 void enter(Immediate size); | 626 void enter(Immediate size); |
| 586 void leave(); | 627 void leave(); |
| 587 | 628 |
| 588 // Moves | 629 // Moves |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 686 } | 727 } |
| 687 | 728 |
| 688 void addq(const Operand& dst, Immediate src) { | 729 void addq(const Operand& dst, Immediate src) { |
| 689 immediate_arithmetic_op(0x0, dst, src); | 730 immediate_arithmetic_op(0x0, dst, src); |
| 690 } | 731 } |
| 691 | 732 |
| 692 void sbbl(Register dst, Register src) { | 733 void sbbl(Register dst, Register src) { |
| 693 arithmetic_op_32(0x1b, dst, src); | 734 arithmetic_op_32(0x1b, dst, src); |
| 694 } | 735 } |
| 695 | 736 |
| 737 void sbbq(Register dst, Register src) { |
| 738 arithmetic_op(0x1b, dst, src); |
| 739 } |
| 740 |
| 696 void cmpb(Register dst, Immediate src) { | 741 void cmpb(Register dst, Immediate src) { |
| 697 immediate_arithmetic_op_8(0x7, dst, src); | 742 immediate_arithmetic_op_8(0x7, dst, src); |
| 698 } | 743 } |
| 699 | 744 |
| 700 void cmpb_al(Immediate src); | 745 void cmpb_al(Immediate src); |
| 701 | 746 |
| 702 void cmpb(Register dst, Register src) { | 747 void cmpb(Register dst, Register src) { |
| 703 arithmetic_op(0x3A, dst, src); | 748 arithmetic_op(0x3A, dst, src); |
| 704 } | 749 } |
| 705 | 750 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 796 } | 841 } |
| 797 | 842 |
| 798 void andl(Register dst, Immediate src) { | 843 void andl(Register dst, Immediate src) { |
| 799 immediate_arithmetic_op_32(0x4, dst, src); | 844 immediate_arithmetic_op_32(0x4, dst, src); |
| 800 } | 845 } |
| 801 | 846 |
| 802 void andl(Register dst, Register src) { | 847 void andl(Register dst, Register src) { |
| 803 arithmetic_op_32(0x23, dst, src); | 848 arithmetic_op_32(0x23, dst, src); |
| 804 } | 849 } |
| 805 | 850 |
| 851 void andl(Register dst, const Operand& src) { |
| 852 arithmetic_op_32(0x23, dst, src); |
| 853 } |
| 854 |
| 806 void andb(Register dst, Immediate src) { | 855 void andb(Register dst, Immediate src) { |
| 807 immediate_arithmetic_op_8(0x4, dst, src); | 856 immediate_arithmetic_op_8(0x4, dst, src); |
| 808 } | 857 } |
| 809 | 858 |
| 810 void decq(Register dst); | 859 void decq(Register dst); |
| 811 void decq(const Operand& dst); | 860 void decq(const Operand& dst); |
| 812 void decl(Register dst); | 861 void decl(Register dst); |
| 813 void decl(const Operand& dst); | 862 void decl(const Operand& dst); |
| 814 void decb(Register dst); | 863 void decb(Register dst); |
| 815 void decb(const Operand& dst); | 864 void decb(const Operand& dst); |
| 816 | 865 |
| 817 // Sign-extends rax into rdx:rax. | 866 // Sign-extends rax into rdx:rax. |
| 818 void cqo(); | 867 void cqo(); |
| 819 // Sign-extends eax into edx:eax. | 868 // Sign-extends eax into edx:eax. |
| 820 void cdq(); | 869 void cdq(); |
| 821 | 870 |
| 822 // Divide rdx:rax by src. Quotient in rax, remainder in rdx. | 871 // Divide rdx:rax by src. Quotient in rax, remainder in rdx. |
| 823 void idivq(Register src); | 872 void idivq(Register src); |
| 824 // Divide edx:eax by lower 32 bits of src. Quotient in eax, rem. in edx. | 873 // Divide edx:eax by lower 32 bits of src. Quotient in eax, rem. in edx. |
| 825 void idivl(Register src); | 874 void idivl(Register src); |
| 826 | 875 |
| 827 // Signed multiply instructions. | 876 // Signed multiply instructions. |
| 828 void imul(Register src); // rdx:rax = rax * src. | 877 void imul(Register src); // rdx:rax = rax * src. |
| 829 void imul(Register dst, Register src); // dst = dst * src. | 878 void imul(Register dst, Register src); // dst = dst * src. |
| 830 void imul(Register dst, const Operand& src); // dst = dst * src. | 879 void imul(Register dst, const Operand& src); // dst = dst * src. |
| 831 void imul(Register dst, Register src, Immediate imm); // dst = src * imm. | 880 void imul(Register dst, Register src, Immediate imm); // dst = src * imm. |
| 832 // Signed 32-bit multiply instructions. | 881 // Signed 32-bit multiply instructions. |
| 833 void imull(Register dst, Register src); // dst = dst * src. | 882 void imull(Register dst, Register src); // dst = dst * src. |
| 883 void imull(Register dst, const Operand& src); // dst = dst * src. |
| 834 void imull(Register dst, Register src, Immediate imm); // dst = src * imm. | 884 void imull(Register dst, Register src, Immediate imm); // dst = src * imm. |
| 835 | 885 |
| 836 void incq(Register dst); | 886 void incq(Register dst); |
| 837 void incq(const Operand& dst); | 887 void incq(const Operand& dst); |
| 838 void incl(Register dst); | 888 void incl(Register dst); |
| 839 void incl(const Operand& dst); | 889 void incl(const Operand& dst); |
| 840 | 890 |
| 841 void lea(Register dst, const Operand& src); | 891 void lea(Register dst, const Operand& src); |
| 842 void leal(Register dst, const Operand& src); | 892 void leal(Register dst, const Operand& src); |
| 843 | 893 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 857 } | 907 } |
| 858 | 908 |
| 859 void orl(Register dst, Register src) { | 909 void orl(Register dst, Register src) { |
| 860 arithmetic_op_32(0x0B, dst, src); | 910 arithmetic_op_32(0x0B, dst, src); |
| 861 } | 911 } |
| 862 | 912 |
| 863 void or_(Register dst, const Operand& src) { | 913 void or_(Register dst, const Operand& src) { |
| 864 arithmetic_op(0x0B, dst, src); | 914 arithmetic_op(0x0B, dst, src); |
| 865 } | 915 } |
| 866 | 916 |
| 917 void orl(Register dst, const Operand& src) { |
| 918 arithmetic_op_32(0x0B, dst, src); |
| 919 } |
| 920 |
| 867 void or_(const Operand& dst, Register src) { | 921 void or_(const Operand& dst, Register src) { |
| 868 arithmetic_op(0x09, src, dst); | 922 arithmetic_op(0x09, src, dst); |
| 869 } | 923 } |
| 870 | 924 |
| 871 void or_(Register dst, Immediate src) { | 925 void or_(Register dst, Immediate src) { |
| 872 immediate_arithmetic_op(0x1, dst, src); | 926 immediate_arithmetic_op(0x1, dst, src); |
| 873 } | 927 } |
| 874 | 928 |
| 875 void orl(Register dst, Immediate src) { | 929 void orl(Register dst, Immediate src) { |
| 876 immediate_arithmetic_op_32(0x1, dst, src); | 930 immediate_arithmetic_op_32(0x1, dst, src); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1020 arithmetic_op_32(0x33, dst, src); | 1074 arithmetic_op_32(0x33, dst, src); |
| 1021 } else { | 1075 } else { |
| 1022 arithmetic_op(0x33, dst, src); | 1076 arithmetic_op(0x33, dst, src); |
| 1023 } | 1077 } |
| 1024 } | 1078 } |
| 1025 | 1079 |
| 1026 void xorl(Register dst, Register src) { | 1080 void xorl(Register dst, Register src) { |
| 1027 arithmetic_op_32(0x33, dst, src); | 1081 arithmetic_op_32(0x33, dst, src); |
| 1028 } | 1082 } |
| 1029 | 1083 |
| 1084 void xorl(Register dst, const Operand& src) { |
| 1085 arithmetic_op_32(0x33, dst, src); |
| 1086 } |
| 1087 |
| 1088 void xorl(Register dst, Immediate src) { |
| 1089 immediate_arithmetic_op_32(0x6, dst, src); |
| 1090 } |
| 1091 |
| 1092 void xorl(const Operand& dst, Immediate src) { |
| 1093 immediate_arithmetic_op_32(0x6, dst, src); |
| 1094 } |
| 1095 |
| 1030 void xor_(Register dst, const Operand& src) { | 1096 void xor_(Register dst, const Operand& src) { |
| 1031 arithmetic_op(0x33, dst, src); | 1097 arithmetic_op(0x33, dst, src); |
| 1032 } | 1098 } |
| 1033 | 1099 |
| 1034 void xor_(const Operand& dst, Register src) { | 1100 void xor_(const Operand& dst, Register src) { |
| 1035 arithmetic_op(0x31, src, dst); | 1101 arithmetic_op(0x31, src, dst); |
| 1036 } | 1102 } |
| 1037 | 1103 |
| 1038 void xor_(Register dst, Immediate src) { | 1104 void xor_(Register dst, Immediate src) { |
| 1039 immediate_arithmetic_op(0x6, dst, src); | 1105 immediate_arithmetic_op(0x6, dst, src); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1074 // but it may be bound only once. | 1140 // but it may be bound only once. |
| 1075 | 1141 |
| 1076 void bind(Label* L); // binds an unbound label L to the current code position | 1142 void bind(Label* L); // binds an unbound label L to the current code position |
| 1077 void bind(NearLabel* L); | 1143 void bind(NearLabel* L); |
| 1078 | 1144 |
| 1079 // Calls | 1145 // Calls |
| 1080 // Call near relative 32-bit displacement, relative to next instruction. | 1146 // Call near relative 32-bit displacement, relative to next instruction. |
| 1081 void call(Label* L); | 1147 void call(Label* L); |
| 1082 void call(Handle<Code> target, RelocInfo::Mode rmode); | 1148 void call(Handle<Code> target, RelocInfo::Mode rmode); |
| 1083 | 1149 |
| 1150 // Calls directly to the given address using a relative offset. |
| 1151 // Should only ever be used in Code objects for calls within the |
| 1152 // same Code object. Should not be used when generating new code (use labels), |
| 1153 // but only when patching existing code. |
| 1154 void call(Address target); |
| 1155 |
| 1084 // Call near absolute indirect, address in register | 1156 // Call near absolute indirect, address in register |
| 1085 void call(Register adr); | 1157 void call(Register adr); |
| 1086 | 1158 |
| 1087 // Call near indirect | 1159 // Call near indirect |
| 1088 void call(const Operand& operand); | 1160 void call(const Operand& operand); |
| 1089 | 1161 |
| 1090 // Jumps | 1162 // Jumps |
| 1091 // Jump short or near relative. | 1163 // Jump short or near relative. |
| 1092 // Use a 32-bit signed displacement. | 1164 // Use a 32-bit signed displacement. |
| 1093 void jmp(Label* L); // unconditional jump to L | 1165 void jmp(Label* L); // unconditional jump to L |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1180 void movd(XMMRegister dst, Register src); | 1252 void movd(XMMRegister dst, Register src); |
| 1181 void movd(Register dst, XMMRegister src); | 1253 void movd(Register dst, XMMRegister src); |
| 1182 void movq(XMMRegister dst, Register src); | 1254 void movq(XMMRegister dst, Register src); |
| 1183 void movq(Register dst, XMMRegister src); | 1255 void movq(Register dst, XMMRegister src); |
| 1184 void extractps(Register dst, XMMRegister src, byte imm8); | 1256 void extractps(Register dst, XMMRegister src, byte imm8); |
| 1185 | 1257 |
| 1186 void movsd(const Operand& dst, XMMRegister src); | 1258 void movsd(const Operand& dst, XMMRegister src); |
| 1187 void movsd(XMMRegister dst, XMMRegister src); | 1259 void movsd(XMMRegister dst, XMMRegister src); |
| 1188 void movsd(XMMRegister dst, const Operand& src); | 1260 void movsd(XMMRegister dst, const Operand& src); |
| 1189 | 1261 |
| 1262 void movdqa(const Operand& dst, XMMRegister src); |
| 1263 void movdqa(XMMRegister dst, const Operand& src); |
| 1264 |
| 1190 void movss(XMMRegister dst, const Operand& src); | 1265 void movss(XMMRegister dst, const Operand& src); |
| 1191 void movss(const Operand& dst, XMMRegister src); | 1266 void movss(const Operand& dst, XMMRegister src); |
| 1192 | 1267 |
| 1193 void cvttss2si(Register dst, const Operand& src); | 1268 void cvttss2si(Register dst, const Operand& src); |
| 1269 void cvttss2si(Register dst, XMMRegister src); |
| 1194 void cvttsd2si(Register dst, const Operand& src); | 1270 void cvttsd2si(Register dst, const Operand& src); |
| 1271 void cvttsd2si(Register dst, XMMRegister src); |
| 1195 void cvttsd2siq(Register dst, XMMRegister src); | 1272 void cvttsd2siq(Register dst, XMMRegister src); |
| 1196 | 1273 |
| 1197 void cvtlsi2sd(XMMRegister dst, const Operand& src); | 1274 void cvtlsi2sd(XMMRegister dst, const Operand& src); |
| 1198 void cvtlsi2sd(XMMRegister dst, Register src); | 1275 void cvtlsi2sd(XMMRegister dst, Register src); |
| 1199 void cvtqsi2sd(XMMRegister dst, const Operand& src); | 1276 void cvtqsi2sd(XMMRegister dst, const Operand& src); |
| 1200 void cvtqsi2sd(XMMRegister dst, Register src); | 1277 void cvtqsi2sd(XMMRegister dst, Register src); |
| 1201 | 1278 |
| 1202 void cvtlsi2ss(XMMRegister dst, Register src); | 1279 void cvtlsi2ss(XMMRegister dst, Register src); |
| 1203 | 1280 |
| 1204 void cvtss2sd(XMMRegister dst, XMMRegister src); | 1281 void cvtss2sd(XMMRegister dst, XMMRegister src); |
| 1205 void cvtss2sd(XMMRegister dst, const Operand& src); | 1282 void cvtss2sd(XMMRegister dst, const Operand& src); |
| 1206 void cvtsd2ss(XMMRegister dst, XMMRegister src); | 1283 void cvtsd2ss(XMMRegister dst, XMMRegister src); |
| 1207 | 1284 |
| 1208 void cvtsd2si(Register dst, XMMRegister src); | 1285 void cvtsd2si(Register dst, XMMRegister src); |
| 1209 void cvtsd2siq(Register dst, XMMRegister src); | 1286 void cvtsd2siq(Register dst, XMMRegister src); |
| 1210 | 1287 |
| 1211 void addsd(XMMRegister dst, XMMRegister src); | 1288 void addsd(XMMRegister dst, XMMRegister src); |
| 1212 void subsd(XMMRegister dst, XMMRegister src); | 1289 void subsd(XMMRegister dst, XMMRegister src); |
| 1213 void mulsd(XMMRegister dst, XMMRegister src); | 1290 void mulsd(XMMRegister dst, XMMRegister src); |
| 1214 void divsd(XMMRegister dst, XMMRegister src); | 1291 void divsd(XMMRegister dst, XMMRegister src); |
| 1215 | 1292 |
| 1216 void xorpd(XMMRegister dst, XMMRegister src); | 1293 void xorpd(XMMRegister dst, XMMRegister src); |
| 1217 void sqrtsd(XMMRegister dst, XMMRegister src); | 1294 void sqrtsd(XMMRegister dst, XMMRegister src); |
| 1218 | 1295 |
| 1219 void ucomisd(XMMRegister dst, XMMRegister src); | 1296 void ucomisd(XMMRegister dst, XMMRegister src); |
| 1220 void ucomisd(XMMRegister dst, const Operand& src); | 1297 void ucomisd(XMMRegister dst, const Operand& src); |
| 1221 | 1298 |
| 1299 void movmskpd(Register dst, XMMRegister src); |
| 1300 |
| 1222 // The first argument is the reg field, the second argument is the r/m field. | 1301 // The first argument is the reg field, the second argument is the r/m field. |
| 1223 void emit_sse_operand(XMMRegister dst, XMMRegister src); | 1302 void emit_sse_operand(XMMRegister dst, XMMRegister src); |
| 1224 void emit_sse_operand(XMMRegister reg, const Operand& adr); | 1303 void emit_sse_operand(XMMRegister reg, const Operand& adr); |
| 1225 void emit_sse_operand(XMMRegister dst, Register src); | 1304 void emit_sse_operand(XMMRegister dst, Register src); |
| 1226 void emit_sse_operand(Register dst, XMMRegister src); | 1305 void emit_sse_operand(Register dst, XMMRegister src); |
| 1227 | 1306 |
| 1228 // Use either movsd or movlpd. | |
| 1229 // void movdbl(XMMRegister dst, const Operand& src); | |
| 1230 // void movdbl(const Operand& dst, XMMRegister src); | |
| 1231 | |
| 1232 // Debugging | 1307 // Debugging |
| 1233 void Print(); | 1308 void Print(); |
| 1234 | 1309 |
| 1235 // Check the code size generated from label to here. | 1310 // Check the code size generated from label to here. |
| 1236 int SizeOfCodeGeneratedSince(Label* l) { return pc_offset() - l->pos(); } | 1311 int SizeOfCodeGeneratedSince(Label* l) { return pc_offset() - l->pos(); } |
| 1237 | 1312 |
| 1238 // Mark address of the ExitJSFrame code. | 1313 // Mark address of the ExitJSFrame code. |
| 1239 void RecordJSReturn(); | 1314 void RecordJSReturn(); |
| 1240 | 1315 |
| 1241 // Mark address of a debug break slot. | 1316 // Mark address of a debug break slot. |
| 1242 void RecordDebugBreakSlot(); | 1317 void RecordDebugBreakSlot(); |
| 1243 | 1318 |
| 1244 // Record a comment relocation entry that can be used by a disassembler. | 1319 // Record a comment relocation entry that can be used by a disassembler. |
| 1245 // Use --code-comments to enable. | 1320 // Use --code-comments to enable. |
| 1246 void RecordComment(const char* msg); | 1321 void RecordComment(const char* msg); |
| 1247 | 1322 |
| 1248 // Writes a single word of data in the code stream. | 1323 // Writes a single word of data in the code stream. |
| 1249 // Used for inline tables, e.g., jump-tables. | 1324 // Used for inline tables, e.g., jump-tables. |
| 1250 void db(uint8_t data) { UNIMPLEMENTED(); } | 1325 void db(uint8_t data); |
| 1251 void dd(uint32_t data); | 1326 void dd(uint32_t data); |
| 1252 | 1327 |
| 1253 int pc_offset() const { return static_cast<int>(pc_ - buffer_); } | 1328 int pc_offset() const { return static_cast<int>(pc_ - buffer_); } |
| 1254 | 1329 |
| 1255 PositionsRecorder* positions_recorder() { return &positions_recorder_; } | 1330 PositionsRecorder* positions_recorder() { return &positions_recorder_; } |
| 1256 | 1331 |
| 1257 // Check if there is less than kGap bytes available in the buffer. | 1332 // Check if there is less than kGap bytes available in the buffer. |
| 1258 // If this is the case, we need to grow the buffer before emitting | 1333 // If this is the case, we need to grow the buffer before emitting |
| 1259 // an instruction or relocation information. | 1334 // an instruction or relocation information. |
| 1260 inline bool buffer_overflow() const { | 1335 inline bool buffer_overflow() const { |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1504 private: | 1579 private: |
| 1505 Assembler* assembler_; | 1580 Assembler* assembler_; |
| 1506 #ifdef DEBUG | 1581 #ifdef DEBUG |
| 1507 int space_before_; | 1582 int space_before_; |
| 1508 #endif | 1583 #endif |
| 1509 }; | 1584 }; |
| 1510 | 1585 |
| 1511 } } // namespace v8::internal | 1586 } } // namespace v8::internal |
| 1512 | 1587 |
| 1513 #endif // V8_X64_ASSEMBLER_X64_H_ | 1588 #endif // V8_X64_ASSEMBLER_X64_H_ |
| OLD | NEW |