ld: add support for loading 8-bit immediates
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -43,7 +43,7 @@ struct gbasm_operand_r16 {
|
||||
};
|
||||
|
||||
struct gbasm_operand_imm {
|
||||
uint16_t value;
|
||||
int value;
|
||||
};
|
||||
|
||||
enum gbasm_operand_cond_type {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user