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

1333436383970

Comments

  • return 0 in void main () is because I first tested it on the PC with the usual int main (). When copying into the P2 testsuite I forgot to delete. I have now done that because I noticed that after posting. But it doesn't change the result.
  • I want to use fabs() in the underlaying code.
    In the function cplx_mult_float (z1r,z1i,z2r,z2i,&result_r,&result_i) I'll make a standardization to an unit vector. My first idea was to check with fabs whether this was necessary.
    //Example:  Multiplication of 2 complex numbers
    //input:  z1 = real1,imag1
    //        z2 = real2,imag2
    //calc:   z3 = z1 * z2
    //output: real3,imag3
    //
    //testcase: z2 = conj(z1)
    //expected: z3 is pure real. imag3 = 0. 
    
    #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
    
    #define TOFIX(d, q) ((int)( (d)*(double)(1<<(q)) ))
    #define TOFLT(a, q) ( (double)(a) / (double)(1<<(q)) )
    #define q 16
    
    void cplx_mult_float (double real1, double imag1,
    					  double real2, double imag2,
    					  double *res_r,double *res_i)
    {
    
    	int32_t r1 = TOFIX(real1,q);
    	int32_t i1 = TOFIX(imag1,q);
    	int32_t r2 = TOFIX(real2,q);
    	int32_t i2 = TOFIX(imag2,q);
    	
    	
    	
    	int32_t r;
    	int32_t i;
    	cplx_mult_fix (r1,i1,r2,i2,&r,&i);
    	*res_r = TOFLT(r,q);
    	*res_i = TOFLT(i,q);	
    	
    	printf("--debug-- %X %X %X %X %X %X\n",r1,i1,r2,i2,r,i);
    }
    
    void cplx_mult_fix (int32_t real1,   int32_t imag1,
    					int32_t real2,   int32_t imag2,
    					int32_t * real3, int32_t * imag3)
    {
    int32_t _abs1;
    int32_t _arg1;
    int32_t _abs2;
    int32_t _arg2;
    int32_t _abs3;
    int32_t _arg3;
    int32_t result_lo = 0;
    int32_t result_hi = 0;
    __asm {
    	qvector	real1,imag1		//z1 to polar	
    	getqx	_abs1
    	getqy	_arg1
    	qvector	real2,imag2		//z2 to polar	
    	getqx	_abs2
    	getqy	_arg2
    	//qmul	_abs1,_abs2		//multiply the abs
    	//getqx	result_lo
    	//getqy	result_hi
    	//add		result_hi,result_lo
    	
    	mul	_abs1,_abs2
    	mov	result_lo,_abs1
    	mov	_abs3,result_lo
    	shr	_abs3,#16
    
    	add	_arg1,_arg2			//add the phase	
    	mov	_arg3,_arg1
    	qrotate	_abs3,_arg3		//z3 to cartesian
    	getqx	result_lo
    	getqy	result_hi
    	mov	outa,result_lo	
    };	
    *real3 = result_lo;
    *imag3 = result_hi;
    
    }
    
    void main(void)
    {
    double z1r = 0.5;
    double z1i = 0.5;
    double z2r = 0.5;
    double z2i = -0.5;
    double result_r;
    double result_i;
    
    
    	clkset(_SETFREQ, _CLOCKFREQ);
        _setbaud(BAUD);
        sleep(1);
    
    	cplx_mult_float (z1r,z1i,z2r,z2i,&result_r,&result_i);
    	printf("(%f,%f) * (%f,%f) = (%f,%f)\n",z1r,z1i,z2r,z2i,result_r,result_i);
    	
    	cplx_mult_float (1.0,1.0,1.0,-1.0,&result_r,&result_i);
    	printf("(%f,%f) \n",result_r,result_i);
    	
    	cplx_mult_float (0.7,0.7,0.7,-0.7,&result_r,&result_i);
    	printf("(%f,%f) \n",result_r,result_i);
    }
    
    

    on the output you see the problem
    loadp2  -t -b230400 -p/dev/ttyUSB0 cplx_mult_c.binary
    ( Entering terminal mode.  Press Ctrl-] to exit. )
    --debug-- 8000 8000 8000 FFFF8000 8000 0
    (0.500000,0.500000) * (0.500000,-0.500000) = (0.500000,0.000000)  --- correct
    
    --debug-- 10000 10000 10000 FFFF0000 2BEC 0
    (0.171570,0.000000)  --- not correct, here I need an unit vector 
    
    --debug-- B333 B333 B333 FFFF4CCD FAE0 0
    (0.979980,0.000000)  ----- correct
    
    
    Maybe I can think of a workaround.
  • David BetzDavid Betz Posts: 14,191
    edited 2020-01-18 - 15:59:02
    > @Reinhard said:
    > return 0 in void main () is because I first tested it on the PC with the usual int main (). When copying into the P2 testsuite I forgot to delete. I have now done that because I noticed that after posting. But it doesn't change the result.
    What I meant is to put this at the end of main() so that the function doesn't exit. Exiting main() probably halts the chip or something like that.
    while (1) ;
  • Ugh. What happened to the forum editor? The "C" button doesn't seem to work for me to quote code nor do the [code] [/code] tags.
  • PublisonPublison Posts: 11,785
    edited 2020-01-18 - 16:00:45
    Undergoing some work to correct the @ problems as we speak. Check back in a little while.
  • I tested it with the infinite loop, although it was never necessary, but it doesn't change anything.
    The generated pasm file says:
    	calla	#_main
    cogexit
    	cogid	arg01
    	cogstop	arg01
    
    the problem is
    if ( fabs(real1) >= 1.0 ) 
    
    is always true.
    By the way, the code above only has to do with the problem because I want to show what I need fabs for. But I think I can solve it differently.

    Reinhard
  • > @Reinhard said:
    > I tested it with the infinite loop, although it was never necessary, but it doesn't change anything.
    > The generated pasm file says: calla #_main cogexit cogid arg01 cogstop arg01
    >
    > the problem is if ( fabs(real1) >= 1.0 )
    >
    > is always true.
    > By the way, the code above only has to do with the problem because I want to show what I need fabs for. But I think I can solve it differently.
    >
    > Reinhard

    It's the stopping of the COG that I thought might be causing your problem. I've sometimes had trouble with that.
  • Ah, thanks for the note, I'll keep that in mind. but i think the problem here is somewhere else, maybe even behind my eyes ;-)
  • @Reinhard: I think the fabs bug has already been fixed in github. The fabs function was defined in Spin and didn't have a return type, so in the comparison it was being treated as an integer. Assigning it to a temporary variable (float t = fabs(real1), then using "t" everywhere you had fabs(real1)) would be a work-around. Or you could build the beta from source. I hope to put out a new release "soon", but things keep coming up to delay it :(.

  • No rush.
    as soon as new sources are available, I compile the current status.
    I just noticed that they are not just doing FlexGui, which already supports some languages. But also uPhyton and an risc compiler.
    I did some tests with upython, everything was great, but I'm not a py programmer.
    what i want to say, take your time and don't allow any stress.
  • Eric, it looks like fastspin 4.1.0 now supports Chip's RevB+ silicon PNut changes of the |< operator to DECOD and the >< operator to REV when used in a CON block?
    DECOD works as expected but REV appears to work the same as >< where it reverses the number of bits, whilst the new REV syntax is in terms of MSB bit position:
    CON
            SPIN1_REV = %0_0101 >< 5        ' %1_0100 count of bits
            PNUT_REV  = %0_0101 REV (5 - 1) ' %1_0100 new syntax MSB is bit 4, fastspin result is %1010
    
  • Ah, thanks @garryj, I missed that REV was different from ><. So basically
      a REV b == a >< (b+1)
    
    is that right?
  • ersmith wrote: »
    Ah, thanks @garryj, I missed that REV was different from ><. So basically
      a REV b == a >< (b+1)
    
    is that right?

    That would be it. Thanks, Eric!
  • @ersmith,

    Just an observation. I noticed a difference between Propeller Tool v1.3.2 and flegui4.10 from a SPIN/PASM standpoint. Code compiles fine in Propeller Tool but errors are thrown in Flexgui compiling for a Prop1 on Windows 10.

    The label asm throws an Error in Flexgui but compile fine in Propeller Tool.
    {{ Tutorial 3 Basic addition in pasm}}
    
    CON
    _clkmode = xtal1 + pll16x
    _xinfreq = 5_000_000
    
    var
      long x
      long y
      long total
    obj
    
    pst:"parallax serial terminal"
    
    pub main
      x := 30 
      y := 45
      
      pst.start(115200)           
    
      waitcnt(clkfreq*5 + cnt)       
    
      cognew(@asm, @x)              
    
      waitcnt(clkfreq*2 + cnt)              
    
      pst.str(string("total:"))
      pst.dec(total~)
      pst.newline
    
    dat
    asm     org
    
            mov tempvar, par        ' get the address of x from par
            mov xvar, tempvar       ' assign the address to the xvar in pasm
            rdlong xvar, tempvar    ' read the value that is in x 
            add tempvar, #4         ' move over one long to get the address of y 
            mov yvar, tempvar       ' assign the address to yvar
            rdlong yvar, tempvar    ' read the value that is in y
            add tempvar, #4         ' move over one long to get the address of total
            mov totalvar, tempvar ' assign the address to totalvar
            add xvar,yvar           ' add x and y together , answer in xvar
            wrlong xvar, totalvar ' Write x into the total variable for printing
    
    {{ Reserved variables for PASM use }}
    
    tempvar long 0
    xvar long 0
    yvar long 0
    totalvar long 0
    flag long 0
    fit
    
  • asm is a reserved word in Flex to mark inline PASM, Proptool does not support inline pasm so asm is not a reseved word there.

    rename the label to myasm and everything should work with both.

    Mike
  • @TrapperBob : thanks for the bug report. As @msrobots noted, the conflict is because fastspin has "ASM" as a new reserved keyword. For the next release I'll try to make this case and some similar ones work (by treating "ASM" as a regular label in some contexts) but for now changing the word "asm" to something else like "myasm" will fix the problem.
  • I personally like the version of inline pasm enclosed in asm...endasm better then Chips version of just using org.

    It makes more sense as re-using org and is more consistent with the language itself. ASM can just be a reserved word. No need for context sensitive filtering.

    What I think would be nice if that internal system.spin object (or however you call it) you are using to resolve methods not found in sub objects, could be shared between FLEX and Chips Interpreter.

    That would also allow Chip to move some stuff in the common spin file like Smart Pin modes, or other SPIN language enhancements, while FLEX and the interpreter still will work alike.

    anyways,

    Mike
  • _ASM & _ENDASM for inline code maybe ???
  • Reinhard wrote: »
    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 --

    I download the newest (4.0.1) Spin2cpp / Fastspin sources.
    Problem with Parameter passing solved .
    Reinhard
  • @ersmith
    I understand, that is not necessary to implement sin() and cos() in fastspin.
    Therefore we have the cordic - unit.
    But is it possible to implement asin() and acos() ?
    or does someone know a way to calculate these functions with the available means?
    I need this for a 'hot' project.
    Reinhard
  • JRoarkJRoark Posts: 566
    edited 2020-01-25 - 20:08:20
    @ersmith While coding in FlexBASIC on Win10 using FlexGUI V4.1.0:

    I'm having some relationship issues with FlexBASIC. :) Specifically, something appears wonky in the DATA/READ pairing. This code:
    dim a(15) as ulong
    dim n as long
    
    data &h00_00_00_00, &h00_00_AA_00, &h00_AA_00_00, &h00_AA_AA_00, &hAA_00_00_00, &hAA_00_AA_00, &hAA_55_00_00, &hAA_AA_AA_00
    data &h55_55_55_00, &h55_55_FF_00, &h55_FF_55_00, &h55_FF_FF_00, &hFF_55_55_00, &hFF_55_FF_00, &hFF_FF_55_00, &hFF_FF_FF_00
    
    for n = 0 to 15
    	read a(n)
    	print a(n)
    next n
    
    ...yields this for output:
    0, 0, 0, 0, 170, 170, 170, 170, 85, 85, 85, 85, 255, 255, 255, 255
    
    What do you think? I'm torn between begging and chocolate here. lol.

    EDIT: Its the underscore characters. The parser is fine with the "&h" notation, but its fussy at the underscores.
  • yetiyeti Posts: 751
    edited 2020-01-25 - 20:16:14
    @JRoark ... remove the "_" in the data statements.

    But is there a special reason to have the data statements?
    Why not as shared array with initialiser?
    $ cat jr20200125.bas 
    dim shared as ulong a(15) = { _
     &h00_00_00_00, &h00_00_AA_00, &h00_AA_00_00, &h00_AA_AA_00, _
     &hAA_00_00_00, &hAA_00_AA_00, &hAA_55_00_00, &hAA_AA_AA_00, _
     &h55_55_55_00, &h55_55_FF_00, &h55_FF_55_00, &h55_FF_FF_00, _
     &hFF_55_55_00, &hFF_55_FF_00, &hFF_FF_55_00, &hFF_FF_FF_00  _
     }
    dim n as long
    
    for n = 0 to 15
     print a(n)
    next n
    
    $ quiet fastspin jr20200125.bas 
    $ spinsim -b jr20200125.binary 
    0
    43520
    11141120
    11184640
    2852126720
    2852170240
    2857697280
    2863311360
    1431655680
    1431699200
    1442796800
    1442840320
    4283782400
    4283825920
    4294923520
    4294967040
    
  • Reinhard wrote: »
    @ersmith
    I understand, that is not necessary to implement sin() and cos() in fastspin.
    Therefore we have the cordic - unit.
    But is it possible to implement asin() and acos() ?
    or does someone know a way to calculate these functions with the available means?
    I need this for a 'hot' project.
    Reinhard

    I think you could implement asin() and acos() in terms of the CORDIC xy to polar conversion. That is, acos(x) is the angle t for which cos(t) = x, so it's the angle you get when you convert (x, sqrt(1-x^2)) to polar coordinates (if x is in the appropriate quadrant, and is between 0 and 1). You do have to do some sanity checking and have code to handle negatives and such, but that's the basic idea. asin() is similar.
  • @JRoark : as you've discovered, the underscores aren't read properly in READ. Either get rid of them, or use @yeti's suggestion of initializing a static array instead of using DATA/READ. This is a bug, but the whole underscore thing is an extension anyway so I guess it could also be called a "feature" :).
  • @yeti I didn't know you could do that! But that's how I'll do it from now on. Cool! And thanks!

    @ersmith I think all this needs is a brief mention in the manual as a "fix". Honestly, I hate "data/read". It's ugly. But sometimes it's the only way.

    What would be neat is having something in BASIC like the FILE feature of Spin. What led me to this point was trying to make a font table in BASIC that I can pass to Rogloh's video driver. In Spin its easy and you can stick a file in memory with just a...

    FILE "myfont.fon"

    ...and Bob's your uncle. In BASIC... oy vey... you have to bang it in manually.
  • @JRoark ... numeric "data" is stored as unprocessed strings and an initialised array will store the binary representation of the numbers.

    From the version with "data":
    00000d80  6b ee fc 5c 3b 84 fc 5c  26 68 30 30 30 30 30 30  |k..\;..\&h000000|
    00000d90  30 30 2c 20 26 68 30 30  30 30 41 41 30 30 2c 20  |00, &h0000AA00, |
    00000da0  26 68 30 30 41 41 30 30  30 30 2c 20 26 68 30 30  |&h00AA0000, &h00|
    00000db0  41 41 41 41 30 30 0a 26  68 41 41 30 30 30 30 30  |AAAA00.&hAA00000|
    00000dc0  30 2c 20 26 68 41 41 30  30 41 41 30 30 2c 20 26  |0, &hAA00AA00, &|
    00000dd0  68 41 41 35 35 30 30 30  30 2c 20 26 68 41 41 41  |hAA550000, &hAAA|
    00000de0  41 41 41 30 30 0a 26 68  35 35 35 35 35 35 30 30  |AAA00.&h55555500|
    00000df0  2c 20 26 68 35 35 35 35  46 46 30 30 2c 20 26 68  |, &h5555FF00, &h|
    00000e00  35 35 46 46 35 35 30 30  2c 20 26 68 35 35 46 46  |55FF5500, &h55FF|
    00000e10  46 46 30 30 0a 26 68 46  46 35 35 35 35 30 30 2c  |FF00.&hFF555500,|
    00000e20  20 26 68 46 46 35 35 46  46 30 30 2c 20 26 68 46  | &hFF55FF00, &hF|
    00000e30  46 46 46 35 35 30 30 2c  20 26 68 46 46 46 46 46  |FFF5500, &hFFFFF|
    00000e40  46 30 30 0a 00 00 00 00  b6 02 00 00 cc 0e 00 00  |F00.............|
    

    Compiled without optimisation:
    $ ls -l jr*binary
    -rw-r--r-- 1 yeti yeti 2868 Jan 25 21:09 jr20200125.array.binary
    -rw-r--r-- 1 yeti yeti 3880 Jan 25 21:08 jr20200125.data.binary
    
  • @yeti Well, that IS interesting. I never saw that one coming! That's good to know. Saves a bunch of precious space!
  • JRoark wrote: »
    What would be neat is having something in BASIC like the FILE feature of Spin. What led me to this point was trying to make a font table in BASIC that I can pass to Rogloh's video driver. In Spin its easy and you can stick a file in memory with just a...

    FILE "myfont.fon"

    ...and Bob's your uncle. In BASIC... oy vey... you have to bang it in manually.

    You can use FILE inside "asm shared" in BASIC:
    asm shared
    
    font
       file "font.dat"
    end asm
    ...
    dostuffwith @font
    
    I think the type of a label attached to a FILE will be "ubyte" but you can always cast the pointer you get.

    Pretty much anything that can go in a Spin DAT section can go in asm shared.
  • yetiyeti Posts: 751
    edited 2020-01-25 - 22:16:15
    @ersmith ... I just was trying to use FILE in a Spin source to be used from a BASIC main program... but the answer is sooo near... \o/
  • JRoarkJRoark Posts: 566
    edited 2020-01-25 - 22:43:38
    I never even thought about using ASM SHARED. (Bangs head on keyboard). But I *did* hit on doing it from a Spin stub ala Yeti’s suggestion. So now Rogloh’s driver loads its own font and palette data, and I just query the driver for the addresses... (which for the moment I pass right back to the driver as a temporary fix. Lol).

    I sincerely appreciate all of your help @ersmith and @yeti! And thanks again to @rogloh for making such an epic, hackable driver!
Sign In or Register to comment.