Przeglądaj źródła

Implement new masking system for ASM instructions; bugfixes.

master
Ben Kurtovic 9 lat temu
rodzic
commit
76f2783b64
3 zmienionych plików z 32 dodań i 24 usunięć
  1. +28
    -20
      src/assembler/instructions.c
  2. +3
    -3
      src/assembler/parse_util.c
  3. +1
    -1
      src/assembler/tokenizer.c

+ 28
- 20
src/assembler/instructions.c Wyświetl plik

@@ -24,7 +24,7 @@
/* Helper macro for parse_arg() */ /* Helper macro for parse_arg() */


#define TRY_PARSER(func, argtype, field) \ #define TRY_PARSER(func, argtype, field) \
if (argparse_##func(&arg->data.field, info)) { \
if (mask & argtype && argparse_##func(&arg->data.field, info)) { \
arg->type = argtype; \ arg->type = argtype; \
return ED_NONE; \ return ED_NONE; \
} }
@@ -52,13 +52,6 @@
(((reg) == REG_IX || (reg) == REG_IXH || (reg) == REG_IXL) ? \ (((reg) == REG_IX || (reg) == REG_IXH || (reg) == REG_IXL) ? \
INST_IX_PREFIX : INST_IY_PREFIX) INST_IX_PREFIX : INST_IY_PREFIX)


#define INST_RETURN_WITH_SYMBOL_(len, label, ...) { \ // TODO
*symbol = cr_strdup(label.text); \
INST_ALLOC_(len) \
INST_FILL_BYTES_(len - 2, __VA_ARGS__) \
return ED_NONE; \
}

/* Helper macros for instruction parsers */ /* Helper macros for instruction parsers */


#define INST_FUNC(mnemonic) \ #define INST_FUNC(mnemonic) \
@@ -75,8 +68,8 @@ static ASMErrorDesc parse_inst_##mnemonic( \
if (!ap_info.arg) \ if (!ap_info.arg) \
INST_ERROR(TOO_FEW_ARGS) \ INST_ERROR(TOO_FEW_ARGS) \
ASMInstArg args[3]; \ ASMInstArg args[3]; \
size_t nargs = 0; \
ASMArgType masks = {a0, a1, a2}; \
size_t nargs; \
ASMArgType masks[] = {a0, a1, a2}; \
ASMErrorDesc err = parse_args(args, &nargs, ap_info, masks); \ ASMErrorDesc err = parse_args(args, &nargs, ap_info, masks); \
if (err) \ if (err) \
return err; \ return err; \
@@ -102,7 +95,10 @@ static ASMErrorDesc parse_inst_##mnemonic( \


#define INST_INDEX_PREFIX(n) INST_PREFIX_(INST_INDEX(n).reg) #define INST_INDEX_PREFIX(n) INST_PREFIX_(INST_INDEX(n).reg)


#define INST_INDIRECT_IMM(n) \ // TODO
// TODO: must check for imm actually using symbol...
// - hint: *symbol = cr_strdup(label.text);
// - hint: INST_FILL_BYTES_(len - 2, __VA_ARGS__)
#define INST_INDIRECT_IMM(n) \
INST_INDIRECT(n).addr.imm.uval >> 8, \ INST_INDIRECT(n).addr.imm.uval >> 8, \
INST_INDIRECT(n).addr.imm.uval & 0xFF INST_INDIRECT(n).addr.imm.uval & 0xFF


