summaryrefslogtreecommitdiff
path: root/mpu/mpu-context.h
blob: edfd72b9495ef6c8acd8f819397652827c8d48f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
/***************************************************************
  __MPU_CONTEXT.H

       This file contains CONTEXT operation functions & data
       declarations.

       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_CONTEXT_H
#define   __MPU_CONTEXT_H

#ifdef  __cplusplus
extern "C" {
#endif


#define REGISTERS_MEM_SIZE_IN_UNITS  524288

typedef struct __mpu_context mpu_context;
struct __mpu_context
{
  __mpu_error_t _ierrno; /*  integer errno */
  __mpu_error_t _rerrno; /*     real errno */
  __mpu_error_t _cerrno; /*  complex errno */
  __mpu_error_t _merrno; /*     math errno */

  __mpu_error_t _ewarns; /* extra warnings */

  __mpu_uint32_t mflags; /* mpu flags register */

  __mpu_void_t *_cur_brk;
  __mpu_UNIT_t  _mem[REGISTERS_MEM_SIZE_IN_UNITS];
};

extern struct __mpu_context *pmctx;

#define __integer_error_no  (*(&(pmctx->_ierrno)))
#define __real_error_no     (*(&(pmctx->_rerrno)))
#define __complex_error_no  (*(&(pmctx->_cerrno)))
#define __math_error_no     (*(&(pmctx->_merrno)))

#define __extra_warnings    (*(&(pmctx->_ewarns)))

#define __cur_brk  (*((__mpu_void_t **)&(pmctx->_cur_brk)))
#define __mem      ((__mpu_UNIT_t *)&((pmctx->_mem)[0]))


/***************************************************************
  INTEGER OPERATIONS FLAGS:
  ------------------------
      AF - Auxiliary Carry Flag
      CF - Carry Flag
      OF - Overflow Flag
      SF - Sign Flag
      PF - Parity Flag (of lowest significant byte)
      ZF - Zero Flag
      RF - major || remainder
      VF - Invalid operation

      NOTE: AF, PF are set only by 8-, 16-bit operations.

  REAL OPERATIONS FLAGS:
  ---------------------
    DOMF - Domain Flag
    SNGF - Singularity Flag
    OVFF - Overflow Flag
    UDFF - Underflow Flag
    TLSF - TLOSS Flag
    PLSF - PLOSS Flag
    INDF - ind-produsing operation Flag
    INXF - Inexact Flag
 ***************************************************************/

/*
  Значения флагов снимаются часто, а опереция  log2(mask)
  для вычисления сдвига посредством подсчета установленных
  битов

    SHIFT(flag) = __BITCOUNT((flag ## _MASK)-1)

  может занимать время.  Поэтому здесь используются явные
  значения количества битов на которое надо сдвигать флаг,
  чтобы снять его величину.
 */
#define   AF_MASK __mpu_UINT32_C( 0x00000001 )
#define   CF_MASK __mpu_UINT32_C( 0x00000002 )
#define   OF_MASK __mpu_UINT32_C( 0x00000004 )
#define   SF_MASK __mpu_UINT32_C( 0x00000008 )
#define   PF_MASK __mpu_UINT32_C( 0x00000010 )
#define   ZF_MASK __mpu_UINT32_C( 0x00000020 )
#define   RF_MASK __mpu_UINT32_C( 0x00000040 )
#define   VF_MASK __mpu_UINT32_C( 0x00000080 )

#define   AF_SHIFT   0
#define   CF_SHIFT   1
#define   OF_SHIFT   2
#define   SF_SHIFT   3
#define   PF_SHIFT   4
#define   ZF_SHIFT   5
#define   RF_SHIFT   6
#define   VF_SHIFT   7


#define DOMF_MASK __mpu_UINT32_C( 0x00000100 )
#define SNGF_MASK __mpu_UINT32_C( 0x00000200 )
#define OVFF_MASK __mpu_UINT32_C( 0x00000400 )
#define UDFF_MASK __mpu_UINT32_C( 0x00000800 )
#define TLSF_MASK __mpu_UINT32_C( 0x00001000 )
#define PLSF_MASK __mpu_UINT32_C( 0x00002000 )
#define INDF_MASK __mpu_UINT32_C( 0x00004000 )
#define INXF_MASK __mpu_UINT32_C( 0x00008000 )

#define DOMF_SHIFT   8
#define SNGF_SHIFT   9
#define OVFF_SHIFT  10
#define UDFF_SHIFT  11
#define TLSF_SHIFT  12
#define PLSF_SHIFT  13
#define INDF_SHIFT  14
#define INXF_SHIFT  15


#define IFLAGS_MASK __mpu_UINT32_C( 0x000000ff )
#define RFLAGS_MASK __mpu_UINT32_C( 0x0000ff00 )
#define MFLAGS_MASK __mpu_UINT32_C( 0x0000ffff )


