// File: manschga[P]M5GB/M5GB.cpp
// Function: Full_S_Reduce(Lab_poly&, int)
void Full_S_Reduce(Lab_poly &F, const int n)
{
  //number_of_reductions++;
#ifdef PRECISE_DEBUG
  cout << "doing full-reduce with " << F << endl;
#endif
  signature T = F.Get_sign();
  polynomial f = F.Get_poly();
  polynomial f_ = f;
  for (auto& monom : f.Get_monomials())
    {
#ifdef PRECISE_DEBUG
      cout << "t = " << monom.Get_term() << endl;
#endif
      int t = monom.Get_term();
       int c = monom.Get_coeff();
       if (Flags_T.find(t) != Flags_T.end() &&  (Flags_T.find(t)->second > T || Flags_T.find(t)->second == T))
	 {
         if (Generations_T.find(t)->second == G_.size())//t is known to be irreducible -> nothing needs to be done!
	     {
	       continue;
	     }
	   else if (!Check_TGFT(t,T))//if not reducible by G, possible improvement: check only for newer elements, nothing for counting argument!
	     {
	       Generations_T.erase(t);
	       Generations_T[t] = G_.size();
	       Flags_T.erase(t);//update signature flag since new generation, improvement: take only newer ons and do min with old flag
	       Flags_T[t] = Create_term_flag(t);
	     }
	 }
       //bool compatible = false; -> improvement to save some div by G operations
      auto itr = LT_M.find(t);
      if (itr != LT_M.end()) //element in M found
	{
	  Lab_poly m_ = Update_m(Lab_poly(M.find(itr->first)->second,itr->second),T,n); //bring m in right form such that it is tail-irreducible again
	  f_ = f_ - m_.Get_poly().Multiply(c,true); //f - c_t(f)*m_t
	  number_of_reductions++;
	  full_red_steps ++;
	}
      else if (Check_TGFT(t,T))//if reducible by G
	{
	  Flags_T.erase(t);//t is no longer irreducible (only first one needed, rest for less storage) 
	  Generations_T.erase(t);
	  Lab_poly vM = Div_by_M(t,T);//find best divisor in M, improvment: map G -> M, only need to check that m's on divisibility, if not by M -> reduce by G, inside implemented!
	  Lab_poly m_ = Tail_S_Reduce(vM,T,n); //create new element in M such that it is tail-irreducible
	  f_ = f_ - m_.Get_poly().Multiply(c,true); //f - c_t(f)*m_t
	  number_of_reductions++;
	  full_red_steps ++;
	}
      else
	{
	  Flags_T.erase(t);//update signature flag since new generation, improvement: take only newer ons and do min with old flag
	  Flags_T[t] = Create_term_flag(t);
	  Generations_T[t] = G_.size();
      }
    }
  F = Lab_poly(f_,T);
#ifdef DEBUG
  //cout << "Full_reduce element: " << F << endl;
#endif
  return;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x440, %rsp            # imm = 0x440
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq -0x8(%rbp), %rdi
callq 0xb8d0
movups (%rax), %xmm0
movaps %xmm0, -0x20(%rbp)
movq -0x8(%rbp), %rdi
callq 0xb8c0
movq %rax, %rsi
leaq -0x40(%rbp), %rdi
movq %rdi, -0x368(%rbp)
callq 0xd980
movq -0x368(%rbp), %rsi
leaq -0x60(%rbp), %rdi
callq 0xd980
jmp 0x120b0
leaq -0x40(%rbp), %rdi
callq 0x31f0
movq %rax, -0x370(%rbp)
jmp 0x120c2
movq -0x370(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rdi
callq 0xc5c0
movq %rax, -0x80(%rbp)
movq -0x78(%rbp), %rdi
callq 0xc5f0
movq %rax, -0x88(%rbp)
leaq -0x80(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0xc9f0
testb $0x1, %al
jne 0x12103
jmp 0x12954
leaq -0x80(%rbp), %rdi
callq 0xca60
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rdi
callq 0xda60
movq %rax, -0x378(%rbp)
jmp 0x12128
movq -0x378(%rbp), %rax
movl %eax, -0x94(%rbp)
movq -0x90(%rbp), %rdi
callq 0x3220
movl %eax, -0x37c(%rbp)
jmp 0x12149
movl -0x37c(%rbp), %eax
movl %eax, -0x98(%rbp)
movslq -0x94(%rbp), %rax
movq %rax, -0xa8(%rbp)
leaq 0x2e236(%rip), %rdi     # 0x403a0
leaq -0xa8(%rbp), %rsi
callq 0x17170
movq %rax, -0x388(%rbp)
jmp 0x1217f
movq -0x388(%rbp), %rax
movq %rax, -0xa0(%rbp)
leaq 0x2e20c(%rip), %rdi     # 0x403a0
callq 0x17020
movq %rax, -0xb0(%rbp)
leaq -0xa0(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x17050
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x389(%rbp)
jne 0x121c7
jmp 0x122ae
movslq -0x94(%rbp), %rax
movq %rax, -0xc0(%rbp)
leaq 0x2e1c4(%rip), %rdi     # 0x403a0
leaq -0xc0(%rbp), %rsi
callq 0x17170
movq %rax, -0x398(%rbp)
jmp 0x121f1
movq -0x398(%rbp), %rax
movq %rax, -0xb8(%rbp)
leaq -0xb8(%rbp), %rdi
callq 0x171a0
movq %rax, %rdi
addq $0x8, %rdi
leaq -0x20(%rbp), %rsi
callq 0x171d0
movb %al, -0x399(%rbp)
jmp 0x12223
movb -0x399(%rbp), %cl
movb $0x1, %al
testb $0x1, %cl
movb %al, -0x39a(%rbp)
jne 0x122a2
jmp 0x12238
movslq -0x94(%rbp), %rax
movq %rax, -0xd0(%rbp)
leaq 0x2e153(%rip), %rdi     # 0x403a0
leaq -0xd0(%rbp), %rsi
callq 0x17170
movq %rax, -0x3a8(%rbp)
jmp 0x12262
movq -0x3a8(%rbp), %rax
movq %rax, -0xc8(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0x171a0
movq %rax, %rdi
addq $0x8, %rdi
leaq -0x20(%rbp), %rsi
callq 0xbe50
movb %al, -0x3a9(%rbp)
jmp 0x12294
movb -0x3a9(%rbp), %al
movb %al, -0x39a(%rbp)
jmp 0x122a2
movb -0x39a(%rbp), %al
movb %al, -0x389(%rbp)
movb -0x389(%rbp), %al
testb $0x1, %al
jne 0x122bd
jmp 0x12486
movslq -0x94(%rbp), %rax
movq %rax, -0xe0(%rbp)
leaq 0x2e1ae(%rip), %rdi     # 0x40480
leaq -0xe0(%rbp), %rsi
callq 0x17220
movq %rax, -0x3b8(%rbp)
jmp 0x122e7
movq -0x3b8(%rbp), %rax
movq %rax, -0xd8(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x17250
movslq 0x8(%rax), %rax
movq %rax, -0x3c0(%rbp)
leaq 0x2e01d(%rip), %rdi     # 0x40330
callq 0x16cc0
movq %rax, %rcx
movq -0x3c0(%rbp), %rax
cmpq %rcx, %rax
jne 0x1234e
jmp 0x12946
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x129f7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x129ee
movslq -0x94(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x13760
movb %al, -0x3c1(%rbp)
jmp 0x12366
movb -0x3c1(%rbp), %al
testb $0x1, %al
jne 0x12482
jmp 0x12376
movslq -0x94(%rbp), %rax
movq %rax, -0xe8(%rbp)
leaq 0x2e0f5(%rip), %rdi     # 0x40480
leaq -0xe8(%rbp), %rsi
callq 0x16f30
jmp 0x12399
leaq 0x2df90(%rip), %rdi     # 0x40330
callq 0x16cc0
movl %eax, -0x3d4(%rbp)
movslq -0x94(%rbp), %rax
movq %rax, -0xf0(%rbp)
leaq 0x2e0c0(%rip), %rdi     # 0x40480
leaq -0xf0(%rbp), %rsi
callq 0x17280
movq %rax, -0x3d0(%rbp)
jmp 0x123d5
movq -0x3d0(%rbp), %rax
movl -0x3d4(%rbp), %ecx
movl %ecx, (%rax)
movslq -0x94(%rbp), %rax
movq %rax, -0xf8(%rbp)
leaq 0x2dfa7(%rip), %rdi     # 0x403a0
leaq -0xf8(%rbp), %rsi
callq 0x16f90
jmp 0x12407
movslq -0x94(%rbp), %rdi
callq 0x13a00
movq %rdx, -0x3e0(%rbp)
movl %eax, -0x3d8(%rbp)
jmp 0x12422
movq -0x3e0(%rbp), %rax
movl -0x3d8(%rbp), %ecx
movl %ecx, -0x108(%rbp)
movq %rax, -0x100(%rbp)
movslq -0x94(%rbp), %rax
movq %rax, -0x110(%rbp)
leaq 0x2df4f(%rip), %rdi     # 0x403a0
leaq -0x110(%rbp), %rsi
callq 0x172b0
movq %rax, -0x3e8(%rbp)
jmp 0x12466
movq -0x3e8(%rbp), %rax
movq -0x108(%rbp), %rcx
movq %rcx, (%rax)
movq -0x100(%rbp), %rcx
movq %rcx, 0x8(%rax)
jmp 0x12484
jmp 0x12486
movslq -0x94(%rbp), %rax
movq %rax, -0x120(%rbp)
leaq 0x2de5d(%rip), %rdi     # 0x402f8
leaq -0x120(%rbp), %rsi
callq 0x17170
movq %rax, -0x3f0(%rbp)
jmp 0x124b0
movq -0x3f0(%rbp), %rax
movq %rax, -0x118(%rbp)
leaq 0x2de33(%rip), %rdi     # 0x402f8
callq 0x17020
movq %rax, -0x128(%rbp)
leaq -0x118(%rbp), %rdi
leaq -0x128(%rbp), %rsi
callq 0x17050
testb $0x1, %al
jne 0x124ed
jmp 0x126c0
leaq -0x118(%rbp), %rdi
callq 0x171a0
movq %rax, %rsi
leaq 0x2de65(%rip), %rdi     # 0x40368
callq 0x170c0
movq %rax, -0x3f8(%rbp)
jmp 0x12511
movq -0x3f8(%rbp), %rax
movq %rax, -0x1c0(%rbp)
leaq -0x1c0(%rbp), %rdi
callq 0x170f0
movq %rax, %rsi
addq $0x8, %rsi
leaq -0x1b8(%rbp), %rdi
callq 0xd980
jmp 0x12540
leaq -0x118(%rbp), %rdi
callq 0x171a0
movups 0x8(%rax), %xmm0
movaps %xmm0, -0x1d0(%rbp)
movl -0x1d0(%rbp), %edx
movq -0x1c8(%rbp), %rcx
leaq -0x198(%rbp), %rdi
leaq -0x1b8(%rbp), %rsi
callq 0x9d90
jmp 0x12579
movl -0xc(%rbp), %ecx
leaq -0x160(%rbp), %rdi
leaq -0x198(%rbp), %rsi
leaq -0x20(%rbp), %rdx
callq 0x13c40
jmp 0x12595
leaq -0x198(%rbp), %rdi
callq 0xbc80
leaq -0x1b8(%rbp), %rdi
callq 0x44a0
leaq -0x160(%rbp), %rdi
callq 0xb8c0
movq %rax, -0x400(%rbp)
jmp 0x125c2
movq -0x400(%rbp), %rsi
movl -0x98(%rbp), %edx
leaq -0x210(%rbp), %rdi
movl $0x1, %ecx
callq 0xd4a0
jmp 0x125e2
leaq -0x1f0(%rbp), %rdi
leaq -0x60(%rbp), %rsi
leaq -0x210(%rbp), %rdx
callq 0xd790
jmp 0x125fb
leaq -0x60(%rbp), %rdi
leaq -0x1f0(%rbp), %rsi
callq 0xb810
leaq -0x1f0(%rbp), %rdi
callq 0x44a0
leaq -0x210(%rbp), %rdi
callq 0x44a0
movl 0x2dbff(%rip), %eax     # 0x40228
addl $0x1, %eax
movl %eax, 0x2dbf6(%rip)     # 0x40228
movl 0x2dbec(%rip), %eax     # 0x40224
addl $0x1, %eax
movl %eax, 0x2dbe3(%rip)     # 0x40224
leaq -0x160(%rbp), %rdi
callq 0xbc80
jmp 0x12944
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x12678
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x198(%rbp), %rdi
callq 0xbc80
leaq -0x1b8(%rbp), %rdi
callq 0x44a0
jmp 0x129ee
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x126af
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x210(%rbp), %rdi
callq 0x44a0
leaq -0x160(%rbp), %rdi
callq 0xbc80
jmp 0x129ee
movslq -0x94(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x13760
movb %al, -0x401(%rbp)
jmp 0x126d8
movb -0x401(%rbp), %al
testb $0x1, %al
jne 0x126e7
jmp 0x12864
movslq -0x94(%rbp), %rax
movq %rax, -0x218(%rbp)
leaq 0x2dca4(%rip), %rdi     # 0x403a0
leaq -0x218(%rbp), %rsi
callq 0x16f90
jmp 0x1270a
movslq -0x94(%rbp), %rax
movq %rax, -0x220(%rbp)
leaq 0x2dd61(%rip), %rdi     # 0x40480
leaq -0x220(%rbp), %rsi
callq 0x16f30
jmp 0x1272d
movslq -0x94(%rbp), %rsi
leaq -0x258(%rbp), %rdi
leaq -0x20(%rbp), %rdx
callq 0x13dd0
jmp 0x12746
movl -0xc(%rbp), %ecx
leaq -0x290(%rbp), %rdi
leaq -0x258(%rbp), %rsi
leaq -0x20(%rbp), %rdx
callq 0x145a0
jmp 0x12762
leaq -0x290(%rbp), %rdi
callq 0xb8c0
movq %rax, -0x410(%rbp)
jmp 0x12777
movq -0x410(%rbp), %rsi
movl -0x98(%rbp), %edx
leaq -0x2d0(%rbp), %rdi
movl $0x1, %ecx
callq 0xd4a0
jmp 0x12797
leaq -0x2b0(%rbp), %rdi
leaq -0x60(%rbp), %rsi
leaq -0x2d0(%rbp), %rdx
callq 0xd790
jmp 0x127b0
leaq -0x60(%rbp), %rdi
leaq -0x2b0(%rbp), %rsi
callq 0xb810
leaq -0x2b0(%rbp), %rdi
callq 0x44a0
leaq -0x2d0(%rbp), %rdi
callq 0x44a0
movl 0x2da4a(%rip), %eax     # 0x40228
addl $0x1, %eax
movl %eax, 0x2da41(%rip)     # 0x40228
movl 0x2da37(%rip), %eax     # 0x40224
addl $0x1, %eax
movl %eax, 0x2da2e(%rip)     # 0x40224
leaq -0x290(%rbp), %rdi
callq 0xbc80
leaq -0x258(%rbp), %rdi
callq 0xbc80
jmp 0x12942
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x12853
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x12847
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x2d0(%rbp), %rdi
callq 0x44a0
leaq -0x290(%rbp), %rdi
callq 0xbc80
leaq -0x258(%rbp), %rdi
callq 0xbc80
jmp 0x129ee
movslq -0x94(%rbp), %rax
movq %rax, -0x2d8(%rbp)
leaq 0x2db27(%rip), %rdi     # 0x403a0
leaq -0x2d8(%rbp), %rsi
callq 0x16f90
jmp 0x12887
movslq -0x94(%rbp), %rdi
callq 0x13a00
movq %rdx, -0x420(%rbp)
movl %eax, -0x414(%rbp)
jmp 0x128a2
movq -0x420(%rbp), %rax
movl -0x414(%rbp), %ecx
movl %ecx, -0x2e8(%rbp)
movq %rax, -0x2e0(%rbp)
movslq -0x94(%rbp), %rax
movq %rax, -0x2f0(%rbp)
leaq 0x2dacf(%rip), %rdi     # 0x403a0
leaq -0x2f0(%rbp), %rsi
callq 0x172b0
movq %rax, -0x428(%rbp)
jmp 0x128e6
movq -0x428(%rbp), %rax
movups -0x2e8(%rbp), %xmm0
movups %xmm0, (%rax)
leaq 0x2da32(%rip), %rdi     # 0x40330
callq 0x16cc0
movl %eax, -0x434(%rbp)
movslq -0x94(%rbp), %rax
movq %rax, -0x2f8(%rbp)
leaq 0x2db62(%rip), %rdi     # 0x40480
leaq -0x2f8(%rbp), %rsi
callq 0x17280
movq %rax, -0x430(%rbp)
jmp 0x12933
movq -0x430(%rbp), %rax
movl -0x434(%rbp), %ecx
movl %ecx, (%rax)
jmp 0x12944
jmp 0x12946
leaq -0x80(%rbp), %rdi
callq 0xca80
jmp 0x120ea
leaq -0x350(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0xd980
jmp 0x12966
movaps -0x20(%rbp), %xmm0
movaps %xmm0, -0x360(%rbp)
movl -0x360(%rbp), %edx
movq -0x358(%rbp), %rcx
leaq -0x330(%rbp), %rdi
leaq -0x350(%rbp), %rsi
callq 0x9d90
jmp 0x12993
movq -0x8(%rbp), %rdi
leaq -0x330(%rbp), %rsi
callq 0xbf00
leaq -0x330(%rbp), %rdi
callq 0xbc80
leaq -0x350(%rbp), %rdi
callq 0x44a0
leaq -0x60(%rbp), %rdi
callq 0x44a0
leaq -0x40(%rbp), %rdi
callq 0x44a0
addq $0x440, %rsp            # imm = 0x440
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x350(%rbp), %rdi
callq 0x44a0
leaq -0x60(%rbp), %rdi
callq 0x44a0
leaq -0x40(%rbp), %rdi
callq 0x44a0
movq -0x68(%rbp), %rdi
callq 0x2300
nopl (%rax)