@@ -43,12 +43,12 @@ typedef enum {
4343} pn_kind_t ;
4444
4545struct _emit_inline_asm_t {
46+ asm_thumb_t as ;
4647 uint16_t pass ;
4748 scope_t * scope ;
4849 mp_obj_t * error_slot ;
4950 mp_uint_t max_num_labels ;
5051 qstr * label_lookup ;
51- asm_thumb_t * as ;
5252};
5353
5454STATIC void emit_inline_thumb_error_msg (emit_inline_asm_t * emit , const char * msg ) {
@@ -61,17 +61,16 @@ STATIC void emit_inline_thumb_error_exc(emit_inline_asm_t *emit, mp_obj_t exc) {
6161
6262emit_inline_asm_t * emit_inline_thumb_new (mp_uint_t max_num_labels ) {
6363 emit_inline_asm_t * emit = m_new_obj (emit_inline_asm_t );
64+ memset (& emit -> as , 0 , sizeof (emit -> as ));
65+ mp_asm_base_init (& emit -> as .base , max_num_labels );
6466 emit -> max_num_labels = max_num_labels ;
6567 emit -> label_lookup = m_new (qstr , max_num_labels );
66- emit -> as = m_new0 (asm_thumb_t , 1 );
67- mp_asm_base_init (& emit -> as -> base , max_num_labels );
6868 return emit ;
6969}
7070
7171void emit_inline_thumb_free (emit_inline_asm_t * emit ) {
7272 m_del (qstr , emit -> label_lookup , emit -> max_num_labels );
73- mp_asm_base_deinit (& emit -> as -> base , false);
74- m_del_obj (asm_thumb_t , emit -> as );
73+ mp_asm_base_deinit (& emit -> as .base , false);
7574 m_del_obj (emit_inline_asm_t , emit );
7675}
7776
@@ -82,18 +81,18 @@ STATIC void emit_inline_thumb_start_pass(emit_inline_asm_t *emit, pass_kind_t pa
8281 if (emit -> pass == MP_PASS_CODE_SIZE ) {
8382 memset (emit -> label_lookup , 0 , emit -> max_num_labels * sizeof (qstr ));
8483 }
85- mp_asm_base_start_pass (& emit -> as -> base , pass == MP_PASS_EMIT ? MP_ASM_PASS_EMIT : MP_ASM_PASS_COMPUTE );
86- asm_thumb_entry (emit -> as , 0 );
84+ mp_asm_base_start_pass (& emit -> as . base , pass == MP_PASS_EMIT ? MP_ASM_PASS_EMIT : MP_ASM_PASS_COMPUTE );
85+ asm_thumb_entry (& emit -> as , 0 );
8786}
8887
8988STATIC void emit_inline_thumb_end_pass (emit_inline_asm_t * emit , mp_uint_t type_sig ) {
90- asm_thumb_exit (emit -> as );
91- asm_thumb_end_pass (emit -> as );
89+ asm_thumb_exit (& emit -> as );
90+ asm_thumb_end_pass (& emit -> as );
9291
9392 if (emit -> pass == MP_PASS_EMIT ) {
94- void * f = mp_asm_base_get_code (& emit -> as -> base );
93+ void * f = mp_asm_base_get_code (& emit -> as . base );
9594 mp_emit_glue_assign_native (emit -> scope -> raw_code , MP_CODE_NATIVE_ASM , f ,
96- mp_asm_base_get_code_size (& emit -> as -> base ), NULL , emit -> scope -> num_pos_args , 0 , type_sig );
95+ mp_asm_base_get_code_size (& emit -> as . base ), NULL , emit -> scope -> num_pos_args , 0 , type_sig );
9796 }
9897}
9998
@@ -127,16 +126,16 @@ STATIC bool emit_inline_thumb_label(emit_inline_asm_t *emit, mp_uint_t label_num
127126 }
128127 }
129128 emit -> label_lookup [label_num ] = label_id ;
130- mp_asm_base_label_assign (& emit -> as -> base , label_num );
129+ mp_asm_base_label_assign (& emit -> as . base , label_num );
131130 return true;
132131}
133132
134133STATIC void emit_inline_thumb_align (emit_inline_asm_t * emit , mp_uint_t align ) {
135- mp_asm_base_align (& emit -> as -> base , align );
134+ mp_asm_base_align (& emit -> as . base , align );
136135}
137136
138137STATIC void emit_inline_thumb_data (emit_inline_asm_t * emit , mp_uint_t bytesize , mp_uint_t val ) {
139- mp_asm_base_data (& emit -> as -> base , bytesize , val );
138+ mp_asm_base_data (& emit -> as . base , bytesize , val );
140139}
141140
142141typedef struct _reg_name_t { byte reg ; byte name [3 ]; } reg_name_t ;
@@ -445,7 +444,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
445444 op_vfp_twoargs :;
446445 mp_uint_t vd = get_arg_vfpreg (emit , op_str , pn_args [0 ]);
447446 mp_uint_t vm = get_arg_vfpreg (emit , op_str , pn_args [1 ]);
448- asm_thumb_op32 (emit -> as ,
447+ asm_thumb_op32 (& emit -> as ,
449448 op_code_hi | ((vd & 1 ) << 6 ),
450449 op_code | ((vd & 0x1e ) << 11 ) | ((vm & 1 ) << 5 ) | (vm & 0x1e ) >> 1 );
451450 } else if (op == MP_QSTR_vsqrt ) {
@@ -472,7 +471,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
472471 const char * reg_str1 = get_arg_str (pn_args [1 ]);
473472 if (strcmp (reg_str1 , "FPSCR" ) == 0 ) {
474473 // FP status to ARM reg
475- asm_thumb_op32 (emit -> as , 0xeef1 , 0x0a10 | (reg_dest << 12 ));
474+ asm_thumb_op32 (& emit -> as , 0xeef1 , 0x0a10 | (reg_dest << 12 ));
476475 } else {
477476 goto unknown_op ;
478477 }
@@ -488,7 +487,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
488487 vm = get_arg_vfpreg (emit , op_str , pn_args [0 ]);
489488 r_arm = get_arg_reg (emit , op_str , pn_args [1 ], 15 );
490489 }
491- asm_thumb_op32 (emit -> as ,
490+ asm_thumb_op32 (& emit -> as ,
492491 op_code_hi | ((vm & 0x1e ) >> 1 ),
493492 0x0a10 | (r_arm << 12 ) | ((vm & 1 ) << 7 ));
494493 } else if (op == MP_QSTR_vldr ) {
@@ -500,7 +499,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
500499 mp_uint_t rlo_base = get_arg_reg (emit , op_str , pn_base , 7 );
501500 mp_uint_t i8 ;
502501 i8 = get_arg_i (emit , op_str , pn_offset , 0x3fc ) >> 2 ;
503- asm_thumb_op32 (emit -> as ,
502+ asm_thumb_op32 (& emit -> as ,
504503 op_code_hi | rlo_base | ((vd & 1 ) << 6 ),
505504 0x0a00 | ((vd & 0x1e ) << 11 ) | i8 );
506505 }
@@ -519,7 +518,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
519518 mp_uint_t vd = get_arg_vfpreg (emit , op_str , pn_args [0 ]);
520519 mp_uint_t vn = get_arg_vfpreg (emit , op_str , pn_args [1 ]);
521520 mp_uint_t vm = get_arg_vfpreg (emit , op_str , pn_args [2 ]);
522- asm_thumb_op32 (emit -> as ,
521+ asm_thumb_op32 (& emit -> as ,
523522 op_code_hi | ((vd & 1 ) << 6 ) | (vn >> 1 ),
524523 op_code | (vm >> 1 ) | ((vm & 1 ) << 5 ) | ((vd & 0x1e ) << 11 ) | ((vn & 1 ) << 7 ));
525524 return ;
@@ -533,27 +532,27 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
533532 #endif
534533 if (n_args == 0 ) {
535534 if (op == MP_QSTR_nop ) {
536- asm_thumb_op16 (emit -> as , ASM_THUMB_OP_NOP );
535+ asm_thumb_op16 (& emit -> as , ASM_THUMB_OP_NOP );
537536 } else if (op == MP_QSTR_wfi ) {
538- asm_thumb_op16 (emit -> as , ASM_THUMB_OP_WFI );
537+ asm_thumb_op16 (& emit -> as , ASM_THUMB_OP_WFI );
539538 } else {
540539 goto unknown_op ;
541540 }
542541
543542 } else if (n_args == 1 ) {
544543 if (op == MP_QSTR_b ) {
545544 int label_num = get_arg_label (emit , op_str , pn_args [0 ]);
546- if (!asm_thumb_b_n_label (emit -> as , label_num )) {
545+ if (!asm_thumb_b_n_label (& emit -> as , label_num )) {
547546 goto branch_not_in_range ;
548547 }
549548 } else if (op == MP_QSTR_bl ) {
550549 int label_num = get_arg_label (emit , op_str , pn_args [0 ]);
551- if (!asm_thumb_bl_label (emit -> as , label_num )) {
550+ if (!asm_thumb_bl_label (& emit -> as , label_num )) {
552551 goto branch_not_in_range ;
553552 }
554553 } else if (op == MP_QSTR_bx ) {
555554 mp_uint_t r = get_arg_reg (emit , op_str , pn_args [0 ], 15 );
556- asm_thumb_op16 (emit -> as , 0x4700 | (r << 3 ));
555+ asm_thumb_op16 (& emit -> as , 0x4700 | (r << 3 ));
557556 } else if (op_str [0 ] == 'b' && (op_len == 3
558557 || (op_len == 5 && op_str [3 ] == '_'
559558 && (op_str [4 ] == 'n' || (ARMV7M && op_str [4 ] == 'w' ))))) {
@@ -567,7 +566,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
567566 goto unknown_op ;
568567 }
569568 int label_num = get_arg_label (emit , op_str , pn_args [0 ]);
570- if (!asm_thumb_bcc_nw_label (emit -> as , cc , label_num , op_len == 5 && op_str [4 ] == 'w' )) {
569+ if (!asm_thumb_bcc_nw_label (& emit -> as , cc , label_num , op_len == 5 && op_str [4 ] == 'w' )) {
571570 goto branch_not_in_range ;
572571 }
573572 } else if (ARMV7M && op_str [0 ] == 'i' && op_str [1 ] == 't' ) {
@@ -602,32 +601,32 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
602601 goto unknown_op ;
603602 }
604603 }
605- asm_thumb_it_cc (emit -> as , cc , it_mask );
604+ asm_thumb_it_cc (& emit -> as , cc , it_mask );
606605 } else if (op == MP_QSTR_cpsid ) {
607606 // TODO check pn_args[0] == i
608- asm_thumb_op16 (emit -> as , ASM_THUMB_OP_CPSID_I );
607+ asm_thumb_op16 (& emit -> as , ASM_THUMB_OP_CPSID_I );
609608 } else if (op == MP_QSTR_cpsie ) {
610609 // TODO check pn_args[0] == i
611- asm_thumb_op16 (emit -> as , ASM_THUMB_OP_CPSIE_I );
610+ asm_thumb_op16 (& emit -> as , ASM_THUMB_OP_CPSIE_I );
612611 } else if (op == MP_QSTR_push ) {
613612 mp_uint_t reglist = get_arg_reglist (emit , op_str , pn_args [0 ]);
614613 if ((reglist & 0xff00 ) == 0 ) {
615- asm_thumb_op16 (emit -> as , 0xb400 | reglist );
614+ asm_thumb_op16 (& emit -> as , 0xb400 | reglist );
616615 } else {
617616 if (!ARMV7M ) {
618617 goto unknown_op ;
619618 }
620- asm_thumb_op32 (emit -> as , 0xe92d , reglist );
619+ asm_thumb_op32 (& emit -> as , 0xe92d , reglist );
621620 }
622621 } else if (op == MP_QSTR_pop ) {
623622 mp_uint_t reglist = get_arg_reglist (emit , op_str , pn_args [0 ]);
624623 if ((reglist & 0xff00 ) == 0 ) {
625- asm_thumb_op16 (emit -> as , 0xbc00 | reglist );
624+ asm_thumb_op16 (& emit -> as , 0xbc00 | reglist );
626625 } else {
627626 if (!ARMV7M ) {
628627 goto unknown_op ;
629628 }
630- asm_thumb_op32 (emit -> as , 0xe8bd , reglist );
629+ asm_thumb_op32 (& emit -> as , 0xe8bd , reglist );
631630 }
632631 } else {
633632 goto unknown_op ;
@@ -640,31 +639,31 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
640639 if (op == MP_QSTR_mov ) {
641640 mp_uint_t reg_dest = get_arg_reg (emit , op_str , pn_args [0 ], 15 );
642641 mp_uint_t reg_src = get_arg_reg (emit , op_str , pn_args [1 ], 15 );
643- asm_thumb_mov_reg_reg (emit -> as , reg_dest , reg_src );
642+ asm_thumb_mov_reg_reg (& emit -> as , reg_dest , reg_src );
644643 } else if (ARMV7M && op == MP_QSTR_clz ) {
645644 op_code_hi = 0xfab0 ;
646645 op_code = 0xf080 ;
647646 mp_uint_t rd , rm ;
648647 op_clz_rbit :
649648 rd = get_arg_reg (emit , op_str , pn_args [0 ], 15 );
650649 rm = get_arg_reg (emit , op_str , pn_args [1 ], 15 );
651- asm_thumb_op32 (emit -> as , op_code_hi | rm , op_code | (rd << 8 ) | rm );
650+ asm_thumb_op32 (& emit -> as , op_code_hi | rm , op_code | (rd << 8 ) | rm );
652651 } else if (ARMV7M && op == MP_QSTR_rbit ) {
653652 op_code_hi = 0xfa90 ;
654653 op_code = 0xf0a0 ;
655654 goto op_clz_rbit ;
656655 } else if (ARMV7M && op == MP_QSTR_mrs ){
657656 mp_uint_t reg_dest = get_arg_reg (emit , op_str , pn_args [0 ], 12 );
658657 mp_uint_t reg_src = get_arg_special_reg (emit , op_str , pn_args [1 ]);
659- asm_thumb_op32 (emit -> as , 0xf3ef , 0x8000 | (reg_dest << 8 ) | reg_src );
658+ asm_thumb_op32 (& emit -> as , 0xf3ef , 0x8000 | (reg_dest << 8 ) | reg_src );
660659 } else {
661660 if (op == MP_QSTR_and_ ) {
662661 op_code = ASM_THUMB_FORMAT_4_AND ;
663662 mp_uint_t reg_dest , reg_src ;
664663 op_format_4 :
665664 reg_dest = get_arg_reg (emit , op_str , pn_args [0 ], 7 );
666665 reg_src = get_arg_reg (emit , op_str , pn_args [1 ], 7 );
667- asm_thumb_format_4 (emit -> as , op_code , reg_dest , reg_src );
666+ asm_thumb_format_4 (& emit -> as , op_code , reg_dest , reg_src );
668667 return ;
669668 }
670669 // search table for ALU ops
@@ -685,7 +684,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
685684 op_format_3 :
686685 rlo_dest = get_arg_reg (emit , op_str , pn_args [0 ], 7 );
687686 i8_src = get_arg_i (emit , op_str , pn_args [1 ], 0xff );
688- asm_thumb_format_3 (emit -> as , op_code , rlo_dest , i8_src );
687+ asm_thumb_format_3 (& emit -> as , op_code , rlo_dest , i8_src );
689688 } else if (op == MP_QSTR_cmp ) {
690689 op_code = ASM_THUMB_FORMAT_3_CMP ;
691690 goto op_format_3 ;
@@ -701,23 +700,23 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
701700 op_movw_movt :
702701 reg_dest = get_arg_reg (emit , op_str , pn_args [0 ], 15 );
703702 int i_src = get_arg_i (emit , op_str , pn_args [1 ], 0xffff );
704- asm_thumb_mov_reg_i16 (emit -> as , op_code , reg_dest , i_src );
703+ asm_thumb_mov_reg_i16 (& emit -> as , op_code , reg_dest , i_src );
705704 } else if (ARMV7M && op == MP_QSTR_movt ) {
706705 op_code = ASM_THUMB_OP_MOVT ;
707706 goto op_movw_movt ;
708707 } else if (ARMV7M && op == MP_QSTR_movwt ) {
709708 // this is a convenience instruction
710709 mp_uint_t reg_dest = get_arg_reg (emit , op_str , pn_args [0 ], 15 );
711710 uint32_t i_src = get_arg_i (emit , op_str , pn_args [1 ], 0xffffffff );
712- asm_thumb_mov_reg_i16 (emit -> as , ASM_THUMB_OP_MOVW , reg_dest , i_src & 0xffff );
713- asm_thumb_mov_reg_i16 (emit -> as , ASM_THUMB_OP_MOVT , reg_dest , (i_src >> 16 ) & 0xffff );
711+ asm_thumb_mov_reg_i16 (& emit -> as , ASM_THUMB_OP_MOVW , reg_dest , i_src & 0xffff );
712+ asm_thumb_mov_reg_i16 (& emit -> as , ASM_THUMB_OP_MOVT , reg_dest , (i_src >> 16 ) & 0xffff );
714713 } else if (ARMV7M && op == MP_QSTR_ldrex ) {
715714 mp_uint_t r_dest = get_arg_reg (emit , op_str , pn_args [0 ], 15 );
716715 mp_parse_node_t pn_base , pn_offset ;
717716 if (get_arg_addr (emit , op_str , pn_args [1 ], & pn_base , & pn_offset )) {
718717 mp_uint_t r_base = get_arg_reg (emit , op_str , pn_base , 15 );
719718 mp_uint_t i8 = get_arg_i (emit , op_str , pn_offset , 0xff ) >> 2 ;
720- asm_thumb_op32 (emit -> as , 0xe850 | r_base , 0x0f00 | (r_dest << 12 ) | i8 );
719+ asm_thumb_op32 (& emit -> as , 0xe850 | r_base , 0x0f00 | (r_dest << 12 ) | i8 );
721720 }
722721 } else {
723722 // search table for ldr/str instructions
@@ -736,7 +735,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
736735 } else {
737736 i5 = get_arg_i (emit , op_str , pn_offset , 0x7c ) >> 2 ;
738737 }
739- asm_thumb_format_9_10 (emit -> as , op_code , rlo_dest , rlo_base , i5 );
738+ asm_thumb_format_9_10 (& emit -> as , op_code , rlo_dest , rlo_base , i5 );
740739 return ;
741740 }
742741 break ;
@@ -755,7 +754,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
755754 rlo_dest = get_arg_reg (emit , op_str , pn_args [0 ], 7 );
756755 rlo_src = get_arg_reg (emit , op_str , pn_args [1 ], 7 );
757756 i5 = get_arg_i (emit , op_str , pn_args [2 ], 0x1f );
758- asm_thumb_format_1 (emit -> as , op_code , rlo_dest , rlo_src , i5 );
757+ asm_thumb_format_1 (& emit -> as , op_code , rlo_dest , rlo_src , i5 );
759758 } else if (op == MP_QSTR_lsr ) {
760759 op_code = ASM_THUMB_FORMAT_1_LSR ;
761760 goto op_format_1 ;
@@ -776,15 +775,15 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
776775 op_code |= ASM_THUMB_FORMAT_2_IMM_OPERAND ;
777776 src_b = get_arg_i (emit , op_str , pn_args [2 ], 0x7 );
778777 }
779- asm_thumb_format_2 (emit -> as , op_code , rlo_dest , rlo_src , src_b );
778+ asm_thumb_format_2 (& emit -> as , op_code , rlo_dest , rlo_src , src_b );
780779 } else if (ARMV7M && op == MP_QSTR_sdiv ) {
781780 op_code = 0xfb90 ; // sdiv high part
782781 mp_uint_t rd , rn , rm ;
783782 op_sdiv_udiv :
784783 rd = get_arg_reg (emit , op_str , pn_args [0 ], 15 );
785784 rn = get_arg_reg (emit , op_str , pn_args [1 ], 15 );
786785 rm = get_arg_reg (emit , op_str , pn_args [2 ], 15 );
787- asm_thumb_op32 (emit -> as , op_code | rn , 0xf0f0 | (rd << 8 ) | rm );
786+ asm_thumb_op32 (& emit -> as , op_code | rn , 0xf0f0 | (rd << 8 ) | rm );
788787 } else if (ARMV7M && op == MP_QSTR_udiv ) {
789788 op_code = 0xfbb0 ; // udiv high part
790789 goto op_sdiv_udiv ;
@@ -798,7 +797,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
798797 if (get_arg_addr (emit , op_str , pn_args [2 ], & pn_base , & pn_offset )) {
799798 mp_uint_t r_base = get_arg_reg (emit , op_str , pn_base , 15 );
800799 mp_uint_t i8 = get_arg_i (emit , op_str , pn_offset , 0xff ) >> 2 ;
801- asm_thumb_op32 (emit -> as , 0xe840 | r_base , (r_src << 12 ) | (r_dest << 8 ) | i8 );
800+ asm_thumb_op32 (& emit -> as , 0xe840 | r_base , (r_src << 12 ) | (r_dest << 8 ) | i8 );
802801 }
803802 } else {
804803 goto unknown_op ;
0 commit comments