diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2022-05-19 04:13:35 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2022-05-19 04:13:35 -0700 |
commit | 100453d6f78a232b6666c93c6abd9e55a531d953 (patch) | |
tree | 143f0a416326fe569dce3267a2a753d953dafc2c /tests/017/ffi-misc.tl | |
parent | ec80c9c4c2a54bf21062a07281acefaf51688fb4 (diff) | |
download | txr-100453d6f78a232b6666c93c6abd9e55a531d953.tar.gz txr-100453d6f78a232b6666c93c6abd9e55a531d953.tar.bz2 txr-100453d6f78a232b6666c93c6abd9e55a531d953.zip |
ffi: support 64 bit bitfields.
* ffi.c (struct txr_ffi_type): Replace unsigned mask member
with a union m which holds unsigned mask and 64-bit fmask (fat
mask).
(ffi_sbit_put, ffi_sbit_get, ffi_ubit_put, ffi_ubit_get):
Refer to m.mask.
(ffi_fat_sbit_put, ffi_fat_sbit_get, ffi_fat_ubit_put,
ffi_fat_ubit_get): New static functions.
(ffi_generic_fat_sbit_put, ffi_generic_fat_sbit_get,
ffi_generic_fat_ubit_put, ffi_generic_fat_ubit_get):
Likewise.
(make_ffi_type_struct, make_ffi_type_union): Set up fat
mask for bitfields that are wider than int.
(ffi_type_compile): Refer to m.mask for the int and unsigned
int based bitfields declared with sbit and ubit that don't
mention a type. The bit operator now allows int64 and uint64
to be valid types for a bitfield. In this case, the "fat"
get and put functions are selected which use 64 bit operations.
Thus there is no efficiency impact on non-fat bitfields which
continue to use code with 32 bit operands.
(ffi_offsetof): Use the bitfield flag in the member's type
structure to detect bitfields, rather than the mask.
Diffstat (limited to 'tests/017/ffi-misc.tl')
-rw-r--r-- | tests/017/ffi-misc.tl | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/tests/017/ffi-misc.tl b/tests/017/ffi-misc.tl index 1b729bbc..68f67b6f 100644 --- a/tests/017/ffi-misc.tl +++ b/tests/017/ffi-misc.tl @@ -94,3 +94,18 @@ (mtest (ffi-put (new flex x #\a y "bcd") (ffi (struct flex))) #b'6162636400' (ffi-get #b'6162636400' (ffi (struct flex))) #S(flex x #\a y "bcd")) + +(defvarl %big-endian% (zerop [(ffi-put #x1 (ffi uint32)) 0])) + +(typedef foo + (struct foo + (x (bit 48 uint64)) + (y (bit 16 uint64)))) + +(if %big-endian% + (mtest + (ffi-put (new foo x 1 y 1) (ffi foo)) #b'0000000000010001' + (ffi-put (new foo x #xABCDFFFFB00B y #x1234) (ffi foo)) #b'ABCDFFFFB00B1234') + (mtest + (ffi-put (new foo x 1 y 1) (ffi foo)) #b'0100000000000100' + (ffi-put (new foo x #xABCDFFFFB00B y #x1234) (ffi foo)) #b'0BB0FFFFCDAB3412')) |