Pristine Ack-5.5
[Ack-5.5.git] / util / int / data.c
1 /*
2         Data access
3 */
4
5 /* $Id: data.c,v 2.5 1994/06/24 10:45:49 ceriel Exp $ */
6
7 #include        <em_abs.h>
8 #include        "logging.h"
9 #include        "nofloat.h"
10 #include        "global.h"
11 #include        "log.h"
12 #include        "trap.h"
13 #include        "warn.h"
14 #include        "alloc.h"
15 #include        "memdirect.h"
16 #include        "mem.h"
17 #include        "shadow.h"
18
19 #define HEAPSIZE        1000L           /* initial heap size */
20
21 extern size maxheap;                    /* from main.c */
22
23 #ifdef  LOGGING
24 char *data_sh;                          /* shadowbytes */
25 #endif  /* LOGGING */
26
27 PRIVATE warn_dtbits();
28
29 init_data(hb)
30         ptr hb;
31 {
32         HB = hb;                        /* set Heap Base */
33         HP = HB;                        /* initialize Heap Pointer */
34         HL = HB + HEAPSIZE;             /* initialize Heap Limit */
35
36         data = Malloc((size)p2i(HL), "data space");
37 #ifdef  LOGGING
38         data_sh = Malloc((size)p2i(HL), "shadowspace for data");
39         dt_clear_area(i2p(0), HL);
40 #endif  /* LOGGING */
41 }
42
43
44 /********************************************************
45  *      EM-register division.                           *
46  ********************************************************
47  *                                                      *
48  *      newHP(p)     - check and adjust HeapPointer.    *
49  *                                                      *
50  ********************************************************/
51
52 newHP(ap)
53         ptr ap;
54 {
55         register ptr p = ap;
56
57         if (in_gda(p)) {
58                 wtrap(WHPGDA, EHEAP);
59         }
60         if (in_stack(p)) {
61                 wtrap(WHPSTACK, EHEAP);
62         }
63         if (!is_wordaligned(p)) {
64                 wtrap(WHPODD, EHEAP);
65         }
66         if (maxheap) {
67                 /* more than allowed on command line */
68                 if (p - HB > maxheap) {
69                         warning(WEHEAP);
70                         trap(EHEAP);
71                 }
72         }
73         if (p > HL) {
74                 /* extend heap space */
75                 HL = i2p(allocfrac(p2i(p)) - 1);
76                 data = Realloc(data, (size)(p2i(HL) + 1), "heap space");
77 #ifdef  LOGGING
78                 data_sh = Realloc(data_sh, (size)(p2i(HL) + 1),
79                                                 "shadowspace for heap");
80 #endif  /* LOGGING */
81         }
82
83 #ifdef  LOGGING
84         if (p > HP) {
85                 dt_clear_area(HP, p);
86         }
87 #endif  /* LOGGING */
88         HP = p;
89 }
90
91 /************************************************************************
92  *      Data store division.                                            *
93  ************************************************************************
94  *                                                                      *
95  *      dt_stdp(addr, p)        - STore Data Pointer.                   *
96  *      dt_stn(addr, l, n)      - STore N byte integer.                 *
97  *      dt_stw(addr, l)         - STore wsize byte integer.             *
98  *      dt_stf(addr, f, n)      - STore n byte Floating point number.   *
99  *                                                                      *
100  ************************************************************************/
101
102 dt_stdp(addr, ap)
103         register ptr addr;
104         ptr ap;
105 {
106         register int i;
107         register long p = (long) ap;
108
109         LOG(("@g6 dt_stdp(%lu, %lu)", addr, p));
110         ch_in_data(addr, psize);
111         ch_wordaligned(addr);
112         for (i = (int) psize; i > 0; i--, addr++) {
113                 ch_dt_prot(addr);
114                 data_loc(addr) = (char) (p);
115                 dt_dp(addr);
116                 p = p>>8;
117         }
118 }
119
120 dt_stip(addr, ap)
121         register ptr addr;
122         ptr ap;
123 {
124         register int i;
125         register long p = (long) ap;
126
127         LOG(("@g6 dt_stip(%lu, %lu)", addr, p));
128         ch_in_data(addr, psize);
129         ch_wordaligned(addr);
130         for (i = (int) psize; i > 0; i--, addr++) {
131                 ch_dt_prot(addr);
132                 data_loc(addr) = (char) (p);
133                 dt_ip(addr);
134                 p = p>>8;
135         }
136 }
137
138 dt_stn(addr, al, n)
139         register ptr addr;
140         long al;
141         size n;
142 {
143         register int i;
144         register long l = al;
145 #ifdef LOGGING
146         /* a psize zero is ambiguous */
147         int sh_flags = (l == 0 && n == psize) ? (SH_INT|SH_DATAP) : SH_INT;
148 #endif /* LOGGING */
149
150         LOG(("@g6 dt_stn(%lu, %lu, %lu)", addr, l, n));
151         ch_in_data(addr, n);
152         ch_aligned(addr, n);
153         for (i = (int) n; i > 0; i--, addr++) {
154                 ch_dt_prot(addr);
155                 data_loc(addr) = (char) l;
156 #ifdef LOGGING
157                 dt_sh(addr) = sh_flags;
158 #endif  /* LOGGING */
159                 l = l>>8;
160         }
161 }
162
163 dt_stw(addr, al)
164         register ptr addr;
165         long al;
166 {
167         register int i;
168         register long l = al;
169 #ifdef LOGGING
170         /* a psize zero is ambiguous */
171         int sh_flags = (l == 0 && wsize == psize) ? (SH_INT|SH_DATAP) : SH_INT;
172 #endif /* LOGGING */
173
174         LOG(("@g6 dt_stw(%lu, %lu)", addr, l));
175         ch_in_data(addr, wsize);
176         ch_wordaligned(addr);
177         for (i = (int) wsize; i > 0; i--, addr++) {
178                 ch_dt_prot(addr);
179                 data_loc(addr) = (char) l;
180 #ifdef LOGGING
181                 dt_sh(addr) = sh_flags;
182 #endif  /* LOGGING */
183                 l = l>>8;
184         }
185 }
186
187 #ifndef NOFLOAT
188 dt_stf(addr, f, n)
189         register ptr addr;
190         double f;
191         register size n;
192 {
193         register char *cp = (char *) &f;
194         register int i;
195         float fl;
196
197         LOG(("@g6 dt_stf(%lu, %g, %lu)", addr, f, n));
198         ch_in_data(addr, n);
199         ch_wordaligned(addr);
200         if ((int) n == 4) {
201                 fl = f;
202                 cp = (char *) &fl;
203         }
204         for (i = (int) n; i > 0; i--, addr++) {
205                 ch_dt_prot(addr);
206                 data_loc(addr) = *cp++;
207                 dt_fl(addr);
208         }
209 }
210 #endif  /* NOFLOAT */
211
212 /************************************************************************
213  *      Data load division.                                             *
214  ************************************************************************
215  *                                                                      *
216  *      dt_lddp(addr)      - LoaD Data Pointer from data.               *
217  *      dt_ldip(addr)      - LoaD Instruction Pointer from data.        *
218  *      dt_ldu(addr, n)    - LoaD n Unsigned bytes from data.           *
219  *      dt_lduw(addr)      - LoaD wsize Unsigned bytes from data.       *
220  *      dt_lds(addr, n)    - LoaD n Signed bytes from data.             *
221  *      dt_ldsw(addr)      - LoaD wsize Signed bytes from data.         *
222  *                                                                      *
223  ************************************************************************/
224
225 ptr dt_lddp(addr)
226         register ptr addr;
227 {
228         register ptr p;
229
230         LOG(("@g6 dt_lddp(%lu)", addr));
231
232         ch_in_data(addr, psize);
233         ch_wordaligned(addr);
234 #ifdef  LOGGING
235         if (!is_dt_set(addr, psize, SH_DATAP)) {
236                 warning(WGDPEXP);
237                 warn_dtbits(addr, psize);
238         }
239 #endif  /* LOGGING */
240
241         p = p_in_data(addr);
242         LOG(("@g6 dt_lddp() returns %lu", p));
243         return (p);
244 }
245
246 ptr dt_ldip(addr)
247         register ptr addr;
248 {
249         register ptr p;
250
251         LOG(("@g6 dt_ldip(%lu)", addr));
252
253         ch_in_data(addr, psize);
254         ch_wordaligned(addr);
255 #ifdef  LOGGING
256         if (!is_dt_set(addr, psize, SH_INSP)) {
257                 warning(WGIPEXP);
258                 warn_dtbits(addr, psize);
259         }
260 #endif  /* LOGGING */
261
262         p = p_in_data(addr);
263         LOG(("@g6 dt_ldip() returns %lu", p));
264         return (p);
265 }
266
267 unsigned long dt_ldu(addr, n)
268         register ptr addr;
269         size n;
270 {
271         register int i;
272         register unsigned long u = 0;
273
274         LOG(("@g6 dt_ldu(%lu, %lu)", addr, n));
275
276         ch_in_data(addr, n);
277         ch_aligned(addr, n);
278 #ifdef  LOGGING
279         if (!is_dt_set(addr, n, SH_INT)) {
280                 warning(n == 1 ? WGCEXP : WGIEXP);
281                 warn_dtbits(addr, n);
282         }
283 #endif  /* LOGGING */
284
285         addr += n-1;
286         for (i = (int) n-1; i >= 0; i--, addr--) {
287                 u = (u<<8) | btou(data_loc(addr));
288         }
289         LOG(("@g6 dt_ldu() returns %lu", u));
290         return (u);
291 }
292
293 unsigned long dt_lduw(addr)
294         register ptr addr;
295 {
296         register int i;
297         register unsigned long u = 0;
298
299         LOG(("@g6 dt_lduw(%lu)", addr));
300
301         ch_in_data(addr, wsize);
302         ch_wordaligned(addr);
303 #ifdef  LOGGING
304         if (!is_dt_set(addr, wsize, SH_INT)) {
305                 warning(WGIEXP);
306                 warn_dtbits(addr, wsize);
307         }
308 #endif  /* LOGGING */
309
310         addr += wsize-1;
311         for (i = (int) wsize-1; i >= 0; i--, addr--) {
312                 u = (u<<8) | btou(data_loc(addr));
313         }
314         LOG(("@g6 dt_lduw() returns %lu", u));
315         return (u);
316 }
317
318 long dt_lds(addr, n)
319         register ptr addr;
320         size n;
321 {
322         register int i;
323         register long l;
324
325         LOG(("@g6 dt_lds(%lu, %lu)", addr, n));
326
327         ch_in_data(addr, n);
328         ch_aligned(addr, n);
329 #ifdef  LOGGING
330         if (!is_dt_set(addr, n, SH_INT)) {
331                 warning(n == 1 ? WGCEXP : WGIEXP);
332                 warn_dtbits(addr, n);
333         }
334 #endif  /* LOGGING */
335
336         addr += n-2;
337         l = btos(data_loc(addr + 1));
338         for (i = n - 2; i >= 0; i--, addr--) {
339                 l = (l<<8) | btol(data_loc(addr));
340         }
341         LOG(("@g6 dt_lds() returns %lu", l));
342         return (l);
343 }
344
345 long dt_ldsw(addr)
346         register ptr addr;
347 {
348         register int i;
349         register long l;
350
351         LOG(("@g6 dt_ldsw(%lu)", addr));
352
353         ch_in_data(addr, wsize);
354         ch_wordaligned(addr);
355 #ifdef  LOGGING
356         if (!is_dt_set(addr, wsize, SH_INT)) {
357                 warning(WGIEXP);
358                 warn_dtbits(addr, wsize);
359         }
360 #endif  /* LOGGING */
361
362         addr += wsize-2;
363         l = btos(data_loc(addr + 1));
364         for (i = wsize - 2; i >= 0; i--, addr--) {
365                 l = (l<<8) | btol(data_loc(addr));
366         }
367         LOG(("@g6 dt_ldsw() returns %lu", l));
368         return (l);
369 }
370
371 /************************************************************************
372  *      Data move division                                              *
373  ************************************************************************
374  *                                                                      *
375  *      dt_mvd(d2, d1, n) - Move n bytes in data from d1 to d2.         *
376  *      dt_mvs(d, s, n)   - Move n bytes from s in stack to d in data.  *
377  *                                                                      *
378  *      See st_mvs() in stack.c for a description.                      *
379  *                                                                      *
380  ************************************************************************/
381
382 dt_mvd(d2, d1, n)                       /* d1 -> d2 */
383         register ptr d2, d1;
384         size n;
385 {
386         register int i;
387
388         ch_in_data(d1, n);
389         ch_wordaligned(d1);
390         ch_in_data(d2, n);
391         ch_wordaligned(d2);
392
393         for (i = (int) n; i > 0; i--, d1++, d2++) {
394                 ch_dt_prot(d2);
395                 data_loc(d2) = data_loc(d1);
396 #ifdef  LOGGING
397                 dt_sh(d2) = dt_sh(d1) & ~SH_PROT;
398 #endif  /* LOGGING */
399         }
400 }
401
402 dt_mvs(d, s, n)                         /* s -> d */
403         register ptr d, s;
404         size n;
405 {
406         register int i;
407
408         ch_in_stack(s, n);
409         ch_wordaligned(s);
410         ch_in_data(d, n);
411         ch_wordaligned(d);
412
413         for (i = (int) n; i > 0; i--, d++, s++) {
414                 ch_dt_prot(d);
415                 ch_st_prot(s);
416                 data_loc(d) = stack_loc(s);
417 #ifdef  LOGGING
418                 dt_sh(d) = st_sh(s) & ~SH_PROT;
419 #endif  /* LOGGING */
420         }
421 }
422
423 #ifdef  LOGGING
424
425 PRIVATE warn_dtbits(addr, n)
426         register ptr addr;
427         register size n;
428 {
429         register int or_bits = 0;
430         register int and_bits = 0xff;
431
432         while (n--) {
433                 or_bits |= dt_sh(addr);
434                 and_bits &= dt_sh(addr);
435                 addr++;
436         }
437
438         if (or_bits != and_bits) {
439                 /* no use trying to diagnose */
440                 warningcont(WWASMISC);
441                 return;
442         }
443         if (or_bits == 0)
444                 warningcont(WWASUND);
445         if (or_bits & SH_INT)
446                 warningcont(WWASINT);
447         if (or_bits & SH_FLOAT)
448                 warningcont(WWASFLOAT);
449         if (or_bits & SH_DATAP)
450                 warningcont(WWASDATAP);
451         if (or_bits & SH_INSP)
452                 warningcont(WWASINSP);
453 }
454
455 #endif  /* LOGGING */
456