@@ -150,23 +150,38 @@ STATIC const reg_name_t reg_name_table[] = {
150150 {15 , "pc\0" },
151151};
152152
153- STATIC mp_uint_t get_arg_reg (emit_inline_asm_t * emit , const char * op , mp_parse_node_t pn , mp_uint_t max_reg ) {
153+ // return empty string in case of error, so we can attempt to parse the string
154+ // without a special check if it was in fact a string
155+ STATIC const char * get_arg_str (mp_parse_node_t pn ) {
154156 if (MP_PARSE_NODE_IS_ID (pn )) {
155- qstr reg_qstr = MP_PARSE_NODE_LEAF_ARG (pn );
156- const char * reg_str = qstr_str (reg_qstr );
157- for (mp_uint_t i = 0 ; i < MP_ARRAY_SIZE (reg_name_table ); i ++ ) {
158- const reg_name_t * r = & reg_name_table [i ];
159- if (reg_str [0 ] == r -> name [0 ] && reg_str [1 ] == r -> name [1 ] && reg_str [2 ] == r -> name [2 ] && (reg_str [2 ] == '\0' || reg_str [3 ] == '\0' )) {
160- if (r -> reg > max_reg ) {
161- emit_inline_thumb_error_exc (emit , mp_obj_new_exception_msg_varg (& mp_type_SyntaxError , "'%s' expects at most r%d" , op , max_reg ));
162- return 0 ;
163- } else {
164- return r -> reg ;
165- }
157+ qstr qst = MP_PARSE_NODE_LEAF_ARG (pn );
158+ return qstr_str (qst );
159+ } else {
160+ return "" ;
161+ }
162+ }
163+
164+ STATIC mp_uint_t get_arg_reg (emit_inline_asm_t * emit , const char * op , mp_parse_node_t pn , mp_uint_t max_reg ) {
165+ const char * reg_str = get_arg_str (pn );
166+ for (mp_uint_t i = 0 ; i < MP_ARRAY_SIZE (reg_name_table ); i ++ ) {
167+ const reg_name_t * r = & reg_name_table [i ];
168+ if (reg_str [0 ] == r -> name [0 ]
169+ && reg_str [1 ] == r -> name [1 ]
170+ && reg_str [2 ] == r -> name [2 ]
171+ && (reg_str [2 ] == '\0' || reg_str [3 ] == '\0' )) {
172+ if (r -> reg > max_reg ) {
173+ emit_inline_thumb_error_exc (emit ,
174+ mp_obj_new_exception_msg_varg (& mp_type_SyntaxError ,
175+ "'%s' expects at most r%d" , op , max_reg ));
176+ return 0 ;
177+ } else {
178+ return r -> reg ;
166179 }
167180 }
168181 }
169- emit_inline_thumb_error_exc (emit , mp_obj_new_exception_msg_varg (& mp_type_SyntaxError , "'%s' expects a register" , op ));
182+ emit_inline_thumb_error_exc (emit ,
183+ mp_obj_new_exception_msg_varg (& mp_type_SyntaxError ,
184+ "'%s' expects a register" , op ));
170185 return 0 ;
171186}
172187
@@ -312,8 +327,6 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
312327 asm_thumb_op16 (emit -> as , ASM_THUMB_OP_NOP );
313328 } else if (strcmp (op_str , "wfi" ) == 0 ) {
314329 asm_thumb_op16 (emit -> as , ASM_THUMB_OP_WFI );
315- } else if (strcmp (op_str , "ite.ge" ) == 0 ) { // TODO correct name for this op?
316- asm_thumb_op16 (emit -> as , ASM_THUMB_OP_ITE_GE );
317330 } else {
318331 goto unknown_op ;
319332 }
@@ -336,6 +349,39 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
336349 int label_num = get_arg_label (emit , op_str , pn_args [0 ]);
337350 // TODO check that this succeeded, ie branch was within range
338351 asm_thumb_bcc_n (emit -> as , cc , label_num );
352+ } else if (op_str [0 ] == 'i' && op_str [1 ] == 't' ) {
353+ const char * arg_str = get_arg_str (pn_args [0 ]);
354+ mp_uint_t cc = -1 ;
355+ for (mp_uint_t i = 0 ; i < MP_ARRAY_SIZE (cc_name_table ); i ++ ) {
356+ if (arg_str [0 ] == cc_name_table [i ].name [0 ]
357+ && arg_str [1 ] == cc_name_table [i ].name [1 ]
358+ && arg_str [2 ] == '\0' ) {
359+ cc = cc_name_table [i ].cc ;
360+ break ;
361+ }
362+ }
363+ if (cc == -1 ) {
364+ goto unknown_op ;
365+ }
366+ const char * os = op_str + 2 ;
367+ while (* os != '\0' ) {
368+ os ++ ;
369+ }
370+ if (os > op_str + 5 ) {
371+ goto unknown_op ;
372+ }
373+ mp_uint_t it_mask = 8 ;
374+ while (-- os >= op_str + 2 ) {
375+ it_mask >>= 1 ;
376+ if (* os == 't' ) {
377+ it_mask |= (cc & 1 ) << 3 ;
378+ } else if (* os == 'e' ) {
379+ it_mask |= ((~cc ) & 1 ) << 3 ;
380+ } else {
381+ goto unknown_op ;
382+ }
383+ }
384+ asm_thumb_it_cc (emit -> as , cc , it_mask );
339385 } else if (strcmp (op_str , "cpsid" ) == 0 ) {
340386 // TODO check pn_args[0] == i
341387 asm_thumb_op16 (emit -> as , ASM_THUMB_OP_CPSID_I );
0 commit comments