Teach the (non-MC) instruction printer to use the cannonical names for push/pop,
[oota-llvm.git] / lib / Target / ARM / ARMAsmPrinter.cpp
index df75ff203dc46888c91389a6245aff82e64be628..cb57dcdead6f9cfad8c588b86c6f8a71571df75d 100644 (file)
@@ -1147,11 +1147,78 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
     OS << ']';
     OS << "+";
     printOperand(MI, NOps-2, OS);
-    OutStreamer.EmitRawText(OS.str());
-    return;
-  }
+  } else if (MI->getOpcode() == ARM::MOVs) {
+    // FIXME: Thumb variants?
+    const MachineOperand &Dst = MI->getOperand(0);
+    const MachineOperand &MO1 = MI->getOperand(1);
+    const MachineOperand &MO2 = MI->getOperand(2);
+    const MachineOperand &MO3 = MI->getOperand(3);
+
+    OS << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()));
+    printSBitModifierOperand(MI, 6, OS);
+    printPredicateOperand(MI, 4, OS);
+
+    OS << '\t' << getRegisterName(Dst.getReg())
+       << ", " << getRegisterName(MO1.getReg());
+
+    if (ARM_AM::getSORegShOp(MO3.getImm()) != ARM_AM::rrx) {
+      OS << ", ";
+
+      if (MO2.getReg()) {
+        OS << getRegisterName(MO2.getReg());
+        assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
+      } else {
+        OS << "#" << ARM_AM::getSORegOffset(MO3.getImm());
+      }
+    }
+  } else
+  // A8.6.123 PUSH
+  if ((MI->getOpcode() == ARM::STM_UPD || MI->getOpcode() == ARM::t2STM_UPD) &&
+      MI->getOperand(0).getReg() == ARM::SP) {
+    const MachineOperand &MO1 = MI->getOperand(2);
+    if (ARM_AM::getAM4SubMode(MO1.getImm()) == ARM_AM::db) {
+      OS << '\t' << "push";
+      printPredicateOperand(MI, 3, OS);
+      OS << '\t';
+      printRegisterList(MI, 5, OS);
+    }
+  } else
+  // A8.6.122 POP
+  if ((MI->getOpcode() == ARM::LDM_UPD || MI->getOpcode() == ARM::t2LDM_UPD) &&
+      MI->getOperand(0).getReg() == ARM::SP) {
+    const MachineOperand &MO1 = MI->getOperand(2);
+    if (ARM_AM::getAM4SubMode(MO1.getImm()) == ARM_AM::ia) {
+      OS << '\t' << "pop";
+      printPredicateOperand(MI, 3, OS);
+      OS << '\t';
+      printRegisterList(MI, 5, OS);
+    }
+  } else
+  // A8.6.355 VPUSH
+  if ((MI->getOpcode() == ARM::VSTMS_UPD || MI->getOpcode() ==ARM::VSTMD_UPD) &&
+      MI->getOperand(0).getReg() == ARM::SP) {
+    const MachineOperand &MO1 = MI->getOperand(2);
+    if (ARM_AM::getAM4SubMode(MO1.getImm()) == ARM_AM::db) {
+      OS << '\t' << "vpush";
+      printPredicateOperand(MI, 3, OS);
+      OS << '\t';
+      printRegisterList(MI, 5, OS);
+    }
+  } else
+  // A8.6.354 VPOP
+  if ((MI->getOpcode() == ARM::VLDMS_UPD || MI->getOpcode() ==ARM::VLDMD_UPD) &&
+      MI->getOperand(0).getReg() == ARM::SP) {
+    const MachineOperand &MO1 = MI->getOperand(2);
+    if (ARM_AM::getAM4SubMode(MO1.getImm()) == ARM_AM::ia) {
+      OS << '\t' << "vpop";
+      printPredicateOperand(MI, 3, OS);
+      OS << '\t';
+      printRegisterList(MI, 5, OS);
+    }
+  } else
+    printInstruction(MI, OS);
 
-  printInstruction(MI, OS);
+  // Output the instruction to the stream
   OutStreamer.EmitRawText(OS.str());
 
   // Make sure the instruction that follows TBB is 2-byte aligned.
@@ -1351,10 +1418,17 @@ void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
     OutStreamer.EmitInstruction(AddInst);
     return;
   }
-  case ARM::PICLDR: {
+  case ARM::PICSTR:
+  case ARM::PICSTRB:
+  case ARM::PICSTRH:
+  case ARM::PICLDR:
+  case ARM::PICLDRB:
+  case ARM::PICLDRH:
+  case ARM::PICLDRSB:
+  case ARM::PICLDRSH: {
     // This is a pseudo op for a label + instruction sequence, which looks like:
     // LPC0:
-    //     ldr r0, [pc, r0]
+    //     OP r0, [pc, r0]
     // The LCP0 label is referenced by a constant pool entry in order to get
     // a PC-relative address at the ldr instruction.
 
@@ -1367,16 +1441,29 @@ void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
     OutStreamer.EmitLabel(Label);
 
     // Form and emit the load
-    MCInst LdrInst;
-    LdrInst.setOpcode(ARM::LDR);
-    LdrInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
-    LdrInst.addOperand(MCOperand::CreateReg(ARM::PC));
-    LdrInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
-    LdrInst.addOperand(MCOperand::CreateImm(0));
+    unsigned Opcode;
+    switch (MI->getOpcode()) {
+    default:
+      llvm_unreachable("Unexpected opcode!");
+    case ARM::PICSTR:   Opcode = ARM::STR; break;
+    case ARM::PICSTRB:  Opcode = ARM::STRB; break;
+    case ARM::PICSTRH:  Opcode = ARM::STRH; break;
+    case ARM::PICLDR:   Opcode = ARM::LDR; break;
+    case ARM::PICLDRB:  Opcode = ARM::LDRB; break;
+    case ARM::PICLDRH:  Opcode = ARM::LDRH; break;
+    case ARM::PICLDRSB: Opcode = ARM::LDRSB; break;
+    case ARM::PICLDRSH: Opcode = ARM::LDRSH; break;
+    }
+    MCInst LdStInst;
+    LdStInst.setOpcode(Opcode);
+    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
+    LdStInst.addOperand(MCOperand::CreateReg(ARM::PC));
+    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
+    LdStInst.addOperand(MCOperand::CreateImm(0));
     // Add predicate operands.
-    LdrInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
-    LdrInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
-    OutStreamer.EmitInstruction(LdrInst);
+    LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
+    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
+    OutStreamer.EmitInstruction(LdStInst);
 
     return;
   }
@@ -1446,7 +1533,7 @@ void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
       V1 = MCOperand::CreateImm(ImmVal & 65535);
       V2 = MCOperand::CreateImm(ImmVal >> 16);
     } else if (MO.isGlobal()) {
-      MCSymbol *Symbol = MCInstLowering.GetGlobalAddressSymbol(MO);
+      MCSymbol *Symbol = MCInstLowering.GetGlobalAddressSymbol(MO.getGlobal());
       const MCSymbolRefExpr *SymRef1 =
         MCSymbolRefExpr::Create(Symbol,
                                 MCSymbolRefExpr::VK_ARM_LO16, OutContext);
@@ -1504,7 +1591,7 @@ static MCInstPrinter *createARMMCInstPrinter(const Target &T,
                                              unsigned SyntaxVariant,
                                              const MCAsmInfo &MAI) {
   if (SyntaxVariant == 0)
-    return new ARMInstPrinter(MAI, false);
+    return new ARMInstPrinter(MAI);
   return 0;
 }