forked from OSchip/llvm-project
[RISCV] Implement c.lui immediate operand constraint
Implement c.lui immediate constraint to [1, 31] and [0xfffe0, 0xfffff]. The RISC-V ISA describes the constraint as [1, 63], with that value being 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]. Differential Revision: https://reviews.llvm.org/D42834 llvm-svn: 325792
This commit is contained in:
parent
6c1e6bbe0c
commit
7c17242b92
|
@ -273,12 +273,13 @@ public:
|
|||
(VK == RISCVMCExpr::VK_RISCV_None || VK == RISCVMCExpr::VK_RISCV_LO);
|
||||
}
|
||||
|
||||
bool isUImm6NonZero() const {
|
||||
bool isCLUIImm() const {
|
||||
int64_t Imm;
|
||||
RISCVMCExpr::VariantKind VK;
|
||||
bool IsConstantImm = evaluateConstantImm(Imm, VK);
|
||||
return IsConstantImm && isUInt<6>(Imm) && (Imm != 0) &&
|
||||
VK == RISCVMCExpr::VK_RISCV_None;
|
||||
return IsConstantImm && (Imm != 0) &&
|
||||
(isUInt<5>(Imm) || (Imm >= 0xfffe0 && Imm <= 0xfffff)) &&
|
||||
VK == RISCVMCExpr::VK_RISCV_None;
|
||||
}
|
||||
|
||||
bool isUImm7Lsb00() const {
|
||||
|
@ -631,8 +632,10 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
|
||||
(1 << 5) - 1,
|
||||
"immediate must be non-zero in the range");
|
||||
case Match_InvalidUImm6NonZero:
|
||||
return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
|
||||
case Match_InvalidCLUIImm:
|
||||
return generateImmOutOfRangeError(
|
||||
Operands, ErrorInfo, 1, (1 << 5) - 1,
|
||||
"immediate must be in [0xfffe0, 0xfffff] or");
|
||||
case Match_InvalidUImm7Lsb00:
|
||||
return generateImmOutOfRangeError(
|
||||
Operands, ErrorInfo, 0, (1 << 7) - 4,
|
||||
|
|
|
@ -232,6 +232,17 @@ static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm,
|
|||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint64_t Imm,
|
||||
int64_t Address,
|
||||
const void *Decoder) {
|
||||
assert(isUInt<6>(Imm) && "Invalid immediate");
|
||||
if (Imm > 31) {
|
||||
Imm = (SignExtend64<6>(Imm) & 0xfffff);
|
||||
}
|
||||
Inst.addOperand(MCOperand::createImm(Imm));
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
#include "RISCVGenDisassemblerTables.inc"
|
||||
|
||||
DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
|
||||
|
|
|
@ -42,10 +42,25 @@ def simm6nonzero : Operand<XLenVT>,
|
|||
let DecoderMethod = "decodeSImmOperand<6>";
|
||||
}
|
||||
|
||||
def uimm6nonzero : Operand<XLenVT>,
|
||||
ImmLeaf<XLenVT, [{return isUInt<6>(Imm) && (Imm != 0);}]> {
|
||||
let ParserMatchClass = UImmAsmOperand<6, "NonZero">;
|
||||
let DecoderMethod = "decodeUImmOperand<6>";
|
||||
def CLUIImmAsmOperand : AsmOperandClass {
|
||||
let Name = "CLUIImm";
|
||||
let RenderMethod = "addImmOperands";
|
||||
let DiagnosticType = !strconcat("Invalid", Name);
|
||||
}
|
||||
|
||||
|
||||
// c_lui_imm checks the immediate range is in [1, 31] or [0xfffe0, 0xfffff].
|
||||
// The RISC-V ISA describes the constraint as [1, 63], with that value being
|
||||
// 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>,
|
||||
ImmLeaf<XLenVT, [{return (Imm != 0) &&
|
||||
(isUInt<5>(Imm) ||
|
||||
(Imm >= 0xfffe0 && Imm <= 0xfffff));}]> {
|
||||
let ParserMatchClass = CLUIImmAsmOperand;
|
||||
let EncoderMethod = "getImmOpValue";
|
||||
let DecoderMethod = "decodeCLUIImmOperand";
|
||||
}
|
||||
|
||||
// A 7-bit unsigned immediate where the least significant two bits are zero.
|
||||
|
@ -303,7 +318,7 @@ def C_ADDI16SP : RVInst16CI<0b011, 0b01, (outs SP:$rd_wb),
|
|||
|
||||
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
|
||||
def C_LUI : RVInst16CI<0b011, 0b01, (outs GPRNoX0X2:$rd),
|
||||
(ins uimm6nonzero:$imm),
|
||||
(ins c_lui_imm:$imm),
|
||||
"c.lui", "$rd, $imm"> {
|
||||
let Inst{6-2} = imm{4-0};
|
||||
}
|
||||
|
|
|
@ -52,9 +52,11 @@ c.addi t0, 0 # CHECK: :[[@LINE]]:12: error: immediate must be non-zero in the ra
|
|||
c.addi t0, -33 # CHECK: :[[@LINE]]:12: error: immediate must be non-zero in the range [-32, 31]
|
||||
c.addi t0, 32 # CHECK: :[[@LINE]]:12: error: immediate must be non-zero in the range [-32, 31]
|
||||
|
||||
## uimm6nonzero
|
||||
c.lui t0, 64 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [1, 63]
|
||||
c.lui t0, 0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [1, 63]
|
||||
## c_lui_imm
|
||||
c.lui t0, 0 # CHECK: :[[@LINE]]:11: error: immediate must be in [0xfffe0, 0xfffff] or [1, 31]
|
||||
c.lui t0, 32 # CHECK: :[[@LINE]]:11: error: immediate must be in [0xfffe0, 0xfffff] or [1, 31]
|
||||
c.lui t0, 0xffffdf # CHECK: :[[@LINE]]:11: error: immediate must be in [0xfffe0, 0xfffff] or [1, 31]
|
||||
c.lui t0, 0x1000000 # CHECK: :[[@LINE]]:11: error: immediate must be in [0xfffe0, 0xfffff] or [1, 31]
|
||||
|
||||
## uimm8_lsb00
|
||||
c.lwsp ra, 256(sp) # CHECK: :[[@LINE]]:13: error: immediate must be a multiple of 4 bytes in the range [0, 252]
|
||||
|
|
|
@ -94,6 +94,12 @@ c.ebreak
|
|||
# CHECK-INST: c.lui s0, 1
|
||||
# CHECK: encoding: [0x05,0x64]
|
||||
c.lui s0, 1
|
||||
# CHECK-INST: c.lui s0, 63
|
||||
# CHECK-INST: c.lui s0, 31
|
||||
# CHECK: encoding: [0x7d,0x64]
|
||||
c.lui s0, 31
|
||||
# CHECK-INST: c.lui s0, 1048544
|
||||
# CHECK: encoding: [0x01,0x74]
|
||||
c.lui s0, 0xfffe0
|
||||
# CHECK-INST: c.lui s0, 1048575
|
||||
# CHECK: encoding: [0x7d,0x74]
|
||||
c.lui s0, 63
|
||||
c.lui s0, 0xfffff
|
||||
|
|
Loading…
Reference in New Issue