/* $Id$ */
/* Copyright (c) 2011-2018 Pierre Pronchery <khorben@defora.org> */
/* Copyright (c) 2011 Yann Guidon <yg@ygdes.org> */
/* This file is part of DeforaOS Devel Asm */
/* This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>. */



/* platform-specific */
#if !defined(W)
# if defined(ARCH_yasep16)
#  define W	16
# else
#  define W	32
# endif
#endif

/* generic */
/* opcode */
#define OPI(opcode)	((opcode << 2) | 0x2)
#define OPIR(opcode)	((opcode << 2) | 0x2)
#define OPR(opcode)	(opcode << 2)
#define OPRI(opcode)	((opcode << 2) | 0x2)
#define OPRR(opcode)	(opcode << 2)
#define OPLIR(opcode)	((opcode << 2) | 0x1)
#define OPLIRR(opcode)	((opcode << 2) | 0x3 | (0x1 << 17))
#define OPLRI(opcode)	((opcode << 2) | 0x1)
#define OPLRIR(opcode)	((opcode << 2) | 0x1)
#define OPLRRR(opcode)	((opcode << 2) | 0x3)
/* flags */
#define OPIF		(16 << AOD_SIZE)
#define OPIRF		(16 << AOD_SIZE)
#define OPRF		(16 << AOD_SIZE)
#define OPRIF		(16 << AOD_SIZE)
#define OPRRF		(16 << AOD_SIZE)
#define OPLIRF		(32 << AOD_SIZE)
#define OPLIRRF		(32 << AOD_SIZE)
#define OPLRIF		(32 << AOD_SIZE)
#define OPLRIRF		(32 << AOD_SIZE)
#define OPLRRRF		(32 << AOD_SIZE)
/* operands */
#define OP_DST3		AO_REGISTER(0, W, 0)
#define OP_IMM4		AO_IMMEDIATE(0, 4, 0)
#define OP_IMM16	AO_IMMEDIATE(0, W, 0)
#define OP_SI4		AO_REGISTER(0, W, 0)
#define OP_SND		AO_REGISTER(0, W, 0)

/* instructions */
{ "add",	OPIR(0x03), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "add",	OPRR(0x03), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "add",	OPLIRR(0x03),OPLIRRF, AO_3(OP_IMM16, OP_SND, OP_DST3)	},
{ "add",	OPLRIR(0x03),OPLRIRF, AO_3(OP_SI4, OP_IMM16, OP_SND)	},
{ "add",	OPLRRR(0x03),OPLRRRF, AO_3(OP_SND, OP_SI4, OP_DST3)	},
{ "and",	OPIR(0x02), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "and",	OPRR(0x02), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "andn",	OPIR(0x0a), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "andn",	OPRR(0x0a), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "cmps",	OPIR(0x1b), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "cmps",	OPRR(0x1b), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "cmpu",	OPIR(0x13), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "cmpu",	OPRR(0x13), OPRRF,  AO_2(OP_SI4, OP_SND)		},
#if 0 /* XXX aliases */
{ "esb",	OPRR(0x00), OPRRF,  AO_2(OP_SI4, OP_SND)		},
# if defined(ARCH_yasep32)
{ "esh",	OPRR(0x00), OPRRF,  AO_2(OP_SI4, OP_SND)		},
# endif
{ "ezb",	OPRR(0x00), OPRRF,  AO_2(OP_SI4, OP_SND)		},
# if defined(ARCH_yasep32)
{ "ezh",	OPRR(0x00), OPRRF,  AO_2(OP_SI4, OP_SND)		},
# endif
#endif
{ "get",	OPIR(0x05), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "get",	OPRR(0x05), OPRRF,  AO_2(OP_SI4, OP_SND)		},
#if 0 /* XXX aliases */
{ "ib",		OPIR(0x00), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "ib",		OPRR(0x00), OPRRF,  AO_2(OP_SI4, OP_SND)		},
# if defined(ARCH_yasep32)
{ "ih",		OPIR(0x00), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "ih",		OPRR(0x00), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "ihh",	OPIR(0x00), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "ihh",	OPRR(0x00), OPRRF,  AO_2(OP_SI4, OP_SND)		},
# endif
#endif
{ "lsb",	OPRR(0x18), OPRRF,  AO_2(OP_SI4, OP_SND)		},
#if defined(ARCH_yasep32)
{ "lsh",	OPRR(0x38), OPRRF,  AO_2(OP_SI4, OP_SND)		},
#endif
{ "lzb",	OPRR(0x10), OPRRF,  AO_2(OP_SI4, OP_SND)		},
#if defined(ARCH_yasep32)
{ "lzh",	OPRR(0x30), OPRRF,  AO_2(OP_SI4, OP_SND)		},
#endif
{ "mov",	OPIR(0x00), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "mov",	OPRR(0x00), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "mul8h",	OPIR(0x0c), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "mul8h",	OPRR(0x0c), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "mul8l",	OPIR(0x04), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "mul8l",	OPRR(0x04), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "muli",	OPIR(0x14), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "muli",	OPRR(0x14), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "nand",	OPIR(0x12), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "nand",	OPRR(0x12), OPRRF,  AO_2(OP_SI4, OP_SND)		},
#if 0 /* XXX alias */
{ "neg",	OPRR(0x00), OPRRF,  AO_2(OP_SI4, OP_SND)		},
#endif
{ "nor",	OPIR(0x2a), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "nor",	OPRR(0x2a), OPRRF,  AO_2(OP_SI4, OP_SND)		},
#if 0 /* XXX alias */
{ "not",	OPRR(0x00), OPRRF,  AO_2(OP_SI4, OP_SND)		},
#endif
{ "or",		OPIR(0x1a), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "or",		OPRR(0x1a), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "orn",	OPIR(0x22), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "orn",	OPRR(0x22), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "put",	OPRR(0x0d), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "rol",	OPIR(0x21), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "rol",	OPRR(0x21), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "ror",	OPIR(0x19), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "ror",	OPRR(0x19), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "sar",	OPIR(0x09), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "sar",	OPRR(0x09), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "sb",		OPIR(0x08), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "sb",		OPRR(0x08), OPRRF,  AO_2(OP_SI4, OP_SND)		},
#if defined(ARCH_yasep32)
{ "sh",		OPIR(0x20), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "sh",		OPRR(0x20), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "shh",	OPIR(0x28), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "shh",	OPRR(0x28), OPRRF,  AO_2(OP_SI4, OP_SND)		},
#endif
{ "shl",	OPIR(0x11), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "shl",	OPRR(0x11), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "shr",	OPIR(0x01), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "shr",	OPRR(0x01), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "smax",	OPIR(0x3b), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "smax",	OPRR(0x3b), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "smin",	OPIR(0x33), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "smin",	OPRR(0x33), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "sub",	OPIR(0x0b), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "sub",	OPRR(0x0b), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "umax",	OPIR(0x2b), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "umax",	OPRR(0x2b), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "umin",	OPIR(0x23), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "umin",	OPRR(0x23), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "xor",	OPIR(0x32), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "xor",	OPRR(0x32), OPRRF,  AO_2(OP_SI4, OP_SND)		},
{ "xorn",	OPIR(0x3a), OPIRF,  AO_2(OP_IMM4, OP_SND)		},
{ "xorn",	OPRR(0x3a), OPRRF,  AO_2(OP_SI4, OP_SND)		},
