Shop OBEX P1 Docs P2 Docs Learn Events
flexspin compiler for P2: Assembly, Spin, BASIC, and C in one compiler - Page 49 — Parallax Forums

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

14647495152116

Comments

  • David Betz wrote: »
    Thanks! Adding the extra underscore worked fine. How big is the default HEAPSIZE? I assume I need a heap since I'm calling fopen but how big a one is necessary to use the filesystem code? I don't ever call malloc or calloc myself.

    I think the default 4K should be big enough for the filesystem code.
  • Rayman wrote: »
    Looks to me like Wine works on Catalina, but 32-bit apps don't. So, fastspin and flexgui would have to be built as 64-bit applications to work...

    For fastspin you can just use the Mac binaries that come with FlexGUI; no need for wine at all.
  • You do have to bypass the gatekeeper that threatens to move these apps to the Trash. Hold the control key while you click on each of the apps in a Finder window. In the menu you get, choose to open the file rather than Trash it. In my case, the Mac tries to open the file using GraphicConverter. Regardless, the OS then marks the file as safe to open.
  • Mike Green wrote: »
    You do have to bypass the gatekeeper that threatens to move these apps to the Trash. Hold the control key while you click on each of the apps in a Finder window. In the menu you get, choose to open the file rather than Trash it. In my case, the Mac tries to open the file using GraphicConverter. Regardless, the OS then marks the file as safe to open.

    Oh, darn it. I hadn't realized that Apple had implemented that -- on my old Mac Mini everything is fine, but it's running an old Mac OS. Does the gatekeeper cause trouble for programs launched from the command line as well, or is it only if you launch the program from Finder?
  • ersmith wrote: »
    Mike Green wrote: »
    You do have to bypass the gatekeeper that threatens to move these apps to the Trash. Hold the control key while you click on each of the apps in a Finder window. In the menu you get, choose to open the file rather than Trash it. In my case, the Mac tries to open the file using GraphicConverter. Regardless, the OS then marks the file as safe to open.

    Oh, darn it. I hadn't realized that Apple had implemented that -- on my old Mac Mini everything is fine, but it's running an old Mac OS. Does the gatekeeper cause trouble for programs launched from the command line as well, or is it only if you launch the program from Finder?
    I haven't had trouble launching fastspin and loadp2 from the command line. Not sure about flexgui.

  • Any attempt to open or execute the *.mac files in your flexgui archive comes up with a dialog that warns you about dangerous programs and offers to move them to the Trash. This comes up regardless of whether you're working from the command line or the Finder or if some other running program attempts to execute them. If you first control-click on the file using the Finder and attempt to open the file, you'll get this dialog that asks your permission to open the file. In my case, GraphicConverter has registered itself as knowing what to do with *.mac files. It doesn't really, but it will open the file, then complain about it not being something that it recognizes. When the file has been opened once, it's marked as OK and all is good until your next release.
  • Ahle2Ahle2 Posts: 1,178
    edited 2020-05-04 12:44
    ersmith wrote: »
    Cluso99 wrote: »
    Ahle2 wrote: »
    Eric,

    Is there a way of easily calling a Spin2 functions from PASM (in an interrupt service routine)? Or do I have to know everything about the calling conventions and internal workings of FastSpin?

    /Johannes

    You would need to have the spin interpreter loaded and initialised, so you would have needed to call pasm from spin.
    Don't forget that since spin is interpreted it will be much slower than pasm so it's not ideal.

    @Ahle2 is using fastspin, so no need for the spin2 interpreter -- fastspin compiles Spin and Spin2 to machine code directly.

    In general calling back to Spin2 from PASM in fastspin can be accomplished most easily via a function pointer. If "myobj.foo" is a method, then "@myobj.foo" is a 32 bit pointer to two 32 bit values: the first is a pointer to the "myobj" object data, and the second is a pointer to the function to call. So you can do something like:
        ' call via function pointer currently in pb
        ' pb points to (object, method) pair
        wrlong objptr, ptra++  ' push current object pointer
        rdlong objptr, pb      ' fetch new object pointer
        add    pb, #4
        rdlong pb, pb          ' fetch function pointer
        calla  pb              ' call function
        sub    ptra, #4
        rdlong ptra, objptr    ' restore object pointer
    
    This won't always be safe in an ISR though because the code fastspin generates isn't re-entrant.

    Thanks Eric!

    I kind of got my ISR code running with high level Spin2 code by block moving the 512 cog registers to hub on entry and block moving them back on exit. It fails after some time, so is there something more I have to take into consideration? Without the block move it fails immediately, so it helps, but not completely!

    /Johannes
  • Mike Green wrote: »
    Any attempt to open or execute the *.mac files in your flexgui archive comes up with a dialog that warns you about dangerous programs and offers to move them to the Trash. This comes up regardless of whether you're working from the command line or the Finder or if some other running program attempts to execute them. If you first control-click on the file using the Finder and attempt to open the file, you'll get this dialog that asks your permission to open the file. In my case, GraphicConverter has registered itself as knowing what to do with *.mac files. It doesn't really, but it will open the file, then complain about it not being something that it recognizes. When the file has been opened once, it's marked as OK and all is good until your next release.

    Ah, that sucks. I'll try to figure out a way to use codesign with my signing certificate. Unfortunately the directions for MacOS are really sketchy and may be out of date, so I don't know if I can get it to work. I wish there were a version of codesign for Linux (the Windows equivalent of codesign does have a Linux port, which is why I can build the signed Windows binaries on my Linux machine).
  • Ahle2 wrote: »
    I kind of got my ISR code running with high level Spin2 code by block moving the 512 cog registers to hub on entry and block moving them back on exit. It fails after some time, so is there something more I have to take into consideration? Without the block move it fails immediately, so it helps, but not completely!
    /Johannes

    The state of the Cordic (used for multiply, divide and some other operations) could also get messed up by an ISR. Unfortunately there doesn't seem to be any way to save that state :(.

    What exactly do you want your ISR to do? Could it not be done in another COG?
  • Ahle2Ahle2 Posts: 1,178
    I want to prove that reSounds cog attention/interrupt/double buffer mechanism works as intended triggering a read from SD card on the back buffer when needed. I have made a working poll test to prove most of it, but I'm trying to get a fully working interrupt example running. Then I want to test reSound with multiple double buffers (mixed down to two stereo channels) of different sizes running at different sample rates and triggering interrupts asynchronously. The polling version has proven most of it, but I need to make a complete working example before I release the next version of reSound.
  • Ahle2Ahle2 Posts: 1,178
    edited 2020-05-05 11:37
    Eric,

    Yes, the mul and div functions that uses the cordic is the reason why it fails sporadically, I see that now!
    Can't you just put stalli/allowi around the cordic code? It adds 4 extra cycles though, so it might not be worth it?!
    Any change that you might add support for interrupt handling in future versions of FastSpin?
  • @Ahle2: I don't really want to add stalli/allowi in the multiply code, since it's only needed for ISRs (and ISRs have problems for other reasons too, like the COG and LUT memory not being preserved). Basically the main fastspin model is that the main COG runs the high level Spin code and device drivers are running in other COGs. Unfortunately adding support for ISRs would involve a lot of work, so it's not going to happen anytime soon. (Remember that fastspin still supports P1, which doesn't have interrupts at all...)

  • Fastspin uses the CORDIC for multiplications? Interesting, I haven't noticed. I thought multiplications up to 32 bits are faster using the MUL instruction and the CORDIC unit has advantages only if you need 64 bits or are performing lots of multiplications pipelined which would be useful for filter and matrix operations but would definitely require manually optimized assembler code.
  • RaymanRayman Posts: 13,800
    MUL is just 16x16
  • Ahle2Ahle2 Posts: 1,178
    edited 2020-05-05 18:40
    This is my 32x32 multiply code from SIDcog...
    multiply      mov        r1, arg1
                  sar        r1, #16
                  mul        r1, arg2
                  shl        r1, #16
                  mul        arg1, arg2
                  add        r1, arg1
    multiply_ret  ret
    

    It runs in 12 cycles compared to the up to 68 cycles for qmul + getqx using the cordic. The cordic shines for pure throughput when a lot of math functions can be interleaved with "normal" instructions inbetween.
  • @Ahle2, that looks like a 32x16 multiply. It doesn't use the upper 16 bits of arg2.
  • RaymanRayman Posts: 13,800
    Are you sure that isn't a 32x16 multiply? Appears to assume arg2 is 16 bit...

    Also, a real 32x32 has a 64-bit result...
  • Ahle2Ahle2 Posts: 1,178
    Dave, Ray,

    Yes, I'm sorry... I just copied it straight from SIDcog, assuming it was 32x32. Didn't look it over. Memory is short!
  • Rayman wrote: »
    MUL is just 16x16

    Sure. But you can use multiples of them to get 32x32. Check out this. Markmpx claims to have a 32x32 multiplication faster than 68 cycles.
  • I just discovered something strange:
        switch (cmd.reg)
        {
        case reg_FLAG: case reg_MPOL: case reg_ETYP: case reg_ECPR: case reg_PERR: case reg_PMUL:
          float f= cmd.data.num[0];
          com.str (" SetIntPar f=");
    
    The compiler complains "syntax error, unexpected float". If I exchange the last two lines it compiles without error. (?):neutral:
    (BTW, most other compilers don't like declaring a new variable inside a switch/case statement. But this seems to work in FastSpin)
  • And another one...
    int SetParaByReg (int r, float val) ;
    int i = 32768;
    ...
    
      error= SetParaByReg (cmd.reg, i);
    
    I would expect that the compiler does an automatic type conversion (int to float) when it assigns the value of i to the second argument of the SetParaByReg function. However, what happens is that I see the bit pattern (static cast) of the integer number inside the float val argument. That is then interpreted as a very small de-normalized floating point number instead of 32768.0f.

    If I write
      float f= i;
      error= SetParaByReg (cmd.reg, f);
    
    it works as expected. Normally, this should be equivalent, I think.
  • ersmithersmith Posts: 5,900
    edited 2020-05-06 19:26
    ManAtWork wrote: »
    I just discovered something strange:
        switch (cmd.reg)
        {
        case reg_FLAG: case reg_MPOL: case reg_ETYP: case reg_ECPR: case reg_PERR: case reg_PMUL:
          float f= cmd.data.num[0];
          com.str (" SetIntPar f=");
    
    The compiler complains "syntax error, unexpected float". If I exchange the last two lines it compiles without error. (?):neutral:
    (BTW, most other compilers don't like declaring a new variable inside a switch/case statement. But this seems to work in FastSpin)

    fastspin behaves the same as gcc for both of these cases, except that gcc produces a nicer error message than "syntax error, unexpected float":
    foo.c:16:9: error: a label can only be part of a statement and a declaration is not a statement
    
    Gcc's error message is certainly more helpful, but unfortunately it would be difficult to add that to the fastspin C parser.
  • ManAtWork wrote: »
    And another one...
    int SetParaByReg (int r, float val) ;
    int i = 32768;
    ...
    
      error= SetParaByReg (cmd.reg, i);
    
    I would expect that the compiler does an automatic type conversion (int to float) when it assigns the value of i to the second argument of the SetParaByReg function.
    You haven't shown the actual definition of the SetParaByReg function; is it in Spin or some other language? fastspin largely ignores function declarations and only looks at the actual function definition in determining the types of parameters. If everything is in C then the conversion does happen, at least for my test cases.
  • ManAtWork wrote: »
    I just discovered something strange:
        switch (cmd.reg)
        {
        case reg_FLAG: case reg_MPOL: case reg_ETYP: case reg_ECPR: case reg_PERR: case reg_PMUL:
          float f= cmd.data.num[0];
          com.str (" SetIntPar f=");
    
    The compiler complains "syntax error, unexpected float". If I exchange the last two lines it compiles without error. (?):neutral:
    (BTW, most other compilers don't like declaring a new variable inside a switch/case statement. But this seems to work in FastSpin)

    Does it work if you do this?
        switch (cmd.reg)
        {
        case reg_FLAG: case reg_MPOL: case reg_ETYP: case reg_ECPR: case reg_PERR: case reg_PMUL:
          {
            float f= cmd.data.num[0];
            com.str (" SetIntPar f=");
          }
    
    (adding scope around the case)
    That would work for most normal C/C++ compilers.
  • ersmith wrote: »
    > I would expect that the compiler does an automatic type conversion (int to float)
    > when it assigns the value of i to the second argument of the SetParaByReg function.

    You haven't shown the actual definition of the SetParaByReg function; is it in Spin or some other language? fastspin largely ignores function declarations and only looks at the actual function definition in determining the types of parameters. If everything is in C then the conversion does happen, at least for my test cases.

    I thought it would always happen the same way, but the following works (prints 47000000 twice):
    static struct __using("FullDuplexSerial2.spin") com;
    
    void TestArg (float n)
    {
      com.str ("n=");
      com.hex (n, 8);
      com.tx (10);
    }
    
    void TestCast ()
    {
      int i= 32768;
      TestArg (i);
      float f= i;
      TestArg (f);
    }
    
    void main()
    {
      TestCast ();
    }
    

    I can reproduce the bug but only if I keep all of my included files. SetParaByReg() is in C but other files are in Spin. I have to try if I can make a simple example without dependecies on my hardware.

    The actual function body is
    int SetParaByReg (int r, float val)
    {
      int32_t* iPtr= &ParameterTable;
      for (int i=0; i<= maxIndex; i++)
      {
        if (*iPtr == r)
        {
          debug= val;
          if (val > GetMax (i)) return -10;
          if (val < GetMin (i)) return -11;
          block.parameter[i]= val;
          return 0;
        }
        iPtr+= 4;
      }
      val= 0.0;
      return errInvReg;
    }
    
    so the type of val in the definition is not the problem. It must have something to do with the header file though.
  • @ManAtWork : in your example, are you sure you want
    iPtr+= 4;
    
    ? That skips 4 integers, not 4 bytes.
  • Never mind. The code is ugly because it is translated from an old P1 spin program. If I had to write it again I'd define proper stuctures. Here it just reads from a lookup table, and yes, += 4 is intended and correct. The table has 4 entries for each parameter, ID, min, max and default value.

    I just found out that the above "bug" disappears if I place all code in just one main.c file. It's also gone if I write the header file like it's probably meant to be:
    // parameters.h
    bool LoadParameters () __fromfile ("parameters.c");
    bool SaveParameters () __fromfile ("parameters.c");
    float GetParameter (i) __fromfile ("parameters.c");
    int32_t GetIntParameter (i) __fromfile ("parameters.c");
    int GetParaByReg (int r, float* val) __fromfile ("parameters.c");
    int SetParaByReg (int r, float val) __fromfile ("parameters.c");
    char* GetDescriptionPtr () __fromfile ("parameters.c");
    float* GetTable () __fromfile ("parameters.c");
    float GetDebug() __fromfile ("parameters.c");
    
    My original version of the header file had only one __fromfile after the first function declaration. The compiler stopped complaining about missing labels and I forgot adding the rest. So maybe, it's not really a bug but just my fault and a missing error message.

    That's the difficulty about writing a compiler. :wink: You have to foresee all kind of stupid input. You should throw a (hopefully understandable) error message each time something is wrong or unclear. If not you will be blamed for false results even if the original fault was made by the compiler user... :neutral: (me)
    The compiler complains "syntax error, unexpected float".
    Also my fault, I see. Sometimes I don't really understand the rules of C.
  • AribaAriba Posts: 2,682
    some issues in fastspin compiler 4.1.8

    1) strings in send() methode don't work anymore and give the warning:
    'warning: only first element of string is used'
    the same happens in lookup() and maybe other places where multichar strings are allowed (case ?)

    2) the SIGNX operator works different from Spin2, to extend from word to long, fastspin needs: SIGNX 16, while Spin2 needs SIGNX 15

    Andy
  • ersmithersmith Posts: 5,900
    edited 2020-05-10 11:07
    Ariba wrote: »
    some issues in fastspin compiler 4.1.8

    1) strings in send() methode don't work anymore and give the warning:
    'warning: only first element of string is used'
    the same happens in lookup() and maybe other places where multichar strings are allowed (case ?)
    Could you give some examples of this, please? It must be context dependent somehow, because I'm able to build Chip's vga_text_demo (which uses SEND) and it seems to work fine.
    2) the SIGNX operator works different from Spin2, to extend from word to long, fastspin needs: SIGNX 16, while Spin2 needs SIGNX 15
    Thanks, that's fixed in github now.
  • AribaAriba Posts: 2,682
    Eric

    Here is a short version of my code, that shows the effect.
    If you compile and run SerialSend.spin2 alone, it works, but gives a warning that not should be.
    If you run the test2.spin2, which includes SerialSend as an object, then strange things happen.
    If I comment out the testcode in SerialSend, test2 works a bit better, which is also strange.

    Andy
Sign In or Register to comment.