| 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 16 matching lines...) Expand all Loading... |
| 27 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | 27 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| 28 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 28 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 29 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 | 30 |
| 31 // The original source code covered by the above license above has been | 31 // The original source code covered by the above license above has been |
| 32 // modified significantly by Google Inc. | 32 // modified significantly by Google Inc. |
| 33 // Copyright 2011 the V8 project authors. All rights reserved. | 33 // Copyright 2011 the V8 project authors. All rights reserved. |
| 34 | 34 |
| 35 // A light-weight IA32 Assembler. | 35 // A light-weight IA32 Assembler. |
| 36 | 36 |
| 37 #ifndef V8_IA32_ASSEMBLER_IA32_H_ | 37 #ifndef V8_X87_ASSEMBLER_X87_H_ |
| 38 #define V8_IA32_ASSEMBLER_IA32_H_ | 38 #define V8_X87_ASSEMBLER_X87_H_ |
| 39 | 39 |
| 40 #include "isolate.h" | 40 #include "isolate.h" |
| 41 #include "serialize.h" | 41 #include "serialize.h" |
| 42 | 42 |
| 43 namespace v8 { | 43 namespace v8 { |
| 44 namespace internal { | 44 namespace internal { |
| 45 | 45 |
| 46 // CPU Registers. | 46 // CPU Registers. |
| 47 // | 47 // |
| 48 // 1) We would prefer to use an enum, but enum values are assignment- | 48 // 1) We would prefer to use an enum, but enum values are assignment- |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 return (reg.code() >= 6) ? reg.code() - 2 : reg.code(); | 134 return (reg.code() >= 6) ? reg.code() - 2 : reg.code(); |
| 135 } | 135 } |
| 136 | 136 |
| 137 | 137 |
| 138 inline Register Register::FromAllocationIndex(int index) { | 138 inline Register Register::FromAllocationIndex(int index) { |
| 139 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); | 139 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); |
| 140 return (index >= 4) ? from_code(index + 2) : from_code(index); | 140 return (index >= 4) ? from_code(index + 2) : from_code(index); |
| 141 } | 141 } |
| 142 | 142 |
| 143 | 143 |
| 144 struct XMMRegister { | 144 struct X87Register { |
| 145 static const int kMaxNumAllocatableRegisters = 7; | 145 static const int kMaxNumAllocatableRegisters = 8; |
| 146 static const int kMaxNumRegisters = 8; | 146 static const int kMaxNumRegisters = 8; |
| 147 static int NumAllocatableRegisters() { | 147 static int NumAllocatableRegisters() { |
| 148 return kMaxNumAllocatableRegisters; | 148 return kMaxNumAllocatableRegisters; |
| 149 } | 149 } |
| 150 | 150 |
| 151 static int ToAllocationIndex(XMMRegister reg) { | 151 static int ToAllocationIndex(X87Register reg) { |
| 152 ASSERT(reg.code() != 0); | 152 return reg.code_; |
| 153 return reg.code() - 1; | |
| 154 } | 153 } |
| 155 | 154 |
| 156 static XMMRegister FromAllocationIndex(int index) { | 155 static const char* AllocationIndexToString(int index) { |
| 157 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); | 156 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); |
| 158 return from_code(index + 1); | 157 const char* const names[] = { |
| 158 "stX_0", "stX_1", "stX_2", "stX_3", "stX_4", |
| 159 "stX_5", "stX_6", "stX_7" |
| 160 }; |
| 161 return names[index]; |
| 159 } | 162 } |
| 160 | 163 |
| 161 static XMMRegister from_code(int code) { | 164 static X87Register FromAllocationIndex(int index) { |
| 162 XMMRegister result = { code }; | 165 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); |
| 166 X87Register result; |
| 167 result.code_ = index; |
| 163 return result; | 168 return result; |
| 164 } | 169 } |
| 165 | 170 |
| 166 bool is_valid() const { | 171 bool is_valid() const { |
| 167 return 0 <= code_ && code_ < kMaxNumRegisters; | 172 return 0 <= code_ && code_ < kMaxNumRegisters; |
| 168 } | 173 } |
| 169 | 174 |
| 170 int code() const { | 175 int code() const { |
| 171 ASSERT(is_valid()); | 176 ASSERT(is_valid()); |
| 172 return code_; | 177 return code_; |
| 173 } | 178 } |
| 174 | 179 |
| 175 bool is(XMMRegister reg) const { return code_ == reg.code_; } | 180 bool is(X87Register reg) const { |
| 176 | 181 return code_ == reg.code_; |
| 177 static const char* AllocationIndexToString(int index) { | |
| 178 ASSERT(index >= 0 && index < kMaxNumAllocatableRegisters); | |
| 179 const char* const names[] = { | |
| 180 "xmm1", | |
| 181 "xmm2", | |
| 182 "xmm3", | |
| 183 "xmm4", | |
| 184 "xmm5", | |
| 185 "xmm6", | |
| 186 "xmm7" | |
| 187 }; | |
| 188 return names[index]; | |
| 189 } | 182 } |
| 190 | 183 |
| 191 int code_; | 184 int code_; |
| 192 }; | 185 }; |
| 193 | 186 |
| 194 | 187 |
| 195 typedef XMMRegister DoubleRegister; | 188 typedef X87Register DoubleRegister; |
| 196 | 189 |
| 197 | 190 |
| 198 const XMMRegister xmm0 = { 0 }; | 191 const X87Register stX_0 = { 0 }; |
| 199 const XMMRegister xmm1 = { 1 }; | 192 const X87Register stX_1 = { 1 }; |
| 200 const XMMRegister xmm2 = { 2 }; | 193 const X87Register stX_2 = { 2 }; |
| 201 const XMMRegister xmm3 = { 3 }; | 194 const X87Register stX_3 = { 3 }; |
| 202 const XMMRegister xmm4 = { 4 }; | 195 const X87Register stX_4 = { 4 }; |
| 203 const XMMRegister xmm5 = { 5 }; | 196 const X87Register stX_5 = { 5 }; |
| 204 const XMMRegister xmm6 = { 6 }; | 197 const X87Register stX_6 = { 6 }; |
| 205 const XMMRegister xmm7 = { 7 }; | 198 const X87Register stX_7 = { 7 }; |
| 206 const XMMRegister no_xmm_reg = { -1 }; | |
| 207 | 199 |
| 208 | 200 |
| 209 enum Condition { | 201 enum Condition { |
| 210 // any value < 0 is considered no_condition | 202 // any value < 0 is considered no_condition |
| 211 no_condition = -1, | 203 no_condition = -1, |
| 212 | 204 |
| 213 overflow = 0, | 205 overflow = 0, |
| 214 no_overflow = 1, | 206 no_overflow = 1, |
| 215 below = 2, | 207 below = 2, |
| 216 above_equal = 3, | 208 above_equal = 3, |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 times_8 = 3, | 307 times_8 = 3, |
| 316 times_int_size = times_4, | 308 times_int_size = times_4, |
| 317 times_half_pointer_size = times_2, | 309 times_half_pointer_size = times_2, |
| 318 times_pointer_size = times_4, | 310 times_pointer_size = times_4, |
| 319 times_twice_pointer_size = times_8 | 311 times_twice_pointer_size = times_8 |
| 320 }; | 312 }; |
| 321 | 313 |
| 322 | 314 |
| 323 class Operand BASE_EMBEDDED { | 315 class Operand BASE_EMBEDDED { |
| 324 public: | 316 public: |
| 325 // XMM reg | |
| 326 INLINE(explicit Operand(XMMRegister xmm_reg)); | |
| 327 | |
| 328 // [disp/r] | 317 // [disp/r] |
| 329 INLINE(explicit Operand(int32_t disp, RelocInfo::Mode rmode)); | 318 INLINE(explicit Operand(int32_t disp, RelocInfo::Mode rmode)); |
| 330 // disp only must always be relocated | 319 // disp only must always be relocated |
| 331 | 320 |
| 332 // [base + disp/r] | 321 // [base + disp/r] |
| 333 explicit Operand(Register base, int32_t disp, | 322 explicit Operand(Register base, int32_t disp, |
| 334 RelocInfo::Mode rmode = RelocInfo::NONE32); | 323 RelocInfo::Mode rmode = RelocInfo::NONE32); |
| 335 | 324 |
| 336 // [base + index*scale + disp/r] | 325 // [base + index*scale + disp/r] |
| 337 explicit Operand(Register base, | 326 explicit Operand(Register base, |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 626 | 615 |
| 627 void movsx_w(Register dst, Register src) { movsx_w(dst, Operand(src)); } | 616 void movsx_w(Register dst, Register src) { movsx_w(dst, Operand(src)); } |
| 628 void movsx_w(Register dst, const Operand& src); | 617 void movsx_w(Register dst, const Operand& src); |
| 629 | 618 |
| 630 void movzx_b(Register dst, Register src) { movzx_b(dst, Operand(src)); } | 619 void movzx_b(Register dst, Register src) { movzx_b(dst, Operand(src)); } |
| 631 void movzx_b(Register dst, const Operand& src); | 620 void movzx_b(Register dst, const Operand& src); |
| 632 | 621 |
| 633 void movzx_w(Register dst, Register src) { movzx_w(dst, Operand(src)); } | 622 void movzx_w(Register dst, Register src) { movzx_w(dst, Operand(src)); } |
| 634 void movzx_w(Register dst, const Operand& src); | 623 void movzx_w(Register dst, const Operand& src); |
| 635 | 624 |
| 636 // Conditional moves | |
| 637 void cmov(Condition cc, Register dst, Register src) { | |
| 638 cmov(cc, dst, Operand(src)); | |
| 639 } | |
| 640 void cmov(Condition cc, Register dst, const Operand& src); | |
| 641 | |
| 642 // Flag management. | 625 // Flag management. |
| 643 void cld(); | 626 void cld(); |
| 644 | 627 |
| 645 // Repetitive string instructions. | 628 // Repetitive string instructions. |
| 646 void rep_movs(); | 629 void rep_movs(); |
| 647 void rep_stos(); | 630 void rep_stos(); |
| 648 void stos(); | 631 void stos(); |
| 649 | 632 |
| 650 // Exchange two registers | 633 // Exchange two registers |
| 651 void xchg(Register dst, Register src); | 634 void xchg(Register dst, Register src); |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 888 void fwait(); | 871 void fwait(); |
| 889 void fnclex(); | 872 void fnclex(); |
| 890 | 873 |
| 891 void frndint(); | 874 void frndint(); |
| 892 | 875 |
| 893 void sahf(); | 876 void sahf(); |
| 894 void setcc(Condition cc, Register reg); | 877 void setcc(Condition cc, Register reg); |
| 895 | 878 |
| 896 void cpuid(); | 879 void cpuid(); |
| 897 | 880 |
| 898 // SSE instructions | |
| 899 void movaps(XMMRegister dst, XMMRegister src); | |
| 900 void shufps(XMMRegister dst, XMMRegister src, byte imm8); | |
| 901 | |
| 902 void andps(XMMRegister dst, const Operand& src); | |
| 903 void andps(XMMRegister dst, XMMRegister src) { andps(dst, Operand(src)); } | |
| 904 void xorps(XMMRegister dst, const Operand& src); | |
| 905 void xorps(XMMRegister dst, XMMRegister src) { xorps(dst, Operand(src)); } | |
| 906 void orps(XMMRegister dst, const Operand& src); | |
| 907 void orps(XMMRegister dst, XMMRegister src) { orps(dst, Operand(src)); } | |
| 908 | |
| 909 void addps(XMMRegister dst, const Operand& src); | |
| 910 void addps(XMMRegister dst, XMMRegister src) { addps(dst, Operand(src)); } | |
| 911 void subps(XMMRegister dst, const Operand& src); | |
| 912 void subps(XMMRegister dst, XMMRegister src) { subps(dst, Operand(src)); } | |
| 913 void mulps(XMMRegister dst, const Operand& src); | |
| 914 void mulps(XMMRegister dst, XMMRegister src) { mulps(dst, Operand(src)); } | |
| 915 void divps(XMMRegister dst, const Operand& src); | |
| 916 void divps(XMMRegister dst, XMMRegister src) { divps(dst, Operand(src)); } | |
| 917 | |
| 918 // SSE2 instructions | |
| 919 void cvttss2si(Register dst, const Operand& src); | |
| 920 void cvttss2si(Register dst, XMMRegister src) { | |
| 921 cvttss2si(dst, Operand(src)); | |
| 922 } | |
| 923 void cvttsd2si(Register dst, const Operand& src); | |
| 924 void cvtsd2si(Register dst, XMMRegister src); | |
| 925 | |
| 926 void cvtsi2sd(XMMRegister dst, Register src) { cvtsi2sd(dst, Operand(src)); } | |
| 927 void cvtsi2sd(XMMRegister dst, const Operand& src); | |
| 928 void cvtss2sd(XMMRegister dst, XMMRegister src); | |
| 929 void cvtsd2ss(XMMRegister dst, XMMRegister src); | |
| 930 | |
| 931 void addsd(XMMRegister dst, XMMRegister src); | |
| 932 void addsd(XMMRegister dst, const Operand& src); | |
| 933 void subsd(XMMRegister dst, XMMRegister src); | |
| 934 void mulsd(XMMRegister dst, XMMRegister src); | |
| 935 void mulsd(XMMRegister dst, const Operand& src); | |
| 936 void divsd(XMMRegister dst, XMMRegister src); | |
| 937 void xorpd(XMMRegister dst, XMMRegister src); | |
| 938 void sqrtsd(XMMRegister dst, XMMRegister src); | |
| 939 | |
| 940 void andpd(XMMRegister dst, XMMRegister src); | |
| 941 void orpd(XMMRegister dst, XMMRegister src); | |
| 942 | |
| 943 void ucomisd(XMMRegister dst, XMMRegister src) { ucomisd(dst, Operand(src)); } | |
| 944 void ucomisd(XMMRegister dst, const Operand& src); | |
| 945 | |
| 946 enum RoundingMode { | |
| 947 kRoundToNearest = 0x0, | |
| 948 kRoundDown = 0x1, | |
| 949 kRoundUp = 0x2, | |
| 950 kRoundToZero = 0x3 | |
| 951 }; | |
| 952 | |
| 953 void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode); | |
| 954 | |
| 955 void movmskpd(Register dst, XMMRegister src); | |
| 956 void movmskps(Register dst, XMMRegister src); | |
| 957 | |
| 958 void cmpltsd(XMMRegister dst, XMMRegister src); | |
| 959 void pcmpeqd(XMMRegister dst, XMMRegister src); | |
| 960 | |
| 961 void movdqa(XMMRegister dst, const Operand& src); | |
| 962 void movdqa(const Operand& dst, XMMRegister src); | |
| 963 void movdqu(XMMRegister dst, const Operand& src); | |
| 964 void movdqu(const Operand& dst, XMMRegister src); | |
| 965 void movdq(bool aligned, XMMRegister dst, const Operand& src) { | |
| 966 if (aligned) { | |
| 967 movdqa(dst, src); | |
| 968 } else { | |
| 969 movdqu(dst, src); | |
| 970 } | |
| 971 } | |
| 972 | |
| 973 void movd(XMMRegister dst, Register src) { movd(dst, Operand(src)); } | |
| 974 void movd(XMMRegister dst, const Operand& src); | |
| 975 void movd(Register dst, XMMRegister src) { movd(Operand(dst), src); } | |
| 976 void movd(const Operand& dst, XMMRegister src); | |
| 977 void movsd(XMMRegister dst, XMMRegister src) { movsd(dst, Operand(src)); } | |
| 978 void movsd(XMMRegister dst, const Operand& src); | |
| 979 void movsd(const Operand& dst, XMMRegister src); | |
| 980 | |
| 981 | |
| 982 void movss(XMMRegister dst, const Operand& src); | |
| 983 void movss(const Operand& dst, XMMRegister src); | |
| 984 void movss(XMMRegister dst, XMMRegister src) { movss(dst, Operand(src)); } | |
| 985 void extractps(Register dst, XMMRegister src, byte imm8); | |
| 986 | |
| 987 void pand(XMMRegister dst, XMMRegister src); | |
| 988 void pxor(XMMRegister dst, XMMRegister src); | |
| 989 void por(XMMRegister dst, XMMRegister src); | |
| 990 void ptest(XMMRegister dst, XMMRegister src); | |
| 991 | |
| 992 void psllq(XMMRegister reg, int8_t shift); | |
| 993 void psllq(XMMRegister dst, XMMRegister src); | |
| 994 void psrlq(XMMRegister reg, int8_t shift); | |
| 995 void psrlq(XMMRegister dst, XMMRegister src); | |
| 996 void pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle); | |
| 997 void pextrd(Register dst, XMMRegister src, int8_t offset) { | |
| 998 pextrd(Operand(dst), src, offset); | |
| 999 } | |
| 1000 void pextrd(const Operand& dst, XMMRegister src, int8_t offset); | |
| 1001 void pinsrd(XMMRegister dst, Register src, int8_t offset) { | |
| 1002 pinsrd(dst, Operand(src), offset); | |
| 1003 } | |
| 1004 void pinsrd(XMMRegister dst, const Operand& src, int8_t offset); | |
| 1005 | |
| 1006 // Parallel XMM operations. | |
| 1007 void movntdqa(XMMRegister dst, const Operand& src); | |
| 1008 void movntdq(const Operand& dst, XMMRegister src); | |
| 1009 // Prefetch src position into cache level. | |
| 1010 // Level 1, 2 or 3 specifies CPU cache level. Level 0 specifies a | |
| 1011 // non-temporal | |
| 1012 void prefetch(const Operand& src, int level); | |
| 1013 // TODO(lrn): Need SFENCE for movnt? | 881 // TODO(lrn): Need SFENCE for movnt? |
| 1014 | 882 |
| 1015 // Debugging | 883 // Debugging |
| 1016 void Print(); | 884 void Print(); |
| 1017 | 885 |
| 1018 // Check the code size generated from label to here. | 886 // Check the code size generated from label to here. |
| 1019 int SizeOfCodeGeneratedSince(Label* label) { | 887 int SizeOfCodeGeneratedSince(Label* label) { |
| 1020 return pc_offset() - label->pos(); | 888 return pc_offset() - label->pos(); |
| 1021 } | 889 } |
| 1022 | 890 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1060 byte byte_at(int pos) { return buffer_[pos]; } | 928 byte byte_at(int pos) { return buffer_[pos]; } |
| 1061 void set_byte_at(int pos, byte value) { buffer_[pos] = value; } | 929 void set_byte_at(int pos, byte value) { buffer_[pos] = value; } |
| 1062 | 930 |
| 1063 // Allocate a constant pool of the correct size for the generated code. | 931 // Allocate a constant pool of the correct size for the generated code. |
| 1064 Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate); | 932 Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate); |
| 1065 | 933 |
| 1066 // Generate the constant pool for the generated code. | 934 // Generate the constant pool for the generated code. |
| 1067 void PopulateConstantPool(ConstantPoolArray* constant_pool); | 935 void PopulateConstantPool(ConstantPoolArray* constant_pool); |
| 1068 | 936 |
| 1069 protected: | 937 protected: |
| 1070 void emit_sse_operand(XMMRegister reg, const Operand& adr); | |
| 1071 void emit_sse_operand(XMMRegister dst, XMMRegister src); | |
| 1072 void emit_sse_operand(Register dst, XMMRegister src); | |
| 1073 void emit_sse_operand(XMMRegister dst, Register src); | |
| 1074 | |
| 1075 byte* addr_at(int pos) { return buffer_ + pos; } | 938 byte* addr_at(int pos) { return buffer_ + pos; } |
| 1076 | 939 |
| 1077 | 940 |
| 1078 private: | 941 private: |
| 1079 uint32_t long_at(int pos) { | 942 uint32_t long_at(int pos) { |
| 1080 return *reinterpret_cast<uint32_t*>(addr_at(pos)); | 943 return *reinterpret_cast<uint32_t*>(addr_at(pos)); |
| 1081 } | 944 } |
| 1082 void long_at_put(int pos, uint32_t x) { | 945 void long_at_put(int pos, uint32_t x) { |
| 1083 *reinterpret_cast<uint32_t*>(addr_at(pos)) = x; | 946 *reinterpret_cast<uint32_t*>(addr_at(pos)) = x; |
| 1084 } | 947 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1158 | 1021 |
| 1159 private: | 1022 private: |
| 1160 Assembler* assembler_; | 1023 Assembler* assembler_; |
| 1161 #ifdef DEBUG | 1024 #ifdef DEBUG |
| 1162 int space_before_; | 1025 int space_before_; |
| 1163 #endif | 1026 #endif |
| 1164 }; | 1027 }; |
| 1165 | 1028 |
| 1166 } } // namespace v8::internal | 1029 } } // namespace v8::internal |
| 1167 | 1030 |
| 1168 #endif // V8_IA32_ASSEMBLER_IA32_H_ | 1031 #endif // V8_X87_ASSEMBLER_X87_H_ |
| OLD | NEW |