H. Peter Anvin | 9e6747c | 2009-06-28 17:13:04 -0700 | [diff] [blame] | 1 | /* ----------------------------------------------------------------------- * |
Cyrill Gorcunov | f064c1c | 2009-12-21 19:31:45 +0300 | [diff] [blame] | 2 | * |
H. Peter Anvin | 9e6747c | 2009-06-28 17:13:04 -0700 | [diff] [blame] | 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. |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 6 | * |
H. Peter Anvin | 9e6747c | 2009-06-28 17:13:04 -0700 | [diff] [blame] | 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. |
Cyrill Gorcunov | f064c1c | 2009-12-21 19:31:45 +0300 | [diff] [blame] | 17 | * |
H. Peter Anvin | 9e6747c | 2009-06-28 17:13:04 -0700 | [diff] [blame] | 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 |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 36 | */ |
| 37 | |
H. Peter Anvin | fe50195 | 2007-10-02 21:53:51 -0700 | [diff] [blame] | 38 | #include "compiler.h" |
| 39 | |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 40 | |
H. Peter Anvin | 8d024e7 | 2007-09-19 21:41:02 -0700 | [diff] [blame] | 41 | #include "nasmlib.h" |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 42 | #include "sync.h" |
| 43 | |
Cyrill Gorcunov | faaad6e | 2009-12-22 23:33:40 +0300 | [diff] [blame] | 44 | #define SYNC_MAX_SHIFT 31 |
| 45 | #define SYNC_MAX_SIZE (1U << SYNC_MAX_SHIFT) |
| 46 | |
| 47 | /* initial # of sync points (*must* be power of two)*/ |
| 48 | #define SYNC_INITIAL_CHUNK (1U << 12) |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 49 | |
H. Peter Anvin | d7ed89e | 2002-04-30 20:52:08 +0000 | [diff] [blame] | 50 | /* |
| 51 | * This lot manages the current set of sync points by means of a |
| 52 | * heap (priority queue) structure. |
| 53 | */ |
| 54 | |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 55 | static struct Sync { |
Ruslan Kabatsayev | 3ebed50 | 2017-02-12 19:31:19 +0300 | [diff] [blame] | 56 | uint64_t pos; |
Keith Kanios | b7a8954 | 2007-04-12 02:40:54 +0000 | [diff] [blame] | 57 | uint32_t length; |
H. Peter Anvin | 6768eb7 | 2002-04-30 20:52:26 +0000 | [diff] [blame] | 58 | } *synx; |
Cyrill Gorcunov | f064c1c | 2009-12-21 19:31:45 +0300 | [diff] [blame] | 59 | |
Cyrill Gorcunov | faaad6e | 2009-12-22 23:33:40 +0300 | [diff] [blame] | 60 | static uint32_t max_synx, nsynx; |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 61 | |
Cyrill Gorcunov | 2ec4ad8 | 2009-07-11 18:37:08 +0400 | [diff] [blame] | 62 | static inline void swap_sync(uint32_t dst, uint32_t src) |
| 63 | { |
| 64 | struct Sync t = synx[dst]; |
| 65 | synx[dst] = synx[src]; |
| 66 | synx[src] = t; |
| 67 | } |
| 68 | |
H. Peter Anvin | e2c8018 | 2005-01-15 22:15:51 +0000 | [diff] [blame] | 69 | void init_sync(void) |
H. Peter Anvin | eba20a7 | 2002-04-30 20:53:55 +0000 | [diff] [blame] | 70 | { |
Cyrill Gorcunov | faaad6e | 2009-12-22 23:33:40 +0300 | [diff] [blame] | 71 | max_synx = SYNC_INITIAL_CHUNK; |
| 72 | synx = nasm_malloc((max_synx + 1) * sizeof(*synx)); |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 73 | nsynx = 0; |
| 74 | } |
| 75 | |
Ruslan Kabatsayev | 3ebed50 | 2017-02-12 19:31:19 +0300 | [diff] [blame] | 76 | void add_sync(uint64_t pos, uint32_t length) |
H. Peter Anvin | eba20a7 | 2002-04-30 20:53:55 +0000 | [diff] [blame] | 77 | { |
Cyrill Gorcunov | faaad6e | 2009-12-22 23:33:40 +0300 | [diff] [blame] | 78 | uint32_t i; |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 79 | |
H. Peter Anvin | 8d024e7 | 2007-09-19 21:41:02 -0700 | [diff] [blame] | 80 | if (nsynx >= max_synx) { |
Cyrill Gorcunov | faaad6e | 2009-12-22 23:33:40 +0300 | [diff] [blame] | 81 | if (max_synx >= SYNC_MAX_SIZE) /* too many sync points! */ |
| 82 | return; |
| 83 | max_synx = (max_synx << 1); |
Cyrill Gorcunov | f064c1c | 2009-12-21 19:31:45 +0300 | [diff] [blame] | 84 | synx = nasm_realloc(synx, (max_synx + 1) * sizeof(*synx)); |
H. Peter Anvin | 8d024e7 | 2007-09-19 21:41:02 -0700 | [diff] [blame] | 85 | } |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 86 | |
| 87 | nsynx++; |
| 88 | synx[nsynx].pos = pos; |
| 89 | synx[nsynx].length = length; |
| 90 | |
| 91 | for (i = nsynx; i > 1; i /= 2) { |
Cyrill Gorcunov | 2ec4ad8 | 2009-07-11 18:37:08 +0400 | [diff] [blame] | 92 | if (synx[i / 2].pos > synx[i].pos) |
| 93 | swap_sync(i / 2, i); |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 94 | } |
| 95 | } |
| 96 | |
Ruslan Kabatsayev | 3ebed50 | 2017-02-12 19:31:19 +0300 | [diff] [blame] | 97 | uint64_t next_sync(uint64_t position, uint32_t *length) |
H. Peter Anvin | eba20a7 | 2002-04-30 20:53:55 +0000 | [diff] [blame] | 98 | { |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 99 | while (nsynx > 0 && synx[1].pos + synx[1].length <= position) { |
Cyrill Gorcunov | faaad6e | 2009-12-22 23:33:40 +0300 | [diff] [blame] | 100 | uint32_t i, j; |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 101 | |
Cyrill Gorcunov | 2ec4ad8 | 2009-07-11 18:37:08 +0400 | [diff] [blame] | 102 | swap_sync(nsynx, 1); |
H. Peter Anvin | e2c8018 | 2005-01-15 22:15:51 +0000 | [diff] [blame] | 103 | nsynx--; |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 104 | |
| 105 | i = 1; |
H. Peter Anvin | e2c8018 | 2005-01-15 22:15:51 +0000 | [diff] [blame] | 106 | while (i * 2 <= nsynx) { |
| 107 | j = i * 2; |
| 108 | if (synx[j].pos < synx[i].pos && |
| 109 | (j + 1 > nsynx || synx[j + 1].pos > synx[j].pos)) { |
Cyrill Gorcunov | 2ec4ad8 | 2009-07-11 18:37:08 +0400 | [diff] [blame] | 110 | swap_sync(j, i); |
H. Peter Anvin | e2c8018 | 2005-01-15 22:15:51 +0000 | [diff] [blame] | 111 | i = j; |
| 112 | } else if (j + 1 <= nsynx && synx[j + 1].pos < synx[i].pos) { |
Cyrill Gorcunov | 2ec4ad8 | 2009-07-11 18:37:08 +0400 | [diff] [blame] | 113 | swap_sync(j + 1, i); |
H. Peter Anvin | e2c8018 | 2005-01-15 22:15:51 +0000 | [diff] [blame] | 114 | i = j + 1; |
| 115 | } else |
| 116 | break; |
| 117 | } |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 118 | } |
| 119 | |
| 120 | if (nsynx > 0) { |
H. Peter Anvin | e2c8018 | 2005-01-15 22:15:51 +0000 | [diff] [blame] | 121 | if (length) |
| 122 | *length = synx[1].length; |
| 123 | return synx[1].pos; |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 124 | } else { |
H. Peter Anvin | e2c8018 | 2005-01-15 22:15:51 +0000 | [diff] [blame] | 125 | if (length) |
| 126 | *length = 0L; |
H. Peter Anvin | 49da468 | 2007-11-20 13:22:58 -0800 | [diff] [blame] | 127 | return 0; |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 128 | } |
| 129 | } |