unsigned/float and float/unsigned conversions.
SCCS-vsn: old/pcc/ccom.tahoe/local2.c 1.17
-static char sccsid[] = "@(#)local2.c 1.16 (Berkeley) %G%";
+static char sccsid[] = "@(#)local2.c 1.17 (Berkeley) %G%";
#endif
# include "pass2.h"
#endif
# include "pass2.h"
sconv(p, c == 'V');
break;
sconv(p, c == 'V');
break;
- case 'W': /* SCONV float/double => unsigned */
+ case 'W': { /* SCONV or ASSIGN float/double => unsigned */
+ NODE *src = p->in.op == SCONV ? p->in.left : p->in.right;
+
putstr("\n\t");
float_to_unsigned(p);
break;
putstr("\n\t");
float_to_unsigned(p);
break;
- case 'Y': /* SCONV unsigned => float/double */
+ case 'Y': /* SCONV or ASSIGN unsigned => float/double */
unsigned_to_float(p); /* stores into accumulator */
putstr("\n\tst");
prtype(p);
putchar('\t');
unsigned_to_float(p); /* stores into accumulator */
putstr("\n\tst");
prtype(p);
putchar('\t');
+ if (p->in.op == SCONV)
+ adrput(resc);
+ else
+ adrput(p->in.left);
+ rtyflg = 1;
int label1 = getlab();
int label2 = getlab();
int label3 = getlab();
int label1 = getlab();
int label2 = getlab();
int label3 = getlab();
+ NODE *src, *dst;
+
+ if (p->in.op == SCONV) {
+ src = p->in.left;
+ dst = resc;
+ } else {
+ src = p->in.right;
+ dst = p->in.left;
+ }
printf(".data\n\t.align\t2\nL%d:\n\t.long\t0x50000000", label1);
printf(".data\n\t.align\t2\nL%d:\n\t.long\t0x50000000", label1);
- if (l->in.type == DOUBLE)
- putstr(", 0x00000000");
- putstr(" # .double 2147483648\n\t.text\n\tcmp");
- prtype(l);
+ if (src->in.type == DOUBLE)
+ putstr(", 0x00000000 # .double");
+ else
+ putstr(" # .float");
+ putstr(" 2147483648\n\t.text\n\tcmp");
+ prtype(src);
printf("\tL%d\n\tjlss\tL%d\n\tsub", label1, label2);
printf("\tL%d\n\tjlss\tL%d\n\tsub", label1, label2);
printf("\tL%d\n\tcv", label1);
printf("\tL%d\n\tcv", label1);
putstr("\n\taddl2\t$-2147483648,");
putstr("\n\taddl2\t$-2147483648,");
printf("\n\tjbr\tL%d\nL%d:\n\tcv", label3, label2);
printf("\n\tjbr\tL%d\nL%d:\n\tcv", label3, label2);
printf("\nL%d:", label3);
}
printf("\nL%d:", label3);
}
{
int label1 = getlab();
int label2 = getlab();
{
int label1 = getlab();
int label2 = getlab();
+ NODE *src, *dst;
+
+ if (p->in.op == SCONV) {
+ src = p->in.left;
+ dst = resc;
+ } else {
+ src = p->in.right;
+ dst = p->in.left;
+ }
printf(".data\n\t.align\t2\nL%d:\n\t.long\t0x50800000", label2);
if (p->in.type == DOUBLE)
printf(".data\n\t.align\t2\nL%d:\n\t.long\t0x50800000", label2);
if (p->in.type == DOUBLE)
- putstr(", 0x00000000");
- putstr(" # .double 4294967296\n\t.text\n\tmovl\t");
- adrput(p->in.left);
+ putstr(", 0x00000000 # .double");
+ else
+ putstr(" # .float");
+ putstr(" 4294967296\n\t.text\n\tmovl\t");
+ adrput(src);
putstr("\n\tcvl");
prtype(p);
putchar('\t');
putstr("\n\tcvl");
prtype(p);
putchar('\t');
- adrput(resc);
- printf("\n\tjgeq\tL%d\n\taddd\tL%d\nL%d:", label1, label2, label1);
+ adrput(dst);
+ printf("\n\tjgeq\tL%d\n\tadd", label1);
+ prtype(p);
+ printf("\tL%d\nL%d:", label2, label1);
int val;
if (p->in.op == ASSIGN) {
int val;
if (p->in.op == ASSIGN) {
- src = getlr(p, 'R');
- dst = getlr(p, 'L');
+ src = p->in.right;
+ dst = p->in.left;
dstlen = tlen(dst);
dsttype = dst->in.type;
dstlen = tlen(dst);
dsttype = dst->in.type;
- } else /* if (p->in.op == SCONV || optype(p->in.op) == LTYPE) */ {
- src = getlr(p, 'L');
- dst = getlr(p, '1');
+ } else if (p->in.op == SCONV) {
+ src = p->in.left;
+ dst = resc;
dstlen = tlen(p);
dsttype = p->in.type;
dstlen = tlen(p);
dsttype = p->in.type;
+ } else /* if (p->in.op == OPLEAF) */ {
+ src = p;
+ dst = resc;
+ dstlen = SZINT/SZCHAR;
+ dsttype = ISUNSIGNED(src->in.type) ? UNSIGNED : INT;
}
if (src->in.op == REG) {
}
if (src->in.op == REG) {
case SCONV:
l = p->in.left;
case SCONV:
l = p->in.left;
- /* clobber conversions w/o side effects */
- if (!anyfloat(p, l) && l->in.op != PCONV &&
+ if (anyfloat(p, l)) {
+ /* save some labor later */
+ NODE *t = talloc();
+
+ if (p->in.type == UCHAR || p->in.type == USHORT) {
+ *t = *p;
+ t->in.type = UNSIGNED;
+ p->in.left = t;
+ } else if (l->in.type == UCHAR || l->in.type == USHORT) {
+ *t = *p;
+ t->in.type = INT;
+ p->in.left = t;
+ }
+ } else if (l->in.op != PCONV &&
l->in.op != CALL && l->in.op != UNARY CALL &&
tlen(p) == tlen(l)) {
l->in.op != CALL && l->in.op != UNARY CALL &&
tlen(p) == tlen(l)) {
+ /* clobber conversions w/o side effects */
if (l->in.op != FLD)
l->in.type = p->in.type;
ncopy(p, l);
if (l->in.op != FLD)
l->in.type = p->in.type;
ncopy(p, l);
p->in.right = r->in.left;
r->in.op = FREE;
}
p->in.right = r->in.left;
r->in.op = FREE;
}
+ } else if (p->in.left->in.type == UNSIGNED &&
+ r->in.type == UNSIGNED) {
+ /* let the code table handle it */
+ p->in.right = r->in.left;
+ r->in.op = FREE;
+ } else if ((p->in.left->in.type == FLOAT ||
+ p->in.left->in.type == DOUBLE) &&
+ p->in.left->in.type == r->in.type &&
+ r->in.left->in.type == UNSIGNED) {
+ /* let the code table handle it */
+ p->in.right = r->in.left;
+ r->in.op = FREE;