/* 
	oxanf.h	-- v1.430 definition of architecture neutral format
	
	Copyright (c) 1995
	Norman D. Culver dba
	Oxbow Software
	1323 S.E. 17th Street #662
	Ft. Lauderdale, FL 33316
	(954) 463-4754
	ndc@icanect.net
	All rights reserved.

 * Redistribution and use in source and binary forms are permitted
 * provided that: (1) source distributions retain this entire copyright
 * notice and comment, and (2) distributions including binaries display
 * the following acknowledgement:  ``This product includes software
 * developed by Norman D. Culver dba Oxbow Software''
 * in the documentation or other materials provided with the distribution
 * and in all advertising materials mentioning features or use of this
 * software.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

*/


/* F_RETBITS */
#define RET_VOID (0x01)
#define RET_FLOAT (0x02)
#define RET_STRUCT (0x04)
#define RET_DOUBLE (0x08)
#define RET_LDOUBLE (0x10)
#define RET_UNSIGNED (0x20)

/* F_QUALBITS */
#define QUAL_NEAR (0x01)
#define QUAL_FAR (0x02)
#define QUAL_SEG16 (0x04)
#define QUAL_FAR16 (0x08)
#define QUAL_ELLIPSIS (0x10)
#define QUAL_CONST (0x20)
#define QUAL_VOLATILE (0x40)

/* address types in 'atype' for gen_code */
#define A_VALUE (0x0001)
#define A_POINTER (0x0002)
#define A_MEMADDR (0x0004)
#define A_IMMED (0x0008)
#define A_ABSOLUTE (0x0010)
#define A_TEMP (0x0020)
#define A_DATA (0x0040)
#define A_AUTO (0x0080)
#define A_EXTERN (0x0100)
#define A_GLOBAL (0x0200)
#define A_RET (0x0400)
#define A_NOALIAS (0x0800)
#define A_PARAM (0x1000)

/* data types in 'dtype'(low 8 bits) for gen_code */
#define D_SIGNED (0x0000)
#define D_UNSIGNED (0x0001)
#define D_FLOAT (0x0002)
#define D_POINTER (0x0003)
#define D_ARRAY (0x0004)
#define D_STRUCT (0x0005)
#define D_FUNCTION (0x0006)
#define D_FUNCPTR (0x0007)
#define D_SEGMENT (0x0008)

/* data qualifiers in `dtype' (high 8 bits) for gen_code */
#define Q_NEAR	(0x01)
#define Q_FAR	(0x02)
#define Q_HUGE	(0x04)
#define Q_CONST	(0x08)
#define Q_VOLAT (0x10)
#define Q_SEG16	(0x20)
#define Q_FAR16	(0x40)
#define Q_BASED	(0x80)

/* in the opcode 3 address ids */
#define OPIMMED1 (0x00)	/* signed integer type */
#define OPIMMED2 (0x20)	/* unsigned integer type */
#define OPIMMED3 (0x40) /* float type */
#define OPIMMED4 (0x60) /* pointer type */
#define OPTEMP (0x80)
#define OPRET (0xa0)
#define OPAUTO (0xc0)
#define OPDATA (0xe0)

/* HARWARE TYPES */
#define INTEL8616 'i'
#define INTEL8632 'I'
#define POWER_PC 'P'
#define DEC_ALPHA 'D'
#define PA_RISC 'H'
#define MIPS_3000 'm'
#define MIPS_4000 'M'

/* GENCODE TYPE */
#define MACHINE_CODE 'm'
#define SOURCE_CODE 's'
#define BYTE_CODE 'b'
#define RIP_CODE 'r'
#define DEBUG_CODE 'd'
#define ANF_CODE 'n'
#define ASSEMBLER_CODE 'a'

/* OPERATING SYSTEM TYPES */
#define DOS16PLAT 'd'
#define DOS32PLAT 'D'
#define WIN16PLAT 'w'
#define WIN32sPLAT 'W'
#define WIN32gPLAT 'C'
#define WINntPLAT 'N'
#define OS216PLAT 'o'
#define OS232PLAT 'O'
#define UNIXVPLAT 'U'
#define LINUXPLAT 'L'

