harec

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

commit 1b88738358055b47dcc0220615d74a10db3f9a9e
parent 05f17977b358ab385e0c0043697f05cbff51b672
Author: Drew DeVault <sir@cmpwn.com>
Date:   Thu,  1 Jul 2021 14:18:07 -0400

gen: expand type support somewhat

Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
Minclude/gen.h | 7++++---
Msrc/gen.c | 17+++++++++--------
Msrc/qinstr.c | 52++++++++++++++++++++++++++++++++++++++++++----------
Msrc/qtype.c | 54++++++++++++++++++++++++++++++++++++++++++++++++++----
4 files changed, 105 insertions(+), 25 deletions(-)

diff --git a/include/gen.h b/include/gen.h @@ -20,6 +20,7 @@ struct gen_temp { struct gen_arch { const struct qbe_type *ptr; + const struct qbe_type *sz; }; struct gen_context { @@ -41,11 +42,11 @@ void gen(const struct unit *unit, // qinstr.c enum qbe_instr alloc_for_align(size_t align); -enum qbe_instr store_for_type(const struct type *type); -enum qbe_instr load_for_type(const struct type *type); +enum qbe_instr store_for_type(struct gen_context *ctx, const struct type *type); +enum qbe_instr load_for_type(struct gen_context *ctx, const struct type *type); // qtype.c const struct qbe_type *qtype_lookup(struct gen_context *ctx, - const struct type *type); + const struct type *type, bool xtype); #endif diff --git a/src/gen.c b/src/gen.c @@ -18,14 +18,14 @@ gen_name(struct gen_context *ctx, const char *fmt) return str; } -// Initializes a qval with a reference to a gen temporary. +// Initializes a qval with a qbe temporary for a given gen temporary. static void qval_temp(struct gen_context *ctx, - struct qbe_value *out, - const struct gen_temp *temp) + struct qbe_value *out, + const struct gen_temp *temp) { out->kind = QV_TEMPORARY; - out->type = qtype_lookup(ctx, temp->type); + out->type = qtype_lookup(ctx, temp->type, false); out->name = temp->name; } @@ -60,7 +60,7 @@ load_temp(struct gen_context *ctx, struct qbe_value *out, const struct gen_temp *temp) { - const struct qbe_type *qtype = qtype_lookup(ctx, temp->type); + const struct qbe_type *qtype = qtype_lookup(ctx, temp->type, true); assert(qtype->stype != Q__VOID); out->kind = QV_TEMPORARY; @@ -73,7 +73,7 @@ load_temp(struct gen_context *ctx, struct qbe_value addr; qval_temp(ctx, &addr, temp); - enum qbe_instr instr = load_for_type(temp->type); + enum qbe_instr instr = load_for_type(ctx, temp->type); pushi(ctx->current, out, instr, &addr, NULL); } } @@ -142,7 +142,7 @@ gen_expr_constant(struct gen_context *ctx, abort(); // Invariant } - enum qbe_instr instr = store_for_type(expr->result); + enum qbe_instr instr = store_for_type(ctx, expr->result); pushi(ctx->current, NULL, instr, &qval, &qout, NULL); } @@ -251,7 +251,7 @@ gen_function_decl(struct gen_context *ctx, const struct declaration *decl) if (type_dealias(fntype->func.result)->storage != STORAGE_VOID) { ctx->rval = alloc_temp(ctx, fntype->func.result, "rval.%d"); - qdef->func.returns = qtype_lookup(ctx, fntype->func.result); + qdef->func.returns = qtype_lookup(ctx, fntype->func.result, true); } else { qdef->func.returns = &qbe_void; } @@ -299,6 +299,7 @@ gen(const struct unit *unit, struct type_store *store, struct qbe_program *out) .ns = unit->ns, .arch = { .ptr = &qbe_long, + .sz = &qbe_long, }, }; ctx.out->next = &ctx.out->defs; diff --git a/src/qinstr.c b/src/qinstr.c @@ -1,7 +1,9 @@ #include <assert.h> #include <stdlib.h> +#include "gen.h" #include "qbe.h" #include "types.h" +#include "type_store.h" enum qbe_instr alloc_for_align(size_t align) @@ -19,7 +21,7 @@ alloc_for_align(size_t align) } enum qbe_instr -store_for_type(const struct type *type) +store_for_type(struct gen_context *ctx, const struct type *type) { switch (type->storage) { case STORAGE_CHAR: @@ -43,13 +45,28 @@ store_for_type(const struct type *type) return Q_STORES; case STORAGE_F64: return Q_STORED; - case STORAGE_ENUM: - case STORAGE_POINTER: case STORAGE_SIZE: + switch (ctx->arch.sz->stype) { + case Q_LONG: + return Q_STOREL; + default: + assert(0); + } + break; + case STORAGE_POINTER: case STORAGE_UINTPTR: - assert(0); // TODO + switch (ctx->arch.ptr->stype) { + case Q_LONG: + return Q_STOREL; + default: + assert(0); + } + break; + case STORAGE_ENUM: + return store_for_type(ctx, builtin_type_for_storage( + type->_enum.storage, false)); case STORAGE_ALIAS: - return store_for_type(type->alias.type); + return store_for_type(ctx, type->alias.type); case STORAGE_ARRAY: case STORAGE_FCONST: case STORAGE_FUNCTION: @@ -68,7 +85,7 @@ store_for_type(const struct type *type) } enum qbe_instr -load_for_type(const struct type *type) +load_for_type(struct gen_context *ctx, const struct type *type) { switch (type->storage) { case STORAGE_I8: @@ -95,13 +112,28 @@ load_for_type(const struct type *type) return Q_LOADS; case STORAGE_F64: return Q_LOADD; - case STORAGE_ENUM: - case STORAGE_POINTER: case STORAGE_SIZE: + switch (ctx->arch.sz->stype) { + case Q_LONG: + return Q_LOADL; + default: + assert(0); + } + break; + case STORAGE_POINTER: case STORAGE_UINTPTR: - assert(0); // TODO + switch (ctx->arch.ptr->stype) { + case Q_LONG: + return Q_LOADL; + default: + assert(0); + } + break; + case STORAGE_ENUM: + return load_for_type(ctx, builtin_type_for_storage( + type->_enum.storage, false)); case STORAGE_ALIAS: - return store_for_type(type->alias.type); + return load_for_type(ctx, type->alias.type); case STORAGE_ARRAY: case STORAGE_FCONST: case STORAGE_FUNCTION: diff --git a/src/qtype.c b/src/qtype.c @@ -1,12 +1,58 @@ #include <assert.h> +#include <stdlib.h> #include "gen.h" #include "qbe.h" #include "types.h" const struct qbe_type *qtype_lookup( struct gen_context *ctx, - const struct type *type) { - // TODO - assert(type->storage == STORAGE_INT); - return &qbe_word; + const struct type *type, + bool xtype) { + switch (type->storage) { + case STORAGE_U8: + case STORAGE_I8: + case STORAGE_CHAR: + return xtype ? &qbe_byte : &qbe_word; + case STORAGE_I16: + case STORAGE_U16: + return xtype ? &qbe_half : &qbe_word; + case STORAGE_I32: + case STORAGE_U32: + case STORAGE_INT: + case STORAGE_UINT: + case STORAGE_RUNE: + case STORAGE_BOOL: + return &qbe_word; + case STORAGE_U64: + case STORAGE_I64: + return &qbe_long; + case STORAGE_SIZE: + return ctx->arch.sz; + case STORAGE_UINTPTR: + case STORAGE_POINTER: + return ctx->arch.ptr; + case STORAGE_F32: + return &qbe_single; + case STORAGE_F64: + return &qbe_double; + case STORAGE_ENUM: + assert(0); // TODO + case STORAGE_ALIAS: + return qtype_lookup(ctx, type->alias.type, xtype); + case STORAGE_ARRAY: + case STORAGE_SLICE: + case STORAGE_STRING: + case STORAGE_STRUCT: + case STORAGE_TAGGED: + case STORAGE_TUPLE: + case STORAGE_UNION: + assert(0); // TODO + case STORAGE_VOID: + case STORAGE_FUNCTION: + case STORAGE_NULL: + case STORAGE_FCONST: + case STORAGE_ICONST: + abort(); // Invariant + } + abort(); // Invariant }