harec

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

commit af16fa5d315b6f30b0e999e31c18d763839b7d93
parent 65a8d225e0098a23f8edd929d8b5256add800eda
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sat, 16 Jan 2021 09:55:47 -0500

gen: fix gen_copy for signed b/h types

Diffstat:
Minclude/qbe.h | 4++--
Msrc/gen.c | 8+++++---
Msrc/qbe.c | 16+++++++++++++---
Msrc/qtype.c | 8+++++---
4 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/include/qbe.h b/include/qbe.h @@ -30,7 +30,7 @@ struct qbe_type { // Aggregate types only: char *name; size_t align; - bool is_union; + bool is_union, is_signed; struct qbe_field fields; const struct type *base; }; @@ -46,7 +46,7 @@ extern const struct qbe_type qbe_void, qbe_aggregate; -const struct qbe_type *qtype_for_xtype(enum qbe_stype type); +const struct qbe_type *qtype_for_xtype(enum qbe_stype type, bool is_signed); enum qbe_value_kind { QV_CONST, diff --git a/src/gen.c b/src/gen.c @@ -173,6 +173,9 @@ gen_copy(struct gen_context *ctx, while (field) { temp.type = field->type; + if (temp.type->stype == Q_HALF || temp.type->stype == Q_BYTE) { + temp.type = &qbe_word; + } for (size_t i = field->count; i > 0; --i) { struct qbe_value a, b; @@ -183,10 +186,9 @@ gen_copy(struct gen_context *ctx, case Q_LONG: case Q_SINGLE: case Q_DOUBLE: - // TODO: This might be broken for unsigned types - // b and h pushi(ctx->current, &temp, - load_for_type(field->type->stype, true), + load_for_type(field->type->stype, + field->type->is_signed), &srcp, NULL); pushi(ctx->current, NULL, store_for_type(field->type->stype), diff --git a/src/qbe.c b/src/qbe.c @@ -12,10 +12,20 @@ qbe_byte = { .stype = Q_BYTE, .size = 1, }, +qbe_byte_s = { + .stype = Q_BYTE, + .size = 1, + .is_signed = true, +}, qbe_half = { .stype = Q_HALF, .size = 2, }, +qbe_half_s = { + .stype = Q_HALF, + .size = 2, + .is_signed = true, +}, qbe_word = { .stype = Q_WORD, .size = 4, @@ -42,13 +52,13 @@ qbe_aggregate = { }; const struct qbe_type * -qtype_for_xtype(enum qbe_stype type) +qtype_for_xtype(enum qbe_stype type, bool is_signed) { switch (type) { case Q_BYTE: - return &qbe_byte; + return is_signed ? &qbe_byte_s : &qbe_byte; case Q_HALF: - return &qbe_half; + return is_signed ? &qbe_half_s : &qbe_half; case Q_WORD: return &qbe_word; case Q_LONG: diff --git a/src/qtype.c b/src/qtype.c @@ -238,7 +238,9 @@ qtype_for_type(struct gen_context *ctx, const struct type *type, bool extended) case TYPE_STORAGE_I16: case TYPE_STORAGE_U16: if (extended) { - return qtype_for_xtype(qxtype_for_type(type)); + return qtype_for_xtype( + qxtype_for_type(type), + type_is_signed(type)); } // Fallthrough case TYPE_STORAGE_BOOL: @@ -256,7 +258,7 @@ qtype_for_type(struct gen_context *ctx, const struct type *type, bool extended) case TYPE_STORAGE_F32: case TYPE_STORAGE_F64: case TYPE_STORAGE_VOID: - return qtype_for_xtype(qstype_for_type(type)); + return qtype_for_xtype(qstype_for_type(type), false); case TYPE_STORAGE_ARRAY: case TYPE_STORAGE_ENUM: case TYPE_STORAGE_SLICE: @@ -266,7 +268,7 @@ qtype_for_type(struct gen_context *ctx, const struct type *type, bool extended) case TYPE_STORAGE_UNION: return lookup_aggregate(ctx, type); case TYPE_STORAGE_FUNCTION: - return qtype_for_xtype(Q__AGGREGATE); + return qtype_for_xtype(Q__AGGREGATE, false); case TYPE_STORAGE_ALIAS: return qtype_for_type(ctx, type->alias.type, extended); }