diff options
author | Alex Bradbury <asb@lowrisc.org> | 2017-12-15 10:20:51 +0000 |
---|---|---|
committer | Alex Bradbury <asb@lowrisc.org> | 2017-12-15 10:20:51 +0000 |
commit | d25fc4439de98bdc83b74f8312c335de8a6fb6bf (patch) | |
tree | bb9d2ec9fc5cb3f1c0ddbc0528c11d54021f3b1a /lib/Target/RISCV | |
parent | aa177330df39c78a8fdf472c0d0741137487c215 (diff) |
[RISCV] Change shift amount operand of RVC shift instructions to uimmlog2xlennonzero
c.slli/c.srli/c.srai allow a 5-bit shift in RV32C and a 6-bit shift in RV64C.
This patch adds uimmlog2xlennonzero to reflect this constraint as well as
tests.
Differential Revision: https://reviews.llvm.org/D41216
Patch by Shiva Chen.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@320799 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/RISCV')
-rw-r--r-- | lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 18 | ||||
-rw-r--r-- | lib/Target/RISCV/RISCVInstrInfoC.td | 24 |
2 files changed, 33 insertions, 9 deletions
diff --git a/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 1bae18bca92..3299a53ff5b 100644 --- a/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -216,6 +216,18 @@ public: return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm); } + bool isUImmLog2XLenNonZero() const { + int64_t Imm; + RISCVMCExpr::VariantKind VK; + if (!isImm()) + return false; + if (!evaluateConstantImm(Imm, VK) || VK != RISCVMCExpr::VK_RISCV_None) + return false; + if (Imm == 0) + return false; + return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm); + } + bool isUImm5() const { int64_t Imm; RISCVMCExpr::VariantKind VK; @@ -592,10 +604,12 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, if (isRV64()) return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); + case Match_InvalidUImmLog2XLenNonZero: + if (isRV64()) + return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1); + return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1); case Match_InvalidUImm5: return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); - case Match_InvalidUImm5NonZero: - return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1); case Match_InvalidSImm6: return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1); diff --git a/lib/Target/RISCV/RISCVInstrInfoC.td b/lib/Target/RISCV/RISCVInstrInfoC.td index 518f5633585..4ca52652086 100644 --- a/lib/Target/RISCV/RISCVInstrInfoC.td +++ b/lib/Target/RISCV/RISCVInstrInfoC.td @@ -13,10 +13,20 @@ include "RISCVInstrFormatsC.td" // Operand definitions. //===----------------------------------------------------------------------===// -def uimm5nonzero : Operand<XLenVT>, - ImmLeaf<XLenVT, [{return isUInt<5>(Imm) && (Imm != 0);}]> { - let ParserMatchClass = UImmAsmOperand<5, "NonZero">; - let DecoderMethod = "decodeUImmOperand<5>"; +def UImmLog2XLenNonZeroAsmOperand : AsmOperandClass { + let Name = "UImmLog2XLenNonZero"; + let RenderMethod = "addImmOperands"; + let DiagnosticType = "InvalidUImmLog2XLenNonZero"; +} + +def uimmlog2xlennonzero : Operand<XLenVT>, ImmLeaf<XLenVT, [{ + if (Subtarget->is64Bit()) + return isUInt<6>(Imm) && (Imm != 0); + return isUInt<5>(Imm) && (Imm != 0); +}]> { + let ParserMatchClass = UImmLog2XLenNonZeroAsmOperand; + // TODO: should ensure invalid shamt is rejected when decoding. + let DecoderMethod = "decodeUImmOperand<6>"; } def simm6 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<6>(Imm);}]> { @@ -290,8 +300,8 @@ def C_LUI : RVInst16CI<0b011, 0b01, (outs GPRNoX0X2:$rd), let Inst{6-2} = imm{4-0}; } -def C_SRLI : Shift_right<0b00, "c.srli", GPRC, uimm5nonzero>; -def C_SRAI : Shift_right<0b01, "c.srai", GPRC, uimm5nonzero>; +def C_SRLI : Shift_right<0b00, "c.srli", GPRC, uimmlog2xlennonzero>; +def C_SRAI : Shift_right<0b01, "c.srai", GPRC, uimmlog2xlennonzero>; let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in def C_ANDI : RVInst16CB<0b100, 0b01, (outs GPRC:$rs1_wb), (ins GPRC:$rs1, simm6:$imm), @@ -323,7 +333,7 @@ def C_BNEZ : Bcz<0b111, "c.bnez", setne, GPRC>; let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in def C_SLLI : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd_wb), - (ins GPRNoX0:$rd, uimm5nonzero:$imm), + (ins GPRNoX0:$rd, uimmlog2xlennonzero:$imm), "c.slli" ,"$rd, $imm"> { let Constraints = "$rd = $rd_wb"; let Inst{6-2} = imm{4-0}; |