aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/Mips/MipsAsmPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/Mips/MipsAsmPrinter.cpp')
-rw-r--r--lib/Target/Mips/MipsAsmPrinter.cpp80
1 files changed, 55 insertions, 25 deletions
diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp
index 1fb75a2..832fa05 100644
--- a/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -58,10 +58,12 @@ MipsTargetStreamer &MipsAsmPrinter::getTargetStreamer() {
}
bool MipsAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
+ Subtarget = &TM.getSubtarget<MipsSubtarget>();
+
// Initialize TargetLoweringObjectFile.
- if (Subtarget->allowMixed16_32())
- const_cast<TargetLoweringObjectFile&>(getObjFileLowering())
+ const_cast<TargetLoweringObjectFile &>(getObjFileLowering())
.Initialize(OutContext, TM);
+
MipsFI = MF.getInfo<MipsFunctionInfo>();
if (Subtarget->inMips16Mode())
for (std::map<
@@ -129,7 +131,7 @@ void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer,
void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
MipsTargetStreamer &TS = getTargetStreamer();
- TS.setCanHaveModuleDir(false);
+ TS.forbidModuleDirective();
if (MI->isDebugValue()) {
SmallString<128> Str;
@@ -264,7 +266,8 @@ void MipsAsmPrinter::printSavedRegsBitmask() {
if (Mips::GPR32RegClass.contains(Reg))
break;
- unsigned RegNum = TM.getRegisterInfo()->getEncodingValue(Reg);
+ unsigned RegNum =
+ TM.getSubtargetImpl()->getRegisterInfo()->getEncodingValue(Reg);
if (Mips::AFGR64RegClass.contains(Reg)) {
FPUBitmask |= (3 << RegNum);
CSFPRegsSize += AFGR64RegSize;
@@ -279,7 +282,8 @@ void MipsAsmPrinter::printSavedRegsBitmask() {
// Set CPU Bitmask.
for (; i != e; ++i) {
unsigned Reg = CSI[i].getReg();
- unsigned RegNum = TM.getRegisterInfo()->getEncodingValue(Reg);
+ unsigned RegNum =
+ TM.getSubtargetImpl()->getRegisterInfo()->getEncodingValue(Reg);
CPUBitmask |= (1 << RegNum);
}
@@ -304,7 +308,7 @@ void MipsAsmPrinter::printSavedRegsBitmask() {
/// Frame Directive
void MipsAsmPrinter::emitFrameDirective() {
- const TargetRegisterInfo &RI = *TM.getRegisterInfo();
+ const TargetRegisterInfo &RI = *TM.getSubtargetImpl()->getRegisterInfo();
unsigned stackReg = RI.getFrameRegister(*MF);
unsigned returnReg = RI.getRARegister();
@@ -315,11 +319,11 @@ void MipsAsmPrinter::emitFrameDirective() {
/// Emit Set directives.
const char *MipsAsmPrinter::getCurrentABIString() const {
- switch (Subtarget->getTargetABI()) {
- case MipsSubtarget::O32: return "abi32";
- case MipsSubtarget::N32: return "abiN32";
- case MipsSubtarget::N64: return "abi64";
- case MipsSubtarget::EABI: return "eabi32"; // TODO: handle eabi64
+ switch (Subtarget->getABI().GetEnumValue()) {
+ case MipsABIInfo::ABI::O32: return "abi32";
+ case MipsABIInfo::ABI::N32: return "abiN32";
+ case MipsABIInfo::ABI::N64: return "abi64";
+ case MipsABIInfo::ABI::EABI: return "eabi32"; // TODO: handle eabi64
default: llvm_unreachable("Unknown Mips ABI");
}
}
@@ -469,14 +473,12 @@ bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
return false;
case 'z': {
// $0 if zero, regular printing otherwise
- if (MO.getType() != MachineOperand::MO_Immediate)
- return true;
- int64_t Val = MO.getImm();
- if (Val)
- O << Val;
- else
+ if (MO.getType() == MachineOperand::MO_Immediate && MO.getImm() == 0) {
O << "$0";
- return false;
+ return false;
+ }
+ // If not, call printOperand as normal.
+ break;
}
case 'D': // Second part of a double word register operand
case 'L': // Low order register of a double word register operand
@@ -558,7 +560,7 @@ bool MipsAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
void MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
raw_ostream &O) {
- const DataLayout *DL = TM.getDataLayout();
+ const DataLayout *DL = TM.getSubtargetImpl()->getDataLayout();
const MachineOperand &MO = MI->getOperand(opNum);
bool closeP = false;
@@ -643,6 +645,18 @@ printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O) {
// Load/Store memory operands -- imm($reg)
// If PIC target the target is loaded as the
// pattern lw $25,%call16($28)
+
+ // opNum can be invalid if instruction has reglist as operand.
+ // MemOperand is always last operand of instruction (base + offset).
+ switch (MI->getOpcode()) {
+ default:
+ break;
+ case Mips::SWM32_MM:
+ case Mips::LWM32_MM:
+ opNum = MI->getNumOperands() - 2;
+ break;
+ }
+
printOperand(MI, opNum+1, O);
O << "(";
printOperand(MI, opNum, O);
@@ -666,13 +680,19 @@ printFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
O << Mips::MipsFCCToString((Mips::CondCode)MO.getImm());
}
+void MipsAsmPrinter::
+printRegisterList(const MachineInstr *MI, int opNum, raw_ostream &O) {
+ for (int i = opNum, e = MI->getNumOperands(); i != e; ++i) {
+ if (i != opNum) O << ", ";
+ printOperand(MI, i, O);
+ }
+}
+
void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) {
- // TODO: Need to add -mabicalls and -mno-abicalls flags.
- // Currently we assume that -mabicalls is the default.
- bool IsABICalls = true;
+ bool IsABICalls = Subtarget->isABICalls();
if (IsABICalls) {
getTargetStreamer().emitDirectiveAbiCalls();
- Reloc::Model RM = Subtarget->getRelocationModel();
+ Reloc::Model RM = TM.getRelocationModel();
// FIXME: This condition should be a lot more complicated that it is here.
// Ideally it should test for properties of the ABI and not the ABI
// itself.
@@ -706,9 +726,19 @@ void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) {
}
getTargetStreamer().updateABIInfo(*Subtarget);
- getTargetStreamer().emitDirectiveModuleFP();
- if (Subtarget->isABI_O32())
+ // We should always emit a '.module fp=...' but binutils 2.24 does not accept
+ // it. We therefore emit it when it contradicts the ABI defaults (-mfpxx or
+ // -mfp64) and omit it otherwise.
+ if (Subtarget->isABI_O32() && (Subtarget->isABI_FPXX() ||
+ Subtarget->isFP64bit()))
+ getTargetStreamer().emitDirectiveModuleFP();
+
+ // We should always emit a '.module [no]oddspreg' but binutils 2.24 does not
+ // accept it. We therefore emit it when it contradicts the default or an
+ // option has changed the default (i.e. FPXX) and omit it otherwise.
+ if (Subtarget->isABI_O32() && (!Subtarget->useOddSPReg() ||
+ Subtarget->isABI_FPXX()))
getTargetStreamer().emitDirectiveModuleOddSPReg(Subtarget->useOddSPReg(),
Subtarget->isABI_O32());
}