From fc610a6605f8b5e7b3bb6800d63313b609bdfb76 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Mon, 16 Mar 2026 12:00:10 +0000 Subject: [PATCH] memref: implement print/parse for memref.load() --- mie/dialect/memref/diag.c | 27 +++++ mie/dialect/memref/memref.c | 7 ++ mie/dialect/memref/op/load.c | 198 ++++++++++++++++++++++++++++++- mie/include/mie/dialect/memref.h | 7 ++ 4 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 mie/dialect/memref/diag.c diff --git a/mie/dialect/memref/diag.c b/mie/dialect/memref/diag.c new file mode 100644 index 0000000..19b436a --- /dev/null +++ b/mie/dialect/memref/diag.c @@ -0,0 +1,27 @@ +#include +#include +#include +#include + +#define MIE_DIAG_CLASS_PREFIX MIE_MEMREF_E +#define MIE_DIAG_MSG_PREFIX MIE_MEMREF_MSG + +MIE_DIAG_CLASS_LIST_BEGIN(mie_memref_diag) +MIE_DIAG_CLASS_LIST_END(mie_memref_diag) + +MIE_DIAG_MSG_LIST_BEGIN(mie_memref_msg) + MIE_DIAG_MSG( + OP_EXPECTS_MEMREF_ARGUMENT, + "this operation requires a memref parameter.") + MIE_DIAG_MSG( + LAST_MEMREF_RANK_MUST_BE_TYPE, + "the last rank of a memref type must be a type.") + MIE_DIAG_MSG( + MEMREF_MUST_HAVE_AT_LEAST_ONE_RANK, + "memref type must have at least one rank.") + MIE_DIAG_MSG( + OP_RESULT_DETERMINED_BY_LAST_MEMREF_RANK, + "the number and type of operation results is determined by " + "[blue]the " + "type of the last memref rank[reset].") +MIE_DIAG_MSG_LIST_END(mie_memref_msg) diff --git a/mie/dialect/memref/memref.c b/mie/dialect/memref/memref.c index 62beec6..a949545 100644 --- a/mie/dialect/memref/memref.c +++ b/mie/dialect/memref/memref.c @@ -1,3 +1,5 @@ +#include +#include #include #include #include @@ -5,6 +7,11 @@ #include #include +MIE_DIAG_CLASS_LIST_EXTERN(mie_memref_diag); +MIE_DIAG_MSG_LIST_EXTERN(mie_memref_msg); + MIE_DIALECT_BEGIN(mie_memref, struct mie_dialect, "memref") + MIE_DIALECT_DIAG_CLASS_LIST(mie_memref_diag); + MIE_DIALECT_DIAG_MSG_LIST(mie_memref_msg); MIE_DIALECT_ADD_OP(mie_memref_load); MIE_DIALECT_END() diff --git a/mie/dialect/memref/op/load.c b/mie/dialect/memref/op/load.c index e5bf68a..7667ffb 100644 --- a/mie/dialect/memref/op/load.c +++ b/mie/dialect/memref/op/load.c @@ -1,14 +1,210 @@ #include +#include +#include +#include +#include #include +#include #include +#include +#include +#include +#include static enum mie_status print(struct mie_printer *printer, const struct mie_op *op) { + b_stream_write_char(printer->p_stream, ' '); + const struct mie_type *memref_type = NULL; + if (MIE_VECTOR_COUNT(op->op_args) > 0) { + mie_printer_print_op_arg(printer, &op->op_args.items[0], false); + memref_type = mie_op_arg_get_type(&op->op_args.items[0]); + } + + b_stream_write_char(printer->p_stream, '['); + + for (size_t i = 1; i < MIE_VECTOR_COUNT(op->op_args); i++) { + if (i > 1) { + b_stream_write_string(printer->p_stream, ", ", NULL); + } + + mie_printer_print_op_arg(printer, &op->op_args.items[i], false); + } + b_stream_write_char(printer->p_stream, ']'); + + if (memref_type) { + b_stream_write_string(printer->p_stream, " : ", NULL); + mie_printer_print_type(printer, memref_type); + } + return MIE_SUCCESS; } -static enum mie_status parse(struct mie_parser *parser, struct mie_op *out) +static bool parse_param_name( + struct mie_parser *ctx, struct mie_op_arg *out, const char *context) { + memset(out, 0x0, sizeof *out); + b_string *str = mie_parser_get_tempstr(ctx); + + struct mie_file_span loc; + if (mie_parser_parse_vregname(ctx, str, &loc)) { + out->arg_unresolved.reg_name = b_string_steal(str); + out->arg_unresolved.reg_flags = MIE_REGISTER_F_VIRTUAL; + } else if (mie_parser_parse_mregname(ctx, str, &loc)) { + out->arg_unresolved.reg_name = b_string_steal(str); + out->arg_unresolved.reg_flags = MIE_REGISTER_F_MACHINE; + } else { + struct mie_parser_item required[] = { + MIE_PARSE_ITEM_TOKEN(MIE_TOK_VREGNAME), + MIE_PARSE_ITEM_TOKEN(MIE_TOK_MREGNAME), + MIE_PARSE_ITEM_NONE, + }; + mie_parser_report_unexpected_token_v(ctx, required, context); + return false; + } + + out->arg_span = loc; + + return true; +} + +static bool apply_op_result_types( + const struct mie_op *op, const struct mie_type *result_type) +{ + size_t nr_results = 0; + if (!mie_type_is_storage(result_type)) { + if (MIE_VECTOR_COUNT(op->op_result) != 1) { + return false; + } + + op->op_result.items[0].reg_type = result_type; + return true; + } + + const struct mie_storage_type *storage + = (const struct mie_storage_type *)result_type; + nr_results = mie_storage_type_get_nr_parts(storage); + + if (MIE_VECTOR_COUNT(op->op_result) != nr_results) { + return false; + } + + for (size_t i = 0; i < nr_results; i++) { + op->op_result.items[i].reg_type = storage->st_parts.items[i]; + } + + return true; +} + +static enum mie_status parse( + struct mie_parser *parser, struct mie_parser_scope *scope, + struct mie_op *out) +{ + struct mie_op_arg *buf_arg = mie_op_add_arg(out); + if (!mie_parser_parse_parameter( + parser, false, buf_arg, "memref load source")) { + return MIE_ERR_BAD_SYNTAX; + } + + if (!mie_parser_parse_symbol(parser, MIE_SYM_LEFT_BRACKET)) { + mie_parser_report_unexpected_token( + parser, MIE_SYM_LEFT_BRACKET, "memref load index list"); + return MIE_ERR_BAD_SYNTAX; + } + + if (!mie_parser_parse_parameter_list( + parser, false, MIE_VECTOR_REF(out->op_args), + "memref load index")) { + return MIE_ERR_BAD_SYNTAX; + } + +#if 0 + while (1) { + if (mie_parser_parse_symbol(parser, MIE_SYM_RIGHT_BRACKET)) { + break; + } + + if (!mie_parser_parse_symbol(parser, MIE_SYM_COMMA)) { + unsigned int expected[] = { + MIE_SYM_COMMA, + MIE_SYM_RIGHT_BRACKET, + MIE_TOK_NONE, + }; + mie_parser_report_unexpected_token_v( + parser, expected, "memref load index list"); + return MIE_ERR_BAD_SYNTAX; + } + + struct mie_op_arg *index_arg = mie_op_add_arg(out); + if (!parse_param_name(parser, index_arg, "memref load index")) { + return MIE_ERR_BAD_SYNTAX; + } + } +#endif + + if (!mie_parser_parse_symbol(parser, MIE_SYM_RIGHT_BRACKET)) { + mie_parser_report_unexpected_token( + parser, MIE_SYM_RIGHT_BRACKET, "memref load index list"); + return MIE_ERR_BAD_SYNTAX; + } + + if (!mie_parser_parse_symbol(parser, MIE_SYM_COLON)) { + mie_parser_report_unexpected_token( + parser, MIE_SYM_COLON, "memref type"); + return MIE_ERR_BAD_SYNTAX; + } + + const struct mie_type *type = NULL; + struct mie_file_span type_span; + if (!mie_parser_parse_type(parser, "memref type", &type, &type_span)) { + return MIE_ERR_BAD_SYNTAX; + } + + if (!mie_type_is(type, "builtin", "memref")) { + mie_parser_report_error_simple( + parser, "builtin", MIE_BUILTIN_E_INCORRECT_TYPE, + MIE_MEMREF_MSG_OP_EXPECTS_MEMREF_ARGUMENT, &type_span); + return MIE_ERR_BAD_SYNTAX; + } + + size_t nr_ranks = mie_memref_type_get_nr_ranks(type); + if (!nr_ranks) { + mie_parser_report_error_simple( + parser, "builtin", MIE_BUILTIN_E_INVALID_TYPE, + MIE_MEMREF_MSG_MEMREF_MUST_HAVE_AT_LEAST_ONE_RANK, + &type_span); + return MIE_ERR_BAD_SYNTAX; + } + + const struct mie_memref_rank *type_rank + = mie_memref_type_get_rank(type, nr_ranks - 1); + if (type_rank->r_ranktype != MIE_MEMREF_RANK_TYPE) { + mie_parser_report_error_simple( + parser, "builtin", MIE_BUILTIN_E_INVALID_TYPE, + MIE_MEMREF_MSG_LAST_MEMREF_RANK_MUST_BE_TYPE, + &type_rank->r_span); + return MIE_ERR_BAD_SYNTAX; + } + + if (!apply_op_result_types(out, type_rank->r_type)) { + struct mie_file_span results_span; + mie_op_get_results_span(out, &results_span); + struct mie_diag *diag = mie_parser_report_error_simple( + parser, "builtin", + MIE_BUILTIN_E_INCORRECT_NUMBER_OF_RESULTS, + MIE_BUILTIN_MSG_NR_RESULT_NAME_OUTPUT_MISMATCH, + &results_span); + mie_diag_push_msg( + diag, mie_parser_get_mie_ctx(parser), "memref", + MIE_MEMREF_MSG_OP_RESULT_DETERMINED_BY_LAST_MEMREF_RANK); + struct mie_diag_highlight hl[] = { + MIE_DIAG_HL(HINT, type_rank->r_span), + }; + mie_diag_push_snippet( + diag, type_rank->r_span.s_start.c_row, + type_rank->r_span.s_end.c_row, NULL, 0, hl, 1); + return MIE_ERR_BAD_SYNTAX; + } + return MIE_SUCCESS; } diff --git a/mie/include/mie/dialect/memref.h b/mie/include/mie/dialect/memref.h index df27bed..cd5b10f 100644 --- a/mie/include/mie/dialect/memref.h +++ b/mie/include/mie/dialect/memref.h @@ -8,6 +8,13 @@ struct mie_ctx; struct mie_dialect; +enum mie_memref_msg { + MIE_MEMREF_MSG_OP_EXPECTS_MEMREF_ARGUMENT, + MIE_MEMREF_MSG_LAST_MEMREF_RANK_MUST_BE_TYPE, + MIE_MEMREF_MSG_MEMREF_MUST_HAVE_AT_LEAST_ONE_RANK, + MIE_MEMREF_MSG_OP_RESULT_DETERMINED_BY_LAST_MEMREF_RANK, +}; + MIE_API struct mie_dialect *mie_memref_dialect_create(struct mie_ctx *ctx); #endif