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

📄 assembler-ia32.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
}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 + -