[AVR] Fix indirect calls to function pointers

Patch by Carl Peto.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307888 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dylan McKay 2017-07-13 08:09:36 +00:00
parent 3e55e45537
commit 90904c693c
2 changed files with 29 additions and 2 deletions

View File

@ -37,10 +37,22 @@ MCOperand AVRMCInstLower::lowerSymbolOperand(const MachineOperand &MO,
Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
}
bool IsFunction = MO.isGlobal() && isa<Function>(MO.getGlobal());
if (TF & AVRII::MO_LO) {
Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_LO8, Expr, IsNegated, Ctx);
if (IsFunction) {
// N.B. Should we use _GS fixups here to cope with >128k progmem?
Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_PM_LO8, Expr, IsNegated, Ctx);
} else {
Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_LO8, Expr, IsNegated, Ctx);
}
} else if (TF & AVRII::MO_HI) {
Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_HI8, Expr, IsNegated, Ctx);
if (IsFunction) {
// N.B. Should we use _GS fixups here to cope with >128k progmem?
Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_PM_HI8, Expr, IsNegated, Ctx);
} else {
Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_HI8, Expr, IsNegated, Ctx);
}
} else if (TF != 0) {
llvm_unreachable("Unknown target flag on symbol operand");
}

View File

@ -0,0 +1,15 @@
; RUN: llc -mattr=lpm,lpmw < %s -march=avr | FileCheck %s
declare void @callback(i16 zeroext)
; CHECK-LABEL: foo
define void @foo() {
entry:
; CHECK: ldi r{{[0-9]+}}, pm_lo8(callback)
; CHECK-NEXT: ldi r{{[0-9]+}}, pm_hi8(callback)
call void @bar(i8 zeroext undef, void (i16)* @callback)
ret void
}
declare void @bar(i8 zeroext, void (i16)*)