@@ -91,3 +91,216 @@ def TuneLDADDFusion
9191 CheckIsImmOperand<2>,
9292 CheckImmOperand<2, 0>
9393 ]>>;
94+
95+ // Get lower 16 bits:
96+ // slliw r1, r0, 16
97+ // srliw r1, r1, 16
98+ def GetLower16BitsFusion
99+ : SimpleFusion<"get-lower-16bits-fusion", "HasGetLower16BitsFusion",
100+ "Enable SLLIW+SRLIW to be fused to get lower 16 bits",
101+ CheckAll<[
102+ CheckOpcode<[SLLIW]>,
103+ CheckImmOperand<2, 16>
104+ ]>,
105+ CheckAll<[
106+ CheckOpcode<[SRLIW]>,
107+ CheckImmOperand<2, 16>
108+ ]>>;
109+
110+ // Sign-extend a 16-bit number:
111+ // slliw r1, r0, 16
112+ // sraiw r1, r1, 16
113+ def SExtHFusion
114+ : SimpleFusion<"sign-extend-16bits-fusion","HasSExtHFusion",
115+ "Enable SLLIW+SRAIW to be fused to sign-extend a 16-bit number",
116+ CheckAll<[
117+ CheckOpcode<[SLLIW]>,
118+ CheckImmOperand<2, 16>
119+ ]>,
120+ CheckAll<[
121+ CheckOpcode<[SRAIW]>,
122+ CheckImmOperand<2, 16>
123+ ]>>;
124+
125+ // These should be covered by Zba extension.
126+ // * shift left by one and add:
127+ // slli r1, r0, 1
128+ // add r1, r1, r2
129+ // * shift left by two and add:
130+ // slli r1, r0, 2
131+ // add r1, r1, r2
132+ // * shift left by three and add:
133+ // slli r1, r0, 3
134+ // add r1, r1, r2
135+ def ShiftNAddFusion
136+ : SimpleFusion<"shift-n-add-fusion", "HasShiftNAddFusion",
137+ "Enable SLLI+ADD to be fused to shift left by 1/2/3 and add",
138+ CheckAll<[
139+ CheckOpcode<[SLLI]>,
140+ CheckAny<[CheckImmOperand<2, 1>,
141+ CheckImmOperand<2, 2>,
142+ CheckImmOperand<2, 3>]>
143+ ]>,
144+ CheckOpcode<[ADD]>>;
145+
146+ // * Shift zero-extended word left by 1:
147+ // slli r1, r0, 32
148+ // srli r1, r0, 31
149+ // * Shift zero-extended word left by 2:
150+ // slli r1, r0, 32
151+ // srli r1, r0, 30
152+ // * Shift zero-extended word left by 3:
153+ // slli r1, r0, 32
154+ // srli r1, r0, 29
155+ def ShiftZExtByNFusion
156+ : SimpleFusion<"shift-zext-by-n-fusion", "HasShiftZExtByNFusion",
157+ "Enable SLLI+SRLI to be fused to shift zero-extended word left by 1/2/3",
158+ CheckAll<[
159+ CheckOpcode<[SLLI]>,
160+ CheckImmOperand<2, 32>
161+ ]>,
162+ CheckAll<[
163+ CheckOpcode<[SRLI]>,
164+ CheckAny<[CheckImmOperand<2, 29>,
165+ CheckImmOperand<2, 30>,
166+ CheckImmOperand<2, 31>]>
167+ ]>>;
168+
169+ // Get the second byte:
170+ // srli r1, r0, 8
171+ // andi r1, r1, 255
172+ def GetSecondByteFusion
173+ : SimpleFusion<"get-second-byte-fusion", "HasGetSecondByteFusion",
174+ "Enable SRLI+ANDI to be fused to get the second byte",
175+ CheckAll<[
176+ CheckOpcode<[SRLI]>,
177+ CheckImmOperand<2, 8>
178+ ]>,
179+ CheckAll<[
180+ CheckOpcode<[ANDI]>,
181+ CheckImmOperand<2, 255>
182+ ]>>;
183+
184+ // Shift left by four and add:
185+ // slli r1, r0, 4
186+ // add r1, r1, r2
187+ def ShiftLeft4AddFusion
188+ : SimpleFusion<"shift-left-four-add-fusion", "HasShiftLeft4AddFusion",
189+ "Enable SLLI+ADD to be fused to shift left by four and add",
190+ CheckAll<[
191+ CheckOpcode<[SLLI]>,
192+ CheckImmOperand<2, 4>
193+ ]>,
194+ CheckOpcode<[ADD]>>;
195+
196+ // * Shift right by 29 and add:
197+ // srli r1, r0, 29
198+ // add r1, r1, r2
199+ // * Shift right by 30 and add:
200+ // srli r1, r0, 30
201+ // add r1, r1, r2
202+ // * Shift right by 31 and add:
203+ // srli r1, r0, 31
204+ // add r1, r1, r2
205+ // * Shift right by 32 and add:
206+ // srli r1, r0, 32
207+ // add r1, r1, r2
208+ def ShiftRightNAddFusion
209+ : SimpleFusion<"shift-right-n-add-fusion", "HasShiftRightNAddFusion",
210+ "Enable SRLI+add to be fused to shift right by 29/30/31/32 and add",
211+ CheckAll<[
212+ CheckOpcode<[SRLI]>,
213+ CheckAny<[CheckImmOperand<2, 29>,
214+ CheckImmOperand<2, 30>,
215+ CheckImmOperand<2, 31>,
216+ CheckImmOperand<2, 32>]>
217+ ]>,
218+ CheckOpcode<[ADD]>>;
219+
220+ // Add one if odd, otherwise unchanged:
221+ // andi r1, r0, 1
222+ // add r1, r1, r2
223+ // Add one if odd (in word format), otherwise unchanged:
224+ // andi r1, r0, 1
225+ // addw r1, r1, r2
226+ def AddOneIfOddFusion
227+ : SimpleFusion<"add-one-if-odd-fusion", "HasAddOneIfOddFusion",
228+ "Enable ANDI+ADDW to be fused to add one if odd",
229+ CheckAll<[
230+ CheckOpcode<[ANDI]>,
231+ CheckImmOperand<2, 1>
232+ ]>,
233+ CheckOpcode<[ADD, ADDW]>>;
234+
235+ // * Add word and extract its lower 1 bit:
236+ // andw r1, r1, r0
237+ // andi r1, r1, 1
238+ // * Add word and extract its lower 8 bits:
239+ // andw r1, r1, r0
240+ // andi r1, r1, 255
241+ def AddAndExtractNBitsFusion
242+ : SimpleFusion<"add-and-extract-n-bits-fusion", "HasAddAndExtractNBitsFusion",
243+ "Enable ADDW+ANDI to be fused to get lower 16 bits",
244+ CheckOpcode<[ADDW]>,
245+ CheckAll<[
246+ CheckOpcode<[ANDI]>,
247+ CheckAny<[CheckImmOperand<2, 1>,
248+ CheckImmOperand<2, 255>]>
249+ ]>>;
250+
251+ // * Add word and zext.h:
252+ // andw r1, r1, r0
253+ // zext.h r1, r1
254+ // * Add word and sext.h:
255+ // andw r1, r1, r0
256+ // sext.h r1, r1
257+ def AddwAndExtFusion
258+ : SimpleFusion<"addw-and-ext-fusion", "HasAddwAndExtFusion",
259+ "Enable ADDW+ZEXT_H/SEXT_H to be fused",
260+ CheckOpcode<[ADDW]>,
261+ CheckOpcode<[ZEXT_H_RV32, ZEXT_H_RV64, SEXT_H]>>;
262+
263+ // Logic operation and extract its LSB:
264+ // <logic op> r1, r1, r0
265+ // andi r1, r1, 1
266+ def LogicOpAndExtractLSBFusion
267+ : SimpleFusion<"logic-op-and-extract-lsb-fusion", "HasLogicOpAndExtractLSBFusion",
268+ "Enable AND/OR/XOR/ANDI/ORI/XORI/ORC_B+ANDI to be fused to logic operation and extract its LSB",
269+ CheckOpcode<[AND, OR, XOR, ANDI, ORI, XORI, ORC_B]>,
270+ CheckAll<[
271+ CheckOpcode<[ANDI]>,
272+ CheckImmOperand<2, 1>
273+ ]>>;
274+
275+ // Logic operation and extract its lower 16 bits:
276+ // <logic op> r1, r1, r0
277+ // zext.h r1, r1, 1
278+ def LogicOpAndExtractLow16BitsFusion
279+ : SimpleFusion<"logic-op-and-extract-low-16bits-fusion", "HasLogicOpAndExtractLow16BitsFusion",
280+ "Enable AND/OR/XOR/ANDI/ORI/XORI/ORC_B+ANDI to be fused to logic operation and extract its lower 16 bits",
281+ CheckOpcode<[AND, OR, XOR, ANDI, ORI, XORI, ORC_B]>,
282+ CheckOpcode<[ZEXT_H_RV32, ZEXT_H_RV64]>>;
283+
284+ // OR(Cat(src1(63, 8), 0.U(8.W)), src2):
285+ // andi r1, r0, -256
286+ // or r1, r1, r2
287+ def OrCatFusion
288+ : SimpleFusion<"or-cat-fusion", "HasOrCatFusion",
289+ "Enable SLLIW+SRLIW to be fused to get lower 16 bits",
290+ CheckAll<[
291+ CheckOpcode<[ANDI]>,
292+ CheckImmOperand<2, -256>
293+ ]>,
294+ CheckOpcode<[OR]>>;
295+
296+ // Multiply 7-bit data with 32-bit data:
297+ // andi r1, r0, 127
298+ // mulw r1, r1, r2
299+ def Mul7BitsWith32BitsFusion
300+ : SimpleFusion<"mul-7bits-with-32bit-fusion", "HasMul7BitsWith32BitsFusion",
301+ "Enable ANDI+MULW to be fused to multiply 7-bit data with 32-bit data",
302+ CheckAll<[
303+ CheckOpcode<[ANDI]>,
304+ CheckImmOperand<2, 127>
305+ ]>,
306+ CheckOpcode<[MULW]>>;
0 commit comments