diff options
author | Palmer Dabbelt <palmer@rivosinc.com> | 2022-04-01 21:28:00 -0700 |
---|---|---|
committer | Palmer Dabbelt <palmer@rivosinc.com> | 2022-04-01 22:04:46 -0700 |
commit | 678d69d765aa2db1c0ba55205989946eb06eca65 (patch) | |
tree | ce5a12ec0dd148f312a205d3e937f837e1a2691b | |
parent | 53eacc1fa688f066a5426f44fbc85710677fc172 (diff) | |
download | sparse-riscv-wip.tar.gz |
Prototype multi-letter extension parsingriscv-wip
There's way more inter-extension implicit coupling than I thought, so
I've got to re-do this.
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
-rw-r--r-- | target-riscv.c | 51 |
1 files changed, 47 insertions, 4 deletions
diff --git a/target-riscv.c b/target-riscv.c index ff4dfba3..cec725ba 100644 --- a/target-riscv.c +++ b/target-riscv.c @@ -19,8 +19,12 @@ #define RISCV_GENERIC (RISCV_MUL|RISCV_DIV|RISCV_ATOMIC|RISCV_FPU) #define RISCV_ZICSR (1 << 10) #define RISCV_ZIFENCEI (1 << 11) +#define RISCV_MULTI (1 << 12) + +#define RISCV_MULTI_LEN 16 static unsigned int riscv_flags; +static const char *riscv_multi; static void parse_march_riscv(const char *arg) { @@ -41,6 +45,23 @@ static void parse_march_riscv(const char *arg) { "c", RISCV_COMP }, { "_zicsr", RISCV_ZICSR }, { "_zifencei", RISCV_ZIFENCEI }, + { "_zba", RISCV_MULTI }, + { "_zbb", RISCV_MULTI }, + { "_zbc", RISCV_MULTI }, + { "_zbs", RISCV_MULTI }, + { "_zbkb", RISCV_MULTI }, + { "_zbkc", RISCV_MULTI }, + { "_zbkx", RISCV_MULTI }, + { "_zkne", RISCV_MULTI }, + { "_zknd", RISCV_MULTI }, + { "_zknh", RISCV_MULTI }, + { "_zkr", RISCV_MULTI }, + { "_zksed", RISCV_MULTI }, + { "_zksh", RISCV_MULTI }, + { "_zkt", RISCV_MULTI }, + { "_zk", RISCV_MULTI }, + { "_zkn", RISCV_MULTI }, + { "_zks", RISCV_MULTI }, }; int i; @@ -51,6 +72,7 @@ static void parse_march_riscv(const char *arg) if (!strncmp(arg, pat, len)) { riscv_flags = basic_sets[i].flags; arg += len; + riscv_multi = NULL; goto ext; } } @@ -74,6 +96,9 @@ ext: if (!strncmp(arg, pat, len)) { riscv_flags |= extensions[i].flags; + if (extensions[i].flags & RISCV_MULTI && !riscv_multi) + riscv_multi = arg; + arg += len; } } @@ -102,6 +127,15 @@ static void init_riscv32(const struct target *self) init_riscv(self); } +static const char *next_underscore(const char *c) +{ + + do { + c++; + } while (c[0] && c[0] != '_'); + return c; +} + static void predefine_riscv(const struct target *self) { static const char *cmodels[CMODEL_LAST] = { @@ -132,10 +166,19 @@ static void predefine_riscv(const struct target *self) predefine("__riscv_mul", 1, "1"); if ((riscv_flags & RISCV_MUL) && (riscv_flags & RISCV_DIV)) predefine("__riscv_muldiv", 1, "1"); - if (riscv_flags & RISCV_ZICSR) - predefine("__riscv_zicsr", 1, "1"); - if (riscv_flags & RISCV_ZIFENCEI) - predefine("__riscv_zifencei", 1, "1"); + + if (riscv_multi) { + const char *start = riscv_multi; + while (start[0] == '_') { + const char *end = next_underscore(start); + char ext[RISCV_MULTI_LEN]; + memcpy(ext, start, end-start); + ext[end-start] = '\0'; + predefine_strong("__riscv%s", ext); + start = end; + fprintf(stderr, "__riscv%s\n", ext); + } + } if (cmodel) predefine_strong("__riscv_cmodel_%s", cmodel); |