ld: add support for loading 8-bit immediates

This commit is contained in:
2017-05-28 23:46:41 -07:00
parent 6a9e8b06a7
commit 7900ac28ff
5 changed files with 83 additions and 25 deletions

View File

@@ -54,3 +54,13 @@ void gbasm_too_few_args_error(const struct gbasm_parsed_inst *inst,
exit(1); exit(1);
} }
void gbasm_invalid_imm_error(const struct gbasm_parsed_inst *inst,
const struct gbasm_op_info *opcode)
{
gbasm_print_error(
"ERROR: %s:%d out of bounds constant for opcode \"%s\"\n",
inst->file_name, inst->line_num, inst->opcode);
exit(1);
}

View File

@@ -14,4 +14,6 @@ void gbasm_arg_wrong_type_error(const struct gbasm_parsed_inst *inst,
void gbasm_too_few_args_error(const struct gbasm_parsed_inst *inst, void gbasm_too_few_args_error(const struct gbasm_parsed_inst *inst,
const struct gbasm_op_info *opcode); const struct gbasm_op_info *opcode);
void gbasm_invalid_imm_error(const struct gbasm_parsed_inst *inst,
const struct gbasm_op_info *opcode);
#endif #endif

View File

@@ -43,7 +43,7 @@ struct gbasm_operand_r16 {
}; };
struct gbasm_operand_imm { struct gbasm_operand_imm {
uint16_t value; int value;
}; };
enum gbasm_operand_cond_type { enum gbasm_operand_cond_type {

View File

@@ -15,9 +15,10 @@ static bool gbasm_argtype_in_set(uint32_t argtype_set, uint32_t argtype)
return !!(argtype & argtype_set); return !!(argtype & argtype_set);
} }
static bool imm_is_8_bit(uint16_t val) static bool imm_is_8_bit(int val)
{ {
return (val <= 127) && (val >= -128); /* Allow signed or unsigned representation */
return (val <= 255) && (val >= -128);
} }
static int check_no_args(const struct gbasm_parsed_inst *inst, static int check_no_args(const struct gbasm_parsed_inst *inst,
@@ -94,9 +95,13 @@ static int ld_check(const struct gbasm_parsed_inst *inst,
gbasm_arg_wrong_type_error(inst, op_info); gbasm_arg_wrong_type_error(inst, op_info);
} }
if (inst->operands[0].type == GBASM_OPERAND_REG_8 && if (inst->operands[0].type == GBASM_OPERAND_REG_8) {
imm_is_8_bit(inst->operands[1].imm.value)) { if (!imm_is_8_bit(inst->operands[1].imm.value)) {
DEBUG_LOG("inst->operands[1].imm.value = %d",
inst->operands[1].imm.value);
gbasm_invalid_imm_error(inst, op_info);
}
} }
return 0; return 0;

View File

@@ -3,22 +3,40 @@
#include <string.h> #include <string.h>
void init_r8(void); void init_r8_r8(void);
void init_r8_d8(void);
static char ld_r8_src[1024] = { 0 }; /*
* Data for LD R8, R8 tests
*/
static char ld_r8_r8_src[1024] = { 0 };
static uint8_t ld_r8_r8_output[0x40];
static uint8_t ld_r8_output[0x40]; struct gbasm_test r8_r8 = {
.init = init_r8_r8,
.name = "r8/r8",
.asm_source = ld_r8_r8_src,
.expected_output = ld_r8_r8_output,
.expected_output_len = 0,
};
struct gbasm_test r8 = { /*
.init = init_r8, * Data for LD R8, D8 tests
.name = "r8", */
.asm_source = ld_r8_src, static char ld_r8_d8_src[1024] = { 0 };
.expected_output = ld_r8_output, static uint8_t ld_r8_d8_output[0x40];
struct gbasm_test r8_d8 = {
.init = init_r8_d8,
.name = "r8/d8",
.asm_source = ld_r8_d8_src,
.expected_output = ld_r8_d8_output,
.expected_output_len = 0, .expected_output_len = 0,
}; };
static const struct gbasm_test *tests[] = { static const struct gbasm_test *tests[] = {
&r8, &r8_r8,
&r8_d8,
}; };
struct gbasm_tests gbasm_ld_tests = { struct gbasm_tests gbasm_ld_tests = {
@@ -38,7 +56,7 @@ const char *operands[] = {
"A", "A",
}; };
void gen_r8_src(void) void gen_r8_r8_src(void)
{ {
const char *src, *dst; const char *src, *dst;
size_t len = 0; size_t len = 0;
@@ -55,16 +73,16 @@ void gen_r8_src(void)
continue; continue;
} }
len += sprintf(ld_r8_src + len, "ld %s %s\n", src, dst); len += sprintf(ld_r8_r8_src + len, "ld %s %s\n", src, dst);
} }
} }
sprintf(ld_r8_src + len, "halt"); sprintf(ld_r8_r8_src + len, "halt");
DEBUG_LOG("%s", ld_r8_src); DEBUG_LOG("%s", ld_r8_r8_src);
} }
void gen_r8_output(void) void gen_r8_r8_output(void)
{ {
int num_insts = ARRAY_SIZE(operands) * ARRAY_SIZE(operands); int num_insts = ARRAY_SIZE(operands) * ARRAY_SIZE(operands);
int halt_code = 0x76; int halt_code = 0x76;
@@ -75,15 +93,38 @@ void gen_r8_output(void)
continue; continue;
} }
ld_r8_output[i++] = opcode; ld_r8_r8_output[i++] = opcode;
} }
ld_r8_output[i] = halt_code; ld_r8_r8_output[i] = halt_code;
r8.expected_output_len = num_insts; r8_r8.expected_output_len = num_insts;
} }
void init_r8(void) void init_r8_r8(void)
{ {
gen_r8_src(); gen_r8_r8_src();
gen_r8_output(); gen_r8_r8_output();
}
void gen_r8_d8_src(void)
{
snprintf(ld_r8_d8_src,
sizeof(ld_r8_d8_src),
"ld a, $12\n"
"ld b, $0\n"
"ld c, $0xff\n"
"ld d, $127\n"
"ld e, $0xfe\n"
"ld h, $-1\n"
"ld l, $-128");
}
void gen_r8_d8_output(void)
{
}
void init_r8_d8(void)
{
gen_r8_d8_src();
gen_r8_d8_output();
} }