Skip to content

Commit 35de0b9

Browse files
committed
[RISCV] Add macro fusions for Xiangshan
Doc: https://xiangshan-doc.readthedocs.io/zh-cn/latest/frontend/decode/ This PR is to show the usage of TableGen-based macro fusions. Some instrcution pairs can be folded into one MacroFusion definition but I leave them standalone to show the different ways to define a macro fusion. This PR is stacked on llvm#72219, llvm#72222, llvm#72223, llvm#72224, llvm#72227
1 parent 0c623b5 commit 35de0b9

File tree

1 file changed

+213
-0
lines changed

1 file changed

+213
-0
lines changed

llvm/lib/Target/RISCV/RISCVMacroFusion.td

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)