OpenCores
no use no use 1/1 no use no use
Updating the GNU tool chain for C++
by jeremybennett on Nov 1, 2010
jeremybennett
Posts: 815
Joined: May 29, 2008
Last seen: Jun 13, 2019

In preparation for supporting C++, we've made some changes to the GNU tool chain. While mostly concerned with GCC, it has required some important changes in the linker and newlib and some smaller changes in GDB. The headlines are:

  • The linker now uses RELA format and handles ELF extensions correctly.
  • GCC for C now has just 4 regression failures when running with newlib, none of which give significant cause for concern.
  • Newlib symbol naming is now consistent and startup and termination should work correctly with C and C++.
  • GDB Or1ksim simulator now has per instruction tracing (use or32-elf-run -a -t).

We have made some ABI changes, essential to supporting C++ with multiple threads.

  • The registers are now saved at the bottom of the stack frame and may be accessed before the frame is allocated and after it is deallocated. This means that interrupt handlers should not use the first 130 bytes (all registers except r0 and sp).
  • r13 is used as a temporary in the function prologue, and r11 to hold the static chain. Neither of these were explicitly documented in the ABI.

This is work in progress. Feedback is very much appreciated.

Jeremy

--
Tel: +44 (1590) 610184
Cell: +44 (7970) 676050
SkypeID: jeremybennett
Email: jeremy.bennett@embecosm.com
Web: www.embecosm.com

RE: Updating the GNU tool chain for C++
by jeremybennett on Nov 1, 2010
jeremybennett
Posts: 815
Joined: May 29, 2008
Last seen: Jun 13, 2019

Here is some more detail on the changes made.

  • We make use of the switch to RELA by allowing separate scheduling of l.movhi and l.ori instructions when loading a symbol into a register.

  • We have new startfiles and endfiles: crti, crtbegin, crtend, crtn, to deal with constructors and destructors.

  • Structure layout has changed, instead of forcing the size of all structures to a multiple of 4 bytes, we force the alignment to two bytes for structures with a total field size of 2 bytes, and to four bytes for larger structures, with exceptions pertaining structures with alignment/packed attributes. This is handled mostly in config/or32/or32.c:or32_struct_alignment.

    The point of this is better compatibility with code that makes assumptions about the (absence of/limitations of) structure padding, including part of the libstdc++-v3 library.

    The performance impact of the lessened alignment for arrays of small structures is reduced by aligning array objects allocated on the stack or statically to a minimum of 2 bytes for byte sizes of up to 3, and to a minimum of 4 bytes for larger arrays.

  • Frame pointer elimination is now implemented and enabled by default. Because of the broken frame pointer handling of the old compiler, functions compiled with the old compiler which access the frame will invoke undefined behaviour when called (directly or via a (chain of) other functions compiled with the old compiler) from a function with frame pointer elimination active.

  • When the frame pointer is not eliminated, the prologue copies the stack pointer to the frame pointer, and the epilogue restores the stack pointer from the frame pointer. That should allow builtin alloca to work in non-leaf functions without crashes.

  • Since we are outputting prologues/epilogues as RTL, the DWARF unwind information is emitted by the generic code to handle RTL prologues/epilogues, after scheduling takes place. That means you'll likely see unwind information that is a bit different in detail.

  • Sibcall optimization (a restricted type of tail call optimization) is enabled by default when optimizing, hence you might see abbreviated backtraces.

  • We avoid clobbering r12 in nested function trampolines.

Feedback appreciated.

Jeremy

RE: Updating the GNU tool chain for C++
by rfajardo on Mar 21, 2011
rfajardo
Posts: 306
Joined: Jun 12, 2008
Last seen: Jan 6, 2020
Hi Jeremy,

thanks for this information. I wanted to share with you my updates on interrupt handling.

I used to free 116 bytes for interrupt handling to store 29 registers: r3-r31
r0 is hardwired to 0
r1 is the stack pointer (managed)
r2 is the frame pointer (does not change on call? managed by compiler? has to possibly be stored?)

Now I wanted to leave additional 130 bytes, because a function can access the stack frame of a created one. In doing so, I noticed that simply freeing 246 bytes lead to problems. I assume that is due to non-alignment of the stack pointer. I'm freeing 244 instead, which happens to be 128 bytes (32 registers x 4 bytes) plus the usual 29 ones.

That is working just fine.

Regards,
Raul
no use no use 1/1 no use no use
© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.