 Chromium Code Reviews
 Chromium Code Reviews Issue 115571:
  Implement quadword MOV on x64 assembler, emitting REX prefix.  (Closed) 
  Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
    
  
    Issue 115571:
  Implement quadword MOV on x64 assembler, emitting REX prefix.  (Closed) 
  Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/| OLD | NEW | 
|---|---|
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. | 
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without | 
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are | 
| 4 // met: | 4 // met: | 
| 5 // | 5 // | 
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright | 
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. | 
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above | 
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following | 
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 46 // Implementation of Assembler | 46 // Implementation of Assembler | 
| 47 | 47 | 
| 48 // Emit a single byte. Must always be inlined. | 48 // Emit a single byte. Must always be inlined. | 
| 49 #define EMIT(x) \ | 49 #define EMIT(x) \ | 
| 50 *pc_++ = (x) | 50 *pc_++ = (x) | 
| 51 | 51 | 
| 52 #ifdef GENERATED_CODE_COVERAGE | 52 #ifdef GENERATED_CODE_COVERAGE | 
| 53 static void InitCoverageLog(); | 53 static void InitCoverageLog(); | 
| 54 #endif | 54 #endif | 
| 55 | 55 | 
| 56 // ----------------------------------------------------------------------------- | |
| 57 // Implementation of Assembler | |
| 58 | |
| 59 byte* Assembler::spare_buffer_ = NULL; | 56 byte* Assembler::spare_buffer_ = NULL; | 
| 60 | 57 | 
| 61 Assembler::Assembler(void* buffer, int buffer_size) { | 58 Assembler::Assembler(void* buffer, int buffer_size) { | 
| 62 if (buffer == NULL) { | 59 if (buffer == NULL) { | 
| 63 // do our own buffer management | 60 // do our own buffer management | 
| 64 if (buffer_size <= kMinimalBufferSize) { | 61 if (buffer_size <= kMinimalBufferSize) { | 
| 65 buffer_size = kMinimalBufferSize; | 62 buffer_size = kMinimalBufferSize; | 
| 66 | 63 | 
| 67 if (spare_buffer_ != NULL) { | 64 if (spare_buffer_ != NULL) { | 
| 68 buffer = spare_buffer_; | 65 buffer = spare_buffer_; | 
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 152 } | 149 } | 
| 153 | 150 | 
| 154 void Assembler::RecordStatementPosition(int a) { | 151 void Assembler::RecordStatementPosition(int a) { | 
| 155 UNIMPLEMENTED(); | 152 UNIMPLEMENTED(); | 
| 156 } | 153 } | 
| 157 | 154 | 
| 158 void Assembler::bind(Label* a) { | 155 void Assembler::bind(Label* a) { | 
| 159 UNIMPLEMENTED(); | 156 UNIMPLEMENTED(); | 
| 160 } | 157 } | 
| 161 | 158 | 
| 162 void Assembler::nop() { | |
| 163 UNIMPLEMENTED(); | |
| 164 } | |
| 165 | |
| 166 void Assembler::GrowBuffer() { | 159 void Assembler::GrowBuffer() { | 
| 167 ASSERT(overflow()); // should not call this otherwise | 160 ASSERT(overflow()); // should not call this otherwise | 
| 168 if (!own_buffer_) FATAL("external code buffer is too small"); | 161 if (!own_buffer_) FATAL("external code buffer is too small"); | 
| 169 | 162 | 
| 170 // compute new buffer size | 163 // compute new buffer size | 
| 171 CodeDesc desc; // the new buffer | 164 CodeDesc desc; // the new buffer | 
| 172 if (buffer_size_ < 4*KB) { | 165 if (buffer_size_ < 4*KB) { | 
| 173 desc.buffer_size = 4*KB; | 166 desc.buffer_size = 4*KB; | 
| 174 } else { | 167 } else { | 
| 175 desc.buffer_size = 2*buffer_size_; | 168 desc.buffer_size = 2*buffer_size_; | 
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 225 if (*p != 0) { // 0 means uninitialized. | 218 if (*p != 0) { // 0 means uninitialized. | 
| 226 *p += pc_delta; | 219 *p += pc_delta; | 
| 227 } | 220 } | 
| 228 } | 221 } | 
| 229 } | 222 } | 
| 230 | 223 | 
| 231 ASSERT(!overflow()); | 224 ASSERT(!overflow()); | 
| 232 } | 225 } | 
| 233 | 226 | 
| 234 | 227 | 
| 228 void Assembler::emit_operand(Register reg, const Operand& adr) { | |
| 229 const unsigned length = adr.len_; | |
| 230 ASSERT(length > 0); | |
| 231 | |
| 232 // Emit updated ModRM byte containing the given register. | |
| 233 pc_[0] = (adr.buf_[0] & ~0x38) | ((reg.code() && 0x7) << 3); | |
| 234 | |
| 235 // Emit the rest of the encoded operand. | |
| 236 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; | |
| 237 pc_ += length; | |
| 238 } | |
| 239 | |
| 240 | |
| 235 void Assembler::int3() { | 241 void Assembler::int3() { | 
| 236 EnsureSpace ensure_space(this); | 242 EnsureSpace ensure_space(this); | 
| 237 last_pc_ = pc_; | 243 last_pc_ = pc_; | 
| 238 EMIT(0xCC); | 244 EMIT(0xCC); | 
| 239 } | 245 } | 
| 240 | 246 | 
| 247 | |
| 248 void Assembler::hlt() { | |
| 249 EnsureSpace ensure_space(this); | |
| 250 last_pc_ = pc_; | |
| 251 EMIT(0xF4); | |
| 252 } | |
| 253 | |
| 254 | |
| 255 void Assembler::nop() { | |
| 256 EnsureSpace ensure_space(this); | |
| 257 last_pc_ = pc_; | |
| 258 EMIT(0x90); | |
| 259 } | |
| 260 | |
| 261 | |
| 262 void Assembler::ret(int imm16) { | |
| 263 EnsureSpace ensure_space(this); | |
| 264 last_pc_ = pc_; | |
| 265 ASSERT(is_uint16(imm16)); | |
| 266 if (imm16 == 0) { | |
| 267 EMIT(0xC3); | |
| 268 } else { | |
| 269 EMIT(0xC2); | |
| 270 EMIT(imm16 & 0xFF); | |
| 271 EMIT((imm16 >> 8) & 0xFF); | |
| 272 } | |
| 273 } | |
| 274 | |
| 275 | |
| 276 void Assembler::mov(Register dst, const Operand& src) { | |
| 277 EnsureSpace ensure_space(this); | |
| 278 last_pc_ = pc_; | |
| 279 emit_rex_64(dst, src); | |
| 
iposva
2009/05/22 07:56:38
Will all mov instructions need the emit_rex_64 pre
 | |
| 280 EMIT(0x8B); | |
| 281 emit_operand(dst, src); | |
| 282 } | |
| 283 | |
| 284 | |
| 285 void Assembler::mov(Register dst, Register src) { | |
| 286 EnsureSpace ensure_space(this); | |
| 287 last_pc_ = pc_; | |
| 288 emit_rex_64(dst, src); | |
| 289 EMIT(0x89); | |
| 290 EMIT(0xC0 | (src.code() & 0x7) << 3 | (dst.code() & 0x7)); | |
| 291 } | |
| 292 | |
| 241 } } // namespace v8::internal | 293 } } // namespace v8::internal | 
| 242 | 294 | 
| 243 | 295 | 
| 244 // TODO(x64): Implement and move these to their correct cc-files: | 296 // TODO(x64): Implement and move these to their correct cc-files: | 
| 245 #include "ast.h" | 297 #include "ast.h" | 
| 246 #include "bootstrapper.h" | 298 #include "bootstrapper.h" | 
| 247 #include "codegen-inl.h" | 299 #include "codegen-inl.h" | 
| 248 #include "cpu.h" | 300 #include "cpu.h" | 
| 249 #include "debug.h" | 301 #include "debug.h" | 
| 250 #include "disasm.h" | 302 #include "disasm.h" | 
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 519 UNIMPLEMENTED(); | 571 UNIMPLEMENTED(); | 
| 520 return NULL; | 572 return NULL; | 
| 521 } | 573 } | 
| 522 | 574 | 
| 523 byte* JavaScriptFrame::GetCallerStackPointer() const { | 575 byte* JavaScriptFrame::GetCallerStackPointer() const { | 
| 524 UNIMPLEMENTED(); | 576 UNIMPLEMENTED(); | 
| 525 return NULL; | 577 return NULL; | 
| 526 } | 578 } | 
| 527 | 579 | 
| 528 } } // namespace v8::internal | 580 } } // namespace v8::internal | 
| OLD | NEW |