diff options
author | H. Peter Anvin <hpa@zytor.com> | 2008-06-09 17:40:16 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2008-06-09 17:40:16 -0700 |
commit | fcb8909749b2a159ba7f32fec7df8e465a974f77 (patch) | |
tree | 59a257a1d223ca0ed0f3e410830b0cc8544804d0 /raa.c | |
parent | 35d620d2fdd6bfb1502c7db60ad8331edf74354e (diff) | |
download | nasm-fcb8909749b2a159ba7f32fec7df8e465a974f77.tar.gz nasm-fcb8909749b2a159ba7f32fec7df8e465a974f77.tar.bz2 nasm-fcb8909749b2a159ba7f32fec7df8e465a974f77.zip |
Move all the RAA code out of nasmlib
The RAA code doesn't have to be in nasmlib; it is only used by nasm
itself, and is better handled in a separate module.
Diffstat (limited to 'raa.c')
-rw-r--r-- | raa.c | 95 |
1 files changed, 95 insertions, 0 deletions
@@ -0,0 +1,95 @@ +#include "nasmlib.h" +#include "raa.h" + +#define LEAFSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_LEAF)) +#define BRANCHSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_BRANCH)) + +#define LAYERSHIFT(r) ( (r)->layers==0 ? RAA_BLKSHIFT : RAA_LAYERSHIFT ) + +static struct RAA *real_raa_init(int layers) +{ + struct RAA *r; + int i; + + if (layers == 0) { + r = nasm_zalloc(LEAFSIZ); + r->shift = 0; + } else { + r = nasm_malloc(BRANCHSIZ); + r->layers = layers; + for (i = 0; i < RAA_LAYERSIZE; i++) + r->u.b.data[i] = NULL; + r->shift = (RAA_BLKSHIFT-RAA_LAYERSHIFT) + layers*RAA_LAYERSHIFT; + } + return r; +} + +struct RAA *raa_init(void) +{ + return real_raa_init(0); +} + +void raa_free(struct RAA *r) +{ + if (r->layers) { + struct RAA **p; + for (p = r->u.b.data; p - r->u.b.data < RAA_LAYERSIZE; p++) + if (*p) + raa_free(*p); + } + nasm_free(r); +} + +int64_t raa_read(struct RAA *r, int32_t posn) +{ + if ((uint32_t)posn >= (UINT32_C(1) << (r->shift + LAYERSHIFT(r)))) + return 0; /* Return 0 for undefined entries */ + while (r->layers > 0) { + int32_t l = posn >> r->shift; + posn &= (UINT32_C(1) << r->shift)-1; + r = r->u.b.data[l]; + if (!r) + return 0; /* Return 0 for undefined entries */ + } + return r->u.l.data[posn]; +} + +struct RAA *raa_write(struct RAA *r, int32_t posn, int64_t value) +{ + struct RAA *result; + + if (posn < 0) + nasm_malloc_error(ERR_PANIC, "negative position in raa_write"); + + while ((UINT32_C(1) << (r->shift+LAYERSHIFT(r))) <= (uint32_t)posn) { + /* + * Must add a layer. + */ + struct RAA *s; + int i; + + s = nasm_malloc(BRANCHSIZ); + for (i = 0; i < RAA_LAYERSIZE; i++) + s->u.b.data[i] = NULL; + s->layers = r->layers + 1; + s->shift = LAYERSHIFT(r) + r->shift; + s->u.b.data[0] = r; + r = s; + } + + result = r; + + while (r->layers > 0) { + struct RAA **s; + int32_t l = posn >> r->shift; + posn &= (UINT32_C(1) << r->shift)-1; + s = &r->u.b.data[l]; + if (!*s) + *s = real_raa_init(r->layers - 1); + r = *s; + } + + r->u.l.data[posn] = value; + + return result; +} |