/*
 * C compiler
 * ==========
 *
 * Copyright 1989, 1990, 1991 Christoph van Wuellen.
 * Credits to Matthew Brandt.
 * All commercial rights reserved.
 *
 * This compiler may be redistributed as long there is no
 * commercial interest. The compiler must not be redistributed
 * without its full sources. This notice must stay intact.
 *
 * History:
 *
 * 1989   starting an 68000 C compiler, starting with material
 *        originally by M. Brandt
 * 1990   68000 C compiler further bug fixes
 *        started i386 port (December)
 * 1991   i386 port finished (January)
 *        further corrections in the front end and in the 68000
 *        code generator.
 *        The next port will be a SPARC port
 */

#include "chdr.h"
#include "expr.h"
#include "cglbdec.h"
#include "proto.h"
#include "version.h"

/* global definitions	 */
FHANDLE	input;				/* input source file */
FHANDLE	output;				/* output assembler file */
FHANDLE	errfile;			/* error listing file */
#ifdef LIST
FHANDLE	listfile;			/* source listing file */
#endif /* LIST */
#ifdef DEBUG
FHANDLE	debugfile;			/* output file for internal debugging */
#endif /* DEBUG */
LINE    act_line;			/* current line being processed */
CHAR *	act_linetxt;			/* text of the current line */
char	*act_file	= "<stdin>";	/* current file being processed */
LABEL   nextlabel;			/* next internally generated label */
BOOL	need_label	= FALSE;
#ifdef EPOC
char	*newline	= "\r\n";	/* new line character sequence */
#else
char	*newline	= "\n";		/* new line character sequence */
#endif /* EPOC */

/* scanner values */
TOKEN	lastst;				/* last symbol token read by the scanner */
CHAR	*lastsym;			/* pointer to the last symbol */
size_t 	lastsymlen;			/* length of the value in lastsym */
UVAL	ival;				/* integral value */
#ifdef FLOAT_SUPPORT
RVAL	rval;				/* floating point value */
#endif /* FLOAT_SUPPORT */

/* stack frame values */
SIZE	lc_auto;			/* the current size of the stack frame */
SIZE	lc_auto_max;			/* the maximum size that the stack frame has grown */

int	global_flag;			/* allocate memory for "permanent use */
int	error_resync	= 0;		/* prevent error message cascade */
int	total_errors	= 0;		/* number of errors currently encountered */

/* These are the default compiler options */
#ifdef INTEL
BOOL	align_option	= TRUE;		/* align structure fields to smallest alignment */
#else
BOOL	align_option	= FALSE;	/* align structure fields to smallest alignment */
#endif /* INTEL */
#ifdef ASM
BOOL	asm_option	= FALSE;	/* asm keyword allowed */
#endif /* ASM */
BOOL	bitfield_option	= FALSE;	/* reverse allocation order of bitfields */
BOOL	code_option	= TRUE;		/* generate code */
#ifdef DEBUGOPT
BOOL	debug_option	= FALSE;	/* generate debugging information */
#endif /*DEBUGINFO*/
#ifdef EXTERNAL
BOOL	extern_option	= FALSE;	/* generate extern defintions for all globals */
#endif /* EXTERNAL */
#ifdef FLOAT_CHECK
BOOL	 fcheck_option	= FALSE;	/* warn about floating point operations */
#endif /* FLOAT_CHECK */
#ifdef MC680X0
int	frame_option	= 6;		/* register to use as the frame pointer */
#endif /* MC680X0 */
#ifdef DEBUG
int	internal_option	= 0;		/* controls internal debugging options */
#endif /* DEBUG */
BOOL	lattice_option	= FALSE;	/* allow Lattice stype stdarg definitions */
BOOL	IandD_option	= FALSE;	/* separate Instruction and Data segments */
#ifdef MC680X0
BOOL	large_option	= TRUE;		/* allow static function calls >32K */
#endif /* MC680X0 */
#ifdef LIST
BOOL	list_option	= FALSE;	/* list the input source and symbol tables */
#endif /* LIST */
BOOL	longdouble_option = FALSE;	/* long doubles are to be the same size as doubles */
BOOL	obsolete_option	= FALSE;	/* future language directions defined obsolete feature */
BOOL	opt_option	= TRUE;		/* use the global optimiser */
BOOL	optimize_option	= FALSE;	/* do "expensive" optimisations */
#ifdef PACKENUM
BOOL	packenum_option	= FALSE;	/* enumerations are smallest integer type to hold values */
#endif /* PACKENUM */
BOOL	peep_option	= TRUE;		/* use the peep-hole optimiser */
BOOL	reg_option	= TRUE;		/* honour the "register" storage */
#ifdef EPOC
BOOL	short_option	= TRUE;		/* integers are to be the same size as shorts */
#else
BOOL	short_option	= FALSE;	/* integers are to be the same size as shorts */
#endif /* EPOC */
#ifdef EPOC
BOOL	small_option	= TRUE;		/* small model (8086) */
#else
BOOL	small_option	= FALSE;	/* small model (8086) */
#endif /* EPOC */
int	stackopt_option	= TRUE;		/* Use lazy stack optimisation */
#ifdef TOPSPEED
BOOL	topspeed_option	= FALSE;	/* Enable TopSpeed extentions */
#endif /* TOPSPEED */
BOOL	trad_option	= FALSE;	/* accept only K&R plus a few extras */
#ifdef TRANSLATE
BOOL	trans_option	= FALSE;	/* convert identifier > 8 character in output file */
#endif /* TRANSLATE */
BOOL	uchar_option	= FALSE;	/* char type to be unsigned */
BOOL	verbose_option	= FALSE;	/* output extra statistics */
int	error_option	= ERRORLEVEL_DEFAULT;	/* the current error message level */
int	warn_option	= WARNLEVEL_DEFAULT;	/* the current warning message level */
BOOL	fpu_option	= FALSE;	/* generate code which contains floating point instructions */
BOOL	fpu_return_option = FALSE;	/* return FP value in FP register */
#ifdef INTEL_386
BOOL	fpret386_option	= TRUE;		/* return FP values in edx:eax */
#endif /* INTEL_386 */
#ifdef ICODE
BOOL	icode_option	= FALSE;	/* generate an icode file */
#endif /* ICODE */
#ifdef TMS320C30
int	opt_delayed_branches = 2;	/* allow delayed branched */
#endif /* TMS320C30 */
#ifdef PROBES
BOOL	probe_option	= FALSE;	/* generate stack probes on function entry */
#endif /* PROBE */
#ifdef FORMAT_CHECK
BOOL	format_option	= TRUE;		/* check fprintf and fscanf format strings */
#endif /* FORMAT_CHECK */
#ifdef STACK_CHECK
BOOL	stackcheck_option = FALSE;	/* check stack with run-time routine */
#endif /* STACK_CHECK */
#ifdef TRACE
BOOL	trace_option	= FALSE;	/* generate trace code */
#endif /* TRACE */
int	max_error_count	= MAX_ERROR_COUNT; /* maximum number of errors before stopping */
#ifdef MC680X0
BOOL	target_option	= 68000;	/* Motorola 68000 code generation */
#endif /* MC680X0 */

TYP	*ret_type;			/* function return type */
EXPR	*init_node;			/* initializations in compound statement */

#ifndef EPOC
char	*msgtable[] = {
/*
 *	Parsing Error messages
 */
/* ERR_ADDREGVAR   */	"& operator on register variable '%s'",
/* ERR_ARG	   */	"declared argument '%s' missing",
/* ERR_ARITHMETIC  */	"arithmetic type expected",
/* ERR_ARRAYRETURN */	"function returning array type",
/* ERR_BITFIELD    */	"& operator may not be applied to bitfields",
/* ERR_BRACE	   */	"'{' expected on initializer",
/* ERR_BREAK	   */	"break not allowed here",
/* ERR_CASE	   */	"case not allowed here",
/* ERR_CAST	   */	"error doing a cast",
/* ERR_CASTCON	   */	"error casting a constant",
/* ERR_CHARCONST   */ 	"character constant unterminated or too long",
/* ERR_CONST       */	"modified 'const' value",
/* ERR_CONSTEXPR   */	"constant expression expected",
/* ERR_CONSTFLOAT  */	"floating point constant expected",
/* ERR_CONSTINT    */	"constant integer expression expected",
/* ERR_CONT	   */	"continue not allowed here",
/* ERR_COUNTPARAM  */	"parameter count incorrect for function %s",
/* ERR_DEREF	   */	"error dereferencing a pointer",
/* ERR_DUPCASE	   */	"duplicate case label 'case %ld'",
/* ERR_DUPDEFAULT  */	"duplicate default label in case",
/* ERR_DUPLABEL	   */ 	"duplicate label '%s'",
/* ERR_ENUMWRAP	   */	"enumeration constant too large",
/* ERR_EOF         */ 	"unexpected end of file",
/* ERR_ESCRANGE    */	"value of escape sequence out of valid range",
/* ERR_EXPREXPECT  */	"expression expected",
/* ERR_FPCON	   */ 	"illegal floating-point constant",
/* ERR_FUNC	   */	"function declarator not allowed here",
/* ERR_IDEXPECT	   */	"identifier expected",
/* ERR_IDLIST      */	"identifier list not allowed on function declaration",
/* ERR_ILLCAST	   */ 	"illegal cast operation",
/* ERR_ILLCHAR	   */ 	"illegal character '%c'",
/* ERR_ILLCLASS	   */	"illegal storage class",
/* ERR_ILLINIT	   */	"illegal initialization",
/* ERR_ILLSIZEOF   */	"illegal 'sizeof' operation",
/* ERR_ILLTYPE     */	"illegal type combination",
/* ERR_ILLXCHAR	   */ 	"illegal unprintable character (value=0x%x)",
/* ERR_IMPLICITADDR*/	"implicit conversion to pointer on register variable '%s'",
/* ERR_INCOMPLETE  */	"incomplete '%s' declaration",
/* ERR_INITSIZE	   */	"too many initializers",
/* ERR_INTEGER	   */	"integral type expected",
/* ERR_INTEXPR	   */	"illegal constant integer expression",
/* ERR_LINKAGE	   */	"extern definition of '%s' redeclared static",
/* ERR_LVALUE	   */	"l-value required",
/* ERR_MINUS	   */	"cannot subtract a pointer from an integral value",
/* ERR_MISMATCH	   */	"type mismatch error",
/* ERR_NESTED	   */	"cannot nest function definition '%s()'",
/* ERR_NOFUNC	   */	"function type expected",
/* ERR_NOINIT      */	"initialization invalid",
/* ERR_NOMEMBER	   */	"'%s' is not a struct/union member",
/* ERR_NOPOINTER   */	"pointer type expected",
/* ERR_OBJECT	   */	"an object type expected",
/* ERR_PARMS	   */	"error while scanning a parameter list",
/* ERR_PREPROC	   */	"problem with pre-processor output",
/* ERR_PROTODEF    */	"function '%s()' default promotion / prototype mismatch",
/* ERR_PROTO       */	"function '%s()' prototype mismatch",
/* ERR_PUNCT       */	"unexpected symbol '%s' found",
/* ERR_QUAL	   */	"qualifier mismatch",
/* ERR_QUALIFIER   */	"qualifier already specified",
/* ERR_REDECL	   */	"illegal redeclaration of '%s'",
/* ERR_REPRESENT   */	"constant expression exceeds representable range",
#ifdef EXTENSION
/* ERR_RESTRICT	   */	"'restrict' only allowed on pointer types",
#endif /* EXTENSION */
/* ERR_SCALAR	   */	"scalar type expected",
/* ERR_SIZE	   */	"type/operand has unknown size",
/* ERR_STATIC	   */	"function '%s' declared but never defined",
/* ERR_STRINGCONST */ 	"string constant unterminated or too long",
/* ERR_TAG	   */	"tag usage '%s' mismatch",
/* ERR_TYPE	   */	"type already specified",
/* ERR_UNDEFINED   */	"undefined identifier '%s'",
/* ERR_UNDEFLAB	   */	"undefined label '%s'",
/* ERR_VOIDFUNC    */	"return value specified to void function",
/* ERR_VOIDPARM    */	"void parameter is passed to function %s",
/* ERR_VOIDRETURN  */	"return expression of type void",
/* ERR_WIDTH	   */	"illegal field width",

/*
 *	Error/Warning messages are ordered in order of increasing severity
 *	If they are to be treated as errors or merely warnings is controlled
 *	by the current setting of the error_option.   For warnings, whether
 *	theya re to be output at all is controlled by warn_option.
 */
/*
 *	Level 1
 *	This is the most severe level of warnings.   These should
 *	not be suppressed unless one is certain that is OK.
 */
/* WARN_EXTERN	   */	"extern definition of '%s' redeclared static",
/* WARN_FLDTYPE	   */	"bit field type should be unsigned or int",
/* WARN_PRAGMA     */	"#pragma ignored",
/*
 *	Level 2
 *	Default warning level.  These should normally be fixed.
 *	Typically this just requires a cast or something similar.
 */
/* WARN_NOHEX	   */	"\\x not followed by any hex characters",
/* WARN_PARAMSIZE  */	"size of parameter %d changed by prototype on function %s",
/* WARN_SIZEOF0    */	"'sizeof' value is zero",
/* WARN_SIZEOFBIG  */	"'sizeof' value %ld is greater than '65535'",
/* WARN_TYPECAST   */	"conversion between incompatible types",
/*
 *	Level 3
 *	Warnings at this level are often encountered when porting
 *	code. They are quite likely to indicate an error.
 */
/* WARN_DUBIOUS   */	"dubious %s declaration; use tag only",
/* WARN_ESCAPECH   */	"escape ignored in sequence '\\%c'",
/* WARN_IMPLICITFN */	"implicitly declared function: 'int %s()'",
/* WARN_LOCAL	   */	"returning address of a local variable",
/* WARN_OUTSCOPE   */	"using out of scope declaration for '%s'",
/* WARN_PTRCAST    */	"conversion between incompatible pointer types",
/* WARN_QUALIFIER  */	"qualifier inconsistant with type 'void'",
/* WARN_SHORTPTR   */	"dangerous truncation of pointer",
/* WARN_STATIC	   */	"function '%s' declared but never defined",
/* WARN_STDARG	   */	"parameter before ', ...' causes undefined behaviour",
/* WARN_VALRETURN  */	"no value specified in 'return' statement",
/* WARN_UNSIGNED   */	"unsigned type is always positive",
/* WARN_ZERO	   */	"division by zero",
/*
 *	Level 4
 *	Warnings at this level are often encountered when porting
 *	code, but are quite likely not be an error.
 */
/* WARN_ADDFUNC    */	"& operator on function ignored",
/* WARN_CASTCONST  */	"implicit cast of pointer loses const/volatile qualifier",
/* WARN_CONDVOID   */	"%d expression to '?:' operator cast to void",
/* WARN_EMPTY      */	"empty statement",
/* WARN_GLOBAL	   */	"function '%s' redeclared, assumed static",
/* WARN_HIDE       */	"definition of '%s' hides an earlier definition",
/* WARN_IMPLICIT   */	"argument '%s' implicitly declared 'int'",
/* WARN_NOTREACHED */	"statement not reached",
/* WARN_POINTER	   */	"pointer difference between different pointer types",
/* WARN_PROTOTYPE  */	"K&R style function %s",
/* WARN_PROMOTE    */	"parameter %d to function %s() promoted to '%s'",
/* WARN_SHIFT	   */	"shift by %ld outside range",
/* WARN_STORAGE    */	"storage specifier not at start of definition",
/*
 *	Level 5
 *	These are warnings for things that are common C practise, but
 *	that might possibly indicate an error if you are having trouble
 *	tracking down a particular problem
 */
/* WARN_ACCESS     */   "'%s' modified and accessed between sequence points",
/* WARN_ASSIGN     */	"assignment in conditional context",
/* WARN_CONST	   */	"constant expression used in '%s' statement",
/* WARN_CONSTINIT  */	"'%s' has 'const' qualifier but is not initialized",
/* WARN_DISCARD	   */	"result of expression has been discarded",
/* WARN_ELSE	   */	"dangling 'else' statement",
/* WARN_FORMAT	   */	"format mismatch with parameter %d on function %s",
/* WARN_IGNORE     */	"ignored return value from function %s",
/* WARN_IMPLICITRET */	"no value specified in implicit 'return' statement",
/* WARN_LABNOTUSED */	"label '%s' declared but not used",
/* WARN_MINUS	   */	"unary '-' applied to unsigned expression",
/* WARN_MODIFIED   */	"'%s' modified more than once between sequence points",
/* WARN_NEGATIVE   */	"assignment of negative value to unsigned type",
/* WARN_NOPROTO    */	"no prototype defined on called function %s",
/* WARN_NOTSET	   */	"variable '%s' may be used before set",
/* WARN_NOTUSED    */	"variable/function '%s' not used",
/*
 *	Level 6 - Only output if checking for portability
 *	Warnings at this level are normally too pedantic to be useful
 */
/* WARN_CHAR	   */	"use of 'char' is possibly non-portable",
/* WARN_CONSTANT   */	"constant promoted to '%s'",
/* WARN_CONSTCAST  */	"a cast changed an integer constant (%08lx->%08lx)",
/* WARN_ENUM	   */	"implicit cast to enumeration value",
#ifdef FLOAT_CHECK
/* WARN_FLOAT	   */	"expression involving floating point",
#endif /* FLOAT_CHECK */
/* WARN_INCOMPLETE */	"initialisation incomplete - remaining fields zeroed",
/* WARN_NARROWER   */	"a cast to a narrower type loses accuracy",
/*
 *	Level 7 - Only output if you are wishing to "tidy" up your code
 *	Warnings at this level are normally too pedantic to be useful
 */
/* WARN_BITWISE    */	"signed type with bitwise operator possibly nonportable",
/* WARN_BRACE	   */	"partially elided braces on initializer",
/* WARN_DEFAULT	   */	"'switch' has no 'default' statement",
#ifdef FACIST
/* WARN_KEYWORD	   */	"C++ keyword '%s' used",
#endif /* FACIST */
/* WARN_NULLCAST   */	"implicit cast of NULL to pointer type",
/* WARN_OLDDEF     */	"function not using ANSI style parameters",
/* WARN_VOID	   */	"unnecessary cast to 'void'",

#ifdef FACIST
/*
 *	Level 8 - Only output if really strict checking is to be done.
 *	Warnings at this level are really "facist".
 */
/* WARN_NOIMPLICIT */	"implicit cast",
#endif /* FACIST */

/*
 *	Messages below this point are output without file/line number details
 */
/*
 *	Miscellaneous messages
 */
/* MSG_DEFAULTS    */   "\n\nDefault settings are:\n",
/* MSG_ERROR       */	"error",
/* MSG_ERRORCNT	   */	"\n -- %d errors found",
/* MSG_EXTRAPARAM  */	"too many parameters supplied",
/* MSG_FATAL	   */	"FATAL error encountered in file '%s' routine '%s'\nMessage: ",
/* MSG_FILENAMES   */	" input_file output_file listing_file\n",
/* MSG_LABSYMTABLE */	"\n\n*** label symbol table ***\n",
/* MSG_LINE */		"\"%s\", line %u: ",
/* MSG_LOCALMEM    */	"not enough local memory (%d Kbytes used) [global %d Kbytes]",
/* MSG_MAXERROR    */	"Program terminated due to maximum error count",
/* MSG_MAXMEMORY   */	"Maximum memory request was %d Kbytes",
/* MSG_MEMORY	   */	"not enough memory (%ld bytes requested)",
/* MSG_MISSING	   */	"\n(this may occur due to a feature left out of the compiler, or just an\ninternal compiler error)",
/* MSG_NOMEMORY    */	"not enough global memory (%d Kbytes used) [local %d Kbytes]",
/* MSG_OPENINPUT   */	"Cannot open file '%s' for input",
#ifdef LIST
/* MSG_OPENLISTING */	"Cannot open file '%s' for listing",
#endif /*LIST*/
/* MSG_OPENOUTPUT  */	"Cannot open file '%s' for output",
/* MSG_PEEPLABEL   */	"INCONSISTENCY: PEEP LABEL (FATAL?)",
#ifdef VERBOSE
/* MSG_PEEPCHANGES */	"\t%d changes made",
/* MSG_RELEASEGLB  */	"releasing %d Kbytes global tables",
/* MSG_RELEASELOC  */	"releasing %d Kbytes local tables",
#endif /* VERBOSE */
#ifdef SIGNAL
/* MSG_SIGNAL	   */	"TERMINATING: - signal %d received\n",
#endif /* SIGNAL */
#ifdef VERBOSE
/* MSG_TIMES	   */	"Times: %ld + %ld + %ld + %ld + %ld",
#endif /* VERBOSE */
/* MSG_UNKNOWNOPT  */	"option '%s' not recognised",
/* MSG_USEAGE      */	"\nUsage: %s [options] [input_file [output_file [listing_file]]]\n\nOptions available are:\n",
/* MSG_WARNING     */	"warning",
/* MSG_WRITEFAIL   */	"write failure",
};
#endif /*EPOC*/

#ifdef VERBOSE
/* statistics collected during the verbose mode */
clock_t decl_time	= (clock_t)0;	/* time spent parsing the declarations */
clock_t	parse_time	= (clock_t)0;	/* time spend parsing the statments/expressions */
clock_t	opt_time	= (clock_t)0;	/* time spend in the optimisers */
clock_t	gen_time	= (clock_t)0;	/* time spend in the code generator */
clock_t	flush_time	= (clock_t)0;	/* time spent writing out the code */
#endif /* VERBOSE */

BLOCK	init_block	= { {NULL, NULL}, {NULL, NULL}, NULL, 0L };
					/* empty block table */
BOOL	errorloop	= FALSE;	/* prevents recussion during error recovery */

/* the basic types */
TYP	*tp_void ;			/* void type */
TYP	*tp_long ;			/* long type */
TYP	*tp_ulong ;			/* unsigned long type */
TYP	*tp_char ;			/* char type */
TYP	*tp_uchar ;			/* unsigned char type */
TYP	*tp_schar ;			/* signed char type */
TYP	*tp_short ;			/* short type */
TYP	*tp_ushort ;			/* unsigned short type */
TYP	*tp_int ;			/* int type */
TYP	*tp_uint ;			/* unsigned int type */
TYP	*tp_float ;			/* float type */
TYP	*tp_double ;			/* double type */
TYP	*tp_longdouble ; 		/* long double type */
TYP	*tp_string ;			/* pointer to char type */
TYP	*tp_wstring ;			/* pointer to wchar_t type */
TYP	*tp_func ;			/* function type */
TYP	*tp_pointer ;			/* pointer type */
TYP	*tp_array ;			/* array type */
TYP	*tp_enum ;			/* enumeration type */
TYP	*tp_struct ;			/* struct type */
TYP	*tp_union ;			/* union type */
TYP	*tp_ellipsis ;			/* ellipsis type */

/* defined types */
TYP	*tp_wchar ;			/* wchar_t type */
TYP	*tp_size ;			/* size_t type */
TYP	*tp_ptrdiff ;			/* ptrdiff_t type */

int      int_bits	= 32;		/* number of bits in an int */

/* names used in the parser and code generators */
CHAR	*alloca_name;			/* pointer to the name alloca */
CHAR	*printf_name;			/* pointer to the name printf */
CHAR	*fprintf_name;			/* pointer to the name fprintf */
CHAR	*sprintf_name;			/* pointer to the name sprintf */
CHAR	*scanf_name;			/* pointer to the name scanf */
CHAR	*fscanf_name;			/* pointer to the name fscanf */
CHAR	*sscanf_name;			/* pointer to the name sscanf */

struct slit *strtab;			/* table of strings to be output to the assembler file */
BOOL uses_structassign;			/* function uses a structure assignment */
BOOL is_leaf_function;			/* function doesn't call any other function */
BOOL is_parameter	= FALSE;	/* controls whether stack optimation is allowed */

#ifdef MC68000
BOOL	volatile_found	= FALSE;	/* the volatile keyword has been found */
#endif /* MC68000 */

#ifdef FLOAT_SUPPORT
/* floating point constants used within the compiler */
RVAL	F_zero;				/* contains the value  0.0 */
RVAL	F_one;				/* contains the value  1.0 */
RVAL	F_two;				/* contains the value  2.0 */
RVAL	F_ten;				/* contains the value 10.0 */
RVAL	F_half;				/* contains the value  0.5 */
#endif /* FLOAT_SUPPORT */

#ifdef CPU_DEFINED
/* code generator values */

#ifdef MULTIPLE_PROCESSORS
#ifdef MC68000_DEFAULT
struct genfuncs	*GFuncs = &mc68k_funcs;
#else
#ifdef INTEL_386_DEFAULT
struct genfuncs	*GFuncs = &mc386_funcs;
#else
#ifdef INTEL_86_DEFAULT
struct genfuncs	*GFuncs = &mc86_funcs;
#endif /* INTEL_86_DEFAULT */
#ifdef TMS320C30_DEFAULT
struct genfuncs	*GFuncs = &mcc30_funcs;
#endif /* TMS320C30_DEFAULT */
#endif /* INTEL_386_DEFAULT */
#endif /* MC68000_DEFAULT */
#endif /* MULTIPLE_PROCESSORS */

#ifdef MULTIPLE_ASSEMBLERS
/*  Pointers to target code generator and assembler */
#ifdef MC680X0
#ifdef TARGET_ACK_DEFAULT
struct funcs	*Funcs  = &ack68k_funcs;
#else
#ifdef TARGET_GAS_DEFAULT
struct funcs	*Funcs  = &gas68k_funcs;
#else
#ifdef TARGET_CPM_DEFAULT
struct funcs	*Funcs  = &cpm68k_funcs;
#else
#ifdef TARGET_QMAC_DEFAULT
struct funcs	*Funcs	= &qmac68k_funcs;
#endif /* TARGET_QMAC_DEFAULT */
#endif /* TARGET_CPM_DEFAULT */
#endif /* TARGET_GAS_DEFAULT */
#endif /* TARGET_ACK_DEFAULT */
#else
#ifdef INTEL
#ifdef TARGET_MASM_DEFAULT
struct funcs	*Funcs  = &masm386_funcs;
#else
#ifdef TARGET_BAS_DEFAULT
struct funcs	*Funcs  = &bas386_funcs;
#else
#ifdef TARGET_GAS_DEFAULT
struct funcs	*Funcs  = &gas386_funcs;
#else
#ifdef TARGET_SVR4_DEFAULT
struct funcs	*Funcs  = &sysv386_funcs;
#endif /* TARGET_SVR4_DEFAULT */
#endif /* TARGET_GAS_DEFAULT */
#endif /* TARGET_BAS_DEFAULT */
#endif /* TARGET_MASM_DEFAULT */
#else
#ifdef TMS320C30
#ifdef TARGET_ROSSIN_DEFAULT
struct funcs	*Funcs  = &rosc30_funcs;
#endif /* TARGET_ROSSIN_DEFAULT */
#endif /* TMS320C30 */
#endif /* INTEL */
#endif /* MC68000 */

#endif /* MULTIPLE_ASSEMBLERS */

struct swtab *swtables;			/* switch jump tables to be output to the assembler file */
char	*external_prefix = "_";		/* prefix for external/global symbols */
SIZE	stack_offset	= 0L;		/* the number of bytes to remove from the stack */
SIZE	max_scratch;			/* the maxmimum number of bytes allocated to temporary variables */
SIZE	act_scratch;			/* the current number of bytes allocated to temporary variables */
#endif /* CPU_DEFINED */
