| 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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 static Register FromAllocationIndex(int index) { | 105 static Register FromAllocationIndex(int index) { |
| 106 ASSERT(index >= 0 && index < kNumAllocatableRegisters); | 106 ASSERT(index >= 0 && index < kNumAllocatableRegisters); |
| 107 Register result = { registerCodeByAllocationIndex[index] }; | 107 Register result = { registerCodeByAllocationIndex[index] }; |
| 108 return result; | 108 return result; |
| 109 } | 109 } |
| 110 | 110 |
| 111 static const char* AllocationIndexToString(int index) { | 111 static const char* AllocationIndexToString(int index) { |
| 112 ASSERT(index >= 0 && index < kNumAllocatableRegisters); | 112 ASSERT(index >= 0 && index < kNumAllocatableRegisters); |
| 113 const char* const names[] = { | 113 const char* const names[] = { |
| 114 "rax", | 114 "rax", |
| 115 "rbx", |
| 116 "rdx", |
| 115 "rcx", | 117 "rcx", |
| 116 "rdx", | |
| 117 "rbx", | |
| 118 "rdi", | 118 "rdi", |
| 119 "r8", | 119 "r8", |
| 120 "r9", | 120 "r9", |
| 121 "r11", | 121 "r11", |
| 122 "r12", | 122 "r14", |
| 123 "r14" | 123 "r12" |
| 124 }; | 124 }; |
| 125 return names[index]; | 125 return names[index]; |
| 126 } | 126 } |
| 127 | 127 |
| 128 static Register toRegister(int code) { | 128 static Register toRegister(int code) { |
| 129 Register r = { code }; | 129 Register r = { code }; |
| 130 return r; | 130 return r; |
| 131 } | 131 } |
| 132 bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } | 132 bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } |
| 133 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... |
| 146 } | 146 } |
| 147 // 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 |
| 148 // in modR/M, SIB, and opcode bytes. | 148 // in modR/M, SIB, and opcode bytes. |
| 149 int low_bits() const { | 149 int low_bits() const { |
| 150 return code_ & 0x7; | 150 return code_ & 0x7; |
| 151 } | 151 } |
| 152 | 152 |
| 153 // 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 |
| 154 // by assignment. | 154 // by assignment. |
| 155 int code_; | 155 int code_; |
| 156 |
| 156 private: | 157 private: |
| 157 static const int registerCodeByAllocationIndex[kNumAllocatableRegisters]; | 158 static const int registerCodeByAllocationIndex[kNumAllocatableRegisters]; |
| 158 static const int allocationIndexByRegisterCode[kNumRegisters]; | 159 static const int allocationIndexByRegisterCode[kNumRegisters]; |
| 159 }; | 160 }; |
| 160 | 161 |
| 161 const Register rax = { 0 }; | 162 const Register rax = { 0 }; |
| 162 const Register rcx = { 1 }; | 163 const Register rcx = { 1 }; |
| 163 const Register rdx = { 2 }; | 164 const Register rdx = { 2 }; |
| 164 const Register rbx = { 3 }; | 165 const Register rbx = { 3 }; |
| 165 const Register rsp = { 4 }; | 166 const Register rsp = { 4 }; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 "xmm11", | 209 "xmm11", |
| 209 "xmm12", | 210 "xmm12", |
| 210 "xmm13", | 211 "xmm13", |
| 211 "xmm14", | 212 "xmm14", |
| 212 "xmm15" | 213 "xmm15" |
| 213 }; | 214 }; |
| 214 return names[index]; | 215 return names[index]; |
| 215 } | 216 } |
| 216 | 217 |
| 217 bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } | 218 bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } |
| 219 bool is(XMMRegister reg) const { return code_ == reg.code_; } |
| 218 int code() const { | 220 int code() const { |
| 219 ASSERT(is_valid()); | 221 ASSERT(is_valid()); |
| 220 return code_; | 222 return code_; |
| 221 } | 223 } |
| 222 | 224 |
| 223 // Return the high bit of the register code as a 0 or 1. Used often | 225 // Return the high bit of the register code as a 0 or 1. Used often |
| 224 // when constructing the REX prefix byte. | 226 // when constructing the REX prefix byte. |
| 225 int high_bit() const { | 227 int high_bit() const { |
| 226 return code_ >> 3; | 228 return code_ >> 3; |
| 227 } | 229 } |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 // [index*scale + disp/r] | 384 // [index*scale + disp/r] |
| 383 Operand(Register index, | 385 Operand(Register index, |
| 384 ScaleFactor scale, | 386 ScaleFactor scale, |
| 385 int32_t disp); | 387 int32_t disp); |
| 386 | 388 |
| 387 // Offset from existing memory operand. | 389 // Offset from existing memory operand. |
| 388 // Offset is added to existing displacement as 32-bit signed values and | 390 // Offset is added to existing displacement as 32-bit signed values and |
| 389 // this must not overflow. | 391 // this must not overflow. |
| 390 Operand(const Operand& base, int32_t offset); | 392 Operand(const Operand& base, int32_t offset); |
| 391 | 393 |
| 394 // Checks whether either base or index register is the given register. |
| 395 // Does not check the "reg" part of the Operand. |
| 396 bool AddressUsesRegister(Register reg) const; |
| 397 |
| 392 private: | 398 private: |
| 393 byte rex_; | 399 byte rex_; |
| 394 byte buf_[6]; | 400 byte buf_[6]; |
| 395 // The number of bytes in buf_. | 401 // The number of bytes of buf_ in use. |
| 396 unsigned int len_; | 402 byte len_; |
| 397 | 403 |
| 398 // Set the ModR/M byte without an encoded 'reg' register. The | 404 // Set the ModR/M byte without an encoded 'reg' register. The |
| 399 // register is encoded later as part of the emit_operand operation. | 405 // register is encoded later as part of the emit_operand operation. |
| 400 // set_modrm can be called before or after set_sib and set_disp*. | 406 // set_modrm can be called before or after set_sib and set_disp*. |
| 401 inline void set_modrm(int mod, Register rm); | 407 inline void set_modrm(int mod, Register rm); |
| 402 | 408 |
| 403 // Set the SIB byte if one is needed. Sets the length to 2 rather than 1. | 409 // Set the SIB byte if one is needed. Sets the length to 2 rather than 1. |
| 404 inline void set_sib(ScaleFactor scale, Register index, Register base); | 410 inline void set_sib(ScaleFactor scale, Register index, Register base); |
| 405 | 411 |
| 406 // Adds operand displacement fields (offsets added to the memory address). | 412 // Adds operand displacement fields (offsets added to the memory address). |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 // of m. m must be a power of 2. | 606 // of m. m must be a power of 2. |
| 601 void Align(int m); | 607 void Align(int m); |
| 602 // Aligns code to something that's optimal for a jump target for the platform. | 608 // Aligns code to something that's optimal for a jump target for the platform. |
| 603 void CodeTargetAlign(); | 609 void CodeTargetAlign(); |
| 604 | 610 |
| 605 // Stack | 611 // Stack |
| 606 void pushfq(); | 612 void pushfq(); |
| 607 void popfq(); | 613 void popfq(); |
| 608 | 614 |
| 609 void push(Immediate value); | 615 void push(Immediate value); |
| 616 // Push a 32 bit integer, and guarantee that it is actually pushed as a |
| 617 // 32 bit value, the normal push will optimize the 8 bit case. |
| 618 void push_imm32(int32_t imm32); |
| 610 void push(Register src); | 619 void push(Register src); |
| 611 void push(const Operand& src); | 620 void push(const Operand& src); |
| 612 | 621 |
| 613 void pop(Register dst); | 622 void pop(Register dst); |
| 614 void pop(const Operand& dst); | 623 void pop(const Operand& dst); |
| 615 | 624 |
| 616 void enter(Immediate size); | 625 void enter(Immediate size); |
| 617 void leave(); | 626 void leave(); |
| 618 | 627 |
| 619 // Moves | 628 // Moves |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 717 } | 726 } |
| 718 | 727 |
| 719 void addq(const Operand& dst, Immediate src) { | 728 void addq(const Operand& dst, Immediate src) { |
| 720 immediate_arithmetic_op(0x0, dst, src); | 729 immediate_arithmetic_op(0x0, dst, src); |
| 721 } | 730 } |
| 722 | 731 |
| 723 void sbbl(Register dst, Register src) { | 732 void sbbl(Register dst, Register src) { |
| 724 arithmetic_op_32(0x1b, dst, src); | 733 arithmetic_op_32(0x1b, dst, src); |
| 725 } | 734 } |
| 726 | 735 |
| 736 void sbbq(Register dst, Register src) { |
| 737 arithmetic_op(0x1b, dst, src); |
| 738 } |
| 739 |
| 727 void cmpb(Register dst, Immediate src) { | 740 void cmpb(Register dst, Immediate src) { |
| 728 immediate_arithmetic_op_8(0x7, dst, src); | 741 immediate_arithmetic_op_8(0x7, dst, src); |
| 729 } | 742 } |
| 730 | 743 |
| 731 void cmpb_al(Immediate src); | 744 void cmpb_al(Immediate src); |
| 732 | 745 |
| 733 void cmpb(Register dst, Register src) { | 746 void cmpb(Register dst, Register src) { |
| 734 arithmetic_op(0x3A, dst, src); | 747 arithmetic_op(0x3A, dst, src); |
| 735 } | 748 } |
| 736 | 749 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 827 } | 840 } |
| 828 | 841 |
| 829 void andl(Register dst, Immediate src) { | 842 void andl(Register dst, Immediate src) { |
| 830 immediate_arithmetic_op_32(0x4, dst, src); | 843 immediate_arithmetic_op_32(0x4, dst, src); |
| 831 } | 844 } |
| 832 | 845 |
| 833 void andl(Register dst, Register src) { | 846 void andl(Register dst, Register src) { |
| 834 arithmetic_op_32(0x23, dst, src); | 847 arithmetic_op_32(0x23, dst, src); |
| 835 } | 848 } |
| 836 | 849 |
| 850 void andl(Register dst, const Operand& src) { |
| 851 arithmetic_op_32(0x23, dst, src); |
| 852 } |
| 853 |
| 837 void andb(Register dst, Immediate src) { | 854 void andb(Register dst, Immediate src) { |
| 838 immediate_arithmetic_op_8(0x4, dst, src); | 855 immediate_arithmetic_op_8(0x4, dst, src); |
| 839 } | 856 } |
| 840 | 857 |
| 841 void decq(Register dst); | 858 void decq(Register dst); |
| 842 void decq(const Operand& dst); | 859 void decq(const Operand& dst); |
| 843 void decl(Register dst); | 860 void decl(Register dst); |
| 844 void decl(const Operand& dst); | 861 void decl(const Operand& dst); |
| 845 void decb(Register dst); | 862 void decb(Register dst); |
| 846 void decb(const Operand& dst); | 863 void decb(const Operand& dst); |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1211 void movd(XMMRegister dst, Register src); | 1228 void movd(XMMRegister dst, Register src); |
| 1212 void movd(Register dst, XMMRegister src); | 1229 void movd(Register dst, XMMRegister src); |
| 1213 void movq(XMMRegister dst, Register src); | 1230 void movq(XMMRegister dst, Register src); |
| 1214 void movq(Register dst, XMMRegister src); | 1231 void movq(Register dst, XMMRegister src); |
| 1215 void extractps(Register dst, XMMRegister src, byte imm8); | 1232 void extractps(Register dst, XMMRegister src, byte imm8); |
| 1216 | 1233 |
| 1217 void movsd(const Operand& dst, XMMRegister src); | 1234 void movsd(const Operand& dst, XMMRegister src); |
| 1218 void movsd(XMMRegister dst, XMMRegister src); | 1235 void movsd(XMMRegister dst, XMMRegister src); |
| 1219 void movsd(XMMRegister dst, const Operand& src); | 1236 void movsd(XMMRegister dst, const Operand& src); |
| 1220 | 1237 |
| 1238 void movdqa(const Operand& dst, XMMRegister src); |
| 1239 void movdqa(XMMRegister dst, const Operand& src); |
| 1240 |
| 1221 void movss(XMMRegister dst, const Operand& src); | 1241 void movss(XMMRegister dst, const Operand& src); |
| 1222 void movss(const Operand& dst, XMMRegister src); | 1242 void movss(const Operand& dst, XMMRegister src); |
| 1223 | 1243 |
| 1224 void cvttss2si(Register dst, const Operand& src); | 1244 void cvttss2si(Register dst, const Operand& src); |
| 1245 void cvttss2si(Register dst, XMMRegister src); |
| 1225 void cvttsd2si(Register dst, const Operand& src); | 1246 void cvttsd2si(Register dst, const Operand& src); |
| 1247 void cvttsd2si(Register dst, XMMRegister src); |
| 1226 void cvttsd2siq(Register dst, XMMRegister src); | 1248 void cvttsd2siq(Register dst, XMMRegister src); |
| 1227 | 1249 |
| 1228 void cvtlsi2sd(XMMRegister dst, const Operand& src); | 1250 void cvtlsi2sd(XMMRegister dst, const Operand& src); |
| 1229 void cvtlsi2sd(XMMRegister dst, Register src); | 1251 void cvtlsi2sd(XMMRegister dst, Register src); |
| 1230 void cvtqsi2sd(XMMRegister dst, const Operand& src); | 1252 void cvtqsi2sd(XMMRegister dst, const Operand& src); |
| 1231 void cvtqsi2sd(XMMRegister dst, Register src); | 1253 void cvtqsi2sd(XMMRegister dst, Register src); |
| 1232 | 1254 |
| 1233 void cvtlsi2ss(XMMRegister dst, Register src); | 1255 void cvtlsi2ss(XMMRegister dst, Register src); |
| 1234 | 1256 |
| 1235 void cvtss2sd(XMMRegister dst, XMMRegister src); | 1257 void cvtss2sd(XMMRegister dst, XMMRegister src); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1249 | 1271 |
| 1250 void ucomisd(XMMRegister dst, XMMRegister src); | 1272 void ucomisd(XMMRegister dst, XMMRegister src); |
| 1251 void ucomisd(XMMRegister dst, const Operand& src); | 1273 void ucomisd(XMMRegister dst, const Operand& src); |
| 1252 | 1274 |
| 1253 // The first argument is the reg field, the second argument is the r/m field. | 1275 // The first argument is the reg field, the second argument is the r/m field. |
| 1254 void emit_sse_operand(XMMRegister dst, XMMRegister src); | 1276 void emit_sse_operand(XMMRegister dst, XMMRegister src); |
| 1255 void emit_sse_operand(XMMRegister reg, const Operand& adr); | 1277 void emit_sse_operand(XMMRegister reg, const Operand& adr); |
| 1256 void emit_sse_operand(XMMRegister dst, Register src); | 1278 void emit_sse_operand(XMMRegister dst, Register src); |
| 1257 void emit_sse_operand(Register dst, XMMRegister src); | 1279 void emit_sse_operand(Register dst, XMMRegister src); |
| 1258 | 1280 |
| 1259 // Use either movsd or movlpd. | |
| 1260 // void movdbl(XMMRegister dst, const Operand& src); | |
| 1261 // void movdbl(const Operand& dst, XMMRegister src); | |
| 1262 | |
| 1263 // Debugging | 1281 // Debugging |
| 1264 void Print(); | 1282 void Print(); |
| 1265 | 1283 |
| 1266 // Check the code size generated from label to here. | 1284 // Check the code size generated from label to here. |
| 1267 int SizeOfCodeGeneratedSince(Label* l) { return pc_offset() - l->pos(); } | 1285 int SizeOfCodeGeneratedSince(Label* l) { return pc_offset() - l->pos(); } |
| 1268 | 1286 |
| 1269 // Mark address of the ExitJSFrame code. | 1287 // Mark address of the ExitJSFrame code. |
| 1270 void RecordJSReturn(); | 1288 void RecordJSReturn(); |
| 1271 | 1289 |
| 1272 // Mark address of a debug break slot. | 1290 // Mark address of a debug break slot. |
| 1273 void RecordDebugBreakSlot(); | 1291 void RecordDebugBreakSlot(); |
| 1274 | 1292 |
| 1275 // Record a comment relocation entry that can be used by a disassembler. | 1293 // Record a comment relocation entry that can be used by a disassembler. |
| 1276 // Use --code-comments to enable. | 1294 // Use --code-comments to enable. |
| 1277 void RecordComment(const char* msg); | 1295 void RecordComment(const char* msg); |
| 1278 | 1296 |
| 1279 // Writes a single word of data in the code stream. | 1297 // Writes a single word of data in the code stream. |
| 1280 // Used for inline tables, e.g., jump-tables. | 1298 // Used for inline tables, e.g., jump-tables. |
| 1281 void db(uint8_t data) { UNIMPLEMENTED(); } | 1299 void db(uint8_t data); |
| 1282 void dd(uint32_t data); | 1300 void dd(uint32_t data); |
| 1283 | 1301 |
| 1284 int pc_offset() const { return static_cast<int>(pc_ - buffer_); } | 1302 int pc_offset() const { return static_cast<int>(pc_ - buffer_); } |
| 1285 | 1303 |
| 1286 PositionsRecorder* positions_recorder() { return &positions_recorder_; } | 1304 PositionsRecorder* positions_recorder() { return &positions_recorder_; } |
| 1287 | 1305 |
| 1288 // Check if there is less than kGap bytes available in the buffer. | 1306 // Check if there is less than kGap bytes available in the buffer. |
| 1289 // If this is the case, we need to grow the buffer before emitting | 1307 // If this is the case, we need to grow the buffer before emitting |
| 1290 // an instruction or relocation information. | 1308 // an instruction or relocation information. |
| 1291 inline bool buffer_overflow() const { | 1309 inline bool buffer_overflow() const { |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1533 private: | 1551 private: |
| 1534 Assembler* assembler_; | 1552 Assembler* assembler_; |
| 1535 #ifdef DEBUG | 1553 #ifdef DEBUG |
| 1536 int space_before_; | 1554 int space_before_; |
| 1537 #endif | 1555 #endif |
| 1538 }; | 1556 }; |
| 1539 | 1557 |
| 1540 } } // namespace v8::internal | 1558 } } // namespace v8::internal |
| 1541 | 1559 |
| 1542 #endif // V8_X64_ASSEMBLER_X64_H_ | 1560 #endif // V8_X64_ASSEMBLER_X64_H_ |
| OLD | NEW |