Annotation of 3BSD/cmd/as/asjxxx.c, revision 1.1

1.1     ! root        1: /* Copyright (c) 1979 Regents of the University of California */
        !             2: #include       <stdio.h>
        !             3: #include       "as.h"
        !             4: #include       "assyms.h"
        !             5: 
        !             6: #define JBR 0x11
        !             7: #define BRW 0x31
        !             8: 
        !             9: /*
        !            10:  *     The number of bytes to add if the jxxx must be "exploded"
        !            11:  *     into the long form
        !            12:  */
        !            13: #define        JBRFSIZE        1       /*goes to brw*/
        !            14: #define JXXXFSIZE      3       /*goes to brb, brw <byte> <byte> */
        !            15: 
        !            16: /*
        !            17:  *     These variables are filled by asscan.c with the
        !            18:  *     last name encountered (a pointer buried in the intermediate file),
        !            19:  *     and the last jxxx symbol table entry encountered.
        !            20:  */
        !            21: struct         symtab  *lastnam;
        !            22: struct symtab  *lastjxxx;
        !            23: 
        !            24: /*
        !            25:  *     Handle jxxx instructions
        !            26:  */
        !            27: ijxout(op,ap,nact)
        !            28:        struct arg *ap;
        !            29: {
        !            30:        if (passno == 1){
        !            31:                /*
        !            32:                 *      READ THIS BEFORE LOOKING AT jxxxfix()
        !            33:                 *
        !            34:                 *      Record the jxxx in a special symbol table entry
        !            35:                 */
        !            36:                register struct symtab *jumpfrom;
        !            37: 
        !            38:                /*
        !            39:                 *      We assume the MINIMAL length
        !            40:                 */
        !            41:                putins(op,ap,nact); 
        !            42:                jumpfrom = lastjxxx;
        !            43:                jumpfrom->tag = JXACTIVE;
        !            44:                jumpfrom->jxbump = 0;
        !            45:                if (op == JBR)
        !            46:                        jumpfrom->jxfear = JBRFSIZE;
        !            47:                else
        !            48:                        jumpfrom->jxfear = JXXXFSIZE;
        !            49: #ifdef DJXXX
        !            50:                jumpfrom->jxline = lineno;
        !            51: #endif
        !            52:                if (lastnam == 0)
        !            53:                        yyerror("jxxx destination not a label");
        !            54:                jumpfrom->dest = lastnam;
        !            55:                jumpfrom->type = dotp->xtype;   /*only TEXT or DATA*/
        !            56:                jumpfrom->index = dotp-usedot;
        !            57:                /*
        !            58:                 *      value ALWAYS (ALWAYS!!!) indexes the next instruction
        !            59:                 *      after the jump, even in the jump must be exploded
        !            60:                 *      (bumped)
        !            61:                 */
        !            62:                jumpfrom->value = dotp->xvalue;
        !            63:                njxxx++;
        !            64:        } else {/* pass2, resolve */
        !            65:                /*
        !            66:                 *      READ THIS AFTER LOOKING AT jxxxfix()
        !            67:                 */
        !            68:                register long           oxvalue;
        !            69:                register struct exp     *xp; 
        !            70:                register struct symtab  *tunnel;
        !            71:                register struct arg     *aplast;
        !            72: 
        !            73:                aplast = ap + nact - 1;
        !            74:                xp = aplast->xp;
        !            75:                if (lastjxxx->tag == JXTUNNEL){
        !            76:                        lastjxxx->tag = JXINACTIVE;
        !            77:                        tunnel = lastjxxx->dest;
        !            78:                        xp->xvalue = tunnel->value      /*index of instruction following*/
        !            79:                                    - 3                 /* size of brw + word*/
        !            80:                                    + ( ( (tunnel->jxfear == JBRFSIZE) &&
        !            81:                                          (tunnel->jxbump == 0))?1:0);
        !            82:                                                        /*non bumped branch byteis only 2 back*/
        !            83:                }
        !            84:                if (lastjxxx->jxbump == 0){     /*wasn't bumped, so is short form*/
        !            85:                        putins(op, ap, nact);
        !            86:                } else {
        !            87:                        if (op != JBR){ /*branch reverse conditional byte over 
        !            88:                                          branch unconditional word*/
        !            89:                                oxvalue = xp->xvalue;
        !            90:                                xp->xvalue = lastjxxx->value;
        !            91:                                putins(op^1, ap, nact);
        !            92:                                xp->xvalue = oxvalue;
        !            93:                        }
        !            94:                        putins(BRW, aplast, 1);
        !            95:                }
        !            96:        }
        !            97: }      /*end of ijxout*/
        !            98: 
        !            99: jalign(xp, sp)
        !           100:        register struct exp *xp;
        !           101:        register struct symtab *sp;
        !           102: {
        !           103:        register        int     mask;
        !           104:        if (xp->xtype != XABS || xp->xvalue < 0 || xp->xvalue > 16) {
        !           105:                yyerror("Illegal `align' argument");
        !           106:                return;
        !           107:        }
        !           108:        flushfield(NBPW/4);
        !           109:        if (passno == 1) {
        !           110:                sp->tag = JXALIGN;
        !           111:                sp->jxfear = (1 << xp->xvalue) - 1;
        !           112: #ifdef DJXXX
        !           113:                sp->jxline = lineno;
        !           114: #endif
        !           115:                sp->type = dotp->xtype;
        !           116:                sp->index = dotp-usedot;
        !           117:                /*
        !           118:                 *      We guess that the align will take up at least one
        !           119:                 *      byte in the code output.  We will correct for this
        !           120:                 *      initial high guess when we explode (bump) aligns
        !           121:                 *      when we fix the jxxxes.  We must do this guess
        !           122:                 *      so that the symbol table is sorted correctly
        !           123:                 *      and labels declared to fall before the align
        !           124:                 *      really get their, instead of guessing zero size
        !           125:                 *      and have the label (incorrectly) fall after the jxxx.
        !           126:                 *      This is a quirk of our requirement that indices into
        !           127:                 *      the code stream point to the next byte following
        !           128:                 *      the logical entry in the symbol table
        !           129:                 */
        !           130:                dotp->xvalue += 1;
        !           131:                sp->value = dotp->xvalue;
        !           132:                njxxx++;
        !           133:        } else {
        !           134:                mask = (1 << xp->xvalue) - 1;
        !           135:                while (dotp->xvalue & mask){
        !           136:                        outb(0);
        !           137:                }
        !           138:        }
        !           139: }
        !           140: 
        !           141: /*
        !           142:  *     Pass 1.5, resolve jxxx instructions and .align in .text
        !           143:  */
        !           144: jxxxfix() 
        !           145: {
        !           146:        register struct symtab  *jumpfrom;
        !           147:                 struct symtab  **cojumpfrom, *ubjumpfrom;
        !           148:        register struct symtab  *dest;
        !           149:        register struct symtab  *intdest;       /*intermediate dest*/
        !           150:        register struct symtab  **cointdest, *ubintdest;
        !           151: 
        !           152:        register struct symtab  *tunnel;
        !           153:                 int            displ,nchange;
        !           154:                 int            badjxalign;     /*if jump across an align*/
        !           155:                 int            stillactives;   /*if still active jxxxes*/
        !           156:                 int            segno;          /*current segment number*/
        !           157:                 int            topono;         /*which iteration in the topo sort*/
        !           158:        register unsigned char  tag;
        !           159:        /*
        !           160:         *      consider each segment in turn...
        !           161:         */
        !           162:        for (segno = 0; segno < NLOC + NLOC; segno++){
        !           163:            badjxalign = 0;             /*done on a per segment basis*/
        !           164:            /*
        !           165:             *  Do a lazy topological sort.
        !           166:             */
        !           167:            for (topono = 1, nchange = 1; nchange != 0; topono++){
        !           168: #ifdef DEBUG
        !           169:                if (debug)
        !           170:                        printf("\nSegment %d, topo iteration %d\n",
        !           171:                                segno, topono);
        !           172: #endif
        !           173:                nchange = 0;
        !           174:                stillactives = 0;
        !           175:                /*
        !           176:                 *      We keep track of one possible tunnel location.
        !           177:                 *      A tunnel will eventually be an unconditional
        !           178:                 *      branch to the same place that another jxxx
        !           179:                 *      will want to branch to.  We will turn a
        !           180:                 *      branch conditional/unconditional (word) that would
        !           181:                 *      have to get bumped because its destination is too
        !           182:                 *      far away, into a branch conditional/unconditional
        !           183:                 *      byte to the tunnel branch conditional/unconditional.
        !           184:                 *      Of course, the tunnel must branch to the same place
        !           185:                 *      as we want to go.
        !           186:                 */
        !           187:                tunnel = 0;     /*initially, no tunnel*/
        !           188:                SEGITERATE(segno, 0, 0, cojumpfrom, jumpfrom, ubjumpfrom, ++){
        !           189:                        tag = jumpfrom->tag;
        !           190:                        if (tag <= IGNOREBOUND)
        !           191:                                continue;       /*just an ordinary symbol*/
        !           192:                        if (tag == JXALIGN){
        !           193:                                tunnel = 0;     /*avoid tunneling across a flex alocation*/
        !           194:                                continue;       /*we take care of these later*/
        !           195:                        }
        !           196:                        if (   jumpfrom->jxfear == JBRFSIZE     /*unconditional*/
        !           197:                            || (   tag == JXINACTIVE            /*inactive bumped*/
        !           198:                                && (jumpfrom->jxbump != 0)
        !           199:                               )
        !           200:                           ) tunnel = jumpfrom;
        !           201:                        if (tag != JXACTIVE)
        !           202:                                continue;
        !           203:                        dest = jumpfrom->dest;
        !           204:                        if (jumpfrom->index != dest->index){
        !           205:                                yyerror("Intersegment jxxx");
        !           206:                                continue;
        !           207:                        }
        !           208:                        displ = dest->value - jumpfrom->value;
        !           209:                        if (displ < MINBYTE || displ > MAXBYTE) {
        !           210:                                /*
        !           211:                                 *      This is an immediate lose!
        !           212:                                 *
        !           213:                                 *      We first attempt to tunnel
        !           214:                                 *      by finding an intervening jump that
        !           215:                                 *      has  the same destination.
        !           216:                                 *      The tunnel is always the first preceeding
        !           217:                                 *      jxxx instruction, so the displacement
        !           218:                                 *      to the tunnel is less than zero, and
        !           219:                                 *      its relative position will be unaffected
        !           220:                                 *      by future jxxx expansions.
        !           221:                                 */
        !           222:                                if (    (jumpfrom->jxfear > JBRFSIZE)
        !           223:                                     && (tunnel) 
        !           224:                                     && (tunnel->dest == jumpfrom->dest)        
        !           225:                                     && (tunnel->index == jumpfrom->index)
        !           226:                                     && (tunnel->value - jumpfrom->value >=
        !           227:                                                MINBYTE + JXXXFSIZE)
        !           228:                                   ) {
        !           229:                                                /*
        !           230:                                                 *      tunnelling is OK
        !           231:                                                 */
        !           232:                                                jumpfrom->dest = tunnel;
        !           233:                                                /*
        !           234:                                                 * no bumping needed, this
        !           235:                                                 * is now effectively inactive
        !           236:                                                 * but must be remembered
        !           237:                                                 */
        !           238:                                                jumpfrom->tag = JXTUNNEL;
        !           239: #ifdef DEBUG
        !           240:                                                if(debug)
        !           241:                                                printf("Tunnel from %s from line %d\n",
        !           242:                                                        jumpfrom->name, lineno);
        !           243: #endif
        !           244: #ifdef METRIC
        !           245:                                                jxxxtunnel++;
        !           246: #endif
        !           247:                                                continue;
        !           248:                                } else {        /*tunneling not possible*/
        !           249:                                        /*
        !           250:                                         *      since this will be turned
        !           251:                                         *      into a bumped jump, we can
        !           252:                                         *      use the unconditional jump
        !           253:                                         *      as a tunnel
        !           254:                                         */
        !           255:                                        tunnel = jumpfrom;
        !           256:                                        jumpfrom->tag = JXNOTYET;
        !           257:                                        ++nchange;
        !           258:                                        continue;
        !           259:                                }
        !           260:                        }       /*end of immediate lose*/
        !           261:                        /*
        !           262:                         *      Do a forward search for an intervening jxxx
        !           263:                         */
        !           264:                        if (displ >= 0) {
        !           265:                                SEGITERATE(segno, cojumpfrom + 1,0,cointdest,
        !           266:                                                intdest, ubintdest, ++){
        !           267:                                        if (intdest->value > dest->value) 
        !           268:                                                break; /* beyond destination */
        !           269:                                        if (intdest->tag <= JXQUESTIONABLE)
        !           270:                                                continue;       /*frozen solid*/
        !           271:                                        if (intdest->tag == JXALIGN){
        !           272:                                                jumpfrom->jxoveralign = 1;
        !           273:                                                badjxalign++;
        !           274:                                        }
        !           275:                                        /*
        !           276:                                         *      we assume the worst case
        !           277:                                         *      for unfrozen jxxxxes
        !           278:                                         */
        !           279:                                        displ += intdest->jxfear;
        !           280:                                }
        !           281:                                if (displ <= MAXBYTE){
        !           282:                                        /*
        !           283:                                         *      the worst possible conditions
        !           284:                                         *      can't hurt us, so forget about
        !           285:                                         *      this jump
        !           286:                                         */
        !           287:                                        jumpfrom->tag = JXINACTIVE;
        !           288:                                } else {
        !           289:                                        stillactives++;
        !           290:                                }
        !           291:                        } else {
        !           292:                        /*
        !           293:                         *      backward search for intervening jxxx
        !           294:                         */
        !           295:                                SEGITERATE(segno, cojumpfrom - 1,1,cointdest,
        !           296:                                  intdest, ubintdest, --){
        !           297:                                        if (intdest->value <= dest->value) 
        !           298:                                                break; /* beyond destination */
        !           299:                                        if (intdest->tag <= JXQUESTIONABLE)
        !           300:                                                continue;       /*frozen solid*/
        !           301:                                        if (intdest->tag == JXALIGN){
        !           302:                                                jumpfrom->jxoveralign = 1;
        !           303:                                                badjxalign++;
        !           304:                                        }
        !           305:                                        displ -= intdest->jxfear; 
        !           306:                                }
        !           307:                                if (displ >= MINBYTE) {
        !           308:                                        jumpfrom->tag = JXINACTIVE;
        !           309:                                } else {
        !           310:                                        stillactives++;
        !           311:                                }
        !           312:                        }       /*end of backwards search*/
        !           313:                }       /*end of iterating through all symbols in this seg*/
        !           314: 
        !           315:                if (nchange == 0) {
        !           316:                        /*
        !           317:                         *      Now, if there are still active jxxx entries,
        !           318:                         *      we are partially deadlocked.  We can leave
        !           319:                         *      these jxxx entries in their assumed short jump
        !           320:                         *      form, as all initial displacement calcualtions
        !           321:                         *      are hanging on unresolved jxxx instructions
        !           322:                         *      that might explode into a long form, causing
        !           323:                         *      other jxxxes jumping across the first set of
        !           324:                         *      jxxxes to explode, etc.
        !           325:                         *      However, if a jxxx jumps across a .align,
        !           326:                         *      we assume the worst for the deadlock cycle,
        !           327:                         *      and resolve all of them towards the long
        !           328:                         *      jump.
        !           329:                         *      Currently, the C compiler does not produce
        !           330:                         *      jumps across aligns, as aligns are only used
        !           331:                         *      in data segments, or in text segments to align
        !           332:                         *      functions.
        !           333:                         */
        !           334:                        if (stillactives){
        !           335: #ifdef METRIC
        !           336:                                jxdeadlock++;
        !           337: #endif
        !           338:                                SEGITERATE(segno, 0, 0, cojumpfrom, jumpfrom,
        !           339:                                    ubjumpfrom, ++){
        !           340:                                        if (jumpfrom->tag == JXACTIVE){
        !           341:                                                jumpfrom->tag =
        !           342:                                                  badjxalign?JXNOTYET:JXINACTIVE;
        !           343:                                        }
        !           344:                                }
        !           345:                                if (badjxalign){
        !           346:                                        jxxxbump(segno, 0);
        !           347: #ifdef METRIC
        !           348:                                        nbadjxsegs++;
        !           349: #endif
        !           350:                                }
        !           351:                        }
        !           352:                        /*
        !           353:                         *      Handle  all of the .align s
        !           354:                         */
        !           355:                        SEGITERATE(segno, 0, 0, cojumpfrom, jumpfrom,
        !           356:                           ubjumpfrom, ++){
        !           357:                            if (jumpfrom->tag == JXALIGN){
        !           358:                                /*
        !           359:                                 *      Predict the true displacement
        !           360:                                 *      needed, irregardless of the
        !           361:                                 *      fact that we guessed 1
        !           362:                                 */
        !           363:                                displ = (jumpfrom->value - 1) & (unsigned)jumpfrom->jxfear;
        !           364:                                if (displ == 0){        /*no virtual displacement*/
        !           365:                                        jumpfrom->jxfear = -1;
        !           366:                                } else {
        !           367:                                        jumpfrom->jxfear = (jumpfrom->jxfear + 1) - displ;
        !           368:                                        /*
        !           369:                                         *      assert jumpfrom->jxfear > 0
        !           370:                                         */
        !           371:                                        if (jumpfrom->jxfear == 1){
        !           372:                                                /*our prediction was correct*/
        !           373:                                                continue;
        !           374:                                        }
        !           375:                                        /*
        !           376:                                         *      assert jumpfrom->jxfear > 1
        !           377:                                         */
        !           378:                                        jumpfrom->jxfear -= 1;  /*correct guess*/
        !           379:                                }
        !           380:                                /*
        !           381:                                 *      assert jumpfrom->jxfear = -1, +1...2**n-1
        !           382:                                 */
        !           383:                                jumpfrom->tag = JXNOTYET;       /*signal*/
        !           384:                                jxxxbump(segno, cojumpfrom);
        !           385:                                jumpfrom->tag = JXINACTIVE;
        !           386:                                /*
        !           387:                                 *      Assert jxfrom->jxvalue indexes the first
        !           388:                                 *      code byte after the added bytes, and
        !           389:                                 *      has n low order zeroes.
        !           390:                                 */
        !           391:                          }
        !           392:                        }       /*end of walking through each segment*/
        !           393:                }       /*end of no changes */
        !           394:                else {  /*changes, and still have to try another pass*/
        !           395:                        jxxxbump(segno, 0);
        !           396:                }
        !           397:           }    /*end of doing the topologic sort*/
        !           398:        }       /*end of iterating through all segments*/
        !           399: }      /*end of jxxxfix*/
        !           400: 
        !           401: /*
        !           402:  *     Go through the symbols in a given segment number,
        !           403:  *     and see which entries are jxxx entries that have
        !           404:  *     been logically "exploded" (expanded), but for which
        !           405:  *     the value of textually following symbols has not been
        !           406:  *     increased
        !           407:  */
        !           408: 
        !           409: jxxxbump(segno, starthint)
        !           410:        int     segno;
        !           411:        struct  symtab **starthint;
        !           412: {
        !           413:        register        struct  symtab  **cosp, *sp;
        !           414:        register        struct  symtab          *ub;
        !           415:        register        int     cum_bump;
        !           416:        register        unsigned        char    tag;
        !           417: 
        !           418: #ifdef METRIC
        !           419:        jxxxiterate++;
        !           420: #endif
        !           421:        cum_bump = 0;
        !           422:        SEGITERATE(segno, starthint, 0, cosp, sp, ub, ++){
        !           423:                tag = sp->tag;
        !           424:                if (tag == JXNOTYET){
        !           425: #ifdef DEBUG
        !           426:                        if (debug){
        !           427:                        if (sp->dest != 0)
        !           428:                                printf("Explode jump to %s on line %d\n",
        !           429:                                        sp->dest->name, lineno);
        !           430:                        else
        !           431:                                printf("Explode an align!\n");
        !           432:                        }
        !           433: #endif
        !           434:                        sp->tag = JXINACTIVE;
        !           435:                        sp->jxbump = 1;
        !           436:                        cum_bump += sp->jxfear;
        !           437:                }
        !           438:                /*
        !           439:                 *      Only bump labels and jxxxes. Ignored entries can
        !           440:                 *      be incremented, as they are thrown away later on.
        !           441:                 *      Stabds are given their final value in the second 
        !           442:                 *      pass.
        !           443:                 */
        !           444:                if (tag >= OKTOBUMP)    /*only bump labels and jxxxes and floating stabs*/
        !           445:                        sp->value += cum_bump;
        !           446:        }
        !           447:        usedot[segno].xvalue += cum_bump;
        !           448: }

unix.superglobalmegacorp.com

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