summaryrefslogtreecommitdiffstatshomepage
path: root/py/compile2.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2017-09-01 14:55:44 +1000
committerDamien George <damien.p.george@gmail.com>2017-09-01 14:55:44 +1000
commitd64154c730b55606e6212959f976b6fd7f4bd41b (patch)
tree88b1b599925006e53766053a594e47750b49ba95 /py/compile2.c
parent414537711dd05531c63eb830bfc9c3eecf657b1e (diff)
downloadmicropython-d64154c730b55606e6212959f976b6fd7f4bd41b.tar.gz
micropython-d64154c730b55606e6212959f976b6fd7f4bd41b.zip
py/emitinlinethumb: Update to work with new small-heap compiler.
Note that the inline assembler only works with the small-heap compiler enabled.
Diffstat (limited to 'py/compile2.c')
-rw-r--r--py/compile2.c79
1 files changed, 52 insertions, 27 deletions
diff --git a/py/compile2.c b/py/compile2.c
index 935c50f52f..8e6d76edbe 100644
--- a/py/compile2.c
+++ b/py/compile2.c
@@ -34,6 +34,7 @@
#include "py/emit.h"
#include "py/compile.h"
#include "py/runtime.h"
+#include "py/asmbase.h"
#if MICROPY_ENABLE_COMPILER && MICROPY_USE_SMALL_HEAP_COMPILER
@@ -81,6 +82,19 @@ typedef enum {
#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
+#elif MICROPY_EMIT_INLINE_XTENSA
+#define ASM_DECORATOR_QSTR MP_QSTR_asm_xtensa
+#define ASM_EMITTER(f) emit_inline_xtensa_##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__))
@@ -117,7 +131,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
@@ -790,10 +804,10 @@ STATIC bool compile_built_in_decorator(compiler_t *comp, const byte *p, const by
} 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, NULL, "invalid micropython decorator");
}
@@ -3016,7 +3030,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;
@@ -3029,7 +3043,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
}
if (comp->pass > MP_PASS_SCOPE) {
- EMIT_INLINE_ASM_ARG(start_pass, comp->pass, comp->scope_cur, &comp->compile_error);
+ EMIT_INLINE_ASM_ARG(start_pass, comp->pass, &comp->compile_error);
}
// get the function definition parse node
@@ -3134,7 +3148,8 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
return;
}
if (pass > MP_PASS_SCOPE) {
- EMIT_INLINE_ASM_ARG(align, pt_small_int_value(p_args));
+ mp_asm_base_align((mp_asm_base_t*)comp->emit_inline_asm,
+ pt_small_int_value(p_args));
}
} else if (op == MP_QSTR_data) {
if (!(n_args >= 2 && pt_is_small_int(p_args))) {
@@ -3151,7 +3166,8 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
}
mp_int_t val;
p_args = pt_get_small_int(p_args, &val);
- EMIT_INLINE_ASM_ARG(data, bytesize, val);
+ mp_asm_base_data((mp_asm_base_t*)comp->emit_inline_asm,
+ bytesize, val);
}
}
} else {
@@ -3174,6 +3190,13 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
if (comp->pass > MP_PASS_SCOPE) {
EMIT_INLINE_ASM_ARG(end_pass, type_sig);
+
+ if (comp->pass == MP_PASS_EMIT) {
+ void *f = mp_asm_base_get_code((mp_asm_base_t*)comp->emit_inline_asm);
+ mp_emit_glue_assign_native(comp->scope_cur->raw_code, MP_CODE_NATIVE_ASM,
+ f, mp_asm_base_get_code_size((mp_asm_base_t*)comp->emit_inline_asm),
+ NULL, comp->scope_cur->num_pos_args, 0, type_sig);
+ }
}
if (comp->compile_error != MP_OBJ_NULL) {
@@ -3309,10 +3332,10 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f
keep_going = true;
s->raw_code = mp_emit_glue_new_raw_code();
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);
}
@@ -3338,29 +3361,31 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f
#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 (uint i = 0; i < comp->num_scopes && comp->compile_error == MP_OBJ_NULL; ++i) {
scope_t *s = comp->scopes[i];
if (s == NULL) { continue; }
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)(comp->co_data, 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 MICROPY_EMIT_INLINE_XTENSA
+ // Xtensa requires an extra pass to compute size of l32r const table
+ // TODO this can be improved by calculating it during SCOPE pass
+ // but that requires some other structural changes to the asm emitters
compile_scope_inline_asm(comp, s, MP_PASS_CODE_SIZE);
+ #endif
if (comp->compile_error == MP_OBJ_NULL) {
compile_scope_inline_asm(comp, s, MP_PASS_EMIT);
}
-#endif
+ #endif
} else {
@@ -3445,11 +3470,11 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f
#endif
}
#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);