⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 assembler-arm.h.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
  //  // Takes a branch opcode (cc) and a label (L) and generates  // either a backward branch or a forward branch and links it  // to the label fixup chain. Usage:  //  // Label L;    // unbound label  // j(cc, &L);  // forward branch to unbound label  // bind(&L);   // bind label to the current pc  // j(cc, &L);  // backward branch to bound label  // bind(&L);   // illegal: a label may be bound only once  //  // Note: The same Label can be used for forward and backward branches  // but it may be bound only once.  void bind(Label* L);  // binds an unbound label L to the current code position  // Returns the branch offset to the given label from the current code position  // Links the label to the current position if it is still unbound  // Manages the jump elimination optimization if the second parameter is true.  int branch_offset(Label* L, bool jump_elimination_allowed);  // Return the address in the constant pool of the code target address used by  // the branch/call instruction at pc.  INLINE(static Address target_address_address_at(Address pc));  // Read/Modify the code target address in the branch/call instruction at pc.  INLINE(static Address target_address_at(Address pc));  INLINE(static void set_target_address_at(Address pc, Address target));  // Distance between the instruction referring to the address of the call  // target (ldr pc, [target addr in const pool]) and the return address  static const int kTargetAddrToReturnAddrDist = sizeof(Instr);  // ---------------------------------------------------------------------------  // Code generation  // Insert the smallest number of nop instructions  // possible to align the pc offset to a multiple  // of m. m must be a power of 2 (>= 4).  void Align(int m);  // Branch instructions  void b(int branch_offset, Condition cond = al);  void bl(int branch_offset, Condition cond = al);  void blx(int branch_offset);  // v5 and above  void blx(Register target, Condition cond = al);  // v5 and above  void bx(Register target, Condition cond = al);  // v5 and above, plus v4t  // Convenience branch instructions using labels  void b(Label* L, Condition cond = al)  {    b(branch_offset(L, cond == al), cond);  }  void b(Condition cond, Label* L)  { b(branch_offset(L, cond == al), cond); }  void bl(Label* L, Condition cond = al)  { bl(branch_offset(L, false), cond); }  void bl(Condition cond, Label* L)  { bl(branch_offset(L, false), cond); }  void blx(Label* L)  { blx(branch_offset(L, false)); }  // v5 and above  // Data-processing instructions  void and_(Register dst, Register src1, const Operand& src2,            SBit s = LeaveCC, Condition cond = al);  void eor(Register dst, Register src1, const Operand& src2,           SBit s = LeaveCC, Condition cond = al);  void sub(Register dst, Register src1, const Operand& src2,           SBit s = LeaveCC, Condition cond = al);  void sub(Register dst, Register src1, Register src2,           SBit s = LeaveCC, Condition cond = al) {    sub(dst, src1, Operand(src2), s, cond);  }  void rsb(Register dst, Register src1, const Operand& src2,           SBit s = LeaveCC, Condition cond = al);  void add(Register dst, Register src1, const Operand& src2,           SBit s = LeaveCC, Condition cond = al);  void adc(Register dst, Register src1, const Operand& src2,           SBit s = LeaveCC, Condition cond = al);  void sbc(Register dst, Register src1, const Operand& src2,           SBit s = LeaveCC, Condition cond = al);  void rsc(Register dst, Register src1, const Operand& src2,           SBit s = LeaveCC, Condition cond = al);  void tst(Register src1, const Operand& src2, Condition cond = al);  void tst(Register src1, Register src2, Condition cond = al) {    tst(src1, Operand(src2), cond);  }  void teq(Register src1, const Operand& src2, Condition cond = al);  void cmp(Register src1, const Operand& src2, Condition cond = al);  void cmp(Register src1, Register src2, Condition cond = al) {    cmp(src1, Operand(src2), cond);  }  void cmn(Register src1, const Operand& src2, Condition cond = al);  void orr(Register dst, Register src1, const Operand& src2,           SBit s = LeaveCC, Condition cond = al);  void orr(Register dst, Register src1, Register src2,           SBit s = LeaveCC, Condition cond = al) {    orr(dst, src1, Operand(src2), s, cond);  }  void mov(Register dst, const Operand& src,           SBit s = LeaveCC, Condition cond = al);  void mov(Register dst, Register src, SBit s = LeaveCC, Condition cond = al) {    mov(dst, Operand(src), s, cond);  }  void bic(Register dst, Register src1, const Operand& src2,           SBit s = LeaveCC, Condition cond = al);  void mvn(Register dst, const Operand& src,           SBit s = LeaveCC, Condition cond = al);  // Multiply instructions  void mla(Register dst, Register src1, Register src2, Register srcA,           SBit s = LeaveCC, Condition cond = al);  void mul(Register dst, Register src1, Register src2,           SBit s = LeaveCC, Condition cond = al);  void smlal(Register dstL, Register dstH, Register src1, Register src2,             SBit s = LeaveCC, Condition cond = al);  void smull(Register dstL, Register dstH, Register src1, Register src2,             SBit s = LeaveCC, Condition cond = al);  void umlal(Register dstL, Register dstH, Register src1, Register src2,             SBit s = LeaveCC, Condition cond = al);  void umull(Register dstL, Register dstH, Register src1, Register src2,             SBit s = LeaveCC, Condition cond = al);  // Miscellaneous arithmetic instructions  void clz(Register dst, Register src, Condition cond = al);  // v5 and above  // Status register access instructions  void mrs(Register dst, SRegister s, Condition cond = al);  void msr(SRegisterFieldMask fields, const Operand& src, Condition cond = al);  // Load/Store instructions  void ldr(Register dst, const MemOperand& src, Condition cond = al);  void str(Register src, const MemOperand& dst, Condition cond = al);  void ldrb(Register dst, const MemOperand& src, Condition cond = al);  void strb(Register src, const MemOperand& dst, Condition cond = al);  void ldrh(Register dst, const MemOperand& src, Condition cond = al);  void strh(Register src, const MemOperand& dst, Condition cond = al);  void ldrsb(Register dst, const MemOperand& src, Condition cond = al);  void ldrsh(Register dst, const MemOperand& src, Condition cond = al);  // Load/Store multiple instructions  void ldm(BlockAddrMode am, Register base, RegList dst, Condition cond = al);  void stm(BlockAddrMode am, Register base, RegList src, Condition cond = al);  // Semaphore instructions  void swp(Register dst, Register src, Register base, Condition cond = al);  void swpb(Register dst, Register src, Register base, Condition cond = al);  // Exception-generating instructions and debugging support  void stop(const char* msg);  void bkpt(uint32_t imm16);  // v5 and above  void swi(uint32_t imm24, Condition cond = al);  // Coprocessor instructions  void cdp(Coprocessor coproc, int opcode_1,           CRegister crd, CRegister crn, CRegister crm,           int opcode_2, Condition cond = al);  void cdp2(Coprocessor coproc, int opcode_1,            CRegister crd, CRegister crn, CRegister crm,            int opcode_2);  // v5 and above  void mcr(Coprocessor coproc, int opcode_1,           Register rd, CRegister crn, CRegister crm,           int opcode_2 = 0, Condition cond = al);  void mcr2(Coprocessor coproc, int opcode_1,            Register rd, CRegister crn, CRegister crm,            int opcode_2 = 0);  // v5 and above  void mrc(Coprocessor coproc, int opcode_1,           Register rd, CRegister crn, CRegister crm,           int opcode_2 = 0, Condition cond = al);  void mrc2(Coprocessor coproc, int opcode_1,            Register rd, CRegister crn, CRegister crm,            int opcode_2 = 0);  // v5 and above  void ldc(Coprocessor coproc, CRegister crd, const MemOperand& src,           LFlag l = Short, Condition cond = al);  void ldc(Coprocessor coproc, CRegister crd, Register base, int option,           LFlag l = Short, Condition cond = al);  void ldc2(Coprocessor coproc, CRegister crd, const MemOperand& src,            LFlag l = Short);  // v5 and above  void ldc2(Coprocessor coproc, CRegister crd, Register base, int option,            LFlag l = Short);  // v5 and above  void stc(Coprocessor coproc, CRegister crd, const MemOperand& dst,           LFlag l = Short, Condition cond = al);  void stc(Coprocessor coproc, CRegister crd, Register base, int option,           LFlag l = Short, Condition cond = al);  void stc2(Coprocessor coproc, CRegister crd, const MemOperand& dst,            LFlag l = Short);  // v5 and above  void stc2(Coprocessor coproc, CRegister crd, Register base, int option,            LFlag l = Short);  // v5 and above  // Pseudo instructions  void nop()  { mov(r0, Operand(r0)); }  void push(Register src) {    str(src, MemOperand(sp, 4, NegPreIndex), al);  }  void pop(Register dst) {    ldr(dst, MemOperand(sp, 4, PostIndex), al);  }  void pop() {    add(sp, sp, Operand(kPointerSize));  }  // Load effective address of memory operand x into register dst  void lea(Register dst, const MemOperand& x,           SBit s = LeaveCC, Condition cond = al);  // Jump unconditionally to given label.  void jmp(Label* L) { b(L, al); }  // Debugging  // Record a comment relocation entry that can be used by a disassembler.  // Use --debug_code to enable.  void RecordComment(const char* msg);  void RecordPosition(int pos);  void RecordStatementPosition(int pos);  int pc_offset() const { return pc_ - buffer_; }  int last_position() const { return last_position_; }  bool last_position_is_statement() const {    return last_position_is_statement_;  }  // Temporary helper function. Used by codegen.cc.  int last_statement_position() const { return last_position_; } protected:  int buffer_space() const { return reloc_info_writer.pos() - pc_; }  // Read/patch instructions  Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); }  void instr_at_put(byte* pc, Instr instr) {    *reinterpret_cast<Instr*>(pc) = instr;  }  Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); }  void instr_at_put(int pos, Instr instr) {    *reinterpret_cast<Instr*>(buffer_ + pos) = instr;  }  // Decode branch instruction at pos and return branch target pos  int target_at(int pos);  // Patch branch instruction at pos to branch to given branch target pos  void target_at_put(int pos, int target_pos); private:  // Code buffer:  // The buffer into which code and relocation info are generated.  byte* buffer_;  int buffer_size_;  // True if the assembler owns the buffer, false if buffer is external.  bool own_buffer_;  // Buffer size and constant pool distance are checked together at regular  // intervals of kBufferCheckInterval emitted bytes  static const int kBufferCheckInterval = 1*KB/2;  int next_buffer_check_;  // pc offset of next buffer check  // Code generation  static const int kInstrSize = sizeof(Instr);  // signed size  // The relocation writer's position is at least kGap bytes below the end of  // the generated instructions. This is so that multi-instruction sequences do  // not have to check for overflow. The same is true for writes of large  // relocation info entries.  static const int kGap = 32;  byte* pc_;  // the program counter; moves forward  // Constant pool generation  // Pools are emitted in the instruction stream, preferably after unconditional  // jumps or after returns from functions (in dead code locations).  // If a long code sequence does not contain unconditional jumps, it is  // necessary to emit the constant pool before the pool gets too far from the  // location it is accessed from. In this case, we emit a jump over the emitted  // constant pool.  // Constants in the pool may be addresses of functions that gets relocated;  // if so, a relocation info entry is associated to the constant pool entry.  // Repeated checking whether the constant pool should be emitted is rather  // expensive. By default we only check again once a number of instructions  // has been generated. That also means that the sizing of the buffers is not  // an exact science, and that we rely on some slop to not overrun buffers.  static const int kCheckConstIntervalInst = 32;  static const int kCheckConstInterval = kCheckConstIntervalInst * kInstrSize;  // Pools are emitted after function return and in dead code at (more or less)  // regular intervals of kDistBetweenPools bytes  static const int kDistBetweenPools = 1*KB;  // Constants in pools are accessed via pc relative addressing, which can  // reach +/-4KB thereby defining a maximum distance between the instruction  // and the accessed constant. We satisfy this constraint by limiting the  // distance between pools.  static const int kMaxDistBetweenPools = 4*KB - 2*kBufferCheckInterval;  // Emission of the constant pool may be blocked in some code sequences  int no_const_pool_before_;  // block emission before this pc offset  // Keep track of the last emitted pool to guarantee a maximal distance  int last_const_pool_end_;  // pc offset following the last constant pool  // Relocation info generation  // Each relocation is encoded as a variable size value  static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;  RelocInfoWriter reloc_info_writer;  // Relocation info records are also used during code generation as temporary  // containers for constants and code target addresses until they are emitted  // to the constant pool. These pending relocation info records are temporarily  // stored in a separate buffer until a constant pool is emitted.  // If every instruction in a long sequence is accessing the pool, we need one  // pending relocation entry per instruction.  static const int kMaxNumPRInfo = kMaxDistBetweenPools/kInstrSize;  RelocInfo prinfo_[kMaxNumPRInfo];  // the buffer of pending relocation info  int num_prinfo_;  // number of pending reloc info entries in the buffer  // Jump-to-jump elimination:  // The last label to be bound to _binding_pos, if unbound.  Label unbound_label_;  // The position to which _unbound_label has to be bound, if present.  int binding_pos_;  // The position before which jumps cannot be eliminated.  int last_bound_pos_;  // source position information  int last_position_;  bool last_position_is_statement_;  // Code emission  inline void CheckBuffer();  void GrowBuffer();  inline void emit(Instr x);  // Instruction generation  void addrmod1(Instr instr, Register rn, Register rd, const Operand& x);  void addrmod2(Instr instr, Register rd, const MemOperand& x);  void addrmod3(Instr instr, Register rd, const MemOperand& x);  void addrmod4(Instr instr, Register rn, RegList rl);  void addrmod5(Instr instr, CRegister crd, const MemOperand& x);  // Labels  void print(Label* L);  void bind_to(Label* L, int pos);  void link_to(Label* L, Label* appendix);  void next(Label* L);  // Record reloc info for current pc_  void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);  // Check if is time to emit a constant pool for pending reloc info entries  void CheckConstPool(bool force_emit, bool require_jump);  // Block the emission of the constant pool before pc_offset  void BlockConstPoolBefore(int pc_offset) {    if (no_const_pool_before_ < pc_offset) no_const_pool_before_ = pc_offset;  }};} }  // namespace v8::internal#endif  // V8_ASSEMBLER_ARM_H_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -