From: Anton Korobeynikov Date: Sat, 6 Mar 2010 11:41:12 +0000 (+0000) Subject: Do not use '&' prefix for globals when register base field is non-zero, otherwise... X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=9aff323a074658eee2de69862d202a8638b59c05;p=oota-llvm.git 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 def5fc6587f..7a35eb092ae 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 f6565bdec6e..d7636e68a0d 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 115464d7f65..4f9a7248bbf 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 3baf332664a..17ebd873680 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 9144f9af8e3..6676b88cd14 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 333c80011e8..4b327b0578f 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)