|
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" |
@@ -7407,6 +7408,27 @@ static SDValue getTargetNode(JumpTableSDNode *N, const SDLoc &DL, EVT Ty, |
7407 | 7408 | return DAG.getTargetJumpTable(N->getIndex(), Ty, Flags); |
7408 | 7409 | } |
7409 | 7410 |
|
| 7411 | +static SDValue getLargeGlobalAddress(GlobalAddressSDNode *N, const SDLoc &DL, |
| 7412 | + EVT Ty, SelectionDAG &DAG) { |
| 7413 | + RISCVConstantPoolValue *CPV = RISCVConstantPoolValue::Create(N->getGlobal()); |
| 7414 | + SDValue CPAddr = DAG.getTargetConstantPool(CPV, Ty, Align(8)); |
| 7415 | + SDValue LC = DAG.getNode(RISCVISD::LLA, DL, Ty, CPAddr); |
| 7416 | + return DAG.getLoad( |
| 7417 | + Ty, DL, DAG.getEntryNode(), LC, |
| 7418 | + MachinePointerInfo::getConstantPool(DAG.getMachineFunction())); |
| 7419 | +} |
| 7420 | + |
| 7421 | +static SDValue getLargeExternalSymbol(ExternalSymbolSDNode *N, const SDLoc &DL, |
| 7422 | + EVT Ty, SelectionDAG &DAG) { |
| 7423 | + RISCVConstantPoolValue *CPV = |
| 7424 | + RISCVConstantPoolValue::Create(*DAG.getContext(), N->getSymbol()); |
| 7425 | + SDValue CPAddr = DAG.getTargetConstantPool(CPV, Ty, Align(8)); |
| 7426 | + SDValue LC = DAG.getNode(RISCVISD::LLA, DL, Ty, CPAddr); |
| 7427 | + return DAG.getLoad( |
| 7428 | + Ty, DL, DAG.getEntryNode(), LC, |
| 7429 | + MachinePointerInfo::getConstantPool(DAG.getMachineFunction())); |
| 7430 | +} |
| 7431 | + |
7410 | 7432 | template <class NodeTy> |
7411 | 7433 | SDValue RISCVTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG, |
7412 | 7434 | bool IsLocal, bool IsExternWeak) const { |
@@ -7475,6 +7497,14 @@ SDValue RISCVTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG, |
7475 | 7497 | // expands to (addi (auipc %pcrel_hi(sym)) %pcrel_lo(auipc)). |
7476 | 7498 | return DAG.getNode(RISCVISD::LLA, DL, Ty, Addr); |
7477 | 7499 | } |
| 7500 | + case CodeModel::Large: { |
| 7501 | + if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N)) |
| 7502 | + return getLargeGlobalAddress(G, DL, Ty, DAG); |
| 7503 | + |
| 7504 | + // Using pc-relative mode for other node type. |
| 7505 | + SDValue Addr = getTargetNode(N, DL, Ty, DAG, 0); |
| 7506 | + return DAG.getNode(RISCVISD::LLA, DL, Ty, Addr); |
| 7507 | + } |
7478 | 7508 | } |
7479 | 7509 | } |
7480 | 7510 |
|
@@ -20150,7 +20180,12 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI, |
20150 | 20180 | // If the callee is a GlobalAddress/ExternalSymbol node, turn it into a |
20151 | 20181 | // TargetGlobalAddress/TargetExternalSymbol node so that legalize won't |
20152 | 20182 | // split it and then direct call can be matched by PseudoCALL. |
20153 | | - if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) { |
| 20183 | + if (getTargetMachine().getCodeModel() == CodeModel::Large) { |
| 20184 | + if (auto *S = dyn_cast<GlobalAddressSDNode>(Callee)) |
| 20185 | + Callee = getLargeGlobalAddress(S, DL, PtrVT, DAG); |
| 20186 | + else if (auto *S = dyn_cast<ExternalSymbolSDNode>(Callee)) |
| 20187 | + Callee = getLargeExternalSymbol(S, DL, PtrVT, DAG); |
| 20188 | + } else if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) { |
20154 | 20189 | const GlobalValue *GV = S->getGlobal(); |
20155 | 20190 | Callee = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, RISCVII::MO_CALL); |
20156 | 20191 | } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) { |
|
0 commit comments