EmbeddedRelated.com
Forums

How to force the C-compiler to use registers? [ND-Cerberus checked]

Started by reym...@... May 25, 2004
Dear all,

I've been wondering for a while how to avoid this enormous waste of mem
I presently have in the code generated from my program.

The problem I have consists of a rather complex digital logic with very
simple algorithms.  In other words, the program is a huge bunch of if()'s
with
very little maths.
I tried to write it as modular as I could and as a result I need many
static
and global variables keeping flags and states.
Of course the compiler puts them all into normal mem.

On the other hand due to the little amount of maths in the code I rarely
need registers.  Actually R5 ... R 11 are never ever used.

Consequently, if writing assembly, I would simply put some of my
variables into these registers.  This saves ram, and even more
important, it saves code space, which I have very few on my 'F1101.
Unfortunately I cannot see a possibility to get this out if the C-compiler.

Since all this was a little abstract, now for something more practical...
Imagine some code like this:


--------------------
unsigned char Var;

main()
{
    SomeInitialization();
    while (1)
        {
        P1OUT=Var;
        if ( Var == 0x0F )
            Var = 0 ;
        }
}

#pragma vector=PORT1_VECTOR
__interrupt void Func1(void)
{
    Var |=0x01;
}

#pragma vector=PORT2_VECTOR
__interrupt void Func1(void)
{
    Var |=0x02;
}

#pragma vector=TIMERA1_VECTOR
__interrupt void Func1(void)
{
    Var |=0x04;
}

#pragma vector=TIMERA2_VECTOR
__interrupt void Func1(void)
{
    Var |=0x08;
}

--------------------

Here you can easily imagine, that each access to Var wastes 2 Bytes of mem
compared
to if it was in a register.
As I wrote earlier there are 7 registers which are potentially usable for
globals and maybe
6 different accesses for each of these variables.
7 times 6 times 2 is        84       Bytes of wasted mem, which again is
more than 8 percent of
the entire mem available.

This again, in my opinion, is definitely too much.

So, has anyone got a smart idea how to get out of this?


Regards,
Dirk



Beginning Microcontrollers with the MSP430

--- In msp430@msp4..., reymannd@s... wrote:

> So, has anyone got a smart idea how to get out of
this?

I believe that some of the MSP430 compilers allow the user to
specifically reserve one or more registers for the user, and the
compiler won't touch them.

If your compiler can do this, then why not just write your own
assembly to implement what you want, using the reserved register(s)?

I've written assembly for all the MSP430 compilers (save mspgcc) --
it's pretty easy, nothing to be afraid of.

--Andrew


Yes. It's so simple code it in asm.

Al

reymannd@reym... wrote:

> Dear all,
> 
> I've been wondering for a while how to avoid this enormous waste of
mem
> I presently have in the code generated from my program.
> 
> The problem I have consists of a rather complex digital logic with very
> simple algorithms.  In other words, the program is a huge bunch of
if()'s
> with
> very little maths.
> I tried to write it as modular as I could and as a result I need many
> static
> and global variables keeping flags and states.
> Of course the compiler puts them all into normal mem.
> 
> On the other hand due to the little amount of maths in the code I rarely
> need registers.  Actually R5 ... R 11 are never ever used.
> 
> Consequently, if writing assembly, I would simply put some of my
> variables into these registers.  This saves ram, and even more
> important, it saves code space, which I have very few on my 'F1101.
> Unfortunately I cannot see a possibility to get this out if the C-compiler.
> 
> Since all this was a little abstract, now for something more practical...
> Imagine some code like this:
> 
> 
> --------------------
> unsigned char Var;
> 
> main()
> {
>     SomeInitialization();
>     while (1)
>         {
>         P1OUT=Var;
>         if ( Var == 0x0F )
>             Var = 0 ;
>         }
> }
> 
> #pragma vector=PORT1_VECTOR
> __interrupt void Func1(void)
> {
>     Var |=0x01;
> }
> 
> #pragma vector=PORT2_VECTOR
> __interrupt void Func1(void)
> {
>     Var |=0x02;
> }
> 
> #pragma vector=TIMERA1_VECTOR
> __interrupt void Func1(void)
> {
>     Var |=0x04;
> }
> 
> #pragma vector=TIMERA2_VECTOR
> __interrupt void Func1(void)
> {
>     Var |=0x08;
> }
> 
> --------------------
> 
> Here you can easily imagine, that each access to Var wastes 2 Bytes of mem
> compared
> to if it was in a register.
> As I wrote earlier there are 7 registers which are potentially usable for
> globals and maybe
> 6 different accesses for each of these variables.
> 7 times 6 times 2 is        84       Bytes of wasted mem, which again is
> more than 8 percent of
> the entire mem available.
> 
> This again, in my opinion, is definitely too much.
> 
> So, has anyone got a smart idea how to get out of this?
> 
> 
> Regards,
> Dirk
> 
> 
> 
> 
> 
> .
> 
>  
> Yahoo! Groups Links
> 
> 
> 
>  
> 
> 


reymannd@reym... writes:

> Dear all,
>
> I've been wondering for a while how to avoid this enormous waste of
> mem I presently have in the code generated from my program. [...] On
> the other hand due to the little amount of maths in the code I
> rarely need registers.  Actually R5 ... R 11 are never ever used.
>
> Consequently, if writing assembly, I would simply put some of my
> variables into these registers.  This saves ram, and even more
> important, it saves code space, which I have very few on my 'F1101.
> Unfortunately I cannot see a possibility to get this out if the C-compiler.

In version V3.10 of the IAR compiler it is possible to use "global
register variables".  They can do exactly what you ask for.

Unfortunately, we only have support for using two register, R4 and
R5 (well, it's better than nothing).

All you need to do is specify that R4 and R5 should be used for this
by the --regvar_r4 and --regvar_r5 command line options (or their
corresponding checkboxes in the IDE).

The following is an example on how to use this feature:

#include <intrinsics.h>

__no_init __regvar int x @ __R4;

int main()
{
  x = 10;

  return 0;
}

Oh, yes, modules built using regvar:s can only be linked with other
modules that either also has specified the --regvar_xx option, or the
--lock_r5 option, to ensure that the register in quesiton isn't used
by normal compiler-generated code.

    -- Anders Lindgren, IAR Systems
-- 
Disclaimer: Opinions expressed in this posting are strictly my own and
not necessarily those of my employer.

Glad to see you back, Al!

Greg

-----Original Message-----
From: onestone [mailto:onestone@ones...]
Sent: Tuesday, May 25, 2004 9:20 PM
To: msp430@msp4...
Subject: Re: [msp430] How to force the C-compiler to use registers?
[ND-Cerberus checked]


Yes. It's so simple code it in asm.

Al

reymannd@reym... wrote:

> Dear all,
>
> I've been wondering for a while how to avoid this enormous waste of
mem
> I presently have in the code generated from my program.
>
> The problem I have consists of a rather complex digital logic with very
> simple algorithms.  In other words, the program is a huge bunch of
if()'s
> with
> very little maths.
> I tried to write it as modular as I could and as a result I need many
> static
> and global variables keeping flags and states.
> Of course the compiler puts them all into normal mem.
>
> On the other hand due to the little amount of maths in the code I rarely
> need registers.  Actually R5 ... R 11 are never ever used.
>
> Consequently, if writing assembly, I would simply put some of my
> variables into these registers.  This saves ram, and even more
> important, it saves code space, which I have very few on my 'F1101.
> Unfortunately I cannot see a possibility to get this out if the
C-compiler.
>
> Since all this was a little abstract, now for something more practical...
> Imagine some code like this:
>
>
> --------------------
> unsigned char Var;
>
> main()
> {
>     SomeInitialization();
>     while (1)
>         {
>         P1OUT=Var;
>         if ( Var == 0x0F )
>             Var = 0 ;
>         }
> }
>
> #pragma vector=PORT1_VECTOR
> __interrupt void Func1(void)
> {
>     Var |=0x01;
> }
>
> #pragma vector=PORT2_VECTOR
> __interrupt void Func1(void)
> {
>     Var |=0x02;
> }
>
> #pragma vector=TIMERA1_VECTOR
> __interrupt void Func1(void)
> {
>     Var |=0x04;
> }
>
> #pragma vector=TIMERA2_VECTOR
> __interrupt void Func1(void)
> {
>     Var |=0x08;
> }
>
> --------------------
>
> Here you can easily imagine, that each access to Var wastes 2 Bytes of mem
> compared
> to if it was in a register.
> As I wrote earlier there are 7 registers which are potentially usable for
> globals and maybe
> 6 different accesses for each of these variables.
> 7 times 6 times 2 is        84       Bytes of wasted mem, which again is
> more than 8 percent of
> the entire mem available.
>
> This again, in my opinion, is definitely too much.
>
> So, has anyone got a smart idea how to get out of this?
>
>
> Regards,
> Dirk
>
>
>
>
>
> .
>
>
> Yahoo! Groups Links
>
>
>
>
>
>




.


Yahoo! Groups Links






Thank you.

Al

Greg Maki wrote:
> Glad to see you back, Al!
> 
> Greg
> 
> -----Original Message-----
> From: onestone [mailto:onestone@ones...]
> Sent: Tuesday, May 25, 2004 9:20 PM
> To: msp430@msp4...
> Subject: Re: [msp430] How to force the C-compiler to use registers?
> [ND-Cerberus checked]
> 
> 
> Yes. It's so simple code it in asm.
> 
> Al
> 
> reymannd@reym... wrote:
> 
> 
>>Dear all,
>>
>>I've been wondering for a while how to avoid this enormous waste of
mem
>>I presently have in the code generated from my program.
>>
>>The problem I have consists of a rather complex digital logic with very
>>simple algorithms.  In other words, the program is a huge bunch of
if()'s
>>with
>>very little maths.
>>I tried to write it as modular as I could and as a result I need many
>>static
>>and global variables keeping flags and states.
>>Of course the compiler puts them all into normal mem.
>>
>>On the other hand due to the little amount of maths in the code I rarely
>>need registers.  Actually R5 ... R 11 are never ever used.
>>
>>Consequently, if writing assembly, I would simply put some of my
>>variables into these registers.  This saves ram, and even more
>>important, it saves code space, which I have very few on my 'F1101.
>>Unfortunately I cannot see a possibility to get this out if the
> 
> C-compiler.
> 
>>Since all this was a little abstract, now for something more
practical...
>>Imagine some code like this:
>>
>>
>>--------------------
>>unsigned char Var;
>>
>>main()
>>{
>>    SomeInitialization();
>>    while (1)
>>        {
>>        P1OUT=Var;
>>        if ( Var == 0x0F )
>>            Var = 0 ;
>>        }
>>}
>>
>>#pragma vector=PORT1_VECTOR
>>__interrupt void Func1(void)
>>{
>>    Var |=0x01;
>>}
>>
>>#pragma vector=PORT2_VECTOR
>>__interrupt void Func1(void)
>>{
>>    Var |=0x02;
>>}
>>
>>#pragma vector=TIMERA1_VECTOR
>>__interrupt void Func1(void)
>>{
>>    Var |=0x04;
>>}
>>
>>#pragma vector=TIMERA2_VECTOR
>>__interrupt void Func1(void)
>>{
>>    Var |=0x08;
>>}
>>
>>--------------------
>>
>>Here you can easily imagine, that each access to Var wastes 2 Bytes of
mem
>>compared
>>to if it was in a register.
>>As I wrote earlier there are 7 registers which are potentially usable
for
>>globals and maybe
>>6 different accesses for each of these variables.
>>7 times 6 times 2 is        84       Bytes of wasted mem, which again is
>>more than 8 percent of
>>the entire mem available.
>>
>>This again, in my opinion, is definitely too much.
>>
>>So, has anyone got a smart idea how to get out of this?
>>
>>
>>Regards,
>>Dirk
>>
>>
>>
>>
>>
>>.
>>
>>
>>Yahoo! Groups Links
>>
>>
>>
>>
>>
>>
> 
> 
> 
> 
> 
> .
> 
> 
> Yahoo! Groups Links
> 
> 
> 
> 
> 
> 
> 
> 
> .
> 
>  
> Yahoo! Groups Links
> 
> 
> 
>  
> 
> 


Kris wrote:
>The rest is indeed moot. Just like the issue of
C++ and OOP is.
>OOP is a programming concept, not a language. I'm actually trying to
write
more
>and more in what I guess is called "C+"
rather than C if it's worth it.
>Eventually I'd like to learn more about EC++.

Thanks Kris,
sometimes, when a discussion get's a little over-heated it's good to
have
someone
come in and refocus the whole issue.
Actually I, too, was one of those being very sceptic agains the use of a
C-compiler
for small embedded project.

The best statement about this controvercy I've ever read was right on this
list some
months ago.  I don't know, whose copyright this is, maybe someone could
find out...

--------------------
An absolut expert can almost always write better code in assembly than any
compiler would ever do.  But usually a compiler saves code-size, and
execution-time
when used by an average developer.
--------------------


>> I could think in asm, and I absolutely have to
at least when I design
>> the HAL.
>> But in all layers above that I don't want to care at all, if this
>> algorithm is run on an MSP, a PC, my coffee-machine or fed into
"The
>> Matrix".

>I've been following part of this thread with
interest, and I agree here
100%,
>regardless of any other moot issues.
>I work a lot with single chip RF transceivers.
>Now, I've written a Hardware Abstraction Library for many different RF
parts.
>[report about porting capabilities]

I read about your experiences with great interest.

Furthermore I see one of the major benefits of abstraction in the
limitation of
scope you have to care about.

Especially in normal business when the phone rings every 5 minutes,
colleagues
come in frequently, you have many entirely different tasks on your desk,
all with
highest priority, of course,  it's very hard to concetrate on a complicated
technical
problem.

Therefore I see a great advantage in isolating a problem to it's
unavoidable core.
Having to think about many other things, like hardware details or overall
program
structure is just an extra burden that makes life harder and errors more
propable.


Regards,
Dirk











Hi Al,

>Of course you know that this could be an endless
debate ;@}

Yes, I recently noticed.  So I try to keep it short to not overly bother
the other's
on this list.  :-)


>I believe that we have intrinsically different
design philosophies. I
>think about as abstractly as it gets but ultimately thought without
>purpose is wasted thought. The very early stages of solving a problem
>may be abstract, but defining the solution can never be.

That's the key.
I've just learnt that we two have entirly different approaches.
I personally made the experience that the first time that I usually truly
understand
a problem is when I have finished it's solution for the first time.
Therefore I regard programming more like an iterative process that I slowly
start on an abstract basis, and then grows more and more concrete.

Hence I wouldn't dare to just sit down and think about a structure that is
first
defined and then coded.

>I wouldn't. By the time I sit and write ANY
code I have already
>determined the relevant parameters of my design. There is nothing
>abstract, or unknown, or to be discovered. I find this approach a little
>like stepping off a cliff and hoping to hell that my arms flap fast
>enough.

I would, but not entirly so irreversible.  Anyway it's a nice metaphor.
I understand that you stay on top of the cliff for a while scanning it and
then
prepare your smooth jump directly down into the water.
I would rather take a rope and then start may slow decent.

But either way it's mostly a question of personal preference.

Regards,
Dirk


reymannd@reym... wrote:

> Kris wrote:
>  
> Thanks Kris,
> sometimes, when a discussion get's a little over-heated it's good
to have
> someone
> come in and refocus the whole issue.

I felt no temperature rise, and I'm accurate to 0.01C ;@}

> Actually I, too, was one of those being very
sceptic agains the use of a
> C-compiler
> for small embedded project.
> 
> The best statement about this controvercy I've ever read was right on
this
> list some
> months ago.  I don't know, whose copyright this is, maybe someone
could
> find out...
> 
> --------------------
> An absolut expert can almost always write better code in assembly than any
> compiler would ever do.  But usually a compiler saves code-size, and
> execution-time
> when used by an average developer.
> --------------------



  parts.
> 
>>[report about porting capabilities]
> 
> 
> I read about your experiences with great interest.
> 
> Furthermore I see one of the major benefits of abstraction in the
> limitation of
> scope you have to care about.
> 
> Especially in normal business 

Here's the kicker. I'm not normal.

when the phone rings every 5 minutes,

If I'm busy I ignore the phone, In fact It may not even register that 
the phone is ringing. I have message bank.

> colleagues
> come in frequently, 

I work alone.

you have many entirely different tasks on your desk,
> all with
> highest priority, of course, 

I keep 1 desk per project (seriously, I have three desks. I set 
priority, and work on each project as inspiration leads me.

  it's very hard to concetrate on a complicated
> technical
> problem.

I find the opposite, I can get so focussed I forget to eat, drink or go 
the bathroom for hours at a time.

> 
> Therefore I see a great advantage in isolating a problem to it's
> unavoidable core.
> Having to think about many other things, like hardware details or overall
> program
> structure is just an extra burden that makes life harder and errors more
> propable.

Not thinking about it has killed more projects than I care to think 
about though.

Al


reymannd@reym... wrote:

> Hi Al,
> 
> 
>> Of course you know that this could be an endless debate ;@}
> 
> 
> Yes, I recently noticed.  So I try to keep it short to not overly
> bother the other's on this list.  :-)

