#ifndef SH2_DECODE_H_
#define SH2_DECODE_H_
#include <stdint.h>
#include "disasm.h"

enum {
	SH2_INVALID,
	SH2_ADD,
	SH2_ADDC,
	SH2_ADDV,
	SH2_AND,
	SH2_BF,
	SH2_BFS,
	SH2_BRA,
	SH2_BRAF,
	SH2_BSR,
	SH2_BSRF,
	SH2_BT,
	SH2_BTS,
	SH2_CLRMAC,
	SH2_CLRT,
	SH2_CMPEQ,
	SH2_CMPGE,
	SH2_CMPGT,
	SH2_CMPHI,
	SH2_CMPHS,
	SH2_CMPPL,
	SH2_CMPPZ,
	SH2_CMPSTR,
	SH2_DIV0S,
	SH2_DIV0U,
	SH2_DIV1,
	SH2_DMULS,
	SH2_DMULU,
	SH2_DT,
	SH2_EXTSB,
	SH2_EXTSW,
	SH2_EXTUB,
	SH2_EXTUW,
	SH2_JMP,
	SH2_JSR,
	SH2_LDC,
	SH2_LDS,
	SH2_MAC_W,
	SH2_MAC_L,
	SH2_MOV,
	SH2_MOVA,
	SH2_MOVB,
	SH2_MOVW,
	SH2_MOVL,
	SH2_MOVT,
	SH2_MUL,
	SH2_MULS,
	SH2_MULU,
	SH2_NEG,
	SH2_NEGC,
	SH2_NOP,
	SH2_NOT,
	SH2_OR,
	SH2_ROTCL,
	SH2_ROTCR,
	SH2_ROTL,
	SH2_ROTR,
	SH2_RTE,
	SH2_RTS,
	SH2_SETT,
	SH2_SHAL,
	SH2_SHAR,
	SH2_SHLL,
	SH2_SHLL2,
	SH2_SHLL8,
	SH2_SHLL16,
	SH2_SHLR,
	SH2_SHLR2,
	SH2_SHLR8,
	SH2_SHLR16,
	SH2_SLEEP,
	SH2_STC,
	SH2_STS,
	SH2_SUB,
	SH2_SUBC,
	SH2_SUBV,
	SH2_SWAPB,
	SH2_SWAPW,
	SH2_TAS,
	SH2_TRAPA,
	SH2_TST,
	SH2_XOR,
	SH2_XTRCT
};

enum {
	SH2_NOCOND,
	SH2_EQ,
	SH2_GE,
	SH2_GT,
	SH2_HI,
	SH2_HS,
	SH2_PL,
	SH2_PZ,
	SH2_STR
};

enum {
	SH2_UNSIZED,
	SH2_B,
	SH2_W,
	SH2_L
};

enum {
	SH2_NOMODE,
	SH2_REG,
	SH2_IMM,
	SH2_INDIRECT,
	SH2_R0_INDEXED
};

enum {
	SH2_NOREG,
	SH2_SR, SH2_GBR, SH2_VBR,
	SH2_MACH, SH2_MACL, SH2_PR,
	SH2_IMMED, SH2_REL, SH2_IDX_R0_GBR, SH2_DISP_PC,
	SH2_R0 = 16, SH2_R1, SH2_R2, SH2_R3,
	SH2_R4, SH2_R5, SH2_R6, SH2_R7,
	SH2_R8, SH2_R9, SH2_R10, SH2_R11,
	SH2_R12, SH2_R13, SH2_R14, SH2_SP,
	SH2_POSTINC_R0, SH2_POSTINC_R1, SH2_POSTINC_R2, SH2_POSTINC_R3, //32
	SH2_POSTINC_R4, SH2_POSTINC_R5, SH2_POSTINC_R6, SH2_POSTINC_R7,
	SH2_POSTINC_R8, SH2_POSTINC_R9, SH2_POSTINC_R10, SH2_POSTINC_R11,
	SH2_POSTINC_R12, SH2_POSTINC_R13, SH2_POSTINC_R14, SH2_POSTINC_SP,
	SH2_PREDEC_R0, SH2_PREDEC_R1, SH2_PREDEC_R2, SH2_PREDEC_R3, //48
	SH2_PREDEC_R4, SH2_PREDEC_R5, SH2_PREDEC_R6, SH2_PREDEC_R7,
	SH2_PREDEC_R8, SH2_PREDEC_R9, SH2_PREDEC_R10, SH2_PREDEC_R11,
	SH2_PREDEC_R12, SH2_PREDEC_R13, SH2_PREDEC_R14, SH2_PREDEC_SP,
	SH2_IND_R0, SH2_IND_R1, SH2_IND_R2, SH2_IND_R3, //64
	SH2_IND_R4, SH2_IND_R5, SH2_IND_R6, SH2_IND_R7,
	SH2_IND_R8, SH2_IND_R9, SH2_IND_R10, SH2_IND_R11,
	SH2_IND_R12, SH2_IND_R13, SH2_IND_R14, SH2_IND_SP,
	SH2_IDX_R0_R0, SH2_IDX_R0_R1, SH2_IDX_R0_R2, SH2_IDX_R0_R3, //80
	SH2_IDX_R0_R4, SH2_IDX_R0_R5, SH2_IDX_R0_R6, SH2_IDX_R0_R7,
	SH2_IDX_R0_R8, SH2_IDX_R0_R9, SH2_IDX_R0_R10, SH2_IDX_R0_R11,
	SH2_IDX_R0_R12, SH2_IDX_R0_R13, SH2_IDX_R0_R14, SH2_IDX_R0_SP,
	SH2_DISP_R0, SH2_DISP_R1, SH2_DISP_R2, SH2_DISP_R3,
	SH2_DISP_R4, SH2_DISP_R5, SH2_DISP_R6, SH2_DISP_R7,
	SH2_DISP_R8, SH2_DISP_R9, SH2_DISP_R10, SH2_DISP_R11,
	SH2_DISP_R12, SH2_DISP_R13, SH2_DISP_R14, SH2_DISP_SP,
	SH2_DISP_GBR
};

typedef struct {
	int16_t immed;
	uint8_t opcode;
	uint8_t src;
	uint8_t dst;
} sh2_inst;

extern const char *sh2_mnemonics[];

sh2_inst sh2_decode(uint16_t inst);
int sh2_disasm(char *dst, sh2_inst inst, uint32_t address, disasm_context *context);

#endif //SH2_DECODE_H_
