}
virtual std::string getSectionForFunction(const Function &F) const;
+ bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant, const char *ExtraCode);
void printOperand(const MachineInstr *MI, int opNum);
+ void printUnsignedImm(const MachineInstr *MI, int opNum);
void printMemOperand(const MachineInstr *MI, int opNum,
const char *Modifier = 0);
void printFCCOperand(const MachineInstr *MI, int opNum,
const char *Modifier = 0);
void printModuleLevelGV(const GlobalVariable* GVar);
- unsigned int getSavedRegsBitmask(bool isFloat, MachineFunction &MF);
+ void printSavedRegsBitmask(MachineFunction &MF);
void printHex32(unsigned int Value);
const char *emitCurrentABIString(void);
void emitFunctionStart(MachineFunction &MF);
void emitFunctionEnd(MachineFunction &MF);
void emitFrameDirective(MachineFunction &MF);
- void emitMaskDirective(MachineFunction &MF);
- void emitFMaskDirective(MachineFunction &MF);
bool printInstruction(const MachineInstr *MI); // autogenerated.
bool runOnMachineFunction(MachineFunction &F);
// Mask directives
//===----------------------------------------------------------------------===//
-/// Mask directive for GPR
+// 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 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 Floating Point
-void MipsAsmPrinter::
-emitFMaskDirective(MachineFunction &MF)
-{
- unsigned int Bitmask = getSavedRegsBitmask(true, MF);
-
- O << "\t.fmask\t";
- printHex32(Bitmask);
- O << ",0" << '\n';
-}
-
-// 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.
-unsigned int MipsAsmPrinter::
-getSavedRegsBitmask(bool isFloat, MachineFunction &MF)
+printSavedRegsBitmask(MachineFunction &MF)
{
const TargetRegisterInfo &RI = *TM.getRegisterInfo();
+ MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
- // Floating Point Registers, TODO
- if (isFloat)
- return 0;
-
- // CPU Registers
- unsigned int Bitmask = 0;
+ // CPU and FPU Saved Registers Bitmasks
+ unsigned int CPUBitmask = 0;
+ unsigned int FPUBitmask = 0;
+ // Set the CPU and FPU Bitmasks
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()));
+ for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
+ unsigned RegNum = MipsRegisterInfo::getRegisterNumbering(CSI[i].getReg());
+ if (CSI[i].getRegClass() == Mips::CPURegsRegisterClass)
+ CPUBitmask |= (1 << RegNum);
+ else
+ FPUBitmask |= (1 << RegNum);
+ }
+ // Return Address and Frame registers must also be set in CPUBitmask.
if (RI.hasFP(MF))
- Bitmask |= (1 << MipsRegisterInfo::
+ CPUBitmask |= (1 << MipsRegisterInfo::
getRegisterNumbering(RI.getFrameRegister(MF)));
if (MF.getFrameInfo()->hasCalls())
- Bitmask |= (1 << MipsRegisterInfo::
+ CPUBitmask |= (1 << MipsRegisterInfo::
getRegisterNumbering(RI.getRARegister()));
- return Bitmask;
+ // Print CPUBitmask
+ O << "\t.mask \t"; printHex32(CPUBitmask); O << ','
+ << MipsFI->getCPUTopSavedRegOff() << '\n';
+
+ // Print FPUBitmask
+ O << "\t.fmask\t"; printHex32(FPUBitmask); O << ","
+ << MipsFI->getFPUTopSavedRegOff() << '\n';
}
// Print a 32 bit hex number with all numbers.
O << "\t.globl\t" << CurrentFnName << '\n';
O << "\t.ent\t" << CurrentFnName << '\n';
+ printVisibility(CurrentFnName, F->getVisibility());
+
if ((TAI->hasDotTypeDotSizeDirective()) && Subtarget->isLinux())
O << "\t.type\t" << CurrentFnName << ", @function\n";
O << CurrentFnName << ":\n";
emitFrameDirective(MF);
- emitMaskDirective(MF);
- emitFMaskDirective(MF);
+ printSavedRegsBitmask(MF);
O << '\n';
}
return false;
}
+// Print out an operand for an inline asm expression.
+bool MipsAsmPrinter::
+PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant, const char *ExtraCode)
+{
+ // Does this asm operand have a single letter operand modifier?
+ if (ExtraCode && ExtraCode[0])
+ return true; // Unknown modifier.
+
+ printOperand(MI, OpNo);
+ return false;
+}
+
void MipsAsmPrinter::
printOperand(const MachineInstr *MI, int opNum)
{
break;
case MachineOperand::MO_Immediate:
- if ((MI->getOpcode() == Mips::SLTiu) || (MI->getOpcode() == Mips::ORi) ||
- (MI->getOpcode() == Mips::LUi) || (MI->getOpcode() == Mips::ANDi))
- O << (unsigned short int)MO.getImm();
- else
- O << (short int)MO.getImm();
+ O << (short int)MO.getImm();
break;
case MachineOperand::MO_MachineBasicBlock:
<< '_' << MO.getIndex();
break;
- // FIXME: Verify correct
case MachineOperand::MO_ConstantPoolIndex:
O << TAI->getPrivateGlobalPrefix() << "CPI"
<< getFunctionNumber() << "_" << MO.getIndex();
if (closeP) O << ")";
}
+void MipsAsmPrinter::
+printUnsignedImm(const MachineInstr *MI, int opNum)
+{
+ const MachineOperand &MO = MI->getOperand(opNum);
+ if (MO.getType() == MachineOperand::MO_Immediate)
+ O << (unsigned short int)MO.getImm();
+ else
+ printOperand(MI, opNum);
+}
+
void MipsAsmPrinter::
printMemOperand(const MachineInstr *MI, int opNum, const char *Modifier)
{
} else
Align = TD->getPreferredTypeAlignmentShift(CTy);
- // FIXME: ELF supports visibility
+ printVisibility(name, GVar->getVisibility());
SwitchToDataSection(SectionName.c_str());
if (GVar->hasInternalLinkage())
O << "\t.local\t" << name << '\n';
-
+
O << TAI->getCOMMDirective() << name << ',' << Size;
if (TAI->getCOMMDirectiveTakesAlignment())
O << ',' << (1 << Align);
// Fall Through
case GlobalValue::InternalLinkage:
if (CVA && CVA->isCString())
- printSizeAndType = false;
+ printSizeAndType = false;
break;
case GlobalValue::GhostLinkage:
cerr << "Should not have any unmaterialized functions!\n";
assert(0 && "Unknown linkage type!");
}
- if (Align)
- O << "\t.align " << Align << '\n';
+ EmitAlignment(Align, GVar);
if (TAI->hasDotTypeDotSizeDirective() && printSizeAndType) {
O << "\t.type " << name << ",@object\n";