Anyone interested in resurrecting an open source strict Ada 83 (mil-std 1815A) compiler?

No, as in replacing the entire back end.

Congratulations!

Since it is a DIANA-based system, I assume that you would just implement a DIANA → New-Target, or DIANA → other-IR → New-Target.

Ah… You have to write from scratch the expander procedure using idl.ads interface (in /src/ada_comp directory) and DIANA 86 documentation in /doc. You can get inspiration from my expander !

1 Like

There’s no idl generator for creating the skeleton?

I’m working on an IDL generator.

1 Like

Hi Lucretia !
Could you develop what you mean by IDL generator ? And OneWingedShark also.

IDL is a language for describing data-structures; the description file is used to generate the data-structure in the language(s) that the generator targets. So, by ‘generator’ I mean the thing that compiles an IDL file and produces the target language; I’m only planning on an Ada83 and Ada 2012 backend.

@charlie5 and I did an update to DIANA for Ada 2022; so once I get the generator up and running, we might be able to (with this compiler or AdaDoom3’s) do an Ada83 → Ada 2022 boostrap decently easily.

2 Likes

IDL = Interface Definition Language

You write API’s in IDL, run them through a generator and it generates all the framework code.

That’s the OMG IDL and, IIRC, CORBA.
The Wulf/Lamb/Nestor IDL is different; it’s only about the data-structures.
Example:

structure example root E1 is
A => a1: String;
B => b1: Integer, b2: Rational;
C => c1: Rational;

E1 ::= A | B; E2 ::= E1 | C ;

E1 => x : Integer;  -- all members of E1 have x
E2 => y : Rational; -- all members of E2 have y
end

maps to

Type E2_Base is tagged abstract record
  y : Rational;
end record;

Type E1 is tagged record
   x : Integer;
end record;

Type E1_A is new E1 with record
   a1: String;
end record;

Type E1_B is new E1 with record
   b1: Integer;
   b2: Rational;
end record;

Type E2_E1 is new E2 with record
  Data : E1;
End record;

Type E2_C is new E2 with record
   c1: Rational;
end record;

IIUC; there’s some interesting features in IDL, like the WITHOUT keyword, which eliminated a field from the derivation.

And L3/4 and AmigaOS FD files (very basic).

Hi.all
I returned on the AArch64 porting and synchronized the code_arm64.finc with the codi_x86_64.finc .

I cross assembled a TLALOC/T2arm targeted compiler on x86 then transferred it on Orange Pi 3b. On the arm Orange SBC TLALOC/T2arm compiled all predefined packages from source. Now I try to produce T3arm from TLALOC sources with T2arm on Orange Pi.

If everything works. I sync the riscv-64 codi also. and if I can make the Starfive function, I test the same process. So that I hope to have a self hosted compiler for 3 modern 64 bits processors under Linux.
After that I’ll try bare metal exe, for fun.

P.S. Update :slight_smile:

All TLALOC sources have been compiled by TLALOC/T2 in about 5 minutes on Orange Pi 3b. Thus I have a compiler for AArch…

BUT, because there is one : fasmg is written in x86 assembly ! there is no fasmg exec for arm. So I can compile all to FINC but I cannot assemble the FINCs on arm (except qemu solution perhaps). I can only assemble on x86. Wil I have to write a substitute to fasmg in Ada 83 ? :face_exhaling:

2 Likes

There is an old Universal Assembler spec: IEEE Std 694-1985,
along with a Universal Object spec: IEEE Std 695-1990.

That said, there are some really interesting papers on “cheating”:

  1. Using a High Level Language as a Cross Assembler. ← Read This Paper!
  2. Lifting Assembly to Intermediate Representation: A Novel Approach Leveraging Compilers.
  3. No More Translation at Runtime: LLM-Empowered Static Binary Translation might be useful in conjunction with
  4. Toward a foundational typed assembly language.

With Paper #1, it shows exactly how you can leverage the compiler of a high-level language to essentially handle cross-assembler work; it’s not a completely seamless model for processing already-generated assembly, but it can be used to massively reduce what you have to do.

1 Like

Hi !
Thank you for those references !

Hi.all
After some thought I decided to write a new phase TARGET_CODE in replacement of fasmg. It takes exactly the same syntax as fasmg and is intended to produce byte identical output, but just what is necessary for the backend of TLALOC. It will have no multi pass which is a costly and sometimes difficult to debug feature.
With TARGET_CODE I will have a totally independent compiler (I compile this last phase with TLALOC itself so that this new Ada 83 corpus enters the TLALOC exercise. It has already paid with some corrections of the expander as parts of TARGET_CODE are IA generated and the programming style is different from mine.

3 Likes

Hi.all
Some news :
The first exec DIS_BONJOUR obtained with TLALOC.TARGET_CODE for x86 has been obtained byte identical to the one produced by fasmg from .fas and .FINC fasmg files. Next step assembling the whole x86-64 compiler with TARGET_CODE ; then fasmg will become useless on x86. Later same objective for AArch and RISCV : eliminate fasmg.

The first executable DIS_BONJOUR for RISCV-64 obtained from famsg has been run with success. The next step is cross building and testing the whole compiler for the SBC Starfive 2 with processor RISCV-64.

The compiler has been bootstrapped on x86-64 (laptop) and AArch64 (SBC Orange Pi 3b) through fasmg. With RISCV-64 TLALOC will target the main three modern 64 bits processors.

5 Likes

Hi.all
Independence day on x86 : TLALOC.TARGET_CODE has swallowed the whole compiler’s fas and FINC includes (14 Mb of fasmg text ) and produced the 10 294 624 bytes T2 identical to fasmg.

$ ./TARGET_CODE 
NOM FICHIER .fas (sans extension, simple ret faire les tests) : ADA_COMP 
CARTO capacites : 
 elements  765721 / 1000000   differes 4519 / 200000 
 texte     14012708 / 50000000 
 symboles  200347 / 1048576   scopes 17149 / 65536 
 pool      2599348 / 16000000 
 octets    10294504 / 32000000

This wholly homemade exec has compiled T3 (of course, it is byte identical to the fasmg T2).
On x86, TLALOC now compiles itself to ELF64 with no external tool.
Now forcing on arm64 and riscv-64 independence.

5 Likes

Hi.all !

A nice landmark for Ada 83 TLALOC / TARGET_CODE. The assembly process which was done by fasmg is now successfully done by TARGET_CODE which assembles FINCs for x86-64 and AArch-64.

The whole Ada 83 compiler has been converted to LLIR on an Intel laptop and on an Orange Pi 3B/Armbian SBC and independently assembled on each one (and cross assembled also). Gnat and fasmg are now useless but for comparison.

The process is relatively simple The TLALOC source code comprises the front end (FE), the expander (XP) and target_code (TC).

At the beginning FE+XP was compiled with gnat-13 giving T1. T1 compiled all TLALOC sources in FINCs fasmg files. Fasmg was used to assemble the .fas, codi_ and FINCs in a x86 binary on an intel laptop with Ubuntu. This gave T2.

T2 with fasmg compiled and assembled all the TLALOC compiler on laptop.

Then TC1_x86 was developped for x86 directly with T2/fasmg (no gnat). Input to TC1 is fasmg syntax reduced to just useful subset for LLIR. Output of TC1_x86 is byte identical to fasmg output.
LLIR being common for all targets, AArch64 support which was from codi_arm64.finc macros has been translated to TC1 (thus TC1 now targets x86 and arm).

Arm executables (T3_arm and TC2_arm) have been cross-produced on x86 laptop and scp’ed on Orange Pi. There, the arm execs recompiled all the sources giving new arm execs (T4_arm, TC3_arm) wholly built on Orange SBC. Some tweaks with virtual memory have been used (8Gb swapfile, overcommit_memory=1).

TLALOC has now an independent building capability on x86/Linux and AArch/Linux and can cross compile itself (and programs of a comparable complexity) from one to the other (same FINCs compiled once).

The same process is underway for RISCV-64 target on Starfive Vision five 2 SBC. TC will in fine offer the choice between 3 processors for translation of fas/FINCs into static binary code.

Repos are updated. I’ll clean up the source hut repo which is the lightest of the three (framagit, github, source hut).

5 Likes

Very nice! / Congratulations!

On a tangential note, were the papers I provided helpgul?
The “Using a High Level Language as a Cross Assembler” is, I think, very useful in that you can use it to great effect in translation; there was a similar trick that I did in my implementation of Forth: use the compiler to produce the machine-code to implement the Forth words"

-- WORD: a list of words to execute, or else a set of code to execute.
Type Forth_VM is record
  -- Contains a "TEXT" -> WORD map.
  Lookup : Dictionary:= Generate_Predefined_Words;
  -- Contains the parameters/data.
  Data : Data_Stack;
  -- …
end record;

Procedure Sub( Object : in out Forth_VM ) is
 B : Storage_Element renames Pop( Object );
 A : Storage_Element renames Pop( Object );
Begin
  Push( Object, A - B );
End;

Function Generate_Predefined_Words return Dictionary is
Begin
   Return Result : Dictionary := Empty_Map do
      -- …
      Result.Include("-", To_Word(Sub'Access) )
   End return;
End Generate_Predefined_Words;

Thus, I could make the Ada compiler provide all the mechanisms needed to implement the words, and porting to another architecture becomes as simple as using GNAT (or whatever Ada compiler targeting the new architecture) — combine the two techniques and you can generate/port your executable the same way.

2 Likes

Hi OneWingShark !

Yes I read your articles, they were interesting but none was directly applicable. I had some constraints when replacing fasmg : I did not want to throw the expander, so I had to reuse fasmg syntax, but only the necessary subset. I wanted to obtain the exact same binary with fasmg and target_code to assess good working of target_code by comparison.
The good side of TLALOC’s system is that the LLIR in fasmg syntax is the same for all targets. The drawback is that each LLIR instruction is several processor instructions long and not subject to optimisation. But it works and gives a model or at least some ideas for other developments as yours.

1 Like

HI.all !

TLALOC is on RISCV-64. The sources compiled to FINCs on x86 laptop can be assembled on laptop with TARGET_CODE for x86-64, AArch-64, and RISCV-64.

Transferred on Orange Pi 3B or Starfive Visionfive 2 the cross execs can recompile/assemble the compiler for every target, so that every cross combination is possible. But some patience is required especially on Starfive (8 min for all compiler FINCs and assembles in 4 min)

Orange Pi 3B compiles all FINCs in 2 min 40 sec and assembles in 4min22sec.

Laptop with Intel i7 11800 compiles the compiler to FINCs in 7 sec and assembles in 40 sec.

I’ll try to figure out where time is spent and the relation of LLIR performance with processor structure (OoO exec or not for example).

5 Likes