/* TARGET DEBUGGER INFO */
#define CODEVBUG 'v'
#define WATCBUG 'w'
#define BORLBUG 'b'
#define GDBBUG 'g'
#define DWARF 'd'

/* TARGET ASSEMBLER INFO */
#define UNIX 'u'
#define GAS 'g'
#define MASM 'm'
#define TASM 't'

/* MEMORY MODELS */
#define MODTINY 't'
#define MODSMALL 's'
#define MODMEDIUM 'm'
#define MODLARGE 'l'
#define MODCOMPACT 'c'
#define MODHUGE 'h'
#define MODFLAT 'x'

/* OBJECT FILE FORMATS */
#define OMF16FORMAT 'o'
#define OMF32FORMAT 'O'
#define PHARLAPFORMAT 'P'
#define WATCOM32FORMAT 'W'
#define BORLAND32FORMAT 'B'
#define AOUTFORMAT 'a'
#define COFFFORMAT 'c'
#define ELFFORMAT 'e'

#if NEED_FUNCTHUNK

/* FUNCTHUNK CONTENTS */

/* F_MODS */
#define Fretvoid (0x0001)
#define Fretflt (0x0002)
#define Fretstr (0x0004)
#define Fretdbl  (0x0008)
#define Fretldbl (0x0010)
#define Fbuiltin (0x0020)
#define Funused1 (0x0040)
#define Funused2 (0x0080)
#define Fnear	 (0x0100)
#define Ffar	 (0x0200)
#define Fseg16  (0x0400)
#define Ffar16  (0x0800)
#define Fellipsis (0x1000)
#define Fthunked (0x2000)
#define Fnested (0x4000)
#define Fextern (0x8000)

typedef struct _functhunk {/* 16 bytes */
	long funcaddr;
	unsigned short stksiz;
	unsigned short argsiz;
	unsigned short stkbeg;
	unsigned short fmods;
	unsigned short retsiz;
	unsigned short maxes;
} *Pft;

typedef union _datum { /* 16 bytes */
#if SUPPORT_LONG_LONG
	unsigned long long Uulonglong;
	long long		Ulonglong;
#endif
	unsigned char	Uuchar;
	char			Uchar;
	unsigned short	Uushort;
	short			Ushort;
	unsigned int	Uuint;
	int				Uint;
	unsigned long	Uulong;
	long			Ulong;
	void *			Upointer;
	float			Ufloat;
	double			Udouble;
#if SUPPORT_LONG_DOUBLE
	long double		Ulongdouble;
#endif
	struct {
		char d[16];
	} chr;
	struct {
		unsigned char d[16];
	} uchr;
	struct {
		short d[8];
	} shrt;
	struct {
		unsigned short d[8];
	} ushrt;
	struct {
		long d[4];
	} lng;
	struct {
		unsigned long d[4];
	} ulng;
#if SUPPORT_LONG_LONG
	struct {
		long long d[2];
	} lnglng;
	struct {
		unsigned long long d[2];
	} ulnglng;
#endif
	struct {
		void *d[4];
	} ptr;
} DATUM;
#endif /* NEED_FUNCTHUNK */

#ifdef NEED_ANFDEFS
enum basedecls {/* 1-21 */
	bd_array = 1, bd_struct, bd_union, bd_function, bd_funcptr,
	bd_pointer, bd_uchar, bd_ushort, bd_uint, bd_ulong,
	bd_ulonglong, bd_float, bd_longdouble, bd_double, bd_char,
	bd_short, bd_int, bd_long, bd_longlong, bd_void,
	bd_segment
};

typedef struct op {
	unsigned char op;
	unsigned char a1;
	unsigned char a2;
	unsigned char a3;
	unsigned char *next;
	long data;
	long data1;
	short data2;
	unsigned short data3;
	long data4;				/* perhaps skip to data in next area */
	long data5;				/* NODEP in functhunk */
	long data5a;			/* ARGSIZ|STKSIZ in functhunk */
	unsigned short data6;	/* STKBEG in functhunk */
	unsigned short data7;	/* F_MODS in functhunk */
	unsigned short data8;	/* F_RETSIZ in functhunk */
	unsigned short data9;	/* MAXES in functhunk */
} *Pop;
#define POP ((Pop)p)

