// File: joakimkistowski[P]amd-disable-c6/amd-disable-c6.cpp
// Function: direct_execution_main(op_mode const&)
int direct_execution_main(const op_mode &mode) {
    switch(mode) {
        case ERROR:
            return 1;
        case NONE:
            return 0;
        default:
            uint64_t core_msr_value = read_msr(CORE_MSR_ADDR);
            uint64_t package_msr_value = read_msr(PACKAGE_MSR_ADDR);
            if (!core_msr_value || !package_msr_value) {
                std::cerr << "Error reading msr; got invalid value" << std::endl;
                return 1;
            }
            if (mode == ENABLE) {
                    unsigned int err = write_msr(PACKAGE_MSR_ADDR, package_msr_value | PACKAGE_MSR_ENABLED);
                    err = err | write_msr(CORE_MSR_ADDR, core_msr_value | CORE_MSR_ENABLED);
                    if (err) {
                        return 1;
                    }
                    std::cout << "Enabled C6 state" << std::endl;
                    return 0;
            } else if (mode == DISABLE) {
                    unsigned int err = write_msr(PACKAGE_MSR_ADDR, package_msr_value & PACKAGE_MSR_DISABLED);
                    err = err | write_msr(CORE_MSR_ADDR, core_msr_value & CORE_MSR_DISABLED);
                    if (err) {
                        return 1;
                    }
                    std::cout << "Disabled C6 state" << std::endl;
                    return 0;
            } else if (mode == LIST) {
                    std::cout << "C6 State - Package : ";
                    if (package_msr_value & PACKAGE_MSR_ENABLED) {
                        std:: cout << "Enabled" << std::endl;
                    } else {
                        std:: cout << "Disabled" << std::endl;
                    }
                    std::cout << "C6 State - Core    : ";
                    if ((core_msr_value & CORE_MSR_ENABLED) == CORE_MSR_ENABLED) {
                        std:: cout << "Enabled" << std::endl;
                    } else {
                        std:: cout << "Disabled" << std::endl;
                    }
                    return 0;
            }
    }
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x2c(%rbp)
subl $0x4, %eax
je 0x3aa2
jmp 0x3a8c
movl -0x2c(%rbp), %eax
subl $0x5, %eax
jne 0x3aae
jmp 0x3a96
movl $0x1, -0x4(%rbp)
jmp 0x3d33
movl $0x0, -0x4(%rbp)
jmp 0x3d33
movl $0xc0010296, %edi       # imm = 0xC0010296
xorl %esi, %esi
callq 0x3120
movq %rax, -0x18(%rbp)
movl $0xc0010292, %edi       # imm = 0xC0010292
xorl %esi, %esi
callq 0x3120
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0x3adc
cmpq $0x0, -0x20(%rbp)
jne 0x3b0a
movq 0x550d(%rip), %rdi      # 0x8ff0
leaq 0x2816(%rip), %rsi      # 0x6300
callq 0x21b0
movq %rax, %rdi
movq 0x54b7(%rip), %rsi      # 0x8fb0
callq 0x21f0
movl $0x1, -0x4(%rbp)
jmp 0x3d33
movq -0x10(%rbp), %rax
cmpl $0x2, (%rax)
jne 0x3ba1
movabsq $0x100000000, %rsi      # imm = 0x100000000
orq -0x20(%rbp), %rsi
movl $0xc0010292, %edi       # imm = 0xC0010292
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x2d00
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0x30(%rbp)
movq -0x18(%rbp), %rsi
orq $0x404040, %rsi         # imm = 0x404040
movl $0xc0010296, %edi       # imm = 0xC0010296
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x2d00
movl %eax, %ecx
movl -0x30(%rbp), %eax
orl %ecx, %eax
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
je 0x3b73
movl $0x1, -0x4(%rbp)
jmp 0x3d33
movq 0x544e(%rip), %rdi      # 0x8fc8
leaq 0x27a4(%rip), %rsi      # 0x6325
callq 0x21b0
movq %rax, %rdi
movq 0x5420(%rip), %rsi      # 0x8fb0
callq 0x21f0
movl $0x0, -0x4(%rbp)
jmp 0x3d33
movq -0x10(%rbp), %rax
cmpl $0x0, (%rax)
jne 0x3c38
movabsq $-0x100000001, %rsi     # imm = 0xFFFFFFFEFFFFFFFF
andq -0x20(%rbp), %rsi
movl $0xc0010292, %edi       # imm = 0xC0010292
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x2d00
movl %eax, -0x28(%rbp)
movl -0x28(%rbp), %eax
movl %eax, -0x34(%rbp)
movq -0x18(%rbp), %rsi
andq $-0x404041, %rsi        # imm = 0xFFBFBFBF
movl $0xc0010296, %edi       # imm = 0xC0010296
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0x2d00
movl %eax, %ecx
movl -0x34(%rbp), %eax
orl %ecx, %eax
movl %eax, -0x28(%rbp)
cmpl $0x0, -0x28(%rbp)
je 0x3c0a
movl $0x1, -0x4(%rbp)
jmp 0x3d33
movq 0x53b7(%rip), %rdi      # 0x8fc8
leaq 0x271e(%rip), %rsi      # 0x6336
callq 0x21b0
movq %rax, %rdi
movq 0x5389(%rip), %rsi      # 0x8fb0
callq 0x21f0
movl $0x0, -0x4(%rbp)
jmp 0x3d33
movq -0x10(%rbp), %rax
cmpl $0x3, (%rax)
jne 0x3d26
movq 0x537c(%rip), %rdi      # 0x8fc8
leaq 0x26f5(%rip), %rsi      # 0x6348
callq 0x21b0
movabsq $0x100000000, %rax      # imm = 0x100000000
andq -0x20(%rbp), %rax
cmpq $0x0, %rax
je 0x3c90
movq 0x5355(%rip), %rdi      # 0x8fc8
leaq 0x26e4(%rip), %rsi      # 0x635e
callq 0x21b0
movq %rax, %rdi
movq 0x5327(%rip), %rsi      # 0x8fb0
callq 0x21f0
jmp 0x3cb2
movq 0x5331(%rip), %rdi      # 0x8fc8
leaq 0x26c8(%rip), %rsi      # 0x6366
callq 0x21b0
movq %rax, %rdi
movq 0x5303(%rip), %rsi      # 0x8fb0
callq 0x21f0
movq 0x530f(%rip), %rdi      # 0x8fc8
leaq 0x26af(%rip), %rsi      # 0x636f
callq 0x21b0
movq -0x18(%rbp), %rax
andq $0x404040, %rax         # imm = 0x404040
cmpq $0x404040, %rax         # imm = 0x404040
jne 0x3cfb
movq 0x52ea(%rip), %rdi      # 0x8fc8
leaq 0x2679(%rip), %rsi      # 0x635e
callq 0x21b0
movq %rax, %rdi
movq 0x52bc(%rip), %rsi      # 0x8fb0
callq 0x21f0
jmp 0x3d1d
movq 0x52c6(%rip), %rdi      # 0x8fc8
leaq 0x265d(%rip), %rsi      # 0x6366
callq 0x21b0
movq %rax, %rdi
movq 0x5298(%rip), %rsi      # 0x8fb0
callq 0x21f0
movl $0x0, -0x4(%rbp)
jmp 0x3d33
jmp 0x3d28
jmp 0x3d2a
jmp 0x3d2c
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax)