// File: /workspace/github_c_makefile_star2_O3/mvermeulen[P]wspy/topdown.c
// Function: setup_counters
void setup_counters(struct counter_group *counter_group_list){
  unsigned int mask = 0;
  int i,j,k;
  int count;
  int nerror = 0;
  int status;
  int group_id = -1;
  struct counter_group *cgroup;
  struct perf_event_attr pe;

  struct cpu_core_info *coreinfo;
  struct counter_def *counter_def;
  int ncounters;

  // create system-wide counters
  for (cgroup = counter_group_list;cgroup;cgroup = cgroup->next){
    debug("Setting up %s counters\n",cgroup->label);
    for (i=0;i<cgroup->ncounters;i++){
      if (cpu_info->vendor == VENDOR_INTEL){
	group_id = intel_group_id;
      } else {
	if (cgroup->cinfo[i].is_group_leader == 1) group_id = -1;
      }
      memset(&pe,0,sizeof(pe));
      pe.type = (cgroup->type_id==PERF_TYPE_RAW)?cgroup->cinfo[i].device_type:cgroup->type_id;
      pe.config = cgroup->cinfo[i].config;
      pe.sample_type = PERF_SAMPLE_IDENTIFIER; // is this needed?
      pe.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED|PERF_FORMAT_TOTAL_TIME_RUNNING;
      pe.size = sizeof(struct perf_event_attr);
      //      pe.exclude_guest = 1; // is this needed
      pe.inherit = 1;
      pe.disabled = 1;

      if (pe.type == PERF_TYPE_L3){
	// read from any process on this core
	pe.exclude_guest = 0;
	status = perf_event_open(&pe,-1,0,group_id,0);
      } else {
	// read from current process
	status = perf_event_open(&pe,0,-1,group_id,PERF_FLAG_FD_CLOEXEC);	
      }


      if (status == -1){
	error("unable to create %s performance counter, name=%s, errno=%d - %s\n",
	      cgroup->label,cgroup->cinfo[i].label,errno,strerror(errno));
	cgroup->cinfo[i].fd = -1;
	nerror++;
      } else {
	cgroup->cinfo[i].fd = status;
	ioctl(cgroup->cinfo[i].fd,PERF_EVENT_IOC_ENABLE,0);
	debug("   create %s performance counter, name=%s\n",cgroup->label,cgroup->cinfo[i].label);
	if (group_id == -1){
	  group_id = cgroup->cinfo[i].fd;
	  intel_group_id = group_id;
	}
      }
    }
  }
  if (nerror) fatal("unable to open performance counters\n");
}

// Assembly:
testq %rdi, %rdi
je 0x530f
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movq %rdi, %rbx
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
leaq 0xe036(%rip), %r12      # 0x13160
movl $0x3, %r13d
movl $0x0, 0x8(%rsp)
movq (%rbx), %rsi
leaq 0x7913(%rip), %rdi      # 0xca55
xorl %eax, %eax
callq 0x95da
cmpl $0x0, 0xc(%rbx)
jle 0x52dc
xorl %r15d, %r15d
xorl %ebp, %ebp
movq (%r12), %rax
cmpl $0x2, (%rax)
jne 0x516a
movl 0xcf48(%rip), %r14d     # 0x120b0
jmp 0x5181
movq 0x18(%rbx), %rax
movb 0xc(%rax,%r15), %al
andb $0x1, %al
negb %al
movl $0x0, %eax
sbbl %eax, %eax
orl %eax, %r14d
xorps %xmm0, %xmm0
movaps %xmm0, 0x80(%rsp)
movaps %xmm0, 0x70(%rsp)
movaps %xmm0, 0x60(%rsp)
movaps %xmm0, 0x50(%rsp)
movaps %xmm0, 0x40(%rsp)
movaps %xmm0, 0x30(%rsp)
movaps %xmm0, 0x20(%rsp)
movaps %xmm0, 0x10(%rsp)
movl 0x8(%rbx), %eax
movq 0x18(%rbx), %rcx
cmpl $0x4, %eax
jne 0x51c0
movl 0x10(%rcx,%r15), %eax
movl %eax, 0x10(%rsp)
movq 0x18(%rcx,%r15), %rcx
movq %rcx, 0x18(%rsp)
movq $0x10000, 0x28(%rsp)    # imm = 0x10000
movq %r13, 0x30(%rsp)
movl $0x80, 0x14(%rsp)
movq %r13, 0x38(%rsp)
cmpl $0xe, %eax
jne 0x5202
leaq 0x10(%rsp), %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
xorl %edx, %edx
movl %r14d, %ecx
xorl %r8d, %r8d
jmp 0x5217
movl $0x8, %r8d
leaq 0x10(%rsp), %rdi
xorl %esi, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movl %r14d, %ecx
callq 0x4b35
cmpl $-0x1, %eax
je 0x526b
movq 0x18(%rbx), %rcx
movl %eax, 0x28(%rcx,%r15)
movl $0x2400, %esi           # imm = 0x2400
movl %eax, %edi
xorl %edx, %edx
xorl %eax, %eax
callq 0x3110
movq (%rbx), %rsi
movq 0x18(%rbx), %rax
movq (%rax,%r15), %rdx
leaq 0x7862(%rip), %rdi      # 0xcaae
xorl %eax, %eax
callq 0x95da
cmpl $-0x1, %r14d
jne 0x52c8
movq 0x18(%rbx), %rax
movl 0x28(%rax,%r15), %r14d
movl %r14d, 0xce47(%rip)     # 0x120b0
jmp 0x52c8
movl %r14d, 0xc(%rsp)
movq (%rbx), %r14
movq 0x18(%rbx), %rax
movq (%rax,%r15), %r12
callq 0x3040
movl (%rax), %r13d
movl %r13d, %edi
callq 0x32f0
leaq 0x77db(%rip), %rdi      # 0xca6d
movq %r14, %rsi
movl 0xc(%rsp), %r14d
movq %r12, %rdx
leaq 0xdebc(%rip), %r12      # 0x13160
movl %r13d, %ecx
movl $0x3, %r13d
movq %rax, %r8
xorl %eax, %eax
callq 0x9230
movq 0x18(%rbx), %rax
movl $0xffffffff, 0x28(%rax,%r15) # imm = 0xFFFFFFFF
incl 0x8(%rsp)
incq %rbp
movslq 0xc(%rbx), %rax
addq $0x58, %r15
cmpq %rax, %rbp
jl 0x5158
movq 0x20(%rbx), %rbx
testq %rbx, %rbx
jne 0x5138
cmpl $0x0, 0x8(%rsp)
je 0x52fe
leaq 0x77e2(%rip), %rdi      # 0xcad9
xorl %eax, %eax
callq 0x913b
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq