Skip to content

Commit a39ef92

Browse files
committed
[RISCV][MC] Support Base P non-GPR pair instructions
This patch adds support for non-GPR pair instructions in purposed Base P extension for RISC-V. Documentation: jhauser.us/RISCV/ext-P/RVP-baseInstrs-014.pdf jhauser.us/RISCV/ext-P/RVP-instrEncodings-014b.pdf
1 parent e9cba3c commit a39ef92

File tree

10 files changed

+354
-33
lines changed

10 files changed

+354
-33
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,7 @@ struct RISCVOperand final : public MCParsedAsmOperand {
809809

810810
bool isSImm5() const { return isSImm<5>(); }
811811
bool isSImm6() const { return isSImm<6>(); }
812+
bool isSImm10() const { return isSImm<10>(); }
812813
bool isSImm11() const { return isSImm<11>(); }
813814
bool isSImm16() const { return isSImm<16>(); }
814815
bool isSImm26() const { return isSImm<26>(); }
@@ -1538,6 +1539,9 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
15381539
return generateImmOutOfRangeError(
15391540
Operands, ErrorInfo, 0, (1 << 9) - 8,
15401541
"immediate must be a multiple of 8 bytes in the range");
1542+
case Match_InvalidSImm10:
1543+
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
1544+
(1 << 9) - 1);
15411545
case Match_InvalidUImm10Lsb00NonZero:
15421546
return generateImmOutOfRangeError(
15431547
Operands, ErrorInfo, 4, (1 << 10) - 4,

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ enum OperandType : unsigned {
336336
OPERAND_SIMM5_PLUS1,
337337
OPERAND_SIMM6,
338338
OPERAND_SIMM6_NONZERO,
339+
OPERAND_SIMM10,
339340
OPERAND_SIMM10_LSB0000_NONZERO,
340341
OPERAND_SIMM11,
341342
OPERAND_SIMM12,

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2251,6 +2251,16 @@ include "RISCVInstrInfoV.td"
22512251
include "RISCVInstrInfoZvk.td"
22522252
include "RISCVInstrInfoZvqdotq.td"
22532253

2254+
// Packed SIMD
2255+
include "RISCVInstrInfoP.td"
2256+
2257+
// Integer
2258+
include "RISCVInstrInfoZimop.td"
2259+
include "RISCVInstrInfoZicbo.td"
2260+
include "RISCVInstrInfoZicond.td"
2261+
include "RISCVInstrInfoZicfiss.td"
2262+
include "RISCVInstrInfoZilsd.td"
2263+
22542264
// Compressed
22552265
include "RISCVInstrInfoC.td"
22562266
include "RISCVInstrInfoZc.td"
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
//===-- RISCVInstrInfoP.td - RISC-V 'P' instructions -------*- tablegen -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file describes the RISC-V instructions from the standard 'Base P'
10+
// Packed SIMD instruction set extension.
11+
//
12+
// This version is still experimental as the 'P' extension hasn't been
13+
// ratified yet.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
//===----------------------------------------------------------------------===//
18+
// Operand and SDNode transformation definitions.
19+
//===----------------------------------------------------------------------===//
20+
21+
def RVPGPRPairRV32 : RegisterOperand<GPRPair> {
22+
let ParserMatchClass = GPRPairRV32Operand;
23+
let EncoderMethod = "getRVPGPRPair";
24+
let DecoderMethod = "decodeRVPGPRPair";
25+
}
26+
27+
def simm10 : RISCVSImmLeafOp<10>;
28+
29+
//===----------------------------------------------------------------------===//
30+
// Instruction class templates
31+
//===----------------------------------------------------------------------===//
32+
33+
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
34+
class RVPUnaryImm9<bits<7> funct7, string opcodestr>
35+
: RVInstIBase<0b010, OPC_OP_IMM_32, (outs GPR:$rd), (ins simm10:$simm10),
36+
opcodestr, "$rd, $simm10"> {
37+
bits<10> simm10;
38+
39+
let Inst{31-25} = funct7;
40+
let Inst{24-15} = simm10;
41+
}
42+
43+
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
44+
class RVPUnaryImm9Rdp<bits<7> funct7, string opcodestr>
45+
: RVInstIBase<0b010, OPC_OP_IMM_32, (outs RVPGPRPairRV32:$rdp),
46+
(ins simm10:$simm10),
47+
opcodestr, "$rdp, $simm10"> {
48+
bits<10> simm10;
49+
bits<4> rdp;
50+
51+
let Inst{31-25} = funct7;
52+
let Inst{24-15} = simm10;
53+
let Inst{11-8} = rdp;
54+
let Inst{7} = 0b0;
55+
}
56+
57+
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
58+
class RVPUnaryImm8<bits<8> funct8, string opcodestr>
59+
: RVInstIBase<0b010, OPC_OP_IMM_32, (outs GPR:$rd), (ins uimm8:$uimm8),
60+
opcodestr, "$rd, $uimm8"> {
61+
bits<8> uimm8;
62+
63+
let Inst{31-24} = funct8;
64+
let Inst{23-16} = uimm8;
65+
let Inst{15} = 0b0;
66+
}
67+
68+
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
69+
class RVPUnaryImm5<bits<3> f, string opcodestr>
70+
: RVInstIBase<0b010, OPC_OP_IMM_32, (outs GPR:$rd),
71+
(ins GPR:$rs1, uimm5:$uimm5), opcodestr, "$rd, $rs1, $uimm5"> {
72+
bits<5> uimm5;
73+
let Inst{31} = 0b1;
74+
let Inst{30-28} = f;
75+
let Inst{27} = 0b0;
76+
let Inst{26-25} = 0b01;
77+
let Inst{24-20} = uimm5;
78+
}
79+
80+
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
81+
class RVPUnaryImm4<bits<3> f, string opcodestr>
82+
: RVInstIBase<0b010, OPC_OP_IMM_32, (outs GPR:$rd),
83+
(ins GPR:$rs1, uimm4:$uimm4), opcodestr, "$rd, $rs1, $uimm4"> {
84+
bits<4> uimm4;
85+
let Inst{31} = 0b1;
86+
let Inst{30-28} = f;
87+
let Inst{27} = 0b0;
88+
let Inst{26-24} = 0b001;
89+
let Inst{23-20} = uimm4;
90+
}
91+
92+
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
93+
class RVPUnaryImm3<bits<3> f, string opcodestr>
94+
: RVInstIBase<0b010, OPC_OP_IMM_32, (outs GPR:$rd),
95+
(ins GPR:$rs1, uimm3:$uimm3), opcodestr, "$rd, $rs1, $uimm3"> {
96+
bits<3> uimm3;
97+
let Inst{31} = 0b1;
98+
let Inst{30-28} = f;
99+
let Inst{27} = 0b0;
100+
let Inst{26-23} = 0b0001;
101+
let Inst{22-20} = uimm3;
102+
}
103+
104+
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
105+
class RVPUnaryWUF<bits<2> w, bits<5> uf, string opcodestr>
106+
: RVInstIBase<0b010, OPC_OP_IMM_32, (outs GPR:$rd), (ins GPR:$rs1),
107+
opcodestr, "$rd, $rs1"> {
108+
let Inst{31-27} = 0b11100;
109+
let Inst{26-25} = w;
110+
let Inst{24-20} = uf;
111+
}
112+
113+
//===----------------------------------------------------------------------===//
114+
// Instructions
115+
//===----------------------------------------------------------------------===//
116+
117+
let Predicates = [HasStdExtP] in {
118+
def CLS : Unary_r<0b011000000011, 0b001, "cls">;
119+
def ABS : Unary_r<0b011000000111, 0b001, "abs">;
120+
} // Predicates = [HasStdExtP]
121+
let Predicates = [HasStdExtP, IsRV32] in
122+
def REV_RV32 : Unary_r<0b011010011111, 0b101, "rev">;
123+
124+
let Predicates = [HasStdExtP, IsRV64] in {
125+
def REV16 : Unary_r<0b011010110000, 0b101, "rev16">;
126+
def REV_RV64 : Unary_r<0b011110111111, 0b101, "rev">;
127+
128+
def CLSW : UnaryW_r<0b011000000011, 0b001, "clsw">;
129+
def ABSW : UnaryW_r<0b011000000111, 0b001, "absw">;
130+
} // Predicates = [HasStdExtP, IsRV64]
131+
132+
let Predicates = [HasStdExtP] in {
133+
def PSLLI_B : RVPUnaryImm3<0b000, "pslli.b">;
134+
def PSLLI_H : RVPUnaryImm4<0b000, "pslli.h">;
135+
def PSSLAI_H : RVPUnaryImm4<0b101, "psslai.h">;
136+
} // Predicates = [HasStdExtP]
137+
let DecoderNamespace = "RV32Only",
138+
Predicates = [HasStdExtP, IsRV32] in
139+
def SSLAI : RVPUnaryImm5<0b101, "sslai">;
140+
let Predicates = [HasStdExtP, IsRV64] in {
141+
def PSLLI_W : RVPUnaryImm5<0b000, "pslli.w">;
142+
def PSSLAI_W : RVPUnaryImm5<0b101, "psslai.w">;
143+
} // Predicates = [HasStdExtP, IsRV64]
144+
145+
let Predicates = [HasStdExtP] in
146+
def PLI_H : RVPUnaryImm9<0b1011000, "pli.h">;
147+
let Predicates = [HasStdExtP, IsRV64] in
148+
def PLI_W : RVPUnaryImm9<0b1011001, "pli.w">;
149+
let Predicates = [HasStdExtP] in
150+
def PLI_B : RVPUnaryImm8<0b10110100, "pli.b">;
151+
152+
let Predicates = [HasStdExtP] in {
153+
def PSEXT_H_B : RVPUnaryWUF<0b00, 0b00100, "psext.h.b">;
154+
def PSABS_H : RVPUnaryWUF<0b00, 0b00111, "psabs.h">;
155+
def PSABS_B : RVPUnaryWUF<0b10, 0b00111, "psabs.b">;
156+
} // Predicates = [HasStdExtP]
157+
let Predicates = [HasStdExtP, IsRV64] in {
158+
def PSEXT_W_B : RVPUnaryWUF<0b01, 0b00100, "psext.w.b">;
159+
def PSEXT_W_H : RVPUnaryWUF<0b01, 0b00101, "psext.w.h">;
160+
} // Predicates = [HasStdExtP, IsRV64]
161+
162+
let Predicates = [HasStdExtP] in
163+
def PLUI_H : RVPUnaryImm9<0b1111000, "plui.h">;
164+
let Predicates = [HasStdExtP, IsRV64] in
165+
def PLUI_W : RVPUnaryImm9<0b1111001, "plui.w">;

llvm/test/CodeGen/RISCV/attributes.ll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@
333333
; RUN: llc -mtriple=riscv64 -mattr=+sdext %s -o - | FileCheck --check-prefix=RV64SDEXT %s
334334
; RUN: llc -mtriple=riscv64 -mattr=+sdtrig %s -o - | FileCheck --check-prefix=RV64SDTRIG %s
335335
; RUN: llc -mtriple=riscv64 -mattr=+experimental-xqccmp %s -o - | FileCheck --check-prefix=RV64XQCCMP %s
336+
; RUN: llc -mtriple=riscv64 -mattr=+experimental-p %s -o - | FileCheck --check-prefix=RV64P %s
336337

337338

338339
; Tests for profile features.
@@ -520,6 +521,7 @@
520521
; RV32SUPM: .attribute 5, "rv32i2p1_supm1p0"
521522
; RV32SMCTR: .attribute 5, "rv32i2p1_smctr1p0_sscsrind1p0"
522523
; RV32SSCTR: .attribute 5, "rv32i2p1_sscsrind1p0_ssctr1p0"
524+
; RV32P: .attribute 5, "rv32i2p1_p0p14"
523525

524526
; RV64M: .attribute 5, "rv64i2p1_m2p0_zmmul1p0"
525527
; RV64ZMMUL: .attribute 5, "rv64i2p1_zmmul1p0"
@@ -680,6 +682,7 @@
680682
; RV64SDEXT: .attribute 5, "rv64i2p1_sdext1p0"
681683
; RV64SDTRIG: .attribute 5, "rv64i2p1_sdtrig1p0"
682684
; RV64XQCCMP: .attribute 5, "rv64i2p1_zca1p0_xqccmp0p1"
685+
; RV64P: .attribute 5, "rv64i2p1_p0p14"
683686

684687
; RVI20U32: .attribute 5, "rv32i2p1"
685688
; RVI20U64: .attribute 5, "rv64i2p1"

llvm/test/MC/RISCV/invalid-instruction-spellcheck.s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ fl ft0, 0(sp)
2222
# CHECK-RV64IF: did you mean: flw, la, lb, ld, lh, li, lw
2323
# CHECK-NEXT: fl ft0, 0(sp)
2424

25-
addd x1, x1, x1
25+
addc x1, x1, x1
2626
# CHECK-RV32: did you mean: add, addi
2727
# CHECK-RV64: did you mean: add, addi, addw
28-
# CHECK-NEXT: addd x1, x1, x1
28+
# CHECK-NEXT: addc x1, x1, x1
2929

3030
vm x0, x0
3131
# CHECK: did you mean: mv

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# RUN: not llvm-mc -triple=riscv32 --mattr=+experimental-p %s 2>&1 \
2+
# RUN: | FileCheck %s --check-prefixes=CHECK-ERROR
3+
4+
# Imm overflow
5+
pli.h a0, 0x400
6+
# CHECK-ERROR: immediate must be an integer in the range [-512, 511]
7+
pli.b a0, 0x200
8+
# CHECK-ERROR: immediate must be an integer in the range [0, 255]
9+
10+
pslli.b a6, a7, 100
11+
# CHECK-ERROR: immediate must be an integer in the range [0, 7]
12+
pslli.h ra, sp, 100
13+
# CHECK-ERROR: immediate must be an integer in the range [0, 15]
14+
psslai.h t0, t1, 100
15+
# CHECK-ERROR: immediate must be an integer in the range [0, 15]
16+
sslai a4, a5, -1
17+
# CHECK-ERROR: immediate must be an integer in the range [0, 31]

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

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,75 @@
11
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-p -M no-aliases -show-encoding \
22
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
33
# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-p < %s \
4-
# RUN: | llvm-objdump --mattr=+experimental-p -M no-aliases -d -r - \
4+
# RUN: | llvm-objdump --mattr=+experimental-p -M no-aliases -d -r --no-print-imm-hex - \
55
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
66

7-
# CHECK-ASM-AND-OBJ: sh1add a0, a1, a2
8-
# CHECK-ASM: encoding: [0x33,0xa5,0xc5,0x20]
9-
sh1add a0, a1, a2
107
# CHECK-ASM-AND-OBJ: clz a0, a1
118
# CHECK-ASM: encoding: [0x13,0x95,0x05,0x60]
129
clz a0, a1
10+
# CHECK-ASM-AND-OBJ: cls a1, a2
11+
# CHECK-ASM: encoding: [0x93,0x15,0x36,0x60]
12+
cls a1, a2
1313
# CHECK-ASM-AND-OBJ: sext.b a2, a3
1414
# CHECK-ASM: encoding: [0x13,0x96,0x46,0x60]
1515
sext.b a2, a3
1616
# CHECK-ASM-AND-OBJ: sext.h t0, t1
1717
# CHECK-ASM: encoding: [0x93,0x12,0x53,0x60]
1818
sext.h t0, t1
19+
# CHECK-ASM-AND-OBJ: abs a4, a5
20+
# CHECK-ASM: encoding: [0x13,0x97,0x77,0x60]
21+
abs a4, a5
22+
# CHECK-ASM-AND-OBJ: rev8 s0, s1
23+
# CHECK-ASM: encoding: [0x13,0xd4,0x84,0x69]
24+
rev8 s0, s1
25+
# CHECK-ASM-AND-OBJ: rev s2, s3
26+
# CHECK-ASM: encoding: [0x13,0xd9,0xf9,0x69]
27+
rev s2, s3
28+
# CHECK-ASM-AND-OBJ: sh1add a0, a1, a2
29+
# CHECK-ASM: encoding: [0x33,0xa5,0xc5,0x20]
30+
sh1add a0, a1, a2
31+
# CHECK-ASM-AND-OBJ: pack s0, s1, s2
32+
# CHECK-ASM: encoding: [0x33,0xc4,0x24,0x09]
33+
pack s0, s1, s2
1934
# CHECK-ASM-AND-OBJ: min t0, t1, t2
2035
# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x0a]
2136
min t0, t1, t2
22-
# CHECK-ASM-AND-OBJ: minu t0, t1, t2
23-
# CHECK-ASM: encoding: [0xb3,0x52,0x73,0x0a]
24-
minu t0, t1, t2
37+
# CHECK-ASM-AND-OBJ: minu ra, sp, gp
38+
# CHECK-ASM: encoding: [0xb3,0x50,0x31,0x0a]
39+
minu ra, sp, gp
2540
# CHECK-ASM-AND-OBJ: max t3, t4, t5
2641
# CHECK-ASM: encoding: [0x33,0xee,0xee,0x0b]
2742
max t3, t4, t5
2843
# CHECK-ASM-AND-OBJ: maxu a4, a5, a6
2944
# CHECK-ASM: encoding: [0x33,0xf7,0x07,0x0b]
3045
maxu a4, a5, a6
31-
# CHECK-ASM-AND-OBJ: pack s0, s1, s2
32-
# CHECK-ASM: encoding: [0x33,0xc4,0x24,0x09]
33-
pack s0, s1, s2
34-
# CHECK-ASM-AND-OBJ: rev8 s0, s1
35-
# CHECK-ASM: encoding: [0x13,0xd4,0x84,0x69]
36-
rev8 s0, s1
46+
# CHECK-ASM-AND-OBJ: pslli.b a6, a7, 0
47+
# CHECK-ASM: encoding: [0x1b,0xa8,0x88,0x80]
48+
pslli.b a6, a7, 0
49+
# CHECK-ASM-AND-OBJ: pslli.h ra, sp, 1
50+
# CHECK-ASM: encoding: [0x9b,0x20,0x11,0x81]
51+
pslli.h ra, sp, 1
52+
# CHECK-ASM-AND-OBJ: psslai.h t0, t1, 2
53+
# CHECK-ASM: encoding: [0x9b,0x22,0x23,0xd1]
54+
psslai.h t0, t1, 2
55+
# CHECK-ASM-AND-OBJ: sslai a4, a5, 3
56+
# CHECK-ASM: encoding: [0x1b,0xa7,0x37,0xd2]
57+
sslai a4, a5, 3
58+
# CHECK-ASM-AND-OBJ: pli.h a5, 16
59+
# CHECK-ASM: encoding: [0x9b,0x27,0x08,0xb0]
60+
pli.h a5, 16
61+
# CHECK-ASM-AND-OBJ: pli.b a6, 16
62+
# CHECK-ASM: encoding: [0x1b,0x28,0x10,0xb4]
63+
pli.b a6, 16
64+
# CHECK-ASM-AND-OBJ: psext.h.b a7, a0
65+
# CHECK-ASM: encoding: [0x9b,0x28,0x45,0xe0]
66+
psext.h.b a7, a0
67+
# CHECK-ASM-AND-OBJ: psabs.h a1, a2
68+
# CHECK-ASM: encoding: [0x9b,0x25,0x76,0xe0]
69+
psabs.h a1, a2
70+
# CHECK-ASM-AND-OBJ: psabs.b t0, t1
71+
# CHECK-ASM: encoding: [0x9b,0x22,0x73,0xe4]
72+
psabs.b t0, t1
73+
# CHECK-ASM-AND-OBJ: plui.h gp, 32
74+
# CHECK-ASM: encoding: [0x9b,0x21,0x10,0xf0]
75+
plui.h gp, 32

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# RUN: not llvm-mc -triple=riscv64 --mattr=+experimental-p %s 2>&1 \
2+
# RUN: | FileCheck %s --check-prefixes=CHECK-ERROR
3+
4+
# Imm overflow
5+
pli.h a0, 0x400
6+
# CHECK-ERROR: immediate must be an integer in the range [-512, 511]
7+
pli.w a1, -0x201
8+
# CHECK-ERROR: immediate must be an integer in the range [-512, 511]
9+
10+
pslli.b a6, a7, 100
11+
# CHECK-ERROR: immediate must be an integer in the range [0, 7]
12+
pslli.h ra, sp, 100
13+
# CHECK-ERROR: immediate must be an integer in the range [0, 15]
14+
pslli.w ra, sp, 100
15+
# CHECK-ERROR: immediate must be an integer in the range [0, 31]
16+
psslai.h t0, t1, 100
17+
# CHECK-ERROR: immediate must be an integer in the range [0, 15]
18+
psslai.w a4, a5, -1
19+
# CHECK-ERROR: error: immediate must be an integer in the range [0, 31]

0 commit comments

Comments
 (0)