Shop OBEX P1 Docs P2 Docs Learn Events
PropGCC, float math, and -mcog? Unable to work — Parallax Forums

PropGCC, float math, and -mcog? Unable to work

SRLMSRLM Posts: 5,045
edited 2012-03-05 17:38 in Propeller 1
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:
#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

  • Heater.Heater. Posts: 21,230
    edited 2012-03-05 01:41
    I would not use the "-m64bit-doubles" option, be grateful the propgcc provides 32 bit floats. Not sure it caters for 64bit floats at all and I'm sure if it did the code would be much bigger.

    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.
    static _COGMEM volatile int someVariable;


    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.
  • jazzedjazzed Posts: 11,803
    edited 2012-03-05 09:53
    @SLRM,

    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
  • jazzedjazzed Posts: 11,803
    edited 2012-03-05 17:38
    Looking into this issue again. If you use -S when compiling a file, all you get is the assembly for the file.
    Of course that doesn't explain what happens when not using that option:
    $ propeller-elf-gcc -Wall -m32bit-doubles -c -mcog -mspin slrmfp.c -lm
    /tmp/ccJSWWHj.s: Assembler messages:
    /tmp/ccJSWWHj.s:4: Error: junk at end of line, first unrecognized character is `_'
    /tmp/ccJSWWHj.s:10: Error: junk at end of line, first unrecognized character is `['
    /tmp/ccJSWWHj.s:15: Error: Unknown instruction 'start'
    /tmp/ccJSWWHj.s:16: Error: Unknown instruction 'stop'
    /tmp/ccJSWWHj.s:17: Error: junk at end of line, first unrecognized character is `='
    /tmp/ccJSWWHj.s:18: Error: Unknown instruction 'stop'
    /tmp/ccJSWWHj.s:19: Error: non-constant expression in ".if" statement
    /tmp/ccJSWWHj.s:82: Error: end of file inside conditional
    /tmp/ccJSWWHj.s:19: Error: here is the start of the unterminated conditional
    

    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'.
    
Sign In or Register to comment.