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

llvm-svn: 97877
This commit is contained in:
Anton Korobeynikov 2010-03-06 11:41:12 +00:00
parent 1810d77cb4
commit 6f5523aa8b
6 changed files with 35 additions and 27 deletions

View 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()) {

View 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) {

View 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

View 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)

View 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

View 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)