// File: /workspace/github_c_makefile_star2_O2/jwang11[P]intel_avx_perf/test_DLBoost.c
// Function: main
int main() {

   int8_t  op1_int8[64];
   int8_t  op2_int8[64];
   int     op3_int[16];
   int16_t op4_int16[32];

   __m512i v1_int8;
   __m512i v2_int8;
   __m512i v3_int;
   __m512i v4_int16;
   __m512i result;
   int* presult;

   // Choose some sample values
   for (int i = 0; i < 64; i++)
   {
       op1_int8[i]  = 3;
       op2_int8[i]  = 4;
   }
   for (int i = 0; i < 16; i++)
   {
       op3_int[i]   = 1;
   }
   for (int i = 0; i < 32; i++)
   {
       op4_int16[i] = 1;
   }

   //Load 512-bits of integer data
   v1_int8 =_mm512_load_si512(&op1_int8);
   v2_int8 =_mm512_load_si512(&op2_int8);
   v3_int =_mm512_load_si512(&op3_int);
   v4_int16 =_mm512_load_si512(&op4_int16);

   // PERFORM THE DOT PRODUCT OPERATION USING FUSED INSTRUCTION
   result = _mm512_dpbusds_epi32(v3_int,v1_int8,v2_int8);
   presult = (int*) &result;
   printf("RESULTS USING FUSED INSTRUCTION: \n ");
   for (int j = 15; j >= 0; j--)
       cout << presult[j]<<" ";
   cout << endl;
   cout << endl;

   // PERFORM THE DOT PRODUCT OPERATION USING A SEQUENCE OF 3 INSTRUCTIONS

   // Vertically multiply two 8-bit integers,
   // then horizontally add adjacent pairs of 16-bit integers

   __m512i vresult1 = _mm512_maddubs_epi16(v1_int8,v2_int8);

   // Upconvert to 32-bit and horizontally add neighbors. Multiply by 1.
   __m512i vresult2 = _mm512_madd_epi16(vresult1,v4_int16);

   // Add packed 32-bit integers
   result = _mm512_add_epi32(vresult2,v3_int);

   printf("RESULTS USING SEQUENCE OF 3 INSTRUCTIONS: \n ");
   presult = (int*) &result;
   for (int j = 15; j >= 0; j--)
       cout << presult[j]<<" ";
   cout << endl;

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
andq $-0x40, %rsp
subq $0x280, %rsp            # imm = 0x280
xorl %eax, %eax
cmpq $0x40, %rax
je 0x11ed
movb $0x3, 0x210(%rsp,%rax)
movb $0x4, 0x1d0(%rsp,%rax)
incq %rax
jmp 0x11d2
xorl %eax, %eax
cmpq $0x10, %rax
je 0x1205
movl $0x1, 0x190(%rsp,%rax,4)
incq %rax
jmp 0x11ef
xorl %eax, %eax
cmpq $0x20, %rax
je 0x121c
movw $0x1, 0x150(%rsp,%rax,2)
incq %rax
jmp 0x1207
vmovdqa64 0x210(%rsp), %zmm1
vmovdqa64 0x1d0(%rsp), %zmm2
vmovdqa64 0x190(%rsp), %zmm0
vmovaps 0x150(%rsp), %zmm3
vmovaps %zmm3, 0x40(%rsp)
vmovdqa64 %zmm0, 0xc0(%rsp)
vmovdqa64 %zmm1, 0x100(%rsp)
vmovdqa64 %zmm2, 0x80(%rsp)
vpdpbusds %zmm2, %zmm1, %zmm0
vmovdqa64 %zmm0, (%rsp)
leaq 0xd88(%rip), %rdi       # 0x2004
xorl %eax, %eax
vzeroupper
callq 0x1030
pushq $0xf
popq %r15
movq 0x2d47(%rip), %rbx      # 0x3fd8
leaq 0xd8e(%rip), %r14       # 0x2026
testl %r15d, %r15d
js 0x12bb
movl %r15d, %eax
movl (%rsp,%rax,4), %esi
movq %rbx, %rdi
callq 0x1080
movq %rax, %rdi
movq %r14, %rsi
callq 0x1060
decl %r15d
jmp 0x1298
movq 0x2d16(%rip), %rbx      # 0x3fd8
movq %rbx, %rdi
callq 0x1040
movq %rbx, %rdi
callq 0x1040
vmovdqa64 0x100(%rsp), %zmm0
vpmaddubsw 0x80(%rsp), %zmm0, %zmm0
vpmaddwd 0x40(%rsp), %zmm0, %zmm0
vpaddd 0xc0(%rsp), %zmm0, %zmm0
vmovdqa64 %zmm0, (%rsp)
leaq 0xd28(%rip), %rdi       # 0x2028
xorl %eax, %eax
vzeroupper
callq 0x1030
pushq $0xf
popq %r15
leaq 0xd11(%rip), %r14       # 0x2026
testl %r15d, %r15d
js 0x1338
movl %r15d, %eax
movl (%rsp,%rax,4), %esi
movq %rbx, %rdi
callq 0x1080
movq %rax, %rdi
movq %r14, %rsi
callq 0x1060
decl %r15d
jmp 0x1315
movq 0x2c99(%rip), %rdi      # 0x3fd8
callq 0x1040
xorl %eax, %eax
leaq -0x18(%rbp), %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq