//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "mips-asm-printer"
-#include "MipsAsmPrinter.h"
#include "Mips.h"
+#include "MipsAsmPrinter.h"
#include "MipsInstrInfo.h"
+#include "MipsMCInstLower.h"
#include "InstPrinter/MipsInstPrinter.h"
#include "MCTargetDesc/MipsBaseInfo.h"
#include "llvm/ADT/SmallString.h"
do {
MCInst TmpInst0;
+
+ // Direct object specific instruction lowering
+ if (!OutStreamer.hasRawTextSupport())
+ switch (I->getOpcode()) {
+ // If shift amount is >= 32 it the inst needs to be lowered further
+ case Mips::DSLL:
+ case Mips::DSRL:
+ case Mips::DSRA:
+ {
+ assert(I->getNumOperands() == 3 &&
+ "Invalid no. of machine operands for shift!");
+ assert(I->getOperand(2).isImm());
+ int64_t Shift = I->getOperand(2).getImm();
+ if (Shift > 31) {
+ MCInst TmpInst0;
+ MCInstLowering.LowerLargeShift(I, TmpInst0, Shift - 32);
+ OutStreamer.EmitInstruction(TmpInst0);
+ return;
+ }
+ }
+ break;
+ // Double extract instruction is chosen by pos and size operands
+ case Mips::DEXT:
+ case Mips::DINS:
+ assert(Subtarget->hasMips64() && "DEXT/DINS are MIPS64 instructions");
+ {
+ MCInst TmpInst0;
+ MCInstLowering.LowerDextDins(I, TmpInst0);
+ OutStreamer.EmitInstruction(TmpInst0);
+ return;
+ }
+ }
+
MCInstLowering.Lower(I++, TmpInst0);
OutStreamer.EmitInstruction(TmpInst0);
- } while ((I != E) && I->isInsideBundle());
+
+ } while ((I != E) && I->isInsideBundle()); // Delay slot check
}
//===----------------------------------------------------------------------===//
O << "$0";
return false;
}
- case 'D': {
- // Second part of a double word register operand
+ case 'D': // Second part of a double word register operand
+ case 'L': // Low order register of a double word register operand
+ case 'M': // High order register of a double word register operand
+ {
if (OpNum == 0)
return true;
const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1);
}
return true;
}
- unsigned RegOp;
- switch(ExtraCode[0]) {
- case 'D':
- RegOp = (!Subtarget->isGP32bit()) ? OpNum : OpNum + 1;
- break;
+
+ unsigned RegOp = OpNum;
+ if (!Subtarget->isGP64bit()){
+ // Endianess reverses which register holds the high or low value
+ // between M and L.
+ switch(ExtraCode[0]) {
+ case 'M':
+ RegOp = (Subtarget->isLittle()) ? OpNum + 1 : OpNum;
+ break;
+ case 'L':
+ RegOp = (Subtarget->isLittle()) ? OpNum : OpNum + 1;
+ break;
+ case 'D': // Always the second part
+ RegOp = OpNum + 1;
+ }
+ if (RegOp >= MI->getNumOperands())
+ return true;
+ const MachineOperand &MO = MI->getOperand(RegOp);
+ if (!MO.isReg())
+ return true;
+ unsigned Reg = MO.getReg();
+ O << '$' << MipsInstPrinter::getRegisterName(Reg);
+ return false;
}
- if (RegOp >= MI->getNumOperands())
- return true;
- const MachineOperand &MO = MI->getOperand(RegOp);
- if (!MO.isReg())
- return true;
- unsigned Reg = MO.getReg();
- O << '$' << MipsInstPrinter::getRegisterName(Reg);
- return false;
}
}
}