/// 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()); }
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); }
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 }