// File: /workspace/github_cpp_makefile_star2_O2/NGageMegaman[P]NEScutre/src/cpu.cpp
// Function: Cpu::execute()
void Cpu::execute() {
    addr_mode_t addr_mode;
    uint8_t opcode = mem.read_byte(regPC);
    uint32_t addrop = read_operand(opcode, &addr_mode);
    uint16_t address = addrop >> 16;
    uint8_t operand = addrop & 0xFF;

    switch (opcode) {
	case ADC1: case ADC2: case ADC3: case ADC4:
	case ADC5: case ADC6: case ADC7: case ADC8:
	    ADC_execute(operand);
	    break;
	case AND1: case AND2: case AND3: case AND4:
	case AND5: case AND6: case AND7: case AND8:
	    AND_execute(operand);
	    break;
	case ASL2:
	    ASL_A_execute();
	    break;
	case ASL1: case ASL3: case ASL4: case ASL5:
	    ASL_mem_execute(address, operand);
	    break;
	case BCC:
	    BCC_execute(address);
	    break;
	case BCS:
	    BCS_execute(address);
	    break;
	case BEQ:
	    BEQ_execute(address);
	    break;
	case BIT1: case BIT2:
	    BIT_execute(operand);
	    break;
	case BMI:
	    BMI_execute(address);
	    break;
	case BNE:
	    BNE_execute(address);
	    break;
	case BPL:
	    BPL_execute(address);
	    break;
	case BRK:
	    BRK_execute();
	    break;
	case BVC:
	    BVC_execute(address);
	    break;
	case BVS:
	    BVS_execute(address);
	    break;
	case CLC:
	    CLC_execute();
	    break;
	case CLD:
	    CLD_execute();
	    break;
	case CLI:
	    CLI_execute();
	    break;
	case CLV:
	    CLV_execute();
	    break;
	case CMP1: case CMP2: case CMP3: case CMP4:
	case CMP5: case CMP6: case CMP7: case CMP8:
	    CMP_execute(operand);
	    break;
	case CPX1: case CPX2: case CPX3:
	    CPX_execute(operand);
	    break;
	case CPY1: case CPY2: case CPY3:
	    CPY_execute(operand);
	    break;
	case DEC1: case DEC2: case DEC3: case DEC4:
	    DEC_execute(address, operand);
	    break;
	case DEX:
	    DEX_execute();
	    break;
	case DEY:
	    DEY_execute();
	    break;
	case EOR1: case EOR2: case EOR3: case EOR4: 
	case EOR5: case EOR6: case EOR7: case EOR8: 
	    EOR_execute(operand);
	    break;
	case INC1: case INC2: case INC3: case INC4:
	    INC_execute(address, operand);
	    break;
	case INX:
	    INX_execute();
	    break;
	case INY:
	    INY_execute();
	    break;
	case JMP1: case JMP2:
	    JMP_execute(address);
	    break;
	case JSR:
	    JSR_execute(address);
	    break;
	case LDA1: case LDA2: case LDA3: case LDA4:
	case LDA5: case LDA6: case LDA7: case LDA8:
	    LDA_execute(operand);
	    break;
	case LDX1: case LDX2: case LDX3: case LDX4: case LDX5:
	    LDX_execute(operand);
	    break;
	case LDY1: case LDY2: case LDY3: case LDY4: case LDY5:
	    LDY_execute(operand);
	    break;
	case LSR1: case LSR3: case LSR4: case LSR5:
	    LSR_mem_execute(address, operand);
	    break;
	case LSR2:
	    LSR_A_execute();
	    break;
	case ORA1: case ORA2: case ORA3: case ORA4:
	case ORA5: case ORA6: case ORA7: case ORA8:
	    ORA_execute(operand);
	    break;
	case PHA:
	    PHA_execute();
	    break;
	case PHP:
	    PHP_execute();
	    break;
	case PLA:
	    PLA_execute();
	    break;
	case PLP:
	    PLP_execute();
	case ROL1: case ROL3: case ROL4: case ROL5:
	    ROL_mem_execute(address, operand);
	    break;
	case ROL2:
	    ROL_A_execute();
	    break;
	case ROR1: case ROR3: case ROR4: case ROR5:
	    ROR_mem_execute(address, operand);
	    break;
	case ROR2:
	    ROR_A_execute();
	    break;
	case RTI:
	    RTI_execute();
	    break;
	case RTS:
	    RTS_execute();
	    break;
	case SBC1: case SBC2: case SBC3: case SBC4:
	case SBC5: case SBC6: case SBC7: case SBC8:
	    SBC_execute(operand);
	    break;
	case SEC:
	    SEC_execute();
	    break;
	case SED:
	    SED_execute();
	    break;
	case SEI:
	    SEI_execute();
	    break;
	case STA1: case STA2: case STA3:
	case STA4: case STA5: case STA6: case STA7:
	    STA_execute(address);
	    break;
	case STX1: case STX2: case STX3:
	    STX_execute(address);
	    break;
	case STY1: case STY2: case STY3:
	    STY_execute(address);
	    break;
	case TAX:
	    TAX_execute();
	    break;
	case TAY:
	    TAY_execute();
	    break;
	case TSX:
	    TSX_execute();
	    break;
	case TXA:
	    TXA_execute();
	    break;
	case TXS:
	    TXS_execute();
	    break;
	case TYA:
	    TYA_execute();
	    break;
	default : 
	    NOP_execute();
    }
    add_clock_cycles(opcode, address, addr_mode);
    //debug_dump(opcode);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
addq $0x8, %rdi
movzwl 0x10024(%rbx), %esi
callq 0x2be2
movzbl %al, %r14d
leaq 0x4(%rsp), %rdx
movq %rbx, %rdi
movl %r14d, %esi
callq 0x17d6
movl %eax, %r15d
shrl $0x10, %eax
movzwl %ax, %ebp
cmpb $-0x1, %r14b
je 0x14ed
leaq 0x2bc6(%rip), %rcx      # 0x4004
movslq (%rcx,%r14,4), %rdx
addq %rcx, %rdx
jmpq *%rdx
orb 0x10020(%rbx), %r15b
jmp 0x14a5
movb %r15b, 0x10020(%rbx)
jmp 0x14d8
movzbl %r15b, %esi
movq %rbx, %rdi
callq 0x2028
jmp 0x14ed
movb 0x10020(%rbx), %al
movl %eax, %ecx
xorb %r15b, %cl
movb %cl, 0x10020(%rbx)
cmpb %r15b, %al
sete 0x10029(%rbx)
shrb $0x7, %cl
movb %cl, 0x1002e(%rbx)
jmp 0x14ed
movzbl %r15b, %esi
movq %rbx, %rdi
callq 0x188a
jmp 0x14ed
andb 0x10020(%rbx), %r15b
movb %r15b, 0x10020(%rbx)
jmp 0x14db
movzbl %r15b, %esi
movq %rbx, %rdi
callq 0x1ae4
jmp 0x14ed
movq %rbx, %rdi
movl %ebp, %esi
callq 0x2090
jmp 0x14ed
movb %r15b, 0x10021(%rbx)
jmp 0x14d8
movb %r15b, 0x10022(%rbx)
testb %r15b, %r15b
sete 0x10029(%rbx)
shrb $0x7, %r15b
movb %r15b, 0x1002e(%rbx)
movl 0x4(%rsp), %ecx
movq %rbx, %rdi
movl %r14d, %esi
movl %ebp, %edx
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x2170
movzbl %r15b, %edx
movq %rbx, %rdi
movl %ebp, %esi
callq 0x1be2
jmp 0x14ed
movzbl %r15b, %edx
movq %rbx, %rdi
movl %ebp, %esi
callq 0x1b4a
jmp 0x14ed
movzbl %r15b, %edx
movq %rbx, %rdi
movl %ebp, %esi
callq 0x1ed6
jmp 0x14ed
movzbl %r15b, %edx
movq %rbx, %rdi
movl %ebp, %esi
callq 0x1932
jmp 0x14ed
movzbl %r15b, %edx
movq %rbx, %rdi
movl %ebp, %esi
callq 0x1ce4
jmp 0x14ed
movzbl %r15b, %esi
movq %rbx, %rdi
callq 0x1b06
jmp 0x14ed
movq %rbx, %rdi
movl %ebp, %esi
callq 0x20a0
jmp 0x14ed
movq %rbx, %rdi
movl %ebp, %esi
callq 0x20b0
jmp 0x14ed
movzbl %r15b, %esi
movq %rbx, %rdi
callq 0x1b28
jmp 0x14ed
movzbl %r15b, %esi
movq %rbx, %rdi
callq 0x19a8
jmp 0x14ed
cmpb $0x0, 0x10028(%rbx)
jne 0x14ed
jmp 0x16d9
cmpb $0x1, 0x10028(%rbx)
jne 0x14ed
jmp 0x16d9
movb 0x10021(%rbx), %al
movb %al, 0x10026(%rbx)
jmp 0x14ed
movb $0x1, 0x1002a(%rbx)
jmp 0x14ed
movq %rbx, %rdi
callq 0x1d22
jmp 0x14ed
movb 0x10020(%rbx), %al
movb %al, 0x10021(%rbx)
jmp 0x17a6
cmpb $0x1, 0x10029(%rbx)
jne 0x14ed
jmp 0x16d9
cmpb $0x0, 0x10029(%rbx)
jne 0x14ed
jmp 0x16d9
movq %rbx, %rdi
callq 0x1dc8
jmp 0x14ed
movq %rbx, %rdi
callq 0x1d6e
jmp 0x14ed
cmpb $0x1, 0x1002e(%rbx)
jne 0x14ed
jmp 0x16d9
movb 0x10021(%rbx), %al
jmp 0x1778
cmpb $0x1, 0x1002d(%rbx)
jne 0x14ed
jmp 0x16d9
movq %rbx, %rdi
callq 0x1f64
jmp 0x14ed
movb $0x0, 0x10028(%rbx)
jmp 0x14ed
movq %rbx, %rdi
callq 0x1906
jmp 0x14ed
movq %rbx, %rdi
callq 0x1d7a
jmp 0x14ed
movq %rbx, %rdi
callq 0x1dec
movzbl %r15b, %edx
movq %rbx, %rdi
movl %ebp, %esi
callq 0x1e52
jmp 0x14ed
cmpb $0x0, 0x1002d(%rbx)
jne 0x14ed
jmp 0x16d9
cmpb $0x0, 0x1002e(%rbx)
jne 0x14ed
movw %ax, 0x10024(%rbx)
jmp 0x14ed
movq %rbx, %rdi
callq 0x1c36
jmp 0x14ed
movq %rbx, %rdi
callq 0x1a06
jmp 0x14ed
movb $0x1, 0x10028(%rbx)
jmp 0x14ed
movq %rbx, %rdi
movl %ebp, %esi
callq 0x1c5e
jmp 0x14ed
movq %rbx, %rdi
callq 0x1b9c
jmp 0x14ed
movb $0x1, 0x1002b(%rbx)
jmp 0x14ed
movq %rbx, %rdi
callq 0x1c16
jmp 0x14ed
movq %rbx, %rdi
callq 0x1ea4
jmp 0x14ed
movq %rbx, %rdi
callq 0x1b7c
jmp 0x14ed
movb $0x0, 0x1002d(%rbx)
jmp 0x14ed
movb $0x0, 0x1002a(%rbx)
jmp 0x14ed
movb 0x10022(%rbx), %al
movb %al, 0x10020(%rbx)
jmp 0x17a6
movq %rbx, %rdi
callq 0x1ff6
jmp 0x14ed
movq %rbx, %rdi
callq 0x1f2a
jmp 0x14ed
movb 0x10020(%rbx), %al
movb %al, 0x10022(%rbx)
testb %al, %al
sete 0x10029(%rbx)
shrb $0x7, %al
movb %al, 0x1002e(%rbx)
jmp 0x14ed
movq %rbx, %rdi
callq 0x2100
jmp 0x14ed
movb $0x0, 0x1002b(%rbx)
jmp 0x14ed