Changeset View
Changeset View
Standalone View
Standalone View
llvm/lib/Target/LoongArch/LoongArchISelDAGToDAG.cpp
Show All 27 Lines | if (Node->isMachineOpcode()) { | ||||
return; | return; | ||||
} | } | ||||
// Instruction Selection not handled by the auto-generated tablegen selection | // Instruction Selection not handled by the auto-generated tablegen selection | ||||
// should be handled here. | // should be handled here. | ||||
unsigned Opcode = Node->getOpcode(); | unsigned Opcode = Node->getOpcode(); | ||||
MVT GRLenVT = Subtarget->getGRLenVT(); | MVT GRLenVT = Subtarget->getGRLenVT(); | ||||
SDLoc DL(Node); | SDLoc DL(Node); | ||||
MVT VT = Node->getSimpleValueType(0); | |||||
switch (Opcode) { | switch (Opcode) { | ||||
default: | default: | ||||
break; | break; | ||||
case ISD::Constant: { | case ISD::Constant: { | ||||
int64_t Imm = cast<ConstantSDNode>(Node)->getSExtValue(); | int64_t Imm = cast<ConstantSDNode>(Node)->getSExtValue(); | ||||
if (Imm == 0 && Node->getSimpleValueType(0) == GRLenVT) { | if (Imm == 0 && VT == GRLenVT) { | ||||
SDValue New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, | SDValue New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, | ||||
LoongArch::R0, GRLenVT); | LoongArch::R0, GRLenVT); | ||||
ReplaceNode(Node, New.getNode()); | ReplaceNode(Node, New.getNode()); | ||||
return; | return; | ||||
} | } | ||||
SDNode *Result = nullptr; | SDNode *Result = nullptr; | ||||
SDValue SrcReg = CurDAG->getRegister(LoongArch::R0, GRLenVT); | SDValue SrcReg = CurDAG->getRegister(LoongArch::R0, GRLenVT); | ||||
// The instructions in the sequence are handled here. | // The instructions in the sequence are handled here. | ||||
for (LoongArchMatInt::Inst &Inst : LoongArchMatInt::generateInstSeq(Imm)) { | for (LoongArchMatInt::Inst &Inst : LoongArchMatInt::generateInstSeq(Imm)) { | ||||
SDValue SDImm = CurDAG->getTargetConstant(Inst.Imm, DL, GRLenVT); | SDValue SDImm = CurDAG->getTargetConstant(Inst.Imm, DL, GRLenVT); | ||||
if (Inst.Opc == LoongArch::LU12I_W) | if (Inst.Opc == LoongArch::LU12I_W) | ||||
Result = CurDAG->getMachineNode(LoongArch::LU12I_W, DL, GRLenVT, SDImm); | Result = CurDAG->getMachineNode(LoongArch::LU12I_W, DL, GRLenVT, SDImm); | ||||
else | else | ||||
Result = CurDAG->getMachineNode(Inst.Opc, DL, GRLenVT, SrcReg, SDImm); | Result = CurDAG->getMachineNode(Inst.Opc, DL, GRLenVT, SrcReg, SDImm); | ||||
SrcReg = SDValue(Result, 0); | SrcReg = SDValue(Result, 0); | ||||
} | } | ||||
ReplaceNode(Node, Result); | ReplaceNode(Node, Result); | ||||
return; | return; | ||||
} | } | ||||
case ISD::FrameIndex: { | |||||
SDValue Imm = CurDAG->getTargetConstant(0, DL, GRLenVT); | |||||
int FI = cast<FrameIndexSDNode>(Node)->getIndex(); | |||||
SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT); | |||||
unsigned ADDIOp = | |||||
Subtarget->is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W; | |||||
ReplaceNode(Node, CurDAG->getMachineNode(ADDIOp, DL, VT, TFI, Imm)); | |||||
return; | |||||
} | |||||
// TODO: Add selection nodes needed later. | // TODO: Add selection nodes needed later. | ||||
} | } | ||||
// Select the default instruction. | // Select the default instruction. | ||||
SelectCode(Node); | SelectCode(Node); | ||||
} | } | ||||
bool LoongArchDAGToDAGISel::SelectBaseAddr(SDValue Addr, SDValue &Base) { | |||||
// If this is FrameIndex, select it directly. Otherwise just let it get | |||||
// selected to a register independently. | |||||
if (auto *FIN = dyn_cast<FrameIndexSDNode>(Addr)) | |||||
Base = | |||||
CurDAG->getTargetFrameIndex(FIN->getIndex(), Subtarget->getGRLenVT()); | |||||
else | |||||
Base = Addr; | |||||
return true; | |||||
} | |||||
bool LoongArchDAGToDAGISel::selectShiftMask(SDValue N, unsigned ShiftWidth, | bool LoongArchDAGToDAGISel::selectShiftMask(SDValue N, unsigned ShiftWidth, | ||||
SDValue &ShAmt) { | SDValue &ShAmt) { | ||||
// Shift instructions on LoongArch only read the lower 5 or 6 bits of the | // Shift instructions on LoongArch only read the lower 5 or 6 bits of the | ||||
// shift amount. If there is an AND on the shift amount, we can bypass it if | // shift amount. If there is an AND on the shift amount, we can bypass it if | ||||
// it doesn't affect any of those bits. | // it doesn't affect any of those bits. | ||||
if (N.getOpcode() == ISD::AND && isa<ConstantSDNode>(N.getOperand(1))) { | if (N.getOpcode() == ISD::AND && isa<ConstantSDNode>(N.getOperand(1))) { | ||||
const APInt &AndMask = N->getConstantOperandAPInt(1); | const APInt &AndMask = N->getConstantOperandAPInt(1); | ||||
▲ Show 20 Lines • Show All 55 Lines • Show Last 20 Lines |