I'm trying to move some 8051 code from medium model (where it works) to small model (where it compiles but doesn't work). I've isolated at least one error but I'm not sure it it is a compiler error or a programmer error of some kind.
types.h:typedef unsigned char SOCKET; wiz_config.h:#define WIZ_COMMON_BASE 0x0000 wiz.h:#define WIZ_SOCK_BASE (WIZ_COMMON_BASE + 0x4000) wiz.h:#define WIZ_SOCK_SIZE (0x0100) wiz.h:#define WIZ_SOCK_REG(ch, x) (WIZ_SOCK_BASE + ch * WIZ_SOCK_SIZE + x) wiz.h:#define Sn_IR(ch) WIZ_SOCK_REG(ch, 0x0002) /* 1 byte */ /*---------------------------------------------------------------------------*/ void wiz_setSn_IR (SOCKET xdata s, uint8 xdata val) { #if WIZ_USE_INTERRUPT /* NOTE: If value has Sn_IR_SEND_OK set, * we must do the write to the hardware! */ vuint8 xdata tmpEA; unsigned char xdata buf[20]; if (val & Sn_IR_SEND_OK) { sprintf(buf,"sw%x %x\r\n",s,val); serial_print(buf); wiz_write8 (Sn_IR(s), val); /* line 261 in the listing */ } ... compiled with tonites snap (although the results are the same on several different snaps from the last several weeks) with medium and small, the gerenerated code is different and in small incorrect: "c:/program files/sdcc"/bin/sdcc -c wiz.c --model-medium --fverbose-asm --i-code-in-asm 2793 ; wiz.c:261: wiz_write8 (Sn_IR(s), val); 2794 ; [--2--56-] ic:21: iTemp15 [k25 lr2 1:22 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0}{const-int register}[r5 r6 ] = iTemp5 [k10 lr9:21 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0}{int xdata}[r5 r6 ] << 0x8 {con st-unsigned-char literal} 2795 ; genLeftShift 2796 ; genLeftShiftLiteral 2797 ; genlshTwo 0762 8D 06 2798 mov ar6,r5 0764 7D 00 2799 mov r5,#0x00 2800 ; [--2--56-] ic:22: iTemp16 [k26 lr2 2:24 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0}{const-int register}[r5 r6 ] = iTemp15 [k25 lr21:22 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0}{const-int register}[r5 r6 ] + 0x4002 {const-int literal} 2801 ; genPlus 2802 ; genPlusIncr 0766 74 02 2803 mov a,#0x02 2804 ; Peephole 236.a used r5 instead of ar5 0768 2D 2805 add a,r5 0769 FD 2806 mov r5,a 076A 74 40 2807 mov a,#0x40 2808 ; Peephole 236.b used r6 instead of ar6 076C 3E 2809 addc a,r6 076D FE 2810 mov r6,a 2811 ; [--2--56-] ic:23: send iTemp16 [k2 6 lr22:24 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0}{const-int register}[r5 r6 ]{argr eg = 1} 2812 ; [--2--56-] ic:24: _wiz_write8_PARM _2 [k30 lr0:0 so:0]{ ia1 a2p0 re0 rm0 nos0 ru0 dp0}{unsigned-char xdata} := iTem p0 [k4 lr4:43 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0}{unsigned-char xdata}[r2 ] 2813 ; genAssign 076E 90s00r5D 2814 mov dptr,#_wiz_write8_PARM_2 0771 EA 2815 mov a,r2 0772 F0 2816 movx @dptr,a 2817 ; [--2-----] ic:25: iTemp19 [k31 lr2 5:25 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0}{void fixed} = call _wiz_write8 [k22 l r0:0 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0}{void function ( unsigned-int xdata , unsigned-char xdata) fixed} 2818 ; genCall 0773 8D 82 2819 mov dpl,r5 0775 8E 83 2820 mov dph,r6 0777 C0 02 2821 push ar2 0779 12s00r5B 2822 lcall _wiz_write8 077C D0 02 2823 pop ar2 The above code works correctly. However compiled with: "c:/program files/sdcc"/bin/sdcc -c wiz.c --fverbose-asm --i-code-in-asm 2791 ; wiz.c:261: wiz_write8 (Sn_IR(s), val); 2792 ; [--2--56-] ic:21: iTemp15 [k25 lr2 1:22 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0}{const-int register}[r5 r6 ] = iTemp5 [k10 lr9:21 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0}{int xdata}[r5 r6 ] << 0x8 {con st-unsigned-char literal} 2793 ; genLeftShift 2794 ; genLeftShiftLiteral 2795 ; genlshTwo 075D 8D 06 2796 mov ar6,r5 075F 7D 00 2797 mov r5,#0x00 2798 ; [--2--56-] ic:22: iTemp16 [k26 lr2 2:24 so:0]{ ia0 a2p0 re0 rm0 nos0 ru1 dp0}{const-int register} = iTemp15 [k25 lr 21:22 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0}{const-int register}[r5 r6 ] + 0x4002 {const-int literal} 2799 ; genPlus 2800 ; genPlusIncr 0761 74 02 2801 mov a,#0x02 2802 ; Peephole 236.a used r5 instead of ar5 0763 2D 2803 add a,r5 0764 F5 82 2804 mov dpl,a 0766 74 40 2805 mov a,#0x40 2806 ; Peephole 236.b used r6 instead of ar6 0768 3E 2807 addc a,r6 0769 F5 83 2808 mov dph,a 2809 ; [--2-----] ic:23: send iTemp16 [k2 6 lr22:24 so:0]{ ia0 a2p0 re0 rm0 nos0 ru1 dp0}{const-int register}{argreg = 1} 2810 ; [--2-----] ic:24: _wiz_write8_PARM _2 [k30 lr0:0 so:0]{ ia1 a2p0 re0 rm0 nos0 ru0 dp0}{unsigned-char xdata} := iTem p0 [k4 lr4:43 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0}{unsigned-char xdata}[r2 ] 2811 ; genAssign 076B 90s00r5D 2812 mov dptr,#_wiz_write8_PARM_2 076E EA 2813 mov a,r2 076F F0 2814 movx @dptr,a 2815 ; [--2-----] ic:25: iTemp19 [k31 lr2 5:25 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0}{void fixed} = call _wiz_write8 [k22 l r0:0 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0}{void function ( unsigned-int xdata , unsigned-char xdata) fixed} 2816 ; genCall 0770 C0 02 2817 push ar2 0772 12s00r5B 2818 lcall _wiz_write8 It doesn't work. It appears the reason is that at line 2804 and 2808 above the argument values are moved to dpl and dph rather than back to r5 and r6 as they are in the medium model case. Unfortunatly right after that dptr is loaded with _wiz_write8_PARM_2 which overwrites the just calculated parameter value that was saved in dptr with unfortunate results. So is this a compiler bug that I should be reporting or bad C code (neither the vendor's programmers or me are particularly good C programmers and I think I may be the better of the two of us, which is a scary thought :-)). Peter Van Epp ------------------------------------------------------------------------------ _______________________________________________ Sdcc-user mailing list Sdcc-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/sdcc-user