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 | 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 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 int shift_imm_; // valid if rm_ != no_reg && rs_ == no_reg | 369 int shift_imm_; // valid if rm_ != no_reg && rs_ == no_reg |
370 AddrMode am_; // bits P, U, and W | 370 AddrMode am_; // bits P, U, and W |
371 | 371 |
372 friend class Assembler; | 372 friend class Assembler; |
373 }; | 373 }; |
374 | 374 |
375 | 375 |
376 typedef int32_t Instr; | 376 typedef int32_t Instr; |
377 | 377 |
378 | 378 |
| 379 extern const Instr kMovLrPc; |
| 380 extern const Instr kLdrPCPattern; |
| 381 |
| 382 |
379 class Assembler : public Malloced { | 383 class Assembler : public Malloced { |
380 public: | 384 public: |
381 // Create an assembler. Instructions and relocation information are emitted | 385 // Create an assembler. Instructions and relocation information are emitted |
382 // into a buffer, with the instructions starting from the beginning and the | 386 // into a buffer, with the instructions starting from the beginning and the |
383 // relocation information starting from the end of the buffer. See CodeDesc | 387 // relocation information starting from the end of the buffer. See CodeDesc |
384 // for a detailed comment on the layout (globals.h). | 388 // for a detailed comment on the layout (globals.h). |
385 // | 389 // |
386 // If the provided buffer is NULL, the assembler allocates and grows its own | 390 // If the provided buffer is NULL, the assembler allocates and grows its own |
387 // buffer, and buffer_size determines the initial buffer size. The buffer is | 391 // buffer, and buffer_size determines the initial buffer size. The buffer is |
388 // owned by the assembler and deallocated upon destruction of the assembler. | 392 // owned by the assembler and deallocated upon destruction of the assembler. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 void label_at_put(Label* L, int at_offset); | 430 void label_at_put(Label* L, int at_offset); |
427 | 431 |
428 // Return the address in the constant pool of the code target address used by | 432 // Return the address in the constant pool of the code target address used by |
429 // the branch/call instruction at pc. | 433 // the branch/call instruction at pc. |
430 INLINE(static Address target_address_address_at(Address pc)); | 434 INLINE(static Address target_address_address_at(Address pc)); |
431 | 435 |
432 // Read/Modify the code target address in the branch/call instruction at pc. | 436 // Read/Modify the code target address in the branch/call instruction at pc. |
433 INLINE(static Address target_address_at(Address pc)); | 437 INLINE(static Address target_address_at(Address pc)); |
434 INLINE(static void set_target_address_at(Address pc, Address target)); | 438 INLINE(static void set_target_address_at(Address pc, Address target)); |
435 | 439 |
| 440 // Size of an instruction. |
| 441 static const int kInstrSize = sizeof(Instr); |
| 442 |
436 // Distance between the instruction referring to the address of the call | 443 // Distance between the instruction referring to the address of the call |
437 // target (ldr pc, [target addr in const pool]) and the return address | 444 // target (ldr pc, [target addr in const pool]) and the return address |
438 static const int kCallTargetAddressOffset = sizeof(Instr); | 445 static const int kCallTargetAddressOffset = kInstrSize; |
| 446 |
439 // Distance between start of patched return sequence and the emitted address | 447 // Distance between start of patched return sequence and the emitted address |
440 // to jump to. | 448 // to jump to. |
441 static const int kPatchReturnSequenceAddressOffset = 1; | 449 static const int kPatchReturnSequenceAddressOffset = kInstrSize; |
442 | 450 |
443 // Difference between address of current opcode and value read from pc | 451 // Difference between address of current opcode and value read from pc |
444 // register. | 452 // register. |
445 static const int kPcLoadDelta = 8; | 453 static const int kPcLoadDelta = 8; |
446 | 454 |
447 | 455 |
448 // --------------------------------------------------------------------------- | 456 // --------------------------------------------------------------------------- |
449 // Code generation | 457 // Code generation |
450 | 458 |
451 // Insert the smallest number of nop instructions | 459 // Insert the smallest number of nop instructions |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 add(sp, sp, Operand(kPointerSize)); | 653 add(sp, sp, Operand(kPointerSize)); |
646 } | 654 } |
647 | 655 |
648 // Load effective address of memory operand x into register dst | 656 // Load effective address of memory operand x into register dst |
649 void lea(Register dst, const MemOperand& x, | 657 void lea(Register dst, const MemOperand& x, |
650 SBit s = LeaveCC, Condition cond = al); | 658 SBit s = LeaveCC, Condition cond = al); |
651 | 659 |
652 // Jump unconditionally to given label. | 660 // Jump unconditionally to given label. |
653 void jmp(Label* L) { b(L, al); } | 661 void jmp(Label* L) { b(L, al); } |
654 | 662 |
| 663 // Check the code size generated from label to here. |
| 664 int InstructionsGeneratedSince(Label* l) { |
| 665 return (pc_offset() - l->pos()) / kInstrSize; |
| 666 } |
655 | 667 |
656 // Debugging | 668 // Debugging |
657 | 669 |
| 670 // Mark address of the ExitJSFrame code. |
| 671 void RecordJSReturn(); |
| 672 |
658 // Record a comment relocation entry that can be used by a disassembler. | 673 // Record a comment relocation entry that can be used by a disassembler. |
659 // Use --debug_code to enable. | 674 // Use --debug_code to enable. |
660 void RecordComment(const char* msg); | 675 void RecordComment(const char* msg); |
661 | 676 |
662 void RecordPosition(int pos); | 677 void RecordPosition(int pos); |
663 void RecordStatementPosition(int pos); | 678 void RecordStatementPosition(int pos); |
664 void WriteRecordedPositions(); | 679 void WriteRecordedPositions(); |
665 | 680 |
666 int pc_offset() const { return pc_ - buffer_; } | 681 int pc_offset() const { return pc_ - buffer_; } |
667 int current_position() const { return current_position_; } | 682 int current_position() const { return current_position_; } |
668 int current_statement_position() const { return current_position_; } | 683 int current_statement_position() const { return current_position_; } |
669 | 684 |
670 protected: | 685 protected: |
671 int buffer_space() const { return reloc_info_writer.pos() - pc_; } | 686 int buffer_space() const { return reloc_info_writer.pos() - pc_; } |
672 | 687 |
673 // Read/patch instructions | 688 // Read/patch instructions |
674 Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); } | 689 static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); } |
675 void instr_at_put(byte* pc, Instr instr) { | 690 void instr_at_put(byte* pc, Instr instr) { |
676 *reinterpret_cast<Instr*>(pc) = instr; | 691 *reinterpret_cast<Instr*>(pc) = instr; |
677 } | 692 } |
678 Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } | 693 Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); } |
679 void instr_at_put(int pos, Instr instr) { | 694 void instr_at_put(int pos, Instr instr) { |
680 *reinterpret_cast<Instr*>(buffer_ + pos) = instr; | 695 *reinterpret_cast<Instr*>(buffer_ + pos) = instr; |
681 } | 696 } |
682 | 697 |
683 // Decode branch instruction at pos and return branch target pos | 698 // Decode branch instruction at pos and return branch target pos |
684 int target_at(int pos); | 699 int target_at(int pos); |
(...skipping 16 matching lines...) Expand all Loading... |
701 int buffer_size_; | 716 int buffer_size_; |
702 // True if the assembler owns the buffer, false if buffer is external. | 717 // True if the assembler owns the buffer, false if buffer is external. |
703 bool own_buffer_; | 718 bool own_buffer_; |
704 | 719 |
705 // Buffer size and constant pool distance are checked together at regular | 720 // Buffer size and constant pool distance are checked together at regular |
706 // intervals of kBufferCheckInterval emitted bytes | 721 // intervals of kBufferCheckInterval emitted bytes |
707 static const int kBufferCheckInterval = 1*KB/2; | 722 static const int kBufferCheckInterval = 1*KB/2; |
708 int next_buffer_check_; // pc offset of next buffer check | 723 int next_buffer_check_; // pc offset of next buffer check |
709 | 724 |
710 // Code generation | 725 // Code generation |
711 static const int kInstrSize = sizeof(Instr); // signed size | |
712 // The relocation writer's position is at least kGap bytes below the end of | 726 // The relocation writer's position is at least kGap bytes below the end of |
713 // the generated instructions. This is so that multi-instruction sequences do | 727 // the generated instructions. This is so that multi-instruction sequences do |
714 // not have to check for overflow. The same is true for writes of large | 728 // not have to check for overflow. The same is true for writes of large |
715 // relocation info entries. | 729 // relocation info entries. |
716 static const int kGap = 32; | 730 static const int kGap = 32; |
717 byte* pc_; // the program counter; moves forward | 731 byte* pc_; // the program counter; moves forward |
718 | 732 |
719 // Constant pool generation | 733 // Constant pool generation |
720 // Pools are emitted in the instruction stream, preferably after unconditional | 734 // Pools are emitted in the instruction stream, preferably after unconditional |
721 // jumps or after returns from functions (in dead code locations). | 735 // jumps or after returns from functions (in dead code locations). |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 // Labels | 802 // Labels |
789 void print(Label* L); | 803 void print(Label* L); |
790 void bind_to(Label* L, int pos); | 804 void bind_to(Label* L, int pos); |
791 void link_to(Label* L, Label* appendix); | 805 void link_to(Label* L, Label* appendix); |
792 void next(Label* L); | 806 void next(Label* L); |
793 | 807 |
794 // Record reloc info for current pc_ | 808 // Record reloc info for current pc_ |
795 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); | 809 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); |
796 | 810 |
797 friend class RegExpMacroAssemblerARM; | 811 friend class RegExpMacroAssemblerARM; |
| 812 friend class RelocInfo; |
| 813 friend class CodePatcher; |
798 }; | 814 }; |
799 | 815 |
800 } } // namespace v8::internal | 816 } } // namespace v8::internal |
801 | 817 |
802 #endif // V8_ARM_ASSEMBLER_ARM_H_ | 818 #endif // V8_ARM_ASSEMBLER_ARM_H_ |
OLD | NEW |