/***************************************************************
__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 */