uwx_scoreboard.c revision 160158
1/* 2Copyright (c) 2003-2006 Hewlett-Packard Development Company, L.P. 3Permission is hereby granted, free of charge, to any person 4obtaining a copy of this software and associated documentation 5files (the "Software"), to deal in the Software without 6restriction, including without limitation the rights to use, 7copy, modify, merge, publish, distribute, sublicense, and/or sell 8copies of the Software, and to permit persons to whom the 9Software is furnished to do so, subject to the following 10conditions: 11 12The above copyright notice and this permission notice shall be 13included in all copies or substantial portions of the Software. 14 15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22OTHER DEALINGS IN THE SOFTWARE. 23*/ 24 25#include <stdlib.h> 26 27#include "uwx_env.h" 28#include "uwx_scoreboard.h" 29#include "uwx_trace.h" 30 31 32void uwx_prealloc_scoreboard(struct uwx_env *env, struct uwx_scoreboard *sb) 33{ 34 sb->id = env->nscoreboards++; 35 sb->nextused = env->used_scoreboards; 36 sb->prealloc = 1; 37 env->used_scoreboards = sb; 38 TRACE_B_PREALLOC(sb->id) 39} 40 41struct uwx_scoreboard *uwx_alloc_scoreboard(struct uwx_env *env) 42{ 43 struct uwx_scoreboard *sb; 44 int i; 45 46 if (env->free_scoreboards != 0) { 47 sb = env->free_scoreboards; 48 env->free_scoreboards = sb->nextfree; 49 TRACE_B_REUSE(sb->id) 50 } 51 else { 52 if (env->allocate_cb == 0) 53 sb = (struct uwx_scoreboard *) 54 malloc(sizeof(struct uwx_scoreboard)); 55 else 56 sb = (struct uwx_scoreboard *) 57 (*env->allocate_cb)(sizeof(struct uwx_scoreboard)); 58 if (sb == 0) 59 return 0; 60 sb->id = env->nscoreboards++; 61 sb->nextused = env->used_scoreboards; 62 sb->prealloc = 0; 63 env->used_scoreboards = sb; 64 TRACE_B_ALLOC(sb->id) 65 } 66 67 sb->nextstack = 0; 68 sb->nextlabel = 0; 69 for (i = 0; i < env->nsbreg; i++) 70 sb->rstate[i] = UWX_DISP_NONE; 71 sb->rstate[SBREG_RP] = UWX_DISP_REG(UWX_REG_BR(0)); 72 sb->rstate[SBREG_PSP] = UWX_DISP_SPPLUS(0); 73 sb->rstate[SBREG_PFS] = UWX_DISP_REG(UWX_REG_AR_PFS); 74 sb->rstate[SBREG_PRIUNAT] = UWX_DISP_REG(UWX_REG_AR_UNAT); 75 sb->label = 0; 76 return sb; 77} 78 79void uwx_reclaim_scoreboards(struct uwx_env *env) 80{ 81 struct uwx_scoreboard *sb; 82 83 env->free_scoreboards = 0; 84 for (sb = env->used_scoreboards; sb != 0; sb = sb->nextused) { 85 sb->nextfree = env->free_scoreboards; 86 env->free_scoreboards = sb; 87 } 88 env->labeled_scoreboards = 0; 89} 90 91struct uwx_scoreboard *uwx_init_scoreboards(struct uwx_env *env) 92{ 93 struct uwx_scoreboard *sb; 94 95 uwx_reclaim_scoreboards(env); 96 sb = uwx_alloc_scoreboard(env); 97 return sb; 98} 99 100struct uwx_scoreboard *uwx_new_scoreboard( 101 struct uwx_env *env, 102 struct uwx_scoreboard *prevsb) 103{ 104 int i; 105 struct uwx_scoreboard *sb; 106 107 sb = uwx_alloc_scoreboard(env); 108 if (sb == 0) 109 return 0; 110 sb->nextstack = prevsb; 111 for (i = 0; i < env->nsbreg; i++) 112 sb->rstate[i] = prevsb->rstate[i]; 113 return sb; 114} 115 116struct uwx_scoreboard *uwx_pop_scoreboards( 117 struct uwx_env *env, 118 struct uwx_scoreboard *sb, 119 int ecount) 120{ 121 struct uwx_scoreboard *next; 122 123 while (ecount > 0) { 124 next = sb->nextstack; 125 TRACE_B_POP(sb->id) 126 sb->nextstack = 0; 127 sb->nextfree = env->free_scoreboards; 128 env->free_scoreboards = sb; 129 sb = next; 130 if (sb == 0) 131 return 0; 132 ecount--; 133 } 134 return sb; 135} 136 137int uwx_label_scoreboard( 138 struct uwx_env *env, 139 struct uwx_scoreboard *sb, 140 int label) 141{ 142 struct uwx_scoreboard *new; 143 struct uwx_scoreboard *back; 144 struct uwx_scoreboard *next; 145 int i; 146 147 TRACE_B_LABEL(label) 148 149 /* Copy the current stack, storing reverse links */ 150 /* in the "nextstack" field. */ 151 152 back = 0; 153 while (sb != 0) { 154 TRACE_B_LABEL_COPY(sb->id) 155 new = uwx_alloc_scoreboard(env); 156 if (new == 0) 157 return UWX_ERR_NOMEM; 158 new->nextstack = back; 159 for (i = 0; i < env->nsbreg; i++) 160 new->rstate[i] = sb->rstate[i]; 161 sb = sb->nextstack; 162 back = new; 163 } 164 165 /* The "new" pointer now points to the bottom of the new stack, */ 166 /* and the "nextstack" links lead towards the top. */ 167 /* Now go back down the stack, reversing the stack links to their */ 168 /* proper direction. */ 169 170 back = 0; 171 while (new != 0) { 172 next = new->nextstack; 173 new->nextstack = back; 174 TRACE_B_LABEL_REVERSE(back, new) 175 back = new; 176 new = next; 177 } 178 179 /* The "back" pointer now points to the top of the stack. */ 180 181 back->label = label; 182 back->nextlabel = env->labeled_scoreboards; 183 env->labeled_scoreboards = back; 184 return UWX_OK; 185} 186 187int uwx_copy_scoreboard( 188 struct uwx_env *env, 189 struct uwx_scoreboard *sb, 190 int label) 191{ 192 struct uwx_scoreboard *next; 193 struct uwx_scoreboard *next2; 194 struct uwx_scoreboard *lsb; 195 struct uwx_scoreboard *new; 196 struct uwx_scoreboard *back; 197 int i; 198 199 TRACE_B_COPY(label, sb->id) 200 201 /* Free the existing stack. */ 202 203 next = sb->nextstack; 204 while (next != 0) { 205 TRACE_B_COPY_FREE(next->id) 206 next2 = next->nextstack; 207 next->nextstack = 0; 208 next->nextfree = env->free_scoreboards; 209 env->free_scoreboards = next; 210 next = next2; 211 } 212 213 /* Find the scoreboard with the requested label. */ 214 215 for (lsb = env->labeled_scoreboards; lsb != 0; lsb = lsb->nextlabel) { 216 if (lsb->label == label) 217 break; 218 } 219 220 if (lsb == 0) 221 return UWX_ERR_UNDEFLABEL; 222 223 TRACE_B_COPY_FOUND(lsb->id) 224 225 /* Copy the labeled scoreboard. */ 226 227 sb->nextstack = 0; 228 sb->nextlabel = 0; 229 for (i = 0; i < env->nsbreg; i++) 230 sb->rstate[i] = lsb->rstate[i]; 231 sb->label = 0; 232 233 /* Now copy its stack, storing reverse links in the nextstack field. */ 234 235 back = sb; 236 for (next = lsb->nextstack; next != 0; next = next->nextstack) { 237 TRACE_B_COPY_COPY(next->id) 238 new = uwx_alloc_scoreboard(env); 239 if (new == 0) 240 return UWX_ERR_NOMEM; 241 new->nextstack = back; 242 for (i = 0; i < env->nsbreg; i++) 243 new->rstate[i] = next->rstate[i]; 244 back = new; 245 } 246 247 /* The "new" pointer now points to the bottom of the new stack, */ 248 /* and the "nextstack" links lead towards the top. */ 249 /* Now go back down the stack, reversing the nextstack links to their */ 250 /* proper direction. */ 251 252 back = 0; 253 while (new != 0) { 254 next = new->nextstack; 255 new->nextstack = back; 256 TRACE_B_COPY_REVERSE(back, new) 257 back = new; 258 new = next; 259 } 260 261 return UWX_OK; 262} 263 264void uwx_free_scoreboards(struct uwx_env *env) 265{ 266 struct uwx_scoreboard *sb; 267 struct uwx_scoreboard *next; 268 269 for (sb = env->used_scoreboards; sb != 0; sb = next) { 270 TRACE_B_FREE(sb->id) 271 next = sb->nextused; 272 if (!sb->prealloc) { 273 if (env->free_cb == 0) 274 free((void *)sb); 275 else 276 (*env->free_cb)((void *)sb); 277 } 278 } 279 env->free_scoreboards = 0; 280 env->used_scoreboards = 0; 281 env->labeled_scoreboards = 0; 282} 283 284