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
This commit is contained in:
Bruno Cardoso Lopes 2007-08-28 05:06:17 +00:00
parent 2d4575ea5a
commit dc0c04c0ed
2 changed files with 114 additions and 76 deletions

View File

@ -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<MipsFunctionInfo>();
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<MipsFunctionInfo>();
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<CalleeSavedInfo> &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";

View File

@ -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,