[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