aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2023-11-19 20:25:45 +0200
committerKimplul <kimi.h.kuparinen@gmail.com>2023-11-19 20:25:45 +0200
commitc85e4b4d2411e60af7387dec663ea62b03743eab (patch)
treeae9d6a4f0caf4a24b8636050505490d03aa50047 /src
parent17a27d445295bbaf7c7c470b1e4648635af2f0a3 (diff)
downloadek-c85e4b4d2411e60af7387dec663ea62b03743eab.tar.gz
ek-c85e4b4d2411e60af7387dec663ea62b03743eab.zip
add implicit ret to void functions
Diffstat (limited to 'src')
-rw-r--r--src/actualize.c5
-rw-r--r--src/asm.c22
-rw-r--r--src/ops.c17
3 files changed, 39 insertions, 5 deletions
diff --git a/src/actualize.c b/src/actualize.c
index ab72589..694eca9 100644
--- a/src/actualize.c
+++ b/src/actualize.c
@@ -683,6 +683,11 @@ static int actualize_proc(struct act_state *state,
"no return with non-void return type");
ret = -1;
}
+ /* add 'implicit' return */
+ struct ast_node *body = AST_PROC(actual).body;
+ struct ast_node *r = gen_return(NULL);
+ r->scope = body->scope;
+ ast_append(AST_BLOCK(body).body, r);
}
else if (ast_block_last(actual->_proc.body)->node_type != AST_RETURN) {
/* TODO: something more sophisticated than this */
diff --git a/src/asm.c b/src/asm.c
index 4102265..e2076f5 100644
--- a/src/asm.c
+++ b/src/asm.c
@@ -57,6 +57,17 @@ static int print_stt(struct op *op, FILE *f)
return 0;
}
+static int print_ret(struct op *op, FILE *f)
+{
+ /* technically speaking ret takes a number of inputs, but they should be
+ * marshaled into registers with moves etc. so don't worry about them
+ * here */
+ fprintf(f, "jalr x0, 0(x21)\n");
+ /* eventually add in proper ret alias to assembly language once I go
+ * through calling conventions etc. */
+ return 0;
+}
+
static int print_op(struct op *op, FILE *f)
{
int ret = 0;
@@ -66,6 +77,7 @@ static int print_op(struct op *op, FILE *f)
case OP_LI: ret = print_li(op, f); break;
case OP_MV: ret = print_mv(op, f); break;
case OP_STT: ret = print_stt(op, f); break;
+ case OP_RET: ret = print_ret(op, f); break;
default: abort();
}
@@ -77,7 +89,11 @@ int print_asm(struct ops *ops, const char *output)
FILE *f = fopen(output, "w");
/* main should probably be mangled here as well */
- fprintf(f, "jal x0, main\n");
+ fprintf(f, "jal x21, main\n");
+ /* tell simulator to turn off (very much temp) */
+ fprintf(f, "li x1, 3\n");
+ fprintf(f, "csrrw mpower, x0, x1\n");
+
int ret = 0;
struct op *op = ops->base;
while (op) {
@@ -87,10 +103,6 @@ int print_asm(struct ops *ops, const char *output)
op = op->next;
}
- /* tell simulator to turn off (very much temp) */
- fprintf(f, "li x1, 3\n");
- fprintf(f, "csrrw mpower, x0, x1\n");
-
fclose(f);
return ret;
}
diff --git a/src/ops.c b/src/ops.c
index 625f0cf..9562035 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -252,6 +252,21 @@ static int lower_id(struct ast_node *n, struct ops *ops)
return 0;
}
+static int lower_ret(struct ast_node *n, struct ops *ops)
+{
+ if (AST_RETURN(n).expr) {
+ int ret = lower_op(AST_RETURN(n).expr, ops);
+ if (ret)
+ return ret;
+ }
+
+ struct op *op = append_op(ops, OP_RET);
+ if (AST_RETURN(n).expr)
+ set_reg(&op->inputs, HEAD_OUTPUTS(ops).reg);
+
+ return 0;
+}
+
static int lower_op(struct ast_node *n, struct ops *ops)
{
int ret = 0;
@@ -264,6 +279,7 @@ static int lower_op(struct ast_node *n, struct ops *ops)
case AST_ASSIGN: ret = lower_assign(n, ops); break;
case AST_UNOP: ret = lower_unop(n, ops); break;
case AST_ID: ret = lower_id(n, ops); break;
+ case AST_RETURN: ret = lower_ret(n, ops); break;
default:
semantic_error(n->scope->fctx, n, "unimplemented lowering");
return -1;
@@ -316,6 +332,7 @@ static void print_op(struct op *op)
case OP_LDT: printf("ldt"); break;
case OP_STW: printf("stw"); break;
case OP_LDW: printf("ldw"); break;
+ case OP_RET: printf("ret"); break;
case OP_MV: printf("mv"); break;
default: printf("unimp"); break;
}