Electronics & Programming

develissimo

Open Source electronics development and programming

  • You are not logged in.
  • Root
  • » AVR-GCC
  • » [avr-gcc-list] multiply by constant always expands to int [RSS Feed]

#1 Dec. 4, 2005 05:49:19

Ben J.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[avr-gcc-list] multiply by constant always expands to int


Using 3.4.4 (I'm off 4.0.1 for now because I haven't had time to figure
out why all loop variables are promoted to ints) I had a strange experience
where changing:

char x = 10, y;

loop {
f(x * y);
}

got *longer* when I made it 'const char x = 10' or just hardcoded 10.
Turns out to be because mulqi was replaced with mulhi which is longer.
Now I'm not 100% sure what the integral type promotion rules say for
multiply, but I'd be surprised if they were different for const char
vs char, especially if the *const* version widens *more*.

Where's most of the development going on now, 3.x or 4.x? I guess I
need to buckle down and read the gcc internals docs and start
submitting patches.

--
Ben Jackson
<>http://www.ben.com/_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.orghttp://lists.nongnu.org/mailman/listinfo/avr-gcc-list

Offline

#2 Dec. 5, 2005 16:41:53

Eric W.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[avr-gcc-list] multiply by constant always expands to int


Ben Jackson wrote:Using 3.4.4 (I'm off 4.0.1 for now because I haven't had time to figure
out why all loop variables are promoted to ints) I had a strange experience
where changing:

char x = 10, y;

loop {
f(x * y);
}

got *longer* when I made it 'const char x = 10' or just hardcoded 10.
Turns out to be because mulqi was replaced with mulhi which is longer.
Now I'm not 100% sure what the integral type promotion rules say for
multiply, but I'd be surprised if they were different for const char
vs char, especially if the *const* version widens *more*.

Where's most of the development going on now, 3.x or 4.x? I guess I
need to buckle down and read the gcc internals docs and start
submitting patches.I can't say why you are seeing what you describe above. But I know thatthe vast majority of new development work (especially in the AVR port)is being done in 4.x and specifically in the GCC SVN HEAD which willbecome GCC 4.1 upon release.Björn Hasse could probably better answer your question about GCC internals.

--
Eric Weddington


_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.orghttp://lists.nongnu.org/mailman/listinfo/avr-gcc-list

Offline

#3 Dec. 6, 2005 15:21:49

Paulo M.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[avr-gcc-list] multiply by constant always expands to int


Eric Weddington wrote:I can't say why you are seeing what you describe above. But I know thatthe vast majority of new development work (especially in the AVR port)is being done in 4.x and specifically in the GCC SVN HEAD which willbecome GCC 4.1 upon release.Björn Hasse could probably better answer your question about GCC internals.I had a somewhat similar problem with gcc 4.0.2.

The following code:unsigned char a, b;
unsigned short w;

w = a * b;correctly translates into a single "mul" instruction under gcc 3.4.3(modulo the register moves) but promotes "a" and "b" to 2-byte integersunder gcc 4.0.2, generating a bunch of mul's and add's.Compiling with -mint8 and changing the "unsigned short" to "unsignedlong" is even worse as the multiply is done with an 8 bit result,explicitly zeroing the upper byte.I did checkout the latest gcc, using subversion, but since I know littleabout gcc internals, I got lost before reaching any useful conclusion.Is there any documentation (good or bad) about the gcc internals that Icould use as a starting point? Or is this a "use the source, Luke" kindof scenario? :)--
Paulo Marques
Software Development - Grupo PIE, S.A.
Phone: +351 252 290600, Fax: +351 252 290601
Web: www.grupopie.com

Pointy-Haired Boss: I don't see anything that could stand in our way.
Dilbert: Sanity? Reality? The laws of physics?


_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.orghttp://lists.nongnu.org/mailman/listinfo/avr-gcc-list

Offline

#4 Dec. 6, 2005 17:36:41

Eric W.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[avr-gcc-list] multiply by constant always expands to int


Paulo Marques wrote:I had a somewhat similar problem with gcc 4.0.2.

The following code:unsigned char a, b;
unsigned short w;

w = a * b;correctly translates into a single "mul" instruction under gcc 3.4.3(modulo the register moves) but promotes "a" and "b" to 2-byte integersunder gcc 4.0.2, generating a bunch of mul's and add's.Could you provide a complete testcase, and not just a snippet? I'mhaving a hard time reproducing what you are describing with 4.0.2.Is there any documentation (good or bad) about the gcc internals that Icould use as a starting point? Or is this a "use the source, Luke" kindof scenario? :)That's a question for the gcc mailing list. The best thing to do is tostart looking around on the GCC website and looking at all of theavailable documentation. Yes, they have an internals document. However,from what I've heard from others, it's not exactly easy to get through;it takes a lot of perserverance to learn GCC internals.--
Eric Weddington


_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.orghttp://lists.nongnu.org/mailman/listinfo/avr-gcc-list

Offline

#5 Dec. 6, 2005 19:36:23

Paulo M.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[avr-gcc-list] multiply by constant always expands to int


Eric Weddington wrote:Paulo Marques wrote:(modulo the register moves) but promotes "a" and "b" to 2-byteintegers under gcc 4.0.2, generating a bunch of mul's and add's.Could you provide a complete testcase, and not just a snippet? I'mhaving a hard time reproducing what you are describing with 4.0.2.So did I!I thought this would just happen with any multiply operation, and triedto build a simple test case, and to my surprise everything was just fine.I tried to make the simple case more and more like my real program, tono avail. I finally gave up and started the other way around, peeling ofcode from my real program until I could get the simplest possibleprogram that also showed the problem.After a lot of peeling, this is it:void test(void)
{
unsigned short data;
unsigned char a, b;

a = PORTD;
b = PORTC;

data = b * a;

OCR1A = data;

b = PORTC;

data = b * a;

OCR1B = data;
}I read/write values to ports just to make sure the compiler doesn'toptimize the values away.The weird thing is that, if you comment out the _second_ multiply, the_first_ one becomes properly compiled as a single "mul" instruction. Ifyou leave it in, then _both_ become 2 byte wide!I compiled this with today's gcc from subversion and the result is thesame. This was compiled with -Os, but I believe it happens with otherotpimization levels too.Is there any documentation (good or bad) about the gcc internals thatI could use as a starting point? Or is this a "use the source, Luke"kind of scenario? :)That's a question for the gcc mailing list.Oops, sorry.The best thing to do is tostart looking around on the GCC website and looking at all of theavailable documentation.Will do.Yes, they have an internals document. However,from what I've heard from others, it's not exactly easy to get through;it takes a lot of perserverance to learn GCC internals.Ok, thanks for all the help :)

--
Paulo Marques
Software Development Department - Grupo PIE, S.A.
Phone: +351 252 290600, Fax: +351 252 290601
Web: www.grupopie.com

Pointy-Haired Boss: I don't see anything that could stand in our way.
Dilbert: Sanity? Reality? The laws of physics?


_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.orghttp://lists.nongnu.org/mailman/listinfo/avr-gcc-list

Offline

#6 Dec. 6, 2005 21:50:05

Ben J.
Registered: 2009-11-02
Reputation: +  0  -
Profile   Send e-mail  

[avr-gcc-list] multiply by constant always expands to int


On Tue, Dec 06, 2005 at 07:33:51PM +0000, Paulo Marques wrote:
>
> I thought this would just happen with any multiply operation, and tried
> to build a simple test case, and to my surprise everything was just fine.

I just did the same thing. Turns out there are at least two things
required for my version: one of the operands has to be `const', and
you must use `-Os':

void
g(void)
{
extern char f(char);
const char y = 20;
char x, z;

z = f(x * y);
}

Turn off `const' or `-Os' and you get __mulqi3, else __mulhi3

You can probably also just move the literal '20' in for y;

--
Ben Jackson
<>http://www.ben.com/_______________________________________________
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.orghttp://lists.nongnu.org/mailman/listinfo/avr-gcc-list

Offline

  • Root
  • » AVR-GCC
  • » [avr-gcc-list] multiply by constant always expands to int [RSS Feed]

Board footer

Moderator control

Enjoy the 27th of April
PoweredBy

The Forums are managed by develissimo stuff members, if you find any issues or misplaced content please help us to fix it. Thank you! Tell us via Contact Options
Leave a Message
Welcome to Develissimo Live Support