// File: /workspace/github_c_makefile_star2_O1/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 $0x180, %rsp            # imm = 0x180
xorl %eax, %eax
movl $0x1, 0x110(%rsp,%rax,4)
incq %rax
cmpq $0x10, %rax
jne 0x11f2
xorl %eax, %eax
movw $0x1, 0xd0(%rsp,%rax,2)
incq %rax
cmpq $0x20, %rax
jne 0x1208
vmovdqa64 0x110(%rsp), %zmm1
vmovaps 0xd0(%rsp), %zmm0
vmovaps %zmm0, 0x40(%rsp)
vpbroadcastd 0xdc1(%rip), %zmm0 # 0x2004
vmovdqa64 %zmm1, 0x80(%rsp)
vpdpbusds 0xdb3(%rip){1to16}, %zmm0, %zmm1 # 0x2008
vmovdqa64 %zmm1, (%rsp)
leaq 0xdab(%rip), %rdi       # 0x200e
xorl %eax, %eax
vzeroupper
callq 0x1040
movl $0xf, %r15d
movq 0x2d5e(%rip), %rbx      # 0x3fd8
leaq 0xdaf(%rip), %r14       # 0x2030
movl (%rsp,%r15,4), %esi
movq %rbx, %rdi
callq 0x10a0
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x1080
addq $-0x1, %r15
jb 0x1281
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x1070
movsbl %al, %esi
movq %rbx, %rdi
callq 0x1030
movq %rax, %rdi
callq 0x1050
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x1070
movsbl %al, %esi
movq %rbx, %rdi
callq 0x1030
movq %rax, %rdi
callq 0x1050
vpbroadcastw 0xd11(%rip), %zmm0 # 0x200c
vmovdqa64 0x80(%rsp), %zmm1
vpdpwssd 0x40(%rsp), %zmm0, %zmm1
vmovdqa64 %zmm1, (%rsp)
leaq 0xd19(%rip), %rdi       # 0x2032
xorl %eax, %eax
vzeroupper
callq 0x1040
movl $0xf, %r15d
leaq 0xd00(%rip), %r14       # 0x2030
movl (%rsp,%r15,4), %esi
movq %rbx, %rdi
callq 0x10a0
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x1080
addq $-0x1, %r15
jb 0x1330
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x1070
movsbl %al, %esi
movq %rbx, %rdi
callq 0x1030
movq %rax, %rdi
callq 0x1050
xorl %eax, %eax
leaq -0x18(%rbp), %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq