Forums » Programming with the ECS » Oberon »
Looking for a decently large demo project
Added by Rochus Keller over 1 year ago
I'm looking for a decently large demo project. I want to generate a large number of IR files to better understand the IR, and to create and validate an EBNF grammar of the IR syntax.
For this purpose I downloaded the Oberon System V2 Ceres source files and converted them to UTF-8. See the attached ZIP. I also added a dependency graph of the modules.
Then I added an empty implementation to Kernel.Def and was successfully able to compile it with
ecsd -i obcode Kernel.Def.
My intention was to go up the dependency tree and compile one module after the other.
When trying FileDir.Mod I got errors:
ecsd -i obcode FileDir.Mod FileDir.Mod:119:26: error: assigning 'DirMark' of signed integer type 'SIGNED64' to variable of signed integer type 'LONGINT' a.m := N; a.mark := DirMark; ^ FileDir.Mod:152:14: error: assigning 'DirMark' of signed integer type 'SIGNED64' to variable of signed integer type 'LONGINT' a.mark := DirMark; a.m := 1; a.p0 := oldroot; a.e[0] := U;
Is this to be expected? How can I configure the compiler that LONGINT is SIGNED32 instead of SIGNED64?
Or can you recommend another, better suited demo project which I could use for my purpose?
OberonSystemV2.zip (144 KB) OberonSystemV2.zip |
Replies (42)
RE: Looking for a decently large demo project - Added by Rochus Keller over 1 year ago
My goal is to generate decent IR with my compiler (not to read any IR), and I think it is fair to assume that the IR generated by your compilers is a good role model.
RE: Looking for a decently large demo project - Added by Florian Negele over 1 year ago
I would still highly recommend using the existing facilities to generate or at least serialise intermediate code rather than recreating the framework from scratch, especially if you are planning to target multiple platforms.
RE: Looking for a decently large demo project - Added by Rochus Keller over 1 year ago
I don't plan to recreate the framework; currently I just want to generate correct IR text files. But I still haven't understood everything, even though I've read various parts of the documentation several times and looked things up in the source code. In particular, the delimitation of roles with regard to platform-dependent aspects is not yet clear to me. For example, the IR and the generators are responsible for mapping certain calling conventions. But I still have to use the right offsets myself, e.g. to access parameters or local variables; and as we know, these are also dependent on the calling convention. And on Windows, for example, different calling conventions have to be used in parallel, depending on whether you are accessing a system function or a C library. I just need more time to understand which parts of ECS contribute in which way, and what I have to provide myself.
RE: Looking for a decently large demo project - Added by Florian Negele over 1 year ago
The compiler uses the same calling convention accross all architectures and platforms as described in Section 23.2.5. The only thing that differs is the alignment of stack frames and variables therein. This is what the Layout
and Platform
descriptors are for. Granted, this is not well described in the manual, see Section 26.5.4. If you need assistance, I am happy to help. Wrappers for the calling convention of the system and external funtions are provided by files like win32run.asm
and winlib.hpp
located in the runtime
directory.
RE: Looking for a decently large demo project - Added by Rochus Keller over 1 year ago
The only thing that differs is the alignment of stack frames and variables therein
Which I also have to consider in the offsets and alignments I have to write in the IR text file. Therefore even if there is only one common calling convention, as far as I understand the concept I still have to consider platform dependencies in the IR. Since there is debug information from which all sizes and offsets could be derived, this could be automated.
Wrappers for the calling convention of the system and external funtions are provided ...
Does this mean that a user would have to provide wrappers written in assembler for each external library? Or is there a way to adapt the generators to different calling conventions to reduce this effort?
RE: Looking for a decently large demo project - Added by Florian Negele over 1 year ago
Debugging information is completely optional. The intermediate representation was deliberately chosen to be low-level such that there is oftentimes a 1:1 mapping to machine code, so writing a back-end becomes simple and straightforward. Unfortunately this also means, that the machine code generator has to provide some architectural constraints back to the intermediate code emitter. Consider the alternative of a higher-level intermediate representation that abstracts away all plattform dependencies and calling conventions: you would end up with something like C and suddenly every back-end becomes a compiler in itself.
Please have a look at winlib.hpp
and files including that header. Users have to provide the name and parameter count of each desired external function. The library then provides the required wrappers for each supported platform. This approach allows keeping back-ends simple and completely plattform-agnostic while a program can still use multiple different calling conventions if required. The cost is some overhead at runtime, but I have experimented with a C++ library that allows calling functions using different static calling conventions with zero overhead.
RE: Looking for a decently large demo project - Added by Rochus Keller over 1 year ago
higher-level intermediate representation that abstracts away all plattform dependencies and calling conventions: you would end up with something like C
Rather something like ECMA-335, or even simpler like my Micron IL But obviously I still understand your implementation far too little to have a discussion about it.
This approach allows keeping back-ends simple and completely plattform-agnostic while a program can still use multiple different calling conventions if required
Apparently I already had a few misconceptions about what you actually implemented. At the moment I still don't understand how the integration of other code actually works.
I thought you would implement a standard calling convention, e.g. the C calling convention of the platform. What is the name of the calling convention that is actually implemented, i.e. to which is it most similar? And for which reason did you choose it e.g. over the C calling convention?
RE: Looking for a decently large demo project - Added by Florian Negele over 1 year ago
Rather something like ECMA-335, or even simpler like my Micron IL
I had something like LLVM IR in mind which is basically C with a different syntax.
What is the name of the calling convention that is actually implemented, i.e. to which is it most similar?
It has no name. All arguments are passed on the stack in reverse order with suitable alignments. All general-purpose registers are volatile. Results are returned in the result register if possible or using a hidden parameter otherwise.
And for which reason did you choose it e.g. over the C calling convention?
I don't think there is such a thing as a C calling convention. Architectures typically don't define calling conventions at all which is why there are so many different calling conventions for the same platform, even for the same compiler. I just chose the simplest common denominator in order to support interoperability amongst my own compilers, rather than having to support each and every calling convention defined by other compilers.
Please note that since you are using the intermediate code representation for your own compilers you can choose to adopt a different calling convention if you like to. Intermediate code itself has no notion of a calling convention because every single instruction is just translated to the corresponding machine code. You just have to make sure that external functions such as those provided by the compiler runtime use the same calling convention. Passing arguments in registers however is not supported at the moment and requires some extra work.
RE: Looking for a decently large demo project - Added by Rochus Keller over 1 year ago
I don't think there is such a thing as a C calling convention
See e.g. https://refspecs.linuxbase.org/elf/gabi41.pdf and the supplements per architecture, e.g. https://refspecs.linuxbase.org/elf/abi386-4.pdf or https://refspecs.linuxbase.org/elf/ARMELF.pdf.
I just chose the simplest common denominator
Which look quite similar to the usual 32 bit C calling conventions (64 bit use rather registers to transfer arguments).
Intermediate code itself has no notion of a calling convention because every single instruction is just translated to the corresponding machine code
Ok, that's great to hear; as I said I have not yet fully understood how much "intelligence" the IR instructions (especially the function call instructions) have by themselves, and how I could control it (if at all).
Passing arguments in registers however is not supported at the moment and requires some extra work.
Ok, I see; I actually thought that the 64 bit machine code generators would do that. Do you have plans to implement it? So today you apparently have to create stubs somewhere to translate to the calling convention expected by the external code; where are these stubs generated?
RE: Looking for a decently large demo project - Added by Florian Negele over 1 year ago
I have not yet fully understood how much "intelligence" the IR instructions (especially the function call instructions) have by themselves
I would again recommend using the sandbox to see exactly how this translation looks like.
Do you have plans to implement it?
No, not at the moment because even on the same platform the used register sets differ. The goal of a single calling convention was to have a compiler that is completely independent from its runtime environment.
where are these stubs generated?
See win32run.asm
and winlib.hpp
located in the runtime
directory as mentioned above. These are wrappers for calling external functions. The other way round is not supported yet.
RE: Looking for a decently large demo project - Added by Florian Negele over 1 year ago
I have not yet fully understood how much "intelligence" the IR instructions (especially the function call instructions) have by themselves
There is hardly any intelligence. If the description of an instruction appears to be too succinct, it is because there is nothing more to it: A call instruction for example just jumps somewhere and makes the address of the next instruction available for jumping back. It typically maps directly to the call instruction of the target architecture. The same holds for basically all other instructions.
RE: Looking for a decently large demo project - Added by Rochus Keller over 1 year ago
Ok, thanks; so far I only looked at how the oberon and c compiler generate IR.
Am I right to assume that with these constants in combination with assembler expressions I'm essentially able to generate platform independent IR, or is there missing information:
intsize, intalign, fltsize, fltalign, ptrsize, ptralign, funsize, funalign, retsize, retalign, lnksize, and stackdisp?
RE: Looking for a decently large demo project - Added by Florian Negele over 1 year ago
Yes you are right, these definitions were added to allow platform-independent testing of intermediate code. What is missing are the alignments of types with fixed size.
RE: Looking for a decently large demo project - Added by Rochus Keller over 1 year ago
Ok, thanks.
What is missing are the alignments of types with fixed size.
But I guess these can safely be assumed to be known for most architectures.
RE: Looking for a decently large demo project - Added by Florian Negele over 1 year ago
These alignments are given by the layout descriptor of each machine code generator, see RE: Eigen compiler suite compared to LLVM etc..
RE: Looking for a decently large demo project - Added by Rochus Keller over 1 year ago
Sure. I rather should have stated "these can safely be assumed to be known for most architectures in the IR text"; the intention was to generate platform independend IR text.
RE: Looking for a decently large demo project - Added by Rochus Keller over 1 year ago
In case you're interested meanwhile I migrated the chibicc x64 backend to Eigen IR, and the first examples work. Here is the code: https://github.com/rochus-keller/EiGen/tree/chibicc
It's still work in progress and I will gradually add more complex examples. Not all parts of the C language supported by chibicc are yet implemented.
- « Previous
- 1
- 2
- Next »