Jump to page: 1 2 3
Thread overview
July 02
Take a look at this instruction:

https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#addsub_imm

And this bit of implementation:

https://github.com/dlang/dmd/pull/16554/files#diff-230d65c83f6bee1f96ea368513dbbe744372ed550c54ce6f0be171ef0848815dR38

```
/* Add/subtract (immediate)
 * ADD/ADDS/SUB/SUBS Rd,Rn,#imm{, shift}
 * https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#addsub_imm
 */
static uint addsub_imm(uint sf, uint op, uint S, uint sh, uint imm12, ubyte Rn, ubyte Rd)
{
    return (sf     << 31) |
           (op     << 30) |
           (S      << 29) |
           (0x22   << 23) |
           (sh     << 22) |
           (imm12  << 10) |
           (Rn     <<  5) |
            Rd;
}
```
That's just to initialize it. Never mind the shift/mask code to read a fields, or change just one of the fields. There's a large number of these functions in instr.d. Wouldn't it be better with:

```
struct addsub_imm { uint Rd:5, Rn:5, imm12:12, sh:1, x22:6, S:1, op:1, sf: 1; }
```

??
July 03
On 03/07/2024 11:32 AM, Walter Bright wrote:
> That's just to initialize it. Never mind the shift/mask code to read a fields, or change just one of the fields. There's a large number of these functions in instr.d. Wouldn't it be better with:
> 
> |struct addsub_imm { uint Rd:5, Rn:5, imm12:12, sh:1, x22:6, S:1, op:1, sf: 1; } |
> 
> ??

Absolutely!

Especially with the reassurances that changing your target or platform won't end up changing what it does!
July 02
On 7/2/2024 6:39 PM, Richard (Rikki) Andrew Cattermole wrote:
> Especially with the reassurances that changing your target or platform won't end up changing what it does!

It won't. As I've repeatedly stated, if you use uints it won't change.

July 03

On Tuesday, 2 July 2024 at 23:32:22 UTC, Walter Bright wrote:

>

Take a look at this instruction:

https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#addsub_imm

And this bit of implementation:

https://github.com/dlang/dmd/pull/16554/files#diff-230d65c83f6bee1f96ea368513dbbe744372ed550c54ce6f0be171ef0848815dR38

/* Add/subtract (immediate)
 * ADD/ADDS/SUB/SUBS Rd,Rn,#imm{, shift}
 * https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#addsub_imm
 */
static uint addsub_imm(uint sf, uint op, uint S, uint sh, uint imm12, ubyte Rn, ubyte Rd)
{
    return (sf     << 31) |
           (op     << 30) |
           (S      << 29) |
           (0x22   << 23) |
           (sh     << 22) |
           (imm12  << 10) |
           (Rn     <<  5) |
            Rd;
}

That's just to initialize it. Never mind the shift/mask code to read a fields, or change just one of the fields. There's a large number of these functions in instr.d. Wouldn't it be better with:

struct addsub_imm { uint Rd:5, Rn:5, imm12:12, sh:1, x22:6, S:1, op:1, sf: 1; }

Is there a guarantee that the bit pattern will match what the CPU expects?

I remember someone telling me that "If you are still concerned about the layout, like you want a portable file format, don't use bit fields. Use std.bitmanip."

If you are going to use bitfields here, make sure you have tests to ensure the bit layout is as expected.

-Steve

