cpu.hh 7.11 KB
Newer Older
Benoit Perrot's avatar
Benoit Perrot committed
1
//
Benoit Perrot's avatar
Benoit Perrot committed
2
// This file is part of Nolimips, a MIPS simulator with unlimited registers
3
// Copyright (C) 2003, 2004, 2006 Benoit Perrot <benoit@lrde.epita.fr>
Benoit Perrot's avatar
Benoit Perrot committed
4
//
Benoit Perrot's avatar
Benoit Perrot committed
5
// Nolimips is free software; you can redistribute it and/or modify
Benoit Perrot's avatar
Benoit Perrot committed
6
7
8
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
9
//
Benoit Perrot's avatar
Benoit Perrot committed
10
// Nolimips is distributed in the hope that it will be useful,
Benoit Perrot's avatar
Benoit Perrot committed
11
12
13
// 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.
14
//
Benoit Perrot's avatar
Benoit Perrot committed
15
16
17
18
// 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
//
Benoit Perrot's avatar
Benoit Perrot committed
19
20
/** \file vm/cpu.hh
    \brief Declare Central Processor Unit class. */
21
22
23
24
#ifndef VM_CPU_HH
# define VM_CPU_HH

# include <stdint.h>
25
26
# include <vector>

27
28
# include "misc/table.hh"

29
# include "inst/inst.hh"
30
31
# include "inst/visitor.hh"

32
# include "vm/fwd.hh"
33
34
35
36

namespace vm
{

Benoit Perrot's avatar
Benoit Perrot committed
37
38
  typedef int32_t	register_type;
  typedef uint32_t	uregister_type;
39

Benoit Perrot's avatar
Benoit Perrot committed
40
  /// Central Processor Unit abstraction
41
  class Cpu:
Benoit Perrot's avatar
Benoit Perrot committed
42
    protected inst::ConstVisitor
43
  {
44
  public:
Benoit Perrot's avatar
Benoit Perrot committed
45
    /// General purpose registers indices
Benoit Perrot's avatar
Benoit Perrot committed
46
    enum kind_type
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
      {
	zero = 0,
	at,
	v0, v1,
	a0, a1, a2, a3,
	t0, t1, t2, t3, t4, t5, t6, t7,
	s0, s1, s2, s3, s4, s5, s6, s7,
	t8, t9,
	k0, k1,
	gp,
	sp,
	fp,
	ra = 31
      };

62
    /** \name Constructor and destructor
Benoit Perrot's avatar
Benoit Perrot committed
63
	\{ */
64
  public:
Benoit Perrot's avatar
Benoit Perrot committed
65
    /// Construct a CPU.
66
    Cpu(Mmu &mmu, Cp0 &cp0);
Benoit Perrot's avatar
Benoit Perrot committed
67
68
    /// Destroy a CPU.
    virtual ~Cpu();
Benoit Perrot's avatar
Benoit Perrot committed
69
    /** \} */
70
71

  public:
Benoit Perrot's avatar
Benoit Perrot committed
72
    /// Reset the CPU (set general purpose registers to zero, etc.)
73
    void reset();
74

75
    /// Print registers' content
76
    void write(std::ostream &os) const;
77

Benoit Perrot's avatar
Benoit Perrot committed
78
79
    /** \name General purpose registers accessors.
	\{ */
80
  public:
Benoit Perrot's avatar
Benoit Perrot committed
81
    /// Set the general purpose register \a k to \a r.
82
83
84
    void set_register(kind_type k, register_type r);
    /// Return the general purpose register \a k.
    register_type get_register(kind_type k) const;
Benoit Perrot's avatar
Benoit Perrot committed
85
    /** \} */
86

Benoit Perrot's avatar
Benoit Perrot committed
87
88
89
    /** \name Unlimited registers accessors.
	\{ */
  public:
90
91
    /// Set the unlimited register indexed by \a i to \a r.
    void set_unlimited(int i, register_type r);
Benoit Perrot's avatar
Benoit Perrot committed
92
    /// Return true if the unlimited register \a i exists.
93
    bool has_unlimited(int i) const;
Benoit Perrot's avatar
Benoit Perrot committed
94
    /// Return the unlimited register indexed by \a i.
95
    register_type get_unlimited(int i) const;
Benoit Perrot's avatar
Benoit Perrot committed
96
    /** \} */
97

Benoit Perrot's avatar
Benoit Perrot committed
98
99
100
101
    /** \name Registers unified accessors.
	\{ */
  public:
    /// Set the register identified by \a reg to \a r.
102
103
104
    void set_register(const inst::Register &reg, register_type r);
    /// Return the register identified by \a reg.
    register_type get_register(const inst::Register &reg) const;
Benoit Perrot's avatar
Benoit Perrot committed
105
    /** \} */
106

Benoit Perrot's avatar
Benoit Perrot committed
107
108
109
110
    /** \name Special registers accessors.
	\{ */
  public:
    /// Set the HI register to \a r.
111
112
113
    void set_hi(register_type r);
    /// Return the HI register.
    register_type get_hi() const;
Benoit Perrot's avatar
Benoit Perrot committed
114
115

    /// Set the LO register to \a r.
116
117
118
    void set_lo(register_type r);
    /// Return the LO register.
    register_type get_lo() const;
Benoit Perrot's avatar
Benoit Perrot committed
119
120

    /// Set the PC register to \a r.
121
122
123
    void set_pc(register_type r);
    /// Return the PC register.
    register_type get_pc() const;
Benoit Perrot's avatar
Benoit Perrot committed
124
    /** \} */
125

126
127
128
  public:
    Mmu &get_mmu();
    Cp0 &get_cp0();
129

130
131
132
133
134
  public:
    unsigned get_instruction_counter(inst::Inst::format_type format) const;

    const std::vector<register_type> &get_call_stack() const;
    void set_check_callee_save(bool check_callee_save_p);
135

136
137
138
139
140
141
  public:
    /// Set trace flag
    void set_trace(bool trace_p);

    /// Make one execution step
    void step();
142

143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
  protected:
    virtual void	visit(const inst::Add& add);
    virtual void	visit(const inst::Addi& addi);
    virtual void	visit(const inst::Addu& addu);
    virtual void	visit(const inst::Addiu& addiu);
    virtual void	visit(const inst::Sub& sub);
    virtual void	visit(const inst::Subu& subu);

    virtual void	visit(const inst::Sll& sll);
    virtual void	visit(const inst::Sllv& slv);
    virtual void	visit(const inst::Sra& sra);
    virtual void	visit(const inst::Srav& srav);
    virtual void	visit(const inst::Srl& srl);
    virtual void	visit(const inst::Srlv& srlv);

    virtual void	visit(const inst::Mul& mul);
    virtual void	visit(const inst::Div& div);
    virtual void	visit(const inst::Divu& divu);

    virtual void	visit(const inst::Lb& lb);
    virtual void	visit(const inst::Lbu& Lbu);
    virtual void	visit(const inst::Lw& lw);
Benoit Perrot's avatar
Benoit Perrot committed
165
    virtual void	visit(const inst::Lui& lui);
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
    virtual void	visit(const inst::Sb& sb);
    virtual void	visit(const inst::Sw& sw);

    virtual void	visit(const inst::And& _and);
    virtual void	visit(const inst::Andi& andi);
    virtual void	visit(const inst::Or& _or);
    virtual void	visit(const inst::Ori& ori);
    virtual void	visit(const inst::Nor& nor);
    virtual void	visit(const inst::Xor& _xor);
    virtual void	visit(const inst::Xori& xori);

    virtual void	visit(const inst::Slt& slt);
    virtual void	visit(const inst::Slti& slti);
    virtual void	visit(const inst::Sltu&);
    virtual void	visit(const inst::Sltiu& sltiu);

    virtual void	visit(const inst::Jmp& jmp);
    virtual void	visit(const inst::Jr& jr);
    virtual void	visit(const inst::Jal& jal);
    virtual void	visit(const inst::Jalr& jalr);

    virtual void	visit(const inst::Beq& beq);
    virtual void	visit(const inst::Bne& bne);

    virtual void	visit(const inst::Bgez& bgez);
    virtual void	visit(const inst::Bgezal& bgezal);
    virtual void	visit(const inst::Bgtz& bgtz);

    virtual void	visit(const inst::Blez& blez);
    virtual void	visit(const inst::Bltz& bltz);
    virtual void	visit(const inst::Bltzal& bltzal);

    virtual void	visit(const inst::Mfhi& mfhi);
    virtual void	visit(const inst::Mflo& mflo);
    virtual void	visit(const inst::Mthi& mthi);
    virtual void	visit(const inst::Mtlo& mtlo);
Benoit Perrot's avatar
Benoit Perrot committed
202
203
    virtual void	visit(const inst::Mfc0& mfc0);
    virtual void	visit(const inst::Mtc0& mtc0);
204
205
206

    virtual void	visit(const inst::Syscall& sycall);

207
208
209
    void call();
    void ret();

210
  protected:
Benoit Perrot's avatar
Benoit Perrot committed
211
    /// Memory management unit link.
212
    Mmu &mmu_;
Benoit Perrot's avatar
Benoit Perrot committed
213
    /// Control coprocessor link.
214
    Cp0 &cp0_;
Benoit Perrot's avatar
Benoit Perrot committed
215
216

    /// General purpose registers.
217
    register_type GPR_[32];
Benoit Perrot's avatar
Benoit Perrot committed
218
    /// Special HIgh register.
219
    register_type hi_;
Benoit Perrot's avatar
Benoit Perrot committed
220
    /// Special LOw register.
221
    register_type lo_;
Benoit Perrot's avatar
Benoit Perrot committed
222
    /// Special Program Counter.
223
    register_type pc_;
224

225
226
    /// Unlimited registers.
    misc::Table<int, register_type> unlimited_;
Benoit Perrot's avatar
Benoit Perrot committed
227

228
  protected:
229
230
    std::vector<register_type> call_stack_;
    bool check_callee_save_p_;
Benoit Perrot's avatar
Benoit Perrot committed
231
232

  protected:
233
    bool trace_p_;
Benoit Perrot's avatar
Benoit Perrot committed
234

Benoit Perrot's avatar
Benoit Perrot committed
235
    enum pipeline_stage_type
Benoit Perrot's avatar
Benoit Perrot committed
236
      {
Benoit Perrot's avatar
Benoit Perrot committed
237
238
239
240
241
242
	i_stage = 0,	///< Instruction fetch stage
	d_stage,	///< Instruction dispatch stage
	r_stage,	///< Regoster file read stage
	e_stage,	///< Execution stage
	m_stage,	///< Memory access stage
	w_stage		///< Writeback stage
Benoit Perrot's avatar
Benoit Perrot committed
243
      };
244
    inst::Inst *bubble_;
245
246

    /// Instruction pipeline
247
    const inst::Inst *pipeline_[6];
248
249

    /// Instruction counters
250
    unsigned counters_[3];
251
252
  };

253
254
  std::ostream &
  operator<<(std::ostream &ostr, const Cpu &cpu);
255

256
257
} // namespace vm

258
259
# include "vm/cpu.hxx"

260
#endif // !VM_CPU_HH