Improve error message for invalid operand kinds

This commit is contained in:
gingerBill
2026-08-11 11:56:03 +01:00
parent 400203c344
commit b0364d2c60
4 changed files with 36 additions and 4 deletions

View File

@@ -320,7 +320,7 @@ main :: proc() {
strings.write_string(&sb, "\n\n\n")
fmt.sbprintf(&sb, "gb_internal Asm_{0:s} g_asm_{0:s};\n", ISA_NAME)
fmt.sbprintf(&sb, "gb_global Asm_{0:s} g_asm_{0:s};\n", ISA_NAME)
strings.write_string(&sb, "\n\n\n")

View File

@@ -5,6 +5,26 @@ enum AsmOperandKind : u8 {
AsmOperand_Register_Or_Memory,
AsmOperand_Immediate,
AsmOperand_Label,
AsmOperand_COUNT
};
gb_global String const asm_operand_kind_strings[AsmOperand_COUNT] = {
str_lit(""),
str_lit("register"),
str_lit("memory"),
str_lit("register or memory"),
str_lit("immediate"),
str_lit("label"),
};
gb_global String const asm_operand_kind_expected_strings[AsmOperand_COUNT] = {
str_lit(""),
str_lit("a register"),
str_lit("a memory"),
str_lit("a register or memory"),
str_lit("an immediate"),
str_lit("a label"),
};
#include "asm_tables_amd64.cpp"

View File

@@ -341,7 +341,7 @@ struct Asm_amd64 {
gb_internal Asm_amd64 g_asm_amd64;
gb_global Asm_amd64 g_asm_amd64;

View File

@@ -379,6 +379,9 @@ gb_internal void check_mnemonic(CheckerContext *ctx, AstAsmInstruction *instr, u
auto valid_spots = slice_make<bool>(heap_allocator(), max_count);
defer (slice_free(&valid_spots, heap_allocator()));
auto possible_kinds = slice_make<AsmOperandKind>(heap_allocator(), max_count);
defer (slice_free(&possible_kinds, heap_allocator()));
bool ok = true;
for (auto form : forms) {
int explicit_count = cast(int)form.explicit_count();
@@ -394,6 +397,11 @@ gb_internal void check_mnemonic(CheckerContext *ctx, AstAsmInstruction *instr, u
Operand const *operand = &operands[i];
AsmOperandKind dst_kind = g_asm_amd64.kind_from_operand_type(type);
AsmOperandKind src_kind = determine_asm_operand_kind(operand);
// TODO(bill): Is this even correct logic for determine the best error message for the possible operand kinds?
// for partially correct forms of the instruction?
possible_kinds[i] = dst_kind;
if (dst_kind == src_kind) {
valid_spots[i] = true;
continue;
@@ -404,7 +412,6 @@ gb_internal void check_mnemonic(CheckerContext *ctx, AstAsmInstruction *instr, u
continue;
}
ok = false;
break;
}
if (ok) {
// the result has been found to be correct
@@ -432,7 +439,12 @@ gb_internal void check_mnemonic(CheckerContext *ctx, AstAsmInstruction *instr, u
error(instr->name, "The operands to '%.*s' matched non of the expected encoding forms", LIT(name));
for_array(i, valid_spots) {
if (!valid_spots[i] && i < operands.count) {
error(operands[i].expr, "Invalid operand kind for the asm instruction '%.*s'", LIT(name));
auto kind = possible_kinds[i];
if (kind) {
error(operands[i].expr, "Invalid operand kind for the asm instruction '%.*s', expected %.*s operand", LIT(name), LIT(asm_operand_kind_expected_strings[kind]));
} else {
error(operands[i].expr, "Invalid operand kind for the asm instruction '%.*s'", LIT(name));
}
}
}
}