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

📄 assembler-ia32.h.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
  // - function names correspond one-to-one to ia32 instruction mnemonics  // - unless specified otherwise, instructions operate on 32bit operands  // - instructions on 8bit (byte) operands/registers have a trailing '_b'  // - instructions on 16bit (word) operands/registers have a trailing '_w'  // - naming conflicts with C++ keywords are resolved via a trailing '_'  // NOTE ON INTERFACE: Currently, the interface is not very consistent  // in the sense that some operations (e.g. mov()) can be called in more  // the one way to generate the same instruction: The Register argument  // can in some cases be replaced with an Operand(Register) argument.  // This should be cleaned up and made more othogonal. The questions  // is: should we always use Operands instead of Registers where an  // Operand is possible, or should we have a Register (overloaded) form  // instead? We must be carefull to make sure that the selected instruction  // is obvious from the parameters to avoid hard-to-find code generation  // bugs.  // 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.  void Align(int m);  // Stack  void pushad();  void popad();  void pushfd();  void popfd();  void push(const Immediate& x);  void push(Register src);  void push(const Operand& src);  void pop(Register dst);  void pop(const Operand& dst);  // Moves  void mov_b(Register dst, const Operand& src);  void mov_b(const Operand& dst, int8_t imm8);  void mov_b(const Operand& dst, Register src);  void mov_w(Register dst, const Operand& src);  void mov_w(const Operand& dst, Register src);  void mov(Register dst, int32_t imm32);  void mov(Register dst, Handle<Object> handle);  void mov(Register dst, const Operand& src);  void mov(const Operand& dst, const Immediate& x);  void mov(const Operand& dst, Handle<Object> handle);  void mov(const Operand& dst, Register src);  void movsx_b(Register dst, const Operand& src);  void movsx_w(Register dst, const Operand& src);  void movzx_b(Register dst, const Operand& src);  void movzx_w(Register dst, const Operand& src);  // Conditional moves  void cmov(Condition cc, Register dst, int32_t imm32);  void cmov(Condition cc, Register dst, Handle<Object> handle);  void cmov(Condition cc, Register dst, const Operand& src);  // Arithmetics  void adc(Register dst, int32_t imm32);  void adc(Register dst, const Operand& src);  void add(Register dst, const Operand& src);  void add(const Operand& dst, const Immediate& x);  void and_(Register dst, int32_t imm32);  void and_(Register dst, const Operand& src);  void and_(const Operand& src, Register dst);  void and_(const Operand& dst, const Immediate& x);  void cmp(Register reg, int32_t imm32);  void cmp(Register reg, Handle<Object> handle);  void cmp(Register reg, const Operand& op);  void cmp(const Operand& op, const Immediate& imm);  void dec_b(Register dst);  void dec(Register dst);  void dec(const Operand& dst);  void cdq();  void idiv(Register src);  void imul(Register dst, const Operand& src);  void imul(Register dst, Register src, int32_t imm32);  void inc(Register dst);  void inc(const Operand& dst);  void lea(Register dst, const Operand& src);  void mul(Register src);  void neg(Register dst);  void not_(Register dst);  void or_(Register dst, int32_t imm32);  void or_(Register dst, const Operand& src);  void or_(const Operand& dst, Register src);  void or_(const Operand& dst, const Immediate& x);  void rcl(Register dst, uint8_t imm8);  void sar(Register dst, uint8_t imm8);  void sar(Register dst);  void sbb(Register dst, const Operand& src);  void shld(Register dst, const Operand& src);  void shl(Register dst, uint8_t imm8);  void shl(Register dst);  void shrd(Register dst, const Operand& src);  void shr(Register dst, uint8_t imm8);  void shr(Register dst);  void sub(const Operand& dst, const Immediate& x);  void sub(Register dst, const Operand& src);  void sub(const Operand& dst, Register src);  void test(Register reg, const Immediate& imm);  void test(Register reg, const Operand& op);  void test(const Operand& op, const Immediate& imm);  void xor_(Register dst, int32_t imm32);  void xor_(Register dst, const Operand& src);  void xor_(const Operand& src, Register dst);  void xor_(const Operand& dst, const Immediate& x);  // Bit operations.  void bts(const Operand& dst, Register src);  // Miscellaneous  void hlt();  void int3();  void nop();  void rdtsc();  void ret(int imm16);  void leave();  // Label operations & relative jumps (PPUM Appendix D)  //  // 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  // Calls  void call(Label* L);  void call(byte* entry, RelocInfo::Mode rmode);  void call(const Operand& adr);  void call(Handle<Code> code, RelocInfo::Mode rmode);  // Jumps  void jmp(Label* L);  // unconditional jump to L  void jmp(byte* entry, RelocInfo::Mode rmode);  void jmp(const Operand& adr);  void jmp(Handle<Code> code, RelocInfo::Mode rmode);  // Conditional jumps  void j(Condition cc, Label* L, Hint hint = no_hint);  void j(Condition cc, byte* entry, RelocInfo::Mode rmode, Hint hint = no_hint);  void j(Condition cc, Handle<Code> code, Hint hint = no_hint);  // Floating-point operations  void fld(int i);  void fld1();  void fldz();  void fld_s(const Operand& adr);  void fld_d(const Operand& adr);  void fstp_s(const Operand& adr);  void fstp_d(const Operand& adr);  void fild_s(const Operand& adr);  void fild_d(const Operand& adr);  void fist_s(const Operand& adr);  void fistp_s(const Operand& adr);  void fistp_d(const Operand& adr);  void fabs();  void fchs();  void fadd(int i);  void fsub(int i);  void fmul(int i);  void fdiv(int i);  void fisub_s(const Operand& adr);  void faddp(int i = 1);  void fsubp(int i = 1);  void fsubrp(int i = 1);  void fmulp(int i = 1);  void fdivp(int i = 1);  void fprem();  void fprem1();  void fxch(int i = 1);  void fincstp();  void ffree(int i = 0);  void ftst();  void fucomp(int i);  void fucompp();  void fcompp();  void fnstsw_ax();  void fwait();  void frndint();  void sahf();  void cpuid();  // SSE2 instructions  void cvttss2si(Register dst, const Operand& src);  void cvttsd2si(Register dst, const Operand& src);  void cvtsi2sd(XMMRegister dst, const Operand& src);  void addsd(XMMRegister dst, XMMRegister src);  void subsd(XMMRegister dst, XMMRegister src);  void mulsd(XMMRegister dst, XMMRegister src);  void divsd(XMMRegister dst, XMMRegister src);  // Use either movsd or movlpd.  void movdbl(XMMRegister dst, const Operand& src);  void movdbl(const Operand& dst, XMMRegister src);  // Debugging  void Print();  // Check the code size generated from label to here.  int SizeOfCodeGeneratedSince(Label* l) { return pc_offset() - l->pos(); }  // Mark address of the ExitJSFrame code.  void RecordJSReturn();  // 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);  void WriteRecordedPositions();  // Writes a single word of data in the code stream.  // Used for inline tables, e.g., jump-tables.  void dd(uint32_t data, RelocInfo::Mode reloc_info);  // Writes the absolute address of a bound label at the given position in  // the generated code. That positions should have the relocation mode  // internal_reference!  void WriteInternalReference(int position, const Label& bound_label);  int pc_offset() const  { return pc_ - buffer_; }  int last_statement_position() const  { return last_statement_position_; }  int last_position() const  { return last_position_; }  // Check if there is less than kGap bytes available in the buffer.  // If this is the case, we need to grow the buffer before emitting  // an instruction or relocation information.  inline bool overflow() const { return pc_ >= reloc_info_writer.pos() - kGap; }  // Get the number of bytes available in the buffer.  inline int available_space() const { return reloc_info_writer.pos() - pc_; }  // Avoid overflows for displacements etc.  static const int kMaximalBufferSize = 512*MB;  static const int kMinimalBufferSize = 4*KB; protected:  void movsd(XMMRegister dst, const Operand& src);  void movsd(const Operand& dst, XMMRegister src);  void emit_sse_operand(XMMRegister reg, const Operand& adr);  void emit_sse_operand(XMMRegister dst, XMMRegister src); 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_;  // code generation  byte* pc_;  // the program counter; moves forward  RelocInfoWriter reloc_info_writer;  // push-pop elimination  byte* last_pc_;  // 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_;  int last_statement_position_;  byte* addr_at(int pos)  { return buffer_ + pos; }  byte byte_at(int pos)  { return buffer_[pos]; }  uint32_t long_at(int pos)  {    return *reinterpret_cast<uint32_t*>(addr_at(pos));  }  void long_at_put(int pos, uint32_t x)  {    *reinterpret_cast<uint32_t*>(addr_at(pos)) = x;  }  // code emission  void GrowBuffer();  inline void emit(uint32_t x);  inline void emit(Handle<Object> handle);  inline void emit(uint32_t x, RelocInfo::Mode rmode);  inline void emit(const Immediate& x);  // instruction generation  void emit_arith_b(int op1, int op2, Register dst, int imm8);  // Emit a basic arithmetic instruction (i.e. first byte of the family is 0x81)  // with a given destination expression and an immediate operand.  It attempts  // to use the shortest encoding possible.  // sel specifies the /n in the modrm byte (see the Intel PRM).  void emit_arith(int sel, Operand dst, const Immediate& x);  void emit_operand(Register reg, const Operand& adr);  void emit_operand(const Operand& adr, Register reg);  void emit_farith(int b1, int b2, int i);  // labels  void print(Label* L);  void bind_to(Label* L, int pos);  void link_to(Label* L, Label* appendix);  // displacements  inline Displacement disp_at(Label* L);  inline void disp_at_put(Label* L, Displacement disp);  inline void emit_disp(Label* L, Displacement::Type type);  // record reloc info for current pc_  void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);  friend class CodePatcher;  friend class EnsureSpace;};// Helper class that ensures that there is enough space for generating// instructions and relocation information.  The constructor makes// sure that there is enough space and (in debug mode) the destructor// checks that we did not generate too much.class EnsureSpace BASE_EMBEDDED { public:  explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) {    if (assembler_->overflow()) assembler_->GrowBuffer();#ifdef DEBUG    space_before_ = assembler_->available_space();#endif  }#ifdef DEBUG  ~EnsureSpace() {    int bytes_generated = space_before_ - assembler_->available_space();    ASSERT(bytes_generated < assembler_->kGap);  }#endif private:  Assembler* assembler_;#ifdef DEBUG  int space_before_;#endif};} }  // namespace v8::internal#endif  // V8_ASSEMBLER_IA32_H_

⌨️ 快捷键说明

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