aboutsummaryrefslogtreecommitdiff
path: root/sim/common/sim-cpu.h
blob: 83244e09c9eaed79de8427d10444d9426c73e76c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/* CPU support.
   Copyright (C) 1998-2022 Free Software Foundation, Inc.
   Contributed by Cygnus Solutions.

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 3 of the License, 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, see <http://www.gnu.org/licenses/>.  */

/* This file is intended to be included by sim-base.h.

   This file provides an interface between the simulator framework and
   the selected cpu.  */

#ifndef SIM_CPU_H
#define SIM_CPU_H

/* Type of function to return an insn name.  */
typedef const char * (CPU_INSN_NAME_FN) (sim_cpu *, int);

#ifdef CGEN_ARCH
# include "cgen-cpu.h"
#endif

/* Types for register access functions.
   These routines implement the sim_{fetch,store}_register interface.  */
typedef int (CPUREG_FETCH_FN) (sim_cpu *, int, void *, int);
typedef int (CPUREG_STORE_FN) (sim_cpu *, int, const void *, int);

/* Types for PC access functions.
   Some simulators require a functional interface to access the program
   counter [a macro is insufficient as the PC is kept in a cpu-specific part
   of the sim_cpu struct].  */
typedef sim_cia (PC_FETCH_FN) (sim_cpu *);
typedef void (PC_STORE_FN) (sim_cpu *, sim_cia);

/* Pseudo baseclass for each cpu.  */

typedef struct {

  /* Backlink to main state struct.  */
  SIM_DESC state;
#define CPU_STATE(cpu) ((cpu)->base.state)

  /* Processor index within the SD_DESC */
  int index;
#define CPU_INDEX(cpu) ((cpu)->base.index)

  /* The name of the cpu.  */
  const char *name;
#define CPU_NAME(cpu) ((cpu)->base.name)

  /* Options specific to this cpu.  */
  struct option_list *options;
#define CPU_OPTIONS(cpu) ((cpu)->base.options)

  /* Processor specific core data */
  sim_cpu_core core;
#define CPU_CORE(cpu) (& (cpu)->base.core)

  /* Number of instructions (used to iterate over CPU_INSN_NAME).  */
  unsigned int max_insns;
#define CPU_MAX_INSNS(cpu) ((cpu)->base.max_insns)

  /* Function to return the name of an insn.  */
  CPU_INSN_NAME_FN *insn_name;
#define CPU_INSN_NAME(cpu) ((cpu)->base.insn_name)

  /* Trace data.  See sim-trace.h.  */
  TRACE_DATA trace_data;
#define CPU_TRACE_DATA(cpu) (& (cpu)->base.trace_data)

  /* Maximum number of debuggable entities.
     This debugging is not intended for normal use.
     It is only enabled when the simulator is configured with --with-debug
     which shouldn't normally be specified.  */
#ifndef MAX_DEBUG_VALUES
#define MAX_DEBUG_VALUES 4
#endif

  /* Boolean array of specified debugging flags.  */
  char debug_flags[MAX_DEBUG_VALUES];
#define CPU_DEBUG_FLAGS(cpu) ((cpu)->base.debug_flags)
  /* Standard values.  */
#define DEBUG_INSN_IDX 0
#define DEBUG_NEXT_IDX 2 /* simulator specific debug bits begin here */

  /* Debugging output goes to this or stderr if NULL.
     We can't store `stderr' here as stderr goes through a callback.  */
  FILE *debug_file;
#define CPU_DEBUG_FILE(cpu) ((cpu)->base.debug_file)

  /* Profile data.  See sim-profile.h.  */
  PROFILE_DATA profile_data;
#define CPU_PROFILE_DATA(cpu) (& (cpu)->base.profile_data)

  /* Machine tables for this cpu.  See sim-model.h.  */
  const SIM_MACH *mach;
#define CPU_MACH(cpu) ((cpu)->base.mach)
  /* The selected model.  */
  const SIM_MODEL *model;
#define CPU_MODEL(cpu) ((cpu)->base.model)
  /* Model data (profiling state, etc.).  */
  void *model_data;
#define CPU_MODEL_DATA(cpu) ((cpu)->base.model_data)

  /* Routines to fetch/store registers.  */
  CPUREG_FETCH_FN *reg_fetch;
#define CPU_REG_FETCH(c) ((c)->base.reg_fetch)
  CPUREG_STORE_FN *reg_store;
#define CPU_REG_STORE(c) ((c)->base.reg_store)
  PC_FETCH_FN *pc_fetch;
#define CPU_PC_FETCH(c) ((c)->base.pc_fetch)
  PC_STORE_FN *pc_store;
#define CPU_PC_STORE(c) ((c)->base.pc_store)

} sim_cpu_base;

struct _sim_cpu {
  /* All the common state.  */
  sim_cpu_base base;

#ifdef CGEN_ARCH
  /* Static parts of cgen.  */
  CGEN_CPU cgen_cpu;
#define CPU_CGEN_CPU(cpu) ((cpu)->cgen_cpu)
#endif

  /* Pointer for sim target to store arbitrary cpu data.  Normally the
     target should define a struct and use it here.  */
  void *arch_data;
#define CPU_ARCH_DATA(cpu) ((cpu)->arch_data)
};

/* Create all cpus.  */
extern SIM_RC sim_cpu_alloc_all_extra (SIM_DESC, int, size_t);
#define sim_cpu_alloc_all(state, ncpus) sim_cpu_alloc_all_extra (state, ncpus, 0)
/* Create a cpu.  */
extern sim_cpu *sim_cpu_alloc_extra (SIM_DESC, size_t);
#define sim_cpu_alloc(sd) sim_cpu_alloc_extra (sd, 0)
/* Release resources held by all cpus.  */
extern void sim_cpu_free_all (SIM_DESC);
/* Release resources held by a cpu.  */
extern void sim_cpu_free (sim_cpu *);

/* Return a pointer to the cpu data for CPU_NAME, or NULL if not found.  */
extern sim_cpu *sim_cpu_lookup (SIM_DESC, const char *);

/* Return prefix to use in cpu specific messages.  */
extern const char *sim_cpu_msg_prefix (sim_cpu *);
/* Cover fn to sim_io_eprintf.  */
extern void sim_io_eprintf_cpu (sim_cpu *, const char *, ...)
  ATTRIBUTE_PRINTF (2, 3);

/* Get/set a pc value.  */
#define CPU_PC_GET(cpu) ((* CPU_PC_FETCH (cpu)) (cpu))
#define CPU_PC_SET(cpu,newval) ((* CPU_PC_STORE (cpu)) ((cpu), (newval)))
/* External interface to accessing the pc.  */
sim_cia sim_pc_get (sim_cpu *);
void sim_pc_set (sim_cpu *, sim_cia);

#endif /* SIM_CPU_H */