PropGCC, float math, and -mcog? Unable to work
I am trying to compile a program with floating point using PropGCC down to Spin code that can be stored and run in a single cog.
C code:
I compile with:
produces the following spin code:
It clearly calls the floating point routines (___adddf3 and ___muldf3) but those routines aren't here! In the source file, if I uncomment the integer arithmetic routines it does what I expect, which is to include a multiplication routine near the end of the assembly code (similar example can be seen in post #5 here).
Some other threads (here and here) seem to indicate that the floating point library is quite large on the Propeller. I have hope that in my simple program it will strip everything but the floating point multiply/add and hence be quite small. The Spin floating point library (here) multiply routine is quite small:
My Question:Is it possible to use PropGCC to compile to cog ram and use floating point routines?
C code:
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
int main()
{
for(;;){
/*
int num1, num2, num3;
volatile int result0;
num3 = num3 * num3;
num2 = num2 * num2;
num1 = num1 * num1;
result0 = num1 + num2;
result0 = result0 + num3;
result0 = result0 / num3;
*/
volatile double fnum1, fnum2, fnum3;
fnum1 = fnum2 * fnum3;
fnum1 += 5.0;
}
}
I compile with:
propeller-elf-gcc -Wall -m64bit-doubles test.c -S -mcog -mspin -lm
produces the following spin code:
'' spin code automatically generated by gcc
CON
_clkmode = xtal1+pll16x
_clkfreq = 80_000_000
__clkfreq = 0 '' pointer to clock frequency
'' adjust STACKSIZE to how much stack your program needs
STACKSIZE = 256
VAR
long cog '' cog that was started up by start method
long stack[STACKSIZE]
'' add parameters here
long param
'' add any appropriate methods below
PUB start
stop
cog := cognew(@entry, @param) + 1
PUB stop
if cog
cogstop(cog~ - 1)
DAT
org
entry
r0 mov sp,PAR
r1 mov r0,sp
r2 jmp #_main
r3 long 0
r4 long 0
r5 long 0
r6 long 0
r7 long 0
r8 long 0
r9 long 0
r10 long 0
r11 long 0
r12 long 0
r13 long 0
r14 long 0
lr long 0
sp long 0
'.text
long
'global variable _main
_main
sub sp, #4
wrlong r8, sp
sub sp, #4
wrlong r14, sp
sub sp, #4
wrlong lr, sp
mov r14, sp
sub sp, #24
L_L2
mov r7, r14
sub r7, #16
rdlong r3, r7
add r7, #4
rdlong r4, r7
mov r7, r14
sub r7, #8
rdlong r5, r7
add r7, #4
rdlong r6, r7
mov r0, r3
mov r1, r4
mov r2, r5
mov r3, r6
jmpret lr,#___muldf3
mov r5, r0
mov r6, r1
mov r7, r5
mov r8, r6
mov r6, r14
sub r6, #24
wrlong r7, r6
mov r6, r14
sub r6, #20
wrlong r8, r6
mov r6, r14
sub r6, #24
rdlong r7, r6
mov r6, r14
sub r6, #20
rdlong r8, r6
mov r6, L_LC1
mov r0, r7
mov r1, r8
mov r2, L_LC0
rdlong r3, r6
jmpret lr,#___adddf3
mov r5, r0
mov r6, r1
mov r7, r5
mov r8, r6
mov r6, r14
sub r6, #24
wrlong r7, r6
mov r6, r14
sub r6, #20
wrlong r8, r6
jmp #L_L2
long
L_LC0
long 0
long 1075052544
long
L_LC1
long L_LC0+4
It clearly calls the floating point routines (___adddf3 and ___muldf3) but those routines aren't here! In the source file, if I uncomment the integer arithmetic routines it does what I expect, which is to include a multiplication routine near the end of the assembly code (similar example can be seen in post #5 here).
Some other threads (here and here) seem to indicate that the floating point library is quite large on the Propeller. I have hope that in my simple program it will strip everything but the floating point multiply/add and hence be quite small. The Spin floating point library (here) multiply routine is quite small:
'------------------------------------------------------------------------------
' _FMul fnumA = fnumA * fNumB
' _FMulI fnumA = fnumA * {Float immediate}
' changes: fnumA, flagA, expA, manA, fnumB, flagB, expB, manB, t1, t2
'------------------------------------------------------------------------------
_FMulI movs :getB, _FMulI_ret ' get immediate value
add _FMulI_ret, #1
:getB mov fnumB, 0
_FMul call #_Unpack2 ' unpack two variables
if_c jmp #_FMul_ret ' check for NaN
xor flagA, flagB ' get sign of result
add expA, expB ' add exponents
mov t1, #0 ' t2 = upper 32 bits of manB
mov t2, #32 ' loop counter for multiply
shr manB, #1 wc ' get initial multiplier bit
:multiply if_c add t1, manA wc ' 32x32 bit multiply
rcr t1, #1 wc
rcr manB, #1 wc
djnz t2, #:multiply
shl t1, #3 ' justify result and exit
mov manA, t1
call #_Pack
_FMulI_ret
_FMul_ret ret
My Question:Is it possible to use PropGCC to compile to cog ram and use floating point routines?

Comments
I suspect it's better not to use local variables in functions for COG code as there. Declare them as global outside the functions. When working on small bits of COG code like this I don't think locals are so important to have anyway.
Use the _COGMEM attribute to force variables to be allocated in COG space not HUB.
And "static" because they are not used from outside the module. "volatile" to avoid the optimizer eating your code if need be.
Not sure about how to get the float routines into COG, should be possible as floating point add/sub/mul/div from F32 are not so huge.
I'm not sure if this something we intended to allow. It does bring up a good point though.
Being able to generate COG code for floating point seems like a reasonable idea.
I'll add this as a feature request on the issues page.
We may have to defer the "feature" until after general availability though.
Also, 64 bit doubles are the default in Propeller-GCC unless -m32bit-doubles is specified.
Seems like your handle is in a very helpful comment for cloning the repository. Excellent suggestion.
Thanks,
--Steve
Of course that doesn't explain what happens when not using that option:
Of course looking at the manual (/home/opt/parallax/share/info/gcc.info) , one finds this:
`-mspin' Output code suitable for inclusion in Spin DAT sections. This feature is experimental, and may not work correctly in all situations, but is intended to facilitate using GCC to compile the PASM portion of Spin device drivers. This option imples `-mpasm'.