- if( size <= 0 || size > 65535 )
- cerror("structure size <0=0 or >65535");
- /*
- * Can't optimize with movw's or movl's here as
- * we don't know the alignment properties of
- * either source or destination (governed, potentially
- * by alignment of enclosing structure/union).
- * (PERHAPS WE COULD SIMULATE dclstruct?)
- */
- if (size != 1) {
- printf("\tmovab\t");
- adrput(l);
- printf(",r1\n\tmovab\t");
- adrput(r);
- printf(",r0\n\tmovl\t$%d,r2\n\tmovblk\n", size);
- rname(2);
- } else {
- printf("\tmovb\t");
- adrput(r);
- printf(",");
- adrput(l);
- printf("\n");
+/*
+ * Prlen() is a cheap prtype()...
+ */
+static char convtab[SZINT/SZCHAR + 1] = {
+ '?', 'b', 'w', '?', 'l'
+};
+#define prlen(len) putchar(convtab[len])
+
+
+/*
+ * Generate code for integral scalar conversions.
+ * Some of this code is designed to work around a tahoe misfeature
+ * that causes sign- and zero- extension to be defeated in
+ * certain circumstances.
+ * Basically if the source operand of a CVT or MOVZ instruction is
+ * shorter than the destination, and the source is a register
+ * or an immediate constant, sign- and zero- extension are
+ * ignored and the high bits of the source are copied. (Note
+ * that zero-extension is not a problem for immediate
+ * constants.)
+ * Another problem -- condition codes for a conversion with a
+ * register source reflect the source rather than the destination.
+ */
+sconv(p, forcc)
+ NODE *p;
+ int forcc;
+{
+ register NODE *src, *dst;
+ register NODE *tmp;
+ register int srclen, dstlen;
+ int srctype, dsttype;
+ int val;
+ int neg = 0;
+
+ if (p->in.op == ASSIGN) {
+ src = p->in.right;
+ dst = p->in.left;
+ dstlen = tlen(dst);
+ dsttype = dst->in.type;
+ } else if (p->in.op == SCONV) {
+ src = p->in.left;
+ dst = resc;
+ 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) {
+ srclen = SZINT/SZCHAR;
+ srctype = ISUNSIGNED(src->in.type) ? UNSIGNED : INT;
+ } else {
+ srclen = tlen(src);
+ srctype = src->in.type;
+ }
+
+ if (src->in.op == ICON && src->tn.name[0] == '\0') {
+ if (src->tn.lval == 0) {
+ putstr("clr");
+ prtype(dst);
+ putchar('\t');
+ adrput(dst);
+ return;
+ }
+ if (dstlen < srclen) {
+ switch (dsttype) {
+ case CHAR:
+ src->tn.lval = (char) src->tn.lval;
+ break;
+ case UCHAR:
+ src->tn.lval = (unsigned char) src->tn.lval;
+ break;
+ case SHORT:
+ src->tn.lval = (short) src->tn.lval;
+ break;
+ case USHORT:
+ src->tn.lval = (unsigned short) src->tn.lval;
+ break;