/*************************************************************** __MPU_EMUTYPE.H Macro definitions of types EMUSHORT, EMULONG. Bits operations MACRO for EMUSHORT data type. PART OF : MPU - library . USAGE : Internal only . NOTE : Include "libmpu.h" before this FILE . Copyright (C) 2000 - 2024 by Andrew V.Kosteltsev. All Rights Reserved. ***************************************************************/ #ifndef __MPU_EMUTYPE_H #define __MPU_EMUTYPE_H #ifdef __cplusplus extern "C" { #endif /*************************************************************** MACRO FOR REAL ARITHMETIC ***************************************************************/ /* NOTE: ==== SIZE_OF_EMUPART <= SIZE_OF_EMUSHORT: ----------------------------------- if SIZE_OF_EMUSHORT == 4 then SIZE_OF_EMUPART == 4 ; if SIZE_OF_EMUSHORT == 8 then SIZE_OF_EMUPART == 4 . */ #define PART_MASK_SIGN EMUPART_C( 0x80000000 ) /* Mask of Exponent (hight part) */ #define PART_HIGHT_EXP EMUPART_C( 0x7fffffff ) /* Exponent of 1.0 (hight part) */ #define PART_HIGHT_EXONE EMUPART_C( 0x3fffffff ) /* Significand of -1.IND with implisit 1.0 (hight part) */ #define PART_HIGHT_EI_IND EMUPART_C( 0xc0000000 ) #define PART_HIGHT_BYTE EMUPART_C( 0xff000000 ) #define PART_MASK_ALL_BITS EMUPART_C( 0xffffffff ) /*************************************************************** EMUPARTSIZE computes the number of EMUPARTs needed to store n bits; ***************************************************************/ #define EMUPARTSIZE(n) (((n)+(BITS_PER_EMUPART-1))/BITS_PER_EMUPART) /*************************************************************** Calculate the number of EMUSHORT partions in integer data types, or real data types. For example: NP_8 - number of (EMUSHORT) partions in the int8 type; NP_256 - number of (EMUSHORT) partions in the int256 type. ***************************************************************/ #define MASK_CARRY EMULONG_C( 0x100000000 ) #define MASK_SIGN EMUSHORT_C( 0x80000000 ) /* Mask of Exponent (hight part) */ #define HIGHT_EXP EMUSHORT_C( 0x7fffffff ) /* Exponent of 1.0 (hight part) */ #define HIGHT_EXONE EMUSHORT_C( 0x3fffffff ) /* Exponent of 2.0 (hight part) */ #define HIGHT_EXTWO EMUSHORT_C( 0x40000000 ) /* MAX Exponent of 10^[a power of two] (hight part) */ #define HIGHT_EXMAX_P EMUSHORT_C( 0x10000000 ) /* Significand of 10^1 (hight part) */ #define HIGHT_M_TEN EMUSHORT_C( 0xa0000000 ) /* Significand of 10^-1 (hight part) */ #define HIGHT_M_MTEN EMUSHORT_C( 0xcccccccc ) /* Significand of -1.IND with implisit 1.0 (hight part) */ #define HIGHT_EI_IND EMUSHORT_C( 0xc0000000 ) #define HIGHT_BYTE EMUSHORT_C( 0xff000000 ) #define MASK_ALL_BITS EMUSHORT_C( 0xffffffff ) /* zise in BITS EMUSHORTS */ /* ====== ========= */ #define NP_8 0 #define NP_16 0 #define NP_32 1 #define NP_64 2 #define NP_128 4 #define NP_256 8 #define NP_512 16 #define NP_1024 32 #define NP_2048 64 #define NP_4096 128 #define NP_8192 256 #define NP_16384 512 #define NP_32768 1024 #define NP_65536 2048 /* 8192 Kbytes */ #define NP_131072 4096 /* 16384 Kbytes */ #define NP_MAX 4096 #define NP_MAX_2 2048 /* NP_MAX / 2 */ /******************************************************************** РАЗМЕРЫ ТИПОВ ДАННЫХ ПО КОЛИЧЕСТВУ СЛОВ(ПОРЦИЙ-Part) ТИПА EMUSHORT ********************************************************************/ /********** INTEGER: */ #define NPI_8 NP_8 #define NPI_16 NP_16 #define NPI_32 NP_32 #define NPI_64 NP_64 #define NPI_128 NP_128 #define NPI_256 NP_256 #define NPI_512 NP_512 #define NPI_1024 NP_1024 #define NPI_2048 NP_2048 #define NPI_4096 NP_4096 #define NPI_8192 NP_8192 #define NPI_16384 NP_16384 #define NPI_32768 NP_32768 #define NPI_65536 NP_65536 #define NPI_131072 NP_131072 #define NPI_MAX NP_MAX #define NPI_MAX_2 NP_MAX_2 /******* REAL: */ #define NPR_32 NP_32 #define NPR_64 NP_64 #define NPR_128 NP_128 #define NPR_256 NP_256 #define NPR_512 NP_512 #define NPR_1024 NP_1024 #define NPR_2048 NP_2048 #define NPR_4096 NP_4096 #define NPR_8192 NP_8192 #define NPR_16384 NP_16384 #define NPR_32768 NP_32768 #define NPR_65536 NP_65536 #define NPR_131072 NP_131072 #define NPR_MAX NP_MAX #define NPR_MAX_2 NP_MAX_2 /******************************************************************** РАЗМЕРЫ ТИПОВ ДАННЫХ ПО КОЛИЧЕСТВУ БИТ ********************************************************************/ /********** INTEGER: */ #define NBI_8 8 #define NBI_16 16 #define NBI_32 32 #define NBI_64 64 #define NBI_128 128 #define NBI_256 256 #define NBI_512 512 #define NBI_1024 1024 #define NBI_2048 2048 #define NBI_4096 4096 #define NBI_8192 8192 #define NBI_16384 16384 #define NBI_32768 32768 #define NBI_65536 65536 #define NBI_131072 131072 #define NBI_MAX 131072 #define NBI_MAX_2 65536 /******* REAL: */ #define NBR_32 32 #define NBR_64 64 #define NBR_128 128 #define NBR_256 256 #define NBR_512 512 #define NBR_1024 1024 #define NBR_2048 2048 #define NBR_4096 4096 #define NBR_8192 8192 #define NBR_16384 16384 #define NBR_32768 32768 #define NBR_65536 65536 #define NBR_131072 131072 #define NBR_MAX 131072 #define NBR_MAX_2 65536 /********************************************************* REAL Internal e-type: -------------------- SIZE of Exponent in EMUSHORT partitions: */ #define NPIE_32 (NBR_32/BITS_PER_EMUSHORT) #define NPIE_64 (NBR_32/BITS_PER_EMUSHORT) #define NPIE_128 (NBR_32/BITS_PER_EMUSHORT) #define NPIE_256 (NBR_32/BITS_PER_EMUSHORT) #define NPIE_512 (NBR_64/BITS_PER_EMUSHORT) #define NPIE_1024 (NBR_64/BITS_PER_EMUSHORT) #define NPIE_2048 (NBR_128/BITS_PER_EMUSHORT) #define NPIE_4096 (NBR_128/BITS_PER_EMUSHORT) #define NPIE_8192 (NBR_256/BITS_PER_EMUSHORT) #define NPIE_16384 (NBR_256/BITS_PER_EMUSHORT) #define NPIE_32768 (NBR_512/BITS_PER_EMUSHORT) #define NPIE_65536 (NBR_512/BITS_PER_EMUSHORT) #define NPIE_131072 (NBR_1024/BITS_PER_EMUSHORT) #define NPIE_MAX NPIE_131072 /********************************************************* REAL Internal e-type: -------------------- SIZE of Internal e-type number in EMUSHORT partitions: */ #define NPIR_32 (NBR_128/BITS_PER_EMUSHORT+3) #define NPIR_64 (NBR_128/BITS_PER_EMUSHORT+3) #define NPIR_128 (NBR_128/BITS_PER_EMUSHORT+3) #define NPIR_256 (NBR_256/BITS_PER_EMUSHORT+3) #define NPIR_512 (NBR_512/BITS_PER_EMUSHORT+3) #define NPIR_1024 (NBR_1024/BITS_PER_EMUSHORT+3) #define NPIR_2048 (NBR_2048/BITS_PER_EMUSHORT+3) #define NPIR_4096 (NBR_4096/BITS_PER_EMUSHORT+3) #define NPIR_8192 (NBR_8192/BITS_PER_EMUSHORT+3) #define NPIR_16384 (NBR_16384/BITS_PER_EMUSHORT+3) #define NPIR_32768 (NBR_32768/BITS_PER_EMUSHORT+3) #define NPIR_65536 (NBR_65536/BITS_PER_EMUSHORT+3) #define NPIR_131072 (NBR_131072/BITS_PER_EMUSHORT+3) #define NPIR_MAX NPIR_131072 /************************************************************************* Макроопределения для битовых операций над типом EMUSHORT. *************************************************************************/ /************************************************************************* Machine-dependent definitions the following definitions are for the Tahoe they might have to be changed for other machines. BITS_PER_EMUSHORT is the number of bits in a EMUSHORT data type; type EMUSHORT is smaller or equal a C (language) unsigned. EMUSHORTSIZE computes the number of EMUSHORTs needed to store n bits; BIT returns the value of the n-th bit starting from r (0-indexed); SET_BIT sets the n-th bit starting from r (0-indexed); INVERT_BIT convert the n-th bit starting from r (0-indexed). *************************************************************************/ #if BITS_PER_EMUSHORT == 64 #define POW2 6 /************************************************************************* ... r[0] --|------------------------------------------------------------------| | 0000000000000000000000000000000000000000000000000000000000000000 | --|------------------------------------------------------------------| n: 63 0 *************************************************************************/ #else /* not (BITS_PER_EMUSHORT == 64) */ #if BITS_PER_EMUSHORT == 32 #define POW2 5 /************************************************************************* ... r[1] r[0] --|----------------------------------|----------------------------------| | 00000000000000000000000000000000 | 00000000000000000000000000000000 | --|----------------------------------|----------------------------------| n: 63 32 31 0 *************************************************************************/ #else /* not (BITS_PER_EMUSHORT == 32) */ #if BITS_PER_EMUSHORT == 16 #define POW2 4 /************************************************************************* ... r[1] r[0] --|------------------|------------------| | 0000000000000000 | 0000000000000000 | --|------------------|------------------| n: 31 16 15 0 *************************************************************************/ #else /* not (BITS_PER_EMUSHORT == 16) */ #define __NOT_INCLUDE_BIT_MACRO 1 #define EMU_NON_COMPILE #endif /* BITS_PER_EMUSHORT == 16 */ #endif /* BITS_PER_EMUSHORT == 32 */ #endif /* BITS_PER_EMUSHORT == 64 */ #if !defined( __NOT_INCLUDE_BIT_MACRO ) #define EMUSHORTSIZE(n) (((n)+(BITS_PER_EMUSHORT-1))/BITS_PER_EMUSHORT) #define BIT(r,n) ((((r)[(n)>>POW2])>>((n)&(BITS_PER_EMUSHORT-1)))&1) #define SET_BIT(r,n) ((r)[(n)>>POW2]|=((EMUSHORT)1<<((n)&(BITS_PER_EMUSHORT-1)))) #define INVERT_BIT(r,n) ((r)[(n)>>POW2]^=(((EMUSHORT)1<<((n)&(BITS_PER_EMUSHORT-1))))) #if MPU_WORD_ORDER_BIG_ENDIAN == 1 #define ORDER_BIT(r,n,np) ((((r)[((np-1)-((n)>>POW2))])>>((n)&(BITS_PER_EMUSHORT-1)))&1) #define ORDER_SETBIT(r,n,np) ((r)[((np-1)-((n)>>POW2))]|=((EMUSHORT)1<<((n)&(BITS_PER_EMUSHORT-1)))) #define ORDER_INVERT_BIT(r,n,np) ((r)[((np-1)-((n)>>POW2))]^=(((EMUSHORT)1<<((n)&(BITS_PER_EMUSHORT-1))))) #else #define ORDER_BIT(r,n,np) ((((r)[(n)>>POW2])>>((n)&(BITS_PER_EMUSHORT-1)))&1) #define ORDER_SETBIT(r,n,np) ((r)[(n)>>POW2]|=((EMUSHORT)1<<((n)&(BITS_PER_EMUSHORT-1)))) #define ORDER_INVERT_BIT(r,n,np) ((r)[(n)>>POW2]^=(((EMUSHORT)1<<((n)&(BITS_PER_EMUSHORT-1))))) #endif #endif /************************************************************************* Определения BIT(r,n), SET_BIT(r,n), INVERT_BIT(r,n) требуют, чтобы по адресу &r[0] находилась младшая порция набора бит. СЛЕДОВАТЕЛЬНО, ЕСЛИ полное количество бит укладывается в BITS_PER_EMUSHORT, то макросы будут работать корректно при любом значении BIG_ENDIAN. ЕСЛИ полное количество бит не укладывается в BITS_PER_EMUSHORT, то макросы будут работать корректно только при BIG_ENDIAN = 0. ДАННОЕ ОБСТОЯТЕЛЬСТВО НАДО УЧИТЫВАТЬ ПРИ ИСПОЛЬЗОВАНИИ BIT(r,n), SET_BIT(r,n), INVERT_BIT(r,n) в операциях над целыми и вещественными числами. НАПРИМЕР, при BIG_ENDIAN = 1 в массивах EMUSHORT x[NP] младшая часть числа расположена в x[NP-1], а старшая в x[0]; СЛЕДОВАТЕЛЬНО, если надо узнать значение 78 бита (например), то перед применением макроса BIT(x,78) НЕОБХОДИМО поменять расположение ПОРЦИЙ EMUSHORT в числе, расположенном по адресу x (!!!ИМЕННО РАСПОЛОЖЕНИЕ ПОРЦИЙ EMUSHORT, А НЕ БАЙТ: т.к. макросы обращаются к порциям). ЕСЛИ константа MPU_WORD_ORDER_BIG_ENDIAN установлена в 1, то для определения значения n-го бита в длинном числе можно применить определение ORDER_BIT(r,n,np), где np - количество EMUSHORT-порций в числе. Макросы ORDER_BIT(r,n,np), ORDER_SET_BIT(r,n,np), ORDER_INVERT_BIT(r,n,np) работают при любой ориентации слов (big-endian or little-endian). Если MPU_WORD_ORDER_BIG_ENDIAN == 0, то параметр np просто не используется. *************************************************************************/ #ifdef __cplusplus } /* ... extern "C" */ #endif #endif /* __MPU_EMUTYPE_H */