Merge branch 'nasm-2.03.x'
[platform/upstream/nasm.git] / raa.c
1 #include "nasmlib.h"
2 #include "raa.h"
3
4 #define LEAFSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_LEAF))
5 #define BRANCHSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_BRANCH))
6
7 #define LAYERSHIFT(r) ( (r)->layers==0 ? RAA_BLKSHIFT : RAA_LAYERSHIFT )
8
9 static struct RAA *real_raa_init(int layers)
10 {
11     struct RAA *r;
12     int i;
13
14     if (layers == 0) {
15         r = nasm_zalloc(LEAFSIZ);
16         r->shift = 0;
17     } else {
18         r = nasm_malloc(BRANCHSIZ);
19         r->layers = layers;
20         for (i = 0; i < RAA_LAYERSIZE; i++)
21             r->u.b.data[i] = NULL;
22         r->shift = (RAA_BLKSHIFT-RAA_LAYERSHIFT) + layers*RAA_LAYERSHIFT;
23     }
24     return r;
25 }
26
27 struct RAA *raa_init(void)
28 {
29     return real_raa_init(0);
30 }
31
32 void raa_free(struct RAA *r)
33 {
34     if (r->layers) {
35         struct RAA **p;
36         for (p = r->u.b.data; p - r->u.b.data < RAA_LAYERSIZE; p++)
37             if (*p)
38                 raa_free(*p);
39     }
40     nasm_free(r);
41 }
42
43 int64_t raa_read(struct RAA *r, int32_t posn)
44 {
45     if ((uint32_t)posn >= (UINT32_C(1) << (r->shift + LAYERSHIFT(r))))
46         return 0;               /* Return 0 for undefined entries */
47     while (r->layers > 0) {
48         int32_t l = posn >> r->shift;
49         posn &= (UINT32_C(1) << r->shift)-1;
50         r = r->u.b.data[l];
51         if (!r)
52             return 0;           /* Return 0 for undefined entries */
53     }
54     return r->u.l.data[posn];
55 }
56
57 struct RAA *raa_write(struct RAA *r, int32_t posn, int64_t value)
58 {
59     struct RAA *result;
60
61     if (posn < 0)
62         nasm_malloc_error(ERR_PANIC, "negative position in raa_write");
63
64     while ((UINT32_C(1) << (r->shift+LAYERSHIFT(r))) <= (uint32_t)posn) {
65         /*
66          * Must add a layer.
67          */
68         struct RAA *s;
69         int i;
70
71         s = nasm_malloc(BRANCHSIZ);
72         for (i = 0; i < RAA_LAYERSIZE; i++)
73             s->u.b.data[i] = NULL;
74         s->layers = r->layers + 1;
75         s->shift = LAYERSHIFT(r) + r->shift;
76         s->u.b.data[0] = r;
77         r = s;
78     }
79
80     result = r;
81
82     while (r->layers > 0) {
83         struct RAA **s;
84         int32_t l = posn >> r->shift;
85         posn &= (UINT32_C(1) << r->shift)-1;
86         s = &r->u.b.data[l];
87         if (!*s)
88             *s = real_raa_init(r->layers - 1);
89         r = *s;
90     }
91
92     r->u.l.data[posn] = value;
93
94     return result;
95 }