Skip to content

Commit d64154c

Browse files
committed
py/emitinlinethumb: Update to work with new small-heap compiler.
Note that the inline assembler only works with the small-heap compiler enabled.
1 parent 4145377 commit d64154c

File tree

5 files changed

+116
-91
lines changed

5 files changed

+116
-91
lines changed

py/compile2.c

Lines changed: 52 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "py/emit.h"
3535
#include "py/compile.h"
3636
#include "py/runtime.h"
37+
#include "py/asmbase.h"
3738

3839
#if MICROPY_ENABLE_COMPILER && MICROPY_USE_SMALL_HEAP_COMPILER
3940

@@ -81,6 +82,19 @@ typedef enum {
8182

8283
#endif
8384

85+
#if MICROPY_EMIT_INLINE_ASM
86+
// define macros for inline assembler
87+
#if MICROPY_EMIT_INLINE_THUMB
88+
#define ASM_DECORATOR_QSTR MP_QSTR_asm_thumb
89+
#define ASM_EMITTER(f) emit_inline_thumb_##f
90+
#elif MICROPY_EMIT_INLINE_XTENSA
91+
#define ASM_DECORATOR_QSTR MP_QSTR_asm_xtensa
92+
#define ASM_EMITTER(f) emit_inline_xtensa_##f
93+
#else
94+
#error "unknown asm emitter"
95+
#endif
96+
#endif
97+
8498
#define EMIT_INLINE_ASM(fun) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm))
8599
#define EMIT_INLINE_ASM_ARG(fun, ...) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm, __VA_ARGS__))
86100

@@ -117,7 +131,7 @@ typedef struct _compiler_t {
117131
const emit_method_table_t *emit_method_table; // current emit method table
118132
#endif
119133

120-
#if MICROPY_EMIT_INLINE_THUMB
134+
#if MICROPY_EMIT_INLINE_ASM
121135
emit_inline_asm_t *emit_inline_asm; // current emitter for inline asm
122136
const emit_inline_asm_method_table_t *emit_inline_asm_method_table; // current emit method table for inline asm
123137
#endif
@@ -790,10 +804,10 @@ STATIC bool compile_built_in_decorator(compiler_t *comp, const byte *p, const by
790804
} else if (attr == MP_QSTR_viper) {
791805
*emit_options = MP_EMIT_OPT_VIPER;
792806
#endif
793-
#if MICROPY_EMIT_INLINE_THUMB
794-
} else if (attr == MP_QSTR_asm_thumb) {
795-
*emit_options = MP_EMIT_OPT_ASM_THUMB;
796-
#endif
807+
#if MICROPY_EMIT_INLINE_ASM
808+
} else if (attr == ASM_DECORATOR_QSTR) {
809+
*emit_options = MP_EMIT_OPT_ASM;
810+
#endif
797811
} else {
798812
compile_syntax_error(comp, NULL, "invalid micropython decorator");
799813
}
@@ -3016,7 +3030,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
30163030
assert(comp->cur_except_level == 0);
30173031
}
30183032

3019-
#if MICROPY_EMIT_INLINE_THUMB
3033+
#if MICROPY_EMIT_INLINE_ASM
30203034
// requires 3 passes: SCOPE, CODE_SIZE, EMIT
30213035
STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
30223036
comp->pass = pass;
@@ -3029,7 +3043,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
30293043
}
30303044

30313045
if (comp->pass > MP_PASS_SCOPE) {
3032-
EMIT_INLINE_ASM_ARG(start_pass, comp->pass, comp->scope_cur, &comp->compile_error);
3046+
EMIT_INLINE_ASM_ARG(start_pass, comp->pass, &comp->compile_error);
30333047
}
30343048

