Example #1
0
// Pick a DEXT or DINS instruction variant based on the pos and size operands
static void LowerDextDins(MCInst& InstIn) {
    int Opcode = InstIn.getOpcode();

    if (Opcode == Mips::DEXT)
        assert(InstIn.getNumOperands() == 4 &&
               "Invalid no. of machine operands for DEXT!");
    else // Only DEXT and DINS are possible
        assert(InstIn.getNumOperands() == 5 &&
               "Invalid no. of machine operands for DINS!");

    assert(InstIn.getOperand(2).isImm());
    int64_t pos = InstIn.getOperand(2).getImm();
    assert(InstIn.getOperand(3).isImm());
    int64_t size = InstIn.getOperand(3).getImm();

    if (size <= 32) {
        if (pos < 32)  // DEXT/DINS, do nothing
            return;
        // DEXTU/DINSU
        InstIn.getOperand(2).setImm(pos - 32);
        InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU);
        return;
    }
    // DEXTM/DINSM
    assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32");
    InstIn.getOperand(3).setImm(size - 32);
    InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM);
    return;
}
Example #2
0
static bool getARMLoadDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI,
                                      std::string &Info) {
  assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] &&
         "cannot predicate thumb instructions");

  assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
  bool ListContainsPC = false, ListContainsLR = false;
  for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) {
    assert(MI.getOperand(OI).isReg() && "expected register");
    switch (MI.getOperand(OI).getReg()) {
    default:
      break;
    case ARM::LR:
      ListContainsLR = true;
      break;
    case ARM::PC:
      ListContainsPC = true;
      break;
    case ARM::SP:
      Info = "use of SP in the list is deprecated";
      return true;
    }
  }

  if (ListContainsPC && ListContainsLR) {
    Info = "use of LR and PC simultaneously in the list is deprecated";
    return true;
  }

  return false;
}
void WebAssemblyMCCodeEmitter::encodeInstruction(
    const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups,
    const MCSubtargetInfo &STI) const {
  // FIXME: This is not the real binary encoding. This is an extremely
  // over-simplified encoding where we just use uint64_t for everything. This
  // is a temporary measure.
  support::endian::Writer<support::little>(OS).write<uint64_t>(MI.getOpcode());
  const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
  if (Desc.isVariadic())
    support::endian::Writer<support::little>(OS).write<uint64_t>(
        MI.getNumOperands() - Desc.NumOperands);
  for (unsigned i = 0, e = MI.getNumOperands(); i < e; ++i) {
    const MCOperand &MO = MI.getOperand(i);
    if (MO.isReg()) {
      support::endian::Writer<support::little>(OS).write<uint64_t>(MO.getReg());
    } else if (MO.isImm()) {
      support::endian::Writer<support::little>(OS).write<uint64_t>(MO.getImm());
    } else if (MO.isFPImm()) {
      support::endian::Writer<support::little>(OS).write<double>(MO.getFPImm());
    } else if (MO.isExpr()) {
      support::endian::Writer<support::little>(OS).write<uint64_t>(0);
      Fixups.push_back(MCFixup::create(
          (1 + MCII.get(MI.getOpcode()).isVariadic() + i) * sizeof(uint64_t),
          MO.getExpr(),
          STI.getTargetTriple().isArch64Bit() ? FK_Data_8 : FK_Data_4,
          MI.getLoc()));
      ++MCNumFixups;
    } else {
      llvm_unreachable("unexpected operand kind");
    }
  }

  ++MCNumEmitted; // Keep track of the # of mi's emitted.
}
Example #4
0
static bool getARMStoreDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI,
                                       std::string &Info) {
  assert(MI.getNumOperands() > 4 && "expected >4 arguments");
  for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) {
    assert(MI.getOperand(OI).isReg() && "expected register");
    if (MI.getOperand(OI).getReg() == ARM::SP ||
        MI.getOperand(OI).getReg() == ARM::PC) {
      Info = "use of SP or PC in the list is deprecated";
      return true;
    }
  }
  return false;
}
static InstTransResult translate_CALL32r(NativeModulePtr  natM,
                                         BasicBlock       *&block,
                                         InstPtr          ip,
                                         MCInst           &inst)
{
  const MCOperand &tgtOp = inst.getOperand(0);
  //we are calling a register! this is VERY EXCITING
  //first, we need to know which register we are calling. read that
  //register, then make a call to the external procedure. 
  //the external procedure has a signature of
  // void do_call_value(Value *loc, struct regs *r); 

  TASSERT(inst.getNumOperands() == 1, "");
  TASSERT(tgtOp.isReg(), "");

  //read the register
  Value *fromReg = R_READ<32>(block, tgtOp.getReg());

  Module *M = block->getParent()->getParent();
  const std::string &triple = M->getTargetTriple();
  if(triple != WINDOWS_TRIPLE) {
      writeFakeReturnAddr(block);
  }

  doCallV(block, ip, fromReg);

  return ContinueBlock;
}
void X86::X86MCNaClExpander::expandReturn(const MCInst &Inst, MCStreamer &Out,
                                          const MCSubtargetInfo &STI) {
  if (numScratchRegs() == 0) {
    Error(Inst, "No scratch registers specified.");
    exit(1);
  }

  MCOperand ScratchReg = MCOperand::CreateReg(getReg32(getScratchReg(0)));
  MCInst Pop;
  Pop.setOpcode(X86::POP32r);
  Pop.addOperand(ScratchReg);
  Out.EmitInstruction(Pop, STI);

  if (Inst.getNumOperands() > 0) {
    assert(Inst.getOpcode() == X86::RETIL);
    MCInst Add;
    Add.setOpcode(X86::ADD32ri);
    Add.addOperand(MCOperand::CreateReg(X86::ESP));
    Add.addOperand(MCOperand::CreateReg(X86::ESP));
    Add.addOperand(Inst.getOperand(0));
    Out.EmitInstruction(Add, STI);
  }

  MCInst Jmp;
  Jmp.setOpcode(X86::JMP32r);
  Jmp.addOperand(ScratchReg);
  expandIndirectBranch(Jmp, Out, STI);
}
static InstTransResult translate_JMP32r(NativeModulePtr  natM,
                                         BasicBlock       *&block,
                                         InstPtr          ip,
                                         MCInst           &inst)
{
    const MCOperand &tgtOp = inst.getOperand(0);

    TASSERT(inst.getNumOperands() == 1, "");
    TASSERT(tgtOp.isReg(), "");

    //read the register
    Value *fromReg = R_READ<32>(block, tgtOp.getReg());

    if (ip->has_jump_table()) {
        // this is a jump table that got converted
        // into a table in the data section
        llvm::dbgs() << __FUNCTION__ << ": jump table via register: " << to_string<VA>(ip->get_loc(), std::hex) << "\n";

        BasicBlock *defaultb = nullptr;
        
        doJumpTableViaSwitchReg(block, ip, fromReg, defaultb);
        TASSERT(defaultb != nullptr, "Default block has to exit");
        // fallback to doing do_call_value
        doCallV(defaultb, ip, fromReg);
        return doRet(defaultb);

    } else {
        // translate the JMP32r as a call/ret
        llvm::dbgs() << __FUNCTION__ << ": regular jump via register: " << to_string<VA>(ip->get_loc(), std::hex) << "\n";
        doCallV(block, ip, fromReg);
        return doRet(block);
    }
}
Example #8
0
void MCStreamer::EmitInstruction(const MCInst &Inst,
                                 const MCSubtargetInfo &STI) {
  // Scan for values.
  for (unsigned i = Inst.getNumOperands(); i--;)
    if (Inst.getOperand(i).isExpr())
      visitUsedExpr(*Inst.getOperand(i).getExpr());
}
Example #9
0
static bool getARMStoreDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI,
                                       std::string &Info) {
  assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] &&
         "cannot predicate thumb instructions");

  assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
  for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) {
    assert(MI.getOperand(OI).isReg() && "expected register");
    if (MI.getOperand(OI).getReg() == ARM::SP ||
        MI.getOperand(OI).getReg() == ARM::PC) {
      Info = "use of SP or PC in the list is deprecated";
      return true;
    }
  }
  return false;
}
// If the D<shift> instruction has a shift amount that is greater
// than 31 (checked in calling routine), lower it to a D<shift>32 instruction
void Mips::LowerLargeShift(MCInst& Inst) {

  assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!");
  assert(Inst.getOperand(2).isImm());

  bool isLarge = false;
  int64_t Shift;
  Shift = Inst.getOperand(2).getImm();
  if (Shift > 31) {
    Shift -= 32;
    isLarge = true;
  }

  // saminus32
  (Inst.getOperand(2)).setImm(Shift);

  if (isLarge)
    switch (Inst.getOpcode()) {
    default:
      // Calling function is not synchronized
      llvm_unreachable("Unexpected shift instruction");
    case Mips::DSLL:
      Inst.setOpcode(Mips::DSLL32);
      return;
    case Mips::DSRL:
      Inst.setOpcode(Mips::DSRL32);
      return;
    case Mips::DSRA:
      Inst.setOpcode(Mips::DSRA32);
      return;
    }
}
void MipsELFStreamer::EmitInstruction(const MCInst &Inst,
                                      const MCSubtargetInfo &STI) {
  MCELFStreamer::EmitInstruction(Inst, STI);

  MCContext &Context = getContext();
  const MCRegisterInfo *MCRegInfo = Context.getRegisterInfo();
  MipsTargetELFStreamer *ELFTargetStreamer =
      static_cast<MipsTargetELFStreamer *>(getTargetStreamer());

  for (unsigned OpIndex = 0; OpIndex < Inst.getNumOperands(); ++OpIndex) {
    const MCOperand &Op = Inst.getOperand(OpIndex);

    if (!Op.isReg())
      continue;

    unsigned Reg = Op.getReg();
    RegInfoRecord->SetPhysRegUsed(Reg, MCRegInfo);
  }

  if (ELFTargetStreamer->isMicroMipsEnabled()) {
    for (auto Label : Labels) {
      MCSymbolData &Data = getOrCreateSymbolData(Label);
      // The "other" values are stored in the last 6 bits of the second byte.
      // The traditional defines for STO values assume the full byte and thus
      // the shift to pack it.
      MCELF::setOther(Data, ELF::STO_MIPS_MICROMIPS >> 2);
    }
  }

  Labels.clear();
}
Example #12
0
static void removeRegisterOperands(const MachineInstr *MI, MCInst &OutMI) {
  // Remove all uses of stackified registers to bring the instruction format
  // into its final stack form used thruout MC, and transition opcodes to
  // their _S variant.
  // We do this seperate from the above code that still may need these
  // registers for e.g. call_indirect signatures.
  // See comments in lib/Target/WebAssembly/WebAssemblyInstrFormats.td for
  // details.
  // TODO: the code above creates new registers which are then removed here.
  // That code could be slightly simplified by not doing that, though maybe
  // it is simpler conceptually to keep the code above in "register mode"
  // until this transition point.
  // FIXME: we are not processing inline assembly, which contains register
  // operands, because it is used by later target generic code.
  if (MI->isDebugInstr() || MI->isLabel() || MI->isInlineAsm())
    return;

  // Transform to _S instruction.
  auto RegOpcode = OutMI.getOpcode();
  auto StackOpcode = WebAssembly::getStackOpcode(RegOpcode);
  assert(StackOpcode != -1 && "Failed to stackify instruction");
  OutMI.setOpcode(StackOpcode);

  // Remove register operands.
  for (auto I = OutMI.getNumOperands(); I; --I) {
    auto &MO = OutMI.getOperand(I - 1);
    if (MO.isReg()) {
      OutMI.erase(&MO);
    }
  }
}
Example #13
0
// If the D<shift> instruction has a shift amount that is greater
// than 31 (checked in calling routine), lower it to a D<shift>32 instruction
static void LowerLargeShift(MCInst& Inst) {

    assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!");
    assert(Inst.getOperand(2).isImm());

    int64_t Shift = Inst.getOperand(2).getImm();
    if (Shift <= 31)
        return; // Do nothing
    Shift -= 32;

    // saminus32
    Inst.getOperand(2).setImm(Shift);

    switch (Inst.getOpcode()) {
    default:
        // Calling function is not synchronized
        llvm_unreachable("Unexpected shift instruction");
    case Mips::DSLL:
        Inst.setOpcode(Mips::DSLL32);
        return;
    case Mips::DSRL:
        Inst.setOpcode(Mips::DSRL32);
        return;
    case Mips::DSRA:
        Inst.setOpcode(Mips::DSRA32);
        return;
    case Mips::DROTR:
        Inst.setOpcode(Mips::DROTR32);
        return;
    }
}
void MCObjectStreamer::EmitInstruction(const MCInst &Inst) {
  // Scan for values.
  for (unsigned i = Inst.getNumOperands(); i--; )
    if (Inst.getOperand(i).isExpr())
      AddValueSymbols(Inst.getOperand(i).getExpr());

  getCurrentSectionData()->setHasInstructions(true);

  // Now that a machine instruction has been assembled into this section, make
  // a line entry for any .loc directive that has been seen.
  MCLineEntry::Make(this, getCurrentSection());

  // If this instruction doesn't need relaxation, just emit it as data.
  if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) {
    EmitInstToData(Inst);
    return;
  }

  // Otherwise, if we are relaxing everything, relax the instruction as much as
  // possible and emit it as data.
  if (getAssembler().getRelaxAll()) {
    MCInst Relaxed;
    getAssembler().getBackend().RelaxInstruction(Inst, Relaxed);
    while (getAssembler().getBackend().MayNeedRelaxation(Relaxed))
      getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed);
    EmitInstToData(Relaxed);
    return;
  }

  // Otherwise emit to a separate fragment.
  EmitInstToFragment(Inst);
}
/// \brief Simplify FOO $imm, %{al,ax,eax,rax} to FOO $imm, for instruction with
/// a short fixed-register form.
static void SimplifyShortImmForm(MCInst &Inst, unsigned Opcode) {
  unsigned ImmOp = Inst.getNumOperands() - 1;
  assert(Inst.getOperand(0).isReg() && Inst.getOperand(ImmOp).isImm() &&
         ((Inst.getNumOperands() == 3 && Inst.getOperand(1).isReg() &&
           Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) ||
          Inst.getNumOperands() == 2) && "Unexpected instruction!");

  // Check whether the destination register can be fixed.
  unsigned Reg = Inst.getOperand(0).getReg();
  if (Reg != X86::AL && Reg != X86::AX && Reg != X86::EAX && Reg != X86::RAX)
    return;

  // If so, rewrite the instruction.
  MCOperand Saved = Inst.getOperand(ImmOp);
  Inst = MCInst();
  Inst.setOpcode(Opcode);
  Inst.addOperand(Saved);
}
Example #16
0
// returns the first register this instruction uses
// meant to be run on jmp [reg*imm+imm32]
static int regFromInst(const MCInst &inst) {
    for(int i = 0; i < inst.getNumOperands(); i++) {
        const MCOperand &op = inst.getOperand(i);
        if(op.isReg()) {
            return op.getReg();
        }
    }

    return -1;
}
Example #17
0
// this should check if the given instruction writes
// to register 'reg'. Right now it just checks if the
// instruction uses the register 'reg'.
static int writesToReg(const MCInst &inst, unsigned reg) 
{
    for(int i = 0; i < inst.getNumOperands(); i++) {
        const MCOperand &op = inst.getOperand(i);
        if(op.isReg() && op.getReg() == reg) {
            return true;
        }
    }

    return false;
}
Example #18
0
bool MCInstrDesc::hasDefOfPhysReg(const MCInst &MI, unsigned Reg,
                                  const MCRegisterInfo &RI) const {
  for (int i = 0, e = NumDefs; i != e; ++i)
    if (MI.getOperand(i).isReg() &&
        RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg()))
      return true;
  if (variadicOpsAreDefs())
    for (int i = NumOperands - 1, e = MI.getNumOperands(); i != e; ++i)
      if (MI.getOperand(i).isReg() &&
          RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg()))
        return true;
  return hasImplicitDefOfPhysReg(Reg, &RI);
}
/// \brief Simplify things like MOV32rm to MOV32o32a.
static void SimplifyShortMoveForm(X86AsmPrinter &Printer, MCInst &Inst,
                                  unsigned Opcode) {
  // Don't make these simplifications in 64-bit mode; other assemblers don't
  // perform them because they make the code larger.
  if (Printer.getSubtarget().is64Bit())
    return;

  bool IsStore = Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg();
  unsigned AddrBase = IsStore;
  unsigned RegOp = IsStore ? 0 : 5;
  unsigned AddrOp = AddrBase + 3;
  assert(Inst.getNumOperands() == 6 && Inst.getOperand(RegOp).isReg() &&
         Inst.getOperand(AddrBase + X86::AddrBaseReg).isReg() &&
         Inst.getOperand(AddrBase + X86::AddrScaleAmt).isImm() &&
         Inst.getOperand(AddrBase + X86::AddrIndexReg).isReg() &&
         Inst.getOperand(AddrBase + X86::AddrSegmentReg).isReg() &&
         (Inst.getOperand(AddrOp).isExpr() ||
          Inst.getOperand(AddrOp).isImm()) &&
         "Unexpected instruction!");

  // Check whether the destination register can be fixed.
  unsigned Reg = Inst.getOperand(RegOp).getReg();
  if (Reg != X86::AL && Reg != X86::AX && Reg != X86::EAX && Reg != X86::RAX)
    return;

  // Check whether this is an absolute address.
  // FIXME: We know TLVP symbol refs aren't, but there should be a better way
  // to do this here.
  bool Absolute = true;
  if (Inst.getOperand(AddrOp).isExpr()) {
    const MCExpr *MCE = Inst.getOperand(AddrOp).getExpr();
    if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(MCE))
      if (SRE->getKind() == MCSymbolRefExpr::VK_TLVP)
        Absolute = false;
  }

  if (Absolute &&
      (Inst.getOperand(AddrBase + X86::AddrBaseReg).getReg() != 0 ||
       Inst.getOperand(AddrBase + X86::AddrScaleAmt).getImm() != 1 ||
       Inst.getOperand(AddrBase + X86::AddrIndexReg).getReg() != 0))
    return;

  // If so, rewrite the instruction.
  MCOperand Saved = Inst.getOperand(AddrOp);
  MCOperand Seg = Inst.getOperand(AddrBase + X86::AddrSegmentReg);
  Inst = MCInst();
  Inst.setOpcode(Opcode);
  Inst.addOperand(Saved);
  Inst.addOperand(Seg);
}
Example #20
0
DecodeStatus AMDGPUDisassembler::tryDecodeInst(const uint8_t* Table,
                                               MCInst &MI,
                                               uint64_t Inst,
                                               uint64_t Address) const {
  assert(MI.getOpcode() == 0);
  assert(MI.getNumOperands() == 0);
  MCInst TmpInst;
  const auto SavedBytes = Bytes;
  if (decodeInstruction(Table, TmpInst, Inst, Address, this, STI)) {
    MI = TmpInst;
    return MCDisassembler::Success;
  }
  Bytes = SavedBytes;
  return MCDisassembler::Fail;
}
Example #21
0
int LLVMDecodeOpInfoCallback(void *DisInfo, uint64_t PC,
                                  uint64_t Offset, uint64_t Size,
                                  int TagType, void *TagBuf) {
	struct dis_info_s *dis_info = (struct dis_info_s *) DisInfo;
	MCInst *Inst = dis_info->Inst;
	int num_operands = Inst->getNumOperands();
	if (num_operands >= 16) {
		outs() << "num_operands >= 16\n";
		exit(1);
	}
	dis_info->offset[num_operands] = Offset;
	dis_info->size[num_operands] = Size;
	outs() << format("NumOperands = 0x%x, ", num_operands) << format("Offset = 0x%x, ", Offset) << format("Size = 0x%x", Size) << "\n";
	return 0;
}
Example #22
0
void WinCOFFStreamer::EmitInstruction(const MCInst &Instruction) {
  for (unsigned i = 0, e = Instruction.getNumOperands(); i != e; ++i)
    if (Instruction.getOperand(i).isExpr())
      AddValueSymbols(Instruction.getOperand(i).getExpr());

  getCurrentSectionData()->setHasInstructions(true);

  MCInstFragment *Fragment =
    new MCInstFragment(Instruction, getCurrentSectionData());

  raw_svector_ostream VecOS(Fragment->getCode());

  getAssembler().getEmitter().EncodeInstruction(Instruction, VecOS,
                                                Fragment->getFixups());
}
/// \brief Simplify things like MOV32rm to MOV32o32a.
static void SimplifyShortMoveForm(MCInst &Inst, unsigned Opcode) {
  bool IsStore = Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg();
  unsigned AddrBase = IsStore;
  unsigned RegOp = IsStore ? 0 : 5;
  unsigned AddrOp = AddrBase + 3;
  assert(Inst.getNumOperands() == 6 && Inst.getOperand(RegOp).isReg() &&
         Inst.getOperand(AddrBase + 0).isReg() && // base
         Inst.getOperand(AddrBase + 1).isImm() && // scale
         Inst.getOperand(AddrBase + 2).isReg() && // index register
         (Inst.getOperand(AddrOp).isExpr() ||     // address
          Inst.getOperand(AddrOp).isImm())&&
         Inst.getOperand(AddrBase + 4).isReg() && // segment
         "Unexpected instruction!");

  // Check whether the destination register can be fixed.
  unsigned Reg = Inst.getOperand(RegOp).getReg();
  if (Reg != X86::AL && Reg != X86::AX && Reg != X86::EAX && Reg != X86::RAX)
    return;

  // Check whether this is an absolute address.
  // FIXME: We know TLVP symbol refs aren't, but there should be a better way 
  // to do this here.
  bool Absolute = true;
  if (Inst.getOperand(AddrOp).isExpr()) {
    const MCExpr *MCE = Inst.getOperand(AddrOp).getExpr();
    if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(MCE))
      if (SRE->getKind() == MCSymbolRefExpr::VK_TLVP)
        Absolute = false;
  }
  
  if (Absolute &&
      (Inst.getOperand(AddrBase + 0).getReg() != 0 ||
       Inst.getOperand(AddrBase + 2).getReg() != 0 ||
       Inst.getOperand(AddrBase + 4).getReg() != 0 ||
       Inst.getOperand(AddrBase + 1).getImm() != 1))
    return;

  // If so, rewrite the instruction.
  MCOperand Saved = Inst.getOperand(AddrOp);
  Inst = MCInst();
  Inst.setOpcode(Opcode);
  Inst.addOperand(Saved);
}
Example #24
0
void MipsELFStreamer::EmitInstruction(const MCInst &Inst,
                                      const MCSubtargetInfo &STI, bool) {
  MCELFStreamer::EmitInstruction(Inst, STI);

  MCContext &Context = getContext();
  const MCRegisterInfo *MCRegInfo = Context.getRegisterInfo();

  for (unsigned OpIndex = 0; OpIndex < Inst.getNumOperands(); ++OpIndex) {
    const MCOperand &Op = Inst.getOperand(OpIndex);

    if (!Op.isReg())
      continue;

    unsigned Reg = Op.getReg();
    RegInfoRecord->SetPhysRegUsed(Reg, MCRegInfo);
  }

  createPendingLabelRelocs();
}
Example #25
0
/// \brief Gets latency information for \p Inst form the itinerary
/// scheduling model, based on \p DC information.
/// \return The maximum expected latency over all the operands or -1
/// if no information are available.
static int getItineraryLatency(LLVMDisasmContext *DC, const MCInst &Inst) {
  const int NoInformationAvailable = -1;

  // Check if we have a CPU to get the itinerary information.
  if (DC->getCPU().empty())
    return NoInformationAvailable;

  // Get itinerary information.
  const MCSubtargetInfo *STI = DC->getSubtargetInfo();
  InstrItineraryData IID = STI->getInstrItineraryForCPU(DC->getCPU());
  // Get the scheduling class of the requested instruction.
  const MCInstrDesc& Desc = DC->getInstrInfo()->get(Inst.getOpcode());
  unsigned SCClass = Desc.getSchedClass();

  int Latency = 0;
  for (unsigned OpIdx = 0, OpIdxEnd = Inst.getNumOperands(); OpIdx != OpIdxEnd;
       ++OpIdx)
    Latency = std::max(Latency, IID.getOperandCycle(SCClass, OpIdx));

  return Latency;
}
Example #26
0
    bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
                        uint64_t &Target) const override {
        if (Inst.getNumOperands() == 0)
            return false;

        if (Info->get(Inst.getOpcode()).OpInfo[0].OperandType ==
                MCOI::OPERAND_PCREL) {
            int64_t Imm = Inst.getOperand(0).getImm();
            Target = Addr + Size + Imm;
            return true;
        } else {
            int64_t Imm = Inst.getOperand(0).getImm();

            // Skip case where immediate is 0 as that occurs in file that isn't linked
            // and the branch target inferred would be wrong.
            if (Imm == 0)
                return false;

            Target = Imm;
            return true;
        }
    }
Example #27
0
void MCObjectStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) {
  // Scan for values.
  for (unsigned i = Inst.getNumOperands(); i--; )
    if (Inst.getOperand(i).isExpr())
      AddValueSymbols(Inst.getOperand(i).getExpr());

  MCSectionData *SD = getCurrentSectionData();
  SD->setHasInstructions(true);

  // Now that a machine instruction has been assembled into this section, make
  // a line entry for any .loc directive that has been seen.
  MCLineEntry::Make(this, getCurrentSection().first);

  // If this instruction doesn't need relaxation, just emit it as data.
  MCAssembler &Assembler = getAssembler();
  if (!Assembler.getBackend().mayNeedRelaxation(Inst)) {
    EmitInstToData(Inst, STI);
    return;
  }

  // Otherwise, relax and emit it as data if either:
  // - The RelaxAll flag was passed
  // - Bundling is enabled and this instruction is inside a bundle-locked
  //   group. We want to emit all such instructions into the same data
  //   fragment.
  if (Assembler.getRelaxAll() ||
      (Assembler.isBundlingEnabled() && SD->isBundleLocked())) {
    MCInst Relaxed;
    getAssembler().getBackend().relaxInstruction(Inst, Relaxed);
    while (getAssembler().getBackend().mayNeedRelaxation(Relaxed))
      getAssembler().getBackend().relaxInstruction(Relaxed, Relaxed);
    EmitInstToData(Relaxed, STI);
    return;
  }

  // Otherwise emit to a separate fragment.
  EmitInstToFragment(Inst, STI);
}
Example #28
0
// Pick a DINS instruction variant based on the pos and size operands
static void LowerDins(MCInst& InstIn) {
  assert(InstIn.getNumOperands() == 5 &&
         "Invalid no. of machine operands for DINS!");

  assert(InstIn.getOperand(2).isImm());
  int64_t pos = InstIn.getOperand(2).getImm();
  assert(InstIn.getOperand(3).isImm());
  int64_t size = InstIn.getOperand(3).getImm();

  if (size <= 32) {
    if (pos < 32)  // DINS, do nothing
      return;
    // DINSU
    InstIn.getOperand(2).setImm(pos - 32);
    InstIn.setOpcode(Mips::DINSU);
    return;
  }
  // DINSM
  assert(pos < 32 && "DINS cannot have both size and pos > 32");
  InstIn.getOperand(3).setImm(size - 32);
  InstIn.setOpcode(Mips::DINSM);
  return;
}
Example #29
0
/*
 * Disassemble a function, using the LLVM MC disassembler.
 *
 * See also:
 * - http://blog.llvm.org/2010/01/x86-disassembler.html
 * - http://blog.llvm.org/2010/04/intro-to-llvm-mc-project.html
 */
extern "C" void
lp_disassemble(const void* func)
{
#if HAVE_LLVM >= 0x0207
   using namespace llvm;

   const uint8_t *bytes = (const uint8_t *)func;

   /*
    * Limit disassembly to this extent
    */
   const uint64_t extent = 0x10000;

   uint64_t max_pc = 0;

   /*
    * Initialize all used objects.
    */

#if HAVE_LLVM >= 0x0301
   std::string Triple = sys::getDefaultTargetTriple();
#else
   std::string Triple = sys::getHostTriple();
#endif

   std::string Error;
   const Target *T = TargetRegistry::lookupTarget(Triple, Error);

#if HAVE_LLVM >= 0x0208
   InitializeNativeTargetAsmPrinter();
#elif defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
   LLVMInitializeX86AsmPrinter();
#elif defined(PIPE_ARCH_ARM)
   LLVMInitializeARMAsmPrinter();
#elif defined(PIPE_ARCH_PPC)
   LLVMInitializePowerPCAsmPrinter();
#endif

#if HAVE_LLVM >= 0x0301
   InitializeNativeTargetDisassembler();
#elif defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
   LLVMInitializeX86Disassembler();
#elif defined(PIPE_ARCH_ARM)
   LLVMInitializeARMDisassembler();
#endif

#if HAVE_LLVM >= 0x0300
   OwningPtr<const MCAsmInfo> AsmInfo(T->createMCAsmInfo(Triple));
#else
   OwningPtr<const MCAsmInfo> AsmInfo(T->createAsmInfo(Triple));
#endif

   if (!AsmInfo) {
      debug_printf("error: no assembly info for target %s\n", Triple.c_str());
      return;
   }

#if HAVE_LLVM >= 0x0300
   const MCSubtargetInfo *STI = T->createMCSubtargetInfo(Triple, sys::getHostCPUName(), "");
   OwningPtr<const MCDisassembler> DisAsm(T->createMCDisassembler(*STI));
#else 
   OwningPtr<const MCDisassembler> DisAsm(T->createMCDisassembler());
#endif 
   if (!DisAsm) {
      debug_printf("error: no disassembler for target %s\n", Triple.c_str());
      return;
   }

   raw_debug_ostream Out;

#if HAVE_LLVM >= 0x0300
   unsigned int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
#else
   int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
#endif

#if HAVE_LLVM >= 0x0301
   OwningPtr<const MCRegisterInfo> MRI(T->createMCRegInfo(Triple));
   if (!MRI) {
      debug_printf("error: no register info for target %s\n", Triple.c_str());
      return;
   }

   OwningPtr<const MCInstrInfo> MII(T->createMCInstrInfo());
   if (!MII) {
      debug_printf("error: no instruction info for target %s\n", Triple.c_str());
      return;
   }
#endif

#if HAVE_LLVM >= 0x0301
   OwningPtr<MCInstPrinter> Printer(
         T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *MII, *MRI, *STI));
