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

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

Issue 2084017: Version 2.2.11... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 10 years, 7 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/ia32/assembler-ia32.h ('k') | src/ia32/assembler-ia32-inl.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 (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 5 // modification, are permitted provided that the following conditions
6 // are met: 6 // are 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 18 matching lines...) Expand all
29 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31 // OF THE POSSIBILITY OF SUCH DAMAGE. 31 // OF THE POSSIBILITY OF SUCH DAMAGE.
32 32
33 // The original source code covered by the above license above has been modified 33 // The original source code covered by the above license above has been modified
34 // significantly by Google Inc. 34 // significantly by Google Inc.
35 // Copyright 2006-2008 the V8 project authors. All rights reserved. 35 // Copyright 2006-2008 the V8 project authors. All rights reserved.
36 36
37 #include "v8.h" 37 #include "v8.h"
38 38
39 #if defined(V8_TARGET_ARCH_IA32)
40
39 #include "disassembler.h" 41 #include "disassembler.h"
40 #include "macro-assembler.h" 42 #include "macro-assembler.h"
41 #include "serialize.h" 43 #include "serialize.h"
42 44
43 namespace v8 { 45 namespace v8 {
44 namespace internal { 46 namespace internal {
45 47
46 // ----------------------------------------------------------------------------- 48 // -----------------------------------------------------------------------------
47 // Implementation of CpuFeatures 49 // Implementation of CpuFeatures
48 50
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 155
154 // ----------------------------------------------------------------------------- 156 // -----------------------------------------------------------------------------
155 // Implementation of RelocInfo 157 // Implementation of RelocInfo
156 158
157 159
158 const int RelocInfo::kApplyMask = 160 const int RelocInfo::kApplyMask =
159 RelocInfo::kCodeTargetMask | 1 << RelocInfo::RUNTIME_ENTRY | 161 RelocInfo::kCodeTargetMask | 1 << RelocInfo::RUNTIME_ENTRY |
160 1 << RelocInfo::JS_RETURN | 1 << RelocInfo::INTERNAL_REFERENCE; 162 1 << RelocInfo::JS_RETURN | 1 << RelocInfo::INTERNAL_REFERENCE;
161 163
162 164
165 bool RelocInfo::IsCodedSpecially() {
166 // The deserializer needs to know whether a pointer is specially coded. Being
167 // specially coded on IA32 means that it is a relative address, as used by
168 // branch instructions. These are also the ones that need changing when a
169 // code object moves.
170 return (1 << rmode_) & kApplyMask;
171 }
172
173
163 void RelocInfo::PatchCode(byte* instructions, int instruction_count) { 174 void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
164 // Patch the code at the current address with the supplied instructions. 175 // Patch the code at the current address with the supplied instructions.
165 for (int i = 0; i < instruction_count; i++) { 176 for (int i = 0; i < instruction_count; i++) {
166 *(pc_ + i) = *(instructions + i); 177 *(pc_ + i) = *(instructions + i);
167 } 178 }
168 179
169 // Indicate that code has changed. 180 // Indicate that code has changed.
170 CPU::FlushICache(pc_, instruction_count); 181 CPU::FlushICache(pc_, instruction_count);
171 } 182 }
172 183
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 void Assembler::push(const Operand& src) { 437 void Assembler::push(const Operand& src) {
427 EnsureSpace ensure_space(this); 438 EnsureSpace ensure_space(this);
428 last_pc_ = pc_; 439 last_pc_ = pc_;
429 EMIT(0xFF); 440 EMIT(0xFF);
430 emit_operand(esi, src); 441 emit_operand(esi, src);
431 } 442 }
432 443
433 444
434 void Assembler::pop(Register dst) { 445 void Assembler::pop(Register dst) {
435 ASSERT(reloc_info_writer.last_pc() != NULL); 446 ASSERT(reloc_info_writer.last_pc() != NULL);
436 if (FLAG_push_pop_elimination && (reloc_info_writer.last_pc() <= last_pc_)) { 447 if (FLAG_peephole_optimization && (reloc_info_writer.last_pc() <= last_pc_)) {
437 // (last_pc_ != NULL) is rolled into the above check. 448 // (last_pc_ != NULL) is rolled into the above check.
438 // If a last_pc_ is set, we need to make sure that there has not been any 449 // If a last_pc_ is set, we need to make sure that there has not been any
439 // relocation information generated between the last instruction and this 450 // relocation information generated between the last instruction and this
440 // pop instruction. 451 // pop instruction.
441 byte instr = last_pc_[0]; 452 byte instr = last_pc_[0];
442 if ((instr & ~0x7) == 0x50) { 453 if ((instr & ~0x7) == 0x50) {
443 int push_reg_code = instr & 0x7; 454 int push_reg_code = instr & 0x7;
444 if (push_reg_code == dst.code()) { 455 if (push_reg_code == dst.code()) {
445 pc_ = last_pc_; 456 pc_ = last_pc_;
446 if (FLAG_print_push_pop_elimination) { 457 if (FLAG_print_peephole_optimization) {
447 PrintF("%d push/pop (same reg) eliminated\n", pc_offset()); 458 PrintF("%d push/pop (same reg) eliminated\n", pc_offset());
448 } 459 }
449 } else { 460 } else {
450 // Convert 'push src; pop dst' to 'mov dst, src'. 461 // Convert 'push src; pop dst' to 'mov dst, src'.
451 last_pc_[0] = 0x8b; 462 last_pc_[0] = 0x8b;
452 Register src = { push_reg_code }; 463 Register src = { push_reg_code };
453 EnsureSpace ensure_space(this); 464 EnsureSpace ensure_space(this);
454 emit_operand(dst, Operand(src)); 465 emit_operand(dst, Operand(src));
455 if (FLAG_print_push_pop_elimination) { 466 if (FLAG_print_peephole_optimization) {
456 PrintF("%d push/pop (reg->reg) eliminated\n", pc_offset()); 467 PrintF("%d push/pop (reg->reg) eliminated\n", pc_offset());
457 } 468 }
458 } 469 }
459 last_pc_ = NULL; 470 last_pc_ = NULL;
460 return; 471 return;
461 } else if (instr == 0xff) { // push of an operand, convert to a move 472 } else if (instr == 0xff) { // push of an operand, convert to a move
462 byte op1 = last_pc_[1]; 473 byte op1 = last_pc_[1];
463 // Check if the operation is really a push. 474 // Check if the operation is really a push.
464 if ((op1 & 0x38) == (6 << 3)) { 475 if ((op1 & 0x38) == (6 << 3)) {
465 op1 = (op1 & ~0x38) | static_cast<byte>(dst.code() << 3); 476 op1 = (op1 & ~0x38) | static_cast<byte>(dst.code() << 3);
466 last_pc_[0] = 0x8b; 477 last_pc_[0] = 0x8b;
467 last_pc_[1] = op1; 478 last_pc_[1] = op1;
468 last_pc_ = NULL; 479 last_pc_ = NULL;
469 if (FLAG_print_push_pop_elimination) { 480 if (FLAG_print_peephole_optimization) {
470 PrintF("%d push/pop (op->reg) eliminated\n", pc_offset()); 481 PrintF("%d push/pop (op->reg) eliminated\n", pc_offset());
471 } 482 }
472 return; 483 return;
473 } 484 }
474 } else if ((instr == 0x89) && 485 } else if ((instr == 0x89) &&
475 (last_pc_[1] == 0x04) && 486 (last_pc_[1] == 0x04) &&
476 (last_pc_[2] == 0x24)) { 487 (last_pc_[2] == 0x24)) {
477 // 0x71283c 396 890424 mov [esp],eax 488 // 0x71283c 396 890424 mov [esp],eax
478 // 0x71283f 399 58 pop eax 489 // 0x71283f 399 58 pop eax
479 if (dst.is(eax)) { 490 if (dst.is(eax)) {
480 // change to 491 // change to
481 // 0x710fac 216 83c404 add esp,0x4 492 // 0x710fac 216 83c404 add esp,0x4
482 last_pc_[0] = 0x83; 493 last_pc_[0] = 0x83;
483 last_pc_[1] = 0xc4; 494 last_pc_[1] = 0xc4;
484 last_pc_[2] = 0x04; 495 last_pc_[2] = 0x04;
485 last_pc_ = NULL; 496 last_pc_ = NULL;
486 if (FLAG_print_push_pop_elimination) { 497 if (FLAG_print_peephole_optimization) {
487 PrintF("%d push/pop (mov-pop) eliminated\n", pc_offset()); 498 PrintF("%d push/pop (mov-pop) eliminated\n", pc_offset());
488 } 499 }
489 return; 500 return;
490 } 501 }
491 } else if (instr == 0x6a && dst.is(eax)) { // push of immediate 8 bit 502 } else if (instr == 0x6a && dst.is(eax)) { // push of immediate 8 bit
492 byte imm8 = last_pc_[1]; 503 byte imm8 = last_pc_[1];
493 if (imm8 == 0) { 504 if (imm8 == 0) {
494 // 6a00 push 0x0 505 // 6a00 push 0x0
495 // 58 pop eax 506 // 58 pop eax
496 last_pc_[0] = 0x31; 507 last_pc_[0] = 0x31;
497 last_pc_[1] = 0xc0; 508 last_pc_[1] = 0xc0;
498 // change to 509 // change to
499 // 31c0 xor eax,eax 510 // 31c0 xor eax,eax
500 last_pc_ = NULL; 511 last_pc_ = NULL;
501 if (FLAG_print_push_pop_elimination) { 512 if (FLAG_print_peephole_optimization) {
502 PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset()); 513 PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset());
503 } 514 }
504 return; 515 return;
505 } else { 516 } else {
506 // 6a00 push 0xXX 517 // 6a00 push 0xXX
507 // 58 pop eax 518 // 58 pop eax
508 last_pc_[0] = 0xb8; 519 last_pc_[0] = 0xb8;
509 EnsureSpace ensure_space(this); 520 EnsureSpace ensure_space(this);
510 if ((imm8 & 0x80) != 0) { 521 if ((imm8 & 0x80) != 0) {
511 EMIT(0xff); 522 EMIT(0xff);
512 EMIT(0xff); 523 EMIT(0xff);
513 EMIT(0xff); 524 EMIT(0xff);
514 // change to 525 // change to
515 // b8XXffffff mov eax,0xffffffXX 526 // b8XXffffff mov eax,0xffffffXX
516 } else { 527 } else {
517 EMIT(0x00); 528 EMIT(0x00);
518 EMIT(0x00); 529 EMIT(0x00);
519 EMIT(0x00); 530 EMIT(0x00);
520 // change to 531 // change to
521 // b8XX000000 mov eax,0x000000XX 532 // b8XX000000 mov eax,0x000000XX
522 } 533 }
523 last_pc_ = NULL; 534 last_pc_ = NULL;
524 if (FLAG_print_push_pop_elimination) { 535 if (FLAG_print_peephole_optimization) {
525 PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset()); 536 PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset());
526 } 537 }
527 return; 538 return;
528 } 539 }
529 } else if (instr == 0x68 && dst.is(eax)) { // push of immediate 32 bit 540 } else if (instr == 0x68 && dst.is(eax)) { // push of immediate 32 bit
530 // 68XXXXXXXX push 0xXXXXXXXX 541 // 68XXXXXXXX push 0xXXXXXXXX
531 // 58 pop eax 542 // 58 pop eax
532 last_pc_[0] = 0xb8; 543 last_pc_[0] = 0xb8;
533 last_pc_ = NULL; 544 last_pc_ = NULL;
534 // change to 545 // change to
535 // b8XXXXXXXX mov eax,0xXXXXXXXX 546 // b8XXXXXXXX mov eax,0xXXXXXXXX
536 if (FLAG_print_push_pop_elimination) { 547 if (FLAG_print_peephole_optimization) {
537 PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset()); 548 PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset());
538 } 549 }
539 return; 550 return;
540 } 551 }
541 552
542 // Other potential patterns for peephole: 553 // Other potential patterns for peephole:
543 // 0x712716 102 890424 mov [esp], eax 554 // 0x712716 102 890424 mov [esp], eax
544 // 0x712719 105 8b1424 mov edx, [esp] 555 // 0x712719 105 8b1424 mov edx, [esp]
545 } 556 }
546 EnsureSpace ensure_space(this); 557 EnsureSpace ensure_space(this);
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 780
770 781
771 void Assembler::rep_stos() { 782 void Assembler::rep_stos() {
772 EnsureSpace ensure_space(this); 783 EnsureSpace ensure_space(this);
773 last_pc_ = pc_; 784 last_pc_ = pc_;
774 EMIT(0xF3); 785 EMIT(0xF3);
775 EMIT(0xAB); 786 EMIT(0xAB);
776 } 787 }
777 788
778 789
790 void Assembler::stos() {
791 EnsureSpace ensure_space(this);
792 last_pc_ = pc_;
793 EMIT(0xAB);
794 }
795
796
779 void Assembler::xchg(Register dst, Register src) { 797 void Assembler::xchg(Register dst, Register src) {
780 EnsureSpace ensure_space(this); 798 EnsureSpace ensure_space(this);
781 last_pc_ = pc_; 799 last_pc_ = pc_;
782 if (src.is(eax) || dst.is(eax)) { // Single-byte encoding. 800 if (src.is(eax) || dst.is(eax)) { // Single-byte encoding.
783 EMIT(0x90 | (src.is(eax) ? dst.code() : src.code())); 801 EMIT(0x90 | (src.is(eax) ? dst.code() : src.code()));
784 } else { 802 } else {
785 EMIT(0x87); 803 EMIT(0x87);
786 EMIT(0xC0 | src.code() << 3 | dst.code()); 804 EMIT(0xC0 | src.code() << 3 | dst.code());
787 } 805 }
788 } 806 }
(...skipping 17 matching lines...) Expand all
806 void Assembler::add(Register dst, const Operand& src) { 824 void Assembler::add(Register dst, const Operand& src) {
807 EnsureSpace ensure_space(this); 825 EnsureSpace ensure_space(this);
808 last_pc_ = pc_; 826 last_pc_ = pc_;
809 EMIT(0x03); 827 EMIT(0x03);
810 emit_operand(dst, src); 828 emit_operand(dst, src);
811 } 829 }
812 830
813 831
814 void Assembler::add(const Operand& dst, const Immediate& x) { 832 void Assembler::add(const Operand& dst, const Immediate& x) {
815 ASSERT(reloc_info_writer.last_pc() != NULL); 833 ASSERT(reloc_info_writer.last_pc() != NULL);
816 if (FLAG_push_pop_elimination && (reloc_info_writer.last_pc() <= last_pc_)) { 834 if (FLAG_peephole_optimization && (reloc_info_writer.last_pc() <= last_pc_)) {
817 byte instr = last_pc_[0]; 835 byte instr = last_pc_[0];
818 if ((instr & 0xf8) == 0x50) { 836 if ((instr & 0xf8) == 0x50) {
819 // Last instruction was a push. Check whether this is a pop without a 837 // Last instruction was a push. Check whether this is a pop without a
820 // result. 838 // result.
821 if ((dst.is_reg(esp)) && 839 if ((dst.is_reg(esp)) &&
822 (x.x_ == kPointerSize) && (x.rmode_ == RelocInfo::NONE)) { 840 (x.x_ == kPointerSize) && (x.rmode_ == RelocInfo::NONE)) {
823 pc_ = last_pc_; 841 pc_ = last_pc_;
824 last_pc_ = NULL; 842 last_pc_ = NULL;
825 if (FLAG_print_push_pop_elimination) { 843 if (FLAG_print_peephole_optimization) {
826 PrintF("%d push/pop(noreg) eliminated\n", pc_offset()); 844 PrintF("%d push/pop(noreg) eliminated\n", pc_offset());
827 } 845 }
828 return; 846 return;
829 } 847 }
830 } 848 }
831 } 849 }
832 EnsureSpace ensure_space(this); 850 EnsureSpace ensure_space(this);
833 last_pc_ = pc_; 851 last_pc_ = pc_;
834 emit_arith(0, dst, x); 852 emit_arith(0, dst, x);
835 } 853 }
(...skipping 1685 matching lines...) Expand 10 before | Expand all | Expand 10 after
2521 push_insn[1] = 13; // Skip over coverage insns. 2539 push_insn[1] = 13; // Skip over coverage insns.
2522 if (coverage_log != NULL) { 2540 if (coverage_log != NULL) {
2523 fprintf(coverage_log, "%s\n", file_line); 2541 fprintf(coverage_log, "%s\n", file_line);
2524 fflush(coverage_log); 2542 fflush(coverage_log);
2525 } 2543 }
2526 } 2544 }
2527 2545
2528 #endif 2546 #endif
2529 2547
2530 } } // namespace v8::internal 2548 } } // namespace v8::internal
2549
2550 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/assembler-ia32.h ('k') | src/ia32/assembler-ia32-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698