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