| 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 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 extern MMXRegister mm9; | 149 extern MMXRegister mm9; |
| 150 extern MMXRegister mm10; | 150 extern MMXRegister mm10; |
| 151 extern MMXRegister mm11; | 151 extern MMXRegister mm11; |
| 152 extern MMXRegister mm12; | 152 extern MMXRegister mm12; |
| 153 extern MMXRegister mm13; | 153 extern MMXRegister mm13; |
| 154 extern MMXRegister mm14; | 154 extern MMXRegister mm14; |
| 155 extern MMXRegister mm15; | 155 extern MMXRegister mm15; |
| 156 | 156 |
| 157 | 157 |
| 158 struct XMMRegister { | 158 struct XMMRegister { |
| 159 bool is_valid() const { return 0 <= code_ && code_ < 2; } | 159 bool is_valid() const { return 0 <= code_ && code_ < 16; } |
| 160 int code() const { | 160 int code() const { |
| 161 ASSERT(is_valid()); | 161 ASSERT(is_valid()); |
| 162 return code_; | 162 return code_; |
| 163 } | 163 } |
| 164 | 164 |
| 165 int code_; | 165 int code_; |
| 166 }; | 166 }; |
| 167 | 167 |
| 168 extern XMMRegister xmm0; | 168 extern XMMRegister xmm0; |
| 169 extern XMMRegister xmm1; | 169 extern XMMRegister xmm1; |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 inline void set_disp8(int disp); | 323 inline void set_disp8(int disp); |
| 324 inline void set_disp32(int disp); | 324 inline void set_disp32(int disp); |
| 325 | 325 |
| 326 friend class Assembler; | 326 friend class Assembler; |
| 327 }; | 327 }; |
| 328 | 328 |
| 329 | 329 |
| 330 // CpuFeatures keeps track of which features are supported by the target CPU. | 330 // CpuFeatures keeps track of which features are supported by the target CPU. |
| 331 // Supported features must be enabled by a Scope before use. | 331 // Supported features must be enabled by a Scope before use. |
| 332 // Example: | 332 // Example: |
| 333 // if (CpuFeatures::IsSupported(SSE2)) { | 333 // if (CpuFeatures::IsSupported(SSE3)) { |
| 334 // CpuFeatures::Scope fscope(SSE2); | 334 // CpuFeatures::Scope fscope(SSE3); |
| 335 // // Generate SSE2 floating point code. | 335 // // Generate SSE3 floating point code. |
| 336 // } else { | 336 // } else { |
| 337 // // Generate standard x87 floating point code. | 337 // // Generate standard x87 or SSE2 floating point code. |
| 338 // } | 338 // } |
| 339 class CpuFeatures : public AllStatic { | 339 class CpuFeatures : public AllStatic { |
| 340 public: | 340 public: |
| 341 // Feature flags bit positions. They are mostly based on the CPUID spec. | 341 // Feature flags bit positions. They are mostly based on the CPUID spec. |
| 342 // (We assign CPUID itself to one of the currently reserved bits -- | 342 // (We assign CPUID itself to one of the currently reserved bits -- |
| 343 // feel free to change this if needed.) | 343 // feel free to change this if needed.) |
| 344 enum Feature { SSE3 = 32, SSE2 = 26, CMOV = 15, RDTSC = 4, CPUID = 10 }; | 344 enum Feature { SSE3 = 32, SSE2 = 26, CMOV = 15, RDTSC = 4, CPUID = 10 }; |
| 345 // Detect features of the target CPU. Set safe defaults if the serializer | 345 // Detect features of the target CPU. Set safe defaults if the serializer |
| 346 // is enabled (snapshots must be portable). | 346 // is enabled (snapshots must be portable). |
| 347 static void Probe(); | 347 static void Probe(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 364 } | 364 } |
| 365 ~Scope() { CpuFeatures::enabled_ = old_enabled_; } | 365 ~Scope() { CpuFeatures::enabled_ = old_enabled_; } |
| 366 private: | 366 private: |
| 367 uint64_t old_enabled_; | 367 uint64_t old_enabled_; |
| 368 #else | 368 #else |
| 369 public: | 369 public: |
| 370 explicit Scope(Feature f) {} | 370 explicit Scope(Feature f) {} |
| 371 #endif | 371 #endif |
| 372 }; | 372 }; |
| 373 private: | 373 private: |
| 374 // Safe defaults include SSE2 and CMOV for X64. It is always available, if |
| 375 // anyone checks, but they shouldn't need to check. |
| 376 static const uint64_t kDefaultCpuFeatures = |
| 377 (1 << CpuFeatures::SSE2 | 1 << CpuFeatures::CMOV); |
| 374 static uint64_t supported_; | 378 static uint64_t supported_; |
| 375 static uint64_t enabled_; | 379 static uint64_t enabled_; |
| 376 }; | 380 }; |
| 377 | 381 |
| 378 | 382 |
| 379 class Assembler : public Malloced { | 383 class Assembler : public Malloced { |
| 380 private: | 384 private: |
| 381 // We check before assembling an instruction that there is sufficient | 385 // We check before assembling an instruction that there is sufficient |
| 382 // space to write an instruction and its relocation information. | 386 // space to write an instruction and its relocation information. |
| 383 // The relocation writer's position must be kGap bytes above the end of | 387 // The relocation writer's position must be kGap bytes above the end of |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 void movq(Register dst, ExternalReference ext); | 494 void movq(Register dst, ExternalReference ext); |
| 491 void movq(Register dst, Handle<Object> handle, RelocInfo::Mode rmode); | 495 void movq(Register dst, Handle<Object> handle, RelocInfo::Mode rmode); |
| 492 | 496 |
| 493 void movsxlq(Register dst, Register src); | 497 void movsxlq(Register dst, Register src); |
| 494 void movzxbq(Register dst, const Operand& src); | 498 void movzxbq(Register dst, const Operand& src); |
| 495 | 499 |
| 496 // New x64 instruction to load from an immediate 64-bit pointer into RAX. | 500 // New x64 instruction to load from an immediate 64-bit pointer into RAX. |
| 497 void load_rax(void* ptr, RelocInfo::Mode rmode); | 501 void load_rax(void* ptr, RelocInfo::Mode rmode); |
| 498 void load_rax(ExternalReference ext); | 502 void load_rax(ExternalReference ext); |
| 499 | 503 |
| 500 // Conditional moves | 504 // Conditional moves. |
| 501 // Implement conditional moves here. | 505 void cmovq(Condition cc, Register dst, Register src); |
| 506 void cmovq(Condition cc, Register dst, const Operand& src); |
| 507 void cmovl(Condition cc, Register dst, Register src); |
| 508 void cmovl(Condition cc, Register dst, const Operand& src); |
| 502 | 509 |
| 503 // Exchange two registers | 510 // Exchange two registers |
| 504 void xchg(Register dst, Register src); | 511 void xchg(Register dst, Register src); |
| 505 | 512 |
| 506 // Arithmetics | 513 // Arithmetics |
| 507 void addq(Register dst, Register src) { | 514 void addq(Register dst, Register src) { |
| 508 arithmetic_op(0x03, dst, src); | 515 arithmetic_op(0x03, dst, src); |
| 509 } | 516 } |
| 510 | 517 |
| 511 void addl(Register dst, Register src) { | 518 void addl(Register dst, Register src) { |
| 512 arithmetic_op_32(0x03, dst, src); | 519 arithmetic_op_32(0x03, dst, src); |
| 513 } | 520 } |
| 514 | 521 |
| 522 void addl(Register dst, Immediate src) { |
| 523 immediate_arithmetic_op_32(0x0, dst, src); |
| 524 } |
| 525 |
| 515 void addq(Register dst, const Operand& src) { | 526 void addq(Register dst, const Operand& src) { |
| 516 arithmetic_op(0x03, dst, src); | 527 arithmetic_op(0x03, dst, src); |
| 517 } | 528 } |
| 518 | 529 |
| 519 | 530 |
| 520 void addq(const Operand& dst, Register src) { | 531 void addq(const Operand& dst, Register src) { |
| 521 arithmetic_op(0x01, src, dst); | 532 arithmetic_op(0x01, src, dst); |
| 522 } | 533 } |
| 523 | 534 |
| 524 void addq(Register dst, Immediate src) { | 535 void addq(Register dst, Immediate src) { |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 837 void fcompp(); | 848 void fcompp(); |
| 838 void fnstsw_ax(); | 849 void fnstsw_ax(); |
| 839 void fwait(); | 850 void fwait(); |
| 840 void fnclex(); | 851 void fnclex(); |
| 841 | 852 |
| 842 void fsin(); | 853 void fsin(); |
| 843 void fcos(); | 854 void fcos(); |
| 844 | 855 |
| 845 void frndint(); | 856 void frndint(); |
| 846 | 857 |
| 847 // SSE2 instructions | 858 void sahf(); |
| 859 |
| 860 // SSE2 instructions |
| 861 void movsd(const Operand& dst, XMMRegister src); |
| 862 void movsd(Register src, XMMRegister dst); |
| 863 void movsd(XMMRegister dst, Register src); |
| 864 void movsd(XMMRegister src, const Operand& dst); |
| 865 |
| 848 void cvttss2si(Register dst, const Operand& src); | 866 void cvttss2si(Register dst, const Operand& src); |
| 849 void cvttsd2si(Register dst, const Operand& src); | 867 void cvttsd2si(Register dst, const Operand& src); |
| 850 | 868 |
| 851 void cvtsi2sd(XMMRegister dst, const Operand& src); | 869 void cvtlsi2sd(XMMRegister dst, const Operand& src); |
| 870 void cvtlsi2sd(XMMRegister dst, Register src); |
| 871 void cvtqsi2sd(XMMRegister dst, const Operand& src); |
| 872 void cvtqsi2sd(XMMRegister dst, Register src); |
| 852 | 873 |
| 853 void addsd(XMMRegister dst, XMMRegister src); | 874 void addsd(XMMRegister dst, XMMRegister src); |
| 854 void subsd(XMMRegister dst, XMMRegister src); | 875 void subsd(XMMRegister dst, XMMRegister src); |
| 855 void mulsd(XMMRegister dst, XMMRegister src); | 876 void mulsd(XMMRegister dst, XMMRegister src); |
| 856 void divsd(XMMRegister dst, XMMRegister src); | 877 void divsd(XMMRegister dst, XMMRegister src); |
| 857 | 878 |
| 879 |
| 880 void emit_sse_operand(XMMRegister dst, XMMRegister src); |
| 881 void emit_sse_operand(XMMRegister reg, const Operand& adr); |
| 882 void emit_sse_operand(XMMRegister dst, Register src); |
| 883 |
| 858 // Use either movsd or movlpd. | 884 // Use either movsd or movlpd. |
| 859 // void movdbl(XMMRegister dst, const Operand& src); | 885 // void movdbl(XMMRegister dst, const Operand& src); |
| 860 // void movdbl(const Operand& dst, XMMRegister src); | 886 // void movdbl(const Operand& dst, XMMRegister src); |
| 861 | 887 |
| 862 // Debugging | 888 // Debugging |
| 863 void Print(); | 889 void Print(); |
| 864 | 890 |
| 865 // Check the code size generated from label to here. | 891 // Check the code size generated from label to here. |
| 866 int SizeOfCodeGeneratedSince(Label* l) { return pc_offset() - l->pos(); } | 892 int SizeOfCodeGeneratedSince(Label* l) { return pc_offset() - l->pos(); } |
| 867 | 893 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 926 inline void emit(Handle<Object> handle); | 952 inline void emit(Handle<Object> handle); |
| 927 inline void emitq(uint64_t x, RelocInfo::Mode rmode); | 953 inline void emitq(uint64_t x, RelocInfo::Mode rmode); |
| 928 inline void emitw(uint16_t x); | 954 inline void emitw(uint16_t x); |
| 929 void emit(Immediate x) { emitl(x.value_); } | 955 void emit(Immediate x) { emitl(x.value_); } |
| 930 | 956 |
| 931 // Emits a REX prefix that encodes a 64-bit operand size and | 957 // Emits a REX prefix that encodes a 64-bit operand size and |
| 932 // the top bit of both register codes. | 958 // the top bit of both register codes. |
| 933 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. | 959 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. |
| 934 // REX.W is set. | 960 // REX.W is set. |
| 935 inline void emit_rex_64(Register reg, Register rm_reg); | 961 inline void emit_rex_64(Register reg, Register rm_reg); |
| 962 inline void emit_rex_64(XMMRegister reg, Register rm_reg); |
| 936 | 963 |
| 937 // Emits a REX prefix that encodes a 64-bit operand size and | 964 // Emits a REX prefix that encodes a 64-bit operand size and |
| 938 // the top bit of the destination, index, and base register codes. | 965 // the top bit of the destination, index, and base register codes. |
| 939 // The high bit of reg is used for REX.R, the high bit of op's base | 966 // The high bit of reg is used for REX.R, the high bit of op's base |
| 940 // register is used for REX.B, and the high bit of op's index register | 967 // register is used for REX.B, and the high bit of op's index register |
| 941 // is used for REX.X. REX.W is set. | 968 // is used for REX.X. REX.W is set. |
| 942 inline void emit_rex_64(Register reg, const Operand& op); | 969 inline void emit_rex_64(Register reg, const Operand& op); |
| 970 inline void emit_rex_64(XMMRegister reg, const Operand& op); |
| 943 | 971 |
| 944 // Emits a REX prefix that encodes a 64-bit operand size and | 972 // Emits a REX prefix that encodes a 64-bit operand size and |
| 945 // the top bit of the register code. | 973 // the top bit of the register code. |
| 946 // The high bit of register is used for REX.B. | 974 // The high bit of register is used for REX.B. |
| 947 // REX.W is set and REX.R and REX.X are clear. | 975 // REX.W is set and REX.R and REX.X are clear. |
| 948 inline void emit_rex_64(Register rm_reg); | 976 inline void emit_rex_64(Register rm_reg); |
| 949 | 977 |
| 950 // Emits a REX prefix that encodes a 64-bit operand size and | 978 // Emits a REX prefix that encodes a 64-bit operand size and |
| 951 // the top bit of the index and base register codes. | 979 // the top bit of the index and base register codes. |
| 952 // The high bit of op's base register is used for REX.B, and the high | 980 // The high bit of op's base register is used for REX.B, and the high |
| (...skipping 24 matching lines...) Expand all Loading... |
| 977 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. | 1005 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B. |
| 978 // REX.W is cleared. If no REX bits are set, no byte is emitted. | 1006 // REX.W is cleared. If no REX bits are set, no byte is emitted. |
| 979 inline void emit_optional_rex_32(Register reg, Register rm_reg); | 1007 inline void emit_optional_rex_32(Register reg, Register rm_reg); |
| 980 | 1008 |
| 981 // The high bit of reg is used for REX.R, the high bit of op's base | 1009 // The high bit of reg is used for REX.R, the high bit of op's base |
| 982 // register is used for REX.B, and the high bit of op's index register | 1010 // register is used for REX.B, and the high bit of op's index register |
| 983 // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing | 1011 // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing |
| 984 // is emitted. | 1012 // is emitted. |
| 985 inline void emit_optional_rex_32(Register reg, const Operand& op); | 1013 inline void emit_optional_rex_32(Register reg, const Operand& op); |
| 986 | 1014 |
| 1015 // As for emit_optional_rex_32(Register, Register), except that |
| 1016 // the registers are XMM registers. |
| 1017 inline void emit_optional_rex_32(XMMRegister reg, XMMRegister base); |
| 1018 |
| 1019 // As for emit_optional_rex_32(Register, Register), except that |
| 1020 // the registers are XMM registers. |
| 1021 inline void emit_optional_rex_32(XMMRegister reg, Register base); |
| 1022 |
| 1023 // As for emit_optional_rex_32(Register, const Operand&), except that |
| 1024 // the register is an XMM register. |
| 1025 inline void emit_optional_rex_32(XMMRegister reg, const Operand& op); |
| 1026 |
| 987 // Optionally do as emit_rex_32(Register) if the register number has | 1027 // Optionally do as emit_rex_32(Register) if the register number has |
| 988 // the high bit set. | 1028 // the high bit set. |
| 989 inline void emit_optional_rex_32(Register rm_reg); | 1029 inline void emit_optional_rex_32(Register rm_reg); |
| 990 | 1030 |
| 991 // Optionally do as emit_rex_32(const Operand&) if the operand register | 1031 // Optionally do as emit_rex_32(const Operand&) if the operand register |
| 992 // numbers have a high bit set. | 1032 // numbers have a high bit set. |
| 993 inline void emit_optional_rex_32(const Operand& op); | 1033 inline void emit_optional_rex_32(const Operand& op); |
| 994 | 1034 |
| 995 | 1035 |
| 996 // Emit the ModR/M byte, and optionally the SIB byte and | 1036 // Emit the ModR/M byte, and optionally the SIB byte and |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1107 private: | 1147 private: |
| 1108 Assembler* assembler_; | 1148 Assembler* assembler_; |
| 1109 #ifdef DEBUG | 1149 #ifdef DEBUG |
| 1110 int space_before_; | 1150 int space_before_; |
| 1111 #endif | 1151 #endif |
| 1112 }; | 1152 }; |
| 1113 | 1153 |
| 1114 } } // namespace v8::internal | 1154 } } // namespace v8::internal |
| 1115 | 1155 |
| 1116 #endif // V8_X64_ASSEMBLER_X64_H_ | 1156 #endif // V8_X64_ASSEMBLER_X64_H_ |
| OLD | NEW |