Hi,
TL;DR: given a class A : TImmLeaf<i32, [{ return Imm >= 0; }]>; , how can I use ‘min’ instead of ‘0’ in the TImmLeaf predicate?
I am trying to avoid duplication when defining instruction arguments “round number” (context: RISC-V cryptography instructions) which have specific ranges of valid values (e.g., 0-7, 1-10, 2-14).
I was able to use classes pretty successfully, with one caveat. The “Rnum” class inherits from TImmLeaf<> which takes a predicate to validate the value. I am not able to use the template arguments ‘min’ and ‘max’ to generate the predicate block.
Direct attempts to use the arguments fail, with an error stating the the arguments ‘min’ and ‘max’ are undeclared. Below is an attempt to use an intermediary class, with the same result.
Is there a know technique to work around this issue?
Thanks - Eric
class RnumArg<int min, int max> : AsmOperandClass {
// e.g., "Rnum0_31Arg"
let Name = "Rnum" # min # "_" # max # "Arg";
let RenderMethod = "addImmOperands";
// e.g., "InvalidRnum0_31Arg"
let DiagnosticType = "InvalidRnum" # min # "_" # max # "Arg";
}
class Rnum<int min, int max, code pred> : Operand<i32>, TImmLeaf<i32, pred> {
let ParserMatchClass = RnumArg<min, max>;
let EncoderMethod = "getImmOpValue";
let DecoderMethod = "decodeUImmOperand<5>";
let OperandType = "OPERAND_RVKRNUM" # min # "_" # max;
let OperandNamespace = "RISCVOp";
}
class Attempt<int min, int max> : Rnum<min, max, [{return (Imm >= min && Imm <= max);}]>;
// Could we avoid repeating min/max in the predicate code block?
//def rnum0_7 : Rnum<0, 7, [{return (Imm >= 0 && Imm <= 7);}]>;
def rnum0_7 : Attempt<0, 7>;
def rnum0_31 : Rnum<0, 31, [{return (Imm >= 0 && Imm <= 31);}]>;
def rnum1_10 : Rnum<1, 10, [{return (Imm >= 1 && Imm <= 10);}]>;
def rnum2_14 : Rnum<2, 14, [{return (Imm >= 2 && Imm <= 14);}]>;
error: use of undeclared identifier 'min'
return (Imm >= min && Imm <= max);
^