/* * Move data between registers. While basic registers aren't a problem, * we have to handle the special case of overlapping composite registers. */ void rmove(int s, int d, TWORD t) { switch (t) { case LONGLONG: case ULONGLONG: if (s == d+1) { /* dh = sl, copy low word first */ printf("\tmove "); print_reg64name(stdout, d, 0); printf(","); print_reg64name(stdout, s, 0); printf("\t# 64-bit rmove\n"); printf("\tmove "); print_reg64name(stdout, d, 1); printf(","); print_reg64name(stdout, s, 1); printf("\n"); } else { /* copy high word first */ printf("\tmove "); print_reg64name(stdout, d, 1); printf(","); print_reg64name(stdout, s, 1); printf(" # 64-bit rmove\n"); printf("\tmove "); print_reg64name(stdout, d, 0); printf(","); print_reg64name(stdout, s, 0); printf("\n"); } break; case FLOAT: case DOUBLE: case LDOUBLE: if (t == FLOAT) printf("\tmov.s "); else printf("\tmov.d "); print_reg64name(stdout, d, 0); printf(","); print_reg64name(stdout, s, 0); printf("\t# float/double rmove\n"); break; default: printf("\tmove %s,%s\t# default rmove\n", rnames[d], rnames[s]); } }
/* * Write out the upper address, like the upper register of a 2-register * reference, or the next memory location. */ void upput(NODE * p, int size) { size /= SZCHAR; switch (p->n_op) { case REG: if (GCLASS(p->n_rval) == CLASSB || GCLASS(p->n_rval) == CLASSC) print_reg64name(stdout, p->n_rval, 1); else fputs(rnames[p->n_rval], stdout); break; case NAME: case OREG: p->n_lval += size; adrput(stdout, p); p->n_lval -= size; break; case ICON: fprintf(stdout, CONFMT, p->n_lval >> 32); break; default: comperr("upput bad op %d size %d", p->n_op, size); } }
/* * Write out the upper address, like the upper register of a 2-register * reference, or the next memory location. */ void upput(NODE * p, int size) { size /= SZCHAR; switch (p->n_op) { case REG: if (GCLASS(p->n_rval) == CLASSB || GCLASS(p->n_rval) == CLASSC) print_reg64name(stdout, p->n_rval, 1); else printf("%s", rnames[p->n_rval]); break; case NAME: case OREG: setlval(p, getlval(p) + size); adrput(stdout, p); setlval(p, getlval(p) - size); break; case ICON: printf(CONFMT, getlval(p) >> 32); break; default: comperr("upput bad op %d size %d", p->n_op, size); } }
void adrput(FILE * io, NODE * p) { int r; /* output an address, with offsets, from p */ if (p->n_op == FLD) p = p->n_left; switch (p->n_op) { case NAME: if (p->n_name[0] != '\0') fputs(p->n_name, io); if (p->n_lval != 0) fprintf(io, "+" CONFMT, p->n_lval); return; case OREG: r = p->n_rval; if (p->n_lval) fprintf(io, "%d", (int) p->n_lval); fprintf(io, "(%s)", rnames[p->n_rval]); return; case ICON: /* addressable value of the constant */ conput(io, p); return; case REG: if (GCLASS(p->n_rval) == CLASSB || GCLASS(p->n_rval) == CLASSC) print_reg64name(io, p->n_rval, 0); else fputs(rnames[p->n_rval], io); return; default: comperr("illegal address, op %d, node %p", p->n_op, p); return; } }