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);
|
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,
|
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
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user