1
0
mirror of https://github.com/golang/go synced 2024-11-25 05:57:57 -07:00

last of the arm conversions

R=rsc
CC=golang-dev
https://golang.org/cl/3053041
This commit is contained in:
Ken Thompson 2010-11-11 19:54:35 -08:00
parent 6498c1d468
commit 8613eb56b2
7 changed files with 204 additions and 134 deletions

View File

@ -769,49 +769,55 @@ gmove(Node *f, Node *t)
*/ */
case CASE(TFLOAT32, TINT8): case CASE(TFLOAT32, TINT8):
case CASE(TFLOAT32, TUINT8): case CASE(TFLOAT32, TUINT8):
fa = AMOVF;
a = AMOVFW;
ta = AMOVB;
goto fltconv;
case CASE(TFLOAT32, TINT16): case CASE(TFLOAT32, TINT16):
case CASE(TFLOAT32, TUINT16): case CASE(TFLOAT32, TUINT16):
fa = AMOVF;
a = AMOVFW;
ta = AMOVH;
goto fltconv;
case CASE(TFLOAT32, TINT32): case CASE(TFLOAT32, TINT32):
case CASE(TFLOAT32, TUINT32): case CASE(TFLOAT32, TUINT32):
fa = AMOVF; // case CASE(TFLOAT32, TUINT64):
a = AMOVFW;
ta = AMOVW;
goto fltconv;
case CASE(TFLOAT64, TINT8): case CASE(TFLOAT64, TINT8):
case CASE(TFLOAT64, TUINT8): case CASE(TFLOAT64, TUINT8):
fa = AMOVD;
a = AMOVDW;
ta = AMOVB;
goto fltconv;
case CASE(TFLOAT64, TINT16): case CASE(TFLOAT64, TINT16):
case CASE(TFLOAT64, TUINT16): case CASE(TFLOAT64, TUINT16):
fa = AMOVD;
a = AMOVDW;
ta = AMOVH;
goto fltconv;
case CASE(TFLOAT64, TINT32): case CASE(TFLOAT64, TINT32):
case CASE(TFLOAT64, TUINT32): case CASE(TFLOAT64, TUINT32):
// case CASE(TFLOAT64, TUINT64):
fa = AMOVF;
a = AMOVFW;
if(ft == TFLOAT64) {
fa = AMOVD; fa = AMOVD;
a = AMOVDW; a = AMOVDW;
}
ta = AMOVW; ta = AMOVW;
goto fltconv; switch(tt) {
case TINT8:
ta = AMOVB;
break;
case TUINT8:
ta = AMOVBU;
break;
case TINT16:
ta = AMOVH;
break;
case TUINT16:
ta = AMOVHU;
break;
}
case CASE(TFLOAT32, TUINT64): regalloc(&r1, types[ft], f);
case CASE(TFLOAT64, TUINT64): regalloc(&r2, types[tt], t);
fatal("gmove TFLOAT, UINT64 not implemented"); gins(fa, f, &r1); // load to fpu
p1 = gins(a, &r1, &r1); // convert to w
switch(tt) {
case TUINT8:
case TUINT16:
case TUINT32:
p1->scond |= C_UBIT;
}
gins(AMOVW, &r1, &r2); // copy to cpu
gins(ta, &r2, t); // store
regfree(&r1);
regfree(&r2);
return; return;
/* /*
@ -819,45 +825,52 @@ gmove(Node *f, Node *t)
*/ */
case CASE(TINT8, TFLOAT32): case CASE(TINT8, TFLOAT32):
case CASE(TUINT8, TFLOAT32): case CASE(TUINT8, TFLOAT32):
fa = AMOVB;
a = AMOVWF;
ta = AMOVF;
goto fltconv;
case CASE(TINT16, TFLOAT32): case CASE(TINT16, TFLOAT32):
case CASE(TUINT16, TFLOAT32): case CASE(TUINT16, TFLOAT32):
fa = AMOVH;
a = AMOVWF;
ta = AMOVF;
goto fltconv;
case CASE(TINT32, TFLOAT32): case CASE(TINT32, TFLOAT32):
case CASE(TUINT32, TFLOAT32): case CASE(TUINT32, TFLOAT32):
fa = AMOVW;
a = AMOVWF;
ta = AMOVF;
goto fltconv;
case CASE(TINT8, TFLOAT64): case CASE(TINT8, TFLOAT64):
case CASE(TUINT8, TFLOAT64): case CASE(TUINT8, TFLOAT64):
fa = AMOVB;
a = AMOVWD;
ta = AMOVD;
goto fltconv;
case CASE(TINT16, TFLOAT64): case CASE(TINT16, TFLOAT64):
case CASE(TUINT16, TFLOAT64): case CASE(TUINT16, TFLOAT64):
fa = AMOVH;
a = AMOVWD;
ta = AMOVD;
goto fltconv;
case CASE(TINT32, TFLOAT64): case CASE(TINT32, TFLOAT64):
case CASE(TUINT32, TFLOAT64): case CASE(TUINT32, TFLOAT64):
fa = AMOVW; fa = AMOVW;
switch(ft) {
case TINT8:
fa = AMOVB;
break;
case TUINT8:
fa = AMOVBU;
break;
case TINT16:
fa = AMOVH;
break;
case TUINT16:
fa = AMOVHU;
break;
}
a = AMOVWF;
ta = AMOVF;
if(tt == TFLOAT64) {
a = AMOVWD; a = AMOVWD;
ta = AMOVD; ta = AMOVD;
goto fltconv; }
regalloc(&r1, types[ft], f);
regalloc(&r2, types[tt], t);
gins(fa, f, &r1); // load to cpu
gins(AMOVW, &r1, &r2); // copy to fpu
p1 = gins(a, &r2, &r2); // convert
switch(ft) {
case TUINT8:
case TUINT16:
case TUINT32:
p1->scond |= C_UBIT;
}
gins(ta, &r2, t); // store
regfree(&r1);
regfree(&r2);
return;
case CASE(TUINT64, TFLOAT32): case CASE(TUINT64, TFLOAT32):
case CASE(TUINT64, TFLOAT64): case CASE(TUINT64, TFLOAT64):
@ -924,16 +937,6 @@ trunc64:
splitclean(); splitclean();
return; return;
fltconv:
regalloc(&r1, types[ft], f);
regalloc(&r2, types[tt], t);
gins(fa, f, &r1);
gins(a, &r1, &r2);
gins(ta, &r2, t);
regfree(&r1);
regfree(&r2);
return;
fatal: fatal:
// should not happen // should not happen
fatal("gmove %N -> %N", f, t); fatal("gmove %N -> %N", f, t);

View File

@ -189,7 +189,7 @@ enum as
#define C_PBIT (1<<5) #define C_PBIT (1<<5)
#define C_WBIT (1<<6) #define C_WBIT (1<<6)
#define C_FBIT (1<<7) /* psr flags-only */ #define C_FBIT (1<<7) /* psr flags-only */
#define C_UBIT (1<<7) /* up bit */ #define C_UBIT (1<<7) /* up bit, unsigned bit */
#define C_SCOND_EQ 0 #define C_SCOND_EQ 0
#define C_SCOND_NE 1 #define C_SCOND_NE 1

View File

@ -1257,32 +1257,6 @@ if(debug['G']) print("%ux: %s: arm %d %d %d\n", (uint32)(p->pc), p->from.sym->na
o1 |= rf | (r<<16) | (rt<<12); o1 |= rf | (r<<16) | (rt<<12);
break; break;
case 55: /* floating point fix and float */
rf = p->from.reg;
rt = p->to.reg;
if(p->from.type == D_REG) {
// MOV R,FTMP
o1 = oprrr(AMOVWF+AEND, p->scond);
o1 |= (FREGTMP<<16);
o1 |= (rf<<12);
// CVT FTMP,F
o2 = oprrr(p->as, p->scond);
o2 |= (FREGTMP<<0);
o2 |= (rt<<12);
} else {
// CVT F,FTMP
o1 = oprrr(p->as, p->scond);
o1 |= (rf<<0);
o1 |= (FREGTMP<<12);
// MOV FTMP,R
o2 = oprrr(AMOVFW+AEND, p->scond);
o2 |= (FREGTMP<<16);
o2 |= (rt<<12);
}
break;
case 56: /* move to FP[CS]R */ case 56: /* move to FP[CS]R */
o1 = ((p->scond & C_SCOND) << 28) | (0xe << 24) | (1<<8) | (1<<4); o1 = ((p->scond & C_SCOND) << 28) | (0xe << 24) | (1<<8) | (1<<4);
o1 |= ((p->to.reg+1)<<21) | (p->from.reg << 12); o1 |= ((p->to.reg+1)<<21) | (p->from.reg << 12);
@ -1520,8 +1494,7 @@ if(debug['G']) print("%ux: %s: arm %d %d %d\n", (uint32)(p->pc), p->from.sym->na
o1 |= p->to.reg << 12; o1 |= p->to.reg << 12;
o1 |= (p->scond & C_SCOND) << 28; o1 |= (p->scond & C_SCOND) << 28;
break; break;
case 80: /* fmov zfcon,freg */
case 80: /* fmov zfcon,reg */
if((p->scond & C_SCOND) != C_SCOND_NONE) if((p->scond & C_SCOND) != C_SCOND_NONE)
diag("floating point cannot be conditional"); // cant happen diag("floating point cannot be conditional"); // cant happen
o1 = 0xf3000110; // EOR 64 o1 = 0xf3000110; // EOR 64
@ -1532,7 +1505,7 @@ if(debug['G']) print("%ux: %s: arm %d %d %d\n", (uint32)(p->pc), p->from.sym->na
o1 |= r << 12; o1 |= r << 12;
o1 |= r << 16; o1 |= r << 16;
break; break;
case 81: /* fmov sfcon,reg */ case 81: /* fmov sfcon,freg */
o1 = 0x0eb00a00; // VMOV imm 32 o1 = 0x0eb00a00; // VMOV imm 32
if(p->as == AMOVD) if(p->as == AMOVD)
o1 = 0xeeb00b00; // VMOV imm 64 o1 = 0xeeb00b00; // VMOV imm 64
@ -1542,16 +1515,56 @@ if(debug['G']) print("%ux: %s: arm %d %d %d\n", (uint32)(p->pc), p->from.sym->na
o1 |= (v&0xf) << 0; o1 |= (v&0xf) << 0;
o1 |= (v&0xf0) << 12; o1 |= (v&0xf0) << 12;
break; break;
case 82: /* fcmp reg,reg, */ case 82: /* fcmp freg,freg, */
o1 = oprrr(p->as, p->scond); o1 = oprrr(p->as, p->scond);
r = p->reg; o1 |= (p->reg<<12) | (p->from.reg<<0);
if(r == NREG) {
o1 |= (p->from.reg<<12) | (1<<16);
} else
o1 |= (r<<12) | (p->from.reg<<0);
o2 = 0x0ef1fa10; // VMRS R15 o2 = 0x0ef1fa10; // VMRS R15
o2 |= (p->scond & C_SCOND) << 28; o2 |= (p->scond & C_SCOND) << 28;
break; break;
case 83: /* fcmp freg,, */
o1 = oprrr(p->as, p->scond);
o1 |= (p->from.reg<<12) | (1<<16);
o2 = 0x0ef1fa10; // VMRS R15
o2 |= (p->scond & C_SCOND) << 28;
break;
case 84: /* movfw freg,freg - truncate float-to-fix */
o1 = oprrr(p->as, p->scond);
o1 |= (p->from.reg<<0);
o1 |= (p->to.reg<<12);
break;
case 85: /* movwf freg,freg - fix-to-float */
o1 = oprrr(p->as, p->scond);
o1 |= (p->from.reg<<0);
o1 |= (p->to.reg<<12);
break;
case 86: /* movfw freg,reg - truncate float-to-fix */
// macro for movfw freg,FTMP; movw FTMP,reg
o1 = oprrr(p->as, p->scond);
o1 |= (p->from.reg<<0);
o1 |= (FREGTMP<<12);
o2 = oprrr(AMOVFW+AEND, p->scond);
o2 |= (FREGTMP<<16);
o2 |= (p->to.reg<<12);
break;
case 87: /* movwf reg,freg - fix-to-float */
// macro for movw reg,FTMP; movwf FTMP,freg
o1 = oprrr(AMOVWF+AEND, p->scond);
o1 |= (p->from.reg<<12);
o1 |= (FREGTMP<<16);
o2 = oprrr(p->as, p->scond);
o2 |= (FREGTMP<<0);
o2 |= (p->to.reg<<12);
break;
case 88: /* movw reg,freg */
o1 = oprrr(AMOVWF+AEND, p->scond);
o1 |= (p->from.reg<<12);
o1 |= (p->to.reg<<16);
break;
case 89: /* movw freg,reg */
o1 = oprrr(AMOVFW+AEND, p->scond);
o1 |= (p->from.reg<<16);
o1 |= (p->to.reg<<12);
break;
} }
out[0] = o1; out[0] = o1;
@ -1677,14 +1690,27 @@ oprrr(int a, int sc)
case AMOVFD: return o | (0xe<<24) | (0xb<<20) | (7<<16) | (0xa<<8) | (0xc<<4) | case AMOVFD: return o | (0xe<<24) | (0xb<<20) | (7<<16) | (0xa<<8) | (0xc<<4) |
(0<<8); // dtof (0<<8); // dtof
case AMOVWF: return o | (0xe<<24) | (0xb<<20) | (8<<16) | (0xa<<8) | (4<<4) | case AMOVWF:
(0<<18) | (0<<16) | (0<<8) | (1<<7); // toint, signed, double, round if((sc & C_UBIT) == 0)
case AMOVWD: return o | (0xe<<24) | (0xb<<20) | (8<<16) | (0xa<<8) | (4<<4) | o |= 1<<7; /* signed */
(0<<18) | (0<<16) | (1<<8) | (1<<7); // toint, signed, double, round return o | (0xe<<24) | (0xb<<20) | (8<<16) | (0xa<<8) | (4<<4) |
case AMOVFW: return o | (0xe<<24) | (0xb<<20) | (8<<16) | (0xa<<8) | (4<<4) | (0<<18) | (0<<8); // toint, double
(1<<18) | (0<<16) | (0<<8) | (1<<7); // toint, signed, double, round case AMOVWD:
case AMOVDW: return o | (0xe<<24) | (0xb<<20) | (8<<16) | (0xa<<8) | (4<<4) | if((sc & C_UBIT) == 0)
(1<<18) | (0<<16) | (1<<8) | (1<<7); // toint, signed, double, round o |= 1<<7; /* signed */
return o | (0xe<<24) | (0xb<<20) | (8<<16) | (0xa<<8) | (4<<4) |
(0<<18) | (1<<8); // toint, double
case AMOVFW:
if((sc & C_UBIT) == 0)
o |= 1<<16; /* signed */
return o | (0xe<<24) | (0xb<<20) | (8<<16) | (0xa<<8) | (4<<4) |
(1<<18) | (0<<8) | (1<<7); // toint, double, trunc
case AMOVDW:
if((sc & C_UBIT) == 0)
o |= 1<<16; /* signed */
return o | (0xe<<24) | (0xb<<20) | (8<<16) | (0xa<<8) | (4<<4) |
(1<<18) | (1<<8) | (1<<7); // toint, double, trunc
case AMOVWF+AEND: // copy WtoF case AMOVWF+AEND: // copy WtoF
return o | (0xe<<24) | (0x0<<20) | (0xb<<8) | (1<<4); return o | (0xe<<24) | (0x0<<20) | (0xb<<8) | (1<<4);

View File

@ -195,14 +195,6 @@ Optab optab[] =
{ AADDF, C_FREG, C_REG, C_FREG, 54, 4, 0 }, { AADDF, C_FREG, C_REG, C_FREG, 54, 4, 0 },
{ AMOVF, C_FREG, C_NONE, C_FREG, 54, 4, 0 }, { AMOVF, C_FREG, C_NONE, C_FREG, 54, 4, 0 },
{ AMOVF, C_ZFCON,C_NONE, C_FREG, 80, 4, 0 },
{ AMOVF, C_SFCON,C_NONE, C_FREG, 81, 4, 0 },
{ ACMPF, C_FREG, C_REG, C_NONE, 82, 8, 0 },
// { ACMPF, C_FREG, C_NONE, C_NONE, 82, 8, 0 },
{ AMOVFW, C_FREG, C_NONE, C_REG, 55, 8, 0 },
{ AMOVFW, C_REG, C_NONE, C_FREG, 55, 8, 0 },
{ AMOVW, C_REG, C_NONE, C_FCR, 56, 4, 0 }, { AMOVW, C_REG, C_NONE, C_FCR, 56, 4, 0 },
{ AMOVW, C_FCR, C_NONE, C_REG, 57, 4, 0 }, { AMOVW, C_FCR, C_NONE, C_REG, 57, 4, 0 },
@ -244,5 +236,20 @@ Optab optab[] =
{ ALDREX, C_SOREG,C_NONE, C_REG, 77, 4, 0 }, { ALDREX, C_SOREG,C_NONE, C_REG, 77, 4, 0 },
{ ASTREX, C_SOREG,C_REG, C_REG, 78, 4, 0 }, { ASTREX, C_SOREG,C_REG, C_REG, 78, 4, 0 },
{ AMOVF, C_ZFCON,C_NONE, C_FREG, 80, 4, 0 },
{ AMOVF, C_SFCON,C_NONE, C_FREG, 81, 4, 0 },
{ ACMPF, C_FREG, C_REG, C_NONE, 82, 8, 0 },
{ ACMPF, C_FREG, C_NONE, C_NONE, 83, 8, 0 },
{ AMOVFW, C_FREG, C_NONE, C_FREG, 84, 4, 0 },
{ AMOVWF, C_FREG, C_NONE, C_FREG, 85, 4, 0 },
{ AMOVFW, C_FREG, C_NONE, C_REG, 86, 8, 0 },
{ AMOVWF, C_REG, C_NONE, C_FREG, 87, 8, 0 },
{ AMOVW, C_REG, C_NONE, C_FREG, 88, 4, 0 },
{ AMOVW, C_FREG, C_NONE, C_REG, 89, 4, 0 },
{ AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0 }, { AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0 },
}; };

View File

@ -1039,17 +1039,20 @@ buildop(void)
break; break;
case AMOVFW: case AMOVFW:
oprange[AMOVWF] = oprange[r];
oprange[AMOVWD] = oprange[r];
oprange[AMOVDW] = oprange[r]; oprange[AMOVDW] = oprange[r];
break; break;
case AMOVWF:
oprange[AMOVWD] = oprange[r];
break;
case AMULL: case AMULL:
oprange[AMULA] = oprange[r]; oprange[AMULA] = oprange[r];
oprange[AMULAL] = oprange[r]; oprange[AMULAL] = oprange[r];
oprange[AMULLU] = oprange[r]; oprange[AMULLU] = oprange[r];
oprange[AMULALU] = oprange[r]; oprange[AMULALU] = oprange[r];
break; break;
case ALDREX: case ALDREX:
case ASTREX: case ASTREX:
break; break;

View File

@ -935,16 +935,26 @@ walkexpr(Node **np, NodeList **init)
case OCONV: case OCONV:
case OCONVNOP: case OCONVNOP:
if(thechar == '5') { if(thechar == '5') {
if(isfloat[n->left->type->etype] && if(isfloat[n->left->type->etype]) {
(n->type->etype == TINT64 || n->type->etype == TUINT64)) { if(n->type->etype == TINT64) {
n = mkcall("float64toint64", n->type, init, conv(n->left, types[TFLOAT64])); n = mkcall("float64toint64", n->type, init, conv(n->left, types[TFLOAT64]));
goto ret; goto ret;
} }
if((n->left->type->etype == TINT64 || n->left->type->etype == TUINT64) && if(n->type->etype == TUINT64) {
isfloat[n->type->etype]) { n = mkcall("float64touint64", n->type, init, conv(n->left, types[TFLOAT64]));
goto ret;
}
}
if(isfloat[n->type->etype]) {
if(n->left->type->etype == TINT64) {
n = mkcall("int64tofloat64", n->type, init, conv(n->left, types[TINT64])); n = mkcall("int64tofloat64", n->type, init, conv(n->left, types[TINT64]));
goto ret; goto ret;
} }
if(n->left->type->etype == TUINT64) {
n = mkcall("uint64tofloat64", n->type, init, conv(n->left, types[TUINT64]));
goto ret;
}
}
} }
walkexpr(&n->left, init); walkexpr(&n->left, init);
goto ret; goto ret;

View File

@ -88,7 +88,6 @@ _subv(Vlong *r, Vlong a, Vlong b)
r->hi = hi; r->hi = hi;
} }
void void
_d2v(Vlong *y, double d) _d2v(Vlong *y, double d)
{ {
@ -125,7 +124,7 @@ _d2v(Vlong *y, double d)
} else { } else {
/* v = (hi||lo) << -sh */ /* v = (hi||lo) << -sh */
sh = -sh; sh = -sh;
if(sh <= 10) { if(sh <= 11) {
ylo = xlo << sh; ylo = xlo << sh;
yhi = (xhi << sh) | (xlo >> (32-sh)); yhi = (xhi << sh) | (xlo >> (32-sh));
} else { } else {
@ -157,6 +156,23 @@ runtime·float64toint64(double d, Vlong y)
_d2v(&y, d); _d2v(&y, d);
} }
void
runtime·float64touint64(double d, Vlong y)
{
_d2v(&y, d);
}
double
_ul2d(ulong u)
{
// compensate for bug in c
if(u & SIGN(32)) {
u ^= SIGN(32);
return 2147483648. + u;
}
return u;
}
double double
_v2d(Vlong x) _v2d(Vlong x)
{ {
@ -166,9 +182,9 @@ _v2d(Vlong x)
x.hi = ~x.hi; x.hi = ~x.hi;
} else } else
x.hi = -x.hi; x.hi = -x.hi;
return -((long)x.hi*4294967296. + x.lo); return -(_ul2d(x.hi)*4294967296. + _ul2d(x.lo));
} }
return (long)x.hi*4294967296. + x.lo; return x.hi*4294967296. + _ul2d(x.lo);
} }
float float
@ -183,6 +199,11 @@ runtime·int64tofloat64(Vlong y, double d)
d = _v2d(y); d = _v2d(y);
} }
void
runtime·uint64tofloat64(Vlong y, double d)
{
d = _ul2d(y.hi)*4294967296. + _ul2d(y.lo);
}
static void static void
dodiv(Vlong num, Vlong den, Vlong *q, Vlong *r) dodiv(Vlong num, Vlong den, Vlong *q, Vlong *r)