# This shell script emits C code. -*- C -*- # Main loop and support routines for the M32R. # Copyright (C) 1996, 1997 Free Software Foundation, Inc. # Contributed by Cygnus Support. # # This file is part of GDB, the GNU debugger. # # 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|normal|fast|support} # ??? There's lots of conditional compilation here. # After a few more ports are done, revisit. case "x$1" in xinit) cat <argbuf.addr != PC) { PCADDR pc = PC; insn_t insn; #if ! FAST PROFILE_COUNT_SCACHE_MISS (current_cpu); #endif /* This only occurs when single stepping. The test is unnecessary otherwise, but the cost is teensy, compared with decoding/extraction. */ if (pc & 3) { insn = GETMEMUHI (current_cpu, pc); do_extract_insn16 (current_cpu, pc, insn & 0x7fff, sc, FAST); } else { insn = GETMEMUSI (current_cpu, pc); if (insn & 0x80000000) { do_extract_insn32 (current_cpu, pc, insn, sc, FAST); } else { /* 2 16 bit insns. Ignore parallel case for now (2nd always nop). Decode both as we know there's room. ??? Could do a test for an unconditional branch in the left slot if one wanted to. */ do_extract_insn16 (current_cpu, pc, insn >> 16, sc, FAST); do_extract_insn16 (current_cpu, pc + 2, insn & 0x7fff, sc + 1, FAST); } } } #if ! FAST else { PROFILE_COUNT_SCACHE_HIT (current_cpu); } #endif #if 0 /*FIXME:wip*/ /* Run until we get a cache miss. */ do { #if ! FAST TRACE_INSN_INIT (current_cpu); TRACE_INSN (current_cpu, sc->argbuf.opcode, &sc->argbuf, sc->argbuf.addr); #endif sc = (*sc->semantic.sem_fn) (current_cpu, sc); #if ! FAST TRACE_INSN_FINI (current_cpu); #endif } while (sc->argbuf.addr == PC); #if ! FAST PROFILE_COUNT_INSN (current_cpu, pc, CGEN_INSN_INDEX (sc->argbuf.opcode)); #endif #else /* !wip */ #if ! FAST TRACE_INSN_INIT (current_cpu); TRACE_INSN (current_cpu, sc->argbuf.opcode, &sc->argbuf, sc->argbuf.addr); #endif #if FAST && defined (USE_SEM_SWITCH) #define DEFINE_SWITCH #include "sem-switch.c" #else PC = (*sc->semantic.sem_fn) (current_cpu, sc); #endif #if ! FAST TRACE_INSN_FINI (current_cpu); PROFILE_COUNT_INSN (current_cpu, pc, CGEN_INSN_INDEX (sc->argbuf.opcode)); #endif #endif /* !wip */ } #else /* ! WITH_SCACHE */ { insn_t insn; if (PC & 3) { insn = GETMEMUHI (current_cpu, PC); PC = do_insn16 (current_cpu, PC, insn & 0x7fff); } else { insn = GETMEMUSI (current_cpu, PC); if (insn & 0x80000000) { /* 32 bit insn */ PC = do_insn32 (current_cpu, PC, insn); } else { /* 2 16 bit insns. Ignore parallel case for now (2nd always nop). */ PCADDR oldpc = PC; PC = do_insn16 (current_cpu, PC, insn >> 16); if (PC == oldpc + 2) { PC = do_insn16 (current_cpu, PC, insn & 0x7fff); } } } } #endif /* ! WITH_SCACHE */ EOF ;; xsupport) cat <extract) (cpu, pc, insn, &sc->argbuf); if (fast) { #ifdef USE_SEM_SWITCH #ifdef __GNUC__ sc->semantic.sem_case = d->semantic_lab; #else sc->semantic.sem_case = d->insn_type; #endif #else sc->semantic.sem_fn = d->semantic_fast; #endif } else { sc->semantic.sem_fn = d->semantic_fast; sc->argbuf.opcode = d->opcode; } sc->next = pc + 2; } static DO_INLINE void do_extract_insn32 (SIM_CPU *cpu, PCADDR pc, insn_t insn, SCACHE *sc, int fast) { /* 32 bit insn */ DECODE *d = decode (insn >> 16); (*d->extract) (cpu, pc, insn, &sc->argbuf); if (fast) { #ifdef USE_SEM_SWITCH #ifdef __GNUC__ sc->semantic.sem_case = d->semantic_lab; #else sc->semantic.sem_case = d->insn_type; #endif #else sc->semantic.sem_fn = d->semantic_fast; #endif } else { sc->semantic.sem_fn = d->semantic_fast; sc->argbuf.opcode = d->opcode; } sc->next = pc + 4; } #endif /* WITH_SCACHE */ static PCADDR do_insn16 (cpu, pc, insn) SIM_CPU *cpu; PCADDR pc; insn_t insn; { DECODE *d; ARGBUF argbuf; d = decode (insn); (*d->extract) (cpu, pc, insn, &argbuf); argbuf.opcode = d->opcode; TRACE_INSN_INIT (cpu); TRACE_INSN (cpu, d->opcode, &argbuf, pc); pc = (*d->semantic) (cpu, &argbuf); TRACE_INSN_FINI (cpu); PROFILE_COUNT_INSN (cpu, pc, d->insn_type); return pc; } static PCADDR do_insn32 (cpu, pc, insn) SIM_CPU *cpu; PCADDR pc; insn_t insn; { DECODE *d; ARGBUF argbuf; d = decode (insn >> 16); (*d->extract) (cpu, pc, insn, &argbuf); argbuf.opcode = d->opcode; TRACE_INSN_INIT (cpu); TRACE_INSN (cpu, d->opcode, &argbuf, pc); pc = (*d->semantic) (cpu, &argbuf); TRACE_INSN_FINI (cpu); PROFILE_COUNT_INSN (cpu, pc, d->insn_type); return pc; } EOF ;; *) echo "Invalid argument to mainloop.in: $1" >&2 exit 1 ;; esac