#if HAVE___BUILTIN_POPCOUNT
#define __BITCOUNT  __builtin_popcount
#else
#define __BITCOUNT(x) (((_BX(x)+(_BX(x)>>4)) & 0x0F0F0F0F) % 255)
#define _BX(x) ((x) - (((x)>>1)&0x77777777)  \
                    - (((x)>>2)&0x33333333)  \
                    - (((x)>>3)&0x11111111))
#endif

#if HAVE___BUILTIN_PARITY
#define __PARITY  __builtin_parity
#else
#define __PARITY(x) (__BITCOUNT(x) % 2)
#endif

#define __MPARITY(x)  (((x)&0xff)?!__PARITY(x):0)

/* All arithmetic flags for store/restore operations: */
#define __MPU_FLAGS  (pmctx->mflags)

/* Set, clear, or invert particular flag (by name): */
#define __SET_MFLAG(flag)     (pmctx->mflags |= (flag ## _MASK))
#define __CLEAR_MFLAG(flag)   (pmctx->mflags &= (~flag ## _MASK))
#define __INVERT_MFLAG(flag)  (pmctx->mflags ^= (flag ## _MASK))
#define __MFLAG(flag)         ((pmctx->mflags & flag ## _MASK)>>(flag ## _SHIFT))

/* Clear set of integer, relal or all of arithmetic flags: */
#define __CLEAR_IFLAGS  (pmctx->mflags &= (~IFLAGS_MASK))
#define __CLEAR_RFLAGS  (pmctx->mflags &= (~RFLAGS_MASK))
#define __CLEAR_MFLAGS  (pmctx->mflags &= (~MFLAGS_MASK))

#define __CLEAR_IFLAGS_WITHOUT_CARRY  (pmctx->mflags &= (~(IFLAGS_MASK & (~CF_MASK))))


/* Set integer flags: */
#define __STA  __SET_MFLAG( AF )
#define __STC  __SET_MFLAG( CF )
#define __STO  __SET_MFLAG( OF )
#define __STS  __SET_MFLAG( SF )
#define __STP  __SET_MFLAG( PF )
#define __STZ  __SET_MFLAG( ZF )
#define __STR  __SET_MFLAG( RF )
#define __STV  __SET_MFLAG( VF )

/* Clear integer flags: */
#define __CLA  __CLEAR_MFLAG( AF )
#define __CLC  __CLEAR_MFLAG( CF )
#define __CLO  __CLEAR_MFLAG( OF )
#define __CLS  __CLEAR_MFLAG( SF )
#define __CLP  __CLEAR_MFLAG( PF )
#define __CLZ  __CLEAR_MFLAG( ZF )
#define __CLR  __CLEAR_MFLAG( RF )
#define __CLV  __CLEAR_MFLAG( VF )

/* Complement integer flags: */
#define __CMA  __INVERT_MFLAG( AF )
#define __CMC  __INVERT_MFLAG( CF )
#define __CMO  __INVERT_MFLAG( OF )
#define __CMS  __INVERT_MFLAG( SF )
#define __CMP  __INVERT_MFLAG( PF )
#define __CMZ  __INVERT_MFLAG( ZF )
#define __CMR  __INVERT_MFLAG( RF )
#define __CMV  __INVERT_MFLAG( VF )


/* Set real flags: */
#define __STDOM __SET_MFLAG( DOMF )
#define __STSNG __SET_MFLAG( SNGF )
#define __STOVF __SET_MFLAG( OVFF )
#define __STUDF __SET_MFLAG( UDFF )
#define __STTLS __SET_MFLAG( TLSF )
#define __STPLS __SET_MFLAG( PLSF )
#define __STIND __SET_MFLAG( INDF )
#define __STINX __SET_MFLAG( INXF )

/* Clear real flags: */
#define __CLDOM __CLEAR_MFLAG( DOMF )
#define __CLSNG __CLEAR_MFLAG( SNGF )
#define __CLOVF __CLEAR_MFLAG( OVFF )
#define __CLUDF __CLEAR_MFLAG( UDFF )
#define __CLTLS __CLEAR_MFLAG( TLSF )
#define __CLPLS __CLEAR_MFLAG( PLSF )
#define __CLIND __CLEAR_MFLAG( INDF )
#define __CLINX __CLEAR_MFLAG( INXF )

/* Complement real flags: */
#define __CMDOM __INVERT_MFLAG( DOMF )
#define __CMSNG __INVERT_MFLAG( SNGF )
#define __CMOVF __INVERT_MFLAG( OVFF )
#define __CMUDF __INVERT_MFLAG( UDFF )
#define __CMTLS __INVERT_MFLAG( TLSF )
#define __CMPLS __INVERT_MFLAG( PLSF )
#define __CMIND __INVERT_MFLAG( INDF )
#define __CMINX __INVERT_MFLAG( INXF )



extern __mpu_void_t *__mpu_sbrk( int incr );



#ifdef  __cplusplus
}   /* ... extern "C" */
#endif

#endif /* __MPU_CONTEXT_H */