]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/5a, cmd/5g, cmd/5l, liblink: update for portable Prog, Addr
authorRuss Cox <rsc@golang.org>
Mon, 26 Jan 2015 20:15:05 +0000 (15:15 -0500)
committerRuss Cox <rsc@golang.org>
Fri, 30 Jan 2015 03:15:58 +0000 (03:15 +0000)
Change-Id: I06762d4fb3bb2616087339b6ae1eb5267a39c46a
Reviewed-on: https://go-review.googlesource.com/3516
Reviewed-by: Austin Clements <austin@google.com>
18 files changed:
src/cmd/5a/a.y
src/cmd/5a/lex.c
src/cmd/5a/y.tab.c
src/cmd/5g/cgen.c
src/cmd/5g/cgen64.c
src/cmd/5g/galign.c
src/cmd/5g/gg.h
src/cmd/5g/ggen.c
src/cmd/5g/gobj.c
src/cmd/5g/gsubr.c
src/cmd/5g/opt.h
src/cmd/5g/peep.c
src/cmd/5g/prog.c
src/cmd/5g/reg.c
src/cmd/5l/5.out.h
src/liblink/asm5.c
src/liblink/list5.c
src/liblink/obj5.c

index d365c753433f1052d0b5d322e95f36d1750c0cef..9db688f0a5241d6c9b6abccedef6ada5aec6eaa6 100644 (file)
@@ -111,53 +111,53 @@ inst:
        }
 |      LTYPE1 cond imsr ',' reg
        {
-               outcode($1, $2, &$3, NREG, &$5);
+               outcode($1, $2, &$3, 0, &$5);
        }
 /*
  * MVN
  */
 |      LTYPE2 cond imsr ',' reg
        {
-               outcode($1, $2, &$3, NREG, &$5);
+               outcode($1, $2, &$3, 0, &$5);
        }
 /*
  * MOVW
  */
 |      LTYPE3 cond gen ',' gen
        {
-               outcode($1, $2, &$3, NREG, &$5);
+               outcode($1, $2, &$3, 0, &$5);
        }
 /*
  * B/BL
  */
 |      LTYPE4 cond comma rel
        {
-               outcode($1, $2, &nullgen, NREG, &$4);
+               outcode($1, $2, &nullgen, 0, &$4);
        }
 |      LTYPE4 cond comma nireg
        {
-               outcode($1, $2, &nullgen, NREG, &$4);
+               outcode($1, $2, &nullgen, 0, &$4);
        }
 /*
  * BX
  */
 |      LTYPEBX comma ireg
        {
-               outcode($1, Always, &nullgen, NREG, &$3);
+               outcode($1, Always, &nullgen, 0, &$3);
        }
 /*
  * BEQ
  */
 |      LTYPE5 comma rel
        {
-               outcode($1, Always, &nullgen, NREG, &$3);
+               outcode($1, Always, &nullgen, 0, &$3);
        }
 /*
  * SWI
  */
 |      LTYPE6 cond comma gen
        {
-               outcode($1, $2, &nullgen, NREG, &$4);
+               outcode($1, $2, &nullgen, 0, &$4);
        }
 /*
  * CMP
@@ -174,18 +174,18 @@ inst:
                Addr g;
 
                g = nullgen;
-               g.type = D_CONST;
+               g.type = TYPE_CONST;
                g.offset = $6;
-               outcode($1, $2, &$3, NREG, &g);
+               outcode($1, $2, &$3, 0, &g);
        }
 |      LTYPE8 cond '[' reglist ']' ',' ioreg
        {
                Addr g;
 
                g = nullgen;
-               g.type = D_CONST;
+               g.type = TYPE_CONST;
                g.offset = $4;
-               outcode($1, $2, &g, NREG, &$7);
+               outcode($1, $2, &g, 0, &$7);
        }
 /*
  * SWAP
@@ -207,7 +207,7 @@ inst:
  */
 |      LTYPEA cond comma
        {
-               outcode($1, $2, &nullgen, NREG, &nullgen);
+               outcode($1, $2, &nullgen, 0, &nullgen);
        }
 /*
  * TEXT/GLOBL
@@ -215,22 +215,22 @@ inst:
 |      LTYPEB name ',' imm
        {
                settext($2.sym);
-               $4.type = D_CONST2;
-               $4.offset2 = ArgsSizeUnknown;
+               $4.type = TYPE_TEXTSIZE;
+               $4.u.argsize = ArgsSizeUnknown;
                outcode($1, Always, &$2, 0, &$4);
        }
 |      LTYPEB name ',' con ',' imm
        {
                settext($2.sym);
-               $6.type = D_CONST2;
-               $6.offset2 = ArgsSizeUnknown;
+               $6.type = TYPE_TEXTSIZE;
+               $6.u.argsize = ArgsSizeUnknown;
                outcode($1, Always, &$2, $4, &$6);
        }
 |      LTYPEB name ',' con ',' imm '-' con
        {
                settext($2.sym);
-               $6.type = D_CONST2;
-               $6.offset2 = $8;
+               $6.type = TYPE_TEXTSIZE;
+               $6.u.argsize = $8;
                outcode($1, Always, &$2, $4, &$6);
        }
 /*
@@ -245,25 +245,25 @@ inst:
  */
 |      LTYPED cond reg comma
        {
-               outcode($1, $2, &$3, NREG, &nullgen);
+               outcode($1, $2, &$3, 0, &nullgen);
        }
 /*
  * word
  */
 |      LTYPEH comma ximm
        {
-               outcode($1, Always, &nullgen, NREG, &$3);
+               outcode($1, Always, &nullgen, 0, &$3);
        }
 /*
  * floating-point coprocessor
  */
 |      LTYPEI cond freg ',' freg
        {
-               outcode($1, $2, &$3, NREG, &$5);
+               outcode($1, $2, &$3, 0, &$5);
        }
 |      LTYPEK cond frcon ',' freg
        {
-               outcode($1, $2, &$3, NREG, &$5);
+               outcode($1, $2, &$3, 0, &$5);
        }
 |      LTYPEK cond frcon ',' LFREG ',' freg
        {
@@ -281,7 +281,7 @@ inst:
                Addr g;
 
                g = nullgen;
-               g.type = D_CONST;
+               g.type = TYPE_CONST;
                g.offset =
                        (0xe << 24) |           /* opcode */
                        ($1 << 20) |            /* MCR/MRC */
@@ -293,7 +293,7 @@ inst:
                        (($11 & 15) << 0) |     /* Crm */
                        (($12 & 7) << 5) |      /* coprocessor information */
                        (1<<4);                 /* must be set */
-               outcode(AMRC, Always, &nullgen, NREG, &g);
+               outcode(AMRC, Always, &nullgen, 0, &g);
        }
 /*
  * MULL r1,r2,(hi,lo)
@@ -308,7 +308,7 @@ inst:
  */
 |      LTYPEN cond reg ',' reg ',' reg ',' spreg
        {
-               $7.type = D_REGREG2;
+               $7.type = TYPE_REGREG2;
                $7.offset = $9;
                outcode($1, $2, &$3, $5.reg, &$7);
        }
@@ -317,34 +317,34 @@ inst:
  */
 |      LTYPEPLD oreg
        {
-               outcode($1, Always, &$2, NREG, &nullgen);
+               outcode($1, Always, &$2, 0, &nullgen);
        }
 /*
  * PCDATA
  */
 |      LTYPEPC gen ',' gen
        {
-               if($2.type != D_CONST || $4.type != D_CONST)
+               if($2.type != TYPE_CONST || $4.type != TYPE_CONST)
                        yyerror("arguments to PCDATA must be integer constants");
-               outcode($1, Always, &$2, NREG, &$4);
+               outcode($1, Always, &$2, 0, &$4);
        }
 /*
  * FUNCDATA
  */
 |      LTYPEF gen ',' gen
        {
-               if($2.type != D_CONST)
+               if($2.type != TYPE_CONST)
                        yyerror("index for FUNCDATA must be integer constant");
-               if($4.type != D_EXTERN && $4.type != D_STATIC && $4.type != D_OREG)
+               if($4.type != NAME_EXTERN && $4.type != NAME_STATIC && $4.type != TYPE_MEM)
                        yyerror("value for FUNCDATA must be symbol reference");
-               outcode($1, Always, &$2, NREG, &$4);
+               outcode($1, Always, &$2, 0, &$4);
        }
 /*
  * END
  */
 |      LTYPEE comma
        {
-               outcode($1, Always, &nullgen, NREG, &nullgen);
+               outcode($1, Always, &nullgen, 0, &nullgen);
        }
 
 cond:
@@ -367,7 +367,7 @@ rel:
        con '(' LPC ')'
        {
                $$ = nullgen;
-               $$.type = D_BRANCH;
+               $$.type = TYPE_BRANCH;
                $$.offset = $1 + pc;
        }
 |      LNAME offset
@@ -376,30 +376,25 @@ rel:
                $$ = nullgen;
                if(pass == 2 && $1->type != LLAB)
                        yyerror("undefined label: %s", $1->labelname);
-               $$.type = D_BRANCH;
+               $$.type = TYPE_BRANCH;
                $$.offset = $1->value + $2;
        }
 
 ximm:  '$' con
        {
                $$ = nullgen;
-               $$.type = D_CONST;
+               $$.type = TYPE_CONST;
                $$.offset = $2;
        }
 |      '$' oreg
        {
                $$ = $2;
-               $$.type = D_CONST;
-       }
-|      '$' '*' '$' oreg
-       {
-               $$ = $4;
-               $$.type = D_OCONST;
+               $$.type = TYPE_CONST;
        }
 |      '$' LSCONST
        {
                $$ = nullgen;
-               $$.type = D_SCONST;
+               $$.type = TYPE_SCONST;
                memcpy($$.u.sval, $2, sizeof($$.u.sval));
        }
 |      fcon
@@ -408,13 +403,13 @@ fcon:
        '$' LFCONST
        {
                $$ = nullgen;
-               $$.type = D_FCONST;
+               $$.type = TYPE_FCONST;
                $$.u.dval = $2;
        }
 |      '$' '-' LFCONST
        {
                $$ = nullgen;
-               $$.type = D_FCONST;
+               $$.type = TYPE_FCONST;
                $$.u.dval = -$3;
        }
 
@@ -449,19 +444,19 @@ gen:
 |      LPSR
        {
                $$ = nullgen;
-               $$.type = D_PSR;
+               $$.type = TYPE_REG;
                $$.reg = $1;
        }
 |      LFCR
        {
                $$ = nullgen;
-               $$.type = D_FPCR;
+               $$.type = TYPE_REG;
                $$.reg = $1;
        }
 |      con
        {
                $$ = nullgen;
-               $$.type = D_OREG;
+               $$.type = TYPE_MEM;
                $$.offset = $1;
        }
 |      oreg
@@ -472,7 +467,7 @@ nireg:
 |      name
        {
                $$ = $1;
-               if($1.name != D_EXTERN && $1.name != D_STATIC) {
+               if($1.name != NAME_EXTERN && $1.name != NAME_STATIC) {
                }
        }
 
@@ -480,7 +475,7 @@ ireg:
        '(' spreg ')'
        {
                $$ = nullgen;
-               $$.type = D_OREG;
+               $$.type = TYPE_MEM;
                $$.reg = $2;
                $$.offset = 0;
        }
@@ -490,7 +485,7 @@ ioreg:
 |      con '(' sreg ')'
        {
                $$ = nullgen;
-               $$.type = D_OREG;
+               $$.type = TYPE_MEM;
                $$.reg = $3;
                $$.offset = $1;
        }
@@ -500,7 +495,7 @@ oreg:
 |      name '(' sreg ')'
        {
                $$ = $1;
-               $$.type = D_OREG;
+               $$.type = TYPE_MEM;
                $$.reg = $3;
        }
 |      ioreg
@@ -513,7 +508,7 @@ imsr:
 imm:   '$' con
        {
                $$ = nullgen;
-               $$.type = D_CONST;
+               $$.type = TYPE_CONST;
                $$.offset = $2;
        }
 
@@ -521,7 +516,7 @@ reg:
        spreg
        {
                $$ = nullgen;
-               $$.type = D_REG;
+               $$.type = TYPE_REG;
                $$.reg = $1;
        }
 
@@ -529,7 +524,7 @@ regreg:
        '(' spreg ',' spreg ')'
        {
                $$ = nullgen;
-               $$.type = D_REGREG;
+               $$.type = TYPE_REGREG;
                $$.reg = $2;
                $$.offset = $4;
        }
@@ -538,33 +533,33 @@ shift:
        spreg '<' '<' rcon
        {
                $$ = nullgen;
-               $$.type = D_SHIFT;
-               $$.offset = $1 | $4 | (0 << 5);
+               $$.type = TYPE_SHIFT;
+               $$.offset = $1&15 | $4 | (0 << 5);
        }
 |      spreg '>' '>' rcon
        {
                $$ = nullgen;
-               $$.type = D_SHIFT;
-               $$.offset = $1 | $4 | (1 << 5);
+               $$.type = TYPE_SHIFT;
+               $$.offset = $1&15 | $4 | (1 << 5);
        }
 |      spreg '-' '>' rcon
        {
                $$ = nullgen;
-               $$.type = D_SHIFT;
-               $$.offset = $1 | $4 | (2 << 5);
+               $$.type = TYPE_SHIFT;
+               $$.offset = $1&15 | $4 | (2 << 5);
        }
 |      spreg LAT '>' rcon
        {
                $$ = nullgen;
-               $$.type = D_SHIFT;
-               $$.offset = $1 | $4 | (3 << 5);
+               $$.type = TYPE_SHIFT;
+               $$.offset = $1&15 | $4 | (3 << 5);
        }
 
 rcon:
        spreg
        {
-               if($$ < 0 || $$ >= 16)
-                       print("register value out of range\n");
+               if($$ < REG_R0 || $$ > REG_R15)
+                       print("register value out of range in shift\n");
                $$ = (($1&15) << 8) | (1 << 4);
        }
 |      con
@@ -583,8 +578,8 @@ sreg:
 |      LR '(' expr ')'
        {
                if($3 < 0 || $3 >= NREG)
-                       print("register value out of range\n");
-               $$ = $3;
+                       print("register value out of range in R(...)\n");
+               $$ = REG_R0 + $3;
        }
 
 spreg:
@@ -599,8 +594,8 @@ creg:
 |      LC '(' expr ')'
        {
                if($3 < 0 || $3 >= NREG)
-                       print("register value out of range\n");
-               $$ = $3;
+                       print("register value out of range in C(...)\n");
+               $$ = $3; // TODO(rsc): REG_C0+$3
        }
 
 frcon:
@@ -611,21 +606,21 @@ freg:
        LFREG
        {
                $$ = nullgen;
-               $$.type = D_FREG;
+               $$.type = TYPE_REG;
                $$.reg = $1;
        }
 |      LF '(' con ')'
        {
                $$ = nullgen;
-               $$.type = D_FREG;
-               $$.reg = $3;
+               $$.type = TYPE_REG;
+               $$.reg = REG_F0 + $3;
        }
 
 name:
        con '(' pointer ')'
        {
                $$ = nullgen;
-               $$.type = D_OREG;
+               $$.type = TYPE_MEM;
                $$.name = $3;
                $$.sym = nil;
                $$.offset = $1;
@@ -633,7 +628,7 @@ name:
 |      LNAME offset '(' pointer ')'
        {
                $$ = nullgen;
-               $$.type = D_OREG;
+               $$.type = TYPE_MEM;
                $$.name = $4;
                $$.sym = linklookup(ctxt, $1->name, 0);
                $$.offset = $2;
@@ -641,8 +636,8 @@ name:
 |      LNAME '<' '>' offset '(' LSB ')'
        {
                $$ = nullgen;
-               $$.type = D_OREG;
-               $$.name = D_STATIC;
+               $$.type = TYPE_MEM;
+               $$.name = NAME_STATIC;
                $$.sym = linklookup(ctxt, $1->name, 1);
                $$.offset = $4;
        }
index 9273d669b489b31444a2b1d4f8268d1cf2bc4b2c..63b6bd7944c5f116ab67e33591bfa58bad3b8b71 100644 (file)
@@ -187,47 +187,48 @@ struct
        ushort  value;
 } itab[] =
 {
-       "SP",           LSP,    D_AUTO,
-       "SB",           LSB,    D_EXTERN,
-       "FP",           LFP,    D_PARAM,
-       "PC",           LPC,    D_BRANCH,
-
-       "R",            LR,     0,
-       "R0",           LREG,   0,
-       "R1",           LREG,   1,
-       "R2",           LREG,   2,
-       "R3",           LREG,   3,
-       "R4",           LREG,   4,
-       "R5",           LREG,   5,
-       "R6",           LREG,   6,
-       "R7",           LREG,   7,
-       "R8",           LREG,   8,
-       "R9",           LREG,   9,
-       "g",            LREG,   10, // avoid unintentionally clobber g using R10
-       "R11",          LREG,   11,
-       "R12",          LREG,   12,
-       "R13",          LREG,   13,
-       "R14",          LREG,   14,
-       "R15",          LREG,   15,
-
-       "F",            LF,     0,
-
-       "F0",           LFREG,  0,
-       "F1",           LFREG,  1,
-       "F2",           LFREG,  2,
-       "F3",           LFREG,  3,
-       "F4",           LFREG,  4,
-       "F5",           LFREG,  5,
-       "F6",           LFREG,  6,
-       "F7",           LFREG,  7,
-       "F8",           LFREG,  8,
-       "F9",           LFREG,  9,
-       "F10",          LFREG,  10,
-       "F11",          LFREG,  11,
-       "F12",          LFREG,  12,
-       "F13",          LFREG,  13,
-       "F14",          LFREG,  14,
-       "F15",          LFREG,  15,
+       "SP",           LSP,    NAME_AUTO,
+       "SB",           LSB,    NAME_EXTERN,
+       "FP",           LFP,    NAME_PARAM,
+       "PC",           LPC,    TYPE_BRANCH,
+
+       "R",            LR,     REG_F0,
+
+       "R0",           LREG,   REG_R0,
+       "R1",           LREG,   REG_R1,
+       "R2",           LREG,   REG_R2,
+       "R3",           LREG,   REG_R3,
+       "R4",           LREG,   REG_R4,
+       "R5",           LREG,   REG_R5,
+       "R6",           LREG,   REG_R6,
+       "R7",           LREG,   REG_R7,
+       "R8",           LREG,   REG_R8,
+       "R9",           LREG,   REG_R9,
+       "g",            LREG,   REG_R10, // avoid unintentionally clobber g using R10
+       "R11",          LREG,   REG_R11,
+       "R12",          LREG,   REG_R12,
+       "R13",          LREG,   REG_R13,
+       "R14",          LREG,   REG_R14,
+       "R15",          LREG,   REG_R15,
+
+       "F",            LF,     REG_F0,
+
+       "F0",           LFREG,  REG_F0,
+       "F1",           LFREG,  REG_F1,
+       "F2",           LFREG,  REG_F2,
+       "F3",           LFREG,  REG_F3,
+       "F4",           LFREG,  REG_F4,
+       "F5",           LFREG,  REG_F5,
+       "F6",           LFREG,  REG_F6,
+       "F7",           LFREG,  REG_F7,
+       "F8",           LFREG,  REG_F8,
+       "F9",           LFREG,  REG_F9,
+       "F10",          LFREG,  REG_F10,
+       "F11",          LFREG,  REG_F11,
+       "F12",          LFREG,  REG_F12,
+       "F13",          LFREG,  REG_F13,
+       "F14",          LFREG,  REG_F14,
+       "F15",          LFREG,  REG_F15,
 
        "C",            LC,     0,
 
@@ -248,11 +249,11 @@ struct
        "C14",          LCREG,  14,
        "C15",          LCREG,  15,
 
-       "CPSR",         LPSR,   0,
-       "SPSR",         LPSR,   1,
+       "CPSR",         LPSR,   REG_CPSR,
+       "SPSR",         LPSR,   REG_SPSR,
 
-       "FPSR",         LFCR,   0,
-       "FPCR",         LFCR,   1,
+       "FPSR",         LFCR,   REG_FPSR,
+       "FPCR",         LFCR,   REG_FPCR,
 
        ".EQ",          LCOND,  0,
        ".NE",          LCOND,  1,
@@ -437,9 +438,8 @@ cinit(void)
        Sym *s;
        int i;
 
-       nullgen.type = D_NONE;
-       nullgen.name = D_NONE;
-       nullgen.reg = NREG;
+       nullgen.type = TYPE_NONE;
+       nullgen.name = NAME_NONE;
 
        nerrors = 0;
        iostack = I;
@@ -474,7 +474,7 @@ isreg(Addr *g)
 void
 cclean(void)
 {
-       outcode(AEND, Always, &nullgen, NREG, &nullgen);
+       outcode(AEND, Always, &nullgen, 0, &nullgen);
 }
 
 static int bcode[] =
index ace80c7e0eb1325f90e60708ae1098569ad17ada..c3c9c1cbf592c14ba17e84cccc6f43ac0bad5286 100644 (file)
@@ -436,16 +436,16 @@ union yyalloc
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  2
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   640
+#define YYLAST   624
 
 /* YYNTOKENS -- Number of terminals.  */
 #define YYNTOKENS  71
 /* YYNNTS -- Number of nonterminals.  */
 #define YYNNTS  34
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  130
+#define YYNRULES  129
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  333
+#define YYNSTATES  330
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
@@ -500,15 +500,14 @@ static const yytype_uint16 yyprhs[] =
       80,    84,    89,    96,   104,   112,   120,   127,   134,   138,
      143,   150,   159,   166,   171,   175,   181,   187,   195,   202,
      215,   223,   233,   236,   241,   246,   249,   250,   253,   256,
-     257,   260,   265,   268,   271,   274,   279,   282,   284,   287,
-     291,   293,   297,   301,   303,   305,   307,   312,   314,   316,
-     318,   320,   322,   324,   326,   330,   332,   337,   339,   344,
-     346,   348,   350,   352,   355,   357,   363,   368,   373,   378,
-     383,   385,   387,   389,   391,   396,   398,   400,   402,   407,
-     409,   411,   413,   418,   423,   429,   437,   438,   441,   444,
-     446,   448,   450,   452,   454,   457,   460,   463,   467,   468,
-     471,   473,   477,   481,   485,   489,   493,   498,   503,   507,
-     511
+     257,   260,   265,   268,   271,   274,   277,   279,   282,   286,
+     288,   292,   296,   298,   300,   302,   307,   309,   311,   313,
+     315,   317,   319,   321,   325,   327,   332,   334,   339,   341,
+     343,   345,   347,   350,   352,   358,   363,   368,   373,   378,
+     380,   382,   384,   386,   391,   393,   395,   397,   402,   404,
+     406,   408,   413,   418,   424,   432,   433,   436,   439,   441,
+     443,   445,   447,   449,   452,   455,   458,   462,   463,   466,
+     468,   472,   476,   480,   484,   488,   493,   498,   502,   506
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
@@ -541,31 +540,30 @@ static const yytype_int8 yyrhs[] =
       -1,    44,    83,    64,    83,    -1,    26,    78,    -1,    -1,
       77,    53,    -1,    77,    54,    -1,    -1,    64,    78,    -1,
      102,    67,    41,    68,    -1,    58,   100,    -1,    69,   102,
-      -1,    69,    87,    -1,    69,    10,    69,    87,    -1,    69,
-      57,    -1,    81,    -1,    69,    56,    -1,    69,     9,    56,
-      -1,    95,    -1,    95,     9,    95,    -1,    95,    78,    82,
-      -1,    90,    -1,    80,    -1,    92,    -1,    92,    67,    95,
-      68,    -1,    51,    -1,    52,    -1,   102,    -1,    87,    -1,
-      98,    -1,    85,    -1,    99,    -1,    67,    95,    68,    -1,
-      85,    -1,   102,    67,    94,    68,    -1,    99,    -1,    99,
-      67,    94,    68,    -1,    86,    -1,    90,    -1,    89,    -1,
-      92,    -1,    69,   102,    -1,    95,    -1,    67,    95,    64,
-      95,    68,    -1,    95,     6,     6,    93,    -1,    95,     7,
-       7,    93,    -1,    95,     9,     7,    93,    -1,    95,    55,
-       7,    93,    -1,    95,    -1,   102,    -1,    46,    -1,    41,
-      -1,    45,    67,   104,    68,    -1,    94,    -1,    38,    -1,
-      50,    -1,    49,    67,   104,    68,    -1,    98,    -1,    81,
-      -1,    48,    -1,    47,    67,   102,    68,    -1,   102,    67,
-     101,    68,    -1,    58,   100,    67,   101,    68,    -1,    58,
-       6,     7,   100,    67,    39,    68,    -1,    -1,     8,   102,
-      -1,     9,   102,    -1,    39,    -1,    38,    -1,    40,    -1,
-      37,    -1,    60,    -1,     9,   102,    -1,     8,   102,    -1,
-      70,   102,    -1,    67,   104,    68,    -1,    -1,    64,   104,
-      -1,   102,    -1,   104,     8,   104,    -1,   104,     9,   104,
-      -1,   104,    10,   104,    -1,   104,    11,   104,    -1,   104,
-      12,   104,    -1,   104,     6,     6,   104,    -1,   104,     7,
-       7,   104,    -1,   104,     5,   104,    -1,   104,     4,   104,
-      -1,   104,     3,   104,    -1
+      -1,    69,    87,    -1,    69,    57,    -1,    81,    -1,    69,
+      56,    -1,    69,     9,    56,    -1,    95,    -1,    95,     9,
+      95,    -1,    95,    78,    82,    -1,    90,    -1,    80,    -1,
+      92,    -1,    92,    67,    95,    68,    -1,    51,    -1,    52,
+      -1,   102,    -1,    87,    -1,    98,    -1,    85,    -1,    99,
+      -1,    67,    95,    68,    -1,    85,    -1,   102,    67,    94,
+      68,    -1,    99,    -1,    99,    67,    94,    68,    -1,    86,
+      -1,    90,    -1,    89,    -1,    92,    -1,    69,   102,    -1,
+      95,    -1,    67,    95,    64,    95,    68,    -1,    95,     6,
+       6,    93,    -1,    95,     7,     7,    93,    -1,    95,     9,
+       7,    93,    -1,    95,    55,     7,    93,    -1,    95,    -1,
+     102,    -1,    46,    -1,    41,    -1,    45,    67,   104,    68,
+      -1,    94,    -1,    38,    -1,    50,    -1,    49,    67,   104,
+      68,    -1,    98,    -1,    81,    -1,    48,    -1,    47,    67,
+     102,    68,    -1,   102,    67,   101,    68,    -1,    58,   100,
+      67,   101,    68,    -1,    58,     6,     7,   100,    67,    39,
+      68,    -1,    -1,     8,   102,    -1,     9,   102,    -1,    39,
+      -1,    38,    -1,    40,    -1,    37,    -1,    60,    -1,     9,
+     102,    -1,     8,   102,    -1,    70,   102,    -1,    67,   104,
+      68,    -1,    -1,    64,   104,    -1,   102,    -1,   104,     8,
+     104,    -1,   104,     9,   104,    -1,   104,    10,   104,    -1,
+     104,    11,   104,    -1,   104,    12,   104,    -1,   104,     6,
+       6,   104,    -1,   104,     7,     7,   104,    -1,   104,     5,
+     104,    -1,   104,     4,   104,    -1,   104,     3,   104,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
@@ -576,15 +574,14 @@ static const yytype_uint16 yyrline[] =
      151,   158,   165,   172,   181,   193,   197,   201,   208,   215,
      222,   229,   239,   246,   253,   260,   264,   268,   272,   279,
      301,   309,   318,   325,   334,   345,   351,   354,   358,   363,
-     364,   367,   373,   383,   389,   394,   399,   405,   408,   414,
-     422,   426,   435,   441,   442,   443,   444,   449,   455,   461,
-     467,   468,   471,   472,   480,   489,   490,   499,   500,   506,
-     509,   510,   511,   513,   521,   529,   538,   544,   550,   556,
-     564,   570,   578,   579,   583,   591,   592,   598,   599,   607,
-     608,   611,   617,   625,   633,   641,   651,   654,   658,   664,
-     665,   666,   669,   670,   674,   678,   682,   686,   692,   695,
-     701,   702,   706,   710,   714,   718,   722,   726,   730,   734,
-     738
+     364,   367,   373,   383,   389,   394,   400,   403,   409,   417,
+     421,   430,   436,   437,   438,   439,   444,   450,   456,   462,
+     463,   466,   467,   475,   484,   485,   494,   495,   501,   504,
+     505,   506,   508,   516,   524,   533,   539,   545,   551,   559,
+     565,   573,   574,   578,   586,   587,   593,   594,   602,   603,
+     606,   612,   620,   628,   636,   646,   649,   653,   659,   660,
+     661,   664,   665,   669,   673,   677,   681,   687,   690,   696,
+     697,   701,   705,   709,   713,   717,   721,   725,   729,   733
 };
 #endif
 
@@ -633,15 +630,14 @@ static const yytype_uint8 yyr1[] =
       76,    76,    76,    76,    76,    76,    76,    76,    76,    76,
       76,    76,    76,    76,    76,    76,    76,    76,    76,    76,
       76,    76,    76,    76,    76,    76,    77,    77,    77,    78,
-      78,    79,    79,    80,    80,    80,    80,    80,    81,    81,
-      82,    82,    82,    83,    83,    83,    83,    83,    83,    83,
-      83,    83,    84,    84,    85,    86,    86,    87,    87,    87,
-      88,    88,    88,    89,    90,    91,    92,    92,    92,    92,
-      93,    93,    94,    94,    94,    95,    95,    96,    96,    97,
-      97,    98,    98,    99,    99,    99,   100,   100,   100,   101,
-     101,   101,   102,   102,   102,   102,   102,   102,   103,   103,
-     104,   104,   104,   104,   104,   104,   104,   104,   104,   104,
-     104
+      78,    79,    79,    80,    80,    80,    80,    81,    81,    82,
+      82,    82,    83,    83,    83,    83,    83,    83,    83,    83,
+      83,    84,    84,    85,    86,    86,    87,    87,    87,    88,
+      88,    88,    89,    90,    91,    92,    92,    92,    92,    93,
+      93,    94,    94,    94,    95,    95,    96,    96,    97,    97,
+      98,    98,    99,    99,    99,   100,   100,   100,   101,   101,
+     101,   102,   102,   102,   102,   102,   102,   103,   103,   104,
+     104,   104,   104,   104,   104,   104,   104,   104,   104,   104
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
@@ -652,15 +648,14 @@ static const yytype_uint8 yyr2[] =
        3,     4,     6,     7,     7,     7,     6,     6,     3,     4,
        6,     8,     6,     4,     3,     5,     5,     7,     6,    12,
        7,     9,     2,     4,     4,     2,     0,     2,     2,     0,
-       2,     4,     2,     2,     2,     4,     2,     1,     2,     3,
-       1,     3,     3,     1,     1,     1,     4,     1,     1,     1,
-       1,     1,     1,     1,     3,     1,     4,     1,     4,     1,
-       1,     1,     1,     2,     1,     5,     4,     4,     4,     4,
-       1,     1,     1,     1,     4,     1,     1,     1,     4,     1,
-       1,     1,     4,     4,     5,     7,     0,     2,     2,     1,
-       1,     1,     1,     1,     2,     2,     2,     3,     0,     2,
-       1,     3,     3,     3,     3,     3,     4,     4,     3,     3,
-       3
+       2,     4,     2,     2,     2,     2,     1,     2,     3,     1,
+       3,     3,     1,     1,     1,     4,     1,     1,     1,     1,
+       1,     1,     1,     3,     1,     4,     1,     4,     1,     1,
+       1,     1,     2,     1,     5,     4,     4,     4,     4,     1,
+       1,     1,     1,     4,     1,     1,     1,     4,     1,     1,
+       1,     4,     4,     5,     7,     0,     2,     2,     1,     1,
+       1,     1,     1,     2,     2,     2,     3,     0,     2,     1,
+       3,     3,     3,     3,     3,     4,     4,     3,     3,     3
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -672,238 +667,232 @@ static const yytype_uint8 yydefact[] =
       46,    46,    46,    46,    46,     0,     0,    46,    49,    49,
       46,    46,    46,    46,    46,    46,    49,     0,     0,     0,
        0,     0,     9,     4,     0,    11,     0,     0,     0,    49,
-      49,     0,    49,     0,     0,    49,    49,     0,     0,   112,
-     106,   113,     0,     0,     0,     0,     0,     0,    45,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,    75,    79,
-      42,    77,     0,    96,    93,     0,    92,     0,   101,    67,
-      68,     0,    64,    57,     0,    70,    63,    65,    95,    84,
-      71,    69,     0,     5,     0,     0,    10,    47,    48,     0,
-       0,    81,    80,    82,     0,     0,     0,    50,   106,    20,
-       0,     0,     0,     0,     0,     0,     0,     0,    84,    28,
-     115,   114,     0,     0,     0,     0,   120,     0,   116,     0,
-       0,     0,    49,    34,     0,     0,     0,   100,     0,    99,
+      49,     0,    49,     0,     0,    49,    49,     0,     0,   111,
+     105,   112,     0,     0,     0,     0,     0,     0,    45,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,    74,    78,
+      42,    76,     0,    95,    92,     0,    91,     0,   100,    66,
+      67,     0,    63,    56,     0,    69,    62,    64,    94,    83,
+      70,    68,     0,     5,     0,     0,    10,    47,    48,     0,
+       0,    80,    79,    81,     0,     0,     0,    50,   105,    20,
+       0,     0,     0,     0,     0,     0,     0,     0,    83,    28,
+     114,   113,     0,     0,     0,     0,   119,     0,   115,     0,
+       0,     0,    49,    34,     0,     0,     0,    99,     0,    98,
        0,     0,     0,     0,    19,     0,     0,     0,     0,     0,
-       0,     0,    58,    56,    54,    53,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,    83,     0,     0,     0,
-     106,    17,    18,    72,    73,     0,    52,     0,    21,     0,
-       0,    49,     0,     0,     0,     0,   106,   107,   108,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-     117,    29,     0,   110,   109,   111,     0,     0,    33,     0,
-       0,     0,     0,     0,     0,     0,    74,     0,     0,     0,
-       0,    59,     0,    43,     0,     0,     0,     0,     0,    44,
-       6,     7,     8,    14,    84,    15,    16,    52,     0,     0,
-      49,     0,     0,     0,     0,     0,    49,     0,     0,   130,
-     129,   128,     0,     0,   121,   122,   123,   124,   125,     0,
-     103,     0,    35,     0,   101,    36,    49,     0,     0,    78,
-      76,    94,   102,    55,    66,    86,    90,    91,    87,    88,
-      89,    13,    51,    22,     0,    61,    62,     0,    27,    49,
-      26,     0,   104,   126,   127,    30,    32,     0,     0,    38,
-       0,     0,    12,    24,    23,    25,     0,     0,     0,    37,
-       0,    40,     0,   105,    31,     0,     0,     0,     0,    97,
-       0,     0,    41,     0,     0,     0,     0,   118,    85,    98,
-       0,    39,   119
+       0,    57,    55,    54,    53,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,    82,     0,     0,     0,   105,
+      17,    18,    71,    72,     0,    52,     0,    21,     0,     0,
+      49,     0,     0,     0,     0,   105,   106,   107,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,   116,
+      29,     0,   109,   108,   110,     0,     0,    33,     0,     0,
+       0,     0,     0,     0,     0,    73,     0,     0,     0,     0,
+      58,    43,     0,     0,     0,     0,     0,    44,     6,     7,
+       8,    14,    83,    15,    16,    52,     0,     0,    49,     0,
+       0,     0,     0,     0,    49,     0,     0,   129,   128,   127,
+       0,     0,   120,   121,   122,   123,   124,     0,   102,     0,
+      35,     0,   100,    36,    49,     0,     0,    77,    75,    93,
+     101,    65,    85,    89,    90,    86,    87,    88,    13,    51,
+      22,     0,    60,    61,     0,    27,    49,    26,     0,   103,
+     125,   126,    30,    32,     0,     0,    38,     0,     0,    12,
+      24,    23,    25,     0,     0,     0,    37,     0,    40,     0,
+     104,    31,     0,     0,     0,     0,    96,     0,     0,    41,
+       0,     0,     0,     0,   117,    84,    97,     0,    39,   118
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-      -1,     1,     3,    33,   163,    34,    36,   107,   109,    82,
-      83,   180,    84,   172,    68,    69,    85,   100,   101,    86,
-     311,    87,   275,    88,   118,   320,   138,    90,    71,   125,
-     206,   126,   331,   127
+      -1,     1,     3,    33,   162,    34,    36,   107,   109,    82,
+      83,   179,    84,   171,    68,    69,    85,   100,   101,    86,
+     308,    87,   272,    88,   118,   317,   138,    90,    71,   125,
+     205,   126,   328,   127
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -125
+#define YYPACT_NINF -124
 static const yytype_int16 yypact[] =
 {
-    -125,     7,  -125,   308,   -41,  -125,  -125,  -125,  -125,   -19,
-    -125,  -125,  -125,  -125,  -125,    80,    80,  -125,   -19,   -19,
-    -125,  -125,  -125,  -125,  -125,  -125,   -19,   405,   364,   364,
-     -31,   -15,  -125,  -125,    -2,  -125,   528,   528,   337,   -18,
-     -19,   409,   -18,   528,   230,   187,   -18,   448,   448,  -125,
-     257,  -125,   448,   448,    -6,    15,    94,   309,  -125,    49,
-      19,    44,    95,    19,   309,   309,    63,   391,  -125,  -125,
-    -125,    90,   137,  -125,  -125,   145,  -125,   146,  -125,  -125,
-    -125,    66,  -125,  -125,    52,  -125,  -125,   150,  -125,   147,
-    -125,   137,    57,  -125,   448,   448,  -125,  -125,  -125,   448,
-     167,  -125,  -125,  -125,   184,   200,   431,  -125,    47,  -125,
-     201,   364,   217,   189,   223,   221,    63,   228,  -125,  -125,
-    -125,  -125,   289,   448,   448,   231,  -125,   181,  -125,   411,
-      54,   448,   -19,  -125,   237,   238,    12,  -125,   240,  -125,
-     241,   244,   246,   189,  -125,   245,   114,   319,   448,   448,
-     417,   243,  -125,  -125,  -125,   137,   364,   189,   293,   312,
-     313,   341,   364,   308,   542,   552,  -125,   189,   189,   364,
-     257,  -125,  -125,  -125,  -125,   282,  -125,   315,  -125,   189,
-     287,    42,   296,   114,   303,    63,    47,  -125,  -125,    54,
-     448,   448,   448,   363,   369,   448,   448,   448,   448,   448,
-    -125,  -125,   306,  -125,  -125,  -125,   311,   316,  -125,    53,
-     448,   321,    65,    53,   189,   189,  -125,   318,   324,   250,
-     325,  -125,   405,  -125,   326,   391,   391,   391,   391,  -125,
-    -125,  -125,  -125,  -125,   317,  -125,  -125,   231,   130,   328,
-     -19,   323,   189,   189,   189,   189,   334,   336,   340,   602,
-     621,   628,   448,   448,   197,   197,  -125,  -125,  -125,   352,
-    -125,    49,  -125,   516,   359,  -125,   -19,   366,   371,  -125,
-    -125,  -125,  -125,  -125,  -125,  -125,  -125,  -125,  -125,  -125,
-    -125,   189,  -125,  -125,   474,  -125,  -125,   361,  -125,   165,
-    -125,   399,  -125,   235,   235,   432,  -125,   189,    53,  -125,
-     376,   189,  -125,  -125,  -125,  -125,   377,   448,   380,  -125,
-     189,  -125,   383,  -125,  -125,   112,   385,   189,   386,  -125,
-     388,   189,  -125,   448,   112,   382,   267,   395,  -125,  -125,
-     448,  -125,   613
+    -124,     5,  -124,   329,   -61,  -124,  -124,  -124,  -124,   -57,
+    -124,  -124,  -124,  -124,  -124,   157,   157,  -124,   -57,   -57,
+    -124,  -124,  -124,  -124,  -124,  -124,   -57,   264,   385,   385,
+     -31,   -22,  -124,  -124,   -12,  -124,   512,   512,   358,   -16,
+     -57,   268,   -16,   512,   191,   337,   -16,   432,   432,  -124,
+     164,  -124,   432,   432,     0,     9,    58,   450,  -124,    15,
+     172,    49,   235,   172,   450,   450,    11,    34,  -124,  -124,
+    -124,    14,    21,  -124,  -124,    32,  -124,    46,  -124,  -124,
+    -124,    87,  -124,  -124,    59,  -124,  -124,    69,  -124,    91,
+    -124,    21,    75,  -124,   432,   432,  -124,  -124,  -124,   432,
+      85,  -124,  -124,  -124,   129,   141,   405,  -124,    37,  -124,
+      84,   385,   147,    80,   152,   151,    11,   178,  -124,  -124,
+    -124,  -124,   236,   432,   432,   180,  -124,   173,  -124,   411,
+     231,   432,   -57,  -124,   185,   186,    18,  -124,   189,  -124,
+     193,   200,   201,    80,  -124,   199,   107,   471,   432,   432,
+     430,  -124,  -124,  -124,    21,   385,    80,   269,   273,   274,
+     277,   385,   329,   526,   536,  -124,    80,    80,   385,   164,
+    -124,  -124,  -124,  -124,   218,  -124,   261,  -124,    80,   243,
+      56,   260,   107,   263,    11,    37,  -124,  -124,   231,   432,
+     432,   432,   323,   326,   432,   432,   432,   432,   432,  -124,
+    -124,   272,  -124,  -124,  -124,   303,   276,  -124,    44,   432,
+     281,    63,    44,    80,    80,  -124,   306,   308,   288,   311,
+    -124,  -124,   312,    34,    34,    34,    34,  -124,  -124,  -124,
+    -124,  -124,   317,  -124,  -124,   180,   148,   316,   -57,   321,
+      80,    80,    80,    80,   322,   330,   320,   586,   605,   612,
+     432,   432,   296,   296,  -124,  -124,  -124,   331,  -124,    15,
+    -124,   516,   334,  -124,   -57,   338,   343,  -124,  -124,  -124,
+    -124,  -124,  -124,  -124,  -124,  -124,  -124,  -124,    80,  -124,
+    -124,   448,  -124,  -124,   275,  -124,   214,  -124,   369,  -124,
+     225,   225,   406,  -124,    80,    44,  -124,   350,    80,  -124,
+    -124,  -124,  -124,   353,   432,   360,  -124,    80,  -124,   365,
+    -124,  -124,    82,   370,    80,   368,  -124,   380,    80,  -124,
+     432,    82,   378,   309,   383,  -124,  -124,   432,  -124,   597
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-    -125,  -125,  -125,   292,  -125,  -125,   578,    45,   354,   -56,
-     400,   -48,   -25,  -125,    -7,   -42,   -21,    -5,  -124,     5,
-    -125,   -10,    89,  -118,   -28,   140,  -125,   -46,     4,   -90,
-     277,    -4,  -125,   -16
+    -124,  -124,  -124,   287,  -124,  -124,   562,    10,   344,   -55,
+     389,   -19,     3,  -124,   -43,   -41,   -15,   -17,  -123,    25,
+    -124,   132,   144,  -122,   -28,   137,  -124,   -49,     2,   -92,
+     265,     6,  -124,    12
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
    number is the opposite.  If zero, do what YYDEFACT says.
    If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -61
+#define YYTABLE_NINF -60
 static const yytype_int16 yytable[] =
 {
-      89,    89,   114,   133,    92,   201,    70,     2,    89,    89,
-      89,    55,    55,   105,   134,    89,   139,   140,   176,    54,
-      56,   211,    35,    72,    91,    91,   103,   103,   217,   218,
-      93,    94,   104,   103,    91,    97,    98,   110,   112,   145,
-     115,   102,   102,   120,   121,    40,    40,    95,   102,   128,
-     117,   242,    47,    48,    41,   123,   124,   135,   129,   144,
-     154,    96,   132,    58,    59,   218,    77,    78,   152,   141,
-     142,    66,    97,    98,    47,   150,   151,   155,   164,   165,
-     237,    49,   130,    89,   106,   181,   178,   111,    47,    48,
-     116,   119,   203,   204,   205,   166,   247,    97,    98,   173,
-      77,    78,   175,    49,    51,   131,    40,    91,   -60,   184,
-     174,    52,    77,   264,    53,   145,   156,    49,    81,   187,
-     188,   162,   152,   153,    50,   202,    51,   207,    89,   224,
-     143,   223,   219,    67,    89,   295,    53,   229,    50,   234,
-      51,    89,    77,    78,   236,   220,   121,    52,    97,    98,
-      53,   240,    91,   158,   159,    74,   160,   146,    91,    75,
-      76,   318,   319,   262,   136,    91,   265,   266,   203,   204,
-     205,   239,   233,   235,   249,   250,   251,   208,   246,   254,
-     255,   256,   257,   258,   190,   191,   192,   193,   194,   195,
-     196,   197,   198,   199,   263,   286,   287,   276,   276,   276,
-     276,   273,   161,    73,   147,   296,    74,   197,   198,   199,
-      75,    76,   148,   149,   285,   181,   181,   157,    72,   267,
-     268,   277,   277,   277,   277,    73,   243,    73,    74,    40,
-      74,   167,    75,    76,    75,    76,   293,   294,    47,    48,
-      97,    98,   303,   195,   196,   197,   198,   199,   168,   200,
-     288,    40,   309,   190,   191,   192,   193,   194,   195,   196,
-     197,   198,   199,   122,   169,   123,   124,    49,   177,   308,
-     190,   191,   192,   193,   194,   195,   196,   197,   198,   199,
-     115,   179,   316,    97,    98,   283,   302,   182,   183,   322,
-      51,   290,   185,   325,   305,   113,   186,    67,   189,   225,
-      53,   209,   210,   314,   212,   213,   312,   326,   214,     4,
-     215,   299,   222,   216,   332,   278,   279,   280,   271,   226,
-     227,     5,     6,     7,     8,     9,    10,    11,    12,    13,
-      14,    15,    16,    17,    18,   329,    19,    20,    21,    22,
-      23,    24,    25,    26,    27,    47,    48,    73,   228,   238,
-      74,    28,    29,   241,    75,    76,   239,   203,   204,   205,
-      74,   244,    97,    98,    75,    76,    30,   245,    31,   252,
-     259,    32,    47,    48,    49,    73,   253,   221,    74,   260,
-     261,   281,    75,    76,    77,    78,   269,   284,    79,    80,
-      97,    98,   270,   272,   274,    50,   282,    51,   289,    47,
-      48,    49,    73,   291,    67,    74,    81,    53,   292,    75,
-      76,    77,    78,    47,    48,    79,    80,    47,    48,    47,
-      48,    99,    50,   298,    51,    47,    48,   304,    49,    73,
-     300,    67,    74,    81,    53,   301,    75,    76,   306,    47,
-      48,   307,    49,   310,   315,   313,    49,   317,    49,   321,
-     328,    51,   324,   323,    49,   230,    47,    48,    52,   330,
-     171,    53,   137,    50,   327,    51,   248,   108,    49,    51,
-       0,    51,    67,   221,     0,    53,    52,    51,    52,    53,
-      99,    53,    47,    48,    52,    49,     0,    53,     0,   170,
-       0,    51,     0,     0,     0,     0,     0,     0,    67,     0,
-       0,    53,     0,     0,     0,     0,     0,     0,    51,     0,
-       0,    49,     0,     0,     0,    52,     0,     0,    53,   190,
-     191,   192,   193,   194,   195,   196,   197,   198,   199,     0,
-       0,     0,     0,     0,    51,     0,     0,     0,     0,     0,
-       0,    67,     0,     0,    53,   190,   191,   192,   193,   194,
-     195,   196,   197,   198,   199,   190,   191,   192,   193,   194,
-     195,   196,   197,   198,   199,     0,    73,     0,     0,    74,
-       0,     0,     0,    75,    76,     0,     0,     0,     0,     0,
-     297,    97,    98,     0,    37,    38,    39,     0,    42,    43,
-      44,    45,    46,     0,     0,    57,     0,    99,    60,    61,
-      62,    63,    64,    65,     0,   231,   191,   192,   193,   194,
-     195,   196,   197,   198,   199,   232,   190,   191,   192,   193,
-     194,   195,   196,   197,   198,   199,   192,   193,   194,   195,
-     196,   197,   198,   199,   193,   194,   195,   196,   197,   198,
-     199
+      89,    89,    35,   114,   133,     2,   200,    40,    89,    89,
+      89,   134,    70,   139,   140,    89,   175,    54,    56,    41,
+     104,    55,    55,   144,   216,   217,   112,   210,    58,    59,
+      93,    94,    92,    72,    91,    91,    66,    97,    98,   145,
+      95,   105,    47,    48,    91,   123,   124,   110,    40,   106,
+     115,    96,   111,   120,   121,   116,   119,    47,    48,   128,
+     217,   102,   102,   172,   129,   240,   153,   135,   102,   131,
+     117,    49,    73,   183,   151,    74,   130,   235,   143,    75,
+      76,   146,   132,    89,    81,   180,    49,   154,   147,   141,
+     142,    77,    78,   245,    51,    47,   150,   157,   158,   148,
+     159,    52,    97,    98,    53,   165,   163,   164,   173,    51,
+      77,   262,   174,   149,   177,   145,    52,    91,    73,    53,
+      40,    74,   -59,   155,    49,    75,    76,    89,   222,   186,
+     187,   315,   316,    89,   292,   201,   156,   206,   232,   161,
+      89,   244,   207,   151,   152,    50,   160,    51,    74,   166,
+     238,   176,    75,    76,    67,   219,   121,    53,   221,   260,
+     218,    91,   263,   264,   227,    47,    48,    91,   103,   103,
+     122,   234,   123,   124,    91,   103,   189,   190,   191,   192,
+     193,   194,   195,   196,   197,   198,   202,   203,   204,   237,
+     241,   231,   233,   167,    49,   273,   273,   273,   273,    47,
+      48,   247,   248,   249,   293,   168,   252,   253,   254,   255,
+     256,   178,   282,   180,   180,    50,   181,    51,   182,    77,
+      78,   261,   283,   284,    52,    97,    98,    53,    49,   274,
+     274,   274,   274,   194,   195,   196,   197,   198,   265,   266,
+     300,   199,   184,   185,    97,    98,   306,   188,   280,   208,
+     209,    51,    73,   211,   287,    74,   113,   212,    67,    75,
+      76,    53,   290,   291,   213,   214,   305,   215,   285,   202,
+     203,   204,    47,    48,   296,   223,    47,    48,    40,   313,
+     224,   225,    77,    78,   226,   236,   319,   115,    97,    98,
+     322,   189,   190,   191,   192,   193,   194,   195,   196,   197,
+     198,    49,   237,   299,   136,    49,   196,   197,   198,   239,
+     311,   302,   189,   190,   191,   192,   193,   194,   195,   196,
+     197,   198,    50,   309,    51,   242,   108,   243,    51,   250,
+       4,    67,   323,   251,    53,    52,   257,   220,    53,   329,
+     259,   301,     5,     6,     7,     8,     9,    10,    11,    12,
+      13,    14,    15,    16,    17,    18,   269,    19,    20,    21,
+      22,    23,    24,    25,    26,    27,    47,    48,   275,   276,
+     277,   258,    28,    29,   267,    73,   268,   326,    74,   270,
+     271,   278,    75,    76,   279,   281,   286,    30,   289,    31,
+      97,    98,    32,    47,    48,    49,    73,   288,   295,    74,
+      99,    40,   297,    75,    76,    77,    78,   298,   303,    79,
+      80,    97,    98,    47,    48,   304,    50,   307,    51,    47,
+      48,   310,    49,    73,   312,    67,    74,    81,    53,   314,
+      75,    76,    77,    78,   318,   320,    79,    80,    47,    48,
+      47,    48,    49,    50,   321,    51,   325,   327,    49,   228,
+     170,   137,    67,   246,    81,    53,    47,    48,   324,     0,
+       0,     0,     0,   169,     0,    51,     0,    49,     0,    49,
+       0,    51,    67,     0,     0,    53,     0,     0,    52,     0,
+      99,    53,     0,     0,     0,    49,   220,     0,    73,     0,
+      51,    74,    51,     0,     0,    75,    76,    52,     0,    52,
+      53,     0,    53,    97,    98,     0,     0,     0,    51,   202,
+     203,   204,    74,     0,     0,    67,    75,    76,    53,   189,
+     190,   191,   192,   193,   194,   195,   196,   197,   198,   189,
+     190,   191,   192,   193,   194,   195,   196,   197,   198,   189,
+     190,   191,   192,   193,   194,   195,   196,   197,   198,     0,
+      73,     0,     0,    74,     0,     0,     0,    75,    76,     0,
+       0,     0,     0,     0,     0,    97,    98,     0,    37,    38,
+      39,     0,    42,    43,    44,    45,    46,     0,     0,    57,
+     294,    99,    60,    61,    62,    63,    64,    65,     0,   229,
+     190,   191,   192,   193,   194,   195,   196,   197,   198,   230,
+     189,   190,   191,   192,   193,   194,   195,   196,   197,   198,
+     191,   192,   193,   194,   195,   196,   197,   198,   192,   193,
+     194,   195,   196,   197,   198
 };
 
 static const yytype_int16 yycheck[] =
 {
-      28,    29,    44,    59,    29,   129,    27,     0,    36,    37,
-      38,    15,    16,    38,    60,    43,    62,    63,   108,    15,
-      16,     9,    63,    27,    28,    29,    36,    37,   146,   147,
-      61,    62,    37,    43,    38,    53,    54,    41,    43,    67,
-      44,    36,    37,    47,    48,    64,    64,    62,    43,    53,
-      45,     9,     8,     9,     9,     8,     9,    61,    64,    66,
-      81,    63,    57,    18,    19,   183,    47,    48,    56,    64,
-      65,    26,    53,    54,     8,     9,    10,    81,    94,    95,
-     170,    37,    67,   111,    39,   113,   111,    42,     8,     9,
-      45,    46,    38,    39,    40,    99,   186,    53,    54,   106,
-      47,    48,   106,    37,    60,    11,    64,   111,    66,   116,
-     106,    67,    47,    48,    70,   143,    64,    37,    69,   123,
-     124,    64,    56,    57,    58,   129,    60,   131,   156,   157,
-      67,   156,   148,    67,   162,   259,    70,   162,    58,   167,
-      60,   169,    47,    48,   169,   149,   150,    67,    53,    54,
-      70,   179,   156,     6,     7,    41,     9,    67,   162,    45,
-      46,    49,    50,   209,    69,   169,   212,   213,    38,    39,
-      40,    41,   167,   168,   190,   191,   192,   132,   185,   195,
-     196,   197,   198,   199,     3,     4,     5,     6,     7,     8,
-       9,    10,    11,    12,   210,   243,   244,   225,   226,   227,
-     228,   222,    55,    38,    67,   261,    41,    10,    11,    12,
-      45,    46,    67,    67,   242,   243,   244,    67,   222,   214,
-     215,   225,   226,   227,   228,    38,   181,    38,    41,    64,
-      41,    64,    45,    46,    45,    46,   252,   253,     8,     9,
-      53,    54,   284,     8,     9,    10,    11,    12,    64,    68,
-     245,    64,   298,     3,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,     6,    64,     8,     9,    37,    67,   297,
-       3,     4,     5,     6,     7,     8,     9,    10,    11,    12,
-     284,    64,   310,    53,    54,   240,   281,    64,    67,   317,
-      60,   246,    64,   321,   289,    65,     7,    67,    67,     6,
-      70,    64,    64,   307,    64,    64,   301,   323,    64,     1,
-      64,   266,    69,    68,   330,   226,   227,   228,    68,     7,
-       7,    13,    14,    15,    16,    17,    18,    19,    20,    21,
-      22,    23,    24,    25,    26,    68,    28,    29,    30,    31,
-      32,    33,    34,    35,    36,     8,     9,    38,     7,    67,
-      41,    43,    44,    66,    45,    46,    41,    38,    39,    40,
-      41,    65,    53,    54,    45,    46,    58,    64,    60,     6,
-      64,    63,     8,     9,    37,    38,     7,    56,    41,    68,
-      64,    64,    45,    46,    47,    48,    68,    64,    51,    52,
-      53,    54,    68,    68,    68,    58,    68,    60,    64,     8,
-       9,    37,    38,    67,    67,    41,    69,    70,    68,    45,
-      46,    47,    48,     8,     9,    51,    52,     8,     9,     8,
-       9,    69,    58,    64,    60,     8,     9,    66,    37,    38,
-      64,    67,    41,    69,    70,    64,    45,    46,    39,     8,
-       9,     9,    37,    67,    64,    68,    37,    64,    37,    64,
-      68,    60,    64,    67,    37,   163,     8,     9,    67,    64,
-     106,    70,    62,    58,   324,    60,   189,    58,    37,    60,
-      -1,    60,    67,    56,    -1,    70,    67,    60,    67,    70,
-      69,    70,     8,     9,    67,    37,    -1,    70,    -1,    58,
-      -1,    60,    -1,    -1,    -1,    -1,    -1,    -1,    67,    -1,
-      -1,    70,    -1,    -1,    -1,    -1,    -1,    -1,    60,    -1,
-      -1,    37,    -1,    -1,    -1,    67,    -1,    -1,    70,     3,
+      28,    29,    63,    44,    59,     0,   129,    64,    36,    37,
+      38,    60,    27,    62,    63,    43,   108,    15,    16,     9,
+      37,    15,    16,    66,   146,   147,    43,     9,    18,    19,
+      61,    62,    29,    27,    28,    29,    26,    53,    54,    67,
+      62,    38,     8,     9,    38,     8,     9,    41,    64,    39,
+      44,    63,    42,    47,    48,    45,    46,     8,     9,    53,
+     182,    36,    37,   106,    64,     9,    81,    61,    43,    11,
+      45,    37,    38,   116,    56,    41,    67,   169,    67,    45,
+      46,    67,    57,   111,    69,   113,    37,    81,    67,    64,
+      65,    47,    48,   185,    60,     8,     9,     6,     7,    67,
+       9,    67,    53,    54,    70,    99,    94,    95,   106,    60,
+      47,    48,   106,    67,   111,   143,    67,   111,    38,    70,
+      64,    41,    66,    64,    37,    45,    46,   155,   156,   123,
+     124,    49,    50,   161,   257,   129,    67,   131,   166,    64,
+     168,   184,   132,    56,    57,    58,    55,    60,    41,    64,
+     178,    67,    45,    46,    67,   149,   150,    70,   155,   208,
+     148,   155,   211,   212,   161,     8,     9,   161,    36,    37,
+       6,   168,     8,     9,   168,    43,     3,     4,     5,     6,
+       7,     8,     9,    10,    11,    12,    38,    39,    40,    41,
+     180,   166,   167,    64,    37,   223,   224,   225,   226,     8,
+       9,   189,   190,   191,   259,    64,   194,   195,   196,   197,
+     198,    64,   240,   241,   242,    58,    64,    60,    67,    47,
+      48,   209,   241,   242,    67,    53,    54,    70,    37,   223,
+     224,   225,   226,     8,     9,    10,    11,    12,   213,   214,
+     281,    68,    64,     7,    53,    54,   295,    67,   238,    64,
+      64,    60,    38,    64,   244,    41,    65,    64,    67,    45,
+      46,    70,   250,   251,    64,    64,   294,    68,   243,    38,
+      39,    40,     8,     9,   264,     6,     8,     9,    64,   307,
+       7,     7,    47,    48,     7,    67,   314,   281,    53,    54,
+     318,     3,     4,     5,     6,     7,     8,     9,    10,    11,
+      12,    37,    41,   278,    69,    37,    10,    11,    12,    66,
+     304,   286,     3,     4,     5,     6,     7,     8,     9,    10,
+      11,    12,    58,   298,    60,    65,    58,    64,    60,     6,
+       1,    67,   320,     7,    70,    67,    64,    56,    70,   327,
+      64,    66,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    23,    24,    25,    26,    68,    28,    29,    30,
+      31,    32,    33,    34,    35,    36,     8,     9,   224,   225,
+     226,    68,    43,    44,    68,    38,    68,    68,    41,    68,
+      68,    64,    45,    46,    68,    64,    64,    58,    68,    60,
+      53,    54,    63,     8,     9,    37,    38,    67,    64,    41,
+      69,    64,    64,    45,    46,    47,    48,    64,    39,    51,
+      52,    53,    54,     8,     9,     9,    58,    67,    60,     8,
+       9,    68,    37,    38,    64,    67,    41,    69,    70,    64,
+      45,    46,    47,    48,    64,    67,    51,    52,     8,     9,
+       8,     9,    37,    58,    64,    60,    68,    64,    37,   162,
+     106,    62,    67,   188,    69,    70,     8,     9,   321,    -1,
+      -1,    -1,    -1,    58,    -1,    60,    -1,    37,    -1,    37,
+      -1,    60,    67,    -1,    -1,    70,    -1,    -1,    67,    -1,
+      69,    70,    -1,    -1,    -1,    37,    56,    -1,    38,    -1,
+      60,    41,    60,    -1,    -1,    45,    46,    67,    -1,    67,
+      70,    -1,    70,    53,    54,    -1,    -1,    -1,    60,    38,
+      39,    40,    41,    -1,    -1,    67,    45,    46,    70,     3,
+       4,     5,     6,     7,     8,     9,    10,    11,    12,     3,
+       4,     5,     6,     7,     8,     9,    10,    11,    12,     3,
        4,     5,     6,     7,     8,     9,    10,    11,    12,    -1,
-      -1,    -1,    -1,    -1,    60,    -1,    -1,    -1,    -1,    -1,
-      -1,    67,    -1,    -1,    70,     3,     4,     5,     6,     7,
-       8,     9,    10,    11,    12,     3,     4,     5,     6,     7,
-       8,     9,    10,    11,    12,    -1,    38,    -1,    -1,    41,
-      -1,    -1,    -1,    45,    46,    -1,    -1,    -1,    -1,    -1,
-      64,    53,    54,    -1,     6,     7,     8,    -1,    10,    11,
-      12,    13,    14,    -1,    -1,    17,    -1,    69,    20,    21,
-      22,    23,    24,    25,    -1,    63,     4,     5,     6,     7,
-       8,     9,    10,    11,    12,    63,     3,     4,     5,     6,
-       7,     8,     9,    10,    11,    12,     5,     6,     7,     8,
-       9,    10,    11,    12,     6,     7,     8,     9,    10,    11,
-      12
+      38,    -1,    -1,    41,    -1,    -1,    -1,    45,    46,    -1,
+      -1,    -1,    -1,    -1,    -1,    53,    54,    -1,     6,     7,
+       8,    -1,    10,    11,    12,    13,    14,    -1,    -1,    17,
+      64,    69,    20,    21,    22,    23,    24,    25,    -1,    63,
+       4,     5,     6,     7,     8,     9,    10,    11,    12,    63,
+       3,     4,     5,     6,     7,     8,     9,    10,    11,    12,
+       5,     6,     7,     8,     9,    10,    11,    12,     6,     7,
+       8,     9,    10,    11,    12
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -925,25 +914,24 @@ static const yytype_uint8 yystos[] =
      102,   102,     6,     8,     9,   100,   102,   104,   102,    64,
       67,    11,    90,    80,    98,   102,    69,    81,    97,    98,
       98,    90,    90,    67,    85,    95,    67,    67,    67,    67,
-       9,    10,    56,    57,    87,   102,    64,    67,     6,     7,
-       9,    55,    64,    75,   104,   104,   102,    64,    64,    64,
-      58,    79,    84,    85,    99,   102,   100,    67,    83,    64,
-      82,    95,    64,    67,    85,    64,     7,   102,   102,    67,
-       3,     4,     5,     6,     7,     8,     9,    10,    11,    12,
-      68,    89,   102,    38,    39,    40,   101,   102,    78,    64,
-      64,     9,    64,    64,    64,    64,    68,    94,    94,   104,
-     102,    56,    69,    83,    95,     6,     7,     7,     7,    83,
-      74,    63,    63,    90,    95,    90,    83,   100,    67,    41,
-      95,    66,     9,    78,    65,    64,    85,   100,   101,   104,
-     104,   104,     6,     7,   104,   104,   104,   104,   104,    64,
-      68,    64,    98,   104,    48,    98,    98,    90,    90,    68,
-      68,    68,    68,    87,    68,    93,    95,   102,    93,    93,
-      93,    64,    68,    78,    64,    95,    82,    82,    90,    64,
-      78,    67,    68,   104,   104,    89,    80,    64,    64,    78,
-      64,    64,    90,    86,    66,    90,    39,     9,    95,    98,
-      67,    91,    90,    68,   102,    64,    95,    64,    49,    50,
-      96,    64,    95,    67,    64,    95,   104,    96,    68,    68,
-      64,   103,   104
+       9,    56,    57,    87,   102,    64,    67,     6,     7,     9,
+      55,    64,    75,   104,   104,   102,    64,    64,    64,    58,
+      79,    84,    85,    99,   102,   100,    67,    83,    64,    82,
+      95,    64,    67,    85,    64,     7,   102,   102,    67,     3,
+       4,     5,     6,     7,     8,     9,    10,    11,    12,    68,
+      89,   102,    38,    39,    40,   101,   102,    78,    64,    64,
+       9,    64,    64,    64,    64,    68,    94,    94,   104,   102,
+      56,    83,    95,     6,     7,     7,     7,    83,    74,    63,
+      63,    90,    95,    90,    83,   100,    67,    41,    95,    66,
+       9,    78,    65,    64,    85,   100,   101,   104,   104,   104,
+       6,     7,   104,   104,   104,   104,   104,    64,    68,    64,
+      98,   104,    48,    98,    98,    90,    90,    68,    68,    68,
+      68,    68,    93,    95,   102,    93,    93,    93,    64,    68,
+      78,    64,    95,    82,    82,    90,    64,    78,    67,    68,
+     104,   104,    89,    80,    64,    64,    78,    64,    64,    90,
+      86,    66,    90,    39,     9,    95,    98,    67,    91,    90,
+      68,   102,    64,    95,    64,    49,    50,    96,    64,    95,
+      67,    64,    95,   104,    96,    68,    68,    64,   103,   104
 };
 
 #define yyerrok                (yyerrstatus = 0)
@@ -1809,56 +1797,56 @@ yyreduce:
   case 14:
 #line 113 "a.y"
     {
-               outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), NREG, &(yyvsp[(5) - (5)].addr));
+               outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), 0, &(yyvsp[(5) - (5)].addr));
        }
     break;
 
   case 15:
 #line 120 "a.y"
     {
-               outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), NREG, &(yyvsp[(5) - (5)].addr));
+               outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), 0, &(yyvsp[(5) - (5)].addr));
        }
     break;
 
   case 16:
 #line 127 "a.y"
     {
-               outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), NREG, &(yyvsp[(5) - (5)].addr));
+               outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), 0, &(yyvsp[(5) - (5)].addr));
        }
     break;
 
   case 17:
 #line 134 "a.y"
     {
-               outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, NREG, &(yyvsp[(4) - (4)].addr));
+               outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, 0, &(yyvsp[(4) - (4)].addr));
        }
     break;
 
   case 18:
 #line 138 "a.y"
     {
-               outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, NREG, &(yyvsp[(4) - (4)].addr));
+               outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, 0, &(yyvsp[(4) - (4)].addr));
        }
     break;
 
   case 19:
 #line 145 "a.y"
     {
-               outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, NREG, &(yyvsp[(3) - (3)].addr));
+               outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, 0, &(yyvsp[(3) - (3)].addr));
        }
     break;
 
   case 20:
 #line 152 "a.y"
     {
-               outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, NREG, &(yyvsp[(3) - (3)].addr));
+               outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, 0, &(yyvsp[(3) - (3)].addr));
        }
     break;
 
   case 21:
 #line 159 "a.y"
     {
-               outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, NREG, &(yyvsp[(4) - (4)].addr));
+               outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &nullgen, 0, &(yyvsp[(4) - (4)].addr));
        }
     break;
 
@@ -1875,9 +1863,9 @@ yyreduce:
                Addr g;
 
                g = nullgen;
-               g.type = D_CONST;
+               g.type = TYPE_CONST;
                g.offset = (yyvsp[(6) - (7)].lval);
-               outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(3) - (7)].addr), NREG, &g);
+               outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &(yyvsp[(3) - (7)].addr), 0, &g);
        }
     break;
 
@@ -1887,9 +1875,9 @@ yyreduce:
                Addr g;
 
                g = nullgen;
-               g.type = D_CONST;
+               g.type = TYPE_CONST;
                g.offset = (yyvsp[(4) - (7)].lval);
-               outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &g, NREG, &(yyvsp[(7) - (7)].addr));
+               outcode((yyvsp[(1) - (7)].lval), (yyvsp[(2) - (7)].lval), &g, 0, &(yyvsp[(7) - (7)].addr));
        }
     break;
 
@@ -1917,7 +1905,7 @@ yyreduce:
   case 28:
 #line 209 "a.y"
     {
-               outcode((yyvsp[(1) - (3)].lval), (yyvsp[(2) - (3)].lval), &nullgen, NREG, &nullgen);
+               outcode((yyvsp[(1) - (3)].lval), (yyvsp[(2) - (3)].lval), &nullgen, 0, &nullgen);
        }
     break;
 
@@ -1925,8 +1913,8 @@ yyreduce:
 #line 216 "a.y"
     {
                settext((yyvsp[(2) - (4)].addr).sym);
-               (yyvsp[(4) - (4)].addr).type = D_CONST2;
-               (yyvsp[(4) - (4)].addr).offset2 = ArgsSizeUnknown;
+               (yyvsp[(4) - (4)].addr).type = TYPE_TEXTSIZE;
+               (yyvsp[(4) - (4)].addr).u.argsize = ArgsSizeUnknown;
                outcode((yyvsp[(1) - (4)].lval), Always, &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
        }
     break;
@@ -1935,8 +1923,8 @@ yyreduce:
 #line 223 "a.y"
     {
                settext((yyvsp[(2) - (6)].addr).sym);
-               (yyvsp[(6) - (6)].addr).type = D_CONST2;
-               (yyvsp[(6) - (6)].addr).offset2 = ArgsSizeUnknown;
+               (yyvsp[(6) - (6)].addr).type = TYPE_TEXTSIZE;
+               (yyvsp[(6) - (6)].addr).u.argsize = ArgsSizeUnknown;
                outcode((yyvsp[(1) - (6)].lval), Always, &(yyvsp[(2) - (6)].addr), (yyvsp[(4) - (6)].lval), &(yyvsp[(6) - (6)].addr));
        }
     break;
@@ -1945,8 +1933,8 @@ yyreduce:
 #line 230 "a.y"
     {
                settext((yyvsp[(2) - (8)].addr).sym);
-               (yyvsp[(6) - (8)].addr).type = D_CONST2;
-               (yyvsp[(6) - (8)].addr).offset2 = (yyvsp[(8) - (8)].lval);
+               (yyvsp[(6) - (8)].addr).type = TYPE_TEXTSIZE;
+               (yyvsp[(6) - (8)].addr).u.argsize = (yyvsp[(8) - (8)].lval);
                outcode((yyvsp[(1) - (8)].lval), Always, &(yyvsp[(2) - (8)].addr), (yyvsp[(4) - (8)].lval), &(yyvsp[(6) - (8)].addr));
        }
     break;
@@ -1961,28 +1949,28 @@ yyreduce:
   case 33:
 #line 247 "a.y"
     {
-               outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &(yyvsp[(3) - (4)].addr), NREG, &nullgen);
+               outcode((yyvsp[(1) - (4)].lval), (yyvsp[(2) - (4)].lval), &(yyvsp[(3) - (4)].addr), 0, &nullgen);
        }
     break;
 
   case 34:
 #line 254 "a.y"
     {
-               outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, NREG, &(yyvsp[(3) - (3)].addr));
+               outcode((yyvsp[(1) - (3)].lval), Always, &nullgen, 0, &(yyvsp[(3) - (3)].addr));
        }
     break;
 
   case 35:
 #line 261 "a.y"
     {
-               outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), NREG, &(yyvsp[(5) - (5)].addr));
+               outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), 0, &(yyvsp[(5) - (5)].addr));
        }
     break;
 
   case 36:
 #line 265 "a.y"
     {
-               outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), NREG, &(yyvsp[(5) - (5)].addr));
+               outcode((yyvsp[(1) - (5)].lval), (yyvsp[(2) - (5)].lval), &(yyvsp[(3) - (5)].addr), 0, &(yyvsp[(5) - (5)].addr));
        }
     break;
 
@@ -2006,7 +1994,7 @@ yyreduce:
                Addr g;
 
                g = nullgen;
-               g.type = D_CONST;
+               g.type = TYPE_CONST;
                g.offset =
                        (0xe << 24) |           /* opcode */
                        ((yyvsp[(1) - (12)].lval) << 20) |              /* MCR/MRC */
@@ -2018,7 +2006,7 @@ yyreduce:
                        (((yyvsp[(11) - (12)].lval) & 15) << 0) |       /* Crm */
                        (((yyvsp[(12) - (12)].lval) & 7) << 5) |        /* coprocessor information */
                        (1<<4);                 /* must be set */
-               outcode(AMRC, Always, &nullgen, NREG, &g);
+               outcode(AMRC, Always, &nullgen, 0, &g);
        }
     break;
 
@@ -2032,7 +2020,7 @@ yyreduce:
   case 41:
 #line 310 "a.y"
     {
-               (yyvsp[(7) - (9)].addr).type = D_REGREG2;
+               (yyvsp[(7) - (9)].addr).type = TYPE_REGREG2;
                (yyvsp[(7) - (9)].addr).offset = (yyvsp[(9) - (9)].lval);
                outcode((yyvsp[(1) - (9)].lval), (yyvsp[(2) - (9)].lval), &(yyvsp[(3) - (9)].addr), (yyvsp[(5) - (9)].addr).reg, &(yyvsp[(7) - (9)].addr));
        }
@@ -2041,34 +2029,34 @@ yyreduce:
   case 42:
 #line 319 "a.y"
     {
-               outcode((yyvsp[(1) - (2)].lval), Always, &(yyvsp[(2) - (2)].addr), NREG, &nullgen);
+               outcode((yyvsp[(1) - (2)].lval), Always, &(yyvsp[(2) - (2)].addr), 0, &nullgen);
        }
     break;
 
   case 43:
 #line 326 "a.y"
     {
-               if((yyvsp[(2) - (4)].addr).type != D_CONST || (yyvsp[(4) - (4)].addr).type != D_CONST)
+               if((yyvsp[(2) - (4)].addr).type != TYPE_CONST || (yyvsp[(4) - (4)].addr).type != TYPE_CONST)
                        yyerror("arguments to PCDATA must be integer constants");
-               outcode((yyvsp[(1) - (4)].lval), Always, &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+               outcode((yyvsp[(1) - (4)].lval), Always, &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
        }
     break;
 
   case 44:
 #line 335 "a.y"
     {
-               if((yyvsp[(2) - (4)].addr).type != D_CONST)
+               if((yyvsp[(2) - (4)].addr).type != TYPE_CONST)
                        yyerror("index for FUNCDATA must be integer constant");
-               if((yyvsp[(4) - (4)].addr).type != D_EXTERN && (yyvsp[(4) - (4)].addr).type != D_STATIC && (yyvsp[(4) - (4)].addr).type != D_OREG)
+               if((yyvsp[(4) - (4)].addr).type != NAME_EXTERN && (yyvsp[(4) - (4)].addr).type != NAME_STATIC && (yyvsp[(4) - (4)].addr).type != TYPE_MEM)
                        yyerror("value for FUNCDATA must be symbol reference");
-               outcode((yyvsp[(1) - (4)].lval), Always, &(yyvsp[(2) - (4)].addr), NREG, &(yyvsp[(4) - (4)].addr));
+               outcode((yyvsp[(1) - (4)].lval), Always, &(yyvsp[(2) - (4)].addr), 0, &(yyvsp[(4) - (4)].addr));
        }
     break;
 
   case 45:
 #line 346 "a.y"
     {
-               outcode((yyvsp[(1) - (2)].lval), Always, &nullgen, NREG, &nullgen);
+               outcode((yyvsp[(1) - (2)].lval), Always, &nullgen, 0, &nullgen);
        }
     break;
 
@@ -2097,7 +2085,7 @@ yyreduce:
 #line 368 "a.y"
     {
                (yyval.addr) = nullgen;
-               (yyval.addr).type = D_BRANCH;
+               (yyval.addr).type = TYPE_BRANCH;
                (yyval.addr).offset = (yyvsp[(1) - (4)].lval) + pc;
        }
     break;
@@ -2109,7 +2097,7 @@ yyreduce:
                (yyval.addr) = nullgen;
                if(pass == 2 && (yyvsp[(1) - (2)].sym)->type != LLAB)
                        yyerror("undefined label: %s", (yyvsp[(1) - (2)].sym)->labelname);
-               (yyval.addr).type = D_BRANCH;
+               (yyval.addr).type = TYPE_BRANCH;
                (yyval.addr).offset = (yyvsp[(1) - (2)].sym)->value + (yyvsp[(2) - (2)].lval);
        }
     break;
@@ -2118,7 +2106,7 @@ yyreduce:
 #line 384 "a.y"
     {
                (yyval.addr) = nullgen;
-               (yyval.addr).type = D_CONST;
+               (yyval.addr).type = TYPE_CONST;
                (yyval.addr).offset = (yyvsp[(2) - (2)].lval);
        }
     break;
@@ -2127,54 +2115,46 @@ yyreduce:
 #line 390 "a.y"
     {
                (yyval.addr) = (yyvsp[(2) - (2)].addr);
-               (yyval.addr).type = D_CONST;
+               (yyval.addr).type = TYPE_CONST;
        }
     break;
 
   case 55:
 #line 395 "a.y"
-    {
-               (yyval.addr) = (yyvsp[(4) - (4)].addr);
-               (yyval.addr).type = D_OCONST;
-       }
-    break;
-
-  case 56:
-#line 400 "a.y"
     {
                (yyval.addr) = nullgen;
-               (yyval.addr).type = D_SCONST;
+               (yyval.addr).type = TYPE_SCONST;
                memcpy((yyval.addr).u.sval, (yyvsp[(2) - (2)].sval), sizeof((yyval.addr).u.sval));
        }
     break;
 
-  case 58:
-#line 409 "a.y"
+  case 57:
+#line 404 "a.y"
     {
                (yyval.addr) = nullgen;
-               (yyval.addr).type = D_FCONST;
+               (yyval.addr).type = TYPE_FCONST;
                (yyval.addr).u.dval = (yyvsp[(2) - (2)].dval);
        }
     break;
 
-  case 59:
-#line 415 "a.y"
+  case 58:
+#line 410 "a.y"
     {
                (yyval.addr) = nullgen;
-               (yyval.addr).type = D_FCONST;
+               (yyval.addr).type = TYPE_FCONST;
                (yyval.addr).u.dval = -(yyvsp[(3) - (3)].dval);
        }
     break;
 
-  case 60:
-#line 423 "a.y"
+  case 59:
+#line 418 "a.y"
     {
                (yyval.lval) = 1 << (yyvsp[(1) - (1)].lval);
        }
     break;
 
-  case 61:
-#line 427 "a.y"
+  case 60:
+#line 422 "a.y"
     {
                int i;
                (yyval.lval)=0;
@@ -2185,161 +2165,161 @@ yyreduce:
        }
     break;
 
-  case 62:
-#line 436 "a.y"
+  case 61:
+#line 431 "a.y"
     {
                (yyval.lval) = (1<<(yyvsp[(1) - (3)].lval)) | (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 66:
-#line 445 "a.y"
+  case 65:
+#line 440 "a.y"
     {
                (yyval.addr) = (yyvsp[(1) - (4)].addr);
                (yyval.addr).reg = (yyvsp[(3) - (4)].lval);
        }
     break;
 
-  case 67:
-#line 450 "a.y"
+  case 66:
+#line 445 "a.y"
     {
                (yyval.addr) = nullgen;
-               (yyval.addr).type = D_PSR;
+               (yyval.addr).type = TYPE_REG;
                (yyval.addr).reg = (yyvsp[(1) - (1)].lval);
        }
     break;
 
-  case 68:
-#line 456 "a.y"
+  case 67:
+#line 451 "a.y"
     {
                (yyval.addr) = nullgen;
-               (yyval.addr).type = D_FPCR;
+               (yyval.addr).type = TYPE_REG;
                (yyval.addr).reg = (yyvsp[(1) - (1)].lval);
        }
     break;
 
-  case 69:
-#line 462 "a.y"
+  case 68:
+#line 457 "a.y"
     {
                (yyval.addr) = nullgen;
-               (yyval.addr).type = D_OREG;
+               (yyval.addr).type = TYPE_MEM;
                (yyval.addr).offset = (yyvsp[(1) - (1)].lval);
        }
     break;
 
-  case 73:
-#line 473 "a.y"
+  case 72:
+#line 468 "a.y"
     {
                (yyval.addr) = (yyvsp[(1) - (1)].addr);
-               if((yyvsp[(1) - (1)].addr).name != D_EXTERN && (yyvsp[(1) - (1)].addr).name != D_STATIC) {
+               if((yyvsp[(1) - (1)].addr).name != NAME_EXTERN && (yyvsp[(1) - (1)].addr).name != NAME_STATIC) {
                }
        }
     break;
 
-  case 74:
-#line 481 "a.y"
+  case 73:
+#line 476 "a.y"
     {
                (yyval.addr) = nullgen;
-               (yyval.addr).type = D_OREG;
+               (yyval.addr).type = TYPE_MEM;
                (yyval.addr).reg = (yyvsp[(2) - (3)].lval);
                (yyval.addr).offset = 0;
        }
     break;
 
-  case 76:
-#line 491 "a.y"
+  case 75:
+#line 486 "a.y"
     {
                (yyval.addr) = nullgen;
-               (yyval.addr).type = D_OREG;
+               (yyval.addr).type = TYPE_MEM;
                (yyval.addr).reg = (yyvsp[(3) - (4)].lval);
                (yyval.addr).offset = (yyvsp[(1) - (4)].lval);
        }
     break;
 
-  case 78:
-#line 501 "a.y"
+  case 77:
+#line 496 "a.y"
     {
                (yyval.addr) = (yyvsp[(1) - (4)].addr);
-               (yyval.addr).type = D_OREG;
+               (yyval.addr).type = TYPE_MEM;
                (yyval.addr).reg = (yyvsp[(3) - (4)].lval);
        }
     break;
 
-  case 83:
-#line 514 "a.y"
+  case 82:
+#line 509 "a.y"
     {
                (yyval.addr) = nullgen;
-               (yyval.addr).type = D_CONST;
+               (yyval.addr).type = TYPE_CONST;
                (yyval.addr).offset = (yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 84:
-#line 522 "a.y"
+  case 83:
+#line 517 "a.y"
     {
                (yyval.addr) = nullgen;
-               (yyval.addr).type = D_REG;
+               (yyval.addr).type = TYPE_REG;
                (yyval.addr).reg = (yyvsp[(1) - (1)].lval);
        }
     break;
 
-  case 85:
-#line 530 "a.y"
+  case 84:
+#line 525 "a.y"
     {
                (yyval.addr) = nullgen;
-               (yyval.addr).type = D_REGREG;
+               (yyval.addr).type = TYPE_REGREG;
                (yyval.addr).reg = (yyvsp[(2) - (5)].lval);
                (yyval.addr).offset = (yyvsp[(4) - (5)].lval);
        }
     break;
 
-  case 86:
-#line 539 "a.y"
+  case 85:
+#line 534 "a.y"
     {
                (yyval.addr) = nullgen;
-               (yyval.addr).type = D_SHIFT;
-               (yyval.addr).offset = (yyvsp[(1) - (4)].lval) | (yyvsp[(4) - (4)].lval) | (0 << 5);
+               (yyval.addr).type = TYPE_SHIFT;
+               (yyval.addr).offset = (yyvsp[(1) - (4)].lval)&15 | (yyvsp[(4) - (4)].lval) | (0 << 5);
        }
     break;
 
-  case 87:
-#line 545 "a.y"
+  case 86:
+#line 540 "a.y"
     {
                (yyval.addr) = nullgen;
-               (yyval.addr).type = D_SHIFT;
-               (yyval.addr).offset = (yyvsp[(1) - (4)].lval) | (yyvsp[(4) - (4)].lval) | (1 << 5);
+               (yyval.addr).type = TYPE_SHIFT;
+               (yyval.addr).offset = (yyvsp[(1) - (4)].lval)&15 | (yyvsp[(4) - (4)].lval) | (1 << 5);
        }
     break;
 
-  case 88:
-#line 551 "a.y"
+  case 87:
+#line 546 "a.y"
     {
                (yyval.addr) = nullgen;
-               (yyval.addr).type = D_SHIFT;
-               (yyval.addr).offset = (yyvsp[(1) - (4)].lval) | (yyvsp[(4) - (4)].lval) | (2 << 5);
+               (yyval.addr).type = TYPE_SHIFT;
+               (yyval.addr).offset = (yyvsp[(1) - (4)].lval)&15 | (yyvsp[(4) - (4)].lval) | (2 << 5);
        }
     break;
 
-  case 89:
-#line 557 "a.y"
+  case 88:
+#line 552 "a.y"
     {
                (yyval.addr) = nullgen;
-               (yyval.addr).type = D_SHIFT;
-               (yyval.addr).offset = (yyvsp[(1) - (4)].lval) | (yyvsp[(4) - (4)].lval) | (3 << 5);
+               (yyval.addr).type = TYPE_SHIFT;
+               (yyval.addr).offset = (yyvsp[(1) - (4)].lval)&15 | (yyvsp[(4) - (4)].lval) | (3 << 5);
        }
     break;
 
-  case 90:
-#line 565 "a.y"
+  case 89:
+#line 560 "a.y"
     {
-               if((yyval.lval) < 0 || (yyval.lval) >= 16)
-                       print("register value out of range\n");
+               if((yyval.lval) < REG_R0 || (yyval.lval) > REG_R15)
+                       print("register value out of range in shift\n");
                (yyval.lval) = (((yyvsp[(1) - (1)].lval)&15) << 8) | (1 << 4);
        }
     break;
 
-  case 91:
-#line 571 "a.y"
+  case 90:
+#line 566 "a.y"
     {
                if((yyval.lval) < 0 || (yyval.lval) >= 32)
                        print("shift value out of range\n");
@@ -2347,224 +2327,224 @@ yyreduce:
        }
     break;
 
-  case 93:
-#line 580 "a.y"
+  case 92:
+#line 575 "a.y"
     {
                (yyval.lval) = REGPC;
        }
     break;
 
-  case 94:
-#line 584 "a.y"
+  case 93:
+#line 579 "a.y"
     {
                if((yyvsp[(3) - (4)].lval) < 0 || (yyvsp[(3) - (4)].lval) >= NREG)
-                       print("register value out of range\n");
-               (yyval.lval) = (yyvsp[(3) - (4)].lval);
+                       print("register value out of range in R(...)\n");
+               (yyval.lval) = REG_R0 + (yyvsp[(3) - (4)].lval);
        }
     break;
 
-  case 96:
-#line 593 "a.y"
+  case 95:
+#line 588 "a.y"
     {
                (yyval.lval) = REGSP;
        }
     break;
 
-  case 98:
-#line 600 "a.y"
+  case 97:
+#line 595 "a.y"
     {
                if((yyvsp[(3) - (4)].lval) < 0 || (yyvsp[(3) - (4)].lval) >= NREG)
-                       print("register value out of range\n");
-               (yyval.lval) = (yyvsp[(3) - (4)].lval);
+                       print("register value out of range in C(...)\n");
+               (yyval.lval) = (yyvsp[(3) - (4)].lval); // TODO(rsc): REG_C0+$3
        }
     break;
 
-  case 101:
-#line 612 "a.y"
+  case 100:
+#line 607 "a.y"
     {
                (yyval.addr) = nullgen;
-               (yyval.addr).type = D_FREG;
+               (yyval.addr).type = TYPE_REG;
                (yyval.addr).reg = (yyvsp[(1) - (1)].lval);
        }
     break;
 
-  case 102:
-#line 618 "a.y"
+  case 101:
+#line 613 "a.y"
     {
                (yyval.addr) = nullgen;
-               (yyval.addr).type = D_FREG;
-               (yyval.addr).reg = (yyvsp[(3) - (4)].lval);
+               (yyval.addr).type = TYPE_REG;
+               (yyval.addr).reg = REG_F0 + (yyvsp[(3) - (4)].lval);
        }
     break;
 
-  case 103:
-#line 626 "a.y"
+  case 102:
+#line 621 "a.y"
     {
                (yyval.addr) = nullgen;
-               (yyval.addr).type = D_OREG;
+               (yyval.addr).type = TYPE_MEM;
                (yyval.addr).name = (yyvsp[(3) - (4)].lval);
                (yyval.addr).sym = nil;
                (yyval.addr).offset = (yyvsp[(1) - (4)].lval);
        }
     break;
 
-  case 104:
-#line 634 "a.y"
+  case 103:
+#line 629 "a.y"
     {
                (yyval.addr) = nullgen;
-               (yyval.addr).type = D_OREG;
+               (yyval.addr).type = TYPE_MEM;
                (yyval.addr).name = (yyvsp[(4) - (5)].lval);
                (yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (5)].sym)->name, 0);
                (yyval.addr).offset = (yyvsp[(2) - (5)].lval);
        }
     break;
 
-  case 105:
-#line 642 "a.y"
+  case 104:
+#line 637 "a.y"
     {
                (yyval.addr) = nullgen;
-               (yyval.addr).type = D_OREG;
-               (yyval.addr).name = D_STATIC;
+               (yyval.addr).type = TYPE_MEM;
+               (yyval.addr).name = NAME_STATIC;
                (yyval.addr).sym = linklookup(ctxt, (yyvsp[(1) - (7)].sym)->name, 1);
                (yyval.addr).offset = (yyvsp[(4) - (7)].lval);
        }
     break;
 
-  case 106:
-#line 651 "a.y"
+  case 105:
+#line 646 "a.y"
     {
                (yyval.lval) = 0;
        }
     break;
 
-  case 107:
-#line 655 "a.y"
+  case 106:
+#line 650 "a.y"
     {
                (yyval.lval) = (yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 108:
-#line 659 "a.y"
+  case 107:
+#line 654 "a.y"
     {
                (yyval.lval) = -(yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 113:
-#line 671 "a.y"
+  case 112:
+#line 666 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (1)].sym)->value;
        }
     break;
 
-  case 114:
-#line 675 "a.y"
+  case 113:
+#line 670 "a.y"
     {
                (yyval.lval) = -(yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 115:
-#line 679 "a.y"
+  case 114:
+#line 674 "a.y"
     {
                (yyval.lval) = (yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 116:
-#line 683 "a.y"
+  case 115:
+#line 678 "a.y"
     {
                (yyval.lval) = ~(yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 117:
-#line 687 "a.y"
+  case 116:
+#line 682 "a.y"
     {
                (yyval.lval) = (yyvsp[(2) - (3)].lval);
        }
     break;
 
-  case 118:
-#line 692 "a.y"
+  case 117:
+#line 687 "a.y"
     {
                (yyval.lval) = 0;
        }
     break;
 
-  case 119:
-#line 696 "a.y"
+  case 118:
+#line 691 "a.y"
     {
                (yyval.lval) = (yyvsp[(2) - (2)].lval);
        }
     break;
 
-  case 121:
-#line 703 "a.y"
+  case 120:
+#line 698 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) + (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 122:
-#line 707 "a.y"
+  case 121:
+#line 702 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) - (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 123:
-#line 711 "a.y"
+  case 122:
+#line 706 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) * (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 124:
-#line 715 "a.y"
+  case 123:
+#line 710 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) / (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 125:
-#line 719 "a.y"
+  case 124:
+#line 714 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) % (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 126:
-#line 723 "a.y"
+  case 125:
+#line 718 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (4)].lval) << (yyvsp[(4) - (4)].lval);
        }
     break;
 
-  case 127:
-#line 727 "a.y"
+  case 126:
+#line 722 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (4)].lval) >> (yyvsp[(4) - (4)].lval);
        }
     break;
 
-  case 128:
-#line 731 "a.y"
+  case 127:
+#line 726 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) & (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 129:
-#line 735 "a.y"
+  case 128:
+#line 730 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) ^ (yyvsp[(3) - (3)].lval);
        }
     break;
 
-  case 130:
-#line 739 "a.y"
+  case 129:
+#line 734 "a.y"
     {
                (yyval.lval) = (yyvsp[(1) - (3)].lval) | (yyvsp[(3) - (3)].lval);
        }
@@ -2572,7 +2552,7 @@ yyreduce:
 
 
 /* Line 1267 of yacc.c.  */
-#line 2576 "y.tab.c"
+#line 2556 "y.tab.c"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
index 87c64f6e8126147d2134e7eb449d5897e10c25ea..3885172e520e8ee9fcb31b64dd73a7e9df173db0 100644 (file)
@@ -1029,7 +1029,7 @@ agenr(Node *n, Node *a, Node *res)
                        regalloc(&n3, types[tptr], res);
                        p1 = gins(AMOVW, N, &n3);
                        datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
-                       p1->from.type = D_CONST;
+                       p1->from.type = TYPE_CONST;
                } else
                if(isslice(nl->type) || nl->type->etype == TSTRING) {
                        n1 = n3;
@@ -1552,7 +1552,7 @@ sgen(Node *n, Node *res, int64 w)
                regalloc(&nend, types[TUINT32], N);
 
                p = gins(AMOVW, &src, &nend);
-               p->from.type = D_CONST;
+               p->from.type = TYPE_CONST;
                if(dir < 0)
                        p->from.offset = dir;
                else
@@ -1562,24 +1562,24 @@ sgen(Node *n, Node *res, int64 w)
        // move src and dest to the end of block if necessary
        if(dir < 0) {
                p = gins(AMOVW, &src, &src);
-               p->from.type = D_CONST;
+               p->from.type = TYPE_CONST;
                p->from.offset = w + dir;
 
                p = gins(AMOVW, &dst, &dst);
-               p->from.type = D_CONST;
+               p->from.type = TYPE_CONST;
                p->from.offset = w + dir;
        }
        
        // move
        if(c >= 4) {
                p = gins(op, &src, &tmp);
-               p->from.type = D_OREG;
+               p->from.type = TYPE_MEM;
                p->from.offset = dir;
                p->scond |= C_PBIT;
                ploop = p;
 
                p = gins(op, &tmp, &dst);
-               p->to.type = D_OREG;
+               p->to.type = TYPE_MEM;
                p->to.offset = dir;
                p->scond |= C_PBIT;
 
@@ -1591,12 +1591,12 @@ sgen(Node *n, Node *res, int64 w)
        } else {
                while(c-- > 0) {
                        p = gins(op, &src, &tmp);
-                       p->from.type = D_OREG;
+                       p->from.type = TYPE_MEM;
                        p->from.offset = dir;
                        p->scond |= C_PBIT;
        
                        p = gins(op, &tmp, &dst);
-                       p->to.type = D_OREG;
+                       p->to.type = TYPE_MEM;
                        p->to.offset = dir;
                        p->scond |= C_PBIT;
                }
index ef11e2adb94d231a86d6d4c50251a713e667732e..9abab4c6502eeb2d4e11aa5f75122dcc7e44f486 100644 (file)
@@ -163,30 +163,30 @@ cgen64(Node *n, Node *res)
 
                // bl * cl -> ah al
                p1 = gins(AMULLU, N, N);
-               p1->from.type = D_REG;
+               p1->from.type = TYPE_REG;
                p1->from.reg = bl.val.u.reg;
                p1->reg = cl.val.u.reg;
-               p1->to.type = D_REGREG;
+               p1->to.type = TYPE_REGREG;
                p1->to.reg = ah.val.u.reg;
                p1->to.offset = al.val.u.reg;
 //print("%P\n", p1);
 
                // bl * ch + ah -> ah
                p1 = gins(AMULA, N, N);
-               p1->from.type = D_REG;
+               p1->from.type = TYPE_REG;
                p1->from.reg = bl.val.u.reg;
                p1->reg = ch.val.u.reg;
-               p1->to.type = D_REGREG2;
+               p1->to.type = TYPE_REGREG2;
                p1->to.reg = ah.val.u.reg;
                p1->to.offset = ah.val.u.reg;
 //print("%P\n", p1);
 
                // bh * cl + ah -> ah
                p1 = gins(AMULA, N, N);
-               p1->from.type = D_REG;
+               p1->from.type = TYPE_REG;
                p1->from.reg = bh.val.u.reg;
                p1->reg = cl.val.u.reg;
-               p1->to.type = D_REGREG2;
+               p1->to.type = TYPE_REGREG2;
                p1->to.reg = ah.val.u.reg;
                p1->to.offset = ah.val.u.reg;
 //print("%P\n", p1);
index 812ce5c7fc9230649b274b8a20e1a97ef68e1ed4..c2940f3b5141cc7398f627fa813a9211c4adb637 100644 (file)
@@ -36,14 +36,8 @@ betypeinit(void)
        widthint = 4;
        widthreg = 4;
 
-       zprog.link = P;
        zprog.as = AGOK;
        zprog.scond = C_SCOND_NONE;
-       zprog.reg = NREG;
-       zprog.from.type = D_NONE;
-       zprog.from.name = D_NONE;
-       zprog.from.reg = NREG;
-       zprog.to = zprog.from;
        arch.zprog = zprog;
 
        listinit5();
@@ -73,10 +67,6 @@ main(int argc, char **argv)
        arch.AUNDEF = AUNDEF;
        arch.AVARDEF = AVARDEF;
        arch.AVARKILL = AVARKILL;
-       arch.D_AUTO = D_AUTO;
-       arch.D_BRANCH = D_BRANCH;
-       arch.D_NONE = D_NONE;
-       arch.D_PARAM = D_PARAM;
        arch.MAXWIDTH = MAXWIDTH;
        arch.afunclit = afunclit;
        arch.anyregalloc = anyregalloc;
index f5c795a63ddee0c5b5bb5471fd56ce8f3d809a00..8fbb7734739ea6c417a24d4f6cd0d638ccea2f21 100644 (file)
 
 enum
 {
-       REGALLOC_R0 = 0,
+       REGALLOC_R0 = REG_R0,
        REGALLOC_RMAX = REGEXT,
-       REGALLOC_F0 = NREG,
-       REGALLOC_FMAX = REGALLOC_F0 + FREGEXT,
+       REGALLOC_F0 = REG_F0,
+       REGALLOC_FMAX = FREGEXT,
 };
 
 EXTERN int32   dynloc;
index 0888f4451d684e8af0920fb1e6fbdcc44c9cbc06..7f1716e91cf4bae03377812fbf9a133fe5aa230c 100644 (file)
@@ -22,8 +22,8 @@ defframe(Prog *ptxt)
        Node *n;
 
        // fill in argument size
-       ptxt->to.type = D_CONST2;
-       ptxt->to.offset2 = rnd(curfn->type->argwid, widthptr);
+       ptxt->to.type = TYPE_TEXTSIZE;
+       ptxt->to.u.argsize = rnd(curfn->type->argwid, widthptr);
 
        // fill in final stack size
        frame = rnd(stksize+maxarg, widthptr);
@@ -70,30 +70,30 @@ zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *r0)
        if(cnt == 0)
                return p;
        if(*r0 == 0) {
-               p = appendpp(p, AMOVW, D_CONST, NREG, 0, D_REG, 0, 0);
+               p = appendpp(p, AMOVW, TYPE_CONST, 0, 0, TYPE_REG, REG_R0, 0);
                *r0 = 1;
        }
        if(cnt < 4*widthptr) {
                for(i = 0; i < cnt; i += widthptr) 
-                       p = appendpp(p, AMOVW, D_REG, 0, 0, D_OREG, REGSP, 4+frame+lo+i);
+                       p = appendpp(p, AMOVW, TYPE_REG, REG_R0, 0, TYPE_MEM, REGSP, 4+frame+lo+i);
        } else if(!nacl && (cnt <= 128*widthptr)) {
-               p = appendpp(p, AADD, D_CONST, NREG, 4+frame+lo, D_REG, 1, 0);
+               p = appendpp(p, AADD, TYPE_CONST, 0, 4+frame+lo, TYPE_REG, REG_R1, 0);
                p->reg = REGSP;
-               p = appendpp(p, ADUFFZERO, D_NONE, NREG, 0, D_OREG, NREG, 0);
+               p = appendpp(p, ADUFFZERO, TYPE_NONE, 0, 0, TYPE_MEM, 0, 0);
                f = sysfunc("duffzero");
                naddr(f, &p->to, 1);
                afunclit(&p->to, f);
                p->to.offset = 4*(128-cnt/widthptr);
        } else {
-               p = appendpp(p, AADD, D_CONST, NREG, 4+frame+lo, D_REG, 1, 0);
+               p = appendpp(p, AADD, TYPE_CONST, 0, 4+frame+lo, TYPE_REG, REG_R1, 0);
                p->reg = REGSP;
-               p = appendpp(p, AADD, D_CONST, NREG, cnt, D_REG, 2, 0);
-               p->reg = 1;
-               p1 = p = appendpp(p, AMOVW, D_REG, 0, 0, D_OREG, 1, 4);
+               p = appendpp(p, AADD, TYPE_CONST, 0, cnt, TYPE_REG, REG_R2, 0);
+               p->reg = REG_R1;
+               p1 = p = appendpp(p, AMOVW, TYPE_REG, REG_R0, 0, TYPE_MEM, REG_R1, 4);
                p->scond |= C_PBIT;
-               p = appendpp(p, ACMP, D_REG, 1, 0, D_NONE, 0, 0);
-               p->reg = 2;
-               p = appendpp(p, ABNE, D_NONE, NREG, 0, D_BRANCH, NREG, 0);
+               p = appendpp(p, ACMP, TYPE_REG, REG_R1, 0, TYPE_NONE, 0, 0);
+               p->reg = REG_R2;
+               p = appendpp(p, ABNE, TYPE_NONE, 0, 0, TYPE_BRANCH, 0, 0);
                patch(p, p1);
        }
        return p;
@@ -142,7 +142,7 @@ fixautoused(Prog* p)
        Prog **lp;
 
        for (lp=&p; (p=*lp) != P; ) {
-               if (p->as == ATYPE && p->from.node && p->from.name == D_AUTO && !((Node*)(p->from.node))->used) {
+               if (p->as == ATYPE && p->from.node && p->from.name == NAME_AUTO && !((Node*)(p->from.node))->used) {
                        *lp = p->link;
                        continue;
                }
@@ -151,16 +151,14 @@ fixautoused(Prog* p)
                        // VARDEFs are interspersed with other code, and a jump might be using the
                        // VARDEF as a target. Replace with a no-op instead. A later pass will remove
                        // the no-ops.
-                       p->to.type = D_NONE;
-                       p->to.node = N;
-                       p->as = ANOP;
+                       nopout(p);
                        continue;
                }
 
-               if (p->from.name == D_AUTO && p->from.node)
+               if (p->from.name == NAME_AUTO && p->from.node)
                        p->from.offset += ((Node*)(p->from.node))->stkdelta;
 
-               if (p->to.name == D_AUTO && p->to.node)
+               if (p->to.name == NAME_AUTO && p->to.node)
                        p->to.offset += ((Node*)(p->to.node))->stkdelta;
 
                lp = &p->link;
@@ -208,7 +206,7 @@ ginscall(Node *f, int proc)
                                // ARM NOP 0x00000000 is really AND.EQ R0, R0, R0.
                                // Use the latter form because the NOP pseudo-instruction
                                // would be removed by the linker.
-                               nodreg(&r, types[TINT], 0);
+                               nodreg(&r, types[TINT], REG_R0);
                                p = gins(AAND, &r, &r);
                                p->scond = C_SCOND_EQ;
                        }
@@ -218,8 +216,8 @@ ginscall(Node *f, int proc)
                                gins(AUNDEF, N, N);
                        break;
                }
-               nodreg(&r, types[tptr], 7);
-               nodreg(&r1, types[tptr], 1);
+               nodreg(&r, types[tptr], REG_R7);
+               nodreg(&r1, types[tptr], REG_R1);
                gmove(f, &r);
                r.op = OINDREG;
                gmove(&r, &r1);
@@ -238,7 +236,7 @@ ginscall(Node *f, int proc)
                nodconst(&con, types[TINT32], argsize(f->type));
                gins(AMOVW, &con, &r);
                p = gins(AMOVW, &r, N);
-               p->to.type = D_OREG;
+               p->to.type = TYPE_MEM;
                p->to.reg = REGSP;
                p->to.offset = 4;
 
@@ -247,7 +245,7 @@ ginscall(Node *f, int proc)
                n1.left = f;
                gins(AMOVW, &n1, &r);
                p = gins(AMOVW, &r, N);
-               p->to.type = D_OREG;
+               p->to.type = TYPE_MEM;
                p->to.reg = REGSP;
                p->to.offset = 8;
 
@@ -261,7 +259,7 @@ ginscall(Node *f, int proc)
                if(proc == 2) {
                        nodconst(&con, types[TINT32], 0);
                        p = gins(ACMP, &con, N);
-                       p->reg = 0;
+                       p->reg = REG_R0;
                        p = gbranch(ABEQ, T, +1);
                        cgen_ret(N);
                        patch(p, pc);
@@ -337,7 +335,7 @@ cgen_callinter(Node *n, Node *res, int proc)
        } else {
                // go/defer. generate go func value.
                p = gins(AMOVW, &nodo, &nodr);
-               p->from.type = D_CONST; // REG = &(20+offset(REG)) -- i.tab->fun[f]
+               p->from.type = TYPE_CONST;      // REG = &(20+offset(REG)) -- i.tab->fun[f]
        }
 
        nodr.type = n->left->type;
@@ -484,8 +482,8 @@ cgen_ret(Node *n)
        genlist(curfn->exit);
        p = gins(ARET, N, N);
        if(n != N && n->op == ORETJMP) {
-               p->to.name = D_EXTERN;
-               p->to.type = D_CONST;
+               p->to.name = NAME_EXTERN;
+               p->to.type = TYPE_CONST;
                p->to.sym = linksym(n->left->sym);
        }
 }
@@ -674,7 +672,7 @@ cgen_hmul(Node *nl, Node *nr, Node *res)
                        p = gins(AMULLU, &n2, N);
                // n2 * n1 -> (n1 n2)
                p->reg = n1.val.u.reg;
-               p->to.type = D_REGREG;
+               p->to.type = TYPE_REGREG;
                p->to.reg = n1.val.u.reg;
                p->to.offset = n2.val.u.reg;
                break;
@@ -862,11 +860,11 @@ clearfat(Node *nl)
        if(q > 128) {
                regalloc(&end, types[tptr], N);
                p = gins(AMOVW, &dst, &end);
-               p->from.type = D_CONST;
+               p->from.type = TYPE_CONST;
                p->from.offset = q*4;
 
                p = gins(AMOVW, &nz, &dst);
-               p->to.type = D_OREG;
+               p->to.type = TYPE_MEM;
                p->to.offset = 4;
                p->scond |= C_PBIT;
                pl = p;
@@ -885,7 +883,7 @@ clearfat(Node *nl)
        } else
        while(q > 0) {
                p = gins(AMOVW, &nz, &dst);
-               p->to.type = D_OREG;
+               p->to.type = TYPE_MEM;
                p->to.offset = 4;
                p->scond |= C_PBIT;
 //print("1. %P\n", p);
@@ -894,7 +892,7 @@ clearfat(Node *nl)
 
        while(c > 0) {
                p = gins(AMOVB, &nz, &dst);
-               p->to.type = D_OREG;
+               p->to.type = TYPE_MEM;
                p->to.offset = 1;
                p->scond |= C_PBIT;
 //print("2. %P\n", p);
@@ -917,7 +915,7 @@ expandchecks(Prog *firstp)
                        continue;
                if(debug_checknil && p->lineno > 1) // p->lineno==1 in generated wrappers
                        warnl(p->lineno, "generated nil check");
-               if(p->from.type != D_REG)
+               if(p->from.type != TYPE_REG)
                        fatal("invalid nil check %P", p);
                reg = p->from.reg;
                // check is
@@ -930,15 +928,15 @@ expandchecks(Prog *firstp)
                p1->lineno = p->lineno;
                p1->pc = 9999;
                p1->as = AMOVW;
-               p1->from.type = D_REG;
+               p1->from.type = TYPE_REG;
                p1->from.reg = reg;
-               p1->to.type = D_OREG;
+               p1->to.type = TYPE_MEM;
                p1->to.reg = reg;
                p1->to.offset = 0;
                p1->scond = C_SCOND_EQ;
                p->as = ACMP;
-               p->from.type = D_CONST;
-               p->from.reg = NREG;
+               p->from.type = TYPE_CONST;
+               p->from.reg = 0;
                p->from.offset = 0;
                p->reg = reg;
        }
index 65f731685e6eac2ed129bcdf4a237740a7c40323..696c6131f677d8c33fbecf1f67bd121f6a8d3b2b 100644 (file)
@@ -38,18 +38,18 @@ dsname(Sym *sym, int off, char *t, int n)
        Prog *p;
 
        p = gins(ADATA, N, N);
-       p->from.type = D_OREG;
-       p->from.name = D_EXTERN;
+       p->from.type = TYPE_MEM;
+       p->from.name = NAME_EXTERN;
        p->from.etype = TINT32;
        p->from.offset = off;
-       p->from.reg = NREG;
+       p->from.reg = 0;
        p->from.sym = linksym(sym);
        
        p->reg = n;
        
-       p->to.type = D_SCONST;
-       p->to.name = D_NONE;
-       p->to.reg = NREG;
+       p->to.type = TYPE_SCONST;
+       p->to.name = NAME_NONE;
+       p->to.reg = 0;
        p->to.offset = 0;
        memmove(p->to.u.sval, t, n);
        return off + n;
@@ -65,11 +65,11 @@ datastring(char *s, int len, Addr *a)
        Sym *sym;
        
        sym = stringsym(s, len);
-       a->type = D_OREG;
-       a->name = D_EXTERN;
+       a->type = TYPE_MEM;
+       a->name = NAME_EXTERN;
        a->etype = TINT32;
        a->offset = widthptr+4;  // skip header
-       a->reg = NREG;
+       a->reg = 0;
        a->sym = linksym(sym);
        a->node = sym->def;
 }
@@ -84,11 +84,11 @@ datagostring(Strlit *sval, Addr *a)
        Sym *sym;
        
        sym = stringsym(sval->s, sval->len);
-       a->type = D_OREG;
-       a->name = D_EXTERN;
+       a->type = TYPE_MEM;
+       a->name = NAME_EXTERN;
        a->etype = TSTRING;
        a->offset = 0;  // header
-       a->reg = NREG;
+       a->reg = 0;
        a->sym = linksym(sym);
        a->node = sym->def;
 }
@@ -134,13 +134,13 @@ gdatacomplex(Node *nam, Mpcplx *cval)
 
        p = gins(ADATA, nam, N);
        p->reg = w;
-       p->to.type = D_FCONST;
+       p->to.type = TYPE_FCONST;
        p->to.u.dval = mpgetflt(&cval->real);
 
        p = gins(ADATA, nam, N);
        p->reg = w;
        p->from.offset += w;
-       p->to.type = D_FCONST;
+       p->to.type = TYPE_FCONST;
        p->to.u.dval = mpgetflt(&cval->imag);
 }
 
@@ -153,7 +153,7 @@ gdatastring(Node *nam, Strlit *sval)
        p = gins(ADATA, nam, N);
        datastring(sval->s, sval->len, &p->to);
        p->reg = types[tptr]->width;
-       p->to.type = D_CONST;
+       p->to.type = TYPE_CONST;
        p->to.etype = TINT32;
 //print("%P\n", p);
 
@@ -170,14 +170,14 @@ dstringptr(Sym *s, int off, char *str)
 
        off = rnd(off, widthptr);
        p = gins(ADATA, N, N);
-       p->from.type = D_OREG;
-       p->from.name = D_EXTERN;
+       p->from.type = TYPE_MEM;
+       p->from.name = NAME_EXTERN;
        p->from.sym = linksym(s);
        p->from.offset = off;
        p->reg = widthptr;
 
        datastring(str, strlen(str)+1, &p->to);
-       p->to.type = D_CONST;
+       p->to.type = TYPE_CONST;
        p->to.etype = TINT32;
        off += widthptr;
 
@@ -194,13 +194,13 @@ dgostrlitptr(Sym *s, int off, Strlit *lit)
 
        off = rnd(off, widthptr);
        p = gins(ADATA, N, N);
-       p->from.type = D_OREG;
-       p->from.name = D_EXTERN;
+       p->from.type = TYPE_MEM;
+       p->from.name = NAME_EXTERN;
        p->from.sym = linksym(s);
        p->from.offset = off;
        p->reg = widthptr;
        datagostring(lit, &p->to);
-       p->to.type = D_CONST;
+       p->to.type = TYPE_CONST;
        p->to.etype = TINT32;
        off += widthptr;
 
@@ -231,13 +231,13 @@ dsymptr(Sym *s, int off, Sym *x, int xoff)
        off = rnd(off, widthptr);
 
        p = gins(ADATA, N, N);
-       p->from.type = D_OREG;
-       p->from.name = D_EXTERN;
+       p->from.type = TYPE_MEM;
+       p->from.name = NAME_EXTERN;
        p->from.sym = linksym(s);
        p->from.offset = off;
        p->reg = widthptr;
-       p->to.type = D_CONST;
-       p->to.name = D_EXTERN;
+       p->to.type = TYPE_CONST;
+       p->to.name = NAME_EXTERN;
        p->to.sym = linksym(x);
        p->to.offset = xoff;
        off += widthptr;
@@ -249,4 +249,8 @@ void
 nopout(Prog *p)
 {
        p->as = ANOP;
+       p->scond = zprog.scond;
+       p->from = zprog.from;
+       p->to = zprog.to;
+       p->reg = zprog.reg;
 }
index f09197963ca3e0215241520b8b9e7e98d059ce31..ab8feb6e0b9dcd1e91dce75f13a32042d9c8a76c 100644 (file)
@@ -42,14 +42,14 @@ void
 clearp(Prog *p)
 {
        p->as = AEND;
-       p->reg = NREG;
+       p->reg = 0;
        p->scond = C_SCOND_NONE;
-       p->from.type = D_NONE;
-       p->from.name = D_NONE;
-       p->from.reg = NREG;
-       p->to.type = D_NONE;
-       p->to.name = D_NONE;
-       p->to.reg = NREG;
+       p->from.type = TYPE_NONE;
+       p->from.name = NAME_NONE;
+       p->from.reg = 0;
+       p->to.type = TYPE_NONE;
+       p->to.name = NAME_NONE;
+       p->to.reg = 0;
        p->pc = pcloc;
        pcloc++;
 }
@@ -124,7 +124,7 @@ gbranch(int as, Type *t, int likely)
        USED(likely);  // TODO: record this for linker
 
        p = prog(as);
-       p->to.type = D_BRANCH;
+       p->to.type = TYPE_BRANCH;
        p->to.u.branch = P;
        return p;
 }
@@ -135,7 +135,7 @@ gbranch(int as, Type *t, int likely)
 void
 patch(Prog *p, Prog *to)
 {
-       if(p->to.type != D_BRANCH)
+       if(p->to.type != TYPE_BRANCH)
                fatal("patch: not a branch");
        p->to.u.branch = to;
        p->to.offset = to->pc;
@@ -146,7 +146,7 @@ unpatch(Prog *p)
 {
        Prog *q;
 
-       if(p->to.type != D_BRANCH)
+       if(p->to.type != TYPE_BRANCH)
                fatal("unpatch: not a branch");
        q = p->to.u.branch;
        p->to.u.branch = P;
@@ -197,7 +197,7 @@ ggloblnod(Node *nam)
        p->lineno = nam->lineno;
        p->from.sym->gotype = linksym(ngotype(nam));
        p->to.sym = nil;
-       p->to.type = D_CONST;
+       p->to.type = TYPE_CONST;
        p->to.offset = nam->type->width;
        if(nam->readonly)
                p->reg = RODATA;
@@ -211,11 +211,11 @@ ggloblsym(Sym *s, int32 width, int8 flags)
        Prog *p;
 
        p = gins(AGLOBL, N, N);
-       p->from.type = D_OREG;
-       p->from.name = D_EXTERN;
+       p->from.type = TYPE_MEM;
+       p->from.name = NAME_EXTERN;
        p->from.sym = linksym(s);
-       p->to.type = D_CONST;
-       p->to.name = D_NONE;
+       p->to.type = TYPE_CONST;
+       p->to.name = NAME_NONE;
        p->to.offset = width;
        p->reg = flags;
 }
@@ -226,8 +226,8 @@ gtrack(Sym *s)
        Prog *p;
        
        p = gins(AUSEFIELD, N, N);
-       p->from.type = D_OREG;
-       p->from.name = D_EXTERN;
+       p->from.type = TYPE_MEM;
+       p->from.name = NAME_EXTERN;
        p->from.sym = linksym(s);
 }
 
@@ -249,13 +249,13 @@ isfat(Type *t)
  * naddr of func generates code for address of func.
  * if using opcode that can take address implicitly,
  * call afunclit to fix up the argument.
- * also fix up direct register references to be D_OREG.
+ * also fix up direct register references to be TYPE_MEM.
  */
 void
 afunclit(Addr *a, Node *n)
 {
-       if(a->type == D_CONST && a->name == D_EXTERN || a->type == D_REG) {
-               a->type = D_OREG;
+       if(a->type == TYPE_CONST && a->name == NAME_EXTERN || a->type == TYPE_REG) {
+               a->type = TYPE_MEM;
                if(n->op == ONAME)
                        a->sym = linksym(n->sym);
        }
@@ -385,7 +385,7 @@ regalloc(Node *n, Type *t, Node *o)
        yyerror("regalloc: unknown type %T", t);
 
 err:
-       nodreg(n, t, 0);
+       nodreg(n, t, REG_R0);
        return;
 
 out:
@@ -852,9 +852,9 @@ gmove(Node *f, Node *t)
                regalloc(&r2, thi.type, N);
                gmove(f, &r1);
                p1 = gins(AMOVW, &r1, &r2);
-               p1->from.type = D_SHIFT;
-               p1->from.offset = 2 << 5 | 31 << 7 | r1.val.u.reg; // r1->31
-               p1->from.reg = NREG;
+               p1->from.type = TYPE_SHIFT;
+               p1->from.offset = 2 << 5 | 31 << 7 | (r1.val.u.reg&15); // r1->31
+               p1->from.reg = 0;
 //print("gmove: %P\n", p1);
                gins(AMOVW, &r1, &tlo);
                gins(AMOVW, &r2, &thi);
@@ -1124,12 +1124,12 @@ raddr(Node *n, Prog *p)
        Addr a;
 
        naddr(n, &a, 1);
-       if(a.type != D_REG && a.type != D_FREG) {
+       if(a.type != TYPE_REG) {
                if(n)
                        fatal("bad in raddr: %O", n->op);
                else
                        fatal("bad in raddr: <null>");
-               p->reg = NREG;
+               p->reg = 0;
        } else
                p->reg = a.reg;
 }
@@ -1164,8 +1164,8 @@ gshift(int as, Node *lhs, int32 stype, int32 sval, Node *rhs)
        sval = sval&0x1f;
 
        p = gins(as, N, rhs);
-       p->from.type = D_SHIFT;
-       p->from.offset = stype | sval<<7 | lhs->val.u.reg;
+       p->from.type = TYPE_SHIFT;
+       p->from.offset = stype | sval<<7 | (lhs->val.u.reg&15);
        return p;
 }
 
@@ -1176,8 +1176,8 @@ gregshift(int as, Node *lhs, int32 stype, Node *reg, Node *rhs)
 {
        Prog *p;
        p = gins(as, N, rhs);
-       p->from.type = D_SHIFT;
-       p->from.offset = stype | reg->val.u.reg << 8 | 1<<4 | lhs->val.u.reg;
+       p->from.type = TYPE_SHIFT;
+       p->from.offset = stype | (reg->val.u.reg&15) << 8 | 1<<4 | (lhs->val.u.reg&15);
        return p;
 }
 
@@ -1190,9 +1190,9 @@ naddr(Node *n, Addr *a, int canemitcode)
 {
        Sym *s;
 
-       a->type = D_NONE;
-       a->name = D_NONE;
-       a->reg = NREG;
+       a->type = TYPE_NONE;
+       a->name = NAME_NONE;
+       a->reg = 0;
        a->gotype = nil;
        a->node = N;
        a->etype = 0;
@@ -1210,13 +1210,8 @@ naddr(Node *n, Addr *a, int canemitcode)
                break;
 
        case OREGISTER:
-               if(n->val.u.reg <= REGALLOC_RMAX) {
-                       a->type = D_REG;
-                       a->reg = n->val.u.reg;
-               } else {
-                       a->type = D_FREG;
-                       a->reg = n->val.u.reg - REGALLOC_F0;
-               }
+               a->type = TYPE_REG;
+               a->reg = n->val.u.reg;
                a->sym = nil;
                break;
 
@@ -1227,12 +1222,12 @@ naddr(Node *n, Addr *a, int canemitcode)
 //             if(a->type >= D_AX && a->type <= D_DI)
 //                     a->type += D_INDIR;
 //             else
-//             if(a->type == D_CONST)
-//                     a->type = D_NONE+D_INDIR;
+//             if(a->type == TYPE_CONST)
+//                     a->type = TYPE_NONE+D_INDIR;
 //             else
-//             if(a->type == D_ADDR) {
+//             if(a->type == TYPE_ADDR) {
 //                     a->type = a->index;
-//                     a->index = D_NONE;
+//                     a->index = TYPE_NONE;
 //             } else
 //                     goto bad;
 //             if(n->op == OINDEX) {
@@ -1242,7 +1237,7 @@ naddr(Node *n, Addr *a, int canemitcode)
 //             break;
 
        case OINDREG:
-               a->type = D_OREG;
+               a->type = TYPE_MEM;
                a->reg = n->val.u.reg;
                a->sym = linksym(n->sym);
                a->offset = n->xoffset;
@@ -1255,16 +1250,16 @@ naddr(Node *n, Addr *a, int canemitcode)
                a->width = n->left->type->width;
                a->offset = n->xoffset;
                a->sym = linksym(n->left->sym);
-               a->type = D_OREG;
-               a->name = D_PARAM;
+               a->type = TYPE_MEM;
+               a->name = NAME_PARAM;
                a->node = n->left->orig;
                break;
        
        case OCLOSUREVAR:
                if(!curfn->needctxt)
                        fatal("closurevar without needctxt");
-               a->type = D_OREG;
-               a->reg = 7;
+               a->type = TYPE_MEM;
+               a->reg = REG_R7;
                a->offset = n->xoffset;
                a->sym = nil;
                break;          
@@ -1277,7 +1272,7 @@ naddr(Node *n, Addr *a, int canemitcode)
        case ONAME:
                a->etype = 0;
                a->width = 0;
-               a->reg = NREG;
+               a->reg = 0;
                if(n->type != T) {
                        a->etype = simtype[n->type->etype];
                        a->width = n->type->width;
@@ -1296,23 +1291,23 @@ naddr(Node *n, Addr *a, int canemitcode)
                                s = pkglookup(s->name, n->type->sym->pkg);
                }
 
-               a->type = D_OREG;
+               a->type = TYPE_MEM;
                switch(n->class) {
                default:
                        fatal("naddr: ONAME class %S %d\n", n->sym, n->class);
                case PEXTERN:
-                       a->name = D_EXTERN;
+                       a->name = NAME_EXTERN;
                        break;
                case PAUTO:
-                       a->name = D_AUTO;
+                       a->name = NAME_AUTO;
                        break;
                case PPARAM:
                case PPARAMOUT:
-                       a->name = D_PARAM;
+                       a->name = NAME_PARAM;
                        break;
                case PFUNC:
-                       a->name = D_EXTERN;
-                       a->type = D_CONST;
+                       a->name = NAME_EXTERN;
+                       a->type = TYPE_CONST;
                        s = funcsym(s);
                        break;
                }
@@ -1325,13 +1320,13 @@ naddr(Node *n, Addr *a, int canemitcode)
                        fatal("naddr: const %lT", n->type);
                        break;
                case CTFLT:
-                       a->type = D_FCONST;
+                       a->type = TYPE_FCONST;
                        a->u.dval = mpgetflt(n->val.u.fval);
                        break;
                case CTINT:
                case CTRUNE:
                        a->sym = nil;
-                       a->type = D_CONST;
+                       a->type = TYPE_CONST;
                        a->offset = mpgetfix(n->val.u.xval);
                        break;
                case CTSTR:
@@ -1339,12 +1334,12 @@ naddr(Node *n, Addr *a, int canemitcode)
                        break;
                case CTBOOL:
                        a->sym = nil;
-                       a->type = D_CONST;
+                       a->type = TYPE_CONST;
                        a->offset = n->val.u.bval;
                        break;
                case CTNIL:
                        a->sym = nil;
-                       a->type = D_CONST;
+                       a->type = TYPE_CONST;
                        a->offset = 0;
                        break;
                }
@@ -1354,7 +1349,7 @@ naddr(Node *n, Addr *a, int canemitcode)
                // itable of interface value
                naddr(n->left, a, canemitcode);
                a->etype = simtype[tptr];
-               if(a->type == D_CONST && a->offset == 0)
+               if(a->type == TYPE_CONST && a->offset == 0)
                        break;  // len(nil)
                a->width = widthptr;
                break;
@@ -1362,7 +1357,7 @@ naddr(Node *n, Addr *a, int canemitcode)
        case OSPTR:
                // pointer in a string or slice
                naddr(n->left, a, canemitcode);
-               if(a->type == D_CONST && a->offset == 0)
+               if(a->type == TYPE_CONST && a->offset == 0)
                        break;  // ptr(nil)
                a->etype = simtype[tptr];
                a->offset += Array_array;
@@ -1373,7 +1368,7 @@ naddr(Node *n, Addr *a, int canemitcode)
                // len of string or slice
                naddr(n->left, a, canemitcode);
                a->etype = TINT32;
-               if(a->type == D_CONST && a->offset == 0)
+               if(a->type == TYPE_CONST && a->offset == 0)
                        break;  // len(nil)
                a->offset += Array_nel;
                break;
@@ -1382,7 +1377,7 @@ naddr(Node *n, Addr *a, int canemitcode)
                // cap of string or slice
                naddr(n->left, a, canemitcode);
                a->etype = TINT32;
-               if(a->type == D_CONST && a->offset == 0)
+               if(a->type == TYPE_CONST && a->offset == 0)
                        break;  // cap(nil)
                a->offset += Array_cap;
                break;
@@ -1391,12 +1386,12 @@ naddr(Node *n, Addr *a, int canemitcode)
                naddr(n->left, a, canemitcode);
                a->etype = tptr;
                switch(a->type) {
-               case D_OREG:
-                       a->type = D_CONST;
+               case TYPE_MEM:
+                       a->type = TYPE_CONST;
                        break;
 
-               case D_REG:
-               case D_CONST:
+               case TYPE_REG:
+               case TYPE_CONST:
                        break;
                
                default:
@@ -1903,8 +1898,8 @@ odot:
                n1.xoffset = -(oary[i]+1);
        }
 
-       a->type = D_NONE;
-       a->name = D_NONE;
+       a->type = TYPE_NONE;
+       a->name = NAME_NONE;
        n1.type = n->type;
        naddr(&n1, a, 1);
        goto yes;
@@ -2022,7 +2017,7 @@ oindex:
        }
 
        naddr(reg1, a, 1);
-       a->type = D_OREG;
+       a->type = TYPE_MEM;
        a->reg = reg->val.u.reg;
        a->offset = 0;
        goto yes;
@@ -2069,8 +2064,8 @@ oindex_const:
        n2 = *reg;
        n2.op = OINDREG;
        n2.xoffset = v * (*w);
-       a->type = D_NONE;
-       a->name = D_NONE;
+       a->type = TYPE_NONE;
+       a->name = NAME_NONE;
        naddr(&n2, a, 1);
        goto yes;
 
index 64c83f1b5ac43e5f3a70def43f986a324efac99d..08ac4ec3f7f118c010943a557be244823d346686 100644 (file)
@@ -32,8 +32,8 @@
 #define        Z       N
 #define        Adr     Addr
 
-#define        D_HI    D_NONE
-#define        D_LO    D_NONE
+#define        D_HI    TYPE_NONE
+#define        D_LO    TYPE_NONE
 
 #define        BLOAD(r)        band(bnot(r->refbehind), r->refahead)
 #define        BSTORE(r)       band(bnot(r->calbehind), r->calahead)
@@ -52,8 +52,8 @@ typedef       struct  Rgn     Rgn;
 extern Node *Z;
 enum
 {
-       D_HI = D_NONE,
-       D_LO = D_NONE,
+       D_HI = TYPE_NONE,
+       D_LO = TYPE_NONE,
        CLOAD = 5,
        CREF = 5,
        CINF = 1000,
@@ -116,8 +116,6 @@ struct      Rgn
        short   regno;
 };
 
-EXTERN int32   exregoffset;            // not set
-EXTERN int32   exfregoffset;           // not set
 EXTERN Reg     zreg;
 EXTERN Reg*    freer;
 EXTERN Reg**   rpo2r;
@@ -126,7 +124,6 @@ EXTERN      Rgn*    rgp;
 EXTERN int     nregion;
 EXTERN int     nvar;
 EXTERN int32   regbits;
-EXTERN int32   exregbits;
 EXTERN Bits    externs;
 EXTERN Bits    params;
 EXTERN Bits    consts;
index 639f4c5f634569768a7d01258a2d4ecd5d8837a3..46c7046ca35fbd2f430e2cbb2b06dc08535d1dd1 100644 (file)
@@ -46,6 +46,7 @@ static int    copysub1(Prog*, Adr*, Adr*, int);
 static Flow*   findpre(Flow *r, Adr *v);
 static int     copyau1(Prog *p, Adr *v);
 static int     isdconst(Addr *a);
+static int     isfloatreg(Addr*);
 
 static uint32  gactive;
 
@@ -54,6 +55,7 @@ int   shiftprop(Flow *r);
 void   constprop(Adr *c1, Adr *v1, Flow *r);
 void   predicate(Graph*);
 
+
 void
 peep(Prog *firstp)
 {
@@ -79,7 +81,7 @@ loop1:
                case ASRL:
                case ASRA:
                        /*
-                        * elide shift into D_SHIFT operand of subsequent instruction
+                        * elide shift into TYPE_SHIFT operand of subsequent instruction
                         */
 //                     if(shiftprop(r)) {
 //                             excise(r);
@@ -94,7 +96,7 @@ loop1:
                case AMOVF:
                case AMOVD:
                        if(regtyp(&p->from))
-                       if(p->from.type == p->to.type)
+                       if(p->from.type == p->to.type && isfloatreg(&p->from) == isfloatreg(&p->to))
                        if(p->scond == C_SCOND_NONE) {
                                if(copyprop(g, r)) {
                                        excise(r);
@@ -113,13 +115,14 @@ loop1:
                case AMOVHU:
                case AMOVBS:
                case AMOVBU:
-                       if(p->from.type == D_REG) {
+                       if(p->from.type == TYPE_REG) {
                                if(shortprop(r))
                                        t++;
                        }
                        break;
 
 #ifdef NOTDEF
+XXX
                        if(p->scond == C_SCOND_NONE)
                        if(regtyp(&p->to))
                        if(isdconst(&p->from)) {
@@ -141,12 +144,12 @@ loop1:
                         */
                        if(isdconst(&p->from) && p->from.offset == -1) {
                                p->as = AMVN;
-                               p->from.type = D_REG;
-                               if(p->reg != NREG)
+                               p->from.type = TYPE_REG;
+                               if(p->reg != 0)
                                        p->from.reg = p->reg;
                                else
                                        p->from.reg = p->to.reg;
-                               p->reg = NREG;
+                               p->reg = 0;
                        }
                        break;
                }
@@ -159,10 +162,10 @@ loop1:
                case AMOVB:
                case AMOVBS:
                case AMOVBU:
-                       if(p->from.type == D_OREG && p->from.offset == 0)
+                       if(p->from.type == TYPE_MEM && p->from.offset == 0)
                                xtramodes(g, r, &p->from);
                        else
-                       if(p->to.type == D_OREG && p->to.offset == 0)
+                       if(p->to.type == TYPE_MEM && p->to.offset == 0)
                                xtramodes(g, r, &p->to);
                        else
                                continue;
@@ -205,17 +208,17 @@ loop1:
 //                     if(r1 == nil)
 //                             continue;
 //                     p1 = r1->prog;
-//                     if(p1->to.type != D_REG)
+//                     if(p1->to.type != TYPE_REG)
 //                             continue;
 //                     if(p1->to.reg != p->reg)
-//                     if(!(p1->as == AMOVW && p1->from.type == D_REG && p1->from.reg == p->reg))
+//                     if(!(p1->as == AMOVW && p1->from.type == TYPE_REG && p1->from.reg == p->reg))
 //                             continue;
 //
 //                     switch(p1->as) {
 //                     default:
 //                             continue;
 //                     case AMOVW:
-//                             if(p1->from.type != D_REG)
+//                             if(p1->from.type != TYPE_REG)
 //                                     continue;
 //                     case AAND:
 //                     case AEOR:
@@ -245,12 +248,7 @@ loop1:
 int
 regtyp(Adr *a)
 {
-
-       if(a->type == D_REG)
-               return 1;
-       if(a->type == D_FREG)
-               return 1;
-       return 0;
+       return a->type == TYPE_REG && (REG_R0 <= a->reg && a->reg <= REG_R15 || REG_F0 <= a->reg && a->reg <= REG_F15);
 }
 
 /*
@@ -293,7 +291,7 @@ subprop(Flow *r0)
                if(info.flags & Call)
                        return 0;
 
-               if((info.flags & CanRegRead) && p->to.type == D_REG) {
+               if((info.flags & CanRegRead) && p->to.type == TYPE_REG) {
                        info.flags |= RegRead;
                        info.flags &= ~(CanRegRead | RightRead);
                        p->reg = p->to.reg;
@@ -575,12 +573,12 @@ shiftprop(Flow *r)
        Adr a;
 
        p = r->prog;
-       if(p->to.type != D_REG)
+       if(p->to.type != TYPE_REG)
                FAIL("BOTCH: result not reg");
        n = p->to.reg;
        a = zprog.from;
-       if(p->reg != NREG && p->reg != p->to.reg) {
-               a.type = D_REG;
+       if(p->reg != 0 && p->reg != p->to.reg) {
+               a.type = TYPE_REG;
                a.reg = p->reg;
        }
        if(debug['P'])
@@ -598,8 +596,8 @@ shiftprop(Flow *r)
                        print("\n%P", p1);
                switch(copyu(p1, &p->to, nil)) {
                case 0: /* not used or set */
-                       if((p->from.type == D_REG && copyu(p1, &p->from, nil) > 1) ||
-                          (a.type == D_REG && copyu(p1, &a, nil) > 1))
+                       if((p->from.type == TYPE_REG && copyu(p1, &p->from, nil) > 1) ||
+                          (a.type == TYPE_REG && copyu(p1, &a, nil) > 1))
                                FAIL("args modified");
                        continue;
                case 3: /* set, not used */
@@ -620,8 +618,8 @@ shiftprop(Flow *r)
        case ASBC:
        case ARSB:
        case ARSC:
-               if(p1->reg == n || (p1->reg == NREG && p1->to.type == D_REG && p1->to.reg == n)) {
-                       if(p1->from.type != D_REG)
+               if(p1->reg == n || (p1->reg == 0 && p1->to.type == TYPE_REG && p1->to.reg == n)) {
+                       if(p1->from.type != TYPE_REG)
                                FAIL("can't swap");
                        p1->reg = p1->from.reg;
                        p1->from.reg = n;
@@ -648,12 +646,12 @@ shiftprop(Flow *r)
        case ACMN:
                if(p1->reg == n)
                        FAIL("can't swap");
-               if(p1->reg == NREG && p1->to.reg == n)
+               if(p1->reg == 0 && p1->to.reg == n)
                        FAIL("shift result used twice");
 //     case AMVN:
-               if(p1->from.type == D_SHIFT)
+               if(p1->from.type == TYPE_SHIFT)
                        FAIL("shift result used in shift");
-               if(p1->from.type != D_REG || p1->from.reg != n)
+               if(p1->from.type != TYPE_REG || p1->from.reg != n)
                        FAIL("BOTCH: where is it used?");
                break;
        }
@@ -679,18 +677,19 @@ shiftprop(Flow *r)
        }
 
        /* make the substitution */
-       p2->from.type = D_SHIFT;
-       p2->from.reg = NREG;
+       p2->from.type = TYPE_SHIFT;
+       p2->from.reg = 0;
        o = p->reg;
-       if(o == NREG)
+       if(o == 0)
                o = p->to.reg;
+       o &= 15;
 
        switch(p->from.type){
-       case D_CONST:
+       case TYPE_CONST:
                o |= (p->from.offset&0x1f)<<7;
                break;
-       case D_REG:
-               o |= (1<<4) | (p->from.reg<<8);
+       case TYPE_REG:
+               o |= (1<<4) | ((p->from.reg&15)<<8);
                break;
        }
        switch(p->as){
@@ -774,16 +773,16 @@ nochange(Flow *r, Flow *r2, Prog *p)
        if(r == r2)
                return 1;
        n = 0;
-       if(p->reg != NREG && p->reg != p->to.reg) {
-               a[n].type = D_REG;
+       if(p->reg != 0 && p->reg != p->to.reg) {
+               a[n].type = TYPE_REG;
                a[n++].reg = p->reg;
        }
        switch(p->from.type) {
-       case D_SHIFT:
-               a[n].type = D_REG;
-               a[n++].reg = p->from.offset&0xf;
-       case D_REG:
-               a[n].type = D_REG;
+       case TYPE_SHIFT:
+               a[n].type = TYPE_REG;
+               a[n++].reg = REG_R0 + (p->from.offset&0xf);
+       case TYPE_REG:
+               a[n].type = TYPE_REG;
                a[n++].reg = p->from.reg;
        }
        if(n == 0)
@@ -851,55 +850,55 @@ xtramodes(Graph *g, Flow *r, Adr *a)
 
        p = r->prog;
        v = *a;
-       v.type = D_REG;
+       v.type = TYPE_REG;
        r1 = findpre(r, &v);
        if(r1 != nil) {
                p1 = r1->prog;
-               if(p1->to.type == D_REG && p1->to.reg == v.reg)
+               if(p1->to.type == TYPE_REG && p1->to.reg == v.reg)
                switch(p1->as) {
                case AADD:
                        if(p1->scond & C_SBIT)
                                // avoid altering ADD.S/ADC sequences.
                                break;
-                       if(p1->from.type == D_REG ||
-                          (p1->from.type == D_SHIFT && (p1->from.offset&(1<<4)) == 0 &&
+                       if(p1->from.type == TYPE_REG ||
+                          (p1->from.type == TYPE_SHIFT && (p1->from.offset&(1<<4)) == 0 &&
                            ((p->as != AMOVB && p->as != AMOVBS) || (a == &p->from && (p1->from.offset&~0xf) == 0))) ||
-                          (p1->from.type == D_CONST &&
+                          (p1->from.type == TYPE_CONST &&
                            p1->from.offset > -4096 && p1->from.offset < 4096))
                        if(nochange(uniqs(r1), r, p1)) {
                                if(a != &p->from || v.reg != p->to.reg)
                                if (finduse(g, r->s1, &v)) {
-                                       if(p1->reg == NREG || p1->reg == v.reg)
+                                       if(p1->reg == 0 || p1->reg == v.reg)
                                                /* pre-indexing */
                                                p->scond |= C_WBIT;
                                        else return 0;
                                }
                                switch (p1->from.type) {
-                               case D_REG:
+                               case TYPE_REG:
                                        /* register offset */
                                        if(nacl)
                                                return 0;
-                                       a->type = D_SHIFT;
-                                       a->offset = p1->from.reg;
+                                       a->type = TYPE_SHIFT;
+                                       a->offset = p1->from.reg&15;
                                        break;
-                               case D_SHIFT:
+                               case TYPE_SHIFT:
                                        /* scaled register offset */
                                        if(nacl)
                                                return 0;
-                                       a->type = D_SHIFT;
-                               case D_CONST:
+                                       a->type = TYPE_SHIFT;
+                               case TYPE_CONST:
                                        /* immediate offset */
                                        a->offset = p1->from.offset;
                                        break;
                                }
-                               if(p1->reg != NREG)
+                               if(p1->reg != 0)
                                        a->reg = p1->reg;
                                excise(r1);
                                return 1;
                        }
                        break;
                case AMOVW:
-                       if(p1->from.type == D_REG)
+                       if(p1->from.type == TYPE_REG)
                        if((r2 = findinc(r1, r, &p1->from)) != nil) {
                        for(r3=uniqs(r2); r3->prog->as==ANOP; r3=uniqs(r3))
                                ;
@@ -948,9 +947,9 @@ copyu(Prog *p, Adr *v, Adr *s)
                return 2;
 
        case AMOVM:
-               if(v->type != D_REG)
+               if(v->type != TYPE_REG)
                        return 0;
-               if(p->from.type == D_CONST) {   /* read reglist, read/rar */
+               if(p->from.type == TYPE_CONST) {        /* read reglist, read/rar */
                        if(s != nil) {
                                if(p->from.offset&(1<<v->reg))
                                        return 1;
@@ -1002,8 +1001,8 @@ copyu(Prog *p, Adr *v, Adr *s)
        case AMOVFD:
        case AMOVDF:
                if(p->scond&(C_WBIT|C_PBIT))
-               if(v->type == D_REG) {
-                       if(p->from.type == D_OREG || p->from.type == D_SHIFT) {
+               if(v->type == TYPE_REG) {
+                       if(p->from.type == TYPE_MEM || p->from.type == TYPE_SHIFT) {
                                if(p->from.reg == v->reg)
                                        return 2;
                        } else {
@@ -1084,7 +1083,7 @@ copyu(Prog *p, Adr *v, Adr *s)
                if(copyas(&p->to, v)) {
                        if(p->scond != C_SCOND_NONE)
                                return 2;
-                       if(p->reg == NREG)
+                       if(p->reg == 0)
                                p->reg = p->to.reg;
                        if(copyau(&p->from, v))
                                return 4;
@@ -1143,16 +1142,20 @@ copyu(Prog *p, Adr *v, Adr *s)
                return 3;
 
        case ABL:       /* funny */
-               if(v->type == D_REG) {
-                       if(v->reg <= REGEXT && v->reg > exregoffset)
+               if(v->type == TYPE_REG) {
+                       // TODO(rsc): REG_R0 and REG_F0 used to be
+                       // (when register numbers started at 0) exregoffset and exfregoffset,
+                       // which are unset entirely. 
+                       // It's strange that this handles R0 and F0 differently from the other
+                       // registers. Possible failure to optimize?
+                       if(REG_R0 < v->reg && v->reg <= REGEXT)
                                return 2;
                        if(v->reg == REGARG)
                                return 2;
-               }
-               if(v->type == D_FREG)
-                       if(v->reg <= FREGEXT && v->reg > exfregoffset)
+                       if(REG_F0 < v->reg && v->reg <= FREGEXT)
                                return 2;
-               if(p->from.type == D_REG && v->type == D_REG && p->from.reg == v->reg)
+               }
+               if(p->from.type == TYPE_REG && v->type == TYPE_REG && p->from.reg == v->reg)
                        return 2;
 
                if(s != nil) {
@@ -1166,7 +1169,7 @@ copyu(Prog *p, Adr *v, Adr *s)
        case ADUFFZERO:
                // R0 is zero, used by DUFFZERO, cannot be substituted.
                // R1 is ptr to memory, used and set, cannot be substituted.
-               if(v->type == D_REG) {
+               if(v->type == TYPE_REG) {
                        if(v->reg == REGALLOC_R0)
                                return 1;
                        if(v->reg == REGALLOC_R0+1)
@@ -1176,7 +1179,7 @@ copyu(Prog *p, Adr *v, Adr *s)
        case ADUFFCOPY:
                // R0 is scratch, set by DUFFCOPY, cannot be substituted.
                // R1, R2 areptr to src, dst, used and set, cannot be substituted.
-               if(v->type == D_REG) {
+               if(v->type == TYPE_REG) {
                        if(v->reg == REGALLOC_R0)
                                return 3;
                        if(v->reg == REGALLOC_R0+1 || v->reg == REGALLOC_R0+2)
@@ -1185,7 +1188,7 @@ copyu(Prog *p, Adr *v, Adr *s)
                return 0;
                        
        case ATEXT:     /* funny */
-               if(v->type == D_REG)
+               if(v->type == TYPE_REG)
                        if(v->reg == REGARG)
                                return 3;
                return 0;
@@ -1212,7 +1215,7 @@ copyas(Adr *a, Adr *v)
                if(a->reg == v->reg)
                        return 1;
        } else
-       if(v->type == D_CONST) {                /* for constprop */
+       if(v->type == TYPE_CONST) {             /* for constprop */
                if(a->type == v->type)
                if(a->name == v->name)
                if(a->sym == v->sym)
@@ -1230,10 +1233,11 @@ sameaddr(Adr *a, Adr *v)
                return 0;
        if(regtyp(v) && a->reg == v->reg)
                return 1;
-       if(v->type == D_AUTO || v->type == D_PARAM) {
-               if(v->offset == a->offset)
-                       return 1;
-       }
+       // TODO(rsc): Change v->type to v->name and enable.
+       //if(v->type == NAME_AUTO || v->type == NAME_PARAM) {
+       //      if(v->offset == a->offset)
+       //              return 1;
+       //}
        return 0;
 }
 
@@ -1246,94 +1250,31 @@ copyau(Adr *a, Adr *v)
 
        if(copyas(a, v))
                return 1;
-       if(v->type == D_REG) {
-               if(a->type == D_CONST && a->reg != NREG) {
+       if(v->type == TYPE_REG) {
+               if(a->type == TYPE_CONST && a->reg != 0) {
                        if(a->reg == v->reg)
                                return 1;
                } else
-               if(a->type == D_OREG) {
+               if(a->type == TYPE_MEM) {
                        if(a->reg == v->reg)
                                return 1;
                } else
-               if(a->type == D_REGREG || a->type == D_REGREG2) {
+               if(a->type == TYPE_REGREG || a->type == TYPE_REGREG2) {
                        if(a->reg == v->reg)
                                return 1;
                        if(a->offset == v->reg)
                                return 1;
                } else
-               if(a->type == D_SHIFT) {
-                       if((a->offset&0xf) == v->reg)
+               if(a->type == TYPE_SHIFT) {
+                       if((a->offset&0xf) == v->reg - REG_R0)
                                return 1;
-                       if((a->offset&(1<<4)) && (a->offset>>8) == v->reg)
+                       if((a->offset&(1<<4)) && ((a->offset>>8)&0xf) == v->reg - REG_R0)
                                return 1;
                }
        }
        return 0;
 }
 
-static int
-a2type(Prog *p)
-{
-       if(p->reg == NREG)
-               return D_NONE;
-
-       switch(p->as) {
-       default:
-               fatal("a2type: unhandled %P", p);
-
-       case AAND:
-       case AEOR:
-       case ASUB:
-       case ARSB:
-       case AADD:
-       case AADC:
-       case ASBC:
-       case ARSC:
-       case ATST:
-       case ATEQ:
-       case ACMP:
-       case ACMN:
-       case AORR:
-       case ABIC:
-       case AMVN:
-       case ASRL:
-       case ASRA:
-       case ASLL:
-       case AMULU:
-       case ADIVU:
-       case AMUL:
-       case ADIV:
-       case AMOD:
-       case AMODU:
-       case AMULA:
-       case AMULL:
-       case AMULAL:
-       case AMULLU:
-       case AMULALU:
-       case AMULWT:
-       case AMULWB:
-       case AMULAWT:
-       case AMULAWB:
-               return D_REG;
-
-       case ACMPF:
-       case ACMPD:
-       case AADDF:
-       case AADDD:
-       case ASUBF:
-       case ASUBD:
-       case AMULF:
-       case AMULD:
-       case ADIVF:
-       case ADIVD:
-       case ASQRTF:
-       case ASQRTD:
-       case AABSF:
-       case AABSD:
-               return D_FREG;
-       }
-}
-
 /*
  * compare v to the center
  * register in p (p->reg)
@@ -1341,9 +1282,9 @@ a2type(Prog *p)
 static int
 copyau1(Prog *p, Adr *v)
 {
-       if(v->type == D_REG && v->reg == NREG)
+       if(v->type == TYPE_REG && v->reg == 0)
                return 0;
-       return p->reg == v->reg && a2type(p) == v->type;
+       return p->reg == v->reg;
 }
 
 /*
@@ -1356,13 +1297,13 @@ copysub(Adr *a, Adr *v, Adr *s, int f)
 
        if(f)
        if(copyau(a, v)) {
-               if(a->type == D_SHIFT) {
-                       if((a->offset&0xf) == v->reg)
-                               a->offset = (a->offset&~0xf)|s->reg;
-                       if((a->offset&(1<<4)) && (a->offset>>8) == v->reg)
-                               a->offset = (a->offset&~(0xf<<8))|(s->reg<<8);
+               if(a->type == TYPE_SHIFT) {
+                       if((a->offset&0xf) == v->reg - REG_R0)
+                               a->offset = (a->offset&~0xf)|(s->reg&0xf);
+                       if((a->offset&(1<<4)) && ((a->offset>>8)&0xf) == v->reg - REG_R0)
+                               a->offset = (a->offset&~(0xf<<8))|((s->reg&0xf)<<8);
                } else
-               if(a->type == D_REGREG || a->type == D_REGREG2) {
+               if(a->type == TYPE_REGREG || a->type == TYPE_REGREG2) {
                        if(a->offset == v->reg)
                                a->offset = s->reg;
                        if(a->reg == v->reg)
@@ -1609,11 +1550,17 @@ predicate(Graph *g)
 static int
 isdconst(Addr *a)
 {
-       if(a->type == D_CONST && a->reg == NREG)
+       if(a->type == TYPE_CONST && a->reg == 0)
                return 1;
        return 0;
 }
 
+static int
+isfloatreg(Addr *a)
+{
+       return REG_F0 <= a->reg && a->reg <= REG_F15;
+}
+
 int
 stackaddr(Addr *a)
 {
@@ -1623,7 +1570,7 @@ stackaddr(Addr *a)
 int
 smallindir(Addr *a, Addr *reg)
 {
-       return reg->type == D_REG && a->type == D_OREG &&
+       return reg->type == TYPE_REG && a->type == TYPE_MEM &&
                a->reg == reg->reg &&
                0 <= a->offset && a->offset < 4096;
 }
index 797bc0718ed18147ea1dfb1f42f5f332af5e4624..ab771481fcdb74ff24ff57307eca642dae9ec804 100644 (file)
@@ -136,12 +136,12 @@ proginfo(ProgInfo *info, Prog *p)
        if(info->flags == 0)
                fatal("unknown instruction %P", p);
 
-       if(p->from.type == D_CONST && p->from.sym != nil && (info->flags & LeftRead)) {
+       if(p->from.type == TYPE_CONST && p->from.sym != nil && (info->flags & LeftRead)) {
                info->flags &= ~LeftRead;
                info->flags |= LeftAddr;
        }
 
-       if((info->flags & RegRead) && p->reg == NREG) {
+       if((info->flags & RegRead) && p->reg == 0) {
                info->flags &= ~RegRead;
                info->flags |= CanRegRead | RightRead;
        }
index 49f87af84d28bbf859ccb2acb27504bb78ea4443..04ea2c202d5a629d552e06fcb67d50940ddcaad6 100644 (file)
@@ -67,11 +67,7 @@ excise(Flow *r)
        Prog *p;
 
        p = r->prog;
-       p->as = ANOP;
-       p->scond = zprog.scond;
-       p->from = zprog.from;
-       p->to = zprog.to;
-       p->reg = zprog.reg;
+       nopout(p);
 }
 
 static void
@@ -199,7 +195,7 @@ regopt(Prog *firstp)
                proginfo(&info, p);
 
                // Avoid making variables for direct-called functions.
-               if(p->as == ABL && p->to.name == D_EXTERN)
+               if(p->as == ABL && p->to.name == NAME_EXTERN)
                        continue;
 
                bit = mkvar(r, &p->from);
@@ -209,12 +205,8 @@ regopt(Prog *firstp)
                if(info.flags & LeftAddr)
                        setaddrs(bit);
 
-               if(info.flags & RegRead) {      
-                       if(p->from.type != D_FREG)
-                               r->use1.b[0] |= RtoB(p->reg);
-                       else
-                               r->use1.b[0] |= FtoB(p->reg);
-               }
+               if(info.flags & RegRead)        
+                       r->use1.b[0] |= RtoB(p->reg);
 
                if(info.flags & (RightAddr | RightRead | RightWrite)) {
                        bit = mkvar(r, &p->to);
@@ -230,7 +222,7 @@ regopt(Prog *firstp)
 
                /* the mod/div runtime routines smash R12 */
                if(p->as == ADIV || p->as == ADIVU || p->as == AMOD || p->as == AMODU)
-                       r->set.b[0] |= RtoB(12);
+                       r->set.b[0] |= RtoB(REG_R12);
        }
        if(firstr == R)
                return;
@@ -463,18 +455,11 @@ brk:
                vreg = paint2(rgp->enter, rgp->varno, 0);
                vreg = allreg(vreg, rgp);
                if(debug['R']) {
-                       if(rgp->regno >= NREG)
-                               print("%L $%d F%d: %Q\n",
-                                       rgp->enter->f.prog->lineno,
-                                       rgp->cost,
-                                       rgp->regno-NREG,
-                                       bit);
-                       else
-                               print("%L $%d R%d: %Q\n",
-                                       rgp->enter->f.prog->lineno,
-                                       rgp->cost,
-                                       rgp->regno,
-                                       bit);
+                       print("%L $%d %R: %Q\n",
+                               rgp->enter->f.prog->lineno,
+                               rgp->cost,
+                               rgp->regno,
+                               bit);
                }
                if(rgp->regno != 0)
                        paint3(rgp->enter, rgp->varno, vreg, rgp->regno);
@@ -529,7 +514,7 @@ brk:
        for(p = firstp; p != P; p = p->link) {
                while(p->link != P && p->link->as == ANOP)
                        p->link = p->link->link;
-               if(p->to.type == D_BRANCH)
+               if(p->to.type == TYPE_BRANCH)
                        while(p->to.u.branch != P && p->to.u.branch->as == ANOP)
                                p->to.u.branch = p->to.u.branch->link;
                if(p->as == AMOVW && p->to.reg == 13) {
@@ -538,7 +523,7 @@ brk:
 //                             print("%P adjusting %d\n", p, vreg);
                                continue;
                        }
-                       if(p->from.type == D_CONST && p->to.type == D_REG) {
+                       if(p->from.type == TYPE_CONST && p->to.type == TYPE_REG) {
                                if(p->from.offset != vreg)
                                        print("in and out different\n");
 //                             print("%P finish %d\n", p, vreg);
@@ -546,18 +531,18 @@ brk:
                                continue;
                        }
 
-//                     print("%P %d %d from type\n", p, p->from.type, D_CONST);
-//                     print("%P %d %d to type\n\n", p, p->to.type, D_REG);
+//                     print("%P %d %d from type\n", p, p->from.type, TYPE_CONST);
+//                     print("%P %d %d to type\n\n", p, p->to.type, TYPE_REG);
                }
 
                if(p->as == AMOVW && vreg != 0) {
                        if(p->from.sym != nil)
-                       if(p->from.name == D_AUTO || p->from.name == D_PARAM) {
+                       if(p->from.name == NAME_AUTO || p->from.name == NAME_PARAM) {
                                p->from.offset += vreg;
 //                             print("%P adjusting from %d %d\n", p, vreg, p->from.type);
                        }
                        if(p->to.sym != nil)
-                       if(p->to.name == D_AUTO || p->to.name == D_PARAM) {
+                       if(p->to.name == NAME_AUTO || p->to.name == NAME_PARAM) {
                                p->to.offset += vreg;
 //                             print("%P adjusting to %d %d\n", p, vreg, p->from.type);
                        }
@@ -640,7 +625,7 @@ addmove(Reg *r, int bn, int rn, int f)
        // If there's a stack fixup coming (after BL newproc or BL deferproc),
        // delay the load until after the fixup.
        p2 = p->link;
-       if(p2 && p2->as == AMOVW && p2->from.type == D_CONST && p2->from.reg == REGSP && p2->to.reg == REGSP && p2->to.type == D_REG)
+       if(p2 && p2->as == AMOVW && p2->from.type == TYPE_CONST && p2->from.reg == REGSP && p2->to.reg == REGSP && p2->to.type == TYPE_REG)
                p = p2;
 
        p1->link = p->link;
@@ -655,9 +640,9 @@ addmove(Reg *r, int bn, int rn, int f)
        a->sym = linksym(v->node->sym);
        a->offset = v->offset;
        a->etype = v->etype;
-       a->type = D_OREG;
+       a->type = TYPE_MEM;
        if(a->etype == TARRAY || a->sym == nil)
-               a->type = D_CONST;
+               a->type = TYPE_CONST;
 
        if(v->addr)
                fatal("addmove: shouldn't be doing this %A\n", a);
@@ -693,21 +678,13 @@ addmove(Reg *r, int bn, int rn, int f)
                break;
        }
 
-       p1->from.type = D_REG;
+       p1->from.type = TYPE_REG;
        p1->from.reg = rn;
-       if(rn >= NREG) {
-               p1->from.type = D_FREG;
-               p1->from.reg = rn-NREG;
-       }
        if(!f) {
                p1->from = *a;
                *a = zprog.from;
-               a->type = D_REG;
+               a->type = TYPE_REG;
                a->reg = rn;
-               if(rn >= NREG) {
-                       a->type = D_FREG;
-                       a->reg = rn-NREG;
-               }
                if(v->etype == TUINT8 || v->etype == TBOOL)
                        p1->as = AMOVBU;
                if(v->etype == TUINT16)
@@ -749,33 +726,33 @@ mkvar(Reg *r, Adr *a)
                print("type %d %d %D\n", t, a->name, a);
                goto none;
 
-       case D_NONE:
-       case D_FCONST:
-       case D_BRANCH:
+       case TYPE_NONE:
+       case TYPE_FCONST:
+       case TYPE_BRANCH:
                break;
 
 
-       case D_REGREG:
-       case D_REGREG2:
+       case TYPE_REGREG:
+       case TYPE_REGREG2:
                bit = zbits;
-               if(a->offset != NREG)
+               if(a->offset != 0)
                        bit.b[0] |= RtoB(a->offset);
-               if(a->reg != NREG)
+               if(a->reg != 0)
                        bit.b[0] |= RtoB(a->reg);
                return bit;
 
-       case D_CONST:
-       case D_REG:
-       case D_SHIFT:
-               if(a->reg != NREG) {
+       case TYPE_CONST:
+       case TYPE_REG:
+       case TYPE_SHIFT:
+               if(a->reg != 0) {
                        bit = zbits;
                        bit.b[0] = RtoB(a->reg);
                        return bit;
                }
                break;
 
-       case D_OREG:
-               if(a->reg != NREG) {
+       case TYPE_MEM:
+               if(a->reg != 0) {
                        if(a == &r->f.prog->from)
                                r->use1.b[0] |= RtoB(a->reg);
                        else
@@ -784,24 +761,16 @@ mkvar(Reg *r, Adr *a)
                                r->set.b[0] |= RtoB(a->reg);
                }
                break;
-
-       case D_FREG:
-               if(a->reg != NREG) {
-                       bit = zbits;
-                       bit.b[0] = FtoB(a->reg);
-                       return bit;
-               }
-               break;
        }
 
        switch(a->name) {
        default:
                goto none;
 
-       case D_EXTERN:
-       case D_STATIC:
-       case D_AUTO:
-       case D_PARAM:
+       case NAME_EXTERN:
+       case NAME_STATIC:
+       case NAME_AUTO:
+       case NAME_PARAM:
                n = a->name;
                break;
        }
@@ -878,10 +847,10 @@ mkvar(Reg *r, Adr *a)
        node->opt = v;
        
        bit = blsh(i);
-       if(n == D_EXTERN || n == D_STATIC)
+       if(n == NAME_EXTERN || n == NAME_STATIC)
                for(z=0; z<BITS; z++)
                        externs.b[z] |= bit.b[z];
-       if(n == D_PARAM)
+       if(n == NAME_PARAM)
                for(z=0; z<BITS; z++)
                        params.b[z] |= bit.b[z];
 
@@ -1103,8 +1072,8 @@ allreg(uint32 b, Rgn *r)
        case TFLOAT64:
                i = BtoF(~b);
                if(i && r->cost >= 0) {
-                       r->regno = i+NREG;
-                       return FtoB(i);
+                       r->regno = i;
+                       return RtoB(i);
                }
                break;
 
@@ -1329,13 +1298,9 @@ addreg(Adr *a, int rn)
 {
        a->sym = nil;
        a->node = nil;
-       a->name = D_NONE;
-       a->type = D_REG;
+       a->name = NAME_NONE;
+       a->type = TYPE_REG;
        a->reg = rn;
-       if(rn >= NREG) {
-               a->type = D_FREG;
-               a->reg = rn-NREG;
-       }
 }
 
 /*
@@ -1345,13 +1310,29 @@ addreg(Adr *a, int rn)
  *     ...     ...
  *     10      R10
  *     12  R12
+ *
+ *     bit     reg
+ *     18      F2
+ *     19      F3
+ *     ...     ...
+ *     31      F15
  */
 uint32
 RtoB(int r)
 {
-       if(r >= REGTMP-2 && r != 12)    // excluded R9 and R10 for m and g, but not R12
-               return 0;
-       return 1L << r;
+       if(REG_R0 <= r && r <= REG_R15) {
+               if(r >= REGTMP-2 && r != REG_R12)       // excluded R9 and R10 for m and g, but not R12
+                       return 0;
+               return 1L << (r - REG_R0);
+       }
+       
+       if(REG_F0 <= r && r <= REG_F15) {
+               if(r < REG_F2 || r > REG_F0+NFREG-1)
+                       return 0;
+               return 1L << ((r - REG_F0) + 16);
+       }
+       
+       return 0;
 }
 
 int
@@ -1362,33 +1343,16 @@ BtoR(uint32 b)
        b &= 0x11fcL;   // excluded R9 and R10 for m and g, but not R12
        if(b == 0)
                return 0;
-       return bitno(b);
-}
-
-/*
- *     bit     reg
- *     18      F2
- *     19      F3
- *     ...     ...
- *     31      F15
- */
-uint32
-FtoB(int f)
-{
-
-       if(f < 2 || f > NFREG-1)
-               return 0;
-       return 1L << (f + 16);
+       return bitno(b) + REG_R0;
 }
 
 int
 BtoF(uint32 b)
 {
-
        b &= 0xfffc0000L;
        if(b == 0)
                return 0;
-       return bitno(b) - 16;
+       return bitno(b) - 16 + REG_F0;
 }
 
 void
index 38a33db6429dd7f3503d7b07fb65ba614bbdc48c..ba738eeb63902cdcc8d743596b87a7d974182969 100644 (file)
@@ -42,24 +42,64 @@ enum
 
 enum
 {
-       REGRET = 0,
+       REG_R0 = 32, // must be 16-aligned
+       REG_R1,
+       REG_R2,
+       REG_R3,
+       REG_R4,
+       REG_R5,
+       REG_R6,
+       REG_R7,
+       REG_R8,
+       REG_R9,
+       REG_R10,
+       REG_R11,
+       REG_R12,
+       REG_R13,
+       REG_R14,
+       REG_R15,
+       
+       REG_F0, // must be 16-aligned
+       REG_F1,
+       REG_F2,
+       REG_F3,
+       REG_F4,
+       REG_F5,
+       REG_F6,
+       REG_F7,
+       REG_F8,
+       REG_F9,
+       REG_F10,
+       REG_F11,
+       REG_F12,
+       REG_F13,
+       REG_F14,
+       REG_F15,
+
+       REG_FPSR, // must be 2-aligned
+       REG_FPCR,
+
+       REG_CPSR, // must be 2-aligned
+       REG_SPSR,
+
+       REGRET = REG_R0,
        /* compiler allocates R1 up as temps */
        /* compiler allocates register variables R3 up */
        /* compiler allocates external registers R10 down */
-       REGEXT = 10,
+       REGEXT = REG_R10,
        /* these two registers are declared in runtime.h */
        REGG = REGEXT-0,
        REGM = REGEXT-1,
 
-       REGTMP = 11,
-       REGSP = 13,
-       REGLINK = 14,
-       REGPC = 15,
+       REGTMP = REG_R11,
+       REGSP = REG_R13,
+       REGLINK = REG_R14,
+       REGPC = REG_R15,
        
        NFREG = 16,
-       FREGRET = 0,
-       FREGEXT = 7,
-       FREGTMP = 15,
+       FREGRET = REG_F0,
+       FREGEXT = REG_F7,
+       FREGTMP = REG_F15,
 };
 /* compiler allocates register variables F0 up */
 /* compiler allocates external registers F7 down */
@@ -304,43 +344,6 @@ enum
        SHIFT_RR = 3<<5,
 };
 
-enum
-{
-/* type/name */
-       D_GOK = 0,
-       D_NONE = 1,
-
-/* type */
-       D_BRANCH = (D_NONE+1),
-       D_OREG = (D_NONE+2),
-       D_CONST = (D_NONE+7),
-       D_FCONST = (D_NONE+8),
-       D_SCONST = (D_NONE+9),
-       D_PSR = (D_NONE+10),
-       D_REG = (D_NONE+12),
-       D_FREG = (D_NONE+13),
-       D_FILE = (D_NONE+16),
-       D_OCONST = (D_NONE+17),
-       D_FILE1 = (D_NONE+18),
-
-       D_SHIFT = (D_NONE+19),
-       D_FPCR = (D_NONE+20),
-       D_REGREG = (D_NONE+21), // (reg, reg)
-       D_ADDR = (D_NONE+22),
-
-       D_SBIG = (D_NONE+23),
-       D_CONST2 = (D_NONE+24),
-
-       D_REGREG2 = (D_NONE+25), // reg, reg
-
-/* name */
-       D_EXTERN = (D_NONE+3),
-       D_STATIC = (D_NONE+4),
-       D_AUTO = (D_NONE+5),
-       D_PARAM = (D_NONE+6),
-
-       D_LAST = (D_NONE+26),
-};
 
 /*
  * this is the ranlib header
index 9d4fe404240e55b968a6d306cf47ed1f0b2c3ce3..35bd458cdf70d58740fe5cd712896710f5719602 100644 (file)
@@ -355,17 +355,6 @@ static     uchar   xcmp[C_GOK+1][C_GOK+1];
 static Prog zprg = {
        .as = AGOK,
        .scond = C_SCOND_NONE,
-       .reg = NREG,
-       .from = {
-               .name = D_NONE,
-               .type = D_NONE,
-               .reg = NREG,
-       },
-       .to = {
-               .name = D_NONE,
-               .type = D_NONE,
-               .reg = NREG,
-       },
 };
 
 static LSym *deferreturn;
@@ -441,20 +430,20 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
                break;
        case AB:
        case ABL:
-               if(p->to.type != D_OREG) {
+               if(p->to.type != TYPE_MEM) {
                        if(out != nil)
                                asmout(ctxt, p, o, out);
                } else {
-                       if(p->to.offset != 0 || size != 4 || p->to.reg >= 16 || p->to.reg < 0)
+                       if(p->to.offset != 0 || size != 4 || p->to.reg > REG_R15 || p->to.reg < REG_R0)
                                ctxt->diag("unsupported instruction: %P", p);
                        if((p->pc&15) == 12)
                                p->pc += 4;
                        if(out != nil) {
-                               out[0] = ((p->scond&C_SCOND)<<28) | 0x03c0013f | (p->to.reg << 12) | (p->to.reg << 16); // BIC $0xc000000f, Rx
+                               out[0] = ((p->scond&C_SCOND)<<28) | 0x03c0013f | ((p->to.reg&15) << 12) | ((p->to.reg&15) << 16); // BIC $0xc000000f, Rx
                                if(p->as == AB)
-                                       out[1] = ((p->scond&C_SCOND)<<28) | 0x012fff10 | p->to.reg; // BX Rx
+                                       out[1] = ((p->scond&C_SCOND)<<28) | 0x012fff10 | (p->to.reg&15)<<0; // BX Rx
                                else // ABL
-                                       out[1] = ((p->scond&C_SCOND)<<28) | 0x012fff30 | p->to.reg; // BLX Rx
+                                       out[1] = ((p->scond&C_SCOND)<<28) | 0x012fff30 | (p->to.reg&15)<<0; // BLX Rx
                        }
                        size = 8;
                }
@@ -482,7 +471,7 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
        case AMOVW:
        case ASTREX:
        case ASTREXD:
-               if(p->to.type == D_REG && p->to.reg == 15 && p->from.reg == 13) { // MOVW.W x(R13), PC
+               if(p->to.type == TYPE_REG && p->to.reg == REG_R15 && p->from.reg == REG_R13) { // MOVW.W x(R13), PC
                        if(out != nil)
                                asmout(ctxt, p, o, out);
                        if(size == 4) {
@@ -514,10 +503,10 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
                        }
                }
 
-               if(p->to.type == D_REG && p->to.reg == 15)
+               if(p->to.type == TYPE_REG && p->to.reg == REG_R15)
                        ctxt->diag("unsupported instruction (move to another register and use indirect jump instead): %P", p);
 
-               if(p->to.type == D_OREG && p->to.reg == 13 && (p->scond & C_WBIT) && size > 4) {
+               if(p->to.type == TYPE_MEM && p->to.reg == REG_R13 && (p->scond & C_WBIT) && size > 4) {
                        // function prolog with very large frame size: MOVW.W R14,-100004(R13)
                        // split it into two instructions:
                        //      ADD $-100004, R13
@@ -526,7 +515,7 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
                        p->scond &= ~C_WBIT;
                        *q = *p;
                        a = &p->to;
-                       if(p->to.type == D_OREG)
+                       if(p->to.type == TYPE_MEM)
                                a2 = &q->to;
                        else
                                a2 = &q->from;
@@ -539,37 +528,37 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
                        // make p into ADD $X, R13
                        p->as = AADD;
                        p->from = *a;
-                       p->from.reg = NREG;
-                       p->from.type = D_CONST;
+                       p->from.reg = 0;
+                       p->from.type = TYPE_CONST;
                        p->to = zprg.to;
-                       p->to.type = D_REG;
-                       p->to.reg = 13;
+                       p->to.type = TYPE_REG;
+                       p->to.reg = REG_R13;
                        // make q into p but load/store from 0(R13)
                        q->spadj = 0;
                        *a2 = zprg.from;
-                       a2->type = D_OREG;
-                       a2->reg = 13;
+                       a2->type = TYPE_MEM;
+                       a2->reg = REG_R13;
                        a2->sym = nil;
                        a2->offset = 0;
                        size = oplook(ctxt, p)->size;
                        break;
                }
 
-               if((p->to.type == D_OREG && p->to.reg != 13 && p->to.reg != 9) || // MOVW Rx, X(Ry), y != 13 && y != 9
-                  (p->from.type == D_OREG && p->from.reg != 13 && p->from.reg != 9)) { // MOVW X(Rx), Ry, x != 13 && x != 9
-                       if(p->to.type == D_OREG)
+               if((p->to.type == TYPE_MEM && p->to.reg != REG_R13 && p->to.reg != REG_R9) || // MOVW Rx, X(Ry), y != 13 && y != 9
+                  (p->from.type == TYPE_MEM && p->from.reg != REG_R13 && p->from.reg != REG_R9)) { // MOVW X(Rx), Ry, x != 13 && x != 9
+                       if(p->to.type == TYPE_MEM)
                                a = &p->to;
                        else
                                a = &p->from;
                        reg = a->reg;
                        if(size == 4) {
-                               // if addr.reg == NREG, then it is probably load from x(FP) with small x, no need to modify.
-                               if(reg == NREG) {
+                               // if addr.reg == 0, then it is probably load from x(FP) with small x, no need to modify.
+                               if(reg == 0) {
                                        if(out != nil)
                                                asmout(ctxt, p, o, out);
                                } else {
                                        if(out != nil)
-                                               out[0] = ((p->scond&C_SCOND)<<28) | 0x03c00103 | (reg << 16) | (reg << 12); // BIC $0xc0000000, Rx
+                                               out[0] = ((p->scond&C_SCOND)<<28) | 0x03c00103 | ((reg&15) << 16) | ((reg&15) << 12); // BIC $0xc0000000, Rx
                                        if((p->pc&15) == 12)
                                                p->pc += 4;
                                        size += 4;
@@ -587,7 +576,7 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
                                        ctxt->diag("unsupported instruction (.P/.W): %P", p);
                                q = ctxt->arch->prg();
                                *q = *p;
-                               if(p->to.type == D_OREG)
+                               if(p->to.type == TYPE_MEM)
                                        a2 = &q->to;
                                else
                                        a2 = &q->from;
@@ -600,14 +589,14 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
                                // make p into MOVW $X(R), R11
                                p->as = AMOVW;
                                p->from = *a;
-                               p->from.type = D_CONST;
+                               p->from.type = TYPE_CONST;
                                p->to = zprg.to;
-                               p->to.type = D_REG;
-                               p->to.reg = 11;
+                               p->to.type = TYPE_REG;
+                               p->to.reg = REG_R11;
                                // make q into p but load/store from 0(R11)
                                *a2 = zprg.from;
-                               a2->type = D_OREG;
-                               a2->reg = 11;
+                               a2->type = TYPE_MEM;
+                               a2->reg = REG_R11;
                                a2->sym = nil;
                                a2->offset = 0;
                                size = oplook(ctxt, p)->size;
@@ -619,12 +608,12 @@ asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, uint32 *out)
        }
 
        // destination register specific
-       if(p->to.type == D_REG) {
+       if(p->to.type == TYPE_REG) {
                switch(p->to.reg) {
-               case 9:
+               case REG_R9:
                        ctxt->diag("invalid instruction, cannot write to R9: %P", p);
                        break;
-               case 13:
+               case REG_R13:
                        if(out != nil)
                                out[size/4] = 0xe3cdd103; // BIC $0xc0000000, R13
                        if(((p->pc+size) & 15) == 0)
@@ -707,7 +696,7 @@ span5(Link *ctxt, LSym *cursym)
                                flushpool(ctxt, p, 0, 0);
                        break;
                }
-               if(p->as==AMOVW && p->to.type==D_REG && p->to.reg==REGPC && (p->scond&C_SCOND) == C_SCOND_NONE)
+               if(p->as==AMOVW && p->to.type==TYPE_REG && p->to.reg==REGPC && (p->scond&C_SCOND) == C_SCOND_NONE)
                        flushpool(ctxt, p, 0, 0);
                c += m;
        }
@@ -742,14 +731,14 @@ span5(Link *ctxt, LSym *cursym)
                                        q->link = p->link;
                                        p->link = q;
                                        q->as = AB;
-                                       q->to.type = D_BRANCH;
+                                       q->to.type = TYPE_BRANCH;
                                        q->pcond = p->pcond;
                                        p->pcond = q;
                                        q = ctxt->arch->prg();
                                        q->link = p->link;
                                        p->link = q;
                                        q->as = AB;
-                                       q->to.type = D_BRANCH;
+                                       q->to.type = TYPE_BRANCH;
                                        q->pcond = q->link->link;
                                        bflag = 1;
                                }
@@ -865,7 +854,7 @@ flushpool(Link *ctxt, Prog *p, int skip, int force)
                        if(0 && skip==1)print("note: flush literal pool at %llux: len=%ud ref=%ux\n", p->pc+4, pool.size, pool.start);
                        q = ctxt->arch->prg();
                        q->as = AB;
-                       q->to.type = D_BRANCH;
+                       q->to.type = TYPE_BRANCH;
                        q->pcond = p->link;
                        q->link = ctxt->blitrl;
                        q->lineno = p->lineno;
@@ -931,7 +920,7 @@ addpool(Link *ctxt, Prog *p, Addr *a)
        case C_SAUTO:
        case C_LAUTO:
        case C_LACON:
-               t.to.type = D_CONST;
+               t.to.type = TYPE_CONST;
                t.to.offset = ctxt->instoffset;
                break;
        }
@@ -1038,31 +1027,33 @@ aclass(Link *ctxt, Addr *a)
        int t;
 
        switch(a->type) {
-       case D_NONE:
+       case TYPE_NONE:
                return C_NONE;
 
-       case D_REG:
-               return C_REG;
+       case TYPE_REG:
+               if(REG_R0 <= a->reg && a->reg <= REG_R15)
+                       return C_REG;
+               if(REG_F0 <= a->reg && a->reg <= REG_F15)
+                       return C_FREG;
+               if(a->reg == REG_FPSR || a->reg == REG_FPCR)
+                       return C_FCR;
+               if(a->reg == REG_CPSR || a->reg == REG_SPSR)
+                       return C_PSR;
+               return C_GOK;
 
-       case D_REGREG:
+       case TYPE_REGREG:
                return C_REGREG;
 
-       case D_REGREG2:
+       case TYPE_REGREG2:
                return C_REGREG2;
 
-       case D_SHIFT:
+       case TYPE_SHIFT:
                return C_SHIFT;
 
-       case D_FREG:
-               return C_FREG;
-
-       case D_FPCR:
-               return C_FCR;
-
-       case D_OREG:
+       case TYPE_MEM:
                switch(a->name) {
-               case D_EXTERN:
-               case D_STATIC:
+               case NAME_EXTERN:
+               case NAME_STATIC:
                        if(a->sym == 0 || a->sym->name == 0) {
                                print("null sym external\n");
                                return C_GOK;
@@ -1070,7 +1061,7 @@ aclass(Link *ctxt, Addr *a)
                        ctxt->instoffset = 0;   // s.b. unused but just in case
                        return C_ADDR;
 
-               case D_AUTO:
+               case NAME_AUTO:
                        ctxt->instoffset = ctxt->autosize + a->offset;
                        t = immaddr(ctxt->instoffset);
                        if(t){
@@ -1085,7 +1076,7 @@ aclass(Link *ctxt, Addr *a)
                        }
                        return C_LAUTO;
 
-               case D_PARAM:
+               case NAME_PARAM:
                        ctxt->instoffset = ctxt->autosize + a->offset + 4L;
                        t = immaddr(ctxt->instoffset);
                        if(t){
@@ -1099,7 +1090,7 @@ aclass(Link *ctxt, Addr *a)
                                return C_SAUTO;
                        }
                        return C_LAUTO;
-               case D_NONE:
+               case TYPE_NONE:
                        ctxt->instoffset = a->offset;
                        t = immaddr(ctxt->instoffset);
                        if(t) {
@@ -1124,32 +1115,20 @@ aclass(Link *ctxt, Addr *a)
                }
                return C_GOK;
 
-       case D_PSR:
-               return C_PSR;
-
-       case D_OCONST:
-               switch(a->name) {
-               case D_EXTERN:
-               case D_STATIC:
-                       ctxt->instoffset = 0;   // s.b. unused but just in case
-                       return C_ADDR;
-               }
-               return C_GOK;
-
-       case D_FCONST:
+       case TYPE_FCONST:
                if(chipzero5(ctxt, a->u.dval) >= 0)
                        return C_ZFCON;
                if(chipfloat5(ctxt, a->u.dval) >= 0)
                        return C_SFCON;
                return C_LFCON;
 
-       case D_CONST:
-       case D_CONST2:
+       case TYPE_CONST:
+       case TYPE_TEXTSIZE:
                switch(a->name) {
 
-               case D_NONE:
+               case TYPE_NONE:
                        ctxt->instoffset = a->offset;
-                       if(a->reg != NREG)
+                       if(a->reg != 0)
                                return aconsize(ctxt);
 
                        t = immrot(ctxt->instoffset);
@@ -1160,25 +1139,25 @@ aclass(Link *ctxt, Addr *a)
                                return C_NCON;
                        return C_LCON;
 
-               case D_EXTERN:
-               case D_STATIC:
+               case NAME_EXTERN:
+               case NAME_STATIC:
                        s = a->sym;
                        if(s == nil)
                                break;
                        ctxt->instoffset = 0;   // s.b. unused but just in case
                        return C_LCONADDR;
 
-               case D_AUTO:
+               case NAME_AUTO:
                        ctxt->instoffset = ctxt->autosize + a->offset;
                        return aconsize(ctxt);
 
-               case D_PARAM:
+               case NAME_PARAM:
                        ctxt->instoffset = ctxt->autosize + a->offset + 4L;
                        return aconsize(ctxt);
                }
                return C_GOK;
 
-       case D_BRANCH:
+       case TYPE_BRANCH:
                return C_SBRA;
        }
        return C_GOK;
@@ -1224,7 +1203,7 @@ oplook(Link *ctxt, Prog *p)
        }
        a3--;
        a2 = C_NONE;
-       if(p->reg != NREG)
+       if(p->reg != 0)
                a2 = C_REG;
        r = p->as;
        o = oprange[r].start;
@@ -1535,14 +1514,14 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                rf = p->from.reg;
                rt = p->to.reg;
                r = p->reg;
-               if(p->to.type == D_NONE)
+               if(p->to.type == TYPE_NONE)
                        rt = 0;
                if(p->as == AMOVB || p->as == AMOVH || p->as == AMOVW || p->as == AMVN)
                        r = 0;
                else
-               if(r == NREG)
+               if(r == 0)
                        r = rt;
-               o1 |= rf | (r<<16) | (rt<<12);
+               o1 |= ((rf&15)<<0) | ((r&15)<<16) | ((rt&15)<<12);
                break;
 
        case 2:         /* movbu $I,[R],R */
@@ -1551,13 +1530,13 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                o1 |= immrot(ctxt->instoffset);
                rt = p->to.reg;
                r = p->reg;
-               if(p->to.type == D_NONE)
+               if(p->to.type == TYPE_NONE)
                        rt = 0;
                if(p->as == AMOVW || p->as == AMVN)
                        r = 0;
-               else if(r == NREG)
+               else if(r == 0)
                        r = rt;
-               o1 |= (r<<16) | (rt<<12);
+               o1 |= ((r&15)<<16) | ((rt&15)<<12);
                break;
 
        case 3:         /* add R<<[IR],[R],R */
@@ -1569,10 +1548,10 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                o1 = oprrr(ctxt, AADD, p->scond);
                o1 |= immrot(ctxt->instoffset);
                r = p->from.reg;
-               if(r == NREG)
+               if(r == 0)
                        r = o->param;
-               o1 |= r << 16;
-               o1 |= p->to.reg << 12;
+               o1 |= (r&15) << 16;
+               o1 |= (p->to.reg&15) << 12;
                break;
 
        case 5:         /* bra s */
@@ -1597,8 +1576,8 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                aclass(ctxt, &p->to);
                o1 = oprrr(ctxt, AADD, p->scond);
                o1 |= immrot(ctxt->instoffset);
-               o1 |= p->to.reg << 16;
-               o1 |= REGPC << 12;
+               o1 |= (p->to.reg&15) << 16;
+               o1 |= (REGPC&15) << 12;
                break;
 
        case 7:         /* bl (R) -> blx R */
@@ -1606,7 +1585,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                if(ctxt->instoffset != 0)
                        ctxt->diag("%P: doesn't support BL offset(REG) where offset != 0", p);
                o1 = oprrr(ctxt, ABL, p->scond);
-               o1 |= p->to.reg;
+               o1 |= (p->to.reg&15) << 0;
                rel = addrel(ctxt->cursym);
                rel->off = ctxt->pc;
                rel->siz = 0;
@@ -1617,26 +1596,26 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                aclass(ctxt, &p->from);
                o1 = oprrr(ctxt, p->as, p->scond);
                r = p->reg;
-               if(r == NREG)
+               if(r == 0)
                        r = p->to.reg;
-               o1 |= r;
+               o1 |= (r&15) << 0;
                o1 |= (ctxt->instoffset&31) << 7;
-               o1 |= p->to.reg << 12;
+               o1 |= (p->to.reg&15) << 12;
                break;
 
        case 9:         /* sll R,[R],R -> mov (R<<R),R */
                o1 = oprrr(ctxt, p->as, p->scond);
                r = p->reg;
-               if(r == NREG)
+               if(r == 0)
                        r = p->to.reg;
-               o1 |= r;
-               o1 |= (p->from.reg << 8) | (1<<4);
-               o1 |= p->to.reg << 12;
+               o1 |= (r&15) << 0;
+               o1 |= ((p->from.reg&15) << 8) | (1<<4);
+               o1 |= (p->to.reg&15) << 12;
                break;
 
        case 10:        /* swi [$con] */
                o1 = oprrr(ctxt, p->as, p->scond);
-               if(p->to.type != D_NONE) {
+               if(p->to.type != TYPE_NONE) {
                        aclass(ctxt, &p->to);
                        o1 |= ctxt->instoffset & 0xffffff;
                }
@@ -1676,7 +1655,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
        case 12:        /* movw $lcon, reg */
                o1 = omvl(ctxt, p, &p->from, p->to.reg);
                if(o->flag & LPCREL) {
-                       o2 = oprrr(ctxt, AADD, p->scond) | p->to.reg | REGPC << 16 | p->to.reg << 12;
+                       o2 = oprrr(ctxt, AADD, p->scond) | (p->to.reg&15) << 0 | (REGPC&15) << 16 | (p->to.reg&15) << 12;
                }
                break;
 
@@ -1685,15 +1664,15 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                if(!o1)
                        break;
                o2 = oprrr(ctxt, p->as, p->scond);
-               o2 |= REGTMP;
+               o2 |= (REGTMP&15);
                r = p->reg;
                if(p->as == AMOVW || p->as == AMVN)
                        r = 0;
-               else if(r == NREG)
+               else if(r == 0)
                        r = p->to.reg;
-               o2 |= r << 16;
-               if(p->to.type != D_NONE)
-                       o2 |= p->to.reg << 12;
+               o2 |= (r&15) << 16;
+               if(p->to.type != TYPE_NONE)
+                       o2 |= (p->to.reg&15) << 12;
                break;
 
        case 14:        /* movb/movbu/movh/movhu R,R */
@@ -1705,8 +1684,8 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                        o2 = oprrr(ctxt, ASRA, p->scond);
 
                r = p->to.reg;
-               o1 |= (p->from.reg)|(r<<12);
-               o2 |= (r)|(r<<12);
+               o1 |= ((p->from.reg&15)<<0)|((r&15)<<12);
+               o2 |= (r&15)|((r&15)<<12);
                if(p->as == AMOVB || p->as == AMOVBS || p->as == AMOVBU) {
                        o1 |= (24<<7);
                        o2 |= (24<<7);
@@ -1721,18 +1700,18 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                rf = p->from.reg;
                rt = p->to.reg;
                r = p->reg;
-               if(r == NREG)
+               if(r == 0)
                        r = rt;
                if(rt == r) {
                        r = rf;
                        rf = rt;
                }
                if(0)
-               if(rt == r || rf == REGPC || r == REGPC || rt == REGPC) {
+               if(rt == r || rf == (REGPC&15) || r == (REGPC&15) || rt == (REGPC&15)) {
                        ctxt->diag("bad registers in MUL");
                        prasm(p);
                }
-               o1 |= (rf<<8) | r | (rt<<16);
+               o1 |= ((rf&15)<<8) | ((r&15)<<0) | ((rt&15)<<16);
                break;
 
 
@@ -1747,13 +1726,13 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                rt = p->to.reg;
                rt2 = p->to.offset;
                r = p->reg;
-               o1 |= (rf<<8) | r | (rt<<16) | (rt2<<12);
+               o1 |= ((rf&15)<<8) | ((r&15)<<0) | ((rt&15)<<16) | ((rt2&15)<<12);
                break;
 
        case 20:        /* mov/movb/movbu R,O(R) */
                aclass(ctxt, &p->to);
                r = p->to.reg;
-               if(r == NREG)
+               if(r == 0)
                        r = o->param;
                o1 = osr(ctxt, p->as, p->from.reg, ctxt->instoffset, r, p->scond);
                break;
@@ -1761,7 +1740,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
        case 21:        /* mov/movbu O(R),R -> lr */
                aclass(ctxt, &p->from);
                r = p->from.reg;
-               if(r == NREG)
+               if(r == 0)
                        r = o->param;
                o1 = olr(ctxt, ctxt->instoffset, r, p->to.reg, p->scond);
                if(p->as != AMOVW)
@@ -1773,9 +1752,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                if(!o1)
                        break;
                r = p->to.reg;
-               if(r == NREG)
+               if(r == 0)
                        r = o->param;
-               o2 = osrr(ctxt, p->from.reg, REGTMP,r, p->scond);
+               o2 = osrr(ctxt, p->from.reg, REGTMP&15, r, p->scond);
                if(p->as != AMOVW)
                        o2 |= 1<<22;
                break;
@@ -1785,9 +1764,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                if(!o1)
                        break;
                r = p->from.reg;
-               if(r == NREG)
+               if(r == 0)
                        r = o->param;
-               o2 = olrr(ctxt, REGTMP,r, p->to.reg, p->scond);
+               o2 = olrr(ctxt, REGTMP&15, r, p->to.reg, p->scond);
                if(p->as == AMOVBU || p->as == AMOVBS || p->as == AMOVB)
                        o2 |= 1<<22;
                break;
@@ -1798,20 +1777,20 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                        break;
 
                o2 = oprrr(ctxt, AADD, p->scond);
-               o2 |= REGTMP;
+               o2 |= (REGTMP&15);
                r = p->from.reg;
-               if(r == NREG)
+               if(r == 0)
                        r = o->param;
-               o2 |= r << 16;
-               if(p->to.type != D_NONE)
-                       o2 |= p->to.reg << 12;
+               o2 |= (r&15) << 16;
+               if(p->to.type != TYPE_NONE)
+                       o2 |= (p->to.reg&15) << 12;
                break;
 
        case 35:        /* mov PSR,R */
                o1 = (2<<23) | (0xf<<16) | (0<<0);
                o1 |= (p->scond & C_SCOND) << 28;
                o1 |= (p->from.reg & 1) << 22;
-               o1 |= p->to.reg << 12;
+               o1 |= (p->to.reg&15) << 12;
                break;
 
        case 36:        /* mov R,PSR */
@@ -1820,7 +1799,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                        o1 ^= 0x010 << 12;
                o1 |= (p->scond & C_SCOND) << 28;
                o1 |= (p->to.reg & 1) << 22;
-               o1 |= p->from.reg << 0;
+               o1 |= (p->from.reg&15) << 0;
                break;
 
        case 37:        /* mov $con,PSR */
@@ -1831,7 +1810,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                o1 |= (p->scond & C_SCOND) << 28;
                o1 |= immrot(ctxt->instoffset);
                o1 |= (p->to.reg & 1) << 22;
-               o1 |= p->from.reg << 0;
+               o1 |= (p->from.reg&15) << 0;
                break;
 
        case 38:
@@ -1840,14 +1819,14 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                case 38:        /* movm $con,oreg -> stm */
                        o1 = (0x4 << 25);
                        o1 |= p->from.offset & 0xffff;
-                       o1 |= p->to.reg << 16;
+                       o1 |= (p->to.reg&15) << 16;
                        aclass(ctxt, &p->to);
                        break;
        
                case 39:        /* movm oreg,$con -> ldm */
                        o1 = (0x4 << 25) | (1 << 20);
                        o1 |= p->to.offset & 0xffff;
-                       o1 |= p->from.reg << 16;
+                       o1 |= (p->from.reg&15) << 16;
                        aclass(ctxt, &p->from);
                        break;
                }
@@ -1871,9 +1850,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                o1 = (0x2<<23) | (0x9<<4);
                if(p->as != ASWPW)
                        o1 |= 1 << 22;
-               o1 |= p->from.reg << 16;
-               o1 |= p->reg << 0;
-               o1 |= p->to.reg << 12;
+               o1 |= (p->from.reg&15) << 16;
+               o1 |= (p->reg&15) << 0;
+               o1 |= (p->to.reg&15) << 12;
                o1 |= (p->scond & C_SCOND) << 28;
                break;
 
@@ -1884,7 +1863,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
        case 50:        /* floating point store */
                v = regoff(ctxt, &p->to);
                r = p->to.reg;
-               if(r == NREG)
+               if(r == 0)
                        r = o->param;
                o1 = ofsr(ctxt, p->as, p->from.reg, v, r, p->scond, p);
                break;
@@ -1892,7 +1871,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
        case 51:        /* floating point load */
                v = regoff(ctxt, &p->from);
                r = p->from.reg;
-               if(r == NREG)
+               if(r == 0)
                        r = o->param;
                o1 = ofsr(ctxt, p->as, p->to.reg, v, r, p->scond, p) | (1<<20);
                break;
@@ -1902,9 +1881,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                if(!o1)
                        break;
                r = p->to.reg;
-               if(r == NREG)
+               if(r == 0)
                        r = o->param;
-               o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP << 12) | (REGTMP << 16) | r;
+               o2 = oprrr(ctxt, AADD, p->scond) | ((REGTMP&15) << 12) | ((REGTMP&15) << 16) | ((r&15) << 0);
                o3 = ofsr(ctxt, p->as, p->from.reg, 0, REGTMP, p->scond, p);
                break;
 
@@ -1913,10 +1892,10 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                if(!o1)
                        break;
                r = p->from.reg;
-               if(r == NREG)
+               if(r == 0)
                        r = o->param;
-               o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP << 12) | (REGTMP << 16) | r;
-               o3 = ofsr(ctxt, p->as, p->to.reg, 0, REGTMP, p->scond, p) | (1<<20);
+               o2 = oprrr(ctxt, AADD, p->scond) | ((REGTMP&15) << 12) | ((REGTMP&15) << 16) | ((r&15) << 0);
+               o3 = ofsr(ctxt, p->as, p->to.reg, 0, (REGTMP&15), p->scond, p) | (1<<20);
                break;
 
        case 54:        /* floating point arith */
@@ -1924,38 +1903,38 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                rf = p->from.reg;
                rt = p->to.reg;
                r = p->reg;
-               if(r == NREG) {
+               if(r == 0) {
                        r = rt;
                        if(p->as == AMOVF || p->as == AMOVD || p->as == AMOVFD || p->as == AMOVDF ||
                                p->as == ASQRTF || p->as == ASQRTD || p->as == AABSF || p->as == AABSD)
                                r = 0;
                }
-               o1 |= rf | (r<<16) | (rt<<12);
+               o1 |= ((rf&15)<<0) | ((r&15)<<16) | ((rt&15)<<12);
                break;
 
        case 56:        /* move to FP[CS]R */
                o1 = ((p->scond & C_SCOND) << 28) | (0xe << 24) | (1<<8) | (1<<4);
-               o1 |= ((p->to.reg+1)<<21) | (p->from.reg << 12);
+               o1 |= (((p->to.reg&1)+1)<<21) | ((p->from.reg&15) << 12);
                break;
 
        case 57:        /* move from FP[CS]R */
                o1 = ((p->scond & C_SCOND) << 28) | (0xe << 24) | (1<<8) | (1<<4);
-               o1 |= ((p->from.reg+1)<<21) | (p->to.reg<<12) | (1<<20);
+               o1 |= (((p->from.reg&1)+1)<<21) | ((p->to.reg&15)<<12) | (1<<20);
                break;
        case 58:        /* movbu R,R */
                o1 = oprrr(ctxt, AAND, p->scond);
                o1 |= immrot(0xff);
                rt = p->to.reg;
                r = p->from.reg;
-               if(p->to.type == D_NONE)
+               if(p->to.type == TYPE_NONE)
                        rt = 0;
-               if(r == NREG)
+               if(r == 0)
                        r = rt;
-               o1 |= (r<<16) | (rt<<12);
+               o1 |= ((r&15)<<16) | ((rt&15)<<12);
                break;
 
        case 59:        /* movw/bu R<<I(R),R -> ldr indexed */
-               if(p->from.reg == NREG) {
+               if(p->from.reg == 0) {
                        if(p->as != AMOVW)
                                ctxt->diag("byte MOV from shifter operand");
                        o1 = mov(ctxt, p);
@@ -1969,7 +1948,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                break;
 
        case 60:        /* movb R(R),R -> ldrsb indexed */
-               if(p->from.reg == NREG) {
+               if(p->from.reg == 0) {
                        ctxt->diag("byte MOV from shifter operand");
                        o1 = mov(ctxt, p);
                        break;
@@ -1981,7 +1960,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                break;
 
        case 61:        /* movw/b/bu R,R<<[IR](R) -> str indexed */
-               if(p->to.reg == NREG)
+               if(p->to.reg == 0)
                        ctxt->diag("MOV to shifter operand");
                o1 = osrr(ctxt, p->from.reg, p->to.offset, p->to.reg, p->scond);
                if(p->as == AMOVB || p->as == AMOVBS || p->as == AMOVBU)
@@ -1990,12 +1969,12 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
 
        case 62:        /* case R -> movw       R<<2(PC),PC */
                if(o->flag & LPCREL) {
-                       o1 = oprrr(ctxt, AADD, p->scond) | immrot(1) | p->from.reg << 16 | REGTMP << 12;
-                       o2 = olrr(ctxt, REGTMP, REGPC, REGTMP, p->scond);
+                       o1 = oprrr(ctxt, AADD, p->scond) | immrot(1) | (p->from.reg&15) << 16 | (REGTMP&15) << 12;
+                       o2 = olrr(ctxt, REGTMP&15, REGPC, REGTMP, p->scond);
                        o2 |= 2<<7;
-                       o3 = oprrr(ctxt, AADD, p->scond) | REGTMP | REGPC << 16 | REGPC << 12;
+                       o3 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGPC&15) << 12;
                } else {
-                       o1 = olrr(ctxt, p->from.reg, REGPC, REGPC, p->scond);
+                       o1 = olrr(ctxt, p->from.reg&15, REGPC, REGPC, p->scond);
                        o1 |= 2<<7;
                }
                break;
@@ -2029,7 +2008,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                o2 = osr(ctxt, p->as, p->from.reg, 0, REGTMP, p->scond);
                if(o->flag & LPCREL) {
                        o3 = o2;
-                       o2 = oprrr(ctxt, AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
+                       o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
                }
                break;
 
@@ -2042,7 +2021,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                        o2 |= 1<<22;
                if(o->flag & LPCREL) {
                        o3 = o2;
-                       o2 = oprrr(ctxt, AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
+                       o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
                }
                break;
 
@@ -2053,7 +2032,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                o2 = ofsr(ctxt, p->as, p->from.reg, 0, REGTMP, p->scond, p);
                if(o->flag & LPCREL) {
                        o3 = o2;
-                       o2 = oprrr(ctxt, AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
+                       o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
                }
                break;
 
@@ -2061,10 +2040,10 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                o1 = omvl(ctxt, p, &p->from, REGTMP);
                if(!o1)
                        break;
-               o2 = ofsr(ctxt, p->as, p->to.reg, 0, REGTMP, p->scond, p) | (1<<20);
+               o2 = ofsr(ctxt, p->as, p->to.reg, 0, (REGTMP&15), p->scond, p) | (1<<20);
                if(o->flag & LPCREL) {
                        o3 = o2;
-                       o2 = oprrr(ctxt, AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
+                       o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
                }
                break;
 
@@ -2072,14 +2051,14 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
        case 70:        /* movh/movhu R,O(R) -> strh */
                aclass(ctxt, &p->to);
                r = p->to.reg;
-               if(r == NREG)
+               if(r == 0)
                        r = o->param;
                o1 = oshr(ctxt, p->from.reg, ctxt->instoffset, r, p->scond);
                break;
        case 71:        /* movb/movh/movhu O(R),R -> ldrsb/ldrsh/ldrh */
                aclass(ctxt, &p->from);
                r = p->from.reg;
-               if(r == NREG)
+               if(r == 0)
                        r = o->param;
                o1 = olhr(ctxt, ctxt->instoffset, r, p->to.reg, p->scond);
                if(p->as == AMOVB || p->as == AMOVBS)
@@ -2092,18 +2071,18 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                if(!o1)
                        break;
                r = p->to.reg;
-               if(r == NREG)
+               if(r == 0)
                        r = o->param;
-               o2 = oshrr(ctxt, p->from.reg, REGTMP,r, p->scond);
+               o2 = oshrr(ctxt, p->from.reg, REGTMP&15, r, p->scond);
                break;
        case 73:        /* movb/movh/movhu L(R),R -> ldrsb/ldrsh/ldrh */
                o1 = omvl(ctxt, p, &p->from, REGTMP);
                if(!o1)
                        break;
                r = p->from.reg;
-               if(r == NREG)
+               if(r == 0)
                        r = o->param;
-               o2 = olhrr(ctxt, REGTMP, r, p->to.reg, p->scond);
+               o2 = olhrr(ctxt, REGTMP&15, r, p->to.reg, p->scond);
                if(p->as == AMOVB || p->as == AMOVBS)
                        o2 ^= (1<<5)|(1<<6);
                else if(p->as == AMOVH || p->as == AMOVHS)
@@ -2117,16 +2096,16 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                if(ctxt->instoffset != 0)
                        ctxt->diag("non-zero offset in ABX");
 /*
-               o1 =    oprrr(ctxt, AADD, p->scond) | immrot(0) | (REGPC<<16) | (REGLINK<<12);  // mov PC, LR
-               o2 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | p->to.reg;              // BX R
+               o1 =    oprrr(ctxt, AADD, p->scond) | immrot(0) | ((REGPC&15)<<16) | ((REGLINK&15)<<12);        // mov PC, LR
+               o2 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | ((p->to.reg&15) << 0);          // BX R
 */
                // p->to.reg may be REGLINK
                o1 = oprrr(ctxt, AADD, p->scond);
                o1 |= immrot(ctxt->instoffset);
-               o1 |= p->to.reg << 16;
-               o1 |= REGTMP << 12;
-               o2 = oprrr(ctxt, AADD, p->scond) | immrot(0) | (REGPC<<16) | (REGLINK<<12);     // mov PC, LR
-               o3 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | REGTMP;         // BX Rtmp
+               o1 |= (p->to.reg&15) << 16;
+               o1 |= (REGTMP&15) << 12;
+               o2 = oprrr(ctxt, AADD, p->scond) | immrot(0) | ((REGPC&15)<<16) | ((REGLINK&15)<<12);   // mov PC, LR
+               o3 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | (REGTMP&15);            // BX Rtmp
                break;
        case 76:        /* bx O(R) when returning from fn*/
                ctxt->diag("ABXRET");
@@ -2136,8 +2115,8 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                if(ctxt->instoffset != 0)
                        ctxt->diag("offset must be zero in LDREX");
                o1 = (0x19<<20) | (0xf9f);
-               o1 |= p->from.reg << 16;
-               o1 |= p->to.reg << 12;
+               o1 |= (p->from.reg&15) << 16;
+               o1 |= (p->to.reg&15) << 12;
                o1 |= (p->scond & C_SCOND) << 28;
                break;
        case 78:        /* strex reg,oreg,reg */
@@ -2145,9 +2124,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                if(ctxt->instoffset != 0)
                        ctxt->diag("offset must be zero in STREX");
                o1 = (0x18<<20) | (0xf90);
-               o1 |= p->from.reg << 16;
-               o1 |= p->reg << 0;
-               o1 |= p->to.reg << 12;
+               o1 |= (p->from.reg&15) << 16;
+               o1 |= (p->reg&15) << 0;
+               o1 |= (p->to.reg&15) << 12;
                o1 |= (p->scond & C_SCOND) << 28;
                break;
        case 80:        /* fmov zfcon,freg */
@@ -2159,88 +2138,88 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                        o2 = oprrr(ctxt, ASUBF, p->scond);
                }
                v = 0x70;       // 1.0
-               r = p->to.reg;
+               r = (p->to.reg&15) << 0;
 
                // movf $1.0, r
                o1 |= (p->scond & C_SCOND) << 28;
-               o1 |= r << 12;
+               o1 |= (r&15) << 12;
                o1 |= (v&0xf) << 0;
                o1 |= (v&0xf0) << 12;
 
                // subf r,r,r
-               o2 |= r | (r<<16) | (r<<12);
+               o2 |= ((r&15)<<0) | ((r&15)<<16) | ((r&15)<<12);
                break;
        case 81:        /* fmov sfcon,freg */
                o1 = 0x0eb00a00;                // VMOV imm 32
                if(p->as == AMOVD)
                        o1 = 0xeeb00b00;        // VMOV imm 64
                o1 |= (p->scond & C_SCOND) << 28;
-               o1 |= p->to.reg << 12;
+               o1 |= (p->to.reg&15) << 12;
                v = chipfloat5(ctxt, p->from.u.dval);
                o1 |= (v&0xf) << 0;
                o1 |= (v&0xf0) << 12;
                break;
        case 82:        /* fcmp freg,freg, */
                o1 = oprrr(ctxt, p->as, p->scond);
-               o1 |= (p->reg<<12) | (p->from.reg<<0);
+               o1 |= ((p->reg&15)<<12) | ((p->from.reg&15)<<0);
                o2 = 0x0ef1fa10;        // VMRS R15
                o2 |= (p->scond & C_SCOND) << 28;
                break;
        case 83:        /* fcmp freg,, */
                o1 = oprrr(ctxt, p->as, p->scond);
-               o1 |= (p->from.reg<<12) | (1<<16);
+               o1 |= ((p->from.reg&15)<<12) | (1<<16);
                o2 = 0x0ef1fa10;        // VMRS R15
                o2 |= (p->scond & C_SCOND) << 28;
                break;
        case 84:        /* movfw freg,freg - truncate float-to-fix */
                o1 = oprrr(ctxt, p->as, p->scond);
-               o1 |= (p->from.reg<<0);
-               o1 |= (p->to.reg<<12);
+               o1 |= ((p->from.reg&15)<<0);
+               o1 |= ((p->to.reg&15)<<12);
                break;
        case 85:        /* movwf freg,freg - fix-to-float */
                o1 = oprrr(ctxt, p->as, p->scond);
-               o1 |= (p->from.reg<<0);
-               o1 |= (p->to.reg<<12);
+               o1 |= ((p->from.reg&15)<<0);
+               o1 |= ((p->to.reg&15)<<12);
                break;
        case 86:        /* movfw freg,reg - truncate float-to-fix */
                // macro for movfw freg,FTMP; movw FTMP,reg
                o1 = oprrr(ctxt, p->as, p->scond);
-               o1 |= (p->from.reg<<0);
-               o1 |= (FREGTMP<<12);
+               o1 |= ((p->from.reg&15)<<0);
+               o1 |= ((FREGTMP&15)<<12);
                o2 = oprrr(ctxt, AMOVFW+AEND, p->scond);
-               o2 |= (FREGTMP<<16);
-               o2 |= (p->to.reg<<12);
+               o2 |= ((FREGTMP&15)<<16);
+               o2 |= ((p->to.reg&15)<<12);
                break;
        case 87:        /* movwf reg,freg - fix-to-float */
                // macro for movw reg,FTMP; movwf FTMP,freg
                o1 = oprrr(ctxt, AMOVWF+AEND, p->scond);
-               o1 |= (p->from.reg<<12);
-               o1 |= (FREGTMP<<16);
+               o1 |= ((p->from.reg&15)<<12);
+               o1 |= ((FREGTMP&15)<<16);
                o2 = oprrr(ctxt, p->as, p->scond);
-               o2 |= (FREGTMP<<0);
-               o2 |= (p->to.reg<<12);
+               o2 |= ((FREGTMP&15)<<0);
+               o2 |= ((p->to.reg&15)<<12);
                break;
        case 88:        /* movw reg,freg  */
                o1 = oprrr(ctxt, AMOVWF+AEND, p->scond);
-               o1 |= (p->from.reg<<12);
-               o1 |= (p->to.reg<<16);
+               o1 |= ((p->from.reg&15)<<12);
+               o1 |= ((p->to.reg&15)<<16);
                break;
        case 89:        /* movw freg,reg  */
                o1 = oprrr(ctxt, AMOVFW+AEND, p->scond);
-               o1 |= (p->from.reg<<16);
-               o1 |= (p->to.reg<<12);
+               o1 |= ((p->from.reg&15)<<16);
+               o1 |= ((p->to.reg&15)<<12);
                break;
        case 90:        /* tst reg  */
                o1 = oprrr(ctxt, ACMP+AEND, p->scond);
-               o1 |= p->from.reg<<16;
+               o1 |= (p->from.reg&15)<<16;
                break;
        case 91:        /* ldrexd oreg,reg */
                aclass(ctxt, &p->from);
                if(ctxt->instoffset != 0)
                        ctxt->diag("offset must be zero in LDREX");
                o1 = (0x1b<<20) | (0xf9f);
-               o1 |= p->from.reg << 16;
-               o1 |= p->to.reg << 12;
+               o1 |= (p->from.reg&15) << 16;
+               o1 |= (p->to.reg&15) << 12;
                o1 |= (p->scond & C_SCOND) << 28;
                break;
        case 92:        /* strexd reg,oreg,reg */
@@ -2248,9 +2227,9 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                if(ctxt->instoffset != 0)
                        ctxt->diag("offset must be zero in STREX");
                o1 = (0x1a<<20) | (0xf90);
-               o1 |= p->from.reg << 16;
-               o1 |= p->reg << 0;
-               o1 |= p->to.reg << 12;
+               o1 |= (p->from.reg&15) << 16;
+               o1 |= (p->reg&15) << 0;
+               o1 |= (p->to.reg&15) << 12;
                o1 |= (p->scond & C_SCOND) << 28;
                break;
        case 93:        /* movb/movh/movhu addr,R -> ldrsb/ldrsh/ldrh */
@@ -2264,7 +2243,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                        o2 ^= (1<<6);
                if(o->flag & LPCREL) {
                        o3 = o2;
-                       o2 = oprrr(ctxt, AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
+                       o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
                }
                break;
        case 94:        /* movh/movhu R,addr -> strh */
@@ -2274,12 +2253,12 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                o2 = oshr(ctxt, p->from.reg, 0, REGTMP, p->scond);
                if(o->flag & LPCREL) {
                        o3 = o2;
-                       o2 = oprrr(ctxt, AADD, p->scond) | REGTMP | REGPC << 16 | REGTMP << 12;
+                       o2 = oprrr(ctxt, AADD, p->scond) | (REGTMP&15) | (REGPC&15) << 16 | (REGTMP&15) << 12;
                }
                break;
        case 95:        /* PLD off(reg) */
                o1 = 0xf5d0f000;
-               o1 |= p->from.reg << 16;
+               o1 |= (p->from.reg&15) << 16;
                if(p->from.offset < 0) {
                        o1 &= ~(1 << 23);
                        o1 |= (-p->from.offset) & 0xfff;
@@ -2296,21 +2275,21 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
                break;
        case 97:        /* CLZ Rm, Rd */
                o1 = oprrr(ctxt, p->as, p->scond);
-               o1 |= p->to.reg << 12;
-               o1 |= p->from.reg;
+               o1 |= (p->to.reg&15) << 12;
+               o1 |= (p->from.reg&15) << 0;
                break;
        case 98:        /* MULW{T,B} Rs, Rm, Rd */
                o1 = oprrr(ctxt, p->as, p->scond);
-               o1 |= p->to.reg << 16;
-               o1 |= p->from.reg << 8;
-               o1 |= p->reg;
+               o1 |= (p->to.reg&15) << 16;
+               o1 |= (p->from.reg&15) << 8;
+               o1 |= (p->reg&15) << 0;
                break;
        case 99:        /* MULAW{T,B} Rs, Rm, Rn, Rd */
                o1 = oprrr(ctxt, p->as, p->scond);
-               o1 |= p->to.reg << 12;
-               o1 |= p->from.reg << 8;
-               o1 |= p->reg;
-               o1 |= p->to.offset << 16;
+               o1 |= (p->to.reg&15) << 12;
+               o1 |= (p->from.reg&15) << 8;
+               o1 |= (p->reg&15) << 0;
+               o1 |= (p->to.offset&15) << 16;
                break;
        case 100:
                // DATABUNDLE: BKPT $0x5be0, signify the start of NaCl data bundle;
@@ -2339,14 +2318,14 @@ mov(Link *ctxt, Prog *p)
        o1 = oprrr(ctxt, p->as, p->scond);
        o1 |= p->from.offset;
        rt = p->to.reg;
-       r = p->reg;
-       if(p->to.type == D_NONE)
+       if(p->to.type == TYPE_NONE)
                rt = 0;
+       r = p->reg;
        if(p->as == AMOVW || p->as == AMVN)
                r = 0;
-       else if(r == NREG)
+       else if(r == 0)
                r = rt;
-       o1 |= (r<<16) | (rt<<12);
+       o1 |= ((r&15)<<16) | ((rt&15)<<12);
        return o1;
 }
 
@@ -2523,8 +2502,8 @@ olr(Link *ctxt, int32 v, int b, int r, int sc)
        if(v >= (1<<12) || v < 0)
                ctxt->diag("literal span too large: %d (R%d)\n%P", v, b, ctxt->printp);
        o |= v;
-       o |= b << 16;
-       o |= r << 12;
+       o |= (b&15) << 16;
+       o |= (r&15) << 12;
        return o;
 }
 
@@ -2548,8 +2527,8 @@ olhr(Link *ctxt, int32 v, int b, int r, int sc)
        if(v >= (1<<8) || v < 0)
                ctxt->diag("literal span too large: %d (R%d)\n%P", v, b, ctxt->printp);
        o |= (v&0xf)|((v>>4)<<8)|(1<<22);
-       o |= b << 16;
-       o |= r << 12;
+       o |= (b&15) << 16;
+       o |= (r&15) << 12;
        return o;
 }
 
@@ -2623,8 +2602,8 @@ ofsr(Link *ctxt, int a, int r, int32 v, int b, int sc, Prog *p)
        if(v >= (1<<10) || v < 0)
                ctxt->diag("literal span too large: %d\n%P", v, p);
        o |= (v>>2) & 0xFF;
-       o |= b << 16;
-       o |= r << 12;
+       o |= (b&15) << 16;
+       o |= (r&15) << 12;
 
        switch(a) {
        default:
@@ -2652,7 +2631,7 @@ omvl(Link *ctxt, Prog *p, Addr *a, int dr)
                }
                o1 = oprrr(ctxt, AMVN, p->scond&C_SCOND);
                o1 |= v;
-               o1 |= dr << 12;
+               o1 |= (dr&15) << 12;
        } else {
                v = p->pcond->pc - p->pc - 8;
                o1 = olr(ctxt, v, REGPC, dr, p->scond&C_SCOND);
index a91df55e695386fb9858c400549b0bc5d877e288..f88f579ed93d92eceb8858c1697fdc80598c14c0 100644 (file)
@@ -99,10 +99,10 @@ Pconv(Fmt *fp)
        if(s & C_UBIT)          /* ambiguous with FBIT */
                strcat(sc, ".U");
        if(a == AMOVM) {
-               if(p->from.type == D_CONST)
+               if(p->from.type == TYPE_CONST)
                        sprint(str, "%.5lld (%L)        %A%s    %@,%D", p->pc, p->lineno, a, sc, &p->from, &p->to);
                else
-               if(p->to.type == D_CONST)
+               if(p->to.type == TYPE_CONST)
                        sprint(str, "%.5lld (%L)        %A%s    %D,%@", p->pc, p->lineno, a, sc, &p->from, &p->to);
                else
                        sprint(str, "%.5lld (%L)        %A%s    %D,%D", p->pc, p->lineno, a, sc, &p->from, &p->to);
@@ -113,13 +113,10 @@ Pconv(Fmt *fp)
        if(p->as == ATEXT)
                sprint(str, "%.5lld (%L)        %A      %D,%d,%D", p->pc, p->lineno, a, &p->from, p->reg, &p->to);
        else
-       if(p->reg == NREG)
+       if(p->reg == 0)
                sprint(str, "%.5lld (%L)        %A%s    %D,%D", p->pc, p->lineno, a, sc, &p->from, &p->to);
        else
-       if(p->from.type != D_FREG)
-               sprint(str, "%.5lld (%L)        %A%s    %D,R%d,%D", p->pc, p->lineno, a, sc, &p->from, p->reg, &p->to);
-       else
-               sprint(str, "%.5lld (%L)        %A%s    %D,F%d,%D", p->pc, p->lineno, a, sc, &p->from, p->reg, &p->to);
+               sprint(str, "%.5lld (%L)        %A%s    %D,%R,%D", p->pc, p->lineno, a, sc, &p->from, p->reg, &p->to);
        bigP = nil;
        return fmtstrcpy(fp, str);
 }
@@ -152,60 +149,48 @@ Dconv(Fmt *fp)
                sprint(str, "GOK-type(%d)", a->type);
                break;
 
-       case D_NONE:
+       case TYPE_NONE:
                str[0] = 0;
-               if(a->name != D_NONE || a->reg != NREG || a->sym != nil)
-                       sprint(str, "%M(R%d)(NONE)", a, a->reg);
+               if(a->name != TYPE_NONE || a->reg != 0 || a->sym != nil)
+                       sprint(str, "%M(%R)(NONE)", a, a->reg);
                break;
 
-       case D_CONST:
-               if(a->reg != NREG)
-                       sprint(str, "$%M(R%d)", a, a->reg);
+       case TYPE_CONST:
+               if(a->reg != 0)
+                       sprint(str, "$%M(%R)", a, a->reg);
                else
                        sprint(str, "$%M", a);
                break;
 
-       case D_CONST2:
-               sprint(str, "$%lld-%d", a->offset, a->offset2);
+       case TYPE_TEXTSIZE:
+               sprint(str, "$%lld-%d", a->offset, a->u.argsize);
                break;
 
-       case D_SHIFT:
+       case TYPE_SHIFT:
                v = a->offset;
                op = &"<<>>->@>"[(((v>>5) & 3) << 1)];
                if(v & (1<<4))
                        sprint(str, "R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15);
                else
                        sprint(str, "R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31);
-               if(a->reg != NREG)
-                       sprint(str+strlen(str), "(R%d)", a->reg);
+               if(a->reg != 0)
+                       sprint(str+strlen(str), "(%R)", a->reg);
                break;
 
-       case D_OREG:
-               if(a->reg != NREG)
-                       sprint(str, "%M(R%d)", a, a->reg);
+       case TYPE_MEM:
+               if(a->reg != 0)
+                       sprint(str, "%M(%R)", a, a->reg);
                else
                        sprint(str, "%M", a);
                break;
 
-       case D_REG:
-               sprint(str, "R%d", a->reg);
-               if(a->name != D_NONE || a->sym != nil)
-                       sprint(str, "%M(R%d)(REG)", a, a->reg);
-               break;
-
-       case D_FREG:
-               sprint(str, "F%d", a->reg);
-               if(a->name != D_NONE || a->sym != nil)
-                       sprint(str, "%M(R%d)(REG)", a, a->reg);
-               break;
-
-       case D_PSR:
-               sprint(str, "PSR");
-               if(a->name != D_NONE || a->sym != nil)
-                       sprint(str, "%M(PSR)(REG)", a);
+       case TYPE_REG:
+               sprint(str, "%R", a->reg);
+               if(a->name != TYPE_NONE || a->sym != nil)
+                       sprint(str, "%M(%R)(REG)", a, a->reg);
                break;
 
-       case D_BRANCH:
+       case TYPE_BRANCH:
                if(a->sym != nil)
                        sprint(str, "%s(SB)", a->sym->name);
                else if(bigP != nil && bigP->pcond != nil)
@@ -216,11 +201,11 @@ Dconv(Fmt *fp)
                        sprint(str, "%lld(PC)", a->offset/*-pc*/);
                break;
 
-       case D_FCONST:
+       case TYPE_FCONST:
                sprint(str, "$%.17g", a->u.dval);
                break;
 
-       case D_SCONST:
+       case TYPE_SCONST:
                sprint(str, "$\"%$\"", a->u.sval);
                break;
        }
@@ -237,9 +222,9 @@ RAconv(Fmt *fp)
        a = va_arg(fp->args, Addr*);
        sprint(str, "GOK-reglist");
        switch(a->type) {
-       case D_CONST:
-       case D_CONST2:
-               if(a->reg != NREG)
+       case TYPE_CONST:
+       case TYPE_TEXTSIZE:
+               if(a->reg != 0)
                        break;
                if(a->sym != nil)
                        break;
@@ -310,11 +295,27 @@ static int
 Rconv(Fmt *fp)
 {
        int r;
-       char str[STRINGSZ];
 
        r = va_arg(fp->args, int);
-       sprint(str, "R%d", r);
-       return fmtstrcpy(fp, str);
+       if(r == 0)
+               return fmtstrcpy(fp, "NONE");
+       if(REG_R0 <= r && r <= REG_R15)
+               return fmtprint(fp, "R%d", r-REG_R0);
+       if(REG_F0 <= r && r <= REG_F15)
+               return fmtprint(fp, "F%d", r-REG_F0);
+
+       switch(r) {
+       case REG_FPSR:
+               return fmtstrcpy(fp, "FPSR");
+       case REG_FPCR:
+               return fmtstrcpy(fp, "FPCR");
+       case REG_CPSR:
+               return fmtstrcpy(fp, "CPSR");
+       case REG_SPSR:
+               return fmtstrcpy(fp, "SPSR");
+       }
+
+       return fmtprint(fp, "badreg(%d)", r);
 }
 
 static int
@@ -348,23 +349,23 @@ Mconv(Fmt *fp)
                sprint(str, "GOK-name(%d)", a->name);
                break;
 
-       case D_NONE:
+       case NAME_NONE:
                sprint(str, "%lld", a->offset);
                break;
 
-       case D_EXTERN:
+       case NAME_EXTERN:
                sprint(str, "%s+%d(SB)", s->name, (int)a->offset);
                break;
 
-       case D_STATIC:
+       case NAME_STATIC:
                sprint(str, "%s<>+%d(SB)", s->name, (int)a->offset);
                break;
 
-       case D_AUTO:
+       case NAME_AUTO:
                sprint(str, "%s-%d(SP)", s->name, (int)-a->offset);
                break;
 
-       case D_PARAM:
+       case NAME_PARAM:
                sprint(str, "%s+%d(FP)", s->name, (int)a->offset);
                break;
        }
index 86cb902f9c5a01718a4213a8c680dc90f9198b55..0f2e9fa4f24894e5be82b59f1c67ca8ffc55340d 100644 (file)
 static Prog zprg5 = {
        .as = AGOK,
        .scond = C_SCOND_NONE,
-       .reg = NREG,
-       .from = {
-               .name = D_NONE,
-               .type = D_NONE,
-               .reg = NREG,
-       },
-       .to = {
-               .name = D_NONE,
-               .type = D_NONE,
-               .reg = NREG,
-       },
 };
 
-static int
-symtype(Addr *a)
-{
-       return a->name;
-}
-
 static int
 isdata(Prog *p)
 {
@@ -97,14 +80,14 @@ progedit(Link *ctxt, Prog *p)
        p->from.class = 0;
        p->to.class = 0;
 
-       // Rewrite B/BL to symbol as D_BRANCH.
+       // Rewrite B/BL to symbol as TYPE_BRANCH.
        switch(p->as) {
        case AB:
        case ABL:
        case ADUFFZERO:
        case ADUFFCOPY:
-               if(p->to.type == D_OREG && (p->to.name == D_EXTERN || p->to.name == D_STATIC) && p->to.sym != nil)
-                       p->to.type = D_BRANCH;
+               if(p->to.type == TYPE_MEM && (p->to.name == NAME_EXTERN || p->to.name == NAME_STATIC) && p->to.sym != nil)
+                       p->to.type = TYPE_BRANCH;
                break;
        }
 
@@ -124,24 +107,24 @@ progedit(Link *ctxt, Prog *p)
                                        tlsfallback = linklookup(ctxt, "runtime.read_tls_fallback", 0);
                                // MOVW LR, R11
                                p->as = AMOVW;
-                               p->from.type = D_REG;
+                               p->from.type = TYPE_REG;
                                p->from.reg = REGLINK;
-                               p->to.type = D_REG;
+                               p->to.type = TYPE_REG;
                                p->to.reg = REGTMP;
 
                                // BL   runtime.read_tls_fallback(SB)
                                p = appendp(ctxt, p);
                                p->as = ABL;
-                               p->to.type = D_BRANCH;
+                               p->to.type = TYPE_BRANCH;
                                p->to.sym = tlsfallback;
                                p->to.offset = 0;
 
                                // MOVW R11, LR
                                p = appendp(ctxt, p);
                                p->as = AMOVW;
-                               p->from.type = D_REG;
+                               p->from.type = TYPE_REG;
                                p->from.reg = REGTMP;
-                               p->to.type = D_REG;
+                               p->to.type = TYPE_REG;
                                p->to.reg = REGLINK;
                                break;
                        }
@@ -154,7 +137,7 @@ progedit(Link *ctxt, Prog *p)
        // Rewrite float constants to values stored in memory.
        switch(p->as) {
        case AMOVF:
-               if(p->from.type == D_FCONST && chipfloat5(ctxt, p->from.u.dval) < 0 &&
+               if(p->from.type == TYPE_FCONST && chipfloat5(ctxt, p->from.u.dval) < 0 &&
                   (chipzero5(ctxt, p->from.u.dval) < 0 || (p->scond & C_SCOND) != C_SCOND_NONE)) {
                        uint32 i32;
                        float32 f32;
@@ -167,15 +150,15 @@ progedit(Link *ctxt, Prog *p)
                                adduint32(ctxt, s, i32);
                                s->reachable = 0;
                        }
-                       p->from.type = D_OREG;
+                       p->from.type = TYPE_MEM;
                        p->from.sym = s;
-                       p->from.name = D_EXTERN;
+                       p->from.name = NAME_EXTERN;
                        p->from.offset = 0;
                }
                break;
 
        case AMOVD:
-               if(p->from.type == D_FCONST && chipfloat5(ctxt, p->from.u.dval) < 0 &&
+               if(p->from.type == TYPE_FCONST && chipfloat5(ctxt, p->from.u.dval) < 0 &&
                   (chipzero5(ctxt, p->from.u.dval) < 0 || (p->scond & C_SCOND) != C_SCOND_NONE)) {
                        uint64 i64;
                        memmove(&i64, &p->from.u.dval, 8);
@@ -186,9 +169,9 @@ progedit(Link *ctxt, Prog *p)
                                adduint64(ctxt, s, i64);
                                s->reachable = 0;
                        }
-                       p->from.type = D_OREG;
+                       p->from.type = TYPE_MEM;
                        p->from.sym = s;
-                       p->from.name = D_EXTERN;
+                       p->from.name = NAME_EXTERN;
                        p->from.offset = 0;
                }
                break;
@@ -203,10 +186,10 @@ progedit(Link *ctxt, Prog *p)
                if(ctxt->tlsg == nil)
                        ctxt->tlsg = linklookup(ctxt, "runtime.tlsg", 0);
 
-               if(p->from.type == D_CONST && p->from.name == D_EXTERN && p->from.sym == ctxt->tlsg)
-                       p->from.type = D_OREG;
-               if(p->to.type == D_CONST && p->to.name == D_EXTERN && p->to.sym == ctxt->tlsg)
-                       p->to.type = D_OREG;
+               if(p->from.type == TYPE_CONST && p->from.name == NAME_EXTERN && p->from.sym == ctxt->tlsg)
+                       p->from.type = TYPE_MEM;
+               if(p->to.type == TYPE_CONST && p->to.name == NAME_EXTERN && p->to.sym == ctxt->tlsg)
+                       p->to.type = TYPE_MEM;
        }
 }
 
@@ -255,7 +238,7 @@ nocache5(Prog *p)
 }
 
 static void
-addstacksplit(Link *ctxt, LSym *cursym)
+preprocess(Link *ctxt, LSym *cursym)
 {
        Prog *p, *pl, *p1, *p2, *q, *q1, *q2;
        int o;
@@ -282,35 +265,35 @@ addstacksplit(Link *ctxt, LSym *cursym)
        if(autoffset < 0)
                autoffset = 0;
        cursym->locals = autoffset;
-       cursym->args = p->to.offset2;
+       cursym->args = p->to.u.argsize;
 
        if(ctxt->debugzerostack) {
                if(autoffset && !(p->reg&NOSPLIT)) {
                        // MOVW $4(R13), R1
                        p = appendp(ctxt, p);
                        p->as = AMOVW;
-                       p->from.type = D_CONST;
-                       p->from.reg = 13;
+                       p->from.type = TYPE_CONST;
+                       p->from.reg = REG_R13;
                        p->from.offset = 4;
-                       p->to.type = D_REG;
-                       p->to.reg = 1;
+                       p->to.type = TYPE_REG;
+                       p->to.reg = REG_R1;
        
                        // MOVW $n(R13), R2
                        p = appendp(ctxt, p);
                        p->as = AMOVW;
-                       p->from.type = D_CONST;
-                       p->from.reg = 13;
+                       p->from.type = TYPE_CONST;
+                       p->from.reg = REG_R13;
                        p->from.offset = 4 + autoffset;
-                       p->to.type = D_REG;
-                       p->to.reg = 2;
+                       p->to.type = TYPE_REG;
+                       p->to.reg = REG_R2;
        
                        // MOVW $0, R3
                        p = appendp(ctxt, p);
                        p->as = AMOVW;
-                       p->from.type = D_CONST;
+                       p->from.type = TYPE_CONST;
                        p->from.offset = 0;
-                       p->to.type = D_REG;
-                       p->to.reg = 3;
+                       p->to.type = TYPE_REG;
+                       p->to.reg = REG_R3;
        
                        // L:
                        //      MOVW.nil R3, 0(R1) +4
@@ -318,22 +301,22 @@ addstacksplit(Link *ctxt, LSym *cursym)
                        //      BNE L
                        p = pl = appendp(ctxt, p);
                        p->as = AMOVW;
-                       p->from.type = D_REG;
-                       p->from.reg = 3;
-                       p->to.type = D_OREG;
-                       p->to.reg = 1;
+                       p->from.type = TYPE_REG;
+                       p->from.reg = REG_R3;
+                       p->to.type = TYPE_MEM;
+                       p->to.reg = REG_R1;
                        p->to.offset = 4;
                        p->scond |= C_PBIT;
        
                        p = appendp(ctxt, p);
                        p->as = ACMP;
-                       p->from.type = D_REG;
-                       p->from.reg = 1;
-                       p->reg = 2;
+                       p->from.type = TYPE_REG;
+                       p->from.reg = REG_R1;
+                       p->reg = REG_R2;
        
                        p = appendp(ctxt, p);
                        p->as = ABNE;
-                       p->to.type = D_BRANCH;
+                       p->to.type = TYPE_BRANCH;
                        p->pcond = pl;
                }
        }
@@ -445,9 +428,9 @@ addstacksplit(Link *ctxt, LSym *cursym)
                        p = appendp(ctxt, p);
                        p->as = AMOVW;
                        p->scond |= C_WBIT;
-                       p->from.type = D_REG;
+                       p->from.type = TYPE_REG;
                        p->from.reg = REGLINK;
-                       p->to.type = D_OREG;
+                       p->to.type = TYPE_MEM;
                        p->to.offset = -autosize;
                        p->to.reg = REGSP;
                        p->spadj = autosize;
@@ -472,64 +455,64 @@ addstacksplit(Link *ctxt, LSym *cursym)
 
                                p = appendp(ctxt, p);
                                p->as = AMOVW;
-                               p->from.type = D_OREG;
+                               p->from.type = TYPE_MEM;
                                p->from.reg = REGG;
                                p->from.offset = 4*ctxt->arch->ptrsize; // G.panic
-                               p->to.type = D_REG;
-                               p->to.reg = 1;
+                               p->to.type = TYPE_REG;
+                               p->to.reg = REG_R1;
                        
                                p = appendp(ctxt, p);
                                p->as = ACMP;
-                               p->from.type = D_CONST;
+                               p->from.type = TYPE_CONST;
                                p->from.offset = 0;
-                               p->reg = 1;
+                               p->reg = REG_R1;
                        
                                p = appendp(ctxt, p);
                                p->as = ABEQ;
-                               p->to.type = D_BRANCH;
+                               p->to.type = TYPE_BRANCH;
                                p1 = p;
                                
                                p = appendp(ctxt, p);
                                p->as = AMOVW;
-                               p->from.type = D_OREG;
-                               p->from.reg = 1;
+                               p->from.type = TYPE_MEM;
+                               p->from.reg = REG_R1;
                                p->from.offset = 0; // Panic.argp
-                               p->to.type = D_REG;
-                               p->to.reg = 2;
+                               p->to.type = TYPE_REG;
+                               p->to.reg = REG_R2;
                        
                                p = appendp(ctxt, p);
                                p->as = AADD;
-                               p->from.type = D_CONST;
+                               p->from.type = TYPE_CONST;
                                p->from.offset = autosize+4;
-                               p->reg = 13;
-                               p->to.type = D_REG;
-                               p->to.reg = 3;
+                               p->reg = REG_R13;
+                               p->to.type = TYPE_REG;
+                               p->to.reg = REG_R3;
 
                                p = appendp(ctxt, p);
                                p->as = ACMP;
-                               p->from.type = D_REG;
-                               p->from.reg = 2;
-                               p->reg = 3;
+                               p->from.type = TYPE_REG;
+                               p->from.reg = REG_R2;
+                               p->reg = REG_R3;
 
                                p = appendp(ctxt, p);
                                p->as = ABNE;
-                               p->to.type = D_BRANCH;
+                               p->to.type = TYPE_BRANCH;
                                p2 = p;
                        
                                p = appendp(ctxt, p);
                                p->as = AADD;
-                               p->from.type = D_CONST;
+                               p->from.type = TYPE_CONST;
                                p->from.offset = 4;
-                               p->reg = 13;
-                               p->to.type = D_REG;
-                               p->to.reg = 4;
+                               p->reg = REG_R13;
+                               p->to.type = TYPE_REG;
+                               p->to.reg = REG_R4;
 
                                p = appendp(ctxt, p);
                                p->as = AMOVW;
-                               p->from.type = D_REG;
-                               p->from.reg = 4;
-                               p->to.type = D_OREG;
-                               p->to.reg = 1;
+                               p->from.type = TYPE_REG;
+                               p->from.reg = REG_R4;
+                               p->to.type = TYPE_MEM;
+                               p->to.reg = REG_R1;
                                p->to.offset = 0; // Panic.argp
 
                                p = appendp(ctxt, p);
@@ -546,9 +529,9 @@ addstacksplit(Link *ctxt, LSym *cursym)
                                        p->as = AB;
                                        p->from = zprg5.from;
                                        if(p->to.sym) { // retjmp
-                                               p->to.type = D_BRANCH;
+                                               p->to.type = TYPE_BRANCH;
                                        } else {
-                                               p->to.type = D_OREG;
+                                               p->to.type = TYPE_MEM;
                                                p->to.offset = 0;
                                                p->to.reg = REGLINK;
                                        }
@@ -558,10 +541,10 @@ addstacksplit(Link *ctxt, LSym *cursym)
 
                        p->as = AMOVW;
                        p->scond |= C_PBIT;
-                       p->from.type = D_OREG;
+                       p->from.type = TYPE_MEM;
                        p->from.offset = autosize;
                        p->from.reg = REGSP;
-                       p->to.type = D_REG;
+                       p->to.type = TYPE_REG;
                        p->to.reg = REGPC;
                        // If there are instructions following
                        // this ARET, they come from a branch
@@ -571,7 +554,7 @@ addstacksplit(Link *ctxt, LSym *cursym)
                                p->to.reg = REGLINK;
                                q2 = appendp(ctxt, p);
                                q2->as = AB;
-                               q2->to.type = D_BRANCH;
+                               q2->to.type = TYPE_BRANCH;
                                q2->to.sym = p->to.sym;
                                p->to.sym = nil;
                                p = q2;
@@ -579,12 +562,12 @@ addstacksplit(Link *ctxt, LSym *cursym)
                        break;
 
                case AADD:
-                       if(p->from.type == D_CONST && p->from.reg == NREG && p->to.type == D_REG && p->to.reg == REGSP)
+                       if(p->from.type == TYPE_CONST && p->from.reg == 0 && p->to.type == TYPE_REG && p->to.reg == REGSP)
                                p->spadj = -p->from.offset;
                        break;
 
                case ASUB:
-                       if(p->from.type == D_CONST && p->from.reg == NREG && p->to.type == D_REG && p->to.reg == REGSP)
+                       if(p->from.type == TYPE_CONST && p->from.reg == 0 && p->to.type == TYPE_REG && p->to.reg == REGSP)
                                p->spadj = p->from.offset;
                        break;
 
@@ -594,9 +577,9 @@ addstacksplit(Link *ctxt, LSym *cursym)
                case AMODU:
                        if(ctxt->debugdivmod)
                                break;
-                       if(p->from.type != D_REG)
+                       if(p->from.type != TYPE_REG)
                                break;
-                       if(p->to.type != D_REG)
+                       if(p->to.type != TYPE_REG)
                                break;
                        q1 = p;
 
@@ -604,9 +587,9 @@ addstacksplit(Link *ctxt, LSym *cursym)
                        p = appendp(ctxt, p);
                        p->as = AMOVW;
                        p->lineno = q1->lineno;
-                       p->from.type = D_REG;
+                       p->from.type = TYPE_REG;
                        p->from.reg = q1->from.reg;
-                       p->to.type = D_OREG;
+                       p->to.type = TYPE_MEM;
                        p->to.reg = REGSP;
                        p->to.offset = 4;
 
@@ -614,11 +597,11 @@ addstacksplit(Link *ctxt, LSym *cursym)
                        p = appendp(ctxt, p);
                        p->as = AMOVW;
                        p->lineno = q1->lineno;
-                       p->from.type = D_REG;
+                       p->from.type = TYPE_REG;
                        p->from.reg = q1->reg;
-                       if(q1->reg == NREG)
+                       if(q1->reg == 0)
                                p->from.reg = q1->to.reg;
-                       p->to.type = D_REG;
+                       p->to.type = TYPE_REG;
                        p->to.reg = REGTMP;
                        p->to.offset = 0;
 
@@ -626,7 +609,7 @@ addstacksplit(Link *ctxt, LSym *cursym)
                        p = appendp(ctxt, p);
                        p->as = ABL;
                        p->lineno = q1->lineno;
-                       p->to.type = D_BRANCH;
+                       p->to.type = TYPE_BRANCH;
                        switch(o) {
                        case ADIV:
                                p->to.sym = ctxt->sym_div;
@@ -646,21 +629,21 @@ addstacksplit(Link *ctxt, LSym *cursym)
                        p = appendp(ctxt, p);
                        p->as = AMOVW;
                        p->lineno = q1->lineno;
-                       p->from.type = D_REG;
+                       p->from.type = TYPE_REG;
                        p->from.reg = REGTMP;
                        p->from.offset = 0;
-                       p->to.type = D_REG;
+                       p->to.type = TYPE_REG;
                        p->to.reg = q1->to.reg;
 
                        /* ADD $8,SP */
                        p = appendp(ctxt, p);
                        p->as = AADD;
                        p->lineno = q1->lineno;
-                       p->from.type = D_CONST;
-                       p->from.reg = NREG;
+                       p->from.type = TYPE_CONST;
+                       p->from.reg = 0;
                        p->from.offset = 8;
-                       p->reg = NREG;
-                       p->to.type = D_REG;
+                       p->reg = 0;
+                       p->to.type = TYPE_REG;
                        p->to.reg = REGSP;
                        p->spadj = -8;
 
@@ -668,20 +651,20 @@ addstacksplit(Link *ctxt, LSym *cursym)
                        /* MOVW 0(SP), REGTMP; MOVW REGTMP, -8!(SP) */
                        /* TODO: Remove SP adjustments; see issue 6699. */
                        q1->as = AMOVW;
-                       q1->from.type = D_OREG;
+                       q1->from.type = TYPE_MEM;
                        q1->from.reg = REGSP;
                        q1->from.offset = 0;
-                       q1->reg = NREG;
-                       q1->to.type = D_REG;
+                       q1->reg = 0;
+                       q1->to.type = TYPE_REG;
                        q1->to.reg = REGTMP;
 
                        /* SUB $8,SP */
                        q1 = appendp(ctxt, q1);
                        q1->as = AMOVW;
-                       q1->from.type = D_REG;
+                       q1->from.type = TYPE_REG;
                        q1->from.reg = REGTMP;
-                       q1->reg = NREG;
-                       q1->to.type = D_OREG;
+                       q1->reg = 0;
+                       q1->to.type = TYPE_MEM;
                        q1->to.reg = REGSP;
                        q1->to.offset = -8;
                        q1->scond |= C_WBIT;
@@ -689,17 +672,23 @@ addstacksplit(Link *ctxt, LSym *cursym)
 
                        break;
                case AMOVW:
-                       if((p->scond & C_WBIT) && p->to.type == D_OREG && p->to.reg == REGSP)
+                       if((p->scond & C_WBIT) && p->to.type == TYPE_MEM && p->to.reg == REGSP)
                                p->spadj = -p->to.offset;
-                       if((p->scond & C_PBIT) && p->from.type == D_OREG && p->from.reg == REGSP && p->to.reg != REGPC)
+                       if((p->scond & C_PBIT) && p->from.type == TYPE_MEM && p->from.reg == REGSP && p->to.reg != REGPC)
                                p->spadj = -p->from.offset;
-                       if(p->from.type == D_CONST && p->from.reg == REGSP && p->to.type == D_REG && p->to.reg == REGSP)
+                       if(p->from.type == TYPE_CONST && p->from.reg == REGSP && p->to.type == TYPE_REG && p->to.reg == REGSP)
                                p->spadj = -p->from.offset;
                        break;
                }
        }
 }
 
+static int
+isfloatreg(Addr *a)
+{
+       return a->type == TYPE_REG && REG_F0 <= a->reg && a->reg <= REG_F15;
+}
+
 static void
 softfloat(Link *ctxt, LSym *cursym)
 {
@@ -719,7 +708,7 @@ softfloat(Link *ctxt, LSym *cursym)
        for(p = cursym->text; p != nil; p = p->link) {
                switch(p->as) {
                case AMOVW:
-                       if(p->to.type == D_FREG || p->from.type == D_FREG)
+                       if(isfloatreg(&p->to) || isfloatreg(&p->from))
                                goto soft;
                        goto notsoft;
 
@@ -761,7 +750,7 @@ softfloat(Link *ctxt, LSym *cursym)
                        *p = zprg5;
                        p->link = next;
                        p->as = ABL;
-                               p->to.type = D_BRANCH;
+                               p->to.type = TYPE_BRANCH;
                        p->to.sym = symsfloat;
                        p->lineno = next->lineno;
 
@@ -781,21 +770,21 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
        // MOVW                 g_stackguard(g), R1
        p = appendp(ctxt, p);
        p->as = AMOVW;
-       p->from.type = D_OREG;
+       p->from.type = TYPE_MEM;
        p->from.reg = REGG;
        p->from.offset = 2*ctxt->arch->ptrsize; // G.stackguard0
        if(ctxt->cursym->cfunc)
                p->from.offset = 3*ctxt->arch->ptrsize; // G.stackguard1
-       p->to.type = D_REG;
-       p->to.reg = 1;
+       p->to.type = TYPE_REG;
+       p->to.reg = REG_R1;
        
        if(framesize <= StackSmall) {
                // small stack: SP < stackguard
                //      CMP     stackguard, SP
                p = appendp(ctxt, p);
                p->as = ACMP;
-               p->from.type = D_REG;
-               p->from.reg = 1;
+               p->from.type = TYPE_REG;
+               p->from.reg = REG_R1;
                p->reg = REGSP;
        } else if(framesize <= StackBig) {
                // large stack: SP-framesize < stackguard-StackSmall
@@ -803,17 +792,17 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
                //      CMP stackguard, R2
                p = appendp(ctxt, p);
                p->as = AMOVW;
-               p->from.type = D_CONST;
+               p->from.type = TYPE_CONST;
                p->from.reg = REGSP;
                p->from.offset = -framesize;
-               p->to.type = D_REG;
-               p->to.reg = 2;
+               p->to.type = TYPE_REG;
+               p->to.reg = REG_R2;
                
                p = appendp(ctxt, p);
                p->as = ACMP;
-               p->from.type = D_REG;
-               p->from.reg = 1;
-               p->reg = 2;
+               p->from.type = TYPE_REG;
+               p->from.reg = REG_R1;
+               p->reg = REG_R2;
        } else {
                // Such a large stack we need to protect against wraparound
                // if SP is close to zero.
@@ -827,40 +816,40 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
                //      CMP.NE R3, R2
                p = appendp(ctxt, p);
                p->as = ACMP;
-               p->from.type = D_CONST;
+               p->from.type = TYPE_CONST;
                p->from.offset = (uint32)StackPreempt;
-               p->reg = 1;
+               p->reg = REG_R1;
 
                p = appendp(ctxt, p);
                p->as = AMOVW;
-               p->from.type = D_CONST;
+               p->from.type = TYPE_CONST;
                p->from.reg = REGSP;
                p->from.offset = StackGuard;
-               p->to.type = D_REG;
-               p->to.reg = 2;
+               p->to.type = TYPE_REG;
+               p->to.reg = REG_R2;
                p->scond = C_SCOND_NE;
                
                p = appendp(ctxt, p);
                p->as = ASUB;
-               p->from.type = D_REG;
-               p->from.reg = 1;
-               p->to.type = D_REG;
-               p->to.reg = 2;
+               p->from.type = TYPE_REG;
+               p->from.reg = REG_R1;
+               p->to.type = TYPE_REG;
+               p->to.reg = REG_R2;
                p->scond = C_SCOND_NE;
                
                p = appendp(ctxt, p);
                p->as = AMOVW;
-               p->from.type = D_CONST;
+               p->from.type = TYPE_CONST;
                p->from.offset = framesize + (StackGuard - StackSmall);
-               p->to.type = D_REG;
-               p->to.reg = 3;
+               p->to.type = TYPE_REG;
+               p->to.reg = REG_R3;
                p->scond = C_SCOND_NE;
                
                p = appendp(ctxt, p);
                p->as = ACMP;
-               p->from.type = D_REG;
-               p->from.reg = 3;
-               p->reg = 2;
+               p->from.type = TYPE_REG;
+               p->from.reg = REG_R3;
+               p->reg = REG_R2;
                p->scond = C_SCOND_NE;
        }
        
@@ -868,16 +857,16 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
        p = appendp(ctxt, p);
        p->as = AMOVW;
        p->scond = C_SCOND_LS;
-       p->from.type = D_REG;
+       p->from.type = TYPE_REG;
        p->from.reg = REGLINK;
-       p->to.type = D_REG;
-       p->to.reg = 3;
+       p->to.type = TYPE_REG;
+       p->to.reg = REG_R3;
 
        // BL.LS                runtime.morestack(SB) // modifies LR, returns with LO still asserted
        p = appendp(ctxt, p);
        p->as = ABL;
        p->scond = C_SCOND_LS;
-       p->to.type = D_BRANCH;
+       p->to.type = TYPE_BRANCH;
        if(ctxt->cursym->cfunc)
                p->to.sym = linklookup(ctxt, "runtime.morestackc", 0);
        else
@@ -886,7 +875,7 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
        // BLS  start
        p = appendp(ctxt, p);
        p->as = ABLS;
-       p->to.type = D_BRANCH;
+       p->to.type = TYPE_BRANCH;
        p->pcond = ctxt->cursym->text->link;
        
        return p;
@@ -1011,7 +1000,7 @@ loop:
                q = ctxt->arch->prg();
                q->as = a;
                q->lineno = p->lineno;
-               q->to.type = D_BRANCH;
+               q->to.type = TYPE_BRANCH;
                q->to.offset = p->pc;
                q->pcond = p;
                p = q;
@@ -1051,7 +1040,7 @@ LinkArch linkarm = {
        .thechar = '5',
        .endian = LittleEndian,
 
-       .addstacksplit = addstacksplit,
+       .preprocess = preprocess,
        .assemble = span5,
        .datasize = datasize,
        .follow = follow,
@@ -1060,25 +1049,12 @@ LinkArch linkarm = {
        .prg = prg,
        .progedit = progedit,
        .settextflag = settextflag,
-       .symtype = symtype,
        .textflag = textflag,
 
        .minlc = 4,
        .ptrsize = 4,
        .regsize = 4,
 
-       .D_ADDR = D_ADDR,
-       .D_AUTO = D_AUTO,
-       .D_BRANCH = D_BRANCH,
-       .D_CONST = D_CONST,
-       .D_EXTERN = D_EXTERN,
-       .D_FCONST = D_FCONST,
-       .D_NONE = D_NONE,
-       .D_PARAM = D_PARAM,
-       .D_SCONST = D_SCONST,
-       .D_STATIC = D_STATIC,
-       .D_OREG = D_OREG,
-
        .ACALL = ABL,
        .ADATA = ADATA,
        .AEND = AEND,