// File: xiangzejun[P]Optimizing_Implementations_of_Linear_Layers/strategy.cpp
// Function: strgy3(std::vector<std::bitset<32ul>, std::allocator<std::bitset<32ul>>>&)
vector<xpair> strgy3(vector<ROW> &m)
{
	vector<xpair> tmp_seq;
	while(get_ones(m) != m.size())
	{
		vector<xpair> base_oper;
		base_oper.clear();
		int value = 0;

		int Reduced_Row = select_oper(m, base_oper, value, 0);

		vector<ROW> trans_m;
		get_trans_matrix(trans_m,m);

		int Reduced_Col = select_oper(trans_m, base_oper, Reduced_Row, 1);
		if (base_oper.size() >= 1)
			{
				int rand_num = rand_generator() % base_oper.size();
			
				if (!base_oper[rand_num].flag)
				{
					m[base_oper[rand_num].dst] ^= m[base_oper[rand_num].src];
					tmp_seq.push_back(base_oper[rand_num]);
				}
	
				else if (base_oper[rand_num].flag)
				{   
					vector<ROW> trans_tmp_m;
					get_trans_matrix(trans_tmp_m, m);
					trans_tmp_m[base_oper[rand_num].dst] ^= trans_tmp_m[base_oper[rand_num].src];
					get_trans_matrix(m, trans_tmp_m);
					tmp_seq.push_back(base_oper[rand_num]);
				}
			}
			else 
			{
				break;
			}
	}
    
	if (get_ones(m) != m.size())
	{ 
	    // int rnd = rand()%2;
		int rnd = rand_generator() % 2;
		if(rnd == 0)
		{
			vector<xpair> seq_2(strgy1(m));
			tmp_seq.insert(tmp_seq.end(), seq_2.begin(), seq_2.end());
		}
		else if(rnd == 1)
		{
			vector<xpair> seq_2(strgy2(m));
			tmp_seq.insert(tmp_seq.end(), seq_2.begin(), seq_2.end());
		}
	}
	
	int tab[SIZE] = {0};
	build_table(m, tab);
	vector<xpair> final_seq = update_seq_str(tmp_seq, tab);
	return final_seq;
}

// Assembly:
subq $0x378, %rsp            # imm = 0x378
movq %rdi, 0xd8(%rsp)
movq %rdi, %rax
movq %rax, 0xe0(%rsp)
movq %rdi, 0x370(%rsp)
movq %rsi, 0x368(%rsp)
leaq 0x350(%rsp), %rdi
callq 0x5d30
movq 0x368(%rsp), %rsi
leaq 0x338(%rsp), %rdi
callq 0x2fc0
jmp 0x507e
leaq 0x338(%rsp), %rdi
callq 0x5a40
movl %eax, 0xd4(%rsp)
jmp 0x5094
movl 0xd4(%rsp), %eax
cltq
movq %rax, 0xc8(%rsp)
movq 0x368(%rsp), %rdi
callq 0x32a0
movq %rax, 0xc0(%rsp)
leaq 0x338(%rsp), %rdi
callq 0x30c0
movq 0xc0(%rsp), %rcx
movq 0xc8(%rsp), %rax
cmpq %rcx, %rax
je 0x562e
leaq 0x310(%rsp), %rdi
movq %rdi, 0xb8(%rsp)
callq 0x5d30
movq 0xb8(%rsp), %rdi
callq 0x5e60
movl $0x0, 0x30c(%rsp)
movq 0x368(%rsp), %rsi
leaq 0x2f0(%rsp), %rdi
callq 0x2fc0
jmp 0x5124
movl 0x30c(%rsp), %edx
leaq 0x2f0(%rsp), %rdi
leaq 0x310(%rsp), %rsi
xorl %ecx, %ecx
callq 0x5ac0
movl %eax, 0xb4(%rsp)
jmp 0x514b
leaq 0x2f0(%rsp), %rdi
callq 0x30c0
movl 0xb4(%rsp), %eax
movl %eax, 0x308(%rsp)
leaq 0x2d8(%rsp), %rdi
callq 0x5e50
movq 0x368(%rsp), %rsi
leaq 0x2c0(%rsp), %rdi
callq 0x2fc0
jmp 0x518a
leaq 0x2d8(%rsp), %rdi
leaq 0x2c0(%rsp), %rsi
callq 0x4c10
jmp 0x51a1
leaq 0x2c0(%rsp), %rdi
callq 0x30c0
leaq 0x2a0(%rsp), %rdi
leaq 0x2d8(%rsp), %rsi
callq 0x2fc0
jmp 0x51c5
movl 0x308(%rsp), %edx
leaq 0x2a0(%rsp), %rdi
leaq 0x310(%rsp), %rsi
movl $0x1, %ecx
callq 0x5ac0
movl %eax, 0xb0(%rsp)
jmp 0x51ef
leaq 0x2a0(%rsp), %rdi
callq 0x30c0
movl 0xb0(%rsp), %eax
movl %eax, 0x2bc(%rsp)
leaq 0x310(%rsp), %rdi
callq 0x3280
cmpq $0x1, %rax
jb 0x55c9
leaq 0xdf70(%rip), %rdi      # 0x13198
callq 0x5e80
movq %rax, 0xa8(%rsp)
jmp 0x5237
leaq 0x310(%rsp), %rdi
callq 0x3280
movq %rax, %rcx
movq 0xa8(%rsp), %rax
xorl %edx, %edx
divq %rcx
movl %edx, %eax
movl %eax, 0x29c(%rsp)
movslq 0x29c(%rsp), %rsi
leaq 0x310(%rsp), %rdi
callq 0x3430
testb $0x1, 0x8(%rax)
jne 0x5416
movq 0x368(%rsp), %rax
movq %rax, 0x88(%rsp)
movslq 0x29c(%rsp), %rsi
leaq 0x310(%rsp), %rdi
movq %rdi, 0xa0(%rsp)
callq 0x3430
movq 0x88(%rsp), %rdi
movslq (%rax), %rsi
callq 0x33d0
movq 0xa0(%rsp), %rdi
movq %rax, 0x98(%rsp)
movq 0x368(%rsp), %rax
movq %rax, 0x90(%rsp)
movslq 0x29c(%rsp), %rsi
callq 0x3430
movq 0x90(%rsp), %rdi
movslq 0x4(%rax), %rsi
callq 0x33d0
movq 0x98(%rsp), %rsi
movq %rax, %rdi
callq 0x3450
movq 0xa0(%rsp), %rdi
movslq 0x29c(%rsp), %rsi
callq 0x3430
movq %rax, %rsi
leaq 0x350(%rsp), %rdi
callq 0x5de0
jmp 0x532e
jmp 0x55c7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x330(%rsp)
movl %eax, 0x32c(%rsp)
jmp 0x5a17
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x330(%rsp)
movl %eax, 0x32c(%rsp)
leaq 0x338(%rsp), %rdi
callq 0x30c0
jmp 0x5a17
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x330(%rsp)
movl %eax, 0x32c(%rsp)
jmp 0x561c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x330(%rsp)
movl %eax, 0x32c(%rsp)
leaq 0x2f0(%rsp), %rdi
callq 0x30c0
jmp 0x561c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x330(%rsp)
movl %eax, 0x32c(%rsp)
jmp 0x560f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x330(%rsp)
movl %eax, 0x32c(%rsp)
leaq 0x2c0(%rsp), %rdi
callq 0x30c0
jmp 0x560f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x330(%rsp)
movl %eax, 0x32c(%rsp)
leaq 0x2a0(%rsp), %rdi
callq 0x30c0
jmp 0x560f
movslq 0x29c(%rsp), %rsi
leaq 0x310(%rsp), %rdi
callq 0x3430
testb $0x1, 0x8(%rax)
je 0x55c5
leaq 0x280(%rsp), %rdi
callq 0x5e50
movq 0x368(%rsp), %rsi
leaq 0x268(%rsp), %rdi
callq 0x2fc0
jmp 0x5459
leaq 0x280(%rsp), %rdi
leaq 0x268(%rsp), %rsi
callq 0x4c10
jmp 0x5470
leaq 0x268(%rsp), %rdi
callq 0x30c0
movslq 0x29c(%rsp), %rsi
leaq 0x310(%rsp), %rdi
movq %rdi, 0x68(%rsp)
callq 0x3430
movslq (%rax), %rsi
leaq 0x280(%rsp), %rdi
movq %rdi, 0x78(%rsp)
callq 0x33d0
movq 0x68(%rsp), %rdi
movq %rax, 0x70(%rsp)
movslq 0x29c(%rsp), %rsi
callq 0x3430
movq 0x78(%rsp), %rdi
movslq 0x4(%rax), %rsi
callq 0x33d0
movq 0x70(%rsp), %rsi
movq %rax, %rdi
callq 0x3450
movq 0x78(%rsp), %rsi
movq 0x368(%rsp), %rax
movq %rax, 0x80(%rsp)
leaq 0x250(%rsp), %rdi
callq 0x2fc0
jmp 0x5502
movq 0x80(%rsp), %rdi
leaq 0x250(%rsp), %rsi
callq 0x4c10
jmp 0x5519
leaq 0x250(%rsp), %rdi
callq 0x30c0
movslq 0x29c(%rsp), %rsi
leaq 0x310(%rsp), %rdi
callq 0x3430
movq %rax, %rsi
leaq 0x350(%rsp), %rdi
callq 0x5de0
jmp 0x554d
leaq 0x280(%rsp), %rdi
callq 0x30c0
jmp 0x55c5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x330(%rsp)
movl %eax, 0x32c(%rsp)
jmp 0x55b6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x330(%rsp)
movl %eax, 0x32c(%rsp)
leaq 0x268(%rsp), %rdi
callq 0x30c0
jmp 0x55b6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x330(%rsp)
movl %eax, 0x32c(%rsp)
leaq 0x250(%rsp), %rdi
callq 0x30c0
leaq 0x280(%rsp), %rdi
callq 0x30c0
jmp 0x560f
jmp 0x55c7
jmp 0x55d6
movl $0x3, 0x24c(%rsp)
jmp 0x55e1
movl $0x0, 0x24c(%rsp)
leaq 0x2d8(%rsp), %rdi
callq 0x30c0
leaq 0x310(%rsp), %rdi
callq 0x3220
movl 0x24c(%rsp), %eax
testl %eax, %eax
je 0x560a
jmp 0x5608
jmp 0x562e
jmp 0x5067
leaq 0x2d8(%rsp), %rdi
callq 0x30c0
leaq 0x310(%rsp), %rdi
callq 0x3220
jmp 0x5a17
movq 0x368(%rsp), %rsi
leaq 0x230(%rsp), %rdi
callq 0x2fc0
jmp 0x5645
leaq 0x230(%rsp), %rdi
callq 0x5a40
movl %eax, 0x64(%rsp)
jmp 0x5658
movl 0x64(%rsp), %eax
cltq
movq %rax, 0x58(%rsp)
movq 0x368(%rsp), %rdi
callq 0x32a0
movq %rax, 0x50(%rsp)
leaq 0x230(%rsp), %rdi
callq 0x30c0
movq 0x50(%rsp), %rcx
movq 0x58(%rsp), %rax
cmpq %rcx, %rax
je 0x58bb
leaq 0xdafc(%rip), %rdi      # 0x13198
callq 0x5e80
movq %rax, 0x48(%rsp)
jmp 0x56a8
movq 0x48(%rsp), %rax
andq $0x1, %rax
movl %eax, 0x22c(%rsp)
cmpl $0x0, 0x22c(%rsp)
jne 0x57cc
movq 0x368(%rsp), %rsi
leaq 0x210(%rsp), %rdi
callq 0x45e0
jmp 0x56dd
leaq 0x350(%rsp), %rdi
movq %rdi, 0x38(%rsp)
callq 0x6010
movq %rax, 0x200(%rsp)
leaq 0x208(%rsp), %rdi
leaq 0x200(%rsp), %rsi
callq 0x6040
leaq 0x210(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0x6080
movq 0x30(%rsp), %rdi
movq %rax, 0x1f8(%rsp)
callq 0x6010
movq 0x38(%rsp), %rdi
movq %rax, 0x1f0(%rsp)
movq 0x208(%rsp), %rsi
movq 0x1f8(%rsp), %rdx
movq 0x1f0(%rsp), %rcx
callq 0x5f50
movq %rax, 0x40(%rsp)
jmp 0x5761
movq 0x40(%rsp), %rax
movq %rax, 0x1e8(%rsp)
leaq 0x210(%rsp), %rdi
callq 0x3220
jmp 0x58b9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x330(%rsp)
movl %eax, 0x32c(%rsp)
leaq 0x230(%rsp), %rdi
callq 0x30c0
jmp 0x5a17
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x330(%rsp)
movl %eax, 0x32c(%rsp)
leaq 0x210(%rsp), %rdi
callq 0x3220
jmp 0x5a17
cmpl $0x1, 0x22c(%rsp)
jne 0x58b7
movq 0x368(%rsp), %rsi
leaq 0x1d0(%rsp), %rdi
callq 0x4910
jmp 0x57f1
leaq 0x350(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0x6010
movq %rax, 0x1c0(%rsp)
leaq 0x1c8(%rsp), %rdi
leaq 0x1c0(%rsp), %rsi
callq 0x6040
leaq 0x1d0(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x6080
movq 0x18(%rsp), %rdi
movq %rax, 0x1b8(%rsp)
callq 0x6010
movq 0x20(%rsp), %rdi
movq %rax, 0x1b0(%rsp)
movq 0x1c8(%rsp), %rsi
movq 0x1b8(%rsp), %rdx
movq 0x1b0(%rsp), %rcx
callq 0x5f50
movq %rax, 0x28(%rsp)
jmp 0x5875
movq 0x28(%rsp), %rax
movq %rax, 0x1a8(%rsp)
leaq 0x1d0(%rsp), %rdi
callq 0x3220
jmp 0x58b7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x330(%rsp)
movl %eax, 0x32c(%rsp)
leaq 0x1d0(%rsp), %rdi
callq 0x3220
jmp 0x5a17
jmp 0x58b9
jmp 0x58bb
xorps %xmm0, %xmm0
movaps %xmm0, (%rsp)
movaps %xmm0, 0x190(%rsp)
movaps %xmm0, 0x180(%rsp)
movaps %xmm0, 0x170(%rsp)
movaps %xmm0, 0x160(%rsp)
movaps %xmm0, 0x150(%rsp)
movaps %xmm0, 0x140(%rsp)
movaps %xmm0, 0x130(%rsp)
movaps %xmm0, 0x120(%rsp)
movq 0x368(%rsp), %rsi
leaq 0x108(%rsp), %rdi
callq 0x2fc0
jmp 0x5919
leaq 0x108(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x4da0
jmp 0x5930
leaq 0x108(%rsp), %rdi
callq 0x30c0
movb $0x0, 0x107(%rsp)
leaq 0xe8(%rsp), %rdi
leaq 0x350(%rsp), %rsi
callq 0x3120
jmp 0x595c
movq 0xd8(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
leaq 0x120(%rsp), %rdx
callq 0x4e90
jmp 0x597b
leaq 0xe8(%rsp), %rdi
callq 0x3220
movb $0x1, 0x107(%rsp)
movl $0x1, 0x24c(%rsp)
testb $0x1, 0x107(%rsp)
jne 0x59fa
jmp 0x59ed
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x330(%rsp)
movl %eax, 0x32c(%rsp)
leaq 0x108(%rsp), %rdi
callq 0x30c0
jmp 0x5a17
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x330(%rsp)
movl %eax, 0x32c(%rsp)
leaq 0xe8(%rsp), %rdi
callq 0x3220
jmp 0x5a17
movq 0xd8(%rsp), %rdi
callq 0x3220
leaq 0x350(%rsp), %rdi
callq 0x3220
movq 0xe0(%rsp), %rax
addq $0x378, %rsp            # imm = 0x378
retq
leaq 0x350(%rsp), %rdi
callq 0x3220
movq 0x330(%rsp), %rdi
callq 0x22a0
nopw %cs:(%rax,%rax)