Skip to content

[RISCV][NFC] Add base classes of Operand and uimm/simm #68472

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 42 additions & 79 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -149,18 +149,40 @@ class UImmAsmOperand<int width, string suffix = "">
: ImmAsmOperand<"U", width, suffix> {
}

class RISCVOp<ValueType vt = XLenVT> : Operand<vt> {
let OperandNamespace = "RISCVOp";
}

class RISCVUImmOp<int bitsNum> : RISCVOp {
let ParserMatchClass = UImmAsmOperand<bitsNum>;
let DecoderMethod = "decodeUImmOperand<" # bitsNum # ">";
let OperandType = "OPERAND_UIMM" # bitsNum;
}

class RISCVUImmLeafOp<int bitsNum> :
RISCVUImmOp<bitsNum>, ImmLeaf<XLenVT, "return isUInt<" # bitsNum # ">(Imm);">;

class RISCVSImmOp<int bitsNum> : RISCVOp {
let ParserMatchClass = SImmAsmOperand<bitsNum>;
let EncoderMethod = "getImmOpValue";
let DecoderMethod = "decodeSImmOperand<" # bitsNum # ">";
let OperandType = "OPERAND_SIMM" # bitsNum;
}

class RISCVSImmLeafOp<int bitsNum > :
RISCVSImmOp<bitsNum>, ImmLeaf<XLenVT, "return isInt<" # bitsNum # ">(Imm);">;

def FenceArg : AsmOperandClass {
let Name = "FenceArg";
let RenderMethod = "addFenceArgOperands";
let ParserMethod = "parseFenceArg";
}

def fencearg : Operand<XLenVT> {
def fencearg : RISCVOp {
let ParserMatchClass = FenceArg;
let PrintMethod = "printFenceArg";
let DecoderMethod = "decodeUImmOperand<4>";
let OperandType = "OPERAND_UIMM4";
let OperandNamespace = "RISCVOp";
}

def UImmLog2XLenAsmOperand : AsmOperandClass {
Expand All @@ -169,7 +191,7 @@ def UImmLog2XLenAsmOperand : AsmOperandClass {
let DiagnosticType = "InvalidUImmLog2XLen";
}

def uimmlog2xlen : Operand<XLenVT>, ImmLeaf<XLenVT, [{
def uimmlog2xlen : RISCVOp, ImmLeaf<XLenVT, [{
if (Subtarget->is64Bit())
return isUInt<6>(Imm);
return isUInt<5>(Imm);
Expand All @@ -186,97 +208,40 @@ def uimmlog2xlen : Operand<XLenVT>, ImmLeaf<XLenVT, [{
return isUInt<5>(Imm);
}];
let OperandType = "OPERAND_UIMMLOG2XLEN";
let OperandNamespace = "RISCVOp";
}

def uimm1 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isUInt<1>(Imm);}]> {
let ParserMatchClass = UImmAsmOperand<1>;
let DecoderMethod = "decodeUImmOperand<1>";
let OperandType = "OPERAND_UIMM1";
let OperandNamespace = "RISCVOp";
def InsnDirectiveOpcode : AsmOperandClass {
let Name = "InsnDirectiveOpcode";
let ParserMethod = "parseInsnDirectiveOpcode";
let RenderMethod = "addImmOperands";
let PredicateMethod = "isImm";
}

def uimm2 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isUInt<2>(Imm);}]> {
let ParserMatchClass = UImmAsmOperand<2>;
let DecoderMethod = "decodeUImmOperand<2>";
let OperandType = "OPERAND_UIMM2";
let OperandNamespace = "RISCVOp";
def uimm1 : RISCVUImmLeafOp<1>;
def uimm2 : RISCVUImmLeafOp<2> {
let MCOperandPredicate = [{
int64_t Imm;
if (!MCOp.evaluateAsConstantImm(Imm))
return false;
return isUInt<2>(Imm);
}];
}

def uimm3 : Operand<XLenVT> {
let ParserMatchClass = UImmAsmOperand<3>;
let DecoderMethod = "decodeUImmOperand<3>";
let OperandType = "OPERAND_UIMM3";
let OperandNamespace = "RISCVOp";
}

def uimm4 : Operand<XLenVT> {
let ParserMatchClass = UImmAsmOperand<4>;
let DecoderMethod = "decodeUImmOperand<4>";
let OperandType = "OPERAND_UIMM4";
let OperandNamespace = "RISCVOp";
}

def uimm5 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isUInt<5>(Imm);}]> {
let ParserMatchClass = UImmAsmOperand<5>;
let DecoderMethod = "decodeUImmOperand<5>";
let OperandType = "OPERAND_UIMM5";
let OperandNamespace = "RISCVOp";
}

def InsnDirectiveOpcode : AsmOperandClass {
let Name = "InsnDirectiveOpcode";
let ParserMethod = "parseInsnDirectiveOpcode";
let RenderMethod = "addImmOperands";
let PredicateMethod = "isImm";
}

def uimm6 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isUInt<6>(Imm);}]> {
let ParserMatchClass = UImmAsmOperand<6>;
let DecoderMethod = "decodeUImmOperand<6>";
let OperandType = "OPERAND_UIMM6";
let OperandNamespace = "RISCVOp";
}

