From dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988d Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes Date: Tue, 28 Aug 2007 05:06:17 +0000 Subject: [PATCH] Mask directive completed with CalleeSave info Comments for Mips directives added. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41526 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsAsmPrinter.cpp | 187 +++++++++++++++++------------ lib/Target/Mips/MipsInstrInfo.h | 3 +- 2 files changed, 114 insertions(+), 76 deletions(-) diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp index 48879ee3e38..11db54753c1 100644 --- a/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/lib/Target/Mips/MipsAsmPrinter.cpp @@ -31,6 +31,7 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Support/Mangler.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/Debug.h" #include "llvm/Support/CommandLine.h" @@ -62,12 +63,14 @@ namespace { void printMemOperand(const MachineInstr *MI, int opNum, const char *Modifier = 0); + unsigned int getSavedRegsBitmask(bool isFloat, MachineFunction &MF); void printHex32(unsigned int Value); + void emitFunctionStart(MachineFunction &MF); void emitFunctionEnd(); void emitFrameDirective(MachineFunction &MF); void emitMaskDirective(MachineFunction &MF); - void emitFMaskDirective(); + void emitFMaskDirective(MachineFunction &MF); void emitSetDirective(SetDirectiveFlags Flag); bool printInstruction(const MachineInstr *MI); // autogenerated. @@ -89,12 +92,72 @@ FunctionPass *llvm::createMipsCodePrinterPass(std::ostream &o, return new MipsAsmPrinter(o, tm, tm.getTargetAsmInfo()); } -/// This pattern will be emitted : -/// .frame reg1, size, reg2 -/// It describes the stack frame. -/// reg1 - stack pointer -/// size - stack size allocated for the function -/// reg2 - return address register +//===----------------------------------------------------------------------===// +// +// Mips Asm Directives +// +// -- Frame directive "frame Stackpointer, Stacksize, RARegister" +// Describe the stack frame. +// +// -- Mask directives "(f)mask bitmask, offset" +// Tells the assembler which registers are saved and where. +// bitmask - contain a little endian bitset indicating which registers are +// saved on function prologue (e.g. with a 0x80000000 mask, the +// assembler knows the register 31 (RA) is saved at prologue. +// offset - the position before stack pointer subtraction indicating where +// the first saved register on prologue is located. (e.g. with a +// +// Consider the following function prologue: +// +// .frame $fp,48,$ra +// .mask 0xc0000000,-8 +// addiu $sp, $sp, -48 +// sw $ra, 40($sp) +// sw $fp, 36($sp) +// +// With a 0xc0000000 mask, the assembler knows the register 31 (RA) and +// 30 (FP) are saved at prologue. As the save order on prologue is from +// left to right, RA is saved first. A -8 offset means that after the +// stack pointer subtration, the first register in the mask (RA) will be +// saved at address 48-8=40. +// +//===----------------------------------------------------------------------===// + +/// Mask directive for GPR +void MipsAsmPrinter:: +emitMaskDirective(MachineFunction &MF) +{ + MipsFunctionInfo *MipsFI = MF.getInfo(); + + int StackSize = MF.getFrameInfo()->getStackSize(); + int Offset = (!MipsFI->getTopSavedRegOffset()) ? 0 : + (-(StackSize-MipsFI->getTopSavedRegOffset())); + + #ifndef NDEBUG + DOUT << "--> emitMaskDirective" << "\n"; + DOUT << "StackSize : " << StackSize << "\n"; + DOUT << "getTopSavedReg : " << MipsFI->getTopSavedRegOffset() << "\n"; + DOUT << "Offset : " << Offset << "\n\n"; + #endif + + unsigned int Bitmask = getSavedRegsBitmask(false, MF); + O << "\t.mask\t"; + printHex32(Bitmask); + O << "," << Offset << "\n"; +} + +/// TODO: Mask Directive for Float Point +void MipsAsmPrinter:: +emitFMaskDirective(MachineFunction &MF) +{ + unsigned int Bitmask = getSavedRegsBitmask(true, MF); + + O << "\t.fmask\t"; + printHex32(Bitmask); + O << ",0" << "\n"; +} + +/// Frame Directive void MipsAsmPrinter:: emitFrameDirective(MachineFunction &MF) { @@ -111,74 +174,10 @@ emitFrameDirective(MachineFunction &MF) << "\n"; } -/// This pattern will be emitted : -/// .mask bitmask, offset -/// Tells the assembler (and possibly linker) which registers are saved and where. -/// bitmask - mask of all GPRs (little endian) -/// offset - negative value. offset+stackSize should give where on the stack -/// the first GPR is saved. -/// TODO: consider calle saved GPR regs here, not hardcode register numbers. -void MipsAsmPrinter:: -emitMaskDirective(MachineFunction &MF) -{ - const MRegisterInfo &RI = *TM.getRegisterInfo(); - MipsFunctionInfo *MipsFI = MF.getInfo(); - - bool hasFP = RI.hasFP(MF); - bool saveRA = MF.getFrameInfo()->hasCalls(); - - int offset; - - if (!MipsFI->getTopSavedRegOffset()) - offset = 0; - else - offset = -(MF.getFrameInfo()->getStackSize() - -MipsFI->getTopSavedRegOffset()); - - #ifndef NDEBUG - DOUT << "<--ASM PRINTER--emitMaskDirective-->" << "\n"; - DOUT << "StackSize : " << MF.getFrameInfo()->getStackSize() << "\n"; - DOUT << "getTopSavedRegOffset() : " << MipsFI->getTopSavedRegOffset() << "\n"; - DOUT << "offset : " << offset << "\n\n"; - #endif - - unsigned int bitmask = 0; - - if (hasFP) - bitmask |= (1 << 30); - - if (saveRA) - bitmask |= (1 << 31); - - O << "\t.mask\t"; - printHex32(bitmask); - O << "," << offset << "\n"; -} - -/// This pattern will be emitted : -/// .fmask bitmask, offset -/// Tells the assembler (and possibly linker) which float registers are saved. -/// bitmask - mask of all Float Point registers (little endian) -/// offset - negative value. offset+stackSize should give where on the stack -/// the first Float Point register is saved. -/// TODO: implement this, dummy for now -void MipsAsmPrinter:: -emitFMaskDirective() -{ - O << "\t.fmask\t0x00000000,0" << "\n"; -} - -/// Print a 32 bit hex number filling with 0's on the left. -/// TODO: make this setfill and setw -void MipsAsmPrinter:: -printHex32(unsigned int Value) { - O << "0x" << std::hex << Value << std::dec; -} - /// Emit Set directives. void MipsAsmPrinter:: -emitSetDirective(SetDirectiveFlags Flag) { - +emitSetDirective(SetDirectiveFlags Flag) +{ O << "\t.set\t"; switch(Flag) { case REORDER: O << "reorder" << "\n"; break; @@ -187,6 +186,45 @@ emitSetDirective(SetDirectiveFlags Flag) { case NOMACRO: O << "nomacro" << "\n"; break; default: break; } +} + +// Create a bitmask with all callee saved registers for CPU +// or Float Point registers. For CPU registers consider RA, +// GP and FP for saving if necessary. +unsigned int MipsAsmPrinter:: +getSavedRegsBitmask(bool isFloat, MachineFunction &MF) +{ + const MRegisterInfo &RI = *TM.getRegisterInfo(); + + // Float Point Registers, TODO + if (isFloat) + return 0; + + // CPU Registers + unsigned int Bitmask = 0; + + MachineFrameInfo *MFI = MF.getFrameInfo(); + const std::vector &CSI = MFI->getCalleeSavedInfo(); + for (unsigned i = 0, e = CSI.size(); i != e; ++i) + Bitmask |= (1 << MipsRegisterInfo::getRegisterNumbering(CSI[i].getReg())); + + if (RI.hasFP(MF)) + Bitmask |= (1 << MipsRegisterInfo::getRegisterNumbering(RI.getFrameRegister(MF))); + + if (MF.getFrameInfo()->hasCalls()) + Bitmask |= (1 << MipsRegisterInfo::getRegisterNumbering(RI.getRARegister())); + + return Bitmask; +} + +// Print a 32 bit hex number with all numbers. +void MipsAsmPrinter:: +printHex32(unsigned int Value) +{ + O << "0x" << std::hex; + for (int i = 7; i >= 0; i--) + O << std::hex << ( (Value & (0xF << (i*4))) >> (i*4) ); + O << std::dec; } /// Emit the directives used by GAS on the start of functions @@ -208,7 +246,7 @@ emitFunctionStart(MachineFunction &MF) emitFrameDirective(MF); emitMaskDirective(MF); - emitFMaskDirective(); + emitFMaskDirective(MF); emitSetDirective(NOREORDER); emitSetDirective(NOMACRO); O << "\n"; @@ -420,6 +458,7 @@ doFinalization(Module &M) default: assert(0 && "Unknown linkage type!"); } + O << "\t.align " << Align << "\n"; O << "\t.type " << name << ",@object\n"; O << "\t.size " << name << "," << Size << "\n"; diff --git a/lib/Target/Mips/MipsInstrInfo.h b/lib/Target/Mips/MipsInstrInfo.h index b120f232564..f86f1931185 100644 --- a/lib/Target/Mips/MipsInstrInfo.h +++ b/lib/Target/Mips/MipsInstrInfo.h @@ -22,8 +22,7 @@ namespace llvm { namespace Mips { - // All CC branch operations on Mips I are turned - // into BEQ and BNE CC branches instructions. + // Mips Condition Codes enum CondCode { COND_E, COND_GZ,