typedef union opD {
	unsigned char	Uuchar;
	char			Uchar;
	unsigned short	Uushort;
	short			Ushort;
	unsigned int	Uuint;
	int				Uint;
	unsigned long	Uulong;
	long			Ulong;
	void *			Upointer;
	float			Ufloat;
	double			Udouble;
#if SUPPORT_LONG_LONG
	unsigned long long Uulonglong;
	long long		Ulonglong;
#else
	long			Ulonglong[2];
	unsigned long	Uulonglong[2];
#endif
#if SUPPORT_LONG_DOUBLE
	long double		Ulongdouble;
#endif
} opD, *PopD;

typedef struct opR {
	unsigned short dtype;
	unsigned short atype;
	long dsize;
} *PopR;

typedef struct opT {
	unsigned short dtype;
	unsigned short atype;
	long dsize;
	long tmpnum;
} *PopT;

typedef struct opA {
	unsigned short dtype;
	unsigned short atype;
	long dsize;
	long offset;
	unsigned short declnum;
	short symnum;
	long pofs;	/* autovars only */
} *PopA;
#define POPA ((PopA)(p+inc))

typedef struct _inst {
	PopA lptr;
	PopA rptr;
	PopA dptr;
	unsigned char loptype;
	unsigned char roptype;
	unsigned char doptype;
} INST, *PINST;

typedef union opI {
	struct  {
		unsigned long total_size;
		unsigned long thunk_offset;
		unsigned long bss_offset;
	} dat;
	struct  {
		unsigned long size;
		unsigned long offset;
		short symnum;
		unsigned short declnum;
		short segid;
		unsigned short dtype;
	} s;
	struct {
		unsigned short declnum;
		unsigned short basedecl;
	} dcl;
	struct {
		unsigned long swdefault;
		unsigned long swnode;
	} swt;
	struct {
		long argsize;
		long bits;
		long retbits;
	} fc;
	struct {
		unsigned long size;
		unsigned long offset;
	} rs;
	struct {
		unsigned long argloc;
		unsigned long argsize;
	} arg;
	struct {
		unsigned long arysize;
		unsigned long elemsize;
		unsigned long dims1;
		unsigned short dcnt;
		unsigned short declnum;
	} ary;
	struct {
		unsigned long dims[4];
	} ary1;
	struct {
		unsigned short parms[8];
	} parm;
	struct {
		unsigned short prmcnt;
		unsigned short fmods;
		unsigned short quals;
		unsigned short declnum;
		unsigned short parmnum;
		short symnum;
	} funcd;
	struct {
		unsigned char numptrs;
		unsigned char hassegs;
		unsigned char quals[8];
		unsigned short declnum;
	} ptrinf;
	struct {
		unsigned short seg[8];
	} seginf;
	struct {
		unsigned char tfofs;
		unsigned char fsize;
		unsigned char type;
		unsigned char pad;
	} bfinf;
	struct {
		unsigned long membercnt;
		unsigned long susize;
		short symnum;
		unsigned short quals;
	} suinf;
	struct {
		unsigned short memdcl[8];
	} sum;
	struct {
		unsigned long offset;
		short symnum;
		unsigned short declnum;
		unsigned short cdeclnum;	/* container_declnum */
		unsigned char fieldofs;		/* bitfields only */
		unsigned char fieldsiz;
	} memb;
	struct {
		unsigned short major;
		unsigned short minor;
		char code_format;
		char target_hardware;
		char target_debugger;
		char target_os;
		char memory_model;
		char obj_format;
		char target_assembler;
		char pads[4];
		char opt_level;
	} hdr;
	struct {
		long symnum;
		unsigned long hidden_offset;
		unsigned long argsize;
		short segid;
		unsigned short tempmax;
	} funcdef;
	struct {
		long tempmax;
	} funcexit;
	struct {
		unsigned long v1;
		unsigned long v2;
		unsigned long v3;
		short segid;
		short unused;
	} segdef;
	struct {
		unsigned long spot;
		short rsym;
		short rsize;
		unsigned long base;
		long offset;
	} reloc;
	struct {
		long line;
		long filenamenum;
	} line;
	struct {
		long label;
	} jmp;
	struct {
		unsigned char shift;
		unsigned char size;
		unsigned char sign;
	} bfield;
} *PopI;
#define POPI ((PopI)(p+8))
#define DATI (POPI->s)

