예제 #1
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());
}
예제 #2
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;
  }
}
/// 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);
}
예제 #4
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
}