Feature Requests item #860006, was opened at 2003-12-14 22:57
Message generated for change (Comment added) made by mathiasn
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=350599&aid=860006&group_id=599
Category: None
Group: None
Status: Open
Priority: 5
Submitted By: Frieder Ferlemann (frief)
Assigned to: Nobody/Anonymous (nobody)
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: 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

Feature Requests item #860006, was opened at 2003-12-14 15:57
Message generated for change (Comment added) made by epetrich
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=350599&aid=860006&group_id=599
Category: None
Group: None
Status: Open
Priority: 5
Submitted By: Frieder Ferlemann (frief)
Assigned to: Nobody/Anonymous (nobody)
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: Erik Petrich (epetrich)
Date: 2004-01-22 00: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 12: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 14: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 13: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

Feature Requests item #860006, was opened at 2003-12-14 22:57
Message generated for change (Comment added) made by mathiasn
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=350599&aid=860006&group_id=599
Category: None
Group: None
Status: Open
Priority: 5
Submitted By: Frieder Ferlemann (frief)
Assigned to: Nobody/Anonymous (nobody)
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: 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

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: Open
Priority: 5
Submitted By: Frieder Ferlemann (frief)
Assigned to: Nobody/Anonymous (nobody)
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-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

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