// File: /workspace/github_c_makefile_star2_O3/stonezwr[P]SpiKL-IP/neuron.C
// Function: Neuron::LSMNextTimeStep(int, _IO_FILE*, bool, int)
void Neuron::LSMNextTimeStep(int t, FILE * Foutp, bool train, int end_time){

    if(_mode == DEACTIVATED) return;
    if(_mode == READCHANNEL ){
        if(_mode != READCHANNEL){
            // if training the input-reservoir/reservoir-readout synapses, need to keep track the cal!
            _lsm_v_mem_pre = _lsm_v_mem;
            _lsm_calcium_pre = _lsm_calcium;
            _lsm_calcium -= _lsm_calcium/TAU_C;
        }
        if(_t_next_spike == -1) return;
        if(t < _t_next_spike) return;
        if(_mode != READCHANNEL){
            _lsm_calcium += one;
        }

        /** Hand the firing behavior here for both input neurons and reservoir neurons */
        /** @param1: is the neuron only used to output spike? **/
        HandleFiringActivity(true, t, train);
        _fired = true;

        _t_next_spike = _lsm_channel->NextSpikeT();
        if(_t_next_spike == -1) {
            _network->LSMChannelDecrement(_lsm_channel->Mode()); 
        }
        return;
    }
    

    // the following code is to simulate the mode of NORMAL, WRITECHANNEL, and STDP
    _lsm_v_mem_pre = _lsm_v_mem;
    _lsm_calcium_pre = _lsm_calcium;
    _lsm_calcium -= _lsm_calcium/TAU_C;

    if((_teacherSignal==1)&&(_lsm_calcium < LSM_CAL_MID+1)){
        _lsm_v_mem += 20;
    }else if((_teacherSignal==-1)&&(_lsm_calcium > LSM_CAL_MID-1)){
        _lsm_v_mem -= 15*0.75;
    }

    list<Synapse*>::iterator iter;

    int pos;
    double value;
	if(_name[0]=='r')
		ExpDecay(_lsm_v_mem, _lsm_t_m_c);
	else
		ExpDecay(_lsm_v_mem, LSM_T_M_C);
    ExpDecay(_lsm_state_EP, _lsm_tau_EP);
    ExpDecay(_lsm_state_EN, _lsm_tau_EN);
    ExpDecay(_lsm_state_IP, _lsm_tau_IP);
    ExpDecay(_lsm_state_IN, _lsm_tau_IN);

    // sum up the effect
    _lsm_state_EP += _prev_delta_ep;
    _lsm_state_EN += _prev_delta_en;
    _lsm_state_IP += _prev_delta_ip;
    _lsm_state_IN += _prev_delta_in;

    double temp = NOrderSynapticResponse();
    _lsm_v_mem += _lsm_R*temp/_lsm_t_m_c;
	_lsm_input=temp;
	if(temp>0){
		_fire_start=true;
	}

    if(_lsm_ref > 0){
        _lsm_ref--;
        _lsm_v_mem = LSM_V_REST;
        _fired = false;
        return;
    }

    _fired = false;

    if(_lsm_v_mem > _lsm_v_thresh){
        _lsm_calcium += one;

        // 1. handle the _outputSyns after the neuron fires and activate the _outputSyns
        // 2. keep track of the t_spike_pre for the corresponding syns
        // 3. @para1: whether or not the current neuron is only used as a dummy input
        HandleFiringActivity(false, t, train);
        _fired = true;

        _lsm_v_mem = LSM_V_RESET;

		_lsm_ref = LSM_T_REFRAC;

        if(_name[0] == 'o' || _name[0] == 'h'){
            _f_count ++;
            assert(t > (_fire_timings.empty() ? -1 : _fire_timings.back()));
            _fire_timings.push_back(t);
        }
		else
			_f_count++;

        if(_mode == WRITECHANNEL&&_generate_transient){
            if(_lsm_channel == NULL){
                cout<<"Failure to assign a channel ptr to the neuron: "<<_name<<endl;
                assert(_lsm_channel);
            }
            _lsm_channel->AddSpike(t);
        }

    }
#ifdef SPIKL_IP
    if(_SpiKL_ip && _network->LSMGetNetworkMode()==TRANSIENTSTATE)  
        SpiKL_IP(t);
#endif
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x10, %rsp
movl %esi, 0xc(%rsp)
movl 0x8(%rdi), %eax
testl %eax, %eax
je 0x7623
movl %esi, %ebp
movq %rdi, %rbx
cmpl $0x1, %eax
jne 0x72dd
movl 0x218(%rbx), %eax
cmpl $-0x1, %eax
sete %dl
cmpl %ebp, %eax
setg %al
orb %dl, %al
jne 0x7623
movq 0x18(%rbx), %r15
movq 0x20(%rbx), %r12
cmpq %r12, %r15
je 0x7338
movzbl %cl, %ebp
movq (%r15), %r14
movq %r14, %rdi
callq 0xc180
cmpl $0x0, 0x8(%rax)
je 0x7294
cmpb $0x0, 0x13(%r14)
je 0x72a2
addq $0x8, %r15
cmpq %r12, %r15
jne 0x727c
jmp 0x7338
movq %r14, %rdi
callq 0xc18e
movq 0x10(%rbx), %rax
cmpb $0x69, (%rax)
je 0x7294
cmpl $0x1, 0x8(%rbx)
jne 0x7294
movq %r14, %rdi
callq 0xbff8
testb %al, %al
je 0x7294
movq 0x120(%rbx), %rsi
movq %r14, %rdi
movl $0x1, %edx
movl %ebp, %ecx
callq 0xc1ea
jmp 0x7294
movsd 0x168(%rbx), %xmm1
movsd %xmm1, 0x170(%rbx)
movsd 0x178(%rbx), %xmm2
movsd %xmm2, 0x180(%rbx)
movsd 0x10383(%rip), %xmm0    # 0x17688
mulsd %xmm2, %xmm0
addsd %xmm2, %xmm0
movsd %xmm0, 0x178(%rbx)
movl 0x114(%rbx), %eax
cmpl $0x1, %eax
jne 0x737c
movsd 0x10370(%rip), %xmm2    # 0x17698
ucomisd %xmm0, %xmm2
jbe 0x737c
movsd 0x1035a(%rip), %xmm2    # 0x17690
jmp 0x7393
movb $0x1, 0x130(%rbx)
movq 0x210(%rbx), %rdi
callq 0x3e6c
movl %eax, 0x218(%rbx)
cmpl $-0x1, %eax
jne 0x7623
movq 0x120(%rbx), %rdi
movq 0x210(%rbx), %rax
movl 0x44(%rax), %esi
addq $0x10, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x111d4
cmpl $-0x1, %eax
jne 0x739f
ucomisd 0x1031f(%rip), %xmm0    # 0x176a8
jbe 0x739f
movsd 0x1030d(%rip), %xmm2    # 0x176a0
addsd %xmm2, %xmm1
movsd %xmm1, 0x168(%rbx)
movq 0x10(%rbx), %rax
cmpb $0x72, (%rax)
movsd 0x1f0(%rbx), %xmm2
je 0x73be
movsd 0x102f8(%rip), %xmm3    # 0x176b0
mulsd %xmm1, %xmm3
jmp 0x73c6
movapd %xmm1, %xmm3
divsd %xmm2, %xmm3
subsd %xmm3, %xmm1
movupd 0x1a8(%rbx), %xmm3
movupd 0x188(%rbx), %xmm4
movapd %xmm4, %xmm5
divpd %xmm3, %xmm5
subpd %xmm5, %xmm4
movupd 0xd0(%rbx), %xmm5
addpd %xmm4, %xmm5
movupd %xmm5, 0x188(%rbx)
movupd 0x1b8(%rbx), %xmm4
movupd 0x198(%rbx), %xmm6
movapd %xmm6, %xmm7
divpd %xmm4, %xmm7
subpd %xmm7, %xmm6
movupd 0xe0(%rbx), %xmm7
addpd %xmm6, %xmm7
movupd %xmm7, 0x198(%rbx)
movapd %xmm5, %xmm6
unpcklpd %xmm7, %xmm6            # xmm6 = xmm6[0],xmm7[0]
movhlps %xmm5, %xmm7            # xmm7 = xmm5[1],xmm7[1]
subpd %xmm7, %xmm6
movapd %xmm3, %xmm5
unpcklpd %xmm4, %xmm5            # xmm5 = xmm5[0],xmm4[0]
unpckhpd %xmm4, %xmm3            # xmm3 = xmm3[1],xmm4[1]
subpd %xmm3, %xmm5
divpd %xmm5, %xmm6
movapd %xmm6, %xmm4
unpckhpd %xmm6, %xmm4            # xmm4 = xmm4[1],xmm6[1]
addsd %xmm6, %xmm4
movsd 0x1d8(%rbx), %xmm3
mulsd %xmm4, %xmm3
divsd %xmm2, %xmm3
addsd %xmm1, %xmm3
movsd %xmm3, 0x168(%rbx)
movsd %xmm4, 0x1f8(%rbx)
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm4
jbe 0x748e
movb $0x1, 0x1e8(%rbx)
movl 0x208(%rbx), %ecx
testl %ecx, %ecx
jle 0x74b7
decl %ecx
movl %ecx, 0x208(%rbx)
movq $0x0, 0x168(%rbx)
movb $0x0, 0x130(%rbx)
jmp 0x7623
movb $0x0, 0x130(%rbx)
ucomisd 0x1d0(%rbx), %xmm3
jbe 0x7602
addsd 0x101e4(%rip), %xmm0    # 0x176b8
movsd %xmm0, 0x178(%rbx)
movq 0x18(%rbx), %r15
movq 0x20(%rbx), %r12
cmpq %r12, %r15
je 0x7516
movq (%r15), %r14
movq %r14, %rdi
callq 0xc180
cmpl $0x0, 0x8(%rax)
je 0x7509
cmpb $0x0, 0x13(%r14)
jne 0x7509
movq %r14, %rdi
callq 0xc18e
addq $0x8, %r15
cmpq %r12, %r15
jne 0x74e9
movq 0x10(%rbx), %rax
movb $0x1, 0x130(%rbx)
movq $0x0, 0x168(%rbx)
movl $0x2, 0x208(%rbx)
movzbl (%rax), %eax
cmpl $0x6f, %eax
je 0x753f
cmpl $0x68, %eax
jne 0x755a
incl 0x12c(%rbx)
movq 0x90(%rbx), %rsi
cmpq %rsi, 0x88(%rbx)
je 0x7562
movl -0x4(%rsi), %eax
jmp 0x7567
incl 0x12c(%rbx)
jmp 0x7598
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpl %ebp, %eax
jge 0x7630
cmpq 0x98(%rbx), %rsi
je 0x7587
movl %ebp, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x90(%rbx)
jmp 0x7598
leaq 0x88(%rbx), %rdi
leaq 0xc(%rsp), %rdx
callq 0x4500
cmpl $0x2, 0x8(%rbx)
jne 0x7602
movsd 0x200(%rbx), %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x75b2
jnp 0x7602
movq 0x210(%rbx), %rdi
testq %rdi, %rdi
jne 0x75f9
movq 0x19a0b(%rip), %r14     # 0x20fd0
leaq 0x10203(%rip), %rsi     # 0x177cf
movl $0x2f, %edx
movq %r14, %rdi
callq 0x3340
movq 0x10(%rbx), %rsi
movq %r14, %rdi
callq 0x32c0
movq %rax, %rdi
callq 0x3160
movq 0x210(%rbx), %rdi
testq %rdi, %rdi
je 0x764f
movl 0xc(%rsp), %esi
callq 0x3d3c
cmpb $0x1, 0x140(%rbx)
jne 0x7623
movq 0x120(%rbx), %rax
cmpl $0x0, 0x2c0(%rax)
jne 0x7623
movq %rbx, %rdi
callq 0x766e
addq $0x10, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1011a(%rip), %rdi     # 0x17751
leaq 0x1014b(%rip), %rsi     # 0x17789
leaq 0x1014d(%rip), %rcx     # 0x17792
movl $0x18e, %edx            # imm = 0x18E
callq 0x31b0
leaq 0x101a9(%rip), %rdi     # 0x177ff
leaq 0x1012c(%rip), %rsi     # 0x17789
leaq 0x1012e(%rip), %rcx     # 0x17792
movl $0x197, %edx            # imm = 0x197
callq 0x31b0