fastspin compiler for P2: Assembly, Spin, BASIC, and C in one compiler

13335373839

Comments

  • When using FlexGUI 4.1.0-beta, under Win10 and coding in BASIC for the P2-EVAL rev B board:

    @ersmith It appears the RND() function is having a bad day. This bit of code:
    	print int(rnd(1)*100)
    
    makes this mischief happen:
    "d:/Flex2Gui/flexgui/bin/fastspin" -2 -l -O1 -I "d:/Flex2Gui/flexgui/include" -I "d:/Flex2Gui/flexgui/P2 Libs"  "d:/Flex2Gui/flexgui/P2 Libs/SortLibP2.bas"
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
    Version 4.1.0-beta-daaa5547 Compiled on: Jan  2 2020
    SortLibP2.bas
    random.c
    fmt.c
    d:/Flex2Gui/flexgui/include/libsys/random.c:39: error: Unknown symbol _CNT
    child process exited abnormally
    Finished at Sun Jan  5 09:46:26 2020
    
    I'm not much of a C-person these days, but it looks like random.c is complaining about an attempt to use the P2's system counter as a random seed source:
    float _basic_rnd(int n)
    {
        unsigned r;
        if (n < 0) {
            _seed = n;
        } else if (n == 0) {
            _seed = _CNT;   '<--- the guilty party lives here
        }
        r = _lfsr_forward(_seed);
        _seed = r;
        r = (r >> 4) & RAND_MASK;
        return ((float)r) / ((float)(RAND_MASK+1));
    }
    
    I'll leave this covfefe in your capable hands. :)

    BTW: Thanks for your earlier help on the array issues. The code you included was VERY helpful!
  • Hi @JRoark. You've correctly identified the bug, and the fix is very simple (changing "_CNT" to "_getcnt()"). I actually noticed that bug a day or so after I released 4.1.0, and checked the fix into github. I was hoping nobody would run into it :).

    Thanks!

  • I really need to learn how Github works. Maybe that will be tonights project.

    BTW; Breaking things is just one of the many services I provide. You should see my plumbing projects. Lol!
  • Hello, I made a small test program, which accepts parameters via serial and thus starts a second cog. It works well.
    My question is:
    Is there a way to change the parameter at runtime and hand it over to the second cog without stopping and then restarting the cog. I also tried to work with a mailbox, like the P1, but it doesn't work.
    Here is the working program.
    fastspin -2b print.c
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
    Version 4.1.0-beta- Compiled on: Jan  5 2020
    print.c
    gets.c
    fputs.c
    sleep.c
    atoi.c
    fmt.c
    ftab.c
    ctype.c
    print.p2asm
    Done.
    Program size is 5568 bytes
    
    
    loadp2 -t -b 230400 -p /dev/ttyUSB0 print.binary
    ( Entering terminal mode.  Press Ctrl-] to exit. )
    cog 0 -> audio_out: clockmode is $10007f8, clock frequency 160000000 Hz
    Set Frequency in Hz
    set freq to 1000 Hz
    cog 1 started
    .
    .
    .
    .
    
    

    I am very happy with fastspin. Is this the same as FlexC, what I read in the documents?
    Thank you and i hope i haven't repeated the topic, i haven't read all the comments.
    c
    c
    3K
  • Here is the currently non working program.
    fastspin -2b more_cogs.c
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
    Version 4.1.0-beta- Compiled on: Jan  5 2020
    more_cogs.c
    gets.c
    fputs.c
    sleep.c
    atoi.c
    fmt.c
    ftab.c
    ctype.c
    more_cogs.p2asm
    more_cogs.p2asm:438: error: Source operand too big for add
    Done.
    
    

    LR__0015
    	qrotate	##4096, local01
    	getqx	local02
    	getqy	local03
    	xor	local02, ##32768
    	xor	local03, ##32768
    	wypin	local02, #0
    	wypin	local03, #1
    	waitse1
    	add	local01, #@_dat_ + 128       '<-- line 438
    	jmp	#LR__0015
    	mov	ptra, fp
    	calla	#popregs_
    _gen_cos_sin_ret
    
  • Solved with restart the cog:
    loadp2 -t -b 230400 -p /dev/ttyUSB0 more_cogs.binary
    ( Entering terminal mode.  Press Ctrl-] to exit. )
    cog 0 -> audio_out: clockmode is $10007f8, clock frequency 160000000 Hz
    Set Frequency in Hz
    set freq to 1000 Hz
    cog 1 started
    Set Frequency in Hz
    set freq to 2000 Hz
    cog 1 started
    Set Frequency in Hz
    set freq to 1234 Hz
    cog 1 started
    Set Frequency in Hz
    
    
  • You're putting that board I sent you to good use!
  • I'm also happy not to have to simulate anymore. Research is much faster with Osci and printf.
  • Reinhard wrote: »
    Hello, I made a small test program, which accepts parameters via serial and thus starts a second cog. It works well.
    My question is:
    Is there a way to change the parameter at runtime and hand it over to the second cog without stopping and then restarting the cog. I also tried to work with a mailbox, like the P1, but it doesn't work.
    Yes, it's certainly possible to pass parameters with a mailbox. For an example you can look at the led_server_asm.c sample in FlexGUI.

    Your more_cogs.c program is failing because the inline assembly code in gen_cos_sin makes a direct reference to a variable "frq" which isn't a local variable (it's a global). That's not allowed, and it should have been detected by the compiler -- there's a bug in the compiler. To fix more_cogs.c, change gen_cos_sin() to:
    void gen_cos_sin()
    {
        audio_init(); // must done in this cog !
        frq = 268435 * frq;
        int phi = 0;
        int sample;
        int sample2;
        int localfrq;
        
        while (1)
        {
            localfrq = frq; // copy current value of frq
    	__asm {
    	    qrotate	##$1000,phi
                getqx	sample
                getqy	sample2
                xor     	sample, ##$8000
                xor		sample2,##$8000
                wypin   	sample, #L_PIN 
                wypin	sample2,#R_PIN     
                waitse1
                add		phi,localfrq
            };		
        }	
    }
    
    I am very happy with fastspin. Is this the same as FlexC, what I read in the documents?

    Thank you. Yes, FlexC is the name for the C dialect that fastspin accepts. It's intended to be a superset of C99, with some C++ features like classes and reference parameters.
  • Thank you for the fast response, I think you are very busy.
    It is a giant work to support 4 languages in one compiler.

    I think the other direction, send from cog to global, is similar (?)
    Reinhard
  • Reinhard wrote: »
    I think the other direction, send from cog to global, is similar (?)
    Reinhard

    Yes, just make sure to set the global in C from a local variable. The inline assembly code should only ever access local variables, never global. The reason is that local variables are in registers (so can be changed by assembly instructions like "add" directly) but global variables are in HUB memory, so instructions like "add" cannot work on them.
  • Hi,
    for a larger project I need the C - Function size_t strspn(const char *, const char *);
    Therefore I make a test:
    #include <stdio.h>
    #include <string.h>
    
    int main () {
       int len;
       const char str1[] = "ABCDEFG019874";
       const char str2[] = "ABCD";
    
       len = strspn(str1, str2);
    
       printf("Length of initial segment matching %d\n", len );
       
       return(0);
    } 
    
    

    I tested it on PC
    gcc -o test test_strspn.c
     ./test
    Length of initial segment matching 4
    
    

    with fastspin I get
    fastspin -2b test_strspn.c
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
    Version 4.1.0-beta- Compiled on: Jan  5 2020
    test_strspn.c
    test_strspn.c:6: error: incompatible types in assignment
    test_strspn.c:7: error: incompatible types in assignment
    
    

    It is not so urgent now, but I wanted to point it out.
  • Thanks for the bug report, @Reinhard . I think for now you can work around it by using "const char *str1" instead of "const char str1[]".
  • Fastspin 4.0.6 spin method inline assembly:
    PUB method | d, s
      asm
        cmp d, s wcz
      endasm
    
    The compiler issues "warning: instruction cmp used without flags being set". The wc, wz flag writes work as expected.
  • I'm unable to reproduce the problem, @garryj. Is this part of a larger project? Does it still happen if you give the -O0 option to fastspin to disable optimization?
  • garryjgarryj Posts: 293
    edited 2020-01-15 - 01:37:30
    ersmith wrote: »
    I'm unable to reproduce the problem, @garryj. Is this part of a larger project? Does it still happen if you give the -O0 option to fastspin to disable optimization?
    It's part of a larger project. A top object which includes the SmartSerial object and my USB kbd/mouse object. The inline code is in the top object. Compiled using -O0 still throws the warning.
    Attached is (messy) code that triggers the warning (Win10).
  • Thank you, Garry. That was a good bug you found -- I missed a case in some inline assembly translation code. "wcz" is fixed in github now. For a work-around you can write "wc,wz" instead of "wcz"; the former should always work (the wc and wz paths were OK, and fastspin still accepts the old notation for setting both flags).

    Thanks,
    Eric
  • Hi
    I have a testexample, this works also on P1 with gcc. I tried it to run on P2.
    fastspin -2b -o ex-1 ex-1.c bit.c des.c rsa.c
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
    Version 4.1.0-beta- Compiled on: Jan  5 2020
    ex-1.c
    bit.c
    des.c
    rsa.c
    ftab.c
    fprintf.c
    memcpy.c
    memset.c
    dofmt.c
    fmt.c
    /crypto_demo/ex-1.c:133: error: Expected multiple values
    /crypto_demo/ex-1.c:134: error: Expected multiple values
    
    I commented out the affected lines.
       //rsa_encipher(rsatmp, &rsactx, rsapubkey);
       //rsa_decipher(rsactx, &rsaptx, rsaprikey);
    
    Then the program can be compiled and loaded. Of course, error messages come because the commented out functions are missing.
    loadp2 -b 230400 -t -p /dev/ttyUSB0 ex-1.binary
    ( Entering terminal mode.  Press Ctrl-] to exit. )
    Enciphering with DES
    Before enciphering
    destmp: a9 10 11 38 93 ca b4 a1
    deskey: 01 1f 01 1f 01 0e 01 0e
    After enciphering
    destmp: a9 10 11 38 93 ca b4 a1
    desctx: 93 12 bc c0 af 13 c3 3d
    Before deciphering
    desctx: 93 12 bc c0 af 13 c3 3d
    deskey: 01 1f 01 1f 01 0e 01 0e
    After deciphering
    desctx: 93 12 bc c0 af 13 c3 3d
    desptx: a9 10 11 38 93 ca b4 a1
    Enciphering with RSA
    d=53, e=17, n=209
    rsatmp=    0, rsactx=-43778002, rsaptx=-251138024 (ERROR)
    rsatmp=    1, rsactx=-43778002, rsaptx=-251138024 (ERROR)
    rsatmp=    2, rsactx=-43778002, rsaptx=-251138024 (ERROR)
    rsatmp=    3, rsactx=-43778002, rsaptx=-251138024 (ERROR)
    
    It seems this parameter passing causes problems:
    typedef unsigned long Huge;
    typedef struct RsaPubKey_ {
    
    Huge               e;
    Huge               n;
    
    } RsaPubKey;
    
    typedef struct RsaPriKey_ {
    
    Huge               d;
    Huge               n;
    
    } RsaPriKey;
    
    [b]void rsa_encipher(Huge plaintext, Huge *ciphertext, RsaPubKey pubkey);[/b]
    
    void rsa_decipher(Huge ciphertext, Huge *plaintext, RsaPriKey prikey);
    
    

    It is not urgent this time either, but if I can help as a beta tester, please.
    Reinhard

    -- all needed files are attached --
    c
    c
    8K
    h
    h
    1K
    c
    c
    23K
    c
    c
    5K
    c
    c
    4K
  • Thank you for the bug report, @Reinhard. I'm able to reproduce the problem here and I think I know what's wrong, but I'm not sure to fix it yet. I'll look into it.

    Thanks for your help!
    Eric
  • @ersmith
    I have ported a lot of C programs to fastspin / FlexC that work smoothly.
    I only report the problems here. If you want you can send me a list of C functions that you would like to have tested. I want to make a small contribution. I know a lot about C and others are very competent for Basic and Spin2.
    Reinhard
  • Thanks @Reinhard. I don't have any specific C functions in mind for testing right now, just general functionality -- the C compiler is still in its development phase so I'm sure there are still bugs in many places.
  • When using FlexGUI 4.1.0-beta, under Win10 and coding in BASIC for the P2-EVAL rev B board:

    @ersmith It appears that some CLASS/END CLASS structures are giving the complier a headache. This is the error I get:
    "d:/Flex2Gui/flexgui/bin/fastspin" -2 -l -O1 -I "d:/Flex2Gui/flexgui/include" -I "d:/Flex2Gui/flexgui/P2 Libs"  "d:/Flex2Gui/flexgui/classtest.bas"
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2020 Total Spectrum Software Inc.
    Version 4.1.0-beta-a7cd18d7 Compiled on: Jan 10 2020
    classtest.bas
    fmt.c
    error: Cannot handle memrefs of size 12
    error: Cannot handle memref of size 12
    child process exited abnormally
    Finished at Thu Jan 16 09:10:34 2020
    

    This code that causes the error is this:
    	CLASS mytest
    		dim a as long
    		dim b as long
    		dim c as long
    		' dim d as long    '<--- Uncommenting this line fixes everything. 
    	END CLASS
    
    	dim one as mytest
    	dim two as mytest
    
    	one.a = 1
    	one.b = 2
    	one.c = 3
    
    	print one.a, one.b, one.c
    	print two.a, two.b, two.c
    	print
    
    	two = one
    
    	print one.a, one.b, one.c
    	print two.a, two.b, two.c
    
    
    If you uncomment just that **one** line, it runs fine.
  • @ersmith Why does fastspin's listing file not show any COG relative addresses for all the embedded COG objects in my SPIN2 projects written in PASM (with ORG 0 lines) apart from some brief COG address from the very first object at hub address $400? Am I missing something required for getting this in the listing? I am using fastspin 4.0.4 beta in case this limitation is fixed in later versions...
    00000                 | '   baud = 230_400
    00000                 |     baud = 230400
    00000                 | dat
    00000 000 01 A0 63 FD |     cogid   $1d0
    00004 001 02 00 00 FF
    00008 002 00 A0 E7 FC |     coginit $1d0,##$400
    0000c     00 00 00 00 |     orgh    $10
    00010     00 00 00 00 |     long    0   'reserved
    00014     00 00 00 00 |     long    0 ' clock frequency: will default to 108000000
    00018     00 00 00 00 |     long    0 ' clock mode: will default to $6b
    0001c     00 00 00 00 
    
    <snip>
    
    00568 05a             | result1
    00568 05a 00 00 00 00 |     long    0
    0056c 05b             | result2
    0056c 05b 00 00 00 00 |     long    0
    00570 05c             | COG_BSS_START
    00570 05c             |     fit 496    <---- no more COG relative adresses printed until the end of the image
    00570                 |     orgh
    00570                 | hubentry
    00570                 | 
    00570                 | ' 
    00570                 | ' PUB start
    00570                 | _start
    00570                 | '   coginit(cogid, demo, @demostack)
    00570     54 3C 01 F6 |     mov start_tmp002_, ptr__dat__
    00574     9E A0 60 FC |     wrlong  objptr, start_tmp002_
    00578     04 3C 05 F1 |     add start_tmp002_, #4
    
    <snip - all my own PASM code here even with "ORG 0" does not show COG relative addresses>
    
    
    4f6dc     00 00 00 00 
    4f6e0     00 00 00 00 
    4f6e4     00 00 00 00 
    4f6e8     00 00 00 00 
    4f6ec     00 00 00 00 |     long    0[1364]
    4f6f0                 | stackspace
    4f6f0     00 00 00 00 |     long    0[1]
    4f6f4 05c             |     org COG_BSS_START  <--- cog relative addresses resume at the end
    4f6f4 05c             | _tmp001_
    4f6f4 05c             |     res 1
    4f6f4 05d             | _tmp002_
    4f6f4 05d             |     res 1
    4f6f4 05e             | _tmp003_
    4f6f4 05e             |     res 1
    4f6f4 05f             | _tmp005_
    4f6f4 05f             |     res 1
    4f6f4 060             | _tmp006_
    4f6f4 060             |     res 1
    4f6f4 061             | _var01
    4f6f4 061             |     res 1
    4f6f4 062             | _var02
    4f6f4 062             |     res 1
    4f6f4 063             | _var03
    4f6f4 063             |     res 1
    4f6f4 064             | _var04
    4f6f4 064             |     res 1
    4f6f4 065             | _var05
    4f6f4 065             |     res 1
    4f6f4 066             | _var06
    4f6f4 066             |     res 1
    4f6f4 067             | _var07
    4f6f4 067             |     res 1
    4f6f4 068             | _var08
    4f6f4 068             |     res 1
    4f6f4 069             | _var09
    4f6f4 069             |     res 1
    4f6f4 06a             | _var10
    
  • I think I can answer that. It's telling you that that binary component is not targeted at cogRAM, ie: It is ORGH'd but not ORG'd.
  • roglohrogloh Posts: 1,875
    edited 2020-01-17 - 05:51:48
    I do have ORGs in the code as well though but they don't seem to be interpreted during the listing generation step...

    eg. in my included objects is this video driver code
                
    '------------------------------------------------------------------------------
    DAT
                orgh
    
    videodriver
                org 0
    
    '--------------------------------------------------------------------------------------------------
    '
    ' Initial driver entry code, this is also reused later for variable storage 
    '
    '--------------------------------------------------------------------------------------------------
    statusaddr                  mov     statusaddr, ptra        'save ptra as the status address
    mailbox1                    rdlong  mailbox1, ptra[3] wc    'read mailbox address information
    linebuf1                    rdlong  linebuf1, ptra[4]       'extract scan line buffer address
    linebuf2                    rdlong  linebuf2, ptra[5]       'extract scan line buffer address
    mailbox2                    add     ptra, #24               'skip past the init parameters
    paramaddr                   mov     paramaddr, ptra         'save pointer to first region data
    ...
    

    and the listing it generates is this...(all I get is the hub address which makes it harder to verify addresses etc.)
    4a62c                 |     alignl
    4a62c                 | _p2videodrvmonotext_dat_
    4a62c                 |             orgh
    4a62c                 | 
    4a62c                 | videodriver
    4a62c                 |             org 0
    4a62c                 | 
    4a62c                 | '--------------------------------------------------------------------------------------------------
    4a62c                 | '
    4a62c                 | ' Initial driver entry code, this is also reused later for variable storage 
    4a62c                 | '
    4a62c                 | '--------------------------------------------------------------------------------------------------
    4a62c     F8 01 00 F6 | statusaddr                  mov     statusaddr, ptra        'save ptra as the status address
    4a630     03 03 14 FB | mailbox1                    rdlong  mailbox1, ptra[3] wc    'read mailbox address information
    4a634     04 05 04 FB | linebuf1                    rdlong  linebuf1, ptra[4]       'extract scan line buffer address
    4a638     05 07 04 FB | linebuf2                    rdlong  linebuf2, ptra[5]       'extract scan line buffer address
    4a63c     18 F0 07 F1 | mailbox2                    add     ptra, #24               'skip past the init parameters
    4a640     F8 0B 00 F6 | paramaddr                   mov     paramaddr, ptra         'save pointer to first region data
    
  • Shrug.
  • Eric,
    T'was just reading the command help for Fastspin and noted the "-2b" parameter description could be updated to include RevC silicon since there is no software differences.
  • rogloh wrote: »
    @ersmith Why does fastspin's listing file not show any COG relative addresses for all the embedded COG objects in my SPIN2 projects written in PASM (with ORG 0 lines) apart from some brief COG address from the very first object at hub address $400?

    Well, the technical reason is that the DAT sections of sub-objects are compiled first, and seperately (so that labels in them don't conflict, and also so that spin2cpp can output them as hex codes while still translating the Spin to C), so the listing file doesn't actually see the original assembly code for objects, just the compiled code with some comments giving the original code (see the .p2asm file for what exactly gets compiled).

    The "human" reason is that nobody noticed that and complained before :). I agree that it would be nice if the COG addresses showed up, and I'll try to figure out a way to pass that information through to the listing.
    evanh wrote: »
    T'was just reading the command help for Fastspin and noted the "-2b" parameter description could be updated to include RevC silicon since there is no software differences.

    Good point.

    Thanks for the bug reports, guys!

  • When coding a larger application, I came across the following. I reduced it to a simple test case.
    #include <stdio.h>
    #include <unistd.h>
    #include <math.h> 
    
    #include <propeller.h>
    #define P2_TARGET_MHZ 160
    #include "sys/p2es_clock.h"
    
    #define BAUD 230400
    
    void main ()
    {
    	clkset(_SETFREQ, _CLOCKFREQ);
        _setbaud(BAUD);
        sleep(1);
        
    	float real1 = 0.5;
    	printf("%f\n",fabs(real1));	
    	if ( fabs(real1) >= 1.0 ) puts("!\n");
    	
    	return 0;
    }
    
    

    compile and run
    fastspin -2b fabs.c
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
    Version 4.1.0-beta- Compiled on: Jan  5 2020
    fabs.c
    fputs.c
    sleep.c
    fmt.c
    math.c
    ftab.c
    fabs.p2asm
    Done.
    Program size is 9504 bytes
     loadp2  -t -b230400 -p/dev/ttyUSB0 fabs.binary
    ( Entering terminal mode.  Press Ctrl-] to exit. )
    0.500000
    !  <----------------- I wasn't expecting this. 0.5 < 1.0
    
    
  • Reinhard wrote: »
    When coding a larger application, I came across the following. I reduced it to a simple test case.
    #include <stdio.h>
    #include <unistd.h>
    #include <math.h> 
    
    #include <propeller.h>
    #define P2_TARGET_MHZ 160
    #include "sys/p2es_clock.h"
    
    #define BAUD 230400
    
    void main ()
    {
    	clkset(_SETFREQ, _CLOCKFREQ);
        _setbaud(BAUD);
        sleep(1);
        
    	float real1 = 0.5;
    	printf("%f\n",fabs(real1));	
    	if ( fabs(real1) >= 1.0 ) puts("!\n");
    	
    	return 0;
    }
    
    

    compile and run
    fastspin -2b fabs.c
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
    Version 4.1.0-beta- Compiled on: Jan  5 2020
    fabs.c
    fputs.c
    sleep.c
    fmt.c
    math.c
    ftab.c
    fabs.p2asm
    Done.
    Program size is 9504 bytes
     loadp2  -t -b230400 -p/dev/ttyUSB0 fabs.binary
    ( Entering terminal mode.  Press Ctrl-] to exit. )
    0.500000
    !  <----------------- I wasn't expecting this. 0.5 < 1.0
    
    
    You might need to put an infinite loop at the end of main() so it doesn't exit.

Sign In or Register to comment.