// SPDX-FileCopyrightText: 2014 Fedor Sakharov <fedor.sakharov@gmail.com>
// SPDX-License-Identifier: LGPL-3.0-only

#ifndef RZ_CR16_DISASM_H
#define RZ_CR16_DISASM_H

#define CR16_INSTR_MAXLEN 24
#define STOR_LOAD_MASK    0x181F

enum cr16_cmd_types {
	CR16_TYPE_MOV,
	CR16_TYPE_ADD,
	CR16_TYPE_MUL,
	CR16_TYPE_SUB,
	CR16_TYPE_CMP,
	CR16_TYPE_BE,
	CR16_TYPE_BNE,
	CR16_TYPE_AND,
	CR16_TYPE_OR,
	CR16_TYPE_SCOND,
	CR16_TYPE_XOR,
	CR16_TYPE_SHIFT,
	CR16_TYPE_BIT,
	CR16_TYPE_SLPR,
	CR16_TYPE_BCOND,
	CR16_TYPE_BAL,
	CR16_TYPE_BR,
	CR16_TYPE_EXCP,
	CR16_TYPE_JCOND,
	CR16_TYPE_JAL,
	CR16_TYPE_JUMP,
	CR16_TYPE_JUMP_UNK,
	CR16_TYPE_RETX,
	CR16_TYPE_PUSH,
	CR16_TYPE_POP,
	CR16_TYPE_LOAD,
	CR16_TYPE_STOR,
	CR16_TYPE_DI,
	CR16_TYPE_EI,
	CR16_TYPE_NOP,
	CR16_TYPE_WAIT,
	CR16_TYPE_EWAIT,
};

struct cr16_cmd {
	st32 reladdr;
	unsigned type;
	char instr[CR16_INSTR_MAXLEN];
	char operands[CR16_INSTR_MAXLEN];
};

int cr16_decode_command(const ut8 *instr, struct cr16_cmd *cmd, int len);

enum cr16_opcodes {
	CR16_ADD = 0x0,
	CR16_ADDU = 0x1,
	CR16_BITI = 0x2,
	CR16_MUL = 0x3,
	CR16_ASHU = 0x4,
	CR16_LSH = 0x5,
	CR16_XOR = 0x6,
	CR16_CMP = 0x7,
	CR16_AND = 0x8,
	CR16_ADDC = 0x9,
	CR16_BCOND01 = 0xA,
	CR16_TBIT = 0xB,
	CR16_MOV = 0xC,
	CR16_SUB = 0xF,
	CR16_SUBC = 0xD,
	CR16_OR = 0xE,
	CR16_MOVD = 0x19,
	CR16_MULSB = 0x30,
	CR16_MULSW = 0x31,
	CR16_MULUW = 0x3F,
	CR16_MOVXB = 0x34,
	CR16_MOVZB = 0x35,
	CR16_SCOND = 0x37,
	CR16_TBIT_R_R = 0x3B,
	CR16_TBIT_I_R = 0x1B,
	CR16_JUMP = 0x2A,
	CR16_JAL = 0x3A,
	CR16_BAL = 0x1A,
	CR16_LPR = 0x38,
	CR16_SPR = 0x39,
	CR16_BCOND_2 = 0x0A,
	CR16_PUSH = 0xD8,
	CR16_POP = 0xD9,
	CR16_POPRET_1 = 0xDA,
	CR16_POPRET_2 = 0xDB,
	CR16_LOADM = 0xFC,
	CR16_STORM = 0xFD,
};

enum cr16_opcodes_long {
	CR16_RETX = 0x79FE,
	CR16_DI = 0x7DDE,
	CR16_EI = 0x7DFE,
	CR16_NOP = 0x0200,
	CR16_WAIT = 0x7FFE,
	CR16_EWAIT = 0x7FD6,
};

enum cr16_cmd_forms {
	CR16_I_R = 0x0,
	CR16_R_R = 0x1,
};

enum cr16_regs {
	CR16_R0 = 0,
	CR16_R1,
	CR16_R2,
	CR16_R3,
	CR16_R4,
	CR16_R5,
	CR16_R6,
	CR16_R7,
	CR16_R8,
	CR16_R9,
	CR16_R10,
	CR16_R11,
	CR16_R12,
	CR16_R13,
	CR16_RA,
	CR16_SP,
	CR16_LAST,
};

enum cr16_dedic_regs {
	CR16_PSR = 0x1,
	CR16_INTBASE = 0x3,
	CR16_ISP = 0xB,
};

enum cr16_conds {
	CR16_COND_EQ = 0x0,
	CR16_COND_NE,
	CR16_COND_CS,
	CR16_COND_CC,
	CR16_COND_HI,
	CR16_COND_LS,
	CR16_COND_GT,
	CR16_COND_LE,
	CR16_COND_FS,
	CR16_COND_FC,
	CR16_COND_LO,
	CR16_COND_HS,
	CR16_COND_LT,
	CR16_COND_GE,
};

#endif /* CR16_DISASM_H */
