handle enums w/o tags as structure/union members
[unix-history] / usr / src / old / as.vax / asjxxx.c
index a3d4a45..ec62d37 100644 (file)
@@ -1,18 +1,29 @@
-/* Copyright (c) 1980 Regents of the University of California */
-static char sccsid[] = "@(#)asjxxx.c 4.2 %G%";
+/*
+ *     Copyright (c) 1982 Regents of the University of California
+ */
+#ifndef lint
+static char sccsid[] = "@(#)asjxxx.c 4.8 %G%";
+#endif not lint
+
 #include       <stdio.h>
 #include       "as.h"
 #include       "assyms.h"
 
 #include       <stdio.h>
 #include       "as.h"
 #include       "assyms.h"
 
-#define JBR 0x11
-#define BRW 0x31
+#define        JBR     0x11
+#define        BRW     0x31
+#define        JMP     0x17
 
 /*
  *     The number of bytes to add if the jxxx must be "exploded"
  *     into the long form
  */
 
 /*
  *     The number of bytes to add if the jxxx must be "exploded"
  *     into the long form
  */
-#define        JBRFSIZE        1       /*goes to brw*/
-#define JXXXFSIZE      3       /*goes to brb, brw <byte> <byte> */
+#define        JBRDELTA        1       /* brb <byte> ==> brw <byte> <byte> */
+#define        JXXXDELTA       3       /* brb <byte> ==> brb <byte> brw <byte> <byte> */
+#define        JBRJDELTA       d124    /* brb <byte> ==> jmp L^(pc) <byte>*d124 */
+#define        JXXXJDELTA      d124+2  /* brb <byte> ==> brb <byte> jmp L^(pc) <byte>*d124 */
+
+int    jbrfsize = JBRDELTA;
+int    jxxxfsize = JXXXDELTA;
 
 /*
  *     These variables are filled by asscan.c with the
 
 /*
  *     These variables are filled by asscan.c with the
@@ -22,11 +33,24 @@ static      char sccsid[] = "@(#)asjxxx.c 4.2 %G%";
 struct         symtab  *lastnam;
 struct symtab  *lastjxxx;
 
 struct         symtab  *lastnam;
 struct symtab  *lastjxxx;
 
+initijxxx()
+{
+       jbrfsize = jxxxJUMP ? JBRJDELTA : JBRDELTA;
+       jxxxfsize = jxxxJUMP ? JXXXJDELTA : JXXXDELTA;
+       /*
+        *      Note: ifjxxxJUMP is set, then we do NOT do any tunnelling;
+        *      this was too complicated to figure out, and in the first
+        *      version of the assembler, tunnelling proved to be the hardest
+        *      to get to work!
+        */
+}
 /*
  *     Handle jxxx instructions
  */
 /*
  *     Handle jxxx instructions
  */
-ijxout(op,ap,nact)
-       struct arg *ap;
+ijxout(opcode, ap, nact)
+       struct  Opcode  opcode;
+       struct  arg     *ap;
+       int     nact;
 {
        if (passno == 1){
                /*
 {
        if (passno == 1){
                /*
@@ -39,22 +63,26 @@ ijxout(op,ap,nact)
                /*
                 *      We assume the MINIMAL length
                 */
                /*
                 *      We assume the MINIMAL length
                 */
-               putins(op,ap,nact); 
+               putins(opcode, ap, nact); 
                jumpfrom = lastjxxx;
                jumpfrom->s_tag = JXACTIVE;
                jumpfrom->s_jxbump = 0;
                jumpfrom = lastjxxx;
                jumpfrom->s_tag = JXACTIVE;
                jumpfrom->s_jxbump = 0;
-               if (op == JBR)
-                       jumpfrom->s_jxfear = JBRFSIZE;
+               if (opcode.Op_popcode == JBR)
+                       jumpfrom->s_jxfear = jbrfsize;
                else
                else
-                       jumpfrom->s_jxfear = JXXXFSIZE;
+                       jumpfrom->s_jxfear = jxxxfsize;
                if (lastnam == 0)
                        yyerror("jxxx destination not a label");
                jumpfrom->s_dest = lastnam;
                jumpfrom->s_type = dotp->e_xtype;       /*only TEXT or DATA*/
                jumpfrom->s_index = dotp-usedot;
                if (lastnam == 0)
                        yyerror("jxxx destination not a label");
                jumpfrom->s_dest = lastnam;
                jumpfrom->s_type = dotp->e_xtype;       /*only TEXT or DATA*/
                jumpfrom->s_index = dotp-usedot;
+#ifdef DEBUG
+               jumpfrom->s_name = ITABFETCH(opcode)->i_name;
+               jumpfrom->s_jxline = lineno;
+#endif
                /*
                 *      value ALWAYS (ALWAYS!!!) indexes the next instruction
                /*
                 *      value ALWAYS (ALWAYS!!!) indexes the next instruction
-                *      after the jump, even in the jump must be exploded
+                *      after the jump, even if the jump must be exploded
                 *      (bumped)
                 */
                jumpfrom->s_value = dotp->e_xvalue;
                 *      (bumped)
                 */
                jumpfrom->s_value = dotp->e_xvalue;
@@ -63,10 +91,11 @@ ijxout(op,ap,nact)
                /*
                 *      READ THIS AFTER LOOKING AT jxxxfix()
                 */
                /*
                 *      READ THIS AFTER LOOKING AT jxxxfix()
                 */
-               register long           oxvalue;
-               register struct exp     *xp; 
-               register struct symtab  *tunnel;
-               register struct arg     *aplast;
+               reg     long            oxvalue;
+               reg     struct  exp     *xp; 
+               reg     struct  symtab  *tunnel;
+               reg     struct  arg     *aplast;
+                       struct  Opcode  nopcode;
 
                aplast = ap + nact - 1;
                xp = aplast->a_xp;
 
                aplast = ap + nact - 1;
                xp = aplast->a_xp;
@@ -75,40 +104,84 @@ ijxout(op,ap,nact)
                        tunnel = lastjxxx->s_dest;
                        xp->e_xvalue = tunnel->s_value  /*index of instruction following*/
                                    - 3                 /* size of brw + word*/
                        tunnel = lastjxxx->s_dest;
                        xp->e_xvalue = tunnel->s_value  /*index of instruction following*/
                                    - 3                 /* size of brw + word*/
-                                   + ( ( (tunnel->s_jxfear == JBRFSIZE) &&
+                                   + ( ( (tunnel->s_jxfear == jbrfsize) &&
                                          (tunnel->s_jxbump == 0))?1:0);
                                                        /*non bumped branch byteis only 2 back*/
                }
                if (lastjxxx->s_jxbump == 0){   /*wasn't bumped, so is short form*/
                                          (tunnel->s_jxbump == 0))?1:0);
                                                        /*non bumped branch byteis only 2 back*/
                }
                if (lastjxxx->s_jxbump == 0){   /*wasn't bumped, so is short form*/
-                       putins(op, ap, nact);
+                       putins(opcode, ap, nact);
                } else {
                } else {
-                       if (op != JBR){ /*branch reverse conditional byte over 
-                                         branch unconditional word*/
+                       if (opcode.Op_popcode != JBR){
+                               /*
+                                *      branch reverse conditional byte over
+                                *      branch unconditional word
+                                */
                                oxvalue = xp->e_xvalue;
                                xp->e_xvalue = lastjxxx->s_value;
                                oxvalue = xp->e_xvalue;
                                xp->e_xvalue = lastjxxx->s_value;
-                               putins(op^1, ap, nact);
+                               nopcode = opcode;
+                               nopcode.Op_popcode ^= 1;
+                               putins(nopcode, ap, nact);
                                xp->e_xvalue = oxvalue;
                        }
                                xp->e_xvalue = oxvalue;
                        }
-                       putins(BRW, aplast, 1);
+                       nopcode.Op_eopcode = CORE;
+                       nopcode.Op_popcode = jxxxJUMP ? JMP : BRW;
+                       putins(nopcode, aplast, 1);
                }
        }
                }
        }
-}      /*end of ijxout*/
+}
 
 jalign(xp, sp)
        register struct exp *xp;
        register struct symtab *sp;
 {
        register        int     mask;
 
 jalign(xp, sp)
        register struct exp *xp;
        register struct symtab *sp;
 {
        register        int     mask;
-       if (xp->e_xtype != XABS || xp->e_xvalue < 0 || xp->e_xvalue > 16) {
+#ifdef DEBUG
+       static struct strdesc noname;
+#endif
+       /*
+        *      Problem with .align
+        *
+        *      When the loader constructs an executable file from
+        *      a number of objects, it effectively concatnates
+        *      together all of the text segments from all objects,
+        *      and then all of the data segments.
+        *
+        *      If we do an align by a large value, we can align
+        *      within the a.out this assembly produces, but
+        *      after the loader concatnates, the alignment can't
+        *      be guaranteed if the objects preceding this one
+        *      in the load are also aligned to the same size.
+        *
+        *      Currently, the loader guarantees full word alignment.
+        *      So, ridiculous aligns are caught here and converted
+        *      to a .align 2, if possible.
+        */
+       if (   ( (xp->e_xtype & XTYPE) != XABS)
+           || (xp->e_xvalue < 0)
+           || (xp->e_xvalue > 16)
+           ) {
                yyerror("Illegal `align' argument");
                return;
        }
                yyerror("Illegal `align' argument");
                return;
        }
+       if (xp->e_xvalue > 2){
+               if (passno == 1){
+                       yywarning(".align %d is NOT preserved by the loader",
+                               xp->e_xvalue);
+                       yywarning(".align %d converted to .align 2",
+                               xp->e_xvalue);
+               }
+               xp->e_xvalue = 2;
+       }
        flushfield(NBPW/4);
        if (passno == 1) {
                sp->s_tag = JXALIGN;
                sp->s_jxfear = (1 << xp->e_xvalue) - 1;
                sp->s_type = dotp->e_xtype;
                sp->s_index = dotp-usedot;
        flushfield(NBPW/4);
        if (passno == 1) {
                sp->s_tag = JXALIGN;
                sp->s_jxfear = (1 << xp->e_xvalue) - 1;
                sp->s_type = dotp->e_xtype;
                sp->s_index = dotp-usedot;
+#ifdef DEBUG
+               sp->s_name = (char *)&noname;
+               sp->s_jxline = lineno;
+#endif
                /*
                 *      We guess that the align will take up at least one
                 *      byte in the code output.  We will correct for this
                /*
                 *      We guess that the align will take up at least one
                 *      byte in the code output.  We will correct for this
@@ -127,16 +200,8 @@ jalign(xp, sp)
                njxxx++;
        } else {
                mask = (1 << xp->e_xvalue) - 1;
                njxxx++;
        } else {
                mask = (1 << xp->e_xvalue) - 1;
-               while (dotp->e_xvalue & mask){
-#ifdef UNIX
-                       outb(0);
-#endif UNIX
-#ifdef VMS
-                       *vms_obj_ptr++ = -1;
-                       *vms_obj_ptr++ = 0;
-                       dotp->e_xvalue += 1;
-#endif VMS
-               }
+               while (dotp->e_xvalue & mask)
+                       Outb(0);
        }
 }
 
        }
 }
 
@@ -167,6 +232,9 @@ jxxxfix()
             *  Do a lazy topological sort.
             */
            for (topono = 1, nchange = 1; nchange != 0; topono++){
             *  Do a lazy topological sort.
             */
            for (topono = 1, nchange = 1; nchange != 0; topono++){
+#ifdef lint
+               topno = topno;
+#endif lint
 #ifdef DEBUG
                if (debug)
                        printf("\nSegment %d, topo iteration %d\n",
 #ifdef DEBUG
                if (debug)
                        printf("\nSegment %d, topo iteration %d\n",
@@ -195,7 +263,7 @@ jxxxfix()
                                tunnel = 0;     /*avoid tunneling across a flex alocation*/
                                continue;       /*we take care of these later*/
                        }
                                tunnel = 0;     /*avoid tunneling across a flex alocation*/
                                continue;       /*we take care of these later*/
                        }
-                       if (   jumpfrom->s_jxfear == JBRFSIZE   /*unconditional*/
+                       if (   jumpfrom->s_jxfear == jbrfsize   /*unconditional*/
                            || (   tag == JXINACTIVE            /*inactive bumped*/
                                && (jumpfrom->s_jxbump != 0)
                               )
                            || (   tag == JXINACTIVE            /*inactive bumped*/
                                && (jumpfrom->s_jxbump != 0)
                               )
@@ -220,13 +288,16 @@ jxxxfix()
                                 *      to the tunnel is less than zero, and
                                 *      its relative position will be unaffected
                                 *      by future jxxx expansions.
                                 *      to the tunnel is less than zero, and
                                 *      its relative position will be unaffected
                                 *      by future jxxx expansions.
+                                *
+                                *      No tunnels if doing jumps...
                                 */
                                 */
-                               if (    (jumpfrom->s_jxfear > JBRFSIZE)
+                               if (    (!jxxxJUMP)
+                                    && (jumpfrom->s_jxfear > jbrfsize)
                                     && (tunnel) 
                                     && (tunnel->s_dest == jumpfrom->s_dest)    
                                     && (tunnel->s_index == jumpfrom->s_index)
                                     && (tunnel->s_value - jumpfrom->s_value >=
                                     && (tunnel) 
                                     && (tunnel->s_dest == jumpfrom->s_dest)    
                                     && (tunnel->s_index == jumpfrom->s_index)
                                     && (tunnel->s_value - jumpfrom->s_value >=
-                                               MINBYTE + JXXXFSIZE)
+                                               MINBYTE + jxxxfsize)
                                   ) {
                                                /*
                                                 *      tunnelling is OK
                                   ) {
                                                /*
                                                 *      tunnelling is OK
@@ -241,7 +312,8 @@ jxxxfix()
 #ifdef DEBUG
                                                if(debug)
                                                printf("Tunnel from %s from line %d\n",
 #ifdef DEBUG
                                                if(debug)
                                                printf("Tunnel from %s from line %d\n",
-                                                       jumpfrom->s_name, lineno);
+                                                       FETCHNAME(jumpfrom),
+                                                       jumpfrom->s_jxline);
 #endif
                                                continue;
                                } else {        /*tunneling not possible*/
 #endif
                                                continue;
                                } else {        /*tunneling not possible*/
@@ -263,7 +335,7 @@ jxxxfix()
                        if (displ >= 0) {
                                SEGITERATE(segno, cojumpfrom + 1,0,cointdest,
                                                intdest, ubintdest, ++){
                        if (displ >= 0) {
                                SEGITERATE(segno, cojumpfrom + 1,0,cointdest,
                                                intdest, ubintdest, ++){
-                                       if (intdest->s_value > dest->s_value) 
+                                       if (intdest->s_value >= dest->s_value) 
                                                break; /* beyond destination */
                                        if (intdest->s_tag <= JXQUESTIONABLE)
                                                continue;       /*frozen solid*/
                                                break; /* beyond destination */
                                        if (intdest->s_tag <= JXQUESTIONABLE)
                                                continue;       /*frozen solid*/
@@ -416,9 +488,10 @@ jxxxbump(segno, starthint)
                        if (debug){
                        if (sp->s_dest != 0)
                                printf("Explode jump to %s on line %d\n",
                        if (debug){
                        if (sp->s_dest != 0)
                                printf("Explode jump to %s on line %d\n",
-                                       sp->s_dest->s_name, lineno);
+                                       FETCHNAME(sp->s_dest), sp->s_jxline);
                        else
                        else
-                               printf("Explode an align!\n");
+                               printf("Explode an align! on line %d\n",
+                                       sp->s_jxline);
                        }
 #endif
                        sp->s_tag = JXINACTIVE;
                        }
 #endif
                        sp->s_tag = JXINACTIVE;