Fix regular expression at doc/rdsrc.pl
[platform/upstream/nasm.git] / sync.c
1 /* ----------------------------------------------------------------------- *
2  *
3  *   Copyright 1996-2009 The NASM Authors - All Rights Reserved
4  *   See the file AUTHORS included with the NASM distribution for
5  *   the specific copyright holders.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following
9  *   conditions are met:
10  *
11  *   * Redistributions of source code must retain the above copyright
12  *     notice, this list of conditions and the following disclaimer.
13  *   * Redistributions in binary form must reproduce the above
14  *     copyright notice, this list of conditions and the following
15  *     disclaimer in the documentation and/or other materials provided
16  *     with the distribution.
17  *
18  *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19  *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20  *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21  *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23  *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * ----------------------------------------------------------------------- */
33
34 /*
35  * sync.c   the Netwide Disassembler synchronisation processing module
36  */
37
38 #include "compiler.h"
39
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <limits.h>
43 #include <inttypes.h>
44
45 #include "nasmlib.h"
46 #include "sync.h"
47
48 #define SYNC_MAX_SHIFT          31
49 #define SYNC_MAX_SIZE           (1U << SYNC_MAX_SHIFT)
50
51 /* initial # of sync points (*must* be power of two)*/
52 #define SYNC_INITIAL_CHUNK      (1U << 12)
53
54 /*
55  * This lot manages the current set of sync points by means of a
56  * heap (priority queue) structure.
57  */
58
59 static struct Sync {
60     uint32_t pos;
61     uint32_t length;
62 } *synx;
63
64 static uint32_t max_synx, nsynx;
65
66 static inline void swap_sync(uint32_t dst, uint32_t src)
67 {
68     struct Sync t = synx[dst];
69     synx[dst] = synx[src];
70     synx[src] = t;
71 }
72
73 void init_sync(void)
74 {
75     max_synx = SYNC_INITIAL_CHUNK;
76     synx = nasm_malloc((max_synx + 1) * sizeof(*synx));
77     nsynx = 0;
78 }
79
80 void add_sync(uint32_t pos, uint32_t length)
81 {
82     uint32_t i;
83
84     if (nsynx >= max_synx) {
85         if (max_synx >= SYNC_MAX_SIZE) /* too many sync points! */
86             return;
87         max_synx = (max_synx << 1);
88         synx = nasm_realloc(synx, (max_synx + 1) * sizeof(*synx));
89     }
90
91     nsynx++;
92     synx[nsynx].pos = pos;
93     synx[nsynx].length = length;
94
95     for (i = nsynx; i > 1; i /= 2) {
96         if (synx[i / 2].pos > synx[i].pos)
97             swap_sync(i / 2, i);
98     }
99 }
100
101 uint32_t next_sync(uint32_t position, uint32_t *length)
102 {
103     while (nsynx > 0 && synx[1].pos + synx[1].length <= position) {
104         uint32_t i, j;
105
106         swap_sync(nsynx, 1);
107         nsynx--;
108
109         i = 1;
110         while (i * 2 <= nsynx) {
111             j = i * 2;
112             if (synx[j].pos < synx[i].pos &&
113                 (j + 1 > nsynx || synx[j + 1].pos > synx[j].pos)) {
114                 swap_sync(j, i);
115                 i = j;
116             } else if (j + 1 <= nsynx && synx[j + 1].pos < synx[i].pos) {
117                 swap_sync(j + 1, i);
118                 i = j + 1;
119             } else
120                 break;
121         }
122     }
123
124     if (nsynx > 0) {
125         if (length)
126             *length = synx[1].length;
127         return synx[1].pos;
128     } else {
129         if (length)
130             *length = 0L;
131         return 0;
132     }
133 }