1 /*
2 *  cHardwareCPU.h
3 *  Avida
4 *
5 *  Called "hardware_cpu.hh" prior to 11/17/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 cHardwareCPU_h
24 #define cHardwareCPU_h
25 
26 #include "avida/Avida.h"
27 
28 #include "cCodeLabel.h"
29 #include "cHeadCPU.h"
30 #include "cCPUMemory.h"
31 #include "cCPUStack.h"
32 #include "cHardwareBase.h"
33 #include "cString.h"
34 #include "cStats.h"
35 #include "tArray.h"
36 #include "tInstLib.h"
37 
38 #include "nHardware.h"
39 
40 #include <iomanip>
41 #include <vector>
42 
43 /**
44 * Each organism may have a cHardwareCPU structure which keeps track of the
45 * current status of all the components of the simulated hardware.
46 *
47 * @see cHardwareCPU_Thread, cCPUStack, cCPUMemory, cInstSet
48 **/
49 
50 class cInstLib;
51 class cInstSet;
52 class cOrganism;
53 
54 
55 class cHardwareCPU : public cHardwareBase
56 {
57 public:
58   typedef bool (cHardwareCPU::*tMethod)(cAvidaContext& ctx);
59 
60 protected:
61   // --------  Structure Constants  --------
62   static const int NUM_REGISTERS = 3;
63   static const int NUM_HEADS = nHardware::NUM_HEADS >= NUM_REGISTERS ? nHardware::NUM_HEADS : NUM_REGISTERS;
64   enum tRegisters { REG_AX = 0, REG_BX, REG_CX, REG_DX, REG_EX, REG_FX };
65   static const int NUM_NOPS = 3;
66 
67   // --------  Data Structures  --------
68   struct cLocalThread
69   {
70   private:
71     int m_id;
72     int m_promoter_inst_executed;
73     int m_messageTriggerType;
74   public:
75     int reg[NUM_REGISTERS];
76     cHeadCPU heads[NUM_HEADS];
77     cCPUStack stack;
78     unsigned char cur_stack;              // 0 = local stack, 1 = global stack.
79     unsigned char cur_head;
80 
81     cCodeLabel read_label;
82     cCodeLabel next_label;
83 
84 
85     cLocalThread(cHardwareBase* in_hardware = NULL, int in_id = -1) { Reset(in_hardware, in_id); }
~cLocalThreadcLocalThread86     ~cLocalThread() { ; }
87 
88     void operator=(const cLocalThread& in_thread);
89 
90     void Reset(cHardwareBase* in_hardware, int in_id);
GetIDcLocalThread91     int GetID() const { return m_id; }
SetIDcLocalThread92     void SetID(int in_id) { m_id = in_id; }
GetPromoterInstExecutedcLocalThread93     int GetPromoterInstExecuted() { return m_promoter_inst_executed; }
IncPromoterInstExecutedcLocalThread94     void IncPromoterInstExecuted() { m_promoter_inst_executed++; }
ResetPromoterInstExecutedcLocalThread95     void ResetPromoterInstExecuted() { m_promoter_inst_executed = 0; }
setMessageTriggerTypecLocalThread96     void setMessageTriggerType(int value) { m_messageTriggerType = value; }
getMessageTriggerTypecLocalThread97     int getMessageTriggerType() { return m_messageTriggerType; }
98   };
99 
100 
101   // --------  Static Variables  --------
102   static tInstLib<tMethod>* s_inst_slib;
103   static tInstLib<tMethod>* initInstLib(void);
104 
105 
106   // --------  Member Variables  --------
107   const tMethod* m_functions;
108 
109   cCPUMemory m_memory;          // Memory...
110   cCPUStack m_global_stack;     // A stack that all threads share.
111 
112   tArray<cLocalThread> m_threads;
113   int m_thread_id_chart;
114   int m_cur_thread;
115 
116   // Flags...
117   struct {
118     bool m_mal_active:1;         // Has an allocate occured since last divide?
119     bool m_advance_ip:1;         // Should the IP advance after this instruction?
120     bool m_executedmatchstrings:1;	// Have we already executed the match strings instruction?
121     bool m_spec_die:1;
122 
123     bool m_thread_slicing_parallel:1;
124     bool m_no_cpu_cycle_time:1;
125 
126     bool m_promoters_enabled:1;
127     bool m_constitutive_regulation:1;
128 
129     bool m_slip_read_head:1;
130   };
131 
132   // <-- Promoter model
133   int m_promoter_index;       //site to begin looking for the next active promoter from
134   int m_promoter_offset;      //bit offset when testing whether a promoter is on
135 
136   struct cPromoter
137   {
138   public:
139     int m_pos;      //position within genome
140     int m_bit_code; //bit code of promoter
141     int m_regulation; //bit code of promoter
142   public:
143     cPromoter(int _pos = 0, int _bit_code = 0, int _regulation = 0) { m_pos = _pos; m_bit_code = _bit_code; m_regulation = _regulation; }
GetRegulatedBitCodecPromoter144     int GetRegulatedBitCode() { return m_bit_code ^ m_regulation; }
~cPromotercPromoter145     ~cPromoter() { ; }
146   };
147   tArray<cPromoter> m_promoters;
148   // Promoter Model -->
149 
150   // <-- Epigenetic State
151   bool m_epigenetic_state;
152   int m_epigenetic_saved_reg[NUM_REGISTERS];
153   cCPUStack m_epigenetic_saved_stack;
154   // Epigenetic State -->
155 
156 
157   bool SingleProcess_ExecuteInst(cAvidaContext& ctx, const cInstruction& cur_inst);
158 
159   // --------  Stack Manipulation...  --------
160   inline void StackPush(int value);
161   inline int StackPop();
162   inline void StackFlip();
163   inline void StackClear();
164   inline void SwitchStack();
165 
166 
167   // --------  Head Manipulation (including IP)  --------
GetActiveHead()168   cHeadCPU& GetActiveHead() { return m_threads[m_cur_thread].heads[m_threads[m_cur_thread].cur_head]; }
169   void AdjustHeads();
170 
171 
172   // --------  Label Manipulation  -------
GetLabel()173   const cCodeLabel& GetLabel() const { return m_threads[m_cur_thread].next_label; }
GetLabel()174   cCodeLabel& GetLabel() { return m_threads[m_cur_thread].next_label; }
175   void ReadLabel(int max_size=nHardware::MAX_LABEL_SIZE);
176   cHeadCPU FindLabel(int direction);
177   int FindLabel_Forward(const cCodeLabel & search_label, const Sequence& search_genome, int pos);
178   int FindLabel_Backward(const cCodeLabel & search_label, const Sequence& search_genome, int pos);
179   cHeadCPU FindLabel(const cCodeLabel & in_label, int direction);
GetReadLabel()180   const cCodeLabel& GetReadLabel() const { return m_threads[m_cur_thread].read_label; }
GetReadLabel()181   cCodeLabel& GetReadLabel() { return m_threads[m_cur_thread].read_label; }
182 
183 
184   // --------  Thread Manipulation  -------
185   bool ForkThread(); // Adds a new thread based off of m_cur_thread.
186   bool InterruptThread(int interruptType); // Create a new thread that interrupts the current thread
187   bool KillThread(); // Kill the current thread!
188 
189   // ---------- Instruction Helpers -----------
190   int FindModifiedRegister(int default_register);
191   int FindModifiedNextRegister(int default_register);
192   int FindModifiedPreviousRegister(int default_register);
193   int FindModifiedHead(int default_head);
194   int FindNextRegister(int base_reg);
195 
getHead(int head_id)196   inline const cHeadCPU& getHead(int head_id) const { return m_threads[m_cur_thread].heads[head_id]; }
getHead(int head_id)197   inline cHeadCPU& getHead(int head_id) { return m_threads[m_cur_thread].heads[head_id];}
getHead(int head_id,int thread)198   inline const cHeadCPU& getHead(int head_id, int thread) const { return m_threads[thread].heads[head_id]; }
getHead(int head_id,int thread)199   inline cHeadCPU& getHead(int head_id, int thread) { return m_threads[thread].heads[head_id];}
200 
getIP()201   inline const cHeadCPU& getIP() const { return m_threads[m_cur_thread].heads[nHardware::HEAD_IP]; }
getIP()202   inline cHeadCPU& getIP() { return m_threads[m_cur_thread].heads[nHardware::HEAD_IP]; }
getIP(int thread)203   inline const cHeadCPU& getIP(int thread) const { return m_threads[thread].heads[nHardware::HEAD_IP]; }
getIP(int thread)204   inline cHeadCPU& getIP(int thread) { return m_threads[thread].heads[nHardware::HEAD_IP]; }
205 
206 
207   bool Allocate_Necro(const int new_size);
208   bool Allocate_Random(cAvidaContext& ctx, const int old_size, const int new_size);
209   bool Allocate_Default(const int new_size);
210   bool Allocate_Main(cAvidaContext& ctx, const int allocated_size);
211 
212 
213   void internalReset();
214 
215   void internalResetOnFailedDivide();
216 
217 
218   int calcCopiedSize(const int parent_size, const int child_size);
219 
220   bool Divide_Main(cAvidaContext& ctx, const int divide_point, const int extra_lines=0, double mut_multiplier=1);
221   bool Divide_MainRS(cAvidaContext& ctx, const int divide_point, const int extra_lines=0, double mut_multiplier=1); //AWC 06/29/06
222   bool Divide_Main1RS(cAvidaContext& ctx, const int divide_point, const int extra_lines=0, double mut_multiplier=1); //AWC 07/28/06
223   bool Divide_Main2RS(cAvidaContext& ctx, const int divide_point, const int extra_lines=0, double mut_multiplier=1); //AWC 07/28/06
224 
225   void Divide_DoTransposons(cAvidaContext& ctx);
226   void InheritState(cHardwareBase& in_hardware);
227 
228   bool HeadCopy_ErrorCorrect(cAvidaContext& ctx, double reduction);
229   bool Inst_HeadDivideMut(cAvidaContext& ctx, double mut_multiplier = 1);
230 
231   void ReadInst(const int in_inst);
232 
233 
234   cHardwareCPU& operator=(const cHardwareCPU&); // @not_implemented
235 
236 public:
237   cHardwareCPU(cAvidaContext& ctx, cWorld* world, cOrganism* in_organism, cInstSet* in_inst_set);
~cHardwareCPU()238   ~cHardwareCPU() { ; }
239 
GetInstLib()240   static tInstLib<tMethod>* GetInstLib() { return s_inst_slib; }
GetDefaultInstFilename()241   static cString GetDefaultInstFilename() { return "instset-heads.cfg"; }
242 
243   bool SingleProcess(cAvidaContext& ctx, bool speculative = false);
244   void ProcessBonusInst(cAvidaContext& ctx, const cInstruction& inst);
245 
246 
247   // --------  Helper methods  --------
GetType()248   int GetType() const { return HARDWARE_TYPE_CPU_ORIGINAL; }
SupportsSpeculative()249   bool SupportsSpeculative() const { return true; }
250   void PrintStatus(std::ostream& fp);
SetupMiniTraceFileHeader(const cString & filename,const int gen_id,const cString & genotype)251   void SetupMiniTraceFileHeader(const cString& filename, const int gen_id, const cString& genotype) { (void)filename, (void)gen_id, (void)genotype; }
PrintMiniTraceStatus(cAvidaContext & ctx,std::ostream & fp,const cString & next_name)252   void PrintMiniTraceStatus(cAvidaContext& ctx, std::ostream& fp, const cString& next_name) { (void)ctx, (void)fp, (void)next_name; }
PrintMiniTraceSuccess(std::ostream & fp,const int exec_success)253   void PrintMiniTraceSuccess(std::ostream& fp, const int exec_success) { (void)fp, (void)exec_success; }
254 
255   // --------  Stack Manipulation...  --------
256   inline int GetStack(int depth=0, int stack_id=-1, int in_thread=-1) const;
GetNumStacks()257   inline int GetNumStacks() const { return 2; }
258 
259 
260   // --------  Head Manipulation (including IP)  --------
GetHead(int head_id)261   const cHeadCPU& GetHead(int head_id) const { return m_threads[m_cur_thread].heads[head_id]; }
GetHead(int head_id)262   cHeadCPU& GetHead(int head_id) { return m_threads[m_cur_thread].heads[head_id];}
GetHead(int head_id,int thread)263   const cHeadCPU& GetHead(int head_id, int thread) const { return m_threads[thread].heads[head_id]; }
GetHead(int head_id,int thread)264   cHeadCPU& GetHead(int head_id, int thread) { return m_threads[thread].heads[head_id];}
GetNumHeads()265   int GetNumHeads() const { return NUM_HEADS; }
266 
IP()267   const cHeadCPU& IP() const { return m_threads[m_cur_thread].heads[nHardware::HEAD_IP]; }
IP()268   cHeadCPU& IP() { return m_threads[m_cur_thread].heads[nHardware::HEAD_IP]; }
IP(int thread)269   const cHeadCPU& IP(int thread) const { return m_threads[thread].heads[nHardware::HEAD_IP]; }
IP(int thread)270   cHeadCPU& IP(int thread) { return m_threads[thread].heads[nHardware::HEAD_IP]; }
271 
272 
273   // --------  Memory Manipulation  --------
GetMemory()274   const cCPUMemory& GetMemory() const { return m_memory; }
GetMemory()275   cCPUMemory& GetMemory() { return m_memory; }
GetMemSize()276   int GetMemSize() const { return m_memory.GetSize(); }
GetMemory(int value)277   const cCPUMemory& GetMemory(int value) const { return m_memory; }
GetMemory(int value)278   cCPUMemory& GetMemory(int value) { return m_memory; }
GetMemSize(int value)279   int GetMemSize(int value) const { return  m_memory.GetSize(); }
GetNumMemSpaces()280   int GetNumMemSpaces() const { return 1; }
281 
282 
283   // --------  Register Manipulation  --------
GetRegister(int reg_id)284   int GetRegister(int reg_id) const { return m_threads[m_cur_thread].reg[reg_id]; }
GetRegister(int reg_id)285   int& GetRegister(int reg_id) { return m_threads[m_cur_thread].reg[reg_id]; }
GetNumRegisters()286   int GetNumRegisters() const { return NUM_REGISTERS; }
287 
288 
289   // --------  Thread Manipulation  --------
290   bool ThreadSelect(const int thread_num);
ThreadSelect(const cCodeLabel & in_label)291   bool ThreadSelect(const cCodeLabel& in_label) { return false; } // Labeled threads not supported
292   inline void ThreadPrev(); // Shift the current thread in use.
293   inline void ThreadNext();
ThreadGetOwner()294   cBioUnit* ThreadGetOwner() { return m_organism; }
295 
GetNumThreads()296   int GetNumThreads() const     { return m_threads.GetSize(); }
GetCurThread()297   int GetCurThread() const      { return m_cur_thread; }
GetCurThreadID()298   int GetCurThreadID() const    { return m_threads[m_cur_thread].GetID(); }
GetThread(int _index)299   const cLocalThread& GetThread(int _index) const { return m_threads[_index]; }
GetThreadMessageTriggerType(int _index)300   int GetThreadMessageTriggerType(int _index) { return m_threads[_index].getMessageTriggerType(); }
301 
302   // --------  Parasite Stuff  --------
ParasiteInfectHost(cBioUnit * bu)303   bool ParasiteInfectHost(cBioUnit* bu) { return false; }
304 
305   // -------- Kaboom Stuff ------------
306   bool checkNoMutList(cHeadCPU to);
307 
308 
309   // Non-Standard Methods
310 
GetActiveStack()311   int GetActiveStack() const { return m_threads[m_cur_thread].cur_stack; }
GetMalActive()312   bool GetMalActive() const   { return m_mal_active; }
313 
314 
315 private:
316   // ---------- Instruction Library -----------
317 
318   // Flow Control
319   bool Inst_If0(cAvidaContext& ctx);
320   bool Inst_IfEqu(cAvidaContext& ctx);
321   bool Inst_IfNot0(cAvidaContext& ctx);
322   bool Inst_If0_defaultAX(cAvidaContext& ctx);
323   bool Inst_IfNot0_defaultAX(cAvidaContext& ctx);
324   bool Inst_IfNEqu(cAvidaContext& ctx);
325   bool Inst_IfGr0(cAvidaContext& ctx);
326   bool Inst_IfGr(cAvidaContext& ctx);
327   bool Inst_IfGrEqu0(cAvidaContext& ctx);
328   bool Inst_IfGrEqu(cAvidaContext& ctx);
329   bool Inst_IfLess0(cAvidaContext& ctx);
330   bool Inst_IfLess(cAvidaContext& ctx);
331   bool Inst_IfLsEqu0(cAvidaContext& ctx);
332   bool Inst_IfLsEqu(cAvidaContext& ctx);
333   bool Inst_IfBit1(cAvidaContext& ctx);
334   bool Inst_IfANotEqB(cAvidaContext& ctx);
335   bool Inst_IfBNotEqC(cAvidaContext& ctx);
336   bool Inst_IfANotEqC(cAvidaContext& ctx);
337   bool Inst_IfGrX(cAvidaContext& ctx);
338   bool Inst_IfEquX(cAvidaContext& ctx);
339 
340   bool Inst_IfAboveResLevel(cAvidaContext& ctx);
341   bool Inst_IfAboveResLevelEnd(cAvidaContext& ctx);
342   bool Inst_IfNotAboveResLevel(cAvidaContext& ctx);
343   bool Inst_IfNotAboveResLevelEnd(cAvidaContext& ctx);
344 
345   bool Inst_IfGerm(cAvidaContext& ctx);
346   bool Inst_IfSoma(cAvidaContext& ctx);
347 
348   // Probabilistic ifs.
349   bool Inst_IfP0p125(cAvidaContext& ctx);
350   bool Inst_IfP0p25(cAvidaContext& ctx);
351   bool Inst_IfP0p50(cAvidaContext& ctx);
352   bool Inst_IfP0p75(cAvidaContext& ctx);
353 
354   // If-less-else-if, else, endif
355   cHeadCPU Find(const char* instr);
356   void Else_TopHalf();
357   bool Inst_IfLessEnd(cAvidaContext& ctx);
358   bool Inst_IfNotEqualEnd(cAvidaContext& ctx);
359   bool Inst_IfGrtEquEnd(cAvidaContext& ctx);
360   bool Inst_Else(cAvidaContext& ctx);
361   bool Inst_EndIf(cAvidaContext& ctx);
362 
363   bool Inst_JumpF(cAvidaContext& ctx);
364   bool Inst_JumpB(cAvidaContext& ctx);
365   bool Inst_Call(cAvidaContext& ctx);
366   bool Inst_Return(cAvidaContext& ctx);
367 
368   bool Inst_Throw(cAvidaContext& ctx);
369   bool Inst_ThrowIf0(cAvidaContext& ctx);
370   bool Inst_ThrowIfNot0(cAvidaContext& ctx);
Inst_Catch(cAvidaContext & ctx)371   bool Inst_Catch(cAvidaContext& ctx) { ReadLabel(); return true; };
372 
373   bool Inst_Goto(cAvidaContext& ctx);
374   bool Inst_GotoIf0(cAvidaContext& ctx);
375   bool Inst_GotoIfNot0(cAvidaContext& ctx);
Inst_Label(cAvidaContext & ctx)376   bool Inst_Label(cAvidaContext& ctx) { ReadLabel(); return true; };
377 
378   // Stack and Register Operations
379   bool Inst_Pop(cAvidaContext& ctx);
380   bool Inst_Push(cAvidaContext& ctx);
381   bool Inst_HeadPop(cAvidaContext& ctx);
382   bool Inst_HeadPush(cAvidaContext& ctx);
383 
384   bool Inst_PopA(cAvidaContext& ctx);
385   bool Inst_PopB(cAvidaContext& ctx);
386   bool Inst_PopC(cAvidaContext& ctx);
387   bool Inst_PushA(cAvidaContext& ctx);
388   bool Inst_PushB(cAvidaContext& ctx);
389   bool Inst_PushC(cAvidaContext& ctx);
390 
391   bool Inst_SwitchStack(cAvidaContext& ctx);
392   bool Inst_FlipStack(cAvidaContext& ctx);
393   bool Inst_Swap(cAvidaContext& ctx);
394   bool Inst_SwapAB(cAvidaContext& ctx);
395   bool Inst_SwapBC(cAvidaContext& ctx);
396   bool Inst_SwapAC(cAvidaContext& ctx);
397   bool Inst_CopyReg(cAvidaContext& ctx);
398   bool Inst_CopyRegAB(cAvidaContext& ctx);
399   bool Inst_CopyRegAC(cAvidaContext& ctx);
400   bool Inst_CopyRegBA(cAvidaContext& ctx);
401   bool Inst_CopyRegBC(cAvidaContext& ctx);
402   bool Inst_CopyRegCA(cAvidaContext& ctx);
403   bool Inst_CopyRegCB(cAvidaContext& ctx);
404   bool Inst_Reset(cAvidaContext& ctx);
405 
406   // Single-Argument Math
407   bool Inst_ShiftR(cAvidaContext& ctx);
408   bool Inst_ShiftL(cAvidaContext& ctx);
409   bool Inst_Bit1(cAvidaContext& ctx);
410   bool Inst_SetNum(cAvidaContext& ctx);
411   bool Inst_ValGrey(cAvidaContext& ctx);
412   bool Inst_ValDir(cAvidaContext& ctx);
413   bool Inst_ValAddP(cAvidaContext& ctx);
414   bool Inst_ValFib(cAvidaContext& ctx);
415   bool Inst_ValPolyC(cAvidaContext& ctx);
416   bool Inst_Inc(cAvidaContext& ctx);
417   bool Inst_Dec(cAvidaContext& ctx);
418   bool Inst_All1s(cAvidaContext& ctx);
419   bool Inst_Zero(cAvidaContext& ctx);
420   bool Inst_Not(cAvidaContext& ctx);
421   bool Inst_Neg(cAvidaContext& ctx);
422   bool Inst_Square(cAvidaContext& ctx);
423   bool Inst_Sqrt(cAvidaContext& ctx);
424   bool Inst_Log(cAvidaContext& ctx);
425   bool Inst_Log10(cAvidaContext& ctx);
426 
427   // Double Argument Math
428   bool Inst_Add(cAvidaContext& ctx);
429   bool Inst_Sub(cAvidaContext& ctx);
430   bool Inst_Mult(cAvidaContext& ctx);
431   bool Inst_Div(cAvidaContext& ctx);
432   bool Inst_Mod(cAvidaContext& ctx);
433   bool Inst_Nand(cAvidaContext& ctx);
434   bool Inst_Or(cAvidaContext& ctx);
435   bool Inst_Nor(cAvidaContext& ctx);
436   bool Inst_And(cAvidaContext& ctx);
437   bool Inst_Order(cAvidaContext& ctx);
438   bool Inst_Xor(cAvidaContext& ctx);
439 
440   // Bit-setting instructions
441   bool Inst_Setbit(cAvidaContext& ctx);
442   bool Inst_Clearbit(cAvidaContext& ctx);
443 
444   // Double Argument Math that are treatable
445   bool Inst_NandTreatable(cAvidaContext& ctx);
446 
447   // Biological
448   bool Inst_Copy(cAvidaContext& ctx);
449   bool Inst_ReadInst(cAvidaContext& ctx);
450   bool Inst_WriteInst(cAvidaContext& ctx);
451   bool Inst_StackReadInst(cAvidaContext& ctx);
452   bool Inst_StackWriteInst(cAvidaContext& ctx);
453   bool Inst_Compare(cAvidaContext& ctx);
454   bool Inst_IfNCpy(cAvidaContext& ctx);
455   bool Inst_Allocate(cAvidaContext& ctx);
456   bool Inst_Divide(cAvidaContext& ctx);
457   bool Inst_DivideRS(cAvidaContext& ctx); // AWC 06/29/06
458   bool Inst_CAlloc(cAvidaContext& ctx);
459   bool Inst_CDivide(cAvidaContext& ctx);
460   bool Inst_MaxAlloc(cAvidaContext& ctx);
461   bool Inst_MaxAllocMoveWriteHead(cAvidaContext& ctx);
462   bool Inst_Transposon(cAvidaContext& ctx);
463   bool Inst_ReproDeme(cAvidaContext& ctx);
464   bool Inst_Repro(cAvidaContext& ctx);
465   bool Inst_ReproSex(cAvidaContext& ctx);
466   bool Inst_ReproGermFlag(cAvidaContext& ctx);
467   bool Inst_TaskPutRepro(cAvidaContext& ctx);
468   bool Inst_TaskPutResetInputsRepro(cAvidaContext& ctx);
469   bool Inst_ConditionalRepro(cAvidaContext& ctx);
470   bool Inst_Sterilize(cAvidaContext& ctx);
471 
472   bool Inst_SpawnDeme(cAvidaContext& ctx);
473   bool Inst_Kazi(cAvidaContext& ctx);
474   bool Inst_Kazi5(cAvidaContext& ctx);
475   bool Inst_Die(cAvidaContext& ctx);
476   bool Inst_Poison(cAvidaContext& ctx);
477   bool Inst_Suicide(cAvidaContext& ctx);
478   bool Inst_RelinquishEnergyToFutureDeme(cAvidaContext& ctx);
479   bool Inst_RelinquishEnergyToNeighborOrganisms(cAvidaContext& ctx);
480   bool Inst_RelinquishEnergyToOrganismsInDeme(cAvidaContext& ctx);
481 
482   // I/O and Sensory
483   bool Inst_TaskGet(cAvidaContext& ctx);
484   bool Inst_TaskGet2(cAvidaContext& ctx);
485   bool Inst_TaskStackGet(cAvidaContext& ctx);
486   bool Inst_TaskStackLoad(cAvidaContext& ctx);
487   bool Inst_TaskPut(cAvidaContext& ctx);
488   bool Inst_TaskPutResetInputs(cAvidaContext& ctx);
489   bool Inst_TaskIO(cAvidaContext& ctx);
490   bool Inst_TaskIO_Feedback(cAvidaContext& ctx);
491   bool Inst_TaskIO_BonusCost(cAvidaContext& ctx, double bonus_cost);
Inst_TaskIO_BonusCost_0_001(cAvidaContext & ctx)492   bool Inst_TaskIO_BonusCost_0_001(cAvidaContext& ctx) { return Inst_TaskIO_BonusCost(ctx, 0.001); };
493   bool Inst_MatchStrings(cAvidaContext& ctx);
494   bool Inst_Sell(cAvidaContext& ctx);
495   bool Inst_Buy(cAvidaContext& ctx);
496   bool Inst_Send(cAvidaContext& ctx);
497   bool Inst_Receive(cAvidaContext& ctx);
498   bool Inst_SenseLog2(cAvidaContext& ctx);
499   bool Inst_SenseUnit(cAvidaContext& ctx);
500   bool Inst_SenseMult100(cAvidaContext& ctx);
501   bool DoSense(cAvidaContext& ctx, int conversion_method, double base);
502   bool DoSenseResourceX(int reg_to_set, int cell_id, int resid, cAvidaContext& ctx);
503   bool Inst_SenseResource0(cAvidaContext& ctx);
504   bool Inst_SenseResource1(cAvidaContext& ctx);
505   bool Inst_SenseResource2(cAvidaContext& ctx);
506   bool Inst_SenseFacedResource0(cAvidaContext& ctx);
507   bool Inst_SenseFacedResource1(cAvidaContext& ctx);
508   bool Inst_SenseFacedResource2(cAvidaContext& ctx);
509   bool Inst_SenseResourceID(cAvidaContext& ctx);
510   // Resources of next group +1 or -1, based on positive or negative value in the nop register,
511   // wrapping from the top group back to group 1 (skipping 0).
512   bool Inst_SenseNextResLevel(cAvidaContext& ctx);
513   bool Inst_SenseOpinionResourceQuantity(cAvidaContext& ctx);
514   bool Inst_SenseDiffFaced(cAvidaContext& ctx);
515   bool Inst_SenseFacedHabitat(cAvidaContext& ctx);
516 
517   // Resources
518   int FindModifiedResource(cAvidaContext& ctx, int& spec_id);
519   bool DoCollect(cAvidaContext& ctx, bool env_remove, bool internal_add, bool probabilistic, bool unit);
520   bool DoActualCollect(cAvidaContext& ctx, int bin_used, bool env_remove, bool internal_add, bool probabilistic, bool unit);
521   bool Inst_Collect(cAvidaContext& ctx);
522   bool Inst_CollectNoEnvRemove(cAvidaContext& ctx);
523   bool Inst_Destroy(cAvidaContext& ctx);
524   bool Inst_NopCollect(cAvidaContext& ctx);
525   bool Inst_CollectUnitProbabilistic(cAvidaContext& ctx);
526   bool Inst_CollectSpecific(cAvidaContext& ctx);
527   bool Inst_DonateSpecific(cAvidaContext& ctx);
528   bool Inst_CheckFacedKin(cAvidaContext& ctx);
529   bool Inst_SetBeggar(cAvidaContext& ctx);
530   bool Inst_CheckFacedBeggar(cAvidaContext& ctx);
531   bool Inst_IfFacedKin(cAvidaContext& ctx);
532   bool Inst_IfFacedBeggar(cAvidaContext& ctx);
533   bool Inst_IfResources(cAvidaContext& ctx);  //! Execute the following instruction if all resources are above their min level.
534   bool Inst_IfFacedBeggarAndNeedResource(cAvidaContext& ctx);
535   bool Inst_IfFacedBeggarAndKin(cAvidaContext& ctx);
536   bool Inst_IfFacedKinAndNeedResource(cAvidaContext& ctx);
537   bool Inst_IfFacedNeedResource(cAvidaContext& ctx);
538   bool Inst_IfFacedKinAndBeggarAndNeedResource(cAvidaContext& ctx);
539   bool Inst_IfFacedKinAndBeggarAndNeedResourceThenDonate(cAvidaContext& ctx);
540   bool Inst_IfFacedBeggarANdNeedsResourceThenDonate(cAvidaContext& ctx);
541   bool Inst_FailIfEmpty(cAvidaContext& ctx);
542   // Donation
543   void DoDonate(cOrganism * to_org);
544   void DoEnergyDonate(cOrganism* to_org);
545   void DoEnergyDonatePercent(cOrganism* to_org, const double frac_energy_given);
546   void DoEnergyDonateAmount(cOrganism* to_org, const double amount);
547   bool Inst_DonateRandom(cAvidaContext& ctx);
548   bool Inst_DonateKin(cAvidaContext& ctx);
549   bool Inst_DonateEditDist(cAvidaContext& ctx);
550   bool Inst_DonateGreenBeardGene(cAvidaContext& ctx);
551   bool Inst_DonateTrueGreenBeard(cAvidaContext& ctx);
552   bool Inst_DonateShadedGreenBeard(cAvidaContext& ctx);
553   bool Inst_DonateThreshGreenBeard(cAvidaContext& ctx);
554   bool Inst_DonateQuantaThreshGreenBeard(cAvidaContext& ctx);
555   bool Inst_DonateGreenBeardSameLocus(cAvidaContext& ctx);
556   bool Inst_DonateNULL(cAvidaContext& ctx);
557   bool Inst_DonateFacing(cAvidaContext& ctx);
558   bool Inst_ReceiveDonatedEnergy(cAvidaContext& ctx);
559   bool Inst_DonateEnergy(cAvidaContext& ctx);
560   bool Inst_UpdateMetabolicRate(cAvidaContext& ctx);
561   bool Inst_DonateEnergyFaced(cAvidaContext& ctx);
562   bool Inst_DonateEnergyFaced1(cAvidaContext& ctx);
563   bool Inst_DonateEnergyFaced2(cAvidaContext& ctx);
564   bool Inst_DonateEnergyFaced5(cAvidaContext& ctx);
565   bool Inst_DonateEnergyFaced10(cAvidaContext& ctx);
566   bool Inst_DonateEnergyFaced20(cAvidaContext& ctx);
567   bool Inst_DonateEnergyFaced50(cAvidaContext& ctx);
568   bool Inst_DonateEnergyFaced100(cAvidaContext& ctx);
569   bool Inst_RotateToMostNeedy(cAvidaContext& ctx);
570   bool Inst_RequestEnergy(cAvidaContext& ctx);
571   bool Inst_RequestEnergyFlagOn(cAvidaContext& ctx);
572   bool Inst_RequestEnergyFlagOff(cAvidaContext& ctx);
573   bool Inst_IncreaseEnergyDonation(cAvidaContext& ctx);
574   bool Inst_DecreaseEnergyDonation(cAvidaContext& ctx);
575 
576   void DoResourceDonatePercent(cAvidaContext& ctx, const int to_cell, const int resource_id, const double frac_resource_given);
577   void DoResourceDonateAmount(cAvidaContext& ctx, const int to_cell, const int resource_id, const double amount);
578   bool DonateResourceX(cAvidaContext& ctx, const int res_id);
579   bool Inst_DonateResource0(cAvidaContext& ctx);
580   bool Inst_DonateResource1(cAvidaContext& ctx);
581   bool Inst_DonateResource2(cAvidaContext& ctx);
582 
583   bool Inst_SearchF(cAvidaContext& ctx);
584   bool Inst_SearchB(cAvidaContext& ctx);
585   bool Inst_MemSize(cAvidaContext& ctx);
586 
587   bool Inst_IOBufAdd1(cAvidaContext& ctx);
588   bool Inst_IOBufAdd0(cAvidaContext& ctx);
589 
590   // Environment
591 
592   bool Inst_RotateL(cAvidaContext& ctx);
593   bool Inst_RotateR(cAvidaContext& ctx);
594   bool Inst_RotateLeftOne(cAvidaContext& ctx);
595   bool Inst_RotateRightOne(cAvidaContext& ctx);
596   bool Inst_RotateLabel(cAvidaContext& ctx);
597   bool Inst_RotateOccupiedCell(cAvidaContext& ctx);
598   bool Inst_RotateNextOccupiedCell(cAvidaContext& ctx);
599   bool Inst_RotateUnoccupiedCell(cAvidaContext& ctx);
600   bool Inst_RotateNextUnoccupiedCell(cAvidaContext& ctx);
601   bool Inst_RotateEventCell(cAvidaContext& ctx);
602   bool Inst_RotateUphill(cAvidaContext& ctx);
603   bool Inst_RotateHome(cAvidaContext& ctx);
604   bool Inst_SetCopyMut(cAvidaContext& ctx);
605   bool Inst_ModCopyMut(cAvidaContext& ctx);
606   bool Inst_GetCellPosition(cAvidaContext& ctx);
607   bool Inst_GetCellPositionX(cAvidaContext& ctx);
608   bool Inst_GetCellPositionY(cAvidaContext& ctx);
609   bool Inst_GetDirectionOffNorth(cAvidaContext& ctx);
610   bool Inst_GetNortherly(cAvidaContext& ctx);
611   bool Inst_GetEasterly(cAvidaContext& ctx);
612   bool Inst_ZeroEasterly(cAvidaContext& ctx);
613   bool Inst_ZeroNortherly(cAvidaContext& ctx);
614 
615   // State Grid Sensory/Movement
616   bool Inst_SGMove(cAvidaContext& ctx);
617   bool Inst_SGRotateL(cAvidaContext& ctx);
618   bool Inst_SGRotateR(cAvidaContext& ctx);
619   bool Inst_SGSense(cAvidaContext& ctx);
620 
621   bool Inst_GetDistanceFromDiagonal(cAvidaContext& ctx);
622   bool Inst_Tumble(cAvidaContext& ctx);
623   bool Inst_Move(cAvidaContext& ctx);
624   bool Inst_MoveToEvent(cAvidaContext& ctx);
625   bool Inst_IfNeighborEventInUnoccupiedCell(cAvidaContext& ctx);
626   bool Inst_IfFacingEventCell(cAvidaContext& ctx);
627   bool Inst_IfEventInCell(cAvidaContext& ctx);
628 
629   // Multi-threading...
630 
631   bool Inst_ForkThread(cAvidaContext& ctx);
632   bool Inst_ForkThreadLabel(cAvidaContext& ctx);
633   bool Inst_ForkThreadLabelIf0(cAvidaContext& ctx);
634   bool Inst_ForkThreadLabelIfNot0(cAvidaContext& ctx);
635   bool Inst_KillThread(cAvidaContext& ctx);
636   bool Inst_ThreadID(cAvidaContext& ctx);
637 
638   // Head-based instructions...
639 
640   bool Inst_SetHead(cAvidaContext& ctx);
641   bool Inst_AdvanceHead(cAvidaContext& ctx);
642   bool Inst_MoveHead(cAvidaContext& ctx);
643   bool Inst_ResMoveHead(cAvidaContext& ctx);
644   bool Inst_JumpHead(cAvidaContext& ctx);
645   bool Inst_ResJumpHead(cAvidaContext& ctx);
646   bool Inst_GetHead(cAvidaContext& ctx);
647   bool Inst_IfLabel(cAvidaContext& ctx);
648   bool Inst_IfLabelDirect(cAvidaContext& ctx);
649   bool Inst_IfLabel2(cAvidaContext& ctx);
650   bool Inst_HeadDivide(cAvidaContext& ctx);
651   bool Inst_HeadDivideRS(cAvidaContext& ctx); //AWC 06/29/06
652   bool Inst_HeadDivide1RS(cAvidaContext& ctx); //AWC 07/28/06
653   bool Inst_HeadDivide2RS(cAvidaContext& ctx); //AWC 08/29/06
654   bool Inst_HeadRead(cAvidaContext& ctx);
655   bool Inst_HeadWrite(cAvidaContext& ctx);
656   bool Inst_HeadCopy(cAvidaContext& ctx);
657   bool Inst_HeadSearch(cAvidaContext& ctx);
658   bool Inst_HeadSearchDirect(cAvidaContext& ctx);
659   bool Inst_SetFlow(cAvidaContext& ctx);
660 
661   bool Inst_HeadCopy2(cAvidaContext& ctx);
662   bool Inst_HeadCopy3(cAvidaContext& ctx);
663   bool Inst_HeadCopy4(cAvidaContext& ctx);
664   bool Inst_HeadCopy5(cAvidaContext& ctx);
665   bool Inst_HeadCopy6(cAvidaContext& ctx);
666   bool Inst_HeadCopy7(cAvidaContext& ctx);
667   bool Inst_HeadCopy8(cAvidaContext& ctx);
668   bool Inst_HeadCopy9(cAvidaContext& ctx);
669   bool Inst_HeadCopy10(cAvidaContext& ctx);
670 
671   bool Inst_HeadDivideSex(cAvidaContext& ctx);
672   bool Inst_HeadDivideAsex(cAvidaContext& ctx);
673   bool Inst_HeadDivideAsexWait(cAvidaContext& ctx);
674   bool Inst_HeadDivideMateSelect(cAvidaContext& ctx);
675 
676   bool Inst_HeadDivide1(cAvidaContext& ctx);
677   bool Inst_HeadDivide2(cAvidaContext& ctx);
678   bool Inst_HeadDivide3(cAvidaContext& ctx);
679   bool Inst_HeadDivide4(cAvidaContext& ctx);
680   bool Inst_HeadDivide5(cAvidaContext& ctx);
681   bool Inst_HeadDivide6(cAvidaContext& ctx);
682   bool Inst_HeadDivide7(cAvidaContext& ctx);
683   bool Inst_HeadDivide8(cAvidaContext& ctx);
684   bool Inst_HeadDivide9(cAvidaContext& ctx);
685   bool Inst_HeadDivide10(cAvidaContext& ctx);
686   bool Inst_HeadDivide16(cAvidaContext& ctx);
687   bool Inst_HeadDivide32(cAvidaContext& ctx);
688   bool Inst_HeadDivide50(cAvidaContext& ctx);
689   bool Inst_HeadDivide100(cAvidaContext& ctx);
690   bool Inst_HeadDivide500(cAvidaContext& ctx);
691   bool Inst_HeadDivide1000(cAvidaContext& ctx);
692   bool Inst_HeadDivide5000(cAvidaContext& ctx);
693   bool Inst_HeadDivide10000(cAvidaContext& ctx);
694   bool Inst_HeadDivide50000(cAvidaContext& ctx);
695   bool Inst_HeadDivide0_5(cAvidaContext& ctx);
696   bool Inst_HeadDivide0_1(cAvidaContext& ctx);
697   bool Inst_HeadDivide0_05(cAvidaContext& ctx);
698   bool Inst_HeadDivide0_01(cAvidaContext& ctx);
699   bool Inst_HeadDivide0_001(cAvidaContext& ctx);
700 
701   bool Inst_IfEnergyLow(cAvidaContext& ctx);
702   bool Inst_IfEnergyNotLow(cAvidaContext& ctx);
703   bool Inst_IfFacedEnergyLow(cAvidaContext& ctx);
704   bool Inst_IfFacedEnergyNotLow(cAvidaContext& ctx);
705   bool Inst_IfEnergyHigh(cAvidaContext& ctx);
706   bool Inst_IfEnergyNotHigh(cAvidaContext& ctx);
707   bool Inst_IfFacedEnergyHigh(cAvidaContext& ctx);
708   bool Inst_IfFacedEnergyNotHigh(cAvidaContext& ctx);
709   bool Inst_IfEnergyMed(cAvidaContext& ctx);
710   bool Inst_IfFacedEnergyMed(cAvidaContext& ctx);
711   bool Inst_IfFacedEnergyMore(cAvidaContext& ctx);
712   bool Inst_IfFacedEnergyLess(cAvidaContext& ctx);
713   bool Inst_IfEnergyInBuffer(cAvidaContext& ctx);
714   bool Inst_IfEnergyNotInBuffer(cAvidaContext& ctx);
715   bool Inst_GetEnergyLevel(cAvidaContext& ctx);
716   bool Inst_GetFacedEnergyLevel(cAvidaContext& ctx);
717   bool Inst_IfFacedEnergyRequestOn(cAvidaContext& ctx);
718   bool Inst_IfFacedEnergyRequestOff(cAvidaContext& ctx);
719   bool Inst_GetEnergyRequestStatus(cAvidaContext& ctx);
720   bool Inst_GetFacedEnergyRequestStatus(cAvidaContext& ctx);
721 
722 
723 
724   bool Inst_Sleep(cAvidaContext& ctx);
725   bool Inst_GetUpdate(cAvidaContext& ctx);
726 
727   //// Promoter Model ////
728   bool Inst_Promoter(cAvidaContext& ctx);
729   bool Inst_Terminate(cAvidaContext& ctx);
730   bool Inst_Regulate(cAvidaContext& ctx);
731   bool Inst_RegulateSpecificPromoters(cAvidaContext& ctx);
732   bool Inst_SenseRegulate(cAvidaContext& ctx);
Inst_Numberate(cAvidaContext & ctx)733   bool Inst_Numberate(cAvidaContext& ctx) { return Do_Numberate(ctx); };
Inst_Numberate24(cAvidaContext & ctx)734   bool Inst_Numberate24(cAvidaContext& ctx) { return Do_Numberate(ctx, 24); };
735   bool Do_Numberate(cAvidaContext& ctx, int num_bits=0);
736 
737   // Helper functions //
738   bool IsActivePromoter();
739   void NextPromoter();
740   int  Numberate(int _pos, int _dir, int _num_bits = 0);
741 
742   //// Bit consensus functions ////
743   inline unsigned int BitCount(unsigned int value) const;
744   bool Inst_BitConsensus(cAvidaContext& ctx);
745   bool Inst_BitConsensus24(cAvidaContext& ctx);
746   bool Inst_IfConsensus(cAvidaContext& ctx);
747   bool Inst_IfConsensus24(cAvidaContext& ctx);
748   bool Inst_IfLessConsensus(cAvidaContext& ctx);
749   bool Inst_IfLessConsensus24(cAvidaContext& ctx);
750 
751   // Bit masking instructions
752   bool Inst_MaskSignBit(cAvidaContext& ctx);
753   bool Inst_MaskOffLower16Bits(cAvidaContext& ctx);
754   bool Inst_MaskOffLower16Bits_defaultAX(cAvidaContext& ctx);
755   bool Inst_MaskOffLower15Bits(cAvidaContext& ctx);
756   bool Inst_MaskOffLower15Bits_defaultAX(cAvidaContext& ctx);
757   bool Inst_MaskOffLower14Bits(cAvidaContext& ctx);
758   bool Inst_MaskOffLower14Bits_defaultAX(cAvidaContext& ctx);
759   bool Inst_MaskOffLower13Bits(cAvidaContext& ctx);
760   bool Inst_MaskOffLower13Bits_defaultAX(cAvidaContext& ctx);
761   bool Inst_MaskOffLower12Bits(cAvidaContext& ctx);
762   bool Inst_MaskOffLower12Bits_defaultAX(cAvidaContext& ctx);
763   bool Inst_MaskOffLower8Bits(cAvidaContext& ctx);
764   bool Inst_MaskOffLower8Bits_defaultAX(cAvidaContext& ctx);
765   bool Inst_MaskOffLower4Bits(cAvidaContext& ctx);
766   bool Inst_MaskOffLower4Bits_defaultAX(cAvidaContext& ctx);
767 
768   //// Messaging ////
769   bool Inst_SendMessage(cAvidaContext& ctx);
770   bool SendMessage(cAvidaContext& ctx, int messageType = 0);
771   bool Inst_RetrieveMessage(cAvidaContext& ctx);
772   bool BroadcastX(cAvidaContext& ctx, int depth);
773   bool Inst_Broadcast1(cAvidaContext& ctx);
774   bool Inst_Broadcast2(cAvidaContext& ctx);
775   bool Inst_Broadcast4(cAvidaContext& ctx);
776   bool Inst_Broadcast8(cAvidaContext& ctx);
777 
778   // Active messaging //
779   bool Inst_SendMessageInterruptType0(cAvidaContext& ctx);
780   bool Inst_SendMessageInterruptType1(cAvidaContext& ctx);
781   bool Inst_SendMessageInterruptType2(cAvidaContext& ctx);
782   bool Inst_SendMessageInterruptType3(cAvidaContext& ctx);
783   bool Inst_SendMessageInterruptType4(cAvidaContext& ctx);
784   bool Inst_SendMessageInterruptType5(cAvidaContext& ctx);
785   bool Inst_START_Handler(cAvidaContext& ctx);
786   bool Inst_End_Handler(cAvidaContext& ctx);
787 
788   //// Alarm ////
789   bool Inst_Alarm_MSG_local(cAvidaContext& ctx);
790   bool Inst_Alarm_MSG_multihop(cAvidaContext& ctx);
791   bool Inst_Alarm_MSG_Bit_Cons24_local(cAvidaContext& ctx);
792   bool Inst_Alarm_MSG_Bit_Cons24_multihop(cAvidaContext& ctx);
793   bool Inst_Alarm_Label(cAvidaContext& ctx);
794   bool Jump_To_Alarm_Label(int jump_label);
795 
796 
797   // -------- Reputation support --------
798   /* These instructions interact with the "reputation" support in cOrganism.h.  They
799   are  based on the donate instructions. However, these instructions donate
800   "raw materials" rather than merit and will eventually be used to support
801   reputation based cooperation.
802   */
803   // Donate a raw material to the neighbor
804   bool Inst_DonateFacingRawMaterials(cAvidaContext& ctx);
805   // Donate a raw material to the neighbor if it is another species
806   bool Inst_DonateFacingRawMaterialsOtherSpecies(cAvidaContext& ctx);
807   // Donate a raw material to the neighbor if it was a prior donor
808   bool Inst_DonateIfDonor(cAvidaContext& ctx);
809   // Donate a string to the neighbor, if it's reputation is > 0
810   bool Inst_DonateStringIfDonorRep(cAvidaContext& ctx);
811   // Donate a string to a neighbor
812   bool Inst_DonateFacingString(cAvidaContext& ctx);
813 
814   // Rotate to the organims with the greatest reputation
815   bool Inst_RotateToGreatestReputation(cAvidaContext& ctx);
816   // Rotate to the organims with the greatest reputation that has a different tag
817   bool Inst_RotateToGreatestReputationWithDifferentTag(cAvidaContext& ctx);
818   // Rotate to the organims with the greatest reputation that has a different tag
819   bool Inst_RotateToGreatestReputationWithDifferentLineage(cAvidaContext& ctx);
820   // Rotate to an organim with a different tag
821   bool Inst_RotateToDifferentTag(cAvidaContext& ctx);
822   // Rotate to the organims with the greatest reputation and donate
823   bool Inst_RotateToGreatestReputationAndDonate(cAvidaContext& ctx);
824   // Get a neighbor's reputation
825   bool Inst_GetNeighborsReputation(cAvidaContext& ctx);
826   // Get the organism's reputation
827   bool Inst_GetReputation(cAvidaContext& ctx);
828   // Execute the following instruction if the facing neighbor was a donor
829   bool Inst_IfDonor(cAvidaContext& ctx);
830   // Produce string
831   bool Inst_ProduceString(cAvidaContext& ctx);
832   // Get the organism's raw material level
833   bool Inst_GetAmountOfRawMaterials(cAvidaContext& ctx);
834   // Get the number of raw materials the organism
835   // has gotten from others
836   bool Inst_GetAmountOfOtherRawMaterials(cAvidaContext& ctx);
837   // Pretend to donate
838   bool Inst_Pose(cAvidaContext& ctx);
839 
840   // Reputation
841   void ComputeReputation();
842 
843 
844   //// Placebo ////
845   bool Inst_Skip(cAvidaContext& ctx);
846 
847   // @BDC Additions for pheromones
848   bool Inst_PheroOn(cAvidaContext& ctx);
849   bool Inst_PheroOff(cAvidaContext& ctx);
850   bool Inst_PheroToggle(cAvidaContext& ctx);
851   bool DoSenseFacing(cAvidaContext& ctx, int conversion_method, double base);
852   bool Inst_SenseLog2Facing(cAvidaContext& ctx);
853   bool Inst_SenseUnitFacing(cAvidaContext& ctx);
854   bool Inst_SenseMult100Facing(cAvidaContext& ctx);
855   bool Inst_SenseTarget(cAvidaContext& ctx);
856   bool Inst_SenseTargetFaced(cAvidaContext& ctx);
857   bool DoSensePheromone(cAvidaContext& ctx, int cellid);
858   bool DoSensePheromoneInDemeGlobal(cAvidaContext& ctx, tRegisters REG_DEFAULT);
859   bool DoSensePheromoneGlobal(cAvidaContext& ctx, tRegisters REG_DEFAULT);
860   bool Inst_SensePheromone(cAvidaContext& ctx);
861   bool Inst_SensePheromoneFaced(cAvidaContext& ctx);
862   bool Inst_SensePheromoneInDemeGlobal(cAvidaContext& ctx);
863   bool Inst_SensePheromoneGlobal(cAvidaContext& ctx);
864   bool Inst_SensePheromoneGlobal_defaultAX(cAvidaContext& ctx);
865   bool Inst_Exploit(cAvidaContext& ctx);
866   bool Inst_ExploitForward5(cAvidaContext& ctx);
867   bool Inst_ExploitForward3(cAvidaContext& ctx);
868   bool Inst_Explore(cAvidaContext& ctx);
869   bool Inst_MoveTarget(cAvidaContext& ctx);
870   bool Inst_MoveTargetForward5(cAvidaContext& ctx);
871   bool Inst_MoveTargetForward3(cAvidaContext& ctx);
872   bool Inst_SuperMove(cAvidaContext& ctx);
873   bool Inst_IfTarget(cAvidaContext& ctx);
874   bool Inst_IfNotTarget(cAvidaContext& ctx);
875   bool Inst_IfPheromone(cAvidaContext& ctx);
876   bool Inst_IfNotPheromone(cAvidaContext& ctx);
877   bool Inst_DropPheromone(cAvidaContext& ctx);
878 
879   // -------- Opinion support --------
880 public:
881   /* These instructions interact with the "opinion" support in cOrganism.h.  The
882   idea is that we're enabling organisms to express an opinion about *something*,
883   where that something is defined by the particular tasks and/or (deme) fitness function
884   in use.  This may have to be extended in the future to support different kinds of
885   opinions that can be expressed during the same experiment, and possibly augmented
886   with a "strength" of that opinion (but not right now).
887   */
888   bool Inst_SetOpinion(cAvidaContext& ctx);
889   bool Inst_GetOpinion(cAvidaContext& ctx);
890   //! Only get opinion.  If none then reg is set to zero
891   bool Inst_GetOpinionOnly_ZeroIfNone(cAvidaContext& ctx);
892   //! Clear this organism's current opinion.
893   bool Inst_ClearOpinion(cAvidaContext& ctx);
894   //! Execute next instruction is org has an opinion, otherwise skip
895   bool Inst_IfOpinionSet(cAvidaContext& ctx);
896   bool Inst_IfOpinionNotSet(cAvidaContext& ctx);
897   bool Inst_SetOpinionToZero(cAvidaContext& ctx);
898   bool Inst_SetOpinionToOne(cAvidaContext& ctx);
899   bool Inst_SetOpinionToTwo(cAvidaContext& ctx);
900 
901 
902   // -------- Cell Data Support --------
903 public:
904   //! Collect this cell's data, and place it in a register.
905   bool Inst_CollectCellData(cAvidaContext& ctx);
906   //! Detect if this cell's data has changed since the last collection.
907   bool Inst_IfCellDataChanged(cAvidaContext& ctx);
908   bool Inst_KillCellEvent(cAvidaContext& ctx);
909   bool Inst_KillFacedCellEvent(cAvidaContext& ctx);
910   bool Inst_CollectCellDataAndKillEvent(cAvidaContext& ctx);
911   bool Inst_ReadCellData(cAvidaContext& ctx);
912   bool Inst_ReadFacedCellData(cAvidaContext& ctx);
913   bool Inst_ReadFacedCellDataOrgID(cAvidaContext& ctx);
914   bool Inst_ReadFacedCellDataFreshness(cAvidaContext& ctx);
915   bool Inst_MarkCellWithID(cAvidaContext& ctx);
916   bool Inst_MarkCellWithVitality(cAvidaContext& ctx);
917   bool Inst_GetResStored(cAvidaContext& ctx);
918   bool Inst_GetID(cAvidaContext& ctx);
919   bool Inst_GetFacedVitalityDiff(cAvidaContext& ctx);
920   bool Inst_GetFacedOrgID(cAvidaContext& ctx);
921   bool Inst_AttackFacedOrg(cAvidaContext& ctx);
922   bool Inst_GetAttackOdds(cAvidaContext& ctx);
923 
924 private:
925   std::pair<bool, int> m_last_cell_data; //<! If cell data has been previously collected, and it's value.
926 
927   // -------- Synchronization primitives --------
928 public:
929   //! Called when the owning organism receives a flash from a neighbor.
930   virtual void ReceiveFlash();
931   //! Sends a "flash" to all neighboring organisms.
932   bool Inst_Flash(cAvidaContext& ctx);
933   //! Test if this organism has ever received a flash.
934   bool Inst_IfRecvdFlash(cAvidaContext& ctx);
935   //! Get if & when this organism last received a flash.
936   bool Inst_FlashInfo(cAvidaContext& ctx);
937   //! Get if (but not when) this organism last received a flash.
938   bool Inst_FlashInfoB(cAvidaContext& ctx);
939   //! Reset the information this organism has regarding receiving a flash.
940   bool Inst_ResetFlashInfo(cAvidaContext& ctx);
941   //! Reset the entire CPU.
942   bool Inst_HardReset(cAvidaContext& ctx);
943   //! Current "time": the number of cycles this CPU has been "alive."
944   bool Inst_GetCycles(cAvidaContext& ctx);
945 
946 private:
947   /*! Used to track the last flash received; first=whether we've received a flash,
948   second= #cycles since we've received a flash, or 0 if we haven't. */
949   std::pair<unsigned int, unsigned int> m_flash_info;
950   //! Cycle timer; counts the number of cycles this virtual CPU has executed.
951   unsigned int m_cycle_counter;
952 
953   // -------- Neighborhood-sensing support --------
954 public:
955   //! Loads the current neighborhood into the organism's memory.
956   bool Inst_GetNeighborhood(cAvidaContext& ctx);
957   //! Test if the current neighborhood has changed from that in the organism's memory.
958   bool Inst_IfNeighborhoodChanged(cAvidaContext& ctx);
959 
960 
961   // -------- Group Formation Support --------
962 public:
963   //! An organism joins a group by setting it opinion to the group id.
964   bool Inst_JoinGroup(cAvidaContext& ctx);
965   bool Inst_JoinMTGroup(cAvidaContext& ctx);
966   // Organism joins group +1 or -1 wrapping from the top group back to group 1 (skipping 0)
967   // based on whether the nop register is positive or negative.
968   bool Inst_JoinNextGroup(cAvidaContext& ctx);
969   bool Inst_JoinNextMTGroup(cAvidaContext& ctx);
970   //! Returns the number of organisms in the current organism's group
971   bool Inst_NumberOrgsInMyGroup(cAvidaContext& ctx);
972   bool Inst_NumberMTInMyGroup(cAvidaContext& ctx);
973   //! Returns the number of organisms in the current organism's group
974   bool Inst_NumberOrgsInGroup(cAvidaContext& ctx);
975   bool Inst_NumberMTInGroup(cAvidaContext& ctx);
976   // Places in BX register, the number of organisms in the group +1 or -1, wrapping from the top back to group 1
977   // skipping 0, based on whether the nop register is positive or negative.
978   bool Inst_NumberNextGroup(cAvidaContext& ctx);
979   bool Inst_NumberMTNextGroup(cAvidaContext& ctx);
980   bool Inst_KillGroupMember(cAvidaContext& ctx);
981 
982   bool Inst_IncTolerance(cAvidaContext& ctx);
983   bool Inst_DecTolerance(cAvidaContext& ctx);
984   bool Inst_GetTolerance(cAvidaContext& ctx);
985   bool Inst_GetGroupTolerance(cAvidaContext& ctx);
986 
987   // -------- Network creation support --------
988 public:
989   //! Create a link to the currently-faced cell.
990   bool Inst_CreateLinkByFacing(cAvidaContext& ctx);
991   //! Create a link to the cell specified by xy-coordinates.
992   bool Inst_CreateLinkByXY(cAvidaContext& ctx);
993   //! Create a link to the cell specified by index.
994   bool Inst_CreateLinkByIndex(cAvidaContext& ctx);
995   //! Broadcast a message in the communication network.
996   bool Inst_NetworkBroadcast1(cAvidaContext& ctx);
997   //! Unicast a message in the communication network.
998   bool Inst_NetworkUnicast(cAvidaContext& ctx);
999   //! Rotate the current active link by the contents of register ?BX?.
1000   bool Inst_NetworkRotate(cAvidaContext& ctx);
1001   //! Select the current active link from the contents of register ?BX?.
1002   bool Inst_NetworkSelect(cAvidaContext& ctx);
1003 
1004 
1005   // -------- Division of labor support --------
1006   bool Inst_GetTimeUsed(cAvidaContext& ctx);
1007   bool Inst_DonateResToDeme(cAvidaContext& ctx);
1008   // If there is a penalty for switching tasks, call this function and
1009   // the additional cycle cost will be added.
1010   void IncrementTaskSwitchingCost(int cost);
GetTaskSwitchingCost()1011   int GetTaskSwitchingCost() { return m_task_switching_cost; }
1012   // Apply point mutations to a genome.
1013   bool Inst_ApplyPointMutations(cAvidaContext& ctx);
1014   // Apply point mutations to a genome, where the mutation rate
1015   // depends on the task last performed
1016   bool Inst_ApplyVaryingPointMutations(cAvidaContext& ctx);
1017   // Apply point mutations to a genome in the deme with the same
1018   // germ/soma status
1019   bool Inst_ApplyPointMutationsGroupGS(cAvidaContext& ctx);
1020   // Apply point mutations to a genome in the deme at random
1021   bool Inst_ApplyPointMutationsGroupRandom(cAvidaContext& ctx);
1022 
1023   bool Inst_JoinGermline(cAvidaContext& ctx);
1024   bool Inst_ExitGermline(cAvidaContext& ctx);
1025   bool Inst_RepairPointMutOn(cAvidaContext& ctx);
1026   bool Inst_RepairPointMutOff(cAvidaContext& ctx);
1027 
1028 
1029   // -------- Mating types support support --------
1030 public:
1031   bool Inst_SetMatingTypeMale(cAvidaContext& ctx);
1032   bool Inst_SetMatingTypeFemale(cAvidaContext& ctx);
1033   bool Inst_SetMatingTypeJuvenile(cAvidaContext& ctx);
1034   bool Inst_DivideSexMatingType(cAvidaContext& ctx);
1035   bool Inst_IfMatingTypeMale(cAvidaContext& ctx);
1036   bool Inst_IfMatingTypeFemale(cAvidaContext& ctx);
1037   bool Inst_IfMatingTypeJuvenile(cAvidaContext& ctx);
1038   bool Inst_IncrementMatingDisplayA(cAvidaContext& ctx);
1039   bool Inst_IncrementMatingDisplayB(cAvidaContext& ctx);
1040   bool Inst_SetMatingDisplayA(cAvidaContext& ctx);
1041   bool Inst_SetMatingDisplayB(cAvidaContext& ctx);
1042   bool Inst_SetMatePreference(cAvidaContext& ctx, int mate_pref);
1043   bool Inst_SetMatePreferenceHighestDisplayA(cAvidaContext& ctx);
1044   bool Inst_SetMatePreferenceHighestDisplayB(cAvidaContext& ctx);
1045   bool Inst_SetMatePreferenceRandom(cAvidaContext& ctx);
1046   bool Inst_SetMatePreferenceHighestMerit(cAvidaContext& ctx);
1047 };
1048 
1049 
ThreadSelect(const int thread_num)1050 inline bool cHardwareCPU::ThreadSelect(const int thread_num)
1051 {
1052   if (thread_num >= 0 && thread_num < m_threads.GetSize()) {
1053     m_cur_thread = thread_num;
1054     return true;
1055   }
1056 
1057   return false;
1058 }
1059 
ThreadNext()1060 inline void cHardwareCPU::ThreadNext()
1061 {
1062   m_cur_thread++;
1063   if (m_cur_thread >= m_threads.GetSize()) m_cur_thread = 0;
1064 }
1065 
ThreadPrev()1066 inline void cHardwareCPU::ThreadPrev()
1067 {
1068   if (m_cur_thread == 0) m_cur_thread = m_threads.GetSize() - 1;
1069   else m_cur_thread--;
1070 }
1071 
StackPush(int value)1072 inline void cHardwareCPU::StackPush(int value)
1073 {
1074   if (m_threads[m_cur_thread].cur_stack == 0) {
1075     m_threads[m_cur_thread].stack.Push(value);
1076   } else {
1077     m_global_stack.Push(value);
1078   }
1079 }
1080 
StackPop()1081 inline int cHardwareCPU::StackPop()
1082 {
1083   int pop_value;
1084 
1085   if (m_threads[m_cur_thread].cur_stack == 0) {
1086     pop_value = m_threads[m_cur_thread].stack.Pop();
1087   } else {
1088     pop_value = m_global_stack.Pop();
1089   }
1090 
1091   return pop_value;
1092 }
1093 
StackFlip()1094 inline void cHardwareCPU::StackFlip()
1095 {
1096   if (m_threads[m_cur_thread].cur_stack == 0) {
1097     m_threads[m_cur_thread].stack.Flip();
1098   } else {
1099     m_global_stack.Flip();
1100   }
1101 }
1102 
GetStack(int depth,int stack_id,int in_thread)1103 inline int cHardwareCPU::GetStack(int depth, int stack_id, int in_thread) const
1104 {
1105   int value = 0;
1106 
1107   if(in_thread >= m_threads.GetSize() || in_thread < 0) in_thread = m_cur_thread;
1108 
1109   if (stack_id == -1) stack_id = m_threads[in_thread].cur_stack;
1110 
1111   if (stack_id == 0) value = m_threads[in_thread].stack.Get(depth);
1112   else if (stack_id == 1) value = m_global_stack.Get(depth);
1113 
1114   return value;
1115 }
1116 
StackClear()1117 inline void cHardwareCPU::StackClear()
1118 {
1119   if (m_threads[m_cur_thread].cur_stack == 0) {
1120     m_threads[m_cur_thread].stack.Clear();
1121   } else {
1122     m_global_stack.Clear();
1123   }
1124 }
1125 
SwitchStack()1126 inline void cHardwareCPU::SwitchStack()
1127 {
1128   m_threads[m_cur_thread].cur_stack++;
1129   if (m_threads[m_cur_thread].cur_stack > 1) m_threads[m_cur_thread].cur_stack = 0;
1130 }
1131 
1132 #endif
1133 
1134 
1135