/// runOnMachineFunction - This uses the printMachineInstruction()
/// method to print assembly for each instruction.
///
bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
  SetupMachineFunction(MF);
  O << "\n\n";

  // Print out constants referenced by the function
  EmitConstantPool(MF.getConstantPool());

  // Print out labels for the function.
  const Function *F = MF.getFunction();
  unsigned CC = F->getCallingConv();

  // Populate function information map.  Actually, We don't want to populate
  // non-stdcall or non-fastcall functions' information right now.
  if (CC == CallingConv::X86_StdCall || CC == CallingConv::X86_FastCall)
    FunctionInfoMap[F] = *MF.getInfo<X86MachineFunctionInfo>();

  decorateName(CurrentFnName, F);

  SwitchToTextSection("_text", F);

  unsigned FnAlign = 4;
  if (F->hasFnAttr(Attribute::OptimizeForSize))
    FnAlign = 1;
  switch (F->getLinkage()) {
  default: assert(0 && "Unsupported linkage type!");
  case Function::PrivateLinkage:
  case Function::InternalLinkage:
    EmitAlignment(FnAlign);
    break;
  case Function::DLLExportLinkage:
    DLLExportedFns.insert(CurrentFnName);
    //FALLS THROUGH
  case Function::ExternalLinkage:
    O << "\tpublic " << CurrentFnName << "\n";
    EmitAlignment(FnAlign);
    break;
  }

  O << CurrentFnName << "\tproc near\n";

  // Print out code for the function.
  for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
       I != E; ++I) {
    // Print a label for the basic block if there are any predecessors.
    if (!I->pred_empty()) {
      printBasicBlockLabel(I, true, true);
      O << '\n';
    }
    for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
         II != E; ++II) {
      // Print the assembly for the instruction.
      printMachineInstruction(II);
    }
  }

  // Print out jump tables referenced by the function.
  EmitJumpTableInfo(MF.getJumpTableInfo(), MF);

  O << CurrentFnName << "\tendp\n";

  O.flush();

  // We didn't modify anything.
  return false;
}
Esempio n. 2
0
bool
MIRParserImpl::initializeMachineFunction(const yaml::MachineFunction &YamlMF,
                                         MachineFunction &MF) {
  // TODO: Recreate the machine function.
  initNames2RegClasses(MF);
  initNames2RegBanks(MF);
  if (YamlMF.Alignment)
    MF.setAlignment(YamlMF.Alignment);
  MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);

  if (YamlMF.Legalized)
    MF.getProperties().set(MachineFunctionProperties::Property::Legalized);
  if (YamlMF.RegBankSelected)
    MF.getProperties().set(
        MachineFunctionProperties::Property::RegBankSelected);
  if (YamlMF.Selected)
    MF.getProperties().set(MachineFunctionProperties::Property::Selected);

  PerFunctionMIParsingState PFS(MF, SM, IRSlots, Names2RegClasses,
                                Names2RegBanks);
  if (parseRegisterInfo(PFS, YamlMF))
    return true;
  if (!YamlMF.Constants.empty()) {
    auto *ConstantPool = MF.getConstantPool();
    assert(ConstantPool && "Constant pool must be created");
    if (initializeConstantPool(PFS, *ConstantPool, YamlMF))
      return true;
  }

  StringRef BlockStr = YamlMF.Body.Value.Value;
  SMDiagnostic Error;
  SourceMgr BlockSM;
  BlockSM.AddNewSourceBuffer(
      MemoryBuffer::getMemBuffer(BlockStr, "",/*RequiresNullTerminator=*/false),
      SMLoc());
  PFS.SM = &BlockSM;
  if (parseMachineBasicBlockDefinitions(PFS, BlockStr, Error)) {
    reportDiagnostic(
        diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
    return true;
  }
  PFS.SM = &SM;

  // Initialize the frame information after creating all the MBBs so that the
  // MBB references in the frame information can be resolved.
  if (initializeFrameInfo(PFS, YamlMF))
    return true;
  // Initialize the jump table after creating all the MBBs so that the MBB
  // references can be resolved.
  if (!YamlMF.JumpTableInfo.Entries.empty() &&
      initializeJumpTableInfo(PFS, YamlMF.JumpTableInfo))
    return true;
  // Parse the machine instructions after creating all of the MBBs so that the
  // parser can resolve the MBB references.
  StringRef InsnStr = YamlMF.Body.Value.Value;
  SourceMgr InsnSM;
  InsnSM.AddNewSourceBuffer(
      MemoryBuffer::getMemBuffer(InsnStr, "", /*RequiresNullTerminator=*/false),
      SMLoc());
  PFS.SM = &InsnSM;
  if (parseMachineInstructions(PFS, InsnStr, Error)) {
    reportDiagnostic(
        diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
    return true;
  }
  PFS.SM = &SM;

  if (setupRegisterInfo(PFS, YamlMF))
    return true;

  computeFunctionProperties(MF);

  MF.verify();
  return false;
}
Esempio n. 3
0
bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) {
  auto It = Functions.find(MF.getName());
  if (It == Functions.end())
    return error(Twine("no machine function information for function '") +
                 MF.getName() + "' in the MIR file");
  // TODO: Recreate the machine function.
  const yaml::MachineFunction &YamlMF = *It->getValue();
  if (YamlMF.Alignment)
    MF.setAlignment(YamlMF.Alignment);
  MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice);

  if (YamlMF.Legalized)
    MF.getProperties().set(MachineFunctionProperties::Property::Legalized);
  if (YamlMF.RegBankSelected)
    MF.getProperties().set(
        MachineFunctionProperties::Property::RegBankSelected);
  if (YamlMF.Selected)
    MF.getProperties().set(MachineFunctionProperties::Property::Selected);

  PerFunctionMIParsingState PFS(MF, SM, IRSlots);
  if (initializeRegisterInfo(PFS, YamlMF))
    return true;
  if (!YamlMF.Constants.empty()) {
    auto *ConstantPool = MF.getConstantPool();
    assert(ConstantPool && "Constant pool must be created");
    if (initializeConstantPool(PFS, *ConstantPool, YamlMF))
      return true;
  }

  StringRef BlockStr = YamlMF.Body.Value.Value;
  SMDiagnostic Error;
  SourceMgr BlockSM;
  BlockSM.AddNewSourceBuffer(
      MemoryBuffer::getMemBuffer(BlockStr, "",/*RequiresNullTerminator=*/false),
      SMLoc());
  PFS.SM = &BlockSM;
  if (parseMachineBasicBlockDefinitions(PFS, BlockStr, Error)) {
    reportDiagnostic(
        diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
    return true;
  }
  PFS.SM = &SM;

  if (MF.empty())
    return error(Twine("machine function '") + Twine(MF.getName()) +
                 "' requires at least one machine basic block in its body");
  // Initialize the frame information after creating all the MBBs so that the
  // MBB references in the frame information can be resolved.
  if (initializeFrameInfo(PFS, YamlMF))
    return true;
  // Initialize the jump table after creating all the MBBs so that the MBB
  // references can be resolved.
  if (!YamlMF.JumpTableInfo.Entries.empty() &&
      initializeJumpTableInfo(PFS, YamlMF.JumpTableInfo))
    return true;
  // Parse the machine instructions after creating all of the MBBs so that the
  // parser can resolve the MBB references.
  StringRef InsnStr = YamlMF.Body.Value.Value;
  SourceMgr InsnSM;
  InsnSM.AddNewSourceBuffer(
      MemoryBuffer::getMemBuffer(InsnStr, "", /*RequiresNullTerminator=*/false),
      SMLoc());
  PFS.SM = &InsnSM;
  if (parseMachineInstructions(PFS, InsnStr, Error)) {
    reportDiagnostic(
        diagFromBlockStringDiag(Error, YamlMF.Body.Value.SourceRange));
    return true;
  }
  PFS.SM = &SM;

  inferRegisterInfo(PFS, YamlMF);

  computeFunctionProperties(MF);

  // FIXME: This is a temporary workaround until the reserved registers can be
  // serialized.
  MF.getRegInfo().freezeReservedRegs(MF);
  MF.verify();
  return false;
}
Esempio n. 4
0
void SVMFrameLowering::emitPrologue(MachineFunction &MF) const
{
    MachineBasicBlock &MBB = MF.front();
    MachineBasicBlock::iterator MBBI = MBB.begin();
    MachineFrameInfo *MFI = MF.getFrameInfo();
    DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
    const SVMInstrInfo &TII =
        *static_cast<const SVMInstrInfo*>(MF.getTarget().getInstrInfo());

    /*
     * Align both the top and bottom of the stack frame, so that our frame
     * size and frame indices are always word-aligned.
     */

    unsigned stackSize = MFI->getStackSize();
    unsigned alignMask = getStackAlignment() - 1;
    assert(alignMask >= 3);
    stackSize = (stackSize + alignMask) & ~alignMask;
    MFI->setStackSize(stackSize);
    
    /*
     * Apply a stack frame adjustment at the beginning of this function.
     * On SVM, there are three ways to do this. In order of decreasing
     * preferability:
     *
     *   1. We can get a small adjustment (0x7F words or less) for
     *      free as part of the 'call' SVC. This stack adjustment is encoded
     *      into the function address at link time, using a FNSTACK
     *      pseudo-instruction, which is used by SVMELFProgramWriter to
     *      generate the proper relocations.
     *
     *   2. Small remainders can be allocated using SPADJ. This works for
     *      up to 31 words at a time.
     *
     *   3. Larger remainders are allocated using an indirect addrop which
     *      can allocate up to 64MB of stack space :)
     *
     * The addrop in (3) clearly trumps the other two methods for dealing
     * with truly large stack frames. But because the FNSTACK adjustment is
     * so cheap, we always try to use it. This also has the nice effect of
     * making large-stacked functions clearly visible, since they'll have
     * a 0x7F in their upper address bits.
     */

    uint32_t wordsRemaining = (stackSize + 3) / 4;

    if (wordsRemaining) {
        uint32_t chunk = std::min(wordsRemaining, (uint32_t)0x7F);
        BuildMI(MBB, MBBI, dl, TII.get(SVM::FNSTACK)).addImm(chunk << 2);
        wordsRemaining -= chunk;
    }

    if (wordsRemaining)
        report_warning(MF.getFunction(), "Large stack frame, " + Twine(stackSize) + " bytes.");

    if (wordsRemaining > 0x1F) {
        assert(wordsRemaining <= 0xFFFFFF);
        uint32_t indir = 0xc3000000 | wordsRemaining;
        LLVMContext &Ctx = MF.getFunction()->getContext();
        Constant *C = ConstantInt::get(Type::getInt32Ty(Ctx),  indir);
        unsigned cpi = MF.getConstantPool()->getConstantPoolIndex(C, 4);
        BuildMI(MBB, MBBI, dl, TII.get(SVM::SPADJi)).addConstantPoolIndex(cpi);

    } else if (wordsRemaining) {
        assert(wordsRemaining <= 0x1F);
        BuildMI(MBB, MBBI, dl, TII.get(SVM::SPADJ)).addImm(wordsRemaining << 2);
    }
}