harec

[hare] Hare compiler, written in C11 for POSIX OSs
Log | Files | Refs | README | LICENSE

commit 65c2fffa59397876f09f45f114825b44732c8857
parent 39d4cd337cc14b36482c00d837f112a3ef3b2359
Author: Quentin Carbonneaux <quentin@c9x.me>
Date:   Thu, 15 Dec 2022 16:04:59 +0100

use the new qbe 'blit' instruction

This avoids chains of loads/stores and gives
precise information to qbe about the intent.

Signed-off-by: Quentin Carbonneaux <quentin@c9x.me>

Diffstat:
Minclude/qbe.h | 1+
Msrc/gen.c | 32++++----------------------------
Msrc/qbe.c | 1+
3 files changed, 6 insertions(+), 28 deletions(-)

diff --git a/include/qbe.h b/include/qbe.h @@ -72,6 +72,7 @@ enum qbe_instr { Q_ALLOC4, Q_ALLOC8, Q_AND, + Q_BLIT, Q_CALL, Q_CAST, Q_CEQD, diff --git a/src/gen.c b/src/gen.c @@ -101,34 +101,10 @@ gen_copy_aligned(struct gen_context *ctx, gen_copy_memcpy(ctx, dest, src); return; } - enum qbe_instr load, store; - assert(dest.type->align && (dest.type->align & (dest.type->align - 1)) == 0); - switch (dest.type->align) { - case 1: load = Q_LOADUB, store = Q_STOREB; break; - case 2: load = Q_LOADUH, store = Q_STOREH; break; - case 4: load = Q_LOADUW, store = Q_STOREW; break; - default: - assert(dest.type->align == 8); - load = Q_LOADL, store = Q_STOREL; - break; - } - struct qbe_value temp = { - .kind = QV_TEMPORARY, - .type = ctx->arch.ptr, - .name = gen_name(ctx, ".%d"), - }; - struct qbe_value destp = mkcopy(ctx, &dest, ".%d"); - struct qbe_value srcp = mkcopy(ctx, &src, ".%d"); - struct qbe_value align = constl(dest.type->align); - for (size_t offset = 0; offset < dest.type->size; - offset += dest.type->align) { - pushi(ctx->current, &temp, load, &srcp, NULL); - pushi(ctx->current, NULL, store, &temp, &destp, NULL); - if (offset + dest.type->align < dest.type->size) { - pushi(ctx->current, &srcp, Q_ADD, &srcp, &align, NULL); - pushi(ctx->current, &destp, Q_ADD, &destp, &align, NULL); - } - } + struct qbe_value srcv = mkqval(ctx, &src); + struct qbe_value destv = mkqval(ctx, &dest); + struct qbe_value size = constl(dest.type->size); + pushi(ctx->current, NULL, Q_BLIT, &srcv, &destv, &size, NULL); } static void diff --git a/src/qbe.c b/src/qbe.c @@ -47,6 +47,7 @@ const char *qbe_instr[Q_LAST_INSTR] = { [Q_ALLOC4] = "alloc4", [Q_ALLOC8] = "alloc8", [Q_AND] = "and", + [Q_BLIT] = "blit", [Q_CALL] = "call", [Q_CAST] = "cast", [Q_CEQD] = "ceqd",