14e98e3e1Schristos# Simulator main loop for lm32. -*- C -*- 24e98e3e1Schristos# Contributed by Jon Beniston <jon@beniston.com> 34e98e3e1Schristos# 44e98e3e1Schristos# This file is part of the GNU Simulators. 54e98e3e1Schristos# 64e98e3e1Schristos# This program is free software; you can redistribute it and/or modify 74e98e3e1Schristos# it under the terms of the GNU General Public License as published by 8a2e2270fSchristos# the Free Software Foundation; either version 3, or (at your option) 94e98e3e1Schristos# any later version. 104e98e3e1Schristos# 114e98e3e1Schristos# This program is distributed in the hope that it will be useful, 124e98e3e1Schristos# but WITHOUT ANY WARRANTY; without even the implied warranty of 134e98e3e1Schristos# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 144e98e3e1Schristos# GNU General Public License for more details. 154e98e3e1Schristos# 164e98e3e1Schristos# You should have received a copy of the GNU General Public License along 17a2e2270fSchristos# with this program; if not, see <http://www.gnu.org/licenses/>. 184e98e3e1Schristos 194e98e3e1Schristos# Syntax: 204e98e3e1Schristos# /bin/sh mainloop.in command 214e98e3e1Schristos# 224e98e3e1Schristos# Command is one of: 234e98e3e1Schristos# 244e98e3e1Schristos# init 254e98e3e1Schristos# support 264e98e3e1Schristos# extract-{simple,scache,pbb} 274e98e3e1Schristos# {full,fast}-exec-{simple,scache,pbb} 284e98e3e1Schristos# 294e98e3e1Schristos 304e98e3e1Schristoscase "x$1" in 314e98e3e1Schristos 324e98e3e1Schristosxsupport) 334e98e3e1Schristos 344e98e3e1Schristoscat <<EOF 35*71f62182Schristos#line $LINENO "$0" 364b169a6bSchristos#include <stdlib.h> 374e98e3e1Schristos 384e98e3e1Schristosstatic INLINE const IDESC * 394e98e3e1Schristosextract (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn, 404e98e3e1Schristos ARGBUF *abuf, int fast_p) 414e98e3e1Schristos{ 424e98e3e1Schristos const IDESC *id = @cpu@_decode (current_cpu, pc, insn, insn, abuf); 434e98e3e1Schristos 444e98e3e1Schristos @cpu@_fill_argbuf (current_cpu, abuf, id, pc, fast_p); 454e98e3e1Schristos if (! fast_p) 464e98e3e1Schristos { 474e98e3e1Schristos int trace_p = PC_IN_TRACE_RANGE_P (current_cpu, pc); 484e98e3e1Schristos int profile_p = PC_IN_PROFILE_RANGE_P (current_cpu, pc); 494e98e3e1Schristos @cpu@_fill_argbuf_tp (current_cpu, abuf, trace_p, profile_p); 504e98e3e1Schristos } 514e98e3e1Schristos return id; 524e98e3e1Schristos} 534e98e3e1Schristos 544e98e3e1Schristosstatic INLINE SEM_PC 554e98e3e1Schristosexecute (SIM_CPU *current_cpu, SCACHE *sc, int fast_p) 564e98e3e1Schristos{ 574e98e3e1Schristos SEM_PC vpc; 584e98e3e1Schristos 594e98e3e1Schristos if (fast_p) 604e98e3e1Schristos { 614e98e3e1Schristos#if ! WITH_SEM_SWITCH_FAST 624e98e3e1Schristos#if WITH_SCACHE 634e98e3e1Schristos vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, sc); 644e98e3e1Schristos#else 654e98e3e1Schristos vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, &sc->argbuf); 664e98e3e1Schristos#endif 674e98e3e1Schristos#else 684e98e3e1Schristos abort (); 694e98e3e1Schristos#endif /* WITH_SEM_SWITCH_FAST */ 704e98e3e1Schristos } 714e98e3e1Schristos else 724e98e3e1Schristos { 734e98e3e1Schristos#if ! WITH_SEM_SWITCH_FULL 744e98e3e1Schristos ARGBUF *abuf = &sc->argbuf; 754e98e3e1Schristos const IDESC *idesc = abuf->idesc; 764e98e3e1Schristos const CGEN_INSN *idata = idesc->idata; 774e98e3e1Schristos#if WITH_SCACHE_PBB 784e98e3e1Schristos int virtual_p = CGEN_INSN_ATTR_VALUE (idata, CGEN_INSN_VIRTUAL); 794e98e3e1Schristos#else 804e98e3e1Schristos int virtual_p = 0; 814e98e3e1Schristos#endif 824e98e3e1Schristos if (! virtual_p) 834e98e3e1Schristos { 844e98e3e1Schristos /* FIXME: call x-before */ 854e98e3e1Schristos if (ARGBUF_PROFILE_P (abuf)) 864e98e3e1Schristos PROFILE_COUNT_INSN (current_cpu, abuf->addr, idesc->num); 874e98e3e1Schristos /* FIXME: Later make cover macros: PROFILE_INSN_{INIT,FINI}. */ 884e98e3e1Schristos if (PROFILE_MODEL_P (current_cpu) 894e98e3e1Schristos && ARGBUF_PROFILE_P (abuf)) 904e98e3e1Schristos @cpu@_model_insn_before (current_cpu, 1 /*first_p*/); 91212397c6Schristos CGEN_TRACE_INSN_INIT (current_cpu, abuf, 1); 92212397c6Schristos CGEN_TRACE_INSN (current_cpu, idata, 934e98e3e1Schristos (const struct argbuf *) abuf, abuf->addr); 944e98e3e1Schristos } 954e98e3e1Schristos#if WITH_SCACHE 964e98e3e1Schristos vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, sc); 974e98e3e1Schristos#else 984e98e3e1Schristos vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, abuf); 994e98e3e1Schristos#endif 1004e98e3e1Schristos if (! virtual_p) 1014e98e3e1Schristos { 1024e98e3e1Schristos /* FIXME: call x-after */ 1034e98e3e1Schristos if (PROFILE_MODEL_P (current_cpu) 1044e98e3e1Schristos && ARGBUF_PROFILE_P (abuf)) 1054e98e3e1Schristos { 1064e98e3e1Schristos int cycles; 1074e98e3e1Schristos 1084e98e3e1Schristos cycles = (*idesc->timing->model_fn) (current_cpu, sc); 1094e98e3e1Schristos @cpu@_model_insn_after (current_cpu, 1 /*last_p*/, cycles); 1104e98e3e1Schristos } 111212397c6Schristos CGEN_TRACE_INSN_FINI (current_cpu, abuf, 1); 1124e98e3e1Schristos } 1134e98e3e1Schristos#else 1144e98e3e1Schristos abort (); 1154e98e3e1Schristos#endif /* WITH_SEM_SWITCH_FULL */ 1164e98e3e1Schristos } 1174e98e3e1Schristos 1184e98e3e1Schristos return vpc; 1194e98e3e1Schristos} 1204e98e3e1Schristos 1214e98e3e1SchristosEOF 1224e98e3e1Schristos 1234e98e3e1Schristos;; 1244e98e3e1Schristos 1254e98e3e1Schristosxinit) 1264e98e3e1Schristos 1274e98e3e1Schristos# Nothing needed. 1284e98e3e1Schristos 1294e98e3e1Schristos;; 1304e98e3e1Schristos 1314e98e3e1Schristosxextract-simple | xextract-scache) 1324e98e3e1Schristos 1334e98e3e1Schristoscat <<EOF 134*71f62182Schristos#line $LINENO "$0" 1354e98e3e1Schristos{ 1364e98e3e1Schristos CGEN_INSN_INT insn = GETIMEMUSI (current_cpu, vpc); 1374e98e3e1Schristos extract (current_cpu, vpc, insn, SEM_ARGBUF (sc), FAST_P); 1384e98e3e1Schristos} 1394e98e3e1SchristosEOF 1404e98e3e1Schristos 1414e98e3e1Schristos;; 1424e98e3e1Schristos 1434e98e3e1Schristosxextract-pbb) 1444e98e3e1Schristos 1454e98e3e1Schristos# Inputs: current_cpu, pc, sc, max_insns, FAST_P 1464e98e3e1Schristos# Outputs: sc, pc 1474e98e3e1Schristos# sc must be left pointing past the last created entry. 1484e98e3e1Schristos# pc must be left pointing past the last created entry. 1494e98e3e1Schristos# If the pbb is terminated by a cti insn, SET_CTI_VPC(sc) must be called 1504e98e3e1Schristos# to record the vpc of the cti insn. 1514e98e3e1Schristos# SET_INSN_COUNT(n) must be called to record number of real insns. 1524e98e3e1Schristos 1534e98e3e1Schristoscat <<EOF 154*71f62182Schristos#line $LINENO "$0" 1554e98e3e1Schristos{ 1564e98e3e1Schristos const IDESC *idesc; 1574e98e3e1Schristos int icount = 0; 1584e98e3e1Schristos 1594e98e3e1Schristos while (max_insns > 0) 1604e98e3e1Schristos { 1614e98e3e1Schristos USI insn = GETIMEMUSI (current_cpu, pc); 1624e98e3e1Schristos 1634e98e3e1Schristos idesc = extract (current_cpu, pc, insn, &sc->argbuf, FAST_P); 1644e98e3e1Schristos ++sc; 1654e98e3e1Schristos --max_insns; 1664e98e3e1Schristos ++icount; 1674e98e3e1Schristos pc += idesc->length; 1684e98e3e1Schristos 1694e98e3e1Schristos if (IDESC_CTI_P (idesc)) 1704e98e3e1Schristos { 1714e98e3e1Schristos SET_CTI_VPC (sc - 1); 1724e98e3e1Schristos break; 1734e98e3e1Schristos } 1744e98e3e1Schristos } 1754e98e3e1Schristos 1764e98e3e1Schristos Finish: 1774e98e3e1Schristos SET_INSN_COUNT (icount); 1784e98e3e1Schristos} 1794e98e3e1SchristosEOF 1804e98e3e1Schristos 1814e98e3e1Schristos;; 1824e98e3e1Schristos 1834e98e3e1Schristosxfull-exec-* | xfast-exec-*) 1844e98e3e1Schristos 1854e98e3e1Schristos# Inputs: current_cpu, vpc, FAST_P 1864e98e3e1Schristos# Outputs: vpc 1874e98e3e1Schristos 1884e98e3e1Schristoscat <<EOF 189*71f62182Schristos#line $LINENO "$0" 1904e98e3e1Schristos /* Update cycle counter */ 1914e98e3e1Schristos SET_H_CSR (LM32_CSR_CC, GET_H_CSR (LM32_CSR_CC) + 1); 1924e98e3e1Schristos#if (! FAST_P && WITH_SEM_SWITCH_FULL) || (FAST_P && WITH_SEM_SWITCH_FAST) 1934e98e3e1Schristos#define DEFINE_SWITCH 1944e98e3e1Schristos#include "sem-switch.c" 1954e98e3e1Schristos#else 1964e98e3e1Schristos vpc = execute (current_cpu, vpc, FAST_P); 1974e98e3e1Schristos#endif 1984e98e3e1SchristosEOF 1994e98e3e1Schristos 2004e98e3e1Schristos;; 2014e98e3e1Schristos 2024e98e3e1Schristos*) 2034e98e3e1Schristos echo "Invalid argument to mainloop.in: $1" >&2 2044e98e3e1Schristos exit 1 2054e98e3e1Schristos ;; 2064e98e3e1Schristos 2074e98e3e1Schristosesac 208