commit 5101702a6464961b16644b5d2a66359df4e5d418
parent b8ebf6258e998d777f5cd7c72f278786fd6ff420
Author: Drew DeVault <sir@cmpwn.com>
Date: Mon, 21 Dec 2020 13:15:03 -0500
gen: copy parameters to the stack
Diffstat:
7 files changed, 65 insertions(+), 4 deletions(-)
diff --git a/include/gen.h b/include/gen.h
@@ -26,6 +26,7 @@ enum qbe_stype qstype_for_type(const struct type *type);
enum qbe_stype qxtype_for_type(const struct type *type);
const struct qbe_type *qtype_for_type(struct gen_context *ctx,
const struct type *type, bool extended);
+bool type_is_aggregate(const struct type *type);
// qinstr.c
enum qbe_instr alloc_for_align(size_t align);
diff --git a/include/qbe.h b/include/qbe.h
@@ -57,6 +57,7 @@ enum qbe_instr {
Q_ALLOC4,
Q_ALLOC8,
Q_AND,
+ Q_CAST,
Q_CEQD,
Q_CEQL,
Q_CEQS,
@@ -74,6 +75,7 @@ enum qbe_instr {
Q_CNES,
Q_CNEW,
Q_COD,
+ Q_COPY,
Q_COS,
Q_CSGEL,
Q_CSGEW,
diff --git a/include/scope.h b/include/scope.h
@@ -7,6 +7,7 @@
struct scope_object {
struct identifier ident;
const struct type *type;
+ char *alias; // Used during gen
struct scope_object *next;
};
@@ -29,7 +30,7 @@ void scope_free_all(struct scopes *scopes);
void scope_insert(struct scope *scope,
const struct identifier *ident, const struct type *type);
-const struct type *scope_lookup(struct scope *scope,
+const struct scope_object *scope_lookup(struct scope *scope,
const struct identifier *ident);
#endif
diff --git a/src/gen.c b/src/gen.c
@@ -224,11 +224,26 @@ gen_function_decl(struct gen_context *ctx, const struct declaration *decl)
struct qbe_func_param *param, **next = &qdef->func.params;
struct scope_object *obj = decl->func.scope->objects;
while (obj) {
- // TODO: Copy params to the stack (for non-aggregate types)
param = *next = calloc(1, sizeof(struct qbe_func_param));
assert(!obj->ident.ns); // Invariant
param->name = strdup(obj->ident.name);
param->type = qtype_for_type(ctx, obj->type, true);
+
+ if (type_is_aggregate(obj->type)) {
+ assert(0); // TODO
+ } else {
+ struct qbe_value val;
+ alloc_temp(ctx, &val, obj->type, "copy.%d");
+ struct qbe_value src = {
+ .kind = QV_TEMPORARY,
+ .type = param->type,
+ .name = param->name,
+ };
+ gen_store(ctx, &val, &src);
+ free(obj->ident.name);
+ obj->alias = strdup(val.name);
+ }
+
obj = obj->next;
next = ¶m->next;
}
@@ -242,7 +257,7 @@ gen_function_decl(struct gen_context *ctx, const struct declaration *decl)
// TODO: Update for void type
struct qbe_value rval;
- alloc_temp(ctx, &rval, fntype->func.result, "return.%d");
+ alloc_temp(ctx, &rval, fntype->func.result, "ret.%d");
ctx->return_value = &rval;
pushl(&qdef->func, &ctx->id, "body.%d");
diff --git a/src/qbe.c b/src/qbe.c
@@ -59,6 +59,7 @@ const char *qbe_instr[Q_LAST_INSTR] = {
[Q_ALLOC4] = "alloc4",
[Q_ALLOC8] = "alloc8",
[Q_AND] = "and",
+ [Q_CAST] = "cast",
[Q_CEQD] = "ceqd",
[Q_CEQL] = "ceql",
[Q_CEQS] = "ceqs",
@@ -76,6 +77,7 @@ const char *qbe_instr[Q_LAST_INSTR] = {
[Q_CNES] = "cnes",
[Q_CNEW] = "cnew",
[Q_COD] = "cod",
+ [Q_COPY] = "copy",
[Q_COS] = "cos",
[Q_CSGEL] = "csgel",
[Q_CSGEW] = "csgew",
diff --git a/src/qtype.c b/src/qtype.c
@@ -1,4 +1,5 @@
#include <assert.h>
+#include <stdbool.h>
#include "gen.h"
#include "qbe.h"
#include "types.h"
@@ -126,3 +127,42 @@ qtype_for_type(struct gen_context *ctx, const struct type *type, bool extended)
}
assert(0); // Unreachable
}
+
+bool
+type_is_aggregate(const struct type *type)
+{
+ switch (type->storage) {
+ case TYPE_STORAGE_BOOL:
+ case TYPE_STORAGE_CHAR:
+ case TYPE_STORAGE_F32:
+ case TYPE_STORAGE_F64:
+ case TYPE_STORAGE_I16:
+ case TYPE_STORAGE_I32:
+ case TYPE_STORAGE_I64:
+ case TYPE_STORAGE_I8:
+ case TYPE_STORAGE_INT:
+ case TYPE_STORAGE_POINTER:
+ case TYPE_STORAGE_RUNE:
+ case TYPE_STORAGE_SIZE:
+ case TYPE_STORAGE_U16:
+ case TYPE_STORAGE_U32:
+ case TYPE_STORAGE_U64:
+ case TYPE_STORAGE_U8:
+ case TYPE_STORAGE_UINT:
+ case TYPE_STORAGE_UINTPTR:
+ case TYPE_STORAGE_VOID:
+ return false;
+ case TYPE_STORAGE_ALIAS:
+ assert(0); // TODO
+ case TYPE_STORAGE_ARRAY:
+ case TYPE_STORAGE_SLICE:
+ case TYPE_STORAGE_STRING:
+ case TYPE_STORAGE_STRUCT:
+ case TYPE_STORAGE_TAGGED_UNION:
+ case TYPE_STORAGE_UNION:
+ return true;
+ case TYPE_STORAGE_FUNCTION:
+ assert(0); // Invariant
+ }
+ assert(0); // Unreachable
+}
diff --git a/src/scope.c b/src/scope.c
@@ -71,7 +71,7 @@ scope_insert(struct scope *scope,
scope->next = &o->next;
}
-const struct type *
+const struct scope_object *
scope_lookup(struct scope *scope, const struct identifier *ident)
{
assert(0); // TODO