Esempio n. 1
0
void EpiphanyAsmPrinter::EmitInstruction(const MachineInstr *MI) {
  // Do any auto-generated pseudo lowerings.
  if (emitPseudoExpansionLowering(*OutStreamer, MI))
    return;

  switch (MI->getOpcode()) {
  case Epiphany::DBG_VALUE: {
    if (isVerbose() && OutStreamer->hasRawTextSupport()) {
      SmallString<128> TmpStr;
      raw_svector_ostream OS(TmpStr);
      PrintDebugValueComment(MI, OS);
      OutStreamer->EmitRawText(StringRef(OS.str()));
    }
    return;
    }
  case Epiphany::MOVT32ri: {
    EmitToStreamer(*OutStreamer, MCInstBuilder(Epiphany::MOVT32ri)
      .addReg(MI->getOperand(0).getReg())
      .addReg(MI->getOperand(0).getReg())
      .addImm(MI->getOperand(1).getImm()));
    return;
    }
  }

  // Generic way
  MachineBasicBlock::const_instr_iterator I = MI;
  MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();
  do {
    MCInst TmpInst;
    MCInstLowering.Lower(I, TmpInst);
    EmitToStreamer(*OutStreamer, TmpInst);
  } while ((++I != E) && I->isInsideBundle());
}
Esempio n. 2
0
void AMDGPUAsmPrinter::EmitInstruction(const MachineInstr *MI) {
  AMDGPUMCInstLower MCInstLowering;

  // Ignore placeholder instructions:
  if (MI->getOpcode() == AMDGPU::MASK_WRITE) {
    return;
  }

  if (MI->isBundle()) {
    const MachineBasicBlock *MBB = MI->getParent();
    MachineBasicBlock::const_instr_iterator I = MI;
    ++I;
    while (I != MBB->end() && I->isInsideBundle()) {
      MCInst MCBundleInst;
      const MachineInstr *BundledInst = I;
      MCInstLowering.lower(BundledInst, MCBundleInst);
      OutStreamer.EmitInstruction(MCBundleInst);
      ++I;
    }
  } else {
    MCInst TmpInst;
    MCInstLowering.lower(MI, TmpInst);
    OutStreamer.EmitInstruction(TmpInst);
  }
}
Esempio n. 3
0
void AMDGPUAsmPrinter::EmitInstruction(const MachineInstr *MI) {
  const AMDGPUSubtarget &STI = MF->getSubtarget<AMDGPUSubtarget>();
  AMDGPUMCInstLower MCInstLowering(OutContext, STI);

#ifdef _DEBUG
  StringRef Err;
  if (!STI.getInstrInfo()->verifyInstruction(MI, Err)) {
    errs() << "Warning: Illegal instruction detected: " << Err << "\n";
    MI->dump();
  }
#endif
  if (MI->isBundle()) {
    const MachineBasicBlock *MBB = MI->getParent();
    MachineBasicBlock::const_instr_iterator I = MI;
    ++I;
    while (I != MBB->end() && I->isInsideBundle()) {
      EmitInstruction(I);
      ++I;
    }
  } else {
    MCInst TmpInst;
    MCInstLowering.lower(MI, TmpInst);
    EmitToStreamer(OutStreamer, TmpInst);

    if (STI.dumpCode()) {
      // Disassemble instruction/operands to text.
      DisasmLines.resize(DisasmLines.size() + 1);
      std::string &DisasmLine = DisasmLines.back();
      raw_string_ostream DisasmStream(DisasmLine);

      AMDGPUInstPrinter InstPrinter(*TM.getMCAsmInfo(),
                                    *MF->getSubtarget().getInstrInfo(),
                                    *MF->getSubtarget().getRegisterInfo());
      InstPrinter.printInst(&TmpInst, DisasmStream, StringRef());

      // Disassemble instruction/operands to hex representation.
      SmallVector<MCFixup, 4> Fixups;
      SmallVector<char, 16> CodeBytes;
      raw_svector_ostream CodeStream(CodeBytes);

      MCObjectStreamer &ObjStreamer = (MCObjectStreamer &)OutStreamer;
      MCCodeEmitter &InstEmitter = ObjStreamer.getAssembler().getEmitter();
      InstEmitter.EncodeInstruction(TmpInst, CodeStream, Fixups,
                                    MF->getSubtarget<MCSubtargetInfo>());
      CodeStream.flush();

      HexLines.resize(HexLines.size() + 1);
      std::string &HexLine = HexLines.back();
      raw_string_ostream HexStream(HexLine);

      for (size_t i = 0; i < CodeBytes.size(); i += 4) {
        unsigned int CodeDWord = *(unsigned int *)&CodeBytes[i];
        HexStream << format("%s%08X", (i > 0 ? " " : ""), CodeDWord);
      }

      DisasmStream.flush();
      DisasmLineMaxLen = std::max(DisasmLineMaxLen, DisasmLine.size());
    }
  }
}
const Function *PatmosInstrInfo::getCallee(const MachineInstr *MI) const
{
  const Function *F = NULL;

  if (MI->isBundle()) {
    MachineBasicBlock::const_instr_iterator it = MI;

    while ((++it)->isBundledWithPred()) {
      if (!it->isCall()) continue;
      if (F) return NULL;
      F = getCallee(it);
      if (!F) return NULL;
    }

    return F;
  }

  // get target
  const MachineOperand &MO(MI->getOperand(2));

  // try to find the target of the call
  if (MO.isGlobal()) {
    // is the global value a function?
    F = dyn_cast<Function>(MO.getGlobal());
  }
  else if (MO.isSymbol()) {
    // find the function in the current module
    const Module &M = *MI->getParent()->getParent()->getFunction()->getParent();

    F = dyn_cast_or_null<Function>(M.getNamedValue(MO.getSymbolName()));
  }

  return F;
}
unsigned int PatmosInstrInfo::getInstrSize(const MachineInstr *MI) const {
  if (MI->isInlineAsm()) {
    // TODO is there a way to get the current context?
    MCContext Ctx(PTM.getMCAsmInfo(),
                  PTM.getRegisterInfo(), PTM.getInstrInfo(), 0);

    // PIA is deleted by AsmPrinter
    PatmosInstrAnalyzer *PIA = createPatmosInstrAnalyzer(Ctx);

    PatmosAsmPrinter PAP(PTM, *PIA);
    PAP.EmitInlineAsm(MI);

    return PIA->getSize();
  }
  else if (MI->isBundle()) {
    const MachineBasicBlock *MBB = MI->getParent();
    MachineBasicBlock::const_instr_iterator I = MI, E = MBB->instr_end();
    unsigned Size = 0;
    while ((++I != E) && I->isInsideBundle()) {
      Size += getInstrSize(I);
    }
    return Size;
  }
  else if (MI->isPseudo()) {
    return 0;
  }
  else {
    // trust the desc..
    return MI->getDesc().getSize();
  }
}
Esempio n. 6
0
/// printMachineInstruction -- Print out a single Hexagon MI in Darwin syntax to
/// the current output stream.
///
void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) {
  MCInst MCB = HexagonMCInstrInfo::createBundle();
  const MCInstrInfo &MCII = *Subtarget->getInstrInfo();

  if (MI->isBundle()) {
    const MachineBasicBlock* MBB = MI->getParent();
    MachineBasicBlock::const_instr_iterator MII = MI->getIterator();
    unsigned IgnoreCount = 0;

    for (++MII; MII != MBB->instr_end() && MII->isInsideBundle(); ++MII)
      if (MII->getOpcode() == TargetOpcode::DBG_VALUE ||
          MII->getOpcode() == TargetOpcode::IMPLICIT_DEF)
        ++IgnoreCount;
      else
        HexagonLowerToMC(MCII, &*MII, MCB, *this);
  }
  else
    HexagonLowerToMC(MCII, MI, MCB, *this);

  bool Ok = HexagonMCInstrInfo::canonicalizePacket(
      MCII, *Subtarget, OutStreamer->getContext(), MCB, nullptr);
  assert(Ok);
  (void)Ok;
  if(HexagonMCInstrInfo::bundleSize(MCB) == 0)
    return;
  OutStreamer->EmitInstruction(MCB, getSubtargetInfo());
}
bool PatmosInstrInfo::isPseudo(const MachineInstr *MI) const {

  if (MI->isBundle()) {
    MachineBasicBlock::const_instr_iterator II = MI; ++II;
    const MachineBasicBlock *MBB = MI->getParent();

    while (II != MBB->instr_end() && II->isBundledWithPred()) {
      if (!isPseudo(II)) return false;
      II++;
    }
    return true;
  }

  if (MI->isDebugValue())
    return true;

  // We must emit inline assembly
  if (MI->isInlineAsm())
    return false;

  // We check if MI has any functional units mapped to it.
  // If it doesn't, we ignore the instruction.
  const MCInstrDesc& TID = MI->getDesc();
  unsigned SchedClass = TID.getSchedClass();
  const InstrStage* IS = PST.getInstrItineraryData().beginStage(SchedClass);
  unsigned FuncUnits = IS->getUnits();
  return !FuncUnits;
}
PatmosII::MemType PatmosInstrInfo::getMemType(const MachineInstr *MI) const {
  assert(MI->mayLoad() || MI->mayStore());

  if (MI->isBundle()) {
    // find mem instruction in bundle (does not need to be the first
    // instruction, they might be sorted later!)
    MachineBasicBlock::const_instr_iterator II = MI; ++II;
    while (II->isInsideBundle() && !II->mayLoad() && !II->mayStore()) {
      ++II;
    }
    return getMemType(II);
  }

  // FIXME: Maybe there is a better way to get this info directly from
  //        the instruction definitions in the .td files
  using namespace Patmos;
  unsigned opc = MI->getOpcode();
  switch (opc) {
    case LWS: case LHS: case LBS: case LHUS: case LBUS:
    case SWS: case SHS: case SBS:
      return PatmosII::MEM_S;
    case LWL: case LHL: case LBL: case LHUL: case LBUL:
    case SWL: case SHL: case SBL:
      return PatmosII::MEM_L;
    case  LWC: case  LHC: case  LBC: case  LHUC: case  LBUC:
    case  SWC: case  SHC: case  SBC:
      return PatmosII::MEM_C;
    case  LWM: case  LHM: case  LBM: case  LHUM: case  LBUM:
    case  SWM: case  SHM: case  SBM:
      return PatmosII::MEM_M;
    default: llvm_unreachable("Unexpected memory access instruction!");
  }

}
bool PatmosInstrInfo::getCallees(const MachineInstr *MI,
                                 SmallSet<const Function*,2> &Callees) const
{
  if (MI->isBundle()) {
    MachineBasicBlock::const_instr_iterator it = MI;
    bool safe = true;

    while ((++it)->isBundledWithPred()) {
      if (!it->isCall() && !it->isInlineAsm()) continue;
      safe = getCallees(it, Callees) && safe;
    }
    return safe;
  }

  if (MI->isCall()) {
    const Function *F = getCallee(MI);
    if (F) {
      Callees.insert(F);
      return true;
    } else {
      // Could be an indirect call..
      return false;
    }
  }
  else if (MI->isInlineAsm()) {
    // We can skip the first operand as this should be the asm string.
    for (unsigned int i = 1; i < MI->getNumOperands(); i++) {
      const MachineOperand &MO(MI->getOperand(i));
      const Function *F = NULL;

      // try to find the target of the call
      if (MO.isGlobal()) {
        // is the global value a function?
        F = dyn_cast_or_null<Function>(MO.getGlobal());
      }
      else if (MO.isSymbol()) {
        // find the function in the current module
        const Module &M =
                  *MI->getParent()->getParent()->getFunction()->getParent();

        F = dyn_cast_or_null<Function>(M.getNamedValue(MO.getSymbolName()));
      }
      if (F) {
        // We are assuming here that if inline-asm uses a function reference
        // as operand, then it is probably used for a call.
        Callees.insert(F);
      }
    }

    // TODO for now we assume that inline asm does not contain CALLR and
    //      that all callees are passed as asm operands. We should do a check
    //      similar to hasCall() here.
    return true;
  }
  else {
    // No other instruction should do a call.
    return true;
  }
}
Esempio n. 10
0
void OR1KAsmPrinter::EmitInstruction(const MachineInstr *MI) {

  MachineBasicBlock::const_instr_iterator I = MI;
  MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();

  do {
    customEmitInstruction(I++);
  } while ((I != E) && I->isInsideBundle());
}
Esempio n. 11
0
unsigned AArch64InstrInfo::getInstBundleLength(const MachineInstr &MI) const {
  unsigned Size = 0;
  MachineBasicBlock::const_instr_iterator I = MI;
  MachineBasicBlock::const_instr_iterator E = MI.getParent()->instr_end();
  while (++I != E && I->isInsideBundle()) {
    assert(!I->isBundle() && "No nested bundle!");
    Size += getInstSizeInBytes(*I);
  }
  return Size;
}
Esempio n. 12
0
void NyuziAsmPrinter::EmitInstruction(const MachineInstr *MI) {
  MachineBasicBlock::const_instr_iterator I = MI->getIterator();
  MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();

  do {
    MCInst TmpInst;
    MCInstLowering.Lower(MI, TmpInst);
    EmitToStreamer(*OutStreamer, TmpInst);
    if (MI->getOpcode() == Nyuzi::JUMP_TABLE) {
      EmitInlineJumpTable(MI);
    }
  } while ((I != E) && I->isInsideBundle());
}
Esempio n. 13
0
void LanaiAsmPrinter::EmitInstruction(const MachineInstr *MI) {
  MachineBasicBlock::const_instr_iterator I = MI->getIterator();
  MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();

  do {
    if (I->isCall()) {
      emitCallInstruction(&*I);
      continue;
    }

    customEmitInstruction(&*I);
  } while ((++I != E) && I->isInsideBundle());
}
void AMDGPUAsmPrinter::EmitInstruction(const MachineInstr *MI) {
    AMDGPUMCInstLower MCInstLowering(OutContext);

    if (MI->isBundle()) {
        const MachineBasicBlock *MBB = MI->getParent();
        MachineBasicBlock::const_instr_iterator I = MI;
        ++I;
        while (I != MBB->end() && I->isInsideBundle()) {
            EmitInstruction(I);
            ++I;
        }
    } else {
        MCInst TmpInst;
        MCInstLowering.lower(MI, TmpInst);
        OutStreamer.EmitInstruction(TmpInst);

        if (DisasmEnabled) {
            // Disassemble instruction/operands to text.
            DisasmLines.resize(DisasmLines.size() + 1);
            std::string &DisasmLine = DisasmLines.back();
            raw_string_ostream DisasmStream(DisasmLine);

            AMDGPUInstPrinter InstPrinter(*TM.getMCAsmInfo(), *TM.getInstrInfo(),
                                          *TM.getRegisterInfo());
            InstPrinter.printInst(&TmpInst, DisasmStream, StringRef());

            // Disassemble instruction/operands to hex representation.
            SmallVector<MCFixup, 4> Fixups;
            SmallVector<char, 16> CodeBytes;
            raw_svector_ostream CodeStream(CodeBytes);

            MCObjectStreamer &ObjStreamer = (MCObjectStreamer &)OutStreamer;
            MCCodeEmitter &InstEmitter = ObjStreamer.getAssembler().getEmitter();
            InstEmitter.EncodeInstruction(TmpInst, CodeStream, Fixups);
            CodeStream.flush();

            HexLines.resize(HexLines.size() + 1);
            std::string &HexLine = HexLines.back();
            raw_string_ostream HexStream(HexLine);

            for (size_t i = 0; i < CodeBytes.size(); i += 4) {
                unsigned int CodeDWord = *(unsigned int *)&CodeBytes[i];
                HexStream << format("%s%08X", (i > 0 ? " " : ""), CodeDWord);
            }

            DisasmStream.flush();
            DisasmLineMaxLen = std::max(DisasmLineMaxLen, DisasmLine.size());
        }
    }
}
Esempio n. 15
0
void PatmosAsmPrinter::EmitInstruction(const MachineInstr *MI) {

  SmallVector<const MachineInstr*, 2> BundleMIs;
  unsigned Size = 1;

  // Unpack BUNDLE instructions
  if (MI->isBundle()) {

    const MachineBasicBlock *MBB = MI->getParent();
    MachineBasicBlock::const_instr_iterator MII = MI;
    ++MII;
    while (MII != MBB->end() && MII->isInsideBundle()) {
      const MachineInstr *MInst = MII;
      if (MInst->isPseudo()) {
        // DBG_VALUE and IMPLICIT_DEFs outside of bundles are handled in
        // AsmPrinter::EmitFunctionBody()
        MInst->dump();
        report_fatal_error("Pseudo instructions must not be bundled!");
      }

      BundleMIs.push_back(MInst);
      ++MII;
    }
    Size = BundleMIs.size();
    assert(Size == MI->getBundleSize() && "Corrupt Bundle!");
  }
  else {
    if (MI->getOpcode() == Patmos::PSEUDO_LOOPBOUND) {
      int LoopBoundMin = MI->getOperand(0).getImm();
      int LoopBoundMax = MI->getOperand(1).getImm();
      OutStreamer.GetCommentOS() << "Loop bound: ["
        << LoopBoundMin << ", " << LoopBoundMax << "]\n";
      return;
    }
    BundleMIs.push_back(MI);
  }

  // Emit all instructions in the bundle.
  for (unsigned Index = 0; Index < Size; Index++) {
    MCInst MCI;
    MCInstLowering.Lower(BundleMIs[Index], MCI);

    // Set bundle marker
    bool isBundled = (Index < Size - 1);
    MCI.addOperand(MCOperand::CreateImm(isBundled));

    OutStreamer.EmitInstruction(MCI);
  }
}
Esempio n. 16
0
const MachineInstr *PatmosInstrInfo::hasOpcode(const MachineInstr *MI,
                                               int Opcode) const {
  if (MI->isBundle()) {
    MachineBasicBlock::const_instr_iterator II = MI; ++II;

    while (II->isInsideBundle()) {
      if (II->getOpcode() == Opcode) return II;
      II++;
    }

    return 0;
  } else {
    return MI->getOpcode() == Opcode ? MI : 0;
  }
}
Esempio n. 17
0
bool PatmosInstrInfo::mayStall(const MachineInstr *MI) const {
  if (MI->isInlineAsm()) {
    // Being conservative here..
    return MI->mayLoad() || MI->mayStore();
  } else if (MI->isBundle()) {
    const MachineBasicBlock *MBB = MI->getParent();
    MachineBasicBlock::const_instr_iterator I = MI, E = MBB->instr_end();
    while ((++I != E) && I->isInsideBundle()) {
      if (mayStall(I)) return true;
    }
    return false;
  } else if (MI->isPseudo()) {
    return false;
  }
  // We could check for load instructions if they are always-hit.
  return isPatmosMayStall(MI->getDesc().TSFlags);
}
Esempio n. 18
0
/// printMachineInstruction -- Print out a single Hexagon MI in Darwin syntax to
/// the current output stream.
///
void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) {
  if (MI->isBundle()) {
    std::vector<MachineInstr const *> BundleMIs;

    const MachineBasicBlock *MBB = MI->getParent();
    MachineBasicBlock::const_instr_iterator MII = MI;
    ++MII;
    unsigned int IgnoreCount = 0;
    while (MII != MBB->end() && MII->isInsideBundle()) {
      const MachineInstr *MInst = MII;
      if (MInst->getOpcode() == TargetOpcode::DBG_VALUE ||
        MInst->getOpcode() == TargetOpcode::IMPLICIT_DEF) {
        IgnoreCount++;
        ++MII;
        continue;
      }
      // BundleMIs.push_back(&*MII);
      BundleMIs.push_back(MInst);
      ++MII;
    }
    unsigned Size = BundleMIs.size();
    assert((Size + IgnoreCount) == MI->getBundleSize() && "Corrupt Bundle!");
    for (unsigned Index = 0; Index < Size; Index++) {
      MCInst MCI;

      HexagonLowerToMC(BundleMIs[Index], MCI, *this);
      HexagonMCInstrInfo::AppendImplicitOperands(MCI);
      HexagonMCInstrInfo::setPacketBegin(MCI, Index == 0);
      HexagonMCInstrInfo::setPacketEnd(MCI, Index == (Size - 1));
      EmitToStreamer(*OutStreamer, MCI);
    }
  }
  else {
    MCInst MCI;
    HexagonLowerToMC(MI, MCI, *this);
    HexagonMCInstrInfo::AppendImplicitOperands(MCI);
    if (MI->getOpcode() == Hexagon::ENDLOOP0) {
      HexagonMCInstrInfo::setPacketBegin(MCI, true);
      HexagonMCInstrInfo::setPacketEnd(MCI, true);
    }
    EmitToStreamer(*OutStreamer, MCI);
  }

  return;
}
Esempio n. 19
0
bool PatmosInstrInfo::isPredicated(const MachineInstr *MI) const {
  if (MI->isBundle()) {
    MachineBasicBlock::const_instr_iterator II = MI;
    while (II->isBundledWithSucc()) {
      ++II;
      if (isPredicated(&*II)) return true;
    }
    return false;
  }

  int i = MI->findFirstPredOperandIdx();
  if (i != -1) {
    unsigned preg = MI->getOperand(i).getReg();
    int      flag = MI->getOperand(++i).getImm();
    return (preg!=Patmos::NoRegister && preg!=Patmos::P0) || flag;
  }
  // no predicates at all
  return false;
}
Esempio n. 20
0
MachineInstr &MachineFunction::CloneMachineInstrBundle(MachineBasicBlock &MBB,
    MachineBasicBlock::iterator InsertBefore, const MachineInstr &Orig) {
  MachineInstr *FirstClone = nullptr;
  MachineBasicBlock::const_instr_iterator I = Orig.getIterator();
  for (;;) {
    MachineInstr *Cloned = CloneMachineInstr(&*I);
    MBB.insert(InsertBefore, Cloned);
    if (FirstClone == nullptr) {
      FirstClone = Cloned;
    } else {
      Cloned->bundleWithPred();
    }

    if (!I->isBundledWithSucc())
      break;
    ++I;
  }
  return *FirstClone;
}
void AMDGPUAsmPrinter::EmitInstruction(const MachineInstr *MI) {
    AMDGPUMCInstLower MCInstLowering(OutContext);

    if (MI->isBundle()) {
        const MachineBasicBlock *MBB = MI->getParent();
        MachineBasicBlock::const_instr_iterator I = MI;
        ++I;
        while (I != MBB->end() && I->isInsideBundle()) {
            MCInst MCBundleInst;
            const MachineInstr *BundledInst = I;
            MCInstLowering.lower(BundledInst, MCBundleInst);
            OutStreamer.EmitInstruction(MCBundleInst);
            ++I;
        }
    } else {
        MCInst TmpInst;
        MCInstLowering.lower(MI, TmpInst);
        OutStreamer.EmitInstruction(TmpInst);
    }
}
Esempio n. 22
0
void SparcAsmPrinter::EmitInstruction(const MachineInstr *MI)
{

  switch (MI->getOpcode()) {
  default: break;
  case TargetOpcode::DBG_VALUE:
    // FIXME: Debug Value.
    return;
  case SP::GETPCX:
    LowerGETPCXAndEmitMCInsts(MI, getSubtargetInfo());
    return;
  }
  MachineBasicBlock::const_instr_iterator I = MI;
  MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();
  do {
    MCInst TmpInst;
    LowerSparcMachineInstrToMCInst(I, TmpInst, *this);
    EmitToStreamer(OutStreamer, TmpInst);
  } while ((++I != E) && I->isInsideBundle()); // Delay slot check.
}
Esempio n. 23
0
bool PatmosInstrInfo::getPredicateOperands(const MachineInstr* MI,
                                   SmallVectorImpl<MachineOperand> &Pred) const
{
  if (!isPredicated(MI)) return false;

  if (MI->isBundle()) {
    MachineBasicBlock::const_instr_iterator II = MI;
    while (II->isBundledWithSucc()) {
      ++II;
      getPredicateOperands(&*II, Pred);
    }
    return true;
  }

  if (!MI->getDesc().isPredicable()) return false;

  unsigned Pos = MI->getDesc().getNumDefs();
  Pred.push_back(MI->getOperand(Pos));
  Pred.push_back(MI->getOperand(Pos+1));

  return true;
}
/// printMachineInstruction -- Print out a single Hexagon MI in Darwin syntax to
/// the current output stream.
///
void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) {
  MCInst MCB;
  MCB.setOpcode(Hexagon::BUNDLE);
  MCB.addOperand(MCOperand::createImm(0));

  if (MI->isBundle()) {
    const MachineBasicBlock* MBB = MI->getParent();
    MachineBasicBlock::const_instr_iterator MII = MI;
    unsigned IgnoreCount = 0;

    for (++MII; MII != MBB->end() && MII->isInsideBundle(); ++MII) {
      if (MII->getOpcode() == TargetOpcode::DBG_VALUE ||
          MII->getOpcode() == TargetOpcode::IMPLICIT_DEF)
        ++IgnoreCount;
      else {
        HexagonLowerToMC(MII, MCB, *this);
      }
    }
  }
  else {
    HexagonLowerToMC(MI, MCB, *this);
    HexagonMCInstrInfo::padEndloop(MCB);
  }
  // Examine the packet and try to find instructions that can be converted
  // to compounds.
  HexagonMCInstrInfo::tryCompound(*Subtarget->getInstrInfo(),
                                  OutStreamer->getContext(), MCB);
  // Examine the packet and convert pairs of instructions to duplex
  // instructions when possible.
  SmallVector<DuplexCandidate, 8> possibleDuplexes;
  possibleDuplexes = HexagonMCInstrInfo::getDuplexPossibilties(
      *Subtarget->getInstrInfo(), MCB);
  HexagonMCShuffle(*Subtarget->getInstrInfo(), *Subtarget,
                   OutStreamer->getContext(), MCB, possibleDuplexes);
  EmitToStreamer(*OutStreamer, MCB);
}
Esempio n. 25
0
void R600AsmPrinter::EmitInstruction(const MachineInstr *MI) {
  const R600Subtarget &STI = MF->getSubtarget<R600Subtarget>();
  R600MCInstLower MCInstLowering(OutContext, STI, *this);

  StringRef Err;
  if (!STI.getInstrInfo()->verifyInstruction(*MI, Err)) {
    LLVMContext &C = MI->getParent()->getParent()->getFunction().getContext();
    C.emitError("Illegal instruction detected: " + Err);
    MI->print(errs());
  }

  if (MI->isBundle()) {
    const MachineBasicBlock *MBB = MI->getParent();
    MachineBasicBlock::const_instr_iterator I = ++MI->getIterator();
    while (I != MBB->instr_end() && I->isInsideBundle()) {
      EmitInstruction(&*I);
      ++I;
    }
  } else {
    MCInst TmpInst;
    MCInstLowering.lower(MI, TmpInst);
    EmitToStreamer(*OutStreamer, TmpInst);
 }
}
Esempio n. 26
0
void AMDGPUAsmPrinter::EmitInstruction(const MachineInstr *MI) {
  const AMDGPUSubtarget &STI = MF->getSubtarget<AMDGPUSubtarget>();
  AMDGPUMCInstLower MCInstLowering(OutContext, STI);

  StringRef Err;
  if (!STI.getInstrInfo()->verifyInstruction(MI, Err)) {
    LLVMContext &C = MI->getParent()->getParent()->getFunction()->getContext();
    C.emitError("Illegal instruction detected: " + Err);
    MI->dump();
  }

  if (MI->isBundle()) {
    const MachineBasicBlock *MBB = MI->getParent();
    MachineBasicBlock::const_instr_iterator I = ++MI->getIterator();
    while (I != MBB->instr_end() && I->isInsideBundle()) {
      EmitInstruction(&*I);
      ++I;
    }
  } else {
    // We don't want SI_MASK_BRANCH/SI_RETURN encoded. They are placeholder
    // terminator instructions and should only be printed as comments.
    if (MI->getOpcode() == AMDGPU::SI_MASK_BRANCH) {
      if (isVerbose()) {
        SmallVector<char, 16> BBStr;
        raw_svector_ostream Str(BBStr);

        const MachineBasicBlock *MBB = MI->getOperand(1).getMBB();
        const MCSymbolRefExpr *Expr
          = MCSymbolRefExpr::create(MBB->getSymbol(), OutContext);
        Expr->print(Str, MAI);
        OutStreamer->emitRawComment(" mask branch " + BBStr);
      }

      return;
    }

    if (MI->getOpcode() == AMDGPU::SI_RETURN) {
      if (isVerbose())
        OutStreamer->emitRawComment(" return");
      return;
    }

    MCInst TmpInst;
    MCInstLowering.lower(MI, TmpInst);
    EmitToStreamer(*OutStreamer, TmpInst);

    if (STI.dumpCode()) {
      // Disassemble instruction/operands to text.
      DisasmLines.resize(DisasmLines.size() + 1);
      std::string &DisasmLine = DisasmLines.back();
      raw_string_ostream DisasmStream(DisasmLine);

      AMDGPUInstPrinter InstPrinter(*TM.getMCAsmInfo(),
                                    *STI.getInstrInfo(),
                                    *STI.getRegisterInfo());
      InstPrinter.printInst(&TmpInst, DisasmStream, StringRef(), STI);

      // Disassemble instruction/operands to hex representation.
      SmallVector<MCFixup, 4> Fixups;
      SmallVector<char, 16> CodeBytes;
      raw_svector_ostream CodeStream(CodeBytes);

      auto &ObjStreamer = static_cast<MCObjectStreamer&>(*OutStreamer);
      MCCodeEmitter &InstEmitter = ObjStreamer.getAssembler().getEmitter();
      InstEmitter.encodeInstruction(TmpInst, CodeStream, Fixups,
                                    MF->getSubtarget<MCSubtargetInfo>());
      HexLines.resize(HexLines.size() + 1);
      std::string &HexLine = HexLines.back();
      raw_string_ostream HexStream(HexLine);

      for (size_t i = 0; i < CodeBytes.size(); i += 4) {
        unsigned int CodeDWord = *(unsigned int *)&CodeBytes[i];
        HexStream << format("%s%08X", (i > 0 ? " " : ""), CodeDWord);
      }

      DisasmStream.flush();
      DisasmLineMaxLen = std::max(DisasmLineMaxLen, DisasmLine.size());
    }
  }
}
Esempio n. 27
0
bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) {
  raw_ostream *OutFile = 0;
  if (OutFileName) {
    std::string ErrorInfo;
    OutFile = new raw_fd_ostream(OutFileName, ErrorInfo,
                                 raw_fd_ostream::F_Append);
    if (!ErrorInfo.empty()) {
      errs() << "Error opening '" << OutFileName << "': " << ErrorInfo << '\n';
      exit(1);
    }

    OS = OutFile;
  } else {
    OS = &errs();
  }

  foundErrors = 0;

  this->MF = &MF;
  TM = &MF.getTarget();
  TII = TM->getInstrInfo();
  TRI = TM->getRegisterInfo();
  MRI = &MF.getRegInfo();

  LiveVars = NULL;
  LiveInts = NULL;
  LiveStks = NULL;
  Indexes = NULL;
  if (PASS) {
    LiveInts = PASS->getAnalysisIfAvailable<LiveIntervals>();
    // We don't want to verify LiveVariables if LiveIntervals is available.
    if (!LiveInts)
      LiveVars = PASS->getAnalysisIfAvailable<LiveVariables>();
    LiveStks = PASS->getAnalysisIfAvailable<LiveStacks>();
    Indexes = PASS->getAnalysisIfAvailable<SlotIndexes>();
  }

  visitMachineFunctionBefore();
  for (MachineFunction::const_iterator MFI = MF.begin(), MFE = MF.end();
       MFI!=MFE; ++MFI) {
    visitMachineBasicBlockBefore(MFI);
    for (MachineBasicBlock::const_instr_iterator MBBI = MFI->instr_begin(),
           MBBE = MFI->instr_end(); MBBI != MBBE; ++MBBI) {
      if (MBBI->getParent() != MFI) {
        report("Bad instruction parent pointer", MFI);
        *OS << "Instruction: " << *MBBI;
        continue;
      }
      // Skip BUNDLE instruction for now. FIXME: We should add code to verify
      // the BUNDLE's specifically.
      if (MBBI->isBundle())
        continue;
      visitMachineInstrBefore(MBBI);
      for (unsigned I = 0, E = MBBI->getNumOperands(); I != E; ++I)
        visitMachineOperand(&MBBI->getOperand(I), I);
      visitMachineInstrAfter(MBBI);
    }
    visitMachineBasicBlockAfter(MFI);
  }
  visitMachineFunctionAfter();

  if (OutFile)
    delete OutFile;
  else if (foundErrors)
    report_fatal_error("Found "+Twine(foundErrors)+" machine code errors.");

  // Clean up.
  regsLive.clear();
  regsDefined.clear();
  regsDead.clear();
  regsKilled.clear();
  regsLiveInButUnused.clear();
  MBBInfoMap.clear();

  return false;                 // no changes
}
Esempio n. 28
0
void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
  MipsTargetStreamer &TS = getTargetStreamer();
  TS.forbidModuleDirective();

  if (MI->isDebugValue()) {
    SmallString<128> Str;
    raw_svector_ostream OS(Str);

    PrintDebugValueComment(MI, OS);
    return;
  }

  // If we just ended a constant pool, mark it as such.
  if (InConstantPool && MI->getOpcode() != Mips::CONSTPOOL_ENTRY) {
    OutStreamer->EmitDataRegion(MCDR_DataRegionEnd);
    InConstantPool = false;
  }
  if (MI->getOpcode() == Mips::CONSTPOOL_ENTRY) {
    // CONSTPOOL_ENTRY - This instruction represents a floating
    //constant pool in the function.  The first operand is the ID#
    // for this instruction, the second is the index into the
    // MachineConstantPool that this is, the third is the size in
    // bytes of this constant pool entry.
    // The required alignment is specified on the basic block holding this MI.
    //
    unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
    unsigned CPIdx   = (unsigned)MI->getOperand(1).getIndex();

    // If this is the first entry of the pool, mark it.
    if (!InConstantPool) {
      OutStreamer->EmitDataRegion(MCDR_DataRegion);
      InConstantPool = true;
    }

    OutStreamer->EmitLabel(GetCPISymbol(LabelId));

    const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
    if (MCPE.isMachineConstantPoolEntry())
      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
    else
      EmitGlobalConstant(MF->getDataLayout(), MCPE.Val.ConstVal);
    return;
  }


  MachineBasicBlock::const_instr_iterator I = MI->getIterator();
  MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end();

  do {
    // Do any auto-generated pseudo lowerings.
    if (emitPseudoExpansionLowering(*OutStreamer, &*I))
      continue;

    if (I->getOpcode() == Mips::PseudoReturn ||
        I->getOpcode() == Mips::PseudoReturn64 ||
        I->getOpcode() == Mips::PseudoIndirectBranch ||
        I->getOpcode() == Mips::PseudoIndirectBranch64) {
      emitPseudoIndirectBranch(*OutStreamer, &*I);
      continue;
    }

    // The inMips16Mode() test is not permanent.
    // Some instructions are marked as pseudo right now which
    // would make the test fail for the wrong reason but
    // that will be fixed soon. We need this here because we are
    // removing another test for this situation downstream in the
    // callchain.
    //
    if (I->isPseudo() && !Subtarget->inMips16Mode()
        && !isLongBranchPseudo(I->getOpcode()))
      llvm_unreachable("Pseudo opcode found in EmitInstruction()");

    MCInst TmpInst0;
    MCInstLowering.Lower(&*I, TmpInst0);
    EmitToStreamer(*OutStreamer, TmpInst0);
  } while ((++I != E) && I->isInsideBundle()); // Delay slot check
}
Esempio n. 29
0
void AMDGPUAsmPrinter::EmitInstruction(const MachineInstr *MI) {
  if (emitPseudoExpansionLowering(*OutStreamer, MI))
    return;

  const GCNSubtarget &STI = MF->getSubtarget<GCNSubtarget>();
  AMDGPUMCInstLower MCInstLowering(OutContext, STI, *this);

  StringRef Err;
  if (!STI.getInstrInfo()->verifyInstruction(*MI, Err)) {
    LLVMContext &C = MI->getParent()->getParent()->getFunction().getContext();
    C.emitError("Illegal instruction detected: " + Err);
    MI->print(errs());
  }

  if (MI->isBundle()) {
    const MachineBasicBlock *MBB = MI->getParent();
    MachineBasicBlock::const_instr_iterator I = ++MI->getIterator();
    while (I != MBB->instr_end() && I->isInsideBundle()) {
      EmitInstruction(&*I);
      ++I;
    }
  } else {
    // We don't want SI_MASK_BRANCH/SI_RETURN_TO_EPILOG encoded. They are
    // placeholder terminator instructions and should only be printed as
    // comments.
    if (MI->getOpcode() == AMDGPU::SI_MASK_BRANCH) {
      if (isVerbose()) {
        SmallVector<char, 16> BBStr;
        raw_svector_ostream Str(BBStr);

        const MachineBasicBlock *MBB = MI->getOperand(0).getMBB();
        const MCSymbolRefExpr *Expr
          = MCSymbolRefExpr::create(MBB->getSymbol(), OutContext);
        Expr->print(Str, MAI);
        OutStreamer->emitRawComment(Twine(" mask branch ") + BBStr);
      }

      return;
    }

    if (MI->getOpcode() == AMDGPU::SI_RETURN_TO_EPILOG) {
      if (isVerbose())
        OutStreamer->emitRawComment(" return to shader part epilog");
      return;
    }

    if (MI->getOpcode() == AMDGPU::WAVE_BARRIER) {
      if (isVerbose())
        OutStreamer->emitRawComment(" wave barrier");
      return;
    }

    if (MI->getOpcode() == AMDGPU::SI_MASKED_UNREACHABLE) {
      if (isVerbose())
        OutStreamer->emitRawComment(" divergent unreachable");
      return;
    }

    MCInst TmpInst;
    MCInstLowering.lower(MI, TmpInst);
    EmitToStreamer(*OutStreamer, TmpInst);

#ifdef EXPENSIVE_CHECKS
    // Sanity-check getInstSizeInBytes on explicitly specified CPUs (it cannot
    // work correctly for the generic CPU).
    //
    // The isPseudo check really shouldn't be here, but unfortunately there are
    // some negative lit tests that depend on being able to continue through
    // here even when pseudo instructions haven't been lowered.
    if (!MI->isPseudo() && STI.isCPUStringValid(STI.getCPU())) {
      SmallVector<MCFixup, 4> Fixups;
      SmallVector<char, 16> CodeBytes;
      raw_svector_ostream CodeStream(CodeBytes);

      std::unique_ptr<MCCodeEmitter> InstEmitter(createSIMCCodeEmitter(
          *STI.getInstrInfo(), *OutContext.getRegisterInfo(), OutContext));
      InstEmitter->encodeInstruction(TmpInst, CodeStream, Fixups, STI);

      assert(CodeBytes.size() == STI.getInstrInfo()->getInstSizeInBytes(*MI));
    }
#endif

    if (STI.dumpCode()) {
      // Disassemble instruction/operands to text.
      DisasmLines.resize(DisasmLines.size() + 1);
      std::string &DisasmLine = DisasmLines.back();
      raw_string_ostream DisasmStream(DisasmLine);

      AMDGPUInstPrinter InstPrinter(*TM.getMCAsmInfo(),
                                    *STI.getInstrInfo(),
                                    *STI.getRegisterInfo());
      InstPrinter.printInst(&TmpInst, DisasmStream, StringRef(), STI);

      // Disassemble instruction/operands to hex representation.
      SmallVector<MCFixup, 4> Fixups;
      SmallVector<char, 16> CodeBytes;
      raw_svector_ostream CodeStream(CodeBytes);

      auto &ObjStreamer = static_cast<MCObjectStreamer&>(*OutStreamer);
      MCCodeEmitter &InstEmitter = ObjStreamer.getAssembler().getEmitter();
      InstEmitter.encodeInstruction(TmpInst, CodeStream, Fixups,
                                    MF->getSubtarget<MCSubtargetInfo>());
      HexLines.resize(HexLines.size() + 1);
      std::string &HexLine = HexLines.back();
      raw_string_ostream HexStream(HexLine);

      for (size_t i = 0; i < CodeBytes.size(); i += 4) {
        unsigned int CodeDWord = *(unsigned int *)&CodeBytes[i];
        HexStream << format("%s%08X", (i > 0 ? " " : ""), CodeDWord);
      }

      DisasmStream.flush();
      DisasmLineMaxLen = std::max(DisasmLineMaxLen, DisasmLine.size());
    }
  }
}