// File: /workspace/github_c_makefile_star2_O1/hobo0xcc[P]rve/src/cpu.c
// Function: ExecInstruction
void ExecInstruction(State *state, uint32_t instr) {
    uint8_t opcode = instr & SetNBits(7);
    // If an instruction is compressed.
    if ((opcode & SetNBits(2)) ^ SetNBits(2)) {
        ExecCompressedInstr(state, (uint16_t)(instr & SetNBits(16)));
        return;
    }

    // 32-bit Instruction.
    switch (opcode) {
    case OP_IMM:
        ExecOpImmInstr(state, instr);
        if (state->excepted) return;
        state->pc += sizeof(instr);
        break;
    case OP_AUIPC:
        ExecAuipc(state, instr);
        if (state->excepted) return;
        state->pc += sizeof(instr);
        break;
    case OP_LUI:
        ExecLui(state, instr);
        if (state->excepted) return;
        state->pc += sizeof(instr);
        break;
    case OP:
        ExecOpInstr(state, instr);
        if (state->excepted) return;
        state->pc += sizeof(instr);
        break;
    case JAL:
        ExecJal(state, instr);
        if (state->excepted) return;
        break;
    case JALR:
        ExecJalr(state, instr);
        if (state->excepted) return;
        break;
    case LOAD:
        ExecLoadInstr(state, instr);
        if (state->excepted) return;
        state->pc += sizeof(instr);
        break;
    case STORE:
        ExecStoreInstr(state, instr);
        if (state->excepted) return;
        state->pc += sizeof(instr);
        break;
    case BRANCH:
        ExecBranchInstr(state, instr);
        if (state->excepted) return;
        break;
    case OP_IMM_32:
        ExecOpImm32Instr(state, instr);
        if (state->excepted) return;
        state->pc += sizeof(instr);
        break;
    case OP_32:
        ExecOp32Instr(state, instr);
        if (state->excepted) return;
        state->pc += sizeof(instr);
        break;
    case SYSTEM:
        ExecSystemInstr(state, instr);
        if (state->excepted) return;
        break;
    case MISC_MEM:
        ExecMiscMem(state, instr);
        if (state->excepted) return;
        state->pc += sizeof(instr);
        break;
    case AMO:
        ExecAmo(state, instr);
        if (state->excepted) return;
        state->pc += sizeof(instr);
        break;
    default:
        Error("Unknown opcode: 0x%.2x.", opcode);
        break;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
pushq %rax
movq %rdi, %rbx
movl %esi, %eax
notl %eax
testb $0x3, %al
jne 0x1b93
movl %esi, %eax
andl $0x7f, %eax
leal -0x3(%rax), %ecx
shrl $0x2, %ecx
cmpl $0x1c, %ecx
ja 0x1d47
leaq 0x6487(%rip), %rdx      # 0x8004
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
movq %rbx, %rdi
callq 0x3db2
jmp 0x1d33
movzwl %si, %esi
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %rbp
jmp 0x523f
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %rbp
jmp 0x5a56
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %rbp
jmp 0x436b
movq %rbx, %rdi
callq 0x44ce
jmp 0x1d33
movl %esi, %eax
shrl $0xb, %eax
andl $0x100000, %eax         # imm = 0x100000
movl %esi, %ecx
andl $0xff000, %ecx          # imm = 0xFF000
movl %esi, %edx
shrl $0x9, %edx
andl $0x800, %edx            # imm = 0x800
movl %esi, %edi
shrl $0x14, %edi
andl $0x7fe, %edi            # imm = 0x7FE
orl %ecx, %edi
orl %edx, %edi
orl %eax, %edi
movq (%rbx), %rax
leaq 0x4(%rax), %rcx
movl %esi, %edx
shrl $0x4, %edx
andl $0xf8, %edx
leaq -0x200000(%rdi), %r8
testl %esi, %esi
movq %rcx, 0x8008(%rbx,%rdx)
cmovnsq %rdi, %r8
addq %rax, %r8
movq %r8, (%rbx)
jmp 0x1d40
movq %rbx, %rdi
callq 0x4082
jmp 0x1d33
movl %esi, %eax
shrl $0x14, %eax
movq (%rbx), %rcx
addq $0x4, %rcx
movl %esi, %edx
shrl $0xc, %edx
movl $0xf8, %edi
andl %edi, %edx
leaq -0x1000(%rax), %r8
testl %esi, %esi
cmovnsq %rax, %r8
addq 0x8008(%rbx,%rdx), %r8
andq $-0x2, %r8
movq %r8, (%rbx)
shrl $0x4, %esi
andl %edi, %esi
movq %rcx, 0x8008(%rbx,%rsi)
jmp 0x1d40
movl %esi, %ecx
andl $0xfffff000, %ecx       # imm = 0xFFFFF000
movabsq $-0x100000000, %rdx     # imm = 0xFFFFFFFF00000000
orq %rcx, %rdx
testl %esi, %esi
movq (%rbx), %rax
cmovnsq %rcx, %rdx
addq %rax, %rdx
shrl $0x4, %esi
andl $0xf8, %esi
movq %rdx, 0x8008(%rbx,%rsi)
cmpb $0x0, 0x8138(%rbx)
jne 0x1d40
addq $0x4, %rax
movq %rax, (%rbx)
jmp 0x1d40
movq %rbx, %rdi
callq 0x3053
jmp 0x1d33
testl $0x6000, %esi           # imm = 0x6000
je 0x1d33
leaq 0x6780(%rip), %rdi      # 0x8461
xorl %eax, %eax
callq 0x6b70
jmp 0x1d33
movq %rbx, %rdi
callq 0x66a8
jmp 0x1d33
movq %rbx, %rdi
callq 0x36cb
jmp 0x1d33
movq %rbx, %rdi
callq 0x493e
jmp 0x1d33
movl %esi, %eax
andl $0xfffff000, %eax       # imm = 0xFFFFF000
movabsq $-0x100000000, %rcx     # imm = 0xFFFFFFFF00000000
orq %rax, %rcx
testl %esi, %esi
cmovnsq %rax, %rcx
shrl $0x4, %esi
andl $0xf8, %esi
movq %rcx, 0x8008(%rbx,%rsi)
cmpb $0x0, 0x8138(%rbx)
jne 0x1d40
addq $0x4, (%rbx)
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
leaq 0x6750(%rip), %rdi      # 0x849e
movl %eax, %esi
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %rbp
jmp 0x6b70