#elif HAVE_LLVM == 0x0300
   OwningPtr<MCInstPrinter> Printer(
         T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *STI));
#elif HAVE_LLVM >= 0x0208
   OwningPtr<MCInstPrinter> Printer(
         T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo));
#else
   OwningPtr<MCInstPrinter> Printer(
         T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, Out));
#endif
   if (!Printer) {
      debug_printf("error: no instruction printer for target %s\n", Triple.c_str());
      return;
   }

#if HAVE_LLVM >= 0x0301
   TargetOptions options;
#if defined(DEBUG)
   options.JITEmitDebugInfo = true;
#endif
#if defined(PIPE_ARCH_X86)
   options.StackAlignmentOverride = 4;
#endif
#if defined(DEBUG) || defined(PROFILE)
   options.NoFramePointerElim = true;
#endif
   TargetMachine *TM = T->createTargetMachine(Triple, sys::getHostCPUName(), "", options);
#elif HAVE_LLVM == 0x0300
   TargetMachine *TM = T->createTargetMachine(Triple, sys::getHostCPUName(), "");
#else
   TargetMachine *TM = T->createTargetMachine(Triple, "");
#endif

   const TargetInstrInfo *TII = TM->getInstrInfo();

   /*
    * Wrap the data in a MemoryObject
    */
   BufferMemoryObject memoryObject((const uint8_t *)bytes, extent);

   uint64_t pc;
   pc = 0;
   while (true) {
      MCInst Inst;
      uint64_t Size;

      /*
       * Print address.  We use addresses relative to the start of the function,
       * so that between runs.
       */

      debug_printf("%6lu:\t", (unsigned long)pc);

      if (!DisAsm->getInstruction(Inst, Size, memoryObject,
                                 pc,
#if HAVE_LLVM >= 0x0300
				  nulls(), nulls())) {
#else
				  nulls())) {
#endif
         debug_printf("invalid\n");
         pc += 1;
      }

      /*
       * Output the bytes in hexidecimal format.
       */

      if (0) {
         unsigned i;
         for (i = 0; i < Size; ++i) {
            debug_printf("%02x ", ((const uint8_t*)bytes)[pc + i]);
         }
         for (; i < 16; ++i) {
            debug_printf("   ");
         }
      }

      /*
       * Print the instruction.
       */

#if HAVE_LLVM >= 0x0300
      Printer->printInst(&Inst, Out, "");
#elif HAVE_LLVM >= 0x208
      Printer->printInst(&Inst, Out);
#else
      Printer->printInst(&Inst);
#endif
      Out.flush();

      /*
       * Advance.
       */

      pc += Size;

#if HAVE_LLVM >= 0x0300
      const MCInstrDesc &TID = TII->get(Inst.getOpcode());
#else
      const TargetInstrDesc &TID = TII->get(Inst.getOpcode());
#endif

      /*
       * Keep track of forward jumps to a nearby address.
       */

      if (TID.isBranch()) {
         for (unsigned i = 0; i < Inst.getNumOperands(); ++i) {
            const MCOperand &operand = Inst.getOperand(i);
            if (operand.isImm()) {
               uint64_t jump;

               /*
                * FIXME: Handle both relative and absolute addresses correctly.
                * EDInstInfo actually has this info, but operandTypes and
                * operandFlags enums are not exposed in the public interface.
                */

               if (1) {
                  /*
                   * PC relative addr.
                   */

                  jump = pc + operand.getImm();
               } else {
                  /*
                   * Absolute addr.
                   */

                  jump = (uint64_t)operand.getImm();
               }

               /*
                * Output the address relative to the function start, given
                * that MC will print the addresses relative the current pc.
                */
               debug_printf("\t\t; %lu", (unsigned long)jump);

               /*
                * Ignore far jumps given it could be actually a tail return to
                * a random address.
                */

               if (jump > max_pc &&
                   jump < extent) {
                  max_pc = jump;
               }
            }
         }
      }

      debug_printf("\n");

      /*
       * Stop disassembling on return statements, if there is no record of a
       * jump to a successive address.
       */

      if (TID.isReturn()) {
         if (pc > max_pc) {
            break;
         }
      }
   }

   /*
    * Print GDB command, useful to verify output.
    */

   if (0) {
      debug_printf("disassemble %p %p\n", bytes, bytes + pc);
   }

   debug_printf("\n");
#else /* HAVE_LLVM < 0x0207 */
   (void)func;
#endif /* HAVE_LLVM < 0x0207 */
}
void HexagonMCELFStreamer::EmitSymbol(const MCInst &Inst) {
  // Scan for values.
  for (unsigned i = Inst.getNumOperands(); i--;)
    if (Inst.getOperand(i).isExpr())
      visitUsedExpr(*Inst.getOperand(i).getExpr());
}