Browse Source

Implement indexed addressing, plus some bugfixes.

master
Ben Kurtovic 9 years ago
parent
commit
baa1c6f0e9
3 changed files with 81 additions and 17 deletions
  1. +2
    -7
      src/assembler/instructions.c
  2. +78
    -10
      src/assembler/parse_util.c
  3. +1
    -0
      src/assembler/parse_util.h

+ 2
- 7
src/assembler/instructions.c View File

@@ -156,10 +156,7 @@ static ASMErrorDesc parse_arg(
USE_PARSER(register, AT_REGISTER, reg)
USE_PARSER(immediate, AT_IMMEDIATE, imm)
USE_PARSER(indirect, AT_INDIRECT, indirect)

// AT_INDEXED
// ASMArgIndexed index;

USE_PARSER(indexed, AT_INDEXED, index)
USE_PARSER(condition, AT_CONDITION, cond)

// AT_LABEL
@@ -202,7 +199,7 @@ static ASMErrorDesc parse_args(
} else {
if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
c == ' ' || c == '+' || c == '-' || c == '(' || c == ')' ||
c == '_' || c == '.')
c == '$' || c == '_' || c == '.')
i++;
else
return ED_PS_ARG_SYNTAX;
@@ -352,8 +349,6 @@ ASMInstParser get_inst_parser(char mstr[MAX_MNEMONIC_SIZE])
// single 32-bit value to do fast lookups:
uint32_t key = (mstr[0] << 24) + (mstr[1] << 16) + (mstr[2] << 8) + mstr[3];

DEBUG("get_inst_parser(): -->%.*s<-- 0x%08X", MAX_MNEMONIC_SIZE, mstr, key)

HANDLE(nop)
HANDLE(inc)
HANDLE(add)


+ 78
- 10
src/assembler/parse_util.c View File

@@ -25,6 +25,37 @@
*/

/*
Adjust *arg_ptr / *size_ptr for an indirect argument, like (hl) or (ix+*).

*size_ptr must be > 2 to begin with, and is assured to be > 0 on success.
The two arguments are not modified on failure.
*/
static bool adjust_for_indirection(const char **arg_ptr, ssize_t *size_ptr)
{
const char *arg = *arg_ptr;
ssize_t size = *size_ptr;

if (arg[0] != '(' || arg[size - 1] != ')')
return false;
arg++;
size -= 2;

if (arg[0] == ' ') {
arg++;
if (--size <= 0)
return false;
}
if (arg[size - 1] == ' ') {
if (--size <= 0)
return false;
}

*arg_ptr = arg;
*size_ptr = size;
return true;
}

/*
Read in a boolean value and store it in *result.
*/
bool parse_bool(bool *result, const char *arg, ssize_t size)
@@ -283,10 +314,10 @@ bool argparse_immediate(ASMArgImmediate *result, const char *arg, ssize_t size)
}

uint32_t uval;
if (!parse_uint32_t(&uval, arg, size) || uval > UINT16_MAX)
if (!parse_uint32_t(&uval, arg + i, size - i) || uval > UINT16_MAX)
return false;

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

@@ -294,15 +325,19 @@ bool argparse_immediate(ASMArgImmediate *result, const char *arg, ssize_t size)
result->sval = sval;
result->mask = 0;

if (negative) {
if (sval >= INT8_MIN && sval <= INT8_MAX)
if (sval < 0) {
if (sval >= INT8_MIN)
result->mask |= IMM_S8;
if (sval >= INT8_MIN + 2 && sval <= INT8_MAX + 2)
if (sval >= INT8_MIN + 2)
result->mask |= IMM_REL;
} else {
result->mask = IMM_U16;
if (uval <= UINT8_MAX)
result->mask |= IMM_U8;
if (uval <= INT8_MAX)
result->mask |= IMM_S8;
if (uval <= INT8_MAX + 2)
result->mask |= IMM_REL;
if (uval <= 7)
result->mask |= IMM_BIT;
if (!(uval & ~0x38))
@@ -318,12 +353,8 @@ bool argparse_immediate(ASMArgImmediate *result, const char *arg, ssize_t size)
*/
bool argparse_indirect(ASMArgIndirect *result, const char *arg, ssize_t size)
{
if (size < 3)
return false;
if (arg[0] != '(' || arg[size - 1] != ')')
if (size < 3 || !adjust_for_indirection(&arg, &size))
return false;
arg++;
size -= 2;

ASMArgRegister reg;
ASMArgImmediate imm;
@@ -344,6 +375,43 @@ bool argparse_indirect(ASMArgIndirect *result, const char *arg, ssize_t size)
}

/*
Read in an indexed argument and store it in *result.
*/
bool argparse_indexed(ASMArgIndexed *result, const char *arg, ssize_t size)
{
if (size < 4 || !adjust_for_indirection(&arg, &size) || size < 2)
return false;

ASMArgRegister reg;
if (arg[0] != 'i')
return false;
if (arg[1] == 'x')
reg = REG_IX;
else if (arg[1] == 'y')
reg = REG_IY;
else
return false;

arg += 2;
size -= 2;
if (size > 0 && arg[0] == ' ') {
arg++;
size--;
}

if (size > 0) {
ASMArgImmediate imm;
if (!argparse_immediate(&imm, arg, size) || !(imm.mask & IMM_S8))
return false;
result->offset = imm.sval;
} else {
result->offset = 0;
}
result->reg = reg;
return true;
}

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


+ 1
- 0
src/assembler/parse_util.h View File

@@ -24,6 +24,7 @@ bool argparse_register(ASMArgRegister*, const char*, ssize_t);
bool argparse_condition(ASMArgCondition*, const char*, ssize_t);
bool argparse_immediate(ASMArgImmediate*, const char*, ssize_t);
bool argparse_indirect(ASMArgIndirect*, const char*, ssize_t);
bool argparse_indexed(ASMArgIndexed*, const char*, ssize_t);

/* Preprocessor directive parsers */
bool dparse_bool(bool*, const ASMLine*, const char*);


Loading…
Cancel
Save