Commit | Line | Data |
---|---|---|
c906108c SS |
1 | /* bag.c -- ARMulator support code: ARM6 Instruction Emulator. |
2 | Copyright (C) 1994 Advanced RISC Machines Ltd. | |
3 | ||
4 | This program is free software; you can redistribute it and/or modify | |
5 | it under the terms of the GNU General Public License as published by | |
6 | the Free Software Foundation; either version 2 of the License, or | |
7 | (at your option) any later version. | |
8 | ||
9 | This program is distributed in the hope that it will be useful, | |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | GNU General Public License for more details. | |
13 | ||
14 | You should have received a copy of the GNU General Public License | |
15 | along with this program; if not, write to the Free Software | |
16 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
17 | ||
18 | /********************************************************************/ | |
19 | /* bag.c: */ | |
20 | /* Offers a data structure for storing and getting pairs of number. */ | |
21 | /* The numbers are stored together, put one can be looked up by */ | |
22 | /* quoting the other. If a new pair is entered and one of the */ | |
23 | /* numbers is a repeat of a previous pair, then the previos pair */ | |
24 | /* is deleted. */ | |
25 | /********************************************************************/ | |
26 | ||
27 | #include "bag.h" | |
28 | ||
29 | #define HASH_TABLE_SIZE 256 | |
30 | #define hash(x) (((x)&0xff)^(((x)>>8)&0xff)^(((x)>>16)&0xff)^(((x)>>24)&0xff)) | |
31 | ||
dfcd3bfb JM |
32 | typedef struct hashentry |
33 | { | |
c906108c SS |
34 | struct hashentry *next; |
35 | int first; | |
36 | int second; | |
dfcd3bfb JM |
37 | } |
38 | Hashentry; | |
c906108c SS |
39 | |
40 | Hashentry *lookupbyfirst[HASH_TABLE_SIZE]; | |
41 | Hashentry *lookupbysecond[HASH_TABLE_SIZE]; | |
42 | ||
dfcd3bfb JM |
43 | void |
44 | addtolist (Hashentry ** add, long first, long second) | |
45 | { | |
46 | while (*add) | |
47 | add = &((*add)->next); | |
c906108c | 48 | /* Malloc will never fail? :o( */ |
dfcd3bfb | 49 | (*add) = (Hashentry *) malloc (sizeof (Hashentry)); |
c906108c SS |
50 | (*add)->next = (Hashentry *) 0; |
51 | (*add)->first = first; | |
52 | (*add)->second = second; | |
53 | } | |
54 | ||
dfcd3bfb JM |
55 | void |
56 | killwholelist (Hashentry * p) | |
57 | { | |
c906108c SS |
58 | Hashentry *q; |
59 | ||
dfcd3bfb JM |
60 | while (p) |
61 | { | |
62 | q = p; | |
63 | p = p->next; | |
64 | free (q); | |
65 | } | |
c906108c SS |
66 | } |
67 | ||
dfcd3bfb JM |
68 | void |
69 | removefromlist (Hashentry ** p, long first, long second) | |
70 | { | |
c906108c SS |
71 | Hashentry *q; |
72 | ||
dfcd3bfb JM |
73 | while (*p) |
74 | { | |
75 | if ((*p)->first == first) | |
76 | { | |
77 | q = (*p)->next; | |
78 | free (*p); | |
79 | *p = q; | |
80 | return; | |
81 | } | |
82 | p = &((*p)->next); | |
c906108c | 83 | } |
c906108c SS |
84 | } |
85 | ||
dfcd3bfb JM |
86 | void |
87 | BAG_putpair (long first, long second) | |
88 | { | |
c906108c SS |
89 | long junk; |
90 | ||
dfcd3bfb JM |
91 | if (BAG_getfirst (&junk, second) != NO_SUCH_PAIR) |
92 | BAG_killpair_bysecond (second); | |
93 | addtolist (&lookupbyfirst[hash (first)], first, second); | |
94 | addtolist (&lookupbysecond[hash (second)], first, second); | |
c906108c SS |
95 | } |
96 | ||
dfcd3bfb JM |
97 | Bag_error |
98 | BAG_getfirst (long *first, long second) | |
99 | { | |
c906108c SS |
100 | Hashentry *look; |
101 | ||
dfcd3bfb JM |
102 | look = lookupbysecond[hash (second)]; |
103 | while (look) | |
104 | if (look->second == second) | |
105 | { | |
106 | *first = look->first; | |
107 | return NO_ERROR; | |
108 | } | |
c906108c SS |
109 | return NO_SUCH_PAIR; |
110 | } | |
111 | ||
dfcd3bfb JM |
112 | Bag_error |
113 | BAG_getsecond (long first, long *second) | |
114 | { | |
c906108c SS |
115 | Hashentry *look; |
116 | ||
dfcd3bfb JM |
117 | look = lookupbyfirst[hash (first)]; |
118 | while (look) | |
119 | { | |
120 | if (look->first == first) | |
121 | { | |
122 | *second = look->second; | |
123 | return NO_ERROR; | |
124 | } | |
125 | look = look->next; | |
c906108c | 126 | } |
c906108c SS |
127 | return NO_SUCH_PAIR; |
128 | } | |
129 | ||
dfcd3bfb JM |
130 | Bag_error |
131 | BAG_killpair_byfirst (long first) | |
132 | { | |
c906108c SS |
133 | long second; |
134 | ||
dfcd3bfb | 135 | if (BAG_getsecond (first, &second) == NO_SUCH_PAIR) |
c906108c | 136 | return NO_SUCH_PAIR; |
dfcd3bfb JM |
137 | removefromlist (&lookupbyfirst[hash (first)], first, second); |
138 | removefromlist (&lookupbysecond[hash (second)], first, second); | |
c906108c SS |
139 | return NO_ERROR; |
140 | } | |
141 | ||
dfcd3bfb JM |
142 | Bag_error |
143 | BAG_killpair_bysecond (long second) | |
144 | { | |
c906108c | 145 | long first; |
dfcd3bfb JM |
146 | |
147 | if (BAG_getfirst (&first, second) == NO_SUCH_PAIR) | |
c906108c | 148 | return NO_SUCH_PAIR; |
dfcd3bfb JM |
149 | removefromlist (&lookupbyfirst[hash (first)], first, second); |
150 | removefromlist (&lookupbysecond[hash (second)], first, second); | |
c906108c SS |
151 | return NO_ERROR; |
152 | } | |
153 | ||
dfcd3bfb JM |
154 | void |
155 | BAG_newbag () | |
156 | { | |
c906108c SS |
157 | int i; |
158 | ||
dfcd3bfb JM |
159 | for (i = 0; i < 256; i++) |
160 | { | |
161 | killwholelist (lookupbyfirst[i]); | |
162 | killwholelist (lookupbysecond[i]); | |
163 | lookupbyfirst[i] = lookupbysecond[i] = (Hashentry *) 0; | |
164 | } | |
c906108c | 165 | } |