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