py: Allow inline-assembler emitter to be generic.
This patch refactors some code so that it is easier to integrate new inline assemblers for different architectures other than ARM Thumb.
This commit is contained in:
54
py/compile.c
54
py/compile.c
@@ -86,6 +86,16 @@ typedef enum {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if MICROPY_EMIT_INLINE_ASM
|
||||
// define macros for inline assembler
|
||||
#if MICROPY_EMIT_INLINE_THUMB
|
||||
#define ASM_DECORATOR_QSTR MP_QSTR_asm_thumb
|
||||
#define ASM_EMITTER(f) emit_inline_thumb_##f
|
||||
#else
|
||||
#error "unknown asm emitter"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define EMIT_INLINE_ASM(fun) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm))
|
||||
#define EMIT_INLINE_ASM_ARG(fun, ...) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm, __VA_ARGS__))
|
||||
|
||||
@@ -120,7 +130,7 @@ typedef struct _compiler_t {
|
||||
const emit_method_table_t *emit_method_table; // current emit method table
|
||||
#endif
|
||||
|
||||
#if MICROPY_EMIT_INLINE_THUMB
|
||||
#if MICROPY_EMIT_INLINE_ASM
|
||||
emit_inline_asm_t *emit_inline_asm; // current emitter for inline asm
|
||||
const emit_inline_asm_method_table_t *emit_inline_asm_method_table; // current emit method table for inline asm
|
||||
#endif
|
||||
@@ -767,10 +777,10 @@ STATIC bool compile_built_in_decorator(compiler_t *comp, int name_len, mp_parse_
|
||||
} else if (attr == MP_QSTR_viper) {
|
||||
*emit_options = MP_EMIT_OPT_VIPER;
|
||||
#endif
|
||||
#if MICROPY_EMIT_INLINE_THUMB
|
||||
} else if (attr == MP_QSTR_asm_thumb) {
|
||||
*emit_options = MP_EMIT_OPT_ASM_THUMB;
|
||||
#endif
|
||||
#if MICROPY_EMIT_INLINE_ASM
|
||||
} else if (attr == ASM_DECORATOR_QSTR) {
|
||||
*emit_options = MP_EMIT_OPT_ASM;
|
||||
#endif
|
||||
} else {
|
||||
compile_syntax_error(comp, name_nodes[1], "invalid micropython decorator");
|
||||
}
|
||||
@@ -3100,7 +3110,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
|
||||
assert(comp->cur_except_level == 0);
|
||||
}
|
||||
|
||||
#if MICROPY_EMIT_INLINE_THUMB
|
||||
#if MICROPY_EMIT_INLINE_ASM
|
||||
// requires 3 passes: SCOPE, CODE_SIZE, EMIT
|
||||
STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
|
||||
comp->pass = pass;
|
||||
@@ -3357,10 +3367,10 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f
|
||||
uint max_num_labels = 0;
|
||||
for (scope_t *s = comp->scope_head; s != NULL && comp->compile_error == MP_OBJ_NULL; s = s->next) {
|
||||
if (false) {
|
||||
#if MICROPY_EMIT_INLINE_THUMB
|
||||
} else if (s->emit_options == MP_EMIT_OPT_ASM_THUMB) {
|
||||
#if MICROPY_EMIT_INLINE_ASM
|
||||
} else if (s->emit_options == MP_EMIT_OPT_ASM) {
|
||||
compile_scope_inline_asm(comp, s, MP_PASS_SCOPE);
|
||||
#endif
|
||||
#endif
|
||||
} else {
|
||||
compile_scope(comp, s, MP_PASS_SCOPE);
|
||||
}
|
||||
@@ -3382,28 +3392,24 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f
|
||||
// compile pass 2 and 3
|
||||
#if MICROPY_EMIT_NATIVE
|
||||
emit_t *emit_native = NULL;
|
||||
#endif
|
||||
#if MICROPY_EMIT_INLINE_THUMB
|
||||
emit_inline_asm_t *emit_inline_thumb = NULL;
|
||||
#endif
|
||||
for (scope_t *s = comp->scope_head; s != NULL && comp->compile_error == MP_OBJ_NULL; s = s->next) {
|
||||
if (false) {
|
||||
// dummy
|
||||
|
||||
#if MICROPY_EMIT_INLINE_THUMB
|
||||
} else if (s->emit_options == MP_EMIT_OPT_ASM_THUMB) {
|
||||
// inline assembly for thumb
|
||||
if (emit_inline_thumb == NULL) {
|
||||
emit_inline_thumb = emit_inline_thumb_new(max_num_labels);
|
||||
#if MICROPY_EMIT_INLINE_ASM
|
||||
} else if (s->emit_options == MP_EMIT_OPT_ASM) {
|
||||
// inline assembly
|
||||
if (comp->emit_inline_asm == NULL) {
|
||||
comp->emit_inline_asm = ASM_EMITTER(new)(max_num_labels);
|
||||
}
|
||||
comp->emit = NULL;
|
||||
comp->emit_inline_asm = emit_inline_thumb;
|
||||
comp->emit_inline_asm_method_table = &emit_inline_thumb_method_table;
|
||||
comp->emit_inline_asm_method_table = &ASM_EMITTER(method_table);
|
||||
compile_scope_inline_asm(comp, s, MP_PASS_CODE_SIZE);
|
||||
if (comp->compile_error == MP_OBJ_NULL) {
|
||||
compile_scope_inline_asm(comp, s, MP_PASS_EMIT);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
} else {
|
||||
|
||||
@@ -3463,11 +3469,11 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f
|
||||
NATIVE_EMITTER(free)(emit_native);
|
||||
}
|
||||
#endif
|
||||
#if MICROPY_EMIT_INLINE_THUMB
|
||||
if (emit_inline_thumb != NULL) {
|
||||
emit_inline_thumb_free(emit_inline_thumb);
|
||||
#if MICROPY_EMIT_INLINE_ASM
|
||||
if (comp->emit_inline_asm != NULL) {
|
||||
ASM_EMITTER(free)(comp->emit_inline_asm);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// free the parse tree
|
||||
mp_parse_tree_clear(parse_tree);
|
||||
|
||||
Reference in New Issue
Block a user