297 lines
7.2 KiB
C
297 lines
7.2 KiB
C
#include <mie/dialect/dialect.h>
|
|
#include <mie/ir/block.h>
|
|
#include <mie/ir/op-definition.h>
|
|
#include <mie/ir/op.h>
|
|
#include <mie/ir/region.h>
|
|
#include <mie/print/printer.h>
|
|
|
|
void mie_printer_print_op_arg(
|
|
struct mie_printer *printer, const struct mie_op_arg *arg, bool include_type)
|
|
{
|
|
enum mie_register_flags arg_flags = 0;
|
|
const char *arg_name = NULL;
|
|
const struct mie_type *arg_type = NULL;
|
|
|
|
if (MIE_TEST_FLAGS(arg->arg_flags, MIE_OP_F_ARG_RESOLVED)) {
|
|
if (!arg->arg_value.u_reg) {
|
|
arg_flags = 0;
|
|
arg_name = "<NULL>";
|
|
arg_type = NULL;
|
|
} else {
|
|
arg_flags = arg->arg_value.u_reg->reg_flags;
|
|
arg_name = arg->arg_value.u_reg->reg_name.n_str;
|
|
arg_type = arg->arg_value.u_reg->reg_type;
|
|
}
|
|
} else {
|
|
arg_flags = arg->arg_unresolved.reg_flags;
|
|
arg_name = arg->arg_unresolved.reg_name;
|
|
arg_type = arg->arg_unresolved.reg_type;
|
|
}
|
|
|
|
if (arg_flags & MIE_REGISTER_F_MACHINE) {
|
|
b_stream_write_char(printer->p_stream, '$');
|
|
} else {
|
|
b_stream_write_char(printer->p_stream, '%');
|
|
}
|
|
|
|
b_stream_write_string(printer->p_stream, arg_name, NULL);
|
|
|
|
if (!include_type || !arg_type) {
|
|
return;
|
|
}
|
|
|
|
b_stream_write_string(printer->p_stream, ": ", NULL);
|
|
|
|
mie_printer_print_type(printer, arg_type);
|
|
}
|
|
|
|
void mie_printer_print_op_successor(
|
|
struct mie_printer *printer, const struct mie_op_successor *successor,
|
|
bool compact)
|
|
{
|
|
b_stream_write_char(printer->p_stream, '^');
|
|
if (successor->s_flags & MIE_OP_F_SUCCESSOR_RESOLVED) {
|
|
b_stream_write_string(
|
|
printer->p_stream, successor->s_block->b_name.n_str, NULL);
|
|
} else {
|
|
b_stream_write_string(
|
|
printer->p_stream, successor->s_block_name, NULL);
|
|
}
|
|
|
|
if (MIE_VECTOR_COUNT(successor->s_args) == 0) {
|
|
return;
|
|
}
|
|
|
|
if (!compact) {
|
|
b_stream_write_char(printer->p_stream, ':');
|
|
}
|
|
|
|
b_stream_write_char(printer->p_stream, '(');
|
|
|
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(successor->s_args); i++) {
|
|
if (i > 0) {
|
|
b_stream_write_string(printer->p_stream, ", ", NULL);
|
|
}
|
|
|
|
mie_printer_print_op_arg(printer, &successor->s_args.items[i], true);
|
|
}
|
|
|
|
b_stream_write_char(printer->p_stream, ')');
|
|
}
|
|
|
|
static void print_successor_list(
|
|
struct mie_printer *printer, const struct mie_op *op)
|
|
{
|
|
if (!MIE_VECTOR_COUNT(op->op_successors)) {
|
|
return;
|
|
}
|
|
|
|
b_stream_write_string(printer->p_stream, " [ ", NULL);
|
|
|
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_successors); i++) {
|
|
if (i > 0) {
|
|
b_stream_write_string(printer->p_stream, ", ", NULL);
|
|
}
|
|
|
|
mie_printer_print_op_successor(
|
|
printer, &op->op_successors.items[i], false);
|
|
}
|
|
|
|
b_stream_write_string(printer->p_stream, " ]", NULL);
|
|
}
|
|
|
|
static void print_region_list(struct mie_printer *printer, const struct mie_op *op)
|
|
{
|
|
if (b_queue_empty(&op->op_regions)) {
|
|
return;
|
|
}
|
|
|
|
b_stream_write_string(printer->p_stream, " (", NULL);
|
|
|
|
struct mie_region *region = mie_op_get_first_region(op);
|
|
size_t i = 0;
|
|
|
|
while (region) {
|
|
if (i > 0) {
|
|
b_stream_write_string(printer->p_stream, ", ", NULL);
|
|
}
|
|
|
|
mie_printer_print_region(printer, region, 0);
|
|
|
|
region = mie_op_get_next_region(op, region);
|
|
i++;
|
|
}
|
|
|
|
b_stream_write_string(printer->p_stream, ")", NULL);
|
|
}
|
|
|
|
static void print_attribute(
|
|
struct mie_printer *printer, const struct mie_attribute_map_iterator *attrib)
|
|
{
|
|
b_stream_write_fmt(printer->p_stream, NULL, "%s = ", attrib->it_name);
|
|
mie_printer_print_attribute(printer, attrib->it_value);
|
|
}
|
|
|
|
static void print_attribute_list(
|
|
struct mie_printer *printer, const struct mie_op *op)
|
|
{
|
|
if (mie_attribute_map_empty(&op->op_attrib)) {
|
|
return;
|
|
}
|
|
|
|
b_stream_write_string(printer->p_stream, " { ", NULL);
|
|
|
|
struct mie_attribute_map_iterator it;
|
|
enum mie_status status
|
|
= mie_attribute_map_iterator_begin(&it, &op->op_attrib);
|
|
size_t i = 0;
|
|
|
|
while (status == MIE_SUCCESS) {
|
|
if (i > 0) {
|
|
b_stream_write_string(printer->p_stream, ", ", NULL);
|
|
}
|
|
|
|
print_attribute(printer, &it);
|
|
status = mie_attribute_map_iterator_move_next(&it);
|
|
i++;
|
|
}
|
|
|
|
b_stream_write_string(printer->p_stream, " }", NULL);
|
|
}
|
|
|
|
static void print_type_signature(
|
|
struct mie_printer *printer, const struct mie_op *op)
|
|
{
|
|
const struct mie_type *type = NULL;
|
|
b_stream_write_string(printer->p_stream, " : (", NULL);
|
|
|
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_args); i++) {
|
|
if (i > 0) {
|
|
b_stream_write_string(printer->p_stream, ", ", NULL);
|
|
}
|
|
|
|
const struct mie_op_arg *arg = &op->op_args.items[i];
|
|
if (arg->arg_flags & MIE_OP_F_ARG_RESOLVED) {
|
|
type = arg->arg_value.u_reg->reg_type;
|
|
} else {
|
|
type = arg->arg_unresolved.reg_type;
|
|
}
|
|
|
|
mie_printer_print_type(printer, type);
|
|
}
|
|
|
|
b_stream_write_string(printer->p_stream, ") -> ", NULL);
|
|
|
|
if (MIE_VECTOR_COUNT(op->op_result) != 1) {
|
|
b_stream_write_char(printer->p_stream, '(');
|
|
}
|
|
|
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_result); i++) {
|
|
if (i > 0) {
|
|
b_stream_write_string(printer->p_stream, ", ", NULL);
|
|
}
|
|
|
|
type = op->op_result.items[i].reg_type;
|
|
mie_printer_print_type(printer, type);
|
|
}
|
|
|
|
if (MIE_VECTOR_COUNT(op->op_result) != 1) {
|
|
b_stream_write_char(printer->p_stream, ')');
|
|
}
|
|
}
|
|
|
|
static void print_generic_op(struct mie_printer *printer, const struct mie_op *op)
|
|
{
|
|
b_stream_write_char(printer->p_stream, '~');
|
|
|
|
if (op->op_flags & MIE_OP_F_OP_RESOLVED) {
|
|
b_stream_write_fmt(
|
|
printer->p_stream, NULL, "%s.%s",
|
|
op->op_info->op_parent->d_name, op->op_info->op_name);
|
|
} else {
|
|
b_stream_write_string(printer->p_stream, op->op_name, NULL);
|
|
}
|
|
|
|
b_stream_write_char(printer->p_stream, '(');
|
|
|
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_args); i++) {
|
|
if (i > 0) {
|
|
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, ')');
|
|
|
|
print_successor_list(printer, op);
|
|
print_region_list(printer, op);
|
|
print_attribute_list(printer, op);
|
|
print_type_signature(printer, op);
|
|
}
|
|
|
|
void mie_printer_print_op(struct mie_printer *printer, const struct mie_op *op)
|
|
{
|
|
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_result); i++) {
|
|
if (i > 0) {
|
|
b_stream_write_string(printer->p_stream, ", ", NULL);
|
|
}
|
|
|
|
mie_printer_print_register(printer, &op->op_result.items[i], 0);
|
|
}
|
|
|
|
if (MIE_VECTOR_COUNT(op->op_result) > 0) {
|
|
b_stream_write_string(printer->p_stream, " = ", NULL);
|
|
}
|
|
|
|
bool use_generic = !op->op_info || !op->op_info->op_print
|
|
|| printer->p_flags & MIE_PRINT_F_GENERIC;
|
|
|
|
if (use_generic) {
|
|
print_generic_op(printer, op);
|
|
return;
|
|
}
|
|
|
|
mie_printer_print_op_name(printer, op);
|
|
|
|
op->op_info->op_print(printer, op);
|
|
}
|
|
|
|
void mie_printer_print_op_name(struct mie_printer *printer, const struct mie_op *op)
|
|
{
|
|
bool builtin = false;
|
|
bool resolved = false;
|
|
bool generic = false;
|
|
bool abbreviate = false;
|
|
|
|
if (op->op_flags & MIE_OP_F_OP_RESOLVED) {
|
|
resolved = true;
|
|
}
|
|
|
|
if (printer->p_flags & MIE_PRINT_F_ABBREVIATED) {
|
|
abbreviate = true;
|
|
}
|
|
|
|
if (printer->p_flags & MIE_PRINT_F_GENERIC) {
|
|
generic = true;
|
|
b_stream_write_char(printer->p_stream, '~');
|
|
} else if (!strcmp(op->op_info->op_parent->d_name, "builtin")) {
|
|
builtin = true;
|
|
}
|
|
|
|
if (!resolved) {
|
|
b_stream_write_string(printer->p_stream, op->op_name, NULL);
|
|
return;
|
|
}
|
|
|
|
if (generic || !builtin || !abbreviate) {
|
|
b_stream_write_fmt(
|
|
printer->p_stream, NULL, "%s.",
|
|
op->op_info->op_parent->d_name);
|
|
}
|
|
|
|
b_stream_write_string(printer->p_stream, op->op_info->op_name, NULL);
|
|
|
|
return;
|
|
}
|