Skip to content

Commit 4a3b699

Browse files
authored
[RISCV] Accept [-128,255] instead of [0, 255] for pli.b (#153913)
pli.h and pli.w both accept signed immediates, so pli.b should too. But unlike those instructions, pli.b doesn't do any extension so its ok to accept an unsigned immediate as well.
1 parent 98f4b77 commit 4a3b699

File tree

6 files changed

+47
-6
lines changed

6 files changed

+47
-6
lines changed

llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
903903
VK == RISCV::S_QC_ABS20;
904904
}
905905

906+
bool isSImm8Unsigned() const { return isSImm<8>() || isUImm<8>(); }
906907
bool isSImm10Unsigned() const { return isSImm<10>() || isUImm<10>(); }
907908

908909
bool isUImm20LUI() const {
@@ -1199,6 +1200,14 @@ struct RISCVOperand final : public MCParsedAsmOperand {
11991200
addExpr(Inst, getImm(), isRV64Imm());
12001201
}
12011202

1203+
void addSImm8UnsignedOperands(MCInst &Inst, unsigned N) const {
1204+
assert(N == 1 && "Invalid number of operands!");
1205+
int64_t Imm;
1206+
[[maybe_unused]] bool IsConstant = evaluateConstantImm(getImm(), Imm);
1207+
assert(IsConstant);
1208+
Inst.addOperand(MCOperand::createImm(SignExtend64<8>(Imm)));
1209+
}
1210+
12021211
void addSImm10UnsignedOperands(MCInst &Inst, unsigned N) const {
12031212
assert(N == 1 && "Invalid number of operands!");
12041213
int64_t Imm;
@@ -1547,6 +1556,9 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
15471556
return generateImmOutOfRangeError(
15481557
Operands, ErrorInfo, 0, (1 << 9) - 8,
15491558
"immediate must be a multiple of 8 bytes in the range");
1559+
case Match_InvalidSImm8Unsigned:
1560+
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
1561+
(1 << 8) - 1);
15501562
case Match_InvalidSImm10:
15511563
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
15521564
(1 << 9) - 1);

llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ enum OperandType : unsigned {
346346
OPERAND_SIMM5_PLUS1,
347347
OPERAND_SIMM6,
348348
OPERAND_SIMM6_NONZERO,
349+
OPERAND_SIMM8,
349350
OPERAND_SIMM10,
350351
OPERAND_SIMM10_LSB0000_NONZERO,
351352
OPERAND_SIMM11,

llvm/lib/Target/RISCV/RISCVInstrInfoP.td

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,26 @@
1818
// Operand and SDNode transformation definitions.
1919
//===----------------------------------------------------------------------===//
2020

21-
def simm10 : RISCVSImmLeafOp<10>;
21+
def simm10 : RISCVSImmOp<10>;
22+
23+
def SImm8UnsignedAsmOperand : SImmAsmOperand<8, "Unsigned"> {
24+
let RenderMethod = "addSImm8UnsignedOperands";
25+
}
26+
27+
// A 8-bit signed immediate allowing range [-128, 255]
28+
// but represented as [-128, 127].
29+
def simm8_unsigned : RISCVOp {
30+
let ParserMatchClass = SImm8UnsignedAsmOperand;
31+
let EncoderMethod = "getImmOpValue";
32+
let DecoderMethod = "decodeSImmOperand<8>";
33+
let OperandType = "OPERAND_SIMM10";
34+
let MCOperandPredicate = [{
35+
int64_t Imm;
36+
if (!MCOp.evaluateAsConstantImm(Imm))
37+
return false;
38+
return isInt<8>(Imm);
39+
}];
40+
}
2241

2342
def SImm10UnsignedAsmOperand : SImmAsmOperand<10, "Unsigned"> {
2443
let RenderMethod = "addSImm10UnsignedOperands";
@@ -75,13 +94,13 @@ class PLUI_i<bits<7> funct7, string opcodestr>
7594

7695
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
7796
class PLI_B_i<bits<8> funct8, string opcodestr>
78-
: RVInst<(outs GPR:$rd), (ins uimm8:$uimm8), opcodestr, "$rd, $uimm8", [],
79-
InstFormatOther> {
80-
bits<8> uimm8;
97+
: RVInst<(outs GPR:$rd), (ins simm8_unsigned:$imm8), opcodestr,
98+
"$rd, $imm8", [], InstFormatOther> {
99+
bits<8> imm8;
81100
bits<5> rd;
82101

83102
let Inst{31-24} = funct8;
84-
let Inst{23-16} = uimm8;
103+
let Inst{23-16} = imm8;
85104
let Inst{15} = 0b0;
86105
let Inst{14-12} = 0b010;
87106
let Inst{11-7} = rd;

llvm/test/MC/RISCV/rv32p-invalid.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# Imm overflow
55
pli.h a0, 0x400 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [-512, 511]
66
plui.h a1, 0x400 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [-512, 1023]
7-
pli.b a0, 0x200 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 255]
7+
pli.b a0, 0x200 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [-128, 255]
88

99
pslli.b a6, a7, 100 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 7]
1010
pslli.h ra, sp, 100 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 15]

llvm/test/MC/RISCV/rv32p-valid.s

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ pli.h a5, 16
6161
# CHECK-ASM-AND-OBJ: pli.b a6, 16
6262
# CHECK-ASM: encoding: [0x1b,0x28,0x10,0xb4]
6363
pli.b a6, 16
64+
# CHECK-ASM-AND-OBJ: pli.b a6, -128
65+
# CHECK-ASM: encoding: [0x1b,0x28,0x80,0xb4]
66+
pli.b a6, -128
6467
# CHECK-ASM-AND-OBJ: psext.h.b a7, a0
6568
# CHECK-ASM: encoding: [0x9b,0x28,0x45,0xe0]
6669
psext.h.b a7, a0

llvm/test/MC/RISCV/rv64p-valid.s

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ pli.w a5, 5
7979
# CHECK-ASM-AND-OBJ: pli.b a6, 6
8080
# CHECK-ASM: encoding: [0x1b,0x28,0x06,0xb4]
8181
pli.b a6, 6
82+
# CHECK-ASM-AND-OBJ: pli.b a6, -1
83+
# CHECK-ASM: encoding: [0x1b,0x28,0xff,0xb4]
84+
pli.b a6, -1
85+
# CHECK-ASM-AND-OBJ: pli.b a6, -1
86+
# CHECK-ASM: encoding: [0x1b,0x28,0xff,0xb4]
87+
pli.b a6, 255
8288
# CHECK-ASM-AND-OBJ: psext.h.b t3, a2
8389
# CHECK-ASM: encoding: [0x1b,0x2e,0x46,0xe0]
8490
psext.h.b t3, a2

0 commit comments

Comments
 (0)