mirror of
https://github.com/micropython/micropython.git
synced 2026-01-06 12:10:13 +01:00
py/asmrv32: Reserve a flag for the Zcmp RV32 CPU extension.
This commit performs the necessary changes to handle an additional RV32 CPU extension flag, for the Zcmp extension in this case. The changes are not limited to RV32-only code, as other parts of the tooling need to be modified for this: the testing framework has to be made aware that an extra bit can be set in sys.implementation._mpy and needs to know how it is called, and "mpy-cross" must be able to actually set that flag bit in the first place via the appropriate command line argument. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
This commit is contained in:
committed by
Damien George
parent
d938d5af4e
commit
1df86516e0
@@ -145,8 +145,8 @@ static int usage(char **argv) {
|
||||
"-march=<arch> : set architecture for native emitter;\n"
|
||||
" x86, x64, armv6, armv6m, armv7m, armv7em, armv7emsp,\n"
|
||||
" armv7emdp, xtensa, xtensawin, rv32imc, rv64imc, host, debug\n"
|
||||
"-march-flags=<flags> : set architecture-specific flags (can be either a dec/hex/bin value or a string)\n"
|
||||
" supported flags for rv32imc: zba\n"
|
||||
"-march-flags=<flags> : set architecture-specific flags (can be either a dec/hex/bin value or a comma-separated flags string)\n"
|
||||
" supported flags for rv32imc: zba, zcmp\n"
|
||||
"\n"
|
||||
"Implementation specific options:\n", argv[0]
|
||||
);
|
||||
@@ -259,6 +259,34 @@ static bool parse_integer(const char *value, mp_uint_t *integer) {
|
||||
return valid;
|
||||
}
|
||||
|
||||
#if MICROPY_EMIT_NATIVE && MICROPY_EMIT_RV32
|
||||
static bool parse_rv32_flags_string(const char *source, mp_uint_t *flags) {
|
||||
assert(source && "Flag arguments string is NULL.");
|
||||
assert(flags && "Collected flags pointer is NULL.");
|
||||
|
||||
const char *current = source;
|
||||
const char *end = source + strlen(source);
|
||||
mp_uint_t collected_flags = 0;
|
||||
while (current < end) {
|
||||
const char *separator = strchr(current, ',');
|
||||
if (separator == NULL) {
|
||||
separator = end;
|
||||
}
|
||||
ptrdiff_t length = separator - current;
|
||||
if (length == (sizeof("zba") - 1) && memcmp(current, "zba", length) == 0) {
|
||||
collected_flags |= RV32_EXT_ZBA;
|
||||
} else if (length == (sizeof("zcmp") - 1) && memcmp(current, "zcmp", length) == 0) {
|
||||
collected_flags |= RV32_EXT_ZCMP;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
current = separator + 1;
|
||||
}
|
||||
*flags = collected_flags;
|
||||
return collected_flags != 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
MP_NOINLINE int main_(int argc, char **argv) {
|
||||
pre_process_options(argc, argv);
|
||||
|
||||
@@ -412,14 +440,11 @@ MP_NOINLINE int main_(int argc, char **argv) {
|
||||
if (mp_dynamic_compiler.native_arch == MP_NATIVE_ARCH_RV32IMC) {
|
||||
mp_dynamic_compiler.backend_options = (void *)&rv32_options;
|
||||
mp_uint_t raw_flags = 0;
|
||||
if (parse_integer(arch_flags, &raw_flags)) {
|
||||
if (parse_integer(arch_flags, &raw_flags) || parse_rv32_flags_string(arch_flags, &raw_flags)) {
|
||||
if ((raw_flags & ~((mp_uint_t)RV32_EXT_ALL)) == 0) {
|
||||
rv32_options.allowed_extensions = raw_flags;
|
||||
processed = true;
|
||||
}
|
||||
} else if (strncmp(arch_flags, "zba", sizeof("zba") - 1) == 0) {
|
||||
rv32_options.allowed_extensions |= RV32_EXT_ZBA;
|
||||
processed = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -125,8 +125,9 @@ typedef struct _asm_rv32_t {
|
||||
enum {
|
||||
RV32_EXT_NONE = 0,
|
||||
RV32_EXT_ZBA = 1 << 0,
|
||||
RV32_EXT_ZCMP = 1 << 1,
|
||||
|
||||
RV32_EXT_ALL = RV32_EXT_ZBA
|
||||
RV32_EXT_ALL = RV32_EXT_ZBA | RV32_EXT_ZCMP
|
||||
};
|
||||
|
||||
typedef struct _asm_rv32_backend_options_t {
|
||||
@@ -710,7 +711,8 @@ static inline void asm_rv32_opcode_xori(asm_rv32_t *state, mp_uint_t rd, mp_uint
|
||||
}
|
||||
|
||||
#define MICROPY_RV32_EXTENSIONS \
|
||||
(MICROPY_EMIT_RV32_ZBA ? RV32_EXT_ZBA : 0)
|
||||
((MICROPY_EMIT_RV32_ZBA ? RV32_EXT_ZBA : 0) | \
|
||||
(MICROPY_EMIT_RV32_ZCMP ? RV32_EXT_ZCMP : 0))
|
||||
|
||||
static inline uint8_t asm_rv32_allowed_extensions(void) {
|
||||
uint8_t extensions = MICROPY_RV32_EXTENSIONS;
|
||||
|
||||
@@ -507,6 +507,11 @@ typedef uint64_t mp_uint_t;
|
||||
#define MICROPY_EMIT_RV32_ZBA (0)
|
||||
#endif
|
||||
|
||||
// Whether to emit RISC-V RV32 Zcmp opcodes in native code
|
||||
#ifndef MICROPY_EMIT_RV32_ZCMP
|
||||
#define MICROPY_EMIT_RV32_ZCMP (0)
|
||||
#endif
|
||||
|
||||
// Whether to enable the RISC-V RV32 inline assembler
|
||||
#ifndef MICROPY_EMIT_INLINE_RV32
|
||||
#define MICROPY_EMIT_INLINE_RV32 (0)
|
||||
|
||||
@@ -22,7 +22,10 @@ TEST_TIMEOUT = float(os.environ.get("MICROPY_TEST_TIMEOUT", 30))
|
||||
# are guaranteed to always work, this one should though.
|
||||
BASEPATH = os.path.dirname(os.path.abspath(inspect.getsourcefile(lambda: None)))
|
||||
|
||||
RV32_ARCH_FLAGS = {"zba": 1 << 0}
|
||||
RV32_ARCH_FLAGS = {
|
||||
"zba": 1 << 0,
|
||||
"zcmp": 1 << 1,
|
||||
}
|
||||
|
||||
|
||||
def base_path(*p):
|
||||
|
||||
Reference in New Issue
Block a user