// File: /workspace/github_cpp_makefile_star2_O1/sus304[P]ForRocket/src/solver/rocket_stage.cpp
// Function: forrocket::RocketStage::FlightSequence(forrocket::SequenceClock*, forrocket::EnvironmentWind*, std::array<double, 14ul>&)
void forrocket::RocketStage::FlightSequence(SequenceClock* master_clock, EnvironmentWind* wind, DynamicsBase::state& x0) {
    namespace odeint = boost::numeric::odeint;

    // Sterpper Select
    ////////////////////////////////////
    double eps_abs = 1.0e-12;
    double eps_rel = 1.0e-7;
    // 4th Order Runge-Kutta Method
    // odeint::runge_kutta4<forrocket::DynamicsBase::state> stepper;

    // 5th Order Runge-Kutta-Dormand-Prince Method : Controled : Dense output : Internal info
    using base_stepper_type = odeint::runge_kutta_dopri5<forrocket::DynamicsBase::state>;
    auto stepper = make_controlled( eps_abs , eps_rel , base_stepper_type());

    // 8th Order Runge-Kutta-Fehlberg Method : Controled
    // using base_stepper_type = odeint::runge_kutta_fehlberg78<forrocket::DynamicsBase::state>;
    // auto stepper = make_controlled( eps_abs , eps_rel , base_stepper_type());

    // Dynamics6dofAero dynamics_6dof_aero(&rocket, master_clock, wind);
    // Dynamics6dofProgramRate dynamics_6dof_programrate(&rocket, master_clock, wind);
    DynamicsBase* p_dynamics;
    p_dynamics = new Dynamics6dofAero(&rocket, master_clock, wind);

    double start, end;
    double time_step_on_launcher = 0.001;  // 1000 Hz
    double time_step_decent_parachute = 0.1;  // 10 Hz
    fdr.ReserveCapacity(static_cast<int>((time_end - time_start) / time_step) * 1.3);

    DynamicsBase::state x0_in_stage = x0;  // x0はソルバで次段のために共有するので内部用にコピー

    if (time_ignittion <= time_start) {
        // 計算開始と同時に点火する場合
        rocket.IgnitionEngine(master_clock->UTC_date_init, master_clock->countup_time);
        start = time_start;
    } else {
        // 点火が計算開始より後の場合
        // Flight start から engine ignittion まで
        SwitchDynamics(time_start, &p_dynamics, master_clock, wind);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, time_start, time_ignittion, time_step, std::ref(fdr)); // 点火までの慣性飛行計算
        start = time_ignittion;
        rocket.IgnitionEngine(master_clock->UTC_date_init, master_clock->countup_time);
    }
    // ここまでにIgnitionEngineが実行されている

    if (enable_launcher) {
        // ランチクリア時刻確定のためにコピー品で短時間回す
        Rocket rocket_on_launcher = rocket;
        SequenceClock clock_on_launcher = *master_clock; // copy
        DynamicsBase::state x0_on_launcher = x0;
        FlightDataRecorder fdr_on_launcher(&rocket_on_launcher);
        p_dynamics = new Dynamics3dofOnLauncher(&rocket_on_launcher, &clock_on_launcher);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_on_launcher, start, start+1.0, time_step_on_launcher, std::ref(fdr_on_launcher));
        
        # ifdef DEBUG_NO
        fdr_on_launcher.dump_csv("test_estimate_launcher.csv");
        # endif
        
        for (int i=0; i < fdr_on_launcher.countup_burn_time.size(); ++i) {
            double distance = (fdr_on_launcher.position[i].LLH(2) - fdr_on_launcher.position[0].LLH(2)) / sin(fdr_on_launcher.attitude[i].euler_angle(1));
            if (distance >= length_launcher_rail) {
                end = time_step_on_launcher * i;
                break;
            }
        }

        // ランチャ滑走の本ちゃん
        p_dynamics = new Dynamics3dofOnLauncher(&rocket, master_clock);
        stepper.initialize(std::ref(*p_dynamics), x0_in_stage, start);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, start + end, time_step_on_launcher, std::ref(fdr));
        // odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, start + end, time_step_on_launcher, std::ref(fdr));
        start = start + end;
        #ifdef DEBUG
        fdr.dump_csv("debug_onlauncher_log.csv");
        #endif
    }
    // ここまでに慣性飛行からの点火もしくはランチクリアまでが実行されている
    
    if (enable_cutoff) {
        // engine cutoff まで 
        SwitchDynamics(start, &p_dynamics, master_clock, wind);
        stepper.initialize(std::ref(*p_dynamics), x0_in_stage, start);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, time_cutoff, time_step, std::ref(fdr));
        start = time_cutoff;
        rocket.CutoffEngine();
    }
    // enable_cutoff=false の場合は質量0で自動cutoffされる（Engineクラス側）

    if (enable_despin) {
        SwitchDynamics(start, &p_dynamics, master_clock, wind);
        stepper.initialize(std::ref(*p_dynamics), x0_in_stage, start);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, time_despin, time_step, std::ref(fdr));
        start = time_despin;
        rocket.DeSpin();
    }

    if (enable_fairing_jettson) {
        SwitchDynamics(start, &p_dynamics, master_clock, wind);
        stepper.initialize(std::ref(*p_dynamics), x0_in_stage, start);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, time_jettson_fairing, time_step, std::ref(fdr));
        start = time_jettson_fairing;
        rocket.JettsonFairing(mass_fairing);
    }

    if (enable_sepation) {
        SwitchDynamics(start, &p_dynamics, master_clock, wind);
        stepper.initialize(std::ref(*p_dynamics), x0_in_stage, start);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, time_separation, time_step, std::ref(fdr));
        start = time_separation;
        rocket.SeparateUpperStage(mass_upper_stage);
        x0 = x0_in_stage;  // 次段のために分離情報をコピー
    }

    if (!enable_parachute_open) {
        // 弾道で落ちるまで
        SwitchDynamics(start, &p_dynamics, master_clock, wind);
        stepper.initialize(std::ref(*p_dynamics), x0_in_stage, start);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, time_end, time_step, std::ref(fdr));
    } else {
        // パラシュート開傘
        if (enable_apogee_parachute_open) {
            // 頂点時刻確定のためにコピー品で回す
            Rocket rocket_apogee_estimate = rocket;
            SequenceClock clock_apogee_estimate = *master_clock; // copy
            DynamicsBase::state x0_apogee_estimate = x0;
            FlightDataRecorder fdr_apogee_estimate(&rocket_apogee_estimate);
            if (enable_program_attitude) {
                p_dynamics = new Dynamics6dofProgramRate(&rocket, &clock_apogee_estimate, wind);
            } else {
                p_dynamics = new Dynamics6dofAero(&rocket, &clock_apogee_estimate, wind);
            }
            odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_apogee_estimate, start, time_end, time_step, std::ref(fdr_apogee_estimate));
            double max_alt = 0.0;
            for (int i=0; i < fdr_apogee_estimate.position.size(); ++i) {
                double alt = fdr_apogee_estimate.position[i].LLH(2);
                if (max_alt < alt) {
                    max_alt = alt;
                } else {
                    end = fdr_apogee_estimate.countup_time[i];
                    break;
                }
            }
        } else {
            end = time_open_parachute;
        }
        // 開傘までの慣性飛行本ちゃん
        SwitchDynamics(start, &p_dynamics, master_clock, wind);
        stepper.initialize(std::ref(*p_dynamics), x0_in_stage, start);
        odeint::integrate_const(stepper, std::ref(*p_dynamics), x0_in_stage, start, end, time_step, std::ref(fdr));
        start = end;

        // ここまでで頂点もしくは開傘時刻まで実行されている
        odeint::runge_kutta4<forrocket::DynamicsBase::state> stepper;
        rocket.OpenParachute();
        Dynamics3dofParachute dynamics_3dof_parachute(&rocket, master_clock, wind);

        if (exist_second_parachute) {
            odeint::integrate_const(stepper, dynamics_3dof_parachute, x0_in_stage, start, time_open_second_parachute, time_step_decent_parachute, std::ref(fdr));
            rocket.OpenParachute();
            odeint::integrate_const(stepper, dynamics_3dof_parachute, x0_in_stage, time_open_second_parachute, time_end, time_step_decent_parachute, std::ref(fdr));
        } else {
            odeint::integrate_const(stepper, dynamics_3dof_parachute, x0_in_stage, start, time_end, time_step_decent_parachute, std::ref(fdr));
        }
    }

    // fdr.dump_csv("flight_log_stage"+std::to_string(stage_number)+".csv");
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1e08, %rsp           # imm = 0x1E08
movq %rcx, %r12
movq %rdx, %r15
movq %rsi, %r13
movq %rdi, %r14
movw $0x100, 0xa09(%rsp)     # imm = 0x100
movw $0x0, 0xd90(%rsp)
movabsq $0x3d719799812dea11, %rax # imm = 0x3D719799812DEA11
movq %rax, 0xd98(%rsp)
movabsq $0x3e7ad7f29abcaf48, %rax # imm = 0x3E7AD7F29ABCAF48
movq %rax, 0xda0(%rsp)
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq %rax, 0xda8(%rsp)
movq %rax, 0xdb0(%rsp)
movq $0x0, 0xdb8(%rsp)
movl $0x0, 0xdc0(%rsp)
movb $0x1, 0xf88(%rsp)
movl $0x20, %edi
callq 0x5340
movq %rax, %rbp
leaq 0x10(%r14), %rbx
movq %rax, %rdi
movq %rbx, %rsi
movq %r13, %rdx
movq %r15, 0x5a8(%rsp)
movq %r15, %rcx
callq 0x2433c
movq %rbp, 0x5a0(%rsp)
leaq 0xe80(%r14), %rdi
movsd 0x11f8(%r14), %xmm0
subsd 0x1150(%r14), %xmm0
divsd 0x1200(%r14), %xmm0
cvttpd2dq %xmm0, %xmm0
cvtdq2pd %xmm0, %xmm0
mulsd 0xea96(%rip), %xmm0     # 0x3d1f8
cvttsd2si %xmm0, %esi
movq %rdi, 0x598(%rsp)
callq 0x1be4c
leaq 0x5d0(%rsp), %rdi
movl $0xe, %ecx
movq %r12, %rsi
rep  movsq (%rsi), %es:(%rdi)
movsd 0x1150(%r14), %xmm0
ucomisd 0x1158(%r14), %xmm0
movq %r12, %r15
jae 0x2e842
leaq 0x5a0(%rsp), %rbp
movq %r14, %rdi
movq %rbp, %rsi
movq %r13, %rdx
movq 0x5a8(%rsp), %rcx
callq 0x2e5ae
movq (%rbp), %rax
movsd 0x1150(%r14), %xmm0
movsd 0x1158(%r14), %xmm1
movsd 0x1200(%r14), %xmm2
leaq 0xa08(%rsp), %rsi
movl $0xb1, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x5d0(%rsp), %rsi
movq %rax, %rdi
movq 0x598(%rsp), %rdx
callq 0x3010d
movsd 0x1158(%r14), %xmm0
movsd %xmm0, 0x5b8(%rsp)
leaq 0x18(%r13), %rsi
leaq 0x700(%rsp), %rbp
movq %rbp, %rdi
callq 0x17896
movsd 0x38(%r13), %xmm0
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x21384
jmp 0x2e879
leaq 0x18(%r13), %rsi
leaq 0x71c(%rsp), %rbp
movq %rbp, %rdi
callq 0x17896
movsd 0x38(%r13), %xmm0
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x21384
movsd 0x1150(%r14), %xmm0
movsd %xmm0, 0x5b8(%rsp)
cmpb $0x1, 0x1160(%r14)
movq %rbx, 0x5b0(%rsp)
jne 0x2ea3c
leaq 0xf90(%rsp), %rdi
movq %rbx, %rsi
callq 0x2fa64
movq 0x10(%r13), %rax
leaq 0x658(%rsp), %rdi
movq %rax, -0x8(%rdi)
movupd (%r13), %xmm0
movapd %xmm0, -0x18(%rdi)
leaq 0x18(%r13), %rsi
callq 0x17896
movupd 0x38(%r13), %xmm0
movupd %xmm0, 0x678(%rsp)
leaq 0x690(%rsp), %rdi
movl $0xe, %ecx
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x738(%rsp), %rdi
leaq 0xf90(%rsp), %rsi
callq 0x1bdec
movl $0x18, %edi
callq 0x5340
movq %rax, %rbp
leaq 0xf90(%rsp), %rsi
leaq 0x640(%rsp), %rdx
movq %rax, %rdi
callq 0x21dac
movq %rbp, 0x5a0(%rsp)
movsd 0xbdb1(%rip), %xmm1     # 0x3a6e0
movsd 0x5b8(%rsp), %xmm0
addsd %xmm0, %xmm1
leaq 0xa08(%rsp), %rsi
movl $0xb1, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x690(%rsp), %rsi
movsd 0xe8a1(%rip), %xmm2     # 0x3d200
leaq 0x738(%rsp), %rdx
movq %rbp, %rdi
callq 0x3010d
movq 0x760(%rsp), %rax
cmpq 0x758(%rsp), %rax
je 0x2ea53
movl $0x8, %ebx
movl $0x40, %r12d
xorl %ebp, %ebp
movq 0x8e8(%rsp), %rax
movq 0x960(%rsp), %rcx
movsd (%rax,%r12), %xmm0
subsd 0x40(%rax), %xmm0
movsd %xmm0, 0x590(%rsp)
movsd (%rcx,%rbx), %xmm0
callq 0x50e0
movsd 0x590(%rsp), %xmm1
divsd %xmm0, %xmm1
movsd 0x1168(%r14), %xmm0
ucomisd %xmm0, %xmm1
movapd %xmm1, %xmm2
xorps %xmm1, %xmm1
cvtsi2sd %ebp, %xmm1
mulsd 0xe813(%rip), %xmm1     # 0x3d200
cmpnlesd %xmm2, %xmm0
movapd 0x5c0(%rsp), %xmm2
andpd %xmm0, %xmm2
andnpd %xmm1, %xmm0
orpd %xmm0, %xmm2
movapd %xmm2, 0x5c0(%rsp)
jae 0x2ea53
incq %rbp
movq 0x760(%rsp), %rax
subq 0x758(%rsp), %rax
sarq $0x3, %rax
addq $0x40, %rbx
addq $0x48, %r12
cmpq %rbp, %rax
ja 0x2e992
jmp 0x2ea53
movsd 0x5b8(%rsp), %xmm0
movsd %xmm0, 0x590(%rsp)
jmp 0x2eb13
movl $0x18, %edi
callq 0x5340
movq 0x5b0(%rsp), %rbx
movq %rax, %rbp
movq %rax, %rdi
movq %rbx, %rsi
movq %r13, %rdx
callq 0x21dac
movq %rbp, 0x5a0(%rsp)
leaq 0xdc8(%rsp), %rdx
movq (%rbp), %rax
leaq 0x5d0(%rsp), %rsi
movq %rbp, %rdi
movsd 0x5b8(%rsp), %xmm0
callq *(%rax)
leaq 0xa08(%rsp), %rsi
movb $0x0, 0x580(%rsi)
movsd 0x5b8(%rsp), %xmm0
movapd %xmm0, %xmm1
addsd 0x5c0(%rsp), %xmm1
movl $0xb1, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x5d0(%rsp), %rsi
movsd 0xe720(%rip), %xmm2     # 0x3d200
movq %rbp, %rdi
movsd %xmm1, 0x590(%rsp)
movq 0x598(%rsp), %rdx
callq 0x3010d
leaq 0x738(%rsp), %rdi
callq 0x2e1fe
leaq 0xf90(%rsp), %rdi
callq 0x2c6b0
cmpb $0x1, 0x1170(%r14)
jne 0x2ebde
leaq 0x5a0(%rsp), %rbp
movq %r14, %rdi
movsd 0x590(%rsp), %xmm0
movq %rbp, %rsi
movq %r13, %rdx
movq 0x5a8(%rsp), %rcx
callq 0x2e5ae
movq (%rbp), %rbp
leaq 0xdc8(%rsp), %rbx
movq (%rbp), %rax
leaq 0x5d0(%rsp), %r12
movq %rbp, %rdi
movq %r12, %rsi
movq %rbx, %rdx
movsd 0x590(%rsp), %xmm0
callq *(%rax)
movb $0x0, 0x1c0(%rbx)
movq 0x5b0(%rsp), %rbx
movsd 0x1178(%r14), %xmm1
movsd 0x1200(%r14), %xmm2
leaq 0xa08(%rsp), %rsi
movl $0xb1, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %rbp, %rdi
movq %r12, %rsi
movsd 0x590(%rsp), %xmm0
movq 0x598(%rsp), %rdx
callq 0x3010d
movsd 0x1178(%r14), %xmm0
movsd %xmm0, 0x590(%rsp)
movq %rbx, %rdi
callq 0x213f6
cmpb $0x1, 0x11b0(%r14)
jne 0x2eca9
leaq 0x5a0(%rsp), %rbx
movq %r14, %rdi
movsd 0x590(%rsp), %xmm0
movq %rbx, %rsi
movq %r13, %rdx
movq 0x5a8(%rsp), %rcx
callq 0x2e5ae
movq (%rbx), %rbx
leaq 0xdc8(%rsp), %r12
movq (%rbx), %rax
leaq 0x5d0(%rsp), %rbp
movq %rbx, %rdi
movq %rbp, %rsi
movq %r12, %rdx
movsd 0x590(%rsp), %xmm0
callq *(%rax)
movb $0x0, 0x1c0(%r12)
movsd 0x11b8(%r14), %xmm1
movsd 0x1200(%r14), %xmm2
leaq 0xa08(%rsp), %rsi
movl $0xb1, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %rbx, %rdi
movq 0x5b0(%rsp), %rbx
movq %rbp, %rsi
movsd 0x590(%rsp), %xmm0
movq 0x598(%rsp), %rdx
callq 0x3010d
movsd 0x11b8(%r14), %xmm0
movsd %xmm0, 0x590(%rsp)
movq %rbx, %rdi
callq 0x21400
cmpb $0x1, 0x11c0(%r14)
jne 0x2ed7d
leaq 0x5a0(%rsp), %rbx
movq %r14, %rdi
movsd 0x590(%rsp), %xmm0
movq %rbx, %rsi
movq %r13, %rdx
movq 0x5a8(%rsp), %rcx
callq 0x2e5ae
movq (%rbx), %rbx
leaq 0xdc8(%rsp), %r12
movq (%rbx), %rax
leaq 0x5d0(%rsp), %rbp
movq %rbx, %rdi
movq %rbp, %rsi
movq %r12, %rdx
movsd 0x590(%rsp), %xmm0
callq *(%rax)
movb $0x0, 0x1c0(%r12)
movsd 0x11c8(%r14), %xmm1
movsd 0x1200(%r14), %xmm2
leaq 0xa08(%rsp), %rsi
movl $0xb1, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %rbx, %rdi
movq 0x5b0(%rsp), %rbx
movq %rbp, %rsi
movsd 0x590(%rsp), %xmm0
movq 0x598(%rsp), %rdx
callq 0x3010d
movsd 0x11c8(%r14), %xmm0
movsd %xmm0, 0x590(%rsp)
movsd 0x11d0(%r14), %xmm0
movq %rbx, %rdi
callq 0x21412
cmpb $0x1, 0x1198(%r14)
jne 0x2ee5f
leaq 0x5a0(%rsp), %rbx
movq %r14, %rdi
movsd 0x590(%rsp), %xmm0
movq %rbx, %rsi
movq %r13, %rdx
movq 0x5a8(%rsp), %rcx
callq 0x2e5ae
movq (%rbx), %rbx
leaq 0xdc8(%rsp), %r12
movq (%rbx), %rax
leaq 0x5d0(%rsp), %rbp
movq %rbx, %rdi
movq %rbp, %rsi
movq %r12, %rdx
movsd 0x590(%rsp), %xmm0
callq *(%rax)
movb $0x0, 0x1c0(%r12)
movsd 0x11a0(%r14), %xmm1
movsd 0x1200(%r14), %xmm2
leaq 0xa08(%rsp), %rsi
movl $0xb1, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %rbx, %rdi
movq 0x5b0(%rsp), %rbx
movq %rbp, %rsi
movsd 0x590(%rsp), %xmm0
movq 0x598(%rsp), %rdx
callq 0x3010d
movsd 0x11a0(%r14), %xmm0
movsd %xmm0, 0x590(%rsp)
movsd 0x11a8(%r14), %xmm0
movq %rbx, %rdi
callq 0x21448
movl $0xe, %ecx
movq %r15, %rdi
movq %rbp, %rsi
rep  movsq (%rsi), %es:(%rdi)
cmpb $0x0, 0x11d8(%r14)
je 0x2ef21
cmpb $0x1, 0x11d9(%r14)
jne 0x2efc0
leaq 0xf90(%rsp), %rdi
movq %rbx, %rsi
callq 0x2fa64
movq 0x10(%r13), %rax
leaq 0x658(%rsp), %rdi
movq %rax, -0x8(%rdi)
movupd (%r13), %xmm0
movapd %xmm0, -0x18(%rdi)
leaq 0x18(%r13), %rsi
callq 0x17896
movupd 0x38(%r13), %xmm0
movupd %xmm0, 0x678(%rsp)
leaq 0x690(%rsp), %rdi
movl $0xe, %ecx
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x738(%rsp), %rdi
leaq 0xf90(%rsp), %rsi
callq 0x1bdec
cmpb $0x1, 0x1180(%r14)
jne 0x2efd7
movl $0x20, %edi
callq 0x5340
movq %rax, %rbp
leaq 0x640(%rsp), %rdx
movq %rax, %rdi
movq %rbx, %rsi
movq 0x5a8(%rsp), %rcx
callq 0x2565c
jmp 0x2efff
leaq 0x5a0(%rsp), %rbx
movq %r14, %rdi
movsd 0x590(%rsp), %xmm0
movq %rbx, %rsi
movq %r13, %rdx
movq 0x5a8(%rsp), %rcx
callq 0x2e5ae
movq (%rbx), %rbx
leaq 0xdc8(%rsp), %r15
movq (%rbx), %rax
leaq 0x5d0(%rsp), %r12
movq %rbx, %rdi
movq %r12, %rsi
movq %r15, %rdx
movsd 0x590(%rsp), %xmm0
callq *(%rax)
movb $0x0, 0x1c0(%r15)
movsd 0x11f8(%r14), %xmm1
movsd 0x1200(%r14), %xmm2
leaq 0xa08(%rsp), %rsi
movl $0xb1, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %rbx, %rdi
movq %r12, %rsi
movsd 0x590(%rsp), %xmm0
movq 0x598(%rsp), %rdx
callq 0x3010d
jmp 0x2f494
movsd 0x11e0(%r14), %xmm0
movapd %xmm0, 0x5c0(%rsp)
jmp 0x2f0e1
movl $0x20, %edi
callq 0x5340
movq %rax, %rbp
leaq 0x640(%rsp), %rdx
movq %rax, %rdi
movq %rbx, %rsi
movq 0x5a8(%rsp), %rcx
callq 0x2433c
movq %rbp, 0x5a0(%rsp)
movsd 0x11f8(%r14), %xmm1
movsd 0x1200(%r14), %xmm2
leaq 0xa08(%rsp), %rsi
movl $0xb1, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x690(%rsp), %rsi
leaq 0x738(%rsp), %rdx
movq %rbp, %rdi
movsd 0x590(%rsp), %xmm0
callq 0x3010d
movq 0x8e8(%rsp), %rax
movq 0x8f0(%rsp), %rdx
subq %rax, %rdx
je 0x2f0c7
sarq $0x3, %rdx
movabsq $-0x71c71c71c71c71c7, %rcx # imm = 0x8E38E38E38E38E39
imulq %rdx, %rcx
cmpq $0x1, %rcx
adcq $-0x1, %rcx
movq 0x740(%rsp), %rdx
addq $0x40, %rax
xorpd %xmm0, %xmm0
xorl %esi, %esi
movsd (%rax), %xmm2
ucomisd %xmm0, %xmm2
movapd %xmm2, %xmm1
ja 0x2f0ad
movsd (%rdx,%rsi,8), %xmm1
movaps %xmm1, 0x5c0(%rsp)
movapd %xmm0, %xmm1
ucomisd %xmm0, %xmm2
jbe 0x2f0c7
leaq 0x1(%rsi), %rdi
addq $0x48, %rax
movapd %xmm1, %xmm0
cmpq %rsi, %rcx
movq %rdi, %rsi
jne 0x2f08e
leaq 0x738(%rsp), %rdi
callq 0x2e1fe
leaq 0xf90(%rsp), %rdi
callq 0x2c6b0
leaq 0x5a0(%rsp), %rbx
movq %r14, %rdi
movsd 0x590(%rsp), %xmm0
movq %rbx, %rsi
movq %r13, %rdx
movq 0x5a8(%rsp), %r15
movq %r15, %rcx
callq 0x2e5ae
movq (%rbx), %rbx
leaq 0xdc8(%rsp), %r12
movq (%rbx), %rax
leaq 0x5d0(%rsp), %rbp
movq %rbx, %rdi
movq %rbp, %rsi
movq %r12, %rdx
movsd 0x590(%rsp), %xmm0
callq *(%rax)
movb $0x0, 0x1c0(%r12)
movsd 0x1200(%r14), %xmm2
leaq 0xa08(%rsp), %rsi
movl $0xb1, %ecx
movq %rsp, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %rbx, %rdi
movq %rbp, %rsi
movsd 0x590(%rsp), %xmm0
movaps 0x5c0(%rsp), %xmm1
movq 0x598(%rsp), %rdx
callq 0x3010d
movq 0x5b0(%rsp), %rbx
movq %rbx, %rdi
callq 0x2147e
leaq 0x690(%rsp), %rbp
movq %rbp, %rdi
movq %rbx, %rsi
movq %r13, %rdx
movq %r15, %rcx
callq 0x23778
cmpb $0x1, 0x11e8(%r14)
jne 0x2f3aa
xorps %xmm0, %xmm0
leaq 0xf90(%rsp), %r12
movups %xmm0, 0xa8(%r12)
movq 0x18(%rbp), %rax
leaq 0x738(%rsp), %rcx
movq %rax, 0x18(%rcx)
movups 0x8(%rbp), %xmm0
movups %xmm0, 0x8(%rcx)
movq %rcx, %rsi
movsd 0x11f0(%r14), %xmm1
xorl %ebx, %ebx
movb %bl, 0x1(%r12)
movq %rbx, 0x78(%r12)
movabsq $0x3fe0000000000000, %r15 # imm = 0x3FE0000000000000
movq %r15, 0x80(%r12)
movq %r15, 0x88(%r12)
movq %rbx, 0x90(%r12)
movq %r15, 0x98(%r12)
movq %r15, 0xa0(%r12)
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq %rax, 0xb8(%r12)
movq %rax, 0xc0(%r12)
movabsq $0x3fc5555555555555, %rax # imm = 0x3FC5555555555555
movq %rax, 0xc8(%r12)
movabsq $0x3fd5555555555555, %rdx # imm = 0x3FD5555555555555
movq %rdx, 0xd0(%r12)
movq %rdx, 0xd8(%r12)
movq %rax, 0xe0(%r12)
movb %bl, 0xe8(%r12)
leaq 0x196c8(%rip), %r13     # 0x48950
addq $0x10, %r13
movq %r13, (%rcx)
leaq 0x5d0(%rsp), %rdx
movsd 0xdf69(%rip), %xmm2     # 0x3d208
movq %r12, %rdi
movaps 0x5c0(%rsp), %xmm0
movq 0x598(%rsp), %rcx
callq 0x31611
movq 0x5b0(%rsp), %rdi
callq 0x2147e
xorps %xmm0, %xmm0
movups %xmm0, 0xa8(%r12)
movq 0x18(%rbp), %rax
leaq 0x738(%rsp), %rcx
movq %rax, 0x18(%rcx)
movups 0x8(%rbp), %xmm0
movups %xmm0, 0x8(%rcx)
movsd 0x11f0(%r14), %xmm0
movsd 0x11f8(%r14), %xmm1
movb %bl, 0x1(%r12)
movq %rbx, 0x78(%r12)
movq %r15, 0x80(%r12)
movq %r15, 0x88(%r12)
movq %rbx, 0x90(%r12)
movq %r15, 0x98(%r12)
movq %r15, 0xa0(%r12)
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq %rax, 0xb8(%r12)
movq %rax, 0xc0(%r12)
movabsq $0x3fc5555555555555, %rax # imm = 0x3FC5555555555555
movq %rax, 0xc8(%r12)
movabsq $0x3fd5555555555555, %rdx # imm = 0x3FD5555555555555
movq %rdx, 0xd0(%r12)
movq %rdx, 0xd8(%r12)
movq %rax, 0xe0(%r12)
movb %bl, 0xe8(%r12)
movq %r13, (%rcx)
leaq 0xf90(%rsp), %rdi
leaq 0x738(%rsp), %rsi
leaq 0x5d0(%rsp), %rdx
movsd 0xde63(%rip), %xmm2     # 0x3d208
jmp 0x2f487
xorps %xmm0, %xmm0
leaq 0xf90(%rsp), %rdi
movups %xmm0, 0xa8(%rdi)
movq 0x18(%rbp), %rax
leaq 0x738(%rsp), %rsi
movq %rax, 0x18(%rsi)
movups 0x8(%rbp), %xmm0
movups %xmm0, 0x8(%rsi)
movsd 0x11f8(%r14), %xmm1
xorl %eax, %eax
movb %al, 0x1(%rdi)
movq %rax, 0x78(%rdi)
movabsq $0x3fe0000000000000, %rcx # imm = 0x3FE0000000000000
movq %rcx, 0x80(%rdi)
movq %rcx, 0x88(%rdi)
movq %rax, 0x90(%rdi)
movq %rcx, 0x98(%rdi)
movq %rcx, 0xa0(%rdi)
movabsq $0x3ff0000000000000, %rcx # imm = 0x3FF0000000000000
movq %rcx, 0xb8(%rdi)
movq %rcx, 0xc0(%rdi)
movabsq $0x3fc5555555555555, %rcx # imm = 0x3FC5555555555555
movq %rcx, 0xc8(%rdi)
movabsq $0x3fd5555555555555, %rdx # imm = 0x3FD5555555555555
movq %rdx, 0xd0(%rdi)
movq %rdx, 0xd8(%rdi)
movq %rcx, 0xe0(%rdi)
movb %al, 0xe8(%rdi)
leaq 0x194e8(%rip), %rax     # 0x48950
addq $0x10, %rax
movq %rax, (%rsi)
leaq 0x5d0(%rsp), %rdx
movsd 0xdd89(%rip), %xmm2     # 0x3d208
movaps 0x5c0(%rsp), %xmm0
movq 0x598(%rsp), %rcx
callq 0x31611
addq $0x1e08, %rsp           # imm = 0x1E08
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x2f4a8
movq %rax, %rbx
movl $0x20, %esi
jmp 0x2f4c2
jmp 0x2f4ce
jmp 0x2f4ce
jmp 0x2f4e5
jmp 0x2f4ba
movq %rax, %rbx
movl $0x18, %esi
movq %rbp, %rdi
callq 0x5350
jmp 0x2f4e8
jmp 0x2f4ce
movq %rax, %rbx
jmp 0x2f4f5
movq %rax, %rbx
movl $0x20, %esi
movq %rbp, %rdi
callq 0x5350
jmp 0x2f502
movq %rax, %rbx
leaq 0x738(%rsp), %rdi
callq 0x2e1fe
leaq 0xf90(%rsp), %rdi
callq 0x2c6b0
movq %rbx, %rdi
callq 0x55e0