@@ -50,6 +50,25 @@ static void emit_inline_thumb_end_pass(emit_inline_asm_t *emit) {
5050 }
5151}
5252
53+ static int emit_inline_thumb_count_params (emit_inline_asm_t * emit , int n_params , py_parse_node_t * pn_params ) {
54+ if (n_params > 4 ) {
55+ printf ("SyntaxError: can only have up to 3 parameters to inline assembler\n" );
56+ return 0 ;
57+ }
58+ for (int i = 0 ; i < n_params ; i ++ ) {
59+ if (!PY_PARSE_NODE_IS_ID (pn_params [i ])) {
60+ printf ("SyntaxError: parameter to inline assembler must be an identifier %d\n" , PY_PARSE_NODE_STRUCT_KIND ((py_parse_node_struct_t * )pn_params [i ]));
61+ return 0 ;
62+ }
63+ const char * p = qstr_str (PY_PARSE_NODE_LEAF_ARG (pn_params [i ]));
64+ if (!(strlen (p ) == 2 && p [0 ] == 'r' && p [1 ] == '0' + i )) {
65+ printf ("SyntaxError: parameter %d to inline assembler must be r%d\n" , i , i );
66+ return 0 ;
67+ }
68+ }
69+ return n_params ;
70+ }
71+
5372static void emit_inline_thumb_label (emit_inline_asm_t * emit , int label_num , qstr label_id ) {
5473 assert (label_num < emit -> max_num_labels );
5574 emit -> label_lookup [label_num ] = label_id ;
@@ -65,12 +84,12 @@ static bool check_n_arg(qstr op, int n_args, int wanted_n_args) {
6584 }
6685}
6786
68- static uint get_arg_rlo (qstr op , py_parse_node_t * pn_arg , int wanted_arg_num ) {
69- if (!PY_PARSE_NODE_IS_ID (pn_arg [wanted_arg_num ])) {
87+ static uint get_arg_rlo (qstr op , py_parse_node_t * pn_args , int wanted_arg_num ) {
88+ if (!PY_PARSE_NODE_IS_ID (pn_args [wanted_arg_num ])) {
7089 printf ("SyntaxError: '%s' expects a register in position %d\n" , qstr_str (op ), wanted_arg_num );
7190 return 0 ;
7291 }
73- qstr reg_qstr = PY_PARSE_NODE_LEAF_ARG (pn_arg [wanted_arg_num ]);
92+ qstr reg_qstr = PY_PARSE_NODE_LEAF_ARG (pn_args [wanted_arg_num ]);
7493 const char * reg_str = qstr_str (reg_qstr );
7594 if (!(strlen (reg_str ) == 2 && reg_str [0 ] == 'r' && ('0' <= reg_str [1 ] && reg_str [1 ] <= '7' ))) {
7695 printf ("SyntaxError: '%s' expects a register in position %d\n" , qstr_str (op ), wanted_arg_num );
@@ -79,25 +98,25 @@ static uint get_arg_rlo(qstr op, py_parse_node_t *pn_arg, int wanted_arg_num) {
7998 return reg_str [1 ] - '0' ;
8099}
81100
82- static int get_arg_i (qstr op , py_parse_node_t * pn_arg , int wanted_arg_num , int fit_mask ) {
83- if (!PY_PARSE_NODE_IS_SMALL_INT (pn_arg [wanted_arg_num ])) {
101+ static int get_arg_i (qstr op , py_parse_node_t * pn_args , int wanted_arg_num , int fit_mask ) {
102+ if (!PY_PARSE_NODE_IS_SMALL_INT (pn_args [wanted_arg_num ])) {
84103 printf ("SyntaxError: '%s' expects an integer in position %d\n" , qstr_str (op ), wanted_arg_num );
85104 return 0 ;
86105 }
87- int i = PY_PARSE_NODE_LEAF_ARG (pn_arg [wanted_arg_num ]);
106+ int i = PY_PARSE_NODE_LEAF_ARG (pn_args [wanted_arg_num ]);
88107 if ((i & (~fit_mask )) != 0 ) {
89108 printf ("SyntaxError: '%s' integer 0x%x does not fit in mask 0x%x\n" , qstr_str (op ), i , fit_mask );
90109 return 0 ;
91110 }
92111 return i ;
93112}
94113
95- static int get_arg_label (emit_inline_asm_t * emit , qstr op , py_parse_node_t * pn_arg , int wanted_arg_num ) {
96- if (!PY_PARSE_NODE_IS_ID (pn_arg [wanted_arg_num ])) {
114+ static int get_arg_label (emit_inline_asm_t * emit , qstr op , py_parse_node_t * pn_args , int wanted_arg_num ) {
115+ if (!PY_PARSE_NODE_IS_ID (pn_args [wanted_arg_num ])) {
97116 printf ("SyntaxError: '%s' expects a label in position %d\n" , qstr_str (op ), wanted_arg_num );
98117 return 0 ;
99118 }
100- qstr label_qstr = PY_PARSE_NODE_LEAF_ARG (pn_arg [wanted_arg_num ]);
119+ qstr label_qstr = PY_PARSE_NODE_LEAF_ARG (pn_args [wanted_arg_num ]);
101120 for (int i = 0 ; i < emit -> max_num_labels ; i ++ ) {
102121 if (emit -> label_lookup [i ] == label_qstr ) {
103122 return i ;
@@ -107,7 +126,7 @@ static int get_arg_label(emit_inline_asm_t *emit, qstr op, py_parse_node_t *pn_a
107126 return 0 ;
108127}
109128
110- static void emit_inline_thumb_op (emit_inline_asm_t * emit , qstr op , int n_args , py_parse_node_t * pn_arg ) {
129+ static void emit_inline_thumb_op (emit_inline_asm_t * emit , qstr op , int n_args , py_parse_node_t * pn_args ) {
111130 // TODO perhaps make two tables:
112131 // two_args =
113132 // "movs", RLO, I8, asm_thumb_movs_reg_i8
@@ -120,40 +139,41 @@ static void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, int n_args, p
120139 if (!check_n_arg (op , n_args , 1 )) {
121140 return ;
122141 }
123- int label_num = get_arg_label (emit , op , pn_arg , 0 );
142+ int label_num = get_arg_label (emit , op , pn_args , 0 );
143+ // TODO check that this succeeded, ie branch was within range
124144 asm_thumb_bgt_n (emit -> as , label_num );
125145
126146 // 2 args
127147 } else if (strcmp (qstr_str (op ), "movs" ) == 0 ) {
128148 if (!check_n_arg (op , n_args , 2 )) {
129149 return ;
130150 }
131- uint rlo_dest = get_arg_rlo (op , pn_arg , 0 );
132- int i_src = get_arg_i (op , pn_arg , 1 , 0xff );
151+ uint rlo_dest = get_arg_rlo (op , pn_args , 0 );
152+ int i_src = get_arg_i (op , pn_args , 1 , 0xff );
133153 asm_thumb_movs_rlo_i8 (emit -> as , rlo_dest , i_src );
134154 } else if (strcmp (qstr_str (op ), "movw" ) == 0 ) {
135155 if (!check_n_arg (op , n_args , 2 )) {
136156 return ;
137157 }
138- uint rlo_dest = get_arg_rlo (op , pn_arg , 0 ); // TODO can be reg lo or hi
139- int i_src = get_arg_i (op , pn_arg , 1 , 0xffff );
158+ uint rlo_dest = get_arg_rlo (op , pn_args , 0 ); // TODO can be reg lo or hi
159+ int i_src = get_arg_i (op , pn_args , 1 , 0xffff );
140160 asm_thumb_movw_reg_i16 (emit -> as , rlo_dest , i_src );
141161 } else if (strcmp (qstr_str (op ), "cmp" ) == 0 ) {
142162 if (!check_n_arg (op , n_args , 2 )) {
143163 return ;
144164 }
145- uint rlo = get_arg_rlo (op , pn_arg , 0 );
146- int i8 = get_arg_i (op , pn_arg , 1 , 0xff );
165+ uint rlo = get_arg_rlo (op , pn_args , 0 );
166+ int i8 = get_arg_i (op , pn_args , 1 , 0xff );
147167 asm_thumb_cmp_rlo_i8 (emit -> as , rlo , i8 );
148168
149169 // 3 args
150170 } else if (strcmp (qstr_str (op ), "subs" ) == 0 ) {
151171 if (!check_n_arg (op , n_args , 3 )) {
152172 return ;
153173 }
154- uint rlo_dest = get_arg_rlo (op , pn_arg , 0 );
155- uint rlo_src = get_arg_rlo (op , pn_arg , 1 );
156- int i3_src = get_arg_i (op , pn_arg , 2 , 0x7 );
174+ uint rlo_dest = get_arg_rlo (op , pn_args , 0 );
175+ uint rlo_src = get_arg_rlo (op , pn_args , 1 );
176+ int i3_src = get_arg_i (op , pn_args , 2 , 0x7 );
157177 asm_thumb_subs_rlo_rlo_i3 (emit -> as , rlo_dest , rlo_src , i3_src );
158178
159179 // unknown op
@@ -166,6 +186,7 @@ static void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, int n_args, p
166186const emit_inline_asm_method_table_t emit_inline_thumb_method_table = {
167187 emit_inline_thumb_start_pass ,
168188 emit_inline_thumb_end_pass ,
189+ emit_inline_thumb_count_params ,
169190 emit_inline_thumb_label ,
170191 emit_inline_thumb_op ,
171192};
0 commit comments