[Avida-SVN] r2602 - in development: Avida.xcodeproj source/cpu
brysonda at myxo.css.msu.edu
brysonda at myxo.css.msu.edu
Fri May 30 08:04:37 PDT 2008
Author: brysonda
Date: 2008-05-30 11:04:37 -0400 (Fri, 30 May 2008)
New Revision: 2602
Modified:
development/Avida.xcodeproj/project.pbxproj
development/source/cpu/cHardwareBase.h
development/source/cpu/cHardwareExperimental.cc
development/source/cpu/cHardwareExperimental.h
Log:
First pass number 'moldiness' in the experimental CPU.
Modified: development/Avida.xcodeproj/project.pbxproj
===================================================================
--- development/Avida.xcodeproj/project.pbxproj 2008-05-30 14:23:37 UTC (rev 2601)
+++ development/Avida.xcodeproj/project.pbxproj 2008-05-30 15:04:37 UTC (rev 2602)
@@ -1352,12 +1352,12 @@
DCC30F7C0762539D008F7A48 /* cpu */ = {
isa = PBXGroup;
children = (
+ 70B1A64F0B7E237F00067486 /* cHardwareExperimental.cc */,
705261050B87AF5C0007426F /* cInstLib.h */,
706C703E0B83FB95003174C1 /* tInstLibEntry.h */,
706C6FFE0B83F265003174C1 /* cInstSet.cc */,
706C6FFD0B83F254003174C1 /* cInstSet.h */,
70B1A6530B7E238F00067486 /* cHardwareExperimental.h */,
- 70B1A64F0B7E237F00067486 /* cHardwareExperimental.cc */,
7049F2D70A66859300640512 /* cHardwareTransSMT.cc */,
7049F2D80A66859300640512 /* cHardwareTransSMT.h */,
70C1EF4608C393BA00F50912 /* cCodeLabel.cc */,
Modified: development/source/cpu/cHardwareBase.h
===================================================================
--- development/source/cpu/cHardwareBase.h 2008-05-30 14:23:37 UTC (rev 2601)
+++ development/source/cpu/cHardwareBase.h 2008-05-30 15:04:37 UTC (rev 2602)
@@ -157,7 +157,6 @@
// -------- Register Manipulation --------
virtual int GetRegister(int reg_id) const = 0;
- virtual int& GetRegister(int reg_id) = 0;
virtual int GetNumRegisters() const = 0;
Modified: development/source/cpu/cHardwareExperimental.cc
===================================================================
--- development/source/cpu/cHardwareExperimental.cc 2008-05-30 14:23:37 UTC (rev 2601)
+++ development/source/cpu/cHardwareExperimental.cc 2008-05-30 15:04:37 UTC (rev 2602)
@@ -122,8 +122,10 @@
tInstLibEntry<tMethod>("nand", &cHardwareExperimental::Inst_Nand, nInstFlag::DEFAULT, "Nand BX by CX and place the result in ?BX?"),
tInstLibEntry<tMethod>("IO", &cHardwareExperimental::Inst_TaskIO, (nInstFlag::DEFAULT | nInstFlag::STALL), "Output ?BX?, and input new number back into ?BX?"),
+ tInstLibEntry<tMethod>("IO-expire", &cHardwareExperimental::Inst_TaskIOExpire, (nInstFlag::DEFAULT | nInstFlag::STALL), "Output ?BX?, and input new number back into ?BX?, if the number has not yet expired"),
tInstLibEntry<tMethod>("input", &cHardwareExperimental::Inst_TaskInput, nInstFlag::STALL, "Input new number into ?BX?"),
tInstLibEntry<tMethod>("output", &cHardwareExperimental::Inst_TaskOutput, nInstFlag::STALL, "Output ?BX?"),
+ tInstLibEntry<tMethod>("output-expire", &cHardwareExperimental::Inst_TaskOutputExpire, nInstFlag::STALL, "Output ?BX?, as long as the output has not yet expired"),
tInstLibEntry<tMethod>("mult", &cHardwareExperimental::Inst_Mult, 0, "Multiple BX by CX and place the result in ?BX?"),
tInstLibEntry<tMethod>("div", &cHardwareExperimental::Inst_Div, 0, "Divide BX by CX and place the result in ?BX?"),
@@ -228,6 +230,8 @@
, m_threads(hardware_cpu.m_threads)
, m_thread_id_chart(hardware_cpu.m_thread_id_chart)
, m_cur_thread(hardware_cpu.m_cur_thread)
+, m_cycle_count(hardware_cpu.m_cycle_count)
+, m_last_output(hardware_cpu.m_last_output)
, m_mal_active(hardware_cpu.m_mal_active)
, m_advance_ip(hardware_cpu.m_advance_ip)
, m_executedmatchstrings(hardware_cpu.m_executedmatchstrings)
@@ -245,6 +249,8 @@
void cHardwareExperimental::Reset()
{
+ m_cycle_count = 0;
+ m_last_output = 0;
m_global_stack.Clear();
// We want to reset to have a single thread.
@@ -276,19 +282,11 @@
}
}
-void cHardwareExperimental::cLocalThread::operator=(const cLocalThread& in_thread)
+void cHardwareExperimental::cLocalThread::Reset(cHardwareExperimental* in_hardware, int in_id)
{
- m_id = in_thread.m_id;
- for (int i = 0; i < NUM_REGISTERS; i++) reg[i] = in_thread.reg[i];
- for (int i = 0; i < NUM_HEADS; i++) heads[i] = in_thread.heads[i];
- stack = in_thread.stack;
-}
-
-void cHardwareExperimental::cLocalThread::Reset(cHardwareBase* in_hardware, int in_id)
-{
m_id = in_id;
- for (int i = 0; i < NUM_REGISTERS; i++) reg[i] = 0;
+ for (int i = 0; i < NUM_REGISTERS; i++) reg[i].Clear();
for (int i = 0; i < NUM_HEADS; i++) heads[i].Reset(in_hardware);
stack.Clear();
@@ -326,6 +324,8 @@
// First instruction - check whether we should be starting at a promoter, when enabled.
if (phenotype.GetCPUCyclesUsed() == 0 && m_promoters_enabled) PromoterTerminate(ctx);
+ m_cycle_count++;
+ assert(m_cycle_count < 0x8000);
phenotype.IncCPUCyclesUsed();
if (!m_no_cpu_cycle_time) phenotype.IncTimeUsed();
@@ -350,7 +350,7 @@
}
#endif
- // Print the status of this CPU at each step...
+ // Print the status of this CPU at each step...
if (m_tracer != NULL) m_tracer->TraceHardware(*this);
// Find the instruction to be executed
@@ -492,7 +492,6 @@
if (!m_memory.OK()) result = false;
for (int i = 0; i < m_threads.GetSize(); i++) {
- if (m_threads[i].stack.OK() == false) result = false;
if (m_threads[i].next_label.OK() == false) result = false;
}
@@ -1059,14 +1058,19 @@
bool cHardwareExperimental::Inst_Pop(cAvidaContext& ctx)
{
const int reg_used = FindModifiedRegister(REG_BX);
- GetRegister(reg_used) = StackPop();
+ sInternalValue pop = StackPop();
+ setInternalValue(m_threads[m_cur_thread].reg[reg_used], pop.value, pop);
return true;
}
bool cHardwareExperimental::Inst_Push(cAvidaContext& ctx)
{
const int reg_used = FindModifiedRegister(REG_BX);
- StackPush(GetRegister(reg_used));
+ if (m_threads[m_cur_thread].cur_stack == 0) {
+ m_threads[m_cur_thread].stack.Push(m_threads[m_cur_thread].reg[reg_used]);
+ } else {
+ m_global_stack.Push(m_threads[m_cur_thread].reg[reg_used]);
+ }
return true;
}
@@ -1077,21 +1081,25 @@
{
const int op1 = FindModifiedRegister(REG_BX);
const int op2 = FindModifiedNextRegister(op1);
- nFunctions::Swap(GetRegister(op1), GetRegister(op2));
+ sInternalValue v1 = m_threads[m_cur_thread].reg[op1];
+ m_threads[m_cur_thread].reg[op1] = m_threads[m_cur_thread].reg[op2];
+ m_threads[m_cur_thread].reg[op2] = v1;
return true;
}
bool cHardwareExperimental::Inst_ShiftR(cAvidaContext& ctx)
{
const int reg_used = FindModifiedRegister(REG_BX);
- GetRegister(reg_used) >>= 1;
+ sInternalValue& reg = m_threads[m_cur_thread].reg[reg_used];
+ setInternalValue(reg, reg.value >> 1, reg);
return true;
}
bool cHardwareExperimental::Inst_ShiftL(cAvidaContext& ctx)
{
const int reg_used = FindModifiedRegister(REG_BX);
- GetRegister(reg_used) <<= 1;
+ sInternalValue& reg = m_threads[m_cur_thread].reg[reg_used];
+ setInternalValue(reg, reg.value << 1, reg);
return true;
}
@@ -1099,14 +1107,16 @@
bool cHardwareExperimental::Inst_Inc(cAvidaContext& ctx)
{
const int reg_used = FindModifiedRegister(REG_BX);
- GetRegister(reg_used) += 1;
+ sInternalValue& reg = m_threads[m_cur_thread].reg[reg_used];
+ setInternalValue(reg, reg.value + 1, reg);
return true;
}
bool cHardwareExperimental::Inst_Dec(cAvidaContext& ctx)
{
const int reg_used = FindModifiedRegister(REG_BX);
- GetRegister(reg_used) -= 1;
+ sInternalValue& reg = m_threads[m_cur_thread].reg[reg_used];
+ setInternalValue(reg, reg.value - 1, reg);
return true;
}
@@ -1116,7 +1126,10 @@
const int dst = FindModifiedRegister(REG_BX);
const int op1 = FindModifiedRegister(dst);
const int op2 = FindModifiedNextRegister(op1);
- GetRegister(dst) = GetRegister(op1) + GetRegister(op2);
+ sInternalValue& dreg = m_threads[m_cur_thread].reg[dst];
+ sInternalValue& r1 = m_threads[m_cur_thread].reg[op1];
+ sInternalValue& r2 = m_threads[m_cur_thread].reg[op2];
+ setInternalValue(dreg, r1.value + r2.value, r1, r2);
return true;
}
@@ -1125,7 +1138,10 @@
const int dst = FindModifiedRegister(REG_BX);
const int op1 = FindModifiedRegister(dst);
const int op2 = FindModifiedNextRegister(op1);
- GetRegister(dst) = GetRegister(op1) - GetRegister(op2);
+ sInternalValue& dreg = m_threads[m_cur_thread].reg[dst];
+ sInternalValue& r1 = m_threads[m_cur_thread].reg[op1];
+ sInternalValue& r2 = m_threads[m_cur_thread].reg[op2];
+ setInternalValue(dreg, r1.value - r2.value, r1, r2);
return true;
}
@@ -1134,7 +1150,10 @@
const int dst = FindModifiedRegister(REG_BX);
const int op1 = FindModifiedRegister(dst);
const int op2 = FindModifiedNextRegister(op1);
- GetRegister(dst) = GetRegister(op1) * GetRegister(op2);
+ sInternalValue& dreg = m_threads[m_cur_thread].reg[dst];
+ sInternalValue& r1 = m_threads[m_cur_thread].reg[op1];
+ sInternalValue& r2 = m_threads[m_cur_thread].reg[op2];
+ setInternalValue(dreg, r1.value * r2.value, r1, r2);
return true;
}
@@ -1143,11 +1162,14 @@
const int dst = FindModifiedRegister(REG_BX);
const int op1 = FindModifiedRegister(dst);
const int op2 = FindModifiedNextRegister(op1);
- if (GetRegister(op2) != 0) {
- if (0-INT_MAX > GetRegister(op1) && GetRegister(op2) == -1)
+ sInternalValue& dreg = m_threads[m_cur_thread].reg[dst];
+ sInternalValue& r1 = m_threads[m_cur_thread].reg[op1];
+ sInternalValue& r2 = m_threads[m_cur_thread].reg[op2];
+ if (r2.value != 0) {
+ if (0 - INT_MAX > r1.value && r2.value == -1)
organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: Float exception");
else
- GetRegister(dst) = GetRegister(op1) / GetRegister(op2);
+ setInternalValue(dreg, r1.value / r2.value, r1, r2);
} else {
organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: dividing by 0");
return false;
@@ -1160,8 +1182,11 @@
const int dst = FindModifiedRegister(REG_BX);
const int op1 = FindModifiedRegister(dst);
const int op2 = FindModifiedNextRegister(op1);
- if (GetRegister(op2) != 0) {
- GetRegister(dst) = GetRegister(op1) % GetRegister(op2);
+ sInternalValue& dreg = m_threads[m_cur_thread].reg[dst];
+ sInternalValue& r1 = m_threads[m_cur_thread].reg[op1];
+ sInternalValue& r2 = m_threads[m_cur_thread].reg[op2];
+ if (r2.value != 0) {
+ setInternalValue(dreg, r1.value % r2.value, r1, r2);
} else {
organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "mod: modding by 0");
return false;
@@ -1175,7 +1200,10 @@
const int dst = FindModifiedRegister(REG_BX);
const int op1 = FindModifiedRegister(dst);
const int op2 = FindModifiedNextRegister(op1);
- GetRegister(dst) = ~(GetRegister(op1) & GetRegister(op2));
+ sInternalValue& dreg = m_threads[m_cur_thread].reg[dst];
+ sInternalValue& r1 = m_threads[m_cur_thread].reg[op1];
+ sInternalValue& r2 = m_threads[m_cur_thread].reg[op2];
+ setInternalValue(dreg, ~(r1.value & r2.value), r1, r2);
return true;
}
@@ -1187,8 +1215,9 @@
const int cur_size = m_memory.GetSize();
const int alloc_size = Min((int) (m_world->GetConfig().CHILD_SIZE_RANGE.Get() * cur_size),
MAX_CREATURE_SIZE - cur_size);
+ sInternalValue& reg = m_threads[m_cur_thread].reg[dst];
if (Allocate_Main(ctx, alloc_size)) {
- GetRegister(dst) = cur_size;
+ setInternalValue(reg, cur_size);
return true;
} else return false;
}
@@ -1197,27 +1226,48 @@
bool cHardwareExperimental::Inst_TaskIO(cAvidaContext& ctx)
{
const int reg_used = FindModifiedRegister(REG_BX);
+ sInternalValue& reg = m_threads[m_cur_thread].reg[reg_used];
// Do the "put" component
- const int value_out = GetRegister(reg_used);
- organism->DoOutput(ctx, value_out); // Check for tasks completed.
+ organism->DoOutput(ctx, reg.value); // Check for tasks completed.
+ m_last_output = m_cycle_count;
// Do the "get" component
const int value_in = organism->GetNextInput();
- GetRegister(reg_used) = value_in;
+ setInternalValue(reg, value_in, true);
organism->DoInput(value_in);
return true;
}
+bool cHardwareExperimental::Inst_TaskIOExpire(cAvidaContext& ctx)
+{
+ const int reg_used = FindModifiedRegister(REG_BX);
+ sInternalValue& reg = m_threads[m_cur_thread].reg[reg_used];
+
+ // Do the "put" component
+ if (reg.env_component && reg.oldest_component < m_last_output) return false;
+
+ organism->DoOutput(ctx, reg.value); // Check for tasks completed.
+ m_last_output = m_cycle_count;
+
+ // Do the "get" component
+ const int value_in = organism->GetNextInput();
+ setInternalValue(reg, value_in, true);
+ organism->DoInput(value_in);
+
+ return true;
+}
+
+
bool cHardwareExperimental::Inst_TaskInput(cAvidaContext& ctx)
{
const int reg_used = FindModifiedRegister(REG_BX);
// Do the "get" component
const int value_in = organism->GetNextInput();
- GetRegister(reg_used) = value_in;
+ setInternalValue(m_threads[m_cur_thread].reg[reg_used], value_in, true);
organism->DoInput(value_in);
return true;
@@ -1227,15 +1277,32 @@
bool cHardwareExperimental::Inst_TaskOutput(cAvidaContext& ctx)
{
const int reg_used = FindModifiedRegister(REG_BX);
+ sInternalValue& reg = m_threads[m_cur_thread].reg[reg_used];
// Do the "put" component
- const int value_out = GetRegister(reg_used);
- organism->DoOutput(ctx, value_out); // Check for tasks completed.
-
+ organism->DoOutput(ctx, reg.value); // Check for tasks completed.
+ m_last_output = m_cycle_count;
+
return true;
}
+bool cHardwareExperimental::Inst_TaskOutputExpire(cAvidaContext& ctx)
+{
+ const int reg_used = FindModifiedRegister(REG_BX);
+ sInternalValue& reg = m_threads[m_cur_thread].reg[reg_used];
+
+ // Do the "put" component
+ if (!reg.env_component || reg.oldest_component >= m_last_output) {
+ organism->DoOutput(ctx, reg.value); // Check for tasks completed.
+ m_last_output = m_cycle_count;
+ return true;
+ }
+
+ return false;
+}
+
+
bool cHardwareExperimental::Inst_MoveHead(cAvidaContext& ctx)
{
const int head_used = FindModifiedHead(nHardware::HEAD_IP);
@@ -1249,7 +1316,7 @@
{
const int head_used = FindModifiedHead(nHardware::HEAD_IP);
const int reg = FindModifiedRegister(REG_CX);
- GetHead(head_used).Jump(GetRegister(reg));
+ GetHead(head_used).Jump(m_threads[m_cur_thread].reg[reg].value);
if (head_used == nHardware::HEAD_IP) m_advance_ip = false;
return true;
}
@@ -1258,7 +1325,7 @@
{
const int head_used = FindModifiedHead(nHardware::HEAD_IP);
const int reg = FindModifiedRegister(REG_CX);
- GetRegister(reg) = GetHead(head_used).GetPosition();
+ setInternalValue(m_threads[m_cur_thread].reg[reg], GetHead(head_used).GetPosition());
return true;
}
@@ -1298,7 +1365,7 @@
} else {
read_inst = GetHead(head_id).GetInst().GetOp();
}
- GetRegister(dst) = read_inst;
+ setInternalValue(m_threads[m_cur_thread].reg[dst], read_inst);
ReadInst(read_inst);
GetHead(head_id).Advance();
@@ -1313,7 +1380,7 @@
active_head.Adjust();
- int value = GetRegister(src);
+ int value = m_threads[m_cur_thread].reg[src].value;
if (value < 0 || value >= m_inst_set->GetSize()) value = 0;
active_head.SetInst(cInstruction(value));
@@ -1360,8 +1427,8 @@
GetLabel().Rotate(1, NUM_NOPS);
cHeadCPU found_pos = FindLabelStart(true);
const int search_size = found_pos.GetPosition() - IP().GetPosition();
- GetRegister(REG_BX) = search_size;
- GetRegister(REG_CX) = GetLabel().GetSize();
+ setInternalValue(m_threads[m_cur_thread].reg[REG_BX], search_size);
+ setInternalValue(m_threads[m_cur_thread].reg[REG_CX], GetLabel().GetSize());
GetHead(nHardware::HEAD_FLOW).Set(found_pos);
GetHead(nHardware::HEAD_FLOW).Advance();
return true;
@@ -1522,7 +1589,7 @@
m_advance_ip = false;
int num = Numberate(IP().GetPosition(), +1, num_bits);
- GetRegister(reg_used) = num;
+ setInternalValue(m_threads[m_cur_thread].reg[reg_used], num);
return true;
}
@@ -1608,7 +1675,7 @@
// Set defaults for when no active promoter is found
m_promoter_index = -1;
IP().Set(0);
- GetRegister(promoter_reg_used) = 0;
+ setInternalValue(m_threads[m_cur_thread].reg[promoter_reg_used], 0);
break;
case 1: // Death to organisms that refuse to use promoters!
@@ -1627,7 +1694,7 @@
// Put its bit code in BX for the organism to have if option is set
if (m_world->GetConfig().PROMOTER_TO_REGISTER.Get())
- GetRegister(promoter_reg_used) = m_promoters[m_promoter_index].m_bit_code;
+ setInternalValue(m_threads[m_cur_thread].reg[promoter_reg_used], m_promoters[m_promoter_index].m_bit_code);
}
}
@@ -1684,7 +1751,9 @@
{
const int reg_used = FindModifiedRegister(REG_BX);
const int op1 = FindModifiedNextRegister(reg_used);
- GetRegister(reg_used) = (BitCount(GetRegister(op1)) >= CONSENSUS) ? 1 : 0;
+ sInternalValue& val = m_threads[m_cur_thread].reg[op1];
+
+ setInternalValue(m_threads[m_cur_thread].reg[reg_used], (BitCount(val.value) >= CONSENSUS) ? 1 : 0, val);
return true;
}
@@ -1693,7 +1762,9 @@
{
const int reg_used = FindModifiedRegister(REG_BX);
const int op1 = FindModifiedNextRegister(reg_used);
- GetRegister(reg_used) = (BitCount(GetRegister(op1) & MASK24) >= CONSENSUS24) ? 1 : 0;
+ sInternalValue& val = m_threads[m_cur_thread].reg[op1];
+
+ setInternalValue(m_threads[m_cur_thread].reg[reg_used], (BitCount(val.value & MASK24) >= CONSENSUS24) ? 1 : 0, val);
return true;
}
@@ -1701,7 +1772,7 @@
bool cHardwareExperimental::Inst_Execurate(cAvidaContext& ctx)
{
const int reg_used = FindModifiedRegister(REG_BX);
- GetRegister(reg_used) = m_threads[m_cur_thread].GetExecurate();
+ setInternalValue(m_threads[m_cur_thread].reg[reg_used], m_threads[m_cur_thread].GetExecurate());
return true;
}
@@ -1709,7 +1780,7 @@
bool cHardwareExperimental::Inst_Execurate24(cAvidaContext& ctx)
{
const int reg_used = FindModifiedRegister(REG_BX);
- GetRegister(reg_used) = (MASK24 & m_threads[m_cur_thread].GetExecurate());
+ setInternalValue(m_threads[m_cur_thread].reg[reg_used], (MASK24 & m_threads[m_cur_thread].GetExecurate()));
return true;
}
Modified: development/source/cpu/cHardwareExperimental.h
===================================================================
--- development/source/cpu/cHardwareExperimental.h 2008-05-30 14:23:37 UTC (rev 2601)
+++ development/source/cpu/cHardwareExperimental.h 2008-05-30 15:04:37 UTC (rev 2602)
@@ -26,8 +26,8 @@
#ifndef cHardwareExperimental_h
#define cHardwareExperimental_h
+#include <cstring>
#include <iomanip>
-#include <vector>
#ifndef defs_h
#include "defs.h"
@@ -44,9 +44,6 @@
#ifndef cCPUMemory_h
#include "cCPUMemory.h"
#endif
-#ifndef cCPUStack_h
-#include "cCPUStack.h"
-#endif
#ifndef cHardwareBase_h
#include "cHardwareBase.h"
#endif
@@ -67,7 +64,7 @@
* Each organism may have a cHardwareExperimental structure which keeps track of the
* current status of all the components of the simulated hardware.
*
- * @see cHardwareExperimental_Thread, cCPUStack, cCPUMemory, cInstSet
+ * @see cCPUMemory, cInstSet
**/
class cInjectGenotype;
@@ -88,7 +85,47 @@
enum tRegisters { REG_AX = 0, REG_BX, REG_CX, REG_DX };
static const int NUM_NOPS = NUM_REGISTERS;
+
// -------- Data Structures --------
+ struct sInternalValue
+ {
+ int value;
+
+ // Actual age of this value
+ unsigned int originated:15;
+ unsigned int from_env:1;
+
+ // Age of the oldest component used to create this value
+ unsigned int oldest_component:15;
+ unsigned int env_component:1;
+
+ inline void Clear() { value = 0; originated = 0; from_env = 0, oldest_component = 0; env_component = 0; }
+ inline sInternalValue& operator=(const sInternalValue& i);
+ };
+
+ class cLocalStack
+ {
+#define SIZE nHardware::STACK_SIZE
+ private:
+ sInternalValue m_stack[SIZE];
+ char m_sp;
+
+ public:
+ cLocalStack() : m_sp(0) { Clear(); }
+ inline cLocalStack(const cLocalStack& is) : m_sp(is.m_sp) { for (int i = 0; i < SIZE; i++) m_stack[i] = is.m_stack[i]; }
+ ~cLocalStack() { ; }
+
+ inline void operator=(const cLocalStack& is) { m_sp = is.m_sp; for (int i = 0; i < SIZE; i++) m_stack[i] = is.m_stack[i]; }
+
+ inline void Push(const sInternalValue& value) { if (--m_sp < 0) m_sp = SIZE - 1; m_stack[(int)m_sp] = value; }
+ inline sInternalValue Pop() { sInternalValue v = m_stack[(int)m_sp]; m_stack[(int)m_sp].Clear(); if (++m_sp == SIZE) m_sp = 0; return v; }
+ inline sInternalValue& Peek() { return m_stack[(int)m_sp]; }
+ inline const sInternalValue& Peek() const { return m_stack[(int)m_sp]; }
+ inline const sInternalValue& Get(int d = 0) const { assert(d > 0); int p = d + m_sp; return m_stack[(p >= SIZE) ? (p - SIZE) : p]; }
+ inline void Clear() { for (int i = 0; i < SIZE; i++) m_stack[i].Clear(); }
+#undef SIZE
+ };
+
struct cLocalThread
{
private:
@@ -98,9 +135,9 @@
public:
- int reg[NUM_REGISTERS];
+ sInternalValue reg[NUM_REGISTERS];
cHeadCPU heads[NUM_HEADS];
- cCPUStack stack;
+ cLocalStack stack;
unsigned char cur_stack; // 0 = local stack, 1 = global stack.
unsigned char cur_head;
@@ -108,12 +145,11 @@
cCodeLabel read_label;
cCodeLabel next_label;
- cLocalThread(cHardwareBase* in_hardware = NULL, int in_id = -1) { Reset(in_hardware, in_id); }
+ inline cLocalThread() { ; }
+ cLocalThread(cHardwareExperimental* in_hardware, int in_id = -1) { Reset(in_hardware, in_id); }
~cLocalThread() { ; }
- void operator=(const cLocalThread& in_thread);
-
- void Reset(cHardwareBase* in_hardware, int in_id);
+ void Reset(cHardwareExperimental* in_hardware, int in_id);
inline int GetID() const { return m_id; }
inline void SetID(int in_id) { m_id = in_id; }
@@ -135,11 +171,16 @@
const tMethod* m_functions;
cCPUMemory m_memory; // Memory...
- cCPUStack m_global_stack; // A stack that all threads share.
+ cLocalStack m_global_stack; // A stack that all threads share.
tArray<cLocalThread> m_threads;
int m_thread_id_chart;
int m_cur_thread;
+
+ struct {
+ unsigned int m_cycle_count:16;
+ unsigned int m_last_output:16;
+ };
// Flags...
struct {
@@ -181,9 +222,7 @@
bool SingleProcess_ExecuteInst(cAvidaContext& ctx, const cInstruction& cur_inst);
// -------- Stack Manipulation... --------
- inline void StackPush(int value);
- inline int StackPop();
- inline void StackFlip();
+ inline sInternalValue StackPop();
inline void StackClear();
inline void SwitchStack();
@@ -281,8 +320,7 @@
// -------- Register Manipulation --------
- int GetRegister(int reg_id) const { return m_threads[m_cur_thread].reg[reg_id]; }
- int& GetRegister(int reg_id) { return m_threads[m_cur_thread].reg[reg_id]; }
+ int GetRegister(int reg_id) const { return m_threads[m_cur_thread].reg[reg_id].value; }
int GetNumRegisters() const { return NUM_REGISTERS; }
@@ -312,6 +350,9 @@
// ---------- Utility Functions -----------
inline unsigned int BitCount(unsigned int value) const;
+ inline void setInternalValue(sInternalValue& dest, int value, bool from_env = false);
+ inline void setInternalValue(sInternalValue& dest, int value, const sInternalValue& src);
+ inline void setInternalValue(sInternalValue& dest, int value, const sInternalValue& op1, const sInternalValue& op2);
// ---------- Instruction Library -----------
@@ -347,8 +388,10 @@
// I/O and Sensory
bool Inst_TaskIO(cAvidaContext& ctx);
+ bool Inst_TaskIOExpire(cAvidaContext& ctx);
bool Inst_TaskInput(cAvidaContext& ctx);
bool Inst_TaskOutput(cAvidaContext& ctx);
+ bool Inst_TaskOutputExpire(cAvidaContext& ctx);
// Head-based instructions...
bool Inst_HeadAlloc(cAvidaContext& ctx);
@@ -399,6 +442,16 @@
};
+inline cHardwareExperimental::sInternalValue& cHardwareExperimental::sInternalValue::operator=(const sInternalValue& i)
+{
+ value = i.value;
+ originated = i.originated;
+ from_env = i.from_env;
+ oldest_component = i.oldest_component;
+ env_component = i.env_component;
+ return *this;
+}
+
inline bool cHardwareExperimental::ThreadSelect(const int thread_num)
{
if (thread_num >= 0 && thread_num < m_threads.GetSize()) {
@@ -421,40 +474,19 @@
else m_cur_thread--;
}
-inline void cHardwareExperimental::StackPush(int value)
+inline cHardwareExperimental::sInternalValue cHardwareExperimental::StackPop()
{
if (m_threads[m_cur_thread].cur_stack == 0) {
- m_threads[m_cur_thread].stack.Push(value);
+ return m_threads[m_cur_thread].stack.Pop();
} else {
- m_global_stack.Push(value);
+ return m_global_stack.Pop();
}
}
-inline int cHardwareExperimental::StackPop()
-{
- int pop_value;
- if (m_threads[m_cur_thread].cur_stack == 0) {
- pop_value = m_threads[m_cur_thread].stack.Pop();
- } else {
- pop_value = m_global_stack.Pop();
- }
-
- return pop_value;
-}
-
-inline void cHardwareExperimental::StackFlip()
-{
- if (m_threads[m_cur_thread].cur_stack == 0) {
- m_threads[m_cur_thread].stack.Flip();
- } else {
- m_global_stack.Flip();
- }
-}
-
inline int cHardwareExperimental::GetStack(int depth, int stack_id, int in_thread) const
{
- int value = 0;
+ sInternalValue value;
if(in_thread >= m_threads.GetSize() || in_thread < 0) in_thread = m_cur_thread;
@@ -463,7 +495,7 @@
if (stack_id == 0) value = m_threads[in_thread].stack.Get(depth);
else if (stack_id == 1) value = m_global_stack.Get(depth);
- return value;
+ return value.value;
}
inline void cHardwareExperimental::StackClear()
@@ -482,4 +514,34 @@
}
+inline void cHardwareExperimental::setInternalValue(sInternalValue& dest, int value, bool from_env)
+{
+ dest.value = value;
+ dest.from_env = from_env;
+ dest.originated = m_cycle_count;
+ dest.oldest_component = m_cycle_count;
+ dest.env_component = from_env;
+}
+
+
+inline void cHardwareExperimental::setInternalValue(sInternalValue& dest, int value, const sInternalValue& src)
+{
+ dest.value = value;
+ dest.from_env = false;
+ dest.originated = m_cycle_count;
+ dest.oldest_component = src.oldest_component;
+ dest.env_component = src.from_env;
+}
+
+
+inline void cHardwareExperimental::setInternalValue(sInternalValue& dest, int value, const sInternalValue& op1, const sInternalValue& op2)
+{
+ dest.value = value;
+ dest.from_env = false;
+ dest.originated = m_cycle_count;
+ dest.oldest_component = (op1.oldest_component < op2.oldest_component) ? op1.oldest_component : op2.oldest_component;
+ dest.env_component = (op1.env_component || op2.env_component);
+}
+
+
#endif
More information about the Avida-cvs
mailing list