// File: /workspace/github_c_makefile_star2_O0/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
andq $-0x40, %rsp
subq $0x600, %rsp            # imm = 0x600
movl $0x0, 0x35c(%rsp)
movl $0x0, 0xf4(%rsp)
cmpl $0x40, 0xf4(%rsp)
jge 0x1232
movslq 0xf4(%rsp), %rax
movb $0x3, 0x310(%rsp,%rax)
movslq 0xf4(%rsp), %rax
movb $0x4, 0x2d0(%rsp,%rax)
movl 0xf4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xf4(%rsp)
jmp 0x11f5
movl $0x0, 0xf0(%rsp)
cmpl $0x10, 0xf0(%rsp)
jge 0x126d
movslq 0xf0(%rsp), %rax
movl $0x1, 0x290(%rsp,%rax,4)
movl 0xf0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xf0(%rsp)
jmp 0x123d
movl $0x0, 0xec(%rsp)
cmpl $0x20, 0xec(%rsp)
jge 0x12a7
movslq 0xec(%rsp), %rax
movw $0x1, 0x250(%rsp,%rax,2)
movl 0xec(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xec(%rsp)
jmp 0x1278
leaq 0x310(%rsp), %rax
movq %rax, 0x378(%rsp)
movq 0x378(%rsp), %rax
vmovdqa64 (%rax), %zmm0
vmovdqa64 %zmm0, 0x200(%rsp)
leaq 0x2d0(%rsp), %rax
movq %rax, 0x370(%rsp)
movq 0x370(%rsp), %rax
vmovdqa64 (%rax), %zmm0
vmovdqa64 %zmm0, 0x1c0(%rsp)
leaq 0x290(%rsp), %rax
movq %rax, 0x368(%rsp)
movq 0x368(%rsp), %rax
vmovdqa64 (%rax), %zmm0
vmovdqa64 %zmm0, 0x180(%rsp)
leaq 0x250(%rsp), %rax
movq %rax, 0x360(%rsp)
movq 0x360(%rsp), %rax
vmovdqa64 (%rax), %zmm0
vmovdqa64 %zmm0, 0x140(%rsp)
vmovdqa64 0x180(%rsp), %zmm2
vmovdqa64 0x200(%rsp), %zmm1
vmovdqa64 0x1c0(%rsp), %zmm0
vmovdqa64 %zmm2, 0x400(%rsp)
vmovdqa64 %zmm1, 0x3c0(%rsp)
vmovdqa64 %zmm0, 0x380(%rsp)
vmovdqa64 0x400(%rsp), %zmm0
vmovdqa64 0x3c0(%rsp), %zmm1
vmovdqa64 0x380(%rsp), %zmm2
vpdpbusds %zmm2, %zmm1, %zmm0
vmovdqa64 %zmm0, 0x100(%rsp)
leaq 0x100(%rsp), %rax
movq %rax, 0xf8(%rsp)
leaq 0xc58(%rip), %rdi       # 0x2004
movb $0x0, %al
vzeroupper
callq 0x1030
movl $0xf, 0xe8(%rsp)
cmpl $0x0, 0xe8(%rsp)
jl 0x140c
movq 0xf8(%rsp), %rax
movslq 0xe8(%rsp), %rcx
movl (%rax,%rcx,4), %esi
movq 0x2bf3(%rip), %rdi      # 0x3fd8
callq 0x1080
movq %rax, %rdi
leaq 0xc32(%rip), %rsi       # 0x2026
callq 0x1050
movl 0xe8(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0xe8(%rsp)
jmp 0x13c1
movq 0x2bc5(%rip), %rdi      # 0x3fd8
movq 0x2bae(%rip), %rsi      # 0x3fc8
callq 0x1060
movq 0x2bb2(%rip), %rdi      # 0x3fd8
movq 0x2b9b(%rip), %rsi      # 0x3fc8
callq 0x1060
vmovdqa64 0x200(%rsp), %zmm1
vmovdqa64 0x1c0(%rsp), %zmm0
vmovdqa64 %zmm1, 0x480(%rsp)
vmovdqa64 %zmm0, 0x440(%rsp)
vmovdqa64 0x480(%rsp), %zmm0
vmovdqa64 0x440(%rsp), %zmm1
vpmaddubsw %zmm1, %zmm0, %zmm0
vmovdqa64 %zmm0, 0x80(%rsp)
vmovdqa64 0x80(%rsp), %zmm1
vmovdqa64 0x140(%rsp), %zmm0
vmovdqa64 %zmm1, 0x500(%rsp)
vmovdqa64 %zmm0, 0x4c0(%rsp)
vmovdqa64 0x500(%rsp), %zmm0
vmovdqa64 0x4c0(%rsp), %zmm1
vpmaddwd %zmm1, %zmm0, %zmm0
vmovdqa64 %zmm0, 0x40(%rsp)
vmovdqa64 0x40(%rsp), %zmm1
vmovdqa64 0x180(%rsp), %zmm0
vmovdqa64 %zmm1, 0x580(%rsp)
vmovdqa64 %zmm0, 0x540(%rsp)
vmovdqa64 0x580(%rsp), %zmm0
vmovdqa64 0x540(%rsp), %zmm1
vpaddd %zmm1, %zmm0, %zmm0
vmovdqa64 %zmm0, 0x100(%rsp)
leaq 0xb35(%rip), %rdi       # 0x2028
movb $0x0, %al
vzeroupper
callq 0x1030
leaq 0x100(%rsp), %rax
movq %rax, 0xf8(%rsp)
movl $0xf, 0x3c(%rsp)
cmpl $0x0, 0x3c(%rsp)
jl 0x1554
movq 0xf8(%rsp), %rax
movslq 0x3c(%rsp), %rcx
movl (%rax,%rcx,4), %esi
movq 0x2aa5(%rip), %rdi      # 0x3fd8
callq 0x1080
movq %rax, %rdi
leaq 0xae4(%rip), %rsi       # 0x2026
callq 0x1050
movl 0x3c(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x3c(%rsp)
jmp 0x1515
movq 0x2a7d(%rip), %rdi      # 0x3fd8
movq 0x2a66(%rip), %rsi      # 0x3fc8
callq 0x1060
movl 0x35c(%rsp), %eax
movq %rbp, %rsp
popq %rbp
retq