Yes - I skipped a fair amount of the code that was in the middle of the function, since it would make the code snippet far bigger. But I've now made a test example with pretty much the same effects. The exact registers used depend on what other variables are declared, and when they are declared. This time the bit I'm looking at uses r14 rather than r15, but it is still doing so unnecessarily. The code does use r14 in the following few lines of assembly, but it could just as easily have used r7.
I get the same code as you for stand-alone lines. This is only an issue when the results of the calculation are to be held in a variable and only written out later on in the function. Extract from the attached list file: 13:t.c **** word nextMux = (mux + 1) & 0x07; 82 000a 1842 0000 mov &mux, r8 ; mux, nextMux 83 000e 0E48 mov r8, r14 ; nextMux 84 0010 1E53 add #llo(1), r14 85 0012 074E mov r14, r7 ; nextMux 86 0014 37F0 0700 and #llo(7), r7 ; nextMux mvh. David > Something is _really_ missing here. > gcc will never use registers below r12 for such a code. > > > The code will be: > > mov &muxSelect, r15 > add #llo(1), r15 > and #llo(7), r15 > mov r15, &muxSelect > ret > > However, slightly better result can be obtained if you'll write: > > muxSelect++; > muxSelect &= 0x07; > > ~d > > On Tuesday 17 December 2002 17:35, David Brown wrote: > > Hi, > > > > I am looking at the code generated for a function, and I feel there is > > often unnecessary movement of data between registers, especially r15. Is > > there some reason while small calcuations always seem to use r15? I'm > > compiling with -O2. > > > > In this particular code snippet, I have a variable "muxSelect" defined as a > > "word" (typedef for unsigned int). The code includes: > > > > void foo(void) { > > word i, j; > > word nextMux = (muxSelect + 1) & 0x07; > > > > // More code, using nextMux and muxSelect > > > > muxSelect = nextMux; > > } > > > > The "nextMux = (muxSelect + 1) & 0x07" line is compiled to: > > mov &muxSelect, r9 // Puts muxSelect in a register, as > > it will be used later > > mov r9, r15 > > add #llo(1), r15 > > mov r15, r7 // Why go through r15, and not > > just use r7 directly? > > and #llo(7), r7 > > > > I've seen this sort of thing on several occasions - r15 is used as a > > scratch register, when the original calculation could have been done > > directly in the destination register. Am I missing something here, or is > > there the possibility of optomising this more? > > > > Just for fun, I added the "-frename-registers" flag to the compile. The > > result was that r8 was used instead of r15, but basically the same code was > > produced. > > > > mvh. > > > > David > > > > > > > > > > ------------------------------------------------------- > > This sf.net email is sponsored by: > > With Great Power, Comes Great Responsibility > > Learn to use your power at OSDN's High Performance Computing Channel > > http://hpc.devchannel.org/ > > _______________________________________________ > > Mspgcc-users mailing list > > Mspgcc-users@lists.sourceforge.net > > https://lists.sourceforge.net/lists/listinfo/mspgcc-users > > > > ------------------------------------------------------- > This sf.net email is sponsored by: > With Great Power, Comes Great Responsibility > Learn to use your power at OSDN's High Performance Computing Channel > http://hpc.devchannel.org/ > _______________________________________________ > Mspgcc-users mailing list > Mspgcc-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/mspgcc-users > >
t.c
Description: Binary data
t.lst
Description: Binary data