#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
-#include "llvm/Target/TargetRegistry.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
#include <cctype>
return "MBlaze Assembly Printer";
}
+ void printSavedRegsBitmask();
+ void emitFrameDirective();
+ virtual void EmitFunctionBodyStart();
+ virtual void EmitFunctionBodyEnd();
+ virtual void EmitFunctionEntryLabel();
+
+ virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB)
+ const;
+
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
unsigned AsmVariant, const char *ExtraCode,
raw_ostream &O);
void printFSLImm(const MachineInstr *MI, int opNum, raw_ostream &O);
void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
const char *Modifier = 0);
- void printSavedRegsBitmask(raw_ostream &OS);
- void emitFrameDirective();
-
- void EmitInstruction(const MachineInstr *MI);
- virtual void EmitFunctionBodyStart();
- virtual void EmitFunctionBodyEnd();
-
- virtual void EmitFunctionEntryLabel();
+ void EmitInstruction(const MachineInstr *MI);
};
} // end of anonymous namespace
//
//===----------------------------------------------------------------------===//
-//===----------------------------------------------------------------------===//
-void MBlazeAsmPrinter::EmitInstruction(const MachineInstr *MI) {
- MBlazeMCInstLower MCInstLowering(OutContext, *Mang, *this);
-
- MCInst TmpInst;
- MCInstLowering.Lower(MI, TmpInst);
- OutStreamer.EmitInstruction(TmpInst);
-}
-
-//===----------------------------------------------------------------------===//
-// Mask directives
-//===----------------------------------------------------------------------===//
-
// Print a 32 bit hex number with all numbers.
static void printHex32(unsigned int Value, raw_ostream &O) {
O << "0x";
for (int i = 7; i >= 0; i--)
- O << utohexstr((Value & (0xF << (i*4))) >> (i*4));
+ O.write_hex((Value & (0xF << (i*4))) >> (i*4));
}
-
// Create a bitmask with all callee saved registers for CPU or Floating Point
// registers. For CPU registers consider RA, GP and FP for saving if necessary.
-void MBlazeAsmPrinter::printSavedRegsBitmask(raw_ostream &O) {
+void MBlazeAsmPrinter::printSavedRegsBitmask() {
+ const TargetFrameLowering *TFI = TM.getFrameLowering();
const TargetRegisterInfo &RI = *TM.getRegisterInfo();
- const MBlazeFunctionInfo *MBlazeFI = MF->getInfo<MBlazeFunctionInfo>();
// CPU Saved Registers Bitmasks
unsigned int CPUBitmask = 0;
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
unsigned Reg = CSI[i].getReg();
- unsigned RegNum = MBlazeRegisterInfo::getRegisterNumbering(Reg);
- if (MBlaze::CPURegsRegisterClass->contains(Reg))
+ unsigned RegNum = getMBlazeRegisterNumbering(Reg);
+ if (MBlaze::GPRRegClass.contains(Reg))
CPUBitmask |= (1 << RegNum);
}
// Return Address and Frame registers must also be set in CPUBitmask.
- if (RI.hasFP(*MF))
- CPUBitmask |= (1 << MBlazeRegisterInfo::
- getRegisterNumbering(RI.getFrameRegister(*MF)));
+ if (TFI->hasFP(*MF))
+ CPUBitmask |= (1 << getMBlazeRegisterNumbering(RI.getFrameRegister(*MF)));
if (MFI->adjustsStack())
- CPUBitmask |= (1 << MBlazeRegisterInfo::
- getRegisterNumbering(RI.getRARegister()));
+ CPUBitmask |= (1 << getMBlazeRegisterNumbering(RI.getRARegister()));
// Print CPUBitmask
- O << "\t.mask \t"; printHex32(CPUBitmask, O);
- O << ',' << MBlazeFI->getCPUTopSavedRegOff() << '\n';
+ OutStreamer.EmitRawText("\t.mask\t0x" + Twine::utohexstr(CPUBitmask));
}
-//===----------------------------------------------------------------------===//
-// Frame and Set directives
-//===----------------------------------------------------------------------===//
-
/// Frame Directive
void MBlazeAsmPrinter::emitFrameDirective() {
- // const TargetRegisterInfo &RI = *TM.getRegisterInfo();
-
- // unsigned stackReg = RI.getFrameRegister(*MF);
- // unsigned returnReg = RI.getRARegister();
- // unsigned stackSize = MF->getFrameInfo()->getStackSize();
-
+ if (!OutStreamer.hasRawTextSupport())
+ return;
- /*
- OutStreamer.EmitRawText("\t.frame\t" +
- Twine(MBlazeInstPrinter::getRegisterName(stackReg)) +
- "," + Twine(stackSize) + "," +
- Twine(MBlazeInstPrinter::getRegisterName(returnReg)));
- */
+ const TargetRegisterInfo &RI = *TM.getRegisterInfo();
+ unsigned stkReg = RI.getFrameRegister(*MF);
+ unsigned retReg = RI.getRARegister();
+ unsigned stkSze = MF->getFrameInfo()->getStackSize();
+
+ OutStreamer.EmitRawText("\t.frame\t" +
+ Twine(MBlazeInstPrinter::getRegisterName(stkReg)) +
+ "," + Twine(stkSze) + "," +
+ Twine(MBlazeInstPrinter::getRegisterName(retReg)));
}
void MBlazeAsmPrinter::EmitFunctionEntryLabel() {
- // OutStreamer.EmitRawText("\t.ent\t" + Twine(CurrentFnSym->getName()));
- OutStreamer.EmitLabel(CurrentFnSym);
+ if (OutStreamer.hasRawTextSupport())
+ OutStreamer.EmitRawText("\t.ent\t" + Twine(CurrentFnSym->getName()));
+ AsmPrinter::EmitFunctionEntryLabel();
}
-/// EmitFunctionBodyStart - Targets can override this to emit stuff before
-/// the first basic block in the function.
void MBlazeAsmPrinter::EmitFunctionBodyStart() {
- // emitFrameDirective();
-
- // SmallString<128> Str;
- // raw_svector_ostream OS(Str);
- // printSavedRegsBitmask(OS);
- // OutStreamer.EmitRawText(OS.str());
+ if (!OutStreamer.hasRawTextSupport())
+ return;
+
+ emitFrameDirective();
+ printSavedRegsBitmask();
}
-/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
-/// the last basic block in the function.
void MBlazeAsmPrinter::EmitFunctionBodyEnd() {
- // OutStreamer.EmitRawText("\t.end\t" + Twine(CurrentFnSym->getName()));
+ if (OutStreamer.hasRawTextSupport())
+ OutStreamer.EmitRawText("\t.end\t" + Twine(CurrentFnSym->getName()));
+}
+
+//===----------------------------------------------------------------------===//
+void MBlazeAsmPrinter::EmitInstruction(const MachineInstr *MI) {
+ MBlazeMCInstLower MCInstLowering(OutContext, *this);
+
+ MCInst TmpInst;
+ MCInstLowering.Lower(MI, TmpInst);
+ OutStreamer.EmitInstruction(TmpInst);
}
// Print out an operand for an inline asm expression.
break;
case MachineOperand::MO_Immediate:
- O << (int)MO.getImm();
+ O << (int32_t)MO.getImm();
break;
case MachineOperand::MO_FPImmediate: {
raw_ostream &O) {
const MachineOperand &MO = MI->getOperand(opNum);
if (MO.isImm())
- O << (unsigned int)MO.getImm();
+ O << (uint32_t)MO.getImm();
else
printOperand(MI, opNum, O);
}
void MBlazeAsmPrinter::
printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
const char *Modifier) {
- printOperand(MI, opNum+1, O);
- O << ", ";
printOperand(MI, opNum, O);
+ O << ", ";
+ printOperand(MI, opNum+1, O);
}
-static MCInstPrinter *createMBlazeMCInstPrinter(const Target &T,
- unsigned SyntaxVariant,
- const MCAsmInfo &MAI) {
- if (SyntaxVariant == 0)
- return new MBlazeInstPrinter(MAI);
- return 0;
+/// isBlockOnlyReachableByFallthough - Return true if the basic block has
+/// exactly one predecessor and the control transfer mechanism between
+/// the predecessor and this block is a fall-through.
+bool MBlazeAsmPrinter::
+isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
+ // If this is a landing pad, it isn't a fall through. If it has no preds,
+ // then nothing falls through to it.
+ if (MBB->isLandingPad() || MBB->pred_empty())
+ return false;
+
+ // If there isn't exactly one predecessor, it can't be a fall through.
+ MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI;
+ ++PI2;
+ if (PI2 != MBB->pred_end())
+ return false;
+
+ // The predecessor has to be immediately before this block.
+ const MachineBasicBlock *Pred = *PI;
+
+ if (!Pred->isLayoutSuccessor(MBB))
+ return false;
+
+ // If the block is completely empty, then it definitely does fall through.
+ if (Pred->empty())
+ return true;
+
+ // Check if the last terminator is an unconditional branch.
+ MachineBasicBlock::const_iterator I = Pred->end();
+ while (I != Pred->begin() && !(--I)->isTerminator())
+ ; // Noop
+ return I == Pred->end() || !I->isBarrier();
}
// Force static initialization.
extern "C" void LLVMInitializeMBlazeAsmPrinter() {
RegisterAsmPrinter<MBlazeAsmPrinter> X(TheMBlazeTarget);
- TargetRegistry::RegisterMCInstPrinter(TheMBlazeTarget,
- createMBlazeMCInstPrinter);
-
}