1 # This shell script emits C code. -*- C -*-
2 # Main loop and support routines for the M32R.
3 # Copyright (C) 1996, 1997 Free Software Foundation, Inc.
4 # Contributed by Cygnus Support.
6 # This file is part of GDB, the GNU debugger.
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2, or (at your option)
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License along
19 # with this program; if not, write to the Free Software Foundation, Inc.,
20 # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 # /bin/sh mainloop.in {init|normal|fast|support}
25 # ??? There's lots of conditional compilation here.
26 # After a few more ports are done, revisit.
33 #if defined (WITH_SCACHE) && defined (USE_SEM_SWITCH) && defined (__GNUC__)
35 static decode_init_p = 0;
38 /* ??? Later maybe paste sem-switch.c in when building mainloop.c. */
40 #include "sem-switch.c"
59 /* First step: look up current insn in hash table. */
60 hash = SCACHE_HASH_PC (sd, PC);
61 sc = CPU_SCACHE_CACHE (current_cpu) + hash;
63 /* If the entry isn't the one we want (cache miss),
64 fetch and decode the instruction. */
65 if (sc->argbuf.addr != PC)
71 PROFILE_COUNT_SCACHE_MISS (current_cpu);
74 /* This only occurs when single stepping.
75 The test is unnecessary otherwise, but the cost is teensy,
76 compared with decoding/extraction. */
79 insn = GETMEMUHI (current_cpu, pc);
80 do_extract_insn16 (current_cpu, pc, insn & 0x7fff, sc, FAST);
84 insn = GETMEMUSI (current_cpu, pc);
86 if (insn & 0x80000000)
88 do_extract_insn32 (current_cpu, pc, insn, sc, FAST);
92 /* 2 16 bit insns. Ignore parallel case for now
93 (2nd always nop). Decode both as we know there's room.
94 ??? Could do a test for an unconditional branch in the
95 left slot if one wanted to. */
96 do_extract_insn16 (current_cpu, pc, insn >> 16, sc, FAST);
97 do_extract_insn16 (current_cpu, pc + 2, insn & 0x7fff, sc + 1, FAST);
104 PROFILE_COUNT_SCACHE_HIT (current_cpu);
110 /* Run until we get a cache miss. */
114 TRACE_INSN_INIT (current_cpu);
115 TRACE_INSN (current_cpu, sc->argbuf.opcode, &sc->argbuf, sc->argbuf.addr);
118 sc = (*sc->semantic.sem_fn) (current_cpu, sc);
121 TRACE_INSN_FINI (current_cpu);
124 while (sc->argbuf.addr == PC);
127 PROFILE_COUNT_INSN (current_cpu, pc, CGEN_INSN_INDEX (sc->argbuf.opcode));
133 TRACE_INSN_INIT (current_cpu);
134 TRACE_INSN (current_cpu, sc->argbuf.opcode, &sc->argbuf, sc->argbuf.addr);
137 #if FAST && defined (USE_SEM_SWITCH)
138 #define DEFINE_SWITCH
139 #include "sem-switch.c"
141 PC = (*sc->semantic.sem_fn) (current_cpu, sc);
145 TRACE_INSN_FINI (current_cpu);
147 PROFILE_COUNT_INSN (current_cpu, pc, CGEN_INSN_INDEX (sc->argbuf.opcode));
153 #else /* ! WITH_SCACHE */
160 insn = GETMEMUHI (current_cpu, PC);
161 PC = do_insn16 (current_cpu, PC, insn & 0x7fff);
165 insn = GETMEMUSI (current_cpu, PC);
167 if (insn & 0x80000000)
170 PC = do_insn32 (current_cpu, PC, insn);
174 /* 2 16 bit insns. Ignore parallel case for now
178 PC = do_insn16 (current_cpu, PC, insn >> 16);
181 PC = do_insn16 (current_cpu, PC, insn & 0x7fff);
187 #endif /* ! WITH_SCACHE */
200 #define DO_INLINE inline
205 /* FAST is optimized out by GCC. */
207 static DO_INLINE void
208 do_extract_insn16 (SIM_CPU *cpu, PCADDR pc, insn_t insn,
209 SCACHE *sc, int fast)
211 DECODE *d = decode (insn);
212 (*d->extract) (cpu, pc, insn, &sc->argbuf);
215 #ifdef USE_SEM_SWITCH
217 sc->semantic.sem_case = d->semantic_lab;
219 sc->semantic.sem_case = d->insn_type;
222 sc->semantic.sem_fn = d->semantic_fast;
227 sc->semantic.sem_fn = d->semantic_fast;
228 sc->argbuf.opcode = d->opcode;
233 static DO_INLINE void
234 do_extract_insn32 (SIM_CPU *cpu, PCADDR pc, insn_t insn,
235 SCACHE *sc, int fast)
238 DECODE *d = decode (insn >> 16);
239 (*d->extract) (cpu, pc, insn, &sc->argbuf);
242 #ifdef USE_SEM_SWITCH
244 sc->semantic.sem_case = d->semantic_lab;
246 sc->semantic.sem_case = d->insn_type;
249 sc->semantic.sem_fn = d->semantic_fast;
254 sc->semantic.sem_fn = d->semantic_fast;
255 sc->argbuf.opcode = d->opcode;
260 #endif /* WITH_SCACHE */
263 do_insn16 (cpu, pc, insn)
272 (*d->extract) (cpu, pc, insn, &argbuf);
273 argbuf.opcode = d->opcode;
275 TRACE_INSN_INIT (cpu);
276 TRACE_INSN (cpu, d->opcode, &argbuf, pc);
278 pc = (*d->semantic) (cpu, &argbuf);
280 TRACE_INSN_FINI (cpu);
282 PROFILE_COUNT_INSN (cpu, pc, d->insn_type);
288 do_insn32 (cpu, pc, insn)
296 d = decode (insn >> 16);
297 (*d->extract) (cpu, pc, insn, &argbuf);
298 argbuf.opcode = d->opcode;
300 TRACE_INSN_INIT (cpu);
301 TRACE_INSN (cpu, d->opcode, &argbuf, pc);
303 pc = (*d->semantic) (cpu, &argbuf);
305 TRACE_INSN_FINI (cpu);
307 PROFILE_COUNT_INSN (cpu, pc, d->insn_type);
317 echo "Invalid argument to mainloop.in: $1" >&2