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 | |
Cyrill Gorcunov | 2ec4ad8 | 2009-07-11 18:37:08 +0400 | [diff] [blame] | 61 | static inline void swap_sync(uint32_t dst, uint32_t src) |
| 62 | { |
| 63 | struct Sync t = synx[dst]; |
| 64 | synx[dst] = synx[src]; |
| 65 | synx[src] = t; |
| 66 | } |
| 67 | |
H. Peter Anvin | e2c8018 | 2005-01-15 22:15:51 +0000 | [diff] [blame] | 68 | void init_sync(void) |
H. Peter Anvin | eba20a7 | 2002-04-30 20:53:55 +0000 | [diff] [blame] | 69 | { |
H. Peter Anvin | 8d024e7 | 2007-09-19 21:41:02 -0700 | [diff] [blame] | 70 | max_synx = SYNC_MAX-1; |
| 71 | synx = nasm_malloc(SYNC_MAX * sizeof(*synx)); |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 72 | nsynx = 0; |
| 73 | } |
| 74 | |
Keith Kanios | b7a8954 | 2007-04-12 02:40:54 +0000 | [diff] [blame] | 75 | void add_sync(uint32_t pos, uint32_t length) |
H. Peter Anvin | eba20a7 | 2002-04-30 20:53:55 +0000 | [diff] [blame] | 76 | { |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 77 | int i; |
| 78 | |
H. Peter Anvin | 8d024e7 | 2007-09-19 21:41:02 -0700 | [diff] [blame] | 79 | if (nsynx >= max_synx) { |
| 80 | max_synx = (max_synx << 1)+1; |
| 81 | synx = nasm_realloc(synx, (max_synx+1) * sizeof(*synx)); |
| 82 | } |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 83 | |
| 84 | nsynx++; |
| 85 | synx[nsynx].pos = pos; |
| 86 | synx[nsynx].length = length; |
| 87 | |
| 88 | for (i = nsynx; i > 1; i /= 2) { |
Cyrill Gorcunov | 2ec4ad8 | 2009-07-11 18:37:08 +0400 | [diff] [blame] | 89 | if (synx[i / 2].pos > synx[i].pos) |
| 90 | swap_sync(i / 2, i); |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 91 | } |
| 92 | } |
| 93 | |
Keith Kanios | b7a8954 | 2007-04-12 02:40:54 +0000 | [diff] [blame] | 94 | uint32_t next_sync(uint32_t position, uint32_t *length) |
H. Peter Anvin | eba20a7 | 2002-04-30 20:53:55 +0000 | [diff] [blame] | 95 | { |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 96 | while (nsynx > 0 && synx[1].pos + synx[1].length <= position) { |
H. Peter Anvin | e2c8018 | 2005-01-15 22:15:51 +0000 | [diff] [blame] | 97 | int i, j; |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 98 | |
Cyrill Gorcunov | 2ec4ad8 | 2009-07-11 18:37:08 +0400 | [diff] [blame] | 99 | swap_sync(nsynx, 1); |
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)) { |
Cyrill Gorcunov | 2ec4ad8 | 2009-07-11 18:37:08 +0400 | [diff] [blame] | 107 | swap_sync(j, i); |
H. Peter Anvin | e2c8018 | 2005-01-15 22:15:51 +0000 | [diff] [blame] | 108 | i = j; |
| 109 | } else if (j + 1 <= nsynx && synx[j + 1].pos < synx[i].pos) { |
Cyrill Gorcunov | 2ec4ad8 | 2009-07-11 18:37:08 +0400 | [diff] [blame] | 110 | swap_sync(j + 1, i); |
H. Peter Anvin | e2c8018 | 2005-01-15 22:15:51 +0000 | [diff] [blame] | 111 | i = j + 1; |
| 112 | } else |
| 113 | break; |
| 114 | } |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 115 | } |
| 116 | |
| 117 | if (nsynx > 0) { |
H. Peter Anvin | e2c8018 | 2005-01-15 22:15:51 +0000 | [diff] [blame] | 118 | if (length) |
| 119 | *length = synx[1].length; |
| 120 | return synx[1].pos; |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 121 | } else { |
H. Peter Anvin | e2c8018 | 2005-01-15 22:15:51 +0000 | [diff] [blame] | 122 | if (length) |
| 123 | *length = 0L; |
H. Peter Anvin | 49da468 | 2007-11-20 13:22:58 -0800 | [diff] [blame] | 124 | return 0; |
H. Peter Anvin | ea6e34d | 2002-04-30 20:51:32 +0000 | [diff] [blame] | 125 | } |
| 126 | } |