Deutsch   English   Français   Italiano  
<vk0bvf$2nn4a$1@dont-email.me>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: BGB <cr88192@gmail.com>
Newsgroups: comp.lang.c
Subject: Re: transpiling to low level C
Date: Wed, 18 Dec 2024 23:46:21 -0600
Organization: A noiseless patient Spider
Lines: 98
Message-ID: <vk0bvf$2nn4a$1@dont-email.me>
References: <vjlh19$8j4k$1@dont-email.me>
 <vjn9g5$n0vl$1@raubtier-asyl.eternal-september.org>
 <vjnhsq$oh1f$1@dont-email.me> <vjnq5s$pubt$1@dont-email.me>
 <vjp2f3$13k4m$2@dont-email.me> <vjr7np$1j57r$2@dont-email.me>
 <vjsdum$1rfp2$1@dont-email.me> <vjse6l$1rfp2$2@dont-email.me>
 <vjsf6g$1rlkq$1@dont-email.me> <vjsgdr$1rrvs$1@dont-email.me>
 <vjsi61$1rlkq$2@dont-email.me> <vjsk7q$1rrvs$2@dont-email.me>
 <vjv5ir$2ds8r$2@dont-email.me> <vjv8lv$2edrv$1@dont-email.me>
 <vjvp9g$2h6ck$1@dont-email.me> <vjvpos$2gsil$3@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Injection-Date: Thu, 19 Dec 2024 06:46:24 +0100 (CET)
Injection-Info: dont-email.me; posting-host="76877d6a1adb46369aecf81b3ea48ff6";
	logging-data="2874506"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX19PAml9Fw+59aUC7d/GuEu4oDfbdjWvwRE="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:pgVO41CPss1Tee+nu6NWS99+G4Q=
Content-Language: en-US
In-Reply-To: <vjvpos$2gsil$3@dont-email.me>
Bytes: 5552

On 12/18/2024 6:35 PM, bart wrote:
> On 19/12/2024 00:27, BGB wrote:
>> On 12/18/2024 1:43 PM, Thiago Adams wrote:
>>> Em 12/18/2024 3:51 PM, BGB escreveu:
>>>>
>>>> I took a different approach:
>>>> In the backend IR stage, structs are essentially treated as 
>>>> references to the structure.
>>>>
>>>> A local structure may be "initialized" via an IR operation, in which 
>>>> point it will be assigned storage in the stack frame, and the 
>>>> reference will be initialized to the storage area for the structure.
>>>>
>>>> Most operations will pass them by reference.
>>>>
>>>> Assigning a struct will essentially be turned into a struct-copy 
>>>> operation (using the same mechanism as inline memcpy).
>>>
>>> But what happens with calling a external C function that has a struct 
>>> X as parameter? (not pointer to struct)
>>
>>
>> In my ABI, if larger than 16 bytes, it is passed by reference (as a 
>> pointer in a register or on the stack), callee is responsible for 
>> copying it somewhere else if needed.
>>
>> For struct return, a pointer to return the struct into is provided by 
>> the caller, and the callee copies the returned struct into this address.
>>
>> If the caller ignores the return value, the caller provides a dummy 
>> buffer for the return value.
>>
>> If no prototype is provided... well, most likely the program crashes 
>> or similar.
>>
>> So, in effect, the by-value semantics are mostly faked by the compiler.
>>
>>
>> It is roughly similar to the handling of C array types, which in this 
>> case are also seen as a combination of a hidden pointer to the data, 
>> and the backing data (the array's contents). The code-generator mostly 
>> operates in terms of this hidden pointer.
>>
>>
>> By-Value Structs smaller than 16 bytes are passed as-if they were a 64 
>> or 128 bit integer type (as a single register or as a register pair, 
>> with a layout matching their in-memory representation).
>>
>> ...
>>
>>
>> But, yeah, at the IL level, one could potentially eliminate structs 
>> and arrays as a separate construct, and instead have bare pointers and 
>> a generic "reserve a blob of bytes in the frame and initialize this 
>> pointer to point to it" operator (with the business end of this 
>> operator happening in the function prolog).
> 
> The problem with this, that I mentioned elsewhere, is how well it would 
> work with SYS V ABI, since the rules for structs are complex, and 
> apparently recursive.
> 
> Having just a block of bytes might not be enough.

In my case, I am not bothering with the SysV style ABI's (well, along 
with there not being any x86 or x86-64 target...).


For my ISA, it is a custom ABI, but follows mostly similar rules to some 
of the other "Microsoft style" ABIs (where, I have noted that across 
multiple targets, MS tools have tended to use similar ABI designs).

For my compiler targeting RISC-V, it uses a variation of RV's ABI rules.
Argument passing is basically similar, but struct pass/return is 
different; and it passes floating-point values in GPRs (and, in my own 
ISA, all floating-point values use GPRs, as there are no FPU registers; 
though FPU registers do exist for RISC-V).

Not likely a huge issue as one is unlikely to use ELF and PE/COFF in the 
same program.


For the "OS" that runs on my CPU core, it is natively using PE/COFF, but 
ELF is supported for RISC-V (currently PIE only). It generally needs to 
use my own C library as I still haven't gotten glibc or musl libc to 
work on it (and they work in a different way from my own C library).

Seemingly, something is going terribly wrong in the "dynamic linking" 
process, but too hard to figure out in the absence of any real debugging 
interface (what debug mechanisms I have, effectively lack any symbols 
for things inside "ld-linux.so"'s domain).

Theoretically, could make porting usermode software easier, as then I 
could compile stuff as-if it were running on an RV64 port of Linux.

But, easier said than done.

....