📄 assembler-ia32.cc.svn-base
字号:
}void Assembler::test(Register reg, const Immediate& imm) { EnsureSpace ensure_space(this); last_pc_ = pc_; // Only use test against byte for registers that have a byte // variant: eax, ebx, ecx, and edx. if (imm.rmode_ == RelocInfo::NONE && is_uint8(imm.x_) && reg.code() < 4) { uint8_t imm8 = imm.x_; if (reg.is(eax)) { EMIT(0xA8); EMIT(imm8); } else { emit_arith_b(0xF6, 0xC0, reg, imm8); } } else { // This is not using emit_arith because test doesn't support // sign-extension of 8-bit operands. if (reg.is(eax)) { EMIT(0xA9); } else { EMIT(0xF7); EMIT(0xC0 | reg.code()); } emit(imm); }}void Assembler::test(Register reg, const Operand& op) { EnsureSpace ensure_space(this); last_pc_ = pc_; EMIT(0x85); emit_operand(reg, op);}void Assembler::test(const Operand& op, const Immediate& imm) { EnsureSpace ensure_space(this); last_pc_ = pc_; EMIT(0xF7); emit_operand(eax, op); emit(imm);}void Assembler::xor_(Register dst, int32_t imm32) { EnsureSpace ensure_space(this); last_pc_ = pc_; emit_arith(6, Operand(dst), Immediate(imm32));}void Assembler::xor_(Register dst, const Operand& src) { EnsureSpace ensure_space(this); last_pc_ = pc_; EMIT(0x33); emit_operand(dst, src);}void Assembler::xor_(const Operand& src, Register dst) { EnsureSpace ensure_space(this); last_pc_ = pc_; EMIT(0x31); emit_operand(dst, src);}void Assembler::xor_(const Operand& dst, const Immediate& x) { EnsureSpace ensure_space(this); last_pc_ = pc_; emit_arith(6, dst, x);}void Assembler::bts(const Operand& dst, Register src) { EnsureSpace ensure_space(this); last_pc_ = pc_; EMIT(0x0F); EMIT(0xAB); emit_operand(src, dst);}void Assembler::hlt() { EnsureSpace ensure_space(this); last_pc_ = pc_; EMIT(0xF4);}void Assembler::int3() { EnsureSpace ensure_space(this); last_pc_ = pc_; EMIT(0xCC);}void Assembler::nop() { EnsureSpace ensure_space(this); last_pc_ = pc_; EMIT(0x90);}void Assembler::rdtsc() { ASSERT(CpuFeatures::IsEnabled(CpuFeatures::RDTSC)); EnsureSpace ensure_space(this); last_pc_ = pc_; EMIT(0x0F); EMIT(0x31);}void Assembler::ret(int imm16) { EnsureSpace ensure_space(this); last_pc_ = pc_; ASSERT(is_uint16(imm16)); if (imm16 == 0) { EMIT(0xC3); } else { EMIT(0xC2); EMIT(imm16 & 0xFF); EMIT((imm16 >> 8) & 0xFF); }}void Assembler::leave() { EnsureSpace ensure_space(this); last_pc_ = pc_; EMIT(0xC9);}// Labels refer to positions in the (to be) generated code.// There are bound, linked, and unused labels.//// Bound labels refer to known positions in the already// generated code. pos() is the position the label refers to.//// Linked labels refer to unknown positions in the code// to be generated; pos() is the position of the 32bit// Displacement of the last instruction using the label.void Assembler::print(Label* L) { if (L->is_unused()) { PrintF("unused label\n"); } else if (L->is_bound()) { PrintF("bound label to %d\n", L->pos()); } else if (L->is_linked()) { Label l = *L; PrintF("unbound label"); while (l.is_linked()) { Displacement disp = disp_at(&l); PrintF("@ %d ", l.pos()); disp.print(); PrintF("\n"); disp.next(&l); } } else { PrintF("label in inconsistent state (pos = %d)\n", L->pos_); }}void Assembler::bind_to(Label* L, int pos) { EnsureSpace ensure_space(this); last_pc_ = NULL; ASSERT(0 <= pos && pos <= pc_offset()); // must have a valid binding position while (L->is_linked()) { Displacement disp = disp_at(L); int fixup_pos = L->pos(); if (disp.type() == Displacement::UNCONDITIONAL_JUMP) { ASSERT(byte_at(fixup_pos - 1) == 0xE9); // jmp expected } // relative address, relative to point after address int imm32 = pos - (fixup_pos + sizeof(int32_t)); long_at_put(fixup_pos, imm32); disp.next(L); } L->bind_to(pos); // do not eliminate jump instructions before the last bound position if (pos > last_bound_pos_) last_bound_pos_ = pos;}void Assembler::link_to(Label* L, Label* appendix) { EnsureSpace ensure_space(this); last_pc_ = NULL; if (appendix->is_linked()) { if (L->is_linked()) { // append appendix to L's list Label p; Label q = *L; do { p = q; Displacement disp = disp_at(&q); disp.next(&q); } while (q.is_linked()); Displacement disp = disp_at(&p); disp.link_to(appendix); disp_at_put(&p, disp); p.Unuse(); // to avoid assertion failure in ~Label } else { // L is empty, simply use appendix *L = *appendix; } } appendix->Unuse(); // appendix should not be used anymore}void Assembler::bind(Label* L) { EnsureSpace ensure_space(this); last_pc_ = NULL; ASSERT(!L->is_bound()); // label can only be bound once if (FLAG_eliminate_jumps) { // Resolve unbound label. if (unbound_label_.is_linked()) { // Unbound label exists => link it with L if same binding // position, otherwise fix it. if (binding_pos_ == pc_offset()) { // Link it to L's list. link_to(L, &unbound_label_); } else { // Otherwise bind unbound label. ASSERT(binding_pos_ < pc_offset()); bind_to(&unbound_label_, binding_pos_); } } ASSERT(!unbound_label_.is_linked()); // try to eliminate jumps to next instruction const int absolute_jump_size = 5; // Do not remove an already bound jump target. while (last_bound_pos_ < pc_offset() && reloc_info_writer.last_pc() <= pc_ - absolute_jump_size && L->is_linked() && (L->pos() + static_cast<int>(sizeof(int32_t)) == pc_offset()) && (disp_at(L).type() == Displacement::UNCONDITIONAL_JUMP)) { // Previous instruction is jump jumping immediately after it => // eliminate it. // jmp expected. ASSERT(byte_at(pc_offset() - absolute_jump_size) == 0xE9); if (FLAG_print_jump_elimination) { PrintF("@ %d jump to next eliminated\n", L->pos()); } // Remove first entry from label list. Displacement disp = disp_at(L); disp.next(L); // Eliminate instruction (set code pointers back). pc_ -= absolute_jump_size; // Make sure not to skip relocation information when rewinding. ASSERT(reloc_info_writer.last_pc() <= pc_); } // Delay fixup of L => store it as unbound label. unbound_label_ = *L; binding_pos_ = pc_offset(); L->Unuse(); } bind_to(L, pc_offset());}void Assembler::call(Label* L) { EnsureSpace ensure_space(this); last_pc_ = pc_; if (L->is_bound()) { const int long_size = 5; int offs = L->pos() - pc_offset(); ASSERT(offs <= 0); // 1110 1000 #32-bit disp EMIT(0xE8); emit(offs - long_size); } else { // 1110 1000 #32-bit disp EMIT(0xE8); emit_disp(L, Displacement::OTHER); }}void Assembler::call(byte* entry, RelocInfo::Mode rmode) { EnsureSpace ensure_space(this); last_pc_ = pc_; ASSERT(!RelocInfo::IsCodeTarget(rmode)); EMIT(0xE8); emit(entry - (pc_ + sizeof(int32_t)), rmode);}void Assembler::call(const Operand& adr) { EnsureSpace ensure_space(this); last_pc_ = pc_; EMIT(0xFF); emit_operand(edx, adr);}void Assembler::call(Handle<Code> code, RelocInfo::Mode rmode) { WriteRecordedPositions(); EnsureSpace ensure_space(this); last_pc_ = pc_; ASSERT(RelocInfo::IsCodeTarget(rmode)); EMIT(0xE8); emit(reinterpret_cast<intptr_t>(code.location()), rmode);}void Assembler::jmp(Label* L) { EnsureSpace ensure_space(this); last_pc_ = pc_; if (L->is_bound()) { const int short_size = 2; const int long_size = 5; int offs = L->pos() - pc_offset(); ASSERT(offs <= 0); if (is_int8(offs - short_size)) { // 1110 1011 #8-bit disp EMIT(0xEB); EMIT((offs - short_size) & 0xFF); } else { // 1110 1001 #32-bit disp EMIT(0xE9); emit(offs - long_size); } } else { if (FLAG_eliminate_jumps && unbound_label_.is_linked() && binding_pos_ == pc_offset()) { // Current position is target of jumps if (FLAG_print_jump_elimination) { PrintF("eliminated jumps/calls to %d from ", binding_pos_); print(&unbound_label_); } link_to(L, &unbound_label_); } // 1110 1001 #32-bit disp EMIT(0xE9); emit_disp(L, Displacement::UNCONDITIONAL_JUMP); }}void Assembler::jmp(byte* entry, RelocInfo::Mode rmode) { EnsureSpace ensure_space(this); last_pc_ = pc_; ASSERT(!RelocInfo::IsCodeTarget(rmode)); EMIT(0xE9); emit(entry - (pc_ + sizeof(int32_t)), rmode);}void Assembler::jmp(const Operand& adr) { EnsureSpace ensure_space(this); last_pc_ = pc_; EMIT(0xFF); emit_operand(esp, adr);}void Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) { EnsureSpace ensure_space(this); last_pc_ = pc_; ASSERT(RelocInfo::IsCodeTarget(rmode)); EMIT(0xE9); emit(reinterpret_cast<intptr_t>(code.location()), rmode);}void Assembler::j(Condition cc, Label* L, Hint hint) { EnsureSpace ensure_space(this); last_pc_ = pc_; ASSERT(0 <= cc && cc < 16); if (FLAG_emit_branch_hints && hint != no_hint) EMIT(hint); if (L->is_bound()) { const int short_size = 2; const int long_size = 6; int offs = L->pos() - pc_offset(); ASSERT(offs <= 0); if (is_int8(offs - short_size)) { // 0111 tttn #8-bit disp EMIT(0x70 | cc); EMIT((offs - short_size) & 0xFF); } else { // 0000 1111 1000 tttn #32-bit disp EMIT(0x0F); EMIT(0x80 | cc); emit(offs - long_size); } } else { // 0000 1111 1000 tttn #32-bit disp // Note: could eliminate cond. jumps to this jump if condition // is the same however, seems to be rather unlikely case. EMIT(0x0F); EMIT(0x80 | cc); emit_disp(L, Displacement::OTHER); }}void Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode, Hint hint) { EnsureSpace ensure_space(this); last_pc_ = pc_; ASSERT((0 <= cc) && (cc < 16)); if (FLAG_emit_branch_hints && hint != no_hint) EMIT(hint); // 0000 1111 1000 tttn #32-bit disp EMIT(0x0F); EMIT(0x80 | cc); emit(entry - (pc_ + sizeof(int32_t)), rmode);}void Assembler::j(Condition cc, Handle<Code> code, Hint hint) { EnsureSpace ensure_space(this); last_pc_ = pc_; if (FLAG_emit_branch_hints && hint != no_hint) EMIT(hint); // 0000 1111 1000 tttn #32-bit disp EMIT(0x0F); EMIT(0x80 | cc); emit(reinterpret_cast<intptr_t>(code.location()), RelocInfo::CODE_TARGET);}// FPU instructionsvoid Assembler::fld(int i) { EnsureSpace ensure_space(this); last_pc_ = pc_; emit_farith(0xD9, 0xC0, i);}void Assembler::fld1() { EnsureSpace ensure_space(this); last_pc_ = pc_; EMIT(0xD9); EMIT(0xE8);}void Assembler::fldz() { EnsureSpace ensure_space(this); last_pc_ = pc_; EMIT(0xD9); EMIT(0xEE);}void Assembler::fld_s(const Operand& adr) { EnsureSpace ensure_space(this); last_pc_ = pc_; EMIT(0xD9); emit_operand(eax, adr);}void Assembler::fld_d(const Operand& adr) { EnsureSpace ensure_space(this); last_pc_ = pc_; EMIT(0xDD); emit_operand(eax, adr);}void Assembler::fstp_s(const Operand& adr) { EnsureSpace ensure_space(this); last_pc_ = pc_; EMIT(0xD9); emit_operand(ebx, adr);}void Assembler::fstp_d(const Operand& adr) { EnsureSpace ensure_space(this); last_pc_ = pc_; EMIT(0xDD); emit_operand(ebx, adr);}void Assembler::fild_s(const Operand& adr) { EnsureSpace ensure_space(this); last_pc_ = pc_; EMIT(0xDB); emit_operand(eax, adr);}void Assembler::fild_d(const Operand& adr) { EnsureSpace ensure_space(this); last_pc_ = pc_; EMIT(0xDF); emit_operand(ebp, adr);}void Assembler::fistp_s(const Operand& adr) { EnsureSpace ensure_space(this); last_pc_ = pc_; EMIT(0xDB); emit_operand(ebx, adr);}void Assembler::fist_s(const Operand& adr) { EnsureSpace ensure_space(this); last_pc_ = pc_; EMIT(0xDB); emit_operand(edx, adr);}void Assembler::fistp_d(const Operand& adr) { EnsureSpace ensure_space(this); last_pc_ = pc_;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -