Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get GCC to place a C++ constexpr in ROM?

I compile for LPC1114, a small ARM (actually Cortex) target. RAM is much more limited than ROM. I use the latest Mentor (CodeBenchLite) GCC compiler (GCC 4.6.3). I have some constant objects that I'd like to have in ROM. As far as I understand the ffx object in the code below should end up in ROM (code), but instead it is placed in DATA.

class flop {
    public:
       int x;
       constexpr flop( int x ) : x(x){}
};

 extern constexpr flop ffx( 1 );

How can I convince the compiler to pre-compute the object and place it in ROM?

or maybe I should ask:

  • can I somehow expect the G++ compiler to generate ROMable data for ffx
  • if so, is my code correct for this
  • if so, for which G++ version is this supported (I use 4.6, maybe I need 4.7?)

=======================================

This bugzilla entry c++/49673 seems to indicate that mine is a known problem, probably fixed in GCC 4.7. Unfortunately I prefer to use the Mentor/CodeSourcery built, which is still at 4.6.3. So I guess for the time being I am stuck with the bug. :(

like image 290
Wouter van Ooijen Avatar asked Jun 11 '12 14:06

Wouter van Ooijen


1 Answers

Update #2: Test results with gcc 4.7.0

This is indeed fixed in gcc 4.7.0. Your code produces the following assembler output:

    .file   "constexpr.cpp"
    .globl  _ffx
    .section .rdata,"dr"
    .align 4
_ffx:
    .long   1

which is what you probably want. Upgrading?

I think you need a platform specific solution for this. See Locating code and data in memory (Scatterloading):

Scatterloading allows you to partition an application into a number of separate code and data regions spread throughout the address map. The location of these regions can differ between load time and run time:

  1. Load Regions contain application code and/or data used by the application at power-on/load time (typically ROM).

Instead of relying on gcc alone, try to make use of armlink as suggested in the link provided above.

Update: I saw the gcc bug you've noted. LLVM/MinGW is equally hopeless. However, I've been playing around with GCC 4.6 and here's something I think may help you:

struct Data
{
    int i;    
};
constexpr Data getData() { return Data{1}; }

If instead of having a ctor, you have a constexpr function, and try to generate the assembler output, the output will typically be empty (no .data sections). And if you use this to initialize some variable (in global scope) as below:

const Data foo = getData();

you'd get an assembly as follows:

    .file   "constexpr.cpp"
    .section .rdata,"dr"
    .align 4
__ZL3foo:
    .long   1

(this is with g++ -std=c++0x -S command line). Does that work for you?

like image 185
dirkgently Avatar answered Oct 02 '22 03:10

dirkgently