diff --git a/src/tools/aindump/macros.c b/src/tools/aindump/macros.c index 2d73d7e..63641c1 100644 --- a/src/tools/aindump/macros.c +++ b/src/tools/aindump/macros.c @@ -71,6 +71,11 @@ static bool local_check(struct dasm_state *dasm, int32_t *args) #define LOCALASSIGN_check local_check #define LOCALASSIGN2_check local_check +static bool S_LOCALASSIGN_check(struct dasm_state *dasm, int32_t *args) +{ + return is_local(dasm, args[0]) && args[1] == args[0]; +} + static bool LOCALCREATE_check(struct dasm_state *dasm, int32_t *args) { return is_local(dasm, args[0]) && is_struct_type(dasm, args[1]) && args[2] == -1; @@ -85,12 +90,13 @@ static void local_emit(struct dasm_state *dasm, int32_t *args) { print_local(dasm, args[0]); } -#define LOCALREF_emit local_emit -#define LOCALREFREF_emit local_emit -#define LOCALINC_emit local_emit -#define LOCALDEC_emit local_emit -#define LOCALDELETE_emit local_emit -#define LOCALASSIGN2_emit local_emit +#define LOCALREF_emit local_emit +#define LOCALREFREF_emit local_emit +#define LOCALINC_emit local_emit +#define LOCALDEC_emit local_emit +#define LOCALDELETE_emit local_emit +#define LOCALASSIGN2_emit local_emit +#define S_LOCALASSIGN_emit local_emit static void LOCALASSIGN_emit(struct dasm_state *dasm, int32_t *args) { @@ -191,25 +197,26 @@ struct macrodef { }; struct macrodef macrodefs[] = { - DEFMACRO(LOCALREF, PUSHLOCALPAGE, PUSH, REF), - DEFMACRO(LOCALREFREF, PUSHLOCALPAGE, PUSH, REFREF), - DEFMACRO(LOCALINC, PUSHLOCALPAGE, PUSH, INC), - DEFMACRO(LOCALDEC, PUSHLOCALPAGE, PUSH, DEC), - DEFMACRO(LOCALASSIGN, PUSHLOCALPAGE, PUSH, PUSH, ASSIGN, POP), - DEFMACRO(LOCALASSIGN2, PUSHLOCALPAGE, SWAP, PUSH, SWAP, ASSIGN), - DEFMACRO(LOCALCREATE, PUSHLOCALPAGE, PUSH, DUP2, REF, DELETE, DUP2, NEW, ASSIGN, POP, POP, POP), - DEFMACRO(LOCALDELETE, PUSHLOCALPAGE, PUSH, DUP2, REF, DELETE, PUSH, ASSIGN, POP), - DEFMACRO(GLOBALREF, PUSHGLOBALPAGE, PUSH, REF), - DEFMACRO(GLOBALREFREF, PUSHGLOBALPAGE, PUSH, REFREF), - DEFMACRO(GLOBALINC, PUSHGLOBALPAGE, PUSH, INC), - DEFMACRO(GLOBALDEC, PUSHGLOBALPAGE, PUSH, DEC), - DEFMACRO(GLOBALASSIGN, PUSHGLOBALPAGE, PUSH, PUSH, ASSIGN, POP), - DEFMACRO(STRUCTREF, PUSHSTRUCTPAGE, PUSH, REF), - DEFMACRO(STRUCTREFREF, PUSHSTRUCTPAGE, PUSH, REFREF), - DEFMACRO(STRUCTINC, PUSHSTRUCTPAGE, PUSH, INC), - DEFMACRO(STRUCTDEC, PUSHSTRUCTPAGE, PUSH, DEC), - DEFMACRO(STRUCTASSIGN, PUSHSTRUCTPAGE, PUSH, PUSH, ASSIGN, POP), - DEFMACRO(PUSHVMETHOD, PUSHSTRUCTPAGE, PUSH, DUP_U2, PUSH, REF, SWAP, PUSH, ADD, REF), + DEFMACRO(LOCALREF, PUSHLOCALPAGE, PUSH, REF), + DEFMACRO(LOCALREFREF, PUSHLOCALPAGE, PUSH, REFREF), + DEFMACRO(LOCALINC, PUSHLOCALPAGE, PUSH, INC), + DEFMACRO(LOCALDEC, PUSHLOCALPAGE, PUSH, DEC), + DEFMACRO(LOCALASSIGN, PUSHLOCALPAGE, PUSH, PUSH, ASSIGN, POP), + DEFMACRO(LOCALASSIGN2, PUSHLOCALPAGE, SWAP, PUSH, SWAP, ASSIGN), + DEFMACRO(S_LOCALASSIGN, PUSHLOCALPAGE, PUSH, REF, DELETE, PUSHLOCALPAGE, SWAP, PUSH, SWAP, ASSIGN), + DEFMACRO(LOCALCREATE, PUSHLOCALPAGE, PUSH, DUP2, REF, DELETE, DUP2, NEW, ASSIGN, POP, POP, POP), + DEFMACRO(LOCALDELETE, PUSHLOCALPAGE, PUSH, DUP2, REF, DELETE, PUSH, ASSIGN, POP), + DEFMACRO(GLOBALREF, PUSHGLOBALPAGE, PUSH, REF), + DEFMACRO(GLOBALREFREF, PUSHGLOBALPAGE, PUSH, REFREF), + DEFMACRO(GLOBALINC, PUSHGLOBALPAGE, PUSH, INC), + DEFMACRO(GLOBALDEC, PUSHGLOBALPAGE, PUSH, DEC), + DEFMACRO(GLOBALASSIGN, PUSHGLOBALPAGE, PUSH, PUSH, ASSIGN, POP), + DEFMACRO(STRUCTREF, PUSHSTRUCTPAGE, PUSH, REF), + DEFMACRO(STRUCTREFREF, PUSHSTRUCTPAGE, PUSH, REFREF), + DEFMACRO(STRUCTINC, PUSHSTRUCTPAGE, PUSH, INC), + DEFMACRO(STRUCTDEC, PUSHSTRUCTPAGE, PUSH, DEC), + DEFMACRO(STRUCTASSIGN, PUSHSTRUCTPAGE, PUSH, PUSH, ASSIGN, POP), + DEFMACRO(PUSHVMETHOD, PUSHSTRUCTPAGE, PUSH, DUP_U2, PUSH, REF, SWAP, PUSH, ADD, REF), }; struct macro_node { @@ -320,7 +327,7 @@ static bool _dasm_print_macro(struct dasm_state *dasm) // match as many instructions as possible struct macro_node *next, *node = macros; while ((next = find_node(node, dasm->instr->opcode))) { - if (!can_elide(dasm)) + if (node != macros && !can_elide(dasm)) return false; for (int i = 0; i < dasm->instr->nr_args; i++) { diff --git a/src/tools/ainedit/ainedit.h b/src/tools/ainedit/ainedit.h index 2700f63..e56a987 100644 --- a/src/tools/ainedit/ainedit.h +++ b/src/tools/ainedit/ainedit.h @@ -40,6 +40,7 @@ enum asm_pseudo_opcode { PO_LOCALDEC, PO_LOCALASSIGN, PO_LOCALASSIGN2, + PO_S_LOCALASSIGN, PO_LOCALDELETE, PO_LOCALCREATE, PO_GLOBALINC, diff --git a/src/tools/ainedit/asm.c b/src/tools/ainedit/asm.c index 4e69955..db53456 100644 --- a/src/tools/ainedit/asm.c +++ b/src/tools/ainedit/asm.c @@ -55,29 +55,30 @@ KHASH_MAP_INIT_STR(string_ht, size_t); } const struct instruction asm_pseudo_ops[NR_PSEUDO_OPS - PSEUDO_OP_OFFSET] = { - PSEUDO_OP(PO_CASE, ".CASE", 2), - PSEUDO_OP(PO_DEFAULT, ".DEFAULT", 1), - PSEUDO_OP(PO_STR, ".STR", 2), - PSEUDO_OP(PO_MSG, ".MSG", 2), - MACRO(PO_LOCALREF, ".LOCALREF", 1, 10), - MACRO(PO_LOCALREFREF, ".LOCALREFREF", 1, 10), - MACRO(PO_LOCALINC, ".LOCALINC", 1, 10), - MACRO(PO_LOCALDEC, ".LOCALDEC", 1, 10), - MACRO(PO_LOCALASSIGN, ".LOCALASSIGN", 2, 18), - MACRO(PO_LOCALASSIGN2, ".LOCALASSIGN2", 1, 14), - MACRO(PO_LOCALDELETE, ".LOCALDELETE", 1, 24), - MACRO(PO_LOCALCREATE, ".LOCALCREATE", 2, 34), - MACRO(PO_GLOBALREF, ".GLOBALREF", 1, 10), - MACRO(PO_GLOBALREFREF, ".GLOBALREFREF", 1, 10), - MACRO(PO_GLOBALINC, ".GLOBALINC", 1, 10), - MACRO(PO_GLOBALDEC, ".GLOBALDEC", 1, 10), - MACRO(PO_GLOBALASSIGN, ".GLOBALASSIGN", 2, 18), - MACRO(PO_STRUCTREF, ".STRUCTREF", 2, 10), - MACRO(PO_STRUCTREFREF, ".STRUCTREFREF", 2, 10), - MACRO(PO_STRUCTINC, ".STRUCTINC", 2, 10), - MACRO(PO_STRUCTDEC, ".STRUCTDEC", 2, 10), - MACRO(PO_STRUCTASSIGN, ".STRUCTASSIGN", 3, 18), - MACRO(PO_PUSHVMETHOD, ".PUSHVMETHOD", 2, 30), + PSEUDO_OP(PO_CASE, ".CASE", 2), + PSEUDO_OP(PO_DEFAULT, ".DEFAULT", 1), + PSEUDO_OP(PO_STR, ".STR", 2), + PSEUDO_OP(PO_MSG, ".MSG", 2), + MACRO(PO_LOCALREF, ".LOCALREF", 1, 10), + MACRO(PO_LOCALREFREF, ".LOCALREFREF", 1, 10), + MACRO(PO_LOCALINC, ".LOCALINC", 1, 10), + MACRO(PO_LOCALDEC, ".LOCALDEC", 1, 10), + MACRO(PO_LOCALASSIGN, ".LOCALASSIGN", 2, 18), + MACRO(PO_LOCALASSIGN2, ".LOCALASSIGN2", 1, 14), + MACRO(PO_S_LOCALASSIGN, ".S_LOCALASSIGN", 1, 26), + MACRO(PO_LOCALDELETE, ".LOCALDELETE", 1, 24), + MACRO(PO_LOCALCREATE, ".LOCALCREATE", 2, 34), + MACRO(PO_GLOBALREF, ".GLOBALREF", 1, 10), + MACRO(PO_GLOBALREFREF, ".GLOBALREFREF", 1, 10), + MACRO(PO_GLOBALINC, ".GLOBALINC", 1, 10), + MACRO(PO_GLOBALDEC, ".GLOBALDEC", 1, 10), + MACRO(PO_GLOBALASSIGN, ".GLOBALASSIGN", 2, 18), + MACRO(PO_STRUCTREF, ".STRUCTREF", 2, 10), + MACRO(PO_STRUCTREFREF, ".STRUCTREFREF", 2, 10), + MACRO(PO_STRUCTINC, ".STRUCTINC", 2, 10), + MACRO(PO_STRUCTDEC, ".STRUCTDEC", 2, 10), + MACRO(PO_STRUCTASSIGN, ".STRUCTASSIGN", 3, 18), + MACRO(PO_PUSHVMETHOD, ".PUSHVMETHOD", 2, 30), }; struct string_table { @@ -605,6 +606,20 @@ void handle_pseudo_op(struct asm_state *state, struct parse_instruction *instr) asm_write_opcode(state, ASSIGN); break; } + case PO_S_LOCALASSIGN: { + asm_write_opcode(state, PUSHLOCALPAGE); + asm_write_opcode(state, PUSH); + asm_write_argument(state, asm_resolve_arg(state, PUSH, T_LOCAL, kv_A(*instr->args, 0)->text)); + asm_write_opcode(state, REF); + asm_write_opcode(state, DELETE); + asm_write_opcode(state, PUSHLOCALPAGE); + asm_write_opcode(state, SWAP); + asm_write_opcode(state, PUSH); + asm_write_argument(state, asm_resolve_arg(state, PUSH, T_LOCAL, kv_A(*instr->args, 0)->text)); + asm_write_opcode(state, SWAP); + asm_write_opcode(state, ASSIGN); + break; + } case PO_LOCALDELETE: { asm_write_opcode(state, PUSHLOCALPAGE); asm_write_opcode(state, PUSH);