harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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:
Minclude/gen.h | 1+
Minclude/qbe.h | 2++
Minclude/scope.h | 3++-
Msrc/gen.c | 19+++++++++++++++++--
Msrc/qbe.c | 2++
Msrc/qtype.c | 40++++++++++++++++++++++++++++++++++++++++
Msrc/scope.c | 2+-
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 = &param->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