Do not use '&' prefix for globals when register base field is non-zero, otherwise msp430-as will silently miscompile the code (TI's assembler report an error though).

This fixes PR6349

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97877 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp b/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
index def5fc6..7a35eb0 100644
--- a/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
+++ b/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
@@ -98,12 +98,19 @@
     bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
     uint64_t Offset = MO.getOffset();
 
-    O << (isMemOp ? '&' : '#');
+    // If the global address expression is a part of displacement field with a
+    // register base, we should not emit any prefix symbol here, e.g.
+    //   mov.w &foo, r1
+    // vs
+    //   mov.w glb(r1), r2
+    // Otherwise (!) msp430-as will silently miscompile the output :(
+    if (!Modifier || strcmp(Modifier, "nohash"))
+      O << (isMemOp ? '&' : '#');
     if (Offset)
       O << '(' << Offset << '+';
 
     O << *GetGlobalValueSymbol(MO.getGlobal());
-    
+
     if (Offset)
       O << ')';
 
@@ -124,15 +131,11 @@
   const MachineOperand &Disp = MI->getOperand(OpNum+1);
 
   // Print displacement first
-  if (!Disp.isImm()) {
-    printOperand(MI, OpNum+1, "mem");
-  } else {
-    if (!Base.getReg())
-      O << '&';
 
-    printOperand(MI, OpNum+1, "nohash");
-  }
-
+  // Imm here is in fact global address - print extra modifier.
+  if (Disp.isImm() && !Base.getReg())
+    O << '&';
+  printOperand(MI, OpNum+1, "nohash");
 
   // Print register base field
   if (Base.getReg()) {
diff --git a/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp b/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp
index f6565bd..d7636e6 100644
--- a/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp
+++ b/lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp
@@ -62,21 +62,26 @@
   const MCOperand &Disp = MI->getOperand(OpNo+1);
 
   // Print displacement first
-  if (Disp.isExpr()) {
-    O << '&' << *Disp.getExpr();
-  } else {
-    assert(Disp.isImm() && "Expected immediate in displacement field");
-    if (!Base.getReg())
-      O << '&';
 
+  // If the global address expression is a part of displacement field with a
+  // register base, we should not emit any prefix symbol here, e.g.
+  //   mov.w &foo, r1
+  // vs
+  //   mov.w glb(r1), r2
+  // Otherwise (!) msp430-as will silently miscompile the output :(
+  if (!Base.getReg())
+    O << '&';
+
+  if (Disp.isExpr())
+    O << *Disp.getExpr();
+  else {
+    assert(Disp.isImm() && "Expected immediate in displacement field");
     O << Disp.getImm();
   }
 
-
   // Print register base field
-  if (Base.getReg()) {
+  if (Base.getReg())
     O << '(' << getRegisterName(Base.getReg()) << ')';
-  }
 }
 
 void MSP430InstPrinter::printCCOperand(const MCInst *MI, unsigned OpNo) {
diff --git a/test/CodeGen/MSP430/AddrMode-bis-rx.ll b/test/CodeGen/MSP430/AddrMode-bis-rx.ll
index 115464d..4f9a724 100644
--- a/test/CodeGen/MSP430/AddrMode-bis-rx.ll
+++ b/test/CodeGen/MSP430/AddrMode-bis-rx.ll
@@ -29,7 +29,7 @@
 	ret i8 %3
 }
 ; CHECK: am3:
-; CHECK:		bis.b	&bar(r14), r15
+; CHECK:		bis.b	bar(r14), r15
 
 define i16 @am4(i16 %x) nounwind {
 	%1 = volatile load i16* inttoptr(i16 32 to i16*)
@@ -70,5 +70,5 @@
 	ret i8 %4
 }
 ; CHECK: am7:
-; CHECK:		bis.b	&duh+2(r14), r15
+; CHECK:		bis.b	duh+2(r14), r15
 
diff --git a/test/CodeGen/MSP430/AddrMode-bis-xr.ll b/test/CodeGen/MSP430/AddrMode-bis-xr.ll
index 3baf332..17ebd87 100644
--- a/test/CodeGen/MSP430/AddrMode-bis-xr.ll
+++ b/test/CodeGen/MSP430/AddrMode-bis-xr.ll
@@ -32,7 +32,7 @@
 	ret void
 }
 ; CHECK: am3:
-; CHECK:		bis.b	r14, &bar(r15)
+; CHECK:		bis.b	r14, bar(r15)
 
 define void @am4(i16 %x) nounwind {
 	%1 = volatile load i16* inttoptr(i16 32 to i16*)
@@ -77,5 +77,5 @@
 	ret void
 }
 ; CHECK: am7:
-; CHECK:		bis.b	r14, &duh+2(r15)
+; CHECK:		bis.b	r14, duh+2(r15)
 
diff --git a/test/CodeGen/MSP430/AddrMode-mov-rx.ll b/test/CodeGen/MSP430/AddrMode-mov-rx.ll
index 9144f9a..6676b88 100644
--- a/test/CodeGen/MSP430/AddrMode-mov-rx.ll
+++ b/test/CodeGen/MSP430/AddrMode-mov-rx.ll
@@ -26,7 +26,7 @@
 	ret i8 %2
 }
 ; CHECK: am3:
-; CHECK:		mov.b	&bar(r15), r15
+; CHECK:		mov.b	bar(r15), r15
 
 define i16 @am4() nounwind {
 	%1 = volatile load i16* inttoptr(i16 32 to i16*)
@@ -63,5 +63,5 @@
 	ret i8 %3
 }
 ; CHECK: am7:
-; CHECK:		mov.b	&duh+2(r15), r15
+; CHECK:		mov.b	duh+2(r15), r15
 
diff --git a/test/CodeGen/MSP430/AddrMode-mov-xr.ll b/test/CodeGen/MSP430/AddrMode-mov-xr.ll
index 333c800..4b327b0 100644
--- a/test/CodeGen/MSP430/AddrMode-mov-xr.ll
+++ b/test/CodeGen/MSP430/AddrMode-mov-xr.ll
@@ -26,7 +26,7 @@
 	ret void
 }
 ; CHECK: am3:
-; CHECK:		mov.b	r14, &bar(r15)
+; CHECK:		mov.b	r14, bar(r15)
 
 define void @am4(i16 %a) nounwind {
 	volatile store i16 %a, i16* inttoptr(i16 32 to i16*)
@@ -63,5 +63,5 @@
 	ret void
 }
 ; CHECK: am7:
-; CHECK:		mov.b	r14, &duh+2(r15)
+; CHECK:		mov.b	r14, duh+2(r15)