[Avida-SVN] r2289 - development/source/cpu
brysonda at myxo.css.msu.edu
brysonda at myxo.css.msu.edu
Tue Jan 29 11:51:00 PST 2008
Author: brysonda
Date: 2008-01-29 14:51:00 -0500 (Tue, 29 Jan 2008)
New Revision: 2289
Modified:
development/source/cpu/cHardwareExperimental.cc
development/source/cpu/cHardwareExperimental.h
Log:
Implement various bit consensus variants of goto and if instructions. Added reduced side-effect, label acting variation of h-search.
Modified: development/source/cpu/cHardwareExperimental.cc
===================================================================
--- development/source/cpu/cHardwareExperimental.cc 2008-01-29 18:53:23 UTC (rev 2288)
+++ development/source/cpu/cHardwareExperimental.cc 2008-01-29 19:51:00 UTC (rev 2289)
@@ -51,6 +51,19 @@
using namespace std;
+static const unsigned int CONSENSUS = (sizeof(int) * 8) / 2;
+static const unsigned int CONSENSUS24 = 12;
+static const unsigned int MASK24 = 0xFFFFFF;
+
+inline unsigned int cHardwareExperimental::BitCount(unsigned int value) const
+{
+ const unsigned int w = value - ((value >> 1) & 0x55555555);
+ const unsigned int x = (w & 0x33333333) + ((w >> 2) & 0x33333333);
+ const unsigned int bit_count = ((x + (x >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
+ return bit_count;
+}
+
+
tInstLib<cHardwareExperimental::tMethod>* cHardwareExperimental::s_inst_slib = cHardwareExperimental::initInstLib();
tInstLib<cHardwareExperimental::tMethod>* cHardwareExperimental::initInstLib(void)
@@ -82,11 +95,18 @@
tInstLibEntry<tMethod>("NULL", &cHardwareExperimental::Inst_Nop, 0, "True no-operation instruction: does nothing"),
tInstLibEntry<tMethod>("nop-X", &cHardwareExperimental::Inst_Nop, 0, "True no-operation instruction: does nothing"),
+
+ // Standard Conditionals
tInstLibEntry<tMethod>("if-n-equ", &cHardwareExperimental::Inst_IfNEqu, nInstFlag::DEFAULT, "Execute next instruction if ?BX?!=?CX?, else skip it"),
tInstLibEntry<tMethod>("if-less", &cHardwareExperimental::Inst_IfLess, nInstFlag::DEFAULT, "Execute next instruction if ?BX? < ?CX?, else skip it"),
-
- tInstLibEntry<tMethod>("label", &cHardwareExperimental::Inst_Label, (nInstFlag::DEFAULT | nInstFlag::LABEL)),
-
+
+ tInstLibEntry<tMethod>("if-cons", &cHardwareExperimental::Inst_IfConsensus, 0, "Execute next instruction if ?BX? in consensus, else skip it"),
+ tInstLibEntry<tMethod>("if-cons-24", &cHardwareExperimental::Inst_IfConsensus24, 0, "Execute next instruction if ?BX[0:23]? in consensus , else skip it"),
+ tInstLibEntry<tMethod>("if-less-cons", &cHardwareExperimental::Inst_IfLessConsensus, 0, "Execute next instruction if Count(?BX?) < Count(?CX?), else skip it"),
+ tInstLibEntry<tMethod>("if-less-cons-24", &cHardwareExperimental::Inst_IfLessConsensus24, 0, "Execute next instruction if Count(?BX[0:23]?) < Count(?CX[0:23]?), else skip it"),
+
+
+ // Core ALU Operations
tInstLibEntry<tMethod>("pop", &cHardwareExperimental::Inst_Pop, nInstFlag::DEFAULT, "Remove top number from stack and place into ?BX?"),
tInstLibEntry<tMethod>("push", &cHardwareExperimental::Inst_Push, nInstFlag::DEFAULT, "Copy number from ?BX? and place it into the stack"),
tInstLibEntry<tMethod>("swap-stk", &cHardwareExperimental::Inst_SwitchStack, nInstFlag::DEFAULT, "Toggle which stack is currently being used"),
@@ -99,38 +119,45 @@
tInstLibEntry<tMethod>("add", &cHardwareExperimental::Inst_Add, nInstFlag::DEFAULT, "Add BX to CX and place the result in ?BX?"),
tInstLibEntry<tMethod>("sub", &cHardwareExperimental::Inst_Sub, nInstFlag::DEFAULT, "Subtract CX from BX and place the result in ?BX?"),
+ 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, "Output ?BX?, and input new number back into ?BX?"),
+
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?"),
tInstLibEntry<tMethod>("mod", &cHardwareExperimental::Inst_Mod),
- 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, "Output ?BX?, and input new number back into ?BX?"),
- // Head-based instructions
- tInstLibEntry<tMethod>("h-alloc", &cHardwareExperimental::Inst_HeadAlloc, nInstFlag::DEFAULT, "Allocate maximum allowed space"),
- tInstLibEntry<tMethod>("h-divide", &cHardwareExperimental::Inst_HeadDivide, nInstFlag::DEFAULT, "Divide code between read and write heads."),
- tInstLibEntry<tMethod>("h-read", &cHardwareExperimental::Inst_HeadRead),
- tInstLibEntry<tMethod>("h-write", &cHardwareExperimental::Inst_HeadWrite),
- tInstLibEntry<tMethod>("h-copy", &cHardwareExperimental::Inst_HeadCopy, nInstFlag::DEFAULT, "Copy from read-head to write-head; advance both"),
+ // Flow Control Instructions
+ tInstLibEntry<tMethod>("label", &cHardwareExperimental::Inst_Label, (nInstFlag::DEFAULT | nInstFlag::LABEL)),
+
tInstLibEntry<tMethod>("h-search", &cHardwareExperimental::Inst_HeadSearch, nInstFlag::DEFAULT, "Find complement template and make with flow head"),
tInstLibEntry<tMethod>("mov-head", &cHardwareExperimental::Inst_MoveHead, nInstFlag::DEFAULT, "Move head ?IP? to the flow head"),
+
tInstLibEntry<tMethod>("jmp-head", &cHardwareExperimental::Inst_JumpHead, nInstFlag::DEFAULT, "Move head ?Flow? by amount in ?CX? register"),
tInstLibEntry<tMethod>("get-head", &cHardwareExperimental::Inst_GetHead, nInstFlag::DEFAULT, "Copy the position of the ?IP? head into ?CX?"),
+
+ tInstLibEntry<tMethod>("h-search-lbl", &cHardwareExperimental::Inst_HeadSearchLabel, nInstFlag::LABEL, "Find complement template and make with flow head"),
+
+
+ // Replication Instructions
+ tInstLibEntry<tMethod>("h-alloc", &cHardwareExperimental::Inst_HeadAlloc, nInstFlag::DEFAULT, "Allocate maximum allowed space"),
+ tInstLibEntry<tMethod>("h-divide", &cHardwareExperimental::Inst_HeadDivide, nInstFlag::DEFAULT, "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>("if-label", &cHardwareExperimental::Inst_IfLabel, nInstFlag::DEFAULT, "Execute next if we copied complement of attached label"),
- tInstLibEntry<tMethod>("set-flow", &cHardwareExperimental::Inst_SetFlow, nInstFlag::DEFAULT, "Set flow-head to position in ?CX?"),
- tInstLibEntry<tMethod>("goto", &cHardwareExperimental::Inst_Goto, 0, "Move IP to labeled position matching the label that follows"),
+ tInstLibEntry<tMethod>("h-read", &cHardwareExperimental::Inst_HeadRead, 0, "Read from the read-head, place into ?BX?, advance read-head"),
+ tInstLibEntry<tMethod>("h-write", &cHardwareExperimental::Inst_HeadWrite, 0, "Write from ?BX? to the write head, advance write-head"),
+
+ tInstLibEntry<tMethod>("repro", &cHardwareExperimental::Inst_Repro, 0, "Instantly reproduces the organism"),
+
+
// Goto Variants
- tInstLibEntry<tMethod>("goto-if=0", &cHardwareExperimental::Inst_GotoIf0),
- tInstLibEntry<tMethod>("goto-if!=0", &cHardwareExperimental::Inst_GotoIfNot0),
+ tInstLibEntry<tMethod>("goto", &cHardwareExperimental::Inst_Goto, 0, "Move IP to labeled position matching the label that follows"),
+ tInstLibEntry<tMethod>("goto-if-cons", &cHardwareExperimental::Inst_GotoConsensus, 0, "Move IP to the labeled position if BX consensus"),
+ tInstLibEntry<tMethod>("goto-if-cons-24", &cHardwareExperimental::Inst_GotoConsensus24, 0, "Move IP to the labeled position if BX consensus"),
- // Throw-Catch Model
- tInstLibEntry<tMethod>("throw", &cHardwareExperimental::Inst_Throw),
- tInstLibEntry<tMethod>("throwif=0", &cHardwareExperimental::Inst_ThrowIf0),
- tInstLibEntry<tMethod>("throwif!=0", &cHardwareExperimental::Inst_ThrowIfNot0),
- tInstLibEntry<tMethod>("catch", &cHardwareExperimental::Inst_Label, nInstFlag::LABEL),
-
// Promoter Model
tInstLibEntry<tMethod>("promoter", &cHardwareExperimental::Inst_Promoter, nInstFlag::PROMOTER),
tInstLibEntry<tMethod>("terminate", &cHardwareExperimental::Inst_Terminate),
@@ -145,8 +172,9 @@
tInstLibEntry<tMethod>("execurate-24", &cHardwareExperimental::Inst_Execurate24),
- tInstLibEntry<tMethod>("repro", &cHardwareExperimental::Inst_Repro)
-};
+ // DEPRECATED Instructions
+ tInstLibEntry<tMethod>("set-flow", &cHardwareExperimental::Inst_SetFlow, 0, "Set flow-head to position in ?CX?")
+ };
const int n_size = sizeof(s_n_array)/sizeof(cNOPEntry);
@@ -966,6 +994,36 @@
return true;
}
+bool cHardwareExperimental::Inst_IfConsensus(cAvidaContext& ctx)
+{
+ const int op1 = FindModifiedRegister(REG_BX);
+ if (BitCount(GetRegister(op1)) < CONSENSUS) IP().Advance();
+ return true;
+}
+
+bool cHardwareExperimental::Inst_IfConsensus24(cAvidaContext& ctx)
+{
+ const int op1 = FindModifiedRegister(REG_BX);
+ if (BitCount(GetRegister(op1) & MASK24) < CONSENSUS24) IP().Advance();
+ return true;
+}
+
+bool cHardwareExperimental::Inst_IfLessConsensus(cAvidaContext& ctx)
+{
+ const int op1 = FindModifiedRegister(REG_BX);
+ const int op2 = FindModifiedNextRegister(op1);
+ if (BitCount(GetRegister(op1)) >= BitCount(GetRegister(op2))) IP().Advance();
+ return true;
+}
+
+bool cHardwareExperimental::Inst_IfLessConsensus24(cAvidaContext& ctx)
+{
+ const int op1 = FindModifiedRegister(REG_BX);
+ const int op2 = FindModifiedNextRegister(op1);
+ if (BitCount(GetRegister(op1) & MASK24) >= BitCount(GetRegister(op2) & MASK24)) IP().Advance();
+ return true;
+}
+
bool cHardwareExperimental::Inst_Label(cAvidaContext& ctx)
{
ReadLabel();
@@ -1262,6 +1320,16 @@
return true;
}
+bool cHardwareExperimental::Inst_HeadSearchLabel(cAvidaContext& ctx)
+{
+ ReadLabel();
+ GetLabel().Rotate(1, NUM_NOPS);
+ cHeadCPU found_pos = FindLabelStart(true);
+ 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);
@@ -1278,9 +1346,9 @@
return true;
}
-bool cHardwareExperimental::Inst_GotoIfNot0(cAvidaContext& ctx)
+bool cHardwareExperimental::Inst_GotoConsensus(cAvidaContext& ctx)
{
- if (GetRegister(REG_BX) == 0) return true;
+ if (BitCount(GetRegister(REG_BX)) < CONSENSUS) return true;
ReadLabel();
GetLabel().Rotate(1, NUM_NOPS);
@@ -1289,9 +1357,9 @@
return true;
}
-bool cHardwareExperimental::Inst_GotoIf0(cAvidaContext& ctx)
+bool cHardwareExperimental::Inst_GotoConsensus24(cAvidaContext& ctx)
{
- if (GetRegister(REG_BX) != 0) return true;
+ if (BitCount(GetRegister(REG_BX) & MASK24) < CONSENSUS24) return true;
ReadLabel();
GetLabel().Rotate(1, NUM_NOPS);
@@ -1301,37 +1369,8 @@
}
-bool cHardwareExperimental::Inst_Throw(cAvidaContext& ctx)
-{
- ReadLabel();
- cHeadCPU found_pos = FindLabelForward(true);
- IP().Set(found_pos);
- return true;
-}
-bool cHardwareExperimental::Inst_ThrowIfNot0(cAvidaContext& ctx)
-{
- if (GetRegister(REG_BX) == 0) return true;
-
- ReadLabel();
- cHeadCPU found_pos = FindLabelForward(true);
- IP().Set(found_pos);
- return true;
-}
-
-bool cHardwareExperimental::Inst_ThrowIf0(cAvidaContext& ctx)
-{
- if (GetRegister(REG_BX) != 0) return true;
-
- ReadLabel();
- cHeadCPU found_pos = FindLabelForward(true);
- IP().Set(found_pos);
- return true;
-}
-
-
-
// -------- Promoter Model --------
bool cHardwareExperimental::Inst_Promoter(cAvidaContext& ctx)
@@ -1580,33 +1619,18 @@
bool cHardwareExperimental::Inst_BitConsensus(cAvidaContext& ctx)
{
- return BitConsensus(ctx, sizeof(int) * 8);
+ const int reg_used = FindModifiedRegister(REG_BX);
+ const int op1 = FindModifiedNextRegister(reg_used);
+ GetRegister(reg_used) = (BitCount(GetRegister(op1)) >= CONSENSUS) ? 1 : 0;
+ return true;
}
// Looks at only the lower 24 bits
bool cHardwareExperimental::Inst_BitConsensus24(cAvidaContext& ctx)
{
- return BitConsensus(ctx, 24);
-}
-
-bool cHardwareExperimental::BitConsensus(cAvidaContext& ctx, const unsigned int num_bits)
-{
- assert(num_bits <= sizeof(int) * 8);
-
const int reg_used = FindModifiedRegister(REG_BX);
const int op1 = FindModifiedNextRegister(reg_used);
-
- int reg_val = GetRegister(op1);
- unsigned int bits_on = 0;
-
- // @DMB - probably should use fast bit counting here
-
- for (unsigned int i = 0; i < num_bits; i++) {
- bits_on += (reg_val & 1);
- reg_val >>= 1;
- }
-
- GetRegister(reg_used) = ( bits_on >= (sizeof(int) * 8)/2 ) ? 1 : 0;
+ GetRegister(reg_used) = (BitCount(GetRegister(op1) & MASK24) >= CONSENSUS24) ? 1 : 0;
return true;
}
@@ -1622,7 +1646,7 @@
bool cHardwareExperimental::Inst_Execurate24(cAvidaContext& ctx)
{
const int reg_used = FindModifiedRegister(REG_BX);
- GetRegister(reg_used) = (0xFFFFFF & m_threads[m_cur_thread].GetExecurate());
+ GetRegister(reg_used) = (MASK24 & m_threads[m_cur_thread].GetExecurate());
return true;
}
Modified: development/source/cpu/cHardwareExperimental.h
===================================================================
--- development/source/cpu/cHardwareExperimental.h 2008-01-29 18:53:23 UTC (rev 2288)
+++ development/source/cpu/cHardwareExperimental.h 2008-01-29 19:51:00 UTC (rev 2289)
@@ -300,11 +300,20 @@
bool GetMalActive() const { return m_mal_active; }
private:
+
+ // ---------- Utility Functions -----------
+ inline unsigned int BitCount(unsigned int value) const;
+
+
// ---------- Instruction Library -----------
// Flow Control
bool Inst_IfNEqu(cAvidaContext& ctx);
bool Inst_IfLess(cAvidaContext& ctx);
+ bool Inst_IfConsensus(cAvidaContext& ctx);
+ bool Inst_IfConsensus24(cAvidaContext& ctx);
+ bool Inst_IfLessConsensus(cAvidaContext& ctx);
+ bool Inst_IfLessConsensus24(cAvidaContext& ctx);
bool Inst_Label(cAvidaContext& ctx);
// Stack and Register Operations
@@ -341,17 +350,14 @@
bool Inst_HeadWrite(cAvidaContext& ctx);
bool Inst_HeadCopy(cAvidaContext& ctx);
bool Inst_HeadSearch(cAvidaContext& ctx);
+ bool Inst_HeadSearchLabel(cAvidaContext& ctx);
bool Inst_SetFlow(cAvidaContext& ctx);
- bool Inst_Goto(cAvidaContext& ctx);
// Goto Variants
- bool Inst_GotoIfNot0(cAvidaContext& ctx);
- bool Inst_GotoIf0(cAvidaContext& ctx);
+ bool Inst_Goto(cAvidaContext& ctx);
+ bool Inst_GotoConsensus(cAvidaContext& ctx);
+ bool Inst_GotoConsensus24(cAvidaContext& ctx);
- // Throw-Catch Model
- bool Inst_Throw(cAvidaContext& ctx);
- bool Inst_ThrowIf0(cAvidaContext& ctx);
- bool Inst_ThrowIfNot0(cAvidaContext& ctx);
// Promoter Model
bool Inst_Promoter(cAvidaContext& ctx);
@@ -372,7 +378,6 @@
// Bit consensus functions
bool Inst_BitConsensus(cAvidaContext& ctx);
bool Inst_BitConsensus24(cAvidaContext& ctx);
- bool BitConsensus(cAvidaContext& ctx, const unsigned int num_bits);
bool Inst_Execurate(cAvidaContext& ctx);
bool Inst_Execurate24(cAvidaContext& ctx);
@@ -464,4 +469,5 @@
if (m_threads[m_cur_thread].cur_stack > 1) m_threads[m_cur_thread].cur_stack = 0;
}
+
#endif
More information about the Avida-cvs
mailing list