From 82dc040d0690059beb060ba6640907fb2a295958 Mon Sep 17 00:00:00 2001 From: Wesley Peck Date: Wed, 24 Nov 2010 15:39:32 +0000 Subject: [PATCH] 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 --- lib/Target/MBlaze/MBlazeAsmPrinter.cpp | 123 ++++++++++++++++++++-- lib/Target/MBlaze/MBlazeMCAsmInfo.cpp | 7 +- lib/Target/MBlaze/MBlazeMCInstLower.cpp | 22 ++-- lib/Target/MBlaze/MBlazeRegisterInfo.cpp | 5 +- lib/Target/MBlaze/MBlazeTargetMachine.cpp | 2 +- 5 files changed, 126 insertions(+), 33 deletions(-) diff --git a/lib/Target/MBlaze/MBlazeAsmPrinter.cpp b/lib/Target/MBlaze/MBlazeAsmPrinter.cpp index 6c206d0debf..e179a236e97 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(); + + // CPU Saved Registers Bitmasks + unsigned int CPUBitmask = 0; + + // Set the CPU Bitmasks + const MachineFrameInfo *MFI = MF->getFrameInfo(); + const std::vector &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 23b82463208..1467141d34a 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 2a48c0dcf16..a7e400b1d1a 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 f74eea708bf..f8f77f1487e 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 7b0f9bbfa29..67a35d873cb 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); -- 2.34.1