Page 1 of 1

Use of CLR in generated code

Posted: Tue Jan 27, 2015 3:12 am
by Charles MacDonald
I've noticed when assigning a volatile memory location to zero, gcc will emit a CLR instruction. Is there any way to force it to write a constant zero instead of using a read-modify-write instruction such as CLR?

Also I recall there was some way to suppress the requirement of a percent sign on register names in as, so you could write code like "tst.l d0" instead of "tst.l %d0". There's a reference to this functionality at the Atari ST cross compiler page:

"Registers may be prefixed by % like %d0 but in our binutils configuration this is not mandatory."

http://bus-error.nokturnal.pl/article2- ... C-programs
http://vincent.riviere.free.fr/soft/m68k-atari-mint/

Though they make it sound like an option set when compiling the tools and I recall it was a command line parameter passed to as.exe. Does such a feature still exist? (or did it ever exist :)

Posted: Tue Jan 27, 2015 3:40 am
by Chilly Willy
You pass GAS the flags "-m68000 --register-prefix-optional". It still works on the very latest binutils.

The simplest way to force the compiler to use move is inline assembly.

Posted: Tue Jan 27, 2015 4:40 am
by Charles MacDonald
Chilly Willy wrote:You pass GAS the flags "-m68000 --register-prefix-optional". It still works on the very latest binutils.
Wonderful, that did the trick. Thanks!

Posted: Tue Jan 27, 2015 8:39 am
by Chilly Willy
No problem. There's not a whole lot of info on gcc options as regards the 68000. Especially on inline assembly. Virtually all inline assembly info is on x86, with a little on ARM. I've had to scour the net and open source along with experimentation to figure out 68000, SH2, PPC, and MIPS. Flags like that one to avoid needing the prefix is another example of something you gotta hunt diligently to find. Even something as straightforward as the ABI for a particular processor can be a pain to track down.

Posted: Wed Jan 28, 2015 9:33 am
by Stef
To avoid CLR instruction use by GCC i use an infamous trick in SGDK.
I have the following methods :

Code: Select all

u8 getZeroU8()
{
    return 0;
}

u16 getZeroU16()
{
    return 0;
}

u32 getZeroU32()
{
    return 0;
}
and so when i need to zero memory i do :

Code: Select all

u32 fill = getZeroU32();

i = num;
while (i--) *dst++ = fill;
Because getZeroU32() is not a static method it does not optimize it to a constant (and so 0 which result in CLR instruction use).
GCC just store the result of getZeroU32() in a register and use it to fill memory = fast clear.

Posted: Wed Jan 28, 2015 8:38 pm
by Charles MacDonald
Stef wrote:To avoid CLR instruction use by GCC i use an infamous trick in SGDK.
Ha, that's brilliant. I'll definitely use it.

Posted: Wed Jan 28, 2015 9:00 pm
by Chilly Willy
Charles MacDonald wrote:
Stef wrote:To avoid CLR instruction use by GCC i use an infamous trick in SGDK.
Ha, that's brilliant. I'll definitely use it.
Yes, that is. Using the lack of good global optimization to your own benefit. :)

Perhaps make the function into a common constant table fetch...

Code: Select all

u8 getConstantU8(int constant)
{
    switch(constant)
    {
        case CONST_ZERO:
            return 0;
        case CONST_ONE:
            return 1;
        default:
            return 255;
    }
}
Something like that. Maybe even easier

Code: Select all

u8 getValU8(int val)
{
    return (u8)val;
}

Posted: Wed Jan 28, 2015 10:47 pm
by Stef
Charles MacDonald wrote:
Stef wrote:To avoid CLR instruction use by GCC i use an infamous trick in SGDK.
Ha, that's brilliant. I'll definitely use it.
Haha, not sure it's brilliant but at least it works :D

Chilly Willy> Only the 0 constant is a problem, in other case it uses register to store value then fill memory.

Posted: Thu Jan 29, 2015 12:06 am
by Chilly Willy
Stef wrote:
Charles MacDonald wrote:
Stef wrote:To avoid CLR instruction use by GCC i use an infamous trick in SGDK.
Ha, that's brilliant. I'll definitely use it.
Haha, not sure it's brilliant but at least it works :D

Chilly Willy> Only the 0 constant is a problem, in other case it uses register to store value then fill memory.
What? They don't use st for -1? How lazy! :lol: