1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[AVR] Fix indirect calls to function pointers

Patch by Carl Peto.

llvm-svn: 307888
This commit is contained in:
Dylan McKay 2017-07-13 08:09:36 +00:00
parent 2d4de8dcfb
commit dcba8216a6
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)*)