| 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 12 matching lines...) Expand all Loading... |
| 23 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 23 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| 24 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 24 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 25 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 25 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 26 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | 26 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
| 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 2006-2009 the V8 project authors. All rights reserved. | 33 // Copyright 2010 the V8 project authors. All rights reserved. |
| 34 | 34 |
| 35 // A lightweight X64 Assembler. | 35 // A lightweight X64 Assembler. |
| 36 | 36 |
| 37 #ifndef V8_X64_ASSEMBLER_X64_H_ | 37 #ifndef V8_X64_ASSEMBLER_X64_H_ |
| 38 #define V8_X64_ASSEMBLER_X64_H_ | 38 #define V8_X64_ASSEMBLER_X64_H_ |
| 39 | 39 |
| 40 #include "serialize.h" | 40 #include "serialize.h" |
| 41 | 41 |
| 42 namespace v8 { | 42 namespace v8 { |
| 43 namespace internal { | 43 namespace internal { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 // 3) By not using an enum, we are possibly preventing the compiler from | 81 // 3) By not using an enum, we are possibly preventing the compiler from |
| 82 // doing certain constant folds, which may significantly reduce the | 82 // doing certain constant folds, which may significantly reduce the |
| 83 // code generated for some assembly instructions (because they boil down | 83 // code generated for some assembly instructions (because they boil down |
| 84 // to a few constants). If this is a problem, we could change the code | 84 // to a few constants). If this is a problem, we could change the code |
| 85 // such that we use an enum in optimized mode, and the struct in debug | 85 // such that we use an enum in optimized mode, and the struct in debug |
| 86 // mode. This way we get the compile-time error checking in debug mode | 86 // mode. This way we get the compile-time error checking in debug mode |
| 87 // and best performance in optimized code. | 87 // and best performance in optimized code. |
| 88 // | 88 // |
| 89 | 89 |
| 90 struct Register { | 90 struct Register { |
| 91 // The non-allocatable registers are: |
| 92 // rsp - stack pointer |
| 93 // rbp - frame pointer |
| 94 // rsi - context register |
| 95 // r10 - fixed scratch register |
| 96 // r13 - root register |
| 97 // r15 - smi constant register |
| 98 static const int kNumRegisters = 16; |
| 99 static const int kNumAllocatableRegisters = 10; |
| 100 |
| 101 static const char* AllocationIndexToString(int index) { |
| 102 ASSERT(index >= 0 && index < kNumAllocatableRegisters); |
| 103 const char* const names[] = { |
| 104 "rax", |
| 105 "rcx", |
| 106 "rdx", |
| 107 "rbx", |
| 108 "rdi", |
| 109 "r8", |
| 110 "r9", |
| 111 "r11", |
| 112 "r12", |
| 113 "r14" |
| 114 }; |
| 115 return names[index]; |
| 116 } |
| 117 |
| 91 static Register toRegister(int code) { | 118 static Register toRegister(int code) { |
| 92 Register r = { code }; | 119 Register r = { code }; |
| 93 return r; | 120 return r; |
| 94 } | 121 } |
| 95 bool is_valid() const { return 0 <= code_ && code_ < 16; } | 122 bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } |
| 96 bool is(Register reg) const { return code_ == reg.code_; } | 123 bool is(Register reg) const { return code_ == reg.code_; } |
| 97 int code() const { | 124 int code() const { |
| 98 ASSERT(is_valid()); | 125 ASSERT(is_valid()); |
| 99 return code_; | 126 return code_; |
| 100 } | 127 } |
| 101 int bit() const { | 128 int bit() const { |
| 102 return 1 << code_; | 129 return 1 << code_; |
| 103 } | 130 } |
| 104 | 131 |
| 105 // Return the high bit of the register code as a 0 or 1. Used often | 132 // Return the high bit of the register code as a 0 or 1. Used often |
| (...skipping 25 matching lines...) Expand all Loading... |
| 131 const Register r10 = { 10 }; | 158 const Register r10 = { 10 }; |
| 132 const Register r11 = { 11 }; | 159 const Register r11 = { 11 }; |
| 133 const Register r12 = { 12 }; | 160 const Register r12 = { 12 }; |
| 134 const Register r13 = { 13 }; | 161 const Register r13 = { 13 }; |
| 135 const Register r14 = { 14 }; | 162 const Register r14 = { 14 }; |
| 136 const Register r15 = { 15 }; | 163 const Register r15 = { 15 }; |
| 137 const Register no_reg = { -1 }; | 164 const Register no_reg = { -1 }; |
| 138 | 165 |
| 139 | 166 |
| 140 struct XMMRegister { | 167 struct XMMRegister { |
| 141 bool is_valid() const { return 0 <= code_ && code_ < 16; } | 168 static const int kNumRegisters = 16; |
| 169 static const int kNumAllocatableRegisters = 15; |
| 170 |
| 171 static int ToAllocationIndex(XMMRegister reg) { |
| 172 ASSERT(reg.code() != 0); |
| 173 return reg.code() - 1; |
| 174 } |
| 175 |
| 176 static const char* AllocationIndexToString(int index) { |
| 177 ASSERT(index >= 0 && index < kNumAllocatableRegisters); |
| 178 const char* const names[] = { |
| 179 "xmm1", |
| 180 "xmm2", |
| 181 "xmm3", |
| 182 "xmm4", |
| 183 "xmm5", |
| 184 "xmm6", |
| 185 "xmm7", |
| 186 "xmm8", |
| 187 "xmm9", |
| 188 "xmm10", |
| 189 "xmm11", |
| 190 "xmm12", |
| 191 "xmm13", |
| 192 "xmm14", |
| 193 "xmm15" |
| 194 }; |
| 195 return names[index]; |
| 196 } |
| 197 |
| 198 bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; } |
| 142 int code() const { | 199 int code() const { |
| 143 ASSERT(is_valid()); | 200 ASSERT(is_valid()); |
| 144 return code_; | 201 return code_; |
| 145 } | 202 } |
| 146 | 203 |
| 147 // Return the high bit of the register code as a 0 or 1. Used often | 204 // Return the high bit of the register code as a 0 or 1. Used often |
| 148 // when constructing the REX prefix byte. | 205 // when constructing the REX prefix byte. |
| 149 int high_bit() const { | 206 int high_bit() const { |
| 150 return code_ >> 3; | 207 return code_ >> 3; |
| 151 } | 208 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 168 const XMMRegister xmm7 = { 7 }; | 225 const XMMRegister xmm7 = { 7 }; |
| 169 const XMMRegister xmm8 = { 8 }; | 226 const XMMRegister xmm8 = { 8 }; |
| 170 const XMMRegister xmm9 = { 9 }; | 227 const XMMRegister xmm9 = { 9 }; |
| 171 const XMMRegister xmm10 = { 10 }; | 228 const XMMRegister xmm10 = { 10 }; |
| 172 const XMMRegister xmm11 = { 11 }; | 229 const XMMRegister xmm11 = { 11 }; |
| 173 const XMMRegister xmm12 = { 12 }; | 230 const XMMRegister xmm12 = { 12 }; |
| 174 const XMMRegister xmm13 = { 13 }; | 231 const XMMRegister xmm13 = { 13 }; |
| 175 const XMMRegister xmm14 = { 14 }; | 232 const XMMRegister xmm14 = { 14 }; |
| 176 const XMMRegister xmm15 = { 15 }; | 233 const XMMRegister xmm15 = { 15 }; |
| 177 | 234 |
| 235 |
| 236 typedef XMMRegister DoubleRegister; |
| 237 |
| 238 |
| 178 enum Condition { | 239 enum Condition { |
| 179 // any value < 0 is considered no_condition | 240 // any value < 0 is considered no_condition |
| 180 no_condition = -1, | 241 no_condition = -1, |
| 181 | 242 |
| 182 overflow = 0, | 243 overflow = 0, |
| 183 no_overflow = 1, | 244 no_overflow = 1, |
| 184 below = 2, | 245 below = 2, |
| 185 above_equal = 3, | 246 above_equal = 3, |
| 186 equal = 4, | 247 equal = 4, |
| 187 not_equal = 5, | 248 not_equal = 5, |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 // if (CpuFeatures::IsSupported(SSE3)) { | 399 // if (CpuFeatures::IsSupported(SSE3)) { |
| 339 // CpuFeatures::Scope fscope(SSE3); | 400 // CpuFeatures::Scope fscope(SSE3); |
| 340 // // Generate SSE3 floating point code. | 401 // // Generate SSE3 floating point code. |
| 341 // } else { | 402 // } else { |
| 342 // // Generate standard x87 or SSE2 floating point code. | 403 // // Generate standard x87 or SSE2 floating point code. |
| 343 // } | 404 // } |
| 344 class CpuFeatures { | 405 class CpuFeatures { |
| 345 public: | 406 public: |
| 346 // Detect features of the target CPU. Set safe defaults if the serializer | 407 // Detect features of the target CPU. Set safe defaults if the serializer |
| 347 // is enabled (snapshots must be portable). | 408 // is enabled (snapshots must be portable). |
| 348 void Probe(); | 409 void Probe(bool portable); |
| 410 |
| 349 // Check whether a feature is supported by the target CPU. | 411 // Check whether a feature is supported by the target CPU. |
| 350 bool IsSupported(CpuFeature f) const { | 412 bool IsSupported(CpuFeature f) const { |
| 351 if (f == SSE2 && !FLAG_enable_sse2) return false; | 413 if (f == SSE2 && !FLAG_enable_sse2) return false; |
| 352 if (f == SSE3 && !FLAG_enable_sse3) return false; | 414 if (f == SSE3 && !FLAG_enable_sse3) return false; |
| 353 if (f == CMOV && !FLAG_enable_cmov) return false; | 415 if (f == CMOV && !FLAG_enable_cmov) return false; |
| 354 if (f == RDTSC && !FLAG_enable_rdtsc) return false; | 416 if (f == RDTSC && !FLAG_enable_rdtsc) return false; |
| 355 if (f == SAHF && !FLAG_enable_sahf) return false; | 417 if (f == SAHF && !FLAG_enable_sahf) return false; |
| 356 return (supported_ & (V8_UINT64_C(1) << f)) != 0; | 418 return (supported_ & (V8_UINT64_C(1) << f)) != 0; |
| 357 } | 419 } |
| 358 // Check whether a feature is currently enabled. | 420 // Check whether a feature is currently enabled. |
| (...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1183 // Check the code size generated from label to here. | 1245 // Check the code size generated from label to here. |
| 1184 int SizeOfCodeGeneratedSince(Label* l) { return pc_offset() - l->pos(); } | 1246 int SizeOfCodeGeneratedSince(Label* l) { return pc_offset() - l->pos(); } |
| 1185 | 1247 |
| 1186 // Mark address of the ExitJSFrame code. | 1248 // Mark address of the ExitJSFrame code. |
| 1187 void RecordJSReturn(); | 1249 void RecordJSReturn(); |
| 1188 | 1250 |
| 1189 // Mark address of a debug break slot. | 1251 // Mark address of a debug break slot. |
| 1190 void RecordDebugBreakSlot(); | 1252 void RecordDebugBreakSlot(); |
| 1191 | 1253 |
| 1192 // Record a comment relocation entry that can be used by a disassembler. | 1254 // Record a comment relocation entry that can be used by a disassembler. |
| 1193 // Use --debug_code to enable. | 1255 // Use --code-comments to enable. |
| 1194 void RecordComment(const char* msg); | 1256 void RecordComment(const char* msg); |
| 1195 | 1257 |
| 1258 // Writes a single word of data in the code stream. |
| 1259 // Used for inline tables, e.g., jump-tables. |
| 1260 void db(uint8_t data) { UNIMPLEMENTED(); } |
| 1261 void dd(uint32_t data); |
| 1262 |
| 1196 int pc_offset() const { return static_cast<int>(pc_ - buffer_); } | 1263 int pc_offset() const { return static_cast<int>(pc_ - buffer_); } |
| 1197 | 1264 |
| 1198 PositionsRecorder* positions_recorder() { return &positions_recorder_; } | 1265 PositionsRecorder* positions_recorder() { return &positions_recorder_; } |
| 1199 | 1266 |
| 1200 // Check if there is less than kGap bytes available in the buffer. | 1267 // Check if there is less than kGap bytes available in the buffer. |
| 1201 // If this is the case, we need to grow the buffer before emitting | 1268 // If this is the case, we need to grow the buffer before emitting |
| 1202 // an instruction or relocation information. | 1269 // an instruction or relocation information. |
| 1203 inline bool buffer_overflow() const { | 1270 inline bool buffer_overflow() const { |
| 1204 return pc_ >= reloc_info_writer.pos() - kGap; | 1271 return pc_ >= reloc_info_writer.pos() - kGap; |
| 1205 } | 1272 } |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1445 private: | 1512 private: |
| 1446 Assembler* assembler_; | 1513 Assembler* assembler_; |
| 1447 #ifdef DEBUG | 1514 #ifdef DEBUG |
| 1448 int space_before_; | 1515 int space_before_; |
| 1449 #endif | 1516 #endif |
| 1450 }; | 1517 }; |
| 1451 | 1518 |
| 1452 } } // namespace v8::internal | 1519 } } // namespace v8::internal |
| 1453 | 1520 |
| 1454 #endif // V8_X64_ASSEMBLER_X64_H_ | 1521 #endif // V8_X64_ASSEMBLER_X64_H_ |
| OLD | NEW |