Daily bump.
[official-gcc.git] / gcc / config / riscv / genrvv-type-indexer.cc
blob8626ddeaaa8b169bb3c2f046cc0e578e5b920e44
1 /* Generate the RVV type indexer tables.
2 Copyright (C) 2023-2024 Free Software Foundation, Inc.
3 This file is part of GCC.
4 GCC is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 3, or (at your option) any later
7 version.
8 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
9 WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 for more details.
12 You should have received a copy of the GNU General Public License
13 along with GCC; see the file COPYING3. If not see
14 <http://www.gnu.org/licenses/>. */
16 #include "bconfig.h"
17 #define INCLUDE_SSTREAM
18 #include "system.h"
19 #include "errors.h"
21 #include "coretypes.h"
23 #include <assert.h>
24 #include <math.h>
26 #define BOOL_SIZE_LIST {1, 2, 4, 8, 16, 32, 64}
27 #define EEW_SIZE_LIST {8, 16, 32, 64}
28 #define LMUL1_LOG2 0
30 std::string
31 to_lmul (int lmul_log2)
33 std::stringstream lmul_str;
34 if (lmul_log2 >= 0)
35 lmul_str << "m";
36 else
38 lmul_str << "mf";
39 lmul_log2 = -lmul_log2;
42 lmul_str << (1 << lmul_log2);
43 return lmul_str.str ();
46 bool
47 valid_type (unsigned sew, int lmul_log2, bool float_p)
49 if (lmul_log2 > 3)
50 return false;
52 switch (sew)
54 case 8:
55 return lmul_log2 >= -3 && !float_p;
56 case 16:
57 return lmul_log2 >= -2;
58 case 32:
59 return lmul_log2 >= -1;
60 case 64:
61 return lmul_log2 >= 0;
62 default:
63 return false;
67 bool
68 valid_type (unsigned sew, int lmul_log2, unsigned nf, bool float_p)
70 if (!valid_type (sew, lmul_log2, float_p))
71 return false;
73 if (nf > 8 || nf < 1)
74 return false;
76 switch (lmul_log2)
78 case 1:
79 return nf < 5;
80 case 2:
81 return nf < 3;
82 case 3:
83 return nf == 1;
84 default:
85 return true;
89 std::string
90 inttype (unsigned sew, int lmul_log2, bool unsigned_p)
92 if (!valid_type (sew, lmul_log2, /*float_t*/ false))
93 return "INVALID";
95 std::stringstream mode;
96 mode << "v";
97 if (unsigned_p)
98 mode << "u";
99 mode << "int" << sew << to_lmul (lmul_log2) << "_t";
100 return mode.str ();
103 std::string
104 inttype (unsigned sew, int lmul_log2, unsigned nf, bool unsigned_p)
106 if (!valid_type (sew, lmul_log2, nf, /*float_t*/ false))
107 return "INVALID";
109 std::stringstream mode;
110 mode << "v";
111 if (unsigned_p)
112 mode << "u";
113 mode << "int" << sew << to_lmul (lmul_log2);
114 if (nf > 1)
115 mode << "x" << nf;
116 mode << "_t";
117 return mode.str ();
120 std::string
121 bfloat16_type (int lmul_log2)
123 if (!valid_type (16, lmul_log2, /*float_t*/ true))
124 return "INVALID";
126 std::stringstream mode;
127 mode << "vbfloat16" << to_lmul (lmul_log2) << "_t";
128 return mode.str ();
131 std::string
132 bfloat16_wide_type (int lmul_log2)
134 if (!valid_type (32, lmul_log2, /*float_t*/ true))
135 return "INVALID";
137 std::stringstream mode;
138 mode << "vfloat32" << to_lmul (lmul_log2) << "_t";
139 return mode.str ();
142 std::string
143 bfloat16_type (int lmul_log2, unsigned nf)
145 if (!valid_type (16, lmul_log2, nf, /*float_t*/ true))
146 return "INVALID";
148 std::stringstream mode;
149 mode << "vbfloat16" << to_lmul (lmul_log2);
150 if (nf > 1)
151 mode << "x" << nf;
152 mode << "_t";
153 return mode.str ();
156 std::string
157 floattype (unsigned sew, int lmul_log2)
159 if (!valid_type (sew, lmul_log2, /*float_t*/ true))
160 return "INVALID";
162 std::stringstream mode;
163 mode << "vfloat" << sew << to_lmul (lmul_log2) << "_t";
164 return mode.str ();
167 std::string
168 floattype (unsigned sew, int lmul_log2, unsigned nf)
170 if (!valid_type (sew, lmul_log2, nf, /*float_t*/ true))
171 return "INVALID";
173 std::stringstream mode;
174 mode << "vfloat" << sew << to_lmul (lmul_log2);
175 if (nf > 1)
176 mode << "x" << nf;
177 mode << "_t";
178 return mode.str ();
181 std::string
182 maskmode (unsigned sew, int lmul_log2)
184 if (!valid_type (sew, lmul_log2, /*float_t*/ false))
185 return "INVALID";
187 std::stringstream mode;
189 int mlen;
190 if (lmul_log2 >= 0)
191 mlen = sew / (1 << lmul_log2);
192 else
193 mlen = sew * (1 << -lmul_log2);
195 mode << "vbool" << mlen << "_t";
196 return mode.str ();
199 std::string
200 same_ratio_eew_type (unsigned sew, int lmul_log2, unsigned eew, bool unsigned_p,
201 bool float_p)
203 if (!valid_type (sew, lmul_log2, float_p))
204 return "INVALID";
206 int elmul_log2;
208 if (sew == eew)
209 elmul_log2 = lmul_log2;
210 else if (sew > eew)
211 elmul_log2 = lmul_log2 - log2 (sew / eew);
212 else /* sew < eew */
213 elmul_log2 = lmul_log2 + log2 (eew / sew);
215 if (float_p)
216 return floattype (eew, elmul_log2);
217 else
218 return inttype (eew, elmul_log2, unsigned_p);
221 std::string
222 same_ratio_eew_bf16_type (unsigned sew, int lmul_log2)
224 if (sew != 32)
225 return "INVALID";
226 int elmul_log2 = lmul_log2 - 1;
227 return bfloat16_type (elmul_log2);
231 main (int argc, const char **argv)
233 // Require at least one argument.
234 if (argc < 2)
235 return 1;
237 FILE *fp = fopen (argv[1], "w");
239 if (!fp)
240 return 1;
242 fprintf (fp, "/* Generated by genrvv-type-indexer */\n");
244 for (unsigned vbool : {64, 32, 16, 8, 4, 2, 1})
246 std::stringstream mode;
247 mode << "vbool" << vbool << "_t";
248 fprintf (fp, "DEF_RVV_TYPE_INDEX (\n");
249 fprintf (fp, " /*VECTOR*/ %s,\n", mode.str ().c_str ());
250 fprintf (fp, " /*MASK*/ %s,\n", mode.str ().c_str ());
251 fprintf (fp, " /*SIGNED*/ INVALID,\n");
252 fprintf (fp, " /*UNSIGNED*/ INVALID,\n");
253 for (unsigned eew : {8, 16, 32, 64})
254 fprintf (fp, " /*EEW%d_INDEX*/ INVALID,\n", eew);
255 fprintf (fp, " /*SHIFT*/ INVALID,\n");
256 fprintf (fp, " /*DOUBLE_TRUNC*/ INVALID,\n");
257 fprintf (fp, " /*QUAD_TRUNC*/ INVALID,\n");
258 fprintf (fp, " /*OCT_TRUNC*/ INVALID,\n");
259 fprintf (fp, " /*DOUBLE_TRUNC_SCALAR*/ INVALID,\n");
260 fprintf (fp, " /*DOUBLE_TRUNC_SIGNED*/ INVALID,\n");
261 fprintf (fp, " /*DOUBLE_TRUNC_UNSIGNED*/ INVALID,\n");
262 fprintf (fp, " /*DOUBLE_TRUNC_UNSIGNED_SCALAR*/ INVALID,\n");
263 fprintf (fp, " /*DOUBLE_TRUNC_BFLOAT_SCALAR*/ INVALID,\n");
264 fprintf (fp, " /*DOUBLE_TRUNC_BFLOAT*/ INVALID,\n");
265 fprintf (fp, " /*DOUBLE_TRUNC_FLOAT*/ INVALID,\n");
266 fprintf (fp, " /*FLOAT*/ INVALID,\n");
267 fprintf (fp, " /*LMUL1*/ INVALID,\n");
268 fprintf (fp, " /*WLMUL1*/ INVALID,\n");
269 for (unsigned eew : {8, 16, 32, 64})
270 fprintf (fp, " /*EEW%d_INTERPRET*/ INVALID,\n", eew);
272 for (unsigned boolsize : BOOL_SIZE_LIST)
273 fprintf (fp, " /*BOOL%d_INTERPRET*/ INVALID,\n", boolsize);
275 for (unsigned eew : EEW_SIZE_LIST)
276 fprintf (fp, " /*SIGNED_EEW%d_LMUL1_INTERPRET*/ %s,\n", eew,
277 inttype (eew, LMUL1_LOG2, /* unsigned_p */false).c_str ());
279 for (unsigned eew : EEW_SIZE_LIST)
280 fprintf (fp, " /*UNSIGNED_EEW%d_LMUL1_INTERPRET*/ %s,\n", eew,
281 inttype (eew, LMUL1_LOG2, /* unsigned_p */true).c_str ());
283 for (unsigned lmul_log2_offset : {1, 2, 3, 4, 5, 6})
285 unsigned multiple_of_lmul = 1 << lmul_log2_offset;
286 fprintf (fp, " /*X%d_INTERPRET*/ INVALID,\n", multiple_of_lmul);
288 fprintf (fp, " /*TUPLE_SUBPART*/ INVALID\n");
289 fprintf (fp, ")\n");
292 // Build for vint and vuint
293 for (unsigned sew : {8, 16, 32, 64})
294 for (int lmul_log2 : {-3, -2, -1, 0, 1, 2, 3})
295 for (unsigned nf : {1, 2, 3, 4, 5, 6, 7, 8})
296 for (bool unsigned_p : {false, true})
298 if (!valid_type (sew, lmul_log2, nf, /*float_t*/ false))
299 continue;
301 fprintf (fp, "DEF_RVV_TYPE_INDEX (\n");
302 fprintf (fp, " /*VECTOR*/ %s,\n",
303 inttype (sew, lmul_log2, nf, unsigned_p).c_str ());
304 fprintf (fp, " /*MASK*/ %s,\n",
305 maskmode (sew, lmul_log2).c_str ());
306 fprintf (fp, " /*SIGNED*/ %s,\n",
307 inttype (sew, lmul_log2, /*unsigned_p*/ false).c_str ());
308 fprintf (fp, " /*UNSIGNED*/ %s,\n",
309 inttype (sew, lmul_log2, /*unsigned_p*/ true).c_str ());
310 for (unsigned eew : {8, 16, 32, 64})
311 fprintf (fp, " /*EEW%d_INDEX*/ %s,\n", eew,
312 same_ratio_eew_type (sew, lmul_log2, eew,
313 /*unsigned_p*/ true, false)
314 .c_str ());
315 fprintf (fp, " /*SHIFT*/ %s,\n",
316 inttype (sew, lmul_log2, /*unsigned_p*/ true).c_str ());
317 fprintf (fp, " /*DOUBLE_TRUNC*/ %s,\n",
318 same_ratio_eew_type (sew, lmul_log2, sew / 2, unsigned_p,
319 false)
320 .c_str ());
321 fprintf (fp, " /*QUAD_TRUNC*/ %s,\n",
322 same_ratio_eew_type (sew, lmul_log2, sew / 4, unsigned_p,
323 false)
324 .c_str ());
325 fprintf (fp, " /*OCT_TRUNC*/ %s,\n",
326 same_ratio_eew_type (sew, lmul_log2, sew / 8, unsigned_p,
327 false)
328 .c_str ());
329 fprintf (fp, " /*DOUBLE_TRUNC_SCALAR*/ %s,\n",
330 same_ratio_eew_type (sew, lmul_log2, sew / 2, unsigned_p,
331 false)
332 .c_str ());
333 fprintf (fp, " /*DOUBLE_TRUNC_SIGNED*/ INVALID,\n");
334 fprintf (fp, " /*DOUBLE_TRUNC_UNSIGNED*/ %s,\n",
335 same_ratio_eew_type (sew, lmul_log2, sew / 2, true, false)
336 .c_str ());
337 if (unsigned_p)
338 fprintf (fp, " /*DOUBLE_TRUNC_UNSIGNED_SCALAR*/ INVALID,\n");
339 else
340 fprintf (fp, " /*DOUBLE_TRUNC_UNSIGNED_SCALAR*/ %s,\n",
341 same_ratio_eew_type (sew, lmul_log2, sew / 2, true,
342 false)
343 .c_str ());
344 fprintf (fp, " /*DOUBLE_TRUNC_BFLOAT_SCALAR*/ INVALID,\n");
345 fprintf (fp, " /*DOUBLE_TRUNC_BFLOAT*/ INVALID,\n");
346 fprintf (fp, " /*DOUBLE_TRUNC_FLOAT*/ %s,\n",
347 same_ratio_eew_type (sew, lmul_log2, sew / 2, false, true)
348 .c_str ());
349 fprintf (fp, " /*FLOAT*/ %s,\n",
350 floattype (sew, lmul_log2).c_str ());
351 fprintf (fp, " /*LMUL1*/ %s,\n",
352 inttype (sew, /*lmul_log2*/ 0, unsigned_p).c_str ());
353 fprintf (fp, " /*WLMUL1*/ %s,\n",
354 inttype (sew * 2, /*lmul_log2*/ 0, unsigned_p).c_str ());
355 for (unsigned eew : {8, 16, 32, 64})
357 if (eew == sew)
358 fprintf (fp, " /*EEW%d_INTERPRET*/ INVALID,\n", eew);
359 else
360 fprintf (fp, " /*EEW%d_INTERPRET*/ %s,\n", eew,
361 inttype (eew, lmul_log2, unsigned_p).c_str ());
364 for (unsigned boolsize : BOOL_SIZE_LIST)
366 std::stringstream mode;
367 mode << "vbool" << boolsize << "_t";
369 fprintf (fp, " /*BOOL%d_INTERPRET*/ %s,\n", boolsize,
370 nf == 1 && lmul_log2 == 0 ? mode.str ().c_str ()
371 : "INVALID");
374 for (unsigned eew : EEW_SIZE_LIST)
375 fprintf (fp, " /*SIGNED_EEW%d_LMUL1_INTERPRET*/ INVALID,\n",
376 eew);
378 for (unsigned eew : EEW_SIZE_LIST)
379 fprintf (fp, " /*UNSIGNED_EEW%d_LMUL1_INTERPRET*/ INVALID,\n",
380 eew);
382 for (unsigned lmul_log2_offset : {1, 2, 3, 4, 5, 6})
384 unsigned multiple_of_lmul = 1 << lmul_log2_offset;
385 fprintf (fp, " /*X%d_VLMUL_EXT*/ %s,\n", multiple_of_lmul,
386 inttype (sew, lmul_log2 + lmul_log2_offset, unsigned_p)
387 .c_str ());
389 fprintf (fp, " /*TUPLE_SUBPART*/ %s\n",
390 inttype (sew, lmul_log2, 1, unsigned_p).c_str ());
391 fprintf (fp, ")\n");
393 // Build for vbfloat16
394 for (int lmul_log2 : {-2, -1, 0, 1, 2, 3})
395 for (unsigned nf : {1, 2, 3, 4, 5, 6, 7, 8})
397 if (!valid_type (16, lmul_log2, nf, /*float_t*/ true))
398 continue;
400 fprintf (fp, "DEF_RVV_TYPE_INDEX (\n");
401 fprintf (fp, " /*VECTOR*/ %s,\n",
402 bfloat16_type (lmul_log2, nf).c_str ());
403 fprintf (fp, " /*MASK*/ %s,\n", maskmode (16, lmul_log2).c_str ());
404 fprintf (fp, " /*SIGNED*/ %s,\n",
405 inttype (16, lmul_log2, /*unsigned_p*/ false).c_str ());
406 fprintf (fp, " /*UNSIGNED*/ %s,\n",
407 inttype (16, lmul_log2, /*unsigned_p*/ true).c_str ());
408 for (unsigned eew : {8, 16, 32, 64})
409 fprintf (
410 fp, " /*EEW%d_INDEX*/ %s,\n", eew,
411 same_ratio_eew_type (16, lmul_log2, eew, true, false).c_str ());
412 fprintf (fp, " /*SHIFT*/ INVALID,\n");
413 fprintf (fp, " /*DOUBLE_TRUNC*/ %s,\n",
414 same_ratio_eew_type (16, lmul_log2, 8, false, true).c_str ());
415 fprintf (fp, " /*QUAD_TRUNC*/ INVALID,\n");
416 fprintf (fp, " /*OCT_TRUNC*/ INVALID,\n");
417 fprintf (fp, " /*DOUBLE_TRUNC_SCALAR*/ %s,\n",
418 same_ratio_eew_type (16, lmul_log2, 8, false, true).c_str ());
419 fprintf (fp, " /*DOUBLE_TRUNC_SIGNED*/ %s,\n",
420 same_ratio_eew_type (16, lmul_log2, 8, false, false).c_str ());
421 fprintf (fp, " /*DOUBLE_TRUNC_UNSIGNED*/ %s,\n",
422 same_ratio_eew_type (16, lmul_log2, 8, true, false).c_str ());
423 fprintf (fp, " /*DOUBLE_TRUNC_UNSIGNED_SCALAR*/ INVALID,\n");
424 fprintf (fp, " /*DOUBLE_TRUNC_BFLOAT_SCALAR*/ INVALID,\n");
425 fprintf (fp, " /*DOUBLE_TRUNC_BFLOAT*/ INVALID,\n");
426 fprintf (fp, " /*DOUBLE_TRUNC_FLOAT*/ %s,\n",
427 same_ratio_eew_type (16, lmul_log2, 8, false, true).c_str ());
428 fprintf (fp, " /*FLOAT*/ INVALID,\n");
429 fprintf (fp, " /*LMUL1*/ %s,\n",
430 bfloat16_type (/*lmul_log2*/ 0).c_str ());
431 fprintf (fp, " /*WLMUL1*/ %s,\n",
432 bfloat16_wide_type (/*lmul_log2*/ 0).c_str ());
433 for (unsigned eew : {8, 16, 32, 64})
434 fprintf (fp, " /*EEW%d_INTERPRET*/ INVALID,\n", eew);
436 for (unsigned boolsize : BOOL_SIZE_LIST)
437 fprintf (fp, " /*BOOL%d_INTERPRET*/ INVALID,\n", boolsize);
439 for (unsigned eew : EEW_SIZE_LIST)
440 fprintf (fp, " /*SIGNED_EEW%d_LMUL1_INTERPRET*/ INVALID,\n", eew);
442 for (unsigned eew : EEW_SIZE_LIST)
443 fprintf (fp, " /*UNSIGNED_EEW%d_LMUL1_INTERPRET*/ INVALID,\n", eew);
445 for (unsigned lmul_log2_offset : {1, 2, 3, 4, 5, 6})
447 unsigned multiple_of_lmul = 1 << lmul_log2_offset;
448 fprintf (fp, " /*X%d_VLMUL_EXT*/ %s,\n", multiple_of_lmul,
449 bfloat16_type (lmul_log2 + lmul_log2_offset).c_str ());
451 fprintf (fp, " /*TUPLE_SUBPART*/ %s\n",
452 bfloat16_type (lmul_log2, 1U).c_str ());
453 fprintf (fp, ")\n");
455 // Build for vfloat
456 for (unsigned sew : {16, 32, 64})
457 for (int lmul_log2 : {-3, -2, -1, 0, 1, 2, 3})
458 for (unsigned nf : {1, 2, 3, 4, 5, 6, 7, 8})
460 if (!valid_type (sew, lmul_log2, nf, /*float_t*/ true))
461 continue;
463 fprintf (fp, "DEF_RVV_TYPE_INDEX (\n");
464 fprintf (fp, " /*VECTOR*/ %s,\n",
465 floattype (sew, lmul_log2, nf).c_str ());
466 fprintf (fp, " /*MASK*/ %s,\n", maskmode (sew, lmul_log2).c_str ());
467 fprintf (fp, " /*SIGNED*/ %s,\n",
468 inttype (sew, lmul_log2, /*unsigned_p*/ false).c_str ());
469 fprintf (fp, " /*UNSIGNED*/ %s,\n",
470 inttype (sew, lmul_log2, /*unsigned_p*/ true).c_str ());
471 for (unsigned eew : {8, 16, 32, 64})
472 fprintf (fp, " /*EEW%d_INDEX*/ %s,\n", eew,
473 same_ratio_eew_type (sew, lmul_log2, eew,
474 /*unsigned_p*/ true, false)
475 .c_str ());
476 fprintf (fp, " /*SHIFT*/ INVALID,\n");
477 fprintf (fp, " /*DOUBLE_TRUNC*/ %s,\n",
478 same_ratio_eew_type (sew, lmul_log2, sew / 2, false, true)
479 .c_str ());
480 fprintf (fp, " /*QUAD_TRUNC*/ INVALID,\n");
481 fprintf (fp, " /*OCT_TRUNC*/ INVALID,\n");
482 fprintf (fp, " /*DOUBLE_TRUNC_SCALAR*/ %s,\n",
483 same_ratio_eew_type (sew, lmul_log2, sew / 2, false, true)
484 .c_str ());
485 fprintf (fp, " /*DOUBLE_TRUNC_SIGNED*/ %s,\n",
486 same_ratio_eew_type (sew, lmul_log2, sew / 2, false, false)
487 .c_str ());
488 fprintf (fp, " /*DOUBLE_TRUNC_UNSIGNED*/ %s,\n",
489 same_ratio_eew_type (sew, lmul_log2, sew / 2, true, false)
490 .c_str ());
491 fprintf (fp, " /*DOUBLE_TRUNC_UNSIGNED_SCALAR*/ INVALID,\n");
492 fprintf (fp, " /*DOUBLE_TRUNC_BFLOAT_SCALAR*/ %s,\n",
493 same_ratio_eew_bf16_type (sew, lmul_log2).c_str ());
494 fprintf (fp, " /*DOUBLE_TRUNC_BFLOAT*/ %s,\n",
495 same_ratio_eew_bf16_type (sew, lmul_log2).c_str ());
496 fprintf (fp, " /*DOUBLE_TRUNC_FLOAT*/ %s,\n",
497 same_ratio_eew_type (sew, lmul_log2, sew / 2, false, true)
498 .c_str ());
499 fprintf (fp, " /*FLOAT*/ INVALID,\n");
500 fprintf (fp, " /*LMUL1*/ %s,\n",
501 floattype (sew, /*lmul_log2*/ 0).c_str ());
502 fprintf (fp, " /*WLMUL1*/ %s,\n",
503 floattype (sew * 2, /*lmul_log2*/ 0).c_str ());
504 for (unsigned eew : {8, 16, 32, 64})
505 fprintf (fp, " /*EEW%d_INTERPRET*/ INVALID,\n", eew);
507 for (unsigned boolsize : BOOL_SIZE_LIST)
508 fprintf (fp, " /*BOOL%d_INTERPRET*/ INVALID,\n", boolsize);
510 for (unsigned eew : EEW_SIZE_LIST)
511 fprintf (fp, " /*SIGNED_EEW%d_LMUL1_INTERPRET*/ INVALID,\n", eew);
513 for (unsigned eew : EEW_SIZE_LIST)
514 fprintf (fp, " /*UNSIGNED_EEW%d_LMUL1_INTERPRET*/ INVALID,\n",
515 eew);
517 for (unsigned lmul_log2_offset : {1, 2, 3, 4, 5, 6})
519 unsigned multiple_of_lmul = 1 << lmul_log2_offset;
520 fprintf (fp, " /*X%d_VLMUL_EXT*/ %s,\n", multiple_of_lmul,
521 floattype (sew, lmul_log2 + lmul_log2_offset).c_str ());
523 fprintf (fp, " /*TUPLE_SUBPART*/ %s\n",
524 floattype (sew, lmul_log2, 1).c_str ());
525 fprintf (fp, ")\n");
528 return 0;