blob: fae89893ecbcbceee432574aa12248683ef7695a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
|
;; Iterators for the machine description for RISC-V
;; Copyright (C) 2011-2024 Free Software Foundation, Inc.
;; This file is part of GCC.
;;
;; GCC is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; GCC is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
;; -------------------------------------------------------------------
;; Mode Iterators
;; -------------------------------------------------------------------
;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated
;; from the same template.
(define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
;; A copy of GPR that can be used when a pattern has two independent
;; modes.
(define_mode_iterator GPR2 [SI (DI "TARGET_64BIT")])
;; This mode iterator allows :P to be used for patterns that operate on
;; pointer-sized quantities. Exactly one of the two alternatives will match.
(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
;; Likewise, but for XLEN-sized quantities.
(define_mode_iterator X [(SI "!TARGET_64BIT") (DI "TARGET_64BIT")])
;; Likewise, but for XLEN/2 -sized quantities.
(define_mode_iterator HX [(HI "!TARGET_64BIT") (SI "TARGET_64BIT")])
;; Branches operate on XLEN-sized quantities, but for RV64 we accept
;; QImode values so we can force zero-extension.
(define_mode_iterator BR [(QI "TARGET_64BIT") SI (DI "TARGET_64BIT")])
;; 32-bit moves for which we provide move patterns.
(define_mode_iterator MOVE32 [SI])
;; 64-bit modes for which we provide move patterns.
(define_mode_iterator MOVE64 [DI DF])
;; Iterator for sub-32-bit integer modes.
(define_mode_iterator SHORT [QI HI])
;; Iterator for HImode constant generation.
(define_mode_iterator HISI [HI SI])
;; Iterator for QImode extension patterns.
(define_mode_iterator SUPERQI [HI SI (DI "TARGET_64BIT")])
;; Iterator for hardware integer modes narrower than XLEN.
(define_mode_iterator SUBX [QI HI (SI "TARGET_64BIT")])
;; Iterator for hardware integer modes narrower than XLEN, same as SUBX.
(define_mode_iterator SUBX1 [QI HI (SI "TARGET_64BIT")])
;; Iterator for hardware-supported integer modes.
(define_mode_iterator ANYI [QI HI SI (DI "TARGET_64BIT")])
;; Iterator for hardware integer modes narrower than XLEN, same as ANYI.
(define_mode_iterator ANYI1 [QI HI SI (DI "TARGET_64BIT")])
(define_mode_iterator ANYI_DOUBLE_TRUNC [HI SI (DI "TARGET_64BIT")])
(define_mode_iterator ANYI_QUAD_TRUNC [SI (DI "TARGET_64BIT")])
(define_mode_iterator ANYI_OCT_TRUNC [(DI "TARGET_64BIT")])
(define_mode_attr ANYI_DOUBLE_TRUNCATED [
(HI "QI") (SI "HI") (DI "SI")
])
(define_mode_attr ANYI_QUAD_TRUNCATED [
(SI "QI") (DI "HI")
])
(define_mode_attr ANYI_OCT_TRUNCATED [
(DI "QI")
])
(define_mode_attr anyi_double_truncated [
(HI "qi") (SI "hi") (DI "si")
])
(define_mode_attr anyi_quad_truncated [
(SI "qi") (DI "hi")
])
(define_mode_attr anyi_oct_truncated [
(DI "qi")
])
;; Iterator for hardware-supported floating-point modes.
(define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT || TARGET_ZFINX")
(DF "TARGET_DOUBLE_FLOAT || TARGET_ZDINX")
(HF "TARGET_ZFH || TARGET_ZHINX")])
;; Iterator for hardware-supported load/store floating-point modes.
(define_mode_iterator ANYLSF [(SF "TARGET_HARD_FLOAT || TARGET_ZFINX")
(DF "TARGET_DOUBLE_FLOAT || TARGET_ZDINX")
(HF "TARGET_ZFHMIN || TARGET_ZHINXMIN")])
;; Iterator for floating-point modes that can be loaded into X registers.
(define_mode_iterator SOFTF [SF (DF "TARGET_64BIT") (HF "TARGET_ZFHMIN")])
;; Iterator for floating-point modes of BF16.
(define_mode_iterator HFBF [HF BF])
;; Conversion between floating-point modes and BF16.
;; SF to BF16 have hardware instructions.
(define_mode_iterator FBF [HF DF TF])
;; -------------------------------------------------------------------
;; Mode attributes
;; -------------------------------------------------------------------
;; This attribute gives the length suffix for a sign- or zero-extension
;; instruction.
(define_mode_attr size [(QI "b") (HI "h")])
;; Mode attributes for loads.
(define_mode_attr load [(QI "lb") (HI "lh") (SI "lw") (DI "ld") (HF "flh") (SF "flw") (DF "fld")])
;; Instruction names for integer loads that aren't explicitly sign or zero
;; extended. See riscv_output_move and LOAD_EXTEND_OP.
(define_mode_attr default_load [(QI "lbu") (HI "lhu") (SI "lw") (DI "ld")])
;; Mode attribute for FP loads into integer registers.
(define_mode_attr softload [(HF "lh") (SF "lw") (DF "ld")])
;; Instruction names for stores.
(define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd") (HF "fsh") (SF "fsw") (DF "fsd")])
;; Instruction names for FP stores from integer registers.
(define_mode_attr softstore [(HF "sh") (SF "sw") (DF "sd")])
;; This attribute gives the best constraint to use for registers of
;; a given mode.
(define_mode_attr reg [(SI "d") (DI "d") (CC "d")])
;; This attribute gives the format suffix for floating-point operations.
(define_mode_attr fmt [(HF "h") (SF "s") (DF "d")])
;; This attribute gives the integer suffix for floating-point conversions.
(define_mode_attr ifmt [(SI "w") (DI "l")])
;; This attribute gives the format suffix for atomic memory operations.
(define_mode_attr amo [(SI "w") (DI "d")])
;; This attribute gives the format suffix for byte and halfword atomic memory operations.
(define_mode_attr amobh [(QI "b") (HI "h")])
;; This attribute gives the upper-case mode name for one unit of a
;; floating-point mode.
(define_mode_attr UNITMODE [(HF "HF") (SF "SF") (DF "DF")])
;; This attribute gives the integer mode that has half the size of
;; the controlling mode.
(define_mode_attr HALFMODE [(DF "SI") (DI "SI") (TF "DI")])
; bitmanip mode attribute
(define_mode_attr shiftm1 [(SI "const_si_mask_operand") (DI "const_di_mask_operand")])
(define_mode_attr shiftm1p [(SI "DsS") (DI "DsD")])
; zcmp mode attribute
(define_mode_attr slot0_offset [(SI "-4") (DI "-8")])
(define_mode_attr slot1_offset [(SI "-8") (DI "-16")])
(define_mode_attr slot2_offset [(SI "-12") (DI "-24")])
(define_mode_attr slot3_offset [(SI "-16") (DI "-32")])
(define_mode_attr slot4_offset [(SI "-20") (DI "-40")])
(define_mode_attr slot5_offset [(SI "-24") (DI "-48")])
(define_mode_attr slot6_offset [(SI "-28") (DI "-56")])
(define_mode_attr slot7_offset [(SI "-32") (DI "-64")])
(define_mode_attr slot8_offset [(SI "-36") (DI "-72")])
(define_mode_attr slot9_offset [(SI "-40") (DI "-80")])
(define_mode_attr slot10_offset [(SI "-44") (DI "-88")])
(define_mode_attr slot11_offset [(SI "-48") (DI "-96")])
(define_mode_attr slot12_offset [(SI "-52") (DI "-104")])
;; -------------------------------------------------------------------
;; Code Iterators
;; -------------------------------------------------------------------
;; This code iterator allows signed and unsigned widening multiplications
;; to use the same template.
(define_code_iterator any_extend [sign_extend zero_extend])
;; These code iterators allow unsigned and signed extraction to be generated
;; from the same template.
(define_code_iterator any_extract [sign_extract zero_extract])
(define_code_attr extract_sidi_shift [(sign_extract "sraiw")
(zero_extract "srliw")])
(define_code_attr extract_shift [(sign_extract "ashiftrt")
(zero_extract "lshiftrt")])
;; This code iterator allows the two right shift instructions to be
;; generated from the same template.
(define_code_iterator any_shiftrt [ashiftrt lshiftrt])
;; This code iterator allows the three shift instructions to be generated
;; from the same template.
(define_code_iterator any_shift [ashift ashiftrt lshiftrt])
;; This code iterator allows the three bitwise instructions to be generated
;; from the same template.
(define_code_iterator any_bitwise [and ior xor])
;; This code iterator allows ior and xor instructions to be generated
;; from the same template.
(define_code_iterator any_or [ior xor])
;; This code iterator allows unsigned and signed division to be generated
;; from the same template.
(define_code_iterator any_div [div udiv mod umod])
;; This code iterator allows unsigned and signed modulus to be generated
;; from the same template.
(define_code_iterator any_mod [mod umod])
;; These code iterators allow unsigned and signed divmod to be generated
;; from the same template.
(define_code_iterator only_div [div udiv])
(define_code_attr paired_mod [(div "mod") (udiv "umod")])
;; These code iterators allow the signed and unsigned scc operations to use
;; the same template.
(define_code_iterator any_gt [gt gtu])
(define_code_iterator any_ge [ge geu])
(define_code_iterator any_lt [lt ltu])
(define_code_iterator any_le [le leu])
(define_code_iterator any_eq [eq ne])
;; Iterators for conditions we can emit a sCC against 0 or a reg directly
(define_code_iterator scc_0 [eq ne gt gtu])
; atomics code iterator
(define_code_iterator any_atomic [plus ior xor and])
; bitmanip code iterators
(define_code_iterator bitmanip_bitwise [and ior])
(define_code_iterator bitmanip_minmax [smin umin smax umax])
(define_code_iterator clz_ctz_pcnt [clz ctz popcount])
(define_code_iterator bitmanip_rotate [rotate rotatert])
;; These code iterators allow the signed and unsigned fix operations to use
;; the same template.
(define_code_iterator fix_ops [fix unsigned_fix])
(define_code_attr fix_uns [(fix "fix") (unsigned_fix "fixuns")])
;; -------------------------------------------------------------------
;; Code Attributes
;; -------------------------------------------------------------------
;; <u> expands to an empty string when doing a signed operation and
;; "u" when doing an unsigned operation.
(define_code_attr u [(sign_extend "") (zero_extend "u")
(gt "") (gtu "u")
(ge "") (geu "u")
(lt "") (ltu "u")
(le "") (leu "u")
(fix "") (unsigned_fix "u")
(div "") (udiv "u")
(float "") (unsigned_float "u")])
;; <su> is like <u>, but the signed form expands to "s" rather than "".
(define_code_attr su [(sign_extend "s") (zero_extend "u")])
;; <optab> expands to the name of the optab for a particular code.
(define_code_attr optab [(ashift "ashl")
(ashiftrt "ashr")
(lshiftrt "lshr")
(div "div")
(mod "mod")
(udiv "udiv")
(umod "umod")
(ge "ge")
(le "le")
(gt "gt")
(lt "lt")
(eq "eq")
(ne "ne")
(ior "ior")
(xor "xor")
(and "and")
(plus "add")
(minus "sub")
(smin "smin")
(smax "smax")
(umin "umin")
(umax "umax")
(mult "mul")
(not "one_cmpl")
(neg "neg")
(abs "abs")
(sqrt "sqrt")
(ss_plus "ssadd")
(us_plus "usadd")
(ss_minus "sssub")
(us_minus "ussub")
(sign_extend "extend")
(zero_extend "zero_extend")
(sign_extract "extract")
(zero_extract "zero_extract")
(fix "fix_trunc")
(unsigned_fix "fixuns_trunc")])
(define_code_attr bit_optab [(ior "bset")
(xor "binv")])
;; <or_optab> code attributes
(define_code_attr or_optab [(ior "ior")
(xor "xor")])
;; <insn> expands to the name of the insn that implements a particular code.
(define_code_attr insn [(ashift "sll")
(ashiftrt "sra")
(lshiftrt "srl")
(div "div")
(mod "rem")
(udiv "divu")
(umod "remu")
(ior "or")
(xor "xor")
(and "and")
(plus "add")
(minus "sub")
(smin "min")
(smax "max")
(umin "minu")
(umax "maxu")
(mult "mul")
(not "not")
(neg "neg")
(abs "abs")
(sqrt "sqrt")
(ss_plus "sadd")
(us_plus "saddu")
(ss_minus "ssub")
(us_minus "ssubu")])
; atomics code attribute
(define_code_attr atomic_optab
[(plus "add") (ior "or") (xor "xor") (and "and")])
; bitmanip code attributes
;; Unsigned variant of a min/max optab.
(define_code_attr uminmax_optab [(smin "umin")
(smax "umax")
(umin "umin")
(umax "umax")])
(define_code_attr bitmanip_optab [(smin "smin")
(smax "smax")
(umin "umin")
(umax "umax")
(clz "clz")
(ctz "ctz")
(popcount "popcount")
(rotate "rotl")
(rotatert "rotr")])
(define_code_attr bitmanip_insn [(smin "min")
(smax "max")
(umin "minu")
(umax "maxu")
(clz "clz")
(ctz "ctz")
(popcount "cpop")
(rotate "rol")
(rotatert "ror")])
;; -------------------------------------------------------------------
;; Int Iterators.
;; -------------------------------------------------------------------
;; Iterator and attributes for quiet comparisons.
(define_int_iterator QUIET_COMPARISON [UNSPEC_FLT_QUIET UNSPEC_FLE_QUIET])
(define_int_attr quiet_pattern [(UNSPEC_FLT_QUIET "lt") (UNSPEC_FLE_QUIET "le")])
(define_int_attr QUIET_PATTERN [(UNSPEC_FLT_QUIET "LT") (UNSPEC_FLE_QUIET "LE")])
(define_int_iterator ROUND [UNSPEC_ROUND UNSPEC_FLOOR UNSPEC_CEIL UNSPEC_BTRUNC UNSPEC_ROUNDEVEN UNSPEC_NEARBYINT])
(define_int_attr round_pattern [(UNSPEC_ROUND "round") (UNSPEC_FLOOR "floor") (UNSPEC_CEIL "ceil")
(UNSPEC_BTRUNC "btrunc") (UNSPEC_ROUNDEVEN "roundeven") (UNSPEC_NEARBYINT "nearbyint")])
(define_int_attr round_rm [(UNSPEC_ROUND "rmm") (UNSPEC_FLOOR "rdn") (UNSPEC_CEIL "rup")
(UNSPEC_BTRUNC "rtz") (UNSPEC_ROUNDEVEN "rne") (UNSPEC_NEARBYINT "dyn")])
|