30353049
// get the function definition parse node
@@ -3134,7 +3148,8 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
31343148
return;
31353149
}
31363150
if (pass > MP_PASS_SCOPE) {
3137-
EMIT_INLINE_ASM_ARG(align, pt_small_int_value(p_args));
3151+
mp_asm_base_align((mp_asm_base_t*)comp->emit_inline_asm,
3152+
pt_small_int_value(p_args));
31383153
}
31393154
} else if (op == MP_QSTR_data) {
31403155
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
31513166
}
31523167
mp_int_t val;
31533168
p_args = pt_get_small_int(p_args, &val);
3154-
EMIT_INLINE_ASM_ARG(data, bytesize, val);
3169+
mp_asm_base_data((mp_asm_base_t*)comp->emit_inline_asm,
3170+
bytesize, val);
31553171
}
31563172
}
31573173
} else {
@@ -3174,6 +3190,13 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
31743190

31753191
if (comp->pass > MP_PASS_SCOPE) {
31763192
EMIT_INLINE_ASM_ARG(end_pass, type_sig);
3193+
3194+
if (comp->pass == MP_PASS_EMIT) {
3195+
void *f = mp_asm_base_get_code((mp_asm_base_t*)comp->emit_inline_asm);
3196+
mp_emit_glue_assign_native(comp->scope_cur->raw_code, MP_CODE_NATIVE_ASM,
3197+
f, mp_asm_base_get_code_size((mp_asm_base_t*)comp->emit_inline_asm),
3198+
NULL, comp->scope_cur->num_pos_args, 0, type_sig);
3199+
}
31773200
}
31783201

31793202
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
33093332
keep_going = true;
33103333
s->raw_code = mp_emit_glue_new_raw_code();
33113334
if (false) {
3312-
#if MICROPY_EMIT_INLINE_THUMB
3313-
} else if (s->emit_options == MP_EMIT_OPT_ASM_THUMB) {
3335+
#if MICROPY_EMIT_INLINE_ASM
3336+
} else if (s->emit_options == MP_EMIT_OPT_ASM) {
33143337
compile_scope_inline_asm(comp, s, MP_PASS_SCOPE);
3315-
#endif
3338+
#endif
33163339
} else {
33173340
compile_scope(comp, s, MP_PASS_SCOPE);
33183341
}
@@ -3337,30 +3360,32 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f
33373360
// compile pass 2 and 3
33383361
#if MICROPY_EMIT_NATIVE
33393362
emit_t *emit_native = NULL;
3340-
#endif
3341-
#if MICROPY_EMIT_INLINE_THUMB
3342-
emit_inline_asm_t *emit_inline_thumb = NULL;
33433363
#endif
33443364
for (uint i = 0; i < comp->num_scopes && comp->compile_error == MP_OBJ_NULL; ++i) {
33453365
scope_t *s = comp->scopes[i];
33463366
if (s == NULL) { continue; }
33473367
if (false) {
33483368
// dummy
33493369

3350-
#if MICROPY_EMIT_INLINE_THUMB
3351-
} else if (s->emit_options == MP_EMIT_OPT_ASM_THUMB) {
3352-
// inline assembly for thumb
3353-
if (emit_inline_thumb == NULL) {
3354-
emit_inline_thumb = emit_inline_thumb_new(max_num_labels);
3370+
#if MICROPY_EMIT_INLINE_ASM
3371+
} else if (s->emit_options == MP_EMIT_OPT_ASM) {
3372+
// inline assembly
3373+
if (comp->emit_inline_asm == NULL) {
3374+
comp->emit_inline_asm = ASM_EMITTER(new)(comp->co_data, max_num_labels);
33553375
}
33563376
comp->emit = NULL;
3357-
comp->emit_inline_asm = emit_inline_thumb;
3358-
comp->emit_inline_asm_method_table = &emit_inline_thumb_method_table;
3377+
comp->emit_inline_asm_method_table = &ASM_EMITTER(method_table);
3378+
compile_scope_inline_asm(comp, s, MP_PASS_CODE_SIZE);
3379+
#if MICROPY_EMIT_INLINE_XTENSA
3380+
// Xtensa requires an extra pass to compute size of l32r const table
3381+
// TODO this can be improved by calculating it during SCOPE pass
3382+
// but that requires some other structural changes to the asm emitters
33593383
compile_scope_inline_asm(comp, s, MP_PASS_CODE_SIZE);
3384+
#endif
33603385
if (comp->compile_error == MP_OBJ_NULL) {
33613386
compile_scope_inline_asm(comp, s, MP_PASS_EMIT);
33623387
}
3363-
#endif
3388+
#endif
33643389

33653390
} else {
33663391

@@ -3445,11 +3470,11 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f
34453470
#endif
34463471
}
34473472
#endif
3448-
#if MICROPY_EMIT_INLINE_THUMB
3449-
if (emit_inline_thumb != NULL) {
3450-
emit_inline_thumb_free(emit_inline_thumb);
3473+
#if MICROPY_EMIT_INLINE_ASM
3474+
if (comp->emit_inline_asm != NULL) {
3475+
ASM_EMITTER(free)(comp->emit_inline_asm);
34513476
}
3452-
#endif
3477+
#endif
34533478

34543479
// free the parse tree
34553480
mp_parse_tree_clear(parse_tree);

py/emit.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ typedef struct _emit_inline_asm_method_table_t {
271271
extern const emit_inline_asm_method_table_t emit_inline_thumb_method_table;
272272
extern const emit_inline_asm_method_table_t emit_inline_xtensa_method_table;
273273

274-
emit_inline_asm_t *emit_inline_thumb_new(mp_uint_t max_num_labels);
274+
emit_inline_asm_t *emit_inline_thumb_new(mp_uint_t *co_data, mp_uint_t max_num_labels);
275275
emit_inline_asm_t *emit_inline_xtensa_new(mp_uint_t max_num_labels);
276276

277277
void emit_inline_thumb_free(emit_inline_asm_t *emit);

0 commit comments

Comments
 (0)