8000 fixing inline assembler (compile2.c) · lapsule/micropython@127d1f5 · GitHub
[go: up one dir, main page]

Skip to content

Commit 127d1f5

Browse files
committed
fixing inline assembler (compile2.c)
1 parent 61398ab commit 127d1f5

File tree

1 file changed

+60
-46
lines changed

1 file changed

+60
-46
lines changed

py/compile2.c

Lines changed: 60 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2932,7 +2932,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
29322932
comp->next_label = 1;
29332933

29342934
if (scope->kind != SCOPE_FUNCTION) {
2935-
compile_syntax_error(comp, MP_PARSE_NODE_NULL, "inline assembler must be a function");
2935+
compile_syntax_error(comp, NULL, "inline assembler must be a function");
29362936
return;
29372937
}
29382938

@@ -2941,109 +2941,123 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
29412941
}
29422942

29432943
// get the function definition parse node
2944-
assert(MP_PARSE_NODE_IS_STRUCT(scope->pn));
2945-
mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)scope->pn;
2946-
assert(MP_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
2944+
const byte *p = scope->pn;
2945+
assert(pt_is_any_id(p));
2946+
p = pt_next(p); // skip the function name
29472947

2948-
//qstr f_id = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); // function name
2949-
2950-
// parameters are in pns->nodes[1]
2948+
// parameters are in next node
29512949
if (comp->pass == MP_PASS_CODE_SIZE) {
2952-
mp_parse_node_t *pn_params;
2953-
int n_params = mp_parse_node_extract_list(&pns->nodes[1], PN_typedargslist, &pn_params);
2954-
scope->num_pos_args = EMIT_INLINE_ASM_ARG(count_params, n_params, pn_params);
2950+
const byte *pp = p;
2951+
const byte *pptop = mp_parse_node_extract_list(&pp, PN_typedargslist);
2952+
scope->num_pos_args = EMIT_INLINE_ASM_ARG(count_params, pp, pptop);
29552953
if (comp->compile_error != MP_OBJ_NULL) {
29562954
goto inline_asm_error;
29572955
}
29582956
}
29592957

2960-
assert(MP_PARSE_NODE_IS_NULL(pns->nodes[2])); // type
2958+
p = pt_next(p); // skip the parameter list
2959+
p = pt_next(p); // skip the return type
29612960

2962-
mp_parse_node_t pn_body = pns->nodes[3]; // body
2963-
mp_parse_node_t *nodes;
2964-
int num = mp_parse_node_extract_list(&pn_body, PN_suite_block_stmts, &nodes);
2961+
// get the list of statements within the body of the function
2962+
const byte *ptop = mp_parse_node_extract_list(&p, PN_suite_block_stmts);
29652963

2966-
for (int i = 0; i < num; i++) {
2967-
assert(MP_PARSE_NODE_IS_STRUCT(nodes[i]));
2968-
mp_parse_node_struct_t *pns2 = (mp_parse_node_struct_t*)nodes[i];
2969-
if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_pass_stmt) {
2964+
for (const byte *p_instr = p; p_instr != ptop; p_instr = pt_next(p_instr)) {
2965+
p = p_instr;
2966+
if (pt_is_rule(p, PN_pass_stmt)) {
29702967
// no instructions
29712968
continue;
2972-
} else if (MP_PARSE_NODE_STRUCT_KIND(pns2) != PN_expr_stmt) {
2969+
} else if (!pt_is_rule(p, PN_expr_stmt)) {
29732970
// not an instruction; error
29742971
not_an_instruction:
2975-
EDBE compile_syntax_error(comp, nodes[i], "expecting an assembler instruction");
2972+
compile_syntax_error(comp, p, "expecting an assembler instruction");
29762973
return;
29772974
}
29782975

29792976
// check structure of parse node
2980-
assert(MP_PARSE_NODE_IS_STRUCT(pns2->nodes[0]));
2981-
if (!MP_PARSE_NODE_IS_NULL(pns2->nodes[1])) {
2977+
const byte *p_expr_top;
2978+
const byte *p_expr = pt_rule_extract_top(p, &p_expr_top);
2979+
if (!pt_is_rule(p_expr, PN_power)) {
2980+
goto not_an_instruction;
2981+
}
2982+
if (pt_next(p_expr) != p_expr_top) {
29822983
goto not_an_instruction;
29832984
}
2984-
pns2 = (mp_parse_node_struct_t*)pns2->nodes[0];
2985-
if (MP_PARSE_NODE_STRUCT_KIND(pns2) != PN_power) {
2985+
p_expr = pt_rule_extract_top(p_expr, &p_expr_top);
2986+
if (!pt_is_any_id(p_expr)) {
29862987
goto not_an_instruction;
29872988
}
2988-
if (!MP_PARSE_NODE_IS_ID(pns2->nodes[0])) {
2989+
const byte *p_expr_paren = pt_next(p_expr);
2990+
if (p_expr_paren == p_expr_top || !pt_is_rule(p_expr_paren, PN_trailer_paren)) {
29892991
goto not_an_instruction;
29902992
}
2991-
if (!MP_PARSE_NODE_IS_STRUCT_KIND(pns2->nodes[1], PN_trailer_paren)) {
2993+
if (pt_next(p_expr_paren) != p_expr_top) {
29922994
goto not_an_instruction;
29932995
}
2994-
assert(MP_PARSE_NODE_IS_NULL(pns2->nodes[2]));
29952996

29962997
// parse node looks like an instruction
29972998
// get instruction name and args
2998-
qstr op = MP_PARSE_NODE_LEAF_ARG(pns2->nodes[0]);
2999-
pns2 = (mp_parse_node_struct_t*)pns2->nodes[1]; // PN_trailer_paren
3000-
mp_parse_node_t *pn_arg;
3001-
int n_args = mp_parse_node_extract_list(&pns2->nodes[0], PN_arglist, &pn_arg);
2999+
qstr op;
3000+
pt_extract_id(p_expr, &op);
3001+
3002+
const byte *p_args = pt_rule_first(p_expr_paren);
3003+
const byte *p_args_top = mp_parse_node_extract_list(&p_args, PN_arglist);
3004+
uint n_args = pt_num_nodes(p_args, p_args_top);
30023005

30033006
// emit instructions
30043007
if (op == MP_QSTR_label) {
3005-
if (!(n_args == 1 && MP_PARSE_NODE_IS_ID(pn_arg[0]))) {
3006-
compile_syntax_error(comp, nodes[i], "'label' requires 1 argument");
3008+
if (!(n_args == 1 && pt_is_any_id(p_args))) {
3009+
compile_syntax_error(comp, p, "'label' requires 1 argument");
30073010
return;
30083011
}
30093012
uint lab = comp_next_label(comp);
30103013
if (pass > MP_PASS_SCOPE) {
3011-
if (!EMIT_INLINE_ASM_ARG(label, lab, MP_PARSE_NODE_LEAF_ARG(pn_arg[0]))) {
3012-
compile_syntax_error(comp, nodes[i], "label redefined");
3014+
qstr id;
3015+
pt_extract_id(p_args, &id);
3016+
if (!EMIT_INLINE_ASM_ARG(label, lab, id)) {
3017+
compile_syntax_error(comp, p, "label redefined");
30133018
return;
30143019
}
30153020
}
30163021
} else if (op == MP_QSTR_align) {
3017-
if (!(n_args == 1 && MP_PARSE_NODE_IS_SMALL_INT(pn_arg[0]))) {
3018-
compile_syntax_error(comp, nodes[i], "'align' requires 1 argument");
3022+
if (!(n_args == 1 && pt_is_small_int(p_args))) {
3023+
compile_syntax_error(comp, p, "'align' requires 1 argument");
30193024
return;
30203025
}
30213026
if (pass > MP_PASS_SCOPE) {
3022-
EMIT_INLINE_ASM_ARG(align, MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[0]));
3027+
EMIT_INLINE_ASM_ARG(align, pt_small_int_value(p_args));
30233028
}
30243029
} else if (op == MP_QSTR_data) {
3025-
if (!(n_args >= 2 && MP_PARSE_NODE_IS_SMALL_INT(pn_arg[0]))) {
3026-
compile_syntax_error(comp, nodes[i], "'data' requires at least 2 arguments");
3030+
if (!(n_args >= 2 && pt_is_small_int(p_args))) {
3031+
compile_syntax_error(comp, p, "'data' requires at least 2 arguments");
30273032
return;
30283033
}
30293034
if (pass > MP_PASS_SCOPE) {
3030-
mp_int_t bytesize = MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[0]);
3035+
mp_int_t bytesize;
3036+
p_args = pt_get_small_int(p_args, &bytesize);
30313037
for (uint j = 1; j < n_args; j++) {
3032-
if (!MP_PARSE_NODE_IS_SMALL_INT(pn_arg[j])) {
3033-
compile_syntax_error(comp, nodes[i], "'data' requires integer arguments");
3038+
if (!pt_is_small_int(p_args)) {
3039+
compile_syntax_error(comp, p, "'data' requires integer arguments");
30343040
return;
30353041
}
3036-
EMIT_INLINE_ASM_ARG(data, bytesize, MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[j]));
3042+
mp_int_t val;
3043+
p_args = pt_get_small_int(p_args, &val);
3044+
EMIT_INLINE_ASM_ARG(data, bytesize, val);
30373045
}
30383046
}
30393047
} else {
30403048
if (pass > MP_PASS_SCOPE) {
3049+
if (n_args > 3) {
3050+
goto not_an_instruction;
3051+
}
3052+
const byte *pn_arg[3];
3053+
pn_arg[0] = p_args;
3054+
pn_arg[1] = pt_next(pn_arg[0]);
3055+
pn_arg[2] = pt_next(pn_arg[1]);
30413056
EMIT_INLINE_ASM_ARG(op, op, n_args, pn_arg);
30423057
}
30433058
}
30443059

30453060
if (comp->compile_error != MP_OBJ_NULL) {
3046-
pns = pns2; // this is the parse node that had the error
30473061
goto inline_asm_error;
30483062
}
30493063
}
@@ -3055,7 +3069,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
30553069
if (comp->compile_error != MP_OBJ_NULL) {
30563070
// inline assembler had an error; set line for its exception
30573071
inline_asm_error:
3058-
comp->compile_error_line = pns->source_line;
3072+
compile_error_set_line(comp, p);
30593073
}
30603074
}
30613075
#endif

0 commit comments

Comments
 (0)
0