mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-25 04:39:44 +00:00
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:
parent
2d4575ea5a
commit
dc0c04c0ed
@ -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";
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user