@@ -392,6 +392,9 @@ STATIC const format_vfp_op_t format_vfp_op_table[] = {
392392};
393393#endif
394394
395+ // shorthand alias for whether we allow ARMv7-M instructions
396+ #define ARMV7M MICROPY_EMIT_INLINE_THUMB_ARMV7M
397+
395398STATIC void emit_inline_thumb_op (emit_inline_asm_t * emit , qstr op , mp_uint_t n_args , mp_parse_node_t * pn_args ) {
396399 // TODO perhaps make two tables:
397400 // one_args =
@@ -527,7 +530,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
527530 asm_thumb_op16 (emit -> as , 0x4700 | (r << 3 ));
528531 } else if (op_str [0 ] == 'b' && (op_len == 3
529532 || (op_len == 5 && op_str [3 ] == '_'
530- && (op_str [4 ] == 'n' || op_str [4 ] == 'w' )))) {
533+ && (op_str [4 ] == 'n' || ( ARMV7M && op_str [4 ] == 'w' ) )))) {
531534 mp_uint_t cc = -1 ;
532535 for (mp_uint_t i = 0 ; i < MP_ARRAY_SIZE (cc_name_table ); i ++ ) {
533536 if (op_str [1 ] == cc_name_table [i ].name [0 ] && op_str [2 ] == cc_name_table [i ].name [1 ]) {
@@ -541,7 +544,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
541544 if (!asm_thumb_bcc_nw_label (emit -> as , cc , label_num , op_len == 5 && op_str [4 ] == 'w' )) {
542545 goto branch_not_in_range ;
543546 }
544- } else if (op_str [0 ] == 'i' && op_str [1 ] == 't' ) {
547+ } else if (ARMV7M && op_str [0 ] == 'i' && op_str [1 ] == 't' ) {
545548 const char * arg_str = get_arg_str (pn_args [0 ]);
546549 mp_uint_t cc = -1 ;
547550 for (mp_uint_t i = 0 ; i < MP_ARRAY_SIZE (cc_name_table ); i ++ ) {
@@ -585,13 +588,19 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
585588 if ((reglist & 0xff00 ) == 0 ) {
586589 asm_thumb_op16 (emit -> as , 0xb400 | reglist );
587590 } else {
591+ if (!ARMV7M ) {
592+ goto unknown_op ;
593+ }
588594 asm_thumb_op32 (emit -> as , 0xe92d , reglist );
589595 }
590596 } else if (strcmp (op_str , "pop" ) == 0 ) {
591597 mp_uint_t reglist = get_arg_reglist (emit , op_str , pn_args [0 ]);
592598 if ((reglist & 0xff00 ) == 0 ) {
593599 asm_thumb_op16 (emit -> as , 0xbc00 | reglist );
594600 } else {
601+ if (!ARMV7M ) {
602+ goto unknown_op ;
603+ }
595604 asm_thumb_op32 (emit -> as , 0xe8bd , reglist );
596605 }
597606 } else {
@@ -606,15 +615,15 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
606615 mp_uint_t reg_dest = get_arg_reg (emit , op_str , pn_args [0 ], 15 );
607616 mp_uint_t reg_src = get_arg_reg (emit , op_str , pn_args [1 ], 15 );
608617 asm_thumb_mov_reg_reg (emit -> as , reg_dest , reg_src );
609- } else if (strcmp (op_str , "clz" ) == 0 ) {
618+ } else if (ARMV7M && strcmp (op_str , "clz" ) == 0 ) {
610619 op_code_hi = 0xfab0 ;
611620 op_code = 0xf080 ;
612621 mp_uint_t rd , rm ;
613622 op_clz_rbit :
614623 rd = get_arg_reg (emit , op_str , pn_args [0 ], 15 );
615624 rm = get_arg_reg (emit , op_str , pn_args [1 ], 15 );
616625 asm_thumb_op32 (emit -> as , op_code_hi | rm , op_code | (rd << 8 ) | rm );
617- } else if (strcmp (op_str , "rbit" ) == 0 ) {
626+ } else if (ARMV7M && strcmp (op_str , "rbit" ) == 0 ) {
618627 op_code_hi = 0xfa90 ;
619628 op_code = 0xf0a0 ;
620629 goto op_clz_rbit ;
@@ -656,24 +665,24 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
656665 } else if (strcmp (op_str , "sub" ) == 0 ) {
657666 op_code = ASM_THUMB_FORMAT_3_SUB ;
658667 goto op_format_3 ;
659- } else if (strcmp (op_str , "movw" ) == 0 ) {
668+ } else if (ARMV7M && strcmp (op_str , "movw" ) == 0 ) {
660669 op_code = ASM_THUMB_OP_MOVW ;
661670 mp_uint_t reg_dest ;
662671 op_movw_movt :
663672 reg_dest = get_arg_reg (emit , op_str , pn_args [0 ], 15 );
664673 int i_src = get_arg_i (emit , op_str , pn_args [1 ], 0xffff );
665674 asm_thumb_mov_reg_i16 (emit -> as , op_code , reg_dest , i_src );
666- } else if (strcmp (op_str , "movt" ) == 0 ) {
675+ } else if (ARMV7M && strcmp (op_str , "movt" ) == 0 ) {
667676 op_code = ASM_THUMB_OP_MOVT ;
668677 goto op_movw_movt ;
669- } else if (strcmp (op_str , "movwt" ) == 0 ) {
678+ } else if (ARMV7M && strcmp (op_str , "movwt" ) == 0 ) {
670679 // this is a convenience instruction
671680 // we clear the MSB since it might be set from extracting the small int value
672681 mp_uint_t reg_dest = get_arg_reg (emit , op_str , pn_args [0 ], 15 );
673682 int i_src = get_arg_i (emit , op_str , pn_args [1 ], 0xffffffff );
674683 asm_thumb_mov_reg_i16 (emit -> as , ASM_THUMB_OP_MOVW , reg_dest , i_src & 0xffff );
675684 asm_thumb_mov_reg_i16 (emit -> as , ASM_THUMB_OP_MOVT , reg_dest , (i_src >> 16 ) & 0x7fff );
676- } else if (strcmp (op_str , "ldrex" ) == 0 ) {
685+ } else if (ARMV7M && strcmp (op_str , "ldrex" ) == 0 ) {
677686 mp_uint_t r_dest = get_arg_reg (emit , op_str , pn_args [0 ], 15 );
678687 mp_parse_node_t pn_base , pn_offset ;
679688 if (get_arg_addr (emit , op_str , pn_args [1 ], & pn_base , & pn_offset )) {
@@ -725,21 +734,21 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
725734 src_b = get_arg_i (emit , op_str , pn_args [2 ], 0x7 );
726735 }
727736 asm_thumb_format_2 (emit -> as , op_code , rlo_dest , rlo_src , src_b );
728- } else if (strcmp (op_str , "sdiv" ) == 0 ) {
737+ } else if (ARMV7M && strcmp (op_str , "sdiv" ) == 0 ) {
729738 op_code = 0xfb90 ; // sdiv high part
730739 mp_uint_t rd , rn , rm ;
731740 op_sdiv_udiv :
732741 rd = get_arg_reg (emit , op_str , pn_args [0 ], 15 );
733742 rn = get_arg_reg (emit , op_str , pn_args [1 ], 15 );
734743 rm = get_arg_reg (emit , op_str , pn_args [2 ], 15 );
735744 asm_thumb_op32 (emit -> as , op_code | rn , 0xf0f0 | (rd << 8 ) | rm );
736- } else if (strcmp (op_str , "udiv" ) == 0 ) {
745+ } else if (ARMV7M && strcmp (op_str , "udiv" ) == 0 ) {
737746 op_code = 0xfbb0 ; // udiv high part
738747 goto op_sdiv_udiv ;
739748 } else if (strcmp (op_str , "sub" ) == 0 ) {
740749 op_code = ASM_THUMB_FORMAT_2_SUB ;
741750 goto op_format_2 ;
742- } else if (strcmp (op_str , "strex" ) == 0 ) {
751+ } else if (ARMV7M && strcmp (op_str , "strex" ) == 0 ) {
743752 mp_uint_t r_dest = get_arg_reg (emit , op_str , pn_args [0 ], 15 );
744753 mp_uint_t r_src = get_arg_reg (emit , op_str , pn_args [1 ], 15 );
745754 mp_parse_node_t pn_base , pn_offset ;
0 commit comments