// File: /workspace/github_c_makefile_star2_O2/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movq %rdi, %rbx
pushq $-0x1
popq %r14
leaq 0xd0d8(%rip), %r12      # 0x12170
pushq $0x3
popq %r13
leaq 0x10(%rsp), %rbp
movl %r14d, %ecx
movl $0x0, (%rsp)
testq %rbx, %rbx
je 0x5259
movq (%rbx), %rsi
leaq 0x6997(%rip), %rdi      # 0xba55
xorl %eax, %eax
movl %ecx, %r15d
callq 0x93c0
movl %r15d, %ecx
xorl %r15d, %r15d
xorl %edx, %edx
movslq 0xc(%rbx), %rax
cmpq %rax, %rdx
jge 0x5250
movq (%r12), %rax
cmpl $0x2, (%rax)
movq %rdx, 0x8(%rsp)
jne 0x50f3
movl 0xbfcf(%rip), %ecx      # 0x110c0
jmp 0x5109
movq 0x18(%rbx), %rax
movb 0xc(%rax,%r15), %al
andb $0x1, %al
negb %al
movl $0x0, %eax
sbbl %eax, %eax
orl %eax, %ecx
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), %rdx
cmpl $0x4, %eax
jne 0x5148
movl 0x10(%rdx,%r15), %eax
movl %eax, 0x10(%rsp)
movq 0x18(%rdx,%r15), %rdx
movq %rdx, 0x18(%rsp)
movq $0x10000, 0x28(%rsp)    # imm = 0x10000
movq %r13, 0x30(%rsp)
movl $0x80, 0x14(%rsp)
movq %r13, 0x38(%rsp)
cmpl $0xe, %eax
movl %ecx, 0x4(%rsp)
movq %rbp, %rdi
jne 0x5187
movl %r14d, %esi
xorl %edx, %edx
xorl %r8d, %r8d
jmp 0x5190
xorl %esi, %esi
movl %r14d, %edx
pushq $0x8
popq %r8
callq 0x4ad8
cmpl $-0x1, %eax
je 0x51e6
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 0x68e9(%rip), %rdi      # 0xbaae
xorl %eax, %eax
callq 0x93c0
movl 0x4(%rsp), %ecx
cmpl $-0x1, %ecx
jne 0x523f
movq 0x18(%rbx), %rax
movl 0x28(%rax,%r15), %ecx
movl %ecx, 0xbedc(%rip)      # 0x110c0
jmp 0x523f
movq (%rbx), %r14
movq 0x18(%rbx), %rax
movq (%rax,%r15), %r13
callq 0x3040
movq %r12, %rbp
movl (%rax), %r12d
movl %r12d, %edi
callq 0x3300
leaq 0x6862(%rip), %rdi      # 0xba6d
movq %r14, %rsi
pushq $-0x1
popq %r14
movq %r13, %rdx
pushq $0x3
popq %r13
movl %r12d, %ecx
movq %rbp, %r12
leaq 0x10(%rsp), %rbp
movq %rax, %r8
xorl %eax, %eax
callq 0x901e
movq 0x18(%rbx), %rax
orl $-0x1, 0x28(%rax,%r15)
incl (%rsp)
movl 0x4(%rsp), %ecx
movq 0x8(%rsp), %rdx
incq %rdx
addq $0x58, %r15
jmp 0x50d0
movq 0x20(%rbx), %rbx
jmp 0x50ab
cmpl $0x0, (%rsp)
je 0x526d
leaq 0x6873(%rip), %rdi      # 0xbad9
xorl %eax, %eax
callq 0x8f2f
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq