Fixed 16-bit address mode bugs
authorceriel <none@none>
Mon, 19 Mar 1990 14:46:55 +0000 (14:46 +0000)
committerceriel <none@none>
Mon, 19 Mar 1990 14:46:55 +0000 (14:46 +0000)
mach/i386/as/mach1.c
mach/i386/as/mach4.c
mach/i386/as/mach5.c

index 5ecaad7..8d67e3a 100644 (file)
@@ -25,7 +25,7 @@
 #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) != 0 && ((reg)&(IS_R8|IS_R32)) == (reg))
+#define is_acc(reg)    (is_reg(reg) && ((reg & 07) == 0))
 
 struct operand {
        int     mod;
index 5e273e8..7e04580 100644 (file)
@@ -102,9 +102,13 @@ oper       :       NOOP_1
        |       IMULB   ea_1
                        {       regsize(0); emit1(0366); ea_1($1&070);}
        |       IMUL    ea_2
-                       {       reg_1 = IS_R32; imul(0); }
+                       {       reg_1 = IS_R32 | (address_long ? 0 : 0310);
+                               imul(0);
+                       }
        |       IMUL    R32 ',' ea_2
-                       {       reg_1 = $2 | IS_R32; imul($2|0x10); }
+                       {       reg_1 = $2 | IS_R32 | (address_long ? 0 : 0310);
+                               imul($2|0x10);
+                       }
        |       IMUL    R32 ',' ea_ea
                        {       imul($2|0x10);}
        |       INT absexp
@@ -196,12 +200,10 @@ st_i      :       ST '(' absexp ')'
 
        ;
 mem    :       '(' expr ')'
-                       {       if (address_long) {
-                                       rm_2 = 05; reg_2 = 05; mod_2 = 0;
-                               }
-                               else {
-                                       reg_2 = 06;
-                               }
+                       {       if (address_long) reg_2 = 05;
+                               else reg_2 = 06;
+                               mod_2 = 0;
+                               rm_2 = 05;
                                exp_2 = $2;
                                RELOMOVE(rel_2, relonami);
                                        
@@ -214,20 +216,15 @@ mem       :       '(' expr ')'
                        }
        ;
 bases  :       '(' R32 ')'
-                       {       if (address_long) {
-                                       reg_2 = $2; sib_2 = 0; rm_2 = 0;
-                               }
+                       {       if (address_long) reg_2 = $2;
                                else    reg_2 = sr_m[$2];
+                               sib_2 = 0; rm_2 = 0;
                        }
        |       '(' R32 ')' '(' R32 scale ')'
-                       {       if (address_long) {
-                                       rm_2 = 04;
-                                        sib_2 |= regindex_ind[$2][$5];
-                                       reg_2 = $2;
-                               }
-                               else {
-                                       reg_2 = dr_m[$2][$5];
-                               }
+                       {       if (address_long) reg_2 = $2;
+                               else reg_2 = dr_m[$2][$5];
+                               rm_2 = 04;
+                               sib_2 |= regindex_ind[$2][$5];
                        }
        |       '(' R32 '*' absexp ')'
                        {       if ($4 == 1) {
@@ -247,13 +244,20 @@ scale     :       /* empty */
        ;
 ea_2   :       mem
        |       R8
-                       {       reg_2 = $1 | IS_R8; rm_2 = 0;}
+                       {       reg_2 = ($1 | IS_R8) | (address_long ? 0 : 0300);
+                               rm_2 = 0;
+                       }
        |       R32
-                       {       reg_2 = $1 | IS_R32; rm_2 = 0;}
+                       {       reg_2 = ($1 | IS_R32) | (address_long ? 0 : 0310);
+                               rm_2 = 0;
+                       }
        |       RSEG
-                       {       reg_2 = $1 | IS_RSEG; rm_2 = 0;}
+                       {       reg_2 = ($1 | IS_RSEG) | (address_long ? 0 : 020);
+                               rm_2 = 0;
+                       }
        |       expr
-                       {       reg_2 = IS_EXPR; exp_2 = $1; rm_2 = 0;
+                       {       reg_2 = IS_EXPR | (address_long ? 0 : 040);
+                               exp_2 = $1; rm_2 = 0;
                                RELOMOVE(rel_2, relonami);
                        }
        ;
index bdd15af..0eaddda 100644 (file)
@@ -10,6 +10,7 @@
 
 ea_1_16(param)
 {
+       reg_1 &= 0377;
         if ((reg_1 & 070) || (param & ~070)) {
                 serror("bad operand");
         }
@@ -127,6 +128,10 @@ regsize(sz)
        if ((is_reg(reg_1) && (reg_1 & IS_R8) != bit) ||
            (is_reg(reg_2) && (reg_2 & IS_R8) != bit)) 
                serror("register error");
+       if (! address_long) {
+               reg_1 &= ~010;
+               reg_2 &= ~010;
+       }
 }
 
 indexed() {
@@ -292,9 +297,6 @@ adsize_exp(exp, relpc)
                emit4((long)(exp.val));
        }
        else {
-               if (! fitw(exp.val) && pass == PASS_3) {
-                       warning("offset does not fit in 2 bytes; remove prefix");
-               }
 #ifdef RELOCATION
                newrelo(exp.typ, RELO2 | relpc);
 #endif
@@ -344,7 +346,7 @@ rolop(opc)
        oreg = reg_2;
        reg_2 = reg_1;
        regsize(opc);
-       if (oreg == (IS_R8 | 1)) {
+       if (oreg == (IS_R8 | 1 | (address_long ? 0 : 0300))) {
                /* cl register */
                emit1(0322 | (opc&1)); ea_1(opc&070);
        } else if (is_expr(oreg) && exp_2.typ == S_ABS && exp_2.val == 1) {
@@ -446,10 +448,10 @@ mov(opc)
        regsize(opc);
        if (is_segreg(reg_1)) {
                /* to segment register */
-               emit1(0216); ea_2((reg_1&3)<<3);
+               emit1(0216); ea_2((reg_1&07)<<3);
        } else if (is_segreg(reg_2)) {
                /* from segment register */
-               emit1(0214); ea_1((reg_2&3)<<3);
+               emit1(0214); ea_1((reg_2&07)<<3);
        } else if (is_expr(reg_2)) {
                /* from immediate */
                if (is_reg(reg_1)) {
@@ -473,10 +475,10 @@ mov(opc)
                adsize_exp(exp_2, 0);
        } else if (is_reg(reg_2)) {
                /* from register to memory or register */
-               emit1(0210 | opc); ea_1((reg_2&7)<<3);
+               emit1(0210 | opc); ea_1((reg_2&07)<<3);
        } else if (is_reg(reg_1)) {
                /* from memory or register to register */
-               emit1(0212 | opc); ea_2((reg_1&7)<<3);
+               emit1(0212 | opc); ea_2((reg_1&07)<<3);
        } else
                badsyntax();
 }
@@ -490,7 +492,7 @@ extshft(opc, reg)
        regsize(1);
 
        emit1(0xF);
-       if (oreg2 == (IS_R8 | 1)) {
+       if (oreg2 == (IS_R8 | 1 | (address_long ? 0 : 0300))) {
                /* cl register */
                emit1(opc|1);
                ea_1(reg << 3);