diff options
| author | Dylan McKay <me@dylanmckay.io> | 2017-07-13 08:09:36 +0000 |
|---|---|---|
| committer | Dylan McKay <me@dylanmckay.io> | 2017-07-13 08:09:36 +0000 |
| commit | 9fb04071a21737729616dbfbbe7adf8c33294251 (patch) | |
| tree | 9e24c659992de76e3382a30419d1f61b34f8c897 | |
| parent | 0c7d406bb2afacc9a08f3e8c058d6c54abb0db4e (diff) | |
| download | bcm5719-llvm-9fb04071a21737729616dbfbbe7adf8c33294251.tar.gz bcm5719-llvm-9fb04071a21737729616dbfbbe7adf8c33294251.zip | |
[AVR] Fix indirect calls to function pointers
Patch by Carl Peto.
llvm-svn: 307888
| -rw-r--r-- | llvm/lib/Target/AVR/AVRMCInstLower.cpp | 16 | ||||
| -rw-r--r-- | llvm/test/CodeGen/AVR/icall-func-pointer-correct-addr-space.ll | 15 |
2 files changed, 29 insertions, 2 deletions
diff --git a/llvm/lib/Target/AVR/AVRMCInstLower.cpp b/llvm/lib/Target/AVR/AVRMCInstLower.cpp index 475dda420e8..dfefd09bc4b 100644 --- a/llvm/lib/Target/AVR/AVRMCInstLower.cpp +++ b/llvm/lib/Target/AVR/AVRMCInstLower.cpp @@ -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"); } diff --git a/llvm/test/CodeGen/AVR/icall-func-pointer-correct-addr-space.ll b/llvm/test/CodeGen/AVR/icall-func-pointer-correct-addr-space.ll new file mode 100644 index 00000000000..17ac29e2cdb --- /dev/null +++ b/llvm/test/CodeGen/AVR/icall-func-pointer-correct-addr-space.ll @@ -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)*) + |