I don't think it bothers most people. Certainly while it is on topic,
which it is, many people here like to read others opinions, no matter
how off the wall they personally consider them to be. While the postings
are not nasty, personal or spiteful, they are usually well accepted.
Often, in fact, there would be no psosts to read without the odd lengthy
discussion.

> 
>> I believe that we have intrinsically different design philosophies.
>> I think about as abstractly as it gets but ultimately thought
>> without purpose is wasted thought. The very early stages of solving
>> a problem may be abstract, but defining the solution can never be.
> 
> 
> That's the key. I've just learnt that we two have entirly
different
> approaches. I personally made the experience that the first time that
> I usually truly understand a problem is when I have finished it's
> solution for the first time.

Yes this is probably the way most people approach problem solving. For
many years I did the same myself. Sit down, write some simple code at a
very high level, that code called a function, or two, which werew ritten
next, gradually building in layers until you discover what was necessary
to actually solve the problem as I went along. This works for a little
while, but, I think even Kris would agree. Most projects have to be
studied and designed first, and all reasonable problems solved or
anticipated before coding begins. THEN you can take the decision to code
abstractly, or directly, it is now a matter of choice, and project need,
rather than necessity. I understood from our many discussions that Kris
is also an advocate of an intense design and specification period
followed by a short code period and a long debug period, thus you and he
are coding in a similar style, ut for very different reasons.

> Therefore I regard programming more like an
iterative process that I
> slowly start on an abstract basis, and then grows more and more
> concrete.

I regard programming as the simple mechanical implementation of a
thoroughly though out design.

> 
> Hence I wouldn't dare to just sit down and think about a structure
> that is first defined and then coded.


>> I wouldn't. By the time I sit and write
ANY code I have already 
>> determined the relevant parameters of my design. There is nothing 
>> abstract, or unknown, or to be discovered. I find this approach a
>> little like stepping off a cliff and hoping to hell that my arms
>> flap fast enough.

Sorry, by the last sentence I meant that this is how I view your method.
You launch into coding without having first determined what the problem
is and how you are going to solve it, whereas I wait at the top of the
cliff until my hangglider is finished then step off into the void in it.

> 
> 
> I would, but not entirly so irreversible.  Anyway it's a nice
> metaphor. I understand that you stay on top of the cliff for a while
> scanning it and then prepare your smooth jump directly down into the
> water. I would rather take a rope and then start may slow decent.

But you yhaven't yet determined if the rope is logn enough ;@{

> 
> But either way it's mostly a question of personal preference.


I actually believe it's a little more than that, but that is only my
belief, the great thing about this group is that we don't have to follow 
others opinions, no matter how out numbered we may be. We are all 
anarchically free to go our own way.

Cheers

Al