[LoongArch] TableGen-erate SDNode descriptions (#168129)
This allows SDNodes to be validated against their expected type profiles and reduces the number of changes required to add a new node. I had to split `VSHUF4I` into two variants (`VSHUF4I` and `VSHUF4I_D`) since `loongarch_vshuf4i` and `loongarch_vshuf4i_d` have different number of operands, and this prevented the node from being imported. There is just one node that currently fails validation, see `LoongArchSelectionDAGInfo::verifyTargetNode()`. Part of #119709. Pull Request: https://github.com/llvm/llvm-project/pull/168129
This commit is contained in:
parent
bb0a95d5b1
commit
b5812c0cf7
@ -10,6 +10,7 @@ tablegen(LLVM LoongArchGenInstrInfo.inc -gen-instr-info)
|
||||
tablegen(LLVM LoongArchGenMCPseudoLowering.inc -gen-pseudo-lowering)
|
||||
tablegen(LLVM LoongArchGenMCCodeEmitter.inc -gen-emitter)
|
||||
tablegen(LLVM LoongArchGenRegisterInfo.inc -gen-register-info)
|
||||
tablegen(LLVM LoongArchGenSDNodeInfo.inc -gen-sd-node-info)
|
||||
tablegen(LLVM LoongArchGenSubtargetInfo.inc -gen-subtarget)
|
||||
|
||||
add_public_tablegen_target(LoongArchCommonTableGen)
|
||||
@ -27,6 +28,7 @@ add_llvm_target(LoongArchCodeGen
|
||||
LoongArchMergeBaseOffset.cpp
|
||||
LoongArchOptWInstrs.cpp
|
||||
LoongArchRegisterInfo.cpp
|
||||
LoongArchSelectionDAGInfo.cpp
|
||||
LoongArchSubtarget.cpp
|
||||
LoongArchTargetMachine.cpp
|
||||
LoongArchTargetTransformInfo.cpp
|
||||
|
||||
@ -30,13 +30,18 @@ def SDT_LoongArchFRSQRTE : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisFP<1>]>;
|
||||
// ISD::BRCOND is custom-lowered to LoongArchISD::BRCOND for floating-point
|
||||
// comparisons to prevent recursive lowering.
|
||||
def loongarch_brcond : SDNode<"LoongArchISD::BRCOND", SDTBrcond, [SDNPHasChain]>;
|
||||
|
||||
// FPR<->GPR transfer operations
|
||||
def loongarch_movgr2fr_w
|
||||
: SDNode<"LoongArchISD::MOVGR2FR_W", SDT_LoongArchMOVGR2FR_W>;
|
||||
def loongarch_movgr2fr_w_la64
|
||||
: SDNode<"LoongArchISD::MOVGR2FR_W_LA64", SDT_LoongArchMOVGR2FR_W_LA64>;
|
||||
def loongarch_movfr2gr_s_la64
|
||||
: SDNode<"LoongArchISD::MOVFR2GR_S_LA64", SDT_LoongArchMOVFR2GR_S_LA64>;
|
||||
|
||||
def loongarch_ftint : SDNode<"LoongArchISD::FTINT", SDT_LoongArchFTINT>;
|
||||
|
||||
// Floating point approximate reciprocal operation
|
||||
def loongarch_frecipe : SDNode<"LoongArchISD::FRECIPE", SDT_LoongArchFRECIPE>;
|
||||
def loongarch_frsqrte : SDNode<"LoongArchISD::FRSQRTE", SDT_LoongArchFRSQRTE>;
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ def SDT_LoongArchMOVGR2FR_D_LO_HI
|
||||
: SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisVT<1, i32>,
|
||||
SDTCisSameAs<1, 2>]>;
|
||||
|
||||
// FPR<->GPR transfer operations
|
||||
def loongarch_movgr2fr_d
|
||||
: SDNode<"LoongArchISD::MOVGR2FR_D", SDT_LoongArchMOVGR2FR_D>;
|
||||
def loongarch_movgr2fr_d_lo_hi
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELDAGTODAG_H
|
||||
|
||||
#include "LoongArch.h"
|
||||
#include "LoongArchSelectionDAGInfo.h"
|
||||
#include "LoongArchTargetMachine.h"
|
||||
#include "llvm/CodeGen/SelectionDAGISel.h"
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#include "LoongArch.h"
|
||||
#include "LoongArchMachineFunctionInfo.h"
|
||||
#include "LoongArchRegisterInfo.h"
|
||||
#include "LoongArchSelectionDAGInfo.h"
|
||||
#include "LoongArchSubtarget.h"
|
||||
#include "MCTargetDesc/LoongArchBaseInfo.h"
|
||||
#include "MCTargetDesc/LoongArchMCTargetDesc.h"
|
||||
@ -1712,7 +1713,7 @@ lowerVECTOR_SHUFFLE_VSHUF4I(const SDLoc &DL, ArrayRef<int> Mask, MVT VT,
|
||||
|
||||
// Return vshuf4i.d
|
||||
if (VT == MVT::v2f64 || VT == MVT::v2i64)
|
||||
return DAG.getNode(LoongArchISD::VSHUF4I, DL, VT, V1, V2,
|
||||
return DAG.getNode(LoongArchISD::VSHUF4I_D, DL, VT, V1, V2,
|
||||
DAG.getConstant(Imm, DL, GRLenVT));
|
||||
|
||||
return DAG.getNode(LoongArchISD::VSHUF4I, DL, VT, V1,
|
||||
@ -4459,7 +4460,7 @@ SDValue LoongArchTargetLowering::lowerShiftRightParts(SDValue Op,
|
||||
|
||||
// Returns the opcode of the target-specific SDNode that implements the 32-bit
|
||||
// form of the given Opcode.
|
||||
static LoongArchISD::NodeType getLoongArchWOpcode(unsigned Opcode) {
|
||||
static unsigned getLoongArchWOpcode(unsigned Opcode) {
|
||||
switch (Opcode) {
|
||||
default:
|
||||
llvm_unreachable("Unexpected opcode");
|
||||
@ -4495,7 +4496,7 @@ static LoongArchISD::NodeType getLoongArchWOpcode(unsigned Opcode) {
|
||||
static SDValue customLegalizeToWOp(SDNode *N, SelectionDAG &DAG, int NumOp,
|
||||
unsigned ExtOpc = ISD::ANY_EXTEND) {
|
||||
SDLoc DL(N);
|
||||
LoongArchISD::NodeType WOpcode = getLoongArchWOpcode(N->getOpcode());
|
||||
unsigned WOpcode = getLoongArchWOpcode(N->getOpcode());
|
||||
SDValue NewOp0, NewRes;
|
||||
|
||||
switch (NumOp) {
|
||||
@ -7483,123 +7484,6 @@ bool LoongArchTargetLowering::allowsMisalignedMemoryAccesses(
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *LoongArchTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
switch ((LoongArchISD::NodeType)Opcode) {
|
||||
case LoongArchISD::FIRST_NUMBER:
|
||||
break;
|
||||
|
||||
#define NODE_NAME_CASE(node) \
|
||||
case LoongArchISD::node: \
|
||||
return "LoongArchISD::" #node;
|
||||
|
||||
// TODO: Add more target-dependent nodes later.
|
||||
NODE_NAME_CASE(CALL)
|
||||
NODE_NAME_CASE(CALL_MEDIUM)
|
||||
NODE_NAME_CASE(CALL_LARGE)
|
||||
NODE_NAME_CASE(RET)
|
||||
NODE_NAME_CASE(TAIL)
|
||||
NODE_NAME_CASE(TAIL_MEDIUM)
|
||||
NODE_NAME_CASE(TAIL_LARGE)
|
||||
NODE_NAME_CASE(SELECT_CC)
|
||||
NODE_NAME_CASE(BR_CC)
|
||||
NODE_NAME_CASE(BRCOND)
|
||||
NODE_NAME_CASE(SLL_W)
|
||||
NODE_NAME_CASE(SRA_W)
|
||||
NODE_NAME_CASE(SRL_W)
|
||||
NODE_NAME_CASE(BSTRINS)
|
||||
NODE_NAME_CASE(BSTRPICK)
|
||||
NODE_NAME_CASE(MOVGR2FR_W)
|
||||
NODE_NAME_CASE(MOVGR2FR_W_LA64)
|
||||
NODE_NAME_CASE(MOVGR2FR_D)
|
||||
NODE_NAME_CASE(MOVGR2FR_D_LO_HI)
|
||||
NODE_NAME_CASE(MOVFR2GR_S_LA64)
|
||||
NODE_NAME_CASE(FTINT)
|
||||
NODE_NAME_CASE(BUILD_PAIR_F64)
|
||||
NODE_NAME_CASE(SPLIT_PAIR_F64)
|
||||
NODE_NAME_CASE(REVB_2H)
|
||||
NODE_NAME_CASE(REVB_2W)
|
||||
NODE_NAME_CASE(BITREV_4B)
|
||||
NODE_NAME_CASE(BITREV_8B)
|
||||
NODE_NAME_CASE(BITREV_W)
|
||||
NODE_NAME_CASE(ROTR_W)
|
||||
NODE_NAME_CASE(ROTL_W)
|
||||
NODE_NAME_CASE(DIV_W)
|
||||
NODE_NAME_CASE(DIV_WU)
|
||||
NODE_NAME_CASE(MOD_W)
|
||||
NODE_NAME_CASE(MOD_WU)
|
||||
NODE_NAME_CASE(CLZ_W)
|
||||
NODE_NAME_CASE(CTZ_W)
|
||||
NODE_NAME_CASE(DBAR)
|
||||
NODE_NAME_CASE(IBAR)
|
||||
NODE_NAME_CASE(BREAK)
|
||||
NODE_NAME_CASE(SYSCALL)
|
||||
NODE_NAME_CASE(CRC_W_B_W)
|
||||
NODE_NAME_CASE(CRC_W_H_W)
|
||||
NODE_NAME_CASE(CRC_W_W_W)
|
||||
NODE_NAME_CASE(CRC_W_D_W)
|
||||
NODE_NAME_CASE(CRCC_W_B_W)
|
||||
NODE_NAME_CASE(CRCC_W_H_W)
|
||||
NODE_NAME_CASE(CRCC_W_W_W)
|
||||
NODE_NAME_CASE(CRCC_W_D_W)
|
||||
NODE_NAME_CASE(CSRRD)
|
||||
NODE_NAME_CASE(CSRWR)
|
||||
NODE_NAME_CASE(CSRXCHG)
|
||||
NODE_NAME_CASE(IOCSRRD_B)
|
||||
NODE_NAME_CASE(IOCSRRD_H)
|
||||
NODE_NAME_CASE(IOCSRRD_W)
|
||||
NODE_NAME_CASE(IOCSRRD_D)
|
||||
NODE_NAME_CASE(IOCSRWR_B)
|
||||
NODE_NAME_CASE(IOCSRWR_H)
|
||||
NODE_NAME_CASE(IOCSRWR_W)
|
||||
NODE_NAME_CASE(IOCSRWR_D)
|
||||
NODE_NAME_CASE(CPUCFG)
|
||||
NODE_NAME_CASE(MOVGR2FCSR)
|
||||
NODE_NAME_CASE(MOVFCSR2GR)
|
||||
NODE_NAME_CASE(CACOP_D)
|
||||
NODE_NAME_CASE(CACOP_W)
|
||||
NODE_NAME_CASE(VSHUF)
|
||||
NODE_NAME_CASE(VPICKEV)
|
||||
NODE_NAME_CASE(VPICKOD)
|
||||
NODE_NAME_CASE(VPACKEV)
|
||||
NODE_NAME_CASE(VPACKOD)
|
||||
NODE_NAME_CASE(VILVL)
|
||||
NODE_NAME_CASE(VILVH)
|
||||
NODE_NAME_CASE(VSHUF4I)
|
||||
NODE_NAME_CASE(VREPLVEI)
|
||||
NODE_NAME_CASE(VREPLGR2VR)
|
||||
NODE_NAME_CASE(XVPERMI)
|
||||
NODE_NAME_CASE(XVPERM)
|
||||
NODE_NAME_CASE(XVREPLVE0)
|
||||
NODE_NAME_CASE(XVREPLVE0Q)
|
||||
NODE_NAME_CASE(XVINSVE0)
|
||||
NODE_NAME_CASE(VPICK_SEXT_ELT)
|
||||
NODE_NAME_CASE(VPICK_ZEXT_ELT)
|
||||
NODE_NAME_CASE(VREPLVE)
|
||||
NODE_NAME_CASE(VALL_ZERO)
|
||||
NODE_NAME_CASE(VANY_ZERO)
|
||||
NODE_NAME_CASE(VALL_NONZERO)
|
||||
NODE_NAME_CASE(VANY_NONZERO)
|
||||
NODE_NAME_CASE(FRECIPE)
|
||||
NODE_NAME_CASE(FRSQRTE)
|
||||
NODE_NAME_CASE(VSLLI)
|
||||
NODE_NAME_CASE(VSRLI)
|
||||
NODE_NAME_CASE(VBSLL)
|
||||
NODE_NAME_CASE(VBSRL)
|
||||
NODE_NAME_CASE(VLDREPL)
|
||||
NODE_NAME_CASE(VMSKLTZ)
|
||||
NODE_NAME_CASE(VMSKGEZ)
|
||||
NODE_NAME_CASE(VMSKEQZ)
|
||||
NODE_NAME_CASE(VMSKNEZ)
|
||||
NODE_NAME_CASE(XVMSKLTZ)
|
||||
NODE_NAME_CASE(XVMSKGEZ)
|
||||
NODE_NAME_CASE(XVMSKEQZ)
|
||||
NODE_NAME_CASE(XVMSKNEZ)
|
||||
NODE_NAME_CASE(VHADDW)
|
||||
}
|
||||
#undef NODE_NAME_CASE
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Calling Convention Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@ -21,179 +21,6 @@
|
||||
|
||||
namespace llvm {
|
||||
class LoongArchSubtarget;
|
||||
namespace LoongArchISD {
|
||||
enum NodeType : unsigned {
|
||||
FIRST_NUMBER = ISD::BUILTIN_OP_END,
|
||||
|
||||
// TODO: add more LoongArchISDs
|
||||
CALL,
|
||||
CALL_MEDIUM,
|
||||
CALL_LARGE,
|
||||
RET,
|
||||
TAIL,
|
||||
TAIL_MEDIUM,
|
||||
TAIL_LARGE,
|
||||
|
||||
// Select
|
||||
SELECT_CC,
|
||||
|
||||
// Branch
|
||||
BR_CC,
|
||||
BRCOND,
|
||||
|
||||
// 32-bit shifts, directly matching the semantics of the named LoongArch
|
||||
// instructions.
|
||||
SLL_W,
|
||||
SRA_W,
|
||||
SRL_W,
|
||||
|
||||
ROTL_W,
|
||||
ROTR_W,
|
||||
|
||||
// unsigned 32-bit integer division
|
||||
DIV_W,
|
||||
MOD_W,
|
||||
DIV_WU,
|
||||
MOD_WU,
|
||||
|
||||
// FPR<->GPR transfer operations
|
||||
MOVGR2FR_W,
|
||||
MOVGR2FR_W_LA64,
|
||||
MOVGR2FR_D,
|
||||
MOVGR2FR_D_LO_HI,
|
||||
MOVFR2GR_S_LA64,
|
||||
MOVFCSR2GR,
|
||||
MOVGR2FCSR,
|
||||
|
||||
FTINT,
|
||||
|
||||
// Build and split F64 pair
|
||||
BUILD_PAIR_F64,
|
||||
SPLIT_PAIR_F64,
|
||||
|
||||
// Bit counting operations
|
||||
CLZ_W,
|
||||
CTZ_W,
|
||||
|
||||
BSTRINS,
|
||||
BSTRPICK,
|
||||
|
||||
// Byte-swapping and bit-reversal
|
||||
REVB_2H,
|
||||
REVB_2W,
|
||||
BITREV_4B,
|
||||
BITREV_8B,
|
||||
BITREV_W,
|
||||
|
||||
// Intrinsic operations start ============================================
|
||||
BREAK,
|
||||
CACOP_D,
|
||||
CACOP_W,
|
||||
DBAR,
|
||||
IBAR,
|
||||
SYSCALL,
|
||||
|
||||
// CRC check operations
|
||||
CRC_W_B_W,
|
||||
CRC_W_H_W,
|
||||
CRC_W_W_W,
|
||||
CRC_W_D_W,
|
||||
CRCC_W_B_W,
|
||||
CRCC_W_H_W,
|
||||
CRCC_W_W_W,
|
||||
CRCC_W_D_W,
|
||||
|
||||
CSRRD,
|
||||
|
||||
// Write new value to CSR and return old value.
|
||||
// Operand 0: A chain pointer.
|
||||
// Operand 1: The new value to write.
|
||||
// Operand 2: The address of the required CSR.
|
||||
// Result 0: The old value of the CSR.
|
||||
// Result 1: The new chain pointer.
|
||||
CSRWR,
|
||||
|
||||
// Similar to CSRWR but with a write mask.
|
||||
// Operand 0: A chain pointer.
|
||||
// Operand 1: The new value to write.
|
||||
// Operand 2: The write mask.
|
||||
// Operand 3: The address of the required CSR.
|
||||
// Result 0: The old value of the CSR.
|
||||
// Result 1: The new chain pointer.
|
||||
CSRXCHG,
|
||||
|
||||
// IOCSR access operations
|
||||
IOCSRRD_B,
|
||||
IOCSRRD_W,
|
||||
IOCSRRD_H,
|
||||
IOCSRRD_D,
|
||||
IOCSRWR_B,
|
||||
IOCSRWR_H,
|
||||
IOCSRWR_W,
|
||||
IOCSRWR_D,
|
||||
|
||||
// Read CPU configuration information operation
|
||||
CPUCFG,
|
||||
|
||||
// Vector Shuffle
|
||||
VREPLVE,
|
||||
VSHUF,
|
||||
VPICKEV,
|
||||
VPICKOD,
|
||||
VPACKEV,
|
||||
VPACKOD,
|
||||
VILVL,
|
||||
VILVH,
|
||||
VSHUF4I,
|
||||
VREPLVEI,
|
||||
VREPLGR2VR,
|
||||
XVPERMI,
|
||||
XVPERM,
|
||||
XVREPLVE0,
|
||||
XVREPLVE0Q,
|
||||
XVINSVE0,
|
||||
|
||||
// Extended vector element extraction
|
||||
VPICK_SEXT_ELT,
|
||||
VPICK_ZEXT_ELT,
|
||||
|
||||
// Vector comparisons
|
||||
VALL_ZERO,
|
||||
VANY_ZERO,
|
||||
VALL_NONZERO,
|
||||
VANY_NONZERO,
|
||||
|
||||
// Floating point approximate reciprocal operation
|
||||
FRECIPE,
|
||||
FRSQRTE,
|
||||
|
||||
// Vector logicial left / right shift by immediate
|
||||
VSLLI,
|
||||
VSRLI,
|
||||
|
||||
// Vector byte logicial left / right shift
|
||||
VBSLL,
|
||||
VBSRL,
|
||||
|
||||
// Scalar load broadcast to vector
|
||||
VLDREPL,
|
||||
|
||||
// Vector mask set by condition
|
||||
VMSKLTZ,
|
||||
VMSKGEZ,
|
||||
VMSKEQZ,
|
||||
VMSKNEZ,
|
||||
XVMSKLTZ,
|
||||
XVMSKGEZ,
|
||||
XVMSKEQZ,
|
||||
XVMSKNEZ,
|
||||
|
||||
// Vector Horizontal Addition with Widening
|
||||
VHADDW
|
||||
|
||||
// Intrinsic operations end =============================================
|
||||
};
|
||||
} // end namespace LoongArchISD
|
||||
|
||||
class LoongArchTargetLowering : public TargetLowering {
|
||||
const LoongArchSubtarget &Subtarget;
|
||||
@ -213,9 +40,6 @@ public:
|
||||
|
||||
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
|
||||
|
||||
// This method returns the name of a target specific DAG node.
|
||||
const char *getTargetNodeName(unsigned Opcode) const override;
|
||||
|
||||
// Lower incoming arguments, copy physregs into vregs.
|
||||
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
|
||||
bool IsVarArg,
|
||||
|
||||
@ -100,14 +100,22 @@ def loongarch_tail_large : SDNode<"LoongArchISD::TAIL_LARGE", SDT_LoongArchCall,
|
||||
def loongarch_selectcc : SDNode<"LoongArchISD::SELECT_CC", SDT_LoongArchSelectCC>;
|
||||
def loongarch_brcc : SDNode<"LoongArchISD::BR_CC", SDT_LoongArchBrCC,
|
||||
[SDNPHasChain]>;
|
||||
|
||||
// 32-bit shifts, directly matching the semantics of the named LoongArch
|
||||
// instructions.
|
||||
def loongarch_sll_w : SDNode<"LoongArchISD::SLL_W", SDT_LoongArchIntBinOpW>;
|
||||
def loongarch_sra_w : SDNode<"LoongArchISD::SRA_W", SDT_LoongArchIntBinOpW>;
|
||||
def loongarch_srl_w : SDNode<"LoongArchISD::SRL_W", SDT_LoongArchIntBinOpW>;
|
||||
|
||||
def loongarch_rotr_w : SDNode<"LoongArchISD::ROTR_W", SDT_LoongArchIntBinOpW>;
|
||||
|
||||
// unsigned 32-bit integer division
|
||||
def loongarch_div_w : SDNode<"LoongArchISD::DIV_W", SDT_LoongArchIntBinOpW>;
|
||||
def loongarch_div_wu : SDNode<"LoongArchISD::DIV_WU", SDT_LoongArchIntBinOpW>;
|
||||
def loongarch_mod_w : SDNode<"LoongArchISD::MOD_W", SDT_LoongArchIntBinOpW>;
|
||||
def loongarch_mod_wu : SDNode<"LoongArchISD::MOD_WU", SDT_LoongArchIntBinOpW>;
|
||||
|
||||
// CRC check operations
|
||||
def loongarch_crc_w_b_w
|
||||
: SDNode<"LoongArchISD::CRC_W_B_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
|
||||
def loongarch_crc_w_h_w
|
||||
@ -124,37 +132,63 @@ def loongarch_crcc_w_w_w : SDNode<"LoongArchISD::CRCC_W_W_W",
|
||||
SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
|
||||
def loongarch_crcc_w_d_w : SDNode<"LoongArchISD::CRCC_W_D_W",
|
||||
SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
|
||||
|
||||
def loongarch_bstrins
|
||||
: SDNode<"LoongArchISD::BSTRINS", SDT_LoongArchBStrIns>;
|
||||
def loongarch_bstrpick
|
||||
: SDNode<"LoongArchISD::BSTRPICK", SDT_LoongArchBStrPick>;
|
||||
|
||||
// Byte-swapping and bit-reversal
|
||||
def loongarch_revb_2h : SDNode<"LoongArchISD::REVB_2H", SDTUnaryOp>;
|
||||
def loongarch_revb_2w : SDNode<"LoongArchISD::REVB_2W", SDTUnaryOp>;
|
||||
def loongarch_bitrev_4b : SDNode<"LoongArchISD::BITREV_4B", SDTUnaryOp>;
|
||||
def loongarch_bitrev_8b : SDNode<"LoongArchISD::BITREV_8B", SDTUnaryOp>;
|
||||
def loongarch_bitrev_w : SDNode<"LoongArchISD::BITREV_W", SDTUnaryOp>;
|
||||
|
||||
// Bit counting operations
|
||||
def loongarch_clzw : SDNode<"LoongArchISD::CLZ_W", SDTIntBitCountUnaryOp>;
|
||||
def loongarch_ctzw : SDNode<"LoongArchISD::CTZ_W", SDTIntBitCountUnaryOp>;
|
||||
|
||||
def loongarch_dbar : SDNode<"LoongArchISD::DBAR", SDT_LoongArchVI,
|
||||
[SDNPHasChain, SDNPSideEffect]>;
|
||||
def loongarch_ibar : SDNode<"LoongArchISD::IBAR", SDT_LoongArchVI,
|
||||
[SDNPHasChain, SDNPSideEffect]>;
|
||||
def loongarch_break : SDNode<"LoongArchISD::BREAK", SDT_LoongArchVI,
|
||||
[SDNPHasChain, SDNPSideEffect]>;
|
||||
|
||||
// FPR<->GPR transfer operations
|
||||
def loongarch_movfcsr2gr : SDNode<"LoongArchISD::MOVFCSR2GR",
|
||||
SDT_LoongArchMovfcsr2gr, [SDNPHasChain]>;
|
||||
def loongarch_movgr2fcsr : SDNode<"LoongArchISD::MOVGR2FCSR",
|
||||
SDT_LoongArchMovgr2fcsr,
|
||||
[SDNPHasChain, SDNPSideEffect]>;
|
||||
|
||||
def loongarch_syscall : SDNode<"LoongArchISD::SYSCALL", SDT_LoongArchVI,
|
||||
[SDNPHasChain, SDNPSideEffect]>;
|
||||
def loongarch_csrrd : SDNode<"LoongArchISD::CSRRD", SDT_LoongArchCsrrd,
|
||||
[SDNPHasChain, SDNPSideEffect]>;
|
||||
|
||||
// Write new value to CSR and return old value.
|
||||
// Operand 0: A chain pointer.
|
||||
// Operand 1: The new value to write.
|
||||
// Operand 2: The address of the required CSR.
|
||||
// Result 0: The old value of the CSR.
|
||||
// Result 1: The new chain pointer.
|
||||
def loongarch_csrwr : SDNode<"LoongArchISD::CSRWR", SDT_LoongArchCsrwr,
|
||||
[SDNPHasChain, SDNPSideEffect]>;
|
||||
|
||||
// Similar to CSRWR but with a write mask.
|
||||
// Operand 0: A chain pointer.
|
||||
// Operand 1: The new value to write.
|
||||
// Operand 2: The write mask.
|
||||
// Operand 3: The address of the required CSR.
|
||||
// Result 0: The old value of the CSR.
|
||||
// Result 1: The new chain pointer.
|
||||
def loongarch_csrxchg : SDNode<"LoongArchISD::CSRXCHG",
|
||||
SDT_LoongArchCsrxchg,
|
||||
[SDNPHasChain, SDNPSideEffect]>;
|
||||
|
||||
// IOCSR access operations
|
||||
def loongarch_iocsrrd_b : SDNode<"LoongArchISD::IOCSRRD_B", SDTUnaryOp,
|
||||
[SDNPHasChain, SDNPSideEffect]>;
|
||||
def loongarch_iocsrrd_h : SDNode<"LoongArchISD::IOCSRRD_H", SDTUnaryOp,
|
||||
@ -175,9 +209,12 @@ def loongarch_iocsrwr_w : SDNode<"LoongArchISD::IOCSRWR_W",
|
||||
def loongarch_iocsrwr_d : SDNode<"LoongArchISD::IOCSRWR_D",
|
||||
SDT_LoongArchIocsrwr,
|
||||
[SDNPHasChain, SDNPSideEffect]>;
|
||||
|
||||
// Read CPU configuration information operation
|
||||
def loongarch_cpucfg : SDNode<"LoongArchISD::CPUCFG", SDTUnaryOp,
|
||||
[SDNPHasChain]>;
|
||||
|
||||
// Build and split F64 pair
|
||||
def loongarch_build_pair_f64 : SDNode<"LoongArchISD::BUILD_PAIR_F64",
|
||||
SDT_LoongArchBuildPairF64>;
|
||||
def loongarch_split_pair_f64 : SDNode<"LoongArchISD::SPLIT_PAIR_F64",
|
||||
|
||||
@ -16,11 +16,15 @@ def SDT_LoongArchXVREPLVE0 : SDTypeProfile<1, 1, [SDTCisVec<0>,
|
||||
SDTCisSameAs<0, 1>]>;
|
||||
|
||||
// Target nodes.
|
||||
|
||||
// Vector Shuffle
|
||||
def loongarch_xvpermi: SDNode<"LoongArchISD::XVPERMI", SDT_LoongArchV1RUimm>;
|
||||
def loongarch_xvperm: SDNode<"LoongArchISD::XVPERM", SDT_LoongArchXVPERM>;
|
||||
def loongarch_xvreplve0: SDNode<"LoongArchISD::XVREPLVE0", SDT_LoongArchXVREPLVE0>;
|
||||
def loongarch_xvreplve0q: SDNode<"LoongArchISD::XVREPLVE0Q", SDT_LoongArchXVREPLVE0>;
|
||||
def loongarch_xvinsve0 : SDNode<"LoongArchISD::XVINSVE0", SDT_LoongArchV2RUimm>;
|
||||
|
||||
// Vector mask set by condition
|
||||
def loongarch_xvmskltz: SDNode<"LoongArchISD::XVMSKLTZ", SDT_LoongArchVMSKCOND>;
|
||||
def loongarch_xvmskgez: SDNode<"LoongArchISD::XVMSKGEZ", SDT_LoongArchVMSKCOND>;
|
||||
def loongarch_xvmskeqz: SDNode<"LoongArchISD::XVMSKEQZ", SDT_LoongArchVMSKCOND>;
|
||||
|
||||
@ -34,7 +34,11 @@ def SDT_LoongArchVLDREPL : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisPtrTy<1>]>;
|
||||
def SDT_LoongArchVMSKCOND : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisVec<1>]>;
|
||||
|
||||
// Target nodes.
|
||||
|
||||
// Vector Shuffle
|
||||
def loongarch_vreplve : SDNode<"LoongArchISD::VREPLVE", SDT_LoongArchVreplve>;
|
||||
|
||||
// Vector comparisons
|
||||
def loongarch_vall_nonzero : SDNode<"LoongArchISD::VALL_NONZERO",
|
||||
SDT_LoongArchVecCond>;
|
||||
def loongarch_vany_nonzero : SDNode<"LoongArchISD::VANY_NONZERO",
|
||||
@ -44,11 +48,13 @@ def loongarch_vall_zero : SDNode<"LoongArchISD::VALL_ZERO",
|
||||
def loongarch_vany_zero : SDNode<"LoongArchISD::VANY_ZERO",
|
||||
SDT_LoongArchVecCond>;
|
||||
|
||||
// Extended vector element extraction
|
||||
def loongarch_vpick_sext_elt : SDNode<"LoongArchISD::VPICK_SEXT_ELT",
|
||||
SDTypeProfile<1, 3, [SDTCisPtrTy<2>]>>;
|
||||
def loongarch_vpick_zext_elt : SDNode<"LoongArchISD::VPICK_ZEXT_ELT",
|
||||
SDTypeProfile<1, 3, [SDTCisPtrTy<2>]>>;
|
||||
|
||||
// Vector Shuffle
|
||||
def loongarch_vshuf: SDNode<"LoongArchISD::VSHUF", SDT_LoongArchVShuf>;
|
||||
def loongarch_vpickev: SDNode<"LoongArchISD::VPICKEV", SDT_LoongArchV2R>;
|
||||
def loongarch_vpickod: SDNode<"LoongArchISD::VPICKOD", SDT_LoongArchV2R>;
|
||||
@ -58,25 +64,30 @@ def loongarch_vilvl: SDNode<"LoongArchISD::VILVL", SDT_LoongArchV2R>;
|
||||
def loongarch_vilvh: SDNode<"LoongArchISD::VILVH", SDT_LoongArchV2R>;
|
||||
|
||||
def loongarch_vshuf4i: SDNode<"LoongArchISD::VSHUF4I", SDT_LoongArchV1RUimm>;
|
||||
def loongarch_vshuf4i_d : SDNode<"LoongArchISD::VSHUF4I", SDT_LoongArchV2RUimm>;
|
||||
def loongarch_vshuf4i_d : SDNode<"LoongArchISD::VSHUF4I_D", SDT_LoongArchV2RUimm>;
|
||||
def loongarch_vreplvei: SDNode<"LoongArchISD::VREPLVEI", SDT_LoongArchV1RUimm>;
|
||||
def loongarch_vreplgr2vr: SDNode<"LoongArchISD::VREPLGR2VR", SDT_LoongArchVreplgr2vr>;
|
||||
|
||||
def loongarch_vfrecipe: SDNode<"LoongArchISD::FRECIPE", SDT_LoongArchVFRECIPE>;
|
||||
def loongarch_vfrsqrte: SDNode<"LoongArchISD::FRSQRTE", SDT_LoongArchVFRSQRTE>;
|
||||
|
||||
// Vector logicial left / right shift by immediate
|
||||
def loongarch_vslli : SDNode<"LoongArchISD::VSLLI", SDT_LoongArchV1RUimm>;
|
||||
def loongarch_vsrli : SDNode<"LoongArchISD::VSRLI", SDT_LoongArchV1RUimm>;
|
||||
|
||||
// Vector byte logicial left / right shift
|
||||
def loongarch_vbsll : SDNode<"LoongArchISD::VBSLL", SDT_LoongArchV1RUimm>;
|
||||
def loongarch_vbsrl : SDNode<"LoongArchISD::VBSRL", SDT_LoongArchV1RUimm>;
|
||||
|
||||
// Vector Horizontal Addition with Widening
|
||||
def loongarch_vhaddw : SDNode<"LoongArchISD::VHADDW", SDT_LoongArchV2R>;
|
||||
|
||||
// Scalar load broadcast to vector
|
||||
def loongarch_vldrepl
|
||||
: SDNode<"LoongArchISD::VLDREPL",
|
||||
SDT_LoongArchVLDREPL, [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
|
||||
|
||||
// Vector mask set by condition
|
||||
def loongarch_vmskltz: SDNode<"LoongArchISD::VMSKLTZ", SDT_LoongArchVMSKCOND>;
|
||||
def loongarch_vmskgez: SDNode<"LoongArchISD::VMSKGEZ", SDT_LoongArchVMSKCOND>;
|
||||
def loongarch_vmskeqz: SDNode<"LoongArchISD::VMSKEQZ", SDT_LoongArchVMSKCOND>;
|
||||
|
||||
29
llvm/lib/Target/LoongArch/LoongArchSelectionDAGInfo.cpp
Normal file
29
llvm/lib/Target/LoongArch/LoongArchSelectionDAGInfo.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "LoongArchSelectionDAGInfo.h"
|
||||
|
||||
#define GET_SDNODE_DESC
|
||||
#include "LoongArchGenSDNodeInfo.inc"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
LoongArchSelectionDAGInfo::LoongArchSelectionDAGInfo()
|
||||
: SelectionDAGGenTargetInfo(LoongArchGenSDNodeInfo) {}
|
||||
|
||||
LoongArchSelectionDAGInfo::~LoongArchSelectionDAGInfo() = default;
|
||||
|
||||
void LoongArchSelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG,
|
||||
const SDNode *N) const {
|
||||
switch (N->getOpcode()) {
|
||||
case LoongArchISD::VLDREPL:
|
||||
// invalid number of operands; expected 2, got 3
|
||||
return;
|
||||
}
|
||||
SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);
|
||||
}
|
||||
31
llvm/lib/Target/LoongArch/LoongArchSelectionDAGInfo.h
Normal file
31
llvm/lib/Target/LoongArch/LoongArchSelectionDAGInfo.h
Normal file
@ -0,0 +1,31 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHSELECTIONDAGINFO_H
|
||||
#define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHSELECTIONDAGINFO_H
|
||||
|
||||
#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
|
||||
|
||||
#define GET_SDNODE_ENUM
|
||||
#include "LoongArchGenSDNodeInfo.inc"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class LoongArchSelectionDAGInfo : public SelectionDAGGenTargetInfo {
|
||||
public:
|
||||
LoongArchSelectionDAGInfo();
|
||||
|
||||
~LoongArchSelectionDAGInfo() override;
|
||||
|
||||
void verifyTargetNode(const SelectionDAG &DAG,
|
||||
const SDNode *N) const override;
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHSELECTIONDAGINFO_H
|
||||
@ -12,6 +12,7 @@
|
||||
|
||||
#include "LoongArchSubtarget.h"
|
||||
#include "LoongArchFrameLowering.h"
|
||||
#include "LoongArchSelectionDAGInfo.h"
|
||||
#include "MCTargetDesc/LoongArchBaseInfo.h"
|
||||
|
||||
using namespace llvm;
|
||||
@ -95,4 +96,12 @@ LoongArchSubtarget::LoongArchSubtarget(const Triple &TT, StringRef CPU,
|
||||
: LoongArchGenSubtargetInfo(TT, CPU, TuneCPU, FS),
|
||||
FrameLowering(
|
||||
initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
|
||||
InstrInfo(*this), TLInfo(TM, *this) {}
|
||||
InstrInfo(*this), TLInfo(TM, *this) {
|
||||
TSInfo = std::make_unique<LoongArchSelectionDAGInfo>();
|
||||
}
|
||||
|
||||
LoongArchSubtarget::~LoongArchSubtarget() = default;
|
||||
|
||||
const SelectionDAGTargetInfo *LoongArchSubtarget::getSelectionDAGInfo() const {
|
||||
return TSInfo.get();
|
||||
}
|
||||
|
||||
@ -18,7 +18,6 @@
|
||||
#include "LoongArchInstrInfo.h"
|
||||
#include "LoongArchRegisterInfo.h"
|
||||
#include "MCTargetDesc/LoongArchBaseInfo.h"
|
||||
#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
|
||||
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
@ -46,7 +45,7 @@ class LoongArchSubtarget : public LoongArchGenSubtargetInfo {
|
||||
LoongArchFrameLowering FrameLowering;
|
||||
LoongArchInstrInfo InstrInfo;
|
||||
LoongArchTargetLowering TLInfo;
|
||||
SelectionDAGTargetInfo TSInfo;
|
||||
std::unique_ptr<const SelectionDAGTargetInfo> TSInfo;
|
||||
|
||||
Align PrefFunctionAlignment;
|
||||
Align PrefLoopAlignment;
|
||||
@ -68,6 +67,8 @@ public:
|
||||
LoongArchSubtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU,
|
||||
StringRef FS, StringRef ABIName, const TargetMachine &TM);
|
||||
|
||||
~LoongArchSubtarget() override;
|
||||
|
||||
// Parses features string setting specified subtarget options. The
|
||||
// definition of this function is auto-generated by tblgen.
|
||||
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
|
||||
@ -82,9 +83,8 @@ public:
|
||||
const LoongArchTargetLowering *getTargetLowering() const override {
|
||||
return &TLInfo;
|
||||
}
|
||||
const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
|
||||
return &TSInfo;
|
||||
}
|
||||
|
||||
const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;
|
||||
|
||||
#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
|
||||
bool GETTER() const { return ATTRIBUTE; }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user