From: SourceForge.net <no...@so...> - 2006-10-16 08:56:30
|
Bugs item #1572431, was opened at 2006-10-07 00:08 Message generated for change (Comment added) made by frief You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1572431&group_id=599 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: C-Front End Group: None >Status: Closed Resolution: None Priority: 5 Submitted By: Wolfgang Heidrich (wolfgang75) Assigned to: Nobody/Anonymous (nobody) Summary: yy -=x*6: wrong assembler code Initial Comment: I'm using: ;-------------------------------------------------------- ; File Created by SDCC : FreeWare ANSI-C Compiler ; Version 2.5.0 #1020 (May 8 2005) ; This file generated Fri Oct 6 23:10:33 2006 ;-------------------------------------------------------- .module bug .optsdcc -mmcs51 --model-small The following is the sample code that produces, in my opinion, the wrong code: -------------------------------------------- #include <stdio.h> void putchar( char a ) { a=0; } void calc( unsigned int yy, unsigned char x) { yy -= x*6; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<< The problem is here. printf("Result: %02u ", yy ); } void main( void ) { unsigned char i; for( i=0; i<10; i++ ) calc( 280, i ); } ------------------------------------------- The following is the produced assembler code ( sdcc bug.c ) of function calc(...): ;------------------------------------------------------------ ;Allocation info for local variables in function 'calc' ;------------------------------------------------------------ ;x Allocated with name '_calc_PARM_2' ;yy Allocated to registers r2 r3 ;------------------------------------------------------------ ;bug.c:8: void calc( unsigned int yy, unsigned char x) ; ----------------------------------------- ; function calc ; ----------------------------------------- _calc: ; genReceive mov r2,dpl mov r3,dph ;bug.c:10: yy -= x*6; ; genMult ; genMultOneByte mov a,_calc_PARM_2 mov b,#0x06 mul ab ; genMinus setb c ; Peephole 236.l used r2 instead of ar2 subb a,r2 cpl a mov r2,a mov a,r3 subb a,b mov r3,a ... ... ... As far as I understood there is missing a "cpl c" just after the "cpl a". Detailed explanation: The compiler tries to implement "yy -= x*6;" (at least concerning the low byte) similar to following c code: p = x*6 yy = p - yy yy = -yy For the negation "yy = -yy" the compiler needs to substract 1 and calculate the complement. Substracting 1 is done indirectly with "setb c" before "subb a,r2". The complement is done with "cpl a". But the compiler forgot to complement the carry bit. The high byte is substracted differently as "yy = yy - p", but now using the wrong (uncomplemented) carry bit. Example: yy = 280 = 0x118 and x = 46 = 0x2E => r2=0x18 r3=0x01 mul ab ; => b=0x01 a=0x14 setb c ; => c=1 subb a,r2 ; => a = a-r2-c = 0x14-0x18-1 = 0xFB = -5 and c=1 because "borrow" happened. cpl a ; => a = 0x04 mov r2,a ; => r2 = 0x04 (this is correct) mov a,r3 ; => a = 0x01 subb a,b ; a = a-b-c = 0x01-0x01-1 = 0xff (carry bit is set, see above, this is wrong) mov r3,a ; r3 = 0xff So the 8051 gets as result 0xff04 instead of the correct result 0x04. Concerning everything else of sdcc I'm highly pleased, thank you very much for the great work! Many greetings from Munich! Wolfgang Heidrich ---------------------------------------------------------------------- >Comment By: Frieder Ferlemann (frief) Date: 2006-10-16 10:56 Message: Logged In: YES user_id=589052 Please get a more recent version of SDCC. This was fixed on 2005-10-26 by Bernhard Held. (This report is a duplicate of bug report #1270906) ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1572431&group_id=599 |