Code generation problem with -mcall-prologues

Go To Last Post
32 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, all!

I'm a couple months or more into the development of an atmega324-based product, and happened across what I think is a compiler bug of a very subtle and insidious kind.

Some weeks ago, I added a "-mcall-prologues" switch to my compiler invocations, because I'm more concerned with overall codesize than execution speed, in most places. There is one aspect of the product where I'm maniacally interested in speed, though: a pair of ISRs that implement software I2C slave communications. To make them as fast as possible, they're constructed to depend on three permanently dedicated processor registers: R3, R4, and R5.

In the early stages of the project, I'd sift through the generated .lss files with a text editor to reassure myself that the generated code hadn't used any of these registers, and for quite awhile, it didn't. I've lately begun to use floating-point operations, though, and I soon saw that some of the larger routines pressed R3..R5 into service.

At that point, I grudgingly applied the remedy described by FAQ item #3 from WinAVR's installed on-line help docs: ("How to permanently bind a variable to a register?"). I set up a header file that permanently bound R3..R5 to some dummy variables, and then ensured that every source module included that header. Doing that kept even those "larger routines" from using any of my ISR-dedicated registers, or so I thought.

Today, though, I did another "sifting" inspection of my overall generated .lss file (mindful that I haven't guaranteed that the code from the external library archives I'm using - mathlib.a, etc. - abide by my rules), and found a place where R5 was used. It wasn't used by any of the library code, though; it was used by the code generated for *my* source, despite its prohibition against the use of R3..R5.

The error was that for one of my routines, the called prologue/epilogue pair "saved" and "restored" register R5, even though R5 was used nowhere within the body of the routine itself (or anywhere else in the .lss file, for that matter). In a "single-threading" execution environment, the only harm done would be squandering four machine cycles (and who'd notice?), but when the ISR depends upon being able to find the value it put in R5 midway through the execution of the bugged subroutine still there after the bugged subroutine exits, there would eventually be (as Robocop would say) ...trouble.

If you unpack the files from my test-case archive into a test folder and "make" them, you should see the problem manifest at address 0x448 in the resultant "Test.lss" listing file:

            break;
        }
    }
} 
 442:	cd b7       	in	r28, 0x3d	; 61
 444:	de b7       	in	r29, 0x3e	; 62
 446:	ef e0       	ldi	r30, 0x0F	; 15
 448:	0c 94 74 04 	jmp	0x8e8	; 0x8e8 <__epilogue_restores__+0x6>

Here is the beginning of the stock "epilogue" sequence:

000008e2 <__epilogue_restores__>:
 8e2:	2a 88       	ldd	r2, Y+18	; 0x12
 8e4:	39 88       	ldd	r3, Y+17	; 0x11
 8e6:	48 88       	ldd	r4, Y+16	; 0x10
 8e8:	5f 84       	ldd	r5, Y+15	; 0x0f
 8ea:	6e 84       	ldd	r6, Y+14	; 0x0e

I apologize for not making any effort to find the "minimum test case" that still exhibits the problem. Because I'd only expect it to manifest when the compiler is stressed for lots of local variables, I was pretty sure it wouldn't show up for a purely trivial program, and it was hard enough just severing all the ties to other modules so this would compile.

Here's an copy of some relevant output from my run of "make":

-------- begin --------
avr-gcc.exe (WinAVR 20100110) 4.3.3

Compiling: setColor.cpp
avr-gcc.exe -c -mcall-prologues -mmcu=atmega324a -Wall -gdwarf-2 -msize -Os -funsigned-char -funsigned-bitfields -fshort-enums -I.  -DF_CPU=20000000UL -MD -MP -MT setColor.o -MF dep/setColor.o.d setColor.cpp -o setColor.o

I don't expect any fixes for the problem, but I thought I would share it here, since it would be an absolute horror to track down from a "why is the application acting so funny every once in a blue moon?" standpoint.

I guess I'll just stop using the "-mcall-prologues" switch.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's not a compiler bug, your application is bogus.

Using global register by, say, -ffixed-3 with all modules to globally reserve R3 for your own progranm, you must ensure that you don't link against any module/library/startup code that use that GPR in a way that shreds your code or reserve a register that the compiler will always need like R0, R1 or R8..R30 because they are needed by the ABI.

Now, by specifying -mcall-prologues, you say "please link in the routine __prologue_saves__ from libgcc" which reads

push r2
push r3
...

Inventing global or local register vars or inline assembly you must know exactly what you are doing or the compiler will bite you. Thus, either write completely in assembly or write in C+assembly and grep on final list file to ensure that no code uses your GPRs.

Note that the compiler won't adapt the ABI by magic, i.e. if you take away R24 from the compiler it won't allocate that GPR for an auto but it will still use it to pass values to functions or get return values. Similar if you use division routines or stuff from avr-libc which had been compiled without your switches.

For the cases I came across, global register variables just lead to marginal performance gain. Factor out the modules where you need speed and compile them with -O2 or do them in (inline) assembler.

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SprinterSB wrote:
It's not a compiler bug, your application is bogus.

If I may take the liberty of opposing your views, the compiler is indeed misbehaving. Yes, I'm very well aware that the giant callable prologue and epilogue routines, which come from some library somewhere, include instructions for saving and restoring EVERY processor register except R0 and R1. That's perfectly understandable, and acceptable, so long as the compiler doesn't generate jump statements into the sections of those prologues and epilogues that involve the regsiters I want reserved. That's what it's done, however. The code it generated for my "implementColor()" subroutine saved and restored (via selected jumpings into the prologue/epilogue sequences) register R5, which was one of the three registers I had declared to be reserved. And this despite not having used R5 for anything during the course of that routine! Even if R5 *hadn't* been reserved, the compiler shouldn't have saved/restored it.

And, subsequent to my OP, I had better success with the Forums' "search" function, and did find your mentions of the '-ffixed-rN' commandline switch in other threads. Using a compiler switch feels way better than including a bunch of 'register char xyz asm("rN")' statements anyway; I only did the asm stuff because that's what the WinAVR online help docs told me to do. I've since removed the "globalRegs.h" #includes and rebuilt everything with "-ffixed-.." compiler switches. The resultant code turned out exactly the same, though.

SprinterSB wrote:

Using global register by, say, -ffixed-3 with all modules to globally reserve R3 for your own progranm, you must ensure that you don't link against any module/library/startup code that use that GPR in a way that shreds your code or reserve a register that the compiler will always need like R0, R1 or R8..R30 because they are needed by the ABI.
So I did well, then, to read that advice from the WinAVR docs, and pick R3, R4, and R5.

SprinterSB wrote:
Inventing global or local register vars or inline assembly you must know exactly what you are doing or the compiler will bite you. Thus, either write completely in assembly or write in C+assembly and grep on final list file to ensure that no code uses your GPRs.

Yes, I'm aware of the risks and concerns. And, as I mentioned in my OP, I already am routinely checking the final linked object to verify that the library code I've pulled in hasn't used any of my global regs. That was, as I said, how I noticed the compiler's bug in the first place.

SprinterSB wrote:

Note that the compiler won't adapt the ABI by magic, i.e. if you take away R24 from the compiler it won't allocate that GPR for an auto but it will still use it to pass values to functions or get return values.
I hadn't known that about the argument-passing behavior; thanks. I don't think there's much chance of my writing a function with such a horribly designed interface that it would need to use R10, let alone R5, though.
SprinterSB wrote:

For the cases I came across, global register variables just lead to marginal performance gain. Factor out the modules where you need speed and compile them with -O2 or do them in (inline) assembler.
So what does it take to be NON-marginal gain for you? TWO orders of magnitude?

The registers are used by a pair of ISRs, which are provided from a module written entirely in assembler.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Levenkay wrote:
SprinterSB wrote:
It's not a compiler bug, your application is bogus.

