@@ -91,3 +91,216 @@ 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
+ 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