Page 5 of 39

Prog8 language and compiler topic

Posted: Tue Nov 10, 2020 11:58 pm
by geek504


1 hour ago, desertfish said:




It no longer uses the software-eval-stack for that.



Hi! Is this "software-eval-stack" you mention a software-based stack used for mathematical computations based on a RPN-type stack? E.g. 2+3 becomes 2, PUSH, 3, PUSH, +? This is what I am using for my BASIC compiler. If so, it does do a lot of function calling and can be greatly optimized if one bypasses the stack entirely but involves major compiler modifications as you mentioned. This is a sample code from my compiler using macros that greatly improves readability:


Quote






10 REM ASSIGNMENT

20 AX = 3 : REM NEED TO OPTIMIZE

30 V = ABS(AX + 2)

35 Q = 1 + 2 * 6 / 3

40 PRINT "THE END"

50 END



start

  line

    10

    comment    REM ASSIGNMENT

  line

    20

    assignment

      AX

      3

    comment    REM NEED TO OPTIMIZE

  line

    30

    assignment

      V

      abs

        add_exp

          AX

          +

          2

  line

    35

    assignment

      Q

      add_exp

        1

        +

        mul_exp

          mul_exp

            2

            *

            6

          /

          3

  line

    40

    print    "THE END"

  line

    50

    end



Tree('start', [Tree('line', [Token('INT', '10'), Tree('comment', [Token('COMMENT', 'REM ASSIGNMENT')])]), Tree('line', [Token('INT', '20'), Tree('assignment', [Token('VAR_ID', 'AX'), Token('INT', '3')]), Tree('comment', [Token('COMMENT', 'REM NEED TO OPTIMIZE')])]), Tree('line', [Token('INT', '30'), Tree('assignment', [Token('VAR_ID', 'V'), Tree('abs', [Tree('add_exp', [Token('VAR_ID', 'AX'), Token('ADD_OP', '+'), Token('INT', '2')])])])]), Tree('line', [Token('INT', '35'), Tree('assignment', [Token('VAR_ID', 'Q'), Tree('add_exp', [Token('INT', '1'), Token('ADD_OP', '+'), Tree('mul_exp', [Tree('mul_exp', [Token('INT', '2'), Token('MUL_OP', '*'), Token('INT', '6')]), Token('MUL_OP', '/'), Token('INT', '3')])])])]), Tree('line', [Token('INT', '40'), Tree('print', [Token('STRING', '"THE END"')])]), Tree('line', [Token('INT', '50'), Tree('end', [])])])



.include "macros.inc"

.include "header.inc"

.code



L10:        ; REM ASSIGNMENT

L20:        PushInt 3

        PullVar AX

        ; REM NEED TO OPTIMIZE

L30:        PushVar AX

        PushInt 2

        jsr ADD

        jsr ABS

        PullVar V

L35:        PushInt 1

        PushInt 2

        PushInt 6

        jsr UMUL

        PushInt 3

        jsr UDIV

        jsr ADD

        PullVar Q

L40:        LoadAddress S0        ; to r0

        jsr PrString

L50:        rts



S0:        .asciiz "the end"

AX:        .res 2

V:        .res 2

Q:        .res 2



.include "io.asm"

.include "math.asm"

 



As you can see, line 20 does a PUSH and a PULL to/from stack for a simple AX=3. It could have simply copied over the INT 3 directly into VAR AX. I'm planning in writing a post-compiler optimizer much later. Note that I couldn't use VAR A since A is a reserved keyword in ca65!


Prog8 language and compiler topic

Posted: Wed Nov 11, 2020 9:44 am
by desertfish

Exactly like that, @geek504  the software eval stack of Prog8 is a (low/high byte split) stack indexed by the X register that functions as a second stack pointer.  Expressions like A+B are evaluated like you pointed out.   I've been working on eliminating some of the need for this stack for intermediary results and trivial expressions and assignments, but for most non-trivial expressions it is still required.

It makes the code generator itself a lot simpler however the generated code is quite inefficient in terms of 6502 assembly....


Prog8 language and compiler topic

Posted: Wed Nov 11, 2020 11:05 pm
by geek504


13 hours ago, desertfish said:




It makes the code generator itself a lot simpler however the generated code is quite inefficient in terms of 6502 assembly....



@desertfish I started coding my compiler without a stack and while I can say it was efficient, it was just too slow (edit: to code and finish the compiler) and prone to bugs... I decided to implement the stack midway just to get the compiler ready and then re-implement the non-stack improvements later if at all. I'm guessing a rough 10-15% speed improvement and am not sure if it is worth the effort right now. 6502 assembly is inefficient by nature (but very simple to implement) especially if we write proper assembly code to preserve A, X, and Y, wasting bytes and cycles with PHA, PHX, PHY, and PLY, PLX, PLA prior to every subroutine. I do feel that this is still more efficient than cc65's C-stack implementation though.

I am not worrying too much about maximum efficiency (I don't think we will ever get close to super tight assembly code) because I hope one day in the future we will be able to crank up the X16's MHz to GHz range!

At least in the emulator scene, we can implement the following 6502 JIT-core to x64 which could bring to a realistic 12GHz!

https://scarybeastsecurity.blogspot.com/2020/04/clocking-6502-to-15ghz.html?m=1

beebjit_15GHz.png.e4ed4ecc5eb06833cbbd73b194b1fa16.png


Prog8 language and compiler topic

Posted: Thu Nov 12, 2020 10:00 am
by desertfish


10 hours ago, geek504 said:




(I don't think we will ever get close to super tight assembly code)



Indeed, especially not with my compiler writing skills ?

That's why I included the inline-assembly block in prog8 from the start, to make it easy and fairly transparent to write critical pieces of code in tuned assembly


Prog8 language and compiler topic

Posted: Sun Nov 22, 2020 6:10 pm
by desertfish

I've just released Prog8 5.1

It contains a few bugfixes (such as making breakpoints in Vice work again), but the bulk of the changes are improvements to the generated assembly code.

Certain array accesses, value assignments and value comparisons have seen optimizations and the result is that the "plasma" benchmark from the millfork-benchmarks project now runs at around the same speed as the optimized CC65 version does.

 

note   I made an error in the setting of the graphics mode in this release. The VIC YSCROLL register ($d011) is not set correctly.  You can fix this in your own code or wait for the next Prog8 version to be released.... Sorry ?


Prog8 language and compiler topic

Posted: Mon Nov 23, 2020 8:07 pm
by geek504

@desertfish curious... which PRNG algorithm did you use?


Prog8 language and compiler topic

Posted: Mon Nov 23, 2020 11:41 pm
by desertfish

I use a few:

floats -> the RND routine in ROM

bytes and words -> the 'small fast' rnd routines by white flame fromhttps://www.codebase64.org/doku.php?id=base:small_fast_16-bit_prng 


Prog8 language and compiler topic

Posted: Tue Dec 01, 2020 10:12 pm
by desertfish

I've just released Prog8 5.2

It contains a few important bug fixes (some value comparisons were done wrong, for instance) and the silly YSCROLL screen issue for graphics bitmap screen mode on the C64 that crept into the 5.1 release, is also fixed.

Note:  starting with this release,  you now require Java version 11 to run the compiler.


Prog8 language and compiler topic

Posted: Tue Dec 08, 2020 10:52 pm
by desertfish

I've just released Prog8 5.3

Once again a bunch of important bugfixes have been made as well as various additions to the library modules.


Prog8 language and compiler topic

Posted: Wed Dec 09, 2020 3:47 am
by Doigt

Good work desertfish!