From: SourceForge.net <no...@so...> - 2005-03-29 20:54:27
|
Feature Requests item #1162453, was opened at 2005-03-13 15:11 Message generated for change (Comment added) made by frief You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=350599&aid=1162453&group_id=599 Category: None Group: None Status: Open Priority: 1 Submitted By: Frieder Ferlemann (frief) Assigned to: Nobody/Anonymous (nobody) Summary: condition (i<0x1000) could be (i&0xf000) Initial Comment: An unsigned compare to a literal which is a power of 2 and >=256 could be reduced to anding a bitmask. unsigned char t; void f(unsigned int i) { if( i < 0x1000 ) t++; /* functionally equivalent, but only upper byte(s) need(s) to be accessed */ if( !( i & 0xf000 ) ) t++; } On the mcs51: ;lessthan.c:6: if( i < 0x1000 ) clr c mov a,r2 subb a,#0x00 mov a,r3 subb a,#0x10 jnc 00102$ ;lessthan.c:10: if( !( i & 0xf000 ) ) mov a,r3 anl a,#0xF0 jz 00111$ ---------------------------------------------------------------------- >Comment By: Frieder Ferlemann (frief) Date: 2005-03-29 20:54 Message: Logged In: YES user_id=589052 attaching the file Hubert sent to me. ---------------------------------------------------------------------- Comment By: Hubert Sack (hsack) Date: 2005-03-29 20:46 Message: Logged In: YES user_id=1160854 I corrected the source and pleased Frieder to do the attachment. ---------------------------------------------------------------------- Comment By: Hubert Sack (hsack) Date: 2005-03-29 16:30 Message: Logged In: YES user_id=1160854 I detected that I made a mistake. The jump is inverted! I'll post a correct version soon. My error was found by running regression tests of two more solutions of RFE's. The example above is also wrong, if 00111$ is the label following the conditional block! ---------------------------------------------------------------------- Comment By: Erik Petrich (epetrich) Date: 2005-03-16 07:08 Message: Logged In: YES user_id=635249 I fixed the bug of x = x being discarded when x is volatile. > left = ((volatile unsigned int)left); > Shouldn't this provoke a dummy read? I don't think so. The cast modifies the type of the value of the expression following, but has no control over how the value is initially derived. Since the object "left" is not itself declared as volatile, the compiler is still free to determine its value by either direct or optimized means. ---------------------------------------------------------------------- Comment By: Hubert Sack (hsack) Date: 2005-03-15 19:02 Message: Logged In: YES user_id=1160854 Hello Frieder, I think, you're right. Volatile is checked in "genAssign" for this. But the modifier "volatile" has no effect. With the option "- -i-code-in-asm" there is no "volatile" shown and therefore no code is generated. But there is a much more strange error (i think it should be reported as bug!): If the variable is declared as volatile, the elemination is already done some stage(s) earlier - there is no icode generated. This is a bug! Reading a volatile variable must be done and can not be simply optimized away... ---------------------------------------------------------------------- Comment By: Frieder Ferlemann (frief) Date: 2005-03-14 21:07 Message: Logged In: YES user_id=589052 Hello Hubert, I added test cases for this in sdcc/support/regression/tests/compare.c (patch is appended). There's a problem lurking somewhere. Off-topic: Another (unrelated) strangeness (with my attached patch) is that there is no code generated for: left = ((volatile unsigned int)left); Shouldn't this provoke a dummy read? ---------------------------------------------------------------------- Comment By: Hubert Sack (hsack) Date: 2005-03-13 21:08 Message: Logged In: YES user_id=1160854 Here is the solution for the RFE: Index: sdcc/src/SDCCopt.c ============================================= ====================== RCS file: /cvsroot/sdcc/sdcc/src/SDCCopt.c,v retrieving revision 1.54 diff -c -r1.54 SDCCopt.c *** sdcc/src/SDCCopt.c 9 Mar 2005 19:18:47 -0000 1.54 --- sdcc/src/SDCCopt.c 13 Mar 2005 21:02:08 -0000 *************** *** 582,587 **** --- 581,611 ---- + if (ic->op == '<' && isOperandLiteral(IC_RIGHT(ic)) && IS_UNSIGNED(operandType(IC_LEFT(ic)))) + { + unsigned litVal = abs(operandLitValue(IC_RIGHT (ic))); + + // See if literal value is greather 255 and a power of 2. + if (litVal > 255) + { + while (litVal && !(litVal & 1)) + { + litVal >>= 1; + } + if (litVal) + { + // discard lowest set bit. + litVal >>= 1; + } + } + if (!litVal) + { + ic->op = BITWISEAND; + IC_RIGHT(ic) = operandFromLit(0 - operandLitValue(IC_RIGHT(ic))); + continue; + } + } It's tested and o.k. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=350599&aid=1162453&group_id=599 |