summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWesley Peck <peckw@wesleypeck.com>2010-11-24 15:39:32 +0000
committerWesley Peck <peckw@wesleypeck.com>2010-11-24 15:39:32 +0000
commit82dc040d0690059beb060ba6640907fb2a295958 (patch)
treefa2629f09feda9c8f53a93f8bbbebddd02b56c84
parent7de81016684979490229ed59c81ff9a94a75d4c2 (diff)
downloadllvm-82dc040d0690059beb060ba6640907fb2a295958.tar.gz
llvm-82dc040d0690059beb060ba6640907fb2a295958.tar.bz2
llvm-82dc040d0690059beb060ba6640907fb2a295958.tar.xz
1. Fixing error where basic block labels were not being printed out when they need to be for the MBlaze backend because AsmPrinter::isBlockOnlyReachableByFallthrough does not take into account delay slots.
2. Re-adding .mask and .frame directives in printed assembly. 3. Adding .ent and .end directives in printed assembly. 4. Minor cleanups to MBlaze backend. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120095 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/MBlaze/MBlazeAsmPrinter.cpp123
-rw-r--r--lib/Target/MBlaze/MBlazeMCAsmInfo.cpp7
-rw-r--r--lib/Target/MBlaze/MBlazeMCInstLower.cpp22
-rw-r--r--lib/Target/MBlaze/MBlazeRegisterInfo.cpp5
-rw-r--r--lib/Target/MBlaze/MBlazeTargetMachine.cpp2
5 files changed, 126 insertions, 33 deletions
diff --git a/lib/Target/MBlaze/MBlazeAsmPrinter.cpp b/lib/Target/MBlaze/MBlazeAsmPrinter.cpp
index 6c206d0deb..e179a236e9 100644
--- a/lib/Target/MBlaze/MBlazeAsmPrinter.cpp
+++ b/lib/Target/MBlaze/MBlazeAsmPrinter.cpp
@@ -60,6 +60,15 @@ namespace {
return "MBlaze Assembly Printer";
}
+ void printSavedRegsBitmask(raw_ostream &O);
+ 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);
@@ -106,6 +115,79 @@ namespace {
//
//===----------------------------------------------------------------------===//
+// 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));
+}
+
+// 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) {
+ const TargetFrameInfo *TFI = TM.getFrameInfo();
+ const TargetRegisterInfo &RI = *TM.getRegisterInfo();
+ const MBlazeFunctionInfo *MBlazeFI = MF->getInfo<MBlazeFunctionInfo>();
+
+ // CPU Saved Registers Bitmasks
+ unsigned int CPUBitmask = 0;
+
+ // Set the CPU Bitmasks
+ const MachineFrameInfo *MFI = MF->getFrameInfo();
+ 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::GPRRegisterClass->contains(Reg))
+ CPUBitmask |= (1 << RegNum);
+ }
+
+ // Return Address and Frame registers must also be set in CPUBitmask.
+ if (TFI->hasFP(*MF))
+ CPUBitmask |= (1 << MBlazeRegisterInfo::
+ getRegisterNumbering(RI.getFrameRegister(*MF)));
+
+ if (MFI->adjustsStack())
+ CPUBitmask |= (1 << MBlazeRegisterInfo::
+ getRegisterNumbering(RI.getRARegister()));
+
+ // Print CPUBitmask
+ O << "\t.mask \t"; printHex32(CPUBitmask, O); O << ','
+ << MBlazeFI->getCPUTopSavedRegOff() << '\n';
+}
+
+/// Frame Directive
+void MBlazeAsmPrinter::emitFrameDirective() {
+ 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()));
+ AsmPrinter::EmitFunctionEntryLabel();
+}
+
+void MBlazeAsmPrinter::EmitFunctionBodyStart() {
+ emitFrameDirective();
+
+ SmallString<128> Str;
+ raw_svector_ostream OS(Str);
+ printSavedRegsBitmask(OS);
+ OutStreamer.EmitRawText(OS.str());
+}
+
+void MBlazeAsmPrinter::EmitFunctionBodyEnd() {
+ OutStreamer.EmitRawText("\t.end\t" + Twine(CurrentFnSym->getName()));
+}
+
//===----------------------------------------------------------------------===//
void MBlazeAsmPrinter::EmitInstruction(const MachineInstr *MI) {
MBlazeMCInstLower MCInstLowering(OutContext, *Mang, *this);
@@ -115,14 +197,6 @@ void MBlazeAsmPrinter::EmitInstruction(const MachineInstr *MI) {
OutStreamer.EmitInstruction(TmpInst);
}
-// 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));
-}
-
-
// Print out an operand for an inline asm expression.
bool MBlazeAsmPrinter::
PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
@@ -210,6 +284,39 @@ printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
printOperand(MI, opNum+1, O);
}
+/// 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)->getDesc().isTerminator())
+ ; // Noop
+ return I == Pred->end() || !I->getDesc().isBarrier();
+}
+
static MCInstPrinter *createMBlazeMCInstPrinter(const Target &T,
unsigned SyntaxVariant,
const MCAsmInfo &MAI) {
diff --git a/lib/Target/MBlaze/MBlazeMCAsmInfo.cpp b/lib/Target/MBlaze/MBlazeMCAsmInfo.cpp
index 23b8246320..1467141d34 100644
--- a/lib/Target/MBlaze/MBlazeMCAsmInfo.cpp
+++ b/lib/Target/MBlaze/MBlazeMCAsmInfo.cpp
@@ -15,13 +15,8 @@
using namespace llvm;
MBlazeMCAsmInfo::MBlazeMCAsmInfo() {
+ SupportsDebugInformation = true;
AlignmentIsInBytes = false;
- Data16bitsDirective = "\t.half\t";
- Data32bitsDirective = "\t.word\t";
- Data64bitsDirective = 0;
PrivateGlobalPrefix = "$";
- CommentString = "#";
- ZeroDirective = "\t.space\t";
GPRel32Directive = "\t.gpword\t";
- HasSetDirective = false;
}
diff --git a/lib/Target/MBlaze/MBlazeMCInstLower.cpp b/lib/Target/MBlaze/MBlazeMCInstLower.cpp
index 2a48c0dcf1..a7e400b1d1 100644
--- a/lib/Target/MBlaze/MBlazeMCInstLower.cpp
+++ b/lib/Target/MBlaze/MBlazeMCInstLower.cpp
@@ -32,10 +32,8 @@ using namespace llvm;
MCSymbol *MBlazeMCInstLower::
GetGlobalAddressSymbol(const MachineOperand &MO) const {
switch (MO.getTargetFlags()) {
- default:
- llvm_unreachable("Unknown target flag on GV operand");
-
- case 0: break;
+ default: llvm_unreachable("Unknown target flag on GV operand");
+ case 0: break;
}
return Printer.Mang->getSymbol(MO.getGlobal());
@@ -44,10 +42,8 @@ GetGlobalAddressSymbol(const MachineOperand &MO) const {
MCSymbol *MBlazeMCInstLower::
GetExternalSymbolSymbol(const MachineOperand &MO) const {
switch (MO.getTargetFlags()) {
- default:
- assert(0 && "Unknown target flag on GV operand");
-
- case 0: break;
+ default: llvm_unreachable("Unknown target flag on GV operand");
+ case 0: break;
}
return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
@@ -59,12 +55,9 @@ GetJumpTableSymbol(const MachineOperand &MO) const {
raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "JTI"
<< Printer.getFunctionNumber() << '_'
<< MO.getIndex();
-
switch (MO.getTargetFlags()) {
- default:
- llvm_unreachable("Unknown target flag on GV operand");
-
- case 0: break;
+ default: llvm_unreachable("Unknown target flag on GV operand");
+ case 0: break;
}
// Create a symbol for the name.
@@ -129,8 +122,7 @@ void MBlazeMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
MCOperand MCOp;
switch (MO.getType()) {
- default:
- assert(0 && "unknown operand type");
+ default: llvm_unreachable("unknown operand type");
case MachineOperand::MO_Register:
// Ignore all implicit register operands.
if (MO.isImplicit()) continue;
diff --git a/lib/Target/MBlaze/MBlazeRegisterInfo.cpp b/lib/Target/MBlaze/MBlazeRegisterInfo.cpp
index f74eea708b..f8f77f1487 100644
--- a/lib/Target/MBlaze/MBlazeRegisterInfo.cpp
+++ b/lib/Target/MBlaze/MBlazeRegisterInfo.cpp
@@ -242,9 +242,8 @@ unsigned MBlazeRegisterInfo::getEHHandlerRegister() const {
return 0;
}
-int MBlazeRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
- llvm_unreachable("What is the dwarf register number");
- return -1;
+int MBlazeRegisterInfo::getDwarfRegNum(unsigned RegNo, bool isEH) const {
+ return MBlazeGenRegisterInfo::getDwarfRegNumFull(RegNo,0);
}
#include "MBlazeGenRegisterInfo.inc"
diff --git a/lib/Target/MBlaze/MBlazeTargetMachine.cpp b/lib/Target/MBlaze/MBlazeTargetMachine.cpp
index 7b0f9bbfa2..67a35d873c 100644
--- a/lib/Target/MBlaze/MBlazeTargetMachine.cpp
+++ b/lib/Target/MBlaze/MBlazeTargetMachine.cpp
@@ -43,7 +43,7 @@ static MCStreamer *createMCStreamer(const Target &T, const std::string &TT,
case Triple::MinGW64:
case Triple::Cygwin:
case Triple::Win32:
- llvm_unreachable("ARM does not support Windows COFF format");
+ llvm_unreachable("MBlaze does not support Windows COFF format");
return NULL;
default:
return createELFStreamer(Ctx, TAB, _OS, _Emitter, RelaxAll);