|
14 | 14 | #include "RISCVISelLowering.h"
|
15 | 15 | #include "MCTargetDesc/RISCVMatInt.h"
|
16 | 16 | #include "RISCV.h"
|
| 17 | +#include "RISCVConstantPoolValue.h" |
17 | 18 | #include "RISCVMachineFunctionInfo.h"
|
18 | 19 | #include "RISCVRegisterInfo.h"
|
19 | 20 | #include "RISCVSubtarget.h"
|
@@ -7518,6 +7519,27 @@ static SDValue getTargetNode(JumpTableSDNode *N, const SDLoc &DL, EVT Ty,
|
7518 | 7519 | return DAG.getTargetJumpTable(N->getIndex(), Ty, Flags);
|
7519 | 7520 | }
|
7520 | 7521 |
|
| 7522 | +static SDValue getLargeGlobalAddress(GlobalAddressSDNode *N, const SDLoc &DL, |
| 7523 | + EVT Ty, SelectionDAG &DAG) { |
| 7524 | + RISCVConstantPoolValue *CPV = RISCVConstantPoolValue::Create(N->getGlobal()); |
| 7525 | + SDValue CPAddr = DAG.getTargetConstantPool(CPV, Ty, Align(8)); |
| 7526 | + SDValue LC = DAG.getNode(RISCVISD::LLA, DL, Ty, CPAddr); |
| 7527 | + return DAG.getLoad( |
| 7528 | + Ty, DL, DAG.getEntryNode(), LC, |
| 7529 | + MachinePointerInfo::getConstantPool(DAG.getMachineFunction())); |
| 7530 | +} |
| 7531 | + |
| 7532 | +static SDValue getLargeExternalSymbol(ExternalSymbolSDNode *N, const SDLoc &DL, |
| 7533 | + EVT Ty, SelectionDAG &DAG) { |
| 7534 | + RISCVConstantPoolValue *CPV = |
| 7535 | + RISCVConstantPoolValue::Create(*DAG.getContext(), N->getSymbol()); |
| 7536 | + SDValue CPAddr = DAG.getTargetConstantPool(CPV, Ty, Align(8)); |
| 7537 | + SDValue LC = DAG.getNode(RISCVISD::LLA, DL, Ty, CPAddr); |
| 7538 | + return DAG.getLoad( |
| 7539 | + Ty, DL, DAG.getEntryNode(), LC, |
| 7540 | + MachinePointerInfo::getConstantPool(DAG.getMachineFunction())); |
| 7541 | +} |
| 7542 | + |
7521 | 7543 | template <class NodeTy>
|
7522 | 7544 | SDValue RISCVTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
|
7523 | 7545 | bool IsLocal, bool IsExternWeak) const {
|
@@ -7586,6 +7608,14 @@ SDValue RISCVTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
|
7586 | 7608 | // expands to (addi (auipc %pcrel_hi(sym)) %pcrel_lo(auipc)).
|
7587 | 7609 | return DAG.getNode(RISCVISD::LLA, DL, Ty, Addr);
|
7588 | 7610 | }
|
| 7611 | + case CodeModel::Large: { |
| 7612 | + if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N)) |
| 7613 | + return getLargeGlobalAddress(G, DL, Ty, DAG); |
| 7614 | + |
| 7615 | + // Using pc-relative mode for other node type. |
| 7616 | + SDValue Addr = getTargetNode(N, DL, Ty, DAG, 0); |
| 7617 | + return DAG.getNode(RISCVISD::LLA, DL, Ty, Addr); |
| 7618 | + } |
7589 | 7619 | }
|
7590 | 7620 | }
|
7591 | 7621 |
|
@@ -19590,7 +19620,12 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
|
19590 | 19620 | // If the callee is a GlobalAddress/ExternalSymbol node, turn it into a
|
19591 | 19621 | // TargetGlobalAddress/TargetExternalSymbol node so that legalize won't
|
19592 | 19622 | // split it and then direct call can be matched by PseudoCALL.
|
19593 |
| - if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) { |
| 19623 | + if (getTargetMachine().getCodeModel() == CodeModel::Large) { |
| 19624 | + if (auto *S = dyn_cast<GlobalAddressSDNode>(Callee)) |
| 19625 | + Callee = getLargeGlobalAddress(S, DL, PtrVT, DAG); |
| 19626 | + else if (auto *S = dyn_cast<ExternalSymbolSDNode>(Callee)) |
| 19627 | + Callee = getLargeExternalSymbol(S, DL, PtrVT, DAG); |
| 19628 | + } else if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) { |
19594 | 19629 | const GlobalValue *GV = S->getGlobal();
|
19595 | 19630 | Callee = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, RISCVII::MO_CALL);
|
19596 | 19631 | } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
|
|
0 commit comments