Added 16-bit mode
authorceriel <none@none>
Mon, 12 Mar 1990 16:24:58 +0000 (16:24 +0000)
committerceriel <none@none>
Mon, 12 Mar 1990 16:24:58 +0000 (16:24 +0000)
mach/i386/as/mach1.c
mach/i386/as/mach2.c
mach/i386/as/mach3.c
mach/i386/as/mach4.c
mach/i386/as/mach5.c

index 910a3b9..5ecaad7 100644 (file)
@@ -75,3 +75,28 @@ char regindex_ind[8][8] = {
 #endif
 
 extern int     address_long INIT(1), operand_long INIT(1);
+extern int     use32 INIT(1);
+
+/* For 16-bit addressing: copied from i86 assembler */
+#ifndef extern
+extern char     sr_m[8];
+#else
+char    sr_m[8] = {
+        -1,     -1,     -1,     7,      -1,     6,      4,      5
+};
+#endif
+
+#ifndef extern
+extern char     dr_m[8][8];
+#else
+char    dr_m[8][8] = {
+        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
+        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
+        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
+        -1,     -1,     -1,     -1,     -1,     -1,     0,      1,
+        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
+        -1,     -1,     -1,     -1,     -1,     -1,     2,      3,
+        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,
+        -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1
+};
+#endif
index 18c16fc..3f899b9 100644 (file)
@@ -8,6 +8,10 @@
  * INTEL 80386 tokens
  */
 
+%token <y_word> ATOGGLE
+%token <y_word> OTOGGLE
+%token <y_word> USE16
+%token <y_word> USE32
 %token <y_word> R32
 %token <y_word> R16
 %token <y_word> R8
index eca3888..f3c06c6 100644 (file)
@@ -10,6 +10,8 @@
  * No system registers for now ...
  */
 
+0,     USE16,          0,              ".use16",
+0,     USE32,          0,              ".use32",
 0,     R32,            0,              "ax",
 0,     R32,            1,              "cx",
 0,     R32,            2,              "dx",
 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,     OTOGGLE,        0146,           "o16",  /* operand size toggle */
+0,     OTOGGLE,        0346,           "o32",  /* operand size toggle */
+0,     ATOGGLE,        0147,           "a16",  /* address size toggle */
+0,     ATOGGLE,        0347,           "a32",  /* address size toggle */
 0,     PREFIX,         0360,           "lock",
 0,     PREFIX,         0362,           "rep",
 0,     PREFIX,         0362,           "repne",
index 0197651..5e273e8 100644 (file)
@@ -8,18 +8,37 @@
 
 operation
        :
-               prefix oper
-                       {       address_long = 1; operand_long = 1; }
+               USE16
+                       {       use32 = 0; address_long = 0; operand_long = 0; }
+       |
+               USE32
+                       {       use32 = 1; address_long = 1; operand_long = 1; }
+       |       prefix oper
+                       {       address_long = use32; operand_long = use32; }
        |       prefix1         /* to allow for only prefixes on a line */
        ;
 prefix :       /* empty */
        |       prefix1
        ;
-prefix1:       prefix PREFIX
-                       {       if ($2 == 0146) operand_long = ! operand_long;
-                               if ($2 == 0147) address_long = ! address_long;
-                               emit1($2);
-                       }
+prefix1:       prefix PREFIX   { emit1($2); }
+       |
+               prefix ATOGGLE
+                               { if ((($2&0200) >> 7) == address_long) {
+                                       if (pass == PASS_3) warning("address size toggle ignored");
+                                 } else {
+                                       emit1($2 & 0177);
+                                       address_long = ! address_long;
+                                 }
+                               }
+       |
+               prefix OTOGGLE
+                               { if ((($2&0200) >> 7) == operand_long) {
+                                       if (pass == PASS_3) warning("operand size toggle ignored");
+                                 } else {
+                                       emit1($2 & 0177);
+                                       operand_long = ! operand_long;
+                                 }
+                               }
        ;
 oper   :       NOOP_1
                        {       emit1($1);}
@@ -177,8 +196,15 @@ st_i       :       ST '(' absexp ')'
 
        ;
 mem    :       '(' expr ')'
-                       {       rm_2 = 05; exp_2 = $2; reg_2 = 05; mod_2 = 0;
+                       {       if (address_long) {
+                                       rm_2 = 05; reg_2 = 05; mod_2 = 0;
+                               }
+                               else {
+                                       reg_2 = 06;
+                               }
+                               exp_2 = $2;
                                RELOMOVE(rel_2, relonami);
+                                       
                        }
        |       bases
                        {       exp_2.val = 0; exp_2.typ = S_ABS; indexed();}
@@ -188,10 +214,20 @@ mem       :       '(' expr ')'
                        }
        ;
 bases  :       '(' R32 ')'
-                       {       reg_2 = $2; sib_2 = 0; rm_2 = 0;}
+                       {       if (address_long) {
+                                       reg_2 = $2; sib_2 = 0; rm_2 = 0;
+                               }
+                               else    reg_2 = sr_m[$2];
+                       }
        |       '(' R32 ')' '(' R32 scale ')'
-                       {       rm_2 = 04; sib_2 |= regindex_ind[$2][$5];
-                               reg_2 = $2;
+                       {       if (address_long) {
+                                       rm_2 = 04;
+                                        sib_2 |= regindex_ind[$2][$5];
+                                       reg_2 = $2;
+                               }
+                               else {
+                                       reg_2 = dr_m[$2][$5];
+                               }
                        }
        |       '(' R32 '*' absexp ')'
                        {       if ($4 == 1) {
index 88b74c8..bdd15af 100644 (file)
@@ -8,7 +8,40 @@
  * INTEL 80386 special routines
  */
 
+ea_1_16(param)
+{
+        if ((reg_1 & 070) || (param & ~070)) {
+                serror("bad operand");
+        }
+        emit1(reg_1 | param);
+        switch(reg_1 >> 6) {
+        case 0:
+                if (reg_1 == 6 || (reg_1 & 040)) {
+#ifdef RELOCATION
+                        RELOMOVE(relonami, rel_1);
+                        newrelo(exp_1.typ, RELO2);
+#endif
+                        emit2(exp_1.val);
+                }
+                break;
+        case 1:
+                emit1(exp_1.val);
+                break;
+        case 2:
+#ifdef RELOCATION
+                RELOMOVE(relonami, rel_1);
+                newrelo(exp_1.typ, RELO2);
+#endif
+                emit2(exp_1.val);
+                break;
+        }
+}
+
 ea_1(param) {
+       if (! address_long) {
+               ea_1_16(param);
+               return;
+       }
        if (is_expr(reg_1)) {
                serror("bad operand");
                return;
@@ -49,6 +82,10 @@ checkscale(val)
 {
        int v = val;
 
+       if (! address_long) {
+               serror("scaling not allowed in 16-bit mode");
+               return 0;
+       }
        if (v != val) v = 0;
        switch(v) {
        case 1:
@@ -93,24 +130,34 @@ regsize(sz)
 }
 
 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 (address_long) {
+               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;
        }
-       if (reg_2 == 015) {
-               reg_2 = 05;
-               return;
+       else {
+               if (reg_2 & ~7)
+                       serror("register error");
+               if (exp_2.typ != S_ABS || fitb(exp_2.val) == 0)
+                       reg_2 |= 0200;
+               else if (exp_2.val != 0 || reg_2 == 6)
+                       reg_2 |= 0100;
        }
-       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)
@@ -245,7 +292,7 @@ adsize_exp(exp, relpc)
                emit4((long)(exp.val));
        }
        else {
-               if (! fitw(exp.val)) {
+               if (! fitw(exp.val) && pass == PASS_3) {
                        warning("offset does not fit in 2 bytes; remove prefix");
                }
 #ifdef RELOCATION