003 File Manager
Current Path:
/usr/include/sys
usr
/
include
/
sys
/
📁
..
📄
_atomic64e.h
(2.91 KB)
📄
_atomic_subword.h
(7.27 KB)
📄
_bitset.h
(2.3 KB)
📄
_blockcount.h
(1.97 KB)
📄
_bus_dma.h
(2.15 KB)
📄
_callout.h
(2.68 KB)
📄
_cpuset.h
(1.76 KB)
📄
_cscan_atomic.h
(18.1 KB)
📄
_cscan_bus.h
(10.22 KB)
📄
_domainset.h
(2.04 KB)
📄
_eventhandler.h
(2.81 KB)
📄
_ffcounter.h
(1.84 KB)
📄
_iovec.h
(1.93 KB)
📄
_lock.h
(2.98 KB)
📄
_lockmgr.h
(1.82 KB)
📄
_mutex.h
(2.63 KB)
📄
_null.h
(1.7 KB)
📄
_pctrie.h
(1.65 KB)
📄
_pthreadtypes.h
(3.51 KB)
📄
_rangeset.h
(1.86 KB)
📄
_rmlock.h
(2.59 KB)
📄
_rwlock.h
(2.39 KB)
📄
_semaphore.h
(2.05 KB)
📄
_seqc.h
(160 B)
📄
_sigset.h
(2.46 KB)
📄
_smr.h
(1.94 KB)
📄
_sockaddr_storage.h
(2.37 KB)
📄
_stack.h
(1.53 KB)
📄
_stdarg.h
(2.15 KB)
📄
_stdint.h
(2.6 KB)
📄
_sx.h
(1.73 KB)
📄
_task.h
(2.62 KB)
📄
_termios.h
(7.64 KB)
📄
_timespec.h
(2 KB)
📄
_timeval.h
(1.88 KB)
📄
_types.h
(5.66 KB)
📄
_ucontext.h
(2.08 KB)
📄
_uio.h
(1.99 KB)
📄
_umtx.h
(2.5 KB)
📄
_unrhdr.h
(1.92 KB)
📄
_winsize.h
(2.14 KB)
📄
aac_ioctl.h
(7.56 KB)
📄
abi_compat.h
(2.42 KB)
📄
acct.h
(4.95 KB)
📄
acl.h
(14.62 KB)
📄
agpio.h
(5.78 KB)
📄
aio.h
(7.69 KB)
📄
alq.h
(4.5 KB)
📄
apm.h
(88 B)
📄
arb.h
(28.88 KB)
📄
assym.h
(2.7 KB)
📄
ata.h
(45.35 KB)
📄
atomic_common.h
(3.26 KB)
📄
auxv.h
(1.58 KB)
📄
backlight.h
(2.02 KB)
📄
bio.h
(6.77 KB)
📄
bitset.h
(8.53 KB)
📄
bitstring.h
(12.16 KB)
📄
blist.h
(3.74 KB)
📄
blockcount.h
(3.03 KB)
📄
boot.h
(1.8 KB)
📄
buf.h
(20.73 KB)
📄
buf_ring.h
(10.6 KB)
📄
bufobj.h
(5.03 KB)
📄
bus.h
(38.2 KB)
📄
bus_dma.h
(13.68 KB)
📄
bus_dma_internal.h
(2.42 KB)
📄
busdma_bufalloc.h
(4.7 KB)
📄
callout.h
(6.62 KB)
📄
caprights.h
(4.17 KB)
📄
capsicum.h
(17.54 KB)
📄
cdefs.h
(27.79 KB)
📄
cdio.h
(7.09 KB)
📄
cdrio.h
(4.88 KB)
📄
cfictl.h
(2.21 KB)
📄
chio.h
(9.53 KB)
📄
ck.h
(251 B)
📄
clock.h
(8.07 KB)
📄
cnv.h
(4.25 KB)
📄
compressor.h
(2.05 KB)
📄
condvar.h
(3.42 KB)
📄
conf.h
(12.4 KB)
📄
cons.h
(5.22 KB)
📄
consio.h
(14.01 KB)
📄
copyright.h
(1.97 KB)
📄
counter.h
(3.02 KB)
📄
coverage.h
(2.36 KB)
📄
cpu.h
(7.02 KB)
📄
cpuctl.h
(2.29 KB)
📄
cpuset.h
(5.93 KB)
📄
csan.h
(1.71 KB)
📄
ctf.h
(14.4 KB)
📄
ctf_api.h
(9.43 KB)
📄
ctype.h
(2.81 KB)
📄
devctl.h
(1.76 KB)
📄
devicestat.h
(6.97 KB)
📄
devmap.h
(4.04 KB)
📄
dirent.h
(4.78 KB)
📁
disk
📄
disk.h
(6.31 KB)
📄
disk_zone.h
(6.52 KB)
📄
disklabel.h
(4.39 KB)
📄
diskmbr.h
(1.84 KB)
📄
dkstat.h
(2.05 KB)
📄
dnv.h
(3.39 KB)
📄
domain.h
(3.64 KB)
📄
domainset.h
(5.05 KB)
📄
dtrace.h
(104.98 KB)
📄
dtrace_bsd.h
(6.93 KB)
📄
dvdio.h
(3.43 KB)
📄
efi.h
(6.21 KB)
📄
efiio.h
(2.06 KB)
📄
elf.h
(1.6 KB)
📄
elf32.h
(7.46 KB)
📄
elf64.h
(7.79 KB)
📄
elf_common.h
(59.51 KB)
📄
elf_generic.h
(2.83 KB)
📄
endian.h
(4.98 KB)
📄
epoch.h
(4.01 KB)
📄
errno.h
(8.29 KB)
📄
eui64.h
(2.05 KB)
📄
event.h
(12.61 KB)
📄
eventfd.h
(1.86 KB)
📄
eventhandler.h
(11.8 KB)
📄
eventvar.h
(2.46 KB)
📄
exec.h
(4.56 KB)
📄
extattr.h
(4.08 KB)
📄
fail.h
(13.1 KB)
📄
fbio.h
(19.95 KB)
📄
fcntl.h
(12.02 KB)
📄
fdcio.h
(7.6 KB)
📄
file.h
(14.06 KB)
📄
filedesc.h
(12.13 KB)
📄
filio.h
(3.67 KB)
📄
firmware.h
(3.11 KB)
📄
fnv_hash.h
(1.41 KB)
📄
font.h
(3.85 KB)
📄
gmon.h
(7.16 KB)
📄
gpio.h
(9.85 KB)
📄
gpt.h
(1.51 KB)
📄
gsb_crc32.h
(998 B)
📄
gtaskqueue.h
(4.21 KB)
📄
hash.h
(3.55 KB)
📄
hhook.h
(5.86 KB)
📄
iconv.h
(8.22 KB)
📄
imgact.h
(5.22 KB)
📄
imgact_aout.h
(5.65 KB)
📄
imgact_binmisc.h
(6.95 KB)
📄
imgact_elf.h
(4.13 KB)
📄
interrupt.h
(8.07 KB)
📄
intr.h
(5.36 KB)
📄
ioccom.h
(3.82 KB)
📄
ioctl.h
(2.24 KB)
📄
ioctl_compat.h
(6.42 KB)
📄
iov.h
(11.67 KB)
📄
iov_schema.h
(2.33 KB)
📄
ipc.h
(4.93 KB)
📄
ipmi.h
(5.4 KB)
📄
jail.h
(14.98 KB)
📄
joystick.h
(2.12 KB)
📄
kbio.h
(7.81 KB)
📄
kcov.h
(2.36 KB)
📄
kdb.h
(5.04 KB)
📄
kenv.h
(2.02 KB)
📄
kern_prefetch.h
(1.67 KB)
📄
kernel.h
(16.18 KB)
📄
kerneldump.h
(4.85 KB)
📄
khelp.h
(3.08 KB)
📄
kobj.h
(6.92 KB)
📄
kpilite.h
(2.01 KB)
📄
ksem.h
(2.34 KB)
📄
kthread.h
(3.04 KB)
📄
ktls.h
(6.52 KB)
📄
ktr.h
(10.92 KB)
📄
ktr_class.h
(3.8 KB)
📄
ktrace.h
(8.13 KB)
📄
libkern.h
(7.74 KB)
📄
limits.h
(3.69 KB)
📄
link_aout.h
(10.2 KB)
📄
link_elf.h
(4.06 KB)
📄
linker.h
(11.88 KB)
📄
linker_set.h
(3.85 KB)
📄
lock.h
(12.24 KB)
📄
lock_profile.h
(2.6 KB)
📄
lockf.h
(5.55 KB)
📄
lockmgr.h
(7 KB)
📄
lockstat.h
(5.13 KB)
📄
loginclass.h
(2.08 KB)
📄
mac.h
(3.96 KB)
📄
malloc.h
(11.76 KB)
📄
mbuf.h
(50.74 KB)
📄
mchain.h
(4.21 KB)
📄
md4.h
(1.63 KB)
📄
md5.h
(1.81 KB)
📄
mdioctl.h
(3.73 KB)
📄
memdesc.h
(3.79 KB)
📄
memrange.h
(2.36 KB)
📄
mman.h
(10.41 KB)
📄
module.h
(8.77 KB)
📄
module_khelp.h
(3.45 KB)
📄
mount.h
(42.05 KB)
📄
mouse.h
(12.69 KB)
📄
mpt_ioctl.h
(4.27 KB)
📄
mqueue.h
(1.86 KB)
📄
msg.h
(4.78 KB)
📄
msgbuf.h
(3.49 KB)
📄
mtio.h
(11.94 KB)
📄
mutex.h
(19.18 KB)
📄
namei.h
(11.27 KB)
📄
nlist_aout.h
(4.23 KB)
📄
nv.h
(10.62 KB)
📄
nvpair.h
(14.77 KB)
📄
osd.h
(4.02 KB)
📄
param.h
(12.23 KB)
📄
pciio.h
(5.67 KB)
📄
pcpu.h
(9.79 KB)
📄
pctrie.h
(5.19 KB)
📄
physmem.h
(2.92 KB)
📄
pidctrl.h
(5.44 KB)
📄
pipe.h
(4.63 KB)
📄
pmc.h
(37.29 KB)
📄
pmckern.h
(8.01 KB)
📄
pmclog.h
(9.23 KB)
📄
poll.h
(4.03 KB)
📄
posix4.h
(3.71 KB)
📄
power.h
(2.34 KB)
📄
priority.h
(4.39 KB)
📄
priv.h
(19.73 KB)
📄
prng.h
(354 B)
📄
proc.h
(50.73 KB)
📄
procctl.h
(4.89 KB)
📄
procdesc.h
(4.46 KB)
📄
procfs.h
(4.2 KB)
📄
protosw.h
(14.56 KB)
📄
ptio.h
(1.57 KB)
📄
ptrace.h
(8.61 KB)
📄
qmath.h
(22.07 KB)
📄
queue.h
(28.61 KB)
📄
racct.h
(7.48 KB)
📄
random.h
(5.41 KB)
📄
rangelock.h
(3.86 KB)
📄
rangeset.h
(2.96 KB)
📄
rctl.h
(5.91 KB)
📄
reboot.h
(3.41 KB)
📄
refcount.h
(5.72 KB)
📄
regression.h
(1.62 KB)
📄
resource.h
(5.32 KB)
📄
resourcevar.h
(6.33 KB)
📄
rman.h
(6.41 KB)
📄
rmlock.h
(5.56 KB)
📄
rtprio.h
(3.08 KB)
📄
runq.h
(2.54 KB)
📄
rwlock.h
(10.61 KB)
📄
sbuf.h
(4.68 KB)
📄
sched.h
(9.06 KB)
📄
sdt.h
(17.89 KB)
📄
select.h
(3.5 KB)
📄
selinfo.h
(2.39 KB)
📄
sem.h
(4.31 KB)
📄
sema.h
(2.61 KB)
📄
seqc.h
(3.26 KB)
📄
serial.h
(3.49 KB)
📄
sf_buf.h
(5.87 KB)
📄
sglist.h
(3.89 KB)
📄
shm.h
(5.69 KB)
📄
sigio.h
(2.83 KB)
📄
signal.h
(15.83 KB)
📄
signalvar.h
(12.95 KB)
📄
sleepqueue.h
(5.61 KB)
📄
slicer.h
(2.19 KB)
📄
smp.h
(8.88 KB)
📄
smr.h
(7.64 KB)
📄
smr_types.h
(4.87 KB)
📄
snoop.h
(1014 B)
📄
sockbuf.h
(9.9 KB)
📄
socket.h
(23.43 KB)
📄
socketvar.h
(18.75 KB)
📄
sockio.h
(7.97 KB)
📄
sockopt.h
(2.98 KB)
📄
soundcard.h
(69.38 KB)
📄
specialfd.h
(1.56 KB)
📄
spigenio.h
(2.28 KB)
📄
stack.h
(2.65 KB)
📄
stat.h
(13.44 KB)
📄
stats.h
(34.73 KB)
📄
statvfs.h
(3.08 KB)
📄
stdatomic.h
(13.94 KB)
📄
stddef.h
(1.7 KB)
📄
stdint.h
(2.63 KB)
📄
sx.h
(11.04 KB)
📄
syscall.h
(13.99 KB)
📄
syscallsubr.h
(16.94 KB)
📄
sysctl.h
(47.96 KB)
📄
sysent.h
(10.82 KB)
📄
syslimits.h
(3.14 KB)
📄
syslog.h
(7.25 KB)
📄
sysproto.h
(153.38 KB)
📄
systm.h
(21.97 KB)
📄
taskqueue.h
(7.65 KB)
📄
terminal.h
(8.25 KB)
📄
termios.h
(151 B)
📄
thr.h
(2.87 KB)
📄
tiio.h
(12.62 KB)
📄
tim_filter.h
(4.61 KB)
📄
time.h
(16.87 KB)
📄
timeb.h
(2.59 KB)
📄
timeet.h
(3.65 KB)
📄
timeffc.h
(11.94 KB)
📄
timepps.h
(6.48 KB)
📄
timers.h
(3.56 KB)
📄
times.h
(2.46 KB)
📄
timespec.h
(2.4 KB)
📄
timetc.h
(3.16 KB)
📄
timex.h
(6.61 KB)
📄
tree.h
(27.93 KB)
📄
tslog.h
(2.3 KB)
📄
tty.h
(8.98 KB)
📄
ttycom.h
(6.48 KB)
📄
ttydefaults.h
(3.92 KB)
📄
ttydevsw.h
(5.28 KB)
📄
ttydisc.h
(2.93 KB)
📄
ttyhook.h
(3.98 KB)
📄
ttyqueue.h
(5.26 KB)
📄
turnstile.h
(4.83 KB)
📄
types.h
(11.64 KB)
📄
ucontext.h
(2.91 KB)
📄
ucred.h
(5.4 KB)
📄
uio.h
(4.15 KB)
📄
umtx.h
(5.94 KB)
📄
un.h
(2.96 KB)
📄
unistd.h
(7.34 KB)
📄
unpcb.h
(6.77 KB)
📄
user.h
(21.58 KB)
📄
utsname.h
(2.47 KB)
📄
uuid.h
(3.17 KB)
📄
vdso.h
(4.26 KB)
📄
vmem.h
(4.91 KB)
📄
vmmeter.h
(7.72 KB)
📄
vnode.h
(40.87 KB)
📄
vtoc.h
(89 B)
📄
wait.h
(6.11 KB)
📄
watchdog.h
(4.22 KB)
Editing: qmath.h
/*- * Copyright (c) 2018 Netflix, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ /* * Data types and APIs for fixed-point math based on the "Q" number format. * * Author: Lawrence Stewart <lstewart@netflix.com> * * The 3 LSBs of all base data types are reserved for embedded control data: * bits 1-2 specify the radix point shift index i.e. 00,01,10,11 == 1,2,3,4 * bit 3 specifies the radix point shift index multiplier as 2 (0) or 16 (1) * * This scheme can therefore represent Q numbers with [2,4,6,8,16,32,48,64] bits * of precision after the binary radix point. The number of bits available for * the integral component depends on the underlying storage type chosen. */ #ifndef _SYS_QMATH_H_ #define _SYS_QMATH_H_ #include <machine/_stdint.h> typedef int8_t s8q_t; typedef uint8_t u8q_t; typedef int16_t s16q_t; typedef uint16_t u16q_t; typedef int32_t s32q_t; typedef uint32_t u32q_t; typedef int64_t s64q_t; typedef uint64_t u64q_t; /* typedef int128_t s128q_t; Not yet */ /* typedef uint128_t u128q_t; Not yet */ typedef s64q_t smaxq_t; typedef u64q_t umaxq_t; #if defined(__GNUC__) && !defined(__clang__) /* Ancient GCC hack to de-const, remove when GCC4 is removed. */ #define Q_BT(q) __typeof(1 * q) #else /* The underlying base type of 'q'. */ #define Q_BT(q) __typeof(q) #endif /* Type-cast variable 'v' to the same underlying type as 'q'. */ #define Q_TC(q, v) ((__typeof(q))(v)) /* Number of total bits associated with the data type underlying 'q'. */ #define Q_NTBITS(q) ((uint32_t)(sizeof(q) << 3)) /* Number of LSBs reserved for control data. */ #define Q_NCBITS ((uint32_t)3) /* Number of control-encoded bits reserved for fractional component data. */ #define Q_NFCBITS(q) \ ((uint32_t)(((Q_GCRAW(q) & 0x3) + 1) << ((Q_GCRAW(q) & 0x4) ? 4 : 1))) /* Min/max number of bits that can be reserved for fractional component data. */ #define Q_MINNFBITS(q) ((uint32_t)(2)) #define Q_MAXNFBITS(q) ((uint32_t)(Q_NTBITS(q) - Q_SIGNED(q) - Q_NCBITS)) /* * Number of bits actually reserved for fractional component data. This can be * less than the value returned by Q_NFCBITS() as we treat any excess * control-encoded number of bits for the underlying data type as meaning all * available bits are reserved for fractional component data i.e. zero int bits. */ #define Q_NFBITS(q) \ (Q_NFCBITS(q) > Q_MAXNFBITS(q) ? Q_MAXNFBITS(q) : Q_NFCBITS(q)) /* Number of bits available for integer component data. */ #define Q_NIBITS(q) ((uint32_t)(Q_NTBITS(q) - Q_RPSHFT(q) - Q_SIGNED(q))) /* The radix point offset relative to the LSB. */ #define Q_RPSHFT(q) (Q_NCBITS + Q_NFBITS(q)) /* The sign bit offset relative to the LSB. */ #define Q_SIGNSHFT(q) (Q_NTBITS(q) - 1) /* Set the sign bit to 0 ('isneg' is F) or 1 ('isneg' is T). */ #define Q_SSIGN(q, isneg) \ ((q) = ((Q_SIGNED(q) && (isneg)) ? (q) | (1ULL << Q_SIGNSHFT(q)) : \ (q) & ~(1ULL << Q_SIGNSHFT(q)))) /* Manipulate the 'q' bits holding control/sign data. */ #define Q_CRAWMASK(q) 0x7ULL #define Q_SRAWMASK(q) (1ULL << Q_SIGNSHFT(q)) #define Q_GCRAW(q) ((q) & Q_CRAWMASK(q)) #define Q_GCVAL(q) Q_GCRAW(q) #define Q_SCVAL(q, cv) ((q) = ((q) & ~Q_CRAWMASK(q)) | (cv)) /* Manipulate the 'q' bits holding combined integer/fractional data. */ #define Q_IFRAWMASK(q) \ Q_TC(q, Q_SIGNED(q) ? ~(Q_SRAWMASK(q) | Q_CRAWMASK(q)) : ~Q_CRAWMASK(q)) #define Q_IFMAXVAL(q) Q_TC(q, Q_IFRAWMASK(q) >> Q_NCBITS) #define Q_IFMINVAL(q) Q_TC(q, Q_SIGNED(q) ? -Q_IFMAXVAL(q) : 0) #define Q_IFVALIMASK(q) Q_TC(q, ~Q_IFVALFMASK(q)) #define Q_IFVALFMASK(q) Q_TC(q, (1ULL << Q_NFBITS(q)) - 1) #define Q_GIFRAW(q) Q_TC(q, (q) & Q_IFRAWMASK(q)) #define Q_GIFABSVAL(q) Q_TC(q, Q_GIFRAW(q) >> Q_NCBITS) #define Q_GIFVAL(q) Q_TC(q, Q_LTZ(q) ? -Q_GIFABSVAL(q) : Q_GIFABSVAL(q)) #define Q_SIFVAL(q, ifv) \ ((q) = ((q) & (~(Q_SRAWMASK(q) | Q_IFRAWMASK(q)))) | \ (Q_TC(q, Q_ABS(ifv)) << Q_NCBITS) | \ (Q_LTZ(ifv) ? 1ULL << Q_SIGNSHFT(q) : 0)) #define Q_SIFVALS(q, iv, fv) \ ((q) = ((q) & (~(Q_SRAWMASK(q) | Q_IFRAWMASK(q)))) | \ (Q_TC(q, Q_ABS(iv)) << Q_RPSHFT(q)) | \ (Q_TC(q, Q_ABS(fv)) << Q_NCBITS) | \ (Q_LTZ(iv) || Q_LTZ(fv) ? 1ULL << Q_SIGNSHFT(q) : 0)) /* Manipulate the 'q' bits holding integer data. */ #define Q_IRAWMASK(q) Q_TC(q, Q_IFRAWMASK(q) & ~Q_FRAWMASK(q)) #define Q_IMAXVAL(q) Q_TC(q, Q_IRAWMASK(q) >> Q_RPSHFT(q)) #define Q_IMINVAL(q) Q_TC(q, Q_SIGNED(q) ? -Q_IMAXVAL(q) : 0) #define Q_GIRAW(q) Q_TC(q, (q) & Q_IRAWMASK(q)) #define Q_GIABSVAL(q) Q_TC(q, Q_GIRAW(q) >> Q_RPSHFT(q)) #define Q_GIVAL(q) Q_TC(q, Q_LTZ(q) ? -Q_GIABSVAL(q) : Q_GIABSVAL(q)) #define Q_SIVAL(q, iv) \ ((q) = ((q) & ~(Q_SRAWMASK(q) | Q_IRAWMASK(q))) | \ (Q_TC(q, Q_ABS(iv)) << Q_RPSHFT(q)) | \ (Q_LTZ(iv) ? 1ULL << Q_SIGNSHFT(q) : 0)) /* Manipulate the 'q' bits holding fractional data. */ #define Q_FRAWMASK(q) Q_TC(q, ((1ULL << Q_NFBITS(q)) - 1) << Q_NCBITS) #define Q_FMAXVAL(q) Q_TC(q, Q_FRAWMASK(q) >> Q_NCBITS) #define Q_GFRAW(q) Q_TC(q, (q) & Q_FRAWMASK(q)) #define Q_GFABSVAL(q) Q_TC(q, Q_GFRAW(q) >> Q_NCBITS) #define Q_GFVAL(q) Q_TC(q, Q_LTZ(q) ? -Q_GFABSVAL(q) : Q_GFABSVAL(q)) #define Q_SFVAL(q, fv) \ ((q) = ((q) & ~(Q_SRAWMASK(q) | Q_FRAWMASK(q))) | \ (Q_TC(q, Q_ABS(fv)) << Q_NCBITS) | \ (Q_LTZ(fv) ? 1ULL << Q_SIGNSHFT(q) : 0)) /* * Calculate the number of bits required per 'base' digit, rounding up or down * for non power-of-two bases. */ #define Q_BITSPERBASEDOWN(base) (flsll(base) - 1) #define Q_BITSPERBASEUP(base) (flsll(base) - (__builtin_popcountll(base) == 1)) #define Q_BITSPERBASE(base, rnd) Q_BITSPERBASE##rnd(base) /* * Upper bound number of digits required to render 'nbits' worth of integer * component bits with numeric base 'base'. Overestimates for power-of-two * bases. */ #define Q_NIBITS2NCHARS(nbits, base) \ ({ \ int _bitsperbase = Q_BITSPERBASE(base, DOWN); \ (((nbits) + _bitsperbase - 1) / _bitsperbase); \ }) #define Q_NFBITS2NCHARS(nbits, base) (nbits) /* * Maximum number of chars required to render 'q' as a C-string of base 'base'. * Includes space for sign, radix point and NUL-terminator. */ #define Q_MAXSTRLEN(q, base) \ (2 + Q_NIBITS2NCHARS(Q_NIBITS(q), base) + \ Q_NFBITS2NCHARS(Q_NFBITS(q), base) + Q_SIGNED(q)) /* Yield the next char from integer bits. */ #define Q_IBITS2CH(q, bits, base) \ ({ \ __typeof(bits) _tmp = (bits) / (base); \ int _idx = (bits) - (_tmp * (base)); \ (bits) = _tmp; \ "0123456789abcdef"[_idx]; \ }) /* Yield the next char from fractional bits. */ #define Q_FBITS2CH(q, bits, base) \ ({ \ int _carry = 0, _idx, _nfbits = Q_NFBITS(q), _shift = 0; \ /* \ * Normalise enough MSBs to yield the next digit, multiply by the \ * base, and truncate residual fractional bits post multiplication. \ */ \ if (_nfbits > Q_BITSPERBASEUP(base)) { \ /* Break multiplication into two steps to ensure no overflow. */\ _shift = _nfbits >> 1; \ _carry = (((bits) & ((1ULL << _shift) - 1)) * (base)) >> _shift;\ } \ _idx = ((((bits) >> _shift) * (base)) + _carry) >> (_nfbits - _shift);\ (bits) *= (base); /* With _idx computed, no overflow concern. */ \ (bits) &= (1ULL << _nfbits) - 1; /* Exclude residual int bits. */ \ "0123456789abcdef"[_idx]; \ }) /* * Render the C-string representation of 'q' into 's'. Returns a pointer to the * final '\0' to allow for easy calculation of the rendered length and easy * appending to the C-string. */ #define Q_TOSTR(q, prec, base, s, slen) \ ({ \ char *_r, *_s = s; \ int _i; \ if (Q_LTZ(q) && ((ptrdiff_t)(slen)) > 0) \ *_s++ = '-'; \ Q_BT(q) _part = Q_GIABSVAL(q); \ _r = _s; \ do { \ /* Render integer chars in reverse order. */ \ if ((_s - (s)) < ((ptrdiff_t)(slen))) \ *_s++ = Q_IBITS2CH(q, _part, base); \ else \ _r = NULL; \ } while (_part > 0 && _r != NULL); \ if (!((_s - (s)) < ((ptrdiff_t)(slen)))) \ _r = NULL; \ _i = (_s - _r) >> 1; /* N digits requires int(N/2) swaps. */ \ while (_i-- > 0 && _r != NULL) { \ /* Work from middle out to reverse integer chars. */ \ *_s = *(_r + _i); /* Stash LHS char temporarily. */ \ *(_r + _i) = *(_s - _i - 1); /* Copy RHS char to LHS. */\ *(_s - _i - 1) = *_s; /* Copy LHS char to RHS. */ \ } \ _i = (prec); \ if (_i != 0 && _r != NULL) { \ if ((_s - (s)) < ((ptrdiff_t)(slen))) \ *_s++ = '.'; \ else \ _r = NULL; \ _part = Q_GFABSVAL(q); \ if (_i < 0 || _i > (int)Q_NFBITS(q)) \ _i = Q_NFBITS(q); \ while (_i-- > 0 && _r != NULL) { \ /* Render fraction chars in correct order. */ \ if ((_s - (s)) < ((ptrdiff_t)(slen))) \ *_s++ = Q_FBITS2CH(q, _part, base); \ else \ _r = NULL; \ } \ } \ if ((_s - (s)) < ((ptrdiff_t)(slen)) && _r != NULL) \ *_s = '\0'; \ else { \ _r = NULL; \ if (((ptrdiff_t)(slen)) > 0) \ *(s) = '\0'; \ } \ /* Return a pointer to the '\0' or NULL on overflow. */ \ (_r != NULL ? _s : _r); \ }) /* Left shift an integral value to align with the int bits of 'q'. */ #define Q_SHL(q, iv) \ (Q_LTZ(iv) ? -(int64_t)(Q_ABS(iv) << Q_NFBITS(q)) : \ Q_TC(q, iv) << Q_NFBITS(q)) /* Calculate the relative fractional precision between 'a' and 'b' in bits. */ #define Q_RELPREC(a, b) ((int)Q_NFBITS(a) - (int)Q_NFBITS(b)) /* * Determine control bits for the desired 'rpshft' radix point shift. Rounds up * to the nearest valid shift supported by the encoding scheme. */ #define Q_CTRLINI(rpshft) \ (((rpshft) <= 8) ? (((rpshft) - 1) >> 1) : (0x4 | (((rpshft) - 1) >> 4))) /* * Convert decimal fractional value 'dfv' to its binary-encoded representation * with 'nfbits' of binary precision. 'dfv' must be passed as a preprocessor * literal to preserve leading zeroes. The returned result can be used to set a * Q number's fractional bits e.g. using Q_SFVAL(). */ #define Q_DFV2BFV(dfv, nfbits) \ ({ \ uint64_t _bfv = 0, _thresh = 5, _tmp = dfv; \ int _i = sizeof(""#dfv) - 1; \ /* \ * Compute decimal threshold to determine which \ * conversion rounds will yield a binary 1. \ */ \ while (--_i > 0) {_thresh *= 10;} \ _i = (nfbits) - 1; \ while (_i >= 0) { \ if (_thresh <= _tmp) { \ _bfv |= 1ULL << _i; \ _tmp = _tmp - _thresh; \ } \ _i--; _tmp <<= 1; \ } \ _bfv; \ }) /* * Initialise 'q' with raw integer value 'iv', decimal fractional value 'dfv', * and radix point shift 'rpshft'. Must be done in two steps in case 'iv' * depends on control bits being set e.g. when passing Q_INTMAX(q) as 'iv'. */ #define Q_INI(q, iv, dfv, rpshft) \ ({ \ (*(q)) = Q_CTRLINI(rpshft); \ Q_SIFVALS(*(q), iv, Q_DFV2BFV(dfv, Q_NFBITS(*(q)))); \ }) /* Test if 'a' and 'b' fractional precision is the same (T) or not (F). */ #define Q_PRECEQ(a, b) (Q_NFBITS(a) == Q_NFBITS(b)) /* Test if 'n' is a signed type (T) or not (F). Works with any numeric type. */ #define Q_SIGNED(n) (Q_TC(n, -1) < 0) /* * Test if 'n' is negative. Works with any numeric type that uses the MSB as the * sign bit, and also works with Q numbers. */ #define Q_LTZ(n) (Q_SIGNED(n) && ((n) & Q_SRAWMASK(n))) /* * Return absolute value of 'n'. Works with any standard numeric type that uses * the MSB as the sign bit, and is signed/unsigned type safe. * Does not work with Q numbers; use Q_QABS() instead. */ #define Q_ABS(n) (Q_LTZ(n) ? -(n) : (n)) /* * Return an absolute value interpretation of 'q'. */ #define Q_QABS(q) (Q_SIGNED(q) ? (q) & ~Q_SRAWMASK(q) : (q)) /* Convert 'q' to float or double representation. */ #define Q_Q2F(q) ((float)Q_GIFVAL(q) / (float)(1ULL << Q_NFBITS(q))) #define Q_Q2D(q) ((double)Q_GIFVAL(q) / (double)(1ULL << Q_NFBITS(q))) /* Numerically compare 'a' and 'b' as whole numbers using provided operators. */ #define Q_QCMPQ(a, b, intcmp, fraccmp) \ ((Q_GIVAL(a) intcmp Q_GIVAL(b)) || \ ((Q_GIVAL(a) == Q_GIVAL(b)) && (Q_GFVAL(a) fraccmp Q_GFVAL(b)))) /* Test if 'a' is numerically less than 'b' (T) or not (F). */ #define Q_QLTQ(a, b) Q_QCMPQ(a, b, <, <) /* Test if 'a' is numerically less than or equal to 'b' (T) or not (F). */ #define Q_QLEQ(a, b) Q_QCMPQ(a, b, <, <=) /* Test if 'a' is numerically greater than 'b' (T) or not (F). */ #define Q_QGTQ(a, b) Q_QCMPQ(a, b, >, >) /* Test if 'a' is numerically greater than or equal to 'b' (T) or not (F). */ #define Q_QGEQ(a, b) Q_QCMPQ(a, b, >, >=) /* Test if 'a' is numerically equal to 'b' (T) or not (F). */ #define Q_QEQ(a, b) Q_QCMPQ(a, b, ==, ==) /* Test if 'a' is numerically not equal to 'b' (T) or not (F). */ #define Q_QNEQ(a, b) Q_QCMPQ(a, b, !=, !=) /* Returns the numerically larger of 'a' and 'b'. */ #define Q_QMAXQ(a, b) (Q_GT(a, b) ? (a) : (b)) /* Returns the numerically smaller of 'a' and 'b'. */ #define Q_QMINQ(a, b) (Q_LT(a, b) ? (a) : (b)) /* * Test if 'a' can be represented by 'b' with full accuracy (T) or not (F). * The type casting has to be done to a's type so that any truncation caused by * the casts will not affect the logic. */ #define Q_QCANREPQ(a, b) \ ((((Q_LTZ(a) && Q_SIGNED(b)) || !Q_LTZ(a)) && \ Q_GIABSVAL(a) <= Q_TC(a, Q_IMAXVAL(b)) && \ Q_GFABSVAL(a) <= Q_TC(a, Q_FMAXVAL(b))) ? \ 0 : EOVERFLOW) /* Test if raw integer value 'i' can be represented by 'q' (T) or not (F). */ #define Q_QCANREPI(q, i) \ ((((Q_LTZ(i) && Q_SIGNED(q)) || !Q_LTZ(i)) && \ Q_ABS(i) <= Q_TC(i, Q_IMAXVAL(q))) ? 0 : EOVERFLOW) /* * Returns a Q variable debug format string with appropriate modifiers and * padding relevant to the underlying Q data type. */ #define Q_DEBUGFMT_(prefmt, postfmt, mod, hexpad) \ prefmt \ /* Var name + address. */ \ "\"%s\"@%p" \ /* Data type. */ \ "\n\ttype=%c%dq_t, " \ /* Qm.n notation; 'm' = # int bits, 'n' = # frac bits. */ \ "Qm.n=Q%d.%d, " \ /* Radix point shift relative to the underlying data type's LSB. */ \ "rpshft=%d, " \ /* Min/max integer values which can be represented. */ \ "imin=0x%0" #mod "x, " \ "imax=0x%0" #mod "x" \ /* Raw hex dump of all bits. */ \ "\n\tqraw=0x%0" #hexpad #mod "x" \ /* Bit masks for int/frac/ctrl bits. */ \ "\n\timask=0x%0" #hexpad #mod "x, " \ "fmask=0x%0" #hexpad #mod "x, " \ "cmask=0x%0" #hexpad #mod "x, " \ "ifmask=0x%0" #hexpad #mod "x" \ /* Hex dump of masked int bits; 'iraw' includes shift */ \ "\n\tiraw=0x%0" #hexpad #mod "x, " \ "iabsval=0x%" #mod "x, " \ "ival=0x%" #mod "x" \ /* Hex dump of masked frac bits; 'fraw' includes shift */ \ "\n\tfraw=0x%0" #hexpad #mod "x, " \ "fabsval=0x%" #mod "x, " \ "fval=0x%" #mod "x" \ "%s" \ postfmt #define Q_DEBUGFMT(q, prefmt, postfmt) \ sizeof(q) == 8 ? Q_DEBUGFMT_(prefmt, postfmt, j, 16) : \ sizeof(q) == 4 ? Q_DEBUGFMT_(prefmt, postfmt, , 8) : \ sizeof(q) == 2 ? Q_DEBUGFMT_(prefmt, postfmt, h, 4) : \ sizeof(q) == 1 ? Q_DEBUGFMT_(prefmt, postfmt, hh, 2) : \ prefmt "\"%s\"@%p: invalid" postfmt \ /* * Returns a format string and data suitable for printf-like rendering * e.g. Print to console with a trailing newline: printf(Q_DEBUG(q, "", "\n")); */ #define Q_DEBUG(q, prefmt, postfmt, incfmt) \ Q_DEBUGFMT(q, prefmt, postfmt) \ , #q \ , &(q) \ , Q_SIGNED(q) ? 's' : 'u' \ , Q_NTBITS(q) \ , Q_NIBITS(q) \ , Q_NFBITS(q) \ , Q_RPSHFT(q) \ , Q_IMINVAL(q) \ , Q_IMAXVAL(q) \ , (q) \ , Q_IRAWMASK(q) \ , Q_FRAWMASK(q) \ , Q_TC(q, Q_CRAWMASK(q)) \ , Q_IFRAWMASK(q) \ , Q_GIRAW(q) \ , Q_GIABSVAL(q) \ , Q_GIVAL(q) \ , Q_GFRAW(q) \ , Q_GFABSVAL(q) \ , Q_GFVAL(q) \ , (incfmt) ? Q_DEBUGFMT(q, "\nfmt:", "") : "" \ /* * If precision differs, attempt to normalise to the greater precision that * preserves the integer component of both 'a' and 'b'. */ #define Q_NORMPREC(a, b) \ ({ \ int _perr = 0, _relprec = Q_RELPREC(*(a), b); \ if (_relprec != 0) \ _perr = ERANGE; /* XXXLAS: Do precision normalisation! */\ _perr; \ }) /* Clone r's control bits and int/frac value into 'l'. */ #define Q_QCLONEQ(l, r) \ ({ \ Q_BT(*(l)) _l = Q_GCVAL(r); \ int _err = Q_QCANREPQ(r, _l); \ if (!_err) { \ *(l) = _l; \ Q_SIFVAL(*(l), Q_GIFVAL(r)); \ } \ _err; \ }) /* Copy r's int/frac vals into 'l', retaining 'l's precision and signedness. */ #define Q_QCPYVALQ(l, r) \ ({ \ int _err = Q_QCANREPQ(r, *(l)); \ if (!_err) \ Q_SIFVALS(*(l), Q_GIVAL(r), Q_GFVAL(r)); \ _err; \ }) #define Q_QADDSUBQ(a, b, eop) \ ({ \ int _aserr; \ if ((_aserr = Q_NORMPREC(a, b))) while(0); /* NOP */ \ else if ((eop) == '+') { \ if (Q_IFMAXVAL(*(a)) - Q_GIFABSVAL(b) < Q_GIFVAL(*(a))) \ _aserr = EOVERFLOW; /* [+/-a + +b] > max(a) */ \ else \ Q_SIFVAL(*(a), Q_GIFVAL(*(a)) + Q_TC(*(a), \ Q_GIFABSVAL(b))); \ } else { /* eop == '-' */ \ if (Q_IFMINVAL(*(a)) + Q_GIFABSVAL(b) > Q_GIFVAL(*(a))) \ _aserr = EOVERFLOW; /* [+/-a - +b] < min(a) */ \ else \ Q_SIFVAL(*(a), Q_GIFVAL(*(a)) - Q_TC(*(a), \ Q_GIFABSVAL(b))); \ } \ _aserr; \ }) #define Q_QADDQ(a, b) Q_QADDSUBQ(a, b, (Q_LTZ(b) ? '-' : '+')) #define Q_QSUBQ(a, b) Q_QADDSUBQ(a, b, (Q_LTZ(b) ? '+' : '-')) #define Q_QDIVQ(a, b) \ ({ \ int _err; \ if ((_err = Q_NORMPREC(a, b))) while(0); /* NOP */ \ else if (Q_GIFABSVAL(b) == 0 || (!Q_SIGNED(*(a)) && Q_LTZ(b))) \ _err = EINVAL; /* Divide by zero or cannot represent. */\ /* XXXLAS: Handle overflow. */ \ else if (Q_GIFABSVAL(*(a)) != 0) { /* Result expected. */ \ Q_SIFVAL(*(a), \ ((Q_GIVAL(*(a)) << Q_NFBITS(*(a))) / Q_GIFVAL(b)) + \ (Q_GFVAL(b) == 0 ? 0 : \ ((Q_GFVAL(*(a)) << Q_NFBITS(*(a))) / Q_GFVAL(b)))); \ } \ _err; \ }) #define Q_QMULQ(a, b) \ ({ \ int _mulerr; \ if ((_mulerr = Q_NORMPREC(a, b))) while(0); /* NOP */ \ else if (!Q_SIGNED(*(a)) && Q_LTZ(b)) \ _mulerr = EINVAL; \ else if (Q_GIFABSVAL(b) != 0 && \ Q_IFMAXVAL(*(a)) / Q_GIFABSVAL(b) < Q_GIFABSVAL(*(a))) \ _mulerr = EOVERFLOW; \ else \ Q_SIFVAL(*(a), (Q_GIFVAL(*(a)) * Q_GIFVAL(b)) >> \ Q_NFBITS(*(a))); \ _mulerr; \ }) #define Q_QCPYVALI(q, i) \ ({ \ int _err = Q_QCANREPI(*(q), i); \ if (!_err) \ Q_SIFVAL(*(q), Q_SHL(*(q), i)); \ _err; \ }) #define Q_QADDSUBI(q, i, eop) \ ({ \ int _aserr = 0; \ if (Q_NTBITS(*(q)) < (uint32_t)flsll(Q_ABS(i))) \ _aserr = EOVERFLOW; /* i cannot fit in q's type. */ \ else if ((eop) == '+') { \ if (Q_IMAXVAL(*(q)) - Q_TC(*(q), Q_ABS(i)) < \ Q_GIVAL(*(q))) \ _aserr = EOVERFLOW; /* [+/-q + +i] > max(q) */ \ else \ Q_SIFVAL(*(q), Q_GIFVAL(*(q)) + \ Q_SHL(*(q), Q_ABS(i))); \ } else { /* eop == '-' */ \ if (Q_IMINVAL(*(q)) + Q_ABS(i) > Q_GIVAL(*(q))) \ _aserr = EOVERFLOW; /* [+/-q - +i] < min(q) */ \ else \ Q_SIFVAL(*(q), Q_GIFVAL(*(q)) - \ Q_SHL(*(q), Q_ABS(i))); \ } \ _aserr; \ }) #define Q_QADDI(q, i) Q_QADDSUBI(q, i, (Q_LTZ(i) ? '-' : '+')) #define Q_QSUBI(q, i) Q_QADDSUBI(q, i, (Q_LTZ(i) ? '+' : '-')) #define Q_QDIVI(q, i) \ ({ \ int _diverr = 0; \ if ((i) == 0 || (!Q_SIGNED(*(q)) && Q_LTZ(i))) \ _diverr = EINVAL; /* Divide by zero or cannot represent. */\ else if (Q_GIFABSVAL(*(q)) != 0) { /* Result expected. */ \ Q_SIFVAL(*(q), Q_GIFVAL(*(q)) / Q_TC(*(q), i)); \ if (Q_GIFABSVAL(*(q)) == 0) \ _diverr = ERANGE; /* q underflow. */ \ } \ _diverr; \ }) #define Q_QMULI(q, i) \ ({ \ int _mulerr = 0; \ if (!Q_SIGNED(*(q)) && Q_LTZ(i)) \ _mulerr = EINVAL; /* Cannot represent. */ \ else if ((i) != 0 && Q_IFMAXVAL(*(q)) / Q_TC(*(q), Q_ABS(i)) < \ Q_GIFABSVAL(*(q))) \ _mulerr = EOVERFLOW; \ else \ Q_SIFVAL(*(q), Q_GIFVAL(*(q)) * Q_TC(*(q), i)); \ _mulerr; \ }) #define Q_QFRACI(q, in, id) \ ({ \ uint64_t _tmp; \ int _err = 0; \ if ((id) == 0) \ _err = EINVAL; /* Divide by zero. */ \ else if ((in) == 0) \ Q_SIFVAL(*(q), in); \ else if ((_tmp = Q_ABS(in)) > (UINT64_MAX >> Q_RPSHFT(*(q)))) \ _err = EOVERFLOW; /* _tmp overflow. */ \ else { \ _tmp = Q_SHL(*(q), _tmp) / Q_ABS(id); \ if (Q_QCANREPI(*(q), _tmp & Q_IFVALIMASK(*(q)))) \ _err = EOVERFLOW; /* q overflow. */ \ else { \ Q_SIFVAL(*(q), _tmp); \ Q_SSIGN(*(q), (Q_LTZ(in) && !Q_LTZ(id)) || \ (!Q_LTZ(in) && Q_LTZ(id))); \ if (_tmp == 0) \ _err = ERANGE; /* q underflow. */ \ } \ } \ _err; \ }) #endif /* _SYS_QMATH_H_ */
Upload File
Create Folder