From: Kai Backman Date: Thu, 25 Jun 2009 18:01:17 +0000 (-0700) Subject: fixes to 5g object file generation. arm specific regalloc. X-Git-Tag: weekly.2009-11-06~1336 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=190b5c9ad22a8f55ff8595cbf93d37509ceba69c;p=gostls13.git fixes to 5g object file generation. arm specific regalloc. R=rsc APPROVED=rsc DELTA=976 (164 added, 237 deleted, 575 changed) OCL=30705 CL=30743 --- diff --git a/src/cmd/5g/gg.h b/src/cmd/5g/gg.h index 914109a05d..19084f34f5 100644 --- a/src/cmd/5g/gg.h +++ b/src/cmd/5g/gg.h @@ -26,6 +26,7 @@ struct Addr Sym* sym; int width; uchar type; + char reg; uchar index; uchar etype; uchar scale; /* doubles as width in DATA op */ @@ -40,12 +41,18 @@ struct Prog Addr from; // src address Addr to; // dst address Prog* link; // next instruction in this func - void* reg; // pointer to containing Reg struct + char reg; + uchar scond; }; +#define REGALLOC_R0 0 +#define REGALLOC_RMAX REGEXT +#define REGALLOC_F0 (REGALLOC_RMAX+1) +#define REGALLOC_FMAX (REGALLOC_F0 + FREGEXT) + EXTERN Biobuf* bout; EXTERN int32 dynloc; -EXTERN uchar reg[D_NONE]; +EXTERN uchar reg[REGALLOC_FMAX]; EXTERN int32 pcloc; // instruction counter EXTERN Strlit emptystring; extern char* anames[]; @@ -57,6 +64,7 @@ EXTERN Node* deferproc; EXTERN Node* deferreturn; EXTERN Node* throwindex; EXTERN Node* throwreturn; +EXTERN int maxstksize; /* * gen.c @@ -115,6 +123,8 @@ void ginit(void); void gclean(void); void regalloc(Node*, Type*, Node*); void regfree(Node*); +void tempalloc(Node*, Type*); +void tempfree(Node*); Node* nodarg(Type*, int); void nodreg(Node*, Type*, int); void nodindreg(Node*, Type*, int); diff --git a/src/cmd/5g/ggen.c b/src/cmd/5g/ggen.c index fe561d8956..9a73480a71 100644 --- a/src/cmd/5g/ggen.c +++ b/src/cmd/5g/ggen.c @@ -65,10 +65,8 @@ compile(Node *fn) ptxt = gins(ATEXT, curfn->nname, &nod1); afunclit(&ptxt->from); - ginit(); gen(curfn->enter); gen(curfn->nbody); - gclean(); checklabels(); if(curfn->type->outtuple != 0) @@ -85,10 +83,14 @@ compile(Node *fn) */ // fill in argument size + ptxt->to.type = D_CONST2; ptxt->to.offset2 = rnd(curfn->type->argwid, maxround); // fill in final stack size - ptxt->to.offset = rnd(stksize+maxarg, maxround); + if(stksize > maxstksize) + maxstksize = stksize; + ptxt->to.offset = rnd(maxstksize+maxarg, maxround); + maxstksize = 0; if(debug['f']) frame(0); @@ -359,42 +361,6 @@ cgen_asop(Node *n) if(!isint[nr->type->etype]) goto hard; - switch(n->etype) { - case OADD: - if(smallintconst(nr)) - if(mpgetfix(nr->val.u.xval) == 1) { - a = optoas(OINC, nl->type); - if(nl->addable) { - gins(a, N, nl); - goto ret; - } - if(sudoaddable(a, nl, &addr)) { - p1 = gins(a, N, N); - p1->to = addr; - sudoclean(); - goto ret; - } - } - break; - - case OSUB: - if(smallintconst(nr)) - if(mpgetfix(nr->val.u.xval) == 1) { - a = optoas(ODEC, nl->type); - if(nl->addable) { - gins(a, N, nl); - goto ret; - } - if(sudoaddable(a, nl, &addr)) { - p1 = gins(a, N, N); - p1->to = addr; - sudoclean(); - goto ret; - } - } - break; - } - switch(n->etype) { case OADD: case OSUB: diff --git a/src/cmd/5g/gobj.c b/src/cmd/5g/gobj.c index ff70d48d34..6f2c94b2b0 100644 --- a/src/cmd/5g/gobj.c +++ b/src/cmd/5g/gobj.c @@ -64,6 +64,8 @@ zhist(Biobuf *b, int line, vlong offset) Addr a; Bputc(b, AHISTORY); + Bputc(b, 0); + Bputc(b, 0); Bputc(b, line); Bputc(b, line>>8); Bputc(b, line>>16); @@ -82,19 +84,26 @@ zaddr(Biobuf *b, Addr *a, int s) { int32 l; Ieee e; + int i; + char *n; -// Bputc(b, a->type); - // TODO(kaib): Re-introduce registers once we figure out what they are used - // for. -// Bputc(b, a->reg); -// Bputc(b, s); - // TODO(kaib): ditto for Addr.name -// Bputc(b, a->name); + switch(a->type) { + case D_STATIC: + case D_EXTERN: + case D_AUTO: + case D_PARAM: + Bputc(b, D_OREG); + Bputc(b, a->reg); + Bputc(b, s); + Bputc(b, a->type); + break; + default: + Bputc(b, a->type); + Bputc(b, a->reg); + Bputc(b, s); + Bputc(b, D_NONE); + } - Bputc(b, 1); - Bputc(b, 0); - Bputc(b, 0); - Bputc(b, 0); switch(a->type) { default: print("unknown type %d in zaddr\n", a->type); @@ -107,10 +116,18 @@ zaddr(Biobuf *b, Addr *a, int s) case D_PARAM: break; + case D_CONST2: + l = a->offset2; + Bputc(b, l); + Bputc(b, l>>8); + Bputc(b, l>>16); + Bputc(b, l>>24); // fall through case D_OREG: case D_CONST: case D_BRANCH: case D_SHIFT: + case D_STATIC: + case D_AUTO: l = a->offset; Bputc(b, l); Bputc(b, l>>8); @@ -118,27 +135,27 @@ zaddr(Biobuf *b, Addr *a, int s) Bputc(b, l>>24); break; -// case D_SCONST: -// n = a->sval; -// for(i=0; idval); -// l = e.l; -// Bputc(b, l); -// Bputc(b, l>>8); -// Bputc(b, l>>16); -// Bputc(b, l>>24); -// l = e.h; -// Bputc(b, l); -// Bputc(b, l>>8); -// Bputc(b, l>>16); -// Bputc(b, l>>24); -// break; + case D_SCONST: + n = a->sval; + for(i=0; idval); + l = e.l; + Bputc(b, l); + Bputc(b, l>>8); + Bputc(b, l>>16); + Bputc(b, l>>24); + l = e.h; + Bputc(b, l); + Bputc(b, l>>8); + Bputc(b, l>>16); + Bputc(b, l>>24); + break; } } @@ -228,6 +245,8 @@ dumpfuncs(void) break; } Bputc(bout, p->as); + Bputc(bout, p->scond); + Bputc(bout, p->reg); Bputc(bout, p->lineno); Bputc(bout, p->lineno>>8); Bputc(bout, p->lineno>>16); diff --git a/src/cmd/5g/gsubr.c b/src/cmd/5g/gsubr.c index ba68a697af..fe83abbb2b 100644 --- a/src/cmd/5g/gsubr.c +++ b/src/cmd/5g/gsubr.c @@ -190,129 +190,118 @@ afunclit(Addr *a) } } -// TODO(kaib): probably not needed. -static int resvd[] = -{ -// D_DI, // for movstring -// D_SI, // for movstring - -// D_AX, // for divide -// D_CX, // for shift -// D_DX, // for divide -// REGSP, // for stack -// D_R14, // reserved for m -// D_R15, // reserved for u -}; - -// TODO(kaib): As per rsc this is probably overcomplicated for arm +/* + * allocate register of type t, leave in n. + * if o != N, o is desired fixed register. + * caller must regfree(n). + */ void -ginit(void) +regalloc(Node *n, Type *t, Node *o) { -// int i; + int i, et; + + if(t == T) + fatal("regalloc: t nil"); + et = simtype[t->etype]; + + switch(et) { + case TINT8: + case TUINT8: + case TINT16: + case TUINT16: + case TINT32: + case TUINT32: + case TINT64: + case TUINT64: + case TPTR32: + case TPTR64: + case TBOOL: + if(o != N && o->op == OREGISTER) { + i = o->val.u.reg; + if(i >= REGALLOC_R0 && i <= REGALLOC_RMAX) + goto out; + } + for(i=REGALLOC_R0; i<=REGALLOC_RMAX; i++) + if(reg[i] == 0) + goto out; -// for(i=0; iop == OREGISTER) { + i = o->val.u.reg; + if(i >= REGALLOC_F0 && i <= REGALLOC_FMAX) + goto out; + } + for(i=REGALLOC_F0; i<=REGALLOC_FMAX; i++) + if(reg[i] == 0) + goto out; + yyerror("out of floating registers"); + goto err; + } + yyerror("regalloc: unknown type %T", t); + +err: + nodreg(n, t, 0); + return; + +out: + reg[i]++; + nodreg(n, t, i); } void -gclean(void) +regfree(Node *n) { -// int i; - -// for(i=0; iop != OREGISTER && n->op != OINDREG) + fatal("regfree: not a register"); + i = n->val.u.reg; + if(i < 0 || i >= sizeof(reg)) + fatal("regfree: reg out of range"); + if(reg[i] <= 0) + fatal("regfree: reg not allocated"); + reg[i]--; } -/* - * allocate register of type t, leave in n. - * if o != N, o is desired fixed register. - * caller must regfree(n). - */ void -regalloc(Node *n, Type *t, Node *o) +tempalloc(Node *n, Type *t) { -// int i, et; - -// if(t == T) -// fatal("regalloc: t nil"); -// et = simtype[t->etype]; - -// switch(et) { -// case TINT8: -// case TUINT8: -// case TINT16: -// case TUINT16: -// case TINT32: -// case TUINT32: -// case TINT64: -// case TUINT64: -// case TPTR32: -// case TPTR64: -// case TBOOL: -// if(o != N && o->op == OREGISTER) { -// i = o->val.u.reg; -// if(i >= D_AX && i <= D_R15) -// goto out; -// } -// for(i=D_AX; i<=D_R15; i++) -// if(reg[i] == 0) -// goto out; - -// yyerror("out of fixed registers"); -// goto err; - -// case TFLOAT32: -// case TFLOAT64: -// case TFLOAT80: -// if(o != N && o->op == OREGISTER) { -// i = o->val.u.reg; -// if(i >= D_X0 && i <= D_X7) -// goto out; -// } -// for(i=D_X0; i<=D_X7; i++) -// if(reg[i] == 0) -// goto out; -// yyerror("out of floating registers"); -// goto err; -// } -// yyerror("regalloc: unknown type %T", t); + int w; -// err: -// nodreg(n, t, 0); -// return; + dowidth(t); -// out: -// reg[i]++; -// nodreg(n, t, i); + memset(n, 0, sizeof(*n)); + n->op = ONAME; + n->sym = S; + n->type = t; + n->etype = t->etype; + n->class = PAUTO; + n->addable = 1; + n->ullman = 1; + n->noescape = 1; + n->ostk = stksize; + + w = t->width; + stksize += w; + stksize = rnd(stksize, w); + n->xoffset = -stksize; +//print("tempalloc %d -> %d from %p\n", n->ostk, n->xoffset, __builtin_return_address(0)); + if(stksize > maxstksize) + maxstksize = stksize; } void -regfree(Node *n) +tempfree(Node *n) { -// int i; - -// if(n->op != OREGISTER && n->op != OINDREG) -// fatal("regfree: not a register"); -// i = n->val.u.reg; -// if(i < 0 || i >= sizeof(reg)) -// fatal("regfree: reg out of range"); -// if(reg[i] <= 0) -// fatal("regfree: reg not allocated"); -// reg[i]--; +//print("tempfree %d\n", n->xoffset); + if(n->xoffset != -stksize) + fatal("tempfree %lld %d", -n->xoffset, stksize); + stksize = n->ostk; } /* @@ -410,575 +399,563 @@ gconreg(int as, vlong c, int reg) gins(as, &n1, &n2); } -#define CASE(a,b) (((a)<<16)|((b)<<0)) - /* - * generate move: - * t = f + * Is this node a memory operand? */ -// TODO(kaib): Crib the new gmove from 8g -void -gmove(Node *f, Node *t) +int +ismem(Node *n) { - int ft, tt, t64, a; - Node nod, nod1, nod2, nod3, nodc; - Prog *p1, *p2; + switch(n->op) { + case OINDREG: + case ONAME: + case OPARAM: + return 1; + } + return 0; +} - ft = simtype[f->type->etype]; - tt = simtype[t->type->etype]; +#define CASE(a,b) (((a)<<16)|((b)<<0)) - t64 = 0; - if(tt == TINT64 || tt == TUINT64 || tt == TPTR64) - t64 = 1; +void +gmove(Node *f, Node *t) +{ + int a, ft, tt; + Type *cvt; + Node r1, r2, t1, t2, flo, fhi, tlo, thi, con, f0, f1, ax, dx, cx; + Prog *p1, *p2, *p3; if(debug['M']) - print("gop: %O %O[%E],%O[%E]\n", OAS, - f->op, ft, t->op, tt); -/* - * load - */ - if(f->op == ONAME || f->op == OINDREG || - f->op == OIND || f->op == OINDEX) - fatal("gmove load not implemented"); -// switch(ft) { -// case TINT8: -// a = AMOVBLSX; -// if(t64) -// a = AMOVBQSX; -// goto ld; -// case TBOOL: -// case TUINT8: -// a = AMOVBLZX; -// if(t64) -// a = AMOVBQZX; -// goto ld; -// case TINT16: -// a = AMOVWLSX; -// if(t64) -// a = AMOVWQSX; -// goto ld; -// case TUINT16: -// a = AMOVWLZX; -// if(t64) -// a = AMOVWQZX; -// goto ld; -// case TINT32: -// if(isfloat[tt]) { -// regalloc(&nod, t->type, t); -// if(tt == TFLOAT64) -// a = ACVTSL2SD; -// else -// a = ACVTSL2SS; -// gins(a, f, &nod); -// gmove(&nod, t); -// regfree(&nod); -// return; -// } -// a = AMOVL; -// if(t64) -// a = AMOVLQSX; -// goto ld; -// case TUINT32: -// case TPTR32: -// a = AMOVL; -// if(t64) -// a = AMOVLQZX; -// goto ld; -// case TINT64: -// if(isfloat[tt]) { -// regalloc(&nod, t->type, t); -// if(tt == TFLOAT64) -// a = ACVTSQ2SD; -// else -// a = ACVTSQ2SS; -// gins(a, f, &nod); -// gmove(&nod, t); -// regfree(&nod); -// return; -// } -// case TUINT64: -// case TPTR64: -// a = AMOVQ; + print("gmove %N -> %N\n", f, t); + + ft = simsimtype(f->type); + tt = simsimtype(t->type); + cvt = t->type; + + // cannot have two integer memory operands; + // except 64-bit, which always copies via registers anyway. + // TODO(kaib): re-enable check +// if(isint[ft] && isint[tt] && !is64(f->type) && !is64(t->type) && ismem(f) && ismem(t)) +// goto hard; + + // convert constant to desired type + if(f->op == OLITERAL) { + if(tt == TFLOAT32) + convconst(&con, types[TFLOAT64], &f->val); + else + convconst(&con, t->type, &f->val); + f = &con; + ft = simsimtype(con.type); + + // some constants can't move directly to memory. + if(ismem(t)) { + // float constants come from memory. + if(isfloat[tt]) + goto hard; + } + } -// ld: -// regalloc(&nod, f->type, t); -// nod.type = t64? types[TINT64]: types[TINT32]; -// gins(a, f, &nod); -// gmove(&nod, t); -// regfree(&nod); -// return; + // value -> value copy, only one memory operand. + // figure out the instruction to use. + // break out of switch for one-instruction gins. + // goto rdst for "destination must be register". + // goto hard for "convert to cvt type first". + // otherwise handle and return. -// case TFLOAT32: -// a = AMOVSS; -// goto fld; -// case TFLOAT64: -// a = AMOVSD; -// fld: -// regalloc(&nod, f->type, t); -// if(tt != TFLOAT64 && tt != TFLOAT32){ /* TO DO: why is this here */ -// dump("odd tree", f); -// nod.type = t64? types[TINT64]: types[TINT32]; -// } -// gins(a, f, &nod); -// gmove(&nod, t); -// regfree(&nod); -// return; -// } + switch(CASE(ft, tt)) { + default: + goto fatal; + + /* + * integer copy and truncate + */ + case CASE(TINT8, TINT8): // same size + case CASE(TINT8, TUINT8): + case CASE(TUINT8, TINT8): + case CASE(TUINT8, TUINT8): + case CASE(TINT16, TINT8): // truncate + case CASE(TUINT16, TINT8): + case CASE(TINT32, TINT8): + case CASE(TUINT32, TINT8): + case CASE(TINT16, TUINT8): + case CASE(TUINT16, TUINT8): + case CASE(TINT32, TUINT8): + case CASE(TUINT32, TUINT8): + a = AMOVB; + break; -/* - * store - */ - if(t->op == ONAME || t->op == OINDREG || - t->op == OIND || t->op == OINDEX) + case CASE(TINT64, TINT8): // truncate low word + case CASE(TUINT64, TINT8): + case CASE(TINT64, TUINT8): + case CASE(TUINT64, TUINT8): + fatal("gmove INT64,INT8 not implemented"); +// split64(f, &flo, &fhi); +// nodreg(&r1, t->type, D_AX); +// gins(AMOVB, &flo, &r1); +// gins(AMOVB, &r1, t); +// splitclean(); + return; - switch(tt) { - case TBOOL: - case TINT8: - case TUINT8: - a = AMOVB; - goto st; - case TINT16: - case TUINT16: + case CASE(TINT16, TINT16): // same size + case CASE(TINT16, TUINT16): + case CASE(TUINT16, TINT16): + case CASE(TUINT16, TUINT16): + case CASE(TINT32, TINT16): // truncate + case CASE(TUINT32, TINT16): + case CASE(TINT32, TUINT16): + case CASE(TUINT32, TUINT16): a = AMOVH; - goto st; - case TINT32: - case TUINT32: - a = AMOVW; - goto st; - case TINT64: - case TUINT64: - fatal("gmove TINT64 and TUINT64 not implemented"); -// a = AMOVQ; - goto st; - - case TPTR64: - fatal("gmove TPTR64 not implemented"); break; - case TPTR32: - /* - * store to pointer. - */ - a = AMOVW; - switch(t->op) { - default: - dump("gmove to", t); - fatal("gmove t %O", t->op); + case CASE(TINT64, TINT16): // truncate low word + case CASE(TUINT64, TINT16): + case CASE(TINT64, TUINT16): + case CASE(TUINT64, TUINT16): + fatal("gmove INT64,INT16 not implemented"); +// split64(f, &flo, &fhi); +// nodreg(&r1, t->type, D_AX); +// gins(AMOVW, &flo, &r1); +// gins(AMOVW, &r1, t); +// splitclean(); + return; - case OINDREG: - if(t->val.u.reg != REGSP) - goto refcount; - break; + case CASE(TINT32, TINT32): // same size + case CASE(TINT32, TUINT32): + case CASE(TUINT32, TINT32): + case CASE(TUINT32, TUINT32): + a = AMOVW; + break; - case ONAME: - switch(t->class) { - default: - dump("gmove", t); - fatal("gmove t %O class %d reg %R", t->op, t->class, t->val.u.reg); - case PEXTERN: - goto refcount; - break; - case PAUTO: - case PPARAM: - case PPARAMOUT: - break; - } - break; - } - goto st; - - st: - // 64-bit immediates only allowed for move into registers. - // this is not a move into a register. - if(f->op == OLITERAL && !t64) { - gins(a, f, t); - return; - } - fst: - regalloc(&nod, t->type, f); - gmove(f, &nod); - gins(a, &nod, t); - regfree(&nod); + case CASE(TINT64, TINT32): // truncate + case CASE(TUINT64, TINT32): + case CASE(TINT64, TUINT32): + case CASE(TUINT64, TUINT32): + fatal("gmove INT64,INT32 not implemented"); +// split64(f, &flo, &fhi); +// nodreg(&r1, t->type, D_AX); +// gins(AMOVL, &flo, &r1); +// gins(AMOVL, &r1, t); +// splitclean(); return; - refcount: - fatal("gmove refcount not implemented"); -// if(!debug['r']) -// goto st; -// // for now, mark ref count updates with AXCHGQ. -// // using a temporary on the left, so no semantic -// // changes. code is likely slower, but still correct. -// if(t64) -// a = AXCHGQ; -// else -// a = AXCHGL; -// regalloc(&nod, t->type, f); -// gmove(f, &nod); -// gins(a, &nod, t); -// regfree(&nod); + case CASE(TINT64, TINT64): // same size + case CASE(TINT64, TUINT64): + case CASE(TUINT64, TINT64): + case CASE(TUINT64, TUINT64): + fatal("gmove INT64,INT64 not implemented"); +// split64(f, &flo, &fhi); +// split64(t, &tlo, &thi); +// if(f->op == OLITERAL) { +// gins(AMOVL, &flo, &tlo); +// gins(AMOVL, &fhi, &thi); +// } else { +// nodreg(&r1, t->type, D_AX); +// nodreg(&r2, t->type, D_DX); +// gins(AMOVL, &flo, &r1); +// gins(AMOVL, &fhi, &r2); +// gins(AMOVL, &r1, &tlo); +// gins(AMOVL, &r2, &thi); +// } +// splitclean(); +// splitclean(); return; - case TFLOAT32: - a = AMOVW; - goto fst; - case TFLOAT64: - fatal("gmove TFLOAT64 not implemented"); -// a = AMOVSD; - goto fst; + /* + * integer up-conversions + */ +// case CASE(TINT8, TINT16): // sign extend int8 +// case CASE(TINT8, TUINT16): +// a = AMOVBWSX; +// goto rdst; +// case CASE(TINT8, TINT32): +// case CASE(TINT8, TUINT32): +// a = AMOVBLSX; +// goto rdst; +// case CASE(TINT8, TINT64): // convert via int32 +// case CASE(TINT8, TUINT64): +// cvt = types[TINT32]; +// goto hard; + +// case CASE(TUINT8, TINT16): // zero extend uint8 +// case CASE(TUINT8, TUINT16): +// a = AMOVBWZX; +// goto rdst; +// case CASE(TUINT8, TINT32): +// case CASE(TUINT8, TUINT32): +// a = AMOVBLZX; +// goto rdst; +// case CASE(TUINT8, TINT64): // convert via uint32 +// case CASE(TUINT8, TUINT64): +// cvt = types[TUINT32]; +// goto hard; + +// case CASE(TINT16, TINT32): // sign extend int16 +// case CASE(TINT16, TUINT32): +// a = AMOVWLSX; +// goto rdst; +// case CASE(TINT16, TINT64): // convert via int32 +// case CASE(TINT16, TUINT64): +// cvt = types[TINT32]; +// goto hard; + +// case CASE(TUINT16, TINT32): // zero extend uint16 +// case CASE(TUINT16, TUINT32): +// a = AMOVWLZX; +// goto rdst; +// case CASE(TUINT16, TINT64): // convert via uint32 +// case CASE(TUINT16, TUINT64): +// cvt = types[TUINT32]; +// goto hard; + +// case CASE(TINT32, TINT64): // sign extend int32 +// case CASE(TINT32, TUINT64): +// fatal("gmove TINT32,INT64 not implemented"); +// // split64(t, &tlo, &thi); +// // nodreg(&flo, tlo.type, D_AX); +// // nodreg(&fhi, thi.type, D_DX); +// // gmove(f, &flo); +// // gins(ACDQ, N, N); +// // gins(AMOVL, &flo, &tlo); +// // gins(AMOVL, &fhi, &thi); +// // splitclean(); +// return; + +// case CASE(TUINT32, TINT64): // zero extend uint32 +// case CASE(TUINT32, TUINT64): +// fatal("gmove TUINT32,INT64 not implemented"); +// // split64(t, &tlo, &thi); +// // gmove(f, &tlo); +// // gins(AMOVL, ncon(0), &thi); +// // splitclean(); +// return; + +// /* +// * float to integer +// */ +// case CASE(TFLOAT32, TINT16): +// case CASE(TFLOAT32, TINT32): +// case CASE(TFLOAT32, TINT64): +// case CASE(TFLOAT64, TINT16): +// case CASE(TFLOAT64, TINT32): +// case CASE(TFLOAT64, TINT64): +// if(t->op == OREGISTER) +// goto hardmem; +// nodreg(&r1, types[ft], D_F0); +// if(ft == TFLOAT32) +// gins(AFMOVF, f, &r1); +// else +// gins(AFMOVD, f, &r1); + +// // set round to zero mode during conversion +// tempalloc(&t1, types[TUINT16]); +// tempalloc(&t2, types[TUINT16]); +// gins(AFSTCW, N, &t1); +// gins(AMOVW, ncon(0xf7f), &t2); +// gins(AFLDCW, &t2, N); +// if(tt == TINT16) +// gins(AFMOVWP, &r1, t); +// else if(tt == TINT32) +// gins(AFMOVLP, &r1, t); +// else +// gins(AFMOVVP, &r1, t); +// gins(AFLDCW, &t1, N); +// tempfree(&t2); +// tempfree(&t1); +// return; + +// case CASE(TFLOAT32, TINT8): +// case CASE(TFLOAT32, TUINT16): +// case CASE(TFLOAT32, TUINT8): +// case CASE(TFLOAT64, TINT8): +// case CASE(TFLOAT64, TUINT16): +// case CASE(TFLOAT64, TUINT8): +// // convert via int32. +// tempalloc(&t1, types[TINT32]); +// gmove(f, &t1); +// switch(tt) { +// default: +// fatal("gmove %T", t); +// case TINT8: +// gins(ACMPL, &t1, ncon(-0x80)); +// p1 = gbranch(optoas(OLT, types[TINT32]), T); +// gins(ACMPL, &t1, ncon(0x7f)); +// p2 = gbranch(optoas(OGT, types[TINT32]), T); +// p3 = gbranch(AJMP, T); +// patch(p1, pc); +// patch(p2, pc); +// gmove(ncon(-0x80), &t1); +// patch(p3, pc); +// gmove(&t1, t); +// break; +// case TUINT8: +// gins(ATESTL, ncon(0xffffff00), &t1); +// p1 = gbranch(AJEQ, T); +// gins(AMOVB, ncon(0), &t1); +// patch(p1, pc); +// gmove(&t1, t); +// break; +// case TUINT16: +// gins(ATESTL, ncon(0xffff0000), &t1); +// p1 = gbranch(AJEQ, T); +// gins(AMOVW, ncon(0), &t1); +// patch(p1, pc); +// gmove(&t1, t); +// break; +// } +// tempfree(&t1); +// return; + +// case CASE(TFLOAT32, TUINT32): +// case CASE(TFLOAT64, TUINT32): +// // convert via int64. +// tempalloc(&t1, types[TINT64]); +// gmove(f, &t1); +// split64(&t1, &tlo, &thi); +// gins(ACMPL, &thi, ncon(0)); +// p1 = gbranch(AJEQ, T); +// gins(AMOVL, ncon(0), &tlo); +// patch(p1, pc); +// gmove(&tlo, t); +// splitclean(); +// tempfree(&t1); +// return; + +// case CASE(TFLOAT32, TUINT64): +// case CASE(TFLOAT64, TUINT64): +// bignodes(); +// nodreg(&f0, types[ft], D_F0); +// nodreg(&f1, types[ft], D_F0 + 1); +// nodreg(&ax, types[TUINT16], D_AX); + +// gmove(f, &f0); + +// // if 0 > v { answer = 0 } +// gmove(&zerof, &f0); +// gins(AFUCOMP, &f0, &f1); +// gins(AFSTSW, N, &ax); +// gins(ASAHF, N, N); +// p1 = gbranch(optoas(OGT, types[tt]), T); +// // if 1<<64 <= v { answer = 0 too } +// gmove(&two64f, &f0); +// gins(AFUCOMP, &f0, &f1); +// gins(AFSTSW, N, &ax); +// gins(ASAHF, N, N); +// p2 = gbranch(optoas(OGT, types[tt]), T); +// patch(p1, pc); +// gins(AFMOVVP, &f0, t); // don't care about t, but will pop the stack +// split64(t, &tlo, &thi); +// gins(AMOVL, ncon(0), &tlo); +// gins(AMOVL, ncon(0), &thi); +// splitclean(); +// p1 = gbranch(AJMP, T); +// patch(p2, pc); + +// // in range; algorithm is: +// // if small enough, use native float64 -> int64 conversion. +// // otherwise, subtract 2^63, convert, and add it back. + +// // set round to zero mode during conversion +// tempalloc(&t1, types[TUINT16]); +// tempalloc(&t2, types[TUINT16]); +// gins(AFSTCW, N, &t1); +// gins(AMOVW, ncon(0xf7f), &t2); +// gins(AFLDCW, &t2, N); +// tempfree(&t2); + +// // actual work +// gmove(&two63f, &f0); +// gins(AFUCOMP, &f0, &f1); +// gins(AFSTSW, N, &ax); +// gins(ASAHF, N, N); +// p2 = gbranch(optoas(OLE, types[tt]), T); +// gins(AFMOVVP, &f0, t); +// p3 = gbranch(AJMP, T); +// patch(p2, pc); +// gmove(&two63f, &f0); +// gins(AFSUBDP, &f0, &f1); +// gins(AFMOVVP, &f0, t); +// split64(t, &tlo, &thi); +// gins(AXORL, ncon(0x80000000), &thi); // + 2^63 +// patch(p3, pc); +// patch(p1, pc); +// splitclean(); + +// // restore rounding mode +// gins(AFLDCW, &t1, N); +// tempfree(&t1); +// return; + +// /* +// * integer to float +// */ +// case CASE(TINT16, TFLOAT32): +// case CASE(TINT16, TFLOAT64): +// case CASE(TINT32, TFLOAT32): +// case CASE(TINT32, TFLOAT64): +// case CASE(TINT64, TFLOAT32): +// case CASE(TINT64, TFLOAT64): +// fatal("gmove TINT,TFLOAT not implemented"); +// // if(t->op != OREGISTER) +// // goto hard; +// // if(f->op == OREGISTER) { +// // cvt = f->type; +// // goto hardmem; +// // } +// // switch(ft) { +// // case TINT16: +// // a = AFMOVW; +// // break; +// // case TINT32: +// // a = AFMOVL; +// // break; +// // default: +// // a = AFMOVV; +// // break; +// // } +// break; + +// case CASE(TINT8, TFLOAT32): +// case CASE(TINT8, TFLOAT64): +// case CASE(TUINT16, TFLOAT32): +// case CASE(TUINT16, TFLOAT64): +// case CASE(TUINT8, TFLOAT32): +// case CASE(TUINT8, TFLOAT64): +// // convert via int32 memory +// cvt = types[TINT32]; +// goto hardmem; + +// case CASE(TUINT32, TFLOAT32): +// case CASE(TUINT32, TFLOAT64): +// // convert via int64 memory +// cvt = types[TINT64]; +// goto hardmem; + +// case CASE(TUINT64, TFLOAT32): +// case CASE(TUINT64, TFLOAT64): +// // algorithm is: +// // if small enough, use native int64 -> uint64 conversion. +// // otherwise, halve (rounding to odd?), convert, and double. +// nodreg(&ax, types[TUINT32], D_AX); +// nodreg(&dx, types[TUINT32], D_DX); +// nodreg(&cx, types[TUINT32], D_CX); +// tempalloc(&t1, f->type); +// split64(&t1, &tlo, &thi); +// gmove(f, &t1); +// gins(ACMPL, &thi, ncon(0)); +// p1 = gbranch(AJLT, T); +// // native +// t1.type = types[TINT64]; +// gmove(&t1, t); +// p2 = gbranch(AJMP, T); +// // simulated +// patch(p1, pc); +// gmove(&tlo, &ax); +// gmove(&thi, &dx); +// p1 = gins(ASHRL, ncon(1), &ax); +// p1->from.index = D_DX; // double-width shift DX -> AX +// p1->from.scale = 0; +// gins(ASETCC, N, &cx); +// gins(AORB, &cx, &ax); +// gins(ASHRL, ncon(1), &dx); +// gmove(&dx, &thi); +// gmove(&ax, &tlo); +// nodreg(&r1, types[tt], D_F0); +// nodreg(&r2, types[tt], D_F0 + 1); +// gmove(&t1, &r1); // t1.type is TINT64 now, set above +// gins(AFMOVD, &r1, &r1); +// gins(AFADDDP, &r1, &r2); +// gmove(&r1, t); +// patch(p2, pc); +// splitclean(); +// tempfree(&t1); +// return; + +// /* +// * float to float +// */ +// case CASE(TFLOAT32, TFLOAT32): +// case CASE(TFLOAT64, TFLOAT64): +// // The way the code generator uses floating-point +// // registers, a move from F0 to F0 is intended as a no-op. +// // On the x86, it's not: it pushes a second copy of F0 +// // on the floating point stack. So toss it away here. +// // Also, F0 is the *only* register we ever evaluate +// // into, so we should only see register/register as F0/F0. +// if(f->op == OREGISTER && t->op == OREGISTER) { +// if(f->val.u.reg != D_F0 || t->val.u.reg != D_F0) +// goto fatal; +// return; +// } +// if(ismem(f) && ismem(t)) +// goto hard; +// a = AFMOVF; +// if(ft == TFLOAT64) +// a = AFMOVD; +// if(ismem(t)) { +// if(f->op != OREGISTER || f->val.u.reg != D_F0) +// fatal("gmove %N", f); +// a = AFMOVFP; +// if(ft == TFLOAT64) +// a = AFMOVDP; +// } +// break; + +// case CASE(TFLOAT32, TFLOAT64): +// if(f->op == OREGISTER && t->op == OREGISTER) { +// if(f->val.u.reg != D_F0 || t->val.u.reg != D_F0) +// goto fatal; +// return; +// } +// if(f->op == OREGISTER) +// gins(AFMOVDP, f, t); +// else +// gins(AFMOVF, f, t); +// return; + +// case CASE(TFLOAT64, TFLOAT32): +// if(f->op == OREGISTER && t->op == OREGISTER) { +// tempalloc(&r1, types[TFLOAT32]); +// gins(AFMOVFP, f, &r1); +// gins(AFMOVF, &r1, t); +// tempfree(&r1); +// return; +// } +// if(f->op == OREGISTER) +// gins(AFMOVFP, f, t); +// else +// gins(AFMOVD, f, t); +// return; } -/* - * convert - */ - fatal("gmove convert not implemented"); -// switch(CASE(ft, tt)) { -// default: -/* - * integer to integer - ******** - * a = AGOK; break; - - * case CASE(TBOOL, TBOOL): - * case CASE(TINT8, TBOOL): - * case CASE(TUINT8, TBOOL): - * case CASE(TINT16, TBOOL): - * case CASE(TUINT16, TBOOL): - * case CASE(TINT32, TBOOL): - * case CASE(TUINT32, TBOOL): - * case CASE(TPTR64, TBOOL): - - * case CASE(TBOOL, TINT8): - * case CASE(TINT8, TINT8): - * case CASE(TUINT8, TINT8): - * case CASE(TINT16, TINT8): - * case CASE(TUINT16, TINT8): - * case CASE(TINT32, TINT8): - * case CASE(TUINT32, TINT8): - * case CASE(TPTR64, TINT8): - - * case CASE(TBOOL, TUINT8): - * case CASE(TINT8, TUINT8): - * case CASE(TUINT8, TUINT8): - * case CASE(TINT16, TUINT8): - * case CASE(TUINT16, TUINT8): - * case CASE(TINT32, TUINT8): - * case CASE(TUINT32, TUINT8): - * case CASE(TPTR64, TUINT8): - - * case CASE(TINT16, TINT16): - * case CASE(TUINT16, TINT16): - * case CASE(TINT32, TINT16): - * case CASE(TUINT32, TINT16): - * case CASE(TPTR64, TINT16): - - * case CASE(TINT16, TUINT16): - * case CASE(TUINT16, TUINT16): - * case CASE(TINT32, TUINT16): - * case CASE(TUINT32, TUINT16): - * case CASE(TPTR64, TUINT16): - - * case CASE(TINT64, TUINT): - * case CASE(TINT64, TUINT32): - * case CASE(TUINT64, TUINT32): - *****/ -// a = AMOVL; -// break; - -// case CASE(TINT64, TINT8): -// case CASE(TINT64, TINT16): -// case CASE(TINT64, TINT32): -// case CASE(TUINT64, TINT8): -// case CASE(TUINT64, TINT16): -// case CASE(TUINT64, TINT32): -// a = AMOVLQSX; // this looks bad -// break; - -// case CASE(TINT32, TINT64): -// case CASE(TINT32, TPTR64): -// a = AMOVLQSX; -// break; - -// case CASE(TUINT32, TINT64): -// case CASE(TUINT32, TUINT64): -// case CASE(TUINT32, TPTR64): -// case CASE(TPTR32, TINT64): -// case CASE(TPTR32, TUINT64): -// case CASE(TPTR32, TPTR64): -// a = AMOVLQZX; -// break; - -// case CASE(TPTR64, TINT64): -// case CASE(TINT64, TINT64): -// case CASE(TUINT64, TINT64): -// case CASE(TINT64, TUINT64): -// case CASE(TUINT64, TUINT64): -// case CASE(TPTR64, TUINT64): -// case CASE(TINT64, TPTR64): -// case CASE(TUINT64, TPTR64): -// case CASE(TPTR64, TPTR64): -// a = AMOVQ; -// break; - -// case CASE(TINT16, TINT32): -// case CASE(TINT16, TUINT32): -// a = AMOVWLSX; -// // if(f->op == OCONST) { -// // f->val.vval &= 0xffff; -// // if(f->val.vval & 0x8000) -// // f->val.vval |= 0xffff0000; -// // a = AMOVL; -// // } -// break; - -// case CASE(TINT16, TINT64): -// case CASE(TINT16, TUINT64): -// case CASE(TINT16, TPTR64): -// a = AMOVWQSX; -// // if(f->op == OCONST) { -// // f->val.vval &= 0xffff; -// // if(f->val.vval & 0x8000){ -// // f->val.vval |= 0xffff0000; -// // f->val.vval |= (vlong)~0 << 32; -// // } -// // a = AMOVL; -// // } -// break; - -// case CASE(TUINT16, TINT32): -// case CASE(TUINT16, TUINT32): -// a = AMOVWLZX; -// // if(f->op == OCONST) { -// // f->val.vval &= 0xffff; -// // a = AMOVL; -// // } -// break; - -// case CASE(TUINT16, TINT64): -// case CASE(TUINT16, TUINT64): -// case CASE(TUINT16, TPTR64): -// a = AMOVWQZX; -// // if(f->op == OCONST) { -// // f->val.vval &= 0xffff; -// // a = AMOVL; /* MOVL also zero-extends to 64 bits */ -// // } -// break; - -// case CASE(TINT8, TINT16): -// case CASE(TINT8, TUINT16): -// case CASE(TINT8, TINT32): -// case CASE(TINT8, TUINT32): -// a = AMOVBLSX; -// // if(f->op == OCONST) { -// // f->val.vval &= 0xff; -// // if(f->val.vval & 0x80) -// // f->val.vval |= 0xffffff00; -// // a = AMOVL; -// // } -// break; - -// case CASE(TINT8, TINT64): -// case CASE(TINT8, TUINT64): -// case CASE(TINT8, TPTR64): -// a = AMOVBQSX; -// // if(f->op == OCONST) { -// // f->val.vval &= 0xff; -// // if(f->val.vval & 0x80){ -// // f->val.vval |= 0xffffff00; -// // f->val.vval |= (vlong)~0 << 32; -// // } -// // a = AMOVQ; -// // } -// break; - -// case CASE(TBOOL, TINT16): -// case CASE(TBOOL, TUINT16): -// case CASE(TBOOL, TINT32): -// case CASE(TBOOL, TUINT32): -// case CASE(TUINT8, TINT16): -// case CASE(TUINT8, TUINT16): -// case CASE(TUINT8, TINT32): -// case CASE(TUINT8, TUINT32): -// a = AMOVBLZX; -// // if(f->op == OCONST) { -// // f->val.vval &= 0xff; -// // a = AMOVL; -// // } -// break; - -// case CASE(TBOOL, TINT64): -// case CASE(TBOOL, TUINT64): -// case CASE(TBOOL, TPTR64): -// case CASE(TUINT8, TINT64): -// case CASE(TUINT8, TUINT64): -// case CASE(TUINT8, TPTR64): -// a = AMOVBQZX; -// // if(f->op == OCONST) { -// // f->val.vval &= 0xff; -// // a = AMOVL; /* zero-extends to 64-bits */ -// // } -// break; - -// /* -// * float to fix -// */ -// case CASE(TFLOAT32, TINT8): -// case CASE(TFLOAT32, TINT16): -// case CASE(TFLOAT32, TINT32): -// regalloc(&nod, t->type, N); -// gins(ACVTTSS2SL, f, &nod); -// gmove(&nod, t); -// regfree(&nod); -// return; - -// case CASE(TFLOAT32, TBOOL): -// case CASE(TFLOAT32, TUINT8): -// case CASE(TFLOAT32, TUINT16): -// case CASE(TFLOAT32, TUINT32): -// case CASE(TFLOAT32, TINT64): -// case CASE(TFLOAT32, TUINT64): -// case CASE(TFLOAT32, TPTR64): -// regalloc(&nod, t->type, N); -// gins(ACVTTSS2SQ, f, &nod); -// gmove(&nod, t); -// regfree(&nod); -// return; - -// case CASE(TFLOAT64, TINT8): -// case CASE(TFLOAT64, TINT16): -// case CASE(TFLOAT64, TINT32): -// regalloc(&nod, t->type, N); -// gins(ACVTTSD2SL, f, &nod); -// gmove(&nod, t); -// regfree(&nod); -// return; - -// case CASE(TFLOAT64, TBOOL): -// case CASE(TFLOAT64, TUINT8): -// case CASE(TFLOAT64, TUINT16): -// case CASE(TFLOAT64, TUINT32): -// case CASE(TFLOAT64, TINT64): -// case CASE(TFLOAT64, TUINT64): -// case CASE(TFLOAT64, TPTR64): -// regalloc(&nod, t->type, N); -// gins(ACVTTSD2SQ, f, &nod); -// gmove(&nod, t); -// regfree(&nod); -// return; - -// /* -// * uvlong to float -// */ -// case CASE(TUINT64, TFLOAT64): -// case CASE(TUINT64, TFLOAT32): -// a = ACVTSQ2SS; -// if(tt == TFLOAT64) -// a = ACVTSQ2SD; -// regalloc(&nod, f->type, f); -// gmove(f, &nod); -// regalloc(&nod1, t->type, t); -// nodconst(&nodc, types[TUINT64], 0); -// gins(ACMPQ, &nod, &nodc); -// p1 = gbranch(AJLT, T); -// gins(a, &nod, &nod1); -// p2 = gbranch(AJMP, T); -// patch(p1, pc); -// regalloc(&nod2, f->type, N); -// regalloc(&nod3, f->type, N); -// gmove(&nod, &nod2); -// nodconst(&nodc, types[TUINT64], 1); -// gins(ASHRQ, &nodc, &nod2); -// gmove(&nod, &nod3); -// gins(AANDL, &nodc, &nod3); -// gins(AORQ, &nod3, &nod2); -// gins(a, &nod2, &nod1); -// gins(tt == TFLOAT64? AADDSD: AADDSS, &nod1, &nod1); -// regfree(&nod2); -// regfree(&nod3); -// patch(p2, pc); -// regfree(&nod); -// regfree(&nod1); -// return; - -// case CASE(TUINT32, TFLOAT64): -// case CASE(TUINT32, TFLOAT32): -// a = ACVTSQ2SS; -// if(tt == TFLOAT64) -// a = ACVTSQ2SD; -// regalloc(&nod, f->type, f); -// gins(AMOVLQZX, f, &nod); -// regalloc(&nod1, t->type, t); -// gins(a, &nod, &nod1); -// gmove(&nod1, t); -// regfree(&nod); -// regfree(&nod1); -// return; - -// /* -// * fix to float -// */ -// case CASE(TINT64, TFLOAT32): -// case CASE(TPTR64, TFLOAT32): -// regalloc(&nod, t->type, t); -// gins(ACVTSQ2SS, f, &nod); -// gmove(&nod, t); -// regfree(&nod); -// return; - -// case CASE(TINT64, TFLOAT64): -// case CASE(TPTR64, TFLOAT64): -// regalloc(&nod, t->type, t); -// gins(ACVTSQ2SD, f, &nod); -// gmove(&nod, t); -// regfree(&nod); -// return; - -// case CASE(TBOOL, TFLOAT32): -// case CASE(TINT8, TFLOAT32): -// case CASE(TUINT8, TFLOAT32): -// case CASE(TINT16, TFLOAT32): -// case CASE(TUINT16, TFLOAT32): -// case CASE(TINT32, TFLOAT32): -// regalloc(&nod, t->type, t); -// gins(ACVTSL2SS, f, &nod); -// gmove(&nod, t); -// regfree(&nod); -// return; - -// case CASE(TBOOL, TFLOAT64): -// case CASE(TINT8, TFLOAT64): -// case CASE(TUINT8, TFLOAT64): -// case CASE(TINT16, TFLOAT64): -// case CASE(TUINT16, TFLOAT64): -// case CASE(TINT32, TFLOAT64): -// regalloc(&nod, t->type, t); -// gins(ACVTSL2SD, f, &nod); -// gmove(&nod, t); -// regfree(&nod); -// return; - -// /* -// * float to float -// */ -// case CASE(TFLOAT32, TFLOAT32): -// a = AMOVSS; -// break; -// case CASE(TFLOAT64, TFLOAT32): -// a = ACVTSD2SS; -// break; -// case CASE(TFLOAT32, TFLOAT64): -// a = ACVTSS2SD; -// break; -// case CASE(TFLOAT64, TFLOAT64): -// a = AMOVSD; -// break; -// } -// if(a == AMOVQ || -// a == AMOVSD || -// a == AMOVSS || -// (a == AMOVL && f->type->width == t->type->width)) /* TO DO: check AMOVL */ -// if(samaddr(f, t)) -// return; gins(a, f, t); + return; + +rdst: + // requires register destination + regalloc(&r1, t->type, t); + gins(a, f, &r1); + gmove(&r1, t); + regfree(&r1); + return; + +hard: + // requires register intermediate + regalloc(&r1, cvt, t); + gmove(f, &r1); + gmove(&r1, t); + regfree(&r1); + return; + +hardmem: + // requires memory intermediate + tempalloc(&r1, cvt); + gmove(f, &r1); + gmove(&r1, t); + tempfree(&r1); + return; + +fatal: + // should not happen + fatal("gmove %N -> %N", f, t); } int @@ -1053,13 +1030,17 @@ naddr(Node *n, Addr *a) fatal("naddr: bad %O %D", n->op, a); break; -// case OREGISTER: -// a->type = n->val.u.reg; -// a->sym = S; -// break; + case OREGISTER: + a->type = D_OREG; + if (n->val.u.reg <= REGALLOC_RMAX) + a->reg = n->val.u.reg; + else + a->reg = n->val.u.reg - REGALLOC_F0; + a->sym = S; + break; -// case OINDEX: -// case OIND: + case OINDEX: + case OIND: // naddr(n->left, a); // if(a->type >= D_AX && a->type <= D_DI) // a->type += D_INDIR; @@ -1376,21 +1357,15 @@ optoas(int op, Type *t) // a = AMOVSD; // break; -// case CASE(OADD, TINT8): -// case CASE(OADD, TUINT8): -// a = AADDB; -// break; - -// case CASE(OADD, TINT16): -// case CASE(OADD, TUINT16): -// a = AADDW; -// break; - -// case CASE(OADD, TINT32): -// case CASE(OADD, TUINT32): -// case CASE(OADD, TPTR32): -// a = AADDL; -// break; + case CASE(OADD, TINT8): + case CASE(OADD, TUINT8): + case CASE(OADD, TINT16): + case CASE(OADD, TUINT16): + case CASE(OADD, TINT32): + case CASE(OADD, TUINT32): + case CASE(OADD, TPTR32): + a = AADD; + break; // case CASE(OADD, TINT64): // case CASE(OADD, TUINT64): @@ -1436,50 +1411,6 @@ optoas(int op, Type *t) // a = ASUBSD; // break; -// case CASE(OINC, TINT8): -// case CASE(OINC, TUINT8): -// a = AINCB; -// break; - -// case CASE(OINC, TINT16): -// case CASE(OINC, TUINT16): -// a = AINCW; -// break; - -// case CASE(OINC, TINT32): -// case CASE(OINC, TUINT32): -// case CASE(OINC, TPTR32): -// a = AINCL; -// break; - -// case CASE(OINC, TINT64): -// case CASE(OINC, TUINT64): -// case CASE(OINC, TPTR64): -// a = AINCQ; -// break; - -// case CASE(ODEC, TINT8): -// case CASE(ODEC, TUINT8): -// a = ADECB; -// break; - -// case CASE(ODEC, TINT16): -// case CASE(ODEC, TUINT16): -// a = ADECW; -// break; - -// case CASE(ODEC, TINT32): -// case CASE(ODEC, TUINT32): -// case CASE(ODEC, TPTR32): -// a = ADECL; -// break; - -// case CASE(ODEC, TINT64): -// case CASE(ODEC, TUINT64): -// case CASE(ODEC, TPTR64): -// a = ADECQ; -// break; - // case CASE(OMINUS, TINT8): // case CASE(OMINUS, TUINT8): // a = ANEGB; diff --git a/src/cmd/5g/list.c b/src/cmd/5g/list.c index 76855bdb57..ab8256ca51 100644 --- a/src/cmd/5g/list.c +++ b/src/cmd/5g/list.c @@ -122,13 +122,14 @@ Dconv(Fmt *fp) break; case D_CONST: - if(fp->flags & FmtLong) { - d1 = a->offset & 0xffffffffLL; - d2 = (a->offset>>32) & 0xffffffffLL; - snprint(str, sizeof(str), "$%lud-%lud", (ulong)d1, (ulong)d2); - break; - } - snprint(str, sizeof(str), "$%d", a->offset); + if(a->reg != NREG) + sprint(str, "$%N(R%d)", a, a->reg); + else + sprint(str, "$%N", a); + break; + + case D_CONST2: + sprint(str, "$%d-%d", a->offset, a->offset2); break; case D_FCONST: