When printing Thumb1 NOP ('mov r8, r8'), make sure to print the predicate.
[oota-llvm.git] / lib / Target / Mips / MipsAsmPrinter.cpp
index 4013d6c1100e7ff5ec3fef8f8c0f779452e02352..c617918e742b6e9ba55246adf38bf7f5dbcf7f7a 100644 (file)
@@ -18,6 +18,7 @@
 #include "MipsInstrInfo.h"
 #include "MipsMachineFunction.h"
 #include "MipsMCInstLower.h"
+#include "MipsMCSymbolRefExpr.h"
 #include "InstPrinter/MipsInstPrinter.h"
 #include "llvm/BasicBlock.h"
 #include "llvm/Instructions.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetOptions.h"
-#include "llvm/Target/TargetRegistry.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/Twine.h"
+#include "llvm/Support/TargetRegistry.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Analysis/DebugInfo.h"
 
@@ -53,22 +55,50 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
   }
 
   MipsMCInstLower MCInstLowering(Mang, *MF, *this);
+  unsigned Opc = MI->getOpcode();
+
+  // If target is Mips1, expand double precision load/store to two single
+  // precision loads/stores (and delay slot if MI is a load).
+  if (Subtarget->isMips1() && (Opc == Mips::LDC1 || Opc == Mips::SDC1)) {
+    SmallVector<MCInst, 4> MCInsts;
+    const unsigned* SubReg = 
+      TM.getRegisterInfo()->getSubRegisters(MI->getOperand(0).getReg());
+    MCInstLowering.LowerMips1F64LoadStore(MI, Opc, MCInsts,
+                                          Subtarget->isLittle(), SubReg);
+    
+    for (SmallVector<MCInst, 4>::iterator I = MCInsts.begin();
+         I != MCInsts.end(); ++I)
+      OutStreamer.EmitInstruction(*I);
+
+    return;
+  }
+
   MCInst TmpInst0;
   MCInstLowering.Lower(MI, TmpInst0);
-  unsigned Opc = MI->getOpcode();
   
   // Convert aligned loads/stores to their unaligned counterparts.
-  // FIXME: expand other unaligned memory accesses too.
-  if ((Opc == Mips::LW || Opc == Mips::SW) && !MI->memoperands_empty() &&
-      (*MI->memoperands_begin())->getAlignment() < 4) {
-    MCInst Directive;
-    Directive.setOpcode(Mips::MACRO);
-    OutStreamer.EmitInstruction(Directive);
-    TmpInst0.setOpcode(Opc == Mips::LW ? Mips::ULW : Mips::USW);
-    OutStreamer.EmitInstruction(TmpInst0);
-    Directive.setOpcode(Mips::NOMACRO);
-    OutStreamer.EmitInstruction(Directive);
-    return;
+  if (!MI->memoperands_empty()) {
+    unsigned NaturalAlignment, UnalignedOpc;
+    
+    switch (Opc) {
+    case Mips::LW:  NaturalAlignment = 4; UnalignedOpc = Mips::ULW;  break;
+    case Mips::SW:  NaturalAlignment = 4; UnalignedOpc = Mips::USW;  break;
+    case Mips::LH:  NaturalAlignment = 2; UnalignedOpc = Mips::ULH;  break;
+    case Mips::LHu: NaturalAlignment = 2; UnalignedOpc = Mips::ULHu; break;
+    case Mips::SH:  NaturalAlignment = 2; UnalignedOpc = Mips::USH;  break;
+    default:        NaturalAlignment = 0;
+    }
+
+    if ((*MI->memoperands_begin())->getAlignment() < NaturalAlignment) {
+      MCInst Directive;
+      Directive.setOpcode(Mips::MACRO);
+      OutStreamer.EmitInstruction(Directive);
+      TmpInst0.setOpcode(UnalignedOpc);
+      OutStreamer.EmitInstruction(TmpInst0);
+      Directive.setOpcode(Mips::NOMACRO);
+      OutStreamer.EmitInstruction(Directive);
+      return;
+    }
   }
 
   OutStreamer.EmitInstruction(TmpInst0);