[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