📄 assembler-arm.cc.svn-base
字号:
int imm24 = branch_offset >> 2; ASSERT(is_int24(imm24)); emit(cond | B27 | B25 | B24 | (imm24 & Imm24Mask));}void Assembler::blx(int branch_offset) { // v5 and above ASSERT((branch_offset & 1) == 0); int h = ((branch_offset & 2) >> 1)*B24; int imm24 = branch_offset >> 2; ASSERT(is_int24(imm24)); emit(15 << 28 | B27 | B25 | h | (imm24 & Imm24Mask));}void Assembler::blx(Register target, Condition cond) { // v5 and above ASSERT(!target.is(pc)); emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | 3*B4 | target.code());}void Assembler::bx(Register target, Condition cond) { // v5 and above, plus v4t ASSERT(!target.is(pc)); // use of pc is actually allowed, but discouraged emit(cond | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | B4 | target.code());}// Data-processing instructionsvoid Assembler::and_(Register dst, Register src1, const Operand& src2, SBit s, Condition cond) { addrmod1(cond | 0*B21 | s, src1, dst, src2);}void Assembler::eor(Register dst, Register src1, const Operand& src2, SBit s, Condition cond) { addrmod1(cond | 1*B21 | s, src1, dst, src2);}void Assembler::sub(Register dst, Register src1, const Operand& src2, SBit s, Condition cond) { addrmod1(cond | 2*B21 | s, src1, dst, src2);}void Assembler::rsb(Register dst, Register src1, const Operand& src2, SBit s, Condition cond) { addrmod1(cond | 3*B21 | s, src1, dst, src2);}void Assembler::add(Register dst, Register src1, const Operand& src2, SBit s, Condition cond) { addrmod1(cond | 4*B21 | 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. int pattern_size = 2 * kInstrSize; if (FLAG_push_pop_elimination && last_bound_pos_ <= (pc_offset() - pattern_size) && reloc_info_writer.last_pc() <= (pc_ - pattern_size) && // pattern instr_at(pc_ - 1 * kInstrSize) == kPopInstruction && (instr_at(pc_ - 2 * kInstrSize) & ~RdMask) == kPushRegPattern) { pc_ -= 2 * kInstrSize; if (FLAG_print_push_pop_elimination) { PrintF("%x push(reg)/pop() eliminated\n", pc_offset()); } }}void Assembler::adc(Register dst, Register src1, const Operand& src2, SBit s, Condition cond) { addrmod1(cond | 5*B21 | s, src1, dst, src2);}void Assembler::sbc(Register dst, Register src1, const Operand& src2, SBit s, Condition cond) { addrmod1(cond | 6*B21 | s, src1, dst, src2);}void Assembler::rsc(Register dst, Register src1, const Operand& src2, SBit s, Condition cond) { addrmod1(cond | 7*B21 | s, src1, dst, src2);}void Assembler::tst(Register src1, const Operand& src2, Condition cond) { addrmod1(cond | 8*B21 | S, src1, r0, src2);}void Assembler::teq(Register src1, const Operand& src2, Condition cond) { addrmod1(cond | 9*B21 | S, src1, r0, src2);}void Assembler::cmp(Register src1, const Operand& src2, Condition cond) { addrmod1(cond | 10*B21 | S, src1, r0, src2);}void Assembler::cmn(Register src1, const Operand& src2, Condition cond) { addrmod1(cond | 11*B21 | S, src1, r0, src2);}void Assembler::orr(Register dst, Register src1, const Operand& src2, SBit s, Condition cond) { addrmod1(cond | 12*B21 | s, src1, dst, src2);}void Assembler::mov(Register dst, const Operand& src, SBit s, Condition cond) { addrmod1(cond | 13*B21 | s, r0, dst, src);}void Assembler::bic(Register dst, Register src1, const Operand& src2, SBit s, Condition cond) { addrmod1(cond | 14*B21 | s, src1, dst, src2);}void Assembler::mvn(Register dst, const Operand& src, SBit s, Condition cond) { addrmod1(cond | 15*B21 | s, r0, dst, src);}// Multiply instructionsvoid Assembler::mla(Register dst, Register src1, Register src2, Register srcA, SBit s, Condition cond) { ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc)); ASSERT(!dst.is(src1)); emit(cond | A | s | dst.code()*B16 | srcA.code()*B12 | src2.code()*B8 | B7 | B4 | src1.code());}void Assembler::mul(Register dst, Register src1, Register src2, SBit s, Condition cond) { ASSERT(!dst.is(pc) && !src1.is(pc) && !src2.is(pc)); ASSERT(!dst.is(src1)); emit(cond | s | dst.code()*B16 | src2.code()*B8 | B7 | B4 | src1.code());}void Assembler::smlal(Register dstL, Register dstH, Register src1, Register src2, SBit s, Condition cond) { ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc)); ASSERT(!dstL.is(dstH) && !dstH.is(src1) && !src1.is(dstL)); emit(cond | B23 | B22 | A | s | dstH.code()*B16 | dstL.code()*B12 | src2.code()*B8 | B7 | B4 | src1.code());}void Assembler::smull(Register dstL, Register dstH, Register src1, Register src2, SBit s, Condition cond) { ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc)); ASSERT(!dstL.is(dstH) && !dstH.is(src1) && !src1.is(dstL)); emit(cond | B23 | B22 | s | dstH.code()*B16 | dstL.code()*B12 | src2.code()*B8 | B7 | B4 | src1.code());}void Assembler::umlal(Register dstL, Register dstH, Register src1, Register src2, SBit s, Condition cond) { ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc)); ASSERT(!dstL.is(dstH) && !dstH.is(src1) && !src1.is(dstL)); emit(cond | B23 | A | s | dstH.code()*B16 | dstL.code()*B12 | src2.code()*B8 | B7 | B4 | src1.code());}void Assembler::umull(Register dstL, Register dstH, Register src1, Register src2, SBit s, Condition cond) { ASSERT(!dstL.is(pc) && !dstH.is(pc) && !src1.is(pc) && !src2.is(pc)); ASSERT(!dstL.is(dstH) && !dstH.is(src1) && !src1.is(dstL)); emit(cond | B23 | s | dstH.code()*B16 | dstL.code()*B12 | src2.code()*B8 | B7 | B4 | src1.code());}// Miscellaneous arithmetic instructionsvoid Assembler::clz(Register dst, Register src, Condition cond) { // v5 and above. ASSERT(!dst.is(pc) && !src.is(pc)); emit(cond | B24 | B22 | B21 | 15*B16 | dst.code()*B12 | 15*B8 | B4 | src.code());}// Status register access instructionsvoid Assembler::mrs(Register dst, SRegister s, Condition cond) { ASSERT(!dst.is(pc)); emit(cond | B24 | s | 15*B16 | dst.code()*B12);}void Assembler::msr(SRegisterFieldMask fields, const Operand& src, Condition cond) { ASSERT(fields >= B16 && fields < B20); // at least one field set Instr instr; if (!src.rm_.is_valid()) { // immediate uint32_t rotate_imm; uint32_t immed_8; if ((src.rmode_ != RelocInfo::NONE && src.rmode_ != RelocInfo::EXTERNAL_REFERENCE)|| !fits_shifter(src.imm32_, &rotate_imm, &immed_8, NULL)) { // immediate operand cannot be encoded, load it first to register ip RecordRelocInfo(src.rmode_, src.imm32_); ldr(ip, MemOperand(pc, 0), cond); msr(fields, Operand(ip), cond); return; } instr = I | rotate_imm*B8 | immed_8; } else { ASSERT(!src.rs_.is_valid() && src.shift_imm_ == 0); // only rm allowed instr = src.rm_.code(); } emit(cond | instr | B24 | B21 | fields | 15*B12);}// Load/Store instructionsvoid Assembler::ldr(Register dst, const MemOperand& src, Condition cond) { addrmod2(cond | B26 | L, dst, src); // Eliminate pattern: push(r), pop(r) // str(r, MemOperand(sp, 4, NegPreIndex), al) // ldr(r, MemOperand(sp, 4, PostIndex), al) // Both instructions can be eliminated. int pattern_size = 2 * kInstrSize; if (FLAG_push_pop_elimination && last_bound_pos_ <= (pc_offset() - pattern_size) && reloc_info_writer.last_pc() <= (pc_ - pattern_size) && // pattern instr_at(pc_ - 1 * kInstrSize) == (kPopRegPattern | dst.code() * B12) && instr_at(pc_ - 2 * kInstrSize) == (kPushRegPattern | dst.code() * B12)) { pc_ -= 2 * kInstrSize; if (FLAG_print_push_pop_elimination) { PrintF("%x push/pop (same reg) eliminated\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 int pattern_size = 2 * kInstrSize; if (FLAG_push_pop_elimination && last_bound_pos_ <= (pc_offset() - pattern_size) && reloc_info_writer.last_pc() <= (pc_ - pattern_size) && 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_push_pop_elimination) { PrintF("%x pop()/push(reg) eliminated\n", pc_offset()); } }}void Assembler::ldrb(Register dst, const MemOperand& src, Condition cond) { addrmod2(cond | B26 | B | L, dst, src);}void Assembler::strb(Register src, const MemOperand& dst, Condition cond) { addrmod2(cond | B26 | B, src, dst);}void Assembler::ldrh(Register dst, const MemOperand& src, Condition cond) { addrmod3(cond | L | B7 | H | B4, dst, src);}void Assembler::strh(Register src, const MemOperand& dst, Condition cond) { addrmod3(cond | B7 | H | B4, src, dst);}void Assembler::ldrsb(Register dst, const MemOperand& src, Condition cond) { addrmod3(cond | L | B7 | S6 | B4, dst, src);}void Assembler::ldrsh(Register dst, const MemOperand& src, Condition cond) { addrmod3(cond | L | B7 | S6 | H | B4, dst, src);}// Load/Store multiple instructionsvoid Assembler::ldm(BlockAddrMode am, Register base, RegList dst, Condition cond) { // ABI stack constraint: ldmxx base, {..sp..} base != sp is not restartable ASSERT(base.is(sp) || (dst & sp.bit()) == 0); addrmod4(cond | B27 | am | L, base, dst); // emit the constant pool after a function return implemented by ldm ..{..pc} if (cond == al && (dst & pc.bit()) != 0) { // There is a slight chance that the ldm instruction was actually a call, // in which case it would be wrong to return into the constant pool; we // recognize this case by checking if the emission of the pool was blocked // at the pc of the ldm instruction by a mov lr, pc instruction; if this is // the case, we emit a jump over the pool. CheckConstPool(true, no_const_pool_before_ == pc_offset() - kInstrSize); }}void Assembler::stm(BlockAddrMode am, Register base, RegList src, Condition cond) { addrmod4(cond | B27 | am, base, src);}// Semaphore instructionsvoid Assembler::swp(Register dst, Register src, Register base, Condition cond) { ASSERT(!dst.is(pc) && !src.is(pc) && !base.is(pc)); ASSERT(!dst.is(base) && !src.is(base)); emit(cond | P | base.code()*B16 | dst.code()*B12 | B7 | B4 | src.code());}void Assembler::swpb(Register dst, Register src, Register base, Condition cond) { ASSERT(!dst.is(pc) && !src.is(pc) && !base.is(pc)); ASSERT(!dst.is(base) && !src.is(base)); emit(cond | P | B | base.code()*B16 | dst.code()*B12 | B7 | B4 | src.code());}// Exception-generating instructions and debugging supportvoid Assembler::stop(const char* msg) {#if !defined(__arm__) // The simulator handles these special instructions and stops execution. emit(15 << 28 | ((intptr_t) msg));#else // Just issue a simple break instruction for now. Alternatively we could use // the swi(0x9f0001) instruction on Linux. bkpt(0);#endif}void Assembler::bkpt(uint32_t imm16) { // v5 and above ASSERT(is_uint16(imm16)); emit(al | B24 | B21 | (imm16 >> 4)*B8 | 7*B4 | (imm16 & 0xf));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -