Changeset View
Changeset View
Standalone View
Standalone View
llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
Show All 11 Lines | |||||
//===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||
#include "LoongArchISelLowering.h" | #include "LoongArchISelLowering.h" | ||||
#include "LoongArch.h" | #include "LoongArch.h" | ||||
#include "LoongArchMachineFunctionInfo.h" | #include "LoongArchMachineFunctionInfo.h" | ||||
#include "LoongArchRegisterInfo.h" | #include "LoongArchRegisterInfo.h" | ||||
#include "LoongArchSubtarget.h" | #include "LoongArchSubtarget.h" | ||||
#include "LoongArchTargetMachine.h" | #include "LoongArchTargetMachine.h" | ||||
#include "MCTargetDesc/LoongArchBaseInfo.h" | |||||
#include "MCTargetDesc/LoongArchMCTargetDesc.h" | #include "MCTargetDesc/LoongArchMCTargetDesc.h" | ||||
#include "llvm/ADT/Statistic.h" | #include "llvm/ADT/Statistic.h" | ||||
#include "llvm/CodeGen/ISDOpcodes.h" | #include "llvm/CodeGen/ISDOpcodes.h" | ||||
#include "llvm/Support/Debug.h" | #include "llvm/Support/Debug.h" | ||||
#include "llvm/Support/KnownBits.h" | #include "llvm/Support/KnownBits.h" | ||||
using namespace llvm; | using namespace llvm; | ||||
▲ Show 20 Lines • Show All 245 Lines • ▼ Show 20 Lines | SDValue LoongArchTargetLowering::lowerGlobalAddress(SDValue Op, | ||||
SelectionDAG &DAG) const { | SelectionDAG &DAG) const { | ||||
SDLoc DL(Op); | SDLoc DL(Op); | ||||
EVT Ty = getPointerTy(DAG.getDataLayout()); | EVT Ty = getPointerTy(DAG.getDataLayout()); | ||||
const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); | const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); | ||||
unsigned ADDIOp = Subtarget.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W; | unsigned ADDIOp = Subtarget.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W; | ||||
// TODO: Support dso_preemptable and target flags. | // TODO: Support dso_preemptable and target flags. | ||||
if (GV->isDSOLocal()) { | if (GV->isDSOLocal()) { | ||||
SDValue GA = DAG.getTargetGlobalAddress(GV, DL, Ty); | SDValue GAHi = | ||||
SDValue AddrHi(DAG.getMachineNode(LoongArch::PCALAU12I, DL, Ty, GA), 0); | DAG.getTargetGlobalAddress(GV, DL, Ty, 0, LoongArchII::MO_PCREL_HI); | ||||
SDValue Addr(DAG.getMachineNode(ADDIOp, DL, Ty, AddrHi, GA), 0); | SDValue GALo = | ||||
return Addr; | DAG.getTargetGlobalAddress(GV, DL, Ty, 0, LoongArchII::MO_PCREL_LO); | ||||
SDValue AddrHi(DAG.getMachineNode(LoongArch::PCALAU12I, DL, Ty, GAHi), 0); | |||||
return SDValue(DAG.getMachineNode(ADDIOp, DL, Ty, AddrHi, GALo), 0); | |||||
} | } | ||||
report_fatal_error("Unable to lowerGlobalAddress"); | report_fatal_error("Unable to lowerGlobalAddress"); | ||||
} | } | ||||
SDValue LoongArchTargetLowering::lowerShiftLeftParts(SDValue Op, | SDValue LoongArchTargetLowering::lowerShiftLeftParts(SDValue Op, | ||||
SelectionDAG &DAG) const { | SelectionDAG &DAG) const { | ||||
SDLoc DL(Op); | SDLoc DL(Op); | ||||
SDValue Lo = Op.getOperand(0); | SDValue Lo = Op.getOperand(0); | ||||
▲ Show 20 Lines • Show All 1,303 Lines • ▼ Show 20 Lines | LoongArchTargetLowering::LowerCall(CallLoweringInfo &CLI, | ||||
for (auto &Reg : RegsToPass) { | for (auto &Reg : RegsToPass) { | ||||
Chain = DAG.getCopyToReg(Chain, DL, Reg.first, Reg.second, Glue); | Chain = DAG.getCopyToReg(Chain, DL, Reg.first, Reg.second, Glue); | ||||
Glue = Chain.getValue(1); | Glue = Chain.getValue(1); | ||||
} | } | ||||
// If the callee is a GlobalAddress/ExternalSymbol node, turn it into a | // If the callee is a GlobalAddress/ExternalSymbol node, turn it into a | ||||
// TargetGlobalAddress/TargetExternalSymbol node so that legalize won't | // TargetGlobalAddress/TargetExternalSymbol node so that legalize won't | ||||
// split it and then direct call can be matched by PseudoCALL. | // split it and then direct call can be matched by PseudoCALL. | ||||
// FIXME: Add target flags for relocation. | if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) { | ||||
if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) | const GlobalValue *GV = S->getGlobal(); | ||||
Callee = DAG.getTargetGlobalAddress(S->getGlobal(), DL, PtrVT); | unsigned OpFlags = | ||||
else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) | getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV) | ||||
Callee = DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT); | ? LoongArchII::MO_CALL | ||||
: LoongArchII::MO_CALL_PLT; | |||||
Callee = DAG.getTargetGlobalAddress(S->getGlobal(), DL, PtrVT, 0, OpFlags); | |||||
} else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) { | |||||
unsigned OpFlags = getTargetMachine().shouldAssumeDSOLocal( | |||||
*MF.getFunction().getParent(), nullptr) | |||||
? LoongArchII::MO_CALL | |||||
: LoongArchII::MO_CALL_PLT; | |||||
Callee = DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT, OpFlags); | |||||
} | |||||
// The first call operand is the chain and the second is the target address. | // The first call operand is the chain and the second is the target address. | ||||
SmallVector<SDValue> Ops; | SmallVector<SDValue> Ops; | ||||
Ops.push_back(Chain); | Ops.push_back(Chain); | ||||
Ops.push_back(Callee); | Ops.push_back(Callee); | ||||
// Add argument registers to the end of the list so that they are | // Add argument registers to the end of the list so that they are | ||||
// known live into the call. | // known live into the call. | ||||
▲ Show 20 Lines • Show All 119 Lines • Show Last 20 Lines |