Annotation of 3BSD/cmd/as/asjxxx.c, revision 1.1.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.