mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-04 17:47:58 +00:00
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
This commit is contained in:
parent
7b323a34fa
commit
9aff323a07
@ -98,12 +98,19 @@ void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
|
|||||||
bool isMemOp = Modifier && !strcmp(Modifier, "mem");
|
bool isMemOp = Modifier && !strcmp(Modifier, "mem");
|
||||||
uint64_t Offset = MO.getOffset();
|
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)
|
if (Offset)
|
||||||
O << '(' << Offset << '+';
|
O << '(' << Offset << '+';
|
||||||
|
|
||||||
O << *GetGlobalValueSymbol(MO.getGlobal());
|
O << *GetGlobalValueSymbol(MO.getGlobal());
|
||||||
|
|
||||||
if (Offset)
|
if (Offset)
|
||||||
O << ')';
|
O << ')';
|
||||||
|
|
||||||
@ -124,15 +131,11 @@ void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum,
|
|||||||
const MachineOperand &Disp = MI->getOperand(OpNum+1);
|
const MachineOperand &Disp = MI->getOperand(OpNum+1);
|
||||||
|
|
||||||
// Print displacement first
|
// 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
|
// Print register base field
|
||||||
if (Base.getReg()) {
|
if (Base.getReg()) {
|
||||||
|
@ -62,21 +62,26 @@ void MSP430InstPrinter::printSrcMemOperand(const MCInst *MI, unsigned OpNo,
|
|||||||
const MCOperand &Disp = MI->getOperand(OpNo+1);
|
const MCOperand &Disp = MI->getOperand(OpNo+1);
|
||||||
|
|
||||||
// Print displacement first
|
// 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();
|
O << Disp.getImm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Print register base field
|
// Print register base field
|
||||||
if (Base.getReg()) {
|
if (Base.getReg())
|
||||||
O << '(' << getRegisterName(Base.getReg()) << ')';
|
O << '(' << getRegisterName(Base.getReg()) << ')';
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MSP430InstPrinter::printCCOperand(const MCInst *MI, unsigned OpNo) {
|
void MSP430InstPrinter::printCCOperand(const MCInst *MI, unsigned OpNo) {
|
||||||
|
@ -29,7 +29,7 @@ define i8 @am3(i8 %x, i16 %n) nounwind {
|
|||||||
ret i8 %3
|
ret i8 %3
|
||||||
}
|
}
|
||||||
; CHECK: am3:
|
; CHECK: am3:
|
||||||
; CHECK: bis.b &bar(r14), r15
|
; CHECK: bis.b bar(r14), r15
|
||||||
|
|
||||||
define i16 @am4(i16 %x) nounwind {
|
define i16 @am4(i16 %x) nounwind {
|
||||||
%1 = volatile load i16* inttoptr(i16 32 to i16*)
|
%1 = volatile load i16* inttoptr(i16 32 to i16*)
|
||||||
@ -70,5 +70,5 @@ define i8 @am7(i8 %x, i16 %n) nounwind {
|
|||||||
ret i8 %4
|
ret i8 %4
|
||||||
}
|
}
|
||||||
; CHECK: am7:
|
; 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
|
ret void
|
||||||
}
|
}
|
||||||
; CHECK: am3:
|
; CHECK: am3:
|
||||||
; CHECK: bis.b r14, &bar(r15)
|
; CHECK: bis.b r14, bar(r15)
|
||||||
|
|
||||||
define void @am4(i16 %x) nounwind {
|
define void @am4(i16 %x) nounwind {
|
||||||
%1 = volatile load i16* inttoptr(i16 32 to i16*)
|
%1 = volatile load i16* inttoptr(i16 32 to i16*)
|
||||||
@ -77,5 +77,5 @@ define void @am7(i16 %n, i8 %x) nounwind {
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
; CHECK: am7:
|
; 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
|
ret i8 %2
|
||||||
}
|
}
|
||||||
; CHECK: am3:
|
; CHECK: am3:
|
||||||
; CHECK: mov.b &bar(r15), r15
|
; CHECK: mov.b bar(r15), r15
|
||||||
|
|
||||||
define i16 @am4() nounwind {
|
define i16 @am4() nounwind {
|
||||||
%1 = volatile load i16* inttoptr(i16 32 to i16*)
|
%1 = volatile load i16* inttoptr(i16 32 to i16*)
|
||||||
@ -63,5 +63,5 @@ define i8 @am7(i16 %n) nounwind {
|
|||||||
ret i8 %3
|
ret i8 %3
|
||||||
}
|
}
|
||||||
; CHECK: am7:
|
; 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
|
ret void
|
||||||
}
|
}
|
||||||
; CHECK: am3:
|
; CHECK: am3:
|
||||||
; CHECK: mov.b r14, &bar(r15)
|
; CHECK: mov.b r14, bar(r15)
|
||||||
|
|
||||||
define void @am4(i16 %a) nounwind {
|
define void @am4(i16 %a) nounwind {
|
||||||
volatile store i16 %a, i16* inttoptr(i16 32 to i16*)
|
volatile store i16 %a, i16* inttoptr(i16 32 to i16*)
|
||||||
@ -63,5 +63,5 @@ define void @am7(i16 %n, i8 %a) nounwind {
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
; CHECK: am7:
|
; CHECK: am7:
|
||||||
; CHECK: mov.b r14, &duh+2(r15)
|
; CHECK: mov.b r14, duh+2(r15)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user