summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorAlex Bradbury <asb@lowrisc.org>2017-12-15 10:20:51 +0000
committerAlex Bradbury <asb@lowrisc.org>2017-12-15 10:20:51 +0000
commit0ad4c265d7202724a07c0473b5212d02b687c2d6 (patch)
tree35a8e5aba5571d6614fb1f9410794235a77a5f13 /llvm/lib/Target
parent74ecf59cc0e3a9306874508dd41f65606a693aa8 (diff)
downloadbcm5719-llvm-0ad4c265d7202724a07c0473b5212d02b687c2d6.tar.gz
bcm5719-llvm-0ad4c265d7202724a07c0473b5212d02b687c2d6.zip
[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. llvm-svn: 320799
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp18
-rw-r--r--llvm/lib/Target/RISCV/RISCVInstrInfoC.td24
2 files changed, 33 insertions, 9 deletions
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 1bae18bca92..3299a53ff5b 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/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/llvm/lib/Target/RISCV/RISCVInstrInfoC.td b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
index 518f5633585..4ca52652086 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
+++ b/llvm/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};
OpenPOWER on IntegriCloud