Skip to content

Commit 6441df3

Browse files
authored
[RISCV] Implement Intrinsics for XCVmac Extension in CV32E40P (#83112)
Implement XCVmac intrinsics 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 0fc4e30 commit 6441df3

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
@@ -30,6 +30,18 @@ class ScalarCoreVAluGprGprGprIntrinsic
3030
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
3131
[IntrNoMem, IntrSpeculatable]>;
3232

33+
class ScalarCoreVMacGprGprGprIntrinsic
34+
: Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
35+
[IntrNoMem, IntrWillReturn, IntrSpeculatable]>;
36+
37+
class ScalarCoreVMacGprGPRImmIntrinsic
38+
: Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
39+
[IntrNoMem, IntrWillReturn, IntrSpeculatable, ImmArg<ArgIndex<2>>]>;
40+
41+
class ScalarCoreVMacGprGprGprImmIntrinsic
42+
: Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
43+
[IntrNoMem, IntrWillReturn, IntrSpeculatable, ImmArg<ArgIndex<3>>]>;
44+
3345
let TargetPrefix = "riscv" in {
3446
def int_riscv_cv_bitmanip_extract : ScalarCoreVBitManipGprGprIntrinsic;
3547
def int_riscv_cv_bitmanip_extractu : ScalarCoreVBitManipGprGprIntrinsic;
@@ -57,4 +69,25 @@ let TargetPrefix = "riscv" in {
5769
def int_riscv_cv_alu_subun : ScalarCoreVAluGprGprGprIntrinsic;
5870
def int_riscv_cv_alu_subrn : ScalarCoreVAluGprGprGprIntrinsic;
5971
def int_riscv_cv_alu_suburn : ScalarCoreVAluGprGprGprIntrinsic;
72+
73+
def int_riscv_cv_mac_mac : ScalarCoreVMacGprGprGprIntrinsic;
74+
def int_riscv_cv_mac_msu : ScalarCoreVMacGprGprGprIntrinsic;
75+
76+
def int_riscv_cv_mac_muluN : ScalarCoreVMacGprGPRImmIntrinsic;
77+
def int_riscv_cv_mac_mulhhuN : ScalarCoreVMacGprGPRImmIntrinsic;
78+
def int_riscv_cv_mac_mulsN : ScalarCoreVMacGprGPRImmIntrinsic;
79+
def int_riscv_cv_mac_mulhhsN : ScalarCoreVMacGprGPRImmIntrinsic;
80+
def int_riscv_cv_mac_muluRN : ScalarCoreVMacGprGPRImmIntrinsic;
81+
def int_riscv_cv_mac_mulhhuRN : ScalarCoreVMacGprGPRImmIntrinsic;
82+
def int_riscv_cv_mac_mulsRN : ScalarCoreVMacGprGPRImmIntrinsic;
83+
def int_riscv_cv_mac_mulhhsRN : ScalarCoreVMacGprGPRImmIntrinsic;
84+
85+
def int_riscv_cv_mac_macuN : ScalarCoreVMacGprGprGprImmIntrinsic;
86+
def int_riscv_cv_mac_machhuN : ScalarCoreVMacGprGprGprImmIntrinsic;
87+
def int_riscv_cv_mac_macsN : ScalarCoreVMacGprGprGprImmIntrinsic;
88+
def int_riscv_cv_mac_machhsN : ScalarCoreVMacGprGprGprImmIntrinsic;
89+
def int_riscv_cv_mac_macuRN : ScalarCoreVMacGprGprGprImmIntrinsic;
90+
def int_riscv_cv_mac_machhuRN : ScalarCoreVMacGprGprGprImmIntrinsic;
91+
def int_riscv_cv_mac_macsRN : ScalarCoreVMacGprGprGprImmIntrinsic;
92+
def int_riscv_cv_mac_machhsRN : ScalarCoreVMacGprGprGprImmIntrinsic;
6093
} // TargetPrefix = "riscv"

llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,3 +826,36 @@ let Predicates = [HasVendorXCVbi, IsRV32], AddedComplexity = 2 in {
826826
def : Selectbi<SETEQ>;
827827
def : Selectbi<SETNE>;
828828
}
829+
830+
class PatCoreVMacGprGprGpr <string intr, string asm>
831+
: Pat<(!cast<Intrinsic>("int_riscv_cv_mac_" # intr) GPR:$rs1, GPR:$rs2, GPR:$rd),
832+
(!cast<RVInst>("CV_" # asm) GPR:$rd, GPR:$rs1, GPR:$rs2)>;
833+
class PatCoreVMacGprGprGprUimm5 <string intr, string asm>
834+
: Pat<(!cast<Intrinsic>("int_riscv_cv_mac_" # intr) GPR:$rs1, GPR:$rs2, GPR:$rd, cv_tuimm5:$imm5),
835+
(!cast<RVInst>("CV_" # asm) GPR:$rd, GPR:$rs1, GPR:$rs2, cv_tuimm5:$imm5)>;
836+
class PatCoreVMacGprGprUimm5 <string intr, string asm>
837+
: Pat<(!cast<Intrinsic>("int_riscv_cv_mac_" # intr) GPR:$rs1, GPR:$rs2, cv_tuimm5:$imm5),
838+
(!cast<RVInst>("CV_" # asm) GPR:$rs1, GPR:$rs2, cv_tuimm5:$imm5)>;
839+
840+
let Predicates = [HasVendorXCVmac] in {
841+
def : PatCoreVMacGprGprGpr<"mac", "MAC">;
842+
def : PatCoreVMacGprGprGpr<"msu", "MSU">;
843+
844+
def : PatCoreVMacGprGprUimm5<"muluN", "MULUN">;
845+
def : PatCoreVMacGprGprUimm5<"mulhhuN", "MULHHUN">;
846+
def : PatCoreVMacGprGprUimm5<"mulsN", "MULSN">;
847+
def : PatCoreVMacGprGprUimm5<"mulhhsN", "MULHHSN">;
848+
def : PatCoreVMacGprGprUimm5<"muluRN", "MULURN">;
849+
def : PatCoreVMacGprGprUimm5<"mulhhuRN", "MULHHURN">;
850+
def : PatCoreVMacGprGprUimm5<"mulsRN", "MULSRN">;
851+
def : PatCoreVMacGprGprUimm5<"mulhhsRN", "MULHHSRN">;
852+
853+
def : PatCoreVMacGprGprGprUimm5<"macuN", "MACUN">;
854+
def : PatCoreVMacGprGprGprUimm5<"machhuN", "MACHHUN">;
855+
def : PatCoreVMacGprGprGprUimm5<"macsN", "MACSN">;
856+
def : PatCoreVMacGprGprGprUimm5<"machhsN", "MACHHSN">;
857+
def : PatCoreVMacGprGprGprUimm5<"macuRN", "MACURN">;
858+
def : PatCoreVMacGprGprGprUimm5<"machhuRN", "MACHHURN">;
859+
def : PatCoreVMacGprGprGprUimm5<"macsRN", "MACSRN">;
860+
def : PatCoreVMacGprGprGprUimm5<"machhsRN", "MACHHSRN">;
861+
}

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)