If I may take the liberty of opposing your views, the compiler is indeed misbehaving.

http://www.nongnu.org/avr-libc/u...

Quote:
Extreme care should be taken that the entire application is compiled with a consistent set of register-allocated variables, including possibly used library functions.

I'm in total agreement with Johann (SprinterSB). If you're going to do something like take away registers from the compiler (and "implementation" which includes the library) for your own specific purposes, then you need to be aware of the consequences. You just ran into one of the consequences.

The only recourse you have is to not use that switch, or don't bind C variables to specific registers. If you need speed, then I suggest you write the relevant code in assembly and free up the registers for the compiler to work with.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Levenkay wrote:
Yes, I'm very well aware that the giant callable prologue and epilogue routines, which come from some library somewhere, include instructions for saving and restoring EVERY processor register except R0 and R1. That's perfectly understandable, and acceptable, so long as the compiler doesn't generate jump statements into the sections of those prologues and epilogues that involve the regsiters I want reserved. That's what it's done, however.
With call-prologues, the compiler saves a sequence of registers, so if you have R3-R5 global and these registers are covered by the sequence it's presumably because the compiler allocates R2. Thus, one fix for you might be to omit -mcall-prologues and another one might be to allocate R2 by -ffixed-2, too. Notice that you need these switches for every module; even for the ones that don't use the(se) global register(s).

In the case you want to file a bug report, please follow the instructions in http://gcc.gnu.org/bugs/#need In particular, don't post a zip-file or source file with external includes and a source that acually compiles (don't need to link). You can also mention that avr.c:sequent_regs_live() is the function to be extended i.e. to take care of global register variables.

Quote:
The code it generated for my "implementColor()" subroutine saved and restored (via selected jumpings into the prologue/epilogue sequences) register R5, which was one of the three registers I had declared to be reserved. And this despite not having used R5 for anything during the course of that routine! Even if R5 *hadn't* been reserved, the compiler shouldn't have saved/restored it.
If R5 is unused and the compiler saves it, then it's because of your assumption that call-prologues leads to smaller code. If there were prologue-call/epilogue-saves routines for each register allocation scenario, the code would be much bigger.

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

EW wrote:
I'm in total agreement with Johann (SprinterSB). If you're going to do something like take away registers from the compiler (and "implementation" which includes the library) for your own specific purposes, then you need to be aware of the consequences. You just ran into one of the consequences.

The only recourse you have is to not use that switch, or don't bind C variables to specific registers. If you need speed, then I suggest you write the relevant code in assembly and free up the registers for the compiler to work with.

I can tell that the horse is dead, so I'll stop. As I said in the OP, I've already ceased using the -mcall-prologues switch. And it isn't that I want C variables bound to specific registers; all I want is for none of the generated code to touch a short list of registers that I want to dedicate to the sole use of some assembler ISR code. The variable-to-register binding was just the first means to that end that my feeble searching of the WinAVR FAQ turned up. SprinterSB's '-ffixed-rNN' switches seem way better, and that's what I'm using now.

For the amusement of the bystanders, though, I'll briefly outline the thinking that led to the OP:

    -mcall-prologues provide an alternate way for the compiler to save and restore the registers needed by subroutine implementations.

    Without -mcall-prologues, the compiler comes up with the correct sequence of inline pushes and pops to preserve just the registers my routine actually uses.

    So why does it decide to save/restore an extra register (unfortunately, one of the three I want preserved) just because it gets to use a more compact mechanism?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As the source of AVR-LibC is online you could copy the source for any components (including the CRT) to your project, use them to replace the system libs and build any C with -ffixed and hnd massage any .S to avoid using your chosen registers.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SprinterSB wrote:
With call-prologues, the compiler saves a sequence of registers, so if you have R3-R5 global and these registers are covered by the sequence it's presumably because the compiler allocates R2.
That would be the conclusion, all right, reasoning from the premise that the compiler never makes any mistakes (usually, a good one :wink: ).
The sequence is arranged to allow any consecutive set of registers ending with R29, in order. You can save/restore just R29, or R28,R29, or R27..29, or R26..29, and so on, up to the sequence of R2..R29. Yes, if it thought it needed R2, R3, or R4, it would have of course saved R5 as well. But then, it should have jumped to the _prologue_saves entry that saved R2, R3, or R4, and to the _epilogue_restores entry for fetching R4, R3, and R2 back again, which it did not do.
SprinterSB wrote:
Thus, one fix for you might be to omit -mcall-prologues and another one might be to allocate R2 by -ffixed-2, too. Notice that you need these switches for every module; even for the ones that don't use the(se) global register(s).
NONE of my compiled modules use the globals, and I have changed over to using -ffixed. Adding R2 to the "-ffixed" list didn't correct the problem I'm experiencing, BTW.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
As the source of AVR-LibC is online you could copy the source for any components (including the CRT) to your project, use them to replace the system libs and build any C with -ffixed and hnd massage any .S to avoid using your chosen registers.
OK, let me consult my map; I'm pretty sure this is "you don't want to be here" territory. I might conceivably be driven to that extreme, but for now I'm going to just inspect the final generated result.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If the problem is that avr-gcc saves and restores R3, R4 and R5 because it has to save R2,
an obvious solution is to reserve R2, R3 and R4, giving R5 back to the compiler.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The lowest-indexed register used by the body of the subroutine in question is R6. Neither R2, R3, R4, or R5 are used (except for the unwanted save/restore of R5).

And I tried reserving R2 as well, with no effect on the problem.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It won't help to use -nostartfiles or to link against you own, private versions of libgcc or avr-libc because the compiler issues the call to __prologue_saves__ + offset and own implementations won't fix that offset. You just hit a place where very few developers hang around. Without -mcall-prologues, the compiler treats global regs (no matter if defined by binding a variable to a register or by means of -ffixed) specially: It won't save or restore them. With call-prologues, however, the compiler does not treat global registers specially and thus just cares for the liveness of that GPR.

This means that you don't want to use call-prologues with global registers resp. -ffixed or/and want to file a bug report and wait until it's fixed in 4.6/4.7.

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Filed as PR50289.

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

> Filed as PR50289.

Fixed in 4.6.2+

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SprinterSB wrote:
> Filed as PR50289.

Fixed in 4.6.2+

That was fast, but is it sufficient?
The problem described in the PR is significantly different from that described by OP:
Levenkay wrote:
NONE of my compiled modules use the globals, and I have changed over to using -ffixed. Adding R2 to the "-ffixed" list didn't correct the problem I'm experiencing, BTW.
The original list was R3, R4, R5.
In the PR, the problem register was indexed between registers that needed saving.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
The problem described in the PR is significantly different from that described by OP.
It's hard to tell from all the prose in the OP and admitting that I am reluctant to dig archives and put puzzles together.

Anyway, the compiler source revealed a flaw around call-prologues + global regs which could easily be made explicit by handfull lines of code and looked as if it could trigger the artifact described by the OP — and that is what I fixed.

Even if there was a test case by the OP it's hard to tell if a newer compiler version would show the issue because of other optimizations, register allcator etc.

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SprinterSB wrote:
skeeve wrote:
The problem described in the PR is significantly different from that described by OP.
It's hard to tell from all the prose in the OP and admitting that I am reluctant to dig archives and put puzzles together.
That was why I added a bit more:
skeeve wrote:
The problem described in the PR is significantly different from that described by OP:
Levenkay wrote:
NONE of my compiled modules use the globals, and I have changed over to using -ffixed. Adding R2 to the "-ffixed" list didn't correct the problem I'm experiencing, BTW.

The original list was R3, R4, R5.
In the PR, the problem register was indexed between registers that needed saving.
Quote:
Anyway, the compiler source revealed a flaw around call-prologues + global regs which could easily be made explicit by handfull lines of code and looked as if it could trigger the artifact described by the OP — and that is what I fixed.

Even if there was a test case by the OP it's hard to tell if a newer compiler version would show the issue because of other optimizations, register allcator etc.

Perhaps I should have written "That was fast and useful, but is it sufficient?"

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
Perhaps I should have written "That was fast and useful, but is it sufficient?"
I claim yes. So you have to find a counterexample :P

I guess it's not that easy to find one because the sources look clean after the patch.

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SprinterSB wrote:
skeeve wrote:
Perhaps I should have written "That was fast and useful, but is it sufficient?"
I claim yes. So you have to find a counterexample :P

I guess it's not that easy to find one because the sources look clean after the patch.

Has it been tested on OP's code?

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you like more tests, please add respective attachement to PR50289 following http://gcc.gnu.org/bugs/#need

I will have a look then as soon as I have time.

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Johann,

I have a related question/request. There are some values output during compilation in form of comments in asm (which then propagate to the asm listing) for each function, presently it is the stack frame size and total stack size (stack frame plus pushed registers), in past versions (<= 2007) it was also the function size in bytes. Could we have more of such, e.g. the register usage (perhaps as a bitmap), or stack usage at the moment of a function call, for writing simple post-compilation analysis tools?

I know I should throw this up in the avr-gcc mailing list, but that's such a cold and unfriendly place... :-)

Jan

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jan,

Just checking: but you use -fverbose-asm right?

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No, I use -Wa,-adhlns=filename.lst as per mfile, but the comments are same as when you use plain -S.

JW

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I just use --save-temps. It's then easy to use/not use -fverbose-asm and see the effect it has. It annotates the register usage with internal variable naming from the code generator which can make it easier to follow what's going on but can also cause a lot of "noise" making the files trickier to read.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You don't need -fverbose-asm to find out the register usage, but it would take a relatively complex parser (in effect equivalent to the assembler's parser) to decipher it, while it's probably very simple to find out during compilation (maybe I am wrong - I am not insider) and output it as a single number (bitmap) once per function.

My second request cannot be fulfilled simply by postprocessing, but again the compiler supposedly knows how many registers it did save on the stack before call. That would facilitate a simplistic an inperfect stack usage calculator.

JW

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

wek wrote:

I know I should throw this up in the avr-gcc mailing list, but that's such a cold and unfriendly place... :-)

:lol:

I think that avr-gcc is more *quiet* than cold and unfriendly...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

wek wrote:
Johann,

I have a related question/request. There are some values output during compilation in form of comments in asm (which then propagate to the asm listing) for each function, presently it is the stack frame size and total stack size (stack frame plus pushed registers), in past versions (<= 2007) it was also the function size in bytes.

You can get function/object size with avr-nm -S, the compiler does not know the size of insns (instruction groups). For example,
avr-gcc-4.6.1 -Os -dp
char foo (unsigned char a, unsigned char b)
{
    return a << b;
}

yields

foo:
/* prologue: function */
/* frame size = 0 */
/* stack size = 0 */
.L__stack_usage = 0
	ldi r25,lo8(0)	 ;  25	*movqi/1	[length = 1]
	rjmp 2f	 ;  9	ashlhi3/1	[length = 6]
1:	lsl r24
	rol r25
2:	dec r22
	brpl 1b
/* epilogue start */
	ret	 ;  28	return	[length = 1]

i.e. the ashlhi3 insn is reported with 6 words. R22 is dead after the insn and thus need not to be moved to R0 which then would cost actually 6. The compiler just tracks an upper bound for the size in order to emit correct relative jumps. If possible, the exact insn lengths are worked out, but that's not the case for every insn; would be too tedious.

Moreover, compiler does not know length of inline assembler; is makes assumptions on it's length by counting line breaks in order to branch across.

wek wrote:
Could we have more of such, e.g. the register usage (perhaps as a bitmap), or stack usage at the moment of a function call, for writing simple post-compilation analysis tools?
For stack it's up to the gcc proper to keep track of SP. There is an option for it; don't remind it's exact name and when stack analysis was added. You will have to browse documentation/release notes/compiler switches.

For the register usage the compiler just knows if a register might be used, e.g. if a black-box call does not change a register, the compiler will assume it's changed, anyway (call-used) or not changed (call-saved). A register is used if it's touched, i.e. in CPSE R2,R3 both R2 and R3 will be reported as used.

It's not possible to report usage information for fixed registers. I'd report a user-fixed register (-ffixed, global reg) as never used and R0/R1 as always used. As that's redundant, I'd prefer not to mention them. To do that analysis in the compiler would require much work and perhaps even an extra pass which would contradict text peepholes. However, avr BE relies on text peepholes; they cannot be transformed to RTL peepholes without getting inferior code.

Same as above, the compiler does not know the usage of registers in inline assembler except the inline assembler itself is correct (using proper constraints and clobber lists).

To print such a list I'd very much prefer human readable output like R8-R25,R28,R29 over encypted representation.

For a parser, you might have a look at the avrtest simulator sources. They are easy to read and to modify to get a tool to analyze register footprint, much exacter than avr-gcc's would be and no matter if you use assembler or not and correct for R0/R1 and T-flag (whith the compiler threats the same way as R0).

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SprinterSB wrote:
You can get function/object size with avr-nm -S, the compiler does not know the size of insns (instruction groups).
I understand, thanks for explanation. Don't get me wrong, I don't cry back the "function size", just mentioned as an example of what the compiler (used to) tell in the comments.

SprinterSB wrote:
wek wrote:
Could we have more of such, e.g. the register usage (perhaps as a bitmap), or stack usage at the moment of a function call, for writing simple post-compilation analysis tools?
For stack it's up to the gcc proper to keep track of SP. There is an option for it; don't remind it's exact name and when stack analysis was added. You will have to browse documentation/release notes/compiler switches.
I don't understand. What do you mean by "keep track of SP" and how does that demonstrate itself?

Is outputting the size of extra stack used for parameters by each function call as I suggested above too complicated to implement?

SprinterSB wrote:
A register is used if it's touched, i.e. in CPSE R2,R3 both R2 and R3 will be reported as used.

I'd be interested in a summary of the "net" register usage of the whole function, i.e. ignoring the usage of registers in called functions and inline assembler; the "touched" is okay with me. The reason is to find out potential collisions with fixed registers which are to be used in assembler routines, so I would prefer if the fixed (which then would not be used in C routines) would be omitted from the list. Any form is okay with me; human readable is harder to parse but it's true that it is of more use generally.

Again, all this makes sense only if it is easy to do.

SprinterSB wrote:
For a parser, you might have a look at the avrtest simulator sources.
Thanks for the suggestion. For now, I prefer my quick and dirty ways. Besides, the post-translation analysis would be plagued by loss of information eg. function with inline assembler using a fixed register (which is intended and okay) is indistinguishable from function where C uses that register inadvertently (which is the unwanted event which is to be detected).

Thanks,

Jan

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Use -fstack-usage and gcc will generate a .su file reporting stack usage.

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Use -fstack-usage and gcc will generate a .su file reporting stack usage.

Wow, nice feature - do you know at which version that was added?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Quote:

Use -fstack-usage and gcc will generate a .su file reporting stack usage.

Wow, nice feature - do you know at which version that was added?
Google told me this:
http://gcc.gnu.org/gcc-4.6/chang...

So Johann's 4.6.1 binaries should be able to do that. [eager smiley]

I am not at a computer with avr-gcc now to try :-(

Jan

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

wek wrote:
So Johann's 4.6.1 binaries for Win32 should be able to do that.
Notice that 4.6.1 comes with some bugs that are closed in 4.6.2:

PR50289, PR49764, PR49487, PR46779, PR34734, PR44643, PR39633, PR39386.

avrfreaks does not support Opera. Profile inactive.