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 |