diff options
| author | Simon Atanasyan <simon@atanasyan.com> | 2017-07-20 12:19:26 +0000 |
|---|---|---|
| committer | Simon Atanasyan <simon@atanasyan.com> | 2017-07-20 12:19:26 +0000 |
| commit | fb953926b155448f1ca460a4cb39f6a4a8cbbdb5 (patch) | |
| tree | a05e05394b9c177c70e617aa90018346949a5610 /llvm/lib | |
| parent | b1c74321170863330ef4a849b21cf778fcc05823 (diff) | |
| download | bcm5719-llvm-fb953926b155448f1ca460a4cb39f6a4a8cbbdb5.tar.gz bcm5719-llvm-fb953926b155448f1ca460a4cb39f6a4a8cbbdb5.zip | |
[mips] Support `long_call/far/near` attributes passed by front-end
This patch adds handling of the `long_call`, `far`, and `near`
attributes passed by front-end. The patch depends on D35479.
Differential revision: https://reviews.llvm.org/D35480.
llvm-svn: 308606
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/Mips/MipsISelLowering.cpp | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp index 20319f85696..dd41fefb55f 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -3152,15 +3152,30 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, // The long-calls feature is ignored in case of PIC. // While we do not support -mshared / -mno-shared properly, // ignore long-calls in case of -mabicalls too. - if (Subtarget.useLongCalls() && !Subtarget.isABICalls() && !IsPIC) { - // Get the address of the callee into a register to prevent - // using of the `jal` instruction for the direct call. - if (auto *N = dyn_cast<GlobalAddressSDNode>(Callee)) - Callee = Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG) - : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG); - else if (auto *N = dyn_cast<ExternalSymbolSDNode>(Callee)) - Callee = Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG) - : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG); + if (!Subtarget.isABICalls() && !IsPIC) { + // If the function should be called using "long call", + // get its address into a register to prevent using + // of the `jal` instruction for the direct call. + if (auto *N = dyn_cast<ExternalSymbolSDNode>(Callee)) { + if (Subtarget.useLongCalls()) + Callee = Subtarget.hasSym32() + ? getAddrNonPIC(N, SDLoc(N), Ty, DAG) + : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG); + } else if (auto *N = dyn_cast<GlobalAddressSDNode>(Callee)) { + bool UseLongCalls = Subtarget.useLongCalls(); + // If the function has long-call/far/near attribute + // it overrides command line switch pased to the backend. + if (auto *F = dyn_cast<Function>(N->getGlobal())) { + if (F->hasFnAttribute("long-call")) + UseLongCalls = true; + else if (F->hasFnAttribute("short-call")) + UseLongCalls = false; + } + if (UseLongCalls) + Callee = Subtarget.hasSym32() + ? getAddrNonPIC(N, SDLoc(N), Ty, DAG) + : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG); + } } if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) { |