typedef struct _nd
{
	unsigned char dtype;
	unsigned char quals;
	unsigned char opsize;
	unsigned char flags;
	long size;
	DATUM *data;
	unsigned short atype;
} ND, *PND;

#define OFFSET data->ulng.d[2]
#define DECLNUM data->ushrt.d[6]
#define SYMNUM data->shrt.d[7]
#define TMPNUM data->ulng.d[2]
#define POFS data->ulng.d[4]
#define ARGSIZE data->ulng.d[1]
#define ARGOFS data->ulng.d[0]

#endif /* NEED_ANFDEFS */

enum genopcodes {nilop=0,
/*01 -- instructions */
	assignop=1,plusop,minusop,mulop,divop,
	lshop,rshop,modop,orop,xorop,

/*11*/
	andop,eqop,neqop,ltop,gtop,
	leop,geop,negop,complop,notop,

/*21*/
	copyop,clrdatop,truthop,jmptrueop,jmpfalseop,
	jmpgotoop,nopop,callop,retvoidop,ljmptrueop,

/*31*/ ljmpfalseop,

/*41*/
	pushop=41,popop,functionop,emitop,signxtdop,

/*64 */
	jmploopop=64,jmpcontinueop,jmpbreakop,regainop,retstructop,
	retdataop,grabop,switchop,argop,callfuncop,

/*74*/
	compsavop,getbitfieldop,putbitfieldop,aliastmpop,castop,
	funcstartop,funcstopop,

/*84 -- address temp creators */
	duptmpop=84,derefop,getvalop,totmpop,

/*101 -- statements */
	labelop=101,gfuncdefop,sfuncdefop,nestedfuncdefop,funcexitop,
	nestedfuncexitop,expstmtop,ifstmtop,ifelsestmtop,switchstmtop,

/*111*/
	whilestmtop,dostmtop,forstmtop,asmstmtop,initstmtop,
	lineop,

/*131 -- expressions */
	condop=131,twopathop,logicalop,binopop,strelemop,
	ptrelemop,arrayelemop,arraydimsop,ptrdimsop,funcallop,

/*141*/
	argloadop,preincrdecop,compoundop,postincrdecop,unopop,

/*161 -- info */
	symbop=161,casevalop,caserangeop,switchidop,	
	headerop,trailerop,declop,ptrinfop,maxtempop,

/*171*/
	memberinfop,arrayinfop,structinfop,funcptrinfop,funcinfop,
	paraminfop,bfieldinfop,symoffsetop,symblockop,dataop,

/*181*/
	datablockop,mallocblockop,thunkblockop,bssblockop,glodatop,
	globssop,glofuncop,extvarop,extfuncop,relocop,
	stringblockop,
/*192*/
	segdefop,anfblockop,extlocop,endfileop,endallop,
	endop
}; 

#ifdef NEED_GENOPS
/* ARRAY OF STRINGS FOR PRINTING THE ENUMERATED OPCODES ABOVE, IT MUST MATCH */
/* PSEUDO ASSEMBLY LANGUAGE (anf) CODES MAY BE ADDED IN SLOTS 31-63 AND
	WILL AUTOMATICALLY BE UNDERSTOOD BY `oxcc' */

char *oxgenops[] = {"<nil>",
/*01 -- instructions */
	"mov", "add", "sub", "mul", "div", 
	"lsh", "rsh", "mod", "or", "xor",

/*11*/
	"and", "eq", "neq", "lt", "gt",
	"le", "ge", "neg","compl","not",

/*21*/
	"copydat","clrdat","truthof","jmptrue","jmpfalse",
	"jmp","nop","call","ret","ljmptrue",

/*31*/
	"ljmpfalse","","","","",
	"","","","","",

/*41 -- codes 41 to 63 not understood by bytecode generator `oxccb' */
/*		ADD NEW CODES FOR __anf__ BLOCKS HERE, NO NEED TO ENUMERATE ABOVE. */
	"push","pop","function","emit","signxtd",
	"","","","","",

/*51*/
	"","","","","",
	"","","","","",

/*61*/
	"","","",

/*64 -- codes 64 to 100 generated only by oxcc */
	"jmploop","jmpcontinue","jmpbreak","regain","retstruct",
	"retdata","grab","switch","arg","call-c",

/*74*/
	"compsave","getbitfield","putbitfield","aliastmp","cast",
	"funcstart","funcstop","","","",

/*84*/
	"duptmp","deref","getval","totmp","",
	"","","","","",

/*94*/
	"","","","","",
	"","",

/*101 -- statements */
	"Label","GFuncdef","SFuncdef","NestedFuncdef","Funcexit",
	"NestedFuncexit","ExpS","If","IfElse","Switch",

/*111*/
	"While","Do","For","Asm","Init",
	"#Line","","","","",

/*121*/
	"","","","","",
	"","","","","",

/*131 -- expressions */
	"Conditional","TwoPath","Logical","Binop","StrElem",
	"Ptrelem","ArrayElem","ArrayDim","PtrDim","FuncCall",

/*141*/
	"ArgLoad","Pre++--","Compound","Post++--","Unop",
	"","","","","",

/*151*/
	"","","","","",
	"","","","","",

/*161 -- info */
	"Symbols","CaseVal","CaseRange","SwitchId",
	"Header","Trailer","Decl","PtrInfo","MaxTemp",

/*171*/
	"Member","ArrayInfo","StructInfo","FuncPtrInfo","FuncInfo",
	"ParamInfo","BitfieldInfo","SymOffset","SymBlock","Data",

/*181*/
	"DataBlock","MallocBlock","ThunkBlock","BssBlock","Glodat",
	"Globss","Glofunc","Extvar","Extfunc","Reloc",
	"StringBlock",

/*192*/
	"SegDef","AnfBlock","Extloc","EndFile","EndAll",
	"End"
};
#else
extern char *oxgenops[];
#endif /* NEED_GENOPS */

#if NEED_ASM_OPCODES
static char *x86opcodes[] = {		
  "aaa","aad","aam","aas",
  "adc","adcb","adcw","adcl",
  "add","addb","addw","addl",
  "and","andb","andw","andl",
  "arpl",
  "bound","boundw","boundl",
  "bsf","bsfw","bsfl",
  "bsr","bsrw","bsrl",
  "bt","btw","btl",
  "btc","btcw","btcl",
  "btr","btrw","btrl",
  "bts","btsw","btsl",
  "call","cbw","cwde","clc","cld","cli","clts","cmc",
  "cmp","cmpb","cmpw","cmpl",
  "cmps","cmpsb","cmpsw","cmpsd","cmpsl",
  "cwd","cdq","daa","das",
  "dec","decb","decw","decl",
  "div","divb","divw","divl",
  "enter","hlt",
  "idiv","idivb","idivw","idivl",
  "imul","imulb","imulw","imull",
  "in","inb","inw","inl",
  "inc","incb","incw","incl",
  "ins","insb","insw","insd","insl",
  "int","into","iret","iretd",
  "ja","jae","jb","jbe","jc","jcxz","jecxz","je","jz","jg","jge","jl","jle",
  "jna","jnae","jnb","jnbe","jnc","jne","jng","jnge","jnl","jnle","jno","jnp",
  "jns","jnz","jo","jp","jpe","jpo","js","jz","jmp",
  "lea","leaw","leal",
  "leave","lgdt","lidt","lgs","lss","lds","les","lfs","lldt","lmsw","lock",
  "lods","lodsb","lodsw","lodsd","lodsl",
  "loop","loope","loopz","loopne","loopnz",
  "lsl","lslw","lsll",
  "ltr",
  "mov","movb","movw","movl",
  "movs","movsb","movsw","movsd","movsl",
  "movsx","movsxb","movsxw",
  "movzx","movzxb","movzxw",
  "mul",
  "neg","negb","negw","negl",
  "nop",
  "not","notb","notw","notl",
  "or","orb","orw","orl",
  "out","outb","outw","outl",
  "outs","outsb","outsw","outsd","outsl",
  "pop","popw","popl",
  "popa","popaw","popad","popal",
  "popf","popfw","popfd","popfl",
  "push","pushw","pushl",
  "pusha","pushad","pushal",
  "pushf","pushfd","pushfl",
  "rcl","rclb","rclw","rcll",
  "rcr","rcrb","rcrl",
  "ror","rorw","rorl",
  "rol","rolb","rolw","roll",
  "rep","repe","repz","repne","repnz",
  "ret","retn",
  "sahf",
  "sal","salb","salw","sall",
  "sar","sarb","sarw","sarl",
  "shl","shlb","shlw","shll",
  "shr","shrb","shrw","shrl",
  "sbb","sbbb","sbbw","sbbl",
  "scas","scasb","scasw","scasd","scasl",
  "seta","setae","setb","setbe","setc","sete","setg","setge","setl","setle",
  "setna","setnae","setnb","setnbe","setnc","setne","setng","setnge","setnl",
  "setnle","setno","setnp","setns","setnz","seto","setp","setpe","setpo",
  "sets","setz","sgdt","sidt",
  "shld",
  "shrd",
  "sldt","smsw","stc","std","sti",
  "stos","stosb","stosw","stosd","stosl",
  "str",
  "sub","subb","subw","subl",
  "test","testb","testw","testl",
  "verr","verrw",
  "wait",
  "xchg","xchgb","xchgw","xchgl",
  "xlat","xlatb",
  "xor","xorb","xorw","xorl",

  "fabs","fadd","fadds","faddl","faddp","fbld","fbstp","fchs","fclex",
  "fnclex","fcom","fcoms","fcoml","fcomp","fcomps","fcompl","fcompp","fcos",
  "fdecstp","fdisi","fndisi","fdiv","fdivs","fdivl","fdivp","fdivr","fdivrs",
  "fdivrl","fdivrp","feni","fneni","ffree","fiadd","fiaddw","fiadds","ficom",
  "ficomw","ficoms","ficomp","ficompw","ficomps","fidiv","fidivw","fidivs",
  "fidivr","fidivrw","fidivrs","fild","fildw","filds","fildl","fimul","fimulw",
  "fimuls","fincstp","finit","fininit","fist","fistw","fists","fistp","fistpw",
  "fistps","fistpl","fisub","fisubw","fisubs","fisubr","fisubrw","fisubrs",
  "fld","fldw","flds","fldl","fldcw","fldenv","fldlg2","fldln2","fldl2e",
  "fldl2t","fldpi","fldz","fld1","fmul","fmuls","fmull","fmult","fmulp",
  "fnop","fpatan","fprem","fprem1","fptan","frndint","frstor","fsave",
  "fnsave","fscale","fsetpm","fsin","fsincos","fsqrt","fst","fsts","fstl",
  "fstcw","fnstcw","fsetenv","fnsetenv","fstp","fstps","fstpl","fstpt",
  "fstsw","fnstsw","fsub","fsubs","fsubl","fsubp","fsubr","fsubrs","fsubrl",
  "fsubrp","ftst","fucom","fucomp","fucompp","fwait","fxam","fxch","fxtract",
  "fyl2x","fyl2xpi","f2xmi",
  0
};
static char *x86words[] = {
  "ah","al","bh","bl","ch","cl","dh","dl","ax","bx","cx","dx","ds","es","ss",
  "fs","gs","si","di","bp","sp","eax","ebx","ecx","edx","esi","edi","ebp","esp",
  "LENGTH","TYPE","SIZE","BYTE","TBYTE","WORD","DWORD","FWORD","QWORD","PTR",
  "OFFSET","EVEN","ALIGN","NEAR","FAR","SHORT","HIGH","LOW","SEG",
  "length","size","type","byte","tbyte","word","dword","fword","qword","ptr",
  "offset","even","align","near","far","short","high","low","seg",
  0
};
#endif /* NEED_ASM_OPCODES */
