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
30213035STATIC 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 );
0 commit comments