H. Peter Anvin | 9e6747c | 2009-06-28 17:13:04 -0700 | [diff] [blame] | 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. |
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. |
| 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 |
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 | #include <stdio.h> |
H. Peter Anvin | 6768eb7 | 2002-04-30 20:52:26 +0000 | [diff] [blame] | 41 | #include <stdlib.h> |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 42 | #include <limits.h> |
Keith Kanios | b7a8954 | 2007-04-12 02:40:54 +0000 | [diff] [blame] | 43 | #include <inttypes.h> |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 44 | |
H. Peter Anvin | 8d024e7 | 2007-09-19 21:41:02 -0700 | [diff] [blame] | 45 | #include "nasmlib.h" |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 46 | #include "sync.h" |
| 47 | |
H. Peter Anvin | 8d024e7 | 2007-09-19 21:41:02 -0700 | [diff] [blame] | 48 | #define SYNC_MAX 4096 /* max # of sync points (initial) */ |
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 { |
Keith Kanios | b7a8954 | 2007-04-12 02:40:54 +0000 | [diff] [blame] | 56 | uint32_t pos; |
| 57 | uint32_t length; |
H. Peter Anvin | 6768eb7 | 2002-04-30 20:52:26 +0000 | [diff] [blame] | 58 | } *synx; |
H. Peter Anvin | 8d024e7 | 2007-09-19 21:41:02 -0700 | [diff] [blame] | 59 | static int max_synx, nsynx; |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 60 | |
H. Peter Anvin | e2c8018 | 2005-01-15 22:15:51 +0000 | [diff] [blame] | 61 | void init_sync(void) |
H. Peter Anvin | eba20a7 | 2002-04-30 20:53:55 +0000 | [diff] [blame] | 62 | { |
H. Peter Anvin | 8d024e7 | 2007-09-19 21:41:02 -0700 | [diff] [blame] | 63 | max_synx = SYNC_MAX-1; |
| 64 | synx = nasm_malloc(SYNC_MAX * sizeof(*synx)); |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 65 | nsynx = 0; |
| 66 | } |
| 67 | |
Keith Kanios | b7a8954 | 2007-04-12 02:40:54 +0000 | [diff] [blame] | 68 | void add_sync(uint32_t pos, uint32_t length) |
H. Peter Anvin | eba20a7 | 2002-04-30 20:53:55 +0000 | [diff] [blame] | 69 | { |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 70 | int i; |
| 71 | |
H. Peter Anvin | 8d024e7 | 2007-09-19 21:41:02 -0700 | [diff] [blame] | 72 | if (nsynx >= max_synx) { |
| 73 | max_synx = (max_synx << 1)+1; |
| 74 | synx = nasm_realloc(synx, (max_synx+1) * sizeof(*synx)); |
| 75 | } |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 76 | |
| 77 | nsynx++; |
| 78 | synx[nsynx].pos = pos; |
| 79 | synx[nsynx].length = length; |
| 80 | |
| 81 | for (i = nsynx; i > 1; i /= 2) { |
H. Peter Anvin | e2c8018 | 2005-01-15 22:15:51 +0000 | [diff] [blame] | 82 | if (synx[i / 2].pos > synx[i].pos) { |
| 83 | struct Sync t; |
| 84 | t = synx[i / 2]; /* structure copy */ |
| 85 | synx[i / 2] = synx[i]; /* structure copy again */ |
| 86 | synx[i] = t; /* another structure copy */ |
| 87 | } |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 88 | } |
| 89 | } |
| 90 | |
Keith Kanios | b7a8954 | 2007-04-12 02:40:54 +0000 | [diff] [blame] | 91 | uint32_t next_sync(uint32_t position, uint32_t *length) |
H. Peter Anvin | eba20a7 | 2002-04-30 20:53:55 +0000 | [diff] [blame] | 92 | { |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 93 | while (nsynx > 0 && synx[1].pos + synx[1].length <= position) { |
H. Peter Anvin | e2c8018 | 2005-01-15 22:15:51 +0000 | [diff] [blame] | 94 | int i, j; |
| 95 | struct Sync t; |
| 96 | t = synx[nsynx]; /* structure copy */ |
| 97 | synx[nsynx] = synx[1]; /* structure copy */ |
| 98 | synx[1] = t; /* ditto */ |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 99 | |
H. Peter Anvin | e2c8018 | 2005-01-15 22:15:51 +0000 | [diff] [blame] | 100 | nsynx--; |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 101 | |
| 102 | i = 1; |
H. Peter Anvin | e2c8018 | 2005-01-15 22:15:51 +0000 | [diff] [blame] | 103 | while (i * 2 <= nsynx) { |
| 104 | j = i * 2; |
| 105 | if (synx[j].pos < synx[i].pos && |
| 106 | (j + 1 > nsynx || synx[j + 1].pos > synx[j].pos)) { |
| 107 | t = synx[j]; /* structure copy */ |
| 108 | synx[j] = synx[i]; /* lots of these... */ |
| 109 | synx[i] = t; /* ...aren't there? */ |
| 110 | i = j; |
| 111 | } else if (j + 1 <= nsynx && synx[j + 1].pos < synx[i].pos) { |
| 112 | t = synx[j + 1]; /* structure copy */ |
| 113 | synx[j + 1] = synx[i]; /* structure <yawn> copy */ |
| 114 | synx[i] = t; /* structure copy <zzzz....> */ |
| 115 | i = j + 1; |
| 116 | } else |
| 117 | break; |
| 118 | } |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 119 | } |
| 120 | |
| 121 | if (nsynx > 0) { |
H. Peter Anvin | e2c8018 | 2005-01-15 22:15:51 +0000 | [diff] [blame] | 122 | if (length) |
| 123 | *length = synx[1].length; |
| 124 | return synx[1].pos; |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 125 | } else { |
H. Peter Anvin | e2c8018 | 2005-01-15 22:15:51 +0000 | [diff] [blame] | 126 | if (length) |
| 127 | *length = 0L; |
H. Peter Anvin | 49da468 | 2007-11-20 13:22:58 -0800 | [diff] [blame] | 128 | return 0; |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 129 | } |
| 130 | } |