Pristine Ack-5.5
[Ack-5.5.git] / util / int / do_array.c
1 /*
2  * Sources of the "ARRAY" group instructions
3  */
4
5 /* $Id: do_array.c,v 2.4 1994/06/24 10:46:01 ceriel Exp $ */
6
7 #include        <em_abs.h>
8 #include        "global.h"
9 #include        "log.h"
10 #include        "trap.h"
11 #include        "mem.h"
12 #include        "text.h"
13 #include        "fra.h"
14
15 #define LAR             1
16 #define SAR             2
17 #define AAR             3
18
19 PRIVATE arr();
20
21 DoLAR(arg)
22         size arg;
23 {
24         /* LAR w: Load array element, descriptor contains integers of size w */
25         LOG(("@A6 DoLAR(%ld)", arg));
26         arr(LAR, arg_wi(arg));
27 }
28
29 DoSAR(arg)
30         size arg;
31 {
32         /* SAR w: Store array element */
33         LOG(("@A6 DoSAR(%ld)", arg));
34         arr(SAR, arg_wi(arg));
35 }
36
37 DoAAR(arg)
38         size arg;
39 {
40         /* AAR w: Load address of array element */
41         LOG(("@A6 DoAAR(%ld)", arg));
42         arr(AAR, arg_wi(arg));
43 }
44
45
46 /********************************************************
47 *               Array arithmetic                        *
48 *                                                       *
49 *       1. The address of the descriptor is popped.     *
50 *       2. The index is popped.                         *
51 *       3. Calculate index - lower bound.               *
52 *       4. Check if in range.                           *
53 *       5. Calculate object size.                       *
54 *       6. Perform the correct function.                *
55 *********************************************************/
56
57 PRIVATE arr(type, elm_size)
58         int type;                       /* operation TYPE */
59         size elm_size;                  /* ELeMent SIZE */
60 {
61         register ptr desc = dppop();    /* array DESCriptor */
62         register size obj_size;         /* OBJect SIZE */
63         register long diff =            /* between index and lower bound */
64                 spop(elm_size) - mem_lds(desc, elm_size);
65         register ptr arr_addr = dppop();/* ARRay ADDRess */
66
67         if (must_test && !(IgnMask&BIT(EARRAY))) {
68                 if (diff < 0 || diff > mem_lds(desc + elm_size, elm_size)) {
69                         trap(EARRAY);
70                 }
71         }
72         obj_size = mem_lds(desc + (2*elm_size), elm_size);
73         obj_size = arg_o(((long) obj_size));
74         spoilFRA();                     /* array functions don't retain FRA */
75         switch (type) {
76                 case LAR:
77                         push_m(arr_addr + diff * obj_size, obj_size);
78                         break;
79                 case SAR:
80                         pop_m(arr_addr + diff * obj_size, obj_size);
81                         break;
82                 case AAR:
83                         dppush(arr_addr + diff * obj_size);
84                         break;
85         }
86 }