From 0b169912b0393d64149a308c4e9f1cb994a620a2 Mon Sep 17 00:00:00 2001 From: MaartenBrock Date: Sun, 10 Sep 2006 18:36:04 +0000 Subject: [PATCH] * as/mcs51/i51mch.c (machine): S_DJNZ fixed bug 1554318 git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4375 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 4 + as/mcs51/i51mch.c | 777 +++++++++++++++++++++++----------------------- 2 files changed, 392 insertions(+), 389 deletions(-) diff --git a/ChangeLog b/ChangeLog index da3d04d5..3a237267 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2006-09-10 Maarten Brock + + * as/mcs51/i51mch.c (machine): S_DJNZ fixed bug 1554318 + 2006-09-09 Borut Razem * debugger/mcs51/sdcdb.c, debugger/mcs51/simi.c: diff --git a/as/mcs51/i51mch.c b/as/mcs51/i51mch.c index 7af6a135..fa09b86f 100644 --- a/as/mcs51/i51mch.c +++ b/as/mcs51/i51mch.c @@ -21,506 +21,507 @@ extern int addr(struct expr *); * Process machine ops. */ VOID -machine(mp) -struct mne *mp; +machine(struct mne *mp) { - register unsigned op; + register unsigned op; register int t, t1, v1; - struct expr e, e1; + struct expr e, e1; - clrexpr(&e); - clrexpr(&e1); + clrexpr(&e); + clrexpr(&e1); - op = mp->m_valu; - switch (mp->m_type) { + op = mp->m_valu; + switch (mp->m_type) { - case S_INH: - outab(op); - break; + case S_INH: + outab(op); + break; - case S_JMP11: - /* ACALL or AJMP. In Flat24 mode, this is a - * 19 bit destination; in 8051 mode, this is a - * 11 bit destination. - * - * The opcode is merged with the address in a - * hack-o-matic fashion by the linker. + case S_JMP11: + /* ACALL or AJMP. In Flat24 mode, this is a + * 19 bit destination; in 8051 mode, this is a + * 11 bit destination. + * + * The opcode is merged with the address in a + * hack-o-matic fashion by the linker. */ - expr(&e, 0); - if (flat24Mode) - { - outr19(&e, op, R_J19); - } - else - { - outr11(&e, op, R_J11); - } - break; - - case S_JMP16: - /* LCALl or LJMP. In Flat24 mode, this is a 24 bit - * destination; in 8051 mode, this is a 16 bit - * destination. - */ - expr(&e, 0); - outab(op); - if (flat24Mode) - { - outr24(&e, 0); - } - else - { - outrw(&e, 0); - } - break; - - case S_ACC: + expr(&e, 0); + if (flat24Mode) + { + outr19(&e, op, R_J19); + } + else + { + outr11(&e, op, R_J11); + } + break; + + case S_JMP16: + /* LCALl or LJMP. In Flat24 mode, this is a 24 bit + * destination; in 8051 mode, this is a 16 bit + * destination. + */ + expr(&e, 0); + outab(op); + if (flat24Mode) + { + outr24(&e, 0); + } + else + { + outrw(&e, 0); + } + break; + + case S_ACC: t = addr(&e); - if (t != S_A) - aerr(); - outab(op); - break; + if (t != S_A) + aerr(); + outab(op); + break; - case S_TYP1: - /* A, direct, @R0, @R1, R0 to R7. "INC" also allows DPTR */ + case S_TYP1: + /* A, direct, @R0, @R1, R0 to R7. "INC" also allows DPTR */ t = addr(&e); - - switch (t) { + + switch (t) { case S_A: - outab(op + 4); + outab(op + 4); break; case S_DIR: case S_EXT: - /* Direct is also legal */ - outab(op + 5); + /* Direct is also legal */ + outab(op + 5); outrb(&e, R_PAG0); - break; + break; case S_AT_R: - outab(op + 6 + e.e_addr); + outab(op + 6 + e.e_addr); break; case S_REG: - outab(op + 8 + e.e_addr); + outab(op + 8 + e.e_addr); break; case S_DPTR: - if (op != 0) - /* only INC (op=0) has DPTR mode */ - aerr(); + if (op != 0) + /* only INC (op=0) has DPTR mode */ + aerr(); else - outab( 0xA3); + outab( 0xA3); break; default: - aerr(); + aerr(); } - break; + break; - case S_TYP2: - /* A,#imm; A,direct; A,@R0; A,@R1; A,R0 to A,R7 */ + case S_TYP2: + /* A,#imm; A,direct; A,@R0; A,@R1; A,R0 to A,R7 */ t = addr(&e); - if (t != S_A) - aerr(); + if (t != S_A) + aerr(); comma(); t1 = addr(&e1); - - switch (t1) { + + switch (t1) { case S_IMMED: - outab(op + 4); - outrb(&e1, 0); + outab(op + 4); + outrb(&e1, 0); break; case S_DIR: case S_EXT: - outab(op + 5); + outab(op + 5); outrb(&e1, R_PAG0); break; case S_AT_R: - outab(op + 6 + e1.e_addr); + outab(op + 6 + e1.e_addr); break; case S_REG: - outab(op + 8 + (e1.e_addr)); + outab(op + 8 + (e1.e_addr)); break; default: - aerr(); + aerr(); } - break; + break; - case S_TYP3: - /* dir,A; dir,#imm; - * A,#imm; A,direct; A,@R0; A,@R1; A,R0 to A,R7 + case S_TYP3: + /* dir,A; dir,#imm; + * A,#imm; A,direct; A,@R0; A,@R1; A,R0 to A,R7 * C,direct; C,/direct */ t = addr(&e); comma(); - t1 = addr(&e1); + t1 = addr(&e1); switch (t) { case S_DIR: case S_EXT: - switch (t1) { + switch (t1) { case S_A: - outab(op + 2); + outab(op + 2); outrb(&e, R_PAG0); break; - - case S_IMMED: - outab(op + 3); - outrb(&e, 0); - outrb(&e1, 0); + + case S_IMMED: + outab(op + 3); + outrb(&e, 0); + outrb(&e1, 0); break; default: - aerr(); + aerr(); } - break; + break; case S_A: - switch (t1) { - case S_IMMED: - outab(op + 4); - outrb(&e1, 0); - break; - - case S_DIR: - case S_EXT: - outab(op + 5); + switch (t1) { + case S_IMMED: + outab(op + 4); + outrb(&e1, 0); + break; + + case S_DIR: + case S_EXT: + outab(op + 5); outrb(&e1, R_PAG0); break; - case S_AT_R: - outab(op + 6 + e1.e_addr); - break; + case S_AT_R: + outab(op + 6 + e1.e_addr); + break; - case S_REG: - outab(op + 8 + e1.e_addr); - break; + case S_REG: + outab(op + 8 + e1.e_addr); + break; - default: - aerr(); + default: + aerr(); } break; case S_C: - /* XRL has no boolean version. Trap it */ - if (op == 0x60) - aerr(); + /* XRL has no boolean version. Trap it */ + if (op == 0x60) + aerr(); - switch (t1) { + switch (t1) { case S_DIR: - case S_EXT: - outab(op + 0x32); + case S_EXT: + outab(op + 0x32); outrb(&e1, R_PAG0); break; - + case S_NOT_BIT: - outab(op + 0x60); - outrb(&e1, 0); - break; - + outab(op + 0x60); + outrb(&e1, 0); + break; + default: - aerr(); - } + aerr(); + } break; default: - aerr(); - } - break; + aerr(); + } + break; - case S_TYP4: - /* A,direct; A,@R0; A,@R1; A,R0 to A,R7 */ + case S_TYP4: + /* A,direct; A,@R0; A,@R1; A,R0 to A,R7 */ t = addr(&e); - if (t != S_A) - aerr(); + if (t != S_A) + aerr(); comma(); t1 = addr(&e1); - switch (t1) { + switch (t1) { case S_DIR: case S_EXT: - outab(op + 5); + outab(op + 5); outrb(&e1, R_PAG0); break; case S_AT_R: - outab(op + 6 + e1.e_addr); + outab(op + 6 + e1.e_addr); break; case S_REG: - outab(op + 8 + e1.e_addr); + outab(op + 8 + e1.e_addr); break; default: - aerr(); + aerr(); } - break; + break; - /* MOV instruction, all modes */ - case S_MOV: + /* MOV instruction, all modes */ + case S_MOV: t = addr(&e); comma(); t1 = addr(&e1); - switch (t) { + switch (t) { case S_A: - switch (t1) { - case S_IMMED: - outab(0x74); - outrb(&e1, 0); - break; - - case S_DIR: - case S_EXT: - outab(0xE5); + switch (t1) { + case S_IMMED: + outab(0x74); + outrb(&e1, 0); + break; + + case S_DIR: + case S_EXT: + outab(0xE5); outrb(&e1, R_PAG0); break; - case S_AT_R: - outab(0xE6 + e1.e_addr); - break; + case S_AT_R: + outab(0xE6 + e1.e_addr); + break; - case S_REG: - outab(0xE8 + e1.e_addr); - break; + case S_REG: + outab(0xE8 + e1.e_addr); + break; - default: - aerr(); - } + default: + aerr(); + } break; case S_REG: - switch (t1) { - case S_A: - outab(0xF8 + e.e_addr); - break; + switch (t1) { + case S_A: + outab(0xF8 + e.e_addr); + break; - case S_IMMED: - outab(0x78 + e.e_addr); + case S_IMMED: + outab(0x78 + e.e_addr); outrb(&e1, 0); break; - - case S_DIR: - case S_EXT: - outab(0xA8 + e.e_addr); + + case S_DIR: + case S_EXT: + outab(0xA8 + e.e_addr); outrb(&e1, R_PAG0); break; - default: - aerr(); - } + default: + aerr(); + } break; case S_DIR: case S_EXT: - switch (t1) { - case S_A: - outab(0xF5); + switch (t1) { + case S_A: + outab(0xF5); outrb(&e, R_PAG0); break; - case S_IMMED: - outab(0x75); + case S_IMMED: + outab(0x75); outrb(&e, R_PAG0); outrb(&e1, 0); - break; - - case S_DIR: - case S_EXT: - outab(0x85); + break; + + case S_DIR: + case S_EXT: + outab(0x85); outrb(&e1, R_PAG0); outrb(&e, R_PAG0); break; - case S_AT_R: - outab(0x86 + e1.e_addr); + case S_AT_R: + outab(0x86 + e1.e_addr); outrb(&e, R_PAG0); break; - case S_REG: - outab(0x88 + e1.e_addr); + case S_REG: + outab(0x88 + e1.e_addr); outrb(&e, R_PAG0); break; - case S_C: - outab(0x92); + case S_C: + outab(0x92); outrb(&e, R_PAG0); break; - default: - aerr(); - } + default: + aerr(); + } break; case S_AT_R: - switch (t1) { - case S_IMMED: - outab(0x76 + e.e_addr); - outrb(&e1, 0); - break; - - case S_DIR: - case S_EXT: - outab(0xA6 + e.e_addr); + switch (t1) { + case S_IMMED: + outab(0x76 + e.e_addr); + outrb(&e1, 0); + break; + + case S_DIR: + case S_EXT: + outab(0xA6 + e.e_addr); outrb(&e1, R_PAG0); break; - case S_A: - outab(0xF6 + e.e_addr); - break; + case S_A: + outab(0xF6 + e.e_addr); + break; - default: - aerr(); - } + default: + aerr(); + } break; case S_C: - if ((t1 != S_DIR) && (t1 != S_EXT)) - aerr(); - outab(0xA2); + if ((t1 != S_DIR) && (t1 != S_EXT)) + aerr(); + outab(0xA2); outrb(&e1, R_PAG0); break; case S_DPTR: - if (t1 != S_IMMED) - aerr(); - outab(0x90); - - /* mov DPTR, #immed: for Flat24 mode, - * #immed is a 24 bit constant. For 8051, - * it is a 16 bit constant. - */ - if (flat24Mode) - { - outr24(&e1, 0); - } - else - { - outrw(&e1, 0); - } + if (t1 != S_IMMED) + aerr(); + outab(0x90); + + /* mov DPTR, #immed: for Flat24 mode, + * #immed is a 24 bit constant. For 8051, + * it is a 16 bit constant. + */ + if (flat24Mode) + { + outr24(&e1, 0); + } + else + { + outrw(&e1, 0); + } break; default: - aerr(); - } + aerr(); + } break; - case S_BITBR: - /* Branch on bit set/clear */ - t = addr(&e); - if ((t != S_DIR) && (t != S_EXT)) - aerr(); - outab(op); + case S_BITBR: + /* Branch on bit set/clear */ + t = addr(&e); + if ((t != S_DIR) && (t != S_EXT)) + aerr(); + outab(op); outrb(&e, R_PAG0); 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 (pass==2 && ((v1 < -128) || (v1 > 127))) - aerr(); - outab(v1); - } else { - outrb(&e1, R_PCR); - } - if (e1.e_mode != S_USER) - rerr(); - break; - - case S_BR: - /* Relative branch */ - outab(op); - 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 = -2; - else - v1 = e1.e_addr - dot.s_addr - 1; - if (pass == 2 && ((v1 < -128) || (v1 > 127))) - aerr(); - outab(v1); - } else { - outrb(&e1, R_PCR); - } - if (e1.e_mode != S_USER) - rerr(); - break; + 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 (pass==2 && ((v1 < -128) || (v1 > 127))) + aerr(); + outab(v1); + } else { + outrb(&e1, R_PCR); + } + if (e1.e_mode != S_USER) + rerr(); + break; + + case S_BR: + /* Relative branch */ + outab(op); + 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 = -2; + else + v1 = e1.e_addr - dot.s_addr - 1; + if (pass == 2 && ((v1 < -128) || (v1 > 127))) + aerr(); + outab(v1); + } else { + outrb(&e1, R_PCR); + } + if (e1.e_mode != S_USER) + rerr(); + break; case S_CJNE: - /* A,#; A,dir; @R0,#; @R1,#; Rn,# */ + /* A,#; A,dir; @R0,#; @R1,#; Rn,# */ t = addr(&e); comma(); t1 = addr(&e1); switch (t) { case S_A: - if (t1 == S_IMMED) { - outab(op + 4); - outrb(&e1, 0); + if (t1 == S_IMMED) { + outab(op + 4); + outrb(&e1, 0); } - else if ((t1 == S_DIR) || (t1 == S_EXT)) { - outab(op + 5); + else if ((t1 == S_DIR) || (t1 == S_EXT)) { + outab(op + 5); outrb(&e1, R_PAG0); } else - aerr(); + aerr(); break; case S_AT_R: - outab(op + 6 + e.e_addr); - if (t1 != S_IMMED) - aerr(); - outrb(&e1, 0); - break; - - case S_REG: - outab(op + 8 + e.e_addr); - if (t1 != S_IMMED) - aerr(); - outrb(&e1, 0); - break; - + outab(op + 6 + e.e_addr); + if (t1 != S_IMMED) + aerr(); + outrb(&e1, 0); + break; + + case S_REG: + outab(op + 8 + e.e_addr); + if (t1 != S_IMMED) + aerr(); + outrb(&e1, 0); + break; + default: - aerr(); + aerr(); } /* 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 (pass == 2 && ((v1 < -128) || (v1 > 127))) - aerr(); - outab(v1); - } else { - outrb(&e1, R_PCR); - } - if (e1.e_mode != S_USER) - rerr(); + 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 (pass == 2 && ((v1 < -128) || (v1 > 127))) + aerr(); + outab(v1); + } else { + outrb(&e1, R_PCR); + } + if (e1.e_mode != S_USER) + rerr(); break; case S_DJNZ: - /* Dir,dest; Reg,dest */ + /* Dir,dest; Reg,dest */ t = addr(&e); - switch (t) { + switch (t) { - case S_DIR: - case S_EXT: + 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); + outab(op + 8 + e.e_addr); + v1 = -2; break; default: @@ -529,166 +530,164 @@ 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 = -2; - else - v1 = e1.e_addr - dot.s_addr - 1; - if (pass == 2 && ((v1 < -128) || (v1 > 127))) - aerr(); - outab(v1); - } else { - outrb(&e1, R_PCR); - } - if (e1.e_mode != S_USER) - rerr(); - break; - - case S_JMP: - /* @A+DPTR */ + 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; + if (pass == 2 && ((v1 < -128) || (v1 > 127))) + aerr(); + outab(v1); + } else { + outrb(&e1, R_PCR); + } + if (e1.e_mode != S_USER) + rerr(); + break; + + case S_JMP: + /* @A+DPTR */ t = addr(&e); if (t != S_AT_ADP) - aerr(); + aerr(); outab(op); - break; + break; case S_MOVC: - /* A,@A+DPTR A,@A+PC */ + /* A,@A+DPTR A,@A+PC */ t = addr(&e); if (t != S_A) - aerr(); - comma(); + aerr(); + comma(); t1 = addr(&e1); if (t1 == S_AT_ADP) - outab(0x93); + outab(0x93); else if (t1 == S_AT_APC) - outab(0x83); - else - aerr(); - break; + outab(0x83); + else + aerr(); + break; case S_MOVX: - /* A,@DPTR A,@R0 A,@R1 @DPTR,A @R0,A @R1,A */ + /* A,@DPTR A,@R0 A,@R1 @DPTR,A @R0,A @R1,A */ t = addr(&e); - comma(); + comma(); t1 = addr(&e1); switch (t) { case S_A: - switch (t1) { + switch (t1) { case S_AT_DP: - outab(0xE0); + outab(0xE0); break; case S_AT_R: - outab(0xE2 + e1.e_addr); + outab(0xE2 + e1.e_addr); break; default: - aerr(); + aerr(); } break; case S_AT_DP: if (t1 == S_A) - outab(0xF0); + outab(0xF0); else - aerr(); + aerr(); break; case S_AT_R: if (t1 == S_A) - outab(0xF2 + e.e_addr); + outab(0xF2 + e.e_addr); else - aerr(); + aerr(); break; default: - aerr(); - } - break; + aerr(); + } + break; - /* MUL/DIV A,B */ - case S_AB: + /* MUL/DIV A,B */ + case S_AB: t = addr(&e); - if (t != S_RAB) aerr(); + if (t != S_RAB) aerr(); outab(op); - break; + break; - /* CLR or CPL: A, C, or bit */ + /* CLR or CPL: A, C, or bit */ case S_ACBIT: t = addr(&e); switch (t) { case S_A: - if (op == 0xB2) - outab(0xF4); + if (op == 0xB2) + outab(0xF4); else - outab(0xE4); - break; + outab(0xE4); + break; case S_C: - outab(op+1); - break; + outab(op+1); + break; case S_DIR: - case S_EXT: - outab(op); + case S_EXT: + outab(op); outrb(&e, R_PAG0); break; default: - aerr(); + aerr(); } - break; + break; - /* SETB C or bit */ + /* SETB C or bit */ case S_SETB: t = addr(&e); switch (t) { case S_C: - outab(op+1); - break; + outab(op+1); + break; case S_DIR: - case S_EXT: - outab(op); + case S_EXT: + outab(op); outrb(&e, R_PAG0); break; default: - aerr(); + aerr(); } - break; + break; - /* direct */ - case S_DIRECT: + /* direct */ + case S_DIRECT: t = addr(&e); if ((t != S_DIR) && (t != S_EXT)) { - aerr(); - break; + aerr(); + break; } outab(op); outrb(&e, R_PAG0); break; - /* XCHD A,@Rn */ + /* XCHD A,@Rn */ case S_XCHD: t = addr(&e); - if (t != S_A) - aerr(); + if (t != S_A) + aerr(); comma(); t1 = addr(&e1); - switch (t1) { + switch (t1) { case S_AT_R: - outab(op + e1.e_addr); + outab(op + e1.e_addr); break; default: - aerr(); + aerr(); } - break; + break; - default: - err('o'); - } + default: + err('o'); + } } /* @@ -697,9 +696,9 @@ struct mne *mp; int comma() { - if (getnb() != ',') - qerr(); - return(1); + if (getnb() != ',') + qerr(); + return(1); } /* @@ -711,15 +710,15 @@ comma() static int beenHere=0; /* set non-zero if we have done that... */ struct sym *sp; struct PreDef *pd; - - /* First time only, add the pe-defined symbols to the symbol table*/ + + /* First time only, add the pre-defined symbols to the symbol table*/ if (beenHere == 0) { pd = preDef; while (*pd->id) { sp = lookup(pd->id); if (sp->s_type == S_NEW) { sp->s_addr = pd->value; - sp->s_type = S_DIR; + sp->s_type = S_DIR; } pd++; } -- 2.30.2