include sys/stat.h
[fw/sdcc] / as / mcs51 / i51mch.c
index f4f4215533e5938d5fa85ccada19fe3760ae3c05..df73096e655a12f6d5d3d859a6859c1ac8f3be96 100644 (file)
@@ -1,13 +1,22 @@
-/* i85mch.c */
+/* i85mch.c
+
+   Copyright (C) 1989-1995 Alan R. Baldwin
+   721 Berkeley St., Kent, Ohio 44240
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
 /*
- * (C) Copyright 1989,1990
- * All Rights Reserved
- *
- * Alan R. Baldwin
- * 721 Berkeley St.
- * Kent, Ohio  44240
- *
  * 28-Oct-97 Ported from 8085 to 8051 by John Hartman
  */
 
@@ -25,10 +34,11 @@ machine(struct mne *mp)
 {
         register unsigned op;
         register int t, t1, v1;
-        struct expr e, e1;
+        struct expr e, e1, e2;
 
         clrexpr(&e);
         clrexpr(&e1);
+        clrexpr(&e2);
 
         op = mp->m_valu;
         switch (mp->m_type) {
@@ -57,7 +67,7 @@ machine(struct mne *mp)
                 break;
 
         case S_JMP16:
-                /* LCALl or LJMP. In Flat24 mode, this is a 24 bit
+                /* LCALL or LJMP. In Flat24 mode, this is a 24 bit
                  * destination; in 8051 mode, this is a 16 bit
                  * destination.
                  */
@@ -413,16 +423,12 @@ machine(struct mne *mp)
                 t = addr(&e);
                 if ((t != S_DIR) && (t != S_EXT))
                         aerr();
-                outab(op);
-                outrb(&e, R_PAG0);
-
                 comma();
                 expr(&e1, 0);
+                outab(op);
+                outrb(&e, R_PAG0);
                 if (e1.e_base.e_ap == NULL || e1.e_base.e_ap == dot.s_area) {
-                        if ( e1.e_addr == dot.s_addr)
-                                v1 = -3;
-                        else
-                                v1 = e1.e_addr - dot.s_addr - 1;
+                        v1 = e1.e_addr - dot.s_addr - 1;
                         if (pass==2 && ((v1 < -128) || (v1 > 127)))
                                 aerr();
                         outab(v1);
@@ -435,13 +441,10 @@ machine(struct mne *mp)
 
         case S_BR:
                 /* Relative branch */
-                outab(op);
                 expr(&e1, 0);
+                outab(op);
                 if (e1.e_base.e_ap == NULL || e1.e_base.e_ap == dot.s_area) {
-                        if ( e1.e_addr == dot.s_addr)
-                                v1 = -2;
-                        else
-                                v1 = e1.e_addr - dot.s_addr - 1;
+                        v1 = e1.e_addr - dot.s_addr - 1;
                         if (pass == 2 && ((v1 < -128) || (v1 > 127)))
                                 aerr();
                         outab(v1);
@@ -457,6 +460,8 @@ machine(struct mne *mp)
                 t = addr(&e);
                 comma();
                 t1 = addr(&e1);
+                comma();
+                expr(&e2, 0);
                 switch (t) {
                 case S_A:
                         if (t1 == S_IMMED) {
@@ -490,51 +495,42 @@ machine(struct mne *mp)
                 }
 
                 /* branch destination */
-                comma();
-                expr(&e1, 0);
-                if (e1.e_base.e_ap == NULL || e1.e_base.e_ap == dot.s_area) {
-                        if ( e1.e_addr == dot.s_addr)
-                                v1 = -3;
-                        else
-                                v1 = e1.e_addr - dot.s_addr - 1;
+                if (e2.e_base.e_ap == NULL || e2.e_base.e_ap == dot.s_area) {
+                        v1 = e2.e_addr - dot.s_addr - 1;
                         if (pass == 2 && ((v1 < -128) || (v1 > 127)))
                                 aerr();
                         outab(v1);
                 } else {
-                        outrb(&e1, R_PCR);
+                        outrb(&e2, R_PCR);
                 }
-                if (e1.e_mode != S_USER)
+                if (e2.e_mode != S_USER)
                         rerr();
                 break;
 
         case S_DJNZ:
                 /* Dir,dest;  Reg,dest */
                 t = addr(&e);
+                comma();
+                expr(&e1, 0);
                 switch (t) {
 
                 case S_DIR:
                 case S_EXT:
                         outab(op + 5);
                         outrb(&e, R_PAG0);
-                        v1 = -3;
                         break;
 
                 case S_REG:
                         outab(op + 8 + e.e_addr);
-                        v1 = -2;
                         break;
 
                 default:
                         aerr();
-                        v1 = 0;
                 }
 
                 /* branch destination */
-                comma();
-                expr(&e1, 0);
                 if (e1.e_base.e_ap == NULL || e1.e_base.e_ap == dot.s_area) {
-                        if ( e1.e_addr != dot.s_addr)
-                                v1 = e1.e_addr - dot.s_addr - 1;
+                        v1 = e1.e_addr - dot.s_addr - 1;
                         if (pass == 2 && ((v1 < -128) || (v1 > 127)))
                                 aerr();
                         outab(v1);