/* $Id$ */
/* Copyright (c) 2011 Pierre Pronchery <khorben@defora.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 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>. */



/* generic */
/* registers */

/* conditions */
#define eq		(0x0 << 28)
#define ne		(0x1 << 28)
#define cs		(0x2 << 28)
#define cc		(0x3 << 28)
#define mi		(0x4 << 28)
#define pl		(0x5 << 28)
#define vs		(0x6 << 28)
#define vc		(0x7 << 28)
#define hi		(0x8 << 28)
#define ls		(0x9 << 28)
#define ge		(0xa << 28)
#define lt		(0xb << 28)
#define gt		(0xc << 28)
#define le		(0xd << 28)
#define al		(0xe << 28)

/* operations */
#define and		(0x0 << 21)
#define eor		(0x1 << 21)
#define sub		(0x2 << 21)
#define rsb		(0x3 << 21)
#define add		(0x4 << 21)
#define adc		(0x5 << 21)
#define sbc		(0x6 << 21)
#define rsc		(0x7 << 21)
#define tst		(0x8 << 21)
#define teq		(0x9 << 21)
#define cmp		(0xa << 21)
#define cmn		(0xb << 21)
#define orr		(0xc << 21)
#define mov		(0xd << 21)
#define bic		(0xe << 21)
#define mvn		(0xf << 21)

/* opcodes */
#define OPNOP		AO_IMMEDIATE(0, 32, 0)
#define OP_R		AO_REGISTER(0, 32, 0)

/* branch, branch with link */
#define OPB(cond)	(cond | (0x5 << 25))
#define OPBF		(32 << AOD_SIZE)
#define OPB_S26		AO_IMMEDIATE(AOF_SIGNED, 26, 0)
#define OPBL(cond)	(cond | (0x5 << 25) | (0x1 << 24))
#define OPBLF		(32 << AOD_SIZE)
#define OPBL_S26	AO_IMMEDIATE(AOF_SIGNED, 26, 0)

/* branch and exchange */
#define OPBX(cond)	(cond | (0x12fff1 << 4))
#define OPBXF		(32 << AOD_SIZE)

/* data processing */
#define OPDATA(cond, op)(cond | op)
#define OPDATAF		(32 << AOD_SIZE)
#define OP_DATA2	AO_IMMEDIATE(0, 12, 0)


/* instructions */
/* adc */
{ "adc",	OPDATA(al,adc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "adceq",	OPDATA(eq,adc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "adcne",	OPDATA(ne,adc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "adccs",	OPDATA(cs,adc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "adccc",	OPDATA(cc,adc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "adcmi",	OPDATA(mi,adc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "adcpl",	OPDATA(pl,adc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "adcvs",	OPDATA(vs,adc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "adcvc",	OPDATA(vc,adc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "adchi",	OPDATA(hi,adc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "adcls",	OPDATA(ls,adc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "adcge",	OPDATA(ge,adc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "adclt",	OPDATA(lt,adc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "adcgt",	OPDATA(gt,adc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "adcle",	OPDATA(le,adc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "adcal",	OPDATA(al,adc),	OPDATAF,OP_R,     OP_R,     OP_R	},
/* add */
{ "add",	OPDATA(al,add),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "addeq",	OPDATA(eq,add),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "addne",	OPDATA(ne,add),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "addcs",	OPDATA(cs,add),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "addcc",	OPDATA(cc,add),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "addmi",	OPDATA(mi,add),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "addpl",	OPDATA(pl,add),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "addvs",	OPDATA(vs,add),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "addvc",	OPDATA(vc,add),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "addhi",	OPDATA(hi,add),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "addls",	OPDATA(ls,add),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "addge",	OPDATA(ge,add),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "addlt",	OPDATA(lt,add),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "addgt",	OPDATA(gt,add),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "addle",	OPDATA(le,add),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "addal",	OPDATA(al,add),	OPDATAF,OP_R,     OP_R,     OP_R	},
/* and */
{ "and",	OPDATA(al,and),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "andeq",	OPDATA(eq,and),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "andne",	OPDATA(ne,and),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "andcs",	OPDATA(cs,and),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "andcc",	OPDATA(cc,and),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "andmi",	OPDATA(mi,and),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "andpl",	OPDATA(pl,and),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "andvs",	OPDATA(vs,and),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "andvc",	OPDATA(vc,and),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "andhi",	OPDATA(hi,and),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "andls",	OPDATA(ls,and),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "andge",	OPDATA(ge,and),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "andlt",	OPDATA(lt,and),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "andgt",	OPDATA(gt,and),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "andle",	OPDATA(le,and),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "andal",	OPDATA(al,and),	OPDATAF,OP_R,     OP_R,     OP_R	},
/* b */
{ "b",		OPB(al),	OPBF,	OPB_S26,  AOT_NONE, AOT_NONE	},
{ "beq",	OPB(eq),	OPBF,	OPB_S26,  AOT_NONE, AOT_NONE	},
{ "bne",	OPB(ne),	OPBF,	OPB_S26,  AOT_NONE, AOT_NONE	},
{ "bcs",	OPB(cs),	OPBF,	OPB_S26,  AOT_NONE, AOT_NONE	},
{ "bcc",	OPB(cc),	OPBF,	OPB_S26,  AOT_NONE, AOT_NONE	},
{ "bmi",	OPB(mi),	OPBF,	OPB_S26,  AOT_NONE, AOT_NONE	},
{ "bpl",	OPB(pl),	OPBF,	OPB_S26,  AOT_NONE, AOT_NONE	},
{ "bvs",	OPB(vs),	OPBF,	OPB_S26,  AOT_NONE, AOT_NONE	},
{ "bvc",	OPB(vc),	OPBF,	OPB_S26,  AOT_NONE, AOT_NONE	},
{ "bhi",	OPB(hi),	OPBF,	OPB_S26,  AOT_NONE, AOT_NONE	},
{ "bls",	OPB(ls),	OPBF,	OPB_S26,  AOT_NONE, AOT_NONE	},
{ "bge",	OPB(ge),	OPBF,	OPB_S26,  AOT_NONE, AOT_NONE	},
{ "blt",	OPB(lt),	OPBF,	OPB_S26,  AOT_NONE, AOT_NONE	},
{ "bgt",	OPB(gt),	OPBF,	OPB_S26,  AOT_NONE, AOT_NONE	},
{ "bge",	OPB(ge),	OPBF,	OPB_S26,  AOT_NONE, AOT_NONE	},
{ "bal",	OPB(al),	OPBF,	OPB_S26,  AOT_NONE, AOT_NONE	},
/* bic */
{ "bic",	OPDATA(al,bic),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "biceq",	OPDATA(eq,bic),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "bicne",	OPDATA(ne,bic),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "biccs",	OPDATA(cs,bic),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "biccc",	OPDATA(cc,bic),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "bicmi",	OPDATA(mi,bic),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "bicpl",	OPDATA(pl,bic),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "bicvs",	OPDATA(vs,bic),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "bicvc",	OPDATA(vc,bic),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "bichi",	OPDATA(hi,bic),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "bicls",	OPDATA(ls,bic),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "bicge",	OPDATA(ge,bic),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "biclt",	OPDATA(lt,bic),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "bicgt",	OPDATA(gt,bic),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "bicle",	OPDATA(le,bic),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "bical",	OPDATA(al,bic),	OPDATAF,OP_R,     OP_R,     OP_R	},
/* bl */
{ "bl",		OPBL(al),	OPBLF,	OPBL_S26, AOT_NONE, AOT_NONE	},
{ "bleq",	OPBL(eq),	OPBLF,	OPBL_S26, AOT_NONE, AOT_NONE	},
{ "blne",	OPBL(ne),	OPBLF,	OPBL_S26, AOT_NONE, AOT_NONE	},
{ "blcs",	OPBL(cs),	OPBLF,	OPBL_S26, AOT_NONE, AOT_NONE	},
{ "blcc",	OPBL(cc),	OPBLF,	OPBL_S26, AOT_NONE, AOT_NONE	},
{ "blmi",	OPBL(mi),	OPBLF,	OPBL_S26, AOT_NONE, AOT_NONE	},
{ "blpl",	OPBL(pl),	OPBLF,	OPBL_S26, AOT_NONE, AOT_NONE	},
{ "blvs",	OPBL(vs),	OPBLF,	OPBL_S26, AOT_NONE, AOT_NONE	},
{ "blvc",	OPBL(vc),	OPBLF,	OPBL_S26, AOT_NONE, AOT_NONE	},
{ "blhi",	OPBL(hi),	OPBLF,	OPBL_S26, AOT_NONE, AOT_NONE	},
{ "blls",	OPBL(ls),	OPBLF,	OPBL_S26, AOT_NONE, AOT_NONE	},
{ "blge",	OPBL(ge),	OPBLF,	OPBL_S26, AOT_NONE, AOT_NONE	},
{ "bllt",	OPBL(lt),	OPBLF,	OPBL_S26, AOT_NONE, AOT_NONE	},
{ "blgt",	OPBL(gt),	OPBLF,	OPBL_S26, AOT_NONE, AOT_NONE	},
{ "blge",	OPBL(ge),	OPBLF,	OPBL_S26, AOT_NONE, AOT_NONE	},
{ "blal",	OPBL(al),	OPBLF,	OPBL_S26, AOT_NONE, AOT_NONE	},
/* bx */
{ "bx",		OPBX(al),	OPBXF,	OP_R,     AOT_NONE, AOT_NONE	},
{ "bxeq",	OPBX(eq),	OPBXF,	OP_R,     AOT_NONE, AOT_NONE	},
{ "bxne",	OPBX(ne),	OPBXF,	OP_R,     AOT_NONE, AOT_NONE	},
{ "bxcs",	OPBX(cs),	OPBXF,	OP_R,     AOT_NONE, AOT_NONE	},
{ "bxcc",	OPBX(cc),	OPBXF,	OP_R,     AOT_NONE, AOT_NONE	},
{ "bxmi",	OPBX(mi),	OPBXF,	OP_R,     AOT_NONE, AOT_NONE	},
{ "bxpl",	OPBX(pl),	OPBXF,	OP_R,     AOT_NONE, AOT_NONE	},
{ "bxvs",	OPBX(vs),	OPBXF,	OP_R,     AOT_NONE, AOT_NONE	},
{ "bxvc",	OPBX(vc),	OPBXF,	OP_R,     AOT_NONE, AOT_NONE	},
{ "bxhi",	OPBX(hi),	OPBXF,	OP_R,     AOT_NONE, AOT_NONE	},
{ "bxls",	OPBX(ls),	OPBXF,	OP_R,     AOT_NONE, AOT_NONE	},
{ "bxge",	OPBX(ge),	OPBXF,	OP_R,     AOT_NONE, AOT_NONE	},
{ "bxlt",	OPBX(lt),	OPBXF,	OP_R,     AOT_NONE, AOT_NONE	},
{ "bxgt",	OPBX(gt),	OPBXF,	OP_R,     AOT_NONE, AOT_NONE	},
{ "bxge",	OPBX(ge),	OPBXF,	OP_R,     AOT_NONE, AOT_NONE	},
{ "bxal",	OPBX(al),	OPBXF,	OP_R,     AOT_NONE, AOT_NONE	},
#if 1 /* FIXME implement correctly */
/* cdp */
{ "cdp",	0x00000000,	OPNOP,	AOT_NONE, AOT_NONE, AOT_NONE	},
#endif
/* cmn */
{ "cmn",	OPDATA(al,cmn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmneq",	OPDATA(eq,cmn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmnne",	OPDATA(ne,cmn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmncs",	OPDATA(cs,cmn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmncc",	OPDATA(cc,cmn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmnmi",	OPDATA(mi,cmn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmnpl",	OPDATA(pl,cmn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmnvs",	OPDATA(vs,cmn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmnvc",	OPDATA(vc,cmn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmnhi",	OPDATA(hi,cmn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmnls",	OPDATA(ls,cmn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmnge",	OPDATA(ge,cmn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmnlt",	OPDATA(lt,cmn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmngt",	OPDATA(gt,cmn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmnle",	OPDATA(le,cmn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmnal",	OPDATA(al,cmn),	OPDATAF,OP_R,     OP_R,     OP_R	},
/* cmp */
{ "cmp",	OPDATA(al,cmp),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmpeq",	OPDATA(eq,cmp),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmpne",	OPDATA(ne,cmp),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmpcs",	OPDATA(cs,cmp),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmpcc",	OPDATA(cc,cmp),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmpmi",	OPDATA(mi,cmp),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmppl",	OPDATA(pl,cmp),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmpvs",	OPDATA(vs,cmp),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmpvc",	OPDATA(vc,cmp),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmphi",	OPDATA(hi,cmp),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmpls",	OPDATA(ls,cmp),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmpge",	OPDATA(ge,cmp),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmplt",	OPDATA(lt,cmp),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmpgt",	OPDATA(gt,cmp),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmple",	OPDATA(le,cmp),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "cmpal",	OPDATA(al,cmp),	OPDATAF,OP_R,     OP_R,     OP_R	},
/* eor */
{ "eor",	OPDATA(al,eor),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "eoreq",	OPDATA(eq,eor),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "eorne",	OPDATA(ne,eor),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "eorcs",	OPDATA(cs,eor),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "eorcc",	OPDATA(cc,eor),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "eormi",	OPDATA(mi,eor),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "eorpl",	OPDATA(pl,eor),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "eorvs",	OPDATA(vs,eor),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "eorvc",	OPDATA(vc,eor),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "eorhi",	OPDATA(hi,eor),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "eorls",	OPDATA(ls,eor),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "eorge",	OPDATA(ge,eor),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "eorlt",	OPDATA(lt,eor),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "eorgt",	OPDATA(gt,eor),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "eorle",	OPDATA(le,eor),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "eoral",	OPDATA(al,eor),	OPDATAF,OP_R,     OP_R,     OP_R	},
#if 1 /* FIXME implement correctly */
{ "ldc",	0x00000000,	OPNOP,	AOT_NONE, AOT_NONE, AOT_NONE	},
{ "ldm",	0x00000000,	OPNOP,	AOT_NONE, AOT_NONE, AOT_NONE	},
{ "ldr",	0x00000000,	OPNOP,	AOT_NONE, AOT_NONE, AOT_NONE	},
{ "mla",	0x00000000,	OPNOP,	AOT_NONE, AOT_NONE, AOT_NONE	},
#endif
/* mov */
{ "mov",	OPDATA(al,mov),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "moveq",	OPDATA(eq,mov),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "movne",	OPDATA(ne,mov),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "movcs",	OPDATA(cs,mov),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "movcc",	OPDATA(cc,mov),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "movmi",	OPDATA(mi,mov),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "movpl",	OPDATA(pl,mov),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "movvs",	OPDATA(vs,mov),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "movvc",	OPDATA(vc,mov),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "movhi",	OPDATA(hi,mov),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "movls",	OPDATA(ls,mov),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "movge",	OPDATA(ge,mov),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "movlt",	OPDATA(lt,mov),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "movgt",	OPDATA(gt,mov),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "movle",	OPDATA(le,mov),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "moval",	OPDATA(al,mov),	OPDATAF,OP_R,     OP_R,     OP_R	},
#if 1 /* FIXME implement correctly */
{ "mrc",	0x00000000,	OPNOP,	AOT_NONE, AOT_NONE, AOT_NONE	},
{ "mrs",	0x00000000,	OPNOP,	OP_R,     OP_R,     AOT_NONE	},
/* msr */
{ "msr",	0x00000000,	OPNOP,	OP_R,     OP_R,     AOT_NONE	},
{ "msreq",	0x00000000,	OPNOP,	OP_R,     OP_R,     AOT_NONE	},
{ "msrne",	0x00000000,	OPNOP,	OP_R,     OP_R,     AOT_NONE	},
{ "msrcs",	0x00000000,	OPNOP,	OP_R,     OP_R,     AOT_NONE	},
{ "msrcc",	0x00000000,	OPNOP,	OP_R,     OP_R,     AOT_NONE	},
{ "msrmi",	0x00000000,	OPNOP,	OP_R,     OP_R,     AOT_NONE	},
{ "msrpl",	0x00000000,	OPNOP,	OP_R,     OP_R,     AOT_NONE	},
{ "msrvs",	0x00000000,	OPNOP,	OP_R,     OP_R,     AOT_NONE	},
{ "msrvc",	0x00000000,	OPNOP,	OP_R,     OP_R,     AOT_NONE	},
{ "msrhi",	0x00000000,	OPNOP,	OP_R,     OP_R,     AOT_NONE	},
{ "msrls",	0x00000000,	OPNOP,	OP_R,     OP_R,     AOT_NONE	},
{ "msrge",	0x00000000,	OPNOP,	OP_R,     OP_R,     AOT_NONE	},
{ "msrlt",	0x00000000,	OPNOP,	OP_R,     OP_R,     AOT_NONE	},
{ "msrgt",	0x00000000,	OPNOP,	OP_R,     OP_R,     AOT_NONE	},
{ "msrle",	0x00000000,	OPNOP,	OP_R,     OP_R,     AOT_NONE	},
{ "msral",	0x00000000,	OPNOP,	OP_R,     OP_R,     AOT_NONE	},
{ "mul",	0x00000000,	OPNOP,	AOT_NONE, AOT_NONE, AOT_NONE	},
#endif
/* mvn */
{ "mvn",	OPDATA(al,mvn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "mvneq",	OPDATA(eq,mvn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "mvnne",	OPDATA(ne,mvn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "mvncs",	OPDATA(cs,mvn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "mvncc",	OPDATA(cc,mvn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "mvnmi",	OPDATA(mi,mvn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "mvnpl",	OPDATA(pl,mvn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "mvnvs",	OPDATA(vs,mvn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "mvnvc",	OPDATA(vc,mvn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "mvnhi",	OPDATA(hi,mvn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "mvnls",	OPDATA(ls,mvn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "mvnge",	OPDATA(ge,mvn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "mvnlt",	OPDATA(lt,mvn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "mvngt",	OPDATA(gt,mvn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "mvnle",	OPDATA(le,mvn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "mvnal",	OPDATA(al,mvn),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "nop",	OPDATA(al,mov),	OPDATAF,AOT_NONE, AOT_NONE, AOT_NONE	},
/* orr */
{ "orr",	OPDATA(al,orr),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "orreq",	OPDATA(eq,orr),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "orrne",	OPDATA(ne,orr),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "orrcs",	OPDATA(cs,orr),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "orrcc",	OPDATA(cc,orr),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "orrmi",	OPDATA(mi,orr),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "orrpl",	OPDATA(pl,orr),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "orrvs",	OPDATA(vs,orr),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "orrvc",	OPDATA(vc,orr),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "orrhi",	OPDATA(hi,orr),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "orrls",	OPDATA(ls,orr),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "orrge",	OPDATA(ge,orr),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "orrlt",	OPDATA(lt,orr),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "orrgt",	OPDATA(gt,orr),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "orrle",	OPDATA(le,orr),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "orral",	OPDATA(al,orr),	OPDATAF,OP_R,     OP_R,     OP_R	},
/* rsb */
{ "rsb",	OPDATA(al,rsb),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rsbeq",	OPDATA(eq,rsb),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rsbne",	OPDATA(ne,rsb),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rsbcs",	OPDATA(cs,rsb),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rsbcc",	OPDATA(cc,rsb),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rsbmi",	OPDATA(mi,rsb),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rsbpl",	OPDATA(pl,rsb),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rsbvs",	OPDATA(vs,rsb),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rsbvc",	OPDATA(vc,rsb),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rsbhi",	OPDATA(hi,rsb),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rsbls",	OPDATA(ls,rsb),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rsbge",	OPDATA(ge,rsb),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rsblt",	OPDATA(lt,rsb),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rsbgt",	OPDATA(gt,rsb),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rsble",	OPDATA(le,rsb),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rsbal",	OPDATA(al,rsb),	OPDATAF,OP_R,     OP_R,     OP_R	},
/* rsc */
{ "rsc",	OPDATA(al,rsc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rsceq",	OPDATA(eq,rsc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rscne",	OPDATA(ne,rsc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rsccs",	OPDATA(cs,rsc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rsccc",	OPDATA(cc,rsc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rscmi",	OPDATA(mi,rsc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rscpl",	OPDATA(pl,rsc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rscvs",	OPDATA(vs,rsc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rscvc",	OPDATA(vc,rsc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rschi",	OPDATA(hi,rsc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rscls",	OPDATA(ls,rsc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rscge",	OPDATA(ge,rsc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rsclt",	OPDATA(lt,rsc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rscgt",	OPDATA(gt,rsc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rscle",	OPDATA(le,rsc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "rscal",	OPDATA(al,rsc),	OPDATAF,OP_R,     OP_R,     OP_R	},
/* sbc */
{ "sbc",	OPDATA(al,sbc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "sbceq",	OPDATA(eq,sbc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "sbcne",	OPDATA(ne,sbc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "sbccs",	OPDATA(cs,sbc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "sbccc",	OPDATA(cc,sbc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "sbcmi",	OPDATA(mi,sbc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "sbcpl",	OPDATA(pl,sbc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "sbcvs",	OPDATA(vs,sbc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "sbcvc",	OPDATA(vc,sbc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "sbchi",	OPDATA(hi,sbc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "sbcls",	OPDATA(ls,sbc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "sbcge",	OPDATA(ge,sbc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "sbclt",	OPDATA(lt,sbc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "sbcgt",	OPDATA(gt,sbc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "sbcle",	OPDATA(le,sbc),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "sbcal",	OPDATA(al,sbc),	OPDATAF,OP_R,     OP_R,     OP_R	},
#if 1 /* FIXME implement correctly */
{ "stc",	0x00000000,	OPNOP,	AOT_NONE, AOT_NONE, AOT_NONE	},
{ "stm",	0x00000000,	OPNOP,	AOT_NONE, AOT_NONE, AOT_NONE	},
{ "str",	0x00000000,	OPNOP,	AOT_NONE, AOT_NONE, AOT_NONE	},
#endif
/* sub */
{ "sub",	OPDATA(al,sub),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "subeq",	OPDATA(eq,sub),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "subne",	OPDATA(ne,sub),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "subcs",	OPDATA(cs,sub),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "subcc",	OPDATA(cc,sub),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "submi",	OPDATA(mi,sub),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "subpl",	OPDATA(pl,sub),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "subvs",	OPDATA(vs,sub),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "subvc",	OPDATA(vc,sub),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "subhi",	OPDATA(hi,sub),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "subls",	OPDATA(ls,sub),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "subge",	OPDATA(ge,sub),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "sublt",	OPDATA(lt,sub),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "subgt",	OPDATA(gt,sub),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "suble",	OPDATA(le,sub),	OPDATAF,OP_R,     OP_R,     OP_R	},
{ "subal",	OPDATA(al,sub),	OPDATAF,OP_R,     OP_R,     OP_R	},
#if 1 /* FIXME implement correctly */
{ "swi",	0x00000000,	OPNOP,	AOT_NONE, AOT_NONE, AOT_NONE	},
{ "swp",	0x00000000,	OPNOP,	AOT_NONE, AOT_NONE, AOT_NONE	},
{ "teq",	0x00000000,	OPNOP,	AOT_NONE, AOT_NONE, AOT_NONE	},
{ "tst",	0x00000000,	OPNOP,	AOT_NONE, AOT_NONE, AOT_NONE	},
#endif
