/* Generate the RVV type indexer tables. Copyright (C) 2023-2023 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 . */ #include "bconfig.h" #define INCLUDE_SSTREAM #include "system.h" #include "errors.h" #include "coretypes.h" #include #include #define BOOL_SIZE_LIST {1} std::string to_lmul (int lmul_log2) { std::stringstream lmul_str; if (lmul_log2 >= 0) lmul_str << "m"; else { lmul_str << "mf"; lmul_log2 = -lmul_log2; } lmul_str << (1 << lmul_log2); return lmul_str.str (); } bool valid_type (unsigned sew, int lmul_log2, bool float_p) { if (lmul_log2 > 3) return false; switch (sew) { case 8: return lmul_log2 >= -3 && !float_p; case 16: return lmul_log2 >= -2 && !float_p; case 32: return lmul_log2 >= -1; case 64: return lmul_log2 >= 0; default: return false; } } bool valid_type (unsigned sew, int lmul_log2, unsigned nf, bool float_p) { if (!valid_type (sew, lmul_log2, float_p)) return false; if (nf > 8 || nf < 1) return false; switch (lmul_log2) { case 1: return nf < 5; case 2: return nf < 3; case 3: return nf == 1; default: return true; } } std::string inttype (unsigned sew, int lmul_log2, bool unsigned_p) { if (!valid_type (sew, lmul_log2, /*float_t*/ false)) return "INVALID"; std::stringstream mode; mode << "v"; if (unsigned_p) mode << "u"; mode << "int" << sew << to_lmul (lmul_log2) << "_t"; return mode.str (); } std::string inttype (unsigned sew, int lmul_log2, unsigned nf, bool unsigned_p) { if (!valid_type (sew, lmul_log2, nf, /*float_t*/ false)) return "INVALID"; std::stringstream mode; mode << "v"; if (unsigned_p) mode << "u"; mode << "int" << sew << to_lmul (lmul_log2); if (nf > 1) mode << "x" << nf; mode << "_t"; return mode.str (); } std::string floattype (unsigned sew, int lmul_log2) { if (!valid_type (sew, lmul_log2, /*float_t*/ true)) return "INVALID"; std::stringstream mode; mode << "vfloat" << sew << to_lmul (lmul_log2) << "_t"; return mode.str (); } std::string floattype (unsigned sew, int lmul_log2, unsigned nf) { if (!valid_type (sew, lmul_log2, nf, /*float_t*/ true)) return "INVALID"; std::stringstream mode; mode << "vfloat" << sew << to_lmul (lmul_log2); if (nf > 1) mode << "x" << nf; mode << "_t"; return mode.str (); } std::string maskmode (unsigned sew, int lmul_log2) { if (!valid_type (sew, lmul_log2, /*float_t*/ false)) return "INVALID"; std::stringstream mode; int mlen; if (lmul_log2 >= 0) mlen = sew / (1 << lmul_log2); else mlen = sew * (1 << -lmul_log2); mode << "vbool" << mlen << "_t"; return mode.str (); } std::string same_ratio_eew_type (unsigned sew, int lmul_log2, unsigned eew, bool unsigned_p, bool float_p) { if (!valid_type (sew, lmul_log2, float_p)) return "INVALID"; int elmul_log2; if (sew == eew) elmul_log2 = lmul_log2; else if (sew > eew) elmul_log2 = lmul_log2 - log2 (sew / eew); else /* sew < eew */ elmul_log2 = lmul_log2 + log2 (eew / sew); if (float_p) return floattype (eew, elmul_log2); else return inttype (eew, elmul_log2, unsigned_p); } int main (int argc, const char **argv) { // Require at least one argument. if (argc < 2) return 1; FILE *fp = fopen (argv[1], "w"); if (!fp) return 1; fprintf (fp, "/* Generated by genrvv-type-indexer */\n"); for (unsigned vbool : {64, 32, 16, 8, 4, 2, 1}) { std::stringstream mode; mode << "vbool" << vbool << "_t"; fprintf (fp, "DEF_RVV_TYPE_INDEX (\n"); fprintf (fp, " /*VECTOR*/ %s,\n", mode.str ().c_str ()); fprintf (fp, " /*MASK*/ %s,\n", mode.str ().c_str ()); fprintf (fp, " /*SIGNED*/ INVALID,\n"); fprintf (fp, " /*UNSIGNED*/ INVALID,\n"); for (unsigned eew : {8, 16, 32, 64}) fprintf (fp, " /*EEW%d_INDEX*/ INVALID,\n", eew); fprintf (fp, " /*SHIFT*/ INVALID,\n"); fprintf (fp, " /*DOUBLE_TRUNC*/ INVALID,\n"); fprintf (fp, " /*QUAD_TRUNC*/ INVALID,\n"); fprintf (fp, " /*OCT_TRUNC*/ INVALID,\n"); fprintf (fp, " /*DOUBLE_TRUNC_SCALAR*/ INVALID,\n"); fprintf (fp, " /*DOUBLE_TRUNC_SIGNED*/ INVALID,\n"); fprintf (fp, " /*DOUBLE_TRUNC_UNSIGNED*/ INVALID,\n"); fprintf (fp, " /*DOUBLE_TRUNC_UNSIGNED_SCALAR*/ INVALID,\n"); fprintf (fp, " /*DOUBLE_TRUNC_FLOAT*/ INVALID,\n"); fprintf (fp, " /*FLOAT*/ INVALID,\n"); fprintf (fp, " /*LMUL1*/ INVALID,\n"); fprintf (fp, " /*WLMUL1*/ INVALID,\n"); for (unsigned eew : {8, 16, 32, 64}) fprintf (fp, " /*EEW%d_INTERPRET*/ INVALID,\n", eew); for (unsigned boolsize : BOOL_SIZE_LIST) fprintf (fp, " /*BOOL%d_INTERPRET*/ INVALID,\n", boolsize); for (unsigned lmul_log2_offset : {1, 2, 3, 4, 5, 6}) { unsigned multiple_of_lmul = 1 << lmul_log2_offset; fprintf (fp, " /*X%d_INTERPRET*/ INVALID,\n", multiple_of_lmul); } fprintf (fp, " /*TUPLE_SUBPART*/ INVALID\n"); fprintf (fp, ")\n"); } // Build for vint and vuint for (unsigned sew : {8, 16, 32, 64}) for (int lmul_log2 : {-3, -2, -1, 0, 1, 2, 3}) for (unsigned nf : {1, 2, 3, 4, 5, 6, 7, 8}) for (bool unsigned_p : {false, true}) { if (!valid_type (sew, lmul_log2, nf, /*float_t*/ false)) continue; fprintf (fp, "DEF_RVV_TYPE_INDEX (\n"); fprintf (fp, " /*VECTOR*/ %s,\n", inttype (sew, lmul_log2, nf, unsigned_p).c_str ()); fprintf (fp, " /*MASK*/ %s,\n", maskmode (sew, lmul_log2).c_str ()); fprintf (fp, " /*SIGNED*/ %s,\n", inttype (sew, lmul_log2, /*unsigned_p*/ false).c_str ()); fprintf (fp, " /*UNSIGNED*/ %s,\n", inttype (sew, lmul_log2, /*unsigned_p*/ true).c_str ()); for (unsigned eew : {8, 16, 32, 64}) fprintf (fp, " /*EEW%d_INDEX*/ %s,\n", eew, same_ratio_eew_type (sew, lmul_log2, eew, /*unsigned_p*/ true, false) .c_str ()); fprintf (fp, " /*SHIFT*/ %s,\n", inttype (sew, lmul_log2, /*unsigned_p*/ true).c_str ()); fprintf (fp, " /*DOUBLE_TRUNC*/ %s,\n", same_ratio_eew_type (sew, lmul_log2, sew / 2, unsigned_p, false) .c_str ()); fprintf (fp, " /*QUAD_TRUNC*/ %s,\n", same_ratio_eew_type (sew, lmul_log2, sew / 4, unsigned_p, false) .c_str ()); fprintf (fp, " /*OCT_TRUNC*/ %s,\n", same_ratio_eew_type (sew, lmul_log2, sew / 8, unsigned_p, false) .c_str ()); fprintf (fp, " /*DOUBLE_TRUNC_SCALAR*/ %s,\n", same_ratio_eew_type (sew, lmul_log2, sew / 2, unsigned_p, false) .c_str ()); fprintf (fp, " /*DOUBLE_TRUNC_SIGNED*/ INVALID,\n"); fprintf (fp, " /*DOUBLE_TRUNC_UNSIGNED*/ %s,\n", same_ratio_eew_type (sew, lmul_log2, sew / 2, true, false) .c_str ()); if (unsigned_p) fprintf (fp, " /*DOUBLE_TRUNC_UNSIGNED_SCALAR*/ INVALID,\n"); else fprintf (fp, " /*DOUBLE_TRUNC_UNSIGNED_SCALAR*/ %s,\n", same_ratio_eew_type (sew, lmul_log2, sew / 2, true, false) .c_str ()); fprintf (fp, " /*DOUBLE_TRUNC_FLOAT*/ %s,\n", same_ratio_eew_type (sew, lmul_log2, sew / 2, false, true) .c_str ()); fprintf (fp, " /*FLOAT*/ %s,\n", floattype (sew, lmul_log2).c_str ()); fprintf (fp, " /*LMUL1*/ %s,\n", inttype (sew, /*lmul_log2*/ 0, unsigned_p).c_str ()); fprintf (fp, " /*WLMUL1*/ %s,\n", inttype (sew * 2, /*lmul_log2*/ 0, unsigned_p).c_str ()); for (unsigned eew : {8, 16, 32, 64}) { if (eew == sew) fprintf (fp, " /*EEW%d_INTERPRET*/ INVALID,\n", eew); else fprintf (fp, " /*EEW%d_INTERPRET*/ %s,\n", eew, inttype (eew, lmul_log2, unsigned_p).c_str ()); } for (unsigned boolsize : BOOL_SIZE_LIST) { std::stringstream mode; mode << "vbool" << boolsize << "_t"; fprintf (fp, " /*BOOL%d_INTERPRET*/ %s,\n", boolsize, nf == 1 && lmul_log2 == 0 ? mode.str ().c_str () : "INVALID"); } for (unsigned lmul_log2_offset : {1, 2, 3, 4, 5, 6}) { unsigned multiple_of_lmul = 1 << lmul_log2_offset; fprintf (fp, " /*X%d_VLMUL_EXT*/ %s,\n", multiple_of_lmul, inttype (sew, lmul_log2 + lmul_log2_offset, unsigned_p) .c_str ()); } fprintf (fp, " /*TUPLE_SUBPART*/ %s\n", inttype (sew, lmul_log2, 1, unsigned_p).c_str ()); fprintf (fp, ")\n"); } // Build for vfloat for (unsigned sew : {32, 64}) for (int lmul_log2 : {-3, -2, -1, 0, 1, 2, 3}) for (unsigned nf : {1, 2, 3, 4, 5, 6, 7, 8}) { if (!valid_type (sew, lmul_log2, nf, /*float_t*/ true)) continue; fprintf (fp, "DEF_RVV_TYPE_INDEX (\n"); fprintf (fp, " /*VECTOR*/ %s,\n", floattype (sew, lmul_log2, nf).c_str ()); fprintf (fp, " /*MASK*/ %s,\n", maskmode (sew, lmul_log2).c_str ()); fprintf (fp, " /*SIGNED*/ %s,\n", inttype (sew, lmul_log2, /*unsigned_p*/ false).c_str ()); fprintf (fp, " /*UNSIGNED*/ %s,\n", inttype (sew, lmul_log2, /*unsigned_p*/ true).c_str ()); for (unsigned eew : {8, 16, 32, 64}) fprintf (fp, " /*EEW%d_INDEX*/ %s,\n", eew, same_ratio_eew_type (sew, lmul_log2, eew, /*unsigned_p*/ true, false) .c_str ()); fprintf (fp, " /*SHIFT*/ INVALID,\n"); fprintf (fp, " /*DOUBLE_TRUNC*/ %s,\n", same_ratio_eew_type (sew, lmul_log2, sew / 2, false, true) .c_str ()); fprintf (fp, " /*QUAD_TRUNC*/ INVALID,\n"); fprintf (fp, " /*OCT_TRUNC*/ INVALID,\n"); fprintf (fp, " /*DOUBLE_TRUNC_SCALAR*/ %s,\n", same_ratio_eew_type (sew, lmul_log2, sew / 2, false, true) .c_str ()); fprintf (fp, " /*DOUBLE_TRUNC_SIGNED*/ %s,\n", same_ratio_eew_type (sew, lmul_log2, sew / 2, false, false) .c_str ()); fprintf (fp, " /*DOUBLE_TRUNC_UNSIGNED*/ %s,\n", same_ratio_eew_type (sew, lmul_log2, sew / 2, true, false) .c_str ()); fprintf (fp, " /*DOUBLE_TRUNC_UNSIGNED_SCALAR*/ INVALID,\n"); fprintf (fp, " /*DOUBLE_TRUNC_FLOAT*/ %s,\n", same_ratio_eew_type (sew, lmul_log2, sew / 2, false, true) .c_str ()); fprintf (fp, " /*FLOAT*/ INVALID,\n"); fprintf (fp, " /*LMUL1*/ %s,\n", floattype (sew, /*lmul_log2*/ 0).c_str ()); fprintf (fp, " /*WLMUL1*/ %s,\n", floattype (sew * 2, /*lmul_log2*/ 0).c_str ()); for (unsigned eew : {8, 16, 32, 64}) fprintf (fp, " /*EEW%d_INTERPRET*/ INVALID,\n", eew); for (unsigned boolsize : BOOL_SIZE_LIST) fprintf (fp, " /*BOOL%d_INTERPRET*/ INVALID,\n", boolsize); for (unsigned lmul_log2_offset : {1, 2, 3, 4, 5, 6}) { unsigned multiple_of_lmul = 1 << lmul_log2_offset; fprintf (fp, " /*X%d_VLMUL_EXT*/ %s,\n", multiple_of_lmul, floattype (sew, lmul_log2 + lmul_log2_offset).c_str ()); } fprintf (fp, " /*TUPLE_SUBPART*/ %s\n", floattype (sew, lmul_log2, 1).c_str ()); fprintf (fp, ")\n"); } return 0; }