Initial revision
authorceriel <none@none>
Thu, 19 Jan 1989 16:20:46 +0000 (16:20 +0000)
committerceriel <none@none>
Thu, 19 Jan 1989 16:20:46 +0000 (16:20 +0000)
mach/i386/as/mach0.c [new file with mode: 0644]
mach/i386/as/mach1.c [new file with mode: 0644]
mach/i386/as/mach2.c [new file with mode: 0644]
mach/i386/as/mach3.c [new file with mode: 0644]
mach/i386/as/mach4.c [new file with mode: 0644]
mach/i386/as/mach5.c [new file with mode: 0644]

diff --git a/mach/i386/as/mach0.c b/mach/i386/as/mach0.c
new file mode 100644 (file)
index 0000000..6721a6f
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
+#define RCSID0 "$Header$"
+
+/*
+ * INTEL 80386 options
+ */
+#define        THREE_PASS      /* branch and offset optimization */
+#define        LISTING         /* enable listing facilities */
+#define RELOCATION     /* generate relocation info */
+#define DEBUG 2
+
+#undef valu_t
+#define valu_t long
diff --git a/mach/i386/as/mach1.c b/mach/i386/as/mach1.c
new file mode 100644 (file)
index 0000000..981d7bd
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
+#define RCSID1 "$Header$"
+
+/*
+ * INTEL 80386 C declarations
+ */
+
+#define        low6(z)         (z & 077)
+#define        fit6(z)         (low6(z) == z)
+
+#define ufitb(z)       ((unsigned)(z) <= 255)
+
+#define        IS_R8           0x100
+#define IS_R32         0x200
+#define IS_EXPR                0x400
+#define IS_RSEG                0x800
+
+#define is_expr(reg)   ((reg)&IS_EXPR)
+#define is_segreg(reg) ((reg)&IS_RSEG)
+#define is_reg(reg)    (((reg)&(IS_R8|IS_R32)) != 0)
+#define is_acc(reg)    (((reg)&(IS_R8|IS_R32)) == (reg))
+
+struct operand {
+       int     mod;
+       int     rm;
+       int     reg;
+       int     sib;            /* scale-index-base */
+       expr_t  exp;
+};
+
+extern struct operand  op_1, op_2;
+
+#define        mod_1   op_1.mod
+#define        mod_2   op_2.mod
+#define        rm_1    op_1.rm
+#define        rm_2    op_2.rm
+#define        reg_1   op_1.reg
+#define        reg_2   op_2.reg
+#define        sib_1   op_1.sib
+#define        sib_2   op_2.sib
+#define        exp_1   op_1.exp
+#define exp_2  op_2.exp
+
+#ifdef RELOCATION
+extern int     rel_1, rel_2;
+#endif
+
+#ifndef extern
+extern char    regindex_ind[8][8];
+#else
+/*     First index is base register; second index is index register;
+       sp cannot be an index register.
+       For base and index register indirect mode, bp cannot be the
+       base register, but this info is not included in this array.
+       This can always be handled by using the base and index register with
+       displacement mode.
+*/
+char   regindex_ind[8][8] = {
+       000,    010,    020,    030,    -1,     050,    060,    070,
+       001,    011,    021,    031,    -1,     051,    061,    071,
+       002,    012,    022,    032,    -1,     052,    062,    072,
+       003,    013,    023,    033,    -1,     053,    063,    073,
+       004,    014,    024,    034,    -1,     054,    064,    074,
+       005,    015,    025,    035,    -1,     055,    065,    075,
+       006,    016,    026,    036,    -1,     056,    066,    076,
+       007,    017,    027,    037,    -1,     057,    067,    077,
+};
+#endif
+
+extern int     address_long INIT(1), operand_long INIT(1);
diff --git a/mach/i386/as/mach2.c b/mach/i386/as/mach2.c
new file mode 100644 (file)
index 0000000..303e648
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
+#define RCSID2 "$Header$"
+
+/*
+ * INTEL 80386 tokens
+ */
+
+%token <y_word> R32
+%token <y_word> R16
+%token <y_word> R8
+%token <y_word> RSEG
+%token <y_word> RSYSCR
+%token <y_word> RSYSDR
+%token <y_word> RSYSTR
+%token <y_word> PREFIX
+%token <y_word> ADDOP
+%token <y_word>        BITTEST
+%token <y_word>        BOUND
+%token <y_word> CALFOP
+%token <y_word> CALLOP
+%token <y_word> ENTER
+%token <y_word> EXTEND
+%token <y_word> EXTOP
+%token <y_word> EXTOP1
+%token <y_word> IMUL
+%token <y_word> IMULB
+%token <y_word> INCOP
+%token <y_word> INT
+%token <y_word> IOOP
+%token <y_word> JOP
+%token <y_word> JOP2
+%token <y_word> LEAOP
+%token <y_word> LEAOP2
+%token <y_word> LSHFT
+%token <y_word> MOV
+%token <y_word> NOOP_1
+%token <y_word> NOOP_2
+%token <y_word> NOTOP
+%token <y_word> PUSHOP
+%token <y_word> RET
+%token <y_word> ROLOP
+%token <y_word> SETCC
+%token <y_word> TEST
+%token <y_word> XCHG
diff --git a/mach/i386/as/mach3.c b/mach/i386/as/mach3.c
new file mode 100644 (file)
index 0000000..c2be16b
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
+#define RCSID3 "$Header$"
+
+/*
+ * INTEL 80386 keywords
+ *
+ * No system registers for now ...
+ */
+
+0,     R32,            0,              "ax",
+0,     R32,            1,              "cx",
+0,     R32,            2,              "dx",
+0,     R32,            3,              "bx",
+0,     R32,            4,              "sp",
+0,     R32,            5,              "bp",
+0,     R32,            6,              "si",
+0,     R32,            7,              "di",
+0,     R32,            0,              "eax",
+0,     R32,            1,              "ecx",
+0,     R32,            2,              "edx",
+0,     R32,            3,              "ebx",
+0,     R32,            4,              "esp",
+0,     R32,            5,              "ebp",
+0,     R32,            6,              "esi",
+0,     R32,            7,              "edi",
+0,     R8,             0,              "al",
+0,     R8,             1,              "cl",
+0,     R8,             2,              "dl",
+0,     R8,             3,              "bl",
+0,     R8,             4,              "ah",
+0,     R8,             5,              "ch",
+0,     R8,             6,              "dh",
+0,     R8,             7,              "bh",
+0,     RSEG,           0,              "es",
+0,     RSEG,           1,              "cs",
+0,     RSEG,           2,              "ss",
+0,     RSEG,           3,              "ds",
+0,     RSEG,           4,              "fs",
+0,     RSEG,           5,              "gs",
+0,     RSYSCR,         0,              "cr0",
+0,     RSYSCR,         2,              "cr2",
+0,     RSYSCR,         3,              "cr3",
+0,     RSYSDR,         0,              "dr0",
+0,     RSYSDR,         1,              "dr1",
+0,     RSYSDR,         2,              "dr2",
+0,     RSYSDR,         3,              "dr3",
+0,     RSYSDR,         6,              "dr6",
+0,     RSYSDR,         7,              "dr7",
+0,     RSYSTR,         6,              "tr6",
+0,     RSYSTR,         7,              "tr7",
+0,     ADDOP,          000,            "addb",
+0,     ADDOP,          001,            "add",
+0,     ADDOP,          010,            "orb",
+0,     ADDOP,          011,            "or",
+0,     ADDOP,          020,            "adcb",
+0,     ADDOP,          021,            "adc",
+0,     ADDOP,          030,            "sbbb",
+0,     ADDOP,          031,            "sbb",
+0,     ADDOP,          040,            "andb",
+0,     ADDOP,          041,            "and",
+0,     ADDOP,          050,            "subb",
+0,     ADDOP,          051,            "sub",
+0,     ADDOP,          060,            "xorb",
+0,     ADDOP,          061,            "xor",
+0,     ADDOP,          070,            "cmpb",
+0,     ADDOP,          071,            "cmp",
+0,     BITTEST,        04,             "bt",
+0,     BITTEST,        05,             "bts",
+0,     BITTEST,        06,             "btr",
+0,     BITTEST,        07,             "btc",
+0,     CALFOP,         030+(0232<<8),  "callf",
+0,     CALFOP,         050+(0352<<8),  "jmpf",
+0,     CALLOP,         020+(0350<<8),  "call",
+0,     CALLOP,         040+(0351<<8),  "jmp",
+0,     ENTER,          0310,           "enter",
+0,     EXTEND,         0266,           "movzx",
+0,     EXTEND,         0276,           "movsx",
+0,     EXTOP,          0002,           "lar",
+0,     EXTOP,          0003,           "lsl",
+0,     EXTOP,          0274,           "bsf",
+0,     EXTOP,          0275,           "bsr",
+0,     EXTOP1,         0000,           "sldt",
+0,     EXTOP1,         0001,           "sgdt",
+0,     EXTOP1,         0010,           "str",
+0,     EXTOP1,         0011,           "sidt",
+0,     EXTOP1,         0020,           "lldt",
+0,     EXTOP1,         0021,           "lgdt",
+0,     EXTOP1,         0030,           "ltr",
+0,     EXTOP1,         0031,           "lidt",
+0,     EXTOP1,         0040,           "verr",
+0,     EXTOP1,         0041,           "smsw",
+0,     EXTOP1,         0050,           "verw",
+0,     EXTOP1,         0061,           "lmsw",
+0,     IMUL,           0,              "imul",
+0,     IMULB,          0,              "imulb",
+0,     INCOP,          000,            "incb",
+0,     INCOP,          001,            "inc",
+0,     INCOP,          010,            "decb",
+0,     INCOP,          011,            "dec",
+0,     INT,            0,              "int",
+0,     IOOP,           0344,           "inb",
+0,     IOOP,           0345,           "in",
+0,     IOOP,           0346,           "outb",
+0,     IOOP,           0347,           "out",
+0,     JOP,            0340,           "loopne",
+0,     JOP,            0340,           "loopnz",
+0,     JOP,            0341,           "loope",
+0,     JOP,            0341,           "loopz",
+0,     JOP,            0342,           "loop",
+0,     JOP,            0343,           "jcxz",
+0,     JOP,            0343,           "jecxz",
+0,     JOP2,           0000,           "jo",
+0,     JOP2,           0001,           "jno",
+0,     JOP2,           0002,           "jb",
+0,     JOP2,           0002,           "jnae",
+0,     JOP2,           0003,           "jae",
+0,     JOP2,           0003,           "jnb",
+0,     JOP2,           0004,           "je",
+0,     JOP2,           0004,           "jz",
+0,     JOP2,           0005,           "jne",
+0,     JOP2,           0005,           "jnz",
+0,     JOP2,           0006,           "jbe",
+0,     JOP2,           0006,           "jna",
+0,     JOP2,           0007,           "ja",
+0,     JOP2,           0007,           "jnbe",
+0,     JOP2,           0010,           "js",
+0,     JOP2,           0011,           "jns",
+0,     JOP2,           0012,           "jp",
+0,     JOP2,           0012,           "jpe",
+0,     JOP2,           0013,           "jnp",
+0,     JOP2,           0013,           "jpo",
+0,     JOP2,           0014,           "jl",
+0,     JOP2,           0014,           "jnge",
+0,     JOP2,           0015,           "jge",
+0,     JOP2,           0015,           "jnl",
+0,     JOP2,           0016,           "jle",
+0,     JOP2,           0016,           "jng",
+0,     JOP2,           0017,           "jg",
+0,     JOP2,           0017,           "jnle",
+0,     LEAOP,          0142,           "bound",
+0,     LEAOP,          0215,           "lea",
+0,     LEAOP,          0304,           "les",
+0,     LEAOP,          0305,           "lds",
+0,     LEAOP2,         0262,           "lss",
+0,     LEAOP2,         0264,           "lfs",
+0,     LEAOP2,         0265,           "lgs",
+0,     LSHFT,          0244,           "shld",
+0,     LSHFT,          0254,           "shrd",
+0,     MOV,            0,              "movb",
+0,     MOV,            1,              "mov",
+0,     NOOP_1,         0140,           "pusha",
+0,     NOOP_1,         0140,           "pushad",
+0,     NOOP_1,         0141,           "popa",
+0,     NOOP_1,         0141,           "popad",
+0,     NOOP_1,         0156,           "outsb",
+0,     NOOP_1,         0157,           "outs",
+0,     NOOP_1,         0220,           "nop",
+0,     NOOP_1,         0230,           "cbw",
+0,     NOOP_1,         0230,           "cwde", /* same opcode as cbw! */
+0,     NOOP_1,         0231,           "cdq",  /* same opcode as cwd! */
+0,     NOOP_1,         0231,           "cwd",
+0,     NOOP_1,         0233,           "wait",
+0,     NOOP_1,         0234,           "pushf",
+0,     NOOP_1,         0235,           "popf",
+0,     NOOP_1,         0236,           "sahf",
+0,     NOOP_1,         0237,           "lahf",
+0,     NOOP_1,         0244,           "movsb",
+0,     NOOP_1,         0245,           "movs",
+0,     NOOP_1,         0246,           "cmpsb",
+0,     NOOP_1,         0246,           "insb",
+0,     NOOP_1,         0247,           "cmps",
+0,     NOOP_1,         0247,           "ins",
+0,     NOOP_1,         0252,           "stosb",
+0,     NOOP_1,         0253,           "stos",
+0,     NOOP_1,         0254,           "lodsb",
+0,     NOOP_1,         0255,           "lods",
+0,     NOOP_1,         0256,           "scasb",
+0,     NOOP_1,         0257,           "scas",
+0,     NOOP_1,         0311,           "leave",
+0,     NOOP_1,         0316,           "into",
+0,     NOOP_1,         0317,           "iret",
+0,     NOOP_1,         0317,           "iretd",
+0,     NOOP_1,         0327,           "xlat",
+0,     NOOP_1,         0364,           "hlt",
+0,     NOOP_1,         0365,           "cmc",
+0,     NOOP_1,         0370,           "clc",
+0,     NOOP_1,         0371,           "stc",
+0,     NOOP_1,         0372,           "cli",
+0,     NOOP_1,         0373,           "sti",
+0,     NOOP_1,         0374,           "cld",
+0,     NOOP_1,         0375,           "std",
+0,     NOOP_1,         047,            "daa",
+0,     NOOP_1,         057,            "das",
+0,     NOOP_1,         067,            "aaa",
+0,     NOOP_1,         077,            "aas",
+0,     NOOP_2,         017+06<<8,      "clts",
+0,     NOOP_2,         0324+012<<8,    "aam",
+0,     NOOP_2,         0325+012<<8,    "aad",
+0,     NOTOP,          020,            "notb",
+0,     NOTOP,          021,            "not",
+0,     NOTOP,          030,            "negb",
+0,     NOTOP,          031,            "neg",
+0,     NOTOP,          040,            "mulb",
+0,     NOTOP,          041,            "mul",
+0,     NOTOP,          060,            "divb",
+0,     NOTOP,          061,            "div",
+0,     NOTOP,          070,            "idivb",
+0,     NOTOP,          071,            "idiv",
+0,     PREFIX,         0144,           "fseg",
+0,     PREFIX,         0145,           "gseg",
+0,     PREFIX,         0146,           "o16",  /* operand size toggle */
+0,     PREFIX,         0146,           "o32",  /* operand size toggle */
+0,     PREFIX,         0147,           "a16",  /* address size toggle */
+0,     PREFIX,         0147,           "a32",  /* address size toggle */
+0,     PREFIX,         0360,           "lock",
+0,     PREFIX,         0362,           "rep",
+0,     PREFIX,         0362,           "repne",
+0,     PREFIX,         0362,           "repnz",
+0,     PREFIX,         0363,           "repe",
+0,     PREFIX,         0363,           "repz",
+0,     PREFIX,         046,            "eseg",
+0,     PREFIX,         056,            "cseg",
+0,     PREFIX,         066,            "sseg",
+0,     PREFIX,         076,            "dseg",
+0,     PUSHOP,         0,              "push",
+0,     PUSHOP,         1,              "pop",
+0,     RET,            0303,           "ret",
+0,     RET,            0313,           "retf",
+0,     ROLOP,          000,            "rolb",
+0,     ROLOP,          001,            "rol",
+0,     ROLOP,          010,            "rorb",
+0,     ROLOP,          011,            "ror",
+0,     ROLOP,          020,            "rclb",
+0,     ROLOP,          021,            "rcl",
+0,     ROLOP,          030,            "rcrb",
+0,     ROLOP,          031,            "rcr",
+0,     ROLOP,          040,            "salb",
+0,     ROLOP,          040,            "shlb",
+0,     ROLOP,          041,            "sal",
+0,     ROLOP,          041,            "shl",
+0,     ROLOP,          050,            "shrb",
+0,     ROLOP,          051,            "shr",
+0,     ROLOP,          070,            "sarb",
+0,     ROLOP,          071,            "sar",
+0,     SETCC,          0000,           "seto",
+0,     SETCC,          0001,           "setno",
+0,     SETCC,          0002,           "setb",
+0,     SETCC,          0002,           "setnae",
+0,     SETCC,          0003,           "setae",
+0,     SETCC,          0003,           "setnb",
+0,     SETCC,          0004,           "sete",
+0,     SETCC,          0004,           "setz",
+0,     SETCC,          0005,           "setne",
+0,     SETCC,          0005,           "setnz",
+0,     SETCC,          0006,           "setbe",
+0,     SETCC,          0006,           "setna",
+0,     SETCC,          0007,           "seta",
+0,     SETCC,          0007,           "setnbe",
+0,     SETCC,          0010,           "sets",
+0,     SETCC,          0011,           "setns",
+0,     SETCC,          0012,           "setp",
+0,     SETCC,          0012,           "setpe",
+0,     SETCC,          0013,           "setnp",
+0,     SETCC,          0013,           "setpo",
+0,     SETCC,          0014,           "setl",
+0,     SETCC,          0014,           "setnge",
+0,     SETCC,          0015,           "setge",
+0,     SETCC,          0015,           "setnl",
+0,     SETCC,          0016,           "setle",
+0,     SETCC,          0016,           "setng",
+0,     SETCC,          0017,           "setg",
+0,     SETCC,          0017,           "setnle",
+0,     TEST,           0,              "testb",
+0,     TEST,           1,              "test",
+0,     XCHG,           0,              "xchgb",
+0,     XCHG,           1,              "xchg",
diff --git a/mach/i386/as/mach4.c b/mach/i386/as/mach4.c
new file mode 100644 (file)
index 0000000..b8da727
--- /dev/null
@@ -0,0 +1,198 @@
+#define RCSID4 "$Header$"
+
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ *
+ */
+
+operation
+       :               {       address_long = 1; operand_long = 1; }
+               prefix oper
+       ;
+prefix :       /* empty */
+       |       prefix PREFIX
+                       {       if ($2 == 0146) operand_long = ! operand_long;
+                               if ($2 == 0147) address_long = ! address_long;
+                               emit1($2);
+                       }
+       ;
+oper   :       NOOP_1
+                       {       emit1($1);}
+       |       NOOP_2
+                       {       emit2($1);}
+       |       JOP expr
+                       {       branch($1,$2);}
+       |       JOP2 expr
+                       {       ebranch($1,$2);}
+       |       PUSHOP ea_1
+                       {       pushop($1);}
+       |       IOOP absexp
+                       {       emit1($1);
+                               fit(ufitb($2));
+                               emit1((int)$2);
+                       }
+       |       IOOP R32
+                       {       if ($2!=2) serror("register error");
+                               emit1($1+010);
+                       }
+       |       BITTEST ea_ea
+                       {       bittestop($1);}
+       |       BOUND R32 ',' mem
+                       {       emit1($1); ea_2($2<<3); }
+       |       ADDOP ea_ea
+                       {       addop($1);}
+       |       ROLOP ea_ea
+                       {       rolop($1);}
+       |       INCOP ea_1
+                       {       incop($1);}
+       |       NOTOP ea_1
+                       {       regsize($1); emit1(0366|($1&1)); ea_1($1&070);}
+       |       CALLOP ea_1
+                       {       callop($1&0xFFFF);}
+       |       CALFOP expr ':' expr
+                       {       emit1($1>>8);
+#ifdef RELOCATION
+                               newrelo($4.typ, RELO4);
+#endif
+                               emit4((long)($4.val));
+#ifdef RELOCATION
+                               newrelo($2.typ, RELO2);
+#endif
+                               emit2((int)($2.val));
+                       }
+       |       CALFOP mem
+                       {       emit1(0377); ea_2($1&0xFF);}
+       |       ENTER absexp ',' absexp
+                       {       fit(fitw($2)); fit(fitb($4));
+                               emit1($1); emit2((int)$2); emit1((int)$4);
+                       }
+       |       LEAOP R32 ',' mem
+                       {       emit1($1); ea_2($2<<3);}
+       |       LEAOP2 R32 ',' mem
+                       {       emit1(0xF); emit1($1); ea_2($2<<3);}
+       |       LSHFT   ea_1 ',' R32 ',' ea_2
+                       {       extshft($1, $4);}
+       |       EXTEND R32 ',' ea_2
+                       {       emit1(0xF); emit1($1|1); ea_2($2<<3);}
+       |       EXTOP R32 ',' ea_2
+                       {       emit1(0xF); emit1($1); ea_2($2<<3);}
+       |       EXTOP1 ea_1
+                       {       emit1(0xF); emit1($1&07); ea_1($1&070);}
+       |       IMULB   ea_1
+                       {       regsize(0); emit1(0366); ea_1($1&070);}
+       |       IMUL    ea_2
+                       {       reg_1 = IS_R32; imul(0); }
+       |       IMUL    R32 ',' ea_2
+                       {       reg_1 = $2 | IS_R32; imul($2); }
+       |       IMUL    R32 ',' ea_ea
+                       {       imul($2);}
+       |       INT absexp
+                       {       if ($2==3)
+                                       emit1(0314);
+                               else {
+                                       fit(ufitb($2));
+                                       emit1(0315); emit1((int)$2);
+                               }
+                       }
+       |       RET
+                       {       emit1($1);}
+       |       RET expr
+                       {       emit1($1-1);
+#ifdef RELOCATION
+                               newrelo($2.typ, RELO2);
+#endif
+                               emit2((int)($2.val));
+                       }
+       |       SETCC ea_2
+                       {       emit1(0xF); emit1($1); ea_2(0);}
+       |       XCHG ea_ea
+                       {       xchg($1);}
+       |       TEST ea_ea
+                       {       test($1);}
+       |       MOV ea_ea
+                       {       mov($1);}
+       |       /*      What is really needed is just
+                       MOV R32 ',' RSYSCR
+                       but this gives a bad yacc conflict
+               */
+               MOV ea_1 ',' RSYSCR
+                       {       
+                               if ($1 != 1 || !(reg_1 & IS_R32))
+                                       serror("syntax error");
+                               emit1(0xF); emit1(042); emit1(0200|($4<<3)|(reg_1&07));}
+       |       MOV ea_1 ',' RSYSDR
+                       {       
+                               if ($1 != 1 || !(reg_1 & IS_R32))
+                                       serror("syntax error");
+                               emit1(0xF); emit1(043); emit1(0200|($4<<3)|(reg_1&07));}
+       |       MOV ea_1 ',' RSYSTR
+                       {       
+                               if ($1 != 1 || !(reg_1 & IS_R32))
+                                       serror("syntax error");
+                               emit1(0xF); emit1(046); emit1(0200|($4<<3)|(reg_1&07));}
+       |       MOV RSYSCR ',' R32
+                       {       
+                               if ($1 != 1) serror("syntax error");
+                               emit1(0xF); emit1(040); emit1(0200|($4<<3)|$2);}
+       |       MOV RSYSDR ',' R32
+                       {       
+                               if ($1 != 1) serror("syntax error");
+                               emit1(0xF); emit1(041); emit1(0200|($4<<3)|$2);}
+       |       MOV RSYSTR ',' R32
+                       {       
+                               if ($1 != 1) serror("syntax error");
+                               emit1(0xF); emit1(044); emit1(0200|($4<<3)|$2);}
+       ;
+mem    :       '(' expr ')'
+                       {       rm_2 = 05; exp_2 = $2; reg_2 = 05; mod_2 = 0;
+                               RELOMOVE(rel_2, relonami);
+                       }
+       |       bases
+                       {       exp_2.val = 0; exp_2.typ = S_ABS; indexed();}
+       |       expr bases
+                       {       exp_2 = $1; indexed();
+                               RELOMOVE(rel_2, relonami);
+                       }
+       ;
+bases  :       '(' R32 ')'
+                       {       reg_2 = $2; sib_2 = 0; rm_2 = 0;}
+       |       '(' R32 ')' '(' R32 scale ')'
+                       {       rm_2 = 04; sib_2 |= regindex_ind[$2][$5];
+                               reg_2 = $2;
+                       }
+       |       '(' R32 '*' absexp ')'
+                       {       if ($4 == 1) {
+                                       reg_2 = $2; sib_2 = 0; rm_2 = 0;
+                               }
+                               else {
+                                       rm_2 = 04;
+                                       sib_2 = checkscale($4) | regindex_ind[05][$2];
+                                       reg_2 = 015;
+                               }
+                       }
+       ;
+scale  :       /* empty */
+                       {       sib_2 = 0;}
+       |       '*' absexp
+                       {       sib_2 = checkscale($2);}
+       ;
+ea_2   :       mem
+       |       R8
+                       {       reg_2 = $1 | IS_R8; rm_2 = 0;}
+       |       R32
+                       {       reg_2 = $1 | IS_R32; rm_2 = 0;}
+       |       RSEG
+                       {       reg_2 = $1 | IS_RSEG; rm_2 = 0;}
+       |       expr
+                       {       reg_2 = IS_EXPR; exp_2 = $1; rm_2 = 0;
+                               RELOMOVE(rel_2, relonami);
+                       }
+       ;
+ea_1   :       ea_2
+                       {       op_1 = op_2;
+                               RELOMOVE(rel_1, rel_2);
+                       }
+       ;
+ea_ea  :       ea_1 ',' ea_2
+       ;
diff --git a/mach/i386/as/mach5.c b/mach/i386/as/mach5.c
new file mode 100644 (file)
index 0000000..1bc9eb9
--- /dev/null
@@ -0,0 +1,533 @@
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
+#define RCSID5 "$Header$"
+
+/*
+ * INTEL 80386 special routines
+ */
+
+ea_1(param) {
+       if (is_expr(reg_1)) {
+               serror("bad operand");
+               return;
+       }
+       if (is_reg(reg_1)) {
+               switch(reg_1&07) {
+               case 4:
+                       emit1(0300 | param | 04);
+                       emit1(0300 | 0100);
+               default:
+                       emit1(0300 | param | (reg_1&07));
+               }
+               return;
+       }
+       if (rm_1 == 04) {
+               /* sib field use here */
+               emit1(mod_1 << 6 | param | 04);
+               emit1(sib_1 | reg_1);
+               if ((mod_1 == 0 && reg_1 == 5) || mod_1 == 2) {
+#ifdef RELOCATION
+                       RELOMOVE(relonami, rel_1);
+                       newrelo(exp_1.typ, RELO4);
+#endif
+                       emit4((long)(exp_1.val));
+               }
+               else if (mod_1 == 1) emit1((int)(exp_1.val));
+               return;
+       }
+       emit1(mod_1<<6 | param | (reg_1&07));
+       if ((mod_1 == 0 && reg_1 == 5) || mod_1 == 2) {
+#ifdef RELOCATION
+               RELOMOVE(relonami, rel_1);
+               newrelo(exp_1.typ, RELO4);
+#endif
+               emit4((long)(exp_1.val));
+       }
+       else if (mod_1 == 1) {
+               emit1((int)(exp_1.val));
+       }
+}
+
+ea_2(param) {
+
+       op_1 = op_2;
+       RELOMOVE(rel_1, rel_2);
+       ea_1(param);
+}
+
+int
+checkscale(val)
+       valu_t val;
+{
+       int v = val;
+
+       if (v != val) v = 0;
+       switch(v) {
+       case 1:
+               return 0;
+       case 2:
+               return 1 << 6;
+       case 4:
+               return 2 << 6;
+       case 8:
+               return 3 << 6;
+       default:
+               serror("bad scale");
+               return 0;
+       }
+       /*NOTREACHED*/
+}
+
+reverse() {
+       struct operand op;
+#ifdef RELOCATION
+       int r = rel_1;
+
+       rel_1 = rel_2; rel_2 = r;
+#endif
+       op = op_1; op_1 = op_2; op_2 = op;
+}
+
+badsyntax() {
+
+       serror("bad operands");
+}
+
+regsize(sz)
+       int sz;
+{
+       register int bit;
+
+       bit = (sz&1) ? 0 : IS_R8;
+       if ((is_reg(reg_1) && (reg_1 & IS_R8) != bit) ||
+           (is_reg(reg_2) && (reg_2 & IS_R8) != bit)) 
+               serror("register error");
+}
+
+indexed() {
+       mod_2 = 0;
+       if (sib_2 == -1)
+               serror("register error");
+       if (rm_2 == 0 && reg_2 == 4) {
+               /* base register sp, no index register; use
+                  indexed mode without index register
+               */
+               rm_2 = 04;
+               sib_2 = 044;
+       }
+       if (reg_2 == 015) {
+               reg_2 = 05;
+               return;
+       }
+       if (exp_2.typ != S_ABS || fitb(exp_2.val) == 0)
+               mod_2 = 02;
+       else if (exp_2.val != 0 || reg_2 == 5)
+               mod_2 = 01;
+}
+
+ebranch(opc,exp)
+       register int opc;
+       expr_t exp;
+{
+       /*      Conditional branching; Full displacements are available
+               on the 80386, so the welknown trick with the reverse branch
+               over a jump is not needed here.
+               The only complication here is with the address size, which
+               can be set with a prefix. In this case, the user gets what
+               he asked for.
+       */
+       register int sm;
+       register long dist;
+       int saving = address_long ? 4 : 2;
+
+       dist = exp.val - (DOTVAL + 2);
+       if (pass == PASS_2 && dist > 0 && !(exp.typ & S_DOT))
+               dist -= DOTGAIN;
+       sm = dist > 0 ? fitb(dist-saving) : fitb(dist);
+       if ((exp.typ & ~S_DOT) != DOTTYP)
+               sm = 0;
+       if ((sm = small(sm,saving)) == 0) {
+               emit1(0xF);
+               emit1(opc | 0x80);
+               dist -= 2;
+               exp.val = dist;
+               adsize_exp(exp);
+       }
+       else {
+               emit1(opc | 0x70);
+               emit1((int)dist);
+       }
+}
+
+branch(opc,exp)
+       register int opc;
+       expr_t exp;
+{
+       /*      LOOP, JCXZ, etc. branch instructions.
+               Here, the offset just must fit in a byte.
+       */
+       register long dist;
+
+       dist = exp.val - (DOTVAL + 2);
+       if (pass == PASS_2 && dist > 0 && !(exp.typ & S_DOT))
+               dist -= DOTGAIN;
+       fit((exp.typ & ~S_DOT) == DOTTYP && fitb(dist));
+       emit1(opc);
+       emit1((int)dist);
+}
+
+pushop(opc)
+       register int opc;
+{
+
+       regsize(1);
+       if (is_segreg(reg_1)) {
+               /* segment register */
+               if ((reg_1 & 07) <= 3)
+                       emit1(6 | opc | (reg_1&7)<<3);
+               else {
+                       emit1(0xF);
+                       emit1(0200 | opc | ((reg_1&7)<<3));
+               }
+       } else if (is_reg(reg_1)) {
+               /* normal register */
+               emit1(0120 | opc<<3 | (reg_1&7));
+       } else if (opc == 0) {
+               if (is_expr(reg_1)) {
+                       if (exp_1.typ == S_ABS && fitb(exp_1.val)) {
+                               emit1(0152);
+                               emit1((int)(exp_1.val));
+                       }
+                       else {
+                               emit1(0150);
+                               RELOMOVE(relonami, rel_1);
+                               opsize_exp(exp_1, 1);
+                       }
+               }
+               else {
+                       emit1(0377); ea_1(6<<3);
+               }
+       } else {
+               emit1(0217); ea_1(0<<3);
+       }
+}
+
+opsize_exp(exp, nobyte)
+       expr_t exp;
+{
+       if (! nobyte) {
+#ifdef RELOCATION
+               newrelo(exp.typ, RELO1);
+#endif
+               emit1((int)(exp.val));
+       }
+       else if (operand_long) {
+#ifdef RELOCATION
+               newrelo(exp.typ, RELO4);
+#endif
+               emit4((long)(exp.val));
+       }
+       else {
+#ifdef RELOCATION
+               newrelo(exp.typ, RELO2);
+#endif
+               emit2((int)(exp.val));
+       }
+}
+
+adsize_exp(exp)
+       expr_t exp;
+{
+       if (address_long) {
+#ifdef RELOCATION
+               newrelo(exp.typ, RELO4 | RELPC);
+#endif
+               emit4((long)(exp.val));
+       }
+       else {
+               if (! fitw(exp.val)) {
+                       warning("offset does not fit in 2 bytes; remove prefix");
+               }
+#ifdef RELOCATION
+               newrelo(exp.typ, RELO2 | RELPC);
+#endif
+               emit2((int)(exp.val));
+       }
+}
+
+addop(opc) 
+       register int opc;
+{
+
+       regsize(opc);
+       if (is_reg(reg_2)) {
+               /*      Add register to register or memory */
+               emit1(opc); ea_1((reg_2&7)<<3);
+       } else if (is_acc(reg_1) && is_expr(reg_2)) {
+               /*      Add immediate to accumulator */
+               emit1(opc | 4);
+               RELOMOVE(relonami, rel_2);
+               opsize_exp(exp_2, (opc&1));
+       } else if (is_expr(reg_2)) {
+               /*      Add immediate to register or memory */
+               if ((opc&1) == 0) {
+                       emit1(0200);
+               } else if (exp_2.typ != S_ABS || fitb(exp_2.val) == 0) {
+                       emit1(0201);
+               } else {
+                       emit1(0203); opc &= ~1;
+               }
+               ea_1(opc & 070);
+               RELOMOVE(relonami, rel_2);
+               opsize_exp(exp_2, (opc&1));
+       } else if (is_reg(reg_1)) {
+               /*      Add register or memory to register */
+               emit1(opc | 2);
+               ea_2((reg_1&7)<<3);
+       } else
+               badsyntax();
+}
+
+rolop(opc)
+       register int opc;
+{
+       register int oreg;
+
+       oreg = reg_2;
+       reg_2 = reg_1;
+       regsize(opc);
+       if (oreg == (IS_R8 | 1)) {
+               /* cl register */
+               emit1(0322 | (opc&1)); ea_1(opc&070);
+       } else if (is_expr(oreg) && exp_2.typ == S_ABS && exp_2.val == 1) {
+               /* shift by 1 */
+               emit1(0320 | (opc&1)); ea_1(opc&070);
+       } else if (is_expr(oreg)) {
+               /* shift by byte count */
+               emit1(0300 | (opc & 1)); 
+               ea_1(opc & 070);
+#ifdef RELOCATION
+               RELOMOVE(relonami, rel_2);
+               newrelo(exp_2.typ, RELO1);
+#endif
+               emit1((int)(exp_2.val));
+       }
+       else
+               badsyntax();
+}
+
+incop(opc)
+       register int opc;
+{
+
+       regsize(opc);
+       if ((opc&1) && is_reg(reg_1)) {
+               /* word register */
+               emit1(0100 | (opc&010) | (reg_1&7));
+       } else {
+               emit1(0376 | (opc&1));
+               ea_1(opc & 010);
+       }
+}
+
+callop(opc) 
+       register int opc;
+{
+
+       regsize(1);
+       if (is_expr(reg_1)) {
+               if (opc == (040+(0351<<8))) {
+                       RELOMOVE(relonami, rel_1);
+                       ebranch(0353,exp_1);
+               } else {
+                       exp_1.val -= (DOTVAL+3);
+                       emit1(opc>>8);
+                       RELOMOVE(relonami, rel_1);
+                       adsize_exp(exp_1);
+               }
+       } else {
+               emit1(0377); ea_1(opc&070);
+       }
+}
+
+xchg(opc)
+       register int opc;
+{
+
+       regsize(opc);
+       if (! is_reg(reg_1) || is_acc(reg_2)) {
+               reverse();
+       }
+       if (opc == 1 && is_acc(reg_1) && is_reg(reg_2)) {
+               emit1(0220 | (reg_2&7));
+       } else if (is_reg(reg_1)) {
+               emit1(0206 | opc); ea_2((reg_1&7)<<3);
+       } else
+               badsyntax();
+}
+
+test(opc)
+       register int opc;
+{
+
+       regsize(opc);
+       if (is_reg(reg_2) || is_expr(reg_1))
+               reverse();
+       if (is_expr(reg_2)) {
+               if (is_acc(reg_1)) {
+                       emit1(0250 | opc);
+                       RELOMOVE(relonami, rel_2);
+                       opsize_exp(exp_2, (opc&1));
+               }
+               else {
+                       emit1(0366 | opc);
+                       ea_1(0<<3);
+                       RELOMOVE(relonami, rel_2);
+                       opsize_exp(exp_2, (opc&1));
+               }
+       } else if (is_reg(reg_1)) {
+               emit1(0204 | opc); ea_2((reg_1&7)<<3);
+       } else
+               badsyntax();
+}
+
+mov(opc)
+       register int opc;
+{
+
+       regsize(opc);
+       if (is_segreg(reg_1)) {
+               /* to segment register */
+               emit1(0216); ea_2((reg_1&3)<<3);
+       } else if (is_segreg(reg_2)) {
+               /* from segment register */
+               emit1(0214); ea_1((reg_2&3)<<3);
+       } else if (is_expr(reg_2)) {
+               /* from immediate */
+               if (is_reg(reg_1)) {
+                       /* to register */
+                       emit1(0260 | opc<<3 | (reg_1&7)); 
+               } else {
+                       /* to memory */
+                       emit1(0306 | opc); ea_1(0<<3); 
+               }
+               RELOMOVE(relonami, rel_2);
+               opsize_exp(exp_2, (opc&1));
+       } else if (rm_1 == 05 && is_acc(reg_2)) {
+               /* from accumulator to memory  (displacement) */
+               emit1(0242 | opc);
+               RELOMOVE(relonami, rel_1);
+               adsize_exp(exp_1);
+       } else if (rm_2 == 05 && is_acc(reg_1)) {
+               /* from memory (displacement) to accumulator */
+               emit1(0240 | opc);
+               RELOMOVE(relonami, rel_2);
+               adsize_exp(exp_2);
+       } else if (is_reg(reg_2)) {
+               /* from register to memory or register */
+               emit1(0210 | opc); ea_1((reg_2&7)<<3);
+       } else if (is_reg(reg_1)) {
+               /* from memory or register to register */
+               emit1(0212 | opc); ea_2((reg_1&7)<<3);
+       } else
+               badsyntax();
+}
+
+extshft(opc, reg)
+       int opc;
+{
+       int oreg2 = reg_2;
+
+       reg_2 = reg_1;
+       regsize(1);
+
+       emit1(0xF);
+       if (oreg2 == (IS_R8 | 1)) {
+               /* cl register */
+               emit1(opc|1);
+               ea_1(reg << 3);
+       }
+       else if (is_expr(oreg2)) {
+               emit1(opc);
+               ea_1(reg << 3);
+#ifdef RELOCATION
+               RELOMOVE(relonami, rel_2);
+               newrelo(exp_2.typ, RELO1);
+#endif
+               emit1((int)(exp_2.val));
+       }
+       else    badsyntax();
+}
+
+bittestop(opc)
+       int opc;
+{
+       regsize(1);
+       emit1(0xF);
+       if (is_expr(reg_2)) {
+               emit1(0272);
+               ea_1(opc << 3);
+#ifdef RELOCATION
+               RELOMOVE(relonami, rel_2);
+               newrelo(exp_2.typ, RELO1);
+#endif
+               emit1((int)(exp_2.val));
+       }
+       else if (is_reg(reg_2)) {
+               emit1(0203 | opc);
+               ea_1((reg_2&7)<<3);
+       }
+       else    badsyntax();
+}
+
+imul(reg)
+       int reg;
+{
+       /*      This instruction is more elaborate on the 80386. Its most
+               general form is:
+                       imul reg, reg_or_mem, immediate.
+               This is the form processed here.
+       */
+       regsize(1);
+       if (is_expr(reg_1)) {
+               /* To also handle
+                       imul reg, immediate, reg_or_mem
+               */
+               reverse();
+       }
+       if (is_expr(reg_2)) {
+               /* The immediate form; two cases: */
+               if (exp_2.typ == S_ABS && fitb(exp_2.val)) {
+                       /* case 1: 1 byte encoding of immediate */
+                       emit1(0153);
+                       ea_1(reg << 3);
+                       emit1((int)(exp_2.val));
+               }
+               else {
+                       /* case 2: WORD or DWORD encoding of immediate */
+                       emit1(0151);
+                       ea_1(reg << 3);
+                       RELOMOVE(relonami, rel_2);
+                       opsize_exp(exp_2, 1);
+               }
+       }
+       else if (is_reg(reg_1) && ((reg_1&7) == reg)) {
+               /* the "reg" field and the "reg_or_mem" field are the same,
+                  and the 3rd operand is not an immediate ...
+               */
+               if (reg == 0) {
+                       /* how lucky we are, the target is the ax register */
+                       emit1(0367);
+                       ea_2(06 << 3);
+               }
+               else {
+                       /* another register ... */
+                       emit1(0xF);
+                       emit1(0257);
+                       ea_2(reg << 3);
+               }
+       }
+       else badsyntax();
+}