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/dialect.h>
|
||||||
#include <mie/dialect/memref.h>
|
#include <mie/dialect/memref.h>
|
||||||
#include <mie/macros.h>
|
#include <mie/macros.h>
|
||||||
@@ -5,6 +7,11 @@
|
|||||||
#include <mie/type/type-definition.h>
|
#include <mie/type/type-definition.h>
|
||||||
#include <mie/type/type.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_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_ADD_OP(mie_memref_load);
|
||||||
MIE_DIALECT_END()
|
MIE_DIALECT_END()
|
||||||
|
|||||||
@@ -1,14 +1,210 @@
|
|||||||
#include <mie/ctx.h>
|
#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-definition.h>
|
||||||
|
#include <mie/ir/op.h>
|
||||||
#include <mie/macros.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)
|
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;
|
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;
|
return MIE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,13 @@
|
|||||||
struct mie_ctx;
|
struct mie_ctx;
|
||||||
struct mie_dialect;
|
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);
|
MIE_API struct mie_dialect *mie_memref_dialect_create(struct mie_ctx *ctx);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user