Mark Perl scripts executable
[nasm/autotest.git] / raa.c
blobee5a5a9efa313c58497a43f3d205f04cef16ce85
1 #include "nasmlib.h"
2 #include "raa.h"
4 #define LEAFSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_LEAF))
5 #define BRANCHSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_BRANCH))
7 #define LAYERSHIFT(r) ( (r)->layers==0 ? RAA_BLKSHIFT : RAA_LAYERSHIFT )
9 static struct RAA *real_raa_init(int layers)
11 struct RAA *r;
12 int i;
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;
24 return r;
27 struct RAA *raa_init(void)
29 return real_raa_init(0);
32 void raa_free(struct RAA *r)
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);
40 nasm_free(r);
43 int64_t raa_read(struct RAA *r, int32_t posn)
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 */
54 return r->u.l.data[posn];
57 struct RAA *raa_write(struct RAA *r, int32_t posn, int64_t value)
59 struct RAA *result;
61 if (posn < 0)
62 nasm_malloc_error(ERR_PANIC, "negative position in raa_write");
64 while ((UINT32_C(1) << (r->shift+LAYERSHIFT(r))) <= (uint32_t)posn) {
66 * Must add a layer.
68 struct RAA *s;
69 int i;
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;
80 result = r;
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;
92 r->u.l.data[posn] = value;
94 return result;