def uimm7_opcode : Operand<XLenVT> {
def uimm3 : RISCVUImmOp<3>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not make all these uimm node as RISCVUImmLeafOp because these nodes may be used in downstream patterns? I think there is no harm than RISCVUImmOp

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding more ImmLeafs will increase predicate code CheckNodePredicate in generated RISCVGenDAGISel.inc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there much effect obviously?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not much.
I'm not opposed to do this and you can fire a PR for this.

def uimm4 : RISCVUImmOp<4>;
def uimm5 : RISCVUImmLeafOp<5>;
def uimm6 : RISCVUImmLeafOp<6>;
def uimm7_opcode : RISCVUImmOp<7> {
let ParserMatchClass = InsnDirectiveOpcode;
let DecoderMethod = "decodeUImmOperand<7>";
let OperandType = "OPERAND_UIMM7";
let OperandNamespace = "RISCVOp";
}

def uimm7 : Operand<XLenVT> {
let ParserMatchClass = UImmAsmOperand<7>;
let DecoderMethod = "decodeUImmOperand<7>";
let OperandType = "OPERAND_UIMM7";
let OperandNamespace = "RISCVOp";
}

def uimm8 : Operand<XLenVT> {
let ParserMatchClass = UImmAsmOperand<8>;
let DecoderMethod = "decodeUImmOperand<8>";
let OperandType = "OPERAND_UIMM8";
let OperandNamespace = "RISCVOp";
}

def simm12 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<12>(Imm);}]> {
let ParserMatchClass = SImmAsmOperand<12>;
let EncoderMethod = "getImmOpValue";
let DecoderMethod = "decodeSImmOperand<12>";
def uimm7 : RISCVUImmOp<7>;
def uimm8 : RISCVUImmOp<8>;
def simm12 : RISCVSImmLeafOp<12> {
let MCOperandPredicate = [{
int64_t Imm;
if (MCOp.evaluateAsConstantImm(Imm))
return isInt<12>(Imm);
return MCOp.isBareSymbolRef();
}];
let OperandType = "OPERAND_SIMM12";
let OperandNamespace = "RISCVOp";
}

// A 12-bit signed immediate which cannot fit in 6-bit signed immediate,
Expand All @@ -299,11 +264,10 @@ def simm13_lsb0 : Operand<OtherVT> {
let OperandType = "OPERAND_PCREL";
}

class UImm20Operand : Operand<XLenVT> {
class UImm20Operand : RISCVOp {
let EncoderMethod = "getImmOpValue";
let DecoderMethod = "decodeUImmOperand<20>";
let OperandType = "OPERAND_UIMM20";
let OperandNamespace = "RISCVOp";
}

class UImm20OperandMaybeSym : UImm20Operand {
Expand Down Expand Up @@ -405,12 +369,11 @@ def CSRSystemRegister : AsmOperandClass {
let DiagnosticType = "InvalidCSRSystemRegister";
}

def csr_sysreg : Operand<XLenVT> {
def csr_sysreg : RISCVOp {
let ParserMatchClass = CSRSystemRegister;
let PrintMethod = "printCSRSystemRegister";
let DecoderMethod = "decodeUImmOperand<12>";
let OperandType = "OPERAND_UIMM12";
let OperandNamespace = "RISCVOp";
}

// A parameterized register class alternative to i32imm/i64imm from Target.td.
Expand Down
40 changes: 12 additions & 28 deletions llvm/lib/Target/RISCV/RISCVInstrInfoC.td
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def UImmLog2XLenNonZeroAsmOperand : AsmOperandClass {
let DiagnosticType = "InvalidUImmLog2XLenNonZero";
}

def uimmlog2xlennonzero : Operand<XLenVT>, ImmLeaf<XLenVT, [{
def uimmlog2xlennonzero : RISCVOp, ImmLeaf<XLenVT, [{
if (Subtarget->is64Bit())
return isUInt<6>(Imm) && (Imm != 0);
return isUInt<5>(Imm) && (Imm != 0);
Expand All @@ -27,7 +27,6 @@ def uimmlog2xlennonzero : Operand<XLenVT>, ImmLeaf<XLenVT, [{
// TODO: should ensure invalid shamt is rejected when decoding.
let DecoderMethod = "decodeUImmNonZeroOperand<6>";
let OperandType = "OPERAND_UIMMLOG2XLEN_NONZERO";
let OperandNamespace = "RISCVOp";
let MCOperandPredicate = [{
int64_t Imm;
if (!MCOp.evaluateAsConstantImm(Imm))
Expand All @@ -38,12 +37,7 @@ def uimmlog2xlennonzero : Operand<XLenVT>, ImmLeaf<XLenVT, [{
}];
}

def simm6 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<6>(Imm);}]> {
let ParserMatchClass = SImmAsmOperand<6>;
let EncoderMethod = "getImmOpValue";
let DecoderMethod = "decodeSImmOperand<6>";
let OperandType = "OPERAND_SIMM6";
let OperandNamespace = "RISCVOp";
def simm6 : RISCVSImmLeafOp<6> {
let MCOperandPredicate = [{
int64_t Imm;
if (MCOp.evaluateAsConstantImm(Imm))
Expand All @@ -52,13 +46,12 @@ def simm6 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<6>(Imm);}]> {
}];
}

def simm6nonzero : Operand<XLenVT>,
def simm6nonzero : RISCVOp,
ImmLeaf<XLenVT, [{return (Imm != 0) && isInt<6>(Imm);}]> {
let ParserMatchClass = SImmAsmOperand<6, "NonZero">;
let EncoderMethod = "getImmOpValue";
let DecoderMethod = "decodeSImmNonZeroOperand<6>";
let OperandType = "OPERAND_SIMM6_NONZERO";
let OperandNamespace = "RISCVOp";
let MCOperandPredicate = [{
int64_t Imm;
if (MCOp.evaluateAsConstantImm(Imm))
Expand All @@ -67,11 +60,10 @@ def simm6nonzero : Operand<XLenVT>,
}];
}

def immzero : Operand<XLenVT>,
def immzero : RISCVOp,
ImmLeaf<XLenVT, [{return (Imm == 0);}]> {
let ParserMatchClass = ImmZeroAsmOperand;
let OperandType = "OPERAND_ZERO";
let OperandNamespace = "RISCVOp";
}

def CLUIImmAsmOperand : AsmOperandClass {
Expand All @@ -86,15 +78,14 @@ def CLUIImmAsmOperand : AsmOperandClass {
// loaded in to bits 17-12 of the destination register and sign extended from
// bit 17. Therefore, this 6-bit immediate can represent values in the ranges
// [1, 31] and [0xfffe0, 0xfffff].
def c_lui_imm : Operand<XLenVT>,
def c_lui_imm : RISCVOp,
ImmLeaf<XLenVT, [{return (Imm != 0) &&
(isUInt<5>(Imm) ||
(Imm >= 0xfffe0 && Imm <= 0xfffff));}]> {
let ParserMatchClass = CLUIImmAsmOperand;
let EncoderMethod = "getImmOpValue";
let DecoderMethod = "decodeCLUIImmOperand";
let OperandType = "OPERAND_CLUI_IMM";
let OperandNamespace = "RISCVOp";
let MCOperandPredicate = [{
int64_t Imm;
if (MCOp.evaluateAsConstantImm(Imm))
Expand All @@ -105,13 +96,12 @@ def c_lui_imm : Operand<XLenVT>,
}

// A 7-bit unsigned immediate where the least significant two bits are zero.
def uimm7_lsb00 : Operand<XLenVT>,
def uimm7_lsb00 : RISCVOp,
ImmLeaf<XLenVT, [{return isShiftedUInt<5, 2>(Imm);}]> {
let ParserMatchClass = UImmAsmOperand<7, "Lsb00">;
let EncoderMethod = "getImmOpValue";
let DecoderMethod = "decodeUImmOperand<7>";
let OperandType = "OPERAND_UIMM7_LSB00";
let OperandNamespace = "RISCVOp";
let MCOperandPredicate = [{
int64_t Imm;
if (!MCOp.evaluateAsConstantImm(Imm))
Expand All @@ -121,13 +111,12 @@ def uimm7_lsb00 : Operand<XLenVT>,
}

// A 8-bit unsigned immediate where the least significant two bits are zero.
def uimm8_lsb00 : Operand<XLenVT>,
def uimm8_lsb00 : RISCVOp,
ImmLeaf<XLenVT, [{return isShiftedUInt<6, 2>(Imm);}]> {
let ParserMatchClass = UImmAsmOperand<8, "Lsb00">;
let EncoderMethod = "getImmOpValue";
let DecoderMethod = "decodeUImmOperand<8>";
let OperandType = "OPERAND_UIMM8_LSB00";
let OperandNamespace = "RISCVOp";
let MCOperandPredicate = [{
int64_t Imm;
if (!MCOp.evaluateAsConstantImm(Imm))
Expand All @@ -137,13 +126,12 @@ def uimm8_lsb00 : Operand<XLenVT>,
}

// A 8-bit unsigned immediate where the least significant three bits are zero.
def uimm8_lsb000 : Operand<XLenVT>,
def uimm8_lsb000 : RISCVOp,
ImmLeaf<XLenVT, [{return isShiftedUInt<5, 3>(Imm);}]> {
let ParserMatchClass = UImmAsmOperand<8, "Lsb000">;
let EncoderMethod = "getImmOpValue";
let DecoderMethod = "decodeUImmOperand<8>";
let OperandType = "OPERAND_UIMM8_LSB000";
let OperandNamespace = "RISCVOp";
let MCOperandPredicate = [{
int64_t Imm;
if (!MCOp.evaluateAsConstantImm(Imm))
Expand All @@ -170,13 +158,12 @@ def simm9_lsb0 : Operand<OtherVT>,
}

// A 9-bit unsigned immediate where the least significant three bits are zero.
def uimm9_lsb000 : Operand<XLenVT>,
def uimm9_lsb000 : RISCVOp,
ImmLeaf<XLenVT, [{return isShiftedUInt<6, 3>(Imm);}]> {
let ParserMatchClass = UImmAsmOperand<9, "Lsb000">;
let EncoderMethod = "getImmOpValue";
let DecoderMethod = "decodeUImmOperand<9>";
let OperandType = "OPERAND_UIMM9_LSB000";
let OperandNamespace = "RISCVOp";
let MCOperandPredicate = [{
int64_t Imm;
if (!MCOp.evaluateAsConstantImm(Imm))
Expand All @@ -187,14 +174,13 @@ def uimm9_lsb000 : Operand<XLenVT>,

// A 10-bit unsigned immediate where the least significant two bits are zero
// and the immediate can't be zero.
def uimm10_lsb00nonzero : Operand<XLenVT>,
def uimm10_lsb00nonzero : RISCVOp,
ImmLeaf<XLenVT,
[{return isShiftedUInt<8, 2>(Imm) && (Imm != 0);}]> {
let ParserMatchClass = UImmAsmOperand<10, "Lsb00NonZero">;
let EncoderMethod = "getImmOpValue";
let DecoderMethod = "decodeUImmNonZeroOperand<10>";
let OperandType = "OPERAND_UIMM10_LSB00_NONZERO";
let OperandNamespace = "RISCVOp";
let MCOperandPredicate = [{
int64_t Imm;
if (!MCOp.evaluateAsConstantImm(Imm))
Expand All @@ -204,14 +190,13 @@ def uimm10_lsb00nonzero : Operand<XLenVT>,
}

// A 10-bit signed immediate where the least significant four bits are zero.
def simm10_lsb0000nonzero : Operand<XLenVT>,
def simm10_lsb0000nonzero : RISCVOp,
ImmLeaf<XLenVT,
[{return (Imm != 0) && isShiftedInt<6, 4>(Imm);}]> {
let ParserMatchClass = SImmAsmOperand<10, "Lsb0000NonZero">;
let EncoderMethod = "getImmOpValue";
let DecoderMethod = "decodeSImmNonZeroOperand<10>";
let OperandType = "OPERAND_SIMM10_LSB0000_NONZERO";
let OperandNamespace = "RISCVOp";
let MCOperandPredicate = [{
int64_t Imm;
if (!MCOp.evaluateAsConstantImm(Imm))
Expand Down Expand Up @@ -243,11 +228,10 @@ def InsnCDirectiveOpcode : AsmOperandClass {
let PredicateMethod = "isImm";
}

def uimm2_opcode : Operand<XLenVT> {
def uimm2_opcode : RISCVOp {
let ParserMatchClass = InsnCDirectiveOpcode;
let DecoderMethod = "decodeUImmOperand<2>";
let OperandType = "OPERAND_UIMM2";
let OperandNamespace = "RISCVOp";
}

//===----------------------------------------------------------------------===//
Expand Down
Loading