summaryrefslogtreecommitdiffstats
path: root/sys/contrib/ia64/libuwx/src/uwx_scoreboard.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/ia64/libuwx/src/uwx_scoreboard.c')
-rw-r--r--sys/contrib/ia64/libuwx/src/uwx_scoreboard.c277
1 files changed, 277 insertions, 0 deletions
diff --git a/sys/contrib/ia64/libuwx/src/uwx_scoreboard.c b/sys/contrib/ia64/libuwx/src/uwx_scoreboard.c
new file mode 100644
index 0000000..fe37559
--- /dev/null
+++ b/sys/contrib/ia64/libuwx/src/uwx_scoreboard.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2002,2003 Hewlett-Packard Company
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _KERNEL
+#include <stdlib.h>
+#else
+#define free(p) /* nullified */
+#define malloc(sz) NULL
+#endif
+
+#include "uwx_env.h"
+#include "uwx_scoreboard.h"
+#include "uwx_trace.h"
+
+
+struct uwx_scoreboard *uwx_alloc_scoreboard(struct uwx_env *env)
+{
+ struct uwx_scoreboard *sb;
+ int i;
+
+ if (env->free_scoreboards != 0) {
+ sb = env->free_scoreboards;
+ env->free_scoreboards = sb->nextfree;
+ TRACE_B_REUSE(sb->id)
+ }
+ else {
+ if (env->allocate_cb == 0)
+ sb = (struct uwx_scoreboard *)
+ malloc(sizeof(struct uwx_scoreboard));
+ else
+ sb = (struct uwx_scoreboard *)
+ (*env->allocate_cb)(sizeof(struct uwx_scoreboard));
+ if (sb == 0)
+ return 0;
+ sb->id = env->nscoreboards++;
+ sb->nextused = env->used_scoreboards;
+ env->used_scoreboards = sb;
+ TRACE_B_ALLOC(sb->id)
+ }
+
+ sb->nextstack = 0;
+ sb->nextlabel = 0;
+ for (i = 0; i < env->nsbreg; i++)
+ sb->rstate[i] = UWX_DISP_NONE;
+ sb->rstate[SBREG_RP] = UWX_DISP_REG(UWX_REG_BR(0));
+ sb->rstate[SBREG_PSP] = UWX_DISP_SPPLUS(0);
+ sb->rstate[SBREG_PFS] = UWX_DISP_REG(UWX_REG_PFS);
+ sb->rstate[SBREG_PRIUNAT] = UWX_DISP_REG(UWX_REG_UNAT);
+ sb->label = 0;
+ return sb;
+}
+
+static
+void uwx_reclaim_scoreboards(struct uwx_env *env)
+{
+ struct uwx_scoreboard *sb;
+
+ env->free_scoreboards = 0;
+ for (sb = env->used_scoreboards; sb != 0; sb = sb->nextused) {
+ sb->nextfree = env->free_scoreboards;
+ env->free_scoreboards = sb;
+ }
+ env->labeled_scoreboards = 0;
+}
+
+struct uwx_scoreboard *uwx_init_scoreboards(struct uwx_env *env)
+{
+ struct uwx_scoreboard *sb;
+
+ uwx_reclaim_scoreboards(env);
+ sb = uwx_alloc_scoreboard(env);
+ return sb;
+}
+
+struct uwx_scoreboard *uwx_new_scoreboard(
+ struct uwx_env *env,
+ struct uwx_scoreboard *prevsb)
+{
+ int i;
+ struct uwx_scoreboard *sb;
+
+ sb = uwx_alloc_scoreboard(env);
+ if (sb == 0)
+ return 0;
+ sb->nextstack = prevsb;
+ for (i = 0; i < env->nsbreg; i++)
+ sb->rstate[i] = prevsb->rstate[i];
+ return sb;
+}
+
+struct uwx_scoreboard *uwx_pop_scoreboards(
+ struct uwx_env *env,
+ struct uwx_scoreboard *sb,
+ int ecount)
+{
+ struct uwx_scoreboard *next;
+
+ while (ecount > 0) {
+ next = sb->nextstack;
+ TRACE_B_POP(sb->id)
+ sb->nextstack = 0;
+ sb->nextfree = env->free_scoreboards;
+ env->free_scoreboards = sb;
+ sb = next;
+ if (sb == 0)
+ return 0;
+ ecount--;
+ }
+ return sb;
+}
+
+int uwx_label_scoreboard(
+ struct uwx_env *env,
+ struct uwx_scoreboard *sb,
+ int label)
+{
+ struct uwx_scoreboard *new;
+ struct uwx_scoreboard *back;
+ struct uwx_scoreboard *next;
+ int i;
+
+ TRACE_B_LABEL(label)
+
+ /* Copy the current stack, storing reverse links */
+ /* in the "nextstack" field. */
+
+ back = 0;
+ new = 0;
+ while (sb != 0) {
+ TRACE_B_LABEL_COPY(sb->id)
+ new = uwx_alloc_scoreboard(env);
+ if (new == 0)
+ return UWX_ERR_NOMEM;
+ new->nextstack = back;
+ for (i = 0; i < env->nsbreg; i++)
+ new->rstate[i] = sb->rstate[i];
+ sb = sb->nextstack;
+ back = new;
+ }
+
+ /* The "new" pointer now points to the bottom of the new stack, */
+ /* and the "nextstack" links lead towards the top. */
+ /* Now go back down the stack, reversing the stack links to their */
+ /* proper direction. */
+
+ back = 0;
+ while (new != 0) {
+ next = new->nextstack;
+ new->nextstack = back;
+ TRACE_B_LABEL_REVERSE(back, new)
+ back = new;
+ new = next;
+ }
+
+ /* The "back" pointer now points to the top of the stack. */
+
+ back->label = label;
+ back->nextlabel = env->labeled_scoreboards;
+ env->labeled_scoreboards = back;
+ return UWX_OK;
+}
+
+int uwx_copy_scoreboard(
+ struct uwx_env *env,
+ struct uwx_scoreboard *sb,
+ int label)
+{
+ struct uwx_scoreboard *next;
+ struct uwx_scoreboard *next2;
+ struct uwx_scoreboard *lsb;
+ struct uwx_scoreboard *new;
+ struct uwx_scoreboard *back;
+ int i;
+
+ TRACE_B_COPY(label, sb->id)
+
+ /* Free the existing stack. */
+
+ next = sb->nextstack;
+ while (next != 0) {
+ TRACE_B_COPY_FREE(next->id)
+ next2 = next->nextstack;
+ next->nextstack = 0;
+ next->nextfree = env->free_scoreboards;
+ env->free_scoreboards = next;
+ next = next2;
+ }
+
+ /* Find the scoreboard with the requested label. */
+
+ for (lsb = env->labeled_scoreboards; lsb != 0; lsb = lsb->nextlabel) {
+ if (lsb->label == label)
+ break;
+ }
+
+ if (lsb == 0)
+ return UWX_ERR_UNDEFLABEL;
+
+ TRACE_B_COPY_FOUND(lsb->id)
+
+ /* Copy the labeled scoreboard. */
+
+ sb->nextstack = 0;
+ sb->nextlabel = 0;
+ for (i = 0; i < env->nsbreg; i++)
+ sb->rstate[i] = lsb->rstate[i];
+ sb->label = 0;
+
+ /* Now copy its stack, storing reverse links in the nextstack field. */
+
+ back = sb;
+ new = 0;
+ for (next = lsb->nextstack; next != 0; next = next->nextstack) {
+ TRACE_B_COPY_COPY(next->id)
+ new = uwx_alloc_scoreboard(env);
+ if (new == 0)
+ return UWX_ERR_NOMEM;
+ new->nextstack = back;
+ for (i = 0; i < env->nsbreg; i++)
+ new->rstate[i] = next->rstate[i];
+ back = new;
+ }
+
+ /* The "new" pointer now points to the bottom of the new stack, */
+ /* and the "nextstack" links lead towards the top. */
+ /* Now go back down the stack, reversing the nextstack links to their */
+ /* proper direction. */
+
+ back = 0;
+ while (new != 0) {
+ next = new->nextstack;
+ new->nextstack = back;
+ TRACE_B_COPY_REVERSE(back, new)
+ back = new;
+ new = next;
+ }
+
+ return UWX_OK;
+}
+
+void uwx_free_scoreboards(struct uwx_env *env)
+{
+ struct uwx_scoreboard *sb;
+ struct uwx_scoreboard *next;
+
+ for (sb = env->used_scoreboards; sb != 0; sb = next) {
+ TRACE_B_FREE(sb->id)
+ next = sb->nextused;
+ if (env->free_cb == 0)
+ free((void *)sb);
+ else
+ (*env->free_cb)((void *)sb);
+ }
+ env->free_scoreboards = 0;
+ env->used_scoreboards = 0;
+ env->labeled_scoreboards = 0;
+}
+
OpenPOWER on IntegriCloud