#include "limbo.h"

uchar movetab[Mend][Tend] =
{
	/* Mas */
	{
		/* Tnone */	0,
		/* Tadt */	IMOVM,
		/* Tadtpick */	IMOVM,
		/* Tarray */	IMOVP,
		/* Tbig */	IMOVL,
		/* Tbyte */	IMOVB,
		/* Tchan */	IMOVP,
		/* Treal */	IMOVF,
		/* Tfn */	0,
		/* Tint */	IMOVW,
		/* Tlist */	IMOVP,
		/* Tmodule */	IMOVP,
		/* Tref */	IMOVP,
		/* Tstring */	IMOVP,
		/* Ttuple */	IMOVM,
		/* Texception */	IMOVM,
		/* Tfix */	IMOVW,
		/* Tpoly */	IMOVP,

		/* Tainit */	0,
		/* Talt */	0,
		/* Tany */	IMOVP,
		/* Tarrow */	0,
		/* Tcase */	0,
		/* Tcasel */	0,
		/* Tcasec */	0,
		/* Tdot */	0,
		/* Terror */	0,
		/* Tgoto */	0,
		/* Tid */	0,
	},
	/* Mcons */
	{
		/* Tnone */	0,
		/* Tadt */	ICONSM,
		/* Tadtpick */	0,
		/* Tarray */	ICONSP,
		/* Tbig */	ICONSL,
		/* Tbyte */	ICONSB,
		/* Tchan */	ICONSP,
		/* Treal */	ICONSF,
		/* Tfn */	0,
		/* Tint */	ICONSW,
		/* Tlist */	ICONSP,
		/* Tmodule */	ICONSP,
		/* Tref */	ICONSP,
		/* Tstring */	ICONSP,
		/* Ttuple */	ICONSM,
		/* Texception */	ICONSM,
		/* Tfix */	ICONSW,
		/* Tpoly */	ICONSP,

		/* Tainit */	0,
		/* Talt */	0,
		/* Tany */	ICONSP,
		/* Tarrow */	0,
		/* Tcase */	0,
		/* Tcasel */	0,
		/* Tcasec */	0,
		/* Tdot */	0,
		/* Terror */	0,
		/* Tgoto */	0,
		/* Tid */	0,
	},
	/* Mhd */
	{
		/* Tnone */	0,
		/* Tadt */	IHEADM,
		/* Tadtpick */	0,
		/* Tarray */	IHEADP,
		/* Tbig */	IHEADL,
		/* Tbyte */	IHEADB,
		/* Tchan */	IHEADP,
		/* Treal */	IHEADF,
		/* Tfn */	0,
		/* Tint */	IHEADW,
		/* Tlist */	IHEADP,
		/* Tmodule */	IHEADP,
		/* Tref */	IHEADP,
		/* Tstring */	IHEADP,
		/* Ttuple */	IHEADM,
		/* Texception */	IHEADM,
		/* Tfix */	IHEADW,
		/* Tpoly */	IHEADP,

		/* Tainit */	0,
		/* Talt */	0,
		/* Tany */	IHEADP,
		/* Tarrow */	0,
		/* Tcase */	0,
		/* Tcasel */	0,
		/* Tcasec */	0,
		/* Tdot*/	0,
		/* Terror */	0,
		/* Tgoto */	0,
		/* Tid */	0,
	},
	/* Mtl */
	{
		/* Tnone */	0,
		/* Tadt */	0,
		/* Tadtpick */	0,
		/* Tarray */	0,
		/* Tbig */	0,
		/* Tbyte */	0,
		/* Tchan */	0,
		/* Treal */	0,
		/* Tfn */	0,
		/* Tint */	0,
		/* Tlist */	ITAIL,
		/* Tmodule */	0,
		/* Tref */	0,
		/* Tstring */	0,
		/* Ttuple */	0,
		/* Texception */	0,
		/* Tfix */	0,
		/* Tpoly */	0,

		/* Tainit */	0,
		/* Talt */	0,
		/* Tany */	0,
		/* Tarrow */	0,
		/* Tcase */	0,
		/* Tcasel */	0,
		/* Tcasec */	0,
		/* Tdot */	0,
		/* Terror */	0,
		/* Tgoto */	0,
		/* Tid */	0,
	},
};

uchar chantab[Tend] =
{
	/* Tnone */	0,
	/* Tadt */	INEWCM,
	/* Tadtpick */	0,
	/* Tarray */	INEWCP,
	/* Tbig */	INEWCL,
	/* Tbyte */	INEWCB,
	/* Tchan */	INEWCP,
	/* Treal */	INEWCF,
	/* Tfn */	0,
	/* Tint */	INEWCW,
	/* Tlist */	INEWCP,
	/* Tmodule */	INEWCP,
	/* Tref */	INEWCP,
	/* Tstring */	INEWCP,
	/* Ttuple */	INEWCM,
	/* Texception */	INEWCM,
	/* Tfix */	INEWCW,
	/* Tpoly */	INEWCP,

	/* Tainit */	0,
	/* Talt */	0,
	/* Tany */	INEWCP,
	/* Tarrow */	0,
	/* Tcase */	0,
	/* Tcasel */	0,
	/* Tcasec */	0,
	/* Tdot */	0,
	/* Terror */	0,
	/* Tgoto */	0,
	/* Tid */	0,
};

uchar disoptab[Oend+1][7] = {
	/* opcode	default	byte	word	big	real	string	fixed	*/
			{0},
	/* Oadd */	{0,	IADDB,	IADDW,	IADDL,	IADDF,	IADDC,	IADDW,},
	/* Oaddas */	{0,	IADDB,	IADDW,	IADDL,	IADDF,	IADDC,	IADDW,},
	/* Oadr */	{0},
	/* Oadtdecl */	{0},
	/* Oalt */	{0},
	/* Oand */	{0,	IANDB,	IANDW,	IANDL,	0,	0,	0,},
	/* Oandand */	{0},
	/* Oandas */	{0,	IANDB,	IANDW,	IANDL,	0, 	0,	0,},
	/* Oarray */	{0},
	/* Oas */	{0},
	/* Obreak */	{0},
	/* Ocall */	{0},
	/* Ocase */	{0},
	/* Ocast */	{0},
	/* Ochan */	{0},
	/* Ocomma */	{0},
	/* Ocomp */	{0},
	/* Ocondecl */	{0},
	/* Ocons */	{0},
	/* Oconst */	{0},
	/* Ocont */	{0},
	/* Odas */	{0},
	/* Odec */	{0,	ISUBB,	ISUBW,	ISUBL,	ISUBF,	0,	ISUBW,},
	/* Odiv */	{0,	IDIVB,	IDIVW,	IDIVL,	IDIVF,	0,	IDIVX,},
	/* Odivas */	{0,	IDIVB,	IDIVW,	IDIVL,	IDIVF,	0,	IDIVX,},
	/* Odo */	{0},
	/* Odot */	{0},
	/* Oelem */	{0},
	/* Oeq */	{IBEQW,	IBEQB,	IBEQW,	IBEQL,	IBEQF,	IBEQC,	IBEQW,},
	/* Oexcept */	{0},
	/* Oexdecl */	{0},
	/* Oexit */	{0},
	/* Oexp */	{0,	0,	IEXPW,	IEXPL,	IEXPF,	0,	0,},
	/* Oexpas */	{0,	0,	IEXPW,	IEXPL,	IEXPF,	0,	0,},
	/* Oexstmt */	{0},
	/* Ofielddecl */{0},
	/* Ofnptr */	{0},
	/* Ofor */	{0},
	/* Ofunc */	{0},
	/* Ogeq */	{0,	IBGEB,	IBGEW,	IBGEL,	IBGEF,	IBGEC,	IBGEW,},
	/* Ogt */	{0,	IBGTB,	IBGTW,	IBGTL,	IBGTF,	IBGTC,	IBGTW,},
	/* Ohd */	{0},
	/* Oif */	{0},
	/* Oimport */	{0},
	/* Oinc */	{0,	IADDB,	IADDW,	IADDL,	IADDF,	0,	IADDW,},
	/* Oind */	{0},
	/* Oindex */	{0,},
	/* Oinds */	{0,	0,	IINDC,	0,	0,	0,	0,},
	/* Oindx */	{0,	0,	IINDX,	0,	0,	0,	0,},
	/* Oinv */	{0},
	/* Ojmp */	{0},
	/* Olabel */	{0},
	/* Olen */	{ILENA,	0,	0,	0,	0,	ILENC,	0,},
	/* Oleq */	{0,	IBLEB,	IBLEW,	IBLEL,	IBLEF,	IBLEC,	IBLEW,},
	/* Oload */	{0},
	/* Olsh */	{0,	ISHLB,	ISHLW,	ISHLL,	0,	0,	0,},
	/* Olshas */	{0,	ISHLB,	ISHLW,	ISHLL,	0,	0,	0,},
	/* Olt */	{0,	IBLTB,	IBLTW,	IBLTL,	IBLTF,	IBLTC,	IBLTW,},
	/* Omdot */	{0},
	/* Omod */	{0,	IMODB,	IMODW,	IMODL,	0,	0,	0,},
	/* Omodas */	{0,	IMODB,	IMODW,	IMODL,	0,	0,	0,},
	/* Omoddecl */	{0},
	/* Omul */	{0,	IMULB,	IMULW,	IMULL,	IMULF,	0,	IMULX,},
	/* Omulas */	{0,	IMULB,	IMULW,	IMULL,	IMULF,	0,	IMULX,},
	/* Oname */	{0},
	/* Oneg */	{0,	0,	0,	0,	INEGF,	0, 	0,},
	/* Oneq */	{IBNEW,	IBNEB,	IBNEW,	IBNEL,	IBNEF,	IBNEC,	IBNEW,},
	/* Onot */	{0},
	/* Onothing */	{0},
	/* Oor */	{0,	IORB,	IORW,	IORL,	0,	0,	0,},
	/* Ooras */	{0,	IORB,	IORW,	IORL,	0,	0,	0,},
	/* Ooror */	{0},
	/* Opick */	{0},
	/* Opickdecl */	{0},
	/* Opredec */	{0},
	/* Opreinc */	{0},
	/* Oraise */	{0},
	/* Orange */	{0},
	/* Orcv */	{0},
	/* Oref */	{0},
	/* Oret */	{0},
	/* Orsh */	{0,	ISHRB,	ISHRW,	ISHRL,	0,	0,	0,},
	/* Orshas */	{0,	ISHRB,	ISHRW,	ISHRL,	0,	0,	0,},
	/* Oscope */	{0},
	/* Oself */	{0},
	/* Oseq */	{0},
	/* Oslice */	{ISLICEA,0,	0,	0,	0,	ISLICEC,	0,},
	/* Osnd */	{0},
	/* Ospawn */	{0},
	/* Osub */	{0,	ISUBB,	ISUBW,	ISUBL,	ISUBF,	0,	ISUBW,},
	/* Osubas */	{0,	ISUBB,	ISUBW,	ISUBL,	ISUBF,	0,	ISUBW,},
	/* Otagof */	{0},
	/* Otl */	{0},
	/* Otuple */	{0},
	/* Otype */	{0},
	/* Otypedecl */	{0},
	/* Oused */	{0},
	/* Ovardecl */	{0},
	/* Ovardecli */	{0},
	/* Owild */	{0},
	/* Oxor */	{0,	IXORB,	IXORW,	IXORL,	0,	0,	0,},
	/* Oxoras */	{0,	IXORB,	IXORW,	IXORL,	0,	0,	0,},

	/* Oend	*/	{0}
};

int setisused[] = {
	Oas,
	Odas,
	Oaddas,
	Osubas,
	Omulas,
	Odivas,
	Omodas,
	Oexpas,
	Oandas,
	Ooras,
	Oxoras,
	Olshas,
	Onothing,
	Orshas,
	Oinc,
	Odec,
	Opreinc,
	Opredec,
	Ocall,
	Oraise,
	Ospawn,
	Osnd,
	Orcv,

	-1
};

int setsideeffect[] = {
	Oas,
	Odas,
	Oaddas,
	Osubas,
	Omulas,
	Odivas,
	Omodas,
	Oexpas,
	Oandas,
	Ooras,
	Oxoras,
	Olshas,
	Orshas,
	Oinc,
	Odec,
	Opreinc,
	Opredec,
	Ocall,
	Oraise,
	Ospawn,
	Osnd,
	Orcv,

	Oadr,
	Oarray,
	Ocast,
	Ochan,
	Ocons,
	Odiv,
	Odot,
	Oind,
	Oindex,
	Oinds,
	Oindx,
	Olen,
	Oload,
	Omod,
	Oref,

	-1
};

char *opname[Oend+1] = {
			"unknown",
	/* Oadd */	"+",
	/* Oaddas */	"+=",
	/* Oadr */	"adr",
	/* Oadtdecl */	"adtdecl",
	/* Oalt */	"alt",
	/* Oand */	"&",
	/* Oandand */	"&&",
	/* Oandas */	"&=",
	/* Oarray */	"array",
	/* Oas */	"=",
	/* Obreak */	"break",
	/* Ocall */	"call",
	/* Ocase */	"case",
	/* Ocast */	"cast",
	/* Ochan */	"chan",
	/* Ocomma */	",",
	/* Ocomp */	"~",
	/* Ocondecl */	"condecl",
	/* Ocons */	"::",
	/* Oconst */	"const",
	/* Ocont */	"continue",
	/* Odas */	":=",
	/* Odec */	"--",
	/* Odiv */	"/",
	/* Odivas */	"/=",
	/* Odo */	"do",
	/* Odot */	".",
	/* Oelem */	"elem",
	/* Oeq */	"==",
	/* Oexcept */	"except",
	/* Oexdecl */	"exdecl",
	/* Oexit */	"exit",
	/* Oexp */	"**",
	/* Oexpas */	"**=",
	/* Oexstmt */	"exstat",
	/* Ofielddecl */"fielddecl",
	/* Ofnptr */	"fnptr",
	/* Ofor */	"for",
	/* Ofunc */	"fn(){}",
	/* Ogeq */	">=",
	/* Ogt */	">",
	/* Ohd */	"hd",
	/* Oif */	"if",
	/* Oimport */	"import",
	/* Oinc */	"++",
	/* Oind */	"*",
	/* Oindex */	"index",
	/* Oinds */	"inds",
	/* Oindx */	"indx",
	/* Oinv */		"inv",
	/* Ojmp */	"jmp",
	/* Olabel */	"label",
	/* Olen */	"len",
	/* Oleq */	"<=",
	/* Oload */	"load",
	/* Olsh */	"<<",
	/* Olshas */	"<<=",
	/* Olt */	"<",
	/* Omdot */	"->",
	/* Omod */	"%",
	/* Omodas */	"%=",
	/* Omoddecl */	"moddecl",
	/* Omul */	"*",
	/* Omulas */	"*=",
	/* Oname */	"name",
	/* Oneg */	"-",
	/* Oneq */	"!=",
	/* Onot */	"!",
	/* Onothing */	"nothing",
	/* Oor */	"|",
	/* Ooras */	"|=",
	/* Ooror */	"||",
	/* Opick */	"pick",
	/* Opickdecl */	"pickdecl",
	/* Opredec */	"--",
	/* Opreinc */	"++",
	/* Oraise */	"raise",
	/* Orange */	"range",
	/* Orcv */	"<-",
	/* Oref */	"ref",
	/* Oret */	"return",
	/* Orsh */	">>",
	/* Orshas */	">>=",
	/* Oscope */	"scope",
	/* Oself */	"self",
	/* Oseq */	"seq",
	/* Oslice */	"slice",
	/* Osnd */	"<-=",
	/* Ospawn */	"spawn",
	/* Osub */	"-",
	/* Osubas */	"-=",
	/* Otl */	"tagof",
	/* Otl */	"tl",
	/* Otuple */	"tuple",
	/* Otype */	"type",
	/* Otypedecl */	"typedecl",
	/* Oused */	"used",
	/* Ovardecl */	"vardecl",
	/* Ovardecli */	"vardecli",
	/* Owild */	"*",
	/* Oxor */	"^",
	/* Oxoras */	"^=",

	/* Oend */	"unknown"
};

