aboutsummaryrefslogtreecommitdiff
path: root/modules/devices/riscv/riscv_data.c
diff options
context:
space:
mode:
authorBurt P <pburt0@gmail.com>2017-07-10 03:46:28 -0500
committerLeandro Pereira <leandro@hardinfo.org>2017-07-12 19:38:41 -0700
commitda2592d984c9f7c37477a71e105fe4ad47907e3f (patch)
tree10b09f9379f85741bf64e5ecb3321e713299ae5c /modules/devices/riscv/riscv_data.c
parent2db90cda115d037971a7405c681fbe43eda0d7c3 (diff)
riscv: improvements
Signed-off-by: Burt P <pburt0@gmail.com>
Diffstat (limited to 'modules/devices/riscv/riscv_data.c')
-rw-r--r--modules/devices/riscv/riscv_data.c71
1 files changed, 48 insertions, 23 deletions
diff --git a/modules/devices/riscv/riscv_data.c b/modules/devices/riscv/riscv_data.c
index 77cb69ca..54b308e0 100644
--- a/modules/devices/riscv/riscv_data.c
+++ b/modules/devices/riscv/riscv_data.c
@@ -42,62 +42,87 @@ static struct {
{ "rv_T", "Transactional memory" },
{ "rv_P", "Packed SIMD instructions" },
{ "rv_L", "Decimal floating-point instructions" },
+ { "rv_J", "Dynamically translated languages" },
+ { "rv_N", "User-level interrupts" },
{ NULL, NULL }
};
const char *riscv_ext_meaning(const char *ext) {
- int i = 0;
- if (ext)
- while(tab_ext_meaning[i].name != NULL) {
- if (strcmp(tab_ext_meaning[i].name, ext) == 0)
- return tab_ext_meaning[i].meaning;
- i++;
+ int i = 0, l = 0;
+ char *c = NULL;
+ if (ext) {
+ c = strchr(ext, ':'); /* allow extension:version, ignore version */
+ if (c != NULL)
+ l = c - ext;
+ else
+ l = strlen(ext);
+ while(tab_ext_meaning[i].name != NULL) {
+ if (strncmp(tab_ext_meaning[i].name, ext, l) == 0)
+ return tab_ext_meaning[i].meaning;
+ i++;
+ }
}
return NULL;
}
+/* see RISC-V spec 2.2: Chapter 22: ISA Subset Naming Conventions */
+
#define FSTR_SIZE 1024
+#define EAT_VERSION() if (isdigit(*ps)) while(isdigit(*ps) || *ps == 'p' ) { ps++; };
+#define CP_EXT_FLAG() while(*ps != 0 && *ps != '_' && *ps != ' ') { if (isdigit(*ps)) { EAT_VERSION(); break; } *pd = *ps; ps++; pd++; }; *pd = ' '; pd++;
#define ADD_EXT_FLAG(ext) l = strlen(ext); strncpy(pd, ext " ", l + 1); pd += l + 1;
char *riscv_isa_to_flags(const char *isa) {
char *flags = NULL, *ps = (char*)isa, *pd = NULL;
+ char ext[64] = "", ver[64] = "";
int l = 0;
if (isa) {
flags = malloc(FSTR_SIZE);
if (flags) {
memset(flags, 0, FSTR_SIZE);
pd = flags;
- if ( strncmp(ps, "RV32", 4) == 0 ) {
+ if ( strncmp(ps, "rv", 2) == 0
+ || strncmp(ps, "RV", 2) == 0 ) {
+ ps += 2;
+ }
+ if ( strncmp(ps, "32", 2) == 0 ) {
ADD_EXT_FLAG("rv32");
- ps += 4;
- } else if ( strncmp(ps, "RV64", 4) == 0 ) {
+ ps += 2;
+ } else if ( strncmp(ps, "64", 2) == 0 ) {
ADD_EXT_FLAG("rv64");
- ps += 4;
- } else if ( strncmp(ps, "RV128", 5) == 0) {
+ ps += 2;
+ } else if ( strncmp(ps, "128", 3) == 0) {
ADD_EXT_FLAG("rv128");
- ps += 5;
+ ps += 3;
}
while (*ps != 0) {
switch(*ps) {
- case 'G': /* G = IMAFD */
+ case 'G': case 'g': /* G = IMAFD */
ADD_EXT_FLAG("rv_I");
ADD_EXT_FLAG("rv_M");
ADD_EXT_FLAG("rv_A");
ADD_EXT_FLAG("rv_F");
ADD_EXT_FLAG("rv_D");
break;
- case 'E': ADD_EXT_FLAG("rv_E"); break;
- case 'I': ADD_EXT_FLAG("rv_I"); break;
- case 'M': ADD_EXT_FLAG("rv_M"); break;
- case 'A': ADD_EXT_FLAG("rv_A"); break;
- case 'C': ADD_EXT_FLAG("rv_C"); break;
- case 'F': ADD_EXT_FLAG("rv_F"); break;
- case 'D': ADD_EXT_FLAG("rv_D"); break;
- case 'Q': ADD_EXT_FLAG("rv_Q"); break;
- case 'B': ADD_EXT_FLAG("rv_B"); break;
- case 'V': ADD_EXT_FLAG("rv_V"); break;
+ case 'E': case 'e': ADD_EXT_FLAG("rv_E"); break;
+ case 'I': case 'i': ADD_EXT_FLAG("rv_I"); break;
+ case 'M': case 'm': ADD_EXT_FLAG("rv_M"); break;
+ case 'A': case 'a': ADD_EXT_FLAG("rv_A"); break;
+ case 'C': case 'c': ADD_EXT_FLAG("rv_C"); break;
+ case 'F': case 'f': ADD_EXT_FLAG("rv_F"); break;
+ case 'D': case 'd': ADD_EXT_FLAG("rv_D"); break;
+ case 'Q': case 'q': ADD_EXT_FLAG("rv_Q"); break;
+ case 'P': case 'p': ADD_EXT_FLAG("rv_P"); break;
+ case 'B': case 'b': ADD_EXT_FLAG("rv_B"); break;
+ case 'V': case 'v': ADD_EXT_FLAG("rv_V"); break;
+ case 'J': case 'j': ADD_EXT_FLAG("rv_J"); break;
+ case 'N': case 'n': ADD_EXT_FLAG("rv_N"); break;
+ case 'S': case 's': CP_EXT_FLAG(); break; /* supervisor extension */
+ case 'X': case 'x': CP_EXT_FLAG(); break; /* custom extension */
+ /* custom supervisor extension (SX..) handled by S */
default: break;
}
ps++;
+ EAT_VERSION();
}
}
}