Menu

The cmach.c module

2018-04-11
2018-04-16
  • Scott Franco

    Scott Franco - 2018-04-11

    The cmach.c module

    A new module has been created, cmach.c. It is a direct, by hand translation of pmach.pas, the P6 interpreter engine created previously.

    To review, pmach.pas is the interpreter engine from pint.pas, but stripped of the assembler and debugger. This makes it much more compact (about 3000 lines vs more than 6000 lines for pint.pas) as well as demonstrating how a stand-alone P6 machine is implemented.

    To make that work, pint included a mode switch (e+) that caused it to output a binary object deck and stop. That binary is then loaded by pmach and run. Several changes led up to this ability, including simplifying and unifying the program deck. The code and fixed constants for the program are in a single block of code designed to be loaded at location 0. If multiple modules exist, they are concatenated into that single block, with the program module at the end. Pint effectively acts as a linker/loader to make that happen.

    Along with multiple module support, the operational scripts such as p6.bat, compile.bat and run.bat now support a --pmach switch to run program decks via the pmach interpreter.

    Now there is available a translation of pmach.pas into the file cmach.c. This is an ANSI C (C89) translation of pmach.pas. Why was this done, and what capabilities does it offer?

    First, cmach.c is a exact functional equivalent to pmach.pas. It even emulates some of the bad characteristics of GPC to stay compatible (by option, it can use the PRD and PRR files, which is due to the poor implementation of header files by GPC -- neither IP Pascal nor FPC have this limitation). The idea is it a complete, drop in replacement for pmach.pas.

    Second, cmach.c uses only ANSI C in the form of C89. I resisted the temptation to use advanced caracteristics of C99 like nested functions, inlining, etc.

    What cmach.c brings to the table is that it allows P6 to run on any system with a reasonable C implementation. The only limitation is how well the target C compiler complies with C89. This allows implementations on systems where there is no P6 code generator, or perhaps never will be. I suspect that there will never be a direct P6 implementation on a 16 bit machine, for example, simply because I don't think there is much reward at this date for doing that (2018).

    I use several embedded processors, but they are 32 bit with full GCC compilers. The days when it was necessary to use 16 bit, or even 8 bit machines (which really are 16 bit machines as far as compilers are concerned) were required to "go embedded" are gone.

    Finally, there is limited time to implement backends, especially if only I do it (volunteers would be appreciated!). So mach makes a quick bridge to machines that are reasonable but have no code generators.

    New operational modes

    cmach.c will implement a new mode I call "packaged binary" mode. A translator program, genobj, takes the binary object deck from pint and converts it to a C format data table. This is then compiled/linked with cmach.c, which detects it and uses that as the program deck. cmach no longer looks for an object file, and just directly runs the program.

    The advantage of packed binary mode is that the resulting program operates exactly as a compiled P6 binary does, except for being slower.

    Targets for P6

    This makes three ways to run P6 programs, using the interpretive engine in pint, the mach engine in pmach, or the mach engine in cmach. Another way would be to use Trevor's p5c translator, of which I admit I don't have much experience.

    I personally prefer direct to code translation, and that will occur shortly.

     
  • Scott Franco

    Scott Franco - 2018-04-16

    Epilog for cmach.c

    This code is tested and complete. Extra effort was put into making it run fast. It show the following times on fbench, a Pascal benchmark:

    Packaged mode, DOCHKDEF and DOSRCLIN both off: 1.147s on fbench.

    GPC direct compile of fbench: 0.184s

    Thus the interpreted version is 6.2 times slower, and is under the 10 times slower "rule of thumb" I have observed with interpreters.

     

Log in to post a comment.