Annotation of researchv9/jerq/src/lib/j/bitblt.c, revision 1.1

1.1     ! root        1: /* BITBLT()    Moves bits around on the screen, and does a LOT of it
        !             2:  *
        !             3:  *     WARNING
        !             4:  *     WARNING:  to any future modifier of this code.  This is highly 
        !             5:  *             hand optimized code, it pushes the frame pointer and
        !             6:  *             references locals off the stack pointer, 
        !             7:  *             and it even simulates register
        !             8:  *             allocation.  Be very careful if you edit this.
        !             9:  */
        !            10: 
        !            11: #include <jerq.h>
        !            12:                /* alignment codes for narrow rectangles */
        !            13: #define S_STRADDLE     0x4     /* source straddles a word boundary */
        !            14: #define D_STRADDLE     0x8     /* dest straddles a word boundary */
        !            15: #define LEFTDIR        8
        !            16: #define NOSHIFT 4
        !            17: #define DAMMIT 4               /* you'll see why */
        !            18: #undef sw
        !            19: #define DX1    m
        !            20: 
        !            21: bitblt(sm,r,dm,p,fc)
        !            22: Bitmap *sm,*dm;
        !            23: Rectangle r;
        !            24: Point p;
        !            25: int fc;
        !            26: {
        !            27:        register Word *source,*dest;            /* %r8-%r7 */
        !            28:        register Word sw, dw;                   /* %r6-%r5 */
        !            29:        register UWord m;                       /* %r4     */
        !            30:        register int i;                         /* %r3     */
        !            31: 
        !            32:        int a,b,j,h,w,dx1,px31,rx31;
        !            33:        unsigned int mask1,mask2,mask3,mask4,ntmask1,ntmask2;
        !            34:        int dummy1, dummy2;             /* for future use, CANNOT CHANGE */
        !            35:                                        /* NUMBER OF LOCALS DUE TO %fp  */
        !            36:                                        /* TRICKS                       */
        !            37:        /* clip to the source Bitmap */
        !            38:        if(r.origin.x < sm->rect.origin.x)
        !            39:                r.origin.x=sm->rect.origin.x;
        !            40:        if(r.corner.x > sm->rect.corner.x)
        !            41:                r.corner.x=sm->rect.corner.x;
        !            42:        if(r.origin.y < sm->rect.origin.y)
        !            43:                r.origin.y=sm->rect.origin.y;
        !            44:        if(r.corner.y > sm->rect.corner.y)
        !            45:                r.corner.y=sm->rect.corner.y;
        !            46:        /*
        !            47:         * If the sm->rect and r are disjoint, r is now degenerate,
        !            48:         * due to the clipping, and the next clipping code will reject it.
        !            49:         * This is safe because we will only increase origin or decrease corner.
        !            50:         */
        !            51:        /* clip to the destination Bitmap */
        !            52:        if(p.x < dm->rect.origin.x){
        !            53:                r.origin.x+=dm->rect.origin.x-p.x;
        !            54:                p.x=dm->rect.origin.x;
        !            55:        }
        !            56:        if(p.y < dm->rect.origin.y){
        !            57:                r.origin.y+=dm->rect.origin.y-p.y;
        !            58:                p.y=dm->rect.origin.y;
        !            59:        }
        !            60:        if(r.corner.x-r.origin.x > dm->rect.corner.x-p.x)
        !            61:                r.corner.x=r.origin.x+(dm->rect.corner.x-p.x);
        !            62:        if(r.corner.y-r.origin.y > dm->rect.corner.y-p.y)
        !            63:                r.corner.y=r.origin.y+(dm->rect.corner.y-p.y);
        !            64:        i = r.corner.y - r.origin.y;    /* going to be h */
        !            65:        dw = r.corner.x - r.origin.x - 1;       /* going to be dx1 */
        !            66:        if (i <= 0 || dw < 0)
        !            67:                return;
        !            68:        if (dw < 32)
        !            69:                goto narrow;
        !            70:        DX1 = dw;
        !            71:        h = i; 
        !            72:        ntmask1 = topbits[p.x & 0x1f];
        !            73:        mask1 = ~ntmask1;
        !            74:        mask2 = topbits[((p.x+DX1) & 31) + 1];
        !            75:        ntmask2 = ~mask2;
        !            76:        w = ((p.x+DX1) >> 5) - (p.x >> 5);      /* inner loop+1: sub 1 later*/
        !            77:        sw = ((sm->width - w) << 2);    /* sleazy hack to avoid shift */
        !            78:        dw = ((dm->width - w) << 2);    /* in outer, inner loops */
        !            79:        if (sm == dm) {         /* may have to mess with loop order */
        !            80:                if (r.origin.y < p.y) {         /* swap top with bottom */
        !            81:                        r.origin.y += i-1;
        !            82:                        p.y += i-1;
        !            83:                        if (r.origin.x < p.x) { /* swap left with right */
        !            84:                                fc |= LEFTDIR;
        !            85:                                r.origin.x = r.origin.x + DX1;
        !            86:                                p.x = p.x + DX1;
        !            87:                                sw = -sw;
        !            88:                                dw = -dw;
        !            89:                        }
        !            90:                        else
        !            91:                        {
        !            92:                                sw -= (sm->width << 3); /* -(w+n) == (w-n) - 2*w  */
        !            93:                                dw -= (dm->width << 3) ;
        !            94:                        }
        !            95:                }
        !            96:                else
        !            97:                {
        !            98:                        if (r.origin.x < p.x) { /* swap left with right */
        !            99:                                fc |= LEFTDIR;
        !           100:                                r.origin.x = r.origin.x + DX1;
        !           101:                                p.x = p.x + DX1;
        !           102:                                sw = (sm->width + w) << 2;
        !           103:                                dw = (dm->width + w) << 2;
        !           104:                        }
        !           105:                }
        !           106:        }
        !           107:        w--;                    /* subtract the 1 like we promised */
        !           108:        px31 = p.x & 0x1f;              /* commonly used expression */
        !           109:        rx31 = r.origin.x & 0x1f;       /* commonly used expression */
        !           110:        dest = addr(dm,p);
        !           111:        source = addr(sm,r.origin);
        !           112:        a = px31 - rx31;
        !           113:        if(a == 0)
        !           114:                fc |= NOSHIFT;
        !           115:        else if (a < 0)
        !           116:                a += 32;
        !           117:                /* a == 0 means no shift, remember that */
        !           118:        b = 32 - a;
        !           119:        switch (fc) {
        !           120: 
        !           121:        case F_OR | NOSHIFT | LEFTDIR:
        !           122:                b = w>>2;
        !           123:                w = w&3;
        !           124:                m = h;          /* m is free => use it */
        !           125:                do {
        !           126:                        *dest-- |= mask2 & *source--;
        !           127:                        if ((i = b) > 0) do {
        !           128:                                *dest |= *source;
        !           129:                                *(dest-1) |= *(source-1);
        !           130:                                *(dest-2) |= *(source-2);
        !           131:                                *(dest-3) |= *(source-3);
        !           132:                                dest -= 4;
        !           133:                                source -= 4;
        !           134:                        } while (--i > 0);
        !           135:                        if ((i = w) > 0) do {
        !           136:                                *dest-- |= *source--;
        !           137:                        } while (--i > 0);
        !           138:                        *dest |= mask1 & *source;
        !           139:                        asm(" ADDW2     %r6,%r8");      /*source += sw; */
        !           140:                        asm(" ADDW2     %r5,%r7");      /*dest += dw; */
        !           141:                } while (--m != 0);
        !           142:                break;
        !           143:        case F_OR | LEFTDIR:
        !           144:                if ((px31) < (rx31))
        !           145:                        source++;       /* adjust for pipeline */
        !           146:                do {
        !           147:                        m = *source--;  /* m is a free register */
        !           148:                        *dest-- |= (((m >> a) | (*source << b)) & mask2);
        !           149:                        if ((i=w) > 0) do {
        !           150:                                m = (*source--) >> a;
        !           151:                                *dest-- |= m | (*source << b);
        !           152:                        } while (--i > 0);
        !           153:                        m = *source;    /* m is a free register */
        !           154:                        *dest |= (((m >> a) | (*(source-1) << b)) & mask1);
        !           155:                        asm(" addw2     %r6,%r8");      /*source += sw; */
        !           156:                        asm(" addw2     %r5,%r7");      /*dest += dw; */
        !           157:                } while (--h > 0);
        !           158:                break;
        !           159:        case F_OR | NOSHIFT:
        !           160:                b = w>>2;
        !           161:                w = w&3;
        !           162:                m = h;          /* m is free => use it */
        !           163:                do {
        !           164:                        *dest++ |= (mask1 & *source++);
        !           165:                        if ((i = b) > 0) do {
        !           166:                                *dest |= *source;
        !           167:                                *(dest+1) |= *(source+1);
        !           168:                                *(dest+2) |= *(source+2);
        !           169:                                *(dest+3) |= *(source+3);
        !           170:                                dest += 4;
        !           171:                                source += 4;
        !           172:                        } while (--i > 0);
        !           173:                        if ((i = w) > 0) do {
        !           174:                                *dest++ |= *source++;
        !           175:                        } while (--i > 0);
        !           176:                        *dest |= (mask2 & *source);
        !           177:                        asm(" addw2     %r6,%r8");      /*source += sw; */
        !           178:                        asm(" addw2     %r5,%r7");      /*dest += dw; */
        !           179:                } while (--m != 0);
        !           180:                break;
        !           181:        case F_OR:
        !           182:                if ((px31) > (rx31))
        !           183:                        source--;       /* adjust for pipeline */
        !           184:                do {
        !           185:                        m = *source++;  /* m is a free register */
        !           186:                        *dest++ |= (((m << b) | (*source >> a)) & mask1);
        !           187:                        if ((i=w) > 0) do {
        !           188:                                m = (*source++) << b;
        !           189:                                *dest++ |= m | (*source >> a);
        !           190:                        } while (--i > 0);
        !           191:                        m = *source;    /* m is a free register */
        !           192:                        *dest |= (((m << b) | (*(source+1) >> a)) & mask2);
        !           193:                        asm(" addw2     %r6,%r8");      /*source += sw; */
        !           194:                        asm(" addw2     %r5,%r7");      /*dest += dw; */
        !           195:                } while (--h > 0);
        !           196:                break;
        !           197:        case F_CLR | NOSHIFT | LEFTDIR:
        !           198:                b = w>>2;
        !           199:                w = w&3;
        !           200:                m = h;          /* m is free => use it */
        !           201:                do {
        !           202:                        *dest-- &= ~(mask2 & *source--);
        !           203:                        if ((i = b) > 0) do {
        !           204:                                *dest &= ~(*source);
        !           205:                                *(dest-1) &= ~(*(source-1));
        !           206:                                *(dest-2) &= ~(*(source-2));
        !           207:                                *(dest-3) &= ~(*(source-3));
        !           208:                                dest -= 4;
        !           209:                                source -= 4;
        !           210:                        } while (--i > 0);
        !           211:                        if ((i = w) > 0) do {
        !           212:                                *dest-- &= ~(*source--);
        !           213:                        } while (--i > 0);
        !           214:                        *dest &= ~(mask1 & *source);
        !           215:                        asm(" addw2     %r6,%r8");      /*source += sw; */
        !           216:                        asm(" addw2     %r5,%r7");      /*dest += dw; */
        !           217:                } while (--m != 0);
        !           218:                break;
        !           219:        case F_CLR | LEFTDIR:
        !           220:                if ((px31) < (rx31))
        !           221:                        source++;       /* adjust for pipeline */
        !           222:                do {
        !           223:                        m = *source--;  /* m is a free register */
        !           224:                        *dest-- &= ~((((m >> a) | (*source << b)) & mask2));
        !           225:                        if ((i=w) > 0) do {
        !           226:                                m = (*source--) >> a;
        !           227:                                *dest-- &= ~(m | (*source << b));
        !           228:                        } while (--i > 0);
        !           229:                        m = *source;    /* m is a free register */
        !           230:                        *dest &= ~((((m >> a) | (*(source-1) << b)) & mask1));
        !           231:                        asm(" addw2     %r6,%r8");      /*source += sw; */
        !           232:                        asm(" addw2     %r5,%r7");      /*dest += dw; */
        !           233:                } while (--h > 0);
        !           234:                break;
        !           235:        case F_CLR | NOSHIFT:
        !           236:                b = w>>2;
        !           237:                w = w&3;
        !           238:                m = h;          /* m is free => use it */
        !           239:                do {
        !           240:                        *dest++ &= ~((mask1 & *source++));
        !           241:                        if ((i = b) > 0) do {
        !           242:                                *dest &= ~(*source);
        !           243:                                *(dest+1) &= ~(*(source+1));
        !           244:                                *(dest+2) &= ~(*(source+2));
        !           245:                                *(dest+3) &= ~(*(source+3));
        !           246:                                dest += 4;
        !           247:                                source += 4;
        !           248:                        } while (--i > 0);
        !           249:                        if ((i = w) > 0) do {
        !           250:                                *dest++ &= ~(*source++);
        !           251:                        } while (--i > 0);
        !           252:                        *dest &= ~((mask2 & *source));
        !           253:                        asm(" addw2     %r6,%r8");      /*source += sw; */
        !           254:                        asm(" addw2     %r5,%r7");      /*dest += dw; */
        !           255:                } while (--m != 0);
        !           256:                break;
        !           257:        case F_CLR:
        !           258:                if ((px31) > (rx31))
        !           259:                        source--;       /* adjust for pipeline */
        !           260:                do {
        !           261:                        m = *source++;  /* m is a free register */
        !           262:                        *dest++ &= ~((((m << b) | (*source >> a)) & mask1));
        !           263:                        if ((i=w) > 0) do {
        !           264:                                m = (*source++) << b;
        !           265:                                *dest++ &= ~(m | (*source >> a));
        !           266:                        } while (--i > 0);
        !           267:                        m = *source;    /* m is a free register */
        !           268:                        *dest &= ~((((m << b) | (*(source+1) >> a)) & mask2));
        !           269:                        asm(" addw2     %r6,%r8");      /*source += sw; */
        !           270:                        asm(" addw2     %r5,%r7");      /*dest += dw; */
        !           271:                } while (--h > 0);
        !           272:                break;
        !           273:        case F_XOR | NOSHIFT | LEFTDIR:
        !           274:                b = w>>2;
        !           275:                w = w&3;
        !           276:                m = h;          /* m is free => use it */
        !           277:                do {
        !           278:                        *dest-- ^= mask2 & *source--;
        !           279:                        if ((i = b) > 0) do {
        !           280:                                *dest ^= *source;
        !           281:                                *(dest-1) ^= *(source-1);
        !           282:                                *(dest-2) ^= *(source-2);
        !           283:                                *(dest-3) ^= *(source-3);
        !           284:                                dest -= 4;
        !           285:                                source -= 4;
        !           286:                        } while (--i > 0);
        !           287:                        if ((i = w) > 0) do {
        !           288:                                *dest-- ^= *source--;
        !           289:                        } while (--i > 0);
        !           290:                        *dest ^= mask1 & *source;
        !           291:                        asm(" addw2     %r6,%r8");      /*source += sw; */
        !           292:                        asm(" addw2     %r5,%r7");      /*dest += dw; */
        !           293:                } while (--m != 0);
        !           294:                break;
        !           295:        case F_XOR | LEFTDIR:
        !           296:                if ((px31) < (rx31))
        !           297:                        source++;       /* adjust for pipeline */
        !           298:                do {
        !           299:                        m = *source--;  /* m is a free register */
        !           300:                        *dest-- ^= (((m >> a) | (*source << b)) & mask2);
        !           301:                        if ((i=w) > 0) do {
        !           302:                                m = (*source--) >> a;
        !           303:                                *dest-- ^= m | (*source << b);
        !           304:                        } while (--i > 0);
        !           305:                        m = *source;    /* m is a free register */
        !           306:                        *dest ^= (((m >> a) | (*(source-1) << b)) & mask1);
        !           307:                        asm(" addw2     %r6,%r8");      /*source += sw; */
        !           308:                        asm(" addw2     %r5,%r7");      /*dest += dw; */
        !           309:                } while (--h > 0);
        !           310:                break;
        !           311:        case F_XOR | NOSHIFT:
        !           312:                b = w>>2;
        !           313:                w = w&3;
        !           314:                m = h;          /* m is free => use it */
        !           315:                do {
        !           316:                        *dest++ ^= (mask1 & *source++);
        !           317:                        if ((i = b) > 0) do {
        !           318:                                *dest ^= *source;
        !           319:                                *(dest+1) ^= *(source+1);
        !           320:                                *(dest+2) ^= *(source+2);
        !           321:                                *(dest+3) ^= *(source+3);
        !           322:                                dest += 4;
        !           323:                                source += 4;
        !           324:                        } while (--i > 0);
        !           325:                        if ((i = w) > 0) do {
        !           326:                                *dest++ ^= *source++;
        !           327:                        } while (--i > 0);
        !           328:                        *dest ^= (mask2 & *source);
        !           329:                        asm(" addw2     %r6,%r8");      /*source += sw; */
        !           330:                        asm(" addw2     %r5,%r7");      /*dest += dw; */
        !           331:                } while (--m != 0);
        !           332:                break;
        !           333:        case F_XOR:
        !           334:                if ((px31) > (rx31))
        !           335:                        source--;       /* adjust for pipeline */
        !           336:                asm(" PUSHW %ap");
        !           337:                m = topbits[a];
        !           338:                asm(" MCOMW %r4, %r1");
        !           339:                asm(" MOVW %r4, %r2");
        !           340:                asm(" MOVW 0(%fp),%ap");
        !           341:                asm(" PUSHW %fp");
        !           342:        asm("BW_XORLOOP:");
        !           343:                asm(" ROTW %ap, 0(%r8), %r4");
        !           344:                asm(" ANDW2 %r2,%r4");
        !           345:                asm(" ADDW2 &4,%r8");
        !           346:                asm(" ROTW %ap,0(%r8),%r0");
        !           347:                asm(" ANDW3 %r0,%r1,%fp");
        !           348:                asm(" ORW2 %r4,%fp");
        !           349:                asm(" ANDW2 -0x28(%sp),%fp");
        !           350:                asm(" XORW2 %fp,0(%r7)");
        !           351:                asm(" ADDW2 &4,%r7");
        !           352:                        /* if (i = w) */
        !           353:                asm(" MOVW -0x38(%sp),%r3");
        !           354:                asm(" BEB BW_XORINNER");
        !           355:                do{
        !           356:                        asm(" ANDW3 %r2,%r0,%r4");
        !           357:                        asm(" ADDW2 &4,%r8");
        !           358:                        asm(" ROTW %ap, 0(%r8),%r0");
        !           359:                        asm(" ANDW3 %r0,%r1,%fp");
        !           360:                        asm(" ORW2 %r4,%fp");
        !           361:                        asm(" XORW2 %fp,0(%r7)");
        !           362:                        asm(" ADDW2 &4, %r7");
        !           363:                } while (--i > 0);
        !           364:        asm("BW_XORINNER:");
        !           365:                asm(" ROTW %ap, 0(%r8),%r4");
        !           366:                asm(" ANDW2 %r2,%r4");
        !           367:                asm(" LRSW3 %ap, 4(%r8),%r0");
        !           368:                asm(" ORW2 %r4,%r0");
        !           369:                asm(" ANDW2 -0x24(%sp),%r0");
        !           370:                asm(" XORW2 %r0,0(%r7)");
        !           371:                asm(" ADDW2     %r6,%r8");      /*source += sw; */
        !           372:                asm(" ADDW2     %r5,%r7");      /*dest += dw; */
        !           373:                        /* } while (--h > 0); */
        !           374:                asm(" DECW -0x3c(%sp)");
        !           375:                asm(" BGB BW_XORLOOP");
        !           376: 
        !           377:                asm(" POPW %fp");
        !           378:                asm(" POPW %ap");
        !           379: 
        !           380:        /* above is similar to: 
        !           381: /*             do {
        !           382: /*                     m = *source++ << b;     /* m is a free register */
        !           383: /*                     *dest++ ^= ((m & LMASK) | ((*source >> a)& RMASK) & mask1);
        !           384: /*                     if ((i=w) > 0) do {
        !           385: /*                             m = ((*source++) << b) & LMASK;
        !           386: /*                             *dest++ ^= m | ((*source >> a)&RMASK);
        !           387: /*                     } while (--i > 0);
        !           388: /*                     m = *source;    /* m is a free register */
        !           389: /*                     *dest ^= (((m << b) | (*(source+1) >> a)) & mask2);
        !           390: /*                     asm(" addw2     %r6,%r8");      /*source += sw; */
        !           391: /*                     asm(" addw2     %r5,%r7");      /*dest += dw; */
        !           392: /*             } while (--h > 0);              */
        !           393:                break;
        !           394:        case F_STORE | NOSHIFT | LEFTDIR:
        !           395:                b = w>>2;
        !           396:                w = w&3;
        !           397:                m = h;          /* m is free => use it */
        !           398:                do {
        !           399:                        *dest = (ntmask2 & *dest) | (mask2 & *source--);
        !           400:                        --dest;
        !           401:                        if ((i = b) > 0) do {
        !           402:                                *dest = *source;
        !           403:                                *(dest-1) = *(source-1);
        !           404:                                *(dest-2) = *(source-2);
        !           405:                                *(dest-3) = *(source-3);
        !           406:                                dest -= 4;
        !           407:                                source -= 4;
        !           408:                        } while (--i > 0);
        !           409:                        if ((i = w) > 0) do {
        !           410:                                *dest-- = *source--;
        !           411:                        } while (--i > 0);
        !           412:                        *dest = (ntmask1 & *dest) | (mask1 & *source);
        !           413:                        asm(" addw2     %r6,%r8");      /*source += sw; */
        !           414:                        asm(" addw2     %r5,%r7");      /*dest += dw; */
        !           415:                } while (--m != 0);
        !           416:                break;
        !           417:        case F_STORE | LEFTDIR:
        !           418:                if ((px31) < (rx31))
        !           419:                        source++;       /* adjust for pipeline */
        !           420:                do {
        !           421:                        m = *source--;  /* m is a free register */
        !           422:                        *dest = (((m >> a) | (*source << b)) & mask2) |
        !           423:                                                 (*dest & ntmask2);
        !           424:                        --dest;
        !           425:                        if ((i=w) > 0) do {
        !           426:                                m = (*source--) >> a;
        !           427:                                *dest-- = m | (*source << b);
        !           428:                        } while (--i > 0);
        !           429:                        m = *source;    /* m is a free register */
        !           430:                        *dest = (((m >> a) | (*(source-1) << b)) & mask1) |
        !           431:                                                 (*dest & ntmask1);
        !           432:                        asm(" addw2     %r6,%r8");      /*source += sw; */
        !           433:                        asm(" addw2     %r5,%r7");      /*dest += dw; */
        !           434:                } while (--h > 0);
        !           435:                break;
        !           436:        case F_STORE | NOSHIFT:
        !           437:                if (w > 25)
        !           438:                        goto widestore;
        !           439:                i = 25 - w;
        !           440:                m = (i << 2) + (i << 1);
        !           441:                
        !           442:                asm(" LLSW3 &0x2,0x10(%fp),%r0");       /* bytewidth in r0*/
        !           443:                asm(" ADDW2 &4,%r0");   /* r0 +=4 for loop offsets */
        !           444:                asm(" MOVAW B_FS_N,%r1");
        !           445:                asm(" ADDW2 %r4,%r1");  /* r1 += &label, or jump addr*/
        !           446:                m = h;          /* m is free reg, use it as height */
        !           447:                asm(" MOVW 0x20(%fp),%r2");     /* r2 = mask1 */
        !           448:                asm(" PUSHW %ap");      /* save fp and ap */
        !           449:                asm(" MOVW 0x24(%fp),%ap");     /* ap = mask2 */
        !           450:                asm(" PUSHW %fp");
        !           451:                asm(" MOVW %r1,%fp");   /* put jump index into fp */
        !           452: 
        !           453:                do{
        !           454: 
        !           455:                asm(" XORW3 0(%r7),0(%r8),%r1");
        !           456:                asm(" ANDW2 %r2,%r1");
        !           457:                asm(" XORW2 %r1,0(%r7)");
        !           458: 
        !           459:                asm(" JMP     0(%fp)");
        !           460:                asm("B_FS_N: ");                /* label */
        !           461:                asm(" MOVW    0x64(%r8),0x64(%r7)");
        !           462:                asm(" MOVW    0x60(%r8),0x60(%r7)"); asm(" MOVW    0x5c(%r8),0x5c(%r7)");
        !           463:                asm(" MOVW    0x58(%r8),0x58(%r7)"); asm(" MOVW    0x54(%r8),0x54(%r7)");
        !           464:                asm(" MOVW    0x50(%r8),0x50(%r7)"); asm(" MOVW    0x4c(%r8),0x4c(%r7)"); asm(" MOVW    0x48(%r8),0x48(%r7)"); asm(" MOVW    0x44(%r8),0x44(%r7)");
        !           465:                asm(" MOVW    0x40(%r8),0x40(%r7)"); asm(" MOVW    0x3c(%r8),0x3c(%r7)"); asm(" MOVW    0x38(%r8),0x38(%r7)"); asm(" MOVW    0x34(%r8),0x34(%r7)");
        !           466:                asm(" MOVW    0x30(%r8),0x30(%r7)"); asm(" MOVW    0x2c(%r8),0x2c(%r7)"); asm(" MOVW    0x28(%r8),0x28(%r7)"); asm(" MOVW    0x24(%r8),0x24(%r7)");
        !           467:                asm(" MOVW    0x20(%r8),0x20(%r7)"); asm(" MOVW    0x1c(%r8),0x1c(%r7)"); asm(" MOVW    0x18(%r8),0x18(%r7)");
        !           468:                asm(" MOVW    0x14(%r8),0x14(%r7)");
        !           469:                asm(" MOVW    0x10(%r8),0x10(%r7)");
        !           470:                asm(" MOVW    0xc(%r8),0xc(%r7)");
        !           471:                asm(" MOVW    0x8(%r8),0x8(%r7)");
        !           472:                asm(" MOVW    0x4(%r8),0x4(%r7)");
        !           473:                asm(" ADDW2   %r0,%r8");
        !           474:                asm(" ADDW2   %r0,%r7");
        !           475:                asm(" XORW3 0(%r7),0(%r8),%r1");
        !           476:                asm(" ANDW2 %ap,%r1");  /* ap has mask2 */
        !           477:                asm(" XORW2 %r1,0(%r7)");
        !           478:                asm(" ADDW2   %r6,%r8");
        !           479:                asm(" ADDW2   %r5,%r7");
        !           480:        } while (--m != 0);
        !           481:                asm(" POPW %fp");
        !           482:                asm(" POPW %ap");
        !           483:        break;
        !           484:        /* ABOVE ALMOST EQUAL TO : */
        !           485: widestore:
        !           486:                b = w >> 2;
        !           487:                w = w & 3;
        !           488:                m = h;
        !           489:                do {
        !           490:                        *dest = (ntmask1 & *dest) | (mask1 & *source++);
        !           491:                        dest++;
        !           492:                        if ((i = b) > 0) do {
        !           493:                                *dest = *source;
        !           494:                                *(dest+1) = *(source+1);
        !           495:                                *(dest+2) = *(source+2);
        !           496:                                *(dest+3) = *(source+3);
        !           497:                                dest += 4;
        !           498:                                source += 4;
        !           499:                        } while (--i > 0);
        !           500:                        if ((i = w) > 0) do {
        !           501:                                *dest++ = *source++;
        !           502:                        } while (--i > 0);
        !           503:                        *dest = (ntmask2 & *dest) | (mask2 & *source);
        !           504:                        asm(" addw2     %r6,%r8");
        !           505:                        asm(" addw2     %r5,%r7");
        !           506:                } while (--m != 0);
        !           507:                break;
        !           508:        case F_STORE:
        !           509:                if ((px31) > (rx31))
        !           510:                        source--;       /* adjust for pipeline */
        !           511:                do {
        !           512:                        m = *source++;  /* m is a free register */
        !           513:                        *dest = (((m << b) | (*source >> a)) & mask1) |
        !           514:                                                 (*dest & ntmask1);
        !           515:                        dest++;
        !           516:                        if ((i=w) > 0) do {
        !           517:                                m = (*source++) << b;
        !           518:                                *dest++ = m | (*source >> a);
        !           519:                        } while (--i > 0);
        !           520:                        m = *source;    /* m is a free register */
        !           521:                        *dest = (((m << b) | (*(source+1) >> a)) & mask2) |
        !           522:                                                 (*dest & ntmask2);
        !           523:                        asm(" addw2     %r6,%r8");      /*source += sw; */
        !           524:                        asm(" addw2     %r5,%r7");      /*dest += dw; */
        !           525:                } while (--h > 0);
        !           526:                break;
        !           527:        }
        !           528: 
        !           529:        return;
        !           530: narrow:
        !           531:        /*
        !           532:         * width is 32 bits or less.  There are four basic cases
        !           533:         * (in addition to the function code), which depend on whether
        !           534:         * the source and dest straddle word boundaries or not
        !           535:         */
        !           536: 
        !           537:        m = p.x & 31;           /* commonly used expression  */
        !           538:        sw = r.origin.x & 31;           /* commonly used expression  */
        !           539:        if (sw + dw > 31)       /* if source is NOT aligned */
        !           540:        {
        !           541:                fc |= S_STRADDLE;
        !           542:                mask1 = ONES >> sw;
        !           543:                mask2 = topbits[((sw + dw) & 31) + 1];
        !           544:        }
        !           545: 
        !           546:        if (m + dw > 31)        /* if dest is NOT aligned */
        !           547:        {
        !           548:                fc |= D_STRADDLE;
        !           549:                mask3 = ONES >> m;
        !           550:                mask4 = topbits[((m + dw) & 31) + 1];
        !           551:        }
        !           552:        px31 = m;
        !           553:        m = m - sw;
        !           554:        a = dw;
        !           555: 
        !           556:        if ((sm == dm) && (r.origin.y < p.y))
        !           557:        {       /* may have to mess with loop order */
        !           558:                r.origin.y += i-1;
        !           559:                p.y += i-1;
        !           560:                sw = -(sm->width << 2); /* sleazy hack to avoid shift */
        !           561:                dw = -(dm->width << 2); /* in outer, inner loops */
        !           562:        }
        !           563:        else
        !           564:        {
        !           565:                sw = sm->width << 2;
        !           566:                dw = dm->width << 2;
        !           567:        }
        !           568: 
        !           569:        source = addr(sm,r.origin);
        !           570:        dest = addr(dm,p);
        !           571: 
        !           572:        switch(fc)
        !           573:        {
        !           574:        case F_STORE:
        !           575:                mask1 = topbits[a+1] >> (px31);
        !           576:                asm(" MOVW 0x20(%fp),%r1");
        !           577:                do {
        !           578:                        asm(" ROTW %r4,0(%r8),%r2");
        !           579:                        asm(" XORW2 0(%r7),%r2");
        !           580:                        asm(" ANDW2 %r1,%r2");
        !           581:                        asm(" XORW2 %r2,0(%r7)");
        !           582:                        asm(" ADDW2 %r6, %r8");
        !           583:                        asm(" ADDW2 %r5, %r7");
        !           584:                } while (--i > 0);
        !           585:                break;
        !           586:        case F_STORE | S_STRADDLE:
        !           587:                mask4 = 32 - m;         /* REALLY the other shift count */
        !           588:                mask3 = topbits[a+1] >> px31;
        !           589:                asm(" PUSHW %ap");      /* store ap on stack */
        !           590:                asm(" MOVW 0x28(%fp),%r0");     /* put mask3 in r0 */
        !           591:                asm(" MOVW 0x2c(%fp),%ap");     /* put other shift in ap */
        !           592: 
        !           593:                do {
        !           594:                        asm(" LLSW3 %ap,0(%r8),%r1"); /* 32-m,lft shft */
        !           595:                        asm(" LRSW3 %r4,4(%r8),%r2");   /* m, right shift */
        !           596:                        asm(" ORW2  %r2, %r1");
        !           597:                        asm(" XORW2 0(%r7),%r1");
        !           598:                        asm(" ANDW2 %r0,%r1");
        !           599:                        asm(" XORW2 %r1,0(%r7)");
        !           600:                        asm(" ADDW2 %r6, %r8");
        !           601:                        asm(" ADDW2 %r5, %r7");
        !           602:                } while (--i > 0);
        !           603:                asm(" POPW %ap");       /* restore ap from stack */
        !           604:                break;
        !           605:        case F_STORE | D_STRADDLE:
        !           606:                asm(" PUSHW %ap");      /* store ap on stack */
        !           607:                asm(" MOVW 0x28(%fp),%r0");     /* put mask3 in r0 */
        !           608:                asm(" MOVW 0x2c(%fp),%ap");     /* put mask4 in ap */
        !           609:                do {
        !           610:                        asm(" ROTW %r4,0(%r8),%r1");
        !           611:                        asm(" XORW3 0(%r7),%r1,%r2");
        !           612:                        asm(" ANDW2 %r0,%r2");
        !           613:                        asm(" XORW2 %r2,0(%r7)");
        !           614:                        asm(" XORW2 4(%r7),%r1");
        !           615:                        asm(" ANDW2 %ap,%r1");
        !           616:                        asm(" XORW2 %r1,4(%r7)");
        !           617:                        asm(" ADDW2 %r6, %r8");
        !           618:                        asm(" ADDW2 %r5, %r7");
        !           619:                    } while (--i > 0);
        !           620:                asm(" POPW %ap");       /* restore ap from stack */
        !           621:                break;
        !           622:        case F_STORE | S_STRADDLE | D_STRADDLE:
        !           623:                asm(" PUSHW %ap");      /* store ap on stack */
        !           624:                asm(" SUBW3 %r4,&0x20,%ap");    /* right shift distance */
        !           625:                asm(" MOVW 0x20(%fp),%r0");     /* r0 <- mask1 */
        !           626:                asm(" MOVW 0x24(%fp),%r2");     /* r2 <- mask2 */
        !           627:                asm(" PUSHW %fp");      /* store fp on stack */
        !           628:                do {
        !           629:                        asm(" ANDW3 %r0, 0(%r8), %r1");
        !           630:                        asm(" ANDW3 %r2, 4(%r8),%ap");
        !           631:                        asm(" ORW2 %ap, %r1");
        !           632:                        asm(" ROTW %r4, %r1, %r1");
        !           633:                        asm(" XORW3 0(%r7), %r1, %ap");
        !           634:                        asm(" ANDW2 0x28(%fp), %ap");
        !           635:                        asm(" XORW2 %ap, 0(%r7)");
        !           636:                        asm(" XORW2 4(%r7), %r1");
        !           637:                        asm(" ANDW2 0x2c(%fp), %r1");
        !           638:                        asm(" XORW2 %r1, 4(%r7)");
        !           639:                        asm(" ADDW2 %r6, %r8");
        !           640:                        asm(" ADDW2 %r5, %r7");
        !           641:                } while (--i > 0);
        !           642:                asm(" POPW %fp");       /* restore fp from stack */
        !           643:                asm(" POPW %ap");       /* restore ap from stack */
        !           644:                break;
        !           645:        case F_OR:
        !           646:                 mask1 = topbits[a+1] >> px31;
        !           647:                asm(" MOVW 0x20(%fp),%r1");     /* mask1 */
        !           648:                do {
        !           649:                        asm(" ROTW %r4,0(%r8),%r2");
        !           650:                        asm(" ANDW2 %r1,%r2");
        !           651:                        asm(" ORW2 %r2,0(%r7)");
        !           652:                        asm(" ADDW2 %r6, %r8");
        !           653:                        asm(" ADDW2 %r5, %r7");
        !           654:                } while (--i > 0);
        !           655:                break;
        !           656:        case F_OR | S_STRADDLE:
        !           657:                asm(" MOVW 0x20(%fp),%r0");     /* store mask1 in a reg */
        !           658:                asm(" PUSHW %ap");      /* store ap on stack */
        !           659:                asm(" MOVW 0x24(%fp),%ap");     /* store mask1 in a reg */
        !           660: 
        !           661:                do {
        !           662:                        asm(" ANDW3 %r0,0(%r8),%r2"); /* x20(fp)=mask1 */
        !           663:                        asm(" ANDW3 %ap,4(%r8),%r1"); /* x24(fp)=mask2 */
        !           664:                        asm(" ORW2 %r2,%r1");
        !           665:                        asm(" ROTW %r4,%r1,%r1");
        !           666:                        asm(" ORW2 %r1,0(%r7)");
        !           667:                        asm(" ADDW2 %r6, %r8");
        !           668:                        asm(" ADDW2 %r5, %r7");
        !           669:                } while (--i > 0);
        !           670:                asm(" POPW %ap");       /* restore ap from stack */
        !           671:                break;
        !           672:        case F_OR | D_STRADDLE:
        !           673:                if (a <= 16)                    /* very narrow, 17 bits max */
        !           674:                {
        !           675:                asm(" MOVW &0xffff0000,%r2");
        !           676:                asm(" ORW3 0x28(%fp),0x2c(%fp),%r0");   /* compute mask */
        !           677:                do {
        !           678:                        asm(" ROTW %r4,0(%r8),%r1");
        !           679:                        asm(" ANDW2 %r0,%r1");  /* mask */
        !           680:                        asm(" ORH2 %r1,2(%r7)");
        !           681:                        asm(" ANDW2 %r2, %r1");
        !           682:                        asm(" ORW2 %r1, 4(%r7)");
        !           683:                        asm(" ADDW2 %r6, %r8");
        !           684:                        asm(" ADDW2 %r5, %r7");
        !           685:                   } while (--i > 0);
        !           686:                }
        !           687:                else
        !           688:                {
        !           689:                asm(" MOVW 0x28(%fp),%r0");     /* store mask3 in a reg */
        !           690:                asm(" PUSHW %ap");      /* store ap on stack */
        !           691:                asm(" MOVW 0x2c(%fp),%ap");     /* store mask4 in a reg */
        !           692:                do {
        !           693:                        asm(" ROTW %r4,0(%r8),%r1");
        !           694:                        asm(" ANDW3 %r0,%r1,%r2");
        !           695:                        asm(" ORW2 %r2,0(%r7)");
        !           696:                        asm(" ANDW2 %ap,%r1");
        !           697:                        asm(" ORW2 %r1,4(%r7)");
        !           698:                        asm(" ADDW2 %r6, %r8");
        !           699:                        asm(" ADDW2 %r5, %r7");
        !           700:                    } while (--i > 0);
        !           701:                asm(" POPW %ap");       /* restore ap from stack */
        !           702:                }
        !           703:                break;
        !           704:        case F_OR | S_STRADDLE | D_STRADDLE:
        !           705:                asm(" MOVW 0x20(%fp),%r0");     /* store mask1 in a reg */
        !           706:                asm(" PUSHW %ap");      /* store ap on stack */
        !           707:                asm(" MOVW 0x24(%fp),%ap");     /* store mask2 in a reg */
        !           708:                if (a > 16){            /* not super narrow */
        !           709:                do {
        !           710:                        asm(" ANDW3 %r0,0(%r8),%r1");
        !           711:                        asm(" ANDW3 %ap,4(%r8),%r2");
        !           712:                        asm(" ORW2 %r2,%r1");
        !           713:                        asm(" ROTW %r4,%r1,%r1");
        !           714:                        asm(" ANDW3 0x28(%fp),%r1,%r2");
        !           715:                        asm(" ORW2 %r2,0(%r7)");
        !           716:                        asm(" ANDW2 0x2c(%fp),%r1");
        !           717:                        asm(" ORW2 %r1,4(%r7)");
        !           718:                        asm(" ADDW2 %r6, %r8");
        !           719:                        asm(" ADDW2 %r5, %r7");
        !           720:                } while (--i > 0);
        !           721:                }
        !           722:                else
        !           723:                {
        !           724:                do {
        !           725:                        asm(" ANDW3 %r0,0(%r8),%r1");
        !           726:                        asm(" ANDW3 %ap,4(%r8),%r2");
        !           727:                        asm(" ORW2 %r2,%r1");
        !           728:                        asm(" ROTW %r4,%r1,%r1");
        !           729:                        asm(" ORH2 %r1,2(%r7)");
        !           730:                        asm(" ANDW2 &0xffff0000,%r1");
        !           731:                        asm(" ORW2 %r1,4(%r7)");
        !           732:                        asm(" ADDW2 %r6, %r8");
        !           733:                        asm(" ADDW2 %r5, %r7");
        !           734:                } while (--i > 0);
        !           735:                }
        !           736:                asm(" POPW %ap");       /* restore ap from stack */
        !           737:                break;
        !           738:        case F_CLR:
        !           739:                mask1 = topbits[a+1] >> px31;
        !           740:                asm(" MOVW 0x20(%fp),%r1");     /* mask1 */
        !           741:                do {
        !           742:                        asm(" ROTW %r4,0(%r8),%r2");
        !           743:                        asm(" ANDW2 %r1,%r2");
        !           744:                        asm(" MCOMW %r2,%r2");
        !           745:                        asm(" ANDW2 %r2,0(%r7)");
        !           746:                        asm(" ADDW2 %r6, %r8");
        !           747:                        asm(" ADDW2 %r5, %r7");
        !           748:                } while (--i > 0);
        !           749:                break;
        !           750:        case F_CLR | S_STRADDLE:
        !           751:                asm(" MOVW 0x20(%fp),%r0");     /* store mask1 in a reg */
        !           752:                asm(" PUSHW %ap");      /* store ap on stack */
        !           753:                asm(" MOVW 0x24(%fp),%ap");     /* store mask1 in a reg */
        !           754: 
        !           755:                do {
        !           756:                        asm(" ANDW3 %r0,0(%r8),%r2"); /* x20(fp)=mask1 */
        !           757:                        asm(" ANDW3 %ap,4(%r8),%r1"); /* x24(fp)=mask2 */
        !           758:                        asm(" ORW2 %r2,%r1");
        !           759:                        asm(" ROTW %r4,%r1,%r1");
        !           760:                        asm(" MCOMW %r1,%r1");
        !           761:                        asm(" ANDW2 %r1,0(%r7)");
        !           762:                        asm(" ADDW2 %r6, %r8");
        !           763:                        asm(" ADDW2 %r5, %r7");
        !           764:                } while (--i > 0);
        !           765:                asm(" POPW %ap");       /* restore ap from stack */
        !           766:                break;
        !           767:        case F_CLR | D_STRADDLE:
        !           768:                if (a <= 16)                    /* very narrow, 17 bits max */
        !           769:                {
        !           770:                asm(" MOVW &0xffff,%r2");
        !           771:                asm(" ORW3 0x28(%fp),0x2c(%fp),%r0");   /* compute mask */
        !           772:                do {
        !           773:                        asm(" ROTW %r4,0(%r8),%r1");
        !           774:                        asm(" ANDW2 %r0,%r1");  /* mask */
        !           775:                        asm(" MCOMW %r1,%r1");
        !           776:                        asm(" ANDH2 %r1,2(%r7)");
        !           777:                        asm(" ORW2 %r2,%r1");
        !           778:                        asm(" ANDW2 %r1,4(%r7)");
        !           779:                        asm(" ADDW2 %r6, %r8");
        !           780:                        asm(" ADDW2 %r5, %r7");
        !           781:                   } while (--i > 0);
        !           782:                }
        !           783:                else
        !           784:                {
        !           785:                asm(" MOVW 0x28(%fp),%r0");     /* store mask3 in a reg */
        !           786:                asm(" PUSHW %ap");      /* store ap on stack */
        !           787:                asm(" MOVW 0x2c(%fp),%ap");     /* store mask4 in a reg */
        !           788:                do {
        !           789:                        asm(" ROTW %r4,0(%r8),%r1");
        !           790:                        asm(" ANDW3 %r0,%r1,%r2");
        !           791:                        asm(" MCOMW %r2,%r2");
        !           792:                        asm(" ANDW2 %r2,0(%r7)");
        !           793:                        asm(" ANDW2 %ap,%r1");
        !           794:                        asm(" MCOMW %r1,%r1");
        !           795:                        asm(" ANDW2 %r1,4(%r7)");
        !           796:                        asm(" ADDW2 %r6, %r8");
        !           797:                        asm(" ADDW2 %r5, %r7");
        !           798:                    } while (--i > 0);
        !           799:                asm(" POPW %ap");       /* restore ap from stack */
        !           800:                }
        !           801:                break;
        !           802:        case F_CLR | S_STRADDLE | D_STRADDLE:
        !           803:                asm(" MOVW 0x20(%fp),%r0");     /* store mask1 in a reg */
        !           804:                asm(" PUSHW %ap");      /* store ap on stack */
        !           805:                asm(" MOVW 0x24(%fp),%ap");     /* store mask2 in a reg */
        !           806:                if (a > 16){            /* not super narrow */
        !           807:                do {
        !           808:                        asm(" ANDW3 %r0,0(%r8),%r1");
        !           809:                        asm(" ANDW3 %ap,4(%r8),%r2");
        !           810:                        asm(" ORW2 %r2,%r1");
        !           811:                        asm(" ROTW %r4,%r1,%r1");
        !           812:                        asm(" ANDW3 0x28(%fp),%r1,%r2");
        !           813:                        asm(" MCOMW %r2,%r2");
        !           814:                        asm(" ANDW2 %r2,0(%r7)");
        !           815:                        asm(" ANDW2 0x2c(%fp),%r1");
        !           816:                        asm(" MCOMW %r1,%r1");
        !           817:                        asm(" ANDW2 %r1,4(%r7)");
        !           818:                        asm(" ADDW2 %r6, %r8");
        !           819:                        asm(" ADDW2 %r5, %r7");
        !           820:                } while (--i > 0);
        !           821:                }
        !           822:                else
        !           823:                {
        !           824:                do {
        !           825:                        asm(" ANDW3 %r0,0(%r8),%r1");
        !           826:                        asm(" ANDW3 %ap,4(%r8),%r2");
        !           827:                        asm(" ORW2 %r2,%r1");
        !           828:                        asm(" ROTW %r4,%r1,%r1");
        !           829:                        asm(" MCOMW %r1,%r1");
        !           830:                        asm(" ANDH2 %r1,2(%r7)");
        !           831:                        asm(" ORW2 &0xffff,%r1");
        !           832:                        asm(" ANDW2 %r1,4(%r7)");
        !           833:                        asm(" ADDW2 %r6, %r8");
        !           834:                        asm(" ADDW2 %r5, %r7");
        !           835:                } while (--i > 0);
        !           836:                }
        !           837:                asm(" POPW %ap");       /* restore ap from stack */
        !           838:                break;
        !           839:        case F_XOR:
        !           840:                mask1 = topbits[a+1] >> px31;
        !           841:                asm(" MOVW 0x20(%fp),%r1");     /* mask1 */
        !           842:                do {
        !           843:                        asm(" ROTW %r4,0(%r8),%r2");
        !           844:                        asm(" ANDW2 %r1,%r2");
        !           845:                        asm(" XORW2 %r2,0(%r7)");
        !           846:                        asm(" ADDW2 %r6, %r8");
        !           847:                        asm(" ADDW2 %r5, %r7");
        !           848:                } while (--i > 0);
        !           849:                break;
        !           850:        case F_XOR | S_STRADDLE:
        !           851:                asm(" MOVW 0x20(%fp),%r0");     /* store mask1 in a reg */
        !           852:                asm(" PUSHW %ap");      /* store ap on stack */
        !           853:                asm(" MOVW 0x24(%fp),%ap");     /* store mask1 in a reg */
        !           854: 
        !           855:                do {
        !           856:                        asm(" ANDW3 %r0,0(%r8),%r2"); /* x20(fp)=mask1 */
        !           857:                        asm(" ANDW3 %ap,4(%r8),%r1"); /* x24(fp)=mask2 */
        !           858:                        asm(" ORW2 %r2,%r1");
        !           859:                        asm(" ROTW %r4,%r1,%r1");
        !           860:                        asm(" XORW2 %r1,0(%r7)");
        !           861:                        asm(" ADDW2 %r6, %r8");
        !           862:                        asm(" ADDW2 %r5, %r7");
        !           863:                } while (--i > 0);
        !           864:                asm(" POPW %ap");       /* restore ap from stack */
        !           865:                break;
        !           866:        case F_XOR | D_STRADDLE:
        !           867:                if (a <= 16)                    /* very narrow, 17 bits max */
        !           868:                {
        !           869:                asm(" MOVW &0xffff0000,%r2");
        !           870:                asm(" ORW3 0x28(%fp),0x2c(%fp),%r0");   /* compute mask */
        !           871:                do {
        !           872:                        asm(" ROTW %r4,0(%r8),%r1");
        !           873:                        asm(" ANDW2 %r0,%r1");  /* mask */
        !           874:                        asm(" XORH2 %r1,2(%r7)");
        !           875:                        asm(" ANDW2 %r2,%r1");
        !           876:                        asm(" XORW2 %r1,4(%r7)");
        !           877:                        asm(" ADDW2 %r6, %r8");
        !           878:                        asm(" ADDW2 %r5, %r7");
        !           879:                   } while (--i > 0);
        !           880:                }
        !           881:                else
        !           882:                {
        !           883:                asm(" MOVW 0x28(%fp),%r0");     /* store mask3 in a reg */
        !           884:                asm(" PUSHW %ap");      /* store ap on stack */
        !           885:                asm(" MOVW 0x2c(%fp),%ap");     /* store mask4 in a reg */
        !           886:                do {
        !           887:                        asm(" ROTW %r4,0(%r8),%r1");
        !           888:                        asm(" ANDW3 %r0,%r1,%r2");
        !           889:                        asm(" XORW2 %r2,0(%r7)");
        !           890:                        asm(" ANDW2 %ap,%r1");
        !           891:                        asm(" XORW2 %r1,4(%r7)");
        !           892:                        asm(" ADDW2 %r6, %r8");
        !           893:                        asm(" ADDW2 %r5, %r7");
        !           894:                    } while (--i > 0);
        !           895:                asm(" POPW %ap");       /* restore ap from stack */
        !           896:                }
        !           897:                break;
        !           898:        case F_XOR | S_STRADDLE | D_STRADDLE:
        !           899:                asm(" MOVW 0x20(%fp),%r0");     /* store mask1 in a reg */
        !           900:                asm(" PUSHW %ap");      /* store ap on stack */
        !           901:                asm(" MOVW 0x24(%fp),%ap");     /* store mask2 in a reg */
        !           902:                if (a > 16){            /* not super narrow */
        !           903:                do {
        !           904:                        asm(" ANDW3 %r0,0(%r8),%r1");
        !           905:                        asm(" ANDW3 %ap,4(%r8),%r2");
        !           906:                        asm(" ORW2 %r2,%r1");
        !           907:                        asm(" ROTW %r4,%r1,%r1");
        !           908:                        asm(" ANDW3 0x28(%fp),%r1,%r2");
        !           909:                        asm(" XORW2 %r2,0(%r7)");
        !           910:                        asm(" ANDW2 0x2c(%fp),%r1");
        !           911:                        asm(" XORW2 %r1,4(%r7)");
        !           912:                        asm(" ADDW2 %r6, %r8");
        !           913:                        asm(" ADDW2 %r5, %r7");
        !           914:                } while (--i > 0);
        !           915:                }
        !           916:                else
        !           917:                {
        !           918:                do {
        !           919:                        asm(" ANDW3 %r0,0(%r8),%r1");
        !           920:                        asm(" ANDW3 %ap,4(%r8),%r2");
        !           921:                        asm(" ORW2 %r2,%r1");
        !           922:                        asm(" ROTW %r4,%r1,%r1");
        !           923:                        asm(" XORH2 %r1,2(%r7)");
        !           924:                        asm(" ANDW2 &0xffff0000,%r1");
        !           925:                        asm(" XORW2 %r1,4(%r7)");
        !           926:                        asm(" ADDW2 %r6, %r8");
        !           927:                        asm(" ADDW2 %r5, %r7");
        !           928:                } while (--i > 0);
        !           929:                }
        !           930:                asm(" POPW %ap");       /* restore ap from stack */
        !           931:                break;
        !           932:        }
        !           933:        return;
        !           934: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.