Latest version from Albert Koelmans
authorceriel <none@none>
Mon, 12 Nov 1990 15:36:03 +0000 (15:36 +0000)
committerceriel <none@none>
Mon, 12 Nov 1990 15:36:03 +0000 (15:36 +0000)
mach/arm/ncg/mach.c
mach/arm/ncg/mach.h
mach/arm/ncg/table

index a58b8d5..dfdd14f 100644 (file)
@@ -1,7 +1,24 @@
+/* mach.c file for ARM backend */
 
-#ifndef NORCSID
-static char rcsid[] = "$Header$" ;
-#endif
+
+#define MAXREGVARS     4               /* Max num of register variables*/
+
+struct reg_stuff
+{
+    char *name;
+    long offset;
+}
+reg [MAXREGVARS];                      /* array of reg var details     */
+
+char regnames[6*MAXREGVARS];           /* comma-delimited list of regs */
+int  n_regs;                           /* current number of reg vars   */
+
+char *segname[] = {
+       ".sect .text",
+       ".sect .data",
+       ".sect .data",
+       ".sect .bss"
+};
 
 con_part(sz, w)
        register int    sz;
@@ -30,79 +47,66 @@ con_mult(sz)
        fprintf(codefile,".long\t%s\n",str);
 }
 
-#ifdef REGVARS
-full lbytes;
-struct regadm {
-       char *ra_str;
-       long ra_off;
-} regadm[4];
-int n_regvars;
-
-regscore(off,size,typ,score,totyp) long off; {
-
-       /*This function is copied from pdp/ncg
-        */
-       /*
-        * This function is full of magic constants.
-        * They are a result of experimentation.
-        */
-
-       if (size != 2)
-               return(-1);
-       score -= 1;     /* allow for save/restore */
-       if (off>=0)
-               score -= 2;
-       if (typ==reg_pointer)
-               score *= 17;
-       else if (typ==reg_loop)
-               score = 10*score+50;    /* Guestimate */
-       else
-               score *= 10;
-       return(score);  /* 10 * estimated # of words of profit */
-}
 
-i_regsave() {
+regscore (offset, size, type, score, totype)
+long offset;
+{
+    if (size > 4)                      /* only consider register-sized */
+       return -1;                      /* variables                    */
+
+    if (score < 2) return -1;
+
+    /* give greater preference to locals */
+    if (offset >= 0) score *= 4; else score *= 8;
 
-       n_regvars=0;
+    return score;
 }
 
-f_regsave(){
-       register i;
 
-       fprintf(codefile, "enter [");
-       if (n_regvars>=1){
-               fprintf(codefile,"%s",regadm[0].ra_str);
-               for (i=1; i<n_regvars; i++)
-                       fprintf(codefile,",%s",regadm[0].ra_str);
-       }
-       fprintf(codefile, "], %d\n", lbytes);
-       for (i=0;i<n_regvars;i++)
-               if (regadm[i].ra_off>=0)
-                       fprintf(codefile, "movd %ld(fp), %s",
-                         regadm[i].ra_off, regadm[i].ra_str);
+i_regsave()
+{
+    n_regs = 0;
+    *regnames = '\0';
 }
 
-regsave(regstr,off,size) char *regstr; long off; {
 
-       fprintf(codefile,"\t! Local %ld into %s\n",off,regstr);
-       regadm[n_regvars].ra_str = regstr;
-       regadm[n_regvars].ra_off = off;
-       n_regvars++;
+regsave(name, offset, size)
+char *name;
+long offset;
+{
+
+    if (n_regs > 0)                    /* if its not the first item    */
+       strcat(regnames, ",");          /* prefix it with a comma       */
+    strcat(regnames, name);            /* add to list of names to save */
+
+    reg[n_regs].name = name;           /* and add to array of reg vars */
+    reg[n_regs++].offset = offset;
 }
 
-regreturn() {
-       register int i;
 
-       fprintf(codefile, "exit [");
-       if (n_regvars>=1){
-               fprintf(codefile,"%s",regadm[0].ra_str);
-               for (i=1; i<n_regvars; i++)
-                       fprintf(codefile,",%s",regadm[0].ra_str);
-       }
-       fprintf(codefile, "]\n");
+f_regsave()
+{
+    int i;
+    long n;
+    char *q;
+
+    if (n_regs > 0)
+       fprintf(codefile, "STMFD R12<,{%s}\n", regnames);
+
+    for (i = 0; i < n_regs; i++) {     /* load their new values        */
+       n = reg[i].offset;
+       q = reg[i].name;
+    if (n > 0)                         /* only proc parameters         */
+           fprintf(codefile, "LDR %s,[R13,#%ld]\n", q, n);
+    }
 }
 
-#endif
+
+regreturn()
+{
+      if (n_regs > 0)
+       fprintf(codefile, "LDMFD R12<,{%s}\n", regnames);
+}
 
 mes(type) word type ; {
        int argt ;
@@ -126,28 +130,156 @@ mes(type) word type ; {
        }
 }
 
-prolog(nlocals) full nlocals; {
-
-#ifndef REGVARS
-       fprintf(codefile, "STMFD R12<, {R14}\n");
-       fprintf(codefile, "STMFD R12<, {R13}\n");
-       fprintf(codefile, "MOV R13, R12\n");
+prolog(nlocals) full nlocals;
+{
+       fprintf(codefile, "STMFD R12<,{R13,R14}\n");
+       fprintf(codefile, "MOV R13,R12\n");
        if (nlocals)
-               fprintf(codefile, "SUB R12, R12, #%d\n", nlocals);
+               fprintf(codefile, "SUB R12,R12,#%d\n", nlocals);
        return;
-#else
-       lbytes = nlocals;
-#endif
 }
 
-char *segname[] = {
-       ".sect .text",
-       ".sect .data",
-       ".sect .data",
-       ".sect .bss"
-};
+#ifdef NOFLOAT
+con_float()  /* warning only -- AMK */
+ {
+       static int been_here;
+         if (argval != 4 && argval != 8)
+               fatal("bad fcon size");
+       fputs(".data4\t", codefile);
+       if (argval == 8)
+               fputs("0,",codefile);
+         fputs("0 !dummy float\n", codefile);
+       if ( !been_here++) {
+               fputs("Warning : dummy float-constant(s)\n", stderr);
+       }
+ }
+#else
+#define IEEEFLOAT
 
 con_float() {
+       double f;
+       double atof();
+       int i;
+       int j;
+       double frexp();
+#ifndef OWNFLOAT
+       int sign = 0;
+       int fraction[4] ;
+#else OWNFLOAT
+       float fl;
+       char *p;
+#endif OWNFLOAT
 
-       fatal("no reals");
+       if (argval!= 4 && argval!= 8)   {
+               fprintf(stderr,"float constant size = %d\n",argval);
+               fatal("bad fcon size");
+       }
+       fprintf(codefile,"!float %s sz %d\n", str, argval);
+       f = atof(str);
+       if (f == 0) {
+               if (argval == 8) fprintf(codefile, ".data2 0, 0\n");
+               fprintf(codefile, ".data2 0, 0\n");
+               return;
+       }
+#ifdef OWNFLOAT
+       if (argval == 4) {
+               /* careful: avoid overflow */
+               double ldexp();
+               f = frexp(f, &i);
+               fl = f;
+               fl = frexp(fl,&j);
+               if (i+j > 127) {
+                       /* overflow situation */
+                       fprintf(codefile, ".data1 0%o, 0377, 0377, 0377 ! overflow\n",
+                               f < 0 ? 0377 : 0177);
+                       return;
+               }
+               if (i+j < -127) {
+                       /* underflow situation */
+                       fprintf(codefile, ".data1 0%o, 0200, 0, 0 ! underflow\n",
+                               f < 0 ? 0200 : 0);
+                       return;
+               }
+               fl = ldexp(fl, i+j);
+               p = (char *) &fl;
+       }
+       else {
+               p = (char *) &f;
+       }
+       fprintf(codefile, ".data1 0%o", *p++ & 0377);
+       for (i = argval-1; i; i--) {
+               fprintf(codefile,",0%o", *p++ & 0377);
+       }
+#else OWNFLOAT
+       f = frexp(f, &i);
+       if (f < 0) {
+               f = -f;
+               sign = 1;
+       }
+       while (f < 0.5) {
+               f += f;
+               i --;
+       }
+       f = 2*f - 1.0;          /* hidden bit */
+#ifdef IEEEFLOAT
+       if (argval == 4) {
+#endif IEEEFLOAT
+               i = (i + 128) & 0377;
+               fraction[0] = (sign << 15) | (i << 7);
+               for (j = 6; j>= 0; j--) {
+                       f *= 2;
+                       if (f >= 1.0) {
+                               f -= 1.0;
+                               fraction[0] |= (1 << j);
+                       }
+               }
+#ifdef IEEEFLOAT
+       }
+       else {
+               i = (i + 1024) & 03777;
+               fraction[0] = (sign << 15) | (i << 4);
+               for (j = 3; j>= 0; j--) {
+                       f *= 2;
+                       if (f >= 1.0) {
+                               fraction[0] |= (1 << j);
+                               f -= 1.0;
+                       }
+               }
+       }
+#endif IEEEFLOAT
+       for (i = 1; i < argval / 2; i++) {
+               fraction[i] = 0;
+               for (j = 15; j>= 0; j--) {
+                       f *= 2;
+                       if (f >= 1.0) {
+                               fraction[i] |= (1 << j);
+                               f -= 1.0;
+                       }
+               }
+       }
+       if (f >= 0.5) {
+               for (i = argval/2 - 1; i >= 0; i--) {
+                       for (j = 0; j < 16; j++) {
+                               if (fraction[i] & (1 << j)) {
+                                       fraction[i] &= ~(1 << j);
+                               }
+                               else {
+                                       fraction[i] |= (1 << j);
+                                       break;
+                               }
+                       }
+                       if (j != 16) break;
+               }
+       }
+       for (i = 0; i < argval/2; i++) {
+               fprintf(codefile,
+                       i != 0 ? ", 0%o, 0%o" : ".data1 0%o, 0%o", 
+                       (fraction[i]>>8)&0377,
+                       fraction[i]&0377);
+       }
+#endif OWNFLOAT
+       putc('\n', codefile);
 }
+#endif
+
index d8e0650..2b09644 100644 (file)
@@ -6,7 +6,6 @@
 #define        dlbdlb(x,y)     fprintf(codefile,"%s = %s\n",x,y)
 #define newlbss(l,x)   fprintf(codefile,"%s:.space\t%ld\n",l,x);
 
-#define        pop_fmt         "(sp)+"
 #define cst_fmt                "%ld"
 #define        off_fmt         "%ld"
 #define ilb_fmt                "I%03x%x"
index ca64085..b774302 100644 (file)
@@ -1,4 +1,28 @@
-#define fitins(a) (a&~0xFF)==0||(a&~0x3FC)==0||(a&~0xFF0)==0||(a&~0x3FC0)==0||(a&~0xFF00)==0||(a&~0x3FC00)==0||(a&~0xFF000)==0||(a&~0x3FC000)==0||(a&~0xFF0000)==0||(a&~0x3FC0000)==0||(a&~0xFF00000)==0||(a&~0x3FC00000)==0||(a&~0xFF000000)==0||(a&~0xFC000003)==0||(a&~0xF000000F)==0||(a&~0xC000003F)==0||(~a&~0xFF)==0
+/****************************************************************************
+ *            ACK backend for Acorn Risc Machine                            *
+ *            First version: A.N.Other, Vrije Universiteit, Amsterdam       *
+ *            Completed by: Albert Koelmans, University of Newcastle        *
+ *            Register variables by Jonathan Hardwick                       *
+ *            With help from: Andy Michael and Ceriel Jacobs                *
+ ****************************************************************************/
+
+#define legal(a)     ((a&~0xFF)==0||(a&~0x3FC)==0||(a&~0xFF0)==0||\
+                    (a&~0x3FC0)==0||(a&~0xFF00)==0||(a&~0x3FC00)==0||\
+                    (a&~0xFF000)==0||(a&~0x3FC000)==0||(a&~0xFF0000)==0||\
+                    (a&~0x3FC0000)==0||(a&~0xFF00000)==0||(a&~0x3FC00000)==0||\
+                    (a&~0xFF000000)==0||(a&~0xFC000003)==0||(a&~0xF000000F)==0||\
+                    (a&~0xC000003F)==0||(~a&~0xFF)==0)
+#define neglegal(a)  (((0-a)&~0xFF)==0||((0-a)&~0x3FC)==0||((0-a)&~0xFF0)==0||\
+                    ((0-a)&~0x3FC0)==0||((0-a)&~0xFF00)==0||((0-a)&~0x3FC00)==0||\
+                    ((0-a)&~0xFF000)==0||((0-a)&~0x3FC000)==0||((0-a)&~0xFF0000)==0||\
+                    ((0-a)&~0x3FC0000)==0||((0-a)&~0xFF00000)==0||((0-a)&~0x3FC00000)==0||\
+                    ((0-a)&~0xFF000000)==0||((0-a)&~0xFC000003)==0||((0-a)&~0xF000000F)==0||\
+                    ((0-a)&~0xC000003F)==0||(~(0-a)&~0xFF)==0)
+
+#define illegal(a)    !legal(a)
+#define minlegal(a)    neglegal(a) && (a < 0)
+#define minillegal(a) !neglegal(a) && (a < 0)
+
 EM_WSIZE=4
 EM_PSIZE=4
 EM_BSIZE=8
@@ -15,132 +39,288 @@ LINKREGISTER
 
 REGISTERS
 
-R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10      :GENREG, REG .
+R0,R1,R2,R3,R8,R9,R10                  :GENREG, REG .
+R4,R5,R6,R7                            :GENREG regvar(reg_any).
 R11                                    :GENREG, SREG  .
-SP("R12")                              :GENREG, STACKPOINTER .
-LB("R13")                              :GENREG, LOCALBASE .
-R14                                    :GENREG, LINKREGISTER .
-PC("R15")                              :GENREG, PCPSR .
+SP("R12")                              :STACKPOINTER .
+LB("R13")                              :LOCALBASE .
+LR("R14")                              :LINKREGISTER .
+PC("R15")                              :PCPSR .
 
 TOKENS
 
-const4         = { INT num; } 4 "#" num .
-fitcon         = { INT num; } 4 "#" num .
-LOCAL          = { INT ind; } 4 "[R13,#" ind "]" .
+const4         = { INT num; } 4 cost(0,4) "#" num .
+fitcon         = { INT num; } 4 cost(0,4) "#" num .
+lb_local       = { INT ind; } 4 "[R13,#" ind "]" .
 addr_local     = { INT ind; } 4 .
-addr_external  = { ADDR add; } 4 add .
-
-imS            = { GENREG reg; ADDR S; INT shift;} 4 reg "," S " #" shift  .
-regS           = { GENREG reg; ADDR S; GENREG sreg;} 4 reg "," S " "sreg  .
-
+naddr_local    = { INT ind; } 4 .
 absolute       = { ADDR add; } 4 add .
-regind         = { GENREG reg; } 4 "[" reg "]" .
-regrel         = { GENREG reg; ADDR ind; } 4 "[" reg ",#" ind "]"  .
-regrelwb       = { GENREG reg; ADDR ind; } 4 "[" reg ",#" ind "]<"  .
-regregrel      = { GENREG reg1; GENREG reg2; } 4 "[" reg1 "," reg2 "]" .
-regminregrel   = { GENREG reg1; GENREG reg2; } 4 "[" reg1 ",-" reg2 "]" .
-regiSregrel    = { GENREG reg1; ADDR S; INT shift; GENREG reg2; } 4 
+addr_external  = { ADDR add; } 4 add .
+label          = { ADDR add; } 4 add .
+autoid         = { STACKPOINTER reg; } 4 reg "<" .
+regexp         = { INT exp;} 4 exp  .
+register       = { GENREG exp;} 4 exp  .
+
+imS            = { GENREG reg; ADDR S; INT shift;} 4 
+                       reg "," S "#" shift  .
+regS           = { GENREG reg; ADDR S; GENREG sreg;} 4 
+                       reg "," S " "sreg  .
+regind         = { GENREG reg; } 4 
+                       "[" reg "]" .
+REGrel         = { REG reg; ADDR ind; } 4 
+                       "[" reg ",#" ind "]"  .
+regrel         = { GENREG reg; ADDR ind; } 4 
+                       "[" reg ",#" ind "]"  .
+st_regrel      = { STACKPOINTER reg; ADDR ind; } 4 
+                       "[" reg ",#" ind "]"  .
+lb_regrel      = { LOCALBASE reg; ADDR ind; } 4 
+                       "[" reg ",#" ind "]"  .
+regregrel      = { GENREG reg1; GENREG reg2; } 4 
+                       "[" reg1 "," reg2 "]" .
+st_regregrel   = { STACKPOINTER reg1; GENREG reg2; } 4 
+                       "[" reg1 "," reg2 "]" .
+lb_regregrel   = { LOCALBASE reg1; GENREG reg2; } 4 
+                       "[" reg1 "," reg2 "]" .
+regminregrel   = { GENREG reg1; GENREG reg2; } 4 
+                       "[" reg1 ",-" reg2 "]" .
+regiSregrel    = { GENREG reg1; ADDR S; INT shift; GENREG reg2; } 4
+                       "[" reg1 "," reg2 ","  S "#" shift "]" .
+st_regiSregrel = { STACKPOINTER reg1; ADDR S; INT shift; GENREG reg2; } 4
                        "[" reg1 "," reg2 ","  S "#" shift "]" .
-regminiSregrel = { GENREG reg1; ADDR S; INT shift; GENREG reg2; } 4 
+regminiSregrel = { GENREG reg1; ADDR S; INT shift; GENREG reg2; } 4
                        "[" reg1 ",-" reg2 ","  S "#" shift "]" .
-regrSregrel    = { GENREG reg1; ADDR S; GENREG sreg; GENREG reg2; } 4 
-                       "[" reg1 "," reg2 ","  S sreg "]" .
-regminrSregrel = { GENREG reg1; ADDR S; GENREG sreg; GENREG reg2; } 4 
-                       "[" reg1 ",-" reg2 ","  S sreg "]" .
+regminrSregrel = { GENREG reg1; ADDR S; GENREG sreg; GENREG reg2; } 4
+                       "[" reg1 ",-" reg2 ","  S " " sreg "]" .
+regrelpi       = { GENREG reg; ADDR ind; } 4 
+                       "[" reg "],#" ind .
+regconst       = { GENREG reg; INT  ind; } 4 
+                       reg ",#" ind  .
+
+regplusreg     = {GENREG reg1; GENREG reg2;} 4
+                       reg1 "," reg2 .
+regplusiSreg   = {GENREG reg1; ADDR S; INT shift; GENREG reg2;} 4
+                       reg1 "," reg2 "," S "#" shift .
+regplusrSreg   = {GENREG reg1; ADDR S; GENREG sreg; GENREG reg2;} 4
+                       reg1 "," reg2 "," S "," sreg .
+regminreg      = {GENREG reg1; GENREG reg2;} 4
+                       reg1 "," reg2 .
+regminiSreg    = {GENREG reg1; ADDR S; INT shift; GENREG reg2;} 4
+                       reg1 "," reg2 "," S "#" shift .
+regminrSreg    = {GENREG reg1; ADDR S; GENREG sreg; GENREG reg2;} 4
+                       reg1 "," reg2 "," S "," sreg .
+
+REGlist1       = {REG reg1; } 4 
+                       "{" reg1 "}" .
+reglist1       = {GENREG reg1; } 4 
+                       "{" reg1 "}" .
+lb_reglist1    = {LOCALBASE reg1; } 4 
+                       "{" reg1 "}" .
+sp_reglist1    = {STACKPOINTER reg1; } 4 
+                       "{" reg1 "}" .
+reglist2       = {GENREG reg1; GENREG reg2; } 8 
+                       "{" reg1 "," reg2 "}" .
+lb_pc_reglist2 = {LOCALBASE reg1; PCPSR reg2; } 8 
+                       "{" reg1 "," reg2 "}" .
+reglist3       = {GENREG reg1; GENREG reg2; GENREG reg3; } 12
+                       "{" reg1 "," reg2 "," reg3 "}" .
+reglist4       = {GENREG reg1; GENREG reg2; GENREG reg3; GENREG reg4; } 16
+                       "{" reg1 "," reg2 "," reg3 "," reg4 "}" .
+
+/* the next 5 are not currently used - perhaps later */
+regrelwb       = { GENREG reg; ADDR ind; } 4 "[" reg ",#" ind "]<"  .
 regregrelwb    = { GENREG reg1; GENREG reg2; } 4 "[" reg1 "," reg2 "]<" .
-regiSregrelwb  = { GENREG reg1; ADDR S; INT shift; GENREG reg2; } 4 
+regiSregrelwb  = { GENREG reg1; ADDR S; INT shift; GENREG reg2; } 4
                        "[" reg1 "," reg2 ","  S "#" shift "]<" .
-regrSregrelwb  = { GENREG reg1; ADDR S; GENREG sreg; GENREG reg2; } 4 
-                       "[" reg1 "," reg2 ","  S sreg "]<" .
-regrelpi       = { GENREG reg; ADDR ind; } 4 "[" reg "],#" ind .
+regrSregrelwb  = { GENREG reg1; ADDR S; GENREG sreg; GENREG reg2; } 4
+                       "[" reg1 "," reg2 ","  S " " sreg "]<" .
 regregrelpi    = { GENREG reg1; GENREG reg2; } 4 "[" reg1 "]," reg2 .
 
-label          = {ADDR add; } 4 add .
+LOCAL          = { INT ind;} 4 ">>> BUG IN LOCAL".
+stack          = { GENREG r;} 4 "R12<,{" r "}".
 
-autoid         = {GENREG reg; } 4 reg "<" .
-reglist1       = {GENREG reg1; } 4 "{" reg1 "}" .
-reglist2       = {GENREG reg1; GENREG reg2; } 8 "{" reg1 "," reg2 "}" .
-reglist3       = {GENREG reg1; GENREG reg2; GENREG reg3; } 12 
-                       "{" reg1 "," reg2 "," reg3 "}" .
-reglist4       = {GENREG reg1; GENREG reg2; GENREG reg3; GENREG reg4; } 16 
-                       "{" reg1 "," reg2 "," reg3 "," reg4 "}" .
-regexp         = {INT exp;} 4 exp  .
+/* tokens to put shifts and rotates into opcodes                       */
+reglslcon      = {GENREG target; INT shift;} 4 target ",LSL#" shift.
+reglsrcon      = {GENREG target; INT shift;} 4 target ",LSR#" shift.
+regasrcon      = {GENREG target; INT shift;} 4 target ",ASR#" shift.
+regrorcon      = {GENREG target; INT shift;} 4 target ",ROR#" shift.
+reglslreg      = {GENREG target; GENREG shift;} 4 cost(0,1) target ",LSL " shift.
+reglsrreg      = {GENREG target; GENREG shift;} 4 cost(0,1) target ",LSR " shift.
+regasrreg      = {GENREG target; GENREG shift;} 4 cost(0,1) target ",ASR " shift.
+regrorreg      = {GENREG target; GENREG shift;} 4 cost(0,1) target ",ROR " shift.
+regrorregr     = {GENREG target; GENREG shift;} 4 cost(0,1) target ",ROR " shift.
 
-regconst       = {GENREG reg; ADDR ind; } 4 reg ",#" ind  .
-regplusreg     = {GENREG reg1; GENREG reg2;} 4  .
-regplusiSreg   = {GENREG reg1; ADDR S; INT shift; GENREG reg2;} 4  .
-regplusrSreg   = {GENREG reg1; ADDR S; GENREG sreg; GENREG reg2;} 4  .
-regminreg      = {GENREG reg1; GENREG reg2;} 4  .
-regminiSreg    = {GENREG reg1; ADDR S; INT shift; GENREG reg2;} 4  .
-regminrSreg    = {GENREG reg1; ADDR S; GENREG sreg; GENREG reg2;} 4  .
 
 SETS
 
 address                = absolute + regind + regrel + regrelwb + regregrel +
-                  regiSregrel + regrSregrel + regiSregrelwb + regrSregrelwb +
+                 st_regrel + st_regregrel + st_regiSregrel +
+                 lb_regrel + lb_regregrel +
+                  regiSregrel + regiSregrelwb + regrSregrelwb +
                  regminregrel + regminiSregrel + regminrSregrel +
-                 regregrelwb + regrelpi + regregrelpi + LOCAL .
+                 regregrelwb + regrelpi + regregrelpi + lb_local .
 REGcon         = GENREG + imS + regS + fitcon  .
-reglist                = reglist1 + reglist2 + reglist3 + reglist4 + regexp  .
+reglist                = reglist1 + reglist2 + reglist3 + reglist4 +
+                 lb_reglist1 + sp_reglist1 + lb_pc_reglist2 +
+                 regexp + REGlist1 .
+constant        = fitcon + const4 .
+local          = lb_local + LOCAL.
+regshift       = reglslreg + reglsrreg + regasrreg + regrorreg + regrorregr +
+                 reglslcon + reglsrcon + regasrcon + regrorcon.
+rhs            = GENREG + constant + regshift + LOCAL.
+mem4           = regregrel + regrel + lb_local.
+extern         = addr_external + absolute + label.
+all_except_con  = mem4 + extern + local.
+any_data       = all_except_con + rhs.
+any_data_except_local = any_data - LOCAL.
+posshifts       = regplusiSreg+regplusrSreg.
+negshifts       = regminiSreg+regminrSreg.
+shifts          = posshifts+negshifts.
 
 INSTRUCTIONS
 
-BAL  label  .
-BAL_L "BAL.L" label  .
-BNV  label  .
-BNE  label  .
-BEQ  label  .
-BMI  label  .
-BGT  label  .
-BLT  label  .
-BLE  label  .
-BGE  label  .
-
-LDR  GENREG:wo,        address:rw  .
-STR  GENREG:ro, address:rw  .
-LDR_B "LDR.B" GENREG:wo, address:rw  .
-STR_B "STR.B" GENREG:ro, address:rw  .
-
-LDMFD autoid:rw, reglist:wo  .
-STMFD autoid:rw, reglist:ro  .
-LDMIA GENREG:rw, reglist:wo  .
-
-ADC  GENREG:wo, GENREG:ro, REGcon:ro  .
-ADD  GENREG:wo, GENREG:ro, REGcon+const4:ro  .
-ADD  GENREG:wo, regconst:ro  .
-AND  GENREG:wo, GENREG:ro, REGcon:ro  .
-BIC  GENREG:wo, GENREG:ro, REGcon:ro  .
-CMN  GENREG:ro, REGcon:ro kills :cc  .
-CMP  GENREG:ro, REGcon:ro kills :cc  .
-EOR  GENREG:wo, GENREG:ro, REGcon:ro  .
-EOR_S "EOR.S"  GENREG:wo:cc, GENREG:ro, REGcon:ro  .
-MOV  GENREG:wo, REGcon+const4:ro  .
-MOV_MI "MOV.MI"  GENREG:wo, REGcon+const4:ro  .
-MOV_LT "MOV.LT"  GENREG:wo, REGcon+const4:ro  .
-MOV_LE "MOV.LE"  GENREG:wo, REGcon+const4:ro  .
-MOV_EQ "MOV.EQ"  GENREG:wo, REGcon+const4:ro  .
-MOV_NE "MOV.NE"  GENREG:wo, REGcon+const4:ro  .
-MOV_GE "MOV.GE"  GENREG:wo, REGcon+const4:ro  .
-MOV_GT "MOV.GT"  GENREG:wo, REGcon+const4:ro  .
-MVN  GENREG:wo, REGcon:ro  .
-ORR  GENREG:wo, GENREG:ro, REGcon:ro  .
-RSB  GENREG:wo, GENREG:ro, REGcon:ro  .
-RSB_S "RSB.S"  GENREG:wo:cc, GENREG:ro, REGcon:ro  .
-RSC  GENREG:wo, GENREG:ro, REGcon:ro  .
-SBC  GENREG:wo, GENREG:ro, REGcon:ro  .
-SUB  GENREG:wo, GENREG:ro, REGcon:ro  .
-SUB_S "SUB.S"  GENREG:wo:cc, GENREG:ro, REGcon:ro  .
-TEQ  GENREG:ro, REGcon:ro kills :cc  .
-TST  GENREG:ro, REGcon:ro kills :cc  .
-ADR  GENREG:wo, addr_external+label:ro  .
-LABEL "" label kills :cc .
+BAL             label                                          cost(4,4) .
+BAL_L   "BAL.L"  label                                                 cost(4,4) .
+BAL_LEQ "BAL.L.EQ" label                                       cost(4,4) .
+BNV             label                                          cost(4,4) .
+BNE             label                                          cost(4,4) .
+BEQ             label                                          cost(4,4) .
+BMI             label                                          cost(4,4) .
+BGT             label                                          cost(4,4) .
+BLT             label                                          cost(4,4) .
+BLE             label                                          cost(4,4) .
+BGE             label                                          cost(4,4) .
+
+LDR             REG+LOCALBASE+GENREG+address:wo, address:rw    cost(4,4) .
+LDR             LOCAL+GENREG:rw,
+                       mem4+absolute+addr_external:ro          cost(4,4) .
+STR             GENREG+REG:ro, REGrel+address:rw               cost(4,4) .
+LDR_B  "LDR.B"   REG+GENREG:wo, address:rw                     cost(4,4) .
+LDR_B           LOCAL:rw, rhs+mem4:ro                          cost(4,4) .
+STR_B  "STR.B"   GENREG+REG:ro, address:rw                     cost(4,4) .
+
+LDMFD           autoid:rw, reglist:wo                          cost(4,7) .
+STMFD           autoid:rw, reglist:ro                          cost(4,7) .
+STMFD           stack                                          cost(4,4) .
+LDMIA           GENREG:rw, reglist:wo                          cost(4,7) .
+
+ADC             REG+GENREG:wo, REG+GENREG:ro, REGcon:ro        cost(4,1) .
+ADD             GENREG+REG:wo, GENREG:ro, REGcon+const4:ro     cost(4,1) .
+ADD             GENREG+STACKPOINTER:wo, GENREG+STACKPOINTER:ro,
+                       STACKPOINTER+REGcon+const4:ro           cost(4,1) .
+ADD             LOCAL+GENREG+REG:wo,
+                       regconst+shifts+regminreg+regplusreg:ro cost(4,1) .
+ADD             LOCAL+GENREG:rw, LOCALBASE+GENREG+LOCAL:ro,
+                                       rhs:ro                  cost(4,1).
+ADD_NE "ADD.NE"  GENREG+REG:wo, GENREG:ro, REGcon+const4:ro    cost(4,1) .
+AND             REG+GENREG:wo, GENREG:ro, GENREG+REGcon:ro     cost(4,1) .
+AND_S  "AND.S"   GENREG+REG:wo, GENREG:ro, REGcon:ro           cost(4,1) .
+BIC             REG+GENREG:wo, GENREG:ro, REGcon:ro            cost(4,1) .
+CMN             GENREG+REG:ro, REGcon:ro kills :cc             cost(4,1) .
+CMP             REG+GENREG:ro, REGcon:ro kills :cc             cost(4,1) .
+EOR             GENREG+REG:wo, GENREG:ro, GENREG+REGcon:ro     cost(4,1) .
+EOR_S  "EOR.S"   REG+GENREG:wo:cc, GENREG:ro, REGcon:ro        cost(4,1) .
+MOV             REG:wo, REGcon+const4:ro                       cost(4,1) .
+MOV             REG:rw, LOCAL:ro                               cost(4,1).
+MOV             LOCALBASE+PCPSR+STACKPOINTER+GENREG:rw, 
+                REGcon+address+LOCALBASE+PCPSR+
+                               STACKPOINTER+GENREG+LOCAL:ro    cost(4,1).
+MOV             LOCAL+GENREG:rw, GENREG+rhs+register+REG:ro    cost(4,1).
+MOV             LOCALBASE+GENREG:wo, REGcon+const4:ro          cost(4,1) .
+MOV_MI "MOV.MI"  REG+GENREG:wo, REGcon+const4:ro               cost(4,1) .
+MOV_HI "MOV.HI"  GENREG+REG:wo, REGcon+const4:ro               cost(4,1) .
+MOV_LS "MOV.LS"  REG+GENREG:wo, REGcon+const4:ro               cost(4,1) .
+MOV_LT "MOV.LT"  GENREG+REG:wo, REGcon+const4:ro               cost(4,1) .
+MOV_LE "MOV.LE"  REG+GENREG:wo, REGcon+const4:ro               cost(4,1) .
+MOV_EQ "MOV.EQ"  GENREG+REG:wo, REGcon+const4:ro               cost(4,1) .
+MOV_NE "MOV.NE"  REG+GENREG:wo, REGcon+const4:ro               cost(4,1) .
+MOV_GE "MOV.GE"  REG+GENREG:wo, REGcon+const4:ro               cost(4,1) .
+MOV_GT "MOV.GT"  REG+GENREG:wo, REGcon+const4:ro               cost(4,1) .
+MOV_NV "MOV.NV"  GENREG+REG:wo, REGcon+const4:ro               cost(4,1) .
+MOV_S  "MOV.S"   GENREG+REG:wo, REGcon+const4+regind:ro
+                                               kills :cc       cost(4,1) .
+MVN             LOCAL+GENREG+REG:wo, REGcon:ro                 cost(4,1) .
+ORR             REG+GENREG:wo, GENREG:ro, GENREG+REGcon:ro     cost(4,1) .
+ORR             REG+GENREG+LOCAL:wo, imS:ro                    cost(4,1) .
+RSB             REG+GENREG+LOCAL:rw, REG+GENREG+LOCAL:ro,
+                                       rhs:ro                  cost(4,1).
+RSB             GENREG+REG:wo, GENREG:ro, REGcon:ro            cost(4,1) .
+RSB_S  "RSB.S"   REG+GENREG:wo:cc, GENREG:ro, REGcon:ro        cost(4,1) .
+RSC             GENREG+REG:wo, GENREG:ro, REGcon:ro            cost(4,1) .
+SBC             REG+GENREG:wo, GENREG:ro, REGcon:ro            cost(4,1) .
+SUB             LOCAL+GENREG:rw,
+                       regconst+shifts+regplusreg+regminreg:ro cost(4,1).
+SUB             LOCAL:rw, LOCAL:ro, rhs:ro                     cost(4,1).
+SUB             LOCAL+REG+GENREG:wo, LOCALBASE+GENREG:ro, 
+                       constant+REGcon:ro                      cost(4,1) .
+SUB_S  "SUB.S"   REG+GENREG:wo:cc, GENREG:ro, REGcon:ro        cost(4,1) .
+TEQ             GENREG+REG:ro, REGcon:ro kills :cc             cost(4,1) .
+TST             REG+GENREG:ro, REGcon:ro kills :cc             cost(4,1) .
+ADR             REG+LINKREGISTER+GENREG:wo,
+                                       addr_external+label:ro  cost(4,1) .
+LABEL  ""       label kills :cc                                cost(4,1) .
+
+/* Dummy instructions for ncgg procedures : lxx is logical operator,   */ 
+/* mxx is conditional move, bxx is conditional branch, rxx is arith-   */
+/* metical operator on register variable (LOCAL).                      */
+
+lxx "lxx : bug in cg"  REG:rw, REG:ro, rhs:ro          cost(4,1).
+mxx "mxx : bug in cg"  REG:rw, rhs:ro                  cost(4,1).
+bxx "bxx : bug in cg"  addr_external                   cost(4,4).
+rxx "rxx : bug in cg"  LOCAL:rw, LOCAL:ro, rhs:ro      cost(4,1).
+rrx "rrx : bug in cg"  LOCAL:rw, LOCAL:ro, LOCAL:ro    cost(4,1).
+
 
 MOVES
 
+from GENREG+STACKPOINTER+LOCALBASE+PCPSR to
+     GENREG+STACKPOINTER+LOCALBASE+PCPSR
+       gen MOV %2, %1
+
+from fitcon+GENREG+REG to LOCAL inreg(%ind)==reg_any
+       gen MOV %2, %1
+
+from LOCAL inreg(%ind)==reg_any to REG+GENREG
+       gen MOV %2, %1
+
+/* illegal immediate operands */
+
+from const4 minlegal(%num+1) to GENREG+LOCAL
+gen MVN %2, {fitcon, 0-%1.num-1}
+
+from const4 (minlegal(%num)) to GENREG+LOCAL
+gen MOV %2, {fitcon, 0-%1.num}
+    RSB %2, %2, {fitcon, 0}
+
+from const4 to GENREG+LOCAL    /* general case */
+      gen MOV %2,     { fitcon,   %1.num & 0xFF}
+          ADD %2, %2, { fitcon,   %1.num & 0xFF00}
+          ADD %2, %2, { fitcon,   %1.num & 0xFF0000}
+          ADD %2, %2, { fitcon,   %1.num & 0xFF000000}
+
+from regconst legal(%ind) && (%ind > 0) to LOCAL inreg(%ind)==reg_any
+       gen ADD %2, %1
+
+from regconst minlegal(%ind) to LOCAL inreg(%ind)==reg_any
+       gen SUB %2, %1.reg, {fitcon, 0-%1.ind}
+
+from lb_local illegal(%ind) to GENREG
+gen move {const4, %1.ind}, R11
+    LDR %2, {lb_regregrel, LB, R11}
+
+from lb_local legal(%ind) to GENREG
+gen LDR %2, {lb_regrel, LB, %1.ind}
+
+from GENREG to lb_local illegal(%ind)
+gen move {const4, %2.ind}, R11
+    STR %1, {lb_regregrel, LB, R11}
+
+from GENREG to lb_local legal(%ind)
+gen STR %1, {lb_regrel, LB, %2.ind}
+
 from GENREG to address
        gen STR %1, %2
 
-from address to GENREG
+from address to GENREG+LOCALBASE
        gen LDR %2, %1
 
 from GENREG to autoid
@@ -149,263 +329,637 @@ from GENREG to autoid
 from autoid to GENREG
        gen LDMFD %1, {reglist1, %2}
 
-from REGcon to GENREG
+from REGcon to GENREG+LOCALBASE
        gen MOV %2, %1
 
-from const4 to GENREG
-       gen MOV %2, %1
 
 from addr_external to GENREG
-       gen ADR %2, %1
+          gen ADR %2, %1
+
+/* strictly speaking, the following move is impossible.
+ * what it really means is: move from reg to address!
+ */
+from GENREG to addr_external
+          gen ADR R11,%2
+              STR %1,{regind,R11}
+
+
 
 TESTS
 
 to test GENREG
 gen CMP %1, {fitcon, 0}
 
+
 STACKINGRULES
 
-from address to STACK
-       gen move %1, R11
-           move R11, {autoid, SP}
+from LOCAL to STACK
+       gen STMFD {stack, regvar(%1.ind)}
+
+from REG to STACK
+       gen STMFD {autoid, SP}, {REGlist1, %1}
 
 from GENREG to STACK
-       gen move %1, {autoid, SP}
+       gen STMFD {autoid, SP}, {reglist1, %1}
+
+from LOCALBASE to STACK
+       gen STMFD {autoid, SP}, {lb_reglist1, %1}
+
+from STACKPOINTER to STACK
+       gen STMFD {autoid, SP}, {sp_reglist1, %1}
 
 from REGcon to STACK
        gen move %1, R11
-           move R11, {autoid, SP}
+           STMFD {autoid, SP}, {reglist1, R11}
 
 from const4 to STACK
        gen move %1, R11
-           move R11, {autoid, SP}
+           STMFD {autoid, SP}, {reglist1, R11}
+
+from addr_local legal(%1.ind) to STACK
+       gen ADD R11, LB, {fitcon, %1.ind}
+           STMFD {autoid, SP}, {reglist1, R11}
 
 from addr_local to STACK
-       gen ADD R11, LB, {const4, %1.ind}
-           move R11, {autoid, SP}
-       
+       gen move {const4, %1.ind}, R11
+           ADD R11, LB, R11
+           STMFD {autoid, SP}, {reglist1, R11}
+
+from naddr_local legal(%1.ind) to STACK
+       gen SUB R11, LB, {fitcon, %1.ind}
+           STMFD {autoid, SP}, {reglist1, R11}
+
+from naddr_local to STACK
+       gen move {const4, %1.ind}, R11
+           SUB R11, LB, R11
+           STMFD {autoid, SP}, {reglist1, R11}
+
 from addr_external to STACK
        gen ADR R11, %1
-           move R11, {autoid, SP}
+           STMFD {autoid, SP}, {reglist1, R11}
+
+from regconst legal(%1.ind) && (%ind > 0) to STACK
+       gen ADD R11, %1.reg, {fitcon,%1.ind}
+           STMFD {autoid, SP}, {reglist1, R11}
 
 from regconst to STACK
-       gen ADD R11, %1
-           move R11, {autoid, SP}
+       gen move {const4, %1.ind}, R11
+           ADD R11, R11, %1.reg
+           STMFD {autoid, SP}, {reglist1, R11}
 
 from regplusreg to STACK
        gen ADD R11, %1.reg1, %1.reg2
-           move R11, {autoid, SP}
+           STMFD {autoid, SP}, {reglist1, R11}
 
 from regminreg to STACK
        gen SUB R11, %1.reg1, %1.reg2
-           move R11, {autoid, SP}
+           STMFD {autoid, SP}, {reglist1, R11}
 
 from regplusiSreg to STACK
        gen ADD R11, %1.reg1, {imS, %1.reg2, %1.S, %1.shift}
-           move R11, {autoid, SP}
+           STMFD {autoid, SP}, {reglist1, R11}
 
 from regminiSreg to STACK
        gen SUB R11, %1.reg1, {imS, %1.reg2, %1.S, %1.shift}
-           move R11, {autoid, SP}
+           STMFD {autoid, SP}, {reglist1, R11}
 
 from regplusrSreg to STACK
        gen ADD R11, %1.reg1, {regS, %1.reg2, %1.S, %1.sreg}
-           move R11, {autoid, SP}
+           STMFD {autoid, SP}, {reglist1, R11}
 
 from regminrSreg to STACK
        gen SUB R11, %1.reg1, {regS, %1.reg2, %1.S, %1.sreg}
-           move R11, {autoid, SP}
+           STMFD {autoid, SP}, {reglist1, R11}
+
+from address to STACK
+       gen move %1, R11
+           STMFD {autoid, SP}, {reglist1, R11}
 
 COERCIONS
 
-from const4
-uses REG
+from LOCAL
+uses GENREG
+gen MOV %a, %1                                 yields %a
+
+from lb_local illegal(%ind)
+uses GENREG
+gen move {const4, %1.ind}, R11 
+    LDR %a, {lb_regregrel, LB, R11}            yields %a
+
+from lb_local legal(%ind)
+uses GENREG
+gen LDR %a, {lb_regrel, LB, %1.ind}            yields %a
+
+from const4 %1.num < 0
+uses GENREG
+       gen move {const4, 0-%1.num}, %a
+           RSB %a, %a, {fitcon, 0}             yields %a
+
+from const4 illegal(%1.num) && (%1.num >= 0)
+uses GENREG
        gen move %1, %a                         yields %a
 
-from const4 fitins(%1.num)                      yields {fitcon, %num}
+from const4 legal(%1.num) && %1.num >= 0       yields {fitcon, %num}
 
 from STACK
-uses REG
-       gen move {autoid, SP}, %a               yields %a
+uses GENREG
+       gen LDMFD {autoid, SP}, {reglist1, %a}  yields %a
 
-from address 
-uses REG
+from address
+uses GENREG
        gen move %1, %a                         yields %a
 
-from REGcon 
-uses REG
+from REGcon
+uses GENREG
        gen move %1, %a                         yields %a
-       
+
 from addr_external
-uses REG
+uses GENREG
        gen move %1, %a
                                                yields %a
 
-from addr_local
-uses REG
-       gen ADD %a, LB, {const4, %1.ind}        yields %a
+from addr_local legal(%1.ind)
+uses GENREG
+       gen ADD %a, LB, {fitcon, %1.ind}        yields %a
+
+from addr_local illegal(%1.ind)
+uses GENREG
+       gen move {const4, %1.ind}, %a
+           ADD %a, LB, %a                      yields %a
+
+from naddr_local legal(%1.ind)
+uses GENREG
+       gen SUB %a, LB, {fitcon, %1.ind}        yields %a
 
-from regconst
-uses REG
+from naddr_local illegal(%1.ind)
+uses GENREG
+       gen move {const4, %1.ind}, %a
+           SUB %a, LB, %a                      yields %a
+
+from regconst legal(%1.ind) && (%1.ind > 0)
+uses GENREG
        gen ADD %a, %1                          yields %a
 
-from regplusreg 
-uses REG
+from regconst minlegal(%1.ind)
+uses GENREG
+       gen SUB %a, %1.reg, {fitcon, 0-%1.ind}  yields %a
+
+from regconst minillegal(%1.ind)
+uses GENREG
+       gen move {const4, 0-%1.ind}, %a
+           SUB %a, %a, %1.reg                  yields %a
+
+from regconst illegal(%1.ind)
+uses GENREG
+       gen move {const4, %1.ind}, %a
+           ADD %a, %a, %1.reg                  yields %a
+
+from regplusreg
+uses GENREG
        gen ADD %a, %1.reg1, %1.reg2
                                                yields %a
 
-from regminreg 
-uses REG
+from regminreg
+uses GENREG
        gen SUB %a, %1.reg1, %1.reg2
                                                yields %a
 
-from regplusiSreg 
-uses REG
+from regplusiSreg
+uses GENREG
        gen ADD %a, %1.reg1, {imS, %1.reg2, %1.S, %1.shift}
                                                yields %a
 
-from regminiSreg 
-uses REG
+from regminiSreg
+uses GENREG
        gen SUB %a, %1.reg1, {imS, %1.reg2, %1.S, %1.shift}
                                                yields %a
 
-from regplusrSreg 
-uses REG
+from regplusrSreg
+uses GENREG
        gen ADD %a, %1.reg1, {regS, %1.reg2, %1.S, %1.sreg}
                                                yields %a
 
-from regminrSreg 
-uses REG
+from regminrSreg
+uses GENREG
        gen SUB %a, %1.reg1, {regS, %1.reg2, %1.S, %1.sreg}
                                                yields %a
 
 
 PATTERNS
 
+/************************************************************************
+ *                                                                     *
+ * GROUP 0 :   Register variables                                      *
+ *                                                                     *
+ ************************************************************************/
+
+/* Simple load and store */
+pat lol                        inreg($1)==reg_any
+    yields {LOCAL, $1}
+
+pat lil                        inreg($1)==reg_any
+    yields {regind, regvar($1)}
+
+pat stl                        inreg($1)==reg_any
+with exact const4
+kills local %ind==$1
+gen move %1, {LOCAL, $1}
+with exact fitcon
+kills local %ind==$1
+gen MOV {LOCAL, $1}, %1
+with rhs-constant
+kills local %ind==$1
+       gen MOV {LOCAL, $1}, %1
+with mem4+absolute
+kills local %ind==$1
+       gen LDR {LOCAL, $1}, %1
+with regminreg
+kills local %ind == $1
+       gen SUB {LOCAL, $1}, %1
+with regplusreg+posshifts
+kills local %ind == $1
+       gen ADD {LOCAL, $1}, %1
+with negshifts
+kills local %ind == $1
+       gen SUB {LOCAL, $1}, %1
+
+pat stl        $1==1 && inreg($1)==reg_any
+with rhs
+    kills local %ind==$1
+    gen LDR_B {LOCAL, $1}, %1
+
+pat sil                        inreg($1)==reg_any
+with GENREG
+    kills /*all_except_con*/ address
+    gen move %1, {regind, regvar($1)}
+
+
+/* Increment, decrement, zero                                          */
+pat inl                        inreg($1)==reg_any
+    kills local %ind==$1
+    gen ADD {LOCAL, $1}, {LOCAL, $1}, {fitcon, 1}
+
+pat del                        inreg($1)==reg_any
+    kills local %ind==$1
+    gen SUB {LOCAL, $1}, {LOCAL, $1}, {fitcon, 1}
+
+pat zrl                        inreg($1)==reg_any
+    kills local %ind==$1
+    gen MOV {LOCAL, $1}, {fitcon, 0}
+
+pat lol inc stl                inreg($1)==reg_any && inreg($3)==reg_any
+    kills local %ind==$3
+    gen ADD {LOCAL, $3}, {LOCAL, $1}, {fitcon, 1}
+
+pat lol dec stl                inreg($1)==reg_any && inreg($3)==reg_any
+    kills local %ind==$3
+    gen SUB {LOCAL, $3}, {LOCAL, $1}, {fitcon, 1}
+
+pat lol ngi stl        inreg($1)==reg_any && inreg($3)==reg_any
+    kills local %ind==$3
+    gen RSB {LOCAL, $3}, {LOCAL, $1}, {fitcon, 0}
+
+/* Procedure :  load register, op xx, store register */
+proc lol_op_stl example lol adi stl
+with rhs
+    kills local %ind==$3
+    gen rxx* {LOCAL, $3}, {LOCAL, $1}, %1
+
+pat lol adi stl                inreg($1)==reg_any && inreg($3)==reg_any && $2==4
+    call lol_op_stl("ADD")
+
+pat lol adu stl                leaving lol $1 adi $2 stl $3
+
+pat lol sbi stl                inreg($1)==reg_any && inreg($3)==reg_any && $2==4
+    call lol_op_stl("RSB")
+
+pat lol sbu stl                leaving lol $1 sbi $2 stl $3
+
+pat lol and stl                inreg($1)==reg_any && inreg($3)==reg_any && $2==4
+    call lol_op_stl("AND")
+
+pat lol ior stl                inreg($1)==reg_any && inreg($3)==reg_any && $2==4
+    call lol_op_stl("ORR")
+
+pat lol xor stl                inreg($1)==reg_any && inreg($3)==reg_any && $2==4
+    call lol_op_stl("EOR")
+
+/* Procedure : load register, load constant, op xx, store register */
+proc lol_loc_op_stl example lol loc adi stl
+    kills local %ind==$4
+    gen rxx* {LOCAL, $4}, {LOCAL, $1}, {const4, $2}
+
+pat lol loc adi stl    inreg($1)==reg_any && inreg($4)==reg_any && $3==4
+    call lol_loc_op_stl("ADD")
+
+pat lol loc adu stl    leaving lol $1 loc $2 adi $3 stl $4
+
+pat lol loc sbi stl    inreg($1)==reg_any && inreg($4)==reg_any && $3==4
+    call lol_loc_op_stl("SUB")
+
+pat lol loc sbu stl    leaving lol $1 loc $2 sbi $3 stl $4
+
+pat lol loc and stl    inreg($1)==reg_any && inreg($4)==reg_any && $3==4
+    call lol_loc_op_stl("AND")
+
+pat lol loc ior stl    inreg($1)==reg_any && inreg($4)==reg_any && $3==4
+    call lol_loc_op_stl("ORR")
+
+pat lol loc xor stl    inreg($1)==reg_any && inreg($4)==reg_any && $3==4
+    call lol_loc_op_stl("EOR")
+
+/* Procedure : load register, load register, op xx, store register     */
+proc lol_lol_op_stl example lol lol adi stl
+    kills local %ind==$4
+    gen        rrx* {LOCAL, $4}, {LOCAL, $1}, {LOCAL, $2}
+
+pat lol lol adi stl    inreg($1)==reg_any && inreg($2)==reg_any && 
+                       inreg($4)==reg_any && $3==4
+    call lol_lol_op_stl("ADD")
+
+pat lol lol adu stl    leaving lol $1 lol $2 adi $3 stl $4
+
+pat lol lol sbi stl    inreg($1)==reg_any && inreg($2)==reg_any && 
+                       inreg($4)==reg_any && $3==4
+    call lol_lol_op_stl("SUB")
+
+pat lol lol sbu stl    leaving lol $1 lol $2 sbi $3 stl $4
+
+pat lol lol and stl    inreg($1)==reg_any && inreg($2)==reg_any && 
+                       inreg($4)==reg_any && $3==4
+    call lol_lol_op_stl("AND")
+
+pat lol lol ior stl    inreg($1)==reg_any && inreg($2)==reg_any && 
+                       inreg($4)==reg_any && $3==4
+    call lol_lol_op_stl("ORR")
+
+pat lol lol xor stl    inreg($1)==reg_any && inreg($2)==reg_any && 
+                       inreg($4)==reg_any && $3==4
+    call lol_lol_op_stl("EOR")
+
+/* Shifts                                                              */
+pat lol loc sli stl    inreg($1)==reg_any && inreg($4)==reg_any && $3==4
+    kills local %ind==$4
+    gen MOV {LOCAL, $4}, {reglslcon, regvar($1), $2}
+
+pat lol loc slu stl    leaving lol $1 loc $2 sli $3 stl $4
+
+pat lol loc sri stl    inreg($1)==reg_any && inreg($4)==reg_any && $3==4
+    kills local %ind==$4
+    gen        MOV {LOCAL, $4}, {regasrcon, regvar($1), $2}
+
+pat lol loc sru stl    inreg($1)==reg_any && inreg($4)==reg_any && $3==4
+    kills local %ind==$4
+    gen        MOV {LOCAL, $4}, {reglsrcon, regvar($1), $2}
+
+pat lol lol sli stl    inreg($1)==reg_any && inreg($2)==reg_any &&
+                       inreg($4)==reg_any && $3==4
+    kills local %ind==$4
+    gen MOV {LOCAL, $4}, {reglslreg, regvar($1), regvar($2)}
+
+pat lol lol slu stl    leaving lol $1 lol $2 sli $3 stl $4
+
+pat lol lol sri stl    inreg($1)==reg_any && inreg($2)==reg_any &&
+                       inreg($4)==reg_any && $3==4
+    kills local %ind==$4
+    gen MOV {LOCAL, $4}, {regasrreg, regvar($1), regvar($2)}
+
+pat lol lol sru stl    inreg($1)==reg_any && inreg($2)==reg_any &&
+                       inreg($4)==reg_any && $3==4
+    kills local %ind==$4
+    gen MOV {LOCAL, $4}, {reglsrreg, regvar($1), regvar($2)}
+
+/* Rotates                                                             */
+pat lol loc ror stl    inreg($1)==reg_any && inreg($4)==reg_any && $3==4
+    kills local %ind==$4
+    gen        MOV {LOCAL, $4}, {regrorcon, regvar($1), $2}
+
+pat lol lol ror stl    inreg($1)==reg_any && inreg($2)==reg_any && 
+                       inreg($4)==reg_any && $3==4
+    kills local %ind==$4
+    gen        MOV {LOCAL, $4}, {regrorreg, regvar($1), regvar($2)}
+
+pat lol loc rol stl    inreg($1)==reg_any && inreg($4)==reg_any && $3==4
+    kills local %ind==$4
+    gen        MOV {LOCAL, $4}, {regrorcon, regvar($1), 32-$2}
+
+pat lol lol ror stl    inreg($1)==reg_any && inreg($2)==reg_any &&
+                       inreg($4)==reg_any && $3==4
+    kills local %ind==$4
+    gen        RSB R11, {LOCAL, $2}, {fitcon, 32}
+       MOV {LOCAL, $4}, {regrorregr, regvar($1), R11}
+
+/* code for *p++ and *p-- (integers) */
+pat lol lol adp stl loi $1==$2 && $2==$4 && $5==4 && inreg($1)==reg_any
+kills GENREG
+uses GENREG
+gen LDR %a, {regrelpi, regvar($1), $5}                 yields %a
+
+pat lol lol adp stl sti $1==$2 && $2==$4 && $5==4 && inreg($1)==reg_any
+with GENREG
+kills GENREG
+gen STR %1, {regrelpi, regvar($1), $5}
+
+/* code for *p++ and *p-- (bytes)*/
+pat lol lol adp stl loi $1==$2 && $2==$4 && $5==1 && inreg($1)==reg_any
+kills GENREG
+uses GENREG
+gen LDR_B %a, {regrelpi, regvar($1), $5}               yields %a
+
+pat lol lol adp stl sti $1==$2 && $2==$4 && $5==1 && inreg($1)==reg_any
+with GENREG
+kills GENREG
+gen STR_B %1, {regrelpi, regvar($1), $5}
+
+/* code for *pp->p++ and *pp->p-- (integers) */
+pat lil lil adp sil loi $1==$2 && $2==$4 && $5==4 && inreg($1)==reg_any
+kills GENREG
+uses GENREG,GENREG
+gen LDR %a, {regind, regvar($1)}
+    ADD %b, %a, {fitcon, $3}
+    STR %b, {regind, regvar($1)}
+    LDR %b, {regind, %a}                               yields %b
+
+pat lil lil adp sil sti $1==$2 && $2==$4 && $5==4 && inreg($1)==reg_any
+with GENREG
+kills GENREG
+uses GENREG,GENREG
+gen LDR %a, {regind, regvar($1)}
+    ADD %b, %a, {fitcon, $3}
+    STR %b, {regind, regvar($1)}
+    STR %1, {regind, %a}
+
+/* code for *pp->p++ and *pp->p-- (bytes) */
+pat lil lil adp sil loi $1==$2 && $2==$4 && $5==1 && inreg($1)==reg_any
+kills GENREG
+uses GENREG,GENREG
+gen LDR %a, {regind, regvar($1)}
+    ADD %b, %a, {fitcon, $3}
+    STR %b, {regind, regvar($1)}
+    LDR_B %b, {regind, %a}                             yields %b
+
+pat lil lil adp sil sti $1==$2 && $2==$4 && $5==1 && inreg($1)==reg_any
+with GENREG
+kills GENREG
+uses GENREG,GENREG
+gen LDR %a, {regind, regvar($1)}
+    ADD %b, %a, {fitcon, $3}
+    STR %b, {regind, regvar($1)}
+    STR_B %1, {regind, %a}
+
 /************************************************************************
  *                                                                     *
  * GROUP I :   Load Instructions                                       *
  *                                                                     *
  ************************************************************************/
 
-pat loc fitins($1)             yields {fitcon, $1}
+pat loc $1 < 0                                         yields {const4, $1}
+
+pat loc illegal($1) && $1 >= 0                         yields {const4, $1}
 
-pat loc !(fitins($1))          yields {const4, $1}
+pat loc legal($1)                                      yields {fitcon, $1}
 
-pat ldc                                leaving loc 18
-                                       trp
+pat ldc        leaving loc 18 trp
 
-pat lol                                yields {LOCAL, $1}
+pat lol                                                        yields {lb_local, $1}
 
-pat loe                                yields {absolute, $1}
+pat loe                                                        yields {absolute, $1}
 
-pat lil                                leaving lol $1 loi 4
+pat lil        leaving lol $1 loi 4
 
 pat lof
 with GENREG                    yields {regrel, %1, $1}
-with exact addr_local          yields {LOCAL, %1.ind+$1}
+with exact addr_local          yields {lb_local, %1.ind+$1}
 with exact addr_external       yields {absolute, %1.add+$1}
 with exact regconst            yields {regrel, %1.reg, $1+%1.ind}
 
-pat lal                                yields {addr_local, $1}
+pat lal $1 > 0                 yields {addr_local, $1}
+pat lal $1 < 0                 yields {naddr_local, 0-$1}
+pat lal $1 == 0                        yields LB
 
 pat lae                                yields {addr_external, $1}
+pat lae loi lae sti $2==$4      leaving lae $1 lae $3 blm $2
 
 pat lxl $1==0                  yields LB
 
-pat lxl $1==1                  yields {LOCAL,8}
+pat lxl $1==1                  yields {lb_local,8}
 
 pat lxl $1>1
-uses REG={const4, $1}, REG=LB
-gen move {regrel, %b, 8}, %b
+uses GENREG={const4, $1}, GENREG=LB
+gen LABEL {label, "1:"}
+    move {regrel, %b, 8}, %b
     SUB_S %a, %a, {fitcon,1}
     BNE {label,"1B"}           yields %b
 
 pat lxa $1==0                  yields {addr_local,8}
 
 pat lxa $1==1
-uses REG={LOCAL,8}             yields {regconst,%a,8}
+uses GENREG={lb_local,8}               yields {regconst,%a,8}
 
 
 pat lxa $1>1
-uses REG={const4, $1}, REG=LB
-gen move {regrel, %b, 8}, %b
+uses GENREG={const4, $1}, GENREG=LB
+gen LABEL {label, "1:"}
+    move {regrel, %b, 8}, %b
     SUB_S %a, %a, {fitcon,1}
     BNE {label,"1B"}           yields {regconst, %b, 8}
 
 pat loi $1==1
 with GENREG
-uses REG
-gen LDR_B %a, {regind, %1}     yields %a
+uses GENREG
+gen LDR_B %a, {regind, %1}                                     yields %a
+with exact naddr_local
+uses GENREG
+gen LDR_B %a, {lb_local, 0-%1.ind}                             yields %a
 with exact addr_local
-uses REG
-gen LDR_B %a, {LOCAL, %1.ind}  yields %a
+uses GENREG
+gen LDR_B %a, {lb_local, %1.ind}                               yields %a
 with exact addr_external
-uses REG
-gen LDR_B %a, {absolute, %1.add}       yields %a
+uses GENREG
+gen LDR_B %a, {absolute, %1.add}                               yields %a
 with exact regconst
-uses REG
-gen LDR_B %a, {regrel, %1.reg, %1.ind} yields %a
+uses GENREG
+gen LDR_B %a, {regrel, %1.reg, %1.ind}                         yields %a
 with exact regplusreg
-uses REG
-gen LDR_B %a, {regregrel, %1.reg1, %1.reg2}    yields %a
+uses GENREG
+gen LDR_B %a, {regregrel, %1.reg1, %1.reg2}                    yields %a
 with exact regminreg
-uses REG
-gen LDR_B %a, {regminregrel, %1.reg1, %1.reg2} yields %a
+uses GENREG
+gen LDR_B %a, {regminregrel, %1.reg1, %1.reg2}                 yields %a
 with exact regplusiSreg
-uses REG
+uses GENREG
 gen LDR_B %a, {regiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2}  yields %a
 with exact regminiSreg
-uses REG
-gen LDR_B %a, {regminiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2}       yields %a
+uses GENREG
+gen LDR_B %a, {regminiSregrel,%1.reg1,%1.S,%1.shift,%1.reg2}   yields %a
+
 with exact regplusrSreg
-uses REG
-gen LDR_B %a, {regrSregrel, %1.reg1, %1.S, %1.sreg, %1.reg2}   yields %a
+uses GENREG,GENREG
+gen move {regS,%1.reg2,%1.S,%1.sreg}, %b
+    LDR_B %a, {regregrel, %1.reg1, %b}                         yields %a
+
 with exact regminrSreg
-uses REG
-gen LDR_B %a, {regminrSregrel, %1.reg1, %1.S, %1.sreg, %1.reg2}        yields %a
+uses GENREG
+gen LDR_B %a, {regminrSregrel,%1.reg1,%1.S,%1.sreg,%1.reg2}    yields %a
 
 pat loi $1==2
 with GENREG
-uses REG, REG
+uses GENREG, GENREG
 gen LDR_B %a, {regind, %1}
     LDR_B %b, {regrel, %1, 1}
-    ADD %a, %a, {imS, %b, "LSL", 8}    yields %a
+    ADD %a,%a,{imS,%b,"LSL",8} yields %a
 
 pat loi $1==4
 with GENREG                    yields {regind, %1}
-with exact addr_local          yields {LOCAL, %1.ind}
+with exact addr_local          yields {lb_local, %1.ind}
+with exact naddr_local         yields {lb_local, 0-%1.ind}
 with exact addr_external       yields {absolute, %1.add}
 with exact regconst            yields {regrel, %1.reg, %1.ind}
-with exact regplusreg          yields {regregrel, %1.reg1, %1.reg2}    
-with exact regminreg           yields {regminregrel, %1.reg1, %1.reg2} 
-with exact regplusiSreg         yields {regiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2} 
-with exact regminiSreg  yields {regminiSregrel,%1.reg1,%1.S,%1.shift,%1.reg2}  
-with exact regplusrSreg         yields {regrSregrel, %1.reg1, %1.S, %1.sreg, %1.reg2}  
-with exact regminrSreg  yields {regminrSregrel,%1.reg1,%1.S,%1.sreg,%1.reg2}   
+with exact regplusreg          yields {regregrel, %1.reg1, %1.reg2}
+with exact regminreg           yields {regminregrel, %1.reg1, %1.reg2}
+with exact regplusiSreg                yields {regiSregrel,%1.reg1,%1.S,
+                                                   %1.shift,%1.reg2}
+with exact regminiSreg         yields {regminiSregrel,%1.reg1,%1.S,
+                                                      %1.shift,%1.reg2}
+with exact regplusrSreg
+uses GENREG,GENREG
+gen move {regS,%1.reg2,%1.S,%1.sreg}, %b
+    LDR %a, {regregrel, %1.reg1, %b}           yields %a
+
+with exact regminrSreg                         yields {regminrSregrel,%1.reg1,
+                                                         %1.S,%1.sreg,%1.reg2}
 
 pat loi $1==8
 with GENREG
-uses REG, REG
-gen LDMIA %1, {reglist2, %a, %b}       yields %b %a
+uses GENREG, GENREG
+gen LDMIA %1, {reglist2, %a, %b}               yields %b %a
 
 pat loi defined($1)
 with GENREG STACK
-kills ALL
-uses REG = {const4, $1}
+uses GENREG = {const4, $1}
 gen LABEL {label, "1:"}
     SUB_S %a, %a, {fitcon, 4}
     move {regregrel, %1, %a}, R11
-    move R11, {autoid, SP}
-    BLT {label, "1b"}
+    STMFD {autoid, SP}, {reglist1, R11}
+    BGT {label, "1b"}
+
+pat loi loc and $1==2 && $2>0 && $2<256  leaving loi 1 loc $2 and $3
 
-pat los $1==4
+pat loi loc loc cii $1==2 && $2==2 && $3==4
+with GENREG
+uses GENREG,GENREG
+gen LDR_B %a, {regind, %1}
+    LDR_B %b, {regrel, %1, 1}
+    MOV   %b, {imS, %b, "LSL", 24}
+    ORR   %a, %a, {imS, %b, "ASR", 16}                 yields %a
+
+pat los
 with STACK
 kills ALL
 gen BAL_L {label, ".los"}
 
-pat ldl                                yields {LOCAL, $1+4}
-                                      {LOCAL, $1}
+pat ldl                                yields {lb_local, $1+4}
+                                       {lb_local, $1}
 
 pat lde                                yields {absolute, $1+4}
                                       {absolute, $1}
@@ -413,14 +967,14 @@ pat lde                           yields {absolute, $1+4}
 pat ldf
 with GENREG                    yields {regrel, %1, $1+4}
                                       {regrel, %1, $1}
-with exact addr_local          yields {LOCAL, %1.ind+$1+4}
-                                      {LOCAL, %1.ind+$1}
+with exact addr_local          yields {lb_local, %1.ind+$1+4}
+                                      {lb_local, %1.ind+$1}
 with exact addr_external       yields {absolute, %1.add+$1+4}
                                       {absolute, %1.add+$1}
 with exact regconst            yields {regrel, %1.reg, $1+%1.ind+4}
                                       {regrel, %1.reg, $1+%1.ind}
 
-pat lpi                                yields {addr_external, $1}
+pat lpi                                        yields {addr_external,$1}
 
 /************************************************************************
  *                                                                     *
@@ -430,15 +984,20 @@ pat lpi                           yields {addr_external, $1}
 
 pat stl
 with GENREG
-kills address-(absolute+LOCAL), LOCAL %ind-4 < $1 && %ind+4 > $1
-       gen move %1, {LOCAL, $1}
+kills address-(absolute+lb_local), lb_local %ind-4 < $1 && %ind+4 > $1
+       gen move %1, {lb_local, $1}
+
+pat stl lol $1==$2             leaving dup 4 stl $1
 
 pat ste
 with GENREG
 kills address
        gen move %1, {absolute, $1}
 
-pat sil                                        leaving lol $1 sti 4
+pat ste loe $1==$2
+       leaving dup 4 ste $1
+
+pat sil        leaving lol $1 sti 4
 
 pat stf
 with GENREG GENREG
@@ -446,7 +1005,7 @@ kills address
        gen move %2, {regrel, %1, $1}
 with addr_local GENREG
 kills address
-       gen move %2, {LOCAL, %1.ind + $1}
+       gen move %2, {lb_local, %1.ind + $1}
 with addr_external GENREG
 kills address
        gen move %2, {absolute, %1.add + $1}
@@ -460,7 +1019,7 @@ kills address
        gen STR_B %2, {regind, %1}
 with  addr_local GENREG
 kills address
-       gen STR_B %2, {LOCAL, %1.ind}
+       gen STR_B %2, {lb_local, %1.ind}
 with  addr_external GENREG
 kills address
        gen STR_B %2, {absolute, %1.add}
@@ -470,38 +1029,50 @@ kills address
 with  regplusreg GENREG
 kills address
        gen STR_B %2, {regregrel, %1.reg1, %1.reg2}
-with  regminreg GENREG 
+with  regminreg GENREG
 kills address
-       gen STR_B %2, {regminregrel, %1.reg1, %1.reg2}  
+       gen STR_B %2, {regminregrel, %1.reg1, %1.reg2}
 with  regplusiSreg GENREG
 kills address
-       gen STR_B %2, {regiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2}   
+       gen STR_B %2, {regiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2}
 with  regminiSreg GENREG
 kills address
-       gen STR_B %2, {regminiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2}        
+       gen STR_B %2, {regminiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2}
+
 with  regplusrSreg GENREG
 kills address
-       gen STR_B %2, {regrSregrel, %1.reg1, %1.S, %1.sreg, %1.reg2}    
+uses GENREG
+gen move {regS, %1.reg2, %1.S, %1.sreg}, %a
+    STR_B %2, {regregrel, %1.reg1, %a}
+
 with  regminrSreg GENREG
 kills address
-       gen STR_B %2, {regminrSregrel, %1.reg1, %1.S, %1.sreg, %1.reg2} 
+       gen STR_B %2, {regminrSregrel, %1.reg1, %1.S, %1.sreg, %1.reg2}
 
 pat sti $1==2
 with GENREG GENREG
 kills address
-uses REG
+/*uses GENREG
 gen move {imS, %2, "LSR", 8}, %a
     SUB %2, %2, {imS, %a, "LSL", 8}
     STR_B %2, {regind, %1}
     STR_B %a, {regrel, %1, 1}
-
+*/
+gen STR_B %2, {regind, %1}
+    MOV   %2, {imS, %2, "LSR", 8}
+    STR_B %2, {regrel, %1, 1}
+/*with GENREG fitcon %2.num==0
+kills address
+gen STR_B %2, {regind, %1}
+    STR_B %2, {regrel, %1, 1}
+*/
 pat sti $1==4
 with GENREG GENREG
 kills address
        gen move %2, {regind, %1}
 with addr_local GENREG
 kills address
-       gen move %2, {LOCAL, %1.ind}
+       gen move %2, {lb_local, %1.ind}
 with addr_external GENREG
 kills address
        gen move %2, {absolute, %1.add}
@@ -511,34 +1082,48 @@ kills address
 with  regplusreg GENREG
 kills address
        gen move %2, {regregrel, %1.reg1, %1.reg2}
-with  regminreg GENREG 
+with  regminreg GENREG
 kills address
-       gen move %2, {regminregrel, %1.reg1, %1.reg2}   
+       gen move %2, {regminregrel, %1.reg1, %1.reg2}
 with  regplusiSreg GENREG
 kills address
-       gen move %2, {regiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2}    
+       gen move %2, {regiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2}
 with  regminiSreg GENREG
 kills address
-       gen move %2, {regminiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2} 
+       gen move %2, {regminiSregrel, %1.reg1, %1.S, %1.shift, %1.reg2}
 with  regplusrSreg GENREG
 kills address
-       gen move %2, {regrSregrel, %1.reg1, %1.S, %1.sreg, %1.reg2}     
+uses GENREG
+gen move {regS, %1.reg2, %1.S, %1.sreg}, %a
+    STR %2, {regregrel, %1.reg1, %a}
 with  regminrSreg GENREG
 kills address
-       gen move %2, {regminrSregrel, %1.reg1, %1.S, %1.sreg, %1.reg2}  
+       gen move %2, {regminrSregrel, %1.reg1, %1.S, %1.sreg, %1.reg2}
 
-pat sti defined($1)
+pat sti defined($1) && legal($1)
 with GENREG STACK
-kills ALL
-uses REG={const4, $1}
+kills address
+uses GENREG={fitcon, $1}
 gen    LABEL {label, "1:"}
        SUB_S %a, %a, {fitcon, 4}
-       move {regregrel, SP, %a}, R11
+       move {st_regregrel, SP, %a}, R11
        move R11, {regregrel, %1, %a}
-       BLT {label,"1B"}
-       ADD SP, SP, {const4, $1}
+       BGT {label,"1B"}
+       ADD SP, SP, {fitcon, $1}
 
-pat sts $1==4
+pat sti defined($1)
+with GENREG STACK
+kills address
+uses GENREG={const4, $1}, GENREG
+gen    move %a, %b
+       LABEL {label, "1:"}
+       SUB_S %a, %a, {fitcon, 4}
+       move {st_regregrel, SP, %a}, R11
+       move R11, {regregrel, %1, %a}
+       BGT {label,"1B"}
+       ADD SP, SP, %b
+
+pat sts
 with STACK
 kills ALL
 gen BAL_L {label, ".sts"}
@@ -546,8 +1131,8 @@ gen BAL_L {label, ".sts"}
 pat sdl
 with GENREG GENREG
 kills address-absolute
-gen    move %1, {LOCAL,$1}
-       move %2, {LOCAL,$1+4}
+gen    move %1, {lb_local,$1}
+       move %2, {lb_local,$1+4}
 
 pat sde
 with GENREG GENREG
@@ -568,44 +1153,64 @@ gen      move %2, {regrel, %1, $1}
  ************************************************************************/
 
 pat adi $1==4
-with GENREG const4                     yields {regconst, %1, %2.num}
-with const4 GENREG                     yields {regconst, %2, %1.num}
+with GENREG constant                   yields {regconst, %1, %2.num}
+with constant GENREG                   yields {regconst, %2, %1.num}
 with GENREG GENREG                     yields {regplusreg, %1, %2}
-with GENREG imS                        yields {regplusiSreg,%1, %2.S, %2.shift, %2.reg}
-with imS GENREG                yields {regplusiSreg,%2, %1.S, %1.shift, %1.reg}
-with GENREG regS               yields {regplusrSreg,%1, %2.S, %2.sreg, %2.reg}
-with regS GENREG               yields {regplusrSreg,%2, %1.S, %1.sreg, %1.reg}
-with exact addr_local const4           yields {addr_local, %1.ind+%2.num}
-with exact const4 addr_local           yields {addr_local, %2.ind+%1.num}
-with exact addr_external const4                yields {addr_external, %1.add+%2.num}
-with exact const4 addr_external                yields {addr_external, %2.add+%1.num}
+with GENREG imS                                yields {regplusiSreg,%1, %2.S,
+                                                       %2.shift, %2.reg}
+with imS GENREG                        yields {regplusiSreg,%2, %1.S,
+                                                       %1.shift, %1.reg}
+with GENREG regS                       yields {regplusrSreg,%1, %2.S,
+                                                       %2.sreg, %2.reg}
+with regS GENREG                       yields {regplusrSreg,%2, %1.S,
+                                                       %1.sreg, %1.reg}
+with exact addr_local constant         yields {addr_local, %1.ind+%2.num}
+with exact constant addr_local                 yields {addr_local, %2.ind+%1.num}
+with exact addr_external constant      yields {addr_external, %1.add+%2.num}
+with exact constant addr_external      yields {addr_external, %2.add+%1.num}
 
 pat sbi $1==4
 with GENREG GENREG                     yields {regminreg, %2, %1}
-with imS GENREG                        yields {regminiSreg,%2,%1.S,%1.shift,%1.reg}
-with regS GENREG               yields {regminrSreg,%2,%1.S,%1.sreg,%1.reg}
+with imS GENREG                                yields {regminiSreg,%2,%1.S,
+                                                       %1.shift,%1.reg}
+with regS GENREG                       yields {regminrSreg,%2,%1.S,
+                                                       %1.sreg,%1.reg}
+with GENREG fitcon
+uses GENREG
+gen RSB  %a, %1, %2                    yields %a
+with fitcon GENREG
+gen SUB %2, %2, %1                     yields %2
+with GENREG const4
+uses GENREG
+gen move %2, %a
+    RSB  %1, %1, %a                    yields %1
+with const4 GENREG
+uses GENREG
+gen move %1, %a
+    SUB  %a, %2, %a                    yields %a
 with GENREG REGcon
-gen    RSB %1, %1, %2                  yields %1
-with const4 GENREG                     yields {regconst, %2, 0-%1.num}
-with exact const4 addr_local           yields {addr_local, %2.ind-%1.num}
+uses GENREG
+gen    RSB %a, %1, %2                  yields %a
+/*with constant GENREG                 yields {regconst, %2, 0-%1.num}*/
+with exact constant addr_local         yields {addr_local, %2.ind-%1.num}
 
 pat loc mli $1<0 && $2==4              leaving loc 0-$1
                                                mli 4
                                                ngi 4
 
-pat loc mli $1==2 && $2==4             
+pat loc mli $1==2 && $2==4
 with GENREG                            yields {imS, %1, "LSL", 1}
 
-pat loc mli $1==4 && $2==4             
+pat loc mli $1==4 && $2==4
 with GENREG                            yields {imS, %1, "LSL", 2}
 
-pat loc mli $1==8 && $2==4             
+pat loc mli $1==8 && $2==4
 with GENREG                            yields {imS, %1, "LSL", 3}
 
-pat loc mli $1==16 && $2==4            
+pat loc mli $1==16 && $2==4
 with GENREG                            yields {imS, %1, "LSL", 4}
 
-pat loc mli $1==32 && $2==4            
+pat loc mli $1==32 && $2==4
 with GENREG                            yields {imS, %1, "LSL", 5}
 
 pat loc mli $1==3 && $2==4
@@ -616,25 +1221,28 @@ with GENREG                              yields {regplusiSreg,%1,"LSL",2,%1}
 
 pat loc mli $1==6 && $2==4
 with GENREG
-gen ADD %1, %1, {imS, %1, "LSL", 2}    yields {regplusiSreg,%1,"LSR",2,%1}
+uses GENREG
+gen MOV %a, {imS,%1,"LSL",2}
+    ADD %a, %a, {imS,%1,"LSL",1}        yields %a
 
 pat loc mli $1==7 && $2==4
 with GENREG
-gen RSB %1, %1, {imS, %1, "LSL", 3}    yields %1
+uses GENREG
+gen RSB %a, %1, {imS, %1, "LSL", 3}    yields %a
 
 pat loc mli $1==9 && $2==4
-with GENREG
 with GENREG                            yields {regplusiSreg,%1,"LSL",3,%1}
 
 pat loc mli $1==10 && $2==4
 with GENREG
-uses REG
-gen ADD %1, %1, {imS, %1, "LSL", 3}    
-    ADD %1, %1, {imS, %1, "LSR", 3}    yields %1
+uses GENREG
+gen MOV %a,{imS, %1, "LSL", 1}
+    ADD %a, %a, {imS, %1, "LSL", 3}    yields %a
 
 pat loc mli $1==12 && $2==4
 with GENREG
-gen move {imS, %1, "LSL", 3}, %1       yields {regplusiSreg,%1,"LSR",1,%1}
+uses GENREG
+gen move {imS, %1, "LSL", 3}, %a       yields {regplusiSreg,%a,"LSR",1,%a}
 
 pat mli $1==4
 with STACK
@@ -643,22 +1251,6 @@ gen       BAL_L {label, ".mli"}           yields R0
 
 pat loc dvi $1<0 && $2==4              leaving loc 0-$1
                                                dvi 4
-                                               ngi 4
-
-pat loc dvi $1==2 && $2==4     
-with GENREG                            yields {imS, %1, "ASR", 1}
-
-pat loc dvi $1==4 && $2==4     
-with GENREG                            yields {imS, %1, "ASR", 2}
-
-pat loc dvi $1==8 && $2==4     
-with GENREG                            yields {imS, %1, "ASR", 3}
-
-pat loc dvi $1==16 && $2==4    
-with GENREG                            yields {imS, %1, "ASR", 4}
-
-pat loc dvi $1==32 && $2==4    
-with GENREG                            yields {imS, %1, "ASR", 5}
 
 pat dvi $1==4
 with STACK
@@ -672,17 +1264,18 @@ gen      BAL_L {label, ".dvi"}           yields R2
 
 pat ngi $1==4
 with GENREG
-gen    RSB %1, %1, {fitcon, 0}         yields %1
+uses GENREG
+gen    RSB %a, %1, {fitcon, 0}         yields %a
 
 pat sli $1==4
-with const4 GENREG                     yields {imS, %2, "LSL", %1.num}
+with fitcon GENREG                     yields {imS, %2, "LSL", %1.num}
 with GENREG GENREG                     yields {regS, %2, "LSL", %1}
 
-pat loc sri $1==0 && $2==4             
+pat loc sri $1==0 && $2==4
 with address+REGcon                    yields %1
 
 pat sri $1==4
-with const4 GENREG                     yields {imS, %2, "ASR", %1.num}
+with fitcon GENREG                     yields {imS, %2, "ASR", %1.num}
 with GENREG GENREG                     yields {regS, %2, "ASR", %1}
 
 
@@ -719,11 +1312,11 @@ gen      BAL_L {label, ".dvu"}           yields R2
 
 pat slu $1==4
 with GENREG GENREG                     yields {regS, %2, "LSL", %1}
-with const4 GENREG                     yields {imS, %2, "LSL", $1}
+with const4+fitcon GENREG              yields {imS, %2, "LSL", %1.num}
 
 pat sru $1==4
 with GENREG GENREG                     yields {regS, %2, "LSR", %1}
-with const4 GENREG                     yields {imS, %2, "LSR", $1}
+with const4+fitcon GENREG              yields {imS, %2, "LSR", %1.num}
 
 /************************************************************************
  *                                                                     *
@@ -731,26 +1324,69 @@ with const4 GENREG                       yields {imS, %2, "LSR", $1}
  *                                                                     *
  ************************************************************************/
 
- pat adf                               leaving loc 18
-                                               trp
-
- pat sbf                               leaving loc 18
-                                               trp
-
- pat mlf                               leaving loc 18
-                                               trp
-
- pat dvf                               leaving loc 18
-                                               trp
-
- pat  ngf                              leaving loc 18
-                                               trp
-
- pat fif                               leaving loc 18
-                                               trp
-
- pat fef                               leaving loc 18
-                                               trp
+ pat adf $1==8
+ with STACK
+ kills ALL
+ leaving cal ".adf8" asp 16 lfr 4 loi 8
+ pat adf $1==4
+ with STACK
+ kills ALL
+ leaving cal ".adf4" asp 8 lfr 4
+
+ pat sbf $1==8
+ with STACK
+ kills ALL
+ leaving cal ".sbf8" asp 16 lfr 4 loi 8
+ pat sbf $1==4
+ with STACK
+ kills ALL
+ leaving cal ".sbf4" asp 8 lfr 4
+
+ pat mlf $1==8
+ with STACK
+ kills ALL
+ leaving cal ".mlf8" asp 16 lfr 4 loi 8
+ pat mlf $1==4
+ with STACK
+ kills ALL
+ leaving cal ".mlf4" asp 8 lfr 4
+
+ pat dvf $1==8
+ with STACK
+ kills ALL
+ leaving cal ".dvf8" asp 8
+ pat dvf $1==4
+ with STACK
+ kills ALL
+ leaving cal ".dvf4" asp 4
+
+ pat ngf $1==8
+ with STACK
+ kills ALL
+ leaving cal ".ngf8"
+ pat ngf $1==4
+ with STACK
+ kills ALL
+ leaving cal ".ngf4"
+
+ pat fif $1==8
+ with STACK
+ kills ALL
+ leaving cal ".fif8"
+ pat fif $1==4
+ with STACK
+ kills ALL
+ leaving cal ".fif4"
+
+/* the next two need a 4 byte hole on the stack */
+ pat ldl fef $2==8
+ with STACK
+ kills ALL
+ leaving loc 0 ldl $1 cal ".fef8"
+ pat lol fef $2==4
+ with STACK
+ kills ALL
+ leaving loc 0 lol $1 cal ".fef4"
 
 /************************************************************************
  *                                                                     *
@@ -780,43 +1416,44 @@ with exact regconst                      yields {regconst, %1.reg, %1.ind+1}
 
 pat inl
 kills address-absolute
-uses REG={LOCAL,$1}
-gen ADD %a,%a,{const4,1}
-    move %a,{LOCAL,$1}
+uses GENREG={lb_local,$1}
+gen ADD %a,%a,{fitcon,1}
+    move %a,{lb_local,$1}
 
 pat ine
-kills address                  
-uses REG={absolute,$1}
-gen ADD %a,%a,{const4,1}
+kills address
+uses GENREG={absolute,$1}
+gen ADD %a,%a,{fitcon,1}
     move %a,{absolute,$1}
 
 pat dec
 with GENREG                            yields {regconst, %1, 0-1}
+/*gen SUB %a, %1, {fitcon, 1}*/
+with exact regconst                    yields {regconst, %1.reg, %1.ind-1}
 
 pat del
 kills address-absolute
-uses REG={LOCAL,$1}
+uses GENREG={lb_local,$1}
 gen SUB %a,%a,{fitcon,1}
-    move %a,{LOCAL,$1}
+    move %a,{lb_local,$1}
 
 pat dee
-kills address                  
-uses REG={absolute,$1}
+kills address
+uses GENREG={absolute,$1}
 gen SUB %a,%a,{fitcon,1}
     move %a,{absolute,$1}
 
 pat zrl
 kills address-absolute
-uses REG={fitcon,0}
-gen move %a,{LOCAL,$1}
+uses GENREG={fitcon,0}
+gen move %a,{lb_local,$1}
 
 pat zre
 kills address
-uses REG={fitcon,0}
+uses GENREG={fitcon,0}
 gen move %a,{absolute,$1}
 
-pat zrf                                        leaving loc 18
-                                               trp
+pat zrf        leaving zer $1
 
 pat zer $1==4                          yields {fitcon,0}
 
@@ -827,12 +1464,11 @@ pat zer $1==12                           yields {fitcon,0} {fitcon,0} {fitcon,0}
 pat zer defined($1)
 with STACK
 kills ALL
-uses REG={fitcon,0},REG={const4,$1}
+uses GENREG={fitcon,0},GENREG={const4,$1}
 gen LABEL {label, "1:"}
-    move %a,{autoid,SP}
+    STMFD {autoid, SP}, {reglist1, %a}
     SUB_S %b,%b,{fitcon,4}
     BNE {label,"1B"}
-    move R14,PC
 
 /************************************************************************
  *                                                                     *
@@ -840,17 +1476,45 @@ gen LABEL {label, "1:"}
  *                                                                     *
  ************************************************************************/
 
-pat cii
-with address + REGcon address + REGcon
+/* sign extension short -> integer */
+pat loc loc cii $1==2 && $2==4
+with GENREG
+uses GENREG
+gen MOV %a, {imS, %1, "LSL", 16}
+    MOV %a, {imS, %a, "ASR", 16}               yields %a
+
+/* sign extension byte -> integer */
+pat loc loc cii $1==1 && $2==4
+with GENREG
+uses GENREG
+gen MOV %a, {imS, %1, "LSL", 24}
+    MOV %a, {imS, %a, "ASR", 24}               yields %a
+
+pat loc loc cii ($1 > 2)
 
 pat cui
 with address +REGcon address + REGcon
 
-pat cfi                                        leaving loc 18 trp
-pat cif                                        leaving loc 18 trp
-pat cuf                                        leaving loc 18 trp
-pat cff                                        leaving loc 18 trp
-pat cfu                                        leaving loc 18 trp
+pat loc loc cif        $1==4 && $2==4 leaving loc 4 cal ".cif4" asp 8 lfr 4
+pat loc loc cif        $1==4 && $2==8 leaving loc 4 cal ".cif8" asp 8 lfr 4 loi 8
+
+pat loc loc cuf        $1==4 && $2==4 leaving loc 4 cal ".cuf4" asp 8 lfr 4
+pat loc loc cuf        $1==4 && $2==8 leaving loc 4 cal ".cuf8"
+
+pat loc loc cfi        $1==8 && $2==4
+               leaving loc $1 loc $2 cal ".cfi" asp 16 lfr 4
+pat loc loc cfi $1==4 && $2==4
+               leaving loc $1 loc $2 cal ".cfi" asp 12 lfr 4
+
+pat loc loc cfu $1==8 && $2==4
+               leaving loc $1 loc $2 cal ".cfu" asp 16 lfr 4
+pat loc loc cfu $1==4 && $2==4
+               leaving loc $1 loc $2 cal ".cfu" asp 12 lfr 4
+
+pat loc loc cff        $1==8 && $2==4 leaving cal ".cff4" asp 4
+
+/* this one expects a 4 byte hole on the stack */
+pat loc loc cff        $1==4 && $2==8  leaving dup 4 cal ".cff8"
 
 pat ciu
 with address +REGcon address + REGcon
@@ -866,89 +1530,115 @@ with address +REGcon address + REGcon
 
 pat and $1==4
 with REGcon GENREG
-gen AND %2, %2, %1                     yields %2
+uses GENREG
+gen AND %a, %2, %1                     yields %a
 with GENREG REGcon
-gen AND %1, %1, %2                     yields %1
+uses GENREG
+gen AND %a, %1, %2                     yields %a
 
 pat ior $1==4
 with REGcon GENREG
-gen ORR %2, %2, %1                     yields %2
+uses GENREG
+gen ORR %a, %2, %1                     yields %a
 with GENREG REGcon
-gen ORR %1, %1, %2                     yields %1
+uses GENREG
+gen ORR %a, %1, %2                     yields %a
 
 pat xor $1==4
 with REGcon GENREG
-gen EOR %2, %2, %1                     yields %2
+uses GENREG
+gen EOR %a, %2, %1                     yields %a
 with GENREG REGcon
-gen EOR %1, %1, %2                     yields %1
+uses GENREG
+gen EOR %a, %1, %2                     yields %a
 
 pat com $1==4
 with REGcon
-uses REG
+uses GENREG
 gen MVN %a,%1                          yields %a
 
 pat ror $1==4
-with const4 GENREG                     yields {imS, %2, "ROR", %1.num}
+with constant GENREG                   yields {imS, %2, "ROR", %1.num}
 with GENREG GENREG                     yields {regS, %2, "ROR", %1}
 
 pat rol $1==4
-with const4 GENREG                     yields {imS, %2, "ROR", 32-%1.num}
+with constant GENREG                   yields {imS, %2, "ROR", 32-%1.num}
 with GENREG GENREG
-gen RSB %1, %1, {fitcon,32}            yields {regS, %2, "ROR", %1}
+uses GENREG
+gen RSB %a, %1, {fitcon,32}            yields {regS, %2, "ROR", %a}
 
 pat and $1>4
 with STACK
-gen move {const4,$1}, R1
-    move SP, R0
-    ADD SP, SP, R1
+kills ALL
+uses GENREG,GENREG,GENREG,GENREG
+gen move {const4,$1}, %b
+    move SP, %a
+    ADD SP, SP, %b
     LABEL {label, "1:"}
-    SUB_S R1, R1, {fitcon, 4}
-    move {regregrel,SP,R1},R2
-    move {regregrel,R0,R1},R3
-    AND R2, R2, R3
-    move R2, {regregrel,SP,R1}
+    SUB_S %b, %b, {fitcon, 4}
+    move {st_regregrel, SP,%b}, %c
+    move {regregrel, %a, %b}, %d
+    AND %c, %c, %d
+    move %c, {st_regregrel, SP, %b}
     BNE {label, "1B"}
-    move R14,PC
 
 pat ior $1>4
 with STACK
-gen move {const4,$1}, R1
-    move SP, R0
-    ADD SP, SP, R1
+kills ALL
+uses GENREG,GENREG,GENREG,GENREG
+gen move {const4,$1}, %b
+    move SP, %a
+    ADD SP, SP, %b
     LABEL {label, "1:"}
-    SUB_S R1, R1, {fitcon, 4}
-    move {regregrel,SP,R1},R2
-    move {regregrel,R0,R1},R3
-    ORR R2, R2, R3
-    move R2, {regregrel,SP,R1}
+    SUB_S %b, %b, {fitcon, 4}
+    move {st_regregrel, SP,%b}, %c
+    move {regregrel, %a, %b}, %d
+    ORR %c, %c, %d
+    move %c, {st_regregrel, SP, %b}
+    BNE {label, "1B"}
+
+pat ior !defined($1)
+with STACK
+kills ALL
+uses GENREG,GENREG,GENREG,GENREG
+gen LDMFD {autoid, SP}, {reglist1, %b}
+    move SP, %a
+    ADD SP, SP, %b
+    LABEL {label, "1:"}
+    SUB_S %b, %b, {fitcon, 4}
+    move {st_regregrel, SP, %b}, %c
+    move {regregrel, %a, %b}, %d
+    ORR %c, %c, %d
+    move %c, {st_regregrel, SP, %b}
     BNE {label, "1B"}
-    move R14,PC
 
 
 pat xor $1>4
 with STACK
-gen move {const4,$1}, R1
-    move SP, R0
-    ADD SP, SP, R1
+kills ALL
+uses GENREG,GENREG,GENREG,GENREG
+gen move {const4,$1}, %b
+    move SP, %a
+    ADD SP, SP, %b
     LABEL {label, "1:"}
-    SUB_S R1, R1, {fitcon, 4}
-    move {regregrel,SP,R1},R2
-    move {regregrel,R0,R1},R3
-    EOR R2, R2, R3
-    move R2, {regregrel,SP,R1}
+    SUB_S %b, %b, {fitcon, 4}
+    move {st_regregrel, SP,%b}, %c
+    move {regregrel, %a, %b}, %d
+    EOR %c, %c, %d
+    move %c, {st_regregrel, SP, %b}
     BNE {label, "1B"}
-    move R14,PC
 
 pat com $1>4
 with STACK
-gen move {const4,$1}, R1
+kills ALL
+uses GENREG,GENREG,GENREG
+gen move {const4,$1}, %b
     LABEL {label, "1:"}
-    SUB_S R1, R1, {fitcon, 4}
-    move {regregrel,SP,R1},R2
-    MVN R2, R2
-    move R2,{regregrel,SP,R1}
+    SUB_S %b, %b, {fitcon, 4}
+    move {st_regregrel, SP, %b}, %c
+    MVN %c, %c
+    move %c, {st_regregrel, SP, %b}
     BNE {label, "1B"}
-    move R14,PC
 
 /************************************************************************
  *                                                                     *
@@ -960,8 +1650,8 @@ pat loc loc inn !defined($3)               leaving loc $1 inn $2
 
 pat loc inn $2==4 && $1>=0 && $1<32
 with GENREG
-uses REG={fitcon,1}
-gen AND %1, %1, {imS,%a,"LSL",$1}      yields %1
+uses GENREG={fitcon,1},GENREG
+gen AND %b, %1, {imS,%a,"LSL",$1}      yields %b
 
 pat loc inn $2==4 && $1<0
 with GENREG
@@ -972,29 +1662,40 @@ pat loc inn $2==4 && $1>31               leaving loc 2 trp
 pat loc inn !defined($2)               leaving inn $1
 
 pat inn defined($1)
-with STACK
-kills ALL
-gen move {const4,$1}, R0
-    BAL_L {label, ".inn"}              yields R0
+with GENREG STACK
+uses GENREG={fitcon,1}, GENREG, GENREG
+gen AND %b, %1, {fitcon, 31}
+    move {regS, %a, "LSL", %b}, %b
+    move {imS, %1, "LSR", 5}, %1
+    move {st_regiSregrel, SP, "LSL", 2, %1}, %c
+    AND_S %b, %b, %c
+    MOV_NE %b, {fitcon, 1}
+    ADD SP, SP, {const4, $1}            yields %b
 
 pat inn !defined($1)
-with GENREG
-gen move %1, R0
-    BAL_L {label, ".inn"}              yields R0
+with GENREG GENREG STACK
+uses GENREG={fitcon,1}, GENREG, GENREG
+gen AND %b, %2, {fitcon, 31}
+    move {regS, %a, "LSL", %b}, %b
+    move {imS, %2, "LSR", 5}, %2
+    move {st_regiSregrel, SP, "LSL", 2, %2}, %c
+    AND_S %b, %b, %c
+    MOV_NE %b, {fitcon, 1}
+    ADD SP, SP, %1                      yields %b
 
 pat loc set !defined($2)               leaving set $1
 
 pat set $1==4
-with const4 
-uses REG={fitcon,1}                    yields {imS,%a,"LSL",%1.num}
-with GENREG 
-uses REG={fitcon,1}                    yields {regS,%a,"LSL",%1}
+with const4
+uses GENREG={fitcon,1}                         yields {imS,%a,"LSL",%1.num}
+with GENREG
+uses GENREG={fitcon,1}                 yields {regS,%a,"LSL",%1}
 
 pat set $1>4
 with GENREG STACK
-uses REG={fitcon,1}, REG={fitcon,0}, REG={const4,$1}
+uses GENREG={fitcon,1}, GENREG={fitcon,0}, GENREG={const4,$1}
 gen LABEL {label, "2:"}
-    move %b,{autoid, SP}
+    STMFD {autoid, SP}, {reglist1, %b}
     SUB_S %c, %c, {fitcon,4}
     BGT {label, "2B"}
     CMP %1, {fitcon, 0}
@@ -1002,9 +1703,26 @@ gen LABEL {label, "2:"}
     AND %b, %1, {fitcon, 31}
     move {regS, %a, "LSL", %b}, %b
     move {imS, %1, "LSR", 5}, %1
-    move %b, {regiSregrel, SP, "LSL", 2, %1}
+    move %b, {st_regiSregrel, SP, "LSL", 2, %1}
     LABEL {label, "1:"}
 
+pat set !defined($1)
+with STACK
+kills ALL
+uses GENREG={fitcon,1}, GENREG={fitcon,0}, GENREG, GENREG
+gen LDMFD {autoid, SP}, {reglist1, %c}
+    LDMFD {autoid, SP}, {reglist1, %d}
+    LABEL {label, "2:"}
+    STMFD {autoid, SP}, {reglist1, %b}
+    SUB_S %c, %c, {fitcon,4}
+    BGT {label, "2B"}
+    CMP %d, {fitcon, 0}
+    BMI {label, "1F"}
+    AND %b, %d, {fitcon, 31}
+    move {regS, %a, "LSL", %b}, %b
+    move {imS, %d, "LSR", 5}, %d
+    move %b, {st_regiSregrel, SP, "LSL", 2, %d}
+    LABEL {label, "1:"}
 
 /************************************************************************
  *                                                                     *
@@ -1014,54 +1732,86 @@ gen LABEL {label, "2:"}
 
 pat lae aar $2==4 && rom($1,3)==1 && rom($1,1)==0      leaving adi 4
 
+pat lae aar $2==4 && rom($1,3)==1 && rom($1,1)>0 && legal(rom($1,1))
+with GENREG
+uses GENREG
+gen SUB %a,%1,{fitcon,rom($1,1)}               yields %a
+                                               leaving adi 4
+with exact regconst                            yields {regconst, %1.reg,
+                                                       %1.ind-rom($1,1)}
+                                               leaving adi 4
+
 pat lae aar $2==4 && rom($1,3)==1 && rom($1,1)!=0
 with GENREG
-gen ADD %1, %1, {const4, 1-rom($1,1)}          yields %1
+uses GENREG={const4, 0-rom($1,1)}
+gen ADD %a,%1,%a                               yields %a
+                                               leaving adi 4
+with exact regconst                            yields {regconst, %1.reg,
+                                                       %1.ind-rom($1,1)}
                                                leaving adi 4
 
 pat lae aar $2==4 && rom($1,3)==4 && rom($1,1)==0
 with GENREG                                    yields {imS, %1,"LSL",  2}
                                                leaving adi 4
 
+pat lae aar $2==4 && rom($1,3)==4 && rom($1,1)>0 && legal(rom($1,1))
+with GENREG
+uses GENREG
+gen SUB %a,%1,{fitcon, rom($1,1)}              yields {imS, %a,"LSL", 2}
+                                               leaving adi 4
+
 pat lae aar $2==4 && rom($1,3)==4 && rom($1,1)!=0
 with GENREG
-gen ADD %1, %1, {const4, 1-rom($1,1)}          yields {imS, %1,"LSL", 2}
+uses GENREG={const4, 0-rom($1,1)}
+gen ADD %a,%1,%a                               yields {imS, %a,"LSL", 2}
                                                leaving adi 4
 
 pat lae aar $2==4 && rom($1,1)==0
-                                               leaving loc rom($1,3) 
+                                               leaving loc rom($1,3)
+                                                       mli 4 adi 4
+
+pat lae aar $2==4 && rom($1,1)>0 && legal(rom($1,1))
+with GENREG
+uses GENREG
+gen SUB %a,%1,{fitcon,rom($1,1)}               yields %a
+                                               leaving loc rom($1,3)
                                                        mli 4 adi 4
 
 pat lae aar $2==4 && rom($1,1)!=0
 with GENREG
-gen ADD %1, %1, {const4, 1-rom($1,1)}
-                                               yields %1
-                                               leaving loc rom($1,3) 
+uses GENREG={const4, 0-rom($1,1)}
+gen ADD %a,%1,%a                               yields %a
+                                               leaving loc rom($1,3)
                                                        mli 4 adi 4
 
 pat aar $1==4
 with GENREG GENREG
-uses REG
+uses GENREG
 gen move {regind, %1}, %a
     SUB %2, %2, %a                             yields %2 {regrel, %1, 8}
                                                leaving mli 4 adi 4
 
-pat lae sar $2==4 && defined(rom($1,3))                leaving lae $1 aar 4 
+pat lae sar $2==4 && defined(rom($1,3))                leaving lae $1 aar 4
                                                        sti rom($1,3)
-                                               
-pat lae lar $2==4 && defined(rom($1,3))                leaving lae $1 aar 4 
+
+pat lae lar $2==4 && defined(rom($1,3))                leaving lae $1 aar 4
                                                        loi rom($1,3)
 
 pat loc aar !defined($2)                       leaving aar $1
-                                               
+
 pat lae loc sar !defined($3) && $2==4 && defined(rom($1,3))
                                                leaving lae $1 aar 4
                                                        sti rom($1,3)
-                                               
+
 pat lae loc lar !defined($3) && $2==4 && defined(rom($1,3))
                                                leaving lae $1 aar 4
                                                        loi rom($1,3)
-                                               
+
+/* next two: dynamic arrays in modula2 - not tested */
+
+pat lal sar $2==4 leaving lal $1 aar 4 lal $1 adp 8 loi 4 sts
+
+pat lal lar $2==4 leaving lal $1 aar 4 lal $1 adp 8 loi 4 los
 
 /************************************************************************
  *                                                                     *
@@ -1071,18 +1821,30 @@ pat lae loc lar !defined($3) && $2==4 && defined(rom($1,3))
 
 pat cmi
 with GENREG REGcon
-uses reusing %1, REG
+uses reusing %1, GENREG=%1
 gen RSB_S %a, %1, %2                           yields %a
 with REGcon GENREG
-uses reusing %2, REG
+uses reusing %2, GENREG=%2
 gen SUB_S %a, %2, %1                           yields %a
 
-pat cmu                                                leaving cmi $1
-                                               /* !!! cannot be correct !!! */
+pat cmu $1==4
+with GENREG REGcon
+uses GENREG
+gen CMP %1, %2
+    MOV_HI %a, {fitcon, 0-1}
+    MOV_LS %a, {fitcon, 1}
+    MOV_EQ %a, {fitcon, 0}                     yields %a
+with REGcon GENREG
+uses GENREG
+gen CMP %2, %1
+    MOV_HI %a, {fitcon, 1}
+    MOV_LS %a, {fitcon, 0-1}
+    MOV_EQ %a, {fitcon, 0}                     yields %a
 
 pat cmp                                                leaving cmu 4
 
-pat cmf                                                leaving loc 18 trp
+pat cmf $1==4  leaving cal ".cmf4" asp 8 lfr 4
+pat cmf $1==8  leaving cal ".cmf8" asp 16 lfr 4
 
 pat loc cms !defined($2)                       leaving cms $1
 
@@ -1094,70 +1856,73 @@ gen EOR_S %2, %2, %1                            yields %2
 
 pat cms $1!=4
 with STACK
-uses REG = {const4, $1}, REG, REG, REG
-gen ADD %b, %a, SP
+kills ALL
+uses GENREG = {const4, $1}, GENREG, GENREG, GENREG, GENREG
+gen move %a, %e
+    ADD %b, %a, SP
     LABEL {label, "1:"}
     SUB_S %a, %a, {fitcon, 4}
     BLT {label, "2F"}
-    move {regregrel, SP, %a}, %c
+    move {st_regregrel, SP, %a}, %c
     move {regregrel, %b, %a}, %d
     EOR_S %c, %c, %d
     BEQ {label, "1B"}
     LABEL {label, "2:"}
-    ADD SP, %b, {const4, $1}                   yields %c
+    ADD SP, %b, %e                             yields %c
 
 pat cms !defined($1)
 with GENREG STACK
-uses REG, REG, REG
-gen ADD %a, %1, SP
+uses GENREG, GENREG, GENREG, GENREG
+gen move %1, %d
+    ADD %a, %1, SP
     LABEL {label, "1:"}
     SUB_S %1, %1, {fitcon, 4}
     BLT {label, "2F"}
-    move {regregrel, SP, %1}, %b
+    move {st_regregrel, SP, %1}, %b
     move {regregrel, %a, %1}, %c
     EOR_S %b, %b, %c
     BEQ {label, "1B"}
     LABEL {label, "2:"}
-    ADD SP, %a, {const4, $1}                   yields %b
+    ADD SP, %a, %d                             yields %b
 
 pat tlt
 with GENREG
-uses reusing %1, REG
+uses reusing %1, GENREG=%1
 gen test %1
     MOV_LT %a, {fitcon,1}
     MOV_GE %a, {fitcon,0}                      yields %a
 
 pat tle
 with  GENREG
-uses reusing %1, REG
+uses reusing %1, GENREG=%1
 gen test %1
     MOV_LE %a, {fitcon,1}
     MOV_GT %a, {fitcon,0}                      yields %a
 
 pat teq
 with GENREG
-uses reusing %1, REG
+uses reusing %1, GENREG=%1
 gen test %1
     MOV_EQ %a, {fitcon,1}
     MOV_NE %a, {fitcon,0}                      yields %a
 
 pat tne
 with  GENREG
-uses reusing %1, REG
+uses reusing %1, GENREG=%1
 gen test %1
     MOV_NE %a, {fitcon,1}
     MOV_EQ %a, {fitcon,0}                      yields %a
 
 pat tge
 with  GENREG
-uses reusing %1, REG
+uses reusing %1, GENREG=%1
 gen test %1
     MOV_GE %a, {fitcon,1}
     MOV_LT %a, {fitcon,0}                      yields %a
 
 pat tgt
 with GENREG
-uses reusing %1, REG
+uses reusing %1, GENREG=%1
 gen test %1
     MOV_GT %a, {fitcon,1}
     MOV_LE %a, {fitcon,0}                      yields %a
@@ -1170,6 +1935,7 @@ gen test %1
 
 pat bra
 with STACK
+kills ALL
        gen BAL {label, $1}
 
 pat bne
@@ -1249,7 +2015,13 @@ with STACK
 kills ALL
 gen BAL_L {label, $1}
 
-pat cai                                        leaving loc 18 trp
+pat cai
+with GENREG STACK
+kills ALL
+gen /* the trick is to set up R14 properly */
+    ADR LR, {label, "1F"}
+    MOV PC, %1
+    LABEL {label, "1:"}
 
 pat lfr $1==4                          yields R0
 
@@ -1257,35 +2029,35 @@ pat lfr $1==8                           yields R1 R0
 
 pat lfr $1==12                         yields R2 R1 R0
 
-pat ret $1==0                          
+pat ret $1==0
 with STACK
 kills ALL
-gen move LB, SP 
-    move {autoid, SP}, LB
-    move {autoid, SP}, PC
+gen return
+    MOV SP, LB
+    LDMFD {autoid, SP}, {lb_pc_reglist2, LB, PC}
 
 pat ret $1==4
 with address STACK
 kills ALL
 gen move %1, R0
+    return
     move LB, SP
-    move {autoid, SP}, LB
-    move {autoid, SP}, PC
+    LDMFD {autoid, SP}, {lb_pc_reglist2, LB, PC}
 with REGcon STACK
 kills ALL
 gen move %1, R0
+    return
     move LB, SP
-    move {autoid, SP}, LB
-    move {autoid, SP}, PC
+    LDMFD {autoid, SP}, {lb_pc_reglist2, LB, PC}
 
 pat ret $1==8
 with REGcon REGcon STACK
 kills ALL
 gen move %1, R0
     move %2, R1
+    return
     move LB, SP
-    move {autoid, SP}, LB
-    move {autoid, SP}, PC
+    LDMFD {autoid, SP}, {lb_pc_reglist2, LB, PC}
 
 pat ret $1==12
 with REGcon REGcon REGcon STACK
@@ -1293,10 +2065,9 @@ kills ALL
 gen move %1, R0
     move %2, R1
     move %3, R2
+    return
     move LB, SP
-    move {autoid, SP}, LB
-    move {autoid, SP}, PC
-
+    LDMFD {autoid, SP}, {lb_pc_reglist2, LB, PC}
 
 
 /************************************************************************
@@ -1305,9 +2076,16 @@ gen move %1, R0
  *                                                                     *
  ************************************************************************/
 
-pat asp
+pat asp legal($1)
 with STACK
-gen ADD SP, SP, {const4, $1}
+kills ALL
+gen ADD SP, SP, {fitcon, $1}
+
+pat asp illegal($1)
+with STACK
+kills ALL
+uses GENREG={const4, $1}
+gen ADD SP, SP, %a
 
 pat ass $1==4
 with REGcon STACK
@@ -1316,17 +2094,24 @@ gen ADD SP, SP, %1
 pat blm $1==0
 with address+REGcon address+REGcon
 
+pat blm $1==1
+with GENREG GENREG
+kills address
+uses GENREG
+gen LDR_B %a, {regind, %2}
+    STR_B %a, {regind, %1}
+
 pat blm $1==4
 with GENREG GENREG
 kills address
-uses REG
+uses GENREG
 gen move {regind, %2}, %a
     move %a, {regind, %1}
 
 pat blm $1>4
 with GENREG GENREG
 kills address
-uses REG, REG={const4, $1-4}
+uses GENREG, GENREG={const4, $1-4}
 gen LABEL {label, "1:"}
     move {regregrel, %2, %b}, %a
     move %a, {regregrel, %1, %b}
@@ -1336,18 +2121,26 @@ gen LABEL {label, "1:"}
 pat bls $1==4
 with GENREG GENREG GENREG
 kills address
-uses REG
+uses GENREG
 gen LABEL {label, "1:"}
     SUB_S %1, %1, {fitcon, 4}
     move {regregrel, %3, %1}, %a
     move %a, {regregrel, %2, %1}
     BGT {label,"1B"}
 
-pat csa
+pat csa $1==4
+with STACK
+kills ALL
+gen BAL_L {label, "_Csa"}
+    move R2, PC
 
-pat csb
+pat csb $1==4
+with STACK
+kills ALL
+gen BAL_L {label, "_Csb"}
+    move R3, PC
 
-pat dch                                        leaving loi 4
+pat dch        leaving loi 4
 
 pat dup $1==4
 with address+REGcon                    yields %1 %1
@@ -1357,20 +2150,21 @@ with address+REGcon address+REGcon      yields %2 %1 %2 %1
 
 pat dup $1>8
 with STACK
-uses REG={const4,$1}, REG
+kills ALL
+uses GENREG={const4,$1}, GENREG
 gen LABEL {label, "1:"}
-    move {regrel, SP, $1-4}, %b
-    move %b, {autoid, SP}
+    move {st_regrel, SP, $1-4}, %b
+    STMFD {autoid, SP}, {reglist1, %b}
     SUB_S %a, %a, {fitcon, 4}
     BGT {label, "1B"}
 
 pat dus
 with GENREG STACK
-uses REG, REG
+uses GENREG, GENREG
 gen SUB %b, %1, {fitcon, 4}
     LABEL {label, "1:"}
-    move {regregrel, SP, %b}, %a
-    move %a, {autoid, SP}
+    move {st_regregrel, SP, %b}, %a
+    STMFD {autoid, SP}, {reglist1, %a}
     SUB_S %1, %1, {fitcon, 4}
     BGT {label, "1B"}
 
@@ -1384,54 +2178,110 @@ with address+REGcon address+REGcon
 pat exg $1>8
 with STACK
 kills ALL
-uses REG, REG, REG={const4, $1-4}, REG
-gen ADD %d, SP, {const4, $1}
+uses GENREG, GENREG, GENREG={const4, $1-4}, GENREG, GENREG={const4, $1}
+gen ADD %d, SP, %e
     LABEL {label, "1:"}
-    move {regregrel,SP,%c}, %a
+    move {st_regregrel, SP,%c}, %a
     move {regregrel,%d,%c}, %b
     move %a, {regregrel,%d,%c}
-    move %b, {regregrel,SP,%c}
+    move %b, {st_regregrel, SP,%c}
     SUB_S %c, %c, {fitcon, 4}
     BGE {label, "1B"}
 
 pat fil
-
-pat gto
-
-pat lim
+uses GENREG
+gen move {addr_external,$1}, %a
+    move %a, {addr_external, "_Filna"}
+
+pat gto        /* this code does NOT restore registers */
+uses GENREG,GENREG,GENREG,GENREG
+gen move {addr_external, $1}, %d
+    move {regind, %d}, %a
+    move {regrel, %d, 4}, %b
+    move {regrel, %d, 8}, %c
+    MOV  LB, %c
+    MOV  SP, %b
+    MOV  PC, %a
 
 pat lin
+kills address
+uses GENREG={const4,$1}
+gen move %a,{addr_external,"_Lineno"}
 
 pat lni
+kills address
+uses GENREG
+gen move {addr_external,"_Lineno"}, %a
+    LDR %a, {regind, %a}
+    ADD %a,%a,{fitcon,1}
+    move %a,{addr_external,"_Lineno"}
 
 pat lor $1==0                          yields LB
 
 pat lor $1==1
-with STACK                             yields SP
+with STACK
+kills ALL                              yields SP
 
-pat lor $1==2                          yields {absolute, ".reghp"}
+pat lor $1==2                          yields {absolute, "_RegHp"}
 
 pat lpb                                        leaving adp 8
 
-pat mon
-
 pat nop
+gen MOV_NV R0,R0
 
 pat rck
-with GENREG REGcon STACK
-uses REG
+with GENREG REGcon  STACK 
+uses GENREG,GENREG
 gen move {regind, %1}, %a
+    /* for some reason, the code generator expects the value
+     * to be checked on top of the stack after checking, while
+     * in fact it is held in %2. This causes mayhem later on, and
+     * the following two lines rectify this.
+     */
+    move %2,%b
+    STMFD {autoid, SP}, {reglist1, %b}
     CMP %a, %2
-    BGT {label, "rcktrap"}
+    BGT {label, "_RckTrap"}
     move {regrel, %1, 4}, %a
     CMP %a, %2
-    BLT {label, "rcktrap"}
+    BLT {label, "_RckTrap"}
+
+pat lim
+with STACK
+kills ALL
+uses GENREG
+gen move {addr_external, "_IgnoreMask"}, %a
+    STMFD {autoid, SP}, {reglist1, %a}
+
+pat mon
+with STACK
+kills ALL
+gen BAL_L {label, "_EmMon"}
 
 pat rtt
+            leaving ret 0
 
 pat sig
+with STACK
+kills ALL
+uses GENREG,GENREG
+gen move {addr_external, "_TrpReg"}, %a
+    LDR %a, {regind, %a}
+    LDMFD {autoid, SP}, {reglist1, %b}
+    move %b, {addr_external, "_TrpReg"}
+    STMFD {autoid, SP}, {reglist1, %a}
 
 pat sim
+with STACK
+kills ALL
+uses GENREG
+gen LDMFD {autoid, SP}, {reglist1, %a}
+    move %a, {addr_external, "_IgnoreMask"}
+
+pat trp
+with STACK
+kills ALL
+gen BAL_L {label, "_EmTrp"}
 
 pat str $1==0
 with address
@@ -1441,28 +2291,121 @@ gen move %1, LB
 
 pat str $1==1
 with address
-gen move %1, SP
+gen MOV SP, %1
 with REGcon
-gen move %1, SP
+gen MOV SP, %1
 
 pat str $1==2
 with GENREG
-gen move %1, {absolute, ".reghp"}
-
-pat trp
-
+gen move %1, {absolute, "_RegHp"}
 
 /***********************************************************************/
 
+/* code for *p++ and *p-- (integers)*/
 pat lol lol adp stl loi $1==$2 && $2==$4 && $5==4
-uses REG, REG
-gen move {LOCAL, $1}, %a
-    move {regrelpi, %a, $3}, %b
-    move %a, {LOCAL, $1}               yields %b
+kills GENREG
+uses GENREG, GENREG
+gen move {lb_local, $1}, %a
+    LDR %b, {regrelpi, %a, $5}
+    STR %a, {lb_local, $1}             yields %b
 
 pat lol lol adp stl sti $1==$2 && $2==$4 && $5==4
 with GENREG
-uses REG
-gen move {LOCAL,$1}, %a
-    move %1, {regrelpi, %a, $3}
-    move %a, {LOCAL, $1}
+kills GENREG
+uses GENREG
+gen move {lb_local,$1}, %a
+    STR %1, {regrelpi, %a, $5}
+    STR %a, {lb_local, $1}
+
+/* code for *p++ and *p-- (bytes)*/
+pat lol lol adp stl loi $1==$2 && $2==$4 && $5==1
+kills GENREG
+uses GENREG, GENREG
+gen move {lb_local, $1}, %a
+    LDR_B %b, {regrelpi, %a, $5}
+    STR %a, {lb_local, $1}             yields %b
+
+pat lol lol adp stl sti $1==$2 && $2==$4 && $5==1
+with GENREG
+kills GENREG
+uses GENREG
+gen move {lb_local,$1}, %a
+    STR_B %1, {regrelpi, %a, $5}
+    STR %a, {lb_local, $1}
+
+/* code for *pp->p++ and *pp->p-- (integers)*/
+pat lil lil adp sil loi $1==$2 && $2==$4 && $5==4
+kills GENREG
+uses GENREG, GENREG, GENREG
+gen move {lb_local, $1}, %a
+    LDR %b, {regind, %a}
+    ADD %c, %b, {fitcon, $5}
+    STR %c, {regind, %a}
+    LDR %c, {regind, %b}               yields %c
+
+pat lil lil adp sil sti $1==$2 && $2==$4 && $5==4
+with GENREG
+kills GENREG
+uses GENREG, GENREG, GENREG
+gen move {lb_local, $1}, %a
+    LDR %b, {regind, %a}
+    ADD %c, %b, {fitcon, $5}
+    STR %c, {regind, %a}
+    STR %1, {regind, %b}
+
+/* code for *pp->p++ and *pp->p-- (bytes)*/
+pat lil lil adp sil loi $1==$2 && $2==$4 && $5==1
+kills GENREG
+uses GENREG, GENREG, GENREG
+gen move {lb_local, $1}, %a
+    LDR %b, {regind, %a}
+    ADD %c, %b, {fitcon, $5}
+    STR %c, {regind, %a}
+    LDR_B %c, {regind, %b}             yields %c
+
+pat lil lil adp sil sti $1==$2 && $2==$4 && $5==1
+with GENREG
+kills GENREG
+uses GENREG, GENREG, GENREG
+gen move {lb_local, $1}, %a
+    LDR %b, {regind, %a}
+    ADD %c, %b, {fitcon, $5}
+    STR %c, {regind, %a}
+    STR_B %1, {regind, %b}
+
+
+/* global array access of the form x[y-1] */
+
+pat lol loc mli loc sbi $2==$4 && $3==4 && $5==4
+    leaving lol $1 dec 4 loc $2 mli 4
+
+/* x[i] = y with large array elements */
+
+pat lae loi lae lol loc mli ads sti $2==$8 && $2 > 4
+    leaving lae $1 lae $3 lol $4 loc $5 mli $6 ads $7 blm $8
+pat lae loi lae lol loc mlu ads sti $2==$8 && $2 > 4
+    leaving lae $1 lae $3 lol $4 loc $5 mlu $6 ads $7 blm $8
+
+/* prevent double push/pull of $1 */
+
+pat lae lol loc mli ads
+    leaving lol $2 loc $3 mli $4 lae $1 ads $5
+pat lae lol loc mlu ads
+    leaving lol $2 loc $3 mlu $4 lae $1 ads $5
+
+pat lae lol loc mli ads lol loc mli ads $5==$9 && $4==$8
+    leaving lol $2 loc $3 mli $4 lol $6 loc $7 mli $8 ads $5 lae $1 ads $9
+pat lae lol loc mlu ads lol loc mlu ads $5==$9 && $4==$8
+    leaving lol $2 loc $3 mlu $4 lol $6 loc $7 mlu $8 ads $5 lae $1 ads $9
+
+pat lae lol adp loi loc mli ads
+    leaving lol $2 adp $3 loi $4 loc $5 mli $6 lae $1 ads $7
+pat lae lol adp loi loc mlu ads
+    leaving lol $2 adp $3 loi $4 loc $5 mlu $6 lae $1 ads $7
+
+/*
+pat lae loi lae lol adp loi loc mli ads sti $2==$10 && $2 > 4
+    leaving lae $1 lae $3 lol $4 adp $5 loi $6 loc $7 mli $8 ads $9 blm $2
+pat lae loi lae lol adp loi loc mlu ads sti $2==$10 && $2 > 4
+    leaving lae $1 lae $3 lol $4 adp $5 loi $6 loc $7 mlu $8 ads $9 blm $2
+*/