@@ -134,13 +130,15 @@ static uint8_t fill_bytes_variadic(uint8_t *bytes, size_t len, ...)
Return ED_NONE (0) on success or an error code on failure. Return ED_NONE (0) on success or an error code on failure.
*/ */
static ASMErrorDesc parse_arg( static ASMErrorDesc parse_arg(
ASMInstArg *arg, const char *str, size_t size, ASMDefineTable *deftable)
ASMInstArg *arg, const char *str, size_t size, ASMDefineTable *deftable,
ASMArgType mask)
{ {
ASMArgParseInfo info = {.arg = str, .size = size, .deftable = deftable}; ASMArgParseInfo info = {.arg = str, .size = size, .deftable = deftable};
TRY_PARSER(register, AT_REGISTER, reg) TRY_PARSER(register, AT_REGISTER, reg)
TRY_PARSER(condition, AT_CONDITION, cond) TRY_PARSER(condition, AT_CONDITION, cond)
TRY_PARSER(indirect, AT_INDIRECT, indirect)
TRY_PARSER(indexed, AT_INDEXED, index) TRY_PARSER(indexed, AT_INDEXED, index)
TRY_PARSER(indirect, AT_INDIRECT, indirect)
TRY_PARSER(port, AT_PORT, port)
TRY_PARSER(immediate, AT_IMMEDIATE, imm) TRY_PARSER(immediate, AT_IMMEDIATE, imm)
return ED_PS_ARG_SYNTAX; return ED_PS_ARG_SYNTAX;
} }
@@ -151,21 +149,25 @@ static ASMErrorDesc parse_arg(
Return ED_NONE (0) on success or an error code on failure. Return ED_NONE (0) on success or an error code on failure.
*/ */
static ASMErrorDesc parse_args( static ASMErrorDesc parse_args(
ASMInstArg args[3], size_t *nargs, ASMArgParseInfo ap_info, ASMArgType masks[3]) // TODO
ASMInstArg args[3], size_t *nargs, ASMArgParseInfo ap_info,
ASMArgType masks[3])
{ {
ASMErrorDesc err; ASMErrorDesc err;
ASMDefineTable *dt = ap_info.deftable; ASMDefineTable *dt = ap_info.deftable;
const char *str = ap_info.arg; const char *str = ap_info.arg;
size_t size = ap_info.size, start = 0, i = 0;
size_t size = ap_info.size, start = 0, i = 0, n = 0;


while (i < size) { while (i < size) {
char c = str[i]; char c = str[i];
if (c == ',') { if (c == ',') {
if (i == start) if (i == start)
return ED_PS_ARG_SYNTAX; return ED_PS_ARG_SYNTAX;
if ((err = parse_arg(&args[*nargs], str + start, i - start, dt)))
if (masks[n] == AT_NONE)
return ED_PS_TOO_MANY_ARGS;
err = parse_arg(&args[n], str + start, i - start, dt, masks[n]);
if (err)
return err; return err;
(*nargs)++;
n++;


i++; i++;
if (i < size && str[i] == ' ') if (i < size && str[i] == ' ')
@@ -173,7 +175,7 @@ static ASMErrorDesc parse_args(
start = i; start = i;
if (i == size) if (i == size)
return ED_PS_ARG_SYNTAX; return ED_PS_ARG_SYNTAX;
if (*nargs >= 3)
if (n >= 3)
return ED_PS_TOO_MANY_ARGS; return ED_PS_TOO_MANY_ARGS;
} else { } else {
if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
@@ -186,10 +188,16 @@ static ASMErrorDesc parse_args(
} }


if (i > start) { if (i > start) {
if ((err = parse_arg(&args[*nargs], str + start, i - start, dt)))
if (masks[n] == AT_NONE)
return ED_PS_TOO_MANY_ARGS;
if ((err = parse_arg(&args[n], str + start, i - start, dt, masks[n])))
return err; return err;
(*nargs)++;
n++;
} }

if (n < 3 && masks[n] != AT_NONE && !(masks[n] & AT_OPTIONAL))
return ED_PS_TOO_FEW_ARGS;
*nargs = n;
return ED_NONE; return ED_NONE;
} }




+ 3
- 3
src/assembler/parse_util.c Wyświetl plik

@@ -460,7 +460,7 @@ bool argparse_indexed(ASMArgIndexed *result, ASMArgParseInfo ai)
/* /*
Read in a port argument and store it in *result. Read in a port argument and store it in *result.
*/ */
bool argparse_port(ASMArgPort*, ASMArgParseInfo)
bool argparse_port(ASMArgPort *result, ASMArgParseInfo ai)
{ {
if (ai.size < 3 || !adjust_for_indirection(&ai)) if (ai.size < 3 || !adjust_for_indirection(&ai))
return false; return false;
@@ -470,13 +470,13 @@ bool argparse_port(ASMArgPort*, ASMArgParseInfo)
if (argparse_register(&reg, ai)) { if (argparse_register(&reg, ai)) {
if (reg == REG_C) { if (reg == REG_C) {
result->type = AT_REGISTER; result->type = AT_REGISTER;
result->addr.reg = reg;
result->port.reg = reg;
return true; return true;
} }
} else if (argparse_immediate(&imm, ai)) { } else if (argparse_immediate(&imm, ai)) {
if (imm.mask & IMM_U8) { if (imm.mask & IMM_U8) {
result->type = AT_IMMEDIATE; result->type = AT_IMMEDIATE;
result->addr.imm = imm;
result->port.imm = imm;
return true; return true;
} }
} }


+ 1
- 1
src/assembler/tokenizer.c Wyświetl plik

@@ -155,7 +155,7 @@ static ErrorInfo* handle_define_directive(
ASMArgImmediate imm; ASMArgImmediate imm;
ASMArgParseInfo info = { ASMArgParseInfo info = {
.arg = line->data + i, .size = line->length - i, .deftable = deftab}; .arg = line->data + i, .size = line->length - i, .deftable = deftab};
if (!argparse_immediate(&imm, info) || imm->is_label)
if (!argparse_immediate(&imm, info) || imm.is_label)
return error_info_create(line, ET_PREPROC, ED_PP_BAD_ARG); return error_info_create(line, ET_PREPROC, ED_PP_BAD_ARG);


ASMDefine *define = cr_malloc(sizeof(ASMDefine)); ASMDefine *define = cr_malloc(sizeof(ASMDefine));


Ładowanie…
Anuluj
Zapisz