DecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size, const MemoryObject &Region, uint64_t Address, raw_ostream &os, raw_ostream &cs) const { CommentStream = &cs; uint8_t bytes[4]; // We want to read exactly 4 bytes of data. if (Region.readBytes(Address, 4, (uint8_t*)bytes, NULL) == -1) { Size = 0; return MCDisassembler::Fail; } // Encoded as a small-endian 32-bit word in the stream. uint32_t insn = (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | (bytes[0] << 0); // Calling the auto-generated decoder function. DecodeStatus result = decodeInstruction(DecoderTableA6432, MI, insn, Address, this, STI); if (result != MCDisassembler::Fail) { Size = 4; return result; } MI.clear(); Size = 0; return MCDisassembler::Fail; }
static DecodeStatus DecodeL5RInstructionFail(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder) { // Try and decode as a L6R instruction. Inst.clear(); unsigned Opcode = fieldFromInstruction(Insn, 27, 5); switch (Opcode) { case 0x00: Inst.setOpcode(XCore::LMUL_l6r); return DecodeL6RInstruction(Inst, Insn, Address, Decoder); } return MCDisassembler::Fail; }
void HexagonMCShuffler::copyTo(MCInst &MCB) { MCB.clear(); MCB.addOperand(MCOperand::createImm(BundleFlags)); // Copy the results into the bundle. for (HexagonShuffler::iterator I = begin(); I != end(); ++I) { MCInst const *MI = I->getDesc(); MCInst const *Extender = I->getExtender(); if (Extender) MCB.addOperand(MCOperand::createInst(Extender)); MCB.addOperand(MCOperand::createInst(MI)); } }
void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst, const MachineInstr &MI) { MCInst &MappedInst = static_cast <MCInst &>(Inst); const MCRegisterInfo *RI = OutStreamer->getContext().getRegisterInfo(); switch (Inst.getOpcode()) { default: return; case Hexagon::A2_iconst: { Inst.setOpcode(Hexagon::A2_addi); MCOperand Reg = Inst.getOperand(0); MCOperand S16 = Inst.getOperand(1); HexagonMCInstrInfo::setMustNotExtend(*S16.getExpr()); HexagonMCInstrInfo::setS23_2_reloc(*S16.getExpr()); Inst.clear(); Inst.addOperand(Reg); Inst.addOperand(MCOperand::createReg(Hexagon::R0)); Inst.addOperand(S16); break; } // "$dst = CONST64(#$src1)", case Hexagon::CONST64: if (!OutStreamer->hasRawTextSupport()) { const MCOperand &Imm = MappedInst.getOperand(1); MCSectionSubPair Current = OutStreamer->getCurrentSection(); MCSymbol *Sym = smallData(*this, MI, *OutStreamer, Imm, 8); OutStreamer->SwitchSection(Current.first, Current.second); MCInst TmpInst; MCOperand &Reg = MappedInst.getOperand(0); TmpInst.setOpcode(Hexagon::L2_loadrdgp); TmpInst.addOperand(Reg); TmpInst.addOperand(MCOperand::createExpr( MCSymbolRefExpr::create(Sym, OutContext))); MappedInst = TmpInst; } break; case Hexagon::CONST32: if (!OutStreamer->hasRawTextSupport()) { MCOperand &Imm = MappedInst.getOperand(1); MCSectionSubPair Current = OutStreamer->getCurrentSection(); MCSymbol *Sym = smallData(*this, MI, *OutStreamer, Imm, 4); OutStreamer->SwitchSection(Current.first, Current.second); MCInst TmpInst; MCOperand &Reg = MappedInst.getOperand(0); TmpInst.setOpcode(Hexagon::L2_loadrigp); TmpInst.addOperand(Reg); TmpInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create( MCSymbolRefExpr::create(Sym, OutContext), OutContext))); MappedInst = TmpInst; } break; // C2_pxfer_map maps to C2_or instruction. Though, it's possible to use // C2_or during instruction selection itself but it results // into suboptimal code. case Hexagon::C2_pxfer_map: { MCOperand &Ps = Inst.getOperand(1); MappedInst.setOpcode(Hexagon::C2_or); MappedInst.addOperand(Ps); return; } // Vector reduce complex multiply by scalar, Rt & 1 map to :hi else :lo // The insn is mapped from the 4 operand to the 3 operand raw form taking // 3 register pairs. case Hexagon::M2_vrcmpys_acc_s1: { MCOperand &Rt = Inst.getOperand(3); assert (Rt.isReg() && "Expected register and none was found"); unsigned Reg = RI->getEncodingValue(Rt.getReg()); if (Reg & 1) MappedInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_h); else MappedInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_l); Rt.setReg(getHexagonRegisterPair(Rt.getReg(), RI)); return; } case Hexagon::M2_vrcmpys_s1: { MCOperand &Rt = Inst.getOperand(2); assert (Rt.isReg() && "Expected register and none was found"); unsigned Reg = RI->getEncodingValue(Rt.getReg()); if (Reg & 1) MappedInst.setOpcode(Hexagon::M2_vrcmpys_s1_h); else MappedInst.setOpcode(Hexagon::M2_vrcmpys_s1_l); Rt.setReg(getHexagonRegisterPair(Rt.getReg(), RI)); return; } case Hexagon::M2_vrcmpys_s1rp: { MCOperand &Rt = Inst.getOperand(2); assert (Rt.isReg() && "Expected register and none was found"); unsigned Reg = RI->getEncodingValue(Rt.getReg()); if (Reg & 1) MappedInst.setOpcode(Hexagon::M2_vrcmpys_s1rp_h); else MappedInst.setOpcode(Hexagon::M2_vrcmpys_s1rp_l); Rt.setReg(getHexagonRegisterPair(Rt.getReg(), RI)); return; } case Hexagon::A4_boundscheck: { MCOperand &Rs = Inst.getOperand(1); assert (Rs.isReg() && "Expected register and none was found"); unsigned Reg = RI->getEncodingValue(Rs.getReg()); if (Reg & 1) // Odd mapped to raw:hi, regpair is rodd:odd-1, like r3:2 MappedInst.setOpcode(Hexagon::A4_boundscheck_hi); else // raw:lo MappedInst.setOpcode(Hexagon::A4_boundscheck_lo); Rs.setReg(getHexagonRegisterPair(Rs.getReg(), RI)); return; } case Hexagon::S5_asrhub_rnd_sat_goodsyntax: { MCOperand &MO = MappedInst.getOperand(2); int64_t Imm; MCExpr const *Expr = MO.getExpr(); bool Success = Expr->evaluateAsAbsolute(Imm); assert (Success && "Expected immediate and none was found"); (void)Success; MCInst TmpInst; if (Imm == 0) { TmpInst.setOpcode(Hexagon::S2_vsathub); TmpInst.addOperand(MappedInst.getOperand(0)); TmpInst.addOperand(MappedInst.getOperand(1)); MappedInst = TmpInst; return; } TmpInst.setOpcode(Hexagon::S5_asrhub_rnd_sat); TmpInst.addOperand(MappedInst.getOperand(0)); TmpInst.addOperand(MappedInst.getOperand(1)); const MCExpr *One = MCConstantExpr::create(1, OutContext); const MCExpr *Sub = MCBinaryExpr::createSub(Expr, One, OutContext); TmpInst.addOperand( MCOperand::createExpr(HexagonMCExpr::create(Sub, OutContext))); MappedInst = TmpInst; return; } case Hexagon::S5_vasrhrnd_goodsyntax: case Hexagon::S2_asr_i_p_rnd_goodsyntax: { MCOperand &MO2 = MappedInst.getOperand(2); MCExpr const *Expr = MO2.getExpr(); int64_t Imm; bool Success = Expr->evaluateAsAbsolute(Imm); assert (Success && "Expected immediate and none was found"); (void)Success; MCInst TmpInst; if (Imm == 0) { TmpInst.setOpcode(Hexagon::A2_combinew); TmpInst.addOperand(MappedInst.getOperand(0)); MCOperand &MO1 = MappedInst.getOperand(1); unsigned High = RI->getSubReg(MO1.getReg(), Hexagon::subreg_hireg); unsigned Low = RI->getSubReg(MO1.getReg(), Hexagon::subreg_loreg); // Add a new operand for the second register in the pair. TmpInst.addOperand(MCOperand::createReg(High)); TmpInst.addOperand(MCOperand::createReg(Low)); MappedInst = TmpInst; return; } if (Inst.getOpcode() == Hexagon::S2_asr_i_p_rnd_goodsyntax) TmpInst.setOpcode(Hexagon::S2_asr_i_p_rnd); else TmpInst.setOpcode(Hexagon::S5_vasrhrnd); TmpInst.addOperand(MappedInst.getOperand(0)); TmpInst.addOperand(MappedInst.getOperand(1)); const MCExpr *One = MCConstantExpr::create(1, OutContext); const MCExpr *Sub = MCBinaryExpr::createSub(Expr, One, OutContext); TmpInst.addOperand( MCOperand::createExpr(HexagonMCExpr::create(Sub, OutContext))); MappedInst = TmpInst; return; } // if ("#u5==0") Assembler mapped to: "Rd=Rs"; else Rd=asr(Rs,#u5-1):rnd case Hexagon::S2_asr_i_r_rnd_goodsyntax: { MCOperand &MO = Inst.getOperand(2); MCExpr const *Expr = MO.getExpr(); int64_t Imm; bool Success = Expr->evaluateAsAbsolute(Imm); assert (Success && "Expected immediate and none was found"); (void)Success; MCInst TmpInst; if (Imm == 0) { TmpInst.setOpcode(Hexagon::A2_tfr); TmpInst.addOperand(MappedInst.getOperand(0)); TmpInst.addOperand(MappedInst.getOperand(1)); MappedInst = TmpInst; return; } TmpInst.setOpcode(Hexagon::S2_asr_i_r_rnd); TmpInst.addOperand(MappedInst.getOperand(0)); TmpInst.addOperand(MappedInst.getOperand(1)); const MCExpr *One = MCConstantExpr::create(1, OutContext); const MCExpr *Sub = MCBinaryExpr::createSub(Expr, One, OutContext); TmpInst.addOperand( MCOperand::createExpr(HexagonMCExpr::create(Sub, OutContext))); MappedInst = TmpInst; return; } // Translate a "$Rdd = #imm" to "$Rdd = combine(#[-1,0], #imm)" case Hexagon::A2_tfrpi: { MCInst TmpInst; MCOperand &Rdd = MappedInst.getOperand(0); MCOperand &MO = MappedInst.getOperand(1); TmpInst.setOpcode(Hexagon::A2_combineii); TmpInst.addOperand(Rdd); int64_t Imm; bool Success = MO.getExpr()->evaluateAsAbsolute(Imm); if (Success && Imm < 0) { const MCExpr *MOne = MCConstantExpr::create(-1, OutContext); TmpInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(MOne, OutContext))); } else { const MCExpr *Zero = MCConstantExpr::create(0, OutContext); TmpInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(Zero, OutContext))); } TmpInst.addOperand(MO); MappedInst = TmpInst; return; } // Translate a "$Rdd = $Rss" to "$Rdd = combine($Rs, $Rt)" case Hexagon::A2_tfrp: { MCOperand &MO = MappedInst.getOperand(1); unsigned High = RI->getSubReg(MO.getReg(), Hexagon::subreg_hireg); unsigned Low = RI->getSubReg(MO.getReg(), Hexagon::subreg_loreg); MO.setReg(High); // Add a new operand for the second register in the pair. MappedInst.addOperand(MCOperand::createReg(Low)); MappedInst.setOpcode(Hexagon::A2_combinew); return; } case Hexagon::A2_tfrpt: case Hexagon::A2_tfrpf: { MCOperand &MO = MappedInst.getOperand(2); unsigned High = RI->getSubReg(MO.getReg(), Hexagon::subreg_hireg); unsigned Low = RI->getSubReg(MO.getReg(), Hexagon::subreg_loreg); MO.setReg(High); // Add a new operand for the second register in the pair. MappedInst.addOperand(MCOperand::createReg(Low)); MappedInst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrpt) ? Hexagon::C2_ccombinewt : Hexagon::C2_ccombinewf); return; } case Hexagon::A2_tfrptnew: case Hexagon::A2_tfrpfnew: { MCOperand &MO = MappedInst.getOperand(2); unsigned High = RI->getSubReg(MO.getReg(), Hexagon::subreg_hireg); unsigned Low = RI->getSubReg(MO.getReg(), Hexagon::subreg_loreg); MO.setReg(High); // Add a new operand for the second register in the pair. MappedInst.addOperand(MCOperand::createReg(Low)); MappedInst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrptnew) ? Hexagon::C2_ccombinewnewt : Hexagon::C2_ccombinewnewf); return; } case Hexagon::M2_mpysmi: { MCOperand &Imm = MappedInst.getOperand(2); MCExpr const *Expr = Imm.getExpr(); int64_t Value; bool Success = Expr->evaluateAsAbsolute(Value); assert(Success); (void)Success; if (Value < 0 && Value > -256) { MappedInst.setOpcode(Hexagon::M2_mpysin); Imm.setExpr(HexagonMCExpr::create( MCUnaryExpr::createMinus(Expr, OutContext), OutContext)); } else MappedInst.setOpcode(Hexagon::M2_mpysip); return; } case Hexagon::A2_addsp: { MCOperand &Rt = Inst.getOperand(1); assert (Rt.isReg() && "Expected register and none was found"); unsigned Reg = RI->getEncodingValue(Rt.getReg()); if (Reg & 1) MappedInst.setOpcode(Hexagon::A2_addsph); else MappedInst.setOpcode(Hexagon::A2_addspl); Rt.setReg(getHexagonRegisterPair(Rt.getReg(), RI)); return; } case Hexagon::HEXAGON_V6_vd0_pseudo: case Hexagon::HEXAGON_V6_vd0_pseudo_128B: { MCInst TmpInst; assert (Inst.getOperand(0).isReg() && "Expected register and none was found"); TmpInst.setOpcode(Hexagon::V6_vxor); TmpInst.addOperand(Inst.getOperand(0)); TmpInst.addOperand(Inst.getOperand(0)); TmpInst.addOperand(Inst.getOperand(0)); MappedInst = TmpInst; return; } } }