mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-09-30 02:48:14 +03:00
aindump/ainedit: more macros
.LOCALINC .LOCALDEC .LOCALASSIGN .LOCALDELETE .LOCALCREATE .GLOBALINC .GLOBALDEC .GLOBALASSIGN
This commit is contained in:
+175
-6
@@ -34,7 +34,149 @@ static bool check_opcode(struct dasm_state *dasm, enum opcode opcode)
|
||||
return dasm->instr->opcode == opcode && can_elide(dasm);
|
||||
}
|
||||
|
||||
static bool print_localref(struct dasm_state *dasm)
|
||||
static bool check_next_opcode(struct dasm_state *dasm, enum opcode opcode)
|
||||
{
|
||||
dasm_next(dasm);
|
||||
return check_opcode(dasm, opcode);
|
||||
}
|
||||
|
||||
/* Macro List
|
||||
|
||||
.GLOBALREF <varname>:
|
||||
PUSHGLOBALPAGE
|
||||
PUSH <varno>
|
||||
REF
|
||||
|
||||
.GLOBALREFREF <varname>:
|
||||
PUSHGLOBALPAGE
|
||||
PUSH <varno>
|
||||
REFREF
|
||||
|
||||
.LOCALREF <varname>:
|
||||
PUSHLOCALPAGE
|
||||
PUSH <varno>
|
||||
REF
|
||||
|
||||
.LOCALREFREF <varname>:
|
||||
PUSHLOCALPAGE
|
||||
PUSH <varno>
|
||||
REFREF
|
||||
|
||||
.LOCALINC:
|
||||
PUSHLOCALPAGE
|
||||
PUSH <varno>
|
||||
INC
|
||||
|
||||
.LOCALDEC:
|
||||
PUSHLOCALPAGE
|
||||
PUSH <varno>
|
||||
DEC
|
||||
|
||||
.LOCALASSIGN <varname> <value>:
|
||||
PUSHLOCALPAGE
|
||||
PUSH <varno>
|
||||
PUSH <value>
|
||||
ASSIGN
|
||||
|
||||
.LOCALDELETE:
|
||||
PUSHLOCALPAGE
|
||||
PUSH <varno>
|
||||
DUP2
|
||||
REF
|
||||
DELETE
|
||||
PUSH -1
|
||||
ASSIGN
|
||||
POP
|
||||
|
||||
.LOCALCREATE:
|
||||
PUSHLOCALPAGE
|
||||
PUSH <varno>
|
||||
DUP2
|
||||
REF
|
||||
DELETE
|
||||
DUP2
|
||||
NEW <structno> -1
|
||||
ASSIGN
|
||||
POP
|
||||
POP
|
||||
POP
|
||||
|
||||
*/
|
||||
|
||||
static void print_local(struct dasm_state *dasm, int32_t no)
|
||||
{
|
||||
dasm_print_local_variable(dasm, &dasm->ain->functions[dasm->func], no);
|
||||
}
|
||||
|
||||
static bool local_create_or_delete_macro(struct dasm_state *dasm, int32_t varno)
|
||||
{
|
||||
if (!check_next_opcode(dasm, REF))
|
||||
return false;
|
||||
|
||||
if (!check_next_opcode(dasm, DELETE))
|
||||
return false;
|
||||
|
||||
dasm_next(dasm);
|
||||
if (check_opcode(dasm, PUSH)) {
|
||||
// localdelete
|
||||
if (dasm_arg(dasm, 0) != -1)
|
||||
return false;
|
||||
|
||||
if (!check_next_opcode(dasm, ASSIGN))
|
||||
return false;
|
||||
|
||||
if (!check_next_opcode(dasm, POP))
|
||||
return false;
|
||||
|
||||
fprintf(dasm->out, ".LOCALDELETE ");
|
||||
dasm_print_local_variable(dasm, &dasm->ain->functions[dasm->func], varno);
|
||||
fputc('\n', dasm->out);
|
||||
return true;
|
||||
} else if (check_opcode(dasm, DUP2)) {
|
||||
// localcreate
|
||||
if (!check_next_opcode(dasm, NEW))
|
||||
return false;
|
||||
|
||||
int32_t structno = dasm_arg(dasm, 0);
|
||||
if (structno < 0 || structno >= dasm->ain->nr_structures)
|
||||
return false;
|
||||
if (dasm_arg(dasm, 1) != -1)
|
||||
return false;
|
||||
|
||||
if (!check_next_opcode(dasm, ASSIGN))
|
||||
return false;
|
||||
if (!check_next_opcode(dasm, POP))
|
||||
return false;
|
||||
if (!check_next_opcode(dasm, POP))
|
||||
return false;
|
||||
if (!check_next_opcode(dasm, POP))
|
||||
return false;
|
||||
|
||||
fprintf(dasm->out, ".LOCALCREATE ");
|
||||
print_local(dasm, varno);
|
||||
fputc(' ', dasm->out);
|
||||
dasm_print_identifier(dasm, dasm->ain->structures[structno].name);
|
||||
fputc('\n', dasm->out);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool localassign_macro(struct dasm_state *dasm, int32_t no)
|
||||
{
|
||||
int32_t val = dasm_arg(dasm, 0);
|
||||
if (!check_next_opcode(dasm, ASSIGN))
|
||||
return false;
|
||||
|
||||
fprintf(dasm->out, ".LOCALASSIGN ");
|
||||
print_local(dasm, no);
|
||||
fputc(' ', dasm->out);
|
||||
fprintf(dasm->out, "%d\n", val);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool localpage_macro(struct dasm_state *dasm)
|
||||
{
|
||||
dasm_next(dasm);
|
||||
if (!check_opcode(dasm, PUSH))
|
||||
@@ -49,18 +191,39 @@ static bool print_localref(struct dasm_state *dasm)
|
||||
fprintf(dasm->out, ".LOCALREF ");
|
||||
} else if (check_opcode(dasm, REFREF)) {
|
||||
fprintf(dasm->out, ".LOCALREFREF ");
|
||||
} else if (check_opcode(dasm, INC)) {
|
||||
fprintf(dasm->out, ".LOCALINC ");
|
||||
} else if (check_opcode(dasm, DEC)) {
|
||||
fprintf(dasm->out, ".LOCALDEC ");
|
||||
} else if (check_opcode(dasm, PUSH)) {
|
||||
return localassign_macro(dasm, no);
|
||||
} else if (check_opcode(dasm, DUP2)) {
|
||||
return local_create_or_delete_macro(dasm, no);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
//dasm_print_identifier(dasm, dasm->ain->functions[dasm->func].vars[no].name);
|
||||
dasm_print_local_variable(dasm, &dasm->ain->functions[dasm->func], no);
|
||||
print_local(dasm, no);
|
||||
fputc('\n', dasm->out);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool print_globalref(struct dasm_state *dasm)
|
||||
static bool globalassign_macro(struct dasm_state *dasm, int32_t no)
|
||||
{
|
||||
int32_t val = dasm_arg(dasm, 0);
|
||||
if (!check_next_opcode(dasm, ASSIGN))
|
||||
return false;
|
||||
|
||||
fprintf(dasm->out, ".GLOBALASSIGN ");
|
||||
dasm_print_identifier(dasm, dasm->ain->globals[no].name);
|
||||
fputc(' ', dasm->out);
|
||||
fprintf(dasm->out, "%d\n", val);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
static bool globalpage_macro(struct dasm_state *dasm)
|
||||
{
|
||||
dasm_next(dasm);
|
||||
if (!check_opcode(dasm, PUSH))
|
||||
@@ -75,6 +238,12 @@ static bool print_globalref(struct dasm_state *dasm)
|
||||
fprintf(dasm->out, ".GLOBALREF ");
|
||||
} else if (check_opcode(dasm, REFREF)) {
|
||||
fprintf(dasm->out, ".GLOBALREFREF ");
|
||||
} else if (check_opcode(dasm, INC)) {
|
||||
fprintf(dasm->out, ".GLOBALINC ");
|
||||
} else if (check_opcode(dasm, DEC)) {
|
||||
fprintf(dasm->out, ".GLOBALDEC ");
|
||||
} else if (check_opcode(dasm, PUSH)) {
|
||||
return globalassign_macro(dasm, no);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -89,9 +258,9 @@ static bool _dasm_print_macro(struct dasm_state *dasm)
|
||||
{
|
||||
switch (dasm->instr->opcode) {
|
||||
case PUSHLOCALPAGE:
|
||||
return print_localref(dasm);
|
||||
return localpage_macro(dasm);
|
||||
case PUSHGLOBALPAGE:
|
||||
return print_globalref(dasm);
|
||||
return globalpage_macro(dasm);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,14 @@ enum asm_pseudo_opcode {
|
||||
PO_GLOBALREF,
|
||||
PO_LOCALREFREF,
|
||||
PO_GLOBALREFREF,
|
||||
PO_LOCALINC,
|
||||
PO_LOCALDEC,
|
||||
PO_LOCALASSIGN,
|
||||
PO_LOCALDELETE,
|
||||
PO_LOCALCREATE,
|
||||
PO_GLOBALINC,
|
||||
PO_GLOBALDEC,
|
||||
PO_GLOBALASSIGN,
|
||||
NR_PSEUDO_OPS
|
||||
};
|
||||
|
||||
|
||||
+93
-9
@@ -34,7 +34,7 @@ KHASH_MAP_INIT_STR(string_ht, size_t);
|
||||
// TODO: better error messages
|
||||
#define ASM_ERROR(state, ...) ERROR(__VA_ARGS__)
|
||||
|
||||
#define _PSEUDO_OP(code, _name, nargs, _ip_inc, ...) \
|
||||
#define MACRO(code, _name, nargs, _ip_inc, ...) \
|
||||
[code - PSEUDO_OP_OFFSET] = { \
|
||||
.opcode = code, \
|
||||
.name = _name, \
|
||||
@@ -55,14 +55,22 @@ 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),
|
||||
_PSEUDO_OP(PO_LOCALREF, ".LOCALREF", 1, 10),
|
||||
_PSEUDO_OP(PO_GLOBALREF, ".GLOBALREF", 1, 10),
|
||||
_PSEUDO_OP(PO_LOCALREFREF, ".LOCALREFREF", 1, 10),
|
||||
_PSEUDO_OP(PO_GLOBALREFREF, ".GLOBALREFREF", 1, 10),
|
||||
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_GLOBALREF, ".GLOBALREF", 1, 10),
|
||||
MACRO(PO_LOCALREFREF, ".LOCALREFREF", 1, 10),
|
||||
MACRO(PO_GLOBALREFREF, ".GLOBALREFREF", 1, 10),
|
||||
MACRO(PO_LOCALINC, ".LOCALINC", 1, 10),
|
||||
MACRO(PO_LOCALDEC, ".LOCALDEC", 1, 10),
|
||||
MACRO(PO_LOCALASSIGN, ".LOCALASSIGN", 2, 16),
|
||||
MACRO(PO_LOCALDELETE, ".LOCALDELETE", 1, 24),
|
||||
MACRO(PO_LOCALCREATE, ".LOCALCREATE", 2, 34),
|
||||
MACRO(PO_GLOBALINC, ".GLOBALINC", 1, 10),
|
||||
MACRO(PO_GLOBALDEC, ".GLOBALDEC", 1, 10),
|
||||
MACRO(PO_GLOBALASSIGN, ".GLOBALASSIGN", 2, 16),
|
||||
};
|
||||
|
||||
struct string_table {
|
||||
@@ -513,6 +521,82 @@ void handle_pseudo_op(struct asm_state *state, struct parse_instruction *instr)
|
||||
asm_write_opcode(state, REFREF);
|
||||
break;
|
||||
}
|
||||
case PO_LOCALINC: {
|
||||
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, INC);
|
||||
break;
|
||||
}
|
||||
case PO_LOCALDEC: {
|
||||
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, DEC);
|
||||
break;
|
||||
}
|
||||
case PO_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, PUSH);
|
||||
asm_write_argument(state, asm_resolve_arg(state, PUSH, T_INT, kv_A(*instr->args, 1)->text));
|
||||
asm_write_opcode(state, ASSIGN);
|
||||
break;
|
||||
}
|
||||
case PO_LOCALDELETE: {
|
||||
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, DUP2);
|
||||
asm_write_opcode(state, REF);
|
||||
asm_write_opcode(state, DELETE);
|
||||
asm_write_opcode(state, PUSH);
|
||||
asm_write_argument(state, -1);
|
||||
asm_write_opcode(state, ASSIGN);
|
||||
asm_write_opcode(state, POP);
|
||||
break;
|
||||
}
|
||||
case PO_LOCALCREATE: {
|
||||
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, DUP2);
|
||||
asm_write_opcode(state, REF);
|
||||
asm_write_opcode(state, DELETE);
|
||||
asm_write_opcode(state, DUP2);
|
||||
asm_write_opcode(state, NEW);
|
||||
asm_write_argument(state, asm_resolve_arg(state, NEW, T_STRUCT, kv_A(*instr->args, 1)->text));
|
||||
asm_write_argument(state, -1);
|
||||
asm_write_opcode(state, ASSIGN);
|
||||
asm_write_opcode(state, POP);
|
||||
asm_write_opcode(state, POP);
|
||||
asm_write_opcode(state, POP);
|
||||
break;
|
||||
}
|
||||
case PO_GLOBALINC: {
|
||||
asm_write_opcode(state, PUSHGLOBALPAGE);
|
||||
asm_write_opcode(state, PUSH);
|
||||
asm_write_argument(state, asm_resolve_arg(state, PUSH, T_GLOBAL, kv_A(*instr->args, 0)->text));
|
||||
asm_write_opcode(state, INC);
|
||||
break;
|
||||
}
|
||||
case PO_GLOBALDEC: {
|
||||
asm_write_opcode(state, PUSHGLOBALPAGE);
|
||||
asm_write_opcode(state, PUSH);
|
||||
asm_write_argument(state, asm_resolve_arg(state, PUSH, T_GLOBAL, kv_A(*instr->args, 0)->text));
|
||||
asm_write_opcode(state, DEC);
|
||||
break;
|
||||
}
|
||||
case PO_GLOBALASSIGN: {
|
||||
asm_write_opcode(state, PUSHGLOBALPAGE);
|
||||
asm_write_opcode(state, PUSH);
|
||||
asm_write_argument(state, asm_resolve_arg(state, PUSH, T_GLOBAL, kv_A(*instr->args, 0)->text));
|
||||
asm_write_opcode(state, PUSH);
|
||||
asm_write_argument(state, asm_resolve_arg(state, PUSH, T_INT, kv_A(*instr->args, 1)->text));
|
||||
asm_write_opcode(state, ASSIGN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user