July 03
Walter Bright kirjoitti 3.7.2024 klo 2.32:
> static uint addsub_imm(uint sf, uint op, uint S, uint sh, uint imm12, ubyte Rn, ubyte Rd)
> {
>      return (sf     << 31) |
>             (op     << 30) |
>             (S      << 29) |
>             (0x22   << 23) |
>             (sh     << 22) |
>             (imm12  << 10) |
>             (Rn     <<  5) |
>              Rd;
> }
> ```
> That's just to initialize it. Never mind the shift/mask code to read a fields, or change just one of the fields. There's a large number of these functions in instr.d. Wouldn't it be better with:
> 
> ```
> struct addsub_imm { uint Rd:5, Rn:5, imm12:12, sh:1, x22:6, S:1, op:1, sf: 1; }
> ```
> 
> ??

Yes. And we already basically have it:

```D
import std.bitmanip;
struct addsub_imm
{   mixin(bitfields!
    (  ubyte, "Rd", 5,
       ubyte, "Rn", 5,
       uint, "imm12", 12,
       uint, "sh", 1,
       ubyte, "x22", 6,
       uint, "S", 1,
       uint, "op", 1,
       uint, "sf", 1
    ));
}
```

The language builtin would have somewhat nicer syntax though. What if bitfields were moved from `std.bitmanip` to `core.*` and the compiler would lower any bitfield declarations in struct/class to a `bitfields` mixin?
July 03

On Wednesday, 3 July 2024 at 09:24:52 UTC, Dukc wrote:

>

What if bitfields were moved from std.bitmanip to core.* and the compiler would lower any bitfield declarations in struct/class to a bitfields mixin?

Then there could even be extern(C) bitfields guaranteeing compatibility with the associated C compiler, and extern(D) bitfields guaranteeing portability. (extern(C++) bitfields would be the same as extern(C), I guess.)

The extern(C) bitfields would have to be a compiler intrinsic, whereas the extern(D) ones could be a lowering to some mixin template in core.bitfield.

July 03
On 7/2/2024 8:26 PM, Steven Schveighoffer wrote:
> Is there a guarantee that the bit pattern will match what the CPU expects?

As I've written many times, if you stick with uint the layout is portable with every C compiler I know of.
July 03
On 7/3/2024 2:24 AM, Dukc wrote:
> The language builtin would have somewhat nicer syntax though.

A much nicer syntax.

> What if bitfields were moved from `std.bitmanip` to `core.*` and the compiler would lower any bitfield declarations in struct/class to a `bitfields` mixin?

Then they won't be compatible with C bitfields.

July 04

On Wednesday, 3 July 2024 at 17:58:53 UTC, Walter Bright wrote:

>

On 7/2/2024 8:26 PM, Steven Schveighoffer wrote:

>

Is there a guarantee that the bit pattern will match what the CPU expects?

As I've written many times, if you stick with uint the layout is portable with every C compiler I know of.

So my response was mostly tongue in cheek, since the dismissal of previous concerns about exact layout was always "just use std.bitmanip". I have since relented that I'm OK with the C compatibility as long as there is some expectation that "as long as you use uint, it's fine".

But... I'm thinking now, why not just specify that? If you use uint, this is the explicit layout, and any C compiler that doesn't implement that mechanism, D does not support bitfield compatibility.

That would go a long way to alleviating any concerns that portability would be based on the whim of some C compiler.

This should be fine, because, as you say, everyone already does it that way. D has the opportunity to make this official.

-Steve

July 05
On 04/07/2024 1:47 PM, Steven Schveighoffer wrote:
> On Wednesday, 3 July 2024 at 17:58:53 UTC, Walter Bright wrote:
>> On 7/2/2024 8:26 PM, Steven Schveighoffer wrote:
>>> Is there a guarantee that the bit pattern will match what the CPU expects?
>>
>> As I've written many times, if you stick with uint the layout is portable with every C compiler I know of.
> 
> So my response was mostly tongue in cheek, since the dismissal of previous concerns about exact layout was always "just use std.bitmanip". I have since relented that I'm OK with the C compatibility as long as there is some expectation that "as long as you use uint, it's fine".
> 
> But... I'm thinking now, why not just specify that? If you use uint, this is the explicit layout, and any C compiler that doesn't implement that mechanism, D does not support bitfield compatibility.
> 
> That would go a long way to alleviating any concerns that portability would be based on the whim of some C compiler.
> 
> This should be fine, because, as you say, everyone already does it that way. D has the opportunity to make this official.
> 
> -Steve

As a consequence it does mean that you shouldn't be doing things like tagged pointers with it.

And that's a problem since pretty much all new cpu designs are 64bit.
« First   ‹ Prev
1 2 3