10BC0 py/emitinlinerv32: Refactor load/store opcodes validation. · micropython/micropython@385e4f3 · GitHub
[go: up one dir, main page]

Skip to content

Commit 385e4f3

Browse files
agattidpgeorge
authored andcommitted
py/emitinlinerv32: Refactor load/store opcodes validation.
This commit minimises the amount of code required to perform validation of load/store opcodes, streamlining their validation and serialisation. Load/store opcodes used to be handled as a special case due to how its peculiar syntax yields parse node arguments that cannot be handled by the regular validation and serialisation functions. The changes in this commit attempt to reduce the amount of special code needed for those opcodes to its bare minimum, by removing the special opcode handling step, merging the validation and serialisation pass for the combined offset + base register operand, and integrate said changes in the existing argument handling structure. That allowed to rework the special operand parsing function to make it smaller, and remove the code that performed the special case validation and emitted the opcode. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
1 parent 3da5295 commit 385e4f3

File tree

1 file changed

+52
-88
lines changed

1 file changed

+52
-88
lines changed

py/emitinlinerv32.c

Lines changed: 52 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ typedef struct _opcode_t {
223223
uint16_t argument1_mask : 4;
224224
uint16_t argument2_mask : 4;
225225
uint16_t argument3_mask : 4;
226-
uint16_t arguments_count : 2;
226+
uint16_t parse_nodes : 2;
227227
// 2 bits available here
228228
uint32_t calling_convention : 4;
229229
uint32_t argument1_kind : 4;
@@ -327,7 +327,7 @@ static const opcode_t OPCODES[] = {
327327
{ MP_QSTR_c_jr, MASK_FFFFFFFE, MASK_NOT_USED, MASK_NOT_USED, 1, CALL_R, R, 0, N, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cjr },
328328
{ MP_QSTR_c_li, MASK_FFFFFFFE, MASK_0000003F, MASK_NOT_USED, 2, CALL_RI, R, 0, I, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cli },
329329
{ MP_QSTR_c_lui, MASK_FFFFFFFA, MASK_0001F800, MASK_NOT_USED, 2, CALL_RI, R, 0, IUZ, 12, N, 0, RV32_EXT_NONE, asm_rv32_opcode_clui },
330-
{ MP_QSTR_c_lw, MASK_0000FF00, MASK_0000007C, MASK_0000FF00, 3, CALL_RIR, RC, 0, I, 0, RC, 0, RV32_EXT_NONE, asm_rv32_opcode_clw },
330+
{ MP_QSTR_c_lw, MASK_0000FF00, MASK_0000007C, MASK_0000FF00, 2, CALL_RIR, RC, 0, I, 0, RC, 0, RV32_EXT_NONE, asm_rv32_opcode_clw },
331331
{ MP_QSTR_c_lwsp, MASK_FFFFFFFE, MASK_000000FC, MASK_NOT_USED, 2, CALL_RI C02E , R, 0, I, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_clwsp },
332332
{ MP_QSTR_c_mv, MASK_FFFFFFFE, MASK_FFFFFFFE, MASK_NOT_USED, 2, CALL_RR, R, 0, R, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cmv },
333333
{ MP_QSTR_c_nop, MASK_NOT_USED, MASK_NOT_USED, MASK_NOT_USED, 0, CALL_N, N, 0, N, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cnop },
@@ -336,7 +336,7 @@ static const opcode_t OPCODES[] = {
336336
{ MP_QSTR_c_srai, MASK_0000FF00, MASK_0000001F, MASK_NOT_USED, 2, CALL_RI, RC, 0, IU, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_csrai },
337337
{ MP_QSTR_c_srli, MASK_0000FF00, MASK_0000001F, MASK_NOT_USED, 2, CALL_RI, RC, 0, IU, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_csrli },
338338
{ MP_QSTR_c_sub, MASK_0000FF00, MASK_0000FF00, MASK_NOT_USED, 2, CALL_RR, RC, 0, RC, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_csub },
339-
{ MP_QSTR_c_sw, MASK_0000FF00, MASK_0000007C, MASK_0000FF00, 3, CALL_RIR, RC, 0, I, 0, RC, 0, RV32_EXT_NONE, asm_rv32_opcode_csw },
339+
{ MP_QSTR_c_sw, MASK_0000FF00, MASK_0000007C, MASK_0000FF00, 2, CALL_RIR, RC, 0, I, 0, RC, 0, RV32_EXT_NONE, asm_rv32_opcode_csw },
340340
{ MP_QSTR_c_swsp, MASK_FFFFFFFF, MASK_000000FC, MASK_NOT_USED, 2, CALL_RI, R, 0, I, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cswsp },
341341
{ MP_QSTR_c_xor, MASK_0000FF00, MASK_0000FF00, MASK_NOT_USED, 2, CALL_RR, RC, 0, RC, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cxor },
342342
{ MP_QSTR_div, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_div },
@@ -346,13 +346,13 @@ static const opcode_t OPCODES[] = {
346346
{ MP_QSTR_jal, MASK_FFFFFFFF, MASK_001FFFFE, MASK_NOT_USED, 2, CALL_RL, R, 0, L, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_jal },
347347
{ MP_QSTR_jalr, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_00000FFF, 3, CALL_RRI, R, 0, R, 0, I, 0, RV32_EXT_NONE, asm_rv32_opcode_jalr },
348348
{ MP_QSTR_la, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_NOT_USED, 2, CALL_RL, R, 0, L, 0, N, 0, RV32_EXT_NONE, opcode_la },
349-
{ MP_QSTR_lb, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 3, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_lb },
350-
{ MP_QSTR_lbu, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 3, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_lbu },
351-
{ MP_QSTR_lh, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 3, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_lh },
352-
{ MP_QSTR_lhu, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 3, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_lhu },
349+
{ MP_QSTR_lb, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 2, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_lb },
350+
{ MP_QSTR_lbu, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 2, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_lbu },
351+
{ MP_QSTR_lh, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 2, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_lh },
352+
{ MP_QSTR_lhu, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 2, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_lhu },
353353
{ MP_QSTR_li, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_NOT_USED, 2, CALL_RI, R, 0, I, 0, N, 0, RV32_EXT_NONE, opcode_li },
354354
{ MP_QSTR_lui, MASK_FFFFFFFF, MASK_FFFFF000, MASK_NOT_USED, 2, CALL_RI, R, 0, I, 12, N, 0, RV32_EXT_NONE, asm_rv32_opcode_lui },
355-
{ MP_QSTR_lw, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 3, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_lw },
355+
{ MP_QSTR_lw, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 2, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_lw },
356356
{ MP_QSTR_mv, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_NOT_USED, 2, CALL_RR, R, 0, R, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cmv },
357357
{ MP_QSTR_mul, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_mul },
358358
{ MP_QSTR_mulh, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_mulh },
@@ -362,8 +362,8 @@ static const opcode_t OPCODES[] = {
362362
{ MP_QSTR_ori, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_00000FFF, 3, CALL_RRI, R, 0, R, 0, I, 0, RV32_EXT_NONE, asm_rv32_opcode_ori },
363363
{ MP_QSTR_rem, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_rem },
364364
{ MP_QSTR_remu, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_remu },
365-
{ MP_QSTR_sb, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 3, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_sb },
366-
{ MP_QSTR_sh, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 3, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_sh },
365+
{ MP_QSTR_sb, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 2, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_sb },
366+
{ MP_QSTR_sh, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 2, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_sh },
367367
{ MP_QSTR_sh1add, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_ZBA, asm_rv32_opcode_sh1add },
368368
{ MP_QSTR_sh2add, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_ZBA, asm_rv32_opcode_sh2add },
369369
{ MP_QSTR_sh3add, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_ZBA, asm_rv32_opcode_sh3add },
@@ -378,7 +378,7 @@ static const opcode_t OPCODES[] = {
378378
{ MP_QSTR_srl, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_srl },
379379
{ MP_QSTR_srli, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_0000001F, 3, CALL_RRI, R, 0, R, 0, IU, 0, RV32_EXT_NONE, asm_rv32_opcode_srli },
380380
{ MP_QSTR_sub, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_sub },
381-
{ MP_QSTR_sw, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 3, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_sw },
381+
{ MP_QSTR_sw, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 2, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_sw },
382382
{ MP_QSTR_xor, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_xor },
383383
{ MP_QSTR_xori, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_00000FFF, 3, CALL_RRI, R, 0, R, 0, I, 0, RV32_EXT_NONE, asm_rv32_opcode_xori },
384384
};
@@ -439,6 +439,7 @@ static bool validate_integer(mp_uint_t value, mp_uint_t mask, mp_uint_t flags) {
439439

440440
static bool serialise_argument(emit_inline_asm_t *emit, const opcode_t *opcode, mp_parse_node_t node, mp_uint_t node_index, mp_uint_t *serialised) {
441441
assert((node_index < 3) && "Invalid argument node number.");
442+
assert(serialised && "Serialised value pointer is NULL.");
442443

443444
uint32_t kind = 0;
444445
uint32_t shift = 0;
@@ -562,10 +563,7 @@ static bool serialise_argument(emit_inline_asm_t *emit, const opcode_t *opcode,
562563
break;
563564
}
564565

565-
if (serialised != NULL) {
566-
*serialised = serialised_value;
567-
}
568-
566+
*serialised = serialised_value;
569567
return true;
570568

571569
out_of_range:
@@ -581,19 +579,18 @@ static bool serialise_argument(emit_inline_asm_t *emit, const opcode_t *opcode,
581579
return false;
582580
}
583581

584-
static bool parse_register_offset_node(emit_inline_asm_t *emit, qstr opcode_qstr, const opcode_t *opcode_data, mp_parse_node_t node, mp_uint_t node_index, mp_parse_node_t *register_node, mp_parse_node_t *offset_node, bool *negative) {
585-
assert(register_node != NULL && "Register node pointer is NULL.");
586-
assert(offset_node != NULL && "Offset node pointer is NULL.");
587-
assert(negative != NULL && "Negative pointer is NULL.");
582+
static bool serialise_register_offset_node(emit_inline_asm_t *emit, const opcode_t *opcode_data, mp_parse_node_t node, mp_uint_t node_index, mp_uint_t *offset, mp_uint_t *base) {
583+
assert(offset && "Attempting to store the offset value into NULL.");
584+
assert(base && "Attempting to store the base register into NULL.");
588585

589586
if (!MP_PARSE_NODE_IS_STRUCT_KIND(node, PN_atom_expr_normal) && !MP_PARSE_NODE_IS_STRUCT_KIND(node, PN_factor_2)) {
590587
goto invalid_structure;
591588
}
592589
mp_parse_node_struct_t *node_struct = (mp_parse_node_struct_t *)node;
593-
*negative = false;
590+
bool negative = false;
594591
if (MP_PARSE_NODE_IS_STRUCT_KIND(node, PN_factor_2)) {
595592
if (MP_PARSE_NODE_IS_TOKEN_KIND(node_struct->nodes[0], MP_TOKEN_OP_MINUS)) {
596-
*negative = true;
593+
negative = true;
597594
} else {
598595
if (!MP_PARSE_NODE_IS_TOKEN_KIND(node_struct->nodes[0], MP_TOKEN_OP_PLUS)) {
599596
goto invalid_structure;
@@ -605,41 +602,40 @@ static bool parse_register_offset_node(emit_inline_asm_t *emit, qstr opcode_qstr
605602
node_struct = (mp_parse_node_struct_t *)node_struct->nodes[1];
606603
}
607604

608-
if (*negative) {
605+
if (negative) {
609606
// If the value is negative, RULE_atom_expr_normal's first token will be the
610607
// offset stripped of its negative marker; range check will then fail if the
611608
// default method is used, so a custom check is used instead.
612609
mp_obj_t object;
613610
if (!mp_parse_node_get_int_maybe(node_struct->nodes[0], &object)) {
614611
emit_inline_rv32_error_exc(emit,
615-
mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, ET_WRONG_ARGUMENT_KIND, opcode_qstr, 2, MP_QSTR_integer));
612+
mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, ET_WRONG_ARGUMENT_KIND, opcode_data->qstring, 2, MP_QSTR_integer));
616613
return false;
617614
}
618615
mp_uint_t value = mp_obj_get_int_truncated(object);
619616
value = (~value + 1) & (mp_uint_t)-1;
620617
if (!validate_integer(value << opcode_data->argument2_shift, OPCODE_MASKS[opcode_data->argument2_mask], opcode_data->argument2_kind)) {
621618
emit_inline_rv32_error_exc(emit,
622-
mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, ET_OUT_OF_RANGE, opcode_qstr, 2));
619+
mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, ET_OUT_OF_RANGE, opcode_data->qstring, 2));
623620
return false;
624621
}
622+
*offset = value;
625623
} else {
626-
if (!serialise_argument(emit, opcode_data, node_struct->nodes[0], 1, NULL)) {
624+
if (!serialise_argument(emit, opcode_data, node_struct->nodes[0], 1, offset)) {
627625
return false;
628626
}
629627
}
630628

631-
*offset_node = node_struct->nodes[0];
632629
node_struct = (mp_parse_node_struct_t *)node_struct->nodes[1];
633-
if (!serialise_argument(emit, opcode_data, node_struct->nodes[0], 2, NULL)) {
630+
if (!serialise_argument(emit, opcode_data, node_struct->nodes[0], 2, base)) {
634631
return false;
635632
}
636-
*register_node = node_struct->nodes[0];
637633
return true;
638634

639635
invalid_structure:
640636
emit_inline_rv32_error_exc(emit,
641637
mp_obj_new_exception_msg_varg(&mp_type_SyntaxError,
642-
ET_WRONG_ARGUMENT_KIND, opcode_qstr, node_index + 1, MP_QSTR_offset));
638+
ET_WRONG_ARGUMENT_KIND, opcode_data->qstring, node_index + 1, MP_QSTR_offset));
643639
return false;
644640
}
645641

@@ -685,49 +681,18 @@ static void handle_opcode(emit_inline_asm_t *emit, const opcode_t *opcode_data,
685681
((call_rii_t)opcode_data->emitter)(&emit->as, arguments[0], arguments[1], arguments[2]);
686682
break;
687683

684+
case CALL_RIR:
685+
// The last two arguments indices are swapped on purpose.
686+
((call_rri_t)opcode_data->emitter)(&emit->as, arguments[0], arguments[2], arguments[1]);
687+
break;
688+
688689
default:
689690
assert(!"Unhandled call convention.");
690691
MP_UNREACHABLE;
691692
break;
692693
}
693694
}
694695

695-
static bool handle_load_store_opcode_with_offset(emit_inline_asm_t *emit, qstr opcode, const opcode_t *opcode_data, mp_parse_node_t *argument_nodes) {
696-
mp_parse_node_t nodes[3] = {0};
697-
if (!serialise_argument(emit, opcode_data, argument_nodes[0], 0, NULL)) {
698-
return false;
699-
}
700-
nodes[0] = argument_nodes[0];
701-
bool negative = false;
702-
if (!parse_register_offset_node(emit, opcode, opcode_data, argument_nodes[1], 1, &nodes[1], &nodes[2], &negative)) {
703-
return false;
704-
}
705-
706-
mp_uint_t rd = 0;
707-
mp_uint_t rs1 = 0;
708-
if (!parse_register_node(nodes[0], &rd, opcode_data->argument1_kind & C)) {
709-
return false;
710-
}
711-
if (!parse_register_node(nodes[1], &rs1, opcode_data->argument3_kind & C)) {
712-
return false;
713-
}
714-
715-
mp_obj_t object;
716-
mp_parse_node_get_int_maybe(nodes[2], &object);
717-
mp_uint_t immediate = mp_obj_get_int_truncated(object) << opcode_data->argument2_shift;
718-
if (negative) {
719-
immediate = (~immediate + 1) & (mp_uint_t)-1;
720-
}
721-
if (!is_in_signed_mask(OPCODE_MASKS[opcode_data->argument2_mask], immediate)) {
722-
emit_inline_rv32_error_exc(emit,
723-
mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, ET_OUT_OF_RANGE, opcode, 2));
724-
return false;
725-
}
726-
727-
((call_rri_t)opcode_data->emitter)(&emit->as, rd, rs1, immediate);
728-
return true;
729-
}
730-
731696
static void emit_inline_rv32_opcode(emit_inline_asm_t *emit, qstr opcode, mp_uint_t arguments_count, mp_parse_node_t *argument_nodes) {
732697
const opcode_t *opcode_data = NULL;
733698
for (mp_uint_t index = 0; index < MP_ARRAY_SIZE(OPCODES); index++) {
@@ -747,37 +712,36 @@ static void emit_inline_rv32_opcode(emit_inline_asm_t *emit, qstr opcode, mp_uin
747712
assert((opcode_data->argument2_mask < MP_ARRAY_SIZE(OPCODE_MASKS)) && "Argument #2 opcode mask index out of bounds.");
748713
assert((opcode_data->argument3_mask < MP_ARRAY_SIZE(OPCODE_MASKS)) && "Argument #3 opcode mask index out of bounds.");
749714
assert((opcode_data->calling_convention < CALL_COUNT) && "Calling convention index out of bounds.");
750-
if (opcode_data->calling_convention != CALL_RIR) {
751-
if (opcode_data->arguments_count != arguments_count) {
752-
emit_inline_rv32_error_exc(emit,
753-
mp_obj_new_exception_msg_varg(&mp_type_SyntaxError,
754-
ET_WRONG_ARGUMENTS_COUNT, opcode, opcode_data->arguments_count));
755-
return;
756-
}
757-
mp_uint_t serialised_arguments[3] = { 0 };
758-
if (opcode_data->arguments_count >= 1 && !serialise_argument(emit, opcode_data, argument_nodes[0], 0, &serialised_arguments[0])) {
715+
mp_uint_t serialised_arguments[3] = { 0 };
716+
if (arguments_count != opcode_data->parse_nodes) {
717+
emit_inline_rv32_error_exc(emit,
718+
mp_obj_new_exception_msg_varg(&mp_type_SyntaxError,
719+
ET_WRONG_ARGUMENTS_COUNT, opcode, opcode_data->parse_nodes));
720+
return;
721+
}
722+
723+
if (opcode_data->parse_nodes >= 1 && !serialise_argument(emit, opcode_data, argument_nodes[0], 0, &serialised_arguments[0])) {
724+
return;
725+
}
726+
if (opcode_data->calling_convention == CALL_RIR) {
727+
// "register, offset(base)" calls require some preprocessing to
728+
// split the offset and base nodes - not to mention that if the offset
729+
// is negative, the parser won't see the offset as a single node but as
730+
// a sequence of the minus sign token followed by the number itself.
731+
732+
if (!serialise_register_offset_node(emit, opcode_data, argument_nodes[1], 1, &serialised_arguments[1], &serialised_arguments[2])) {
759733
return;
760734
}
761-
if (opcode_data->arguments_count >= 2 && !serialise_argument(emit, opcode_data, argument_nodes[1], 1, &serialised_arguments[1])) {
735+
} else {
736+
if (opcode_data->parse_nodes >= 2 && !serialise_argument(emit, opcode_data, argument_nodes[1], 1, &serialised_arguments[1])) {
762737
return;
763738
}
764-
if (opcode_data->arguments_count >= 3 && !serialise_argument(emit, opcode_data, argument_nodes[2], 2, &serialised_arguments[2])) {
739+
if (opcode_data->parse_nodes >= 3 && !serialise_argument(emit, opcode_data, argument_nodes[2], 2, &serialised_arguments[2])) {
765740
return;
766741
}
767-
handle_opcode(emit, opcode_data, serialised_arguments);
768-
return;
769-
}
770-
771-
assert((opcode_data->argument2_kind & U) == 0 && "Offset must not be unsigned.");
772-
assert((opcode_data->argument2_kind & Z) == 0 && "Offset can be zero.");
773-
774-
if (arguments_count != 2) {
775-
emit_inline_rv32_error_exc(emit,
776-
mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, ET_WRONG_ARGUMENTS_COUNT, opcode, 2));
777-
return;
778742
}
779743

780-
handle_load_store_opcode_with_offset(emit, opcode, opcode_data, argument_nodes);
744+
handle_opcode(emit, opcode_data, serialised_arguments);
781745
}
782746

783747
#undef N

0 commit comments

Comments
 (0)
0