- }
- else if( p->in.op == STARG ){ /* store an arg into a temporary */
- l = getlr( p, '3' );
- r = p->in.left;
- }
- else cerror( "STASG bad" );
-
- if( r->in.op == ICON ) r->in.op = NAME;
- else if( r->in.op == REG ) r->in.op = OREG;
- else if( r->in.op != OREG ) cerror( "STASG-r" );
-
- size = p->stn.stsize;
-
- 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 {
+#define MOVB(dst, src, off) { \
+ printf("\tmovb\t"); upput(src, off); putchar(','); \
+ upput(dst, off); putchar('\n'); \
+}
+#define MOVW(dst, src, off) { \
+ printf("\tmovw\t"); upput(src, off); putchar(','); \
+ upput(dst, off); putchar('\n'); \
+}
+#define MOVL(dst, src, off) { \
+ printf("\tmovl\t"); upput(src, off); putchar(','); \
+ upput(dst, off); putchar('\n'); \
+}
+/*
+ * Generate code for a structure assignment.
+ */
+stasg(p)
+ register NODE *p;
+{
+ register NODE *l, *r;
+ register int size;
+
+ switch (p->in.op) {
+ case STASG: /* regular assignment */
+ l = p->in.left;
+ r = p->in.right;
+ break;
+ case STARG: /* place arg on the stack */
+ l = getlr(p, '3');
+ r = p->in.left;
+ break;
+ default:
+ cerror("STASG bad");
+ /*NOTREACHED*/
+ }
+ /*
+ * Pun source for use in code generation.
+ */
+ switch (r->in.op) {
+ case ICON:
+ r->in.op = NAME;
+ break;
+ case REG:
+ r->in.op = OREG;
+ break;
+ default:
+ cerror( "STASG-r" );
+ /*NOTREACHED*/
+ }
+ size = p->stn.stsize;
+ if (size <= 0 || size > 65535)
+ cerror("structure size out of range");
+ /*
+ * Generate optimized code based on structure size
+ * and alignment properties....
+ */
+ switch (size) {
+
+ case 1:
+ printf("\tmovb\t");
+ optimized:
+ adrput(r);
+ printf(",");
+ adrput(l);
+ printf("\n");
+werror("optimized structure assignment (size %d alignment %d)", size, p->stn.stalign);
+ break;
+
+ case 2:
+ if (p->stn.stalign != 2) {
+ MOVB(l, r, SZCHAR);
+ printf("\tmovb\t");
+ } else
+ printf("\tmovw\t");
+ goto optimized;
+
+ case 4:
+ if (p->stn.stalign != 4) {
+ if (p->stn.stalign != 2) {
+ MOVB(l, r, 3*SZCHAR);
+ MOVB(l, r, 2*SZCHAR);
+ MOVB(l, r, 1*SZCHAR);