aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2010-03-06 11:41:12 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2010-03-06 11:41:12 +0000
commit9aff323a074658eee2de69862d202a8638b59c05 (patch)
tree3fe31410bc5e3e7157891018bc011ab36e0269ff
parent7b323a34fa034389e9e439f6c02eeb73e87ab9db (diff)
downloadexternal_llvm-9aff323a074658eee2de69862d202a8638b59c05.zip
external_llvm-9aff323a074658eee2de69862d202a8638b59c05.tar.gz
external_llvm-9aff323a074658eee2de69862d202a8638b59c05.tar.bz2
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
-rw-r--r--lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp23
-rw-r--r--lib/Target/MSP430/AsmPrinter/MSP430InstPrinter.cpp23
-rw-r--r--test/CodeGen/MSP430/AddrMode-bis-rx.ll4
-rw-r--r--test/CodeGen/MSP430/AddrMode-bis-xr.ll4
-rw-r--r--test/CodeGen/MSP430/AddrMode-mov-rx.ll4
-rw-r--r--test/CodeGen/MSP430/AddrMode-mov-xr.ll4
6 files changed, 35 insertions, 27 deletions
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 @@ 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()) {
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 @@ 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) {
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 @@ 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
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 @@ 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)
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 @@ 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
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 @@ 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)