# Simulator main loop for m32rx. -*- C -*- # Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. # # This file is part of the GNU Simulators. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Syntax: # /bin/sh mainloop.in init|support|{full,fast}-{extract,exec}-{scache,noscache} # ??? After a few more ports are done, revisit. # Will eventually need to machine generate a lot of this. case "x$1" in xsupport) cat <> 16); abufs[0].insn = insn; abufs[0].idesc = d1; abufs[0].addr = pc; /* FIXME: wip */ icount = 1; } else { if (insn & 0x8000) { d1 = m32rx_decode (current_cpu, pc, insn >> 16); abufs[0].insn = insn >> 16; abufs[0].idesc = d1; abufs[0].addr = pc; /* FIXME: wip */ d2 = m32rx_decode (current_cpu, pc + 2, insn & 0x7fff); abufs[1].insn = insn & 0x7fff; abufs[1].idesc = d2; abufs[1].addr = pc + 2; /* FIXME: wip */ icount = 2; } else { d1 = m32rx_decode (current_cpu, pc, insn >> 16); abufs[0].insn = insn >> 16; abufs[0].idesc = d1; abufs[0].addr = pc; /* FIXME: wip */ icount = 1; } } } { int icount2 = icount; USI insn = abufs[0].insn; const IDESC *decode = d1; /* decode, par_exec, and insn are refered to by readx.c. */ PAREXEC *par_exec = &pbufs[0]; do { #define DEFINE_SWITCH #include "readx.c" decode = d2; insn = abufs[1].insn; ++par_exec; } while (--icount2 != 0); } } EOF ;; xfull-exec-* | xfast-exec-*) cat <opcode, sem_arg, CPU (h_pc)); new_pc = (*d1->sem_full) (current_cpu, sem_arg, par_exec); m32r_model_update_insn_cycles (current_cpu, icount == 1); TRACE_INSN_FINI (current_cpu, icount == 1); /* The result of the semantic fn is one of: - next address, branch only - NEW_PC_SKIP, sc/snc insn - NEW_PC_2, 2 byte non-branch non-sc/snc insn - NEW_PC_4, 4 byte non-branch insn */ /* The tests are ordered to try to favor the more frequent cases, while keeping the over all costs down. */ if (new_pc == NEW_PC_4) CPU (h_pc) += 4; else if (icount == 2) { /* Note that we only get here if doing parallel execution. */ if (new_pc == NEW_PC_SKIP) { /* ??? Need generic notion of bypassing an insn for the name of this macro. Annulled? On the otherhand such tracing can go in the sc/snc semantic fn. */ ; /*TRACE_INSN_SKIPPED (current_cpu);*/ CPU (h_pc) += 4; } else { PCADDR pc2; ++sem_arg; ++par_exec; m32r_model_init_insn_cycles (current_cpu, 0); TRACE_INSN_INIT (current_cpu, 0); TRACE_INSN (current_cpu, d2->opcode, sem_arg, CPU (h_pc) + 2); /* pc2 isn't used. It's assigned a value for debugging. */ pc2 = (*d2->sem_full) (current_cpu, sem_arg, par_exec); m32r_model_update_insn_cycles (current_cpu, 1); TRACE_INSN_FINI (current_cpu, 1); if (NEW_PC_BRANCH_P (new_pc)) CPU (h_pc) = new_pc; else CPU (h_pc) += 4; } /* Update count of parallel insns executed. */ PROFILE_COUNT_PARINSNS (current_cpu); } else if (NEW_PC_BRANCH_P (new_pc)) CPU (h_pc) = new_pc; else CPU (h_pc) += 2; } EOF ;; *) echo "Invalid argument to mainloop.in: $1" >&2 exit 1 ;; esac