Commit ad297a19 authored by Damien George's avatar Damien George
Browse files

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.
parent 45a6156d
...@@ -31,7 +31,7 @@ ...@@ -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) { ...@@ -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
...@@ -86,6 +86,16 @@ typedef enum { ...@@ -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 { ...@@ -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_ ...@@ -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) { ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 { ...@@ -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 ...@@ -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 ...@@ -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 @@ ...@@ -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) { ...@@ -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 ...@@ -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 ...@@ -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
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment