Initial revision
authorceriel <none@none>
Fri, 5 Dec 1986 16:58:29 +0000 (16:58 +0000)
committerceriel <none@none>
Fri, 5 Dec 1986 16:58:29 +0000 (16:58 +0000)
12 files changed:
mach/6805/as/mach0.c [new file with mode: 0644]
mach/6805/as/mach1.c [new file with mode: 0644]
mach/6805/as/mach2.c [new file with mode: 0644]
mach/6805/as/mach3.c [new file with mode: 0644]
mach/6805/as/mach4.c [new file with mode: 0644]
mach/6805/as/mach5.c [new file with mode: 0644]
mach/ns/as/mach0.c [new file with mode: 0644]
mach/ns/as/mach1.c [new file with mode: 0644]
mach/ns/as/mach2.c [new file with mode: 0644]
mach/ns/as/mach3.c [new file with mode: 0644]
mach/ns/as/mach4.c [new file with mode: 0644]
mach/ns/as/mach5.c [new file with mode: 0644]

diff --git a/mach/6805/as/mach0.c b/mach/6805/as/mach0.c
new file mode 100644 (file)
index 0000000..1d3ae70
--- /dev/null
@@ -0,0 +1,11 @@
+#define RCSID0 "$Header$"
+
+/*
+ * Motorola 6805 options
+ */
+
+#define        BYTES_REVERSED
+#define        WORDS_REVERSED
+#define THREE_PASS
+#define        LISTING
+#define RELOCATION
diff --git a/mach/6805/as/mach1.c b/mach/6805/as/mach1.c
new file mode 100644 (file)
index 0000000..8362018
--- /dev/null
@@ -0,0 +1,9 @@
+#define RCSID1 "$Header$"
+
+/*
+ * Motorola 6805 C declarations
+ */
+
+extern int opt_cmos;
+
+#define        fitj(z)         ((unsigned)z + 0x80 <= 0xFF)
diff --git a/mach/6805/as/mach2.c b/mach/6805/as/mach2.c
new file mode 100644 (file)
index 0000000..6948f5c
--- /dev/null
@@ -0,0 +1,17 @@
+#define RCSID2 "$Header$"
+
+/*
+ * Motorola 6805 tokens
+ */
+
+%token <y_word> X
+%token <y_word> A
+%token <y_word> NOARG
+%token <y_word> BRANCH
+%token <y_word> BBRANCH
+%token <y_word> BIT
+%token <y_word> RMR
+%token <y_word> RM
+%token <y_word> CMOS
+%type <y_expr> expr8
+%type <y_valu> bitexp
diff --git a/mach/6805/as/mach3.c b/mach/6805/as/mach3.c
new file mode 100644 (file)
index 0000000..58e4d1c
--- /dev/null
@@ -0,0 +1,123 @@
+#define RCSID3 "$Header$"
+
+/*
+ * Motorola 6805 keywords
+ */
+/*
+ * The X register
+ */
+0,     X,              0,              "x",
+/*
+ * Bit test and branch
+ */
+0,     BBRANCH,        0x00,           "brset",
+0,     BBRANCH,        0x01,           "brclr",
+/*
+ * Bit manipulation
+ */
+0,     BIT,            0x10,           "bset",
+0,     BIT,            0x11,           "bclr",
+/*
+ * Branches
+ */
+0,     BRANCH,         0x20,           "bra",
+0,     BRANCH,         0x21,           "brn",
+0,     BRANCH,         0x22,           "bhi",
+0,     BRANCH,         0x23,           "bls",
+0,     BRANCH,         0x24,           "bcc",
+0,     BRANCH,         0x25,           "bcs",
+0,     BRANCH,         0x26,           "bne",
+0,     BRANCH,         0x27,           "beq",
+0,     BRANCH,         0x28,           "bhcc",
+0,     BRANCH,         0x29,           "bhcs",
+0,     BRANCH,         0x2a,           "bpl",
+0,     BRANCH,         0x2b,           "bmi",
+0,     BRANCH,         0x2c,           "bmc",
+0,     BRANCH,         0x2d,           "bms",
+0,     BRANCH,         0x2e,           "bil",
+0,     BRANCH,         0x2f,           "bih",
+/*
+ * Read modify write on anything but registers
+ */
+0,     RMR,            0x30,           "neg",
+0,     RMR,            0x33,           "com",
+0,     RMR,            0x34,           "lsr",
+0,     RMR,            0x36,           "ror",
+0,     RMR,            0x36,           "asr",
+0,     RMR,            0x38,           "lsl",
+0,     RMR,            0x39,           "rol",
+0,     RMR,            0x3a,           "dec",
+0,     RMR,            0x3c,           "inc",
+0,     RMR,            0x3d,           "tst",
+0,     RMR,            0x3f,           "clr",
+/*
+ * Implied stuff
+ */
+0,     NOARG,          0x80,           "rti",
+0,     NOARG,          0x81,           "rts",
+0,     NOARG,          0x83,           "swi",
+0,     NOARG,          0x97,           "tax",
+0,     NOARG,          0x98,           "clc",
+0,     NOARG,          0x99,           "sec",
+0,     NOARG,          0x9a,           "cli",
+0,     NOARG,          0x9b,           "sei",
+0,     NOARG,          0x9c,           "rsp",
+0,     NOARG,          0x9d,           "nop",
+0,     NOARG,          0x9f,           "txa",
+/*
+ * Register memory.
+ * Warning. Some imediate opcodes excluded in parser actions.
+ */
+0,     RM,             0xa0,           "sub",
+0,     RM,             0xa1,           "cmp",
+0,     RM,             0xa2,           "sbc",
+0,     RM,             0xa3,           "cpx",
+0,     RM,             0xa4,           "and",
+0,     RM,             0xa5,           "bit",
+0,     RM,             0xa6,           "lda",
+0,     RM,             0xa7,           "sta",
+0,     RM,             0xa8,           "eor",
+0,     RM,             0xa9,           "adc",
+0,     RM,             0xaa,           "ora",
+0,     RM,             0xab,           "add",
+0,     RM,             0xac,           "jmp",
+0,     BRANCH,         0xad,           "bsr",
+0,     RM,             0xad,           "jsr",
+0,     RM,             0xae,           "ldx",
+0,     RM,             0xaf,           "stx",
+/*
+ * Branch synonyms
+ */
+0,     BRANCH,         0x24,           "bhs",  /* bcc */
+0,     BRANCH,         0x25,           "blo",  /* bcs */
+/*
+ * Brain damaged concatenated opcodes for RMR on registers
+ */
+0,     NOARG,          0x40,           "nega",
+0,     NOARG,          0x43,           "coma",
+0,     NOARG,          0x44,           "lsra",
+0,     NOARG,          0x46,           "rora",
+0,     NOARG,          0x47,           "asra",
+0,     NOARG,          0x48,           "lsla",
+0,     NOARG,          0x49,           "rola",
+0,     NOARG,          0x4a,           "deca",
+0,     NOARG,          0x4c,           "inca",
+0,     NOARG,          0x4d,           "tsta",
+0,     NOARG,          0x4f,           "clra",
+0,     NOARG,          0x50,           "negx",
+0,     NOARG,          0x53,           "comx",
+0,     NOARG,          0x54,           "lsrx",
+0,     NOARG,          0x56,           "rorx",
+0,     NOARG,          0x57,           "asrx",
+0,     NOARG,          0x58,           "lslx",
+0,     NOARG,          0x59,           "rolx",
+0,     NOARG,          0x5a,           "decx",
+0,     NOARG,          0x5c,           "incx",
+0,     NOARG,          0x5d,           "tstx",
+0,     NOARG,          0x5f,           "clrx",
+/*
+ * CMOS support
+ */
+0,     CMOS,           0,              ".cmos",
+0,     CMOS,           0x8e,           "stop",
+0,     CMOS,           0x8f,           "wait",
diff --git a/mach/6805/as/mach4.c b/mach/6805/as/mach4.c
new file mode 100644 (file)
index 0000000..6f2d218
--- /dev/null
@@ -0,0 +1,205 @@
+#define RCSID4 "$Header$"
+
+/*
+ * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ *
+ *          This product is part of the Amsterdam Compiler Kit.
+ *
+ * Permission to use, sell, duplicate or disclose this software must be
+ * obtained in writing. Requests for such permissions may be sent to
+ *
+ *      Dr. Andrew S. Tanenbaum
+ *      Wiskundig Seminarium
+ *      Vrije Universiteit
+ *      Postbox 7161
+ *      1007 MC Amsterdam
+ *      The Netherlands
+ *
+ */
+
+/*
+ * Motorola 6805 parsing rules
+ */
+
+expr8
+       :
+               expr
+                       {
+                               fit(fitb($1.val));
+                       }
+       ;
+bitexp
+       :
+               absexp
+                       {
+                               fit((unsigned) $1 <= 7);
+                               $$ = $1 & 07;
+                       }
+       ;
+operation
+       :
+               NOARG
+                       {       emit1($1);}
+       |
+               BRANCH expr
+                       {       branch($1,$2);}
+       |
+               BBRANCH bitexp ',' expr8 ',' expr
+                       {
+                               branch($1+($2 << 1), $6, $4);
+                       }
+       |
+               BIT bitexp ',' expr8
+                       {
+                               emit1($1+($2 << 1));
+#ifdef RELOCATION
+                               newrelo($4.typ, RELO1);
+#endif
+                               emit1($4.val);
+                       }
+       |
+               RMR '<' expr8
+       |
+               RMR expr8
+                       {
+                               emit1($1);
+#ifdef RELOCATION
+                               newrelo($2.typ, RELO1);
+#endif
+                               emit1($2.val);
+                       }
+       |
+               RMR expr8 ',' X
+                       {
+                               if(small($2.val == 0 &&
+                                        ($2.typ & ~S_DOT) == DOTTYP &&
+                                        pass == PASS_2, 1))
+                                       emit1($1+0x40);
+                               else
+                               {
+                                       emit1($1+0x30);
+#ifdef RELOCATION
+                                       newrelo($2.typ, RELO1);
+#endif
+                                       emit1($2.val);
+                               }
+                       }
+       |
+               RMR ',' X
+                       {       emit1($1+0x40); }
+       |
+               RM '#' expr8
+                       {
+                               switch($1) {
+                                       case 0xa7:
+                                       case 0xac:
+                                       case 0xad:
+                                       case 0xaf:
+                                               serror("mode error");
+                                       default:
+                                               emit1($1);
+                               }
+#ifdef RELOCATION
+                               newrelo($3.typ, RELO1);
+#endif
+                               emit1($3.val);
+                       }
+       |
+               RM '<' expr8
+                       {
+                               emit1($1+0x10);
+#ifdef RELOCATION
+                               newrelo($3.typ, RELO1);
+#endif
+                               emit1($3.val);
+                       }
+       |
+               RM expr
+                       {
+                               if(small(pass == PASS_2 &&
+                                        ($2.typ & ~S_DOT) == DOTTYP &&
+                                        fitb($2.val),1)) {
+                                       emit1($1+0x10);
+#ifdef RELOCATION
+                                       newrelo($2.typ, RELO1);
+#endif
+                                       emit1($2.val);
+                               } else {
+                                       emit1($1+0x20);
+#ifdef RELOCATION
+                                       newrelo($2.typ, RELO2|RELBR);
+#endif
+                                       emit2($2.val);
+                               }
+                       }
+       |
+               RM '>' expr
+                       {
+                               emit1($1+0x20);
+#ifdef RELOCATION
+                               newrelo($3.typ, RELO2|RELBR);
+#endif
+                               emit2($3.val);
+                       }
+       |
+               RM '>' expr ',' X
+                       {
+                               emit1($1+0x30);
+#ifdef RELOCATION
+                               newrelo($3.typ, RELO2|RELBR);
+#endif
+                               emit2($3.val);
+                       }
+       |
+               RM expr ',' X
+                       {
+                               if(small(pass == PASS_2 &&
+                                        ($2.typ & ~S_DOT) == DOTTYP &&
+                                        fitb($2.val),1)) {
+                                       if(small(pass == PASS_2 && 
+                                                ($2.typ & ~S_DOT) == DOTTYP &&
+                                                $2.val == 0,1))
+                                               emit1($1+0x50);
+                                       else {
+                                               emit1($1+0x40);
+#ifdef RELOCATION
+                                               newrelo($2.typ, RELO1);
+#endif
+                                               emit1($2.val);
+                                       }
+                               } else {
+                                       small(0,1);  /* dummy */
+                                       emit1($1+0x30);
+#ifdef RELOCATION
+                                       newrelo($2.typ, RELO2|RELBR);
+#endif
+                                       emit2($2.val);
+                               }
+                       }
+       |
+               RM '<' expr8 ',' X
+                       {
+                               emit1($1+0x40);
+#ifdef RELOCATION
+                               newrelo($3.typ, RELO1);
+#endif
+                               emit1($3.val);
+                       }
+       |
+               RM ',' X
+                       {       emit1($1+0x50); }
+       |
+               CMOS
+                       {
+                               switch($1) {
+                                       case 0:
+                                               opt_cmos = 1;
+                                               break;
+                                       case 0x8e:
+                                       case 0x8f:
+                                               if(! opt_cmos)
+                                               serror("bad opcode");
+                                               emit1($1);
+                               }
+                       }
+       ;
diff --git a/mach/6805/as/mach5.c b/mach/6805/as/mach5.c
new file mode 100644 (file)
index 0000000..33c4127
--- /dev/null
@@ -0,0 +1,51 @@
+#define RCSID5 "$Header$"
+
+/*
+ * Motorola 6805 special routines
+ */
+
+/* VARARGS2 */
+branch(opc,exp,cell) register opc; expr_t cell; expr_t exp; {
+       register sm, dist;
+       int saving;
+
+       dist = exp.val - (DOTVAL + 2);
+       if((opc & 0xf0) == 0) dist -= 1;  /* bitbranch */
+       if (pass == PASS_2 && dist > 0 && !(exp.typ & S_DOT))
+               dist -= DOTGAIN;
+       sm = fitj(dist);
+       if ((exp.typ & ~S_DOT) != DOTTYP)
+               sm = 0;
+       if (opc == 0x20 || opc == 0xAD)
+               saving = 1;
+       else
+               saving = 3;
+       if (small(sm,saving)) {
+               emit1(opc);
+               if((opc & 0xF0) == 0)   /* bit branch */
+                       emit1(cell.val);
+#ifdef RELOCATION
+               newrelo(exp.typ, RELPC|RELO1);
+#endif
+               emit1(dist);
+       } else {
+               if (opc == 0xAD)                /* bsr */
+                       emit1(0xBD);            /* jsr */
+               else {
+                       if (opc != 0x20) {      /* bra */
+
+                                       /* reverse condition : */
+
+                               emit1(opc ^ 1);
+                               if((opc & 0xF0) == 0)  /* bitbranch */
+                                       emit1(cell.val);
+                               emit1(3);
+                       }
+                       emit1(0xCC);            /* jmp */
+               }
+#ifdef RELOCATION
+               newrelo(exp.typ, RELPC|RELO2|RELBR);
+#endif
+               emit2(exp.val);
+       }
+}
diff --git a/mach/ns/as/mach0.c b/mach/ns/as/mach0.c
new file mode 100644 (file)
index 0000000..8ead9e5
--- /dev/null
@@ -0,0 +1,21 @@
+#define RCSID0 "$Header$"
+
+/*
+ * NS 16032 options
+ */
+#define        THREE_PASS      /* branch and offset optimization */
+#define        LISTING         /* enable listing facilities */
+
+#undef valu_t
+#define valu_t         long
+#undef addr_t
+#define        addr_t          long
+#undef ALIGNSECT
+#define ALIGNSECT      2
+
+#undef VALWIDTH
+#define        VALWIDTH        8
+
+#define RELOCATION
+
+#define UNUSED         /* Assemble the 'unused' instructions like bfalse */
diff --git a/mach/ns/as/mach1.c b/mach/ns/as/mach1.c
new file mode 100644 (file)
index 0000000..6c8ae00
--- /dev/null
@@ -0,0 +1,113 @@
+#define RCSID1 "$Header$"
+
+/*
+ * NS 16032 C declarations
+ */
+
+#define low4(val)      ((int)(val&0xF))
+
+/* signed value fits in ? bits */
+#define fit32(val)     ( (val)>= -2147483648 && (val)<=2147483647 )
+#define fit16(val)     ( (val)>= -32768 && (val)<=32767 )
+#define fit8(val)      ( (val)>= -128 && (val)<=127 )
+#define        fit4(val)       ( (val)>= -8 && (val)<=7 )
+
+/* Fits in byte, word displacement */
+#define        fitd_b(val)     ( (val)>= -64 && (val)<=63 )
+#define        fitd_w(val)     ( (val)>= -8192 && (val)<=8191 )
+
+/* Assemble and disassemble operator id's */
+/* the i_value's in the instruction keyword table
+   contain five bit fields:
+       0-3     Opcode used in format indicated by the i_type field
+       4-7     Condition Code field. B_?? Also used for reg in FFS type.
+       8-11    The type of the first addressing mode gen1
+       12-15   The type of the second addressing mode gen2
+                       The integer type T_????
+                       The custom Slave type S_????
+                       The Floating point type F_????
+*/
+
+#define MK_op(op)      (op)
+#define MK_cc(cc)      ( (cc)<<4 )
+#define MK_g1(g1)      ( (g1)<<8 )
+#define MK_g2(g2)      ( (g2)<<12 )
+
+#define mk_op(o)       (MK_op(o)|MK_g1(X_ILLGL)|MK_g2(X_ILLGL))
+#define mk_op1(o,g1)   (MK_op(o)|MK_g1(g1)|MK_g2(X_ILLGL))
+#define mk_op2(o,g1,g2) (MK_op(o)|MK_g1(g1)|MK_g2(g2))
+#define mk_c(c)                MK_cc(c)
+#define mk_op1c(o,g1,c)        (MK_op(o)|MK_g1(g1)|MK_g2(X_ILLGL)|MK_cc(c))
+#define mk_op2c(o,g1,g2,c)     (MK_op(o)|MK_g1(g1)|MK_g2(g2)|MK_cc(c))
+
+#define id_op(id)      ((id)      &0xF)
+#define id_cc(id)      (((id)>>4) &0xF)
+#define id_g1(id)      (((id)>>8) &3)
+#define id_g2(id)      (((id)>>12)&3)
+#define id_t1(id)      (((id)>>10)&3)
+#define id_t2(id)      (((id)>>14)&3)
+
+/* Type definitions */
+#define T_INT          0
+#define T_FL           1
+#define T_SLAVE                2
+#define T_ILLGL                3
+
+#define        I_BYTE          (T_INT<<2) | 0
+#define I_WORD         (T_INT<<2) | 1
+#define I_DOUBLE       (T_INT<<2) | 3
+
+#define F_FLOAT                (T_FL<<2) | 1
+#define F_LONG         (T_FL<<2) | 0
+
+#define S_DOUBLE       (T_SLAVE<<2) | 1
+#define S_QUAD         (T_SLAVE<<2) | 0
+
+#define X_ILLGL                (T_ILLGL<<2) | 2
+
+#define B_EQ           0x0
+#define B_NE           0x1
+#define B_CS           0x2
+#define B_CC           0x3
+#define B_HI           0x4
+#define B_LS           0x5
+#define B_GT           0x6
+#define B_LE           0x7
+#define B_FS           0x8
+#define B_FC           0x9
+#define B_LO           0xA
+#define B_HS           0xB
+#define B_LT           0xC
+#define B_GE           0xD
+#define B_TRUE         0xE
+#define B_FALSE                0xF
+
+/* String option bits */
+#define SO_UNTIL       0xC
+#define SO_WHILE       0x4
+#define SO_BACKW       0x2
+#define SO_TRANS       0x1
+
+/* output definitions */
+#define        form0(id)       emit1(0xA + (id_cc(id)<<4) )
+#define        form1(id)       emit1(0x2 + (id_op(id)<<4) )
+#define form6(id)      emit1(0x4E) ; form4(id)
+#define form7(id)      emit1(0xCE) ; form4(id)
+
+
+/* Structure contains information for generation of an addressing mode */
+/* The size of immediates is not stored in here and must be fetched from
+   a id-field
+*/
+extern struct {
+       int     m_mode;         /* The main mode bits */
+       int     m_index ;       /* m_mode= index mode, m_index has index byte */
+       int     m_ndisp ;       /* The number of displacements */
+       expr_t  m_expr1 ;       /* The first expression */
+#ifdef RELOCATION
+       int     m_rel1, m_rel2; /* relocation */
+#endif
+       expr_t  m_expr2 ;       /* The second expression */
+} mode1, mode2, *mode_ptr ;
+
+#define        not_imm(mode_ptr)       if ( (mode_ptr)->m_mode==0x14 ) ill_imm() ;
diff --git a/mach/ns/as/mach2.c b/mach/ns/as/mach2.c
new file mode 100644 (file)
index 0000000..27444aa
--- /dev/null
@@ -0,0 +1,59 @@
+#define RCSID2 "$Header$"
+
+/*
+ * NS 16032 tokens
+ */
+
+%token <y_word> REG
+%token <y_word> AREG
+%token <y_word> FREG
+%token <y_word> MREG
+%token <y_word> CREG
+%token <y_word> EXTERNAL
+%token <y_word> TOS
+%token <y_word> PC
+%token <y_word> INDICATOR
+
+/*
+ * Instruction types
+ */
+%token <y_word> SETCFG
+%token <y_word> LPR
+%token <y_word> LCR
+%token <y_word> BR
+%token <y_word> RET
+%token <y_word> BSR
+%token <y_word> RDVAL
+%token <y_word> CATST
+%token <y_word> LCSR
+%token <y_word> SEQ
+%token <y_word> ADJSP
+%token <y_word> JSR
+%token <y_word> JUMP
+%token <y_word> LFSR
+%token <y_word> ADD_F
+%token <y_word> CCVIS
+%token <y_word> CCVSI
+%token <y_word> CCVSS
+%token <y_word> CMOV
+%token <y_word> ADD_I
+%token <y_word> COM
+%token <y_word> MUL_I
+%token <y_word> MOVID
+%token <y_word> FFS
+%token <y_word> MOVIF
+%token <y_word> MOVFL
+%token <y_word> TRUNC
+%token <y_word> MOVM
+%token <y_word> INSS
+%token <y_word> SAVE
+%token <y_word> ENTER
+%token <y_word> LMR
+%token <y_word> MOVS
+%token <y_word> CHECK
+%token <y_word> INS
+%token <y_word> MOVQ
+%token <y_word> ACB
+%token <y_word> WAIT
+
+%type  <y_word> cpu_opts, cpu_list, string_opts, reg_list, reg_items
diff --git a/mach/ns/as/mach3.c b/mach/ns/as/mach3.c
new file mode 100644 (file)
index 0000000..cad6926
--- /dev/null
@@ -0,0 +1,453 @@
+#define RCSID3 "$Header$"
+
+/*
+ * NS 16032 keywords
+ */
+
+/* Registers */
+0,     REG,            0,              "r0",
+0,     REG,            1,              "r1",
+0,     REG,            2,              "r2",
+0,     REG,            3,              "r3",
+0,     REG,            4,              "r4",
+0,     REG,            5,              "r5",
+0,     REG,            6,              "r6",
+0,     REG,            7,              "r7",
+0,     FREG,           0,              "f0",
+0,     FREG,           1,              "f1",
+0,     FREG,           2,              "f2",
+0,     FREG,           3,              "f3",
+0,     FREG,           4,              "f4",
+0,     FREG,           5,              "f5",
+0,     FREG,           6,              "f6",
+0,     FREG,           7,              "f7",
+/* CPU dedicated registers */
+0,     AREG,           0x0,            "us",
+0,     AREG,           0x8,            "fp",
+0,     AREG,           0x9,            "sp",
+0,     AREG,           0xA,            "sb",
+0,     AREG,           0xD,            "psr",
+0,     AREG,           0xE,            "intbase",
+0,     AREG,           0xF,            "mod",
+/* Tokens dedicated to addressing modes */
+0,     TOS,            0x17,           "tos",
+0,     EXTERNAL,       0x16,           "external",
+0,     PC,             0,              "pc",
+0,     INDICATOR,      'b',            "b",
+0,     INDICATOR,      'c',            "c",
+0,     INDICATOR,      'd',            "d",
+0,     INDICATOR,      'f',            "f",
+0,     INDICATOR,      'i',            "i",
+0,     INDICATOR,      'm',            "m",
+0,     INDICATOR,      'q',            "q",
+0,     INDICATOR,      'u',            "u",
+0,     INDICATOR,      'w',            "w",
+/* Memory management registers */
+0,     MREG,           0x0,            "bpr0",
+0,     MREG,           0x1,            "bpr1",
+0,     MREG,           0x4,            "pf0",
+0,     MREG,           0x5,            "pf1",
+0,     MREG,           0x8,            "sc",
+0,     MREG,           0xA,            "msr",
+0,     MREG,           0xB,            "bcnt",
+0,     MREG,           0xC,            "ptb0",
+0,     MREG,           0xD,            "ptb1",
+0,     MREG,           0xF,            "eia",
+/* Instruction types */
+/* Integer instructions */
+0,     ADD_I,  mk_op2(0x5,I_BYTE,I_BYTE),      "movb",
+0,     ADD_I,  mk_op2(0x5,I_WORD,I_WORD),      "movw",
+0,     ADD_I,  mk_op2(0x5,I_DOUBLE,I_DOUBLE),  "movd",
+0,     ADD_I,  mk_op2(0x1,I_BYTE,I_BYTE),      "cmpb",
+0,     ADD_I,  mk_op2(0x1,I_WORD,I_WORD),      "cmpw",
+0,     ADD_I,  mk_op2(0x1,I_DOUBLE,I_DOUBLE),  "cmpd",
+0,     ADD_I,  mk_op2(0x0,I_BYTE,I_BYTE),      "addb",
+0,     ADD_I,  mk_op2(0x0,I_WORD,I_WORD),      "addw",
+0,     ADD_I,  mk_op2(0x0,I_DOUBLE,I_DOUBLE),  "addd",
+0,     ADD_I,  mk_op2(0x4,I_BYTE,I_BYTE),      "addcb",
+0,     ADD_I,  mk_op2(0x4,I_WORD,I_WORD),      "addcw",
+0,     ADD_I,  mk_op2(0x4,I_DOUBLE,I_DOUBLE),  "addcd",
+0,     ADD_I,  mk_op2(0x8,I_BYTE,I_BYTE),      "subb",
+0,     ADD_I,  mk_op2(0x8,I_WORD,I_WORD),      "subw",
+0,     ADD_I,  mk_op2(0x8,I_DOUBLE,I_DOUBLE),  "subd",
+0,     ADD_I,  mk_op2(0xC,I_BYTE,I_BYTE),      "subcb",
+0,     ADD_I,  mk_op2(0xC,I_WORD,I_WORD),      "subcw",
+0,     ADD_I,  mk_op2(0xC,I_DOUBLE,I_DOUBLE),  "subcd",
+0,     COM,    mk_op2(0x8,I_BYTE,I_BYTE),      "negb",
+0,     COM,    mk_op2(0x8,I_WORD,I_WORD),      "negw",
+0,     COM,    mk_op2(0x8,I_DOUBLE,I_DOUBLE),  "negd",
+0,     COM,    mk_op2(0xC,I_BYTE,I_BYTE),      "absb",
+0,     COM,    mk_op2(0xC,I_WORD,I_WORD),      "absw",
+0,     COM,    mk_op2(0xC,I_DOUBLE,I_DOUBLE),  "absd",
+0,     MUL_I,  mk_op2(0x8,I_BYTE,I_BYTE),      "mulb",
+0,     MUL_I,  mk_op2(0x8,I_WORD,I_WORD),      "mulw",
+0,     MUL_I,  mk_op2(0x8,I_DOUBLE,I_DOUBLE),  "muld",
+0,     MUL_I,  mk_op2(0xF,I_BYTE,I_BYTE),      "divb",
+0,     MUL_I,  mk_op2(0xF,I_WORD,I_WORD),      "divw",
+0,     MUL_I,  mk_op2(0xF,I_DOUBLE,I_DOUBLE),  "divd",
+0,     MUL_I,  mk_op2(0xE,I_BYTE,I_BYTE),      "modb",
+0,     MUL_I,  mk_op2(0xE,I_WORD,I_WORD),      "modw",
+0,     MUL_I,  mk_op2(0xE,I_DOUBLE,I_DOUBLE),  "modd",
+0,     MUL_I,  mk_op2(0xC,I_BYTE,I_BYTE),      "quob",
+0,     MUL_I,  mk_op2(0xC,I_WORD,I_WORD),      "quow",
+0,     MUL_I,  mk_op2(0xC,I_DOUBLE,I_DOUBLE),  "quod",
+0,     MUL_I,  mk_op2(0xD,I_BYTE,I_BYTE),      "remb",
+0,     MUL_I,  mk_op2(0xD,I_WORD,I_WORD),      "remw",
+0,     MUL_I,  mk_op2(0xD,I_DOUBLE,I_DOUBLE),  "remd",
+0,     ADD_I,  mk_op2(0xA,I_BYTE,I_BYTE),      "andb",
+0,     ADD_I,  mk_op2(0xA,I_WORD,I_WORD),      "andw",
+0,     ADD_I,  mk_op2(0xA,I_DOUBLE,I_DOUBLE),  "andd",
+0,     ADD_I,  mk_op2(0x6,I_BYTE,I_BYTE),      "orb",
+0,     ADD_I,  mk_op2(0x6,I_WORD,I_WORD),      "orw",
+0,     ADD_I,  mk_op2(0x6,I_DOUBLE,I_DOUBLE),  "ord",
+0,     ADD_I,  mk_op2(0x2,I_BYTE,I_BYTE),      "bicb",
+0,     ADD_I,  mk_op2(0x2,I_WORD,I_WORD),      "bicw",
+0,     ADD_I,  mk_op2(0x2,I_DOUBLE,I_DOUBLE),  "bicd",
+0,     ADD_I,  mk_op2(0xE,I_BYTE,I_BYTE),      "xorb",
+0,     ADD_I,  mk_op2(0xE,I_WORD,I_WORD),      "xorw",
+0,     ADD_I,  mk_op2(0xE,I_DOUBLE,I_DOUBLE),  "xord",
+0,     COM,    mk_op2(0xD,I_BYTE,I_BYTE),      "comb",
+0,     COM,    mk_op2(0xD,I_WORD,I_WORD),      "comw",
+0,     COM,    mk_op2(0xD,I_DOUBLE,I_DOUBLE),  "comd",
+0,     COM,    mk_op2(0x1,I_BYTE,I_BYTE),      "ashb",
+0,     COM,    mk_op2(0x1,I_BYTE,I_WORD),      "ashw",
+0,     COM,    mk_op2(0x1,I_BYTE,I_DOUBLE),    "ashd",
+0,     COM,    mk_op2(0x5,I_BYTE,I_BYTE),      "lshb",
+0,     COM,    mk_op2(0x5,I_BYTE,I_WORD),      "lshw",
+0,     COM,    mk_op2(0x5,I_BYTE,I_DOUBLE),    "lshd",
+0,     COM,    mk_op2(0x0,I_BYTE,I_BYTE),      "rotb",
+0,     COM,    mk_op2(0x0,I_BYTE,I_WORD),      "rotw",
+0,     COM,    mk_op2(0x0,I_BYTE,I_DOUBLE),    "rotd",
+0,     MOVID,  mk_op2(0x4,I_BYTE,I_WORD),      "movxbw",
+0,     MOVID,  mk_op2(0x7,I_BYTE,I_DOUBLE),    "movxbd",
+0,     MOVID,  mk_op2(0x7,I_WORD,I_DOUBLE),    "movxwd",
+0,     MOVID,  mk_op2(0x5,I_BYTE,I_WORD),      "movzbw",
+0,     MOVID,  mk_op2(0x6,I_BYTE,I_DOUBLE),    "movzbd",
+0,     MOVID,  mk_op2(0x6,I_WORD,I_DOUBLE),    "movzwd",
+#ifdef UNUSED
+0,     MOVID,  mk_op2(0x7,I_DOUBLE,I_DOUBLE),  "movxdd",
+0,     MOVID,  mk_op2(0x6,I_DOUBLE,I_DOUBLE),  "movzdd",
+#endif
+0,     ADD_I,  mk_op2(0x9,I_DOUBLE,I_DOUBLE),  "addr",
+/* Quick integer instructions */
+0,     MOVQ,   mk_op1(0x5,I_BYTE),     "movqb",
+0,     MOVQ,   mk_op1(0x5,I_WORD),     "movqw",
+0,     MOVQ,   mk_op1(0x5,I_DOUBLE),   "movqd",
+0,     MOVQ,   mk_op1(0x1,I_BYTE),     "cmpqb",
+0,     MOVQ,   mk_op1(0x1,I_WORD),     "cmpqw",
+0,     MOVQ,   mk_op1(0x1,I_DOUBLE),   "cmpqd",
+0,     MOVQ,   mk_op1(0x0,I_BYTE),     "addqb",
+0,     MOVQ,   mk_op1(0x0,I_WORD),     "addqw",
+0,     MOVQ,   mk_op1(0x0,I_DOUBLE),   "addqd",
+/* Extended integer instructions */
+0,     MUL_I,  mk_op2(0x9,I_BYTE,I_BYTE),      "meib",
+0,     MUL_I,  mk_op2(0x9,I_WORD,I_WORD),      "meiw",
+0,     MUL_I,  mk_op2(0x9,I_DOUBLE,I_DOUBLE),  "meid",
+0,     MUL_I,  mk_op2(0xB,I_BYTE,I_BYTE),      "deib",
+0,     MUL_I,  mk_op2(0xB,I_WORD,I_WORD),      "deiw",
+0,     MUL_I,  mk_op2(0xB,I_DOUBLE,I_DOUBLE),  "deid",
+/* Boolean instructions */
+0,     COM,    mk_op2(0x9,I_BYTE,I_BYTE),      "notb",
+0,     COM,    mk_op2(0x9,I_WORD,I_WORD),      "notw",
+0,     COM,    mk_op2(0x9,I_DOUBLE,I_DOUBLE),  "notd",
+0,     SEQ,    mk_op1c(0x3,I_BYTE,B_EQ),       "seqb",
+0,     SEQ,    mk_op1c(0x3,I_WORD,B_EQ),       "seqw",
+0,     SEQ,    mk_op1c(0x3,I_DOUBLE,B_EQ),     "seqd",
+0,     SEQ,    mk_op1c(0x3,I_BYTE,B_NE),       "sneb",
+0,     SEQ,    mk_op1c(0x3,I_WORD,B_NE),       "snew",
+0,     SEQ,    mk_op1c(0x3,I_DOUBLE,B_NE),     "sned",
+0,     SEQ,    mk_op1c(0x3,I_BYTE,B_CS),       "scsb",
+0,     SEQ,    mk_op1c(0x3,I_WORD,B_CS),       "scsw",
+0,     SEQ,    mk_op1c(0x3,I_DOUBLE,B_CS),     "scsd",
+0,     SEQ,    mk_op1c(0x3,I_BYTE,B_CC),       "sccb",
+0,     SEQ,    mk_op1c(0x3,I_WORD,B_CC),       "sccw",
+0,     SEQ,    mk_op1c(0x3,I_DOUBLE,B_CC),     "sccd",
+0,     SEQ,    mk_op1c(0x3,I_BYTE,B_HI),       "shib",
+0,     SEQ,    mk_op1c(0x3,I_WORD,B_HI),       "shiw",
+0,     SEQ,    mk_op1c(0x3,I_DOUBLE,B_HI),     "shid",
+0,     SEQ,    mk_op1c(0x3,I_BYTE,B_LS),       "slsb",
+0,     SEQ,    mk_op1c(0x3,I_WORD,B_LS),       "slsw",
+0,     SEQ,    mk_op1c(0x3,I_DOUBLE,B_LS),     "slsd",
+0,     SEQ,    mk_op1c(0x3,I_BYTE,B_GT),       "sgtb",
+0,     SEQ,    mk_op1c(0x3,I_WORD,B_GT),       "sgtw",
+0,     SEQ,    mk_op1c(0x3,I_DOUBLE,B_GT),     "sgtd",
+0,     SEQ,    mk_op1c(0x3,I_BYTE,B_LE),       "sleb",
+0,     SEQ,    mk_op1c(0x3,I_WORD,B_LE),       "slew",
+0,     SEQ,    mk_op1c(0x3,I_DOUBLE,B_LE),     "sled",
+0,     SEQ,    mk_op1c(0x3,I_BYTE,B_FS),       "sfsb",
+0,     SEQ,    mk_op1c(0x3,I_WORD,B_FS),       "sfsw",
+0,     SEQ,    mk_op1c(0x3,I_DOUBLE,B_FS),     "sfsd",
+0,     SEQ,    mk_op1c(0x3,I_BYTE,B_FC),       "sfcb",
+0,     SEQ,    mk_op1c(0x3,I_WORD,B_FC),       "sfcw",
+0,     SEQ,    mk_op1c(0x3,I_DOUBLE,B_FC),     "sfcd",
+0,     SEQ,    mk_op1c(0x3,I_BYTE,B_LO),       "slob",
+0,     SEQ,    mk_op1c(0x3,I_WORD,B_LO),       "slow",
+0,     SEQ,    mk_op1c(0x3,I_DOUBLE,B_LO),     "slod",
+0,     SEQ,    mk_op1c(0x3,I_BYTE,B_HS),       "shsb",
+0,     SEQ,    mk_op1c(0x3,I_WORD,B_HS),       "shsw",
+0,     SEQ,    mk_op1c(0x3,I_DOUBLE,B_HS),     "shsd",
+0,     SEQ,    mk_op1c(0x3,I_BYTE,B_LT),       "sltb",
+0,     SEQ,    mk_op1c(0x3,I_WORD,B_LT),       "sltw",
+0,     SEQ,    mk_op1c(0x3,I_DOUBLE,B_LT),     "sltd",
+0,     SEQ,    mk_op1c(0x3,I_BYTE,B_GE),       "sgeb",
+0,     SEQ,    mk_op1c(0x3,I_WORD,B_GE),       "sgew",
+0,     SEQ,    mk_op1c(0x3,I_DOUBLE,B_GE),     "sged",
+#ifdef UNUSED
+0,     SEQ,    mk_op1c(0x3,I_BYTE,B_TRUE),     "strueb",
+0,     SEQ,    mk_op1c(0x3,I_WORD,B_TRUE),     "struew",
+0,     SEQ,    mk_op1c(0x3,I_DOUBLE,B_TRUE),   "strued",
+0,     SEQ,    mk_op1c(0x3,I_BYTE,B_FALSE),    "sfalseb",
+0,     SEQ,    mk_op1c(0x3,I_WORD,B_FALSE),    "sfalsew",
+0,     SEQ,    mk_op1c(0x3,I_DOUBLE,B_FALSE),  "sfalsed",
+#endif
+/* Bit instructions */
+0,     ADD_I,  mk_op2(0xD,I_BYTE,I_BYTE),      "tbitb",
+0,     ADD_I,  mk_op2(0xD,I_WORD,I_WORD),      "tbitw",
+0,     ADD_I,  mk_op2(0xD,I_DOUBLE,I_DOUBLE),  "tbitd",
+0,     COM,    mk_op2(0x6,I_BYTE,I_BYTE),      "sbitb",
+0,     COM,    mk_op2(0x6,I_WORD,I_WORD),      "sbitw",
+0,     COM,    mk_op2(0x6,I_DOUBLE,I_DOUBLE),  "sbitd",
+0,     COM,    mk_op2(0x7,I_BYTE,I_BYTE),      "sbitib",
+0,     COM,    mk_op2(0x7,I_WORD,I_WORD),      "sbitiw",
+0,     COM,    mk_op2(0x7,I_DOUBLE,I_DOUBLE),  "sbitid",
+0,     COM,    mk_op2(0x2,I_BYTE,I_BYTE),      "cbitb",
+0,     COM,    mk_op2(0x2,I_WORD,I_WORD),      "cbitw",
+0,     COM,    mk_op2(0x2,I_DOUBLE,I_DOUBLE),  "cbitd",
+0,     COM,    mk_op2(0x3,I_BYTE,I_BYTE),      "cbitib",
+0,     COM,    mk_op2(0x3,I_WORD,I_WORD),      "cbitiw",
+0,     COM,    mk_op2(0x3,I_DOUBLE,I_DOUBLE),  "cbitid",
+0,     COM,    mk_op2(0xE,I_BYTE,I_BYTE),      "ibitb",
+0,     COM,    mk_op2(0xE,I_WORD,I_WORD),      "ibitw",
+0,     COM,    mk_op2(0xE,I_DOUBLE,I_DOUBLE),  "ibitd",
+0,     CHECK,  mk_op1(0x1,I_DOUBLE),           "cvtp",
+0,     FFS,    mk_op2c(0x5,I_BYTE,I_BYTE,0),   "ffsb",
+0,     FFS,    mk_op2c(0x5,I_WORD,I_BYTE,0),   "ffsw",
+0,     FFS,    mk_op2c(0x5,I_DOUBLE,I_BYTE,0), "ffsd",
+/* Field instructions */
+0,     INS,    mk_op2(0x0,I_BYTE,I_BYTE),      "extb",
+0,     INS,    mk_op2(0x0,I_WORD,I_WORD),      "extw",
+0,     INS,    mk_op2(0x0,I_DOUBLE,I_DOUBLE),  "extd",
+0,     INSS,   mk_op2(0x3,I_BYTE,I_BYTE),      "extsb",
+0,     INSS,   mk_op2(0x3,I_WORD,I_WORD),      "extsw",
+0,     INSS,   mk_op2(0x3,I_DOUBLE,I_DOUBLE),  "extsd",
+0,     INS,    mk_op2(0x2,I_BYTE,I_BYTE),      "insb",
+0,     INS,    mk_op2(0x2,I_WORD,I_WORD),      "insw",
+0,     INS,    mk_op2(0x2,I_DOUBLE,I_DOUBLE),  "insd",
+0,     INSS,   mk_op2(0x2,I_BYTE,I_BYTE),      "inssb",
+0,     INSS,   mk_op2(0x2,I_WORD,I_WORD),      "inssw",
+0,     INSS,   mk_op2(0x2,I_DOUBLE,I_DOUBLE),  "inssd",
+/* String instructions */
+0,     MOVS,   mk_op1c(0x0,I_BYTE,0),          "movsb",
+0,     MOVS,   mk_op1c(0x0,I_WORD,0),          "movsw",
+0,     MOVS,   mk_op1c(0x0,I_DOUBLE,0),        "movsd",
+0,     MOVS,   mk_op1c(0x0,I_BYTE,SO_TRANS),   "movst",
+0,     MOVS,   mk_op1c(0x1,I_BYTE,0),          "cmpsb",
+0,     MOVS,   mk_op1c(0x1,I_WORD,0),          "cmpsw",
+0,     MOVS,   mk_op1c(0x1,I_DOUBLE,0),        "cmpsd",
+0,     MOVS,   mk_op1c(0x1,I_BYTE,SO_TRANS),   "cmpst",
+0,     MOVS,   mk_op1c(0x3,I_BYTE,0),          "skpsb",
+0,     MOVS,   mk_op1c(0x3,I_WORD,0),          "skpsw",
+0,     MOVS,   mk_op1c(0x3,I_DOUBLE,0),        "skpsd",
+0,     MOVS,   mk_op1c(0x3,I_BYTE,SO_TRANS),   "skpst",
+/* Block instructions */
+0,     MOVM,   mk_op2(0x0,I_BYTE,I_BYTE),      "movmb",
+0,     MOVM,   mk_op2(0x0,I_WORD,I_WORD),      "movmw",
+0,     MOVM,   mk_op2(0x0,I_DOUBLE,I_DOUBLE),  "movmd",
+0,     MOVM,   mk_op2(0x1,I_BYTE,I_BYTE),      "cmpmb",
+0,     MOVM,   mk_op2(0x1,I_WORD,I_WORD),      "cmpmw",
+0,     MOVM,   mk_op2(0x1,I_DOUBLE,I_DOUBLE),  "cmpmd",
+/* Packed decimal instructions */
+0,     COM,    mk_op2(0xF,I_BYTE,I_BYTE),      "addpb",
+0,     COM,    mk_op2(0xF,I_WORD,I_WORD),      "addpw",
+0,     COM,    mk_op2(0xF,I_DOUBLE,I_DOUBLE),  "addpd",
+0,     COM,    mk_op2(0xB,I_BYTE,I_BYTE),      "subpb",
+0,     COM,    mk_op2(0xB,I_WORD,I_WORD),      "subpw",
+0,     COM,    mk_op2(0xB,I_DOUBLE,I_DOUBLE),  "subpd",
+/* Array instructions */
+0,     CHECK,  mk_op2(0x4,I_BYTE,I_BYTE),      "indexb",
+0,     CHECK,  mk_op2(0x4,I_WORD,I_WORD),      "indexw",
+0,     CHECK,  mk_op2(0x4,I_DOUBLE,I_DOUBLE),  "indexd",
+0,     CHECK,  mk_op2(0x3,I_BYTE,I_BYTE),      "checkb",
+0,     CHECK,  mk_op2(0x3,I_WORD,I_WORD),      "checkw",
+0,     CHECK,  mk_op2(0x3,I_DOUBLE,I_DOUBLE),  "checkd",
+/* Processor control instructions */
+0,     JUMP,   mk_op1(0x4,I_DOUBLE),   "jump",
+0,     BR,     mk_c(B_EQ),             "beq",
+0,     BR,     mk_c(B_NE),             "bne",
+0,     BR,     mk_c(B_CS),             "bcs",
+0,     BR,     mk_c(B_CC),             "bcc",
+0,     BR,     mk_c(B_HI),             "bhi",
+0,     BR,     mk_c(B_LS),             "bls",
+0,     BR,     mk_c(B_GT),             "bgt",
+0,     BR,     mk_c(B_LE),             "ble",
+0,     BR,     mk_c(B_FS),             "bfs",
+0,     BR,     mk_c(B_FC),             "bfc",
+0,     BR,     mk_c(B_LO),             "blo",
+0,     BR,     mk_c(B_HS),             "bhs",
+0,     BR,     mk_c(B_LT),             "blt",
+0,     BR,     mk_c(B_GE),             "bge",
+0,     BR,     mk_c(B_TRUE),           "br",
+#ifdef UNUSED
+0,     BR,     mk_c(B_FALSE),          "bfalse",
+#endif
+0,     ADJSP,  mk_op1(0xE,I_BYTE),     "caseb",
+0,     ADJSP,  mk_op1(0xE,I_WORD),     "casew",
+0,     ADJSP,  mk_op1(0xE,I_DOUBLE),   "cased",
+0,     ACB,    mk_op1(0x4,I_BYTE),     "acbb",
+0,     ACB,    mk_op1(0x4,I_WORD),     "acbw",
+0,     ACB,    mk_op1(0x4,I_DOUBLE),   "acbd",
+0,     JSR,    mk_op1(0xC,I_DOUBLE),   "jsr",
+0,     BSR,    mk_op(0x0),             "bsr",
+0,     RET,    mk_op(0x1),             "ret",
+0,     RET,    mk_op(0x2),             "cxp",
+0,     ADJSP,  mk_op1(0x0,I_DOUBLE),   "cxpd",
+0,     RET,    mk_op(0x3),             "rxp",
+0,     RET,    mk_op(0x4),             "rett",
+0,     WAIT,   mk_op(0x5),             "reti",
+0,     WAIT,   mk_op(0xC),             "dia",
+/* Processor service instructions */
+0,     ADJSP,  mk_op1(0xA,I_BYTE),     "adjspb",
+0,     ADJSP,  mk_op1(0xA,I_WORD),     "adjspw",
+0,     ADJSP,  mk_op1(0xA,I_DOUBLE),   "adjspd",
+0,     ADJSP,  mk_op1(0x2,I_BYTE),     "bicpsrb",
+0,     ADJSP,  mk_op1(0x2,I_WORD),     "bicpsrw",
+0,     ADJSP,  mk_op1(0x6,I_BYTE),     "bispsrb",
+0,     ADJSP,  mk_op1(0x6,I_WORD),     "bispsrw",
+#ifdef UNUSED
+0,     ADJSP,  mk_op1(0x2,I_DOUBLE),   "bicpsrd",
+0,     ADJSP,  mk_op1(0x6,I_DOUBLE),   "bispsrd",
+#endif
+0,     SAVE,   mk_op(0x6),             "save",
+0,     SAVE,   mk_op(0x7),             "restore",
+0,     ENTER,  mk_op(0x8),             "enter",
+0,     SAVE,   mk_op(0x9),             "exit",
+0,     LPR,    mk_op1(0x6,I_BYTE),     "lprb",
+0,     LPR,    mk_op1(0x6,I_WORD),     "lprw",
+0,     LPR,    mk_op1(0x6,I_DOUBLE),   "lprd",
+0,     LPR,    mk_op1(0x2,I_BYTE),     "sprb",
+0,     LPR,    mk_op1(0x2,I_WORD),     "sprw",
+0,     LPR,    mk_op1(0x2,I_DOUBLE),   "sprd",
+0,     SETCFG, mk_op1(0x2,I_DOUBLE),   "setcfg",
+0,     WAIT,   mk_op(0xF),             "bpt",
+0,     WAIT,   mk_op(0xD),             "flag",
+0,     WAIT,   mk_op(0xE),             "svc",
+0,     WAIT,   mk_op(0xA),             "nop",
+0,     WAIT,   mk_op(0xB),             "wait",
+/* Memory management instructions */
+0,     LMR,    mk_op1(0x2,I_DOUBLE),   "lmr",
+0,     LMR,    mk_op1(0x3,I_DOUBLE),   "smr",
+0,     RDVAL,  mk_op1(0x0,I_DOUBLE),   "rdval",
+0,     RDVAL,  mk_op1(0x1,I_DOUBLE),   "wrval",
+#ifdef SU_ASSEM
+/* The assembler ref. man and the CPU description booklet differ
+   in the encoding of these instructions
+*/
+0,     FFS,    mk_op2c(0x6,I_BYTE,I_BYTE,1),   "movsub",
+0,     FFS,    mk_op2c(0x6,I_WORD,I_WORD,1),   "movsuw",
+0,     FFS,    mk_op2c(0x6,I_DOUBLE,I_DOUBLE,1),"movsud",
+0,     FFS,    mk_op2c(0x6,I_BYTE,I_BYTE,3),   "movusb",
+0,     FFS,    mk_op2c(0x6,I_WORD,I_WORD,3),   "movusw",
+0,     FFS,    mk_op2c(0x6,I_DOUBLE,I_DOUBLE,3),"movusd",
+#else
+/* assembler reference manual version */
+0,     FFS,    mk_op2c(0x7,I_BYTE,I_BYTE,0),   "movsub",
+0,     FFS,    mk_op2c(0x7,I_WORD,I_WORD,0),   "movsuw",
+0,     FFS,    mk_op2c(0x7,I_DOUBLE,I_DOUBLE,0),"movsud",
+0,     FFS,    mk_op2c(0x6,I_BYTE,I_BYTE,0),   "movusb",
+0,     FFS,    mk_op2c(0x6,I_WORD,I_WORD,0),   "movusw",
+0,     FFS,    mk_op2c(0x6,I_DOUBLE,I_DOUBLE,0),"movusd",
+#endif
+/* Floating point instructions */
+0,     ADD_F,  mk_op2(0xD,F_FLOAT,F_FLOAT),    "absf",
+0,     ADD_F,  mk_op2(0xD,F_LONG,F_LONG),      "absl",
+0,     ADD_F,  mk_op2(0x0,F_FLOAT,F_FLOAT),    "addf",
+0,     ADD_F,  mk_op2(0x0,F_LONG,F_LONG),      "addl",
+0,     ADD_F,  mk_op2(0x2,F_FLOAT,F_FLOAT),    "cmpf",
+0,     ADD_F,  mk_op2(0x2,F_LONG,F_LONG),      "cmpl",
+0,     ADD_F,  mk_op2(0x8,F_FLOAT,F_FLOAT),    "divf",
+0,     ADD_F,  mk_op2(0x8,F_LONG,F_LONG),      "divl",
+0,     ADD_F,  mk_op2(0xC,F_FLOAT,F_FLOAT),    "mulf",
+0,     ADD_F,  mk_op2(0xC,F_LONG,F_LONG),      "mull",
+0,     ADD_F,  mk_op2(0x4,F_FLOAT,F_FLOAT),    "subf",
+0,     ADD_F,  mk_op2(0x4,F_LONG,F_LONG),      "subl",
+0,     ADD_F,  mk_op2(0x5,F_FLOAT,F_FLOAT),    "negf",
+0,     ADD_F,  mk_op2(0x5,F_LONG,F_LONG),      "negl",
+0,     ADD_F,  mk_op2(0x1,F_FLOAT,F_FLOAT),    "movf",
+0,     ADD_F,  mk_op2(0x1,F_LONG,F_LONG),      "movl",
+0,     MOVIF,  mk_op2(0x0,I_BYTE,F_FLOAT),     "movbf",
+0,     MOVIF,  mk_op2(0x0,I_WORD,F_FLOAT),     "movwf",
+0,     MOVIF,  mk_op2(0x0,I_DOUBLE,F_FLOAT),   "movdf",
+0,     MOVIF,  mk_op2(0x0,I_BYTE,F_LONG),      "movbl",
+0,     MOVIF,  mk_op2(0x0,I_WORD,F_LONG),      "movwl",
+0,     MOVIF,  mk_op2(0x0,I_DOUBLE,F_LONG),    "movdl",
+0,     MOVFL,  mk_op2(0x3,F_FLOAT,F_LONG),     "movfl",
+0,     MOVFL,  mk_op2(0x2,F_LONG,F_FLOAT),     "movlf",
+0,     TRUNC,  mk_op2(0x7,F_FLOAT,I_BYTE),     "floorfb",
+0,     TRUNC,  mk_op2(0x7,F_FLOAT,I_WORD),     "floorfw",
+0,     TRUNC,  mk_op2(0x7,F_FLOAT,I_DOUBLE),   "floorfd",
+0,     TRUNC,  mk_op2(0x7,F_LONG,I_BYTE),      "floorlb",
+0,     TRUNC,  mk_op2(0x7,F_LONG,I_WORD),      "floorlw",
+0,     TRUNC,  mk_op2(0x7,F_LONG,I_DOUBLE),    "floorld",
+0,     TRUNC,  mk_op2(0x4,F_FLOAT,I_BYTE),     "roundfb",
+0,     TRUNC,  mk_op2(0x4,F_FLOAT,I_WORD),     "roundfw",
+0,     TRUNC,  mk_op2(0x4,F_FLOAT,I_DOUBLE),   "roundfd",
+0,     TRUNC,  mk_op2(0x4,F_LONG,I_BYTE),      "roundlb",
+0,     TRUNC,  mk_op2(0x4,F_LONG,I_WORD),      "roundlw",
+0,     TRUNC,  mk_op2(0x4,F_LONG,I_DOUBLE),    "roundld",
+0,     TRUNC,  mk_op2(0x5,F_FLOAT,I_BYTE),     "truncfb",
+0,     TRUNC,  mk_op2(0x5,F_FLOAT,I_WORD),     "truncfw",
+0,     TRUNC,  mk_op2(0x5,F_FLOAT,I_DOUBLE),   "truncfd",
+0,     TRUNC,  mk_op2(0x5,F_LONG,I_BYTE),      "trunclb",
+0,     TRUNC,  mk_op2(0x5,F_LONG,I_WORD),      "trunclw",
+0,     TRUNC,  mk_op2(0x5,F_LONG,I_DOUBLE),    "truncld",
+0,     LFSR,   mk_op(0x1),             "lfsr",
+0,     LFSR,   mk_op(0x6),             "sfsr",
+/* Slave processor instructions */
+0,     LCR,    mk_op1(0x2,I_DOUBLE),   "lcr", /* Sure ? */
+0,     LCR,    mk_op1(0x3,I_DOUBLE),   "scr", /* Sure ? */
+0,     CATST,  mk_op1(0x0,I_DOUBLE),   "catst0",/* Sure ? */
+0,     CATST,  mk_op1(0x1,I_DOUBLE),   "catst1",/* Sure ? */
+0,     LCSR,   mk_op1(0x1,S_DOUBLE),   "lcsr",  /* Sure ? */
+0,     LCSR,   mk_op1(0x6,S_DOUBLE),   "scsr",  /* Sure ? */
+0,     CCVSI,  mk_op2(0x7,S_DOUBLE,I_BYTE),    "ccv0db",
+0,     CCVSI,  mk_op2(0x7,S_DOUBLE,I_WORD),    "ccv0dw",
+0,     CCVSI,  mk_op2(0x7,S_DOUBLE,I_DOUBLE),  "ccv0dd",
+0,     CCVSI,  mk_op2(0x7,S_QUAD,I_BYTE),      "ccv0qb",
+0,     CCVSI,  mk_op2(0x7,S_QUAD,I_WORD),      "ccv0qw",
+0,     CCVSI,  mk_op2(0x7,S_QUAD,I_DOUBLE),    "ccv0qd",
+0,     CCVSI,  mk_op2(0x5,S_DOUBLE,I_BYTE),    "ccv1db",
+0,     CCVSI,  mk_op2(0x5,S_DOUBLE,I_WORD),    "ccv1dw",
+0,     CCVSI,  mk_op2(0x5,S_DOUBLE,I_DOUBLE),  "ccv1dd",
+0,     CCVSI,  mk_op2(0x5,S_QUAD,I_BYTE),      "ccv1qb",
+0,     CCVSI,  mk_op2(0x5,S_QUAD,I_WORD),      "ccv1qw",
+0,     CCVSI,  mk_op2(0x5,S_QUAD,I_DOUBLE),    "ccv1qd",
+0,     CCVSI,  mk_op2(0x4,S_DOUBLE,I_BYTE),    "ccv2db",
+0,     CCVSI,  mk_op2(0x4,S_DOUBLE,I_WORD),    "ccv2dw",
+0,     CCVSI,  mk_op2(0x4,S_DOUBLE,I_DOUBLE),  "ccv2dd",
+0,     CCVSI,  mk_op2(0x4,S_QUAD,I_BYTE),      "ccv2qb",
+0,     CCVSI,  mk_op2(0x4,S_QUAD,I_WORD),      "ccv2qw",
+0,     CCVSI,  mk_op2(0x4,S_QUAD,I_DOUBLE),    "ccv2qd",
+0,     CCVIS,  mk_op2(0x0,I_BYTE,S_DOUBLE),    "ccv3bd",
+0,     CCVIS,  mk_op2(0x0,I_WORD,S_DOUBLE),    "ccv3wd",
+0,     CCVIS,  mk_op2(0x0,I_DOUBLE,S_DOUBLE),  "ccv3dd",
+0,     CCVIS,  mk_op2(0x0,I_BYTE,S_QUAD),      "ccv3bq",
+0,     CCVIS,  mk_op2(0x0,I_WORD,S_QUAD),      "ccv3wq",
+0,     CCVIS,  mk_op2(0x0,I_DOUBLE,S_QUAD),    "ccv3dq",
+0,     CCVSS,  mk_op2(0x3,S_DOUBLE,S_QUAD),    "ccv4dq",
+0,     CCVSS,  mk_op2(0x2,S_QUAD,S_DOUBLE),    "ccv5qd",
+0,     CMOV,   mk_op2(0x0,S_DOUBLE,S_DOUBLE),  "ccal0d",
+0,     CMOV,   mk_op2(0x0,S_QUAD,S_QUAD),      "ccal0q",
+0,     CMOV,   mk_op2(0x4,S_DOUBLE,S_DOUBLE),  "ccal1d",
+0,     CMOV,   mk_op2(0x4,S_QUAD,S_QUAD),      "ccal1q",
+0,     CMOV,   mk_op2(0xC,S_DOUBLE,S_DOUBLE),  "ccal2d",
+0,     CMOV,   mk_op2(0xC,S_QUAD,S_QUAD),      "ccal2q",
+0,     CMOV,   mk_op2(0x8,S_DOUBLE,S_DOUBLE),  "ccal3d",
+0,     CMOV,   mk_op2(0x8,S_QUAD,S_QUAD),      "ccal3q",
+0,     CMOV,   mk_op2(0x2,S_DOUBLE,S_DOUBLE),  "ccmpd",
+0,     CMOV,   mk_op2(0x2,S_QUAD,S_QUAD),      "ccmpq",
+0,     CMOV,   mk_op2(0x1,S_DOUBLE,S_DOUBLE),  "cmov0d",
+0,     CMOV,   mk_op2(0x1,S_QUAD,S_QUAD),      "cmov0q",
+0,     CMOV,   mk_op2(0xD,S_DOUBLE,S_DOUBLE),  "cmov1d",
+0,     CMOV,   mk_op2(0xD,S_QUAD,S_QUAD),      "cmov1q",
+0,     CMOV,   mk_op2(0x5,S_DOUBLE,S_DOUBLE),  "cmov2d",
+0,     CMOV,   mk_op2(0x5,S_QUAD,S_QUAD),      "cmov2q",
diff --git a/mach/ns/as/mach4.c b/mach/ns/as/mach4.c
new file mode 100644 (file)
index 0000000..74772fc
--- /dev/null
@@ -0,0 +1,416 @@
+#define RCSID4 "$Header$"
+
+/*
+ * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ *
+ *          This product is part of the Amsterdam Compiler Kit.
+ *
+ * Permission to use, sell, duplicate or disclose this software must be
+ * obtained in writing. Requests for such permissions may be sent to
+ *
+ *      Dr. Andrew S. Tanenbaum
+ *      Wiskundig Seminarium
+ *      Vrije Universiteit
+ *      Postbox 7161
+ *      1007 MC Amsterdam
+ *      The Netherlands
+ *
+ */
+
+/* Author: Ed Keizer */
+
+operation:
+               BR      expr
+               /* format 0 */
+                       { dot_adjust(&$2) ; form0($1) ; disp(&$2, RELPC) ;}
+       |       WAIT
+               /* format 1 */
+                       { form1($1) ;}
+       |       BSR     expr
+               /* format 1 */
+                       { dot_adjust(&$2) ; form1($1) ; disp(&$2, RELPC) ;}
+       |       RET     expr
+               /* format 1 */
+                       { form1($1) ; disp(&$2, 0) ;}
+       |       SAVE    reg_list
+               /* format 1 */
+                       { form1($1) ; emit1(reg_list($2,id_op($1)!=0x6)) ;}
+       |       ENTER   reg_list ',' expr
+               /* format 1 */
+                       { form1($1) ; emit1(reg_list($2,0)) ; disp(&$4, 0) ;}
+       |       LPR     AREG ',' gen1
+               /* format 2 */
+                       { if ( id_op($1)==0x2 ) not_imm(&mode1) ;
+                         form2($1,$2) ; gen1($1) ;
+                       }
+       |       SEQ     gen1
+               /* format 2 */
+                       { form2($1,id_cc($1)) ; gen1($1) ; not_imm(&mode1) ;}
+       |       MOVQ    absexp ',' gen1
+               /* format 2 */
+                       {
+                         if ( !fit4($2) ) {
+                               serror("Constant too large") ;
+                         }
+                         form2($1,low4($2)) ; gen1($1) ;
+                         if ( id_op($1)!=0x1 ) not_imm(&mode1) ; /* !cmp */
+                       }
+       |       ACB     absexp ',' gen1 ',' expr
+               /* format 2 */
+                       {
+                         dot_adjust(&$6) ;
+                         if (!fit4($2) ) {
+                               serror("Constant too large") ;
+                         }
+                         form2($1,low4($2)) ; gen1($1) ; not_imm(&mode1) ;
+                         disp(&$6, RELPC) ;
+                       }
+       |       ADJSP   gen1
+               /* format 3 */
+                       {
+                         if ( id_op($1)==0 ) not_imm(&mode1) ; /* cxpd */
+                         form3($1) ; gen1($1) ;}
+       |       JSR     gen1
+               /* format 3 */
+                       {
+#ifndef NO_OPTIM
+                         if ( mode1.m_mode==0x15 ) { /* Absolute */
+                               dot_adjust(&mode1.m_expr1) ;
+                               RELOMOVE(relonami, mode1.m_rel1);
+                               form1(0) ; disp(&mode1.m_expr1, RELPC) ; /* bsr */
+                         } else
+#endif
+                         { form3($1) ; gen1($1) ; }
+                         not_imm(&mode1) ;
+                       }
+       |       JUMP    gen1
+               /* format 3 */
+                       {
+#ifndef NO_OPTIM
+                         if ( mode1.m_mode==0x15 ) { /* Absolute */
+                               dot_adjust(&mode1.m_expr1) ;
+                               RELOMOVE(relonami, mode1.m_rel1);
+                               form0(B_TRUE) ; disp(&mode1.m_expr1, RELPC) ; /* br */
+                         } else
+#endif
+                         { form3($1) ; gen1($1) ; }
+                         not_imm(&mode1) ;
+                       }
+       |       ADD_I   gen1 ',' gen2
+               /* format 4 */
+                       {
+                         register opc ;
+                         opc=id_op($1) ;
+                         if ( opc==0x9 ) not_imm(&mode1) ; /* addr */
+                         if ( opc!=0x1 ) not_imm(&mode2) ; /* !cmp */
+#ifndef NO_OPTIM
+                         if ( mode1.m_mode==0x14 && /* Immediate */
+                              (mode1.m_expr1.typ & ~S_EXT) == S_ABS &&
+                              (
+                                (fit4(mode1.m_expr1.val) &&
+                                 (opc==0 || opc==1 || opc==5))
+                                ||
+                                (fit4(-mode1.m_expr1.val) &&
+                                 (opc==8))
+                              )
+                            )
+                          {
+                              /* Warning, an absolute expression derived
+                                 from a symbol that is defined after
+                                 use might - if the value now suddenly fits -
+                                 cause failed assertions in newlabel
+                               */
+                              /* add,     cmp,     mov         */
+                              /* added: the subtract of a signed
+                               *        short is the same as the add
+                               *        of the negation of that short
+                               * so: subi short,x == addqi -short,x
+                               * 19/04/85 h.m.kodden,m.j.a.leliveld 
+                               */
+                               if (opc==8)     /* do the negate */
+                                       mode1.m_expr1.val = 
+                                       (~mode1.m_expr1.val+1)&0xF;
+                               opc=low4(mode1.m_expr1.val) ;
+                               mode1= mode2 ;
+                               form2($1,opc) ; gen1($1) ;
+                         } else
+#endif
+                         { form4($1) ; gengen($1) ; }
+                       }
+       |       SETCFG  cpu_opts
+               /* format 5 */
+                       { form5($1,$2) ;}
+       |       MOVS    string_opts
+               /* format 5 */
+                       { form5($1,($2)|id_cc($1)) ;}
+       |       COM     gen1 ',' gen2
+               /* format 6 */
+                       { form6($1) ; gengen($1) ; not_imm(&mode2) ;}
+       |       MUL_I   gen1 ',' gen2
+               /* format 7 */
+                       { 
+                         if ( id_op($1)==0x9 || id_op($1)==0xB ) {
+                               /* mei or dei */
+                               switch ( mode2.m_mode ) {
+                               case 1 : case 3 : case 5 : case 7 :
+                                       serror("register must be even") ;
+                               }
+                         }
+                         form7($1) ; gengen($1) ; not_imm(&mode2) ;
+                       }
+       |       MOVID   gen1 ',' gen2
+               /* format 7 */
+                       { form7x($1,id_g1($1)) ; gengen($1) ; not_imm(&mode2) ;}
+       |       MOVM    gen1 ',' gen2 ',' expr
+               /* format 7 */
+                       {
+                         register s_size ;
+                         s_size= id_g1($1)+1 ;
+                         /* $6.val= $6.val*s_size - s_size ; */
+                         $6.val= $6.val -1 ;
+                         form7($1) ; gengen($1) ; disp(&$6, 0) ;
+                         not_imm(&mode1) ; not_imm(&mode2) ;
+                       }
+       |       INSS    gen1 ',' gen2 ',' absexp ',' absexp
+               /* format 7 */
+                       { 
+                         if ( ( $6<0 || $6>7 || $8<1 || $8>32 )
+                            ) { serror("Constant out of bounds") ; }
+                         form7($1) ; gengen($1) ;
+                         if ( id_op($1)==0x3 ) not_imm(&mode1) ; /* exts */
+                         not_imm(&mode2) ;
+                         emit1((((int)$6)<<5)+(int)$8-1) ;
+                       }
+       |       FFS     gen1 ',' gen2
+               /* format 8 */
+                       { form8($1,id_cc($1)) ; gengen($1) ; not_imm(&mode2) ;}
+       |       CHECK   REG ',' gen1 ',' gen2
+               /* format 8 */
+                       {
+                         form8($1,$2) ; gengen($1) ;
+                         if ( id_op($1)!=0x4 ) {
+                               not_imm(&mode1) ; /* check, cvtp */
+                               if ( id_op($1)==0x1 ) not_imm(&mode2) ;/*cvtp */
+                         }
+                       }
+       |       INS     REG ',' gen1 ',' gen2 ',' expr
+               /* format 8 */
+                       {
+                         form8($1,$2) ; gengen($1) ; disp(&$8, 0) ;
+                         if ( id_op($1)==0x0 ) not_imm(&mode1) ;
+                         not_imm(&mode2) ;
+                       }
+       |       MOVIF   gen1 ',' fgen2
+               /* format 9 */
+                       {
+                         assert( id_t1($1)==T_INT && id_t2($1)==T_FL ) ;
+                         form9($1,id_g1($1),id_g2($1)) ; gengen($1) ;
+                         not_imm(&mode2) ;
+                       }
+       |       MOVFL   fgen1 ',' fgen2
+               /* format 9 */
+                       {
+                         assert( id_t1($1)==T_FL && id_t2($1)==T_FL ) ;
+                         form9($1,id_g1($1),( id_g2($1)==F_LONG?3:2 )) ;
+                         gengen($1) ; not_imm(&mode2) ;
+                       }
+       |       TRUNC   fgen1 ',' gen2
+               /* format 9 */
+                       {
+                         assert( id_t1($1)==T_FL && id_t2($1)==T_INT ) ;
+                         form9($1,id_g2($1),id_g1($1)) ; gengen($1) ;
+                         not_imm(&mode2) ;
+                       }
+       |       LFSR    gen1
+               /* format 9 */
+                       { 
+                         if ( id_op($1)==6 ) { /* SFSR */
+                               not_imm(&mode1) ;
+                               mode2.m_mode=mode1.m_mode ;
+                               mode1.m_mode=0 ;
+                         } else {
+                               mode2.m_mode=0 ;
+                         }
+                         form9($1,0,0) ;
+                         if ( id_op($1)==6 ) {
+                               mode1.m_mode=mode2.m_mode ;
+                         }
+                         gen1($1) ;
+                       }
+       |       ADD_F   fgen1 ',' fgen2
+               /* format 11 */
+                       { if ( id_op($1)!=0x2 ) not_imm(&mode2) ; /* !CMPF */
+                         form11($1) ; gengen($1) ;
+                       }
+       |       RDVAL   gen1
+               /* format 14 */
+                       { form14($1,0) ; gen1($1) ; not_imm(&mode1) ;}
+       |       LMR     MREG ',' gen1
+               /* format 14 */
+                       {
+                         form14($1,$2) ; gen1($1) ;
+                         if ( id_op($1)==0x3 ) not_imm(&mode1) ;
+                       }
+                       /* All remaining categories are not checked for
+                          illegal immediates */
+       |       LCR     CREG ',' gen1
+               /* format 15.0 */
+                       { frm15_0($1,$2) ; gen1($1) ;}
+       |       CATST   gen1
+               /* format 15.0 */
+                       { frm15_0($1,0) ; gen1($1) ;}
+       |       LCSR    gen1
+               /* format 15.1 */ /* Sure? */
+                       { mode2.m_mode=0 ; frm15_1($1,0,0) ; gen1($1) ;}
+       |       CCVIS   gen1 ',' gen2
+               /* format 15.1 */
+                       {
+                         assert( id_t1($1)==T_INT && id_t2($1)==T_SLAVE ) ;
+                         frm15_1($1,id_g1($1),id_g2($1)) ; gengen($1) ;
+                       }
+       |       CCVSI   gen1 ',' gen2
+               /* format 15.1 */
+                       { 
+                         assert( id_t1($1)==T_SLAVE && id_t2($1)==T_INT ) ;
+                         frm15_1($1,id_g2($1),id_g1($1)) ; gengen($1) ;
+                       }
+       |       CCVSS   gen1 ',' gen2
+               /* format 15.1 */
+                       {
+                         assert( id_t1($1)==T_SLAVE && id_t2($1)==T_SLAVE ) ;
+                         frm15_1($1,0,0) ; gengen($1) ; /* Sure? */
+                       }
+       |       CMOV    gen1 ',' gen2
+               /* format 15.5 */
+                       { frm15_5($1) ; gengen($1) ;}
+       ;
+
+gen1   :       { mode_ptr= &mode1 ; clrmode() ; } gen
+       ;
+gen2   :       { mode_ptr= &mode2 ; clrmode() ; } gen
+       ;
+fgen1  :       { mode_ptr= &mode1 ; clrmode() ; } fgen
+       ;
+fgen2  :       { mode_ptr= &mode2 ; clrmode() ; } fgen
+       ;
+
+gen    :       gen_not_reg             /* Every mode except register */
+       |       REG
+                       { mode_ptr->m_mode= $1 ; }
+       ;
+fgen   :       gen_not_reg             /* Every mode except register */
+       |       FREG
+                       { mode_ptr->m_mode= $1 ; }
+       ;
+
+gen_not_reg:   gen_a                   /* general mode with eff. address */
+       |       REG { mode_ptr->m_mode=$1 ;} index
+                               /* The register is supposed to contain the
+                                  address
+                               */
+       |       gen_a index             /* As above, but indexed */
+       |       expr                    /* Immediate */
+                       { mode_ptr->m_mode= 0x14 ;
+                         mode_ptr->m_expr1= $1 ;
+                         RELOMOVE(mode_ptr->m_rel1, relonami);
+                       }
+       ;
+
+gen_a  :       expr '(' REG ')'                /* Register relative */
+                       { mode_ptr->m_mode= 0x8 + $3 ;
+                         mode_ptr->m_ndisp= 1 ;
+                         mode_ptr->m_expr1= $1 ;
+                         RELOMOVE(mode_ptr->m_rel1, relonami);
+                       }
+       |       expr '(' AREG ')'               /* Memory space */
+                       { if ( $3<0x8 || $3>0xA ) badsyntax() ;
+                         mode_ptr->m_mode= 0x18 + ($3&3) ;
+                         mode_ptr->m_ndisp= 1 ;
+                         mode_ptr->m_expr1= $1 ;
+                         RELOMOVE(mode_ptr->m_rel1, relonami);
+                       }
+       |       expr '(' PC ')'                 /* Memory space */
+                       { mode_ptr->m_mode= 0x1B ;
+                         mode_ptr->m_ndisp= 1 ;
+                         mode_ptr->m_expr1= $1 ;
+                         RELOMOVE(mode_ptr->m_rel1, relonami);
+                         dot_adjust(&mode_ptr->m_expr1) ;
+                       }
+       |       expr '('
+                       { mode_ptr->m_expr2 = $1;
+                         RELOMOVE(mode_ptr->m_rel2, relonami);
+                       }
+               expr '(' AREG ')' ')'   /* Memory relative */
+                       { if ( $6<0x8 || $6>0xA ) badsyntax() ;
+                         mode_ptr->m_mode= 0x10 + ($6&3) ;
+                         mode_ptr->m_ndisp= 2 ;
+                         mode_ptr->m_expr1= $4 ;
+                         RELOMOVE(mode_ptr->m_rel1, relonami);
+                       }
+       |       '@' expr                        /* Absolute */
+                       { mode_ptr->m_mode= 0x15 ;
+                         mode_ptr->m_ndisp= 1 ;
+                         mode_ptr->m_expr1= $2 ;
+                         RELOMOVE(mode_ptr->m_rel1, relonami);
+                       }
+       |       EXTERNAL '(' expr ')' 
+                       { mode_ptr->m_mode= 0x16 ;
+                         mode_ptr->m_ndisp= 2 ;
+                         mode_ptr->m_expr1= $3 ;
+                         RELOMOVE(mode_ptr->m_rel1, relonami);
+                       }
+               '+' expr        /* External */
+                       {
+                         mode_ptr->m_expr2= $7 ;
+                         RELOMOVE(mode_ptr->m_rel2, relonami);
+                       }
+       |       TOS                             /* Top Of Stack */
+                       { mode_ptr->m_mode= 0x17 ; }
+       ;
+
+index  :       '[' REG ':' INDICATOR ']'       /* Indexed postfix */
+                       { mode_ptr->m_index= (mode_ptr->m_mode<<3) | $2 ;
+                         mode_ptr->m_mode= ind_mode( $4 ) ;
+                       }
+       ;
+
+cpu_opts:
+               '[' ']'
+                       { $$=0 ;}
+       |       '[' cpu_list ']'
+                       { $$= $2 ;}
+       ;
+
+cpu_list:
+               INDICATOR
+                       { $$=cpu_opt($1) ; }
+       |       cpu_list ',' INDICATOR
+                       { $$= ($1) | cpu_opt($3) ;}
+       ;
+
+string_opts:
+                       { $$=0 ;}
+       |       INDICATOR
+                       { $$= string_opt($1) ; }
+       |       INDICATOR ',' INDICATOR
+                       { if ( $1 != 'b' ||
+                               ( $3 != 'u' && $3 != 'w' ) ) {
+                                       serror("illegal string options") ;
+                         }
+                         $$ = string_opt($1)|string_opt($3) ;
+                       }
+       ;
+
+reg_list:
+               '[' ']'
+                       { $$=0 ;}
+       |       '[' reg_items ']'
+                       { $$= $2 ;}
+       ;
+
+reg_items:
+               REG
+                       { $$= 1<<($1) ; }
+       |       reg_items ',' REG
+                       { $$= ($1) | ( 1<<($3) ) ;}
+       ;
diff --git a/mach/ns/as/mach5.c b/mach/ns/as/mach5.c
new file mode 100644 (file)
index 0000000..b61ccb1
--- /dev/null
@@ -0,0 +1,311 @@
+#define RCSID5 "$Header$"
+
+/*
+ * NS 16032 special routines
+ */
+
+clrmode() {    /* clear the current mode */
+       mode_ptr->m_ndisp   = 0 ;
+}
+
+int ind_mode(type) {
+       switch ( type ) {
+       case 'b' :      return 0x1C ;
+       case 'w' :      return 0x1D ;
+       case 'd' :      return 0x1E ;
+       case 'q' :      return 0x1F ;
+       default :
+                       serror("illegal size indicator") ;
+                       return 0x1F ;
+       }
+}
+
+badsyntax() {
+
+       serror("bad operands");
+}
+
+ill_imm() {
+       serror("immediate operand not allowed") ;
+}
+/* Create  the output formats */
+form2(id,sval) {
+       assert ( id_t1(id)==T_INT ) ;
+       emit1( id_g1(id) | 0xC | (id_op(id)<<4) | ((sval&1)<<7 ) ) ;
+       emit1( (sval>>1) | (mode1.m_mode<<3) ) ;
+}
+
+form3(id) {
+       assert ( id_t1(id)==T_INT ) ;
+       emit1( id_g1(id) | 0x7C | ((id_op(id)&1)<<7) ) ;
+       emit1( (id_op(id)>>1) | (mode1.m_mode<<3) ) ;
+}
+
+form4(id) {
+       assert ( id_t1(id)==T_INT && id_t2(id)==T_INT );
+       emit1( id_g2(id) | (id_op(id)<<2) | ((mode2.m_mode&3)<<6) ) ;
+       emit1( (mode2.m_mode>>2) | (mode1.m_mode<<3) ) ;
+}
+
+form5(id,sval) {
+       assert ( id_t1(id)==T_INT ) ;
+       emit1(0xE) ;
+       emit1( id_g1(id) | (id_op(id)<<2) | ((sval&1)<<7 ) ) ;
+       emit1( (sval>>1) ) ;
+}
+
+form7x(id,i_type) {
+       assert ( id_t1(id)==T_INT && id_t2(id)==T_INT );
+       emit1(0xCE) ;
+       emit1( i_type | (id_op(id)<<2) | ((mode2.m_mode&3)<<6) ) ;
+       emit1( (mode2.m_mode>>2) | (mode1.m_mode<<3) ) ;
+}
+
+form8(id,reg) {
+       assert ( id_t1(id)==T_INT ) ;
+       emit1( 0x2E | ((id_op(id)&3)<<6) ) ;
+       emit1( id_g1(id) | (id_op(id)&04) | (reg<<3) | ((mode2.m_mode&03)<<6) ) ;
+       emit1( (mode2.m_mode>>2) | (mode1.m_mode<<3) ) ;
+}
+
+form9(id,i_type,f_type) {
+       emit1(0x3E) ;
+       emit1( i_type | (f_type<<2) | (id_op(id)<<3) | ((mode2.m_mode&03)<<6) ) ;
+       emit1( (mode2.m_mode>>2) | (mode1.m_mode<<3) ) ;
+}
+
+form11(id) {
+       assert ( id_t1(id)==T_FL && id_t2(id)==T_FL && id_g1(id)==id_g2(id) );
+       emit1(0xBE) ;
+       emit1( id_g1(id) | (id_op(id)<<2) | ((mode2.m_mode&3)<<6) ) ;
+       emit1( (mode2.m_mode>>2) | (mode1.m_mode<<3) ) ;
+}
+
+form14(id,reg) {
+       assert ( id_t1(id)==T_INT ) ;
+       emit1(0x1E) ;
+       emit1( id_g1(id) | (id_op(id)<<2) | ((reg&1)<<7 ) ) ;
+       emit1( (reg>>1) | (mode1.m_mode<<3) ) ;
+}
+
+frm15_0(id,reg) {
+       assert ( id_t1(id)==T_INT ) ;
+       emit1(0x16 /* + slave<<5 */ ) ;
+       emit1( id_g1(id) | (id_op(id)<<2) | ((reg&1)<<7 ) ) ;
+       emit1( (reg>>1) | (mode1.m_mode<<3) ) ;
+}
+
+frm15_1(id,i_type,s_type) {
+       emit1(0x16 /* + slave<<5 */ ) ;
+       emit1( i_type | (s_type<<2) | (id_op(id)<<3) | ((mode2.m_mode&03)<<6) ) ;
+       emit1( (mode2.m_mode>>2) | (mode1.m_mode<<3) ) ;
+}
+
+frm15_5(id) {
+       assert(id_t1(id)==T_SLAVE&& id_t2(id)==T_SLAVE&& id_g1(id)==id_g2(id) );
+       emit1(0x16 /* + slave<<5 */ ) ;
+       emit1( id_g1(id) | (id_op(id)<<2) | ((mode2.m_mode&3)<<6) ) ;
+       emit1( (mode2.m_mode>>2) | (mode1.m_mode<<3) ) ;
+}
+
+gen1(id) {
+       if ( (mode1.m_mode&0x1C)==0x1C ) {
+               emit1(mode1.m_index) ;
+       }
+       if ( mode1.m_mode==0x14 ) { /* Immediate */
+               RELOMOVE(relonami, mode1.m_rel1);
+               imm(id_g1(id),&mode1.m_expr1) ;
+       } else
+       if ( mode1.m_ndisp >0 ) {
+               RELOMOVE(relonami, mode1.m_rel1);
+               disp(&mode1.m_expr1, mode1.m_mode == 0x1B ? RELPC : 0) ;
+               if ( mode1.m_ndisp >1 ) {
+                       RELOMOVE(relonami, mode1.m_rel2);
+                       disp(&mode1.m_expr2, 0) ;
+               }
+       }
+}
+
+gengen(id) {
+       if ( (mode1.m_mode&0x1C)==0x1C ) {
+               emit1(mode1.m_index) ;
+       }
+       if ( (mode2.m_mode&0x1C)==0x1C ) {
+               emit1(mode2.m_index) ;
+       }
+       if ( mode1.m_mode==0x14 ) { /* Immediate */
+               RELOMOVE(relonami, mode1.m_rel1);
+               imm(id_g1(id),&mode1.m_expr1) ;
+       } else
+       if ( mode1.m_ndisp >0 ) {
+               RELOMOVE(relonami, mode1.m_rel1);
+               disp(&mode1.m_expr1, mode1.m_mode == 0x1B ? RELPC : 0) ;
+               if ( mode1.m_ndisp >1 ) {
+                       RELOMOVE(relonami, mode1.m_rel2);
+                       disp(&mode1.m_expr2, 0) ;
+               }
+       }
+       if ( mode2.m_mode==0x14 ) { /* Immediate */
+               RELOMOVE(relonami, mode2.m_rel1);
+               imm(id_g2(id),&mode2.m_expr1) ;
+       } else
+       if ( mode2.m_ndisp >0 ) {
+               RELOMOVE(relonami, mode2.m_rel1);
+               disp(&mode2.m_expr1, mode2.m_mode == 0x1B ? RELPC : 0) ;
+               if ( mode2.m_ndisp >1 ) {
+                       RELOMOVE(relonami, mode2.m_rel2);
+                       disp(&mode2.m_expr2, 0) ;
+               }
+       }
+}
+
+disp(expr, relpc) register expr_t *expr ; {
+       register sm1, sm2 ;
+
+       sm1=0 ; sm2=0 ;
+       if (DOTTYP >= 0x2 && DOTTYP<=0x7F &&
+#ifdef ASLD
+           (pass==PASS_1 ? expr->typ==S_ABS : expr->typ!=S_VAR ) ) {
+#else
+          expr->typ == S_ABS) {
+#endif
+               /* All non-text displacements are quad-sized.
+                  The algorithm currently used for minimizing the size
+                  (See CACM article) might generate assertion failures if
+                  any displacement it is trying to minimize increases during
+                  the assembly process. The only way to avoid increases
+                  like that is to fix the sizes of all displacements in
+                  non-text segments.
+                  If the framework included enough information one
+                  might detect in the first pass (0) whether the value
+                  of the expression depends on any symbols whose value
+                  might alter later on in the assembly process. In that case
+                  one could determine the right size in the first pass in
+                  most cases.
+               */
+               if ( fitd_b(expr->val) ) {
+                       sm1=1 ; sm2= 1 ;
+               } else {
+                       if ( fitd_w(expr->val) ) sm2=1 ;
+               }
+       }
+       sm1=small(sm1,1) ; sm2=small(sm2,2) ;
+#ifdef RELOCATION
+       newrelo(expr->typ, RELO4|RELBR|RELWR|relpc);
+#endif
+       if ( sm1 )      putdisp(expr->val,1) ;
+       else if ( sm2 ) putdisp(expr->val,2) ;
+       else            putdisp(expr->val,4) ;
+}
+
+putdisp(val,size) valu_t val ; {
+       switch ( size ) {
+       case 1 :
+               emit1( ((int)val)&0x7F ) ;
+               break ;
+       case 2 :
+               emit1( ( (((int)val)>>8)&0x3F ) | 0x80 ) ;
+               emit1( ((int)val)&0xFF ) ;
+               break ;
+       case 4 :
+               emit1( (((int)(val>>24)) | 0xC0) & 0xFF ) ;
+               emit1( ((int)(val>>16)) & 0xFF ) ;
+               emit1( (((int)val)>>8) & 0xFF ) ;
+               emit1( ((int)val)&0xFF ) ;
+               break ;
+       }
+}
+
+dot_adjust(expr) register expr_t *expr ; {
+       expr->val -= DOTVAL ;
+       if ( pass==PASS_2 ) {
+               if ( (expr->typ&S_DOT) == 0 && expr->val>0 ) {
+                       expr->val -= DOTGAIN;
+               }
+       }
+       if ( (expr->typ & ~S_DOT) == DOTTYP ) {
+               expr->typ=S_ABS ;
+       } else {
+               expr->typ=S_VAR ;
+       }
+}
+
+/* The idea of the following is:
+ * Give the assembler programmer a warning if he tries to store
+ * an immediate value in a field which is too small to fit in.
+ */
+
+testsize(type,val) {
+/* check if value fits in type */
+       switch( type ) {
+       case I_DOUBLE : return fit32(val);
+       case I_WORD   : return fit16(val);
+       case I_BYTE   : return fit8(val);
+       }
+}
+
+imm(i_type,expr) register expr_t *expr ; {
+/* emit value of immediate expression , after check on FIT */
+       if (!testsize(i_type,(int)expr->val))
+               warning("immediate operand too large");
+       switch( i_type ) {
+       case I_DOUBLE : 
+#ifdef RELOCATION
+                       newrelo(expr->typ, RELO4|RELBR|RELWR);
+#endif
+                       emit1( ((int)(expr->val>>24)) & 0xFF ) ;
+                       emit1( ((int)(expr->val>>16)) & 0xFF ) ;
+                       emit1( (((int)expr->val)>>8)  & 0xFF ) ;
+                       emit1(  ((int)expr->val)      & 0xFF ) ;
+                       break;
+       case I_WORD:
+#ifdef RELOCATION
+                       newrelo(expr->typ, RELO2|RELBR);
+#endif
+                       emit1( (((int)expr->val)>>8)  & 0xFF ) ;
+                       emit1(  ((int)expr->val)      & 0xFF ) ;
+                       break;
+       case I_BYTE:    
+#ifdef RELOCATION
+                       newrelo(expr->typ, RELO1);
+#endif
+                       emit1(  ((int)expr->val)      & 0xFF ) ;
+       }
+}
+
+
+reg_list(list,reverse) {
+       register rev_list, i ;
+       if ( !reverse ) {
+               return list ;
+       }
+       rev_list= 0 ;
+       for ( i=0 ; i<8 ; i++ ) {
+               if ( list & (1<<i) ) {
+                       rev_list |= 1<<(7-i) ;
+               }
+       }
+       return rev_list ;
+}
+cpu_opt(indic) {
+       switch( indic ) {
+       case 'i' : return 1 ;
+       case 'f' : return 2 ;
+       case 'm' : return 4 ;
+       case 'c' : return 8 ;
+       default :
+               serror("illegal cpu option %c",indic) ;
+               return 0 ;
+       }
+}
+
+string_opt(indic) {
+       switch( indic ) {
+       case 'b' : return SO_BACKW ;
+       case 'u' : return SO_UNTIL ;
+       case 'w' : return SO_WHILE ;
+       default :
+               serror("illegal string option %c",indic) ;
+               return 0 ;
+       }
+}