📄 assembler-ia32.h.svn-base
字号:
// - 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 + -