// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x60, %rsp
movb %cl, %al
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
andb $0x1, %al
movb %al, -0x19(%rbp)
movl %r8d, -0x20(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x48(%rbp)
cmpl $0x0, 0x8(%rax)
jne 0xc3d1
jmp 0xc97c
movq -0x48(%rbp), %rax
cmpl $0x1, 0x8(%rax)
jne 0xc4f1
movq -0x48(%rbp), %rax
cmpl $0x1, 0x8(%rax)
je 0xc435
movq -0x48(%rbp), %rax
movsd 0x168(%rax), %xmm0
movsd %xmm0, 0x170(%rax)
movsd 0x178(%rax), %xmm0
movsd %xmm0, 0x180(%rax)
movsd 0x178(%rax), %xmm1
movsd 0x28173(%rip), %xmm0    # 0x34590
divsd %xmm0, %xmm1
movsd 0x178(%rax), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, 0x178(%rax)
movq -0x48(%rbp), %rax
cmpl $-0x1, 0x218(%rax)
jne 0xc447
jmp 0xc97c
movq -0x48(%rbp), %rcx
movl -0xc(%rbp), %eax
cmpl 0x218(%rcx), %eax
jge 0xc45b
jmp 0xc97c
movq -0x48(%rbp), %rax
cmpl $0x1, 0x8(%rax)
je 0xc481
movq -0x48(%rbp), %rax
movsd 0x2814f(%rip), %xmm0    # 0x345c0
addsd 0x178(%rax), %xmm0
movsd %xmm0, 0x178(%rax)
movq -0x48(%rbp), %rdi
movl -0xc(%rbp), %edx
movb -0x19(%rbp), %al
movl $0x1, %esi
andb $0x1, %al
movzbl %al, %ecx
callq 0x121a0
movq -0x48(%rbp), %rax
movb $0x1, 0x130(%rax)
movq 0x210(%rax), %rdi
callq 0x4e00
movl %eax, %ecx
movq -0x48(%rbp), %rax
movl %ecx, 0x218(%rax)
cmpl $-0x1, 0x218(%rax)
jne 0xc4ec
movq -0x48(%rbp), %rax
movq 0x120(%rax), %rcx
movq %rcx, -0x50(%rbp)
movq 0x210(%rax), %rdi
callq 0x122c0
movq -0x50(%rbp), %rdi
movl %eax, %esi
callq 0x235a0
jmp 0xc97c
movq -0x48(%rbp), %rax
movsd 0x168(%rax), %xmm0
movsd %xmm0, 0x170(%rax)
movsd 0x178(%rax), %xmm0
movsd %xmm0, 0x180(%rax)
movsd 0x178(%rax), %xmm1
movsd 0x2806b(%rip), %xmm0    # 0x34590
divsd %xmm0, %xmm1
movsd 0x178(%rax), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, 0x178(%rax)
cmpl $0x1, 0x114(%rax)
jne 0xc57a
movq -0x48(%rbp), %rax
movsd 0x2804e(%rip), %xmm0    # 0x345a0
ucomisd 0x178(%rax), %xmm0
jbe 0xc57a
movq -0x48(%rbp), %rax
movsd 0x28050(%rip), %xmm0    # 0x345b8
addsd 0x168(%rax), %xmm0
movsd %xmm0, 0x168(%rax)
jmp 0xc5c3
movq -0x48(%rbp), %rax
cmpl $-0x1, 0x114(%rax)
jne 0xc5c1
movq -0x48(%rbp), %rax
movsd 0x178(%rax), %xmm0
movsd 0x2800d(%rip), %xmm1    # 0x345a8
ucomisd %xmm1, %xmm0
jbe 0xc5c1
movq -0x48(%rbp), %rax
movsd 0x168(%rax), %xmm0
movsd 0x27ffb(%rip), %xmm1    # 0x345b0
subsd %xmm1, %xmm0
movsd %xmm0, 0x168(%rax)
jmp 0xc5c3
leaq -0x28(%rbp), %rdi
callq 0x122e0
movq -0x48(%rbp), %rax
movq 0x10(%rax), %rax
movsbl (%rax), %eax
cmpl $0x72, %eax
jne 0xc5f9
movq -0x48(%rbp), %rdi
movq %rdi, %rsi
addq $0x168, %rsi            # imm = 0x168
movsd 0x1f0(%rdi), %xmm0
callq 0x12300
jmp 0xc611
movq -0x48(%rbp), %rdi
movq %rdi, %rsi
addq $0x168, %rsi            # imm = 0x168
movl $0x40, %edx
callq 0x12330
movq -0x48(%rbp), %rdi
movq %rdi, %rsi
addq $0x188, %rsi            # imm = 0x188
movsd 0x1a8(%rdi), %xmm0
callq 0x12300
movq -0x48(%rbp), %rdi
movq %rdi, %rsi
addq $0x190, %rsi            # imm = 0x190
movsd 0x1b0(%rdi), %xmm0
callq 0x12300
movq -0x48(%rbp), %rdi
movq %rdi, %rsi
addq $0x198, %rsi            # imm = 0x198
movsd 0x1b8(%rdi), %xmm0
callq 0x12300
movq -0x48(%rbp), %rdi
movq %rdi, %rsi
addq $0x1a0, %rsi            # imm = 0x1A0
movsd 0x1c0(%rdi), %xmm0
callq 0x12300
movq -0x48(%rbp), %rdi
movsd 0xd0(%rdi), %xmm0
addsd 0x188(%rdi), %xmm0
movsd %xmm0, 0x188(%rdi)
movsd 0xd8(%rdi), %xmm0
addsd 0x190(%rdi), %xmm0
movsd %xmm0, 0x190(%rdi)
movsd 0xe0(%rdi), %xmm0
addsd 0x198(%rdi), %xmm0
movsd %xmm0, 0x198(%rdi)
movsd 0xe8(%rdi), %xmm0
addsd 0x1a0(%rdi), %xmm0
movsd %xmm0, 0x1a0(%rdi)
callq 0x12370
movq -0x48(%rbp), %rax
movsd %xmm0, -0x40(%rbp)
movsd 0x1d8(%rax), %xmm0
mulsd -0x40(%rbp), %xmm0
divsd 0x1f0(%rax), %xmm0
addsd 0x168(%rax), %xmm0
movsd %xmm0, 0x168(%rax)
movsd -0x40(%rbp), %xmm0
movsd %xmm0, 0x1f8(%rax)
movsd -0x40(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0xc73a
movq -0x48(%rbp), %rax
movb $0x1, 0x1e8(%rax)
movq -0x48(%rbp), %rax
cmpl $0x0, 0x208(%rax)
jle 0xc771
movq -0x48(%rbp), %rax
movl 0x208(%rax), %ecx
addl $-0x1, %ecx
movl %ecx, 0x208(%rax)
xorps %xmm0, %xmm0
movsd %xmm0, 0x168(%rax)
movb $0x0, 0x130(%rax)
jmp 0xc97c
movq -0x48(%rbp), %rax
movb $0x0, 0x130(%rax)
movsd 0x168(%rax), %xmm0
ucomisd 0x1d0(%rax), %xmm0
jbe 0xc94e
movq -0x48(%rbp), %rdi
movsd 0x27e22(%rip), %xmm0    # 0x345c0
addsd 0x178(%rdi), %xmm0
movsd %xmm0, 0x178(%rdi)
movl -0xc(%rbp), %edx
movb -0x19(%rbp), %al
xorl %esi, %esi
andb $0x1, %al
movzbl %al, %ecx
callq 0x121a0
movq -0x48(%rbp), %rax
movb $0x1, 0x130(%rax)
xorps %xmm0, %xmm0
movsd %xmm0, 0x168(%rax)
movl $0x2, 0x208(%rax)
movq 0x10(%rax), %rax
movsbl (%rax), %eax
cmpl $0x6f, %eax
je 0xc800
movq -0x48(%rbp), %rax
movq 0x10(%rax), %rax
movsbl (%rax), %eax
cmpl $0x68, %eax
jne 0xc88b
movq -0x48(%rbp), %rdi
movl 0x12c(%rdi), %eax
addl $0x1, %eax
movl %eax, 0x12c(%rdi)
movl -0xc(%rbp), %eax
movl %eax, -0x54(%rbp)
addq $0x88, %rdi
callq 0x56b0
testb $0x1, %al
jne 0xc82b
jmp 0xc835
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl %eax, -0x58(%rbp)
jmp 0xc84a
movq -0x48(%rbp), %rdi
addq $0x88, %rdi
callq 0x6ce0
movl (%rax), %eax
movl %eax, -0x58(%rbp)
movl -0x54(%rbp), %eax
movl -0x58(%rbp), %ecx
cmpl %ecx, %eax
jle 0xc856
jmp 0xc875
leaq 0x27e0c(%rip), %rdi     # 0x34669
leaq 0x27e3d(%rip), %rsi     # 0x346a1
movl $0x18e, %edx            # imm = 0x18E
leaq 0x27e3a(%rip), %rcx     # 0x346aa
callq 0x4210
movq -0x48(%rbp), %rdi
addq $0x88, %rdi
leaq -0xc(%rbp), %rsi
callq 0x5640
jmp 0xc89e
movq -0x48(%rbp), %rax
movl 0x12c(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x12c(%rax)
movq -0x48(%rbp), %rax
cmpl $0x2, 0x8(%rax)
jne 0xc94c
movq -0x48(%rbp), %rax
movsd 0x200(%rax), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0xc8c8
jp 0xc8c8
jmp 0xc94c
movq -0x48(%rbp), %rax
cmpq $0x0, 0x210(%rax)
jne 0xc939
movq 0x406eb(%rip), %rdi     # 0x4cfc8
leaq 0x27e03(%rip), %rsi     # 0x346e7
callq 0x4360
movq %rax, %rdi
movq -0x48(%rbp), %rax
movq 0x10(%rax), %rsi
callq 0x4360
movq %rax, %rdi
movq 0x406b5(%rip), %rsi     # 0x4cfb8
callq 0x43b0
movq -0x48(%rbp), %rax
cmpq $0x0, 0x210(%rax)
je 0xc918
jmp 0xc937
leaq 0x27df8(%rip), %rdi     # 0x34717
leaq 0x27d7b(%rip), %rsi     # 0x346a1
movl $0x197, %edx            # imm = 0x197
leaq 0x27d78(%rip), %rcx     # 0x346aa
callq 0x4210
jmp 0xc939
movq -0x48(%rbp), %rax
movq 0x210(%rax), %rdi
movl -0xc(%rbp), %esi
callq 0x4c60
jmp 0xc94e
movq -0x48(%rbp), %rax
testb $0x1, 0x140(%rax)
je 0xc97c
movq -0x48(%rbp), %rax
movq 0x120(%rax), %rdi
callq 0x123d0
cmpl $0x0, %eax
jne 0xc97c
movq -0x48(%rbp), %rdi
movl -0xc(%rbp), %esi
callq 0xc990
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)