aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPalmer Dabbelt <palmer@rivosinc.com>2022-04-01 21:28:00 -0700
committerPalmer Dabbelt <palmer@rivosinc.com>2022-04-01 22:04:46 -0700
commit678d69d765aa2db1c0ba55205989946eb06eca65 (patch)
treece5a12ec0dd148f312a205d3e937f837e1a2691b
parent53eacc1fa688f066a5426f44fbc85710677fc172 (diff)
downloadsparse-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.c51
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);