Correct asmprinting of memory operands
[oota-llvm.git] / lib / Target / MSP430 / MSP430AsmPrinter.cpp
index e8004a7d1b42c592bbf10711911247a7b24a6431..fb642835c12e4ae5936648c54c0e34aa6e36f8ef 100644 (file)
@@ -47,7 +47,10 @@ namespace {
       return "MSP430 Assembly Printer";
     }
 
-    void printOperand(const MachineInstr *MI, int OpNum);
+    void printOperand(const MachineInstr *MI, int OpNum,
+                      const char* Modifier = 0);
+    void printSrcMemOperand(const MachineInstr *MI, int OpNum,
+                            const char* Modifier = 0);
     bool printInstruction(const MachineInstr *MI);  // autogenerated.
     void printMachineInstruction(const MachineInstr * MI);
     bool runOnMachineFunction(MachineFunction &F);
@@ -119,22 +122,63 @@ void MSP430AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
   assert(0 && "Should not happen");
 }
 
-void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum) {
+void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
+                                    const char* Modifier) {
   const MachineOperand &MO = MI->getOperand(OpNum);
   switch (MO.getType()) {
   case MachineOperand::MO_Register:
-    if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
-      O << TM.getRegisterInfo()->get(MO.getReg()).AsmName;
-    else
-      assert(0 && "not implemented");
-    break;
+    assert (TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
+            "Virtual registers should be already mapped!");
+    O << TM.getRegisterInfo()->get(MO.getReg()).AsmName;
+    return;
   case MachineOperand::MO_Immediate:
-     O << "#" << MO.getImm();
-    break;
+    if (!Modifier || strcmp(Modifier, "nohash"))
+      O << '#';
+    O << MO.getImm();
+    return;
   case MachineOperand::MO_MachineBasicBlock:
     printBasicBlockLabel(MO.getMBB());
-    break;
+    return;
+  case MachineOperand::MO_GlobalAddress: {
+    bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
+    bool isCallOp = Modifier && !strcmp(Modifier, "call");
+    std::string Name = Mang->getValueName(MO.getGlobal());
+    assert(MO.getOffset() == 0 && "No offsets allowed!");
+
+    if (isCallOp)
+      O << '#';
+    else if (isMemOp)
+      O << '&';
+
+    O << Name;
+
+    return;
+  }
   default:
     assert(0 && "Not implemented yet!");
   }
 }
+
+void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum,
+                                          const char* Modifier) {
+  const MachineOperand &Disp = MI->getOperand(OpNum);
+  const MachineOperand &Base = MI->getOperand(OpNum+1);
+
+  if (Disp.isGlobal())
+    printOperand(MI, OpNum, "mem");
+  else if (Disp.isImm() && !Base.getReg())
+    printOperand(MI, OpNum);
+  else if (Base.getReg()) {
+    if (Disp.getImm()) {
+      printOperand(MI, OpNum, "nohash");
+      O << '(';
+      printOperand(MI, OpNum + 1);
+      O << ')';
+    } else {
+      O << '@';
+      printOperand(MI, OpNum + 1);
+    }
+  } else
+    assert(0 && "Unsupported memory operand");
+}
+