Big Integers



  • the support for flags is sort of quirky by now.

    After execution of a command, the current flags get returned via the command long into the SPIN return value. bit 2 is C, bit1 is Z
    In theory, you can set the flags while calling a command. Flags as above (0-3) can be set by adding the flags shifted by 8 to the command.

    so far so good.

    The issues are, that I still do not return correct flags from division or multiplication. To do that, I still need to find some spare longs in the PASM code.

    All other operations seem to return the correct flags.

    Setting the flags works also, but makes for now just a difference for RCL, all other operations (like add/sub/...) do not use the flags on entry because the extended form (addx/subx/...) is not implemented yet, doing that is not so complicated, I just need to find some space in my PASM.

    I could replace add by addx/sub by subx and then just set no carry if I wand the un-extended form, that might fit.

    All my tests show that decimal out is now working correctly in V1.3.


  • Take a look at what I did, it should have freed up quite a few longs.

    And take a look at my test program, which didn't display powers of 10 correctly.


  • Ok, I am looking.

    first thing I stumbled upon is
        biResultVar := bi.setVarClr(@bufResult,MaxLongs+MaxLongs)
        biParam1Var := bi.setVarClr(@bufParam1,MaxLongs)
        biParam2Var := bi.setVarClr(@bufParam2,MaxLongs)
        biWorkSp1Var := bi.setVarClr(@bufWorkSp1,MaxLongs+MaxLongs)
        biWorkSp2Var := bi.setVarClr(@bufWorkSp2,MaxLongs+MaxLongs)
        biWorkSp3Var := bi.setVarClr(@bufWorkSp3,MaxLongs+MaxLongs)
        biWorkSp4Var := bi.setVarClr(@bufWorkSp4,MaxLongs+MaxLongs)
        biValueE := bi.setVarClr(@bufValueE,MaxLongs) 
        biValue1 := bi.setVarClr(@bufValue1,MaxLongs)
        biValue10 := bi.setVarClr(@bufValue10,MaxLongs)
        biValueFactorial := bi.setVarClr(@bufValueFactorial,MaxLongs)
        biValueDivisor := bi.setVarClr(@bufValueDivisor,1)

    Here I set my Vars at size of Maxlongs and result/work to the double of it.
    And you set your new Vars at size of Maxlongs - this is correct

    But later on I reduce my Var size to size of InputSize and result/work to the double of it
          biResultVar := bi.setVar(@bufResult,InputSize+InputSize)
          biParam1Var := bi.setVar(@bufParam1,InputSize)
          biParam2Var := bi.setVar(@bufParam2,InputSize)
          biWorkSp1Var := bi.setVar(@bufWorkSp1,InputSize+InputSize)
          biWorkSp2Var := bi.setVar(@bufWorkSp2,InputSize+InputSize)
          biWorkSp3Var := bi.setVar(@bufWorkSp3,InputSize+InputSize)
          biWorkSp4Var := bi.setVar(@bufWorkSp4,InputSize+InputSize)

    this might not be what you want for your calculations, you should comment it out

    In CalculateE you set your Var biValue10 correctly to 10 by
      bufValue10[0] := 10                                 'Set to 10
    but you messed up with your Var biValue1 and set it to 10 as well, not to 1
    bufValue1[0] := 10
    should be
    bufValue1[0] := 1

    Your longmoves should basically work, but they do not account for different sized variables, and work/result have the double size of the parameters.

    so instead of longmove(@bufValueE, @bufResult, MaxLongs)

    better to use bi.mov_(biValueE ,biResultVar)

    this zero extends or truncates the values moved.

    for signed extension use bi.movs_(..)

    All operations can use different sized variables, the PASM code should take care of it.

    Your variables biValue1 and biValue10 can be one long sized like I did with InputSize, instead of
    long    biValue1
    long    biValue10
    long    bufValue1[MaxLongs]
    long    bufValue10[MaxLongs]
        biValue1 := bi.setVarClr(@bufValue1,MaxLongs)
        biValue10 := bi.setVarClr(@bufValue10,MaxLongs)
    bufValue1[0] := 1
    bufValue10[0] := 10
    you could save a lot of space by reducing the buffer size
    long    biValue1
    long    biValue10
    long    bufValue1
    long    bufValue10
        biValue1 := bi.setVarClr(@bufValue1,1)
        biValue10 := bi.setVarClr(@bufValue10,1)
    bufValue1 := 1
    bufValue10 := 10

    I really like your time measurement. This is nicely done. I never had time to play with the counters.



  • On a different subject, I stumbled over the thread of @Cluso99 regarding a Simple As Possible CPU.

    He has a instruction set of 16 instructions and I sort of noticed that the commands I do have are almost the same as his instructions.

    And now I am thinking (dangerous) if I could use the BigInt math for simulating a CPU with a variable register-size.

    @cluso99 uses currently 4 bits for instruction, I might go for 5 bits to support all existing BigInt operations, but I never wrote a CPU emulator and have to ponder about all of this a bit.

    BigInt Variables are just pointer to a memory block, and if all registers of the CPU are BigInts, the same byte code could run with 32 bit registers or 96bit or whatever fits into memory-bits per register.

    It sounds really useless, for me one more reason to try it. On the other hand it sounds like a lot of fun.


  • msrobotsmsrobots Posts: 3,076
    edited 2017-09-04 - 00:26:17
    Ohh I spoke to soon.

    I had to remove movs_ and mov_ does just copy the smaller size.

    its safer as your longmoves since it does not overwrite buffers, but not better.

    I had planned to integrate zero or signed extensions for mov but it never fit.

    But this is just for mov_

    all other signed commands like adds_ subs_, muls_, divs_ do expand their parameter correctly as signed parameter while the unsigned commands extend parameters unsigned, aka zero filled.

    I need to get BigInt PASM smaller. Will start with your suggestion of TJZ/TJNZ


  • Thanks for the suggestions, I didn't do anything with this yesterday but will look at it tonight.

    A cpu with big integers would be interesting.

    So would (hint, hint) an extension: big decimals. Basically assigning and tracking an implied decimal point.

    I estimated that my IBM 1130 emulator project - which is how I got into the Propeller world - would take 6 months.

    It's now 7 years, 7 months. And counting. There are still some things that I look at how I implemented them and want to rewrite the code. Never mind that it works. It's just plain ugly.

    And nothing is truly useless if you learn from it. And if you have fun while learning, great!

  • wmosscrop wrote: »

    And nothing is truly useless if you learn from it. And if you have fun while learning, great!


  • msrobotsmsrobots Posts: 3,076
    edited 2017-09-13 - 02:32:32
    Big Decimals. Hmm. Interesting

    for my Gcode Test I also have to wander into decimal point handling.

    Using TJZ/TJNZ I was able to recover 7 longs. not bad, now I need to use them wisely...


  • OK, a newer version.

    I was able to squeeze some more longs out of the PASM and was able to combine RCL/SHL/RCR/SHR better.

    I also decided to replace MOV by CPY, because MOV does not move anything it copies.

    Slowly this piece of goal-less software is forming into something, but I am still not sure into what, exactly.

    It now supports:

    cAdd,cAdds,cBit,cClr,cCmp,cCmps,cCpy,cCpys,cDiv,cDivs,cMul,cMuls,cNeg,cRcl,cRcr,cShl,cShr,cSub,cSubs for multiple-long-longs.

    CPY and CPYS will zero or sign extend while copying, or truncate to the size of the result. Same goes for the Parameter of the other instructions.

    After understanding @TonyB's usage of the Flags to also signal overflow, I will try to build that in also. I have still some longs left in PASM!

    Currently Div and Mul require that the result-variable is different of the parameters, I need to use a second work variable to avoid that.

    so ADD var1,var1,var1 (var1:=var1+var1) works but mul and div need a separate result MUL var1,var2,var2 works, MUL var1,var1,var1 not.

    I also gave spin own buffers for decimal output, so the main 4 test variables stay undisturbed by decimal output to serial.

    as usual serial input/output at 115200, press THE ANY KEY when your terminal is ready to test it out.

  • jmgjmg Posts: 14,246
    msrobots wrote: »
    Slowly this piece of goal-less software is forming into something, but I am still not sure into what, exactly.
    Big numbers are useful to have, for the PC side I like the ConsoleCalc from Zoesoft, but I think they may have let the website lapse ?

    I'm not as sure what a MCU could use them for, but perhaps an open source calculator based on the Prop, as a teaching project ?
    That would need a prop and a small display, and some keyboard means ?
    or maybe include a larger-font terminal ?
    I've thought about a larger font terminal a few times for instruments etc ?

  • Yeah, I can't really find a use for it.

    I even thought BIG and took the current American Debt, but 3 longs are already good for it.

    Astronomy would be one place where high integer precision would make sense, and I might be able to build floating point on top of variable long integers.

    On the other hand this could be nice for VGA, adding memory areas of the screen memory? subtracting from it?

    The content of a variable is just a memory block. Can be anywhere, even in the ROM part.

    just some silly project, like the idea to use FASM as assembler for the P2. I love it, but its not really platform independent, being written in assembler. For me? I would love it, and I happen to not use ARMs so FASM and FASMG works fine for me.



Sign In or Register to comment.