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);
}
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,
const struct gbasm_op_info *opcode);
void gbasm_invalid_imm_error(const struct gbasm_parsed_inst *inst,
const struct gbasm_op_info *opcode);
#endif

View File

@@ -43,7 +43,7 @@ struct gbasm_operand_r16 {
};
struct gbasm_operand_imm {
uint16_t value;
int value;
};
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);
}
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,
@@ -94,9 +95,13 @@ static int ld_check(const struct gbasm_parsed_inst *inst,
gbasm_arg_wrong_type_error(inst, op_info);
}
if (inst->operands[0].type == GBASM_OPERAND_REG_8 &&
imm_is_8_bit(inst->operands[1].imm.value)) {
if (inst->operands[0].type == GBASM_OPERAND_REG_8) {
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;

View File

@@ -3,22 +3,40 @@
#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,
.name = "r8",
.asm_source = ld_r8_src,
.expected_output = ld_r8_output,
/*
* Data for LD R8, D8 tests
*/
static char ld_r8_d8_src[1024] = { 0 };
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,
};
static const struct gbasm_test *tests[] = {
&r8,
&r8_r8,
&r8_d8,
};
struct gbasm_tests gbasm_ld_tests = {
@@ -38,7 +56,7 @@ const char *operands[] = {
"A",
};
void gen_r8_src(void)
void gen_r8_r8_src(void)
{
const char *src, *dst;
size_t len = 0;
@@ -55,16 +73,16 @@ void gen_r8_src(void)
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 halt_code = 0x76;
@@ -75,15 +93,38 @@ void gen_r8_output(void)
continue;
}
ld_r8_output[i++] = opcode;
ld_r8_r8_output[i++] = opcode;
}
ld_r8_output[i] = halt_code;
r8.expected_output_len = num_insts;
ld_r8_r8_output[i] = halt_code;
r8_r8.expected_output_len = num_insts;
}
void init_r8(void)
void init_r8_r8(void)
{
gen_r8_src();
gen_r8_output();
gen_r8_r8_src();
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();
}