Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: src/x64/assembler-x64.cc

Issue 574009: Fixed random style violations. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/assembler-x64.h ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 set_modrm(1, rsp); 258 set_modrm(1, rsp);
259 set_disp8(disp); 259 set_disp8(disp);
260 } else { 260 } else {
261 set_modrm(2, rsp); 261 set_modrm(2, rsp);
262 set_disp32(disp); 262 set_disp32(disp);
263 } 263 }
264 } 264 }
265 265
266 266
267 // ----------------------------------------------------------------------------- 267 // -----------------------------------------------------------------------------
268 // Implementation of Assembler 268 // Implementation of Assembler.
269 269
270 #ifdef GENERATED_CODE_COVERAGE 270 #ifdef GENERATED_CODE_COVERAGE
271 static void InitCoverageLog(); 271 static void InitCoverageLog();
272 #endif 272 #endif
273 273
274 byte* Assembler::spare_buffer_ = NULL; 274 byte* Assembler::spare_buffer_ = NULL;
275 275
276 Assembler::Assembler(void* buffer, int buffer_size) 276 Assembler::Assembler(void* buffer, int buffer_size)
277 : code_targets_(100) { 277 : code_targets_(100) {
278 if (buffer == NULL) { 278 if (buffer == NULL) {
279 // do our own buffer management 279 // Do our own buffer management.
280 if (buffer_size <= kMinimalBufferSize) { 280 if (buffer_size <= kMinimalBufferSize) {
281 buffer_size = kMinimalBufferSize; 281 buffer_size = kMinimalBufferSize;
282 282
283 if (spare_buffer_ != NULL) { 283 if (spare_buffer_ != NULL) {
284 buffer = spare_buffer_; 284 buffer = spare_buffer_;
285 spare_buffer_ = NULL; 285 spare_buffer_ = NULL;
286 } 286 }
287 } 287 }
288 if (buffer == NULL) { 288 if (buffer == NULL) {
289 buffer_ = NewArray<byte>(buffer_size); 289 buffer_ = NewArray<byte>(buffer_size);
290 } else { 290 } else {
291 buffer_ = static_cast<byte*>(buffer); 291 buffer_ = static_cast<byte*>(buffer);
292 } 292 }
293 buffer_size_ = buffer_size; 293 buffer_size_ = buffer_size;
294 own_buffer_ = true; 294 own_buffer_ = true;
295 } else { 295 } else {
296 // use externally provided buffer instead 296 // Use externally provided buffer instead.
297 ASSERT(buffer_size > 0); 297 ASSERT(buffer_size > 0);
298 buffer_ = static_cast<byte*>(buffer); 298 buffer_ = static_cast<byte*>(buffer);
299 buffer_size_ = buffer_size; 299 buffer_size_ = buffer_size;
300 own_buffer_ = false; 300 own_buffer_ = false;
301 } 301 }
302 302
303 // Clear the buffer in debug mode unless it was provided by the 303 // Clear the buffer in debug mode unless it was provided by the
304 // caller in which case we can't be sure it's okay to overwrite 304 // caller in which case we can't be sure it's okay to overwrite
305 // existing code in it. 305 // existing code in it.
306 #ifdef DEBUG 306 #ifdef DEBUG
307 if (own_buffer_) { 307 if (own_buffer_) {
308 memset(buffer_, 0xCC, buffer_size); // int3 308 memset(buffer_, 0xCC, buffer_size); // int3
309 } 309 }
310 #endif 310 #endif
311 311
312 // setup buffer pointers 312 // Setup buffer pointers.
313 ASSERT(buffer_ != NULL); 313 ASSERT(buffer_ != NULL);
314 pc_ = buffer_; 314 pc_ = buffer_;
315 reloc_info_writer.Reposition(buffer_ + buffer_size, pc_); 315 reloc_info_writer.Reposition(buffer_ + buffer_size, pc_);
316 316
317 last_pc_ = NULL; 317 last_pc_ = NULL;
318 current_statement_position_ = RelocInfo::kNoPosition; 318 current_statement_position_ = RelocInfo::kNoPosition;
319 current_position_ = RelocInfo::kNoPosition; 319 current_position_ = RelocInfo::kNoPosition;
320 written_statement_position_ = current_statement_position_; 320 written_statement_position_ = current_statement_position_;
321 written_position_ = current_position_; 321 written_position_ = current_position_;
322 #ifdef GENERATED_CODE_COVERAGE 322 #ifdef GENERATED_CODE_COVERAGE
323 InitCoverageLog(); 323 InitCoverageLog();
324 #endif 324 #endif
325 } 325 }
326 326
327 327
328 Assembler::~Assembler() { 328 Assembler::~Assembler() {
329 if (own_buffer_) { 329 if (own_buffer_) {
330 if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) { 330 if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) {
331 spare_buffer_ = buffer_; 331 spare_buffer_ = buffer_;
332 } else { 332 } else {
333 DeleteArray(buffer_); 333 DeleteArray(buffer_);
334 } 334 }
335 } 335 }
336 } 336 }
337 337
338 338
339 void Assembler::GetCode(CodeDesc* desc) { 339 void Assembler::GetCode(CodeDesc* desc) {
340 // finalize code 340 // Finalize code (at this point overflow() may be true, but the gap ensures
341 // (at this point overflow() may be true, but the gap ensures that 341 // that we are still not overlapping instructions and relocation info).
342 // we are still not overlapping instructions and relocation info) 342 ASSERT(pc_ <= reloc_info_writer.pos()); // No overlap.
343 ASSERT(pc_ <= reloc_info_writer.pos()); // no overlap 343 // Setup code descriptor.
344 // setup desc
345 desc->buffer = buffer_; 344 desc->buffer = buffer_;
346 desc->buffer_size = buffer_size_; 345 desc->buffer_size = buffer_size_;
347 desc->instr_size = pc_offset(); 346 desc->instr_size = pc_offset();
348 ASSERT(desc->instr_size > 0); // Zero-size code objects upset the system. 347 ASSERT(desc->instr_size > 0); // Zero-size code objects upset the system.
349 desc->reloc_size = 348 desc->reloc_size =
350 static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos()); 349 static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos());
351 desc->origin = this; 350 desc->origin = this;
352 351
353 Counters::reloc_info_size.Increment(desc->reloc_size); 352 Counters::reloc_info_size.Increment(desc->reloc_size);
354 } 353 }
355 354
356 355
357 void Assembler::Align(int m) { 356 void Assembler::Align(int m) {
358 ASSERT(IsPowerOf2(m)); 357 ASSERT(IsPowerOf2(m));
359 while ((pc_offset() & (m - 1)) != 0) { 358 while ((pc_offset() & (m - 1)) != 0) {
360 nop(); 359 nop();
361 } 360 }
362 } 361 }
363 362
364 363
365 void Assembler::bind_to(Label* L, int pos) { 364 void Assembler::bind_to(Label* L, int pos) {
366 ASSERT(!L->is_bound()); // Label may only be bound once. 365 ASSERT(!L->is_bound()); // Label may only be bound once.
367 last_pc_ = NULL; 366 last_pc_ = NULL;
368 ASSERT(0 <= pos && pos <= pc_offset()); // Position must be valid. 367 ASSERT(0 <= pos && pos <= pc_offset()); // Position must be valid.
369 if (L->is_linked()) { 368 if (L->is_linked()) {
370 int current = L->pos(); 369 int current = L->pos();
371 int next = long_at(current); 370 int next = long_at(current);
372 while (next != current) { 371 while (next != current) {
373 // relative address, relative to point after address 372 // Relative address, relative to point after address.
374 int imm32 = pos - (current + sizeof(int32_t)); 373 int imm32 = pos - (current + sizeof(int32_t));
375 long_at_put(current, imm32); 374 long_at_put(current, imm32);
376 current = next; 375 current = next;
377 next = long_at(next); 376 next = long_at(next);
378 } 377 }
379 // Fix up last fixup on linked list. 378 // Fix up last fixup on linked list.
380 int last_imm32 = pos - (current + sizeof(int32_t)); 379 int last_imm32 = pos - (current + sizeof(int32_t));
381 long_at_put(current, last_imm32); 380 long_at_put(current, last_imm32);
382 } 381 }
383 L->bind_to(pos); 382 L->bind_to(pos);
384 } 383 }
385 384
386 385
387 void Assembler::bind(Label* L) { 386 void Assembler::bind(Label* L) {
388 bind_to(L, pc_offset()); 387 bind_to(L, pc_offset());
389 } 388 }
390 389
391 390
392 void Assembler::GrowBuffer() { 391 void Assembler::GrowBuffer() {
393 ASSERT(buffer_overflow()); // should not call this otherwise 392 ASSERT(buffer_overflow());
394 if (!own_buffer_) FATAL("external code buffer is too small"); 393 if (!own_buffer_) FATAL("external code buffer is too small");
395 394
396 // compute new buffer size 395 // Compute new buffer size.
397 CodeDesc desc; // the new buffer 396 CodeDesc desc; // the new buffer
398 if (buffer_size_ < 4*KB) { 397 if (buffer_size_ < 4*KB) {
399 desc.buffer_size = 4*KB; 398 desc.buffer_size = 4*KB;
400 } else { 399 } else {
401 desc.buffer_size = 2*buffer_size_; 400 desc.buffer_size = 2*buffer_size_;
402 } 401 }
403 // Some internal data structures overflow for very large buffers, 402 // Some internal data structures overflow for very large buffers,
404 // they must ensure that kMaximalBufferSize is not too large. 403 // they must ensure that kMaximalBufferSize is not too large.
405 if ((desc.buffer_size > kMaximalBufferSize) || 404 if ((desc.buffer_size > kMaximalBufferSize) ||
406 (desc.buffer_size > Heap::MaxOldGenerationSize())) { 405 (desc.buffer_size > Heap::MaxOldGenerationSize())) {
407 V8::FatalProcessOutOfMemory("Assembler::GrowBuffer"); 406 V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
408 } 407 }
409 408
410 // setup new buffer 409 // Setup new buffer.
411 desc.buffer = NewArray<byte>(desc.buffer_size); 410 desc.buffer = NewArray<byte>(desc.buffer_size);
412 desc.instr_size = pc_offset(); 411 desc.instr_size = pc_offset();
413 desc.reloc_size = 412 desc.reloc_size =
414 static_cast<int>((buffer_ + buffer_size_) - (reloc_info_writer.pos())); 413 static_cast<int>((buffer_ + buffer_size_) - (reloc_info_writer.pos()));
415 414
416 // Clear the buffer in debug mode. Use 'int3' instructions to make 415 // Clear the buffer in debug mode. Use 'int3' instructions to make
417 // sure to get into problems if we ever run uninitialized code. 416 // sure to get into problems if we ever run uninitialized code.
418 #ifdef DEBUG 417 #ifdef DEBUG
419 memset(desc.buffer, 0xCC, desc.buffer_size); 418 memset(desc.buffer, 0xCC, desc.buffer_size);
420 #endif 419 #endif
421 420
422 // copy the data 421 // Copy the data.
423 intptr_t pc_delta = desc.buffer - buffer_; 422 intptr_t pc_delta = desc.buffer - buffer_;
424 intptr_t rc_delta = (desc.buffer + desc.buffer_size) - 423 intptr_t rc_delta = (desc.buffer + desc.buffer_size) -
425 (buffer_ + buffer_size_); 424 (buffer_ + buffer_size_);
426 memmove(desc.buffer, buffer_, desc.instr_size); 425 memmove(desc.buffer, buffer_, desc.instr_size);
427 memmove(rc_delta + reloc_info_writer.pos(), 426 memmove(rc_delta + reloc_info_writer.pos(),
428 reloc_info_writer.pos(), desc.reloc_size); 427 reloc_info_writer.pos(), desc.reloc_size);
429 428
430 // switch buffers 429 // Switch buffers.
431 if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) { 430 if (spare_buffer_ == NULL && buffer_size_ == kMinimalBufferSize) {
432 spare_buffer_ = buffer_; 431 spare_buffer_ = buffer_;
433 } else { 432 } else {
434 DeleteArray(buffer_); 433 DeleteArray(buffer_);
435 } 434 }
436 buffer_ = desc.buffer; 435 buffer_ = desc.buffer;
437 buffer_size_ = desc.buffer_size; 436 buffer_size_ = desc.buffer_size;
438 pc_ += pc_delta; 437 pc_ += pc_delta;
439 if (last_pc_ != NULL) { 438 if (last_pc_ != NULL) {
440 last_pc_ += pc_delta; 439 last_pc_ += pc_delta;
441 } 440 }
442 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta, 441 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
443 reloc_info_writer.last_pc() + pc_delta); 442 reloc_info_writer.last_pc() + pc_delta);
444 443
445 // relocate runtime entries 444 // Relocate runtime entries.
446 for (RelocIterator it(desc); !it.done(); it.next()) { 445 for (RelocIterator it(desc); !it.done(); it.next()) {
447 RelocInfo::Mode rmode = it.rinfo()->rmode(); 446 RelocInfo::Mode rmode = it.rinfo()->rmode();
448 if (rmode == RelocInfo::INTERNAL_REFERENCE) { 447 if (rmode == RelocInfo::INTERNAL_REFERENCE) {
449 intptr_t* p = reinterpret_cast<intptr_t*>(it.rinfo()->pc()); 448 intptr_t* p = reinterpret_cast<intptr_t*>(it.rinfo()->pc());
450 if (*p != 0) { // 0 means uninitialized. 449 if (*p != 0) { // 0 means uninitialized.
451 *p += pc_delta; 450 *p += pc_delta;
452 } 451 }
453 } 452 }
454 } 453 }
455 454
456 ASSERT(!buffer_overflow()); 455 ASSERT(!buffer_overflow());
457 } 456 }
458 457
459 458
460 void Assembler::emit_operand(int code, const Operand& adr) { 459 void Assembler::emit_operand(int code, const Operand& adr) {
461 ASSERT(is_uint3(code)); 460 ASSERT(is_uint3(code));
462 const unsigned length = adr.len_; 461 const unsigned length = adr.len_;
463 ASSERT(length > 0); 462 ASSERT(length > 0);
464 463
465 // Emit updated ModR/M byte containing the given register. 464 // Emit updated ModR/M byte containing the given register.
466 ASSERT((adr.buf_[0] & 0x38) == 0); 465 ASSERT((adr.buf_[0] & 0x38) == 0);
467 pc_[0] = adr.buf_[0] | code << 3; 466 pc_[0] = adr.buf_[0] | code << 3;
468 467
469 // Emit the rest of the encoded operand. 468 // Emit the rest of the encoded operand.
470 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; 469 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
471 pc_ += length; 470 pc_ += length;
472 } 471 }
473 472
474 473
475 // Assembler Instruction implementations 474 // Assembler Instruction implementations.
476 475
477 void Assembler::arithmetic_op(byte opcode, Register reg, const Operand& op) { 476 void Assembler::arithmetic_op(byte opcode, Register reg, const Operand& op) {
478 EnsureSpace ensure_space(this); 477 EnsureSpace ensure_space(this);
479 last_pc_ = pc_; 478 last_pc_ = pc_;
480 emit_rex_64(reg, op); 479 emit_rex_64(reg, op);
481 emit(opcode); 480 emit(opcode);
482 emit_operand(reg, op); 481 emit_operand(reg, op);
483 } 482 }
484 483
485 484
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 emit_rex_64(src, dst); 748 emit_rex_64(src, dst);
750 emit(0x0F); 749 emit(0x0F);
751 emit(0xAB); 750 emit(0xAB);
752 emit_operand(src, dst); 751 emit_operand(src, dst);
753 } 752 }
754 753
755 754
756 void Assembler::call(Label* L) { 755 void Assembler::call(Label* L) {
757 EnsureSpace ensure_space(this); 756 EnsureSpace ensure_space(this);
758 last_pc_ = pc_; 757 last_pc_ = pc_;
759 // 1110 1000 #32-bit disp 758 // 1110 1000 #32-bit disp.
760 emit(0xE8); 759 emit(0xE8);
761 if (L->is_bound()) { 760 if (L->is_bound()) {
762 int offset = L->pos() - pc_offset() - sizeof(int32_t); 761 int offset = L->pos() - pc_offset() - sizeof(int32_t);
763 ASSERT(offset <= 0); 762 ASSERT(offset <= 0);
764 emitl(offset); 763 emitl(offset);
765 } else if (L->is_linked()) { 764 } else if (L->is_linked()) {
766 emitl(L->pos()); 765 emitl(L->pos());
767 L->link_to(pc_offset() - sizeof(int32_t)); 766 L->link_to(pc_offset() - sizeof(int32_t));
768 } else { 767 } else {
769 ASSERT(L->is_unused()); 768 ASSERT(L->is_unused());
770 int32_t current = pc_offset(); 769 int32_t current = pc_offset();
771 emitl(current); 770 emitl(current);
772 L->link_to(current); 771 L->link_to(current);
773 } 772 }
774 } 773 }
775 774
776 775
777 void Assembler::call(Handle<Code> target, RelocInfo::Mode rmode) { 776 void Assembler::call(Handle<Code> target, RelocInfo::Mode rmode) {
778 EnsureSpace ensure_space(this); 777 EnsureSpace ensure_space(this);
779 last_pc_ = pc_; 778 last_pc_ = pc_;
780 // 1110 1000 #32-bit disp 779 // 1110 1000 #32-bit disp.
781 emit(0xE8); 780 emit(0xE8);
782 emit_code_target(target, rmode); 781 emit_code_target(target, rmode);
783 } 782 }
784 783
785 784
786 void Assembler::call(Register adr) { 785 void Assembler::call(Register adr) {
787 EnsureSpace ensure_space(this); 786 EnsureSpace ensure_space(this);
788 last_pc_ = pc_; 787 last_pc_ = pc_;
789 // Opcode: FF /2 r64 788 // Opcode: FF /2 r64.
790 if (adr.high_bit()) { 789 if (adr.high_bit()) {
791 emit_rex_64(adr); 790 emit_rex_64(adr);
792 } 791 }
793 emit(0xFF); 792 emit(0xFF);
794 emit_modrm(0x2, adr); 793 emit_modrm(0x2, adr);
795 } 794 }
796 795
797 796
798 void Assembler::call(const Operand& op) { 797 void Assembler::call(const Operand& op) {
799 EnsureSpace ensure_space(this); 798 EnsureSpace ensure_space(this);
800 last_pc_ = pc_; 799 last_pc_ = pc_;
801 // Opcode: FF /2 m64 800 // Opcode: FF /2 m64.
802 emit_rex_64(op); 801 emit_rex_64(op);
803 emit(0xFF); 802 emit(0xFF);
804 emit_operand(2, op); 803 emit_operand(2, op);
805 } 804 }
806 805
807 806
808 void Assembler::clc() { 807 void Assembler::clc() {
809 EnsureSpace ensure_space(this); 808 EnsureSpace ensure_space(this);
810 last_pc_ = pc_; 809 last_pc_ = pc_;
811 emit(0xF8); 810 emit(0xF8);
(...skipping 10 matching lines...) Expand all
822 if (cc == always) { 821 if (cc == always) {
823 movq(dst, src); 822 movq(dst, src);
824 } else if (cc == never) { 823 } else if (cc == never) {
825 return; 824 return;
826 } 825 }
827 // No need to check CpuInfo for CMOV support, it's a required part of the 826 // No need to check CpuInfo for CMOV support, it's a required part of the
828 // 64-bit architecture. 827 // 64-bit architecture.
829 ASSERT(cc >= 0); // Use mov for unconditional moves. 828 ASSERT(cc >= 0); // Use mov for unconditional moves.
830 EnsureSpace ensure_space(this); 829 EnsureSpace ensure_space(this);
831 last_pc_ = pc_; 830 last_pc_ = pc_;
832 // Opcode: REX.W 0f 40 + cc /r 831 // Opcode: REX.W 0f 40 + cc /r.
833 emit_rex_64(dst, src); 832 emit_rex_64(dst, src);
834 emit(0x0f); 833 emit(0x0f);
835 emit(0x40 + cc); 834 emit(0x40 + cc);
836 emit_modrm(dst, src); 835 emit_modrm(dst, src);
837 } 836 }
838 837
839 838
840 void Assembler::cmovq(Condition cc, Register dst, const Operand& src) { 839 void Assembler::cmovq(Condition cc, Register dst, const Operand& src) {
841 if (cc == always) { 840 if (cc == always) {
842 movq(dst, src); 841 movq(dst, src);
843 } else if (cc == never) { 842 } else if (cc == never) {
844 return; 843 return;
845 } 844 }
846 ASSERT(cc >= 0); 845 ASSERT(cc >= 0);
847 EnsureSpace ensure_space(this); 846 EnsureSpace ensure_space(this);
848 last_pc_ = pc_; 847 last_pc_ = pc_;
849 // Opcode: REX.W 0f 40 + cc /r 848 // Opcode: REX.W 0f 40 + cc /r.
850 emit_rex_64(dst, src); 849 emit_rex_64(dst, src);
851 emit(0x0f); 850 emit(0x0f);
852 emit(0x40 + cc); 851 emit(0x40 + cc);
853 emit_operand(dst, src); 852 emit_operand(dst, src);
854 } 853 }
855 854
856 855
857 void Assembler::cmovl(Condition cc, Register dst, Register src) { 856 void Assembler::cmovl(Condition cc, Register dst, Register src) {
858 if (cc == always) { 857 if (cc == always) {
859 movl(dst, src); 858 movl(dst, src);
860 } else if (cc == never) { 859 } else if (cc == never) {
861 return; 860 return;
862 } 861 }
863 ASSERT(cc >= 0); 862 ASSERT(cc >= 0);
864 EnsureSpace ensure_space(this); 863 EnsureSpace ensure_space(this);
865 last_pc_ = pc_; 864 last_pc_ = pc_;
866 // Opcode: 0f 40 + cc /r 865 // Opcode: 0f 40 + cc /r.
867 emit_optional_rex_32(dst, src); 866 emit_optional_rex_32(dst, src);
868 emit(0x0f); 867 emit(0x0f);
869 emit(0x40 + cc); 868 emit(0x40 + cc);
870 emit_modrm(dst, src); 869 emit_modrm(dst, src);
871 } 870 }
872 871
873 872
874 void Assembler::cmovl(Condition cc, Register dst, const Operand& src) { 873 void Assembler::cmovl(Condition cc, Register dst, const Operand& src) {
875 if (cc == always) { 874 if (cc == always) {
876 movl(dst, src); 875 movl(dst, src);
877 } else if (cc == never) { 876 } else if (cc == never) {
878 return; 877 return;
879 } 878 }
880 ASSERT(cc >= 0); 879 ASSERT(cc >= 0);
881 EnsureSpace ensure_space(this); 880 EnsureSpace ensure_space(this);
882 last_pc_ = pc_; 881 last_pc_ = pc_;
883 // Opcode: 0f 40 + cc /r 882 // Opcode: 0f 40 + cc /r.
884 emit_optional_rex_32(dst, src); 883 emit_optional_rex_32(dst, src);
885 emit(0x0f); 884 emit(0x0f);
886 emit(0x40 + cc); 885 emit(0x40 + cc);
887 emit_operand(dst, src); 886 emit_operand(dst, src);
888 } 887 }
889 888
890 889
891 void Assembler::cmpb_al(Immediate imm8) { 890 void Assembler::cmpb_al(Immediate imm8) {
892 ASSERT(is_int8(imm8.value_) || is_uint8(imm8.value_)); 891 ASSERT(is_int8(imm8.value_) || is_uint8(imm8.value_));
893 EnsureSpace ensure_space(this); 892 EnsureSpace ensure_space(this);
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1103 } 1102 }
1104 EnsureSpace ensure_space(this); 1103 EnsureSpace ensure_space(this);
1105 last_pc_ = pc_; 1104 last_pc_ = pc_;
1106 ASSERT(is_uint4(cc)); 1105 ASSERT(is_uint4(cc));
1107 if (L->is_bound()) { 1106 if (L->is_bound()) {
1108 const int short_size = 2; 1107 const int short_size = 2;
1109 const int long_size = 6; 1108 const int long_size = 6;
1110 int offs = L->pos() - pc_offset(); 1109 int offs = L->pos() - pc_offset();
1111 ASSERT(offs <= 0); 1110 ASSERT(offs <= 0);
1112 if (is_int8(offs - short_size)) { 1111 if (is_int8(offs - short_size)) {
1113 // 0111 tttn #8-bit disp 1112 // 0111 tttn #8-bit disp.
1114 emit(0x70 | cc); 1113 emit(0x70 | cc);
1115 emit((offs - short_size) & 0xFF); 1114 emit((offs - short_size) & 0xFF);
1116 } else { 1115 } else {
1117 // 0000 1111 1000 tttn #32-bit disp 1116 // 0000 1111 1000 tttn #32-bit disp.
1118 emit(0x0F); 1117 emit(0x0F);
1119 emit(0x80 | cc); 1118 emit(0x80 | cc);
1120 emitl(offs - long_size); 1119 emitl(offs - long_size);
1121 } 1120 }
1122 } else if (L->is_linked()) { 1121 } else if (L->is_linked()) {
1123 // 0000 1111 1000 tttn #32-bit disp 1122 // 0000 1111 1000 tttn #32-bit disp.
1124 emit(0x0F); 1123 emit(0x0F);
1125 emit(0x80 | cc); 1124 emit(0x80 | cc);
1126 emitl(L->pos()); 1125 emitl(L->pos());
1127 L->link_to(pc_offset() - sizeof(int32_t)); 1126 L->link_to(pc_offset() - sizeof(int32_t));
1128 } else { 1127 } else {
1129 ASSERT(L->is_unused()); 1128 ASSERT(L->is_unused());
1130 emit(0x0F); 1129 emit(0x0F);
1131 emit(0x80 | cc); 1130 emit(0x80 | cc);
1132 int32_t current = pc_offset(); 1131 int32_t current = pc_offset();
1133 emitl(current); 1132 emitl(current);
1134 L->link_to(current); 1133 L->link_to(current);
1135 } 1134 }
1136 } 1135 }
1137 1136
1138 1137
1139 void Assembler::j(Condition cc, 1138 void Assembler::j(Condition cc,
1140 Handle<Code> target, 1139 Handle<Code> target,
1141 RelocInfo::Mode rmode) { 1140 RelocInfo::Mode rmode) {
1142 EnsureSpace ensure_space(this); 1141 EnsureSpace ensure_space(this);
1143 last_pc_ = pc_; 1142 last_pc_ = pc_;
1144 ASSERT(is_uint4(cc)); 1143 ASSERT(is_uint4(cc));
1145 // 0000 1111 1000 tttn #32-bit disp 1144 // 0000 1111 1000 tttn #32-bit disp.
1146 emit(0x0F); 1145 emit(0x0F);
1147 emit(0x80 | cc); 1146 emit(0x80 | cc);
1148 emit_code_target(target, rmode); 1147 emit_code_target(target, rmode);
1149 } 1148 }
1150 1149
1151 1150
1152 void Assembler::jmp(Label* L) { 1151 void Assembler::jmp(Label* L) {
1153 EnsureSpace ensure_space(this); 1152 EnsureSpace ensure_space(this);
1154 last_pc_ = pc_; 1153 last_pc_ = pc_;
1155 if (L->is_bound()) { 1154 if (L->is_bound()) {
1156 int offs = L->pos() - pc_offset() - 1; 1155 int offs = L->pos() - pc_offset() - 1;
1157 ASSERT(offs <= 0); 1156 ASSERT(offs <= 0);
1158 if (is_int8(offs - sizeof(int8_t))) { 1157 if (is_int8(offs - sizeof(int8_t))) {
1159 // 1110 1011 #8-bit disp 1158 // 1110 1011 #8-bit disp.
1160 emit(0xEB); 1159 emit(0xEB);
1161 emit((offs - sizeof(int8_t)) & 0xFF); 1160 emit((offs - sizeof(int8_t)) & 0xFF);
1162 } else { 1161 } else {
1163 // 1110 1001 #32-bit disp 1162 // 1110 1001 #32-bit disp.
1164 emit(0xE9); 1163 emit(0xE9);
1165 emitl(offs - sizeof(int32_t)); 1164 emitl(offs - sizeof(int32_t));
1166 } 1165 }
1167 } else if (L->is_linked()) { 1166 } else if (L->is_linked()) {
1168 // 1110 1001 #32-bit disp 1167 // 1110 1001 #32-bit disp.
1169 emit(0xE9); 1168 emit(0xE9);
1170 emitl(L->pos()); 1169 emitl(L->pos());
1171 L->link_to(pc_offset() - sizeof(int32_t)); 1170 L->link_to(pc_offset() - sizeof(int32_t));
1172 } else { 1171 } else {
1173 // 1110 1001 #32-bit disp 1172 // 1110 1001 #32-bit disp.
1174 ASSERT(L->is_unused()); 1173 ASSERT(L->is_unused());
1175 emit(0xE9); 1174 emit(0xE9);
1176 int32_t current = pc_offset(); 1175 int32_t current = pc_offset();
1177 emitl(current); 1176 emitl(current);
1178 L->link_to(current); 1177 L->link_to(current);
1179 } 1178 }
1180 } 1179 }
1181 1180
1182 1181
1183 void Assembler::jmp(Handle<Code> target, RelocInfo::Mode rmode) { 1182 void Assembler::jmp(Handle<Code> target, RelocInfo::Mode rmode) {
1184 EnsureSpace ensure_space(this); 1183 EnsureSpace ensure_space(this);
1185 last_pc_ = pc_; 1184 last_pc_ = pc_;
1186 // 1110 1001 #32-bit disp 1185 // 1110 1001 #32-bit disp.
1187 emit(0xE9); 1186 emit(0xE9);
1188 emit_code_target(target, rmode); 1187 emit_code_target(target, rmode);
1189 } 1188 }
1190 1189
1191 1190
1192 void Assembler::jmp(Register target) { 1191 void Assembler::jmp(Register target) {
1193 EnsureSpace ensure_space(this); 1192 EnsureSpace ensure_space(this);
1194 last_pc_ = pc_; 1193 last_pc_ = pc_;
1195 // Opcode FF/4 r64 1194 // Opcode FF/4 r64.
1196 if (target.high_bit()) { 1195 if (target.high_bit()) {
1197 emit_rex_64(target); 1196 emit_rex_64(target);
1198 } 1197 }
1199 emit(0xFF); 1198 emit(0xFF);
1200 emit_modrm(0x4, target); 1199 emit_modrm(0x4, target);
1201 } 1200 }
1202 1201
1203 1202
1204 void Assembler::jmp(const Operand& src) { 1203 void Assembler::jmp(const Operand& src) {
1205 EnsureSpace ensure_space(this); 1204 EnsureSpace ensure_space(this);
1206 last_pc_ = pc_; 1205 last_pc_ = pc_;
1207 // Opcode FF/4 m64 1206 // Opcode FF/4 m64.
1208 emit_optional_rex_32(src); 1207 emit_optional_rex_32(src);
1209 emit(0xFF); 1208 emit(0xFF);
1210 emit_operand(0x4, src); 1209 emit_operand(0x4, src);
1211 } 1210 }
1212 1211
1213 1212
1214 void Assembler::lea(Register dst, const Operand& src) { 1213 void Assembler::lea(Register dst, const Operand& src) {
1215 EnsureSpace ensure_space(this); 1214 EnsureSpace ensure_space(this);
1216 last_pc_ = pc_; 1215 last_pc_ = pc_;
1217 emit_rex_64(dst, src); 1216 emit_rex_64(dst, src);
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
1406 void Assembler::movq(const Operand& dst, Immediate value) { 1405 void Assembler::movq(const Operand& dst, Immediate value) {
1407 EnsureSpace ensure_space(this); 1406 EnsureSpace ensure_space(this);
1408 last_pc_ = pc_; 1407 last_pc_ = pc_;
1409 emit_rex_64(dst); 1408 emit_rex_64(dst);
1410 emit(0xC7); 1409 emit(0xC7);
1411 emit_operand(0, dst); 1410 emit_operand(0, dst);
1412 emit(value); 1411 emit(value);
1413 } 1412 }
1414 1413
1415 1414
1416 /* 1415 // Loads the ip-relative location of the src label into the target location
1417 * Loads the ip-relative location of the src label into the target 1416 // (as a 32-bit offset sign extended to 64-bit).
1418 * location (as a 32-bit offset sign extended to 64-bit).
1419 */
1420 void Assembler::movl(const Operand& dst, Label* src) { 1417 void Assembler::movl(const Operand& dst, Label* src) {
1421 EnsureSpace ensure_space(this); 1418 EnsureSpace ensure_space(this);
1422 last_pc_ = pc_; 1419 last_pc_ = pc_;
1423 emit_optional_rex_32(dst); 1420 emit_optional_rex_32(dst);
1424 emit(0xC7); 1421 emit(0xC7);
1425 emit_operand(0, dst); 1422 emit_operand(0, dst);
1426 if (src->is_bound()) { 1423 if (src->is_bound()) {
1427 int offset = src->pos() - pc_offset() - sizeof(int32_t); 1424 int offset = src->pos() - pc_offset() - sizeof(int32_t);
1428 ASSERT(offset <= 0); 1425 ASSERT(offset <= 0);
1429 emitl(offset); 1426 emitl(offset);
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after
1999 emit(mask); 1996 emit(mask);
2000 } else { 1997 } else {
2001 emit_rex_64(dst); 1998 emit_rex_64(dst);
2002 emit(0xF7); 1999 emit(0xF7);
2003 emit_modrm(0, dst); 2000 emit_modrm(0, dst);
2004 emit(mask); 2001 emit(mask);
2005 } 2002 }
2006 } 2003 }
2007 2004
2008 2005
2009 // FPU instructions 2006 // FPU instructions.
2010 2007
2011 2008
2012 void Assembler::fld(int i) { 2009 void Assembler::fld(int i) {
2013 EnsureSpace ensure_space(this); 2010 EnsureSpace ensure_space(this);
2014 last_pc_ = pc_; 2011 last_pc_ = pc_;
2015 emit_farith(0xD9, 0xC0, i); 2012 emit_farith(0xD9, 0xC0, i);
2016 } 2013 }
2017 2014
2018 2015
2019 void Assembler::fld1() { 2016 void Assembler::fld1() {
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
2370 } 2367 }
2371 2368
2372 2369
2373 void Assembler::emit_farith(int b1, int b2, int i) { 2370 void Assembler::emit_farith(int b1, int b2, int i) {
2374 ASSERT(is_uint8(b1) && is_uint8(b2)); // wrong opcode 2371 ASSERT(is_uint8(b1) && is_uint8(b2)); // wrong opcode
2375 ASSERT(is_uint3(i)); // illegal stack offset 2372 ASSERT(is_uint3(i)); // illegal stack offset
2376 emit(b1); 2373 emit(b1);
2377 emit(b2 + i); 2374 emit(b2 + i);
2378 } 2375 }
2379 2376
2380 // SSE 2 operations 2377 // SSE 2 operations.
2381 2378
2382 void Assembler::movsd(const Operand& dst, XMMRegister src) { 2379 void Assembler::movsd(const Operand& dst, XMMRegister src) {
2383 EnsureSpace ensure_space(this); 2380 EnsureSpace ensure_space(this);
2384 last_pc_ = pc_; 2381 last_pc_ = pc_;
2385 emit(0xF2); // double 2382 emit(0xF2); // double
2386 emit_optional_rex_32(src, dst); 2383 emit_optional_rex_32(src, dst);
2387 emit(0x0F); 2384 emit(0x0F);
2388 emit(0x11); // store 2385 emit(0x11); // store
2389 emit_sse_operand(src, dst); 2386 emit_sse_operand(src, dst);
2390 } 2387 }
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
2520 2517
2521 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) { 2518 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
2522 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits()); 2519 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
2523 } 2520 }
2524 2521
2525 void Assembler::emit_sse_operand(XMMRegister dst, Register src) { 2522 void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
2526 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits()); 2523 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
2527 } 2524 }
2528 2525
2529 2526
2530 // Relocation information implementations 2527 // Relocation information implementations.
2531 2528
2532 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { 2529 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2533 ASSERT(rmode != RelocInfo::NONE); 2530 ASSERT(rmode != RelocInfo::NONE);
2534 // Don't record external references unless the heap will be serialized. 2531 // Don't record external references unless the heap will be serialized.
2535 if (rmode == RelocInfo::EXTERNAL_REFERENCE && 2532 if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
2536 !Serializer::enabled() && 2533 !Serializer::enabled() &&
2537 !FLAG_debug_code) { 2534 !FLAG_debug_code) {
2538 return; 2535 return;
2539 } 2536 }
2540 RelocInfo rinfo(pc_, rmode, data); 2537 RelocInfo rinfo(pc_, rmode, data);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2588 written_position_ = current_position_; 2585 written_position_ = current_position_;
2589 } 2586 }
2590 } 2587 }
2591 2588
2592 2589
2593 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask | 2590 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
2594 1 << RelocInfo::INTERNAL_REFERENCE | 2591 1 << RelocInfo::INTERNAL_REFERENCE |
2595 1 << RelocInfo::JS_RETURN; 2592 1 << RelocInfo::JS_RETURN;
2596 2593
2597 } } // namespace v8::internal 2594 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/assembler-x64.h ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698