Browse Source

Implement parsing of immediates; bugfix.

master
Ben Kurtovic 9 years ago
parent
commit
ae2fd5b2c8
5 changed files with 82 additions and 30 deletions
  1. +2
    -1
      src/assembler/inst_args.h
  2. +21
    -22
      src/assembler/instructions.c
  3. +51
    -2
      src/assembler/parse_util.c
  4. +6
    -3
      src/assembler/parse_util.h
  5. +2
    -2
      src/assembler/tokenizer.c

+ 2
- 1
src/assembler/inst_args.h View File

@@ -34,7 +34,8 @@ typedef enum {

typedef struct {
ASMArgImmType mask;
uint16_t value;
uint16_t uval;
int16_t sval;
} ASMArgImmediate;

typedef struct {


+ 21
- 22
src/assembler/instructions.c View File

@@ -147,35 +147,30 @@ static uint8_t fill_bytes_variadic(uint8_t *bytes, size_t len, ...)
static ASMErrorDesc parse_arg(
ASMInstArg *arg, const char *str, size_t size, char **symbol)
{
// TODO
#define USE_PARSER(func, argtype, field) \
if (argparse_##func(&arg->data.field, str, size)) { \
arg->type = argtype; \
return ED_NONE; \
}

// AT_REGISTER
// AT_IMMEDIATE
// AT_INDIRECT
// AT_INDEXED
// AT_LABEL
// AT_CONDITION
DEBUG("parse_arg(): -->%.*s<-- %zu", (int) size, str, size)
USE_PARSER(register, AT_REGISTER, reg)
USE_PARSER(immediate, AT_IMMEDIATE, imm)

// ASMArgRegister reg;
// ASMArgImmediate imm;
// AT_INDIRECT
// ASMArgIndirect indirect;
// ASMArgIndexed index;
// ASMArgLabel label;
// ASMArgCondition cond;

DEBUG("parse_arg(): -->%.*s<-- %zu", (int) size, str, size)
// AT_INDEXED
// ASMArgIndexed index;

if (parse_register(&arg->data.reg, str, size)) {
arg->type = AT_REGISTER;
return ED_NONE;
}
USE_PARSER(condition, AT_CONDITION, cond)

if (parse_condition(&arg->data.cond, str, size)) {
arg->type = AT_CONDITION;
return ED_NONE;
}
// AT_LABEL
// ASMArgLabel label;

return ED_PS_ARG_SYNTAX;

#undef USE_PARSER
}

/*
@@ -193,6 +188,8 @@ static ASMErrorDesc parse_args(
while (i < size) {
char c = str[i];
if (c == ',') {
if (i == start)
return ED_PS_ARG_SYNTAX;
if ((err = parse_arg(&args[*nargs], str + start, i - start, &symbol)))
return err;
(*nargs)++;
@@ -201,7 +198,9 @@ static ASMErrorDesc parse_args(
if (i < size && str[i] == ' ')
i++;
start = i;
if (*nargs >= 3 && i < size)
if (i == size)
return ED_PS_ARG_SYNTAX;
if (*nargs >= 3)
return ED_PS_TOO_MANY_ARGS;
} else {
if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||


+ 51
- 2
src/assembler/parse_util.c View File

@@ -177,7 +177,7 @@ bool parse_bytes(uint8_t **result, size_t *length, const char *arg, ssize_t size
/*
Read in a register argument and store it in *result.
*/
bool parse_register(ASMArgRegister *result, const char *arg, ssize_t size)
bool argparse_register(ASMArgRegister *result, const char *arg, ssize_t size)
{
if (size < 1 || size > 3)
return false;
@@ -232,7 +232,7 @@ bool parse_register(ASMArgRegister *result, const char *arg, ssize_t size)
/*
Read in a register argument and store it in *result.
*/
bool parse_condition(ASMArgCondition *result, const char *arg, ssize_t size)
bool argparse_condition(ASMArgCondition *result, const char *arg, ssize_t size)
{
if (size < 1 || size > 2)
return false;
@@ -265,6 +265,55 @@ bool parse_condition(ASMArgCondition *result, const char *arg, ssize_t size)
}

/*
Read in an immediate argument and store it in *result.
*/
bool argparse_immediate(ASMArgImmediate *result, const char *arg, ssize_t size)
{
bool negative = false;
ssize_t i = 0;

if (size <= 0)
return false;

while (arg[i] == '-' || arg[i] == '+' || arg[i] == ' ') {
if (arg[i] == '-')
negative = !negative;
if (++i >= size)
return false;
}

uint32_t uval;
if (parse_uint32_t(&uval, arg, size) && uval > UINT16_MAX)
return false;

int32_t sval = negative ? uval : -uval;
if (sval < INT16_MIN)
return false;

result->uval = uval;
result->sval = sval;
result->mask = 0;

if (negative) {
if (sval >= INT8_MIN && sval <= INT8_MAX)
result->mask |= IMM_S8;
if (sval >= INT8_MIN + 2 && sval <= INT8_MAX + 2)
result->mask |= IMM_REL;
} else {
result->mask = IMM_U16;
if (uval <= UINT8_MAX)
result->mask |= IMM_U8;
if (uval <= 7)
result->mask |= IMM_BIT;
if (!(uval & ~0x38))
result->mask |= IMM_RST;
if (uval <= 2)
result->mask |= IMM_IM;
}
return true;
}

/*
Read in a boolean argument from the given line and store it in *result.
*/
DIRECTIVE_PARSE_FUNC(bool, bool)


+ 6
- 3
src/assembler/parse_util.h View File

@@ -13,19 +13,22 @@

/* Functions */

/* General parsers */
bool parse_bool(bool*, const char*, ssize_t);
bool parse_uint32_t(uint32_t*, const char*, ssize_t);
bool parse_string(char**, size_t*, const char*, ssize_t);
bool parse_bytes(uint8_t**, size_t*, const char*, ssize_t);

bool parse_register(ASMArgRegister*, const char*, ssize_t);
bool parse_condition(ASMArgCondition*, const char*, ssize_t);
/* Instruction argument parsers */
bool argparse_register(ASMArgRegister*, const char*, ssize_t);
bool argparse_condition(ASMArgCondition*, const char*, ssize_t);
bool argparse_immediate(ASMArgImmediate*, const char*, ssize_t);

/* Preprocessor directive parsers */
bool dparse_bool(bool*, const ASMLine*, const char*);
bool dparse_uint32_t(uint32_t*, const ASMLine*, const char*);
bool dparse_uint16_t(uint16_t*, const ASMLine*, const char*);
bool dparse_uint8_t(uint8_t*, const ASMLine*, const char*);

bool dparse_rom_size(uint32_t*, const ASMLine*, const char*);
bool dparse_region_string(uint8_t*, const ASMLine*, const char*);
bool dparse_size_code(uint8_t*, const ASMLine*, const char*);

+ 2
- 2
src/assembler/tokenizer.c View File

@@ -63,11 +63,11 @@ static ErrorInfo* add_label_to_table(
ASMSymbolTable *symtable, const ASMLine *line, size_t offset, int8_t slot)
{
ASMArgRegister reg;
if (parse_register(&reg, line->data, line->length - 1))
if (argparse_register(&reg, line->data, line->length - 1))
return error_info_create(line, ET_SYMBOL, ED_SYM_IS_REGISTER);

ASMArgCondition cond;
if (parse_condition(&cond, line->data, line->length - 1))
if (argparse_condition(&cond, line->data, line->length - 1))
return error_info_create(line, ET_SYMBOL, ED_SYM_IS_CONDITION);

char *symbol = strndup(line->data, line->length - 1);


Loading…
Cancel
Save