Skip to content

Commit 0215040

Browse files
committed
[RISCV] Implement Intrinsics for XCVmac Extension in CV32E40P
Implement XCVmac intrinsics and CodeGen for CV32E40P according to the specification. This commit is part of a patch-set to upstream the vendor specific extensions of CV32E40P that need LLVM intrinsics to implement Clang builtins. Contributors: @CharKeaney, @ChunyuLiao, @jeremybennett, @lewis-revill, @NandniJamnadas, @PaoloS02, @serkm, @simonpcook, @xingmingjie.
1 parent 7318585 commit 0215040

File tree

3 files changed

+277
-0
lines changed

3 files changed

+277
-0
lines changed

llvm/include/llvm/IR/IntrinsicsRISCVXCV.td

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@ class ScalarCoreVBitManipGprIntrinsic
1818
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty],
1919
[IntrNoMem, IntrSpeculatable]>;
2020

21+
class ScalarCoreVMacGprGprGprIntrinsic
22+
: Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
23+
[IntrNoMem, IntrWillReturn, IntrSpeculatable]>;
24+
25+
class ScalarCoreVMacGprGPRImmIntrinsic
26+
: Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
27+
[IntrNoMem, IntrWillReturn, IntrSpeculatable, ImmArg<ArgIndex<2>>]>;
28+
29+
class ScalarCoreVMacGprGprGprImmIntrinsic
30+
: Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
31+
[IntrNoMem, IntrWillReturn, IntrSpeculatable, ImmArg<ArgIndex<3>>]>;
32+
2133
let TargetPrefix = "riscv" in {
2234
def int_riscv_cv_bitmanip_extract : ScalarCoreVBitManipGprGprIntrinsic;
2335
def int_riscv_cv_bitmanip_extractu : ScalarCoreVBitManipGprGprIntrinsic;
@@ -34,4 +46,25 @@ let TargetPrefix = "riscv" in {
3446
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
3547
[IntrNoMem, IntrWillReturn, IntrSpeculatable,
3648
ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
49+
50+
def int_riscv_cv_mac_mac : ScalarCoreVMacGprGprGprIntrinsic;
51+
def int_riscv_cv_mac_msu : ScalarCoreVMacGprGprGprIntrinsic;
52+
53+
def int_riscv_cv_mac_muluN : ScalarCoreVMacGprGPRImmIntrinsic;
54+
def int_riscv_cv_mac_mulhhuN : ScalarCoreVMacGprGPRImmIntrinsic;
55+
def int_riscv_cv_mac_mulsN : ScalarCoreVMacGprGPRImmIntrinsic;
56+
def int_riscv_cv_mac_mulhhsN : ScalarCoreVMacGprGPRImmIntrinsic;
57+
def int_riscv_cv_mac_muluRN : ScalarCoreVMacGprGPRImmIntrinsic;
58+
def int_riscv_cv_mac_mulhhuRN : ScalarCoreVMacGprGPRImmIntrinsic;
59+
def int_riscv_cv_mac_mulsRN : ScalarCoreVMacGprGPRImmIntrinsic;
60+
def int_riscv_cv_mac_mulhhsRN : ScalarCoreVMacGprGPRImmIntrinsic;
61+
62+
def int_riscv_cv_mac_macuN : ScalarCoreVMacGprGprGprImmIntrinsic;
63+
def int_riscv_cv_mac_machhuN : ScalarCoreVMacGprGprGprImmIntrinsic;
64+
def int_riscv_cv_mac_macsN : ScalarCoreVMacGprGprGprImmIntrinsic;
65+
def int_riscv_cv_mac_machhsN : ScalarCoreVMacGprGprGprImmIntrinsic;
66+
def int_riscv_cv_mac_macuRN : ScalarCoreVMacGprGprGprImmIntrinsic;
67+
def int_riscv_cv_mac_machhuRN : ScalarCoreVMacGprGprGprImmIntrinsic;
68+
def int_riscv_cv_mac_macsRN : ScalarCoreVMacGprGprGprImmIntrinsic;
69+
def int_riscv_cv_mac_machhsRN : ScalarCoreVMacGprGprGprImmIntrinsic;
3770
} // TargetPrefix = "riscv"

llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,3 +704,36 @@ let Predicates = [HasVendorXCVbitmanip, IsRV32] in {
704704
(CV_BITREV GPR:$rs1, cv_tuimm2:$radix, cv_tuimm5:$pts)>;
705705
def : Pat<(bitreverse (XLenVT GPR:$rs)), (CV_BITREV GPR:$rs, 0, 0)>;
706706
}
707+
708+
class PatCoreVMacGprGprGpr <string intr, string asm>
709+
: Pat<(!cast<Intrinsic>("int_riscv_cv_mac_" # intr) GPR:$rs1, GPR:$rs2, GPR:$rd),
710+
(!cast<RVInst>("CV_" # asm) GPR:$rd, GPR:$rs1, GPR:$rs2)>;
711+
class PatCoreVMacGprGprGprUimm5 <string intr, string asm>
712+
: Pat<(!cast<Intrinsic>("int_riscv_cv_mac_" # intr) GPR:$rs1, GPR:$rs2, GPR:$rd, cv_tuimm5:$imm5),
713+
(!cast<RVInst>("CV_" # asm) GPR:$rd, GPR:$rs1, GPR:$rs2, cv_tuimm5:$imm5)>;
714+
class PatCoreVMacGprGprUimm5 <string intr, string asm>
715+
: Pat<(!cast<Intrinsic>("int_riscv_cv_mac_" # intr) GPR:$rs1, GPR:$rs2, cv_tuimm5:$imm5),
716+
(!cast<RVInst>("CV_" # asm) GPR:$rs1, GPR:$rs2, cv_tuimm5:$imm5)>;
717+
718+
let Predicates = [HasVendorXCVmac] in {
719+
def : PatCoreVMacGprGprGpr<"mac", "MAC">;
720+
def : PatCoreVMacGprGprGpr<"msu", "MSU">;
721+
722+
def : PatCoreVMacGprGprUimm5<"muluN", "MULUN">;
723+
def : PatCoreVMacGprGprUimm5<"mulhhuN", "MULHHUN">;
724+
def : PatCoreVMacGprGprUimm5<"mulsN", "MULSN">;
725+
def : PatCoreVMacGprGprUimm5<"mulhhsN", "MULHHSN">;
726+
def : PatCoreVMacGprGprUimm5<"muluRN", "MULURN">;
727+
def : PatCoreVMacGprGprUimm5<"mulhhuRN", "MULHHURN">;
728+
def : PatCoreVMacGprGprUimm5<"mulsRN", "MULSRN">;
729+
def : PatCoreVMacGprGprUimm5<"mulhhsRN", "MULHHSRN">;
730+
731+
def : PatCoreVMacGprGprGprUimm5<"macuN", "MACUN">;
732+
def : PatCoreVMacGprGprGprUimm5<"machhuN", "MACHHUN">;
733+
def : PatCoreVMacGprGprGprUimm5<"macsN", "MACSN">;
734+
def : PatCoreVMacGprGprGprUimm5<"machhsN", "MACHHSN">;
735+
def : PatCoreVMacGprGprGprUimm5<"macuRN", "MACURN">;
736+
def : PatCoreVMacGprGprGprUimm5<"machhuRN", "MACHHURN">;
737+
def : PatCoreVMacGprGprGprUimm5<"macsRN", "MACSRN">;
738+
def : PatCoreVMacGprGprGprUimm5<"machhsRN", "MACHHSRN">;
739+
}

llvm/test/CodeGen/RISCV/xcvmac.ll

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=riscv32 -mattr=+m -mattr=+xcvmac -verify-machineinstrs < %s \
3+
; RUN: | FileCheck %s
4+
5+
declare i32 @llvm.riscv.cv.mac.mac(i32, i32, i32)
6+
7+
define i32 @test.mac(i32 %a, i32 %b, i32 %c) {
8+
; CHECK-LABEL: test.mac:
9+
; CHECK: # %bb.0:
10+
; CHECK-NEXT: cv.mac a2, a0, a1
11+
; CHECK-NEXT: mv a0, a2
12+
; CHECK-NEXT: ret
13+
%1 = call i32 @llvm.riscv.cv.mac.mac(i32 %a, i32 %b, i32 %c)
14+
ret i32 %1
15+
}
16+
17+
declare i32 @llvm.riscv.cv.mac.msu(i32, i32, i32)
18+
19+
define i32 @test.msu(i32 %a, i32 %b, i32 %c) {
20+
; CHECK-LABEL: test.msu:
21+
; CHECK: # %bb.0:
22+
; CHECK-NEXT: cv.msu a2, a0, a1
23+
; CHECK-NEXT: mv a0, a2
24+
; CHECK-NEXT: ret
25+
%1 = call i32 @llvm.riscv.cv.mac.msu(i32 %a, i32 %b, i32 %c)
26+
ret i32 %1
27+
}
28+
29+
declare i32 @llvm.riscv.cv.mac.muluN(i32, i32, i32)
30+
31+
define i32 @test.muluN(i32 %a, i32 %b) {
32+
; CHECK-LABEL: test.muluN:
33+
; CHECK: # %bb.0:
34+
; CHECK-NEXT: cv.mulun a0, a0, a1, 5
35+
; CHECK-NEXT: ret
36+
%1 = call i32 @llvm.riscv.cv.mac.muluN(i32 %a, i32 %b, i32 5)
37+
ret i32 %1
38+
}
39+
40+
declare i32 @llvm.riscv.cv.mac.mulhhuN(i32, i32, i32)
41+
42+
define i32 @test.mulhhuN(i32 %a, i32 %b) {
43+
; CHECK-LABEL: test.mulhhuN:
44+
; CHECK: # %bb.0:
45+
; CHECK-NEXT: cv.mulhhun a0, a0, a1, 5
46+
; CHECK-NEXT: ret
47+
%1 = call i32 @llvm.riscv.cv.mac.mulhhuN(i32 %a, i32 %b, i32 5)
48+
ret i32 %1
49+
}
50+
51+
declare i32 @llvm.riscv.cv.mac.mulsN(i32, i32, i32)
52+
53+
define i32 @test.mulsN(i32 %a, i32 %b) {
54+
; CHECK-LABEL: test.mulsN:
55+
; CHECK: # %bb.0:
56+
; CHECK-NEXT: cv.mulsn a0, a0, a1, 5
57+
; CHECK-NEXT: ret
58+
%1 = call i32 @llvm.riscv.cv.mac.mulsN(i32 %a, i32 %b, i32 5)
59+
ret i32 %1
60+
}
61+
62+
declare i32 @llvm.riscv.cv.mac.mulhhsN(i32, i32, i32)
63+
64+
define i32 @test.mulhhsN(i32 %a, i32 %b) {
65+
; CHECK-LABEL: test.mulhhsN:
66+
; CHECK: # %bb.0:
67+
; CHECK-NEXT: cv.mulhhsn a0, a0, a1, 5
68+
; CHECK-NEXT: ret
69+
%1 = call i32 @llvm.riscv.cv.mac.mulhhsN(i32 %a, i32 %b, i32 5)
70+
ret i32 %1
71+
}
72+
73+
declare i32 @llvm.riscv.cv.mac.muluRN(i32, i32, i32)
74+
75+
define i32 @test.muluRN(i32 %a, i32 %b) {
76+
; CHECK-LABEL: test.muluRN:
77+
; CHECK: # %bb.0:
78+
; CHECK-NEXT: cv.mulurn a0, a0, a1, 5
79+
; CHECK-NEXT: ret
80+
%1 = call i32 @llvm.riscv.cv.mac.muluRN(i32 %a, i32 %b, i32 5)
81+
ret i32 %1
82+
}
83+
84+
declare i32 @llvm.riscv.cv.mac.mulhhuRN(i32, i32, i32)
85+
86+
define i32 @test.mulhhuRN(i32 %a, i32 %b) {
87+
; CHECK-LABEL: test.mulhhuRN:
88+
; CHECK: # %bb.0:
89+
; CHECK-NEXT: cv.mulhhurn a0, a0, a1, 5
90+
; CHECK-NEXT: ret
91+
%1 = call i32 @llvm.riscv.cv.mac.mulhhuRN(i32 %a, i32 %b, i32 5)
92+
ret i32 %1
93+
}
94+
95+
declare i32 @llvm.riscv.cv.mac.mulsRN(i32, i32, i32)
96+
97+
define i32 @test.mulsRN(i32 %a, i32 %b) {
98+
; CHECK-LABEL: test.mulsRN:
99+
; CHECK: # %bb.0:
100+
; CHECK-NEXT: cv.mulsrn a0, a0, a1, 5
101+
; CHECK-NEXT: ret
102+
%1 = call i32 @llvm.riscv.cv.mac.mulsRN(i32 %a, i32 %b, i32 5)
103+
ret i32 %1
104+
}
105+
106+
declare i32 @llvm.riscv.cv.mac.mulhhsRN(i32, i32, i32)
107+
108+
define i32 @test.mulhhsRN(i32 %a, i32 %b) {
109+
; CHECK-LABEL: test.mulhhsRN:
110+
; CHECK: # %bb.0:
111+
; CHECK-NEXT: cv.mulhhsrn a0, a0, a1, 5
112+
; CHECK-NEXT: ret
113+
%1 = call i32 @llvm.riscv.cv.mac.mulhhsRN(i32 %a, i32 %b, i32 5)
114+
ret i32 %1
115+
}
116+
117+
declare i32 @llvm.riscv.cv.mac.macuN(i32, i32, i32, i32)
118+
119+
define i32 @test.macuN(i32 %a, i32 %b, i32 %c) {
120+
; CHECK-LABEL: test.macuN:
121+
; CHECK: # %bb.0:
122+
; CHECK-NEXT: cv.macun a2, a0, a1, 5
123+
; CHECK-NEXT: mv a0, a2
124+
; CHECK-NEXT: ret
125+
%1 = call i32 @llvm.riscv.cv.mac.macuN(i32 %a, i32 %b, i32 %c, i32 5)
126+
ret i32 %1
127+
}
128+
129+
declare i32 @llvm.riscv.cv.mac.machhuN(i32, i32, i32, i32)
130+
131+
define i32 @test.machhuN(i32 %a, i32 %b, i32 %c) {
132+
; CHECK-LABEL: test.machhuN:
133+
; CHECK: # %bb.0:
134+
; CHECK-NEXT: cv.machhun a2, a0, a1, 5
135+
; CHECK-NEXT: mv a0, a2
136+
; CHECK-NEXT: ret
137+
%1 = call i32 @llvm.riscv.cv.mac.machhuN(i32 %a, i32 %b, i32 %c, i32 5)
138+
ret i32 %1
139+
}
140+
141+
declare i32 @llvm.riscv.cv.mac.macsN(i32, i32, i32, i32)
142+
143+
define i32 @test.macsN(i32 %a, i32 %b, i32 %c) {
144+
; CHECK-LABEL: test.macsN:
145+
; CHECK: # %bb.0:
146+
; CHECK-NEXT: cv.macsn a2, a0, a1, 5
147+
; CHECK-NEXT: mv a0, a2
148+
; CHECK-NEXT: ret
149+
%1 = call i32 @llvm.riscv.cv.mac.macsN(i32 %a, i32 %b, i32 %c, i32 5)
150+
ret i32 %1
151+
}
152+
153+
declare i32 @llvm.riscv.cv.mac.machhsN(i32, i32, i32, i32)
154+
155+
define i32 @test.machhsN(i32 %a, i32 %b, i32 %c) {
156+
; CHECK-LABEL: test.machhsN:
157+
; CHECK: # %bb.0:
158+
; CHECK-NEXT: cv.machhsn a2, a0, a1, 5
159+
; CHECK-NEXT: mv a0, a2
160+
; CHECK-NEXT: ret
161+
%1 = call i32 @llvm.riscv.cv.mac.machhsN(i32 %a, i32 %b, i32 %c, i32 5)
162+
ret i32 %1
163+
}
164+
165+
declare i32 @llvm.riscv.cv.mac.macuRN(i32, i32, i32, i32)
166+
167+
define i32 @test.macuRN(i32 %a, i32 %b, i32 %c) {
168+
; CHECK-LABEL: test.macuRN:
169+
; CHECK: # %bb.0:
170+
; CHECK-NEXT: cv.macurn a2, a0, a1, 5
171+
; CHECK-NEXT: mv a0, a2
172+
; CHECK-NEXT: ret
173+
%1 = call i32 @llvm.riscv.cv.mac.macuRN(i32 %a, i32 %b, i32 %c, i32 5)
174+
ret i32 %1
175+
}
176+
177+
declare i32 @llvm.riscv.cv.mac.machhuRN(i32, i32, i32, i32)
178+
179+
define i32 @test.machhuRN(i32 %a, i32 %b, i32 %c) {
180+
; CHECK-LABEL: test.machhuRN:
181+
; CHECK: # %bb.0:
182+
; CHECK-NEXT: cv.machhurn a2, a0, a1, 5
183+
; CHECK-NEXT: mv a0, a2
184+
; CHECK-NEXT: ret
185+
%1 = call i32 @llvm.riscv.cv.mac.machhuRN(i32 %a, i32 %b, i32 %c, i32 5)
186+
ret i32 %1
187+
}
188+
189+
declare i32 @llvm.riscv.cv.mac.macsRN(i32, i32, i32, i32)
190+
191+
define i32 @test.macsRN(i32 %a, i32 %b, i32 %c) {
192+
; CHECK-LABEL: test.macsRN:
193+
; CHECK: # %bb.0:
194+
; CHECK-NEXT: cv.macsrn a2, a0, a1, 5
195+
; CHECK-NEXT: mv a0, a2
196+
; CHECK-NEXT: ret
197+
%1 = call i32 @llvm.riscv.cv.mac.macsRN(i32 %a, i32 %b, i32 %c, i32 5)
198+
ret i32 %1
199+
}
200+
201+
declare i32 @llvm.riscv.cv.mac.machhsRN(i32, i32, i32, i32)
202+
203+
define i32 @test.machhsRN(i32 %a, i32 %b, i32 %c) {
204+
; CHECK-LABEL: test.machhsRN:
205+
; CHECK: # %bb.0:
206+
; CHECK-NEXT: cv.machhsrn a2, a0, a1, 5
207+
; CHECK-NEXT: mv a0, a2
208+
; CHECK-NEXT: ret
209+
%1 = call i32 @llvm.riscv.cv.mac.machhsRN(i32 %a, i32 %b, i32 %c, i32 5)
210+
ret i32 %1
211+
}

0 commit comments

Comments
 (0)