[llvm] r325792 - [RISCV] Implement c.lui immediate operand constraint
Shiva Chen via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 22 07:02:28 PST 2018
Author: shiva
Date: Thu Feb 22 07:02:28 2018
New Revision: 325792
URL: http://llvm.org/viewvc/llvm-project?rev=325792&view=rev
Log:
[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
Modified:
llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
llvm/trunk/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
llvm/trunk/lib/Target/RISCV/RISCVInstrInfoC.td
llvm/trunk/test/MC/RISCV/rv32c-invalid.s
llvm/trunk/test/MC/RISCV/rv32c-valid.s
Modified: llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp?rev=325792&r1=325791&r2=325792&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp Thu Feb 22 07:02:28 2018
@@ -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::MatchAndEmitInstruc
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,
Modified: llvm/trunk/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp?rev=325792&r1=325791&r2=325792&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp Thu Feb 22 07:02:28 2018
@@ -232,6 +232,17 @@ static DecodeStatus decodeSImmOperandAnd
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,
Modified: llvm/trunk/lib/Target/RISCV/RISCVInstrInfoC.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVInstrInfoC.td?rev=325792&r1=325791&r2=325792&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVInstrInfoC.td (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVInstrInfoC.td Thu Feb 22 07:02:28 2018
@@ -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,
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};
}
Modified: llvm/trunk/test/MC/RISCV/rv32c-invalid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rv32c-invalid.s?rev=325792&r1=325791&r2=325792&view=diff
==============================================================================
--- llvm/trunk/test/MC/RISCV/rv32c-invalid.s (original)
+++ llvm/trunk/test/MC/RISCV/rv32c-invalid.s Thu Feb 22 07:02:28 2018
@@ -52,9 +52,11 @@ c.addi t0, 0 # CHECK: :[[@LINE]]:12: err
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]
Modified: llvm/trunk/test/MC/RISCV/rv32c-valid.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/RISCV/rv32c-valid.s?rev=325792&r1=325791&r2=325792&view=diff
==============================================================================
--- llvm/trunk/test/MC/RISCV/rv32c-valid.s (original)
+++ llvm/trunk/test/MC/RISCV/rv32c-valid.s Thu Feb 22 07:02:28 2018
@@ -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
More information about the llvm-commits
mailing list