summaryrefslogtreecommitdiff
path: root/src/cmd/5c/txt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/5c/txt.c')
-rw-r--r--src/cmd/5c/txt.c61
1 files changed, 45 insertions, 16 deletions
diff --git a/src/cmd/5c/txt.c b/src/cmd/5c/txt.c
index 9dac0312f..0f17cea89 100644
--- a/src/cmd/5c/txt.c
+++ b/src/cmd/5c/txt.c
@@ -388,7 +388,7 @@ err:
void
regsalloc(Node *n, Node *nn)
{
- cursafe = align(cursafe, nn->type, Aaut3);
+ cursafe = align(cursafe, nn->type, Aaut3, nil);
maxargsafe = maxround(maxargsafe, cursafe+curarg);
*n = *nodsafe;
n->xoffset = -(stkoff + cursafe);
@@ -402,22 +402,22 @@ regaalloc1(Node *n, Node *nn)
{
nodreg(n, nn, REGARG);
reg[REGARG]++;
- curarg = align(curarg, nn->type, Aarg1);
- curarg = align(curarg, nn->type, Aarg2);
+ curarg = align(curarg, nn->type, Aarg1, nil);
+ curarg = align(curarg, nn->type, Aarg2, nil);
maxargsafe = maxround(maxargsafe, cursafe+curarg);
}
void
regaalloc(Node *n, Node *nn)
{
- curarg = align(curarg, nn->type, Aarg1);
+ curarg = align(curarg, nn->type, Aarg1, nil);
*n = *nn;
n->op = OINDREG;
n->reg = REGSP;
n->xoffset = curarg + SZ_LONG;
n->complex = 0;
n->addable = 20;
- curarg = align(curarg, nn->type, Aarg2);
+ curarg = align(curarg, nn->type, Aarg2, nil);
maxargsafe = maxround(maxargsafe, cursafe+curarg);
}
@@ -580,7 +580,8 @@ void
gmove(Node *f, Node *t)
{
int ft, tt, a;
- Node nod;
+ Node nod, nod1;
+ Prog *p1;
ft = f->type->etype;
tt = t->type->etype;
@@ -709,21 +710,53 @@ gmove(Node *f, Node *t)
}
break;
case TUINT:
- case TINT:
case TULONG:
+ if(tt == TFLOAT || tt == TDOUBLE) {
+ // ugly and probably longer than necessary,
+ // but vfp has a single instruction for this,
+ // so hopefully it won't last long.
+ //
+ // tmp = f
+ // tmp1 = tmp & 0x80000000
+ // tmp ^= tmp1
+ // t = float(int32(tmp))
+ // if(tmp1)
+ // t += 2147483648.
+ //
+ regalloc(&nod, f, Z);
+ regalloc(&nod1, f, Z);
+ gins(AMOVW, f, &nod);
+ gins(AMOVW, &nod, &nod1);
+ gins(AAND, nodconst(0x80000000), &nod1);
+ gins(AEOR, &nod1, &nod);
+ if(tt == TFLOAT)
+ gins(AMOVWF, &nod, t);
+ else
+ gins(AMOVWD, &nod, t);
+ gins(ACMP, nodconst(0), Z);
+ raddr(&nod1, p);
+ gins(ABEQ, Z, Z);
+ regfree(&nod);
+ regfree(&nod1);
+ p1 = p;
+ regalloc(&nod, t, Z);
+ gins(AMOVF, nodfconst(2147483648.), &nod);
+ gins(AADDF, &nod, t);
+ regfree(&nod);
+ patch(p1, pc);
+ return;
+ }
+ // fall through
+
+ case TINT:
case TLONG:
case TIND:
switch(tt) {
case TDOUBLE:
- case TVLONG:
gins(AMOVWD, f, t);
- if(ft == TULONG) {
- }
return;
case TFLOAT:
gins(AMOVWF, f, t);
- if(ft == TULONG) {
- }
return;
case TINT:
case TUINT:
@@ -741,7 +774,6 @@ gmove(Node *f, Node *t)
case TSHORT:
switch(tt) {
case TDOUBLE:
- case TVLONG:
regalloc(&nod, f, Z);
gins(AMOVH, f, &nod);
gins(AMOVWD, &nod, t);
@@ -771,7 +803,6 @@ gmove(Node *f, Node *t)
case TUSHORT:
switch(tt) {
case TDOUBLE:
- case TVLONG:
regalloc(&nod, f, Z);
gins(AMOVHU, f, &nod);
gins(AMOVWD, &nod, t);
@@ -801,7 +832,6 @@ gmove(Node *f, Node *t)
case TCHAR:
switch(tt) {
case TDOUBLE:
- case TVLONG:
regalloc(&nod, f, Z);
gins(AMOVB, f, &nod);
gins(AMOVWD, &nod, t);
@@ -831,7 +861,6 @@ gmove(Node *f, Node *t)
case TUCHAR:
switch(tt) {
case TDOUBLE:
- case TVLONG:
regalloc(&nod, f, Z);
gins(AMOVBU, f, &nod);
gins(AMOVWD, &nod, t);