Annotation of 40BSD/games/compat/dofloat.c, revision 1.1

1.1     ! root        1: #
        !             2: /*
        !             3:  *     Simulate pdp11 floating point for compatability mode programs.
        !             4:  *     Quick and dirty with no big effort at speed since it takes so
        !             5:  *     much overhead to get here in the first place.
        !             6:  *     I make no claims on the completeness of this simulation.
        !             7:  *     Art Wetzel 3/16/80
        !             8:  */
        !             9: #ifndef NOFPSIM
        !            10: #ifdef DEBUG
        !            11: #include <stdio.h>
        !            12: #endif
        !            13: #include "defs.h"
        !            14: /* output codes */
        !            15: #define        NONE    0
        !            16: #define        SHORT   01
        !            17: #define        LONG    02
        !            18: #define        FLOAT   04
        !            19: #define        DOUBLE  010
        !            20: #define        OUTPUT  020
        !            21: /* parts of fps */
        !            22: #define        FD      0200
        !            23: #define        FL      0100
        !            24: #define        FN      010
        !            25: #define        FZ      04
        !            26: #define        FV      02
        !            27: #define        FC      01
        !            28: /* fis instructions */
        !            29: #define        FADD    075000
        !            30: #define        FSUB    075010
        !            31: #define        FMUL    075020
        !            32: #define        FDIV    075030
        !            33: /* fpu instructions */
        !            34: #define        ABSD    0170600
        !            35: #define        ABSF    0170600
        !            36: #define        ADDD    0172000
        !            37: #define        ADDF    0172000
        !            38: #define        CFCC    0170000
        !            39: #define        CLRD    0170400
        !            40: #define        CLRF    0170400
        !            41: #define        CMPD    0173400
        !            42: #define        CMPF    0173400
        !            43: #define        DIVD    0174400
        !            44: #define        DIVF    0174400
        !            45: #define        LDCFD   0177400
        !            46: #define        LDCFF   0177400
        !            47: #define        LDCLD   0177000
        !            48: #define        LDCLF   0177000
        !            49: #define        LDCIF   0177000
        !            50: #define        LDCID   0177000
        !            51: #define        LDEXP   0176400
        !            52: #define        LDD     0172400
        !            53: #define        LDF     0172400
        !            54: #define        LDFPS   0170100
        !            55: #define        MODD    0171400
        !            56: #define        MODF    0171400
        !            57: #define        MULD    0171000
        !            58: #define        MULF    0171000
        !            59: #define        NEGD    0170700
        !            60: #define        NEGF    0170700
        !            61: #define        SETF    0170001
        !            62: #define        SETD    0170011
        !            63: #define        SETI    0170002
        !            64: #define        SETL    0170012
        !            65: #define        STCDF   0176000
        !            66: #define        STCFD   0176000
        !            67: #define        STCDL   0175400
        !            68: #define        STCDI   0175400
        !            69: #define        STCFL   0175400
        !            70: #define        STCFI   0175400
        !            71: #define        STEXP   0175000
        !            72: #define        STD     0174000
        !            73: #define        STF     0174000
        !            74: #define        STFPS   0170200
        !            75: #define        STST    0170300
        !            76: #define        SUBD    0173000
        !            77: #define        SUBF    0173000
        !            78: #define        TSTD    0170500
        !            79: #define        TSTF    0170500
        !            80: union  alltypes        {
        !            81:        double  d;
        !            82:        float   f;
        !            83:        long    l;
        !            84:        short   s;
        !            85:        unsigned short p[4];
        !            86: };
        !            87: /* static storage for floating registers */
        !            88: static union   alltypes        fregs[6];
        !            89: static union   alltypes        srcdst;
        !            90: int    fps = FD|FL;
        !            91: int    dbl = 0;
        !            92: int    lng = 0;
        !            93: #endif
        !            94: dofloat(instr) unsigned int instr; {
        !            95: #ifdef NOFPSIM
        !            96:        return(-1);
        !            97: #else
        !            98:        register unsigned short *wptr;
        !            99:        register unsigned int opcode, ac, mode, fac, adjust, output, ccset;
        !           100:        unsigned short *locate();
        !           101:        /* indicate what condition codes will be changed by op - assume none */
        !           102:        ccset = 0;
        !           103:        /* type of memory output - assume none */
        !           104:        output = NONE;
        !           105:        /* default adjust to type */
        !           106:        if(dbl)
        !           107:                adjust = DOUBLE;
        !           108:        else
        !           109:                adjust = FLOAT;
        !           110:        /* chop up instruction to get relevent parts */
        !           111:        opcode = instr & 0177700;
        !           112:        fac = (instr>>6) & 03;
        !           113:        mode = (instr>>3) & 07;
        !           114:        ac = instr & 07;
        !           115:        /* if the instruction uses a src/dst construct ptr and fetch */
        !           116:        switch(opcode) {
        !           117:        case    FADD:
        !           118:        case    CFCC:
        !           119:                break;
        !           120:        default:
        !           121:                wptr = locate(mode, ac);
        !           122:                /* special case for mode 0 */
        !           123:                if(mode == 0) switch(opcode & 0177400) {
        !           124:                /* special instructions to use cpu regs */
        !           125:                case    LDEXP:
        !           126:                case    STEXP:
        !           127:                        wptr = &regs[ac];
        !           128:                        break;
        !           129:                case    STCDL:
        !           130:                        wptr = &regs[ac];
        !           131:                default:
        !           132:                        break;
        !           133:                }
        !           134:                if(dbl)
        !           135:                        srcdst.d = *(double *)wptr;
        !           136:                else
        !           137:                        srcdst.f = *(float *)wptr;
        !           138:                /* immediate fetches are 16 bits */
        !           139:                if(ac == 7 && (mode == 2)) {
        !           140:                        srcdst.p[1] = 0;
        !           141:                        srcdst.p[2] = 0;
        !           142:                        srcdst.p[3] = 0;
        !           143:                }
        !           144:                break;
        !           145:        }
        !           146: #ifdef DEBUG
        !           147: fprintf(stderr,"pc %o sp %o instr %o srcdst %o mode %o reg %o fac %o\n", pc-1,regs[6],instr,srcdst.s,mode,ac,fac);
        !           148: #endif
        !           149:        switch(opcode) {
        !           150:        case    FADD:
        !           151:                /* catches all fis instructions */
        !           152:                /* last 3 bits are stack pointer register */
        !           153:                ac = instr & 07;
        !           154:                /* get pointer to stack words */
        !           155:                wptr = (unsigned short *)regs[ac];
        !           156:                /* getch floating value from stack */
        !           157:                srcdst.f = *(float *)wptr;
        !           158:                /* shorten stack */
        !           159:                wptr += 2;
        !           160:                /* do appropriate operation */
        !           161:                switch(instr & 0177770) {
        !           162:                case    FADD:
        !           163:                        srcdst.f += *(float *)wptr;
        !           164:                        break;
        !           165:                case    FSUB:
        !           166:                        srcdst.f = *(float *)wptr - srcdst.f;
        !           167:                        break;
        !           168:                case    FMUL:
        !           169:                        srcdst.f *= *(float *)wptr;
        !           170:                        break;
        !           171:                case    FDIV:
        !           172:                        srcdst.f = *(float *)wptr / srcdst.f;
        !           173:                        break;
        !           174:                default:
        !           175:                        return(-1);
        !           176:                }
        !           177:                /* copy out result */
        !           178:                *(float *)wptr = srcdst.f;
        !           179:                /* set up condition codes */
        !           180:                psl &= ~017;
        !           181:                if(srcdst.f == 0.) psl |= FZ;
        !           182:                if(srcdst.f < 0.) psl |= FN;
        !           183:                /* adjust register to reflect stack change */
        !           184:                regs[ac] = (unsigned short)(int)wptr;
        !           185:                return(0);
        !           186:        case    CFCC:
        !           187:                switch(instr) {
        !           188:                case    SETF:
        !           189:                        dbl = 0;
        !           190:                        break;
        !           191:                case    SETD:
        !           192:                        dbl = 1;
        !           193:                        break;
        !           194:                case    SETI:
        !           195:                        lng = 0;
        !           196:                        break;
        !           197:                case    SETL:
        !           198:                        lng = 1;
        !           199:                        break;
        !           200:                case    CFCC:
        !           201:                        psl &= ~017;
        !           202:                        psl |= (fps & 017);
        !           203: #ifdef DEBUG
        !           204: fprintf(stderr,"CFCC %o\n",psl);
        !           205: #endif
        !           206:                        break;
        !           207:                default:
        !           208:                        return(-1);
        !           209:                }
        !           210:                return(0);
        !           211:        case    ABSD:
        !           212:                if(srcdst.d < 0.0 ) srcdst.d = -srcdst.d;
        !           213:                ccset = FZ;
        !           214:                if(dbl) 
        !           215:                        output = DOUBLE;
        !           216:                else
        !           217:                        output = FLOAT;
        !           218:                break;
        !           219:        case    CLRD:
        !           220:                srcdst.d =0.0;
        !           221:                ccset = FZ;
        !           222:                if(dbl)
        !           223:                        output = DOUBLE;
        !           224:                else
        !           225:                        output = FLOAT;
        !           226:                break;
        !           227:        case    LDFPS:
        !           228:                adjust = SHORT;
        !           229:                fps = srcdst.s;
        !           230:                if(fps & FD)
        !           231:                        dbl = 1;
        !           232:                else
        !           233:                        dbl = 0;
        !           234:                if(fps & FL )
        !           235:                        lng = 1;
        !           236:                else
        !           237:                        lng = 0;
        !           238:                break;
        !           239:        case    NEGD:
        !           240:                srcdst.d = -srcdst.d;
        !           241:                ccset = FZ|FN;
        !           242:                if(dbl)
        !           243:                        output = DOUBLE;
        !           244:                else
        !           245:                        output = FLOAT;
        !           246:                break;
        !           247:        case    STFPS:
        !           248:                srcdst.s = fps;
        !           249:                adjust = output = SHORT;
        !           250:                break;
        !           251:        case    STST:
        !           252:                return(0);
        !           253:                break;
        !           254:        case    TSTD:
        !           255:                ccset = FZ|FN;
        !           256:                break;
        !           257:        default:
        !           258:                opcode = instr & 0177400;
        !           259:                switch(opcode) {
        !           260:                case    STD:
        !           261:                        srcdst.d = fregs[fac].d;
        !           262: #ifdef DEBUG
        !           263: fprintf(stderr,"STD %o\n",srcdst.s);
        !           264: #endif
        !           265:                        if(dbl)
        !           266:                                output = DOUBLE;
        !           267:                        else
        !           268:                                output = FLOAT;
        !           269:                        break;
        !           270:                case    LDD:
        !           271: #ifdef DEBUG
        !           272: fprintf(stderr,"LDD %o\n",srcdst.s);
        !           273: #endif
        !           274:                        fregs[fac].d = srcdst.d;
        !           275:                        ccset = FZ|FN;
        !           276:                        break;
        !           277:                case    ADDD:
        !           278:                        fregs[fac].d += srcdst.d;
        !           279:                        ccset = FZ|FN;
        !           280:                        break;
        !           281:                case    SUBD:
        !           282:                        fregs[fac].d -= srcdst.d;
        !           283:                        ccset = FZ|FN;
        !           284:                        break;
        !           285:                case    MULD:
        !           286:                        fregs[fac].d *= srcdst.d;
        !           287:                        ccset = FZ|FN;
        !           288:                        break;
        !           289:                case    DIVD:
        !           290: #ifdef DEBUG
        !           291: fprintf(stderr,"DIVD %f by %f gives ",fregs[fac].d,srcdst.d);
        !           292: #endif
        !           293:                        fregs[fac].d /= srcdst.d;
        !           294: #ifdef DEBUG
        !           295: fprintf(stderr,"-> %f\n",fregs[fac].d);
        !           296: #endif
        !           297:                        ccset = FZ|FN;
        !           298:                        break;
        !           299:                case    STCDF:
        !           300:                        adjust = output = FLOAT;
        !           301:                        ccset = FZ|FN;
        !           302:                        break;
        !           303:                case    LDCFD:
        !           304:                        adjust = FLOAT;
        !           305:                        ccset = FZ|FN;
        !           306:                        break;
        !           307:                case    LDCLD:
        !           308:                        if(lng) {
        !           309:                                adjust = LONG;
        !           310:                                srcdst.d = srcdst.l;
        !           311:                        } else {
        !           312:                                adjust = SHORT;
        !           313:                                srcdst.d = srcdst.s;
        !           314:                        }
        !           315:                        ccset = FZ|FN;
        !           316:                        break;
        !           317:                case    CMPD:
        !           318:                        srcdst.d -= fregs[fac].d;
        !           319:                        ccset = FZ|FN;
        !           320:                        break;
        !           321:                case    LDEXP:
        !           322:                        srcdst.d = 0.0;
        !           323:                        srcdst.s = *wptr;
        !           324:                        srcdst.s <<= 7;
        !           325:                        srcdst.s += 0200;
        !           326:                        adjust = SHORT;
        !           327:                        ccset = FZ|FN;
        !           328: #ifdef DEBUG
        !           329: fprintf(stderr,"LDEXP %o gives %o\n",*wptr,srcdst.s);
        !           330: #endif
        !           331:                        break;
        !           332:                case    MODD:
        !           333:                        srcdst.d *= fregs[fac].d;
        !           334:                        fregs[fac].d = (double)(long)srcdst.d;
        !           335:                        if(~fac & 1) fregs[fac + 1].d = fregs[fac].d;
        !           336:                        srcdst.d -= fregs[fac].d;
        !           337:                        ccset = FN|FZ;
        !           338:                        fregs[fac].d = srcdst.d;
        !           339: #ifdef DEBUG
        !           340: fprintf(stderr,"MODD %o %o\n",fregs[fac].s,fregs[fac+1].s);
        !           341: #endif
        !           342:                        break;
        !           343:                case    STCDL:
        !           344:                        if(lng)
        !           345:                                adjust = output = LONG;
        !           346:                        else
        !           347:                                adjust = output = SHORT;
        !           348:                        if(mode == 0) output = SHORT;
        !           349:                        srcdst.l = fregs[fac].d;
        !           350: #ifdef DEBUG
        !           351: fprintf(stderr,"STCDL %o\n",srcdst.l);
        !           352: #endif
        !           353:                        ccset = FZ|FN;
        !           354:                        break;
        !           355:                case    STEXP:
        !           356: #ifdef DEBUG
        !           357: fprintf(stderr,"STEXP of %o gives ",srcdst.s);
        !           358: #endif
        !           359:                        srcdst.s &= 077600;
        !           360:                        srcdst.s >>= 7;
        !           361:                        srcdst.s -= 0200;
        !           362:                        adjust = output = SHORT;
        !           363:                        ccset = FZ|FN;
        !           364: #ifdef DEBUG
        !           365: fprintf(stderr,"%o\n",srcdst.s);
        !           366: #endif
        !           367:                        break;
        !           368:                default:
        !           369:                        return(-1);
        !           370:                }
        !           371:        }
        !           372:        if(ccset & FZ) {
        !           373:                fps &= ~FZ;
        !           374:                if(srcdst.d == 0.0) fps |= FZ;
        !           375:                if(!dbl && srcdst.f == 0.0) fps |= FZ;
        !           376:        }
        !           377:        if(ccset & FN) {
        !           378:                fps &= ~FN;
        !           379:                if(srcdst.f < 0.0) fps |= FN;
        !           380:        }
        !           381:        switch(instr & 0177400) {
        !           382:        case    STCDL:
        !           383:        case    STEXP:
        !           384:                psl &= ~017;
        !           385:                psl |= (fps & 017);
        !           386:                break;
        !           387:        default:
        !           388:                break;
        !           389:        }
        !           390:        switch(output) {
        !           391:        case    NONE:
        !           392:                break;
        !           393:        case    SHORT:
        !           394:                *((short *)wptr) = srcdst.s;
        !           395:                srcdst.d = 0.0;
        !           396:                break;
        !           397:        case    LONG:
        !           398:                if(mode == 4) wptr--;
        !           399:                *((long *)wptr) = longrev(srcdst.l);
        !           400:                break;
        !           401:        case    FLOAT:
        !           402:                if(mode == 4) wptr--;
        !           403:                *((float *)wptr) = srcdst.f;
        !           404:                break;
        !           405:        case    DOUBLE:
        !           406:                if(mode == 4) wptr -= 3;
        !           407:                *((double *)wptr) = srcdst.d;
        !           408:                break;
        !           409:        }
        !           410:        switch(mode) {
        !           411:        case    0:
        !           412:        case    1:
        !           413:                break;
        !           414:        case    2:
        !           415:                switch(adjust) {
        !           416:                case    SHORT:
        !           417:                        regs[ac] += 2;
        !           418:                        break;
        !           419:                case    LONG:
        !           420:                case    FLOAT:
        !           421:                        regs[ac] += 4;
        !           422:                        break;
        !           423:                case    DOUBLE:
        !           424:                        regs[ac] += 8;
        !           425:                        break;
        !           426:                case    NONE:
        !           427:                        break;
        !           428:                }
        !           429:                if(ac == 7) pc++;
        !           430:                break;
        !           431:        case    3:
        !           432:                regs[ac] += 2;
        !           433:                if(ac == 7) pc++;
        !           434:                break;
        !           435:        case    4:
        !           436:                switch(adjust) {
        !           437:                case    SHORT:
        !           438:                        regs[ac] -= 2;
        !           439:                        break;
        !           440:                case    LONG:
        !           441:                case    FLOAT:
        !           442:                        regs[ac] -= 4;
        !           443:                        break;
        !           444:                case    DOUBLE:
        !           445:                        regs[ac] -= 8;
        !           446:                        break;
        !           447:                case    NONE:
        !           448:                        break;
        !           449:                }
        !           450:                break;
        !           451:        case    5:
        !           452:                regs[ac] -= 2;
        !           453:                break;
        !           454:        case    6:
        !           455:        case    7:
        !           456:                pc++;
        !           457:                break;
        !           458:        }
        !           459:        return(0);
        !           460: #endif
        !           461: }
        !           462: #ifndef NOFPSIM
        !           463: unsigned short *locate(mode, ac) {
        !           464:        register unsigned short *wptr;
        !           465:        switch(mode) {
        !           466:        case    0:
        !           467:                /* mode 0 normally implies fregs */
        !           468:                wptr = (unsigned short *)&fregs[ac];
        !           469:                break;
        !           470:        case    1:
        !           471:                break;
        !           472:        case    2:
        !           473:                wptr = (unsigned short *)(int)regs[ac];
        !           474:                break;
        !           475:        case    3:
        !           476:                wptr = (unsigned short *)regs[ac];
        !           477:                wptr = (unsigned short *)*wptr;
        !           478:                break;
        !           479:        case    4:
        !           480:                wptr = (unsigned short *)regs[ac];
        !           481:                wptr--;
        !           482:                break;
        !           483:        case    5:
        !           484:                wptr = (unsigned short *)regs[ac];
        !           485:                wptr--;
        !           486:                wptr = (unsigned short *)*wptr;
        !           487:                break;
        !           488:        case    6:
        !           489:                wptr = (unsigned short *)((regs[ac] + *pc) & 0177776);
        !           490:                if(ac == 7) wptr++;
        !           491:                break;
        !           492:        case    7:
        !           493:                wptr = (unsigned short *)((regs[ac] + *pc) & 0177776);
        !           494:                if(ac == 7) wptr++;
        !           495:                wptr = (unsigned short *)*wptr;
        !           496:                break;
        !           497:        }
        !           498:        return(wptr);
        !           499: }
        !           500: #endif

unix.superglobalmegacorp.com

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