// File: JMMackenzie[P]binary_to_jass/bin_to_jass_disk.cpp
// Function: void fastDelta<unsigned int>(unsigned int*, unsigned long)
static void fastDelta(T * pData, const size_t TotalQty) {
         if (TotalQty < 5) {
             delta(pData, TotalQty);// no SIMD
             return;
         }

         const size_t Qty4 = TotalQty / 4;
         __m128i* pCurr = reinterpret_cast<__m128i*>(pData);
         const __m128i* pEnd = pCurr + Qty4;

         __m128i last = _mm_setzero_si128();
         while (pCurr < pEnd) {
             __m128i a0 = _mm_load_si128(pCurr);
             __m128i a1 = _mm_sub_epi32(a0, _mm_srli_si128(last, 12));
             a1 = _mm_sub_epi32(a1, _mm_slli_si128(a0, 4));
             last = a0;
            
             _mm_store_si128(pCurr++ , a1);
         }

         if (Qty4 * 4 < TotalQty) {
             uint32_t lastVal = _mm_cvtsi128_si32(_mm_srli_si128(last, 12));
             for (size_t i = Qty4 * 4; i < TotalQty; ++i) {
                 uint32_t newVal = pData[i];
                 pData[i] -= lastVal;
                 lastVal = newVal;
             }
         }
    }

// Assembly:
subq $0x128, %rsp            # imm = 0x128
movq %rdi, 0x78(%rsp)
movq %rsi, 0x70(%rsp)
cmpq $0x5, 0x70(%rsp)
jae 0x415d
movq 0x78(%rsp), %rdi
movq 0x70(%rsp), %rsi
callq 0x4ab0
jmp 0x4342
movq 0x70(%rsp), %rax
shrq $0x2, %rax
movq %rax, 0x68(%rsp)
movq 0x78(%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rax
movq 0x68(%rsp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, 0x58(%rsp)
vxorps %xmm0, %xmm0, %xmm0
vmovdqa %xmm0, 0x80(%rsp)
vmovdqa 0x80(%rsp), %xmm0
vmovdqa %xmm0, 0x40(%rsp)
movq 0x60(%rsp), %rax
cmpq 0x58(%rsp), %rax
jae 0x42a2
movq 0x60(%rsp), %rax
movq %rax, 0x98(%rsp)
movq 0x98(%rsp), %rax
vmovdqa (%rax), %xmm0
vmovdqa %xmm0, 0x30(%rsp)
vmovdqa 0x30(%rsp), %xmm1
vmovdqa 0x40(%rsp), %xmm0
vpsrldq $0xc, %xmm0, %xmm0      # xmm0 = xmm0[12,13,14,15],zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero
vmovdqa %xmm1, 0xd0(%rsp)
vmovdqa %xmm0, 0xc0(%rsp)
vmovdqa 0xd0(%rsp), %xmm0
vmovdqa 0xc0(%rsp), %xmm1
vpsubd %xmm1, %xmm0, %xmm0
vmovdqa %xmm0, 0x20(%rsp)
vmovdqa 0x20(%rsp), %xmm1
vmovdqa 0x30(%rsp), %xmm0
vpslldq $0x4, %xmm0, %xmm0      # xmm0 = zero,zero,zero,zero,xmm0[0,1,2,3,4,5,6,7,8,9,10,11]
vmovdqa %xmm1, 0xb0(%rsp)
vmovdqa %xmm0, 0xa0(%rsp)
vmovdqa 0xb0(%rsp), %xmm0
vmovdqa 0xa0(%rsp), %xmm1
vpsubd %xmm1, %xmm0, %xmm0
vmovdqa %xmm0, 0x20(%rsp)
vmovdqa 0x30(%rsp), %xmm0
vmovdqa %xmm0, 0x40(%rsp)
movq 0x60(%rsp), %rax
movq %rax, %rcx
addq $0x10, %rcx
movq %rcx, 0x60(%rsp)
vmovdqa 0x20(%rsp), %xmm0
movq %rax, 0xf8(%rsp)
vmovdqa %xmm0, 0xe0(%rsp)
vmovdqa 0xe0(%rsp), %xmm0
movq 0xf8(%rsp), %rax
vmovdqa %xmm0, (%rax)
jmp 0x41a7
movq 0x68(%rsp), %rax
shlq $0x2, %rax
cmpq 0x70(%rsp), %rax
jae 0x4342
vmovdqa 0x40(%rsp), %xmm0
vpsrldq $0xc, %xmm0, %xmm0      # xmm0 = xmm0[12,13,14,15],zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero
vmovdqa %xmm0, 0x110(%rsp)
vmovdqa 0x110(%rsp), %xmm0
vmovdqa %xmm0, 0x100(%rsp)
movl 0x100(%rsp), %eax
movl %eax, 0x1c(%rsp)
movq 0x68(%rsp), %rax
shlq $0x2, %rax
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rax
cmpq 0x70(%rsp), %rax
jae 0x4340
movq 0x78(%rsp), %rax
movq 0x10(%rsp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, 0xc(%rsp)
movl 0x1c(%rsp), %esi
movq 0x78(%rsp), %rax
movq 0x10(%rsp), %rcx
movl (%rax,%rcx,4), %edx
subl %esi, %edx
movl %edx, (%rax,%rcx,4)
movl 0xc(%rsp), %eax
movl %eax, 0x1c(%rsp)
movq 0x10(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x10(%rsp)
jmp 0x42f5
jmp 0x4342
addq $0x128, %rsp            # imm = 0x128
retq
nopw (%rax,%rax)