2020-09-30 17:12:32 +02:00

499 lines
17 KiB
C

/* SCCSWHAT( "@(#)il.h 3.9 89/12/06 13:45:39 " )*/
/*
* Special defined constants and information structures needed by both the p1-p2
* IL and the p2-p3 IL
*/
#ifndef _VC_VER_INC
#include "..\include\vcver.h"
#endif
typedef unsigned long symkey_t;
#define MAXSYMKEY 0x7fffffff // to accomodate compressed il output
#if 1 || _VC_VER >= 300
#define MAXLOCALSYMKEY 0x3fffff
#define MINLOCALSYMKEY (MAXLOCALSYMKEY - 0xffff)
#define LOCALILKEYBIAS (MAXLOCALSYMKEY - 0x7f)
#define MINGLOBALSYMKEY 1
#define MAXGLOBALSYMKEY (MINLOCALSYMKEY - 1)
#endif
#define MAXSBRKEY 0xffffff
#define MINEXTSBRKEY 0x8000
#if FARLIST
# define FAR_DATA far
#else
# define FAR_DATA
#endif
#if !defined(CONST)
# define CONST
#endif
#if 0
#if !defined(NODEBUG) && !defined(MDEBUG)
#define VERS_DEBUG 1
#endif
#endif
#define END_OF_EXPRESSION 'X'
#if VERS_DEBUG
# define MAC_STRING(X) #X,
#else
# define MAC_STRING(X)
#endif
/* expression IL primitive data types */
#define P_UNDEFINED 0
#define P_SINTEGER 1
#define P_UINTEGER 2
#define P_ADDRESS 3
#define P_HADDRESS 4
#define P_REAL 5
#define P_MULTI_BYTE 6
#define P_VOID 7
#define P_COMPLEX 8
#define P_LOGICAL 9
#define P_CREAL 10
#define P_F16ADDRESS 11
#define P_MAX 15
#define PRIM_TYPE unsigned short
#define P_UNION 16
#define P_VOLATILE 0x1000
#define P_CONST 0x2000
#define P_RESTRICT 0x4000
#define P_SPARE 0x4000
#define P_ALIGNSHFT 9
#define P_ALIGNMSK 0x0E00
#define P_SIZESHFT 4
#define P_SIZEMSK 0x01F0
#define P_TYPESHFT 0
#define P_TYPEMSK 0x000F
/* variable base types */
#define BA_UNDEFINED 0
#define BA_DYNAMIC 1
#define BA_STATIC 2
#define BA_PARAMS 3
#define BA_CONSTANT 4
#define BA_SEPARATE 5
#define BA_BSS 6 /* introduced by P2 */
#define BA_MAX 7
#define BA_FR_DATA 8 /* FORTRAN runtime data segment */
#define BASE_TYPE unsigned short
/* Base visibility class */
#define CLASS_UNDEFINED 0
#define CLASS_DEF 1
#define CLASS_REF 2
#define CLASS_COM 3
#define CLASS_LOC 4
#define CLASS_EQU 5
#define CLASS_EXPDEF 6 // Old __export
#define CLASS_DLLEXPDEF 7 // New __declspec(dllexport) M00GEN Need seperate REF?
#define CLASS_DLLIMPREF 8 // __declspec(dllimport)
#define CLASS_DLLEXPCOM 9 // __declspec(dllexport), uninitialized, in C!
#define CLASS_MAX 10
#define BASE_CLASS unsigned short
/* Label reference field -- bit patterns needed rather than enumerations */
typedef enum
{
REF_UNREFERENCED = 0,
REF_FORWARD = 1,
REF_BACKWARD = 2,
REF_OUT_OF_SCOPE = 4
} REFERENCE;
typedef enum /* procedure entry visibility */
{
EN_UNDEFINED = 0,
EN_LOCAL = 1,
EN_ST_REF = 2,
EN_ST_DEF = 3,
EN_GL_REF = 4,
EN_GL_DEF = 5,
EN_GL_EXT = 6,
EN_GL_EXPORT = 7, // __export. Potentially different from __declspec(dllexport)
EN_EXPORT = 7,
EN_ST_EXPORT = 8, // M00MERGE: Is this used by anybody?
EN_DLLEXPORT = 9, // __declspec(dllexport)
EN_DLLIMPORT = 10, // __declspec(dllimport)
} VIS_ENTRY;
/*
* Data sizes
*/
#define BYTE_SIZE 1
#define WORD_SIZE 2
#define DWORD_SIZE 4
#define QWORD_SIZE 8
#define SINGLE_SIZE MACH_FLOAT
#define DOUBLE_SIZE MACH_DOUBLE
#define QUAD_SIZE (MACH_DOUBLE * 2)
#define TREAL_SIZE MACH_TREAL
#define TCOMP_SIZE (MACH_TREAL * 2)
#define SADDR_SIZE MACH_NEAR
#define LADDR_SIZE MACH_FAR
/* this is the size of a long double (temp real) as passed
* in the ail. Because fp constants are passed in the ail
* as length preceeded strings, and sizeof(Srealt_t) = 12. */
#define AIL_TREAL_SIZE 12
/*
* DEBUG_IL definitions
*/
#define D_COMPLEX 0 /* expression too complex to type */
#define D_FIRSTKEY 10 /* first key available to P1 */
/*
* bitfield definitions for the attribute/use field in the symbol
* table entries. Some attributes are used by SSR_NAME records (N),
* some by SSR_ENTRY (E), and some by both (NE).
*/
/*
Some bits need to be in the low byte of SSR_NAME, because we want them
passed through to p3 (eg, AA_INIT). Some bits need to be in the low byte of
SSR_ENTRY because they have to be on the calltype.
Should AA_RETVAL be on the low byte? AA_SYMOUT?
Have we ever considered adding an SSR_STRING?
*/
#if _VC_VER >= 300
#define AA_NODEBUG 0x00010000 // used for ICC
#define AA_COMDAT_LARGEST 0x00020000 // used for RTTI
#define AA_COMDAT_NEWEST 0x00040000 // reserved for ICC
#define AA_BIASOFFSET 0x00080000 // for RTTI
#endif
/* SSR_NAME */
#define AA_REFERENCED 0x8000 /* p2 internal, for transitive refs */
#define AA_SYMOUT 0x8000 /* p3 internal */
#define AA_REGISTER 0x4000
#define AA_ADDRESSED 0x2000
#define AA_REGARG 0x1000 /* p2 internal */
#define AA_ALLOC 0x0800 /* p2 internal */
#define AA_PUBDECL 0x1000 /* p3 internal */
#define AA_THREAD 0x1000 // Place in thread-local storage: P1->P2
#define AA_CSTRING 0x0400
#define AA_SEG 0x0200
#define AA_USED 0x0100
#define AA_INIT 0x0080
#define AA_INSTANTIATE 0x0040 // Must instantiate this (COMDAT) variable
#define AA_COMDAT 0x0020 /* also used for SSR_ENTRY symbols */
#if VERSP_MIPS
#define AA_OLDSTYLEFORMAL 0x0010 // old style formal parameter
#endif
#if VERSP_ALPHA || VERSP_MIPS
#define AA_CDTOR_PARAM 0x0008 // parameter symbol has a constructor or destructor
#endif
/* SSR_ENTRY */
#define AA_KILLOPT 0x8000
#define AA_LOADDS 0x4000 // OBSOLETE? Not found in frontend
#define AA_SYSAPI 0x4000
#define AA_RETVAL 0x2000 // OBSOLETE? Not found in frontend
#define AA_TRY 0x1000
#define AA_NEARCALL 0x0800 // OBSOLETE? Not found in frontend /* p2 -> p3 */
#define AA_NOTHROW 0x0800 // __declspec(nothrow), or excpt spec "throw()"
#define AA_NAKED 0x0400 // __declspec(naked), or thunks
#define AA_SEG 0x0200
#define AA_SETJMP 0x0100 // OBSOLETE? Not found in frontend
#define AA_SAVEREGS 0x0080 // OBSOLETE? Not found in frontend
#define AA_VARARGS 0x0040
#define AA_LSHFT 2
#define AA_LMSK (0x7 << AA_LSHFT)
#define AA_CALLTYPE AA_LMSK
#define AA_LDEFAULT (0 << AA_LSHFT)
#define AA_C (0 << AA_LSHFT)
#define AA_OLDCALL (1 << AA_LSHFT) /* VERS_N10 only */
#define AA_FASTCALL (1 << AA_LSHFT)
#define AA_PASCAL (2 << AA_LSHFT)
#define AA_FORTRAN (2 << AA_LSHFT)
#define AA_JAVA (2 << AA_LSHFT)
#define AA_INTERRUPT (3 << AA_LSHFT)
#define AA_CPP (3 << AA_LSHFT) /* MIPS only, used in SSR_HEADER */
#define AA_STDCALL (4 << AA_LSHFT)
#define AA_THISCALL (5 << AA_LSHFT)
#define AA_SYSCALL (6 << AA_LSHFT)
#define AA_CNOPROTO (7 << AA_LSHFT)
#define AA_MSHFT 0
#define AA_MMSK (0x3 << AA_MSHFT)
#define AA_NFH (0x3 << AA_MSHFT)
#define AA_NEAR (1 << AA_MSHFT)
#define AA_FAR (2 << AA_MSHFT)
#define AA_HUGE (3 << AA_MSHFT)
#define AA_FAR16 (3 << AA_MSHFT)
/*
* definitions of p1-p2 IL dope vector and extraction macros
*/
typedef struct
{
#if VERS_DEBUG
char *d_name; /* opcode name -- opcodes.h is generated from this */
#endif
short d_node; /* node attributes -- what operations are allowed */
char *d_attr; /* IL attributes -- how to read IL stream */
} DOPEVECT ;
#ifndef SEPDS_DEBUG
extern CONST DOPEVECT expdope[]; /* universal declaration so macros will work */
#else
extern CONST DOPEVECT far expdope[]; /* far if debugging in separate segment */
#endif
#if CC_QC2PASS
extern CONST unsigned char expdope2[]; /* dope vector for QC node attribute */
#endif /* CC_QC2PASS */
/* bitfield definitions for the node attributes in the dope vector */
#define NODE_TYPE 0x3 /* node type */
#define COMM 0x4 /* is the node commutative ? */
#define SORT 0x8 /* can the node be sorted ? */
#define RELA 0x10 /* is this a relational operator ? */
#define FOLD 0x20 /* constant folding operation allowed */
#define COLEAF 0x40 /* coalesced leaf */
#define CSET 0x80 /* commutativity set : +,-,-' */
#define CSEE 0x100 /* Node can be used with CSE. */
#define KILL 0x200 /* Node kills CSE. */
#define LVALUE 0x400 /* ASSIG or OPextract */
#define ASSIG 0x800 /* is an assignment */
#define ENDEXPR 0x1000 /* end of expression */
#define HAS_RC 0x2000 /* has rchild */
#define CSER 0x4000 /* look below for CSE */
/* M00UNUSED in P1 */
#define OPEQ 0x8000 /* can be transformed into opeq (e.g. +=, -=) */
#define ADDR_ON_LEFT LVALUE
/* access to the fields of the dope vector */
#if VERS_DEBUG
#define D_NAME(op) (expdope[(int)(op)].d_name)
#endif
#define D_ATTRIBUTES(op) (expdope[(int)(op)].d_attr)
#define D_TYPE(op) (expdope[(int)(op)].d_node & NODE_TYPE)
#define D_COMM(op) (expdope[(int)(op)].d_node & COMM)
#define D_SORT(op) (expdope[(int)(op)].d_node & SORT)
#define D_RELA(op) (expdope[(int)(op)].d_node & RELA)
#define D_FOLD(op) (expdope[(int)(op)].d_node & FOLD)
#define D_COLEAF(op) (expdope[(int)(op)].d_node & COLEAF)
#define D_CSET(op) (expdope[(int)(op)].d_node & CSET)
#define D_CSEE(op) (expdope[(int)(op)].d_node & CSEE)
#define D_KILL(op) (expdope[(int)(op)].d_node & KILL)
#define D_LVALUE(op) (expdope[(int)(op)].d_node & LVALUE)
#define D_ASSIG(op) (expdope[(int)(op)].d_node & ASSIG)
#define D_ENDEXPR(op) (expdope[(int)(op)].d_node & ENDEXPR)
#define D_HAS_RC(op) (expdope[(int)(op)].d_node & HAS_RC)
#define D_CSER(op) (expdope[(int)(op)].d_node & CSER)
#define NODETYPE(n) ((int)D_TYPE(OPCODE(n)))
#define IS_LEAF(n) (NODETYPE(n) == LEAF)
#define HAS_RCHILD(n) (D_HAS_RC(OPCODE(n)))
#define HAS_LCHILD(n) (NODETYPE(n) != LEAF)
/*
* definition of the information tables used to hold information on all the
* il streams, including record type names, attributes for reading/writing
* those records, and size information for record allocation within the
* pass which needs those records. The only IL stream which does not use
* this structure to hold this information is the p1-p2 expression il stream
* which does not need the size information, but does need other information.
* This information is carried in a DOPEVECT table, defined above.
*/
typedef struct IL_INFO {
#if VERS_DEBUG
char *name; /* record type names */
#endif
char FAR_DATA *attrs; /* IL attributes - how to read/write IL stream */
short size; /* allocation size for record of this type */
} IL_INFO;
#if _VC_VER >= 300
extern CONST IL_INFO symdope[]; /* universal declaration so macros will work */
extern CONST IL_INFO Pragma_attrs[];
extern CONST IL_INFO Init_info[];
#else
extern CONST IL_INFO symdope[22]; /* universal declaration so macros will work */
extern CONST IL_INFO Pragma_attrs[38];
extern CONST IL_INFO Init_info[14];
#endif
#define IL_NAME(p) (symdope[(int)(p)].name)
#define IL_ATTRS(p) (symdope[(int)(p)].attrs)
#define IL_SIZE(p) (symdope[(int)(p)].size)
#if _VC_VER < 300
/* maximum key numbers for each pass */
#define KY_P1MAX 20000
#define KY_P2MAX 40000
#define KY_P3MAX 60000
#endif
/* comment pragma types */
#define COMMENT_END 0
#define COMMENT_COMPILER 1
#define COMMENT_DATE 2
#define COMMENT_EXESTR 3
#define COMMENT_LIB 4
#define COMMENT_TIMESTAMP 5
#define COMMENT_USER 6
#define COMMENT_LITERAL 7
#define COMMENT_EXPDEF 8
#define COMMENT_NOLIB 9 /* tell the linker: do NOT search this lib by default */
#define COMMENT_LINKER 10 /* arbitrary option strings passed to the linker */
#define KY_CURRENTLOCATION 1 /* reserved symbol key for "$" */
/* predefined segment keys */
#define KY_DATA 2
#define KY_CONST 3
#define KY_BSS 4
#define KY_TEXT 5
#define KY_STACK 6
#define KY_CLCRC 6 // YES 6 just like KY_STACK, OK KY_STACK is never output (not a real segment) - sps
#define KY_ATEXT 7
#define KY_SYMBOLS 8
#define KY_TLS 9 // Used by P2 for TLS data
#define KY_LOCALSIZE 10 // Reserved symbol key for __FRAME_SIZE in inline asembler
#define KY_FARDATA 11 // Currently Wings specific. Specifies data which cannot be got to using
// 16-bit offset addressing,
#define KY_FARBSS 12 // Bss for the FARDATA segment above.
// Not used by FE just put in here to avoid key
// collision with the ALAR backend.
#define KY_PDATA 13 // PowerPC (both)
#define KY_RELDATA 14 // PowerNT Relative Data?
#define KY_XDATA 15 // PowerNT exceptions
#if _VC_VER >= 300
#define KY_STARTUSERKEYS 16
#else
#define KY_STARTUSERKEYS 100
#endif
/* segment types */
#define SEGT_TEXT 0
#define SEGT_DATA 1
#define SEGT_ENDTEXT 2
#define SEGT_BSS 3
#define SEGT_CONST 4
#define SEGT_FARCONST 5
#define SEGT_TLS 6
#define SEGT_FARDATA 7
#define SEGT_UNKNOWN 8
#define SEGT_ISTEXT(a) ((a) == SEGT_TEXT)
#define SEGT_ISDATA(a) ((a) == SEGT_DATA)
#define SEGT_ISENDTEXT(a) ((a) == SEGT_ENDTEXT)
#define SEGT_ISBSS(a) ((a) == SEGT_BSS)
#define SEGT_ISCONST(a) ((a) == SEGT_CONST)
#define SEGT_ISFARCONST(a) ((a) == SEGT_FARCONST)
#define SEGT_ISTLS(a) ((a) == SEGT_TLS)
#define SEGT_ISFARDATA ((a) == SEGT_FARDATA)
#define SEGT_ISUNKNOWN(a) ((a) == SEGT_UNKNOWN)
#define SEGT_ISANYTEXT(a) (SEGT_ISTEXT(a) || SEGT_ISENDTEXT(a))
/* thunk numbers */
#define THNK_ADJUSTOR 1
#define THNK_VCALL 2
#define THNK_VCALL16 2
#define THNK_VCALL32 3
#define THNK_VTDISP_ADJUSTER 4
// extended entry attribute descriptor
typedef char ExtEntryAttr_t; // M00C9IL: This becomes __int16 for C9
#define EE_INLINE 0x80 // user explicit inline function - p2 read only
#define EE_EXPAND 0x40 // candidate for expansion
#define EE_INSTANTIATE 0x20 // function must be instantiated - p2 read only
#define EE_EXPANDING 0x10 // currently being expanded
#define EE_EXPLICIT 0x08 // if comdat func, no anonymous allocation
#define EE_REFERENCED 0x04 // function was ref'd
#define EE_CGEN 0x02 // compiler generated function
#define EE_ILINPCH 0x01 // il can be found in the pch file
// New extended attributes, under C9IL only
#define EE_HASEHUNWIND 0x0100 // Function has EH unwind semantics
#define EE_HASEHTRY 0x0200 // Function has try/catch
#define EE_HASEHSTATES 0x0400 // Destructors are specified using OPnewstate / OPretstate
#if _VC_VER >= 300
#define EE_CHANGED 0x0800 // il has changed - for incremental
#endif
#define AUTOINLINETHRESHOLD 175
// EH State Attributes: (a dword so there's lots of room to grow)
// (on OPnewstate)
#define EHA_FIXED 0x00000001 // Fixed state (mustn't be reordered)
#define EHA_MBARG 0x00000002 // Special state associated with IV_MBARG
#define EHA_TEMPORARY 0x00000003 // Construction of statement life temp
#define EHA_RETURN 0x00000004 // Construction of Return Expression
#define EHA_CLASS_MASK 0x00000007 // Mask for the above
#define EHA_ISFORMAL 0x00000008 // This State is ass. with a formal arg
#define EHA_NOUNWIND 0x00000010 // This Object needs no unwinding
#define EHA_MUSTPOP 0x00000020 // This State needs to be popped
#define EHA_CONDITIONAL 0x00000040 // This State is executed conditionally
#define EHA_ISDEAD 0x00000080 // This opcode is just cleaning up
#define EHA_CATCHRET 0x00000100 // This pushstate is used to exit a Catch block
#if CC_MACTRAP
#define MacReg__None 0
#define MacReg__D0 1
#define MacReg__D1 2
#define MacReg__D2 3
#define MacReg__A0 4
#define MacReg__A1 5
#define MacReg__UpperBound 6
#define MacTrapRegisterMask 7
#define MacTrapBitsPerReg 3
#define MacTrapReturn 0
#define MacTrapParam1 1
#define MacTrapParam2 2
#define MacTrapParam3 3
#define MacTrapParam4 4
#define MacTrapParam5 5
#define MacTrapEncodedMask 000777777UL
#define MacTrapToil(v) ((v) & MacTrapEncodedMask)
#define MacTrapError 001000000UL
#define MacTrapVoidVoid 010000000UL
// MacTrapEncodeReg(MacTrapParam3, MacReg__D2)
// MacTrapDecodeReg(VarHoldingEncoding, MacTrapReturn)
// (internal helpers for below)
#define MacTrapEncodeReg(p, r) (((r) << (MacTrapBitsPerReg * (p))))
#define MacTrapDecodeReg(v, p) (((v) >> (MacTrapBitsPerReg * (p))))
// ClearMacTrap(VarHoldingEncodings, MacTrapParam4)
// SetMacTrap(VarHoldingEncoding, MacTrapParam5, MacReg__A1)
// GetMacTrap(VarHoldingEncoding, MacTrapParam3)
#define ClearMacTrap(v, p) ((v) &= (~(MacTrapEncodeReg(p, MacTrapRegisterMask))))
#define SetMacTrap(v, p, r) (ClearMacTrap(v, p), (v) |= (MacTrapEncodeReg(p, r)))
#define GetMacTrap(v, p) (MacTrapDecodeReg(v, p) & MacTrapRegisterMask)
#endif