summaryrefslogtreecommitdiffstats
path: root/tests/017/ffi-misc.tl
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-05-19 04:13:35 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-05-19 04:13:35 -0700
commit100453d6f78a232b6666c93c6abd9e55a531d953 (patch)
tree143f0a416326fe569dce3267a2a753d953dafc2c /tests/017/ffi-misc.tl
parentec80c9c4c2a54bf21062a07281acefaf51688fb4 (diff)
downloadtxr-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.tl15
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'))