Newbie questions about Pliant

Newbie questions about Pliant

Pliant bitfields

In C, you can use structs to create bitfields by specifying
the bit field-width of each member. Is there a similar way in Pliant?
Message posted by mujtaba on 2002/12/24 17:27:47
In C, you can use structs to create bitfields by specifying
the bit field-width of each member. Is there a similar thing in Pliant?
Or am I stuck to using bit masks?  I want to extract info from a C-library 
function that uses this type of structure.

eg.

struct bitfield{
 unsigned int x :4;       /*4 bits*/
 unsigned int y :4;       /*4 bits*/
 unsigned int v :1;       /*1 bit, boolean*/
 unsigned int unused :23; /*Align to 32-bit boundry*/
}

Message posted by maybe Hubert Tonneau on 2002/12/28 12:15:46
It should be possible to define bitfields in Pliant, though a meta.
The problem with bitfields is that they are just trics, even in C: you can't get
a pointer to such a field, then pass it to a function that will modify it.

The problem lies very deap in the hardware processors technology.
Basically, on a modern processor, the memory is byte aligned for historical
reasons, whereas it should be bit aligned. Now, when you write an integer to
a location it should also be possible to specify how many bits to write.
Since it's not available in mainstream processors native instructions, all this
will remain trics.

I'm also not sure that all compilers implement bit fields the same way. As an
example, if one of the bits field size is height bits, the compiler will have
to choose beetween packed implementation which can be portable, or a more
efficient implementation where it will invert some of the fields, in order to
try to align the 8 bits fields on a byte boundary.
As a result, most portable C libraries don't use bit fields, and rather use
constants instead. So the question is does it worse implementating in Pliant
for easier interfacing the fiew C libraries using bitfields, or should the
guy writing the Pliant glue change these bit fields to constants.
Message posted by mujtaba on 2002/12/29 16:40:23
I think you're right on that. I replaced the bit-subfields with an integer, and
wrote methods (using the attribute's name) to decode the bit flag. This way, 
I maintain the look of the original API:


struct BitField{
 unsigned int x :4;       /*4 bit*/
 unsigned int y :4;       /*4 bit*/
 unsigned int v :1;       /*1 bit, boolean*/
 unsigned int unused :23; /*Align to 32-bit boundry*/
}

--> 
#Contain errors, but the point is there

type BitField
 packed
 field uInt32 field

method bitfield x -> z
 arg BitField bitfield; arg uInt z
 z := bitfield.field .and. 0000000Fh

method bitfield y -> z
 arg BitField bitfield; arg uInt y
 z := (bitfield.field .and. 000000F0h) / 2^4

method bitfield v -> b
 arg BitField bitfield; arg Bool b
 b := (bitfield.field .and. 00000100h) <> 0

Message posted by hubert.tonneau on 2002/12/29 16:44:18
Just a fiew remarks.

> z := (bitfield.field .and. 000000F0h) / 2^4

should be:

z := (bitfield.field .and. 000000F0h) \ 2^4

because '/' will compute floatting point result.

> method bitfield v -> b
>   arg BitField bitfield; arg Bool b

should be:

method bitfield v -> b
  arg BitField bitfield; arg CBool b

because 'CBool' is more efficient than 'Bool'.



Message posted by hubert.tonneau on 2002/12/29 16:58:34
You seem to have problems with Pliant details, so here is a sample implementation
that might help you:

module "/pliant/language/unsafe.pli"

type BitField
 packed
 field uInt32 field

method bf y -> y
 arg BitField bf ; arg uInt y
 y := (bf:field .and. 000000F0h) \ 2^4

method bf 'y :=' y
 arg_rw BitField bf ; arg uInt y
 bf field := (bf:field .and. .not. 000000F0h) .or. y*2^4

# sample usage
gvar BitField bf
bf y := 5
console bf:y eol

Please notice that Pliant 'y :=' method is also a trick that enables to very
easily code the write method. In other words, in Pliant, you can very easily
create a 'virtual' field in a data type through a couple of methods.