summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp25
-rw-r--r--llvm/lib/Target/RISCV/RISCVInstrInfoC.td18
2 files changed, 34 insertions, 9 deletions
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 3299a53ff5b..64f59c230ec 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -260,6 +260,19 @@ public:
(VK == RISCVMCExpr::VK_RISCV_None || VK == RISCVMCExpr::VK_RISCV_LO);
}
+ bool isSImm6NonZero() const {
+ RISCVMCExpr::VariantKind VK;
+ int64_t Imm;
+ bool IsValid;
+ bool IsConstantImm = evaluateConstantImm(Imm, VK);
+ if (!IsConstantImm)
+ IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
+ else
+ IsValid = ((Imm != 0) && isInt<6>(Imm));
+ return IsValid &&
+ (VK == RISCVMCExpr::VK_RISCV_None || VK == RISCVMCExpr::VK_RISCV_LO);
+ }
+
bool isUImm6NonZero() const {
int64_t Imm;
RISCVMCExpr::VariantKind VK;
@@ -338,11 +351,11 @@ public:
bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); }
- bool isSImm10Lsb0000() const {
+ bool isSImm10Lsb0000NonZero() const {
int64_t Imm;
RISCVMCExpr::VariantKind VK;
bool IsConstantImm = evaluateConstantImm(Imm, VK);
- return IsConstantImm && isShiftedInt<6, 4>(Imm) &&
+ return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) &&
VK == RISCVMCExpr::VK_RISCV_None;
}
@@ -613,6 +626,10 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_InvalidSImm6:
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
(1 << 5) - 1);
+ case Match_InvalidSImm6NonZero:
+ 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_InvalidUImm7Lsb00:
@@ -639,10 +656,10 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return generateImmOutOfRangeError(
Operands, ErrorInfo, 4, (1 << 10) - 4,
"immediate must be a multiple of 4 bytes in the range");
- case Match_InvalidSImm10Lsb0000:
+ case Match_InvalidSImm10Lsb0000NonZero:
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
- "immediate must be a multiple of 16 bytes in the range");
+ "immediate must be a multiple of 16 bytes and non-zero in the range");
case Match_InvalidSImm12:
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11),
(1 << 11) - 1);
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
index f39b128099d..fc9c1dea5a8 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
@@ -35,6 +35,13 @@ def simm6 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<6>(Imm);}]> {
let DecoderMethod = "decodeSImmOperand<6>";
}
+def simm6nonzero : Operand<XLenVT>,
+ ImmLeaf<XLenVT, [{return (Imm != 0) && isInt<6>(Imm);}]> {
+ let ParserMatchClass = SImmAsmOperand<6, "NonZero">;
+ let EncoderMethod = "getImmOpValue";
+ let DecoderMethod = "decodeSImmOperand<6>";
+}
+
def uimm6nonzero : Operand<XLenVT>,
ImmLeaf<XLenVT, [{return isUInt<6>(Imm) && (Imm != 0);}]> {
let ParserMatchClass = UImmAsmOperand<6, "NonZero">;
@@ -91,9 +98,10 @@ def uimm10_lsb00nonzero : Operand<XLenVT>,
}
// A 10-bit signed immediate where the least significant four bits are zero.
-def simm10_lsb0000 : Operand<XLenVT>,
- ImmLeaf<XLenVT, [{return isShiftedInt<6, 4>(Imm);}]> {
- let ParserMatchClass = SImmAsmOperand<10, "Lsb0000">;
+def simm10_lsb0000nonzero : Operand<XLenVT>,
+ ImmLeaf<XLenVT,
+ [{return (Imm != 0) && isShiftedInt<6, 4>(Imm);}]> {
+ let ParserMatchClass = SImmAsmOperand<10, "Lsb0000NonZero">;
let EncoderMethod = "getImmOpValue";
let DecoderMethod = "decodeSImmOperand<10>";
}
@@ -253,7 +261,7 @@ def C_NOP : RVInst16CI<0b000, 0b01, (outs), (ins), "c.nop", "">;
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
def C_ADDI : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb),
- (ins GPRNoX0:$rd, simm6:$imm),
+ (ins GPRNoX0:$rd, simm6nonzero:$imm),
"c.addi", "$rd, $imm"> {
let Constraints = "$rd = $rd_wb";
let Inst{6-2} = imm{4-0};
@@ -282,7 +290,7 @@ def C_LI : RVInst16CI<0b010, 0b01, (outs GPRNoX0:$rd), (ins simm6:$imm),
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
def C_ADDI16SP : RVInst16CI<0b011, 0b01, (outs SP:$rd_wb),
- (ins SP:$rd, simm10_lsb0000:$imm),
+ (ins SP:$rd, simm10_lsb0000nonzero:$imm),
"c.addi16sp", "$rd, $imm"> {
let Constraints = "$rd = $rd_wb";
let Inst{12} = imm{9};
OpenPOWER on IntegriCloud