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:
parent
45a6156dfd
commit
ad297a1950
@ -31,7 +31,7 @@
|
|||||||
#include "py/misc.h"
|
#include "py/misc.h"
|
||||||
#include "py/asmbase.h"
|
#include "py/asmbase.h"
|
||||||
|
|
||||||
#if MICROPY_EMIT_NATIVE || MICROPY_EMIT_INLINE_THUMB
|
#if MICROPY_EMIT_NATIVE || MICROPY_EMIT_INLINE_ASM
|
||||||
|
|
||||||
void mp_asm_base_init(mp_asm_base_t *as, size_t max_num_labels) {
|
void mp_asm_base_init(mp_asm_base_t *as, size_t max_num_labels) {
|
||||||
as->max_num_labels = max_num_labels;
|
as->max_num_labels = max_num_labels;
|
||||||
@ -101,4 +101,4 @@ void mp_asm_base_data(mp_asm_base_t* as, unsigned int bytesize, uintptr_t val) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MICROPY_EMIT_NATIVE || MICROPY_EMIT_INLINE_THUMB
|
#endif // MICROPY_EMIT_NATIVE || MICROPY_EMIT_INLINE_ASM
|
||||||
|
54
py/compile.c
54
py/compile.c
@ -86,6 +86,16 @@ typedef enum {
|
|||||||
#endif
|
#endif
|
||||||
#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(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__))
|
#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
|
const emit_method_table_t *emit_method_table; // current emit method table
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MICROPY_EMIT_INLINE_THUMB
|
#if MICROPY_EMIT_INLINE_ASM
|
||||||
emit_inline_asm_t *emit_inline_asm; // current emitter for 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
|
const emit_inline_asm_method_table_t *emit_inline_asm_method_table; // current emit method table for inline asm
|
||||||
#endif
|
#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) {
|
} else if (attr == MP_QSTR_viper) {
|
||||||
*emit_options = MP_EMIT_OPT_VIPER;
|
*emit_options = MP_EMIT_OPT_VIPER;
|
||||||
#endif
|
#endif
|
||||||
#if MICROPY_EMIT_INLINE_THUMB
|
#if MICROPY_EMIT_INLINE_ASM
|
||||||
} else if (attr == MP_QSTR_asm_thumb) {
|
} else if (attr == ASM_DECORATOR_QSTR) {
|
||||||
*emit_options = MP_EMIT_OPT_ASM_THUMB;
|
*emit_options = MP_EMIT_OPT_ASM;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
compile_syntax_error(comp, name_nodes[1], "invalid micropython decorator");
|
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);
|
assert(comp->cur_except_level == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MICROPY_EMIT_INLINE_THUMB
|
#if MICROPY_EMIT_INLINE_ASM
|
||||||
// requires 3 passes: SCOPE, CODE_SIZE, EMIT
|
// requires 3 passes: SCOPE, CODE_SIZE, EMIT
|
||||||
STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
|
STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
|
||||||
comp->pass = 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;
|
uint max_num_labels = 0;
|
||||||
for (scope_t *s = comp->scope_head; s != NULL && comp->compile_error == MP_OBJ_NULL; s = s->next) {
|
for (scope_t *s = comp->scope_head; s != NULL && comp->compile_error == MP_OBJ_NULL; s = s->next) {
|
||||||
if (false) {
|
if (false) {
|
||||||
#if MICROPY_EMIT_INLINE_THUMB
|
#if MICROPY_EMIT_INLINE_ASM
|
||||||
} else if (s->emit_options == MP_EMIT_OPT_ASM_THUMB) {
|
} else if (s->emit_options == MP_EMIT_OPT_ASM) {
|
||||||
compile_scope_inline_asm(comp, s, MP_PASS_SCOPE);
|
compile_scope_inline_asm(comp, s, MP_PASS_SCOPE);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
compile_scope(comp, s, MP_PASS_SCOPE);
|
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
|
// compile pass 2 and 3
|
||||||
#if MICROPY_EMIT_NATIVE
|
#if MICROPY_EMIT_NATIVE
|
||||||
emit_t *emit_native = NULL;
|
emit_t *emit_native = NULL;
|
||||||
#endif
|
|
||||||
#if MICROPY_EMIT_INLINE_THUMB
|
|
||||||
emit_inline_asm_t *emit_inline_thumb = NULL;
|
|
||||||
#endif
|
#endif
|
||||||
for (scope_t *s = comp->scope_head; s != NULL && comp->compile_error == MP_OBJ_NULL; s = s->next) {
|
for (scope_t *s = comp->scope_head; s != NULL && comp->compile_error == MP_OBJ_NULL; s = s->next) {
|
||||||
if (false) {
|
if (false) {
|
||||||
// dummy
|
// dummy
|
||||||
|
|
||||||
#if MICROPY_EMIT_INLINE_THUMB
|
#if MICROPY_EMIT_INLINE_ASM
|
||||||
} else if (s->emit_options == MP_EMIT_OPT_ASM_THUMB) {
|
} else if (s->emit_options == MP_EMIT_OPT_ASM) {
|
||||||
// inline assembly for thumb
|
// inline assembly
|
||||||
if (emit_inline_thumb == NULL) {
|
if (comp->emit_inline_asm == NULL) {
|
||||||
emit_inline_thumb = emit_inline_thumb_new(max_num_labels);
|
comp->emit_inline_asm = ASM_EMITTER(new)(max_num_labels);
|
||||||
}
|
}
|
||||||
comp->emit = NULL;
|
comp->emit = NULL;
|
||||||
comp->emit_inline_asm = emit_inline_thumb;
|
comp->emit_inline_asm_method_table = &ASM_EMITTER(method_table);
|
||||||
comp->emit_inline_asm_method_table = &emit_inline_thumb_method_table;
|
|
||||||
compile_scope_inline_asm(comp, s, MP_PASS_CODE_SIZE);
|
compile_scope_inline_asm(comp, s, MP_PASS_CODE_SIZE);
|
||||||
if (comp->compile_error == MP_OBJ_NULL) {
|
if (comp->compile_error == MP_OBJ_NULL) {
|
||||||
compile_scope_inline_asm(comp, s, MP_PASS_EMIT);
|
compile_scope_inline_asm(comp, s, MP_PASS_EMIT);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} else {
|
} 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);
|
NATIVE_EMITTER(free)(emit_native);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if MICROPY_EMIT_INLINE_THUMB
|
#if MICROPY_EMIT_INLINE_ASM
|
||||||
if (emit_inline_thumb != NULL) {
|
if (comp->emit_inline_asm != NULL) {
|
||||||
emit_inline_thumb_free(emit_inline_thumb);
|
ASM_EMITTER(free)(comp->emit_inline_asm);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// free the parse tree
|
// free the parse tree
|
||||||
mp_parse_tree_clear(parse_tree);
|
mp_parse_tree_clear(parse_tree);
|
||||||
|
@ -36,7 +36,7 @@ enum {
|
|||||||
MP_EMIT_OPT_BYTECODE,
|
MP_EMIT_OPT_BYTECODE,
|
||||||
MP_EMIT_OPT_NATIVE_PYTHON,
|
MP_EMIT_OPT_NATIVE_PYTHON,
|
||||||
MP_EMIT_OPT_VIPER,
|
MP_EMIT_OPT_VIPER,
|
||||||
MP_EMIT_OPT_ASM_THUMB,
|
MP_EMIT_OPT_ASM,
|
||||||
};
|
};
|
||||||
|
|
||||||
// the compiler will raise an exception if an error occurred
|
// the compiler will raise an exception if an error occurred
|
||||||
|
@ -82,7 +82,7 @@ void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, const byte *code, mp_uint_t
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MICROPY_EMIT_NATIVE || MICROPY_EMIT_INLINE_THUMB
|
#if MICROPY_EMIT_NATIVE || MICROPY_EMIT_INLINE_ASM
|
||||||
void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun_data, mp_uint_t fun_len, const mp_uint_t *const_table, mp_uint_t n_pos_args, mp_uint_t scope_flags, mp_uint_t type_sig) {
|
void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun_data, mp_uint_t fun_len, const mp_uint_t *const_table, mp_uint_t n_pos_args, mp_uint_t scope_flags, mp_uint_t type_sig) {
|
||||||
assert(kind == MP_CODE_NATIVE_PY || kind == MP_CODE_NATIVE_VIPER || kind == MP_CODE_NATIVE_ASM);
|
assert(kind == MP_CODE_NATIVE_PY || kind == MP_CODE_NATIVE_VIPER || kind == MP_CODE_NATIVE_ASM);
|
||||||
rc->kind = kind;
|
rc->kind = kind;
|
||||||
@ -138,7 +138,7 @@ mp_obj_t mp_make_function_from_raw_code(const mp_raw_code_t *rc, mp_obj_t def_ar
|
|||||||
fun = mp_obj_new_fun_viper(rc->n_pos_args, rc->data.u_native.fun_data, rc->data.u_native.type_sig);
|
fun = mp_obj_new_fun_viper(rc->n_pos_args, rc->data.u_native.fun_data, rc->data.u_native.type_sig);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if MICROPY_EMIT_INLINE_THUMB
|
#if MICROPY_EMIT_INLINE_ASM
|
||||||
case MP_CODE_NATIVE_ASM:
|
case MP_CODE_NATIVE_ASM:
|
||||||
fun = mp_obj_new_fun_asm(rc->n_pos_args, rc->data.u_native.fun_data, rc->data.u_native.type_sig);
|
fun = mp_obj_new_fun_asm(rc->n_pos_args, rc->data.u_native.fun_data, rc->data.u_native.type_sig);
|
||||||
break;
|
break;
|
||||||
|
@ -296,6 +296,9 @@
|
|||||||
// Convenience definition for whether any native emitter is enabled
|
// Convenience definition for whether any native emitter is enabled
|
||||||
#define MICROPY_EMIT_NATIVE (MICROPY_EMIT_X64 || MICROPY_EMIT_X86 || MICROPY_EMIT_THUMB || MICROPY_EMIT_ARM || MICROPY_EMIT_XTENSA)
|
#define MICROPY_EMIT_NATIVE (MICROPY_EMIT_X64 || MICROPY_EMIT_X86 || MICROPY_EMIT_THUMB || MICROPY_EMIT_ARM || MICROPY_EMIT_XTENSA)
|
||||||
|
|
||||||
|
// Convenience definition for whether any inline assembler emitter is enabled
|
||||||
|
#define MICROPY_EMIT_INLINE_ASM (MICROPY_EMIT_INLINE_THUMB)
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Compiler configuration */
|
/* Compiler configuration */
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ mp_uint_t mp_convert_obj_to_native(mp_obj_t obj, mp_uint_t type) {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if MICROPY_EMIT_NATIVE || MICROPY_EMIT_INLINE_THUMB
|
#if MICROPY_EMIT_NATIVE || MICROPY_EMIT_INLINE_ASM
|
||||||
|
|
||||||
// convert a native value to a Micro Python object based on type
|
// convert a native value to a Micro Python object based on type
|
||||||
mp_obj_t mp_convert_native_to_obj(mp_uint_t val, mp_uint_t type) {
|
mp_obj_t mp_convert_native_to_obj(mp_uint_t val, mp_uint_t type) {
|
||||||
|
@ -471,7 +471,7 @@ mp_obj_t mp_obj_new_fun_viper(mp_uint_t n_args, void *fun_data, mp_uint_t type_s
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* inline assembler functions */
|
/* inline assembler functions */
|
||||||
|
|
||||||
#if MICROPY_EMIT_INLINE_THUMB
|
#if MICROPY_EMIT_INLINE_ASM
|
||||||
|
|
||||||
typedef struct _mp_obj_fun_asm_t {
|
typedef struct _mp_obj_fun_asm_t {
|
||||||
mp_obj_base_t base;
|
mp_obj_base_t base;
|
||||||
@ -582,4 +582,4 @@ mp_obj_t mp_obj_new_fun_asm(mp_uint_t n_args, void *fun_data, mp_uint_t type_sig
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MICROPY_EMIT_INLINE_THUMB
|
#endif // MICROPY_EMIT_INLINE_ASM
|
||||||
|
Loading…
Reference in New Issue
Block a user