1
4
5# ifndef LMT_UTILITIES_SPARSEARRAY_H
6# define LMT_UTILITIES_SPARSEARRAY_H
7
8
16
17
27
28# if (0)
29
30
31
32# define LMT_SA_HIGHPART 128
33# define LMT_SA_MIDPART 128
34# define LMT_SA_LOWPART 128
35
36# define LMT_SA_H_PART(a) (((a)>>14)&127)
37# define LMT_SA_M_PART(a) (((a)>> 7)&127)
38# define LMT_SA_L_PART(a) ( (a) &127)
39
40# else
41
42
43
44
45
46
47# define LMT_SA_HIGHPART 128
48# define LMT_SA_MIDPART 256
49# define LMT_SA_LOWPART 64
50
51# define LMT_SA_H_PART(a) (((a)>>14)&127)
52# define LMT_SA_M_PART(a) (((a)>> 6)&255)
53# define LMT_SA_L_PART(a) ( (a) &63)
54
55# endif
56
57
74
75typedef struct sparse_state_info {
76 memory_data sparse_data;
77} sparse_state_info;
78
79extern sparse_state_info lmt_sparse_state;
80
81typedef struct sa_mathblob {
82 unsigned int class_value:math_class_bits;
83 unsigned int family_value:math_family_bits;
84 unsigned int character_value:math_character_bits;
85} sa_mathblob;
86
87typedef struct sa_mathspec {
88 unsigned short properties;
89 unsigned short group;
90 unsigned int index;
91} sa_mathspec;
92
93typedef struct packed_math_character {
94 union {
95 sa_mathblob sa_value;
96 unsigned ui_value;
97 };
98} packed_math_character;
99
100typedef union sa_tree_item {
101 unsigned int uint_value;
102 int int_value;
103 sa_mathblob math_code_value;
104 sa_mathspec math_spec_value;
105 unsigned short ushort_value[2];
106 unsigned char uchar_value[4];
107} sa_tree_item;
108
109typedef struct sa_stack_item {
110 int code;
111 int level;
112 sa_tree_item value_1;
113 sa_tree_item value_2;
114} sa_stack_item;
115
116typedef struct sa_tree_head {
117 int sa_stack_size;
118 int sa_stack_step;
119 int sa_stack_ptr;
120 sa_tree_item dflt;
121
122 sa_tree_item **tree[LMT_SA_HIGHPART];
123 sa_stack_item *stack;
124 int bytes;
125 int identifier;
126} sa_tree_head;
127
128typedef sa_tree_head *sa_tree;
129
130
131
132
133static inline unsigned int set_nibble(unsigned int original, int position, int nibble)
134{
135 position = 4 * (position % 8);
136 return (original & ~(0xF << position)) | ((nibble & 0xF) << position);
137}
138
139static inline unsigned int get_nibble(unsigned int original, int position)
140{
141 return (original >> (4 * (position % 8))) & 0xF;
142}
143
144# if (1)
145
146 extern int sa_get_item_0 (const sa_tree head, int n);
147 extern int sa_get_item_1 (const sa_tree head, int n);
148 extern int sa_get_item_2 (const sa_tree head, int n);
149 extern int sa_get_item_4 (const sa_tree head, int n, sa_tree_item *v);
150 extern int sa_get_item_8 (const sa_tree head, int n, sa_tree_item *v1, sa_tree_item *v2);
151
152# else
153
154 inline int sa_get_item_0(const sa_tree head, int n)
155 {
156 int h = LMT_SA_H_PART(n);
157 int m = LMT_SA_M_PART(n);
158 if (head->tree[h][m]) {
159 return get_nibble(head->tree[h][m][LMT_SA_L_PART(n)/8].uint_value,n);
160 }
161 return (int) get_nibble(head->dflt.uint_value,0);
162 }
163
164 inline int sa_get_item_1(const sa_tree head, int n)
165 {
166 int h = LMT_SA_H_PART(n);
167 int m = LMT_SA_M_PART(n);
168 if (head->tree[h][m]) {
169 return head->tree[h][m][LMT_SA_L_PART(n)/4].uchar_value[n%4];
170 }
171 return (int) head->dflt.uchar_value[0];
172 }
173
174 inline int sa_get_item_2(const sa_tree head, int n)
175 {
176 int h = LMT_SA_H_PART(n);
177 int m = LMT_SA_M_PART(n);
178 if (head->tree[h][m]) {
179 return head->tree[h][m][LMT_SA_L_PART(n)/2].ushort_value[n%2];
180 }
181 return (int) head->dflt.ushort_value[0];
182 }
183
184 inline int sa_get_item_4(const sa_tree head, int n, sa_tree_item *v)
185 {
186 int h = LMT_SA_H_PART(n);
187 int m = LMT_SA_M_PART(n);
188 if (head->tree[h][m]) {
189 *v = head->tree[h][m][LMT_SA_L_PART(n)];
190 return 1;
191 }
192 *v = head->dflt;
193 return 0;
194 }
195
196 inline int sa_get_item_8(const sa_tree head, int n, sa_tree_item *v1, sa_tree_item *v2)
197 {
198 int h = LMT_SA_H_PART(n);
199 int m = LMT_SA_M_PART(n);
200 if (head->tree[h][m]) {
201 int l = 2*LMT_SA_L_PART(n);
202 *v1 = head->tree[h][m][l];
203 *v2 = head->tree[h][m][l+1];
204 return 1;
205 }
206 *v1 = head->dflt;
207 *v2 = head->dflt;
208 return 0;
209 }
210
211# endif
212
213extern void sa_set_item_0 (const sa_tree head, int n, int v, int gl);
214extern void sa_set_item_1 (const sa_tree head, int n, int v, int gl);
215extern void sa_set_item_2 (const sa_tree head, int n, int v, int gl);
216extern void sa_set_item_4 (const sa_tree head, int n, const sa_tree_item v, int gl);
217extern void sa_set_item_8 (const sa_tree head, int n, const sa_tree_item v1, const sa_tree_item v2, int gl);
218extern sa_tree sa_new_tree (int identifier, int stacksize, int stackstep, int bytes, const sa_tree_item dflt);
219extern sa_tree sa_copy_tree (const sa_tree head);
220extern void sa_destroy_tree (sa_tree head);
221extern void sa_dump_tree (dumpstream f, sa_tree a);
222extern sa_tree sa_undump_tree (dumpstream f);
223extern void sa_restore_stack (const sa_tree a, int gl);
224extern void sa_reinit_stack (const sa_tree a, int gl);
225extern void sa_show_stack (const sa_tree a);
226extern void sa_clear_stack (const sa_tree a);
227
228extern void sa_set_item_n (const sa_tree head, int n, int v, int gl);
229extern int sa_get_item_n (const sa_tree head, int n);
230
231static inline halfword sa_return_item_0(const sa_tree head, halfword n)
232{
233 int hp = LMT_SA_H_PART(n);
234 if (head->tree[hp]) {
235 int mp = LMT_SA_M_PART(n);
236 if (head->tree[hp][mp]) {
237 return (halfword) get_nibble(head->tree[hp][mp][LMT_SA_L_PART(n)/8].uint_value,n);
238 }
239 }
240 return (halfword) get_nibble(head->dflt.uint_value,0);
241}
242
243static inline halfword sa_return_item_1(const sa_tree head, halfword n)
244{
245 int hp = LMT_SA_H_PART(n);
246 if (head->tree[hp]) {
247 int mp = LMT_SA_M_PART(n);
248 if (head->tree[hp][mp]) {
249 return (halfword) head->tree[hp][mp][LMT_SA_L_PART(n)/4].uchar_value[n%4];
250 }
251 }
252 return (halfword) head->dflt.uchar_value[0];
253}
254
255static inline halfword sa_return_item_2(const sa_tree head, halfword n)
256{
257 int hp = LMT_SA_H_PART(n);
258 if (head->tree[hp]) {
259 int mp = LMT_SA_M_PART(n);
260 if (head->tree[hp][mp]) {
261 return (halfword) head->tree[hp][mp][LMT_SA_L_PART(n)/2].ushort_value[n%2];
262 }
263 }
264 return (halfword) head->dflt.ushort_value[0];
265}
266
267static inline halfword sa_return_item_4(const sa_tree head, halfword n)
268{
269 int hp = LMT_SA_H_PART(n);
270 if (head->tree[hp]) {
271 int mp = LMT_SA_M_PART(n);
272 if (head->tree[hp][mp]) {
273 return (halfword) head->tree[hp][mp][LMT_SA_L_PART(n)].int_value;
274 }
275 }
276 return (halfword) head->dflt.int_value;
277}
278
279static inline void sa_rawset_item_0(const sa_tree head, halfword n, unsigned char v)
280{
281 head->tree[LMT_SA_H_PART(n)][LMT_SA_M_PART(n)][LMT_SA_L_PART(n)/8].uint_value = set_nibble(head->tree[LMT_SA_H_PART(n)][LMT_SA_M_PART(n)][LMT_SA_L_PART(n)/8].uint_value,n,v);
282}
283
284static inline void sa_rawset_item_1(const sa_tree head, halfword n, unsigned char v)
285{
286 head->tree[LMT_SA_H_PART(n)][LMT_SA_M_PART(n)][LMT_SA_L_PART(n)/4].uchar_value[n%4] = v;
287}
288
289static inline void sa_rawset_item_2(const sa_tree head, halfword n, unsigned short v)
290{
291 head->tree[LMT_SA_H_PART(n)][LMT_SA_M_PART(n)][LMT_SA_L_PART(n)/2].ushort_value[n%2] = v;
292}
293
294static inline void sa_rawset_item_4(const sa_tree head, halfword n, const sa_tree_item v)
295{
296 head->tree[LMT_SA_H_PART(n)][LMT_SA_M_PART(n)][LMT_SA_L_PART(n)] = v;
297}
298
299static inline void sa_rawset_item_8(const sa_tree head, halfword n, const sa_tree_item v1, const sa_tree_item v2)
300{
301 sa_tree_item *low = head->tree[LMT_SA_H_PART(n)][LMT_SA_M_PART(n)];
302 int l = 2*LMT_SA_L_PART(n);
303 low[l] = v1;
304 low[l+1] = v2;
305}
306
307
308
309extern void *sa_malloc_array (int recordsize, int size);
310extern void *sa_realloc_array (void *p, int recordsize, int size, int step);
311extern void *sa_calloc_array (int recordsize, int size);
312extern void *sa_free_array (void *p);
313extern void sa_wipe_array (void *head, int recordsize, int size);
314
315# endif
316 |