int setisbyteinst[] = {
	IMULB,
	ISUBB,
	IADDB,
	IDIVB,
	IORB,
	IXORB,
	ISHLB,
	ISHRB,
	IMODB,
	IANDB,
	IBEQB,
	IBNEB,
	IBLTB,
	IBLEB,
	IBGTB,
	IBGEB,

	-1
};

char *instname[256] = {
	"nop",
	"alt",
	"nbalt",
	"goto",
	"call",
	"frame",
	"spawn",
	"runt",
	"load",
	"mcall",
	"mspawn",
	"mframe",
	"ret",
	"jmp",
	"case",
	"exit",
	"new",
	"newa",
	"newcb",
	"newcw",
	"newcf",
	"newcp",
	"newcm",
	"newcmp",
	"send",
	"recv",
	"consb",
	"consw",
	"consp",
	"consf",
	"consm",
	"consmp",
	"headb",
	"headw",
	"headp",
	"headf",
	"headm",
	"headmp",
	"tail",
	"lea",
	"indx",
	"movp",
	"movm",
	"movmp",
	"movb",
	"movw",
	"movf",
	"cvtbw",
	"cvtwb",
	"cvtfw",
	"cvtwf",
	"cvtca",
	"cvtac",
	"cvtwc",
	"cvtcw",
	"cvtfc",
	"cvtcf",
	"addb",
	"addw",
	"addf",
	"subb",
	"subw",
	"subf",
	"mulb",
	"mulw",
	"mulf",
	"divb",
	"divw",
	"divf",
	"modw",
	"modb",
	"andb",
	"andw",
	"orb",
	"orw",
	"xorb",
	"xorw",
	"shlb",
	"shlw",
	"shrb",
	"shrw",
	"insc",
	"indc",
	"addc",
	"lenc",
	"lena",
	"lenl",
	"beqb",
	"bneb",
	"bltb",
	"bleb",
	"bgtb",
	"bgeb",
	"beqw",
	"bnew",
	"bltw",
	"blew",
	"bgtw",
	"bgew",
	"beqf",
	"bnef",
	"bltf",
	"blef",
	"bgtf",
	"bgef",
	"beqc",
	"bnec",
	"bltc",
	"blec",
	"bgtc",
	"bgec",
	"slicea",
	"slicela",
	"slicec",
	"indw",
	"indf",
	"indb",
	"negf",
	"movl",
	"addl",
	"subl",
	"divl",
	"modl",
	"mull",
	"andl",
	"orl",
	"xorl",
	"shll",
	"shrl",
	"bnel",
	"bltl",
	"blel",
	"bgtl",
	"bgel",
	"beql",
	"cvtlf",
	"cvtfl",
	"cvtlw",
	"cvtwl",
	"cvtlc",
	"cvtcl",
	"headl",
	"consl",
	"newcl",
	"casec",
	"indl",
	"movpc",
	"tcmp",
	"mnewz",
	"cvtrf",
	"cvtfr",
	"cvtws",
	"cvtsw",
	"lsrw",
	"lsrl",
	"eclr",
	"newz",
	"newaz",
	"raise",
	"casel",
	"mulx",
	"divx",
	"cvtxx",
	"mulx0",
	"divx0",
	"cvtxx0",
	"mulx1",
	"divx1",
	"cvtxx1",
	"cvtfx",
	"cvtxf",
	"expw",
	"expl",
	"expf",
	"self",
};
