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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy