#include <assert.h>
Type VoidType = {
- .form = FORM_VOID,
+ .form = FORM_VOID
};
Type BoolType = {
{
Symbol* s = symbol_getbyid(p, var->symid);
char* name = (s->name[0] == '$' ? "" : s->name);
- bool is_global = (s->global || s->class == SYM_PROC) && (s->class != SYM_TYPE);
- char scope = (is_global ? '@' : '%');
- printf("%c%s.%lu", scope, name, var->symver);
+ if ((s->global || s->class == SYM_PROC) && (s->class != SYM_TYPE))
+ {
+ printf("@%s", name);
+ }
+ else
+ {
+ printf("%%%s.%lu", name, var->symver);
+ }
}
static void print_const(Type* type, SsaValue* val)
{
- emit_type(type);
if (type->form == FORM_INT)
{
- printf(" %d", val->val.i);
+ printf(" %lld", val->val.i);
}
else if (type->form == FORM_REAL)
{
}
}
-char* BinOpNames[NUM_TOKENS] = {
- ['+'] = "add",
- ['-'] = "sub",
- ['*'] = "mul",
- ['/'] = "div",
- ['%'] = "rem",
-
-};
-
char* binop_name(SsaNode* node)
{
char* name = NULL;
{
switch(node->code)
{
- case '+': name = "add"; break;
- case '-': name = "sub"; break;
- case '*': name = "mul"; break;
- case '/': name = "div"; break;
- case '%': name = "rem"; break;
+ case '+': name = "add"; break;
+ case '-': name = "sub"; break;
+ case '*': name = "mul"; break;
+ case '/': name = "sdiv"; break;
+ case '%': name = "srem"; break;
case EQ: name = "icmp eq"; break;
case NEQ: name = "icmp ne"; break;
- case LT: name = "icmp slt"; break;
- case GT: name = "icmp sgt"; break;
+ case '<': name = "icmp slt"; break;
+ case '>': name = "icmp sgt"; break;
case LTEQ: name = "icmp sle"; break;
case GTEQ: name = "icmp sge"; break;
}
{
switch(node->code)
{
- case '+': name = "fadd"; break;
- case '-': name = "fsub"; break;
- case '*': name = "fmul"; break;
- case '/': name = "fdiv"; break;
- case '%': name = "frem"; break;
+ case '+': name = "fadd"; break;
+ case '-': name = "fsub"; break;
+ case '*': name = "fmul"; break;
+ case '/': name = "fdiv"; break;
+ case '%': name = "frem"; break;
case EQ: name = "fcmp eq"; break;
case NEQ: name = "fcmp ne"; break;
{
assert(!"not implemented");
}
+ return name;
}
-
-//static void print_dest(Parser* p, SsaNode* node)
-//{
-// if (node->mode != MODE_CONTROL)
-// {
-// print_ident(p, &(node->dest));
-// printf(" = ");
-// }
-//}
-//
-//static void print_opcode(SsaNode* node)
-//{
-// int op = node->code;
-// if (op < 256)
-// {
-// printf(" %c ", op);
-// }
-// else if (op == RETURN)
-// {
-// printf(" return ");
-// }
-// else if (op == IF)
-// {
-// printf("if ");
-// }
-// else if (op == EQ)
-// {
-// printf(" == ");
-// }
-// else if (op == NEQ)
-// {
-// printf(" != ");
-// }
-// else if (op == LTEQ)
-// {
-// printf(" <= ");
-// }
-// else if (op == GTEQ)
-// {
-// printf(" >= ");
-// }
-// else
-// {
-// printf("%d\n", op);
-// }
-//}
-//
-//void print_op(Parser* p, SsaNode* expr)
-//{
-// (void)p;
-// switch(expr->code)
-// {
-// case IDENT:
-// print_ident(p, &(expr->left.var));
-// break;
-//
-// case BOOL:
-// printf("load %%Bool, %d", ssa_asbool(expr));
-// break;
-//
-// case INT:
-// printf("internal constant %%Int %lld", ssa_asint(expr));
-// break;
-//
-// case REAL:
-// printf("load %%Real, %f", ssa_asreal(expr));
-// break;
-//
-// case IF:
-// printf("if ");
-// print_ident(p, &(expr->dest));
-// printf(" then block%lu else block%lu", expr->left.block->id, expr->right.block->id);
-// break;
-//
-// case RETURN:
-// printf("return ");
-// print_ident(p, &(expr->dest));
-// break;
-//
-// default:
-// if (expr->mode == MODE_VAR)
-// {
-// print_ident(p, &(expr->left.var));
-// }
-// else if (expr->mode == MODE_UNOP)
-// {
-// print_opcode(expr);
-// print_ident(p, &(expr->left.var));
-// }
-// else if (expr->mode == MODE_BINOP)
-// {
-// print_ident(p, &(expr->left.var));
-// print_opcode(expr);
-// print_ident(p, &(expr->right.var));
-// }
-// else
-// {
-// printf("??? M:%d C:%d\n", expr->mode, expr->code);
-// }
-// break;
-// }
-//}
-//
-
void print_op(Parser* p, SsaNode* expr)
{
switch(expr->mode)
{
+ case MODE_MEMORY:
+ if (expr->code == LOAD)
+ {
+ printf(" ");
+ print_ident(p, &(expr->dest));
+ printf(" = load ");
+ emit_type(expr->type);
+ printf(", ");
+ emit_type(expr->type);
+ printf("* ");
+ print_ident(p, &(expr->left.var));
+ puts("");
+ }
+ else if (expr->code == STORE)
+ {
+ printf(" store ");
+ emit_type(expr->type);
+ printf(" ");
+ print_ident(p, &(expr->left.var));
+ printf(", ");
+ emit_type(expr->type);
+ printf("* ");
+ print_ident(p, &(expr->dest));
+ puts("");
+ }
+ else
+ {
+ assert(!"not implemented");
+ }
+ break;
+
case MODE_CONTROL:
+ if (expr->code == RETURN)
+ {
+ printf(" ret ");
+ emit_type(expr);
+ puts("");
+ }
break;
case MODE_UNOP:
break;
case MODE_BINOP_LC:
- printf(" %%");
+ printf(" ");
print_ident(p, &(expr->dest));
- printf(" = add ");
+ printf(" = %s ", binop_name(expr));
emit_type(expr->type);
- print_ident(p, &(expr->dest));
+ printf(" ");
+ print_const(expr->type, &(expr->left));
+ printf(", ");
+ print_ident(p, &(expr->right.var));
printf("\n");
break;
case MODE_BINOP_RC:
printf(" ");
print_ident(p, &(expr->dest));
- printf(" = %s ", BinOpNames[expr->code]);
+ printf(" = %s ", binop_name(expr));
emit_type(expr->type);
printf(" ");
print_ident(p, &(expr->left.var));
default:
printf("OP ????\n");
+ assert(!"not implemented");
break;
}
}
printf("{\n");
for (SsaBlock* curr = sorted; curr; curr = curr->next)
{
- if (curr->phis || curr->head)
+ if (curr->head)
{
- printf("L%lu:\n", curr->id);
- }
+ if (curr->head)
+ {
+ printf("L%lu:\n", curr->id);
+ }
- /* print the phis */
- for (SsaPhi* phi = curr->phis; phi; phi = phi->next)
- {
- Symbol* s = symbol_getbyid(p, phi->symid);
- printf(" %%%s.%lu = phi ", s->name, phi->latest_ver);
- emit_type(s->type);
- printf(" ");
- for (SsaPhiVar* var = phi->vars; var; var = var->next)
+ /* print the phis */
+ for (SsaPhi* phi = curr->phis; phi; phi = phi->next)
{
- printf("[%%%s.%lu, %%L%lu]", s->name, var->version, var->block);
- if (var->next)
+ Symbol* s = symbol_getbyid(p, phi->symid);
+ printf(" %%%s.%lu = phi ", s->name, phi->latest_ver);
+ emit_type(s->type);
+ printf(" ");
+ for (SsaPhiVar* var = phi->vars; var; var = var->next)
{
- printf(", ");
+ printf("[%%%s.%lu, %%L%lu]", s->name, var->version, var->block);
+ if (var->next)
+ {
+ printf(", ");
+ }
}
+ puts("");
}
- puts("");
- }
- /* print the instructions */
- for (SsaNode* node = curr->head; node; node = node->next)
- {
- print_op(p, node);
+ /* print the instructions */
+ for (SsaNode* node = curr->head; node; node = node->next)
+ {
+ print_op(p, node);
+ }
}
}
printf("}\n");
{
node = ssa_node(IDENT, MODE_VAR);
node->type = sym->type;
- node->loaded = 1;
+ node->loaded = !sym->global;
node->dest.symid = index;
node->dest.symver = sym->version;
node->left.var.symid = index;
SsaNode* ssa_store(Parser* p, SsaNode* dest, SsaNode* value)
{
load(p, value);
- SsaNode* node = ssa_node('=', MODE_VAR);
+ SsaNode* node = ssa_node(STORE, MODE_MEMORY);
node->type = dest->type;
node->dest = dest->left.var;
node->left.var = value->dest;
SsaNode* ssa_return(Parser* p, SsaNode* expr)
{
- load(p, expr);
SsaNode* node = ssa_node(RETURN, MODE_CONTROL);
- node->type = expr->type;
- node = load(p, node);
- node->dest = expr->dest;
+ if (expr)
+ {
+ load(p, expr);
+ node->type = expr->type;
+ node = load(p, node);
+ node->dest = expr->dest;
+ }
+ else
+ {
+ node->type = &VoidType;
+ node = load(p, node);
+ }
return node;
}
}
else
{
+ left = load(p, left);
+ right = load(p, right);
+
if (left->mode == MODE_CONST)
{
- right = load(p, right);
node = ssa_node(op, MODE_BINOP_LC);
node->left = left->left;
node->right.var = right->dest;
}
else if (right->mode == MODE_CONST)
{
- left = load(p, left);
node = ssa_node(op, MODE_BINOP_RC);
node->left.var = left->dest;
node->right = right->left;
}
else
{
- left = load(p, left);
- right = load(p, right);
node = ssa_node(op, MODE_BINOP);
node->left.var = left->dest;
node->right.var = right->dest;
static SsaNode* load(Parser* p, SsaNode* node)
{
// if (!node->loaded && (node->mode != MODE_CONST) && (node->mode != MODE_VAR))
- if (!node->loaded)
+// if (node->mode == MODE_VAR && node->dest.symid != 0)
+// {
+// Symbol* sym = symbol_getbyid(p, node->dest.symid);
+// printf("load %s\n", sym->name);
+// }
+// else
+ if (!node->loaded && (node->mode != MODE_CONST))
{
+ if (node->mode == MODE_VAR)
+ {
+ node->left.var = node->dest;
+ node->dest.symid = 0;
+ node->mode = MODE_MEMORY;
+ node->code = LOAD;
+ }
+
if (node->dest.symid == 0)
{
Symbol* sym = symbol_getbyid(p, 0);