forked from OSchip/llvm-project
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:
parent
1810d77cb4
commit
6f5523aa8b
|
@ -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()) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
Loading…
Reference in New Issue