ref: 2de9ac9347b4e39b641c747ef19fdbfd34b03ee6
parent: 8c020dc669d3ab38062110ee60886bfee8958045
author: Ori Bernstein <[email protected]>
date: Sun Sep 7 20:49:24 EDT 2014
Make blits take into account type alignment. Only use aligned values, conservatively.
--- a/6/isel.c
+++ b/6/isel.c
@@ -372,28 +372,32 @@
return l;
}
-static void blit(Isel *s, Loc *to, Loc *from, size_t dstoff, size_t srcoff, size_t sz)
+static void blit(Isel *s, Loc *to, Loc *from, size_t dstoff, size_t srcoff, size_t sz, size_t align)
{
- size_t i, m, modesz;
- Mode modes[] = {ModeQ, ModeL, ModeW, ModeB, ModeNone};
+ static const Mode modes[] = {
+ [8] = ModeQ,
+ [4] = ModeL,
+ [2] = ModeW,
+ [1] = ModeB
+ };
+ size_t i, modesz;
Loc *sp, *dp; /* pointers to src, dst */
Loc *tmp, *src, *dst; /* source memory, dst memory */
+ assert(modes[align] != ModeNone); /* make sure we have a valid alignment */
sp = inr(s, from);
dp = inr(s, to);
- modesz = 8;
i = 0;
- for (m = 0; modes[m] != ModeNone; m++) {
- tmp = locreg(modes[m]);
+ for (modesz = align; modes[modesz] != ModeNone; modesz /= 2) {
+ tmp = locreg(modes[modesz]);
while (i + modesz <= sz) {
- src = locmem(i + srcoff, sp, NULL, modes[m]);
- dst = locmem(i + dstoff, dp, NULL, modes[m]);
+ src = locmem(i + srcoff, sp, NULL, modes[modesz]);
+ dst = locmem(i + dstoff, dp, NULL, modes[modesz]);
g(s, Imov, src, tmp, NULL);
g(s, Imov, tmp, dst, NULL);
i += modesz;
}
- modesz /= 2;
}
}
@@ -432,7 +436,7 @@
Loc *retloc, *rsp, *ret; /* hard-coded registers */
Loc *stkbump; /* calculated stack offset */
int argsz, argoff;
- size_t i;
+ size_t i, a;
rsp = locphysreg(Rrsp);
if (tybase(exprtype(n))->type == Tyvoid) {
@@ -472,7 +476,8 @@
if (stacknode(n->expr.args[i])) {
src = locreg(ModeQ);
g(s, Ilea, arg, src, NULL);
- blit(s, rsp, src, argoff, 0, size(n->expr.args[i]));
+ a = alignto(1, n->expr.args[i]->expr.type);
+ blit(s, rsp, src, argoff, 0, size(n->expr.args[i]), a);
} else {
dst = locmem(argoff, rsp, NULL, arg->mode);
arg = inri(s, arg);
@@ -497,6 +502,7 @@
Loc *a, *b, *c, *d, *r;
Loc *eax, *edx, *cl; /* x86 wants some hard-coded regs */
Node **args;
+ size_t al;
args = n->expr.args;
eax = locphysreg(Reax);
@@ -683,7 +689,8 @@
case Oblit:
a = selexpr(s, args[0]);
r = selexpr(s, args[1]);
- blit(s, a, r, 0, 0, args[2]->expr.args[0]->lit.intval);
+ al = alignto(1, args[0]->expr.type->sub[0]);
+ blit(s, a, r, 0, 0, args[2]->expr.args[0]->lit.intval, al);
break;
case Otrunc:
a = selexpr(s, args[0]);