8000 fixing inline assembler (emitinlinethumb.c) · mimoccc/circuitpython@6cdf816 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6cdf816

Browse files
committed
fixing inline assembler (emitinlinethumb.c)
1 parent 127d1f5 commit 6cdf816

File tree

1 file changed

+70
-62
lines changed

1 file changed

+70
-62
lines changed

py/emitinlinethumb.c

Lines changed: 70 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -95,18 +95,21 @@ STATIC void emit_inline_thumb_end_pass(emit_inline_asm_t *emit, mp_uint_t type_s
9595
}
9696
}
9797

98-
STATIC mp_uint_t emit_inline_thumb_count_params(emit_inline_asm_t *emit, mp_uint_t n_params, mp_parse_node_t *pn_params) {
99-
if (n_params > 4) {
100-
emit_inline_thumb_error_msg(emit, "can only have up to 4 parameters to Thumb assembly");
101-
return 0;
102-
}
103-
for (mp_uint_t i = 0; i < n_params; i++) {
104-
if (!MP_PARSE_NODE_IS_ID(pn_params[i])) {
98+
STATIC mp_uint_t emit_inline_thumb_count_params(emit_inline_asm_t *emit, const byte *p, const byte *ptop) {
99+
mp_uint_t n_params = 0;
100+
while (p != ptop) {
101+
if (++n_params > 4) {
102+
emit_inline_thumb_error_msg(emit, "can only have up to 4 parameters to Thumb assembly");
103+
return 0;
104+
}
105+
if (!pt_is_any_id(p)) {
105106
emit_inline_thumb_error_msg(emit, "parameters must be registers in sequence r0 to r3");
106107
return 0;
107108
}
108-
const char *p = qstr_str(MP_PARSE_NODE_LEAF_ARG(pn_params[i]));
109-
if (!(strlen(p) == 2 && p[0] == 'r' && p[1] == '0' + i)) {
109+
qstr qst;
110+
p = pt_extract_id(p, &qst);
111+
const char *param = qstr_str(qst);
112+
if (!(strlen(param) == 2 && param[0] == 'r' && param[1] == '0' + n_params - 1)) {
110113
emit_inline_thumb_error_msg(emit, "parameters must be registers in sequence r0 to r3");
111114
return 0;
112115
}
@@ -171,16 +174,17 @@ STATIC const special_reg_name_t special_reg_name_table[] = {
171174

172175
// return empty string in case of error, so we can attempt to parse the string
173176
// without a special check if it was in fact a string
174-
STATIC const char *get_arg_str(mp_parse_node_t pn) {
175-
if (MP_PARSE_NODE_IS_ID(pn)) {
176-
qstr qst = MP_PARSE_NODE_LEAF_ARG(pn);
177+
STATIC const char *get_arg_str(const byte *pn) {
178+
if (pt_is_any_id(pn)) {
179+
qstr qst;
180+
pt_extract_id(pn, &qst);
177181
return qstr_str(qst);
178182
} else {
179183
return "";
180184
}
181185
}
182186

183-
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) {
187+
STATIC mp_uint_t get_arg_reg(emit_inline_asm_t *emit, const char *op, const byte *pn, mp_uint_t max_reg) {
184188
const char *reg_str = get_arg_str(pn);
185189
for (mp_uint_t i = 0; i < MP_ARRAY_SIZE(reg_name_table); i++) {
186190
const reg_name_t *r = &reg_name_table[i];
@@ -204,7 +208,7 @@ STATIC mp_uint_t get_arg_reg(emit_inline_asm_t *emit, const char *op, mp_parse_n
204208
return 0;
205209
}
206210

207-
STATIC mp_uint_t get_arg_special_reg(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn) {
211+
STATIC mp_uint_t get_arg_special_reg(emit_inline_asm_t *emit, const char *op, const byte *pn) {
208212
const char *reg_str = get_arg_str(pn);
209213
for (mp_uint_t i = 0; i < MP_ARRAY_SIZE(special_reg_name_table); i++) {
210214
const special_reg_name_t *r = &special_reg_name_table[i];
@@ -219,7 +223,7 @@ STATIC mp_uint_t get_arg_special_reg(emit_inline_asm_t *emit, const char *op, mp
219223
}
220224

221225
#if MICROPY_EMIT_INLINE_THUMB_FLOAT
222-
STATIC mp_uint_t get_arg_vfpreg(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn) {
226+
STATIC mp_uint_t get_arg_vfpreg(emit_inline_asm_t *emit, const char *op, const byte *pn) {
223227
const char *reg_str = get_arg_str(pn);
224228
if (reg_str[0] == 's' && reg_str[1] != '\0') {
225229
mp_uint_t regno = 0;
@@ -247,43 +251,42 @@ STATIC mp_uint_t get_arg_vfpreg(emit_inline_asm_t *emit, const char *op, mp_pars
247251
}
248252
#endif
249253

250-
STATIC mp_uint_t get_arg_reglist(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn) {
254+
STATIC mp_uint_t get_arg_reglist(emit_inline_asm_t *emit, const char *op, const byte *p) {
251255
// a register list looks like {r0, r1, r2} and is parsed as a Python set
252256

253-
if (!MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_atom_brace)) {
257+
if (!pt_is_rule(p, PN_atom_brace)) {
254258
goto bad_arg;
255259
}
256260

257-
mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn;
258-
assert(MP_PARSE_NODE_STRUCT_NUM_NODES(pns) == 1); // should always be
259-
pn = pns->nodes[0];
261+
const byte *ptop;
262+
p = pt_rule_extract_top(p, &ptop);
260263

261264
mp_uint_t reglist = 0;
262265

263-
if (MP_PARSE_NODE_IS_ID(pn)) {
266+
if (p == ptop) {
267+
goto bad_arg;
268+
} else if (pt_is_any_id(p)) {
264269
// set with one element
265-
reglist |= 1 << get_arg_reg(emit, op, pn, 15);
266-
} else if (MP_PARSE_NODE_IS_STRUCT(pn)) {
267-
pns = (mp_parse_node_struct_t*)pn;
268-
if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_dictorsetmaker) {
269-
assert(MP_PARSE_NODE_IS_STRUCT(pns->nodes[1])); // should succeed
270-
mp_parse_node_struct_t *pns1 = (mp_parse_node_struct_t*)pns->nodes[1];
271-
if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_dictorsetmaker_list) {
272-
// set with multiple elements
273-
274-
// get first element of set (we rely on get_arg_reg to catch syntax errors)
275-
reglist |= 1 << get_arg_reg(emit, op, pns->nodes[0], 15);
276-
277-
// get tail elements (2nd, 3rd, ...)
278-
mp_parse_node_t *nodes;
279-
int n = mp_parse_node_extract_list(&pns1->nodes[0], PN_dictorsetmaker_list2, &nodes);
280-
281-
// process rest of elements
282-
for (int i = 0; i < n; i++) {
283-
reglist |= 1 << get_arg_reg(emit, op, nodes[i], 15);
284-
}
285-
} else {
286-
goto bad_arg;
270+
reglist |= 1 << get_arg_reg(emit, op, p, 15);
271+
} else if (pt_is_rule(p, PN_dictorsetmaker)) {
272+
p = pt_rule_first(p);
273+
const byte *p1 = pt_next(p);
274+
if (pt_is_rule(p1, PN_dictorsetmaker_list)) {
275+
// set with multiple elements
276+
277+
// get first element of set (we rely on get_arg_reg to catch syntax errors)
278+
reglist |= 1 << get_arg_reg(emit, op, p, 15);
279+
280+
// get tail elements (2nd, 3rd, ...)
281+
const byte *p1_top;
282+
p1 = pt_rule_extract_top(p1, &p1_top);
283+
if (p1 != p1_top) {
284+
mp_parse_node_extract_list(&p1, PN_dictorsetmaker_list2);
285+
}
286+
287+
// process rest of elements
288+
for (; p1 != p1_top; p1 = pt_next(p1)) {
289+
reglist |= 1 << get_arg_reg(emit, op, p1, 15);
287290
}
288291
} else {
289292
goto bad_arg;
@@ -299,7 +302,7 @@ STATIC mp_uint_t get_arg_reglist(emit_inline_asm_t *emit, const char *op, mp_par
299302
return 0;
300303
}
301304

302-
STATIC uint32_t get_arg_i(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn, uint32_t fit_mask) {
305+
STATIC uint32_t get_arg_i(emit_inline_asm_t *emit, const char *op, const byte *pn, uint32_t fit_mask) {
303306
mp_obj_t o;
304307
if (!mp_parse_node_get_int_maybe(pn, &o)) {
305308
emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects an integer", op));
@@ -313,34 +316,39 @@ STATIC uint32_t get_arg_i(emit_inline_asm_t *emit, const char *op, mp_parse_node
313316
return i;
314317
}
315318

316-
STATIC bool get_arg_addr(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn, mp_parse_node_t *pn_base, mp_parse_node_t *pn_offset) {
317-
if (!MP_PARSE_NODE_IS_STRUCT_KIND(pn, PN_atom_bracket)) {
319+
STATIC bool get_arg_addr(emit_inline_asm_t *emit, const char *op, const byte *p, const byte **p_base, const byte **p_offset) {
320+
if (!pt_is_rule(p, PN_atom_bracket)) {
321+
goto bad_arg;
322+
}
323+
if (pt_is_rule_empty(p)) {
318324
goto bad_arg;
319325
}
320-
mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn;
321-
if (!MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_testlist_comp)) {
326+
p = pt_rule_first(p);
327+
if (!pt_is_rule(p, PN_testlist_comp)) {
322328
goto bad_arg;
323329
}
324-
pns = (mp_parse_node_struct_t*)pns->nodes[0];
325-
if (MP_PARSE_NODE_STRUCT_NUM_NODES(pns) != 2) {
330+
const byte *ptop;
331+
p = pt_rule_extract_top(p, &ptop);
332+
if (pt_num_nodes(p, ptop) != 2) {
326333
goto bad_arg;
327334
}
328335

329-
*pn_base = pns->nodes[0];
330-
*pn_offset = pns->nodes[1];
336+
*p_base = p;
337+
*p_offset = pt_next(p);
331338
return true;
332339

333340
bad_arg:
334341
emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects an address of the form [a, b]", op));
335342
return false;
336343
}
337344

338-
STATIC int get_arg_label(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn) {
339-
if (!MP_PARSE_NODE_IS_ID(pn)) {
345+
STATIC int get_arg_label(emit_inline_asm_t *emit, const char *op, const byte *p) {
346+
if (!pt_is_any_id(p)) {
340347
emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects a label", op));
341348
return 0;
342349
}
343-
qstr label_qstr = MP_PARSE_NODE_LEAF_ARG(pn);
350+
qstr label_qstr;
351+
pt_extract_id(p, &label_qstr);
344352
for (uint i = 0; i < emit->max_num_labels; i++) {
345353
if (emit->label_lookup[i] == label_qstr) {
346354
return i;
@@ -419,7 +427,7 @@ STATIC const format_vfp_op_t format_vfp_op_table[] = {
419427
// shorthand alias for whether we allow ARMv7-M instructions
420428
#define ARMV7M MICROPY_EMIT_INLINE_THUMB_ARMV7M
421429

422-
STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_args, mp_parse_node_t *pn_args) {
430+
STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_args, const byte **pn_args) {
423431
// TODO perhaps make two tables:
424432
// one_args =
425433
// "b", LAB, asm_thumb_b_n,
@@ -493,7 +501,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
493501
op_code_hi = 0xed90;
494502
op_vldr_vstr:;
495503
mp_uint_t vd = get_arg_vfpreg(emit, op_str, pn_args[0]);
496-
mp_parse_node_t pn_base, pn_offset;
504+
const byte *pn_base, *pn_offset;
497505
if (get_arg_addr(emit, op_str, pn_args[1], &pn_base, &pn_offset)) {
498506
mp_uint_t rlo_base = get_arg_reg(emit, op_str, pn_base, 7);
499507
mp_uint_t i8;
@@ -632,7 +640,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
632640
}
633641

634642
} else if (n_args == 2) {
635-
if (MP_PARSE_NODE_IS_ID(pn_args[1])) {
643+
if (pt_is_any_id(pn_args[1])) {
636644
// second arg is a register (or should be)
637645
mp_uint_t op_code, op_code_hi;
638646
if (op == MP_QSTR_mov) {
@@ -711,7 +719,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
711719
asm_thumb_mov_reg_i16(emit->as, ASM_THUMB_OP_MOVT, reg_dest, (i_src >> 16) & 0xffff);
712720
} else if (ARMV7M && op == MP_QSTR_ldrex) {
713721
mp_uint_t r_dest = get_arg_reg(emit, op_str, pn_args[0], 15);
714-
mp_parse_node_t pn_base, pn_offset;
722+
const byte *pn_base, *pn_offset;
715723
if (get_arg_addr(emit, op_str, pn_args[1], &pn_base, &pn_offset)) {
716724
mp_uint_t r_base = get_arg_reg(emit, op_str, pn_base, 15);
717725
mp_uint_t i8 = get_arg_i(emit, op_str, pn_offset, 0xff) >> 2;
@@ -722,7 +730,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
722730
for (mp_uint_t i = 0; i < MP_ARRAY_SIZE(format_9_10_op_table); i++) {
723731
if (op == format_9_10_op_table[i].name) {
724732
op_code = format_9_10_op_table[i].op;
725-
mp_parse_node_t pn_base, pn_offset;
733+
const byte *pn_base, *pn_offset;
726734
mp_uint_t rlo_dest = get_arg_reg(emit, op_str, pn_args[0], 7);
727735
if (get_arg_addr(emit, op_str, pn_args[1], &pn_base, &pn_offset)) {
728736
mp_uint_t rlo_base = get_arg_reg(emit, op_str, pn_base, 7);
@@ -767,7 +775,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
767775
rlo_dest = get_arg_reg(emit, op_str, pn_args[0], 7);
768776
rlo_src = get_arg_reg(emit, op_str, pn_args[1], 7);
769777
int src_b;
770-
if (MP_PARSE_NODE_IS_ID(pn_args[2])) {
778+
if (pt_is_any_id(pn_args[2])) {
771779
op_code |= ASM_THUMB_FORMAT_2_REG_OPERAND;
772780
src_b = get_arg_reg(emit, op_str, pn_args[2], 7);
773781
} else {
@@ -792,7 +800,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a
792800
} else if (ARMV7M && op == MP_QSTR_strex) {
793801
mp_uint_t r_dest = get_arg_reg(emit, op_str, pn_args[0], 15);
794802
mp_uint_t r_src = get_arg_reg(emit, op_str, pn_args[1], 15);
795-
mp_parse_node_t pn_base, pn_offset;
803+
const byte *pn_base, *pn_offset;
796804
if (get_arg_addr(emit, op_str, pn_args[2], &pn_base, &pn_offset)) {
797805
mp_uint_t r_base = get_arg_reg(emit, op_str, pn_base, 15);
798806
mp_uint_t i8 = get_arg_i(emit, op_str, pn_offset, 0xff) >> 2;

0 commit comments

Comments
 (0)
0