Warning: mysqli::__construct(): (HY000/1203): User howardkn already has more than 'max_user_connections' active connections in D:\Inetpub\vhosts\howardknight.net\al.howardknight.net\includes\artfuncs.php on line 21
Failed to connect to MySQL: (1203) User howardkn already has more than 'max_user_connections' active connections
Warning: mysqli::query(): Couldn't fetch mysqli in D:\Inetpub\vhosts\howardknight.net\al.howardknight.net\index.php on line 66
Article <vso8os$34hj4$1@dont-email.me>
Deutsch   English   Français   Italiano  
<vso8os$34hj4$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!eternal-september.org!.POSTED!not-for-mail
From: BGB <cr88192@gmail.com>
Newsgroups: comp.lang.c
Subject: Re: "A diagram of C23 basic types"
Date: Fri, 4 Apr 2025 04:27:30 -0500
Organization: A noiseless patient Spider
Lines: 176
Message-ID: <vso8os$34hj4$1@dont-email.me>
References: <87y0wjaysg.fsf@gmail.com> <vsijts$13c9u$1@dont-email.me>
 <vsl9ep$3vdjj$1@dont-email.me> <vsmrfe$1ilno$2@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Fri, 04 Apr 2025 11:29:01 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="d71644f08e4a9bddb58e519aede26fa5";
	logging-data="3294820"; mail-complaints-to="abuse@eternal-september.org";	posting-account="U2FsdGVkX18GLhvga9qHZXPrg25vKITsU11vsr3ekSc="
User-Agent: Mozilla Thunderbird
Cancel-Lock: sha1:zqzsCf+nrs87eoV2AXAj6qIU40w=
Content-Language: en-US
In-Reply-To: <vsmrfe$1ilno$2@dont-email.me>
Bytes: 7281

On 4/3/2025 3:35 PM, Lawrence D'Oliveiro wrote:
> On Thu, 3 Apr 2025 01:20:48 -0500, BGB wrote:
> 
>> So, extended features:
>>     _UBitInt(5)   cr, cg, cb;
>>     _UBitInt(16)  clr;
>>     clr = (_UBitInt(16)) { 0b0u1, cr, cg, cb };
>> Composes an RGB555 value.
>>
>>     cg = clr[9:5]; //extract bits
>>     clr[9:5] = cg;  //assign bits
>>     clr[15:10] = clr[9:5];  //copy bits from one place to another.
>>
>> And:
>>     (_UBitInt(16)) { 0b0u1, cr, cg, cb } = clr;
>>
>> Decomposing it into components, any fixed-width constants being treated
>> as placeholders.
> 
> Next step: what if they’re variable-width bitfields, not fixed-width?

Not really addressed here...

I was basically implementing features matching those in Verilog, where 
except in limited scenarios (such as bit arrays), variable width or 
variable position bitfields don't really exist.

So:
   bi[hi:lo]
Isn't valid unless both hi and lo are constant, and the bit-packing and 
decomposition also only work for fixed layouts, etc.

And, as it currently works in my compiler (in the type-system and code 
generation), it could not work with variably modified bit offsets (there 
is a bit more going on here than just syntax sugar over shifts and masks).



It is possible to use a variable index into a bitint, though in this 
case it internally behaves like a shift. So, say:
   _UBitInt(128) bi;
   _UBitInt(7) ix;
   ...
   v=bi[ix]
Essentially does the equivalent of:
   v=(bi>>ix)&1;


There are other things that would be useful to have, such as an 
efficient way to implement operations like (val[4]?vala:valb).

Say, for example, in Verilog is someone wants to implement shift logic, 
they might write, say:
   tVal0 = { valExt[63:0], valIn[63:0] };
   tVal1 = valShr[5] ? tVal0[127:32] : tVal0[95:0];
   tVal2 = valShr[4] ? tVal1[ 95:16] : tVal1[79:0];
   tVal3 = valShr[3] ? tVal2[ 79: 8] : tVal2[71:0];
   tVal4 = valShr[2] ? tVal3[ 71: 4] : tVal3[67:0];
   tVal5 = valShr[1] ? tVal4[ 67: 2] : tVal4[65:0];
   tVal6 = valShr[0] ? tVal5[ 65: 1] : tVal5[64:0];

