1 /*
2 * cHeadCPU.h
3 * Avida
4 *
5 * Called "head_cpu.hh" prior to 11/30/05.
6 * Copyright 1999-2011 Michigan State University. All rights reserved.
7 * Copyright 1999-2003 California Institute of Technology.
8 *
9 *
10 * This file is part of Avida.
11 *
12 * Avida is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
14 *
15 * Avida is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License along with Avida.
19 * If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23 #ifndef cHeadCPU_h
24 #define cHeadCPU_h
25
26 #include "avida/Avida.h"
27
28 #include "cCPUMemory.h"
29 #include "cHardwareBase.h"
30 #include "cInstSet.h"
31
32 /**
33 * The cHeadCPU class contains a pointer to locations in memory for a CPU.
34 **/
35
36 namespace Avida {
37 class Sequence;
38 };
39 class cCodeLabel;
40 class cInstruction;
41 class cString;
42
43 using namespace Avida;
44
45
46 class cHeadCPU
47 {
48 protected:
49 cHardwareBase* m_hardware;
50 int m_position;
51 int m_mem_space;
52 int m_cached_ms;
53 cCPUMemory* m_memory;
54
55 void fullAdjust(int mem_size = -1);
56
57 int FindLabel_Forward(const cCodeLabel& search_label, const Sequence& search_mem, int pos);
58 int FindLabel_Backward(const cCodeLabel& search_label, const Sequence& search_mem, int pos);
59
60
61 public:
62 inline cHeadCPU(cHardwareBase* hw = NULL, int pos = 0, int ms = 0);
63 inline cHeadCPU(const cHeadCPU& in_cpu_head);
~cHeadCPU()64 ~cHeadCPU() { ; }
65
GetMemory()66 inline const cCPUMemory& GetMemory() const { return *m_memory; }
GetMemory()67 inline cCPUMemory& GetMemory() { return *m_memory; }
GetMemSize()68 inline int GetMemSize() const { return m_memory->GetSize(); }
69
Adjust()70 inline void Adjust() { if (m_mem_space != m_cached_ms || m_position < 0 || m_position >= GetMemSize()) fullAdjust(); }
71 inline void Reset(cHardwareBase* hw, int ms = 0) { m_hardware = hw; m_position = 0; m_mem_space = ms; if (hw) Adjust(); }
72
GetMemSpace()73 inline int GetMemSpace() const { return m_mem_space; }
GetPosition()74 inline int GetPosition() const { return m_position; }
GetFullLocation()75 inline int GetFullLocation() const { return (m_position & 0xFFFFFF) | (m_mem_space << 24); }
76
77 inline void Set(int pos, int ms = 0) { m_position = pos; m_mem_space = ms; Adjust(); }
SetFullLocation(int loc)78 inline void SetFullLocation(int loc) { m_position = loc & 0xFFFFFF; m_mem_space = (loc >> 24); Adjust(); }
Set(const cHeadCPU & in_head)79 inline void Set(const cHeadCPU& in_head) { m_position = in_head.m_position; m_mem_space = in_head.m_mem_space; }
AbsSet(int new_pos)80 inline void AbsSet(int new_pos) { m_position = new_pos; }
81
Jump(int jump)82 inline void Jump(int jump) { m_position += jump; Adjust(); }
AbsJump(int jump)83 inline void AbsJump(int jump) { m_position += jump; }
84 inline void LoopJump(int jump);
85
Advance()86 inline void Advance() { m_position++; Adjust(); }
Retreat()87 inline void Retreat() { m_position--; Adjust(); }
88
GetInst()89 inline const cInstruction& GetInst() const { return GetMemory()[m_position]; }
GetInst(int offset)90 inline const cInstruction& GetInst(int offset) const { return GetMemory()[m_position + offset]; }
91 inline cInstruction GetNextInst() const;
92
SetInst(const cInstruction & value)93 inline void SetInst(const cInstruction& value) { GetMemory()[m_position] = value; }
InsertInst(const cInstruction & inst)94 inline void InsertInst(const cInstruction& inst) { GetMemory().Insert(m_position, inst); }
RemoveInst()95 inline void RemoveInst() { GetMemory().Remove(m_position); }
96
SetFlagCopied()97 inline void SetFlagCopied() { return GetMemory().SetFlagCopied(m_position); }
SetFlagMutated()98 inline void SetFlagMutated() { return GetMemory().SetFlagMutated(m_position); }
SetFlagExecuted()99 inline void SetFlagExecuted() { return GetMemory().SetFlagExecuted(m_position); }
SetFlagBreakpoint()100 inline void SetFlagBreakpoint() { return GetMemory().SetFlagBreakpoint(m_position); }
SetFlagPointMut()101 inline void SetFlagPointMut() { return GetMemory().SetFlagPointMut(m_position); }
SetFlagCopyMut()102 inline void SetFlagCopyMut() { return GetMemory().SetFlagCopyMut(m_position); }
103
ClearFlagCopied()104 inline void ClearFlagCopied() { return GetMemory().ClearFlagCopied(m_position); }
ClearFlagMutated()105 inline void ClearFlagMutated() { return GetMemory().ClearFlagMutated(m_position); }
ClearFlagExecuted()106 inline void ClearFlagExecuted() { return GetMemory().ClearFlagExecuted(m_position); }
ClearFlagBreakpoint()107 inline void ClearFlagBreakpoint() { return GetMemory().ClearFlagBreakpoint(m_position); }
ClearFlagPointMut()108 inline void ClearFlagPointMut() { return GetMemory().ClearFlagPointMut(m_position); }
ClearFlagCopyMut()109 inline void ClearFlagCopyMut() { return GetMemory().ClearFlagCopyMut(m_position); }
110
111 // Operator Overloading...
112 inline cHeadCPU& operator=(const cHeadCPU& in_cpu_head);
113 inline cHeadCPU& operator++() { m_position++; Adjust(); return *this; }
114 inline cHeadCPU& operator--() { m_position--; Adjust(); return *this; }
115 inline cHeadCPU& operator++(int) { return operator++(); }
116 inline cHeadCPU& operator--(int) { return operator--(); }
117 inline int operator-(const cHeadCPU& in_cpu_head) { return m_position - in_cpu_head.m_position; }
118 inline bool operator==(const cHeadCPU& in_cpu_head) const;
119
120 // Bool Tests...
AtFront()121 inline bool AtFront() const { return (m_position == 0); }
AtEnd()122 inline bool AtEnd() const { return (m_position + 1 == GetMemory().GetSize()); }
InMemory()123 inline bool InMemory() const { return (m_position >= 0 && m_position < GetMemory().GetSize()); }
124 };
125
126
cHeadCPU(cHardwareBase * hw,int pos,int ms)127 inline cHeadCPU::cHeadCPU(cHardwareBase* hw, int pos, int ms)
128 : m_hardware(hw), m_position(pos), m_mem_space(ms), m_cached_ms(-1)
129 {
130 if (hw) {
131 if (pos || ms) Adjust();
132 else {
133 m_cached_ms = 0;
134 m_memory = &m_hardware->GetMemory(0);
135 }
136 }
137 }
138
cHeadCPU(const cHeadCPU & in_cpu_head)139 inline cHeadCPU::cHeadCPU(const cHeadCPU& in_cpu_head)
140 {
141 m_hardware = in_cpu_head.m_hardware;
142 m_position = in_cpu_head.m_position;
143 m_mem_space = in_cpu_head.m_mem_space;
144 m_cached_ms = in_cpu_head.m_cached_ms;
145 m_memory = in_cpu_head.m_memory;
146 }
147
LoopJump(int jump)148 inline void cHeadCPU::LoopJump(int jump)
149 {
150 m_position += jump;
151
152 // keep in range
153 m_position %= GetMemory().GetSize();
154 if (m_position <= 0) m_position += GetMemory().GetSize();
155 }
156
157 inline cHeadCPU& cHeadCPU::operator=(const cHeadCPU& in_cpu_head)
158 {
159 m_hardware = in_cpu_head.m_hardware;
160 m_position = in_cpu_head.m_position;
161 m_mem_space = in_cpu_head.m_mem_space;
162 return *this;
163 }
164
165 inline bool cHeadCPU::operator==(const cHeadCPU& in_cpu_head) const
166 {
167 return (m_hardware == in_cpu_head.m_hardware) && (m_position == in_cpu_head.m_position) &&
168 (m_mem_space == in_cpu_head.m_mem_space);
169 }
170
GetNextInst()171 inline cInstruction cHeadCPU::GetNextInst() const
172 {
173 return (AtEnd()) ? m_hardware->GetInstSet().GetInstError() : GetMemory()[m_position + 1];
174 }
175
176 #endif
177