|
@@ -60,6 +60,7 @@ static ErrorInfo* parse_data( |
|
|
const ASMLine *line, ASMData **data_ptr, size_t offset) |
|
|
const ASMLine *line, ASMData **data_ptr, size_t offset) |
|
|
{ |
|
|
{ |
|
|
// TODO |
|
|
// TODO |
|
|
|
|
|
DEBUG("parse_data(): %.*s", (int) line->length, line->data) |
|
|
|
|
|
|
|
|
return error_info_create(line, ET_PARSER, ED_PARSE_SYNTAX); |
|
|
return error_info_create(line, ET_PARSER, ED_PARSE_SYNTAX); |
|
|
} |
|
|
} |
|
@@ -74,6 +75,7 @@ static ErrorInfo* parse_instruction( |
|
|
const ASMLine *line, ASMInstruction **inst_ptr, size_t offset) |
|
|
const ASMLine *line, ASMInstruction **inst_ptr, size_t offset) |
|
|
{ |
|
|
{ |
|
|
// TODO |
|
|
// TODO |
|
|
|
|
|
DEBUG("parse_instruction(): %.*s", (int) line->length, line->data) |
|
|
|
|
|
|
|
|
return error_info_create(line, ET_PARSER, ED_PARSE_SYNTAX); |
|
|
return error_info_create(line, ET_PARSER, ED_PARSE_SYNTAX); |
|
|
} |
|
|
} |
|
@@ -119,7 +121,7 @@ static ErrorInfo* check_layout( |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
|
Tokenize ASMLines into ASMInstructions. |
|
|
|
|
|
|
|
|
Tokenize ASMLines into ASMInstructions and ASMData. |
|
|
|
|
|
|
|
|
NULL is returned on success and an ErrorInfo object is returned on failure. |
|
|
NULL is returned on success and an ErrorInfo object is returned on failure. |
|
|
state->instructions, state->data, and state->symtable may or may not be |
|
|
state->instructions, state->data, and state->symtable may or may not be |
|
@@ -196,6 +198,22 @@ static ErrorInfo* tokenize(AssemblerState *state) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
|
|
|
|
Return the smallest ROM size that can contain the given address. |
|
|
|
|
|
|
|
|
|
|
|
This uses bit twiddling hacks up to the largest possible ROM size. |
|
|
|
|
|
*/ |
|
|
|
|
|
static size_t bounding_rom_size(size_t size) |
|
|
|
|
|
{ |
|
|
|
|
|
size |= size >> 1; |
|
|
|
|
|
size |= size >> 2; |
|
|
|
|
|
size |= size >> 4; |
|
|
|
|
|
size |= size >> 8; |
|
|
|
|
|
size |= size >> 16; |
|
|
|
|
|
size++; |
|
|
|
|
|
return size; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
Resolve default placeholder values in assembler state, such as ROM size. |
|
|
Resolve default placeholder values in assembler state, such as ROM size. |
|
|
|
|
|
|
|
|
On success, no new heap objects are allocated. On error, an ErrorInfo |
|
|
On success, no new heap objects are allocated. On error, an ErrorInfo |
|
@@ -206,7 +224,21 @@ static ErrorInfo* resolve_defaults(AssemblerState *state) |
|
|
if (!state->rom_size) { |
|
|
if (!state->rom_size) { |
|
|
state->rom_size = ROM_SIZE_MIN; |
|
|
state->rom_size = ROM_SIZE_MIN; |
|
|
|
|
|
|
|
|
// TODO: use highest instruction too |
|
|
|
|
|
|
|
|
const ASMInstruction *inst = state->instructions; |
|
|
|
|
|
while (inst) { |
|
|
|
|
|
size_t bound = inst->loc.offset + inst->loc.length; |
|
|
|
|
|
if (bound >= state->rom_size) |
|
|
|
|
|
state->rom_size = bounding_rom_size(bound); |
|
|
|
|
|
inst = inst->next; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const ASMData *data = state->data; |
|
|
|
|
|
while (data) { |
|
|
|
|
|
size_t bound = data->loc.offset + data->loc.length; |
|
|
|
|
|
if (bound >= state->rom_size) |
|
|
|
|
|
state->rom_size = bounding_rom_size(bound); |
|
|
|
|
|
data = data->next; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (state->header.rom_size != INVALID_SIZE_CODE) { |
|
|
if (state->header.rom_size != INVALID_SIZE_CODE) { |
|
|
size_t decl_size = size_code_to_bytes(state->header.rom_size); |
|
|
size_t decl_size = size_code_to_bytes(state->header.rom_size); |
|
|