| 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 |