aboutsummaryrefslogtreecommitdiff
path: root/sim/sparc/mloop32.in
diff options
context:
space:
mode:
Diffstat (limited to 'sim/sparc/mloop32.in')
-rw-r--r--sim/sparc/mloop32.in133
1 files changed, 133 insertions, 0 deletions
diff --git a/sim/sparc/mloop32.in b/sim/sparc/mloop32.in
new file mode 100644
index 0000000..effc19a
--- /dev/null
+++ b/sim/sparc/mloop32.in
@@ -0,0 +1,133 @@
+# Simulator main loop for sparc. -*- C -*-
+# Copyright (C) 1999 Cygnus Solutions.
+
+# Syntax:
+# /bin/sh mainloop.in command
+#
+# Command is one of:
+#
+# init
+# support
+# extract-{simple,scache,pbb}
+# {full,fast}-exec-{simple,scache,pbb}
+#
+# A target need only provide a "full" version of one of simple,scache,pbb.
+# If the target wants it can also provide a fast version of same, or if
+# the slow (full featured) version is `simple', then the fast version can be
+# one of scache/pbb.
+# A target can't provide more than this.
+
+# ??? After a few more ports are done, revisit.
+# Will eventually need to machine generate a lot of this.
+
+case "x$1" in
+
+xsupport)
+
+cat <<EOF
+
+static INLINE void
+execute (SIM_CPU *current_cpu, SCACHE *sc)
+{
+ ARGBUF *abuf = &sc->argbuf;
+ IADDR pc = GET_H_PC ();
+ USI insn = GETIMEMUSI (current_cpu, pc);
+ int fast_p = STATE_RUN_FAST_P (CPU_STATE (current_cpu));
+
+ if (fast_p)
+ {
+ const IDESC *id = @cpu@_decode (current_cpu, pc, insn, insn, abuf);
+
+ @cpu@_fill_argbuf (current_cpu, abuf, id, pc, fast_p);
+ (*id->sem_full) (current_cpu, sc, insn);
+ }
+ else
+ {
+ const IDESC *id = @cpu@_decode (current_cpu, pc, insn, insn, abuf);
+ const CGEN_INSN *opcode = id->opcode;
+ int trace_p = PC_IN_TRACE_RANGE_P (current_cpu, pc);
+ int profile_p = PC_IN_PROFILE_RANGE_P (current_cpu, pc);
+
+ @cpu@_fill_argbuf (current_cpu, abuf, id, pc, fast_p);
+ @cpu@_fill_argbuf_tp (current_cpu, abuf, trace_p, profile_p);
+
+ /* FIXME: call x-before */
+ if (ARGBUF_PROFILE_P (abuf))
+ PROFILE_COUNT_INSN (current_cpu, pc, id->num);
+ /* FIXME: Later make cover macros: PROFILE_INSN_{INIT,FINI}. */
+ if (PROFILE_MODEL_P (current_cpu)
+ && ARGBUF_PROFILE_P (abuf))
+ @cpu@_model_insn_before (current_cpu, 1 /*first_p*/);
+ TRACE_INSN_INIT (current_cpu, abuf, 1);
+ TRACE_INSN (current_cpu, opcode, abuf, pc);
+
+ (*id->sem_full) (current_cpu, sc, insn);
+
+ /* FIXME: call x-after */
+ if (PROFILE_MODEL_P (current_cpu)
+ && ARGBUF_PROFILE_P (abuf))
+ {
+ int cycles;
+
+ cycles = (*id->timing->model_fn) (current_cpu, sc);
+ @cpu@_model_insn_after (current_cpu, 1 /*last_p*/, cycles);
+ }
+ TRACE_INSN_FINI (current_cpu, abuf, 1);
+ }
+}
+
+static INLINE void
+do_annul (SIM_CPU *current_cpu)
+{
+ IADDR npc = GET_H_NPC ();
+
+ /* ??? log profiling data */
+ /* ??? anything else */
+
+ SET_H_PC (npc);
+ SET_H_NPC (npc + 4);
+}
+
+EOF
+
+;;
+
+xinit)
+
+# Nothing needed.
+
+;;
+
+xfull-exec-simple)
+
+# Inputs: current_cpu, sc, FAST_P
+# Outputs: none, instruction is fetched and executed
+# Recorded PC is updated after every insn.
+# ??? Use of `sc' is a bit of a hack as we don't use the scache.
+# We do however use ARGBUF so for consistency with the other engine flavours
+# sc is used.
+
+cat <<EOF
+
+{
+ if (GET_H_ANNUL_P ())
+ {
+ do_annul (current_cpu);
+ SET_H_ANNUL_P (0);
+ }
+ else
+ {
+ execute (current_cpu, sc);
+ }
+}
+
+EOF
+
+;;
+
+*)
+ echo "Invalid argument to mainloop.in: $1" >&2
+ exit 1
+ ;;
+
+esac