memref: implement print/parse for memref.load()
This commit is contained in:
27
mie/dialect/memref/diag.c
Normal file
27
mie/dialect/memref/diag.c
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <mie/diag/class.h>
|
||||
#include <mie/diag/msg.h>
|
||||
#include <mie/dialect/memref.h>
|
||||
#include <mie/macros.h>
|
||||
|
||||
#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)
|
||||
@@ -1,3 +1,5 @@
|
||||
#include <mie/diag/class.h>
|
||||
#include <mie/diag/msg.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/memref.h>
|
||||
#include <mie/macros.h>
|
||||
@@ -5,6 +7,11 @@
|
||||
#include <mie/type/type-definition.h>
|
||||
#include <mie/type/type.h>
|
||||
|
||||
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()
|
||||
|
||||
@@ -1,14 +1,210 @@
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/diag/diag.h>
|
||||
#include <mie/diag/highlight.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/dialect/memref.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/ir/op.h>
|
||||
#include <mie/macros.h>
|
||||
#include <mie/parse/parser.h>
|
||||
#include <mie/print/printer.h>
|
||||
#include <mie/type/storage.h>
|
||||
#include <mie/type/type.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user