Assembler::Assembler(Isolate* arg_isolate, void* buffer, int buffer_size)
: AssemblerBase(arg_isolate),
positions_recorder_(this),
- allow_peephole_optimization_(false),
emit_debug_code_(FLAG_debug_code) {
- allow_peephole_optimization_ = FLAG_peephole_optimization;
if (buffer == NULL) {
// Do our own buffer management.
if (buffer_size <= kMinimalBufferSize) {
void Assembler::add(Register dst, Register src1, const Operand& src2,
SBit s, Condition cond) {
addrmod1(cond | ADD | s, src1, dst, src2);
-
- // Eliminate pattern: push(r), pop()
- // str(src, MemOperand(sp, 4, NegPreIndex), al);
- // add(sp, sp, Operand(kPointerSize));
- // Both instructions can be eliminated.
- if (can_peephole_optimize(2) &&
- // Pattern.
- instr_at(pc_ - 1 * kInstrSize) == kPopInstruction &&
- (instr_at(pc_ - 2 * kInstrSize) & ~kRdMask) == kPushRegPattern) {
- pc_ -= 2 * kInstrSize;
- if (FLAG_print_peephole_optimization) {
- PrintF("%x push(reg)/pop() eliminated\n", pc_offset());
- }
- }
}
positions_recorder()->WriteRecordedPositions();
}
addrmod2(cond | B26 | L, dst, src);
-
- // Eliminate pattern: push(ry), pop(rx)
- // str(ry, MemOperand(sp, 4, NegPreIndex), al)
- // ldr(rx, MemOperand(sp, 4, PostIndex), al)
- // Both instructions can be eliminated if ry = rx.
- // If ry != rx, a register copy from ry to rx is inserted
- // after eliminating the push and the pop instructions.
- if (can_peephole_optimize(2)) {
- Instr push_instr = instr_at(pc_ - 2 * kInstrSize);
- Instr pop_instr = instr_at(pc_ - 1 * kInstrSize);
-
- if (IsPush(push_instr) && IsPop(pop_instr)) {
- if (Instruction::RdValue(pop_instr) != Instruction::RdValue(push_instr)) {
- // For consecutive push and pop on different registers,
- // we delete both the push & pop and insert a register move.
- // push ry, pop rx --> mov rx, ry
- Register reg_pushed, reg_popped;
- reg_pushed = GetRd(push_instr);
- reg_popped = GetRd(pop_instr);
- pc_ -= 2 * kInstrSize;
- // Insert a mov instruction, which is better than a pair of push & pop
- mov(reg_popped, reg_pushed);
- if (FLAG_print_peephole_optimization) {
- PrintF("%x push/pop (diff reg) replaced by a reg move\n",
- pc_offset());
- }
- } else {
- // For consecutive push and pop on the same register,
- // both the push and the pop can be deleted.
- pc_ -= 2 * kInstrSize;
- if (FLAG_print_peephole_optimization) {
- PrintF("%x push/pop (same reg) eliminated\n", pc_offset());
- }
- }
- }
- }
-
- if (can_peephole_optimize(2)) {
- Instr str_instr = instr_at(pc_ - 2 * kInstrSize);
- Instr ldr_instr = instr_at(pc_ - 1 * kInstrSize);
-
- if ((IsStrRegFpOffset(str_instr) &&
- IsLdrRegFpOffset(ldr_instr)) ||
- (IsStrRegFpNegOffset(str_instr) &&
- IsLdrRegFpNegOffset(ldr_instr))) {
- if ((ldr_instr & kLdrStrInstrArgumentMask) ==
- (str_instr & kLdrStrInstrArgumentMask)) {
- // Pattern: Ldr/str same fp+offset, same register.
- //
- // The following:
- // str rx, [fp, #-12]
- // ldr rx, [fp, #-12]
- //
- // Becomes:
- // str rx, [fp, #-12]
-
- pc_ -= 1 * kInstrSize;
- if (FLAG_print_peephole_optimization) {
- PrintF("%x str/ldr (fp + same offset), same reg\n", pc_offset());
- }
- } else if ((ldr_instr & kLdrStrOffsetMask) ==
- (str_instr & kLdrStrOffsetMask)) {
- // Pattern: Ldr/str same fp+offset, different register.
- //
- // The following:
- // str rx, [fp, #-12]
- // ldr ry, [fp, #-12]
- //
- // Becomes:
- // str rx, [fp, #-12]
- // mov ry, rx
-
- Register reg_stored, reg_loaded;
- reg_stored = GetRd(str_instr);
- reg_loaded = GetRd(ldr_instr);
- pc_ -= 1 * kInstrSize;
- // Insert a mov instruction, which is better than ldr.
- mov(reg_loaded, reg_stored);
- if (FLAG_print_peephole_optimization) {
- PrintF("%x str/ldr (fp + same offset), diff reg \n", pc_offset());
- }
- }
- }
- }
-
- if (can_peephole_optimize(3)) {
- Instr mem_write_instr = instr_at(pc_ - 3 * kInstrSize);
- Instr ldr_instr = instr_at(pc_ - 2 * kInstrSize);
- Instr mem_read_instr = instr_at(pc_ - 1 * kInstrSize);
- if (IsPush(mem_write_instr) &&
- IsPop(mem_read_instr)) {
- if ((IsLdrRegFpOffset(ldr_instr) ||
- IsLdrRegFpNegOffset(ldr_instr))) {
- if (Instruction::RdValue(mem_write_instr) ==
- Instruction::RdValue(mem_read_instr)) {
- // Pattern: push & pop from/to same register,
- // with a fp+offset ldr in between
- //
- // The following:
- // str rx, [sp, #-4]!
- // ldr rz, [fp, #-24]
- // ldr rx, [sp], #+4
- //
- // Becomes:
- // if(rx == rz)
- // delete all
- // else
- // ldr rz, [fp, #-24]
-
- if (Instruction::RdValue(mem_write_instr) ==
- Instruction::RdValue(ldr_instr)) {
- pc_ -= 3 * kInstrSize;
- } else {
- pc_ -= 3 * kInstrSize;
- // Reinsert back the ldr rz.
- emit(ldr_instr);
- }
- if (FLAG_print_peephole_optimization) {
- PrintF("%x push/pop -dead ldr fp+offset in middle\n", pc_offset());
- }
- } else {
- // Pattern: push & pop from/to different registers
- // with a fp+offset ldr in between
- //
- // The following:
- // str rx, [sp, #-4]!
- // ldr rz, [fp, #-24]
- // ldr ry, [sp], #+4
- //
- // Becomes:
- // if(ry == rz)
- // mov ry, rx;
- // else if(rx != rz)
- // ldr rz, [fp, #-24]
- // mov ry, rx
- // else if((ry != rz) || (rx == rz)) becomes:
- // mov ry, rx
- // ldr rz, [fp, #-24]
-
- Register reg_pushed, reg_popped;
- if (Instruction::RdValue(mem_read_instr) ==
- Instruction::RdValue(ldr_instr)) {
- reg_pushed = GetRd(mem_write_instr);
- reg_popped = GetRd(mem_read_instr);
- pc_ -= 3 * kInstrSize;
- mov(reg_popped, reg_pushed);
- } else if (Instruction::RdValue(mem_write_instr) !=
- Instruction::RdValue(ldr_instr)) {
- reg_pushed = GetRd(mem_write_instr);
- reg_popped = GetRd(mem_read_instr);
- pc_ -= 3 * kInstrSize;
- emit(ldr_instr);
- mov(reg_popped, reg_pushed);
- } else if ((Instruction::RdValue(mem_read_instr) !=
- Instruction::RdValue(ldr_instr)) ||
- (Instruction::RdValue(mem_write_instr) ==
- Instruction::RdValue(ldr_instr))) {
- reg_pushed = GetRd(mem_write_instr);
- reg_popped = GetRd(mem_read_instr);
- pc_ -= 3 * kInstrSize;
- mov(reg_popped, reg_pushed);
- emit(ldr_instr);
- }
- if (FLAG_print_peephole_optimization) {
- PrintF("%x push/pop (ldr fp+off in middle)\n", pc_offset());
- }
- }
- }
- }
- }
}
void Assembler::str(Register src, const MemOperand& dst, Condition cond) {
addrmod2(cond | B26, src, dst);
-
- // Eliminate pattern: pop(), push(r)
- // add sp, sp, #4 LeaveCC, al; str r, [sp, #-4], al
- // -> str r, [sp, 0], al
- if (can_peephole_optimize(2) &&
- // Pattern.
- instr_at(pc_ - 1 * kInstrSize) == (kPushRegPattern | src.code() * B12) &&
- instr_at(pc_ - 2 * kInstrSize) == kPopInstruction) {
- pc_ -= 2 * kInstrSize;
- emit(al | B26 | 0 | Offset | sp.code() * B16 | src.code() * B12);
- if (FLAG_print_peephole_optimization) {
- PrintF("%x pop()/push(reg) eliminated\n", pc_offset());
- }
- }
}
pc_ = buffer_;
reloc_info_writer.Reposition(buffer_ + buffer_size, pc_);
- last_pc_ = NULL;
#ifdef GENERATED_CODE_COVERAGE
InitCoverageLog();
#endif
void Assembler::cpuid() {
ASSERT(CpuFeatures::IsEnabled(CPUID));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x0F);
EMIT(0xA2);
}
void Assembler::pushad() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x60);
}
void Assembler::popad() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x61);
}
void Assembler::pushfd() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x9C);
}
void Assembler::popfd() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x9D);
}
void Assembler::push(const Immediate& x) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
if (x.is_int8()) {
EMIT(0x6a);
EMIT(x.x_);
void Assembler::push(Register src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x50 | src.code());
}
void Assembler::push(const Operand& src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xFF);
emit_operand(esi, src);
}
void Assembler::pop(Register dst) {
ASSERT(reloc_info_writer.last_pc() != NULL);
- if (FLAG_peephole_optimization && (reloc_info_writer.last_pc() <= last_pc_)) {
- // (last_pc_ != NULL) is rolled into the above check.
- // If a last_pc_ is set, we need to make sure that there has not been any
- // relocation information generated between the last instruction and this
- // pop instruction.
- byte instr = last_pc_[0];
- if ((instr & ~0x7) == 0x50) {
- int push_reg_code = instr & 0x7;
- if (push_reg_code == dst.code()) {
- pc_ = last_pc_;
- if (FLAG_print_peephole_optimization) {
- PrintF("%d push/pop (same reg) eliminated\n", pc_offset());
- }
- } else {
- // Convert 'push src; pop dst' to 'mov dst, src'.
- last_pc_[0] = 0x8b;
- Register src = { push_reg_code };
- EnsureSpace ensure_space(this);
- emit_operand(dst, Operand(src));
- if (FLAG_print_peephole_optimization) {
- PrintF("%d push/pop (reg->reg) eliminated\n", pc_offset());
- }
- }
- last_pc_ = NULL;
- return;
- } else if (instr == 0xff) { // push of an operand, convert to a move
- byte op1 = last_pc_[1];
- // Check if the operation is really a push.
- if ((op1 & 0x38) == (6 << 3)) {
- op1 = (op1 & ~0x38) | static_cast<byte>(dst.code() << 3);
- last_pc_[0] = 0x8b;
- last_pc_[1] = op1;
- last_pc_ = NULL;
- if (FLAG_print_peephole_optimization) {
- PrintF("%d push/pop (op->reg) eliminated\n", pc_offset());
- }
- return;
- }
- } else if ((instr == 0x89) &&
- (last_pc_[1] == 0x04) &&
- (last_pc_[2] == 0x24)) {
- // 0x71283c 396 890424 mov [esp],eax
- // 0x71283f 399 58 pop eax
- if (dst.is(eax)) {
- // change to
- // 0x710fac 216 83c404 add esp,0x4
- last_pc_[0] = 0x83;
- last_pc_[1] = 0xc4;
- last_pc_[2] = 0x04;
- last_pc_ = NULL;
- if (FLAG_print_peephole_optimization) {
- PrintF("%d push/pop (mov-pop) eliminated\n", pc_offset());
- }
- return;
- }
- } else if (instr == 0x6a && dst.is(eax)) { // push of immediate 8 bit
- byte imm8 = last_pc_[1];
- if (imm8 == 0) {
- // 6a00 push 0x0
- // 58 pop eax
- last_pc_[0] = 0x31;
- last_pc_[1] = 0xc0;
- // change to
- // 31c0 xor eax,eax
- last_pc_ = NULL;
- if (FLAG_print_peephole_optimization) {
- PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset());
- }
- return;
- } else {
- // 6a00 push 0xXX
- // 58 pop eax
- last_pc_[0] = 0xb8;
- EnsureSpace ensure_space(this);
- if ((imm8 & 0x80) != 0) {
- EMIT(0xff);
- EMIT(0xff);
- EMIT(0xff);
- // change to
- // b8XXffffff mov eax,0xffffffXX
- } else {
- EMIT(0x00);
- EMIT(0x00);
- EMIT(0x00);
- // change to
- // b8XX000000 mov eax,0x000000XX
- }
- last_pc_ = NULL;
- if (FLAG_print_peephole_optimization) {
- PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset());
- }
- return;
- }
- } else if (instr == 0x68 && dst.is(eax)) { // push of immediate 32 bit
- // 68XXXXXXXX push 0xXXXXXXXX
- // 58 pop eax
- last_pc_[0] = 0xb8;
- last_pc_ = NULL;
- // change to
- // b8XXXXXXXX mov eax,0xXXXXXXXX
- if (FLAG_print_peephole_optimization) {
- PrintF("%d push/pop (imm->reg) eliminated\n", pc_offset());
- }
- return;
- }
-
- // Other potential patterns for peephole:
- // 0x712716 102 890424 mov [esp], eax
- // 0x712719 105 8b1424 mov edx, [esp]
- }
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x58 | dst.code());
}
void Assembler::pop(const Operand& dst) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x8F);
emit_operand(eax, dst);
}
void Assembler::enter(const Immediate& size) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xC8);
emit_w(size);
EMIT(0);
void Assembler::leave() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xC9);
}
void Assembler::mov_b(Register dst, const Operand& src) {
ASSERT(dst.code() < 4);
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x8A);
emit_operand(dst, src);
}
void Assembler::mov_b(const Operand& dst, int8_t imm8) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xC6);
emit_operand(eax, dst);
EMIT(imm8);
void Assembler::mov_b(const Operand& dst, Register src) {
ASSERT(src.code() < 4);
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x88);
emit_operand(src, dst);
}
void Assembler::mov_w(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x8B);
emit_operand(dst, src);
void Assembler::mov_w(const Operand& dst, Register src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x89);
emit_operand(src, dst);
void Assembler::mov(Register dst, int32_t imm32) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xB8 | dst.code());
emit(imm32);
}
void Assembler::mov(Register dst, const Immediate& x) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xB8 | dst.code());
emit(x);
}
void Assembler::mov(Register dst, Handle<Object> handle) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xB8 | dst.code());
emit(handle);
}
void Assembler::mov(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x8B);
emit_operand(dst, src);
}
void Assembler::mov(Register dst, Register src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x89);
EMIT(0xC0 | src.code() << 3 | dst.code());
}
void Assembler::mov(const Operand& dst, const Immediate& x) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xC7);
emit_operand(eax, dst);
emit(x);
void Assembler::mov(const Operand& dst, Handle<Object> handle) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xC7);
emit_operand(eax, dst);
emit(handle);
void Assembler::mov(const Operand& dst, Register src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x89);
emit_operand(src, dst);
}
void Assembler::movsx_b(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x0F);
EMIT(0xBE);
emit_operand(dst, src);
void Assembler::movsx_w(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x0F);
EMIT(0xBF);
emit_operand(dst, src);
void Assembler::movzx_b(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x0F);
EMIT(0xB6);
emit_operand(dst, src);
void Assembler::movzx_w(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x0F);
EMIT(0xB7);
emit_operand(dst, src);
void Assembler::cmov(Condition cc, Register dst, int32_t imm32) {
ASSERT(CpuFeatures::IsEnabled(CMOV));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
UNIMPLEMENTED();
USE(cc);
USE(dst);
void Assembler::cmov(Condition cc, Register dst, Handle<Object> handle) {
ASSERT(CpuFeatures::IsEnabled(CMOV));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
UNIMPLEMENTED();
USE(cc);
USE(dst);
void Assembler::cmov(Condition cc, Register dst, const Operand& src) {
ASSERT(CpuFeatures::IsEnabled(CMOV));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
// Opcode: 0f 40 + cc /r.
EMIT(0x0F);
EMIT(0x40 + cc);
void Assembler::cld() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xFC);
}
void Assembler::rep_movs() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF3);
EMIT(0xA5);
}
void Assembler::rep_stos() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF3);
EMIT(0xAB);
}
void Assembler::stos() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xAB);
}
void Assembler::xchg(Register dst, Register src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
if (src.is(eax) || dst.is(eax)) { // Single-byte encoding.
EMIT(0x90 | (src.is(eax) ? dst.code() : src.code()));
} else {
void Assembler::adc(Register dst, int32_t imm32) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_arith(2, Operand(dst), Immediate(imm32));
}
void Assembler::adc(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x13);
emit_operand(dst, src);
}
void Assembler::add(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x03);
emit_operand(dst, src);
}
void Assembler::add(const Operand& dst, const Immediate& x) {
ASSERT(reloc_info_writer.last_pc() != NULL);
- if (FLAG_peephole_optimization && (reloc_info_writer.last_pc() <= last_pc_)) {
- byte instr = last_pc_[0];
- if ((instr & 0xf8) == 0x50) {
- // Last instruction was a push. Check whether this is a pop without a
- // result.
- if ((dst.is_reg(esp)) &&
- (x.x_ == kPointerSize) && (x.rmode_ == RelocInfo::NONE)) {
- pc_ = last_pc_;
- last_pc_ = NULL;
- if (FLAG_print_peephole_optimization) {
- PrintF("%d push/pop(noreg) eliminated\n", pc_offset());
- }
- return;
- }
- }
- }
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_arith(0, dst, x);
}
void Assembler::and_(Register dst, const Immediate& x) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_arith(4, Operand(dst), x);
}
void Assembler::and_(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x23);
emit_operand(dst, src);
}
void Assembler::and_(const Operand& dst, const Immediate& x) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_arith(4, dst, x);
}
void Assembler::and_(const Operand& dst, Register src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x21);
emit_operand(src, dst);
}
void Assembler::cmpb(const Operand& op, int8_t imm8) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x80);
emit_operand(edi, op); // edi == 7
EMIT(imm8);
void Assembler::cmpb(const Operand& dst, Register src) {
ASSERT(src.is_byte_register());
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x38);
emit_operand(src, dst);
}
void Assembler::cmpb(Register dst, const Operand& src) {
ASSERT(dst.is_byte_register());
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x3A);
emit_operand(dst, src);
}
void Assembler::cmpw(const Operand& op, Immediate imm16) {
ASSERT(imm16.is_int16());
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x81);
emit_operand(edi, op);
void Assembler::cmp(Register reg, int32_t imm32) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_arith(7, Operand(reg), Immediate(imm32));
}
void Assembler::cmp(Register reg, Handle<Object> handle) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_arith(7, Operand(reg), Immediate(handle));
}
void Assembler::cmp(Register reg, const Operand& op) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x3B);
emit_operand(reg, op);
}
void Assembler::cmp(const Operand& op, const Immediate& imm) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_arith(7, op, imm);
}
void Assembler::cmp(const Operand& op, Handle<Object> handle) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_arith(7, op, Immediate(handle));
}
void Assembler::cmpb_al(const Operand& op) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x38); // CMP r/m8, r8
emit_operand(eax, op); // eax has same code as register al.
}
void Assembler::cmpw_ax(const Operand& op) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x39); // CMP r/m16, r16
emit_operand(eax, op); // eax has same code as register ax.
void Assembler::dec_b(Register dst) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xFE);
EMIT(0xC8 | dst.code());
}
void Assembler::dec_b(const Operand& dst) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xFE);
emit_operand(ecx, dst);
}
void Assembler::dec(Register dst) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x48 | dst.code());
}
void Assembler::dec(const Operand& dst) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xFF);
emit_operand(ecx, dst);
}
void Assembler::cdq() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x99);
}
void Assembler::idiv(Register src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF7);
EMIT(0xF8 | src.code());
}
void Assembler::imul(Register reg) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF7);
EMIT(0xE8 | reg.code());
}
void Assembler::imul(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x0F);
EMIT(0xAF);
emit_operand(dst, src);
void Assembler::imul(Register dst, Register src, int32_t imm32) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
if (is_int8(imm32)) {
EMIT(0x6B);
EMIT(0xC0 | dst.code() << 3 | src.code());
void Assembler::inc(Register dst) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x40 | dst.code());
}
void Assembler::inc(const Operand& dst) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xFF);
emit_operand(eax, dst);
}
void Assembler::lea(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x8D);
emit_operand(dst, src);
}
void Assembler::mul(Register src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF7);
EMIT(0xE0 | src.code());
}
void Assembler::neg(Register dst) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF7);
EMIT(0xD8 | dst.code());
}
void Assembler::not_(Register dst) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF7);
EMIT(0xD0 | dst.code());
}
void Assembler::or_(Register dst, int32_t imm32) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_arith(1, Operand(dst), Immediate(imm32));
}
void Assembler::or_(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x0B);
emit_operand(dst, src);
}
void Assembler::or_(const Operand& dst, const Immediate& x) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_arith(1, dst, x);
}
void Assembler::or_(const Operand& dst, Register src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x09);
emit_operand(src, dst);
}
void Assembler::rcl(Register dst, uint8_t imm8) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
ASSERT(is_uint5(imm8)); // illegal shift count
if (imm8 == 1) {
EMIT(0xD1);
void Assembler::rcr(Register dst, uint8_t imm8) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
ASSERT(is_uint5(imm8)); // illegal shift count
if (imm8 == 1) {
EMIT(0xD1);
void Assembler::sar(Register dst, uint8_t imm8) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
ASSERT(is_uint5(imm8)); // illegal shift count
if (imm8 == 1) {
EMIT(0xD1);
void Assembler::sar_cl(Register dst) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xD3);
EMIT(0xF8 | dst.code());
}
void Assembler::sbb(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x1B);
emit_operand(dst, src);
}
void Assembler::shld(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x0F);
EMIT(0xA5);
emit_operand(dst, src);
void Assembler::shl(Register dst, uint8_t imm8) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
ASSERT(is_uint5(imm8)); // illegal shift count
if (imm8 == 1) {
EMIT(0xD1);
void Assembler::shl_cl(Register dst) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xD3);
EMIT(0xE0 | dst.code());
}
void Assembler::shrd(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x0F);
EMIT(0xAD);
emit_operand(dst, src);
void Assembler::shr(Register dst, uint8_t imm8) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
ASSERT(is_uint5(imm8)); // illegal shift count
if (imm8 == 1) {
EMIT(0xD1);
void Assembler::shr_cl(Register dst) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xD3);
EMIT(0xE8 | dst.code());
}
void Assembler::subb(const Operand& op, int8_t imm8) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
if (op.is_reg(eax)) {
EMIT(0x2c);
} else {
void Assembler::sub(const Operand& dst, const Immediate& x) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_arith(5, dst, x);
}
void Assembler::sub(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x2B);
emit_operand(dst, src);
}
void Assembler::subb(Register dst, const Operand& src) {
ASSERT(dst.code() < 4);
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x2A);
emit_operand(dst, src);
}
void Assembler::sub(const Operand& dst, Register src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x29);
emit_operand(src, dst);
}
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) {
void Assembler::test(Register reg, const Operand& op) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x85);
emit_operand(reg, op);
}
void Assembler::test_b(Register reg, const Operand& op) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x84);
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::test_b(const Operand& op, uint8_t imm8) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF6);
emit_operand(eax, op);
EMIT(imm8);
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::bt(const Operand& dst, Register src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x0F);
EMIT(0xA3);
emit_operand(src, dst);
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(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);
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);
void Assembler::bind(Label* L) {
EnsureSpace ensure_space(this);
- last_pc_ = NULL;
ASSERT(!L->is_bound()); // label can only be bound once
bind_to(L, pc_offset());
}
void Assembler::call(Label* L) {
positions_recorder()->WriteRecordedPositions();
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
if (L->is_bound()) {
const int long_size = 5;
int offs = L->pos() - pc_offset();
void Assembler::call(byte* entry, RelocInfo::Mode rmode) {
positions_recorder()->WriteRecordedPositions();
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) {
positions_recorder()->WriteRecordedPositions();
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xFF);
emit_operand(edx, adr);
- ASSERT(pc_ - last_pc_ == CallSize(adr));
}
unsigned ast_id) {
positions_recorder()->WriteRecordedPositions();
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
ASSERT(RelocInfo::IsCodeTarget(rmode));
EMIT(0xE8);
emit(reinterpret_cast<intptr_t>(code.location()), rmode, ast_id);
void Assembler::jmp(Label* L, Label::Distance distance) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
if (L->is_bound()) {
const int short_size = 2;
const int long_size = 5;
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, Label::Distance distance) {
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()) {
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.
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);
void Assembler::fld(int i) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_farith(0xD9, 0xC0, i);
}
void Assembler::fstp(int i) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_farith(0xDD, 0xD8, i);
}
void Assembler::fld1() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xD9);
EMIT(0xE8);
}
void Assembler::fldpi() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xD9);
EMIT(0xEB);
}
void Assembler::fldz() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xD9);
EMIT(0xEE);
}
void Assembler::fldln2() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xD9);
EMIT(0xED);
}
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::fst_d(const Operand& adr) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xDD);
emit_operand(edx, 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::fisttp_s(const Operand& adr) {
ASSERT(CpuFeatures::IsEnabled(SSE3));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xDB);
emit_operand(ecx, adr);
}
void Assembler::fisttp_d(const Operand& adr) {
ASSERT(CpuFeatures::IsEnabled(SSE3));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xDD);
emit_operand(ecx, 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_;
EMIT(0xDF);
emit_operand(edi, adr);
}
void Assembler::fabs() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xD9);
EMIT(0xE1);
}
void Assembler::fchs() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xD9);
EMIT(0xE0);
}
void Assembler::fcos() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xD9);
EMIT(0xFF);
}
void Assembler::fsin() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xD9);
EMIT(0xFE);
}
void Assembler::fyl2x() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xD9);
EMIT(0xF1);
}
void Assembler::fadd(int i) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_farith(0xDC, 0xC0, i);
}
void Assembler::fsub(int i) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_farith(0xDC, 0xE8, i);
}
void Assembler::fisub_s(const Operand& adr) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xDA);
emit_operand(esp, adr);
}
void Assembler::fmul(int i) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_farith(0xDC, 0xC8, i);
}
void Assembler::fdiv(int i) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_farith(0xDC, 0xF8, i);
}
void Assembler::faddp(int i) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_farith(0xDE, 0xC0, i);
}
void Assembler::fsubp(int i) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_farith(0xDE, 0xE8, i);
}
void Assembler::fsubrp(int i) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_farith(0xDE, 0xE0, i);
}
void Assembler::fmulp(int i) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_farith(0xDE, 0xC8, i);
}
void Assembler::fdivp(int i) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_farith(0xDE, 0xF8, i);
}
void Assembler::fprem() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xD9);
EMIT(0xF8);
}
void Assembler::fprem1() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xD9);
EMIT(0xF5);
}
void Assembler::fxch(int i) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_farith(0xD9, 0xC8, i);
}
void Assembler::fincstp() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xD9);
EMIT(0xF7);
}
void Assembler::ffree(int i) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_farith(0xDD, 0xC0, i);
}
void Assembler::ftst() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xD9);
EMIT(0xE4);
}
void Assembler::fucomp(int i) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
emit_farith(0xDD, 0xE8, i);
}
void Assembler::fucompp() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xDA);
EMIT(0xE9);
}
void Assembler::fucomi(int i) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xDB);
EMIT(0xE8 + i);
}
void Assembler::fucomip() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xDF);
EMIT(0xE9);
}
void Assembler::fcompp() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xDE);
EMIT(0xD9);
}
void Assembler::fnstsw_ax() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xDF);
EMIT(0xE0);
}
void Assembler::fwait() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x9B);
}
void Assembler::frndint() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xD9);
EMIT(0xFC);
}
void Assembler::fnclex() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xDB);
EMIT(0xE2);
}
void Assembler::sahf() {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x9E);
}
void Assembler::setcc(Condition cc, Register reg) {
ASSERT(reg.is_byte_register());
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x0F);
EMIT(0x90 | cc);
EMIT(0xC0 | reg.code());
void Assembler::cvttss2si(Register dst, const Operand& src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF3);
EMIT(0x0F);
EMIT(0x2C);
void Assembler::cvttsd2si(Register dst, const Operand& src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF2);
EMIT(0x0F);
EMIT(0x2C);
void Assembler::cvtsi2sd(XMMRegister dst, const Operand& src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF2);
EMIT(0x0F);
EMIT(0x2A);
void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF3);
EMIT(0x0F);
EMIT(0x5A);
void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF2);
EMIT(0x0F);
EMIT(0x5A);
void Assembler::addsd(XMMRegister dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF2);
EMIT(0x0F);
EMIT(0x58);
void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF2);
EMIT(0x0F);
EMIT(0x59);
void Assembler::subsd(XMMRegister dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF2);
EMIT(0x0F);
EMIT(0x5C);
void Assembler::divsd(XMMRegister dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF2);
EMIT(0x0F);
EMIT(0x5E);
void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x0F);
EMIT(0x57);
void Assembler::xorps(XMMRegister dst, XMMRegister src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x0F);
EMIT(0x57);
emit_sse_operand(dst, src);
void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF2);
EMIT(0x0F);
EMIT(0x51);
void Assembler::andpd(XMMRegister dst, XMMRegister src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x0F);
EMIT(0x54);
void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x0F);
EMIT(0x2E);
void Assembler::movmskpd(Register dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x0F);
EMIT(0x50);
void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF2);
EMIT(0x0F);
EMIT(0xC2);
void Assembler::movaps(XMMRegister dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x0F);
EMIT(0x28);
emit_sse_operand(dst, src);
void Assembler::movdqa(const Operand& dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x0F);
EMIT(0x7F);
void Assembler::movdqa(XMMRegister dst, const Operand& src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x0F);
EMIT(0x6F);
void Assembler::movdqu(const Operand& dst, XMMRegister src ) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF3);
EMIT(0x0F);
EMIT(0x7F);
void Assembler::movdqu(XMMRegister dst, const Operand& src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF3);
EMIT(0x0F);
EMIT(0x6F);
void Assembler::movntdqa(XMMRegister dst, const Operand& src) {
ASSERT(CpuFeatures::IsEnabled(SSE4_1));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x0F);
EMIT(0x38);
void Assembler::movntdq(const Operand& dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x0F);
EMIT(0xE7);
void Assembler::prefetch(const Operand& src, int level) {
ASSERT(is_uint2(level));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x0F);
EMIT(0x18);
XMMRegister code = { level }; // Emit hint number in Reg position of RegR/M.
void Assembler::movdbl(XMMRegister dst, const Operand& src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
movsd(dst, src);
}
void Assembler::movdbl(const Operand& dst, XMMRegister src) {
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
movsd(dst, src);
}
void Assembler::movsd(const Operand& dst, XMMRegister src ) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF2); // double
EMIT(0x0F);
EMIT(0x11); // store
void Assembler::movsd(XMMRegister dst, const Operand& src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF2); // double
EMIT(0x0F);
EMIT(0x10); // load
void Assembler::movsd(XMMRegister dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF2);
EMIT(0x0F);
EMIT(0x10);
void Assembler::movss(const Operand& dst, XMMRegister src ) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF3); // float
EMIT(0x0F);
EMIT(0x11); // store
void Assembler::movss(XMMRegister dst, const Operand& src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF3); // float
EMIT(0x0F);
EMIT(0x10); // load
void Assembler::movss(XMMRegister dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0xF3);
EMIT(0x0F);
EMIT(0x10);
void Assembler::movd(XMMRegister dst, const Operand& src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x0F);
EMIT(0x6E);
void Assembler::movd(const Operand& dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x0F);
EMIT(0x7E);
void Assembler::pand(XMMRegister dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x0F);
EMIT(0xDB);
void Assembler::pxor(XMMRegister dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x0F);
EMIT(0xEF);
void Assembler::por(XMMRegister dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x0F);
EMIT(0xEB);
void Assembler::ptest(XMMRegister dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE4_1));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x0F);
EMIT(0x38);
void Assembler::psllq(XMMRegister reg, int8_t shift) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x0F);
EMIT(0x73);
void Assembler::psllq(XMMRegister dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x0F);
EMIT(0xF3);
void Assembler::psrlq(XMMRegister reg, int8_t shift) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x0F);
EMIT(0x73);
void Assembler::psrlq(XMMRegister dst, XMMRegister src) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x0F);
EMIT(0xD3);
void Assembler::pshufd(XMMRegister dst, XMMRegister src, int8_t shuffle) {
ASSERT(CpuFeatures::IsEnabled(SSE2));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x0F);
EMIT(0x70);
void Assembler::pextrd(const Operand& dst, XMMRegister src, int8_t offset) {
ASSERT(CpuFeatures::IsEnabled(SSE4_1));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x0F);
EMIT(0x3A);
void Assembler::pinsrd(XMMRegister dst, const Operand& src, int8_t offset) {
ASSERT(CpuFeatures::IsEnabled(SSE4_1));
EnsureSpace ensure_space(this);
- last_pc_ = pc_;
EMIT(0x66);
EMIT(0x0F);
EMIT(0x3A);
buffer_ = desc.buffer;
buffer_size_ = desc.buffer_size;
pc_ += pc_delta;
- if (last_pc_ != NULL) {
- last_pc_ += pc_delta;
- }
reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
reloc_info_writer.last_pc() + pc_delta);