xref: /netbsd/external/gpl3/gdb.old/dist/sim/bpf/mloop.in (revision 56bb7041)
1*56bb7041Schristos# Simulator main loop for eBPF. -*- C -*-
2*56bb7041Schristos#
3*56bb7041Schristos# Copyright (C) 2020 Free Software Foundation, Inc.
4*56bb7041Schristos#
5*56bb7041Schristos# This file is part of the GNU Simulators.
6*56bb7041Schristos#
7*56bb7041Schristos# This program is free software; you can redistribute it and/or modify
8*56bb7041Schristos# it under the terms of the GNU General Public License as published by
9*56bb7041Schristos# the Free Software Foundation; either version 3 of the License, or
10*56bb7041Schristos# (at your option) any later version.
11*56bb7041Schristos#
12*56bb7041Schristos# This program is distributed in the hope that it will be useful,
13*56bb7041Schristos# but WITHOUT ANY WARRANTY; without even the implied warranty of
14*56bb7041Schristos# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*56bb7041Schristos# GNU General Public License for more details.
16*56bb7041Schristos#
17*56bb7041Schristos# You should have received a copy of the GNU General Public License
18*56bb7041Schristos# along with this program.  If not, see <http://www.gnu.org/licenses/>.
19*56bb7041Schristos
20*56bb7041Schristos# Syntax:
21*56bb7041Schristos# /bin/sh mloop.in command
22*56bb7041Schristos#
23*56bb7041Schristos# Command is one of:
24*56bb7041Schristos#
25*56bb7041Schristos# init
26*56bb7041Schristos# support
27*56bb7041Schristos# extract-{simple,scache,pbb}
28*56bb7041Schristos# {full,fast}-exec-{simple,scache,pbb}
29*56bb7041Schristos#
30*56bb7041Schristos# A target need only provide a "full" version of one of simple,scache,pbb.
31*56bb7041Schristos# If the target wants it can also provide a fast version of same, or if
32*56bb7041Schristos# the slow (full featured) version is `simple', then the fast version can be
33*56bb7041Schristos# one of scache/pbb.
34*56bb7041Schristos# A target can't provide more than this.
35*56bb7041Schristos# However for illustration's sake this file provides examples of all.
36*56bb7041Schristos
37*56bb7041Schristos# ??? After a few more ports are done, revisit.
38*56bb7041Schristos# Will eventually need to machine generate a lot of this.
39*56bb7041Schristos
40*56bb7041Schristoscase "x$1" in
41*56bb7041Schristos
42*56bb7041Schristosxsupport)
43*56bb7041Schristos
44*56bb7041Schristoscat <<EOF
45*56bb7041Schristos
46*56bb7041Schristosstatic INLINE const IDESC *
47*56bb7041Schristosextract (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_WORD insn,
48*56bb7041Schristos         ARGBUF *abuf, int fast_p)
49*56bb7041Schristos{
50*56bb7041Schristos  const IDESC *id = @prefix@_decode (current_cpu, pc, insn, abuf);
51*56bb7041Schristos  @prefix@_fill_argbuf (current_cpu, abuf, id, pc, fast_p);
52*56bb7041Schristos  if (!fast_p)
53*56bb7041Schristos    {
54*56bb7041Schristos      int trace_p = PC_IN_TRACE_RANGE_P (current_cpu, pc);
55*56bb7041Schristos      int profile_p = PC_IN_PROFILE_RANGE_P (current_cpu, pc);
56*56bb7041Schristos      @prefix@_fill_argbuf_tp (current_cpu, abuf, trace_p, profile_p);
57*56bb7041Schristos    }
58*56bb7041Schristos  return id;
59*56bb7041Schristos}
60*56bb7041Schristos
61*56bb7041Schristosstatic INLINE SEM_PC
62*56bb7041Schristosexecute (SIM_CPU *current_cpu, SCACHE *sc, int fast_p)
63*56bb7041Schristos{
64*56bb7041Schristos  SEM_PC vpc;
65*56bb7041Schristos
66*56bb7041Schristos  if (fast_p)
67*56bb7041Schristos      vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, sc);
68*56bb7041Schristos  else
69*56bb7041Schristos    {
70*56bb7041Schristos      ARGBUF *abuf = &sc->argbuf;
71*56bb7041Schristos      const IDESC *idesc = abuf->idesc;
72*56bb7041Schristos      const CGEN_INSN *idata = idesc->idata;
73*56bb7041Schristos      int virtual_p = 0;
74*56bb7041Schristos
75*56bb7041Schristos      if (! virtual_p)
76*56bb7041Schristos        {
77*56bb7041Schristos          /* FIXME: call x-before */
78*56bb7041Schristos          if (ARGBUF_PROFILE_P (abuf))
79*56bb7041Schristos            PROFILE_COUNT_INSN (current_cpu, abuf->addr, idesc->num);
80*56bb7041Schristos          /* FIXME: Later make cover macros: PROFILE_INSN_{INIT,FINI}.  */
81*56bb7041Schristos          if (PROFILE_MODEL_P (current_cpu)
82*56bb7041Schristos              && ARGBUF_PROFILE_P (abuf))
83*56bb7041Schristos            @cpu@_model_insn_before (current_cpu, 1 /*first_p*/);
84*56bb7041Schristos          CGEN_TRACE_INSN_INIT (current_cpu, abuf, 1);
85*56bb7041Schristos          CGEN_TRACE_INSN (current_cpu, idata,
86*56bb7041Schristos                      (const struct argbuf *) abuf, abuf->addr);
87*56bb7041Schristos        }
88*56bb7041Schristos      vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, sc);
89*56bb7041Schristos      if (! virtual_p)
90*56bb7041Schristos        {
91*56bb7041Schristos          /* FIXME: call x-after */
92*56bb7041Schristos          if (PROFILE_MODEL_P (current_cpu)
93*56bb7041Schristos              && ARGBUF_PROFILE_P (abuf))
94*56bb7041Schristos            {
95*56bb7041Schristos              int cycles;
96*56bb7041Schristos
97*56bb7041Schristos              cycles = (*idesc->timing->model_fn) (current_cpu, sc);
98*56bb7041Schristos              @cpu@_model_insn_after (current_cpu, 1 /*last_p*/, cycles);
99*56bb7041Schristos            }
100*56bb7041Schristos          CGEN_TRACE_INSN_FINI (current_cpu, abuf, 1);
101*56bb7041Schristos        }
102*56bb7041Schristos    }
103*56bb7041Schristos
104*56bb7041Schristos  return vpc;
105*56bb7041Schristos}
106*56bb7041Schristos
107*56bb7041SchristosEOF
108*56bb7041Schristos
109*56bb7041Schristos;;
110*56bb7041Schristos
111*56bb7041Schristosxinit)
112*56bb7041Schristos
113*56bb7041Schristos# Nothing needed.
114*56bb7041Schristos
115*56bb7041Schristos;;
116*56bb7041Schristos
117*56bb7041Schristosxextract-scache)
118*56bb7041Schristos
119*56bb7041Schristoscat <<EOF
120*56bb7041Schristos{
121*56bb7041Schristos
122*56bb7041Schristos  UDI insn = GETIMEMUDI (current_cpu, vpc);
123*56bb7041Schristos
124*56bb7041Schristos  if (current_target_byte_order == BFD_ENDIAN_BIG)
125*56bb7041Schristos    {
126*56bb7041Schristos      /* eBPF instructions are little-endian, but GETIMEMUDI reads according
127*56bb7041Schristos         to target byte order. Swap to little-endian. */
128*56bb7041Schristos      insn = SWAP_8 (insn);
129*56bb7041Schristos
130*56bb7041Schristos      /* But, the imm32 and offset16 fields within instructions follow target
131*56bb7041Schristos         byte order. Swap those fields back. */
132*56bb7041Schristos      UHI off16 = (UHI) ((insn & 0x00000000ffff0000) >> 16);
133*56bb7041Schristos      USI imm32 = (USI) ((insn & 0xffffffff00000000) >> 32);
134*56bb7041Schristos      off16 = SWAP_2 (off16);
135*56bb7041Schristos      imm32 = SWAP_4 (imm32);
136*56bb7041Schristos
137*56bb7041Schristos      insn = (((UDI) imm32) << 32) | (((UDI) off16) << 16) | (insn & 0xffff);
138*56bb7041Schristos    }
139*56bb7041Schristos
140*56bb7041Schristos  extract (current_cpu, vpc, insn, sc, FAST_P);
141*56bb7041Schristos
142*56bb7041Schristos  //XXX  SEM_SKIP_COMPILE (current_cpu, sc, 1);
143*56bb7041Schristos}
144*56bb7041SchristosEOF
145*56bb7041Schristos
146*56bb7041Schristos;;
147*56bb7041Schristos
148*56bb7041Schristosxfull-exec-* | xfast-exec-*)
149*56bb7041Schristos
150*56bb7041Schristos# Inputs: current_cpu, vpc, sc, FAST_P
151*56bb7041Schristos# Outputs: vpc
152*56bb7041Schristos# vpc is the virtual program counter.
153*56bb7041Schristos
154*56bb7041Schristoscat <<EOF
155*56bb7041Schristos   vpc = execute (current_cpu, sc, FAST_P);
156*56bb7041SchristosEOF
157*56bb7041Schristos
158*56bb7041Schristos;;
159*56bb7041Schristos
160*56bb7041Schristos*)
161*56bb7041Schristos  echo "Invalid argument to mainloop.in: $1" >&2
162*56bb7041Schristos  exit 1
163*56bb7041Schristos  ;;
164*56bb7041Schristos
165*56bb7041Schristosesac
166