Do not use '&' prefix for globals when register base field is non-zero, otherwise...
authorAnton Korobeynikov <asl@math.spbu.ru>
Sat, 6 Mar 2010 11:41:12 +0000 (11:41 +0000)
committerAnton Korobeynikov <asl@math.spbu.ru>
Sat, 6 Mar 2010 11:41:12 +0000 (11:41 +0000)
This fixes PR6349

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97877 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp
lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp
test/CodeGen/MSP430/AddrMode-bis-rx.ll
test/CodeGen/MSP430/AddrMode-bis-xr.ll
test/CodeGen/MSP430/AddrMode-mov-rx.ll
test/CodeGen/MSP430/AddrMode-mov-xr.ll

index def5fc6587f367882b46f9a43474a60446d68168..7a35eb092ae32c708bbe2e8bcc4edb6833f05085 100644 (file)
@@ -98,12 +98,19 @@ void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
     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 @@ void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum,
   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()) {
index f6565bdec6ed89faa9f5fd94dcf2aaf8e68f93a2..d7636e68a0d606d49f0a35f6ca1de51f5781a665 100644 (file)
@@ -62,21 +62,26 @@ void MSP430InstPrinter::printSrcMemOperand(const MCInst *MI, unsigned OpNo,
   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) {
index 115464d7f65a212b0ddf12feaabcb748c2ec3206..4f9a7248bbf13b2fee4973f6b60e5581d7ab99fe 100644 (file)
@@ -29,7 +29,7 @@ define i8 @am3(i8 %x, i16 %n) nounwind {
        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 @@ define i8 @am7(i8 %x, i16 %n) nounwind {
        ret i8 %4
 }
 ; CHECK: am7:
-; CHECK:               bis.b   &duh+2(r14), r15
+; CHECK:               bis.b   duh+2(r14), r15
 
index 3baf332664af3bf0bf5a4ee63db42d5134fbe80e..17ebd873680b3d99e6cd59eafba3a01f798b11d9 100644 (file)
@@ -32,7 +32,7 @@ define void @am3(i16 %i, i8 %x) nounwind {
        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 @@ define void @am7(i16 %n, i8 %x) nounwind {
        ret void
 }
 ; CHECK: am7:
-; CHECK:               bis.b   r14, &duh+2(r15)
+; CHECK:               bis.b   r14, duh+2(r15)
 
index 9144f9af8e3927a2b110c46a69d832d6dfe285c9..6676b88cd14f6b82a1f1f17de7a16bb8b464fa7c 100644 (file)
@@ -26,7 +26,7 @@ define i8 @am3(i16 %n) nounwind {
        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 @@ define i8 @am7(i16 %n) nounwind {
        ret i8 %3
 }
 ; CHECK: am7:
-; CHECK:               mov.b   &duh+2(r15), r15
+; CHECK:               mov.b   duh+2(r15), r15
 
index 333c80011e8ff2a71b945437a7e7a294843961a1..4b327b0578f2ef0974ffd6bb1f2bb45d82e6c511 100644 (file)
@@ -26,7 +26,7 @@ define void @am3(i16 %i, i8 %a) nounwind {
        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 @@ define void @am7(i16 %n, i8 %a) nounwind {
        ret void
 }
 ; CHECK: am7:
-; CHECK:               mov.b   r14, &duh+2(r15)
+; CHECK:               mov.b   r14, duh+2(r15)