mirror of
https://github.com/odin-lang/Odin.git
synced 2026-08-14 01:34:35 +00:00
Improve error message for invalid operand kinds
This commit is contained in:
@@ -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")
|
||||
|
||||
|
||||
@@ -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"
|
||||
@@ -341,7 +341,7 @@ struct Asm_amd64 {
|
||||
|
||||
|
||||
|
||||
gb_internal Asm_amd64 g_asm_amd64;
|
||||
gb_global Asm_amd64 g_asm_amd64;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user