1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 2003-2011 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Eclipse Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.eclipse.org/org/documents/epl-v10.html *
11 * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Phong Vo <kpv@research.att.com> *
18 * *
19 ***********************************************************************/
20 #include "vcdhdr.h"
21
22 /* Functions to encode/decode COPY addresses based on the caches.
23 **
24 ** Written by Kiem-Phong Vo (kpv@research.att.com)
25 */
26
27 #if __STD_C
vcdkaclose(Vcdcache_t * ka)28 void vcdkaclose(Vcdcache_t* ka)
29 #else
30 void vcdkaclose(ka)
31 Vcdcache_t* ka;
32 #endif
33 {
34 if(ka)
35 free(ka);
36 }
37
38 /* initialize address caches */
39 #if __STD_C
vcdkaopen(ssize_t s_near,ssize_t s_same)40 Vcdcache_t* vcdkaopen(ssize_t s_near, ssize_t s_same)
41 #else
42 Vcdcache_t* vcdkaopen(s_near, s_same)
43 ssize_t s_near;
44 ssize_t s_same;
45 #endif
46 {
47 Vcdcache_t* ka;
48 ssize_t sz;
49
50 sz = sizeof(Vcdcache_t) + s_near*sizeof(ssize_t) + s_same*256*sizeof(ssize_t);
51
52 if(!(ka = (Vcdcache_t*)calloc(1,sz)) )
53 return NIL(Vcdcache_t*);
54 ka->c_same = ka->c_near = NIL(ssize_t*);
55
56 if((ka->s_near = s_near) > 0)
57 ka->c_near = (ssize_t*)(ka+1);
58
59 if((ka->s_same = s_same) > 0)
60 ka->c_same = ((ssize_t*)(ka+1)) + s_near;
61
62 return ka;
63 }
64
65 #if __STD_C
vcdkaclear(Vcdcache_t * ka)66 void vcdkaclear(Vcdcache_t* ka)
67 #else
68 void vcdkaclear(ka)
69 Vcdcache_t* ka;
70 #endif
71 {
72 ssize_t i;
73
74 if(ka)
75 { for(i = 0; i < ka->s_near; ++i)
76 ka->c_near[i] = 0;
77 ka->n = 0;
78 for(i = 0; i < ka->s_same*256; ++i)
79 ka->c_same[i] = 0;
80 }
81 }
82
83 /* update address caches */
84 #if __STD_C
vcdkaupdate(Vcdcache_t * ka,ssize_t addr)85 static void vcdkaupdate(Vcdcache_t* ka, ssize_t addr)
86 #else
87 static void vcdkaupdate(ka, addr)
88 Vcdcache_t* ka;
89 ssize_t addr;
90 #endif
91 {
92 if(ka)
93 { if(ka->s_near > 0)
94 { ka->c_near[ka->n] = addr;
95 if((ka->n += 1) >= ka->s_near)
96 ka->n = 0;
97 }
98 if(ka->s_same > 0)
99 ka->c_same[addr % (ka->s_same*256)] = addr;
100 }
101 }
102
103 /* compute encoding for COPY addresses */
104 #if __STD_C
vcdkasetaddr(Vcdcache_t * ka,ssize_t addr,ssize_t here,ssize_t * mode)105 ssize_t vcdkasetaddr(Vcdcache_t* ka, ssize_t addr, ssize_t here, ssize_t* mode)
106 #else
107 ssize_t vcdkasetaddr(ka, addr, here, mode)
108 Vcdcache_t* ka;
109 ssize_t addr; /* matching address to be encoded */
110 ssize_t here; /* current location */
111 ssize_t* mode; /* to return the coded address */
112 #endif
113 {
114 ssize_t i, d, sz, bestd, bestm, bestsz;
115
116 bestd = addr;
117 bestm = VCD_SELF;
118 if((bestsz = vcsizeu(bestd)) == 1)
119 goto done;
120
121 d = here-addr;
122 if((sz = vcsizeu(d)) < bestsz)
123 { bestd = d;
124 bestm = VCD_HERE;
125 if((bestsz = sz) == 1)
126 goto done;
127 }
128
129 if(ka)
130 { for(i = 0; i < ka->s_near; ++i)
131 { if((d = addr - ka->c_near[i]) < 0)
132 continue;
133 if((sz = vcsizeu(d)) < bestsz)
134 { bestd = d;
135 bestm = (VCD_HERE+1) + i;
136 if((bestsz = sz) == 1)
137 goto done;
138 }
139 }
140 if(ka->s_same > 0 && ka->c_same[d = addr%(ka->s_same*256)] == addr)
141 { bestd = d%256;
142 bestm = (VCD_HERE+1) + ka->s_near + d/256;
143 }
144 }
145
146 done: vcdkaupdate(ka, addr);
147
148 *mode = bestm;
149 return bestd;
150 }
151
152
153 #if __STD_C
vcdkagetaddr(Vcdcache_t * ka,Vcio_t * addr,ssize_t here,ssize_t mode)154 ssize_t vcdkagetaddr(Vcdcache_t* ka, Vcio_t* addr, ssize_t here, ssize_t mode)
155 #else
156 ssize_t vcdkagetaddr(ka, addr, here, mode)
157 Vcdcache_t* ka;
158 Vcio_t* addr;
159 ssize_t here;
160 ssize_t mode;
161 #endif
162 {
163 ssize_t a, m;
164
165 if(mode == VCD_SELF)
166 a = vciogetu(addr);
167 else if(mode == VCD_HERE)
168 a = here - vciogetu(addr);
169 else if(ka)
170 { if((m = mode - (VCD_HERE+1)) >= 0 && m < ka->s_near)
171 a = ka->c_near[m] + vciogetu(addr);
172 else if((m = mode - (VCD_HERE+1+ka->s_near)) >= 0 && m < ka->s_same)
173 a = ka->c_same[vciogetc(addr) + m*256];
174 else return -1;
175 }
176 else return -1;
177
178 vcdkaupdate(ka, a);
179 return a;
180 }
181