Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
12612 Discussions

Nios Compiler Bug - Any Workarounds

Altera_Forum
Honored Contributor II
1,631 Views

I have run into a bug with the version of GCC supplied with the Nios v3.02 development kit (2.9-nios-010801-20030520) when compiling with for 32 bit Nios (compiler flags -O0 -m32 -mflat). If I write a simple small function, like the following trivial example 

int Test_With_Bug (int arg)  {    if (arg < 0)        return (-1);    return (1);  } 

the compiler will sometimes apply the leaf procedure optimization and omit the creation of a stack frame in the prolog (so the routine uses the callers stack frame). Unfortunately, the compiler doesn&#39;t omit the prolog code that saves the function arguments to the stack frame. Since the function is using the callers stack frame, this trashes the saved values of the caller&#39;s arguments, producing some surprising results! 

 

Does anyone know of a compiler option or version upgrage which will prevent GCC from producing code like this? 

 

As a workaround I can prevent GCC from applying this optimization to any particular function by adding a call to an external routine that does nothing. The trick is finding all the routines that might be affected by the bug.
0 Kudos
10 Replies
Altera_Forum
Honored Contributor II
778 Views

First I&#39;d ask if you could try Nios 3.2.  

I couldn&#39;t find a specific bug report on this. But that doesn&#39;t mean it didn&#39;t get fixed. Or that it wasn&#39;t filed, just not with a title that said mflat... 

 

Any chance you can upgrade to Nios II?
0 Kudos
Altera_Forum
Honored Contributor II
778 Views

I don&#39;t have a copy of Nios v3.2 kit handy - does it include a newer version of GCC? 

 

The bug does seem to be related to the -mflat option (avoid use of save/restore), since code compiled without the -mflat option always generates a stack frame using save and restore instructions. This is probably the root of the problem: the rest of the Nios specific code generation (mostly of which probably predates the -mflat option) likely assumes routines always have their own stack frame. 

 

Not using the -mflat option would be very difficult, as it would completely change what we need to do to save task context in our real time executive (need to save all register windows used by a task, not just current one).  

 

Moving to the Nios II might be a possibility, but it would mean re-writing some low level assembler code (the real-time executive context switching) and re-writing some of the hardware interface code. 

 

Does anyone know if the newer version of GCC included in the NiosII development kits is also capable of generating code for Nios, or does it only support the new NiosII target?
0 Kudos
Altera_Forum
Honored Contributor II
778 Views

the new Nios II GCC only supports Nios II. But Nios 3.1 had a newer GCC, 3.2 had no changes. 

So, if you just upgrade to 3.1 you&#39;d have a newer GCC. 

 

Does that help?
0 Kudos
Altera_Forum
Honored Contributor II
778 Views

Another Nios II point: you get a flat 32 register file to start out with -- none of this -mflat business exists (although admittedly the -mflat option was added for Nios I users such as yourself doing RTOS-like things!). And yes, the new GCC version with Nios II only supports Nios II.

0 Kudos
Altera_Forum
Honored Contributor II
778 Views

Our client is actually responsible for designing the FPGA image (which includes some custom IP in addition to the Nios core), so I&#39;ll have to speak to them about the possibility of using the NiosII. 

 

It would mean rewriting a few things, but the NiosII seems to have a better instructions for IO with peripherals (8, 16 and 32 bit reads and writes), and as you point out, it only offers the flat register model (so presumbably the compiler is more thoroughly tested). The debugging support for the NiosII sounds a lot better too. 

 

Does the NiosII work with APEX devices? All the references I found on Altera&#39;s web site about NiosII only mentioned Stratix and Cyclone devices.
0 Kudos
Altera_Forum
Honored Contributor II
778 Views

Nios II only supports Stratix families and Cyclone families at this time. Other device families will be supported as they are created. But APEX is not supported. Sorry.

0 Kudos
Altera_Forum
Honored Contributor II
778 Views

Ok, thanks for the info. I&#39;ll have to pursue a bug fix for the Nios compiler (or at least a script to detect occurences so I can modify the sources to prevent the bug from occuring).

0 Kudos
Altera_Forum
Honored Contributor II
778 Views

Our client had the GCC version from the Nios 3.1 package installed (nios-elf-gcc -v reports version 2.9-nios-010801-20030718). Compiling the example code with this version produced the same result as the version I had: the bug is still present.

0 Kudos
Altera_Forum
Honored Contributor II
778 Views

To get around this with the most recent release of nios-elf-gcc, use the -mdebug-stack option. In the resulting output, look for functions with stack_info.saves = 0. These are the ones to modify. 

 

nios-elf-gcc options -mdebug-stack rest of command >& out
0 Kudos
Altera_Forum
Honored Contributor II
778 Views

The workaround posted by kerry, matches a suggestion from Stephen O&#39;Reilly at Altera I received via e-mail. Namely use the GCC stack debug option 

 

nios-elf-gcc options -mdebug-stack rest of command >& out 

 

and looking for lines in the resulting output with stack_info.saves = 0. This will find routines where the stack frame is omitted. However, omitting the stack frame only causes a problem if the compiler also attempts to save to the parent stack frame using the fp register, in which case stack_info.fp_save will be non-zero. So you really want to look for both conditions. 

 

For now, I&#39;m sticking with my AWK script that parses the assembly language output since it seems to be working fine and it runs automatically as part of my builds. 

 

The -mdebug_stack output does suggest the root of the problem though. The output for a leaf function with one argument that exhibits the bug shows 

Registers to save         stack_info.locals = 0    bytes, 0   words     stack_info.fp_save = 4    bytes, 1   words        stack_info.saves = 0    bytes, 0   words          stack_info.args = 24   bytes, 6   words           stack_info.cwp = 64   bytes, 16  words  stack_info.aggregate = 4    bytes, 1   words                       TOTAL = 96   bytes, 24  words 

In other words, GCC thinks it HAS allocated 23 words on the stack (args, cwp and aggregate). It looks like the Nios specific back-end is just omitting the code to allocate the stack frame in this case, rather than telling the GCC front end not to generate it.
0 Kudos
Reply