While, granted, this will be nowhere near as fast as using a native 
shift instruction, you don't want it to be too unreasonably slow 
(preferably branch-free).

This being for a language where, for the most part, you don't have 
generic high level operators and instead the practice tends to be to 
build them manually.

Where, it is a language where most of the logic is moving bits around, 
and driving logic based on clock edges and similar.

But, here one would usually target an FPGA, which while flexible, does 
not tend to dynamically rewire its logic.


But, I had designed the compiler extension along the assumption of 
similar constraints.


Though, in C, one does have the advantage that, if they want a movable 
bitfield, they still have shift-and-mask.


Well, and shift-and-mask is a "necessary evil" for dealing with this 
sort of variability. Even if my compiler did support variable bitfields, 
they likely couldn't be optimized in any ways more efficient than what 
can already be done with shift and mask (or, the ability to optimize 
this to anything useful depending solely on the assumption that the 
ranges don't move or change in size).

Due to reasons, it is also more efficient with unsigned types, as it is 
cheaper to zero extend a non-power-of-2 value than to sign-extend it 
(say, zero-extension using an AND operator, and sign extension needing a 
pair of shift operations).

While, in theory, one could infer these sorts of constant bitfield 
manipulations from shift-and-mask code, for things like bitfield 
insertion the logic would be too complex to deal with.


However, inferring a bitfield extraction from something like 
((val>>SHR)&MASK) is at least doable (but, unlike the bit-range 
notation, will result in a normal integer type rather than a BitInt).

And intermediate form can be used, say:
   (val>>idx)[3:0]
Which would produce a bitfield output.


But, can note that there are some restrictions on using this notation 
with normal integer types, so:
   int val, idx, v;
   ...
   v=(val>>idx)[0];
Is not allowed (mostly because this seemed like a scenario that had too 
high of a risk of someone stumbling onto by accident, this will work 
with _BitInt(32) or _UBitInt(32) but not with "int" or "unsigned int").


Note also that in the inspiration language, [hi:lo] is not the same 
thing as [lo:hi]. Though, Verilator doesn't support [lo:hi], in some 
other Verilog compilers, it is understood as reversing the bit-order, 
and something like:
   tDst[31:0]=src[0:31];
Would reverse the order of the bits.

Though, I could add compiler support for this if needed.



Well, and in the language in question, the usual way to implement a 
constant value lookup to do something resembling a switch statement:
   case(tIdx)
     6'h00: tVal = 8'h3F;
     6'h01: tVal = 8'h1E;
     ...
   endcase

TODO is possibly to detect this case and turn it into a hidden array lookup:
   static const uint8_t tIdx_LUT1[64] = { 0x3F, 0x1E, ... };
   ...
   tVal = tIdx_LUT1[tIdx];

But, not done yet...

In theory, it could be done for C switch via similar pattern matching 
(say, detecting that every case label is followed by assigning a 
constant to the same variable followed immediately by a "break;"), but 
it is uncommon to use a switch this way in C.


Verilog does support a vaguely C like preprocessor, but:
   Uses ` rather than #
   Doesn't support "if" with a general expression.
     Imagine, you only have ifdef and ifndef.
   Macro-substitution requires a ` prefix.

So:
   `define FOO_1234 16'h1234
   ...
   val = `FOO_1234;

Though, in this language, it is often more preferable to use "parameter"
   parameter[15:0] FOO_1234 = 16'h1234;

Which can be vaguely compared with "const int" or similar (though, using 
parameter for constants in this way is not supported in Verilog-95 or 
Verilog-2001, which are the usual default assumption in a lot of tools; 
but the tools I have used do support doing this).



....