From: SourceForge.net <no...@so...> - 2004-01-27 14:26:26
|
Feature Requests item #860006, was opened at 2003-12-14 22:57 Message generated for change (Comment added) made by bernhardheld You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=350599&aid=860006&group_id=599 Category: None Group: None >Status: Closed Priority: 5 Submitted By: Frieder Ferlemann (frief) >Assigned to: Bernhard Held (bernhardheld) Summary: 8x8 multiply uses 16bit intermediate Initial Comment: the other operators are fine, but multiply uses a 16bit intermediate: volatile unsigned char s,t; void main() { s=t*5; // this uses an 16 bit intermediate s=t/5; // whereas the other operators are fine without s=t%5; s=t+5; s=t-5; } ---------------------------------------------------------------------- >Comment By: Bernhard Held (bernhardheld) Date: 2004-01-25 22:36 Message: Logged In: YES user_id=203539 Fixed, see ChangeLog 1.605 The new type flow is enabled with the environment variable SDCC_NEWTYPEFLOW Discussion in sdcc-user ---------------------------------------------------------------------- Comment By: Bernhard Held (bernhardheld) Date: 2004-01-22 15:13 Message: Logged In: YES user_id=203539 5 is an 'unsigned char' in SDCC, and it would be very unwise to choose anything else. If it would be an int, the code size would explode. In this special case I don't care about a violation of the standard. But I take much care about the correctness of the results. The correct result is of course defined by the standard. ---------------------------------------------------------------------- Comment By: Mathias Neuhaus (mathiasn) Date: 2004-01-22 10:33 Message: Logged In: YES user_id=850360 Eric, as far as I understand the ISO documents, that rule comes into effect only, when the operands are of the same type... ISO/IEC 9899/1999 - 6.3.1.8: "... (conversion rules for float and double) ... Otherwise, the integer promotions are performed on both operands. Then the following rules are applied to the promoted operands: -- If both operands have the same type, then no further conversion is needed. -- Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank. ..." (ranks are defined in 6.3.1.1, and rank (int) > rank (char)) According to 5.1.2.3 ex. 2 the promotion can be skipped, but the type conversions have to be done in any case. Because 5 is of type int (there is no char constant (6.4.4.1)), the other operand (t) has to be converted (not promoted!) to int as well (2nd rule), even though promotion was skipped. On the other hand, when you cast the int constant to a char constant ((char) 5), no conversion has to be done (1st rule). I mixed up "promotion" and "conversion" in my first post, sorry. And 5 is an int constant, not an integer constant (sorry once again). ---------------------------------------------------------------------- Comment By: Erik Petrich (epetrich) Date: 2004-01-22 07:03 Message: Logged In: YES user_id=635249 It is acceptable to skip integer promotion as long as the same result is obtained as if the promotion occurred (often referred to as the "as-if semantics"). A quote from ISO/IEC 9899-1999 (the C-99 standard), section 5.1.2.3 Example 2: "In executing the fragment char c1, c2; /* ... */ c1 = c1 + c2; the "integer promotions" require that the abstract machine promote the value of each variable to int size and then add the two ints and truncate the sum. Provided the addition of two chars can be done without overflow, or with overflow wrapping silently to produce the correct result, the actual execution need only produce the same result, possibly omitting the promotions." The user can't force the use of 8-bit operation by an explicit cast since the integer promotion rules make no exception for dealing with the result of a cast. You can explicitly cast to char all you want, but the rules will still cause a final cast to int before the operator is applied. 8-bit operations are only possible using the as-if semantics. ---------------------------------------------------------------------- Comment By: Mathias Neuhaus (mathiasn) Date: 2004-01-21 19:39 Message: Logged In: YES user_id=850360 According to the ANSI type conversion rules the code generated by SDCC is correct for the multiplication example and the array-access. The code generated for /%+- is incorrect! 5 is an integer constant (there ain't no such thing as a char constant!!), so both operands have to be converted to int; the result of the operation is then cast back to char. Similar for the array access: sizeof (something) returns size_t, which - in most cases - is "typedef int size_t;" or "#define size_t int". Again we start with one int and one char (the index i) which has to be promoted to int. To keep ANSI compatibility, please DON'T change the behaviour for the multiplication, but correct the behaviour for operators /%+-. The user can force use of 8-bit operation by an explicit cast (well, should be, didn't try!). Taking into account the memory- and runtime-constraints of embedded systems, you might implement some #pragma to force 8bit operations, or something a "char-suffix" (similar to the long-suffix L). ---------------------------------------------------------------------- Comment By: Bernhard Held (bernhardheld) Date: 2004-01-20 21:13 Message: Logged In: YES user_id=203539 The array access has been fixed at least in SDCCicode.c 1.183 ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 2004-01-20 20:59 Message: Logged In: YES user_id=888171 This also applies to indexing an array of elements with size <256. long int x[]; long y; unsigned char i; y = x[i]; Both i and sizeof(x[0]) get cast up to int and _mulint is called. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=350599&aid=860006&group_id=599 |