[Avida-SVN] r3431 - development/source/cpu

brysonda at myxo.css.msu.edu brysonda at myxo.css.msu.edu
Wed Sep 30 06:46:33 PDT 2009


Author: brysonda
Date: 2009-09-30 09:46:32 -0400 (Wed, 30 Sep 2009)
New Revision: 3431

Modified:
   development/source/cpu/cHardwareExperimental.cc
   development/source/cpu/cHardwareExperimental.h
Log:
Implement concurrent support for un'label'd nop sequence instructions in the experimental hardware.

Modified: development/source/cpu/cHardwareExperimental.cc
===================================================================
--- development/source/cpu/cHardwareExperimental.cc	2009-09-29 20:26:21 UTC (rev 3430)
+++ development/source/cpu/cHardwareExperimental.cc	2009-09-30 13:46:32 UTC (rev 3431)
@@ -141,6 +141,8 @@
     tInstLibEntry<tMethod>("h-search-direct", &cHardwareExperimental::Inst_HeadSearchDirect, nInstFlag::DEFAULT, "Find direct template and move the flow head"),
     tInstLibEntry<tMethod>("h-search-lbl", &cHardwareExperimental::Inst_HeadSearchLabel, nInstFlag::LABEL, "Find complement template and make with flow head"),
     tInstLibEntry<tMethod>("h-search-direct-lbl", &cHardwareExperimental::Inst_HeadSearchDirectLabel, nInstFlag::LABEL, "Find direct template and move the flow head"),
+    tInstLibEntry<tMethod>("h-search-seq", &cHardwareExperimental::Inst_HeadSearchSequence, nInstFlag::DEFAULT, "Find complement template and make with flow head"),
+    tInstLibEntry<tMethod>("h-search-direct-seq", &cHardwareExperimental::Inst_HeadSearchDirectSequence, nInstFlag::DEFAULT, "Find direct template and move the flow head"),
 
     tInstLibEntry<tMethod>("mov-head", &cHardwareExperimental::Inst_MoveHead, nInstFlag::DEFAULT, "Move head ?IP? to the flow head"),
     
@@ -154,6 +156,7 @@
     tInstLibEntry<tMethod>("h-divide", &cHardwareExperimental::Inst_HeadDivide, (nInstFlag::DEFAULT | nInstFlag::STALL), "Divide code between read and write heads."),
     tInstLibEntry<tMethod>("h-divide-sex", &cHardwareExperimental::Inst_HeadDivideSex, (nInstFlag::DEFAULT | nInstFlag::STALL), "Divide code between read and write heads."),
     tInstLibEntry<tMethod>("h-copy", &cHardwareExperimental::Inst_HeadCopy, nInstFlag::DEFAULT, "Copy from read-head to write-head; advance both"),
+    tInstLibEntry<tMethod>("h-copy-nolabel", &cHardwareExperimental::Inst_HeadCopy_NoLabel, nInstFlag::DEFAULT, "Copy from read-head to write-head; advance both"),
     tInstLibEntry<tMethod>("if-label", &cHardwareExperimental::Inst_IfLabel, nInstFlag::DEFAULT, "Execute next if we copied complement of attached label"),
     tInstLibEntry<tMethod>("if-label-direct", &cHardwareExperimental::Inst_IfLabelDirect, nInstFlag::DEFAULT, "Execute next if we copied direct match of the attached label"),
 
@@ -589,7 +592,51 @@
   return ip;
 }
 
+cHeadCPU cHardwareExperimental::FindNopSequenceStart(bool mark_executed)
+{
+  cHeadCPU& ip = getIP();
+  const cCodeLabel& search_label = GetLabel();
+  
+  // Make sure the label is of size > 0.
+  if (search_label.GetSize() == 0) return ip;
+  
+  cCPUMemory& memory = m_memory;
+  int pos = 0;
+  
+  while (pos < memory.GetSize()) {
+    if (m_inst_set->IsNop(memory[pos])) { // start of sequence found
+      
+      // Check for direct matched label pattern, can be substring of 'label'ed target
+      // - must match all NOPs in search_label
+      // - extra NOPs in 'label'ed target are ignored
+      int size_matched = 0;
+      while (size_matched < search_label.GetSize() && pos < memory.GetSize()) {
+        if (!m_inst_set->IsNop(memory[pos]) || search_label[size_matched] != m_inst_set->GetNopMod(memory[pos])) break;
+        size_matched++;
+        pos++;
+      }
+      
+      // Check that the label matches and has examined the full sequence of nops following the 'label' instruction
+      if (size_matched == search_label.GetSize()) {
+        // Return Head pointed at last NOP of label sequence
+        if (mark_executed) {
+          const int start = pos - size_matched;
+          const int max = m_world->GetConfig().MAX_LABEL_EXE_SIZE.Get();
+          for (int i = 0; i < size_matched && i < max; i++) memory.SetFlagExecuted(start + i);
+        }
+        return cHeadCPU(this, pos - 1, ip.GetMemSpace());
+      }
+      
+      continue; 
+    }
+    pos++;
+  }
+  
+  // Return start point if not found
+  return ip;
+}
 
+
 cHeadCPU cHardwareExperimental::FindLabelForward(bool mark_executed)
 {
   cHeadCPU& ip = getIP();
@@ -624,7 +671,7 @@
         if (mark_executed) {
           pos.Set(label_start);
           const int max = m_world->GetConfig().MAX_LABEL_EXE_SIZE.Get() + 1; // Max label + 1 for the label instruction itself
-          for (int i = 0; i < max; i++) pos.SetFlagExecuted();          
+          for (int i = 0; i < size_matched && i < max; i++, pos++) pos.SetFlagExecuted();
         }
 
         // Return Head pointed at last NOP of label sequence
@@ -640,7 +687,56 @@
   return ip;
 }
 
+cHeadCPU cHardwareExperimental::FindNopSequenceForward(bool mark_executed)
+{
+  cHeadCPU& ip = getIP();
+  const cCodeLabel& search_label = GetLabel();
+  
+  // Make sure the label is of size > 0.
+  if (search_label.GetSize() == 0) return ip;
+  
+  cHeadCPU pos(ip);
+  pos++;
+  
+  while (pos.GetPosition() != ip.GetPosition()) {
+    if (m_inst_set->IsNop(pos.GetInst())) { // starting label found
+      const int label_start = pos.GetPosition();
+      
+      // Check for direct matched nop sequence, can be substring of target
+      // - must match all NOPs in search_label
+      // - extra NOPs in target are ignored
+      int size_matched = 0;
+      while (size_matched < search_label.GetSize() && pos.GetPosition() != ip.GetPosition()) {
+        if (!m_inst_set->IsNop(pos.GetInst()) || search_label[size_matched] != m_inst_set->GetNopMod(pos.GetInst())) break;
+        size_matched++;
+        pos++;
+      }
+      
+      // Check that the label matches and has examined the full sequence of nops
+      if (size_matched == search_label.GetSize()) {
+        pos--;
+        const int found_pos = pos.GetPosition();
+        
+        if (mark_executed) {
+          pos.Set(label_start);
+          const int max = m_world->GetConfig().MAX_LABEL_EXE_SIZE.Get();
+          for (int i = 0; i < size_matched && i < max; i++, pos++) pos.SetFlagExecuted();
+        }
+        
+        // Return Head pointed at last NOP of label sequence
+        return cHeadCPU(this, found_pos, ip.GetMemSpace());
+      }
+      
+      continue; 
+    }
+    pos++;
+  }
+  
+  // Return start point if not found
+  return ip;
+}
 
+
 bool cHardwareExperimental::InjectHost(const cCodeLabel & in_label, const cGenome & injection)
 {
   // Make sure the genome will be below max size after injection.
@@ -695,7 +791,20 @@
   }
 }
 
+void cHardwareExperimental::ReadInst_NoLabel(const int in_inst)
+{
+  if (!ReadingLabel() && m_inst_set->IsNop(cInstruction(in_inst))) {
+    GetReadLabel().AddNop(in_inst);
+    ReadingLabel() = true;
+  } else if (ReadingLabel() && m_inst_set->IsNop(cInstruction(in_inst))) {
+    GetReadLabel().AddNop(in_inst);
+  } else {
+    GetReadLabel().Clear();
+    ReadingLabel() = false;
+  }
+}
 
+
 void cHardwareExperimental::AdjustHeads()
 {
   for (int i = 0; i < m_threads.GetSize(); i++) {
@@ -1472,6 +1581,42 @@
   return true;
 }
 
+bool cHardwareExperimental::Inst_HeadCopy_NoLabel(cAvidaContext& ctx)
+{
+  // For the moment, this cannot be nop-modified.
+  cHeadCPU& read_head = getHead(nHardware::HEAD_READ);
+  cHeadCPU& write_head = getHead(nHardware::HEAD_WRITE);
+  
+  read_head.Adjust();
+  write_head.Adjust();
+  
+  // Do mutations.
+  cInstruction read_inst = read_head.GetInst();
+  ReadInst_NoLabel(read_inst.GetOp());
+  if (m_organism->TestCopyMut(ctx)) {
+    read_inst = m_inst_set->GetRandomInst(ctx);
+    write_head.SetFlagMutated();
+    write_head.SetFlagCopyMut();
+  }
+  
+  write_head.SetInst(read_inst);
+  write_head.SetFlagCopied();  // Set the copied flag...
+  
+  if (m_organism->TestCopyIns(ctx)) write_head.InsertInst(m_inst_set->GetRandomInst(ctx));
+  if (m_organism->TestCopyDel(ctx)) write_head.RemoveInst();
+  if (m_organism->TestCopyUniform(ctx)) doUniformCopyMutation(ctx, write_head);
+  if (m_organism->TestCopySlip(ctx)) {
+    if (m_slip_read_head) {
+      read_head.Set(ctx.GetRandom().GetInt(m_memory.GetSize()));
+    } else 
+      doSlipMutation(ctx, m_memory, write_head.GetPosition());
+  }
+  
+  read_head.Advance();
+  write_head.Advance();
+  return true;
+}
+
 bool cHardwareExperimental::Inst_HeadSearch(cAvidaContext& ctx)
 {
   ReadLabel();
@@ -1516,6 +1661,32 @@
   return true;
 }
 
+bool cHardwareExperimental::Inst_HeadSearchSequence(cAvidaContext& ctx)
+{
+  ReadLabel();
+  GetLabel().Rotate(1, NUM_NOPS);
+  cHeadCPU found_pos = FindNopSequenceStart(true);
+  const int search_size = found_pos.GetPosition() - getIP().GetPosition();
+  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;
+}
+
+bool cHardwareExperimental::Inst_HeadSearchDirectSequence(cAvidaContext& ctx)
+{
+  ReadLabel();
+  cHeadCPU found_pos = FindNopSequenceStart(true);
+  const int search_size = found_pos.GetPosition() - getIP().GetPosition();
+  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;
+}
+
+
 bool cHardwareExperimental::Inst_SetFlow(cAvidaContext& ctx)
 {
   const int reg_used = FindModifiedRegister(REG_CX);

Modified: development/source/cpu/cHardwareExperimental.h
===================================================================
--- development/source/cpu/cHardwareExperimental.h	2009-09-29 20:26:21 UTC (rev 3430)
+++ development/source/cpu/cHardwareExperimental.h	2009-09-30 13:46:32 UTC (rev 3431)
@@ -329,6 +329,8 @@
   void ReadLabel(int max_size=nHardware::MAX_LABEL_SIZE);
   cHeadCPU FindLabelStart(bool mark_executed);
   cHeadCPU FindLabelForward(bool mark_executed);
+  cHeadCPU FindNopSequenceStart(bool mark_executed);
+  cHeadCPU FindNopSequenceForward(bool mark_executed);
   bool& ReadingLabel() { return m_threads[m_cur_thread].reading; }
   const cCodeLabel& GetReadLabel() const { return m_threads[m_cur_thread].read_label; }
   cCodeLabel& GetReadLabel() { return m_threads[m_cur_thread].read_label; }
@@ -379,6 +381,7 @@
   inline void setInternalValue(sInternalValue& dest, int value, const sInternalValue& op1, const sInternalValue& op2);  
 
   void ReadInst(const int in_inst);
+  void ReadInst_NoLabel(const int in_inst);
   
   
   // ---------- Promoter Helper Functions -----------
@@ -440,10 +443,13 @@
   bool Inst_HeadRead(cAvidaContext& ctx);
   bool Inst_HeadWrite(cAvidaContext& ctx);
   bool Inst_HeadCopy(cAvidaContext& ctx);
+  bool Inst_HeadCopy_NoLabel(cAvidaContext& ctx);
   bool Inst_HeadSearch(cAvidaContext& ctx);
   bool Inst_HeadSearchLabel(cAvidaContext& ctx);
   bool Inst_HeadSearchDirect(cAvidaContext& ctx);
   bool Inst_HeadSearchDirectLabel(cAvidaContext& ctx);
+  bool Inst_HeadSearchSequence(cAvidaContext& ctx);
+  bool Inst_HeadSearchDirectSequence(cAvidaContext& ctx);
   bool Inst_SetFlow(cAvidaContext& ctx);
   
   // Goto Variants




More information about the Avida-cvs mailing list