


/* EPC Imp to C Translation Release 4 Version Apr 95 */


#include "imptoc.h"

#undef PI

/** 30Jan98                                                           mprocs18.1*/
/**       Changed Mcall to accept bitmask rather than proctype                  */
/**       Fortunately only calls from mprocs are affected                       */
/**       Chnaged Substiyute to correct IndDirVal Problem in C                   */
/** 12Oct97                                                           mprocs18  */
/**       Added Mtrampcall for KAI parallel stuff                               */
/** 30Sep97                                                           mprocs17.2*/
/**       More careful about unasspat since some compilers separate th 2 word   */
#define modulename ("mprocs")
/** 23Apr96                                                           mprocs17.1*/
/**       Added Extra Mabort message for 64 bit integers                        */
/** 17Apr96                                                           mprocs17*/
/**       Translated to C and hand finished                                   */
/**       Corrections (several) to unassigned checking on PPC Solaris ABI     **/
/**        Added AndyK code for leaf SP calls (like mexpcall)                 **/
/**        Changed to Msetoptions2 and set pic ax extern                       */
/**       Change to Mprecall for MIPS when a Floatval is 1st par               */
/** 13Feb96                                                           mprocs16.1*/
/**        Added code to work with elfput in C                               */
/**        Corrected rounring of framesize in tidy frags                     */
/** 14Dec95                                                           mprocs16*/
/**       Added Mcurrentvalue a target independent variant of Ccurrentvalue  */
/**       Adding this to Mprocs should reduce maintainence                   */
/**       Removable destroyable bit for Pentium profiling                    */
/**       Remove the cror in Mcall for AIX calls via ptr as the linker       */
/**       does not convert these to TOC reloads. The TOC is reloaded         */
/**       in rs6 callind                                                     */
/** 02Oct95                                                           mprocs15.4*/
/*        More care over hidden parameters in Mprecall so Fortran chars      */
/**       are not confused with structures(pds)                              */
/**       Used global string exnameprepend rather than "_" to amend USLC names*/
/**       Added MonetimeLabel to improve ADI ADSYM code(pds)                 */
/**       Added a new bit in callprops to indicate the procedure has         */
/**       varargs. Needed for the Power Sunsoft ABI but not restricted       */
/**       to RS6 targets(pds).                                               */
/** 18Sep95                                                           mprocs15.3*/
/**       Correction to Mprecall for Sparc only. For calls within calls muc!*       decrement SP enough 
to deal with varargs case and also to protect the struct                     */
/**       return pointer which may also be on stack                          */
/** 08Aug95                                                           mprocs15.2*/
/**       Changes to Mexpcall and Mspcall for USLC                           */
/**       Mapped ParI array to allow >199 params in a single call            */
/**       Sunsoft special in Minitialise                                     */
/** 03Aug95                                                           mprocs15.1*/
/**        Ensured there is always a procrag at level0 in case of rogue      */
/**        handles being requested(pds)                                      */
/** 24Jly95                                                           mprocs15*/
/**       Changes in Mtidy end to detect DBXINFO added at level 0 and        */
/**       move it to head of current proc. This eases front end problems     */
/**       of getting correct line information for fns in includes            */
/** 01Jun95                                                           mprocs14.5*/
/**       Changes to remove put references for USLC                          */
/**       Increased the switcsize needed for a dense switch                  */
/** 08May95                                                           mprocs14.4*/
/**      Added Mreinitialise for repositary scheme(pds)                      */
/**      Merged in AK chnages for SunOS(pds)                                 */
/** 06Apr95                                                           mprocs14.3*/
/**       Changes to mexpcall to pass sparc real*16 by address and accept    */
/**       result as a stucture                                               */
/**       Removed historic M88k special from fm Mbrac                        */
/**       Added code in Mstartproc and Mcall for early detection of          */
/**       recursion and to protect the tail recursion label from             */
/**       being optimised away. This facilitates the implementation          */
/**       ot the tail recursion optimisation in target procs(pds)            */
/** 23Mar95                                                          mprocs14.2*/
/**       Ensured generate entry die only called for Unix5.4 macheines       */
/**       Calls cvalidatejumps for all targets. Dummies may be reqd          */
/** 20Mar95                                                          mprocs14.1*/
/**       Changed Mstartproc for m88k to LOad Gla reg in the usual way       */
/** 06Feb95                                                          mprocs14*/
/**       Added code in the Mparaminfo family to cope with real*16 with      */
/**       real*8 alignment. Further cahnges may be needed if the MIPS        */
/**       ABI specifies 16 byte alignment when extended for real*16          */
/**       Also moved some MIP special code in M tidy proc to wrapper sequence*/
/**       Changed Mexpcall and Mspcall ti pass correct type info to Exname   */
/** 27Jan95                                                          mprocs13.10*/
/**       In Minitialise remove GOT setting up. Done also in elfput(pds)     */
/**       Corrected Mtidyproc for fns returning int*8&real*16(pds)           */
/**       this requires boc15.6.inc as include file                          */
/** 02Nov94                                                          mprocs13.9*/
/**       Changes to layout of conds for easier translation to C             */
/**       Corrected Mtidyproc for fns returning int*8(pds)                   */
/**       this requires boc15.5.inc as include file                          */
/** 18Oct94                                                         mprocs13.8*/
/**       Corrected Sunsoft unassigned filling                               */
/**       Added NO COALESCE HEAD to first rs6 frag so wrappers locatable     */
/** 01Sep94                                                         mprocs13.7*/
/**       Added code for m88k profiling which was omitted.                   */
/**       Correction to previous change to include Nonvirtual fp (alloca)    */
/** 09Aug94                                                         mprocs13.6.1*/
/**       Changed Mgetfpparamoffset to handle parameter holes. Fixed Mtidyproc*/
/**       to give procedure NON VIRTUAL FP flag if stack frame bigger than   */
/**       32K. (rt)                                                          */
/** 02Aug94                                                          mprocs13.6*/
/**       Correction to merge                                                */
/**       Output Sunsofts TBT before rather than after the proc body         */
/**       Added code for Sunsoft parameter passing on POWER                  */
/** 01Aug94                                                          mprocs13.5*/
/**       Merge of RT and PDS working versions. (rt)                         */
/** 29Jul94                                                          mprocs13.4*/
/**       Changes for use of 'do wrapping' for RS6000/POWER.                 */
/** 01Aug94                                                          mprocs13.3.2*/
/**       Changed RS/6000 AIX TOC reload to NOPs to support C since we       */
/**       don't known if a procedure is internal or not. (rt)                */
/** 27Jul94                                                          mprocs13.3.1*/
/**       Added calls to target DefAssSymbol to define symbols which are     */
/**       external for some assemblers. (rt)                                 */
/** 22Jul94                                                          mprocs13.3*/
/**       Changes to allow 2 different ABIs on rs6000(pds)                   */
/** 18Jly94                                                          mprocs13.2*/
/**       Changes for MIPS switches no longer in text segment                */
/** 28Jun94                                                          mprocs13.1*/
/**       Changes for parallel Fortran which HAS nested procedures(in effect)*/
/**       Changed profiling code for Pentium which uses a NON STANDARD call  */
/** 21Apr94                                                          mprocs13*/
/**       Changed target accessindrr, target accessindri and target access   */
/**       parameters. Changed calculation of register set for MIPS           */
/**       do wrapping. Changed clearing of register clearing in Mcall to     */
/**       prevent MIPS GOT reload picking up bogus register tracking info.  (rt)*/
/** 07Apr94                                                          mprocs12.3*/
/**       Added leaf call reg routines for PENTIUM. (pds)                    */
/** 24Mar94                                                          mprocs12.2*/
/**       Always pass three parameters to target frlabel. Add back in Mcodeon*/
/**       (although functionally redundant). Also put arrays for support calls*/
/**       back into include file. (pds)                                      */
/** 11Apr94                                                          mprocs12.1.1*/
/**       In Mtidyproc, correct stack unassigned fill count for SPARC to use */
/**       PI_framesize rather than localsize. (ak)                           */
/** 17Mar94                                                          mprocs12.1*/
/**       Merge of GIS development SPARC code generator with latest generic  */
/**       version. (rt)                                                      */
/**------------------------ START OF PENTIUM CHANGES ---------------------------*/
/** 15Mar94                                                          mprocs11.4*/
/**       Added code to mtidyend so that any wrappers are added before       */
/**       a DBXINFO instruction if this was the last instruction planted     */
/** 24Feb94                                                          mprocs11.3*/
/**       Added code for dealing with MIPS got save word >32K from LNB       */
/**       Reenabled code in Mfrlabel disabled by RT (pds)                    */
/**       Marked GOT loading & saving with privprop 'GOT RED TAPE'           */
/** 11Feb94                                                          mprocs11.2*/
/**       Added code for setting diagdisp on mips and PENTIUM. Originally this*/
/**       was missing for side entries. Also some rationalisation of setting */
/**       and post filling of diagdisp(pds)                                  */
/** 25Jan94                                                          mprocs11.1*/
/**     Additional code for MIPS to prevent Fortran Parameter checking data  */
/**     being overwritten by the unassigned pattern(pds)                     */
/** 10Nov93                                                          mprocs11*/
/**       Added code for Pentium(pds)                                        */
/**       Also merged in change from TAM                                     */
/**       Added MAdjustOptions and changed MSetOptions accordingly.          */
/**            Part of fix for B405. (tkr)                                   */
/**        MSetOpnd will now process a chain of opernads                     */
/**------------------------- END OF PENTIUM CHANGES ----------------------------*/
/** 07Jan94                                                          mprocs12*/
/**       Merge of M88K and SPARC code generators for GIS port to SPARC. (rt)*/
/**----------------------- START OF SPARC F90 CHANGES --------------------------*/
/** 13Sep93                                                           mprocs4.7.2*/
/**       in Mstartproc and Msideentry, if profiling on SPARC then           */
/**       clear register memory after calling mcount (OUTPARAM1REG           */
/**       may contain a large (>4K) GLA address and will thus be             */
/**       in the register memory).                                           */
/** 10Sep93                                                                  */
/**       in Mstartproc and Msideentry, remove the double load of            */
/**       the Gla register if generating PIC code for SPARC.                 */
/** 06Sep93                                                                  */
/**       Made exrecheads an allocatable, extendable, array (required        */
/**       by Fortran90 when generating Dwarf).                               */
/** 13Aug93                                                                  */
/**       Correction to Mtidyend: exdata -> exfix                            */
/** 10Aug93                                                           mprocs4.7.1*/
/**       In Mfrlabel, add SPARC to the list of targets that fully           */
/**       support Efrlabel and modify the spec of target frlabel             */
/**       to additionally pass the address of the current fragment.          */
/** 06Aug93                                                                  */
/**       In Mgetprocref, initialise the store reserved for the              */
/**       fixup to zero (on Solaris fixups gets added to the                 */
/**       original contents)                                                 */
/***/
/**       In Msideentry, use the constant STOREINTVAL, and not               */
/**       'INTVAL+4' when calling targetaccess to store the                  */
/**       diagdisp                                                           */
/** 02Aug93                                                                  */
/**       In Mstartproc, allow Fortran90 to have a display                   */
/** 09July93                                                                 */
/**       In Mstartproc, dont forget to store the caller stack frame         */
/**       address after filling the stack with the unassigned pattern        */
/**       if argument checks are on                                          */
/** 06July93                                                           mprocs4.7*/
/**       Further changes from andy-s mprocs46.6.i merged in                 */
/**       Allow dummy fixups in maddrlabel for assembler or gotfix           */
/**------------------------ END OF SPARC F90 CHANGES ---------------------------*/
/** 03Nov93                                                          mprocs11*/
/**       Merge of MIPS, USL C and C++ M88K code generators. Added           */
/**       Mexname function. (rt)                                             */
/**----------------------- START OF M88K USL C CHANGES -------------------------*/
/** 06Sep93                                                          mprocs4.2*/
/**       Mgetname added for USL C.                                          */
/**------------------------ END OF M88K USL C CHANGES --------------------------*/
/**------------------------ START OF M88K C++ CHANGES --------------------------*/
/**                                                                  mprocs42.2*/
/** 09Nov92 .Introduced code to deal with code handles and introduced        */
/**          MProcFrameSize.  (si)                                           */
/**                                                                  mprocs42.1*/
/** 27Jan92 .Changed ESetProcRef and MGetUniqueProcKey to take extra         */
/**          id parameter. This allows multiple fixups to be made to an      */
/**          external function with only a single external reference. (rt)   */
/**------------------------- END OF M88K C++ CHANGES ---------------------------*/
/** 14Oct93                                                          mprocs10.4*/
/**       Made B FreeAllocation work at all procedural levels and            */
/**       deleted calls to B InitAllocation, which is now redundant. (rt)    */
/** 08Oct93                                                          mprocs10.3*/
/**       Added call to abi init in tidy frags for mips specific ABI         */
/**       requirement. (rt)                                                  */
/** 20Sep93                                                          mprocs10.2*/
/**       Made Exrecheads an extendable array and added code to extend       */
/**       if it overflows (F90 requirement)                                  */
/**       Corrections to PIC code for MIPs(pds)                              */
/** 27Aug93                                                            mprocs10.1*/
/**      Removed references to shrink wrapping optimisation. Handle new      */
/**      RETURNS SREAL and RETURNS DREAL flags. Removed HAS LARGE STACK flag */
/**      setting. (rt)                                                       */
/**                                                                    mprocs10*/
/** 17Aug93                                                                  */
/**      Modified setting of registers referenced by return jump instruction */
/**      to handle case of FORTRAN subroutine with side entries returning    */
/** 11Aug93                                                        mprocs9.i */
/**       Further changes from andy-s mprocs46.6.i merged in                 */

/**                                                                    mprocs9*/
/** 27Jul93                                                                  */
/**      If generating code for procedure with unknown control flow then     */
/**      clear all register tracing information on a call. (rt)              */
/**                                                                    mprocs8*/
/** 25Jul93                                                                  */
/**      Set new flags HAS LARGE STACK and NO REG EXPAN to handle pathological*/
/**      cases for global scheduler changing stack frame size. (rt)          */
/**                                                                    mprocs7*/
/** 22Jul93                                                                  */
/**      Clear fragment chain head pointer for global fragments after        */
/**      they have been generated and set up a new empty fragment. Fixed     */
/**      Mtidyend to handle code in level 0 generated after last Eprocend.   */
/**      Add MEndProcs to generate any outstanding level 0 instructions. (rt)*/
/**                                                                    mprocs6*/
/** 19Jul93                                                                  */
/**      Modified stack frame size calculation so that wrapping instructions */
/**      generated after stack frame size is calculated. This is required since*/
/**      we won't know if we need a real frame pointer until the stack frame */
/**      size is known. Changed Msetopnd to remove unncessary check for signed*/
/**      arithmetic when setting new stack frame size. (rt)                  */
/**                                                                    mprocs5*/
/** 14Jun93                                                                  */
/**      Merge of MIPS and SPARC versions for GIS port. Renamed CScheduleProc*/
/**      to COptimiseProc. Handled change of stack frame size ofter optimisation*/
/**      and removed insertion of discarded psuedo ops. Renamed uses of      */
/**      _fragbusy to _fragsize. Renamed _maxparsize to _outparsize. Changed */
/**      Mtidyend to fix up addressed labels via the stored fragment start   */
/**      address. Added UnkCntrlFlow for global scheduler. Also handle malloc*/
/**      failure more gracefully - suggest user recompiles without           */
/**      optimisation. Added parameter to CCall call to indicate if a display*/
/**      register is being passed to the function or not. Also added support */
/**      for line prefixes. These give the complete path by which a source   */
/**      line is included in the code if it appears by virtue of an inlining.*/
/**      The new routine MPrintLine prints a full line number including      */
/**      including any prefix and MAddLinePrefix generates a line prefix     */
/**      record. Also changed dynamic memory allocation to use B Malloc and  */
/**      and B Free. Make return instruction reference the returned          */
/**      registers. Call B InitAllocation and B FreeAllocation to handle     */
/**      allocation of fragments at procedural level 1. (rt)                 */
/** 10Jun93                                                            mprocs4.6*/
/**       Added mnotecodefix and made Mtidyproc a function. (pds)            */
/** 03Jun93                                                            mprocs4.5*/
/**       Further changes to getprockey family and mtidyend for C++          */
/**       to aid setting up virtual tables                                   */
/* 20May93                                                              mprocs4.4*/
/**        Used addiu for stackframes                                        */
/* 17Apr93                                                              mprocs4.3*/
/**       Added Mgetname for USL C and updated M adjust par and              */
/**       M paraminfo family for complete realigning of params               */
/**       that can be required if there is a hidden parameter                */
/**       and also long reals(pds)                                           */
/**       Also added and checked the .init/.fini bits in Mstartproc          */
/* 16Apr93                                                              mprocs4.2*/
/**       support note entry info eyc for Mips (gm)                          */
/* 16Mar93                                                              mprocs4.1*/
/**       Changed Mtidyend to force out unrefenced symbols for FORTRAN       */
/**       which uses this to link in blockdata but not for C or others       */
/**       which rely on this not happening.(pds)                             */
/* 07Mar93                                                                mprocs4*/
/**       includedNote Entry Info, Note Entry Codead, Output DBX Entries     */
/**       introduled by sl for 88K dwarf generation.                         */
/**       Common RS6000, MIPS and 88K                        (gm)            */
/* 24Nov92                                                                mprocs3*/
/**       Revamped for MIPs including reincorporating Mabort and             */
/**       using the generic prefix target mapped via alias to the specific   */
/**       prefixes rs6,sparc,mips,88k88110 etc                               */
/* 30Sep92                                                              mprocs2.6*/
/**           Provides support for Ebrac (sdb-dbx inner blocks)              */
/**           Also supports C floats as parameter when these differ          */
/**           from normal real values (as on RS6000)                         */
/* 03Aug92                                                              mprocs2.5*/
/*        Additional code to restrict the procref descriptor coding          */
/*        to RS6000 only and provide the old code for other targets          */
/* 11Jun92                                                              mprocs2.4*/
/*       Introduces code regions to assist the BEO remove rendundant instrns */
/* 03Jun92                                             mprocs2.3.i           */
/**           Changes to exdata and Mgetprockey to distinguish integernal and external*/
/**           procs. This was formerly done by having no names for internals but when*/
/*            names were added for SDB & DBX ambiguities were introduced. These bit*/
/**           me in the bum when trying to do AIX linkage with descriptors, glue code*/
/**           and TOCs. All internal procs must be introduced with Enextproc which*/
/**           sets a new bit (2**2) in Exdata_Flags.                         */
/***/
/** 15May92                                               mprocs2.2.i        */
/**          Adjusts parameter if the fn returns an aggregate                */
/**                                                               mprocs42   */
/** 25 Sep 91 .Removed the instruction, fragment and label handling          */
/**            routines and relocated them to the bprocs module. The bprocs  */
/**            module is a generic back-end optimiser that is designed to    */
/**            operate with all code generators, including non EMachine 4. The*/
/**            generic backend optimiser operates using the instruction and  */
/**            fragment chains poineered on EMachine 4. Thus chain handling is*/
/**            no longer specific to EMachine 4 and is therefore no longer   */
/**            sited in this EMachine 4 specific module. The following routines*/
/**            were moved and renamed to start with the bprocs module naming */
/**            prefix:                                                       */
/***/
/**               M labrecad      ---> B labrecad                            */
/**               M locate label  ---> B locate label                        */
/**               M new instr     ---> B new instr                           */
/**               M delete instr  ---> B delete instr                        */
/**               M insert instr  ---> B insert instr                        */
/**               M append instr  ---> B append instr                        */
/**               M curinstraddr  ---> B curinstraddr                        */
/**               M curfraginstr  ---> B curfraginstr                        */
/**               newfrag         ---> B newfrag                             */
/**               M break frag    ---> B break frag                          */
/**               delete frags    ---> B delete frags                        */
/***/
/** 19/08/89  definitive version created                                     */
/***/
/**************************************************************************/
/**                                                                      **/
/**                 EPCL back end for RISC chips                         **/
/**                                                                      **/
/**************************************************************************/
/***/
/***/
#include "cgtarget.h"
/***/
#include "cgconsts.h"
/***/
#include "boconsts.h"
/***/
#include "archdefs.h"
/***/
#include "archspnames.h"
/***/
/***/
/***/
/**************************************************************************/
/**                                                                      **/
/**              Imports                                                 **/
/**                                                                      **/
/**************************************************************************/
/***/
extern int epermspace( int ,int );	/*user supplied*/
extern int etempspace( int ,int );	/*user supplied*/
/***/
#include "prototypes.h"

/***/

#if(Language==FORTRAN) 
/** New ENTRY variables for dwarf                                            */	/*SL update*/
struct entryfmt{
	char name[256];
	int lab;
	int labad;
	int codead;
};

#define MAXENTRYS 100	/*max no. of ENTRY statements for -g*/
static struct entryfmt EntryRecs [MAXENTRYS+1];
static int NumEntrys;	/*current number of ENTRYs found for a routine*/
/***/
#endif
/***/

/**************************************************************************/
/**                                                                      **/
/**                  Constant definitions                                **/
/**                                                                      **/
/**************************************************************************/
/***/
#define IMULT 3	/*03*/	/*  (Etos-1) * (Etos) => (Etos)   */
#define DISCARD 48	/*30*/	/* discard (Etos)                 */
#define CVTII 136	/*88*/	/* (int Etos-1) => int size(Etos) */
#define ESTORE 184	/*B8*/	/* ((Etos)) = (Etos-1)            */
#define PUSHVAL 186	/*BA*/	/* push (Etos) as value param     */
#define PUSHADDR 187	/*BB*/	/* push (Etos) as ref param       */
/***/
#define NO 0
#define YES 1
/***/
#define ubswrecheads 31
static int ubexrecheads=31;
#define ublabadheads 31
#define maxexrecheads (0xFFFF)
static int *exrecheads;
/***/
#define curmax 87
static char * Text [curmax] = {
/*00*/	"Mswitchjump fails to find switchid",
	"Mswitchentry fails to find switchid",
	"Mswitchlabel fails to find switchid",
	"Release reg pair fails to find regs",
	"Release reg fails to find regs",
	"Release freg pair fails to find regs",
	"Release freg fails to find regs",
	"Claim reg fails",
	"Claim freg fails",
	"Claim reg pair fails",
/*10*/	"Claim freg pair fails",
	"Load Int with size greater than target supports",
	"Attempt to index a constant or float",
	"Invalid attempt to Refer",
	"Invalid op to Int Unary Op",
	"Invalid op to Real Unary Op",
	"Stklimit exceeded",
	"Invalid reference to a leaf procedure",
	"Invalid op to Ccomparebytes",
	"Invalid use of CStackpf",
/*20*/	"Invalid use of CReferpf",
	"Mswtabad fails to find switchid",
	"Invalid op to Bit Op",
	"Load Int with float destination reg",
	"Load Int with real not of size 4",
	"Load Real with int destination reg",
	"Claim named tgt fails",
	"Load Real with int not of size 4",
	"CPushParam - only 1,2 or 4 byte int params supported",
	"CPushParam - cannot deal with complex parameters",
/*30*/	"StructVal/StringVal should be handled by CPushBytes",
	"CPushBytes - invalid parameter type",
	"CShift - illegal opcode",
	"CLoadRegvars: No Regvar storage area found",
	"Invalid Op in CX Operation",
	"Inconsistant sizes in ECSTORE",
	"Sparse switch table overflow",
	"Mparaminfo called too often",
	"Malloc Space: malloc() returned NULL",
	"Invalid instruction class",
/*40*/	"Invalid instruction variant",
	"Illegal use of FRAMEPOINTER",
	"Only 1,2 or 4 byte integer parameters supported",
	"COMPLEX parameters unsupported",
	"Bad form in StkAccess",
	"labrecheads table overflow",
	"labadheads table overflow",
	"swrecheads table overflow",
	"exrecheads table overflow",
	"malloc() failure - try recompiling without optimisation",
/*50*/	"Illegal attempt to release unpaired regs",
	"Illegally locked register",
	"Illegally locked register pair",
	"Illegally locked float register",
	"Unmatched source/target languages",
	"Illegal opcode in EJump",
	"Illegal stack duplication",
	"Illegal non-literal power",
	"Condition codes not set",
	"Illegal operation in GenInstructions",
/*60*/	"Illegal calling order in LogStk",
	"Erefer requires an operand",
	"Inconsistent E-stack",
	"Epsave requires an operand",
	"Evsave requires an operand",
	"Non-empty stack at Elabel",
	"Too many labels in Enewlab",
	"Label not found in Estmtlabel",
	"PUSHBYTES requires a literal operand",
	"Base must be positive for Epsave",
/*70*/	"ELogNeg requires an operand",
	"ELogStk requires an operand",
	"ECJump requires an operand",
	"FreeRegs unable to save locked register",
	"Negative PARAMS offset is illegal",
	"PUSHSTR not implemented",
	"ParI has not been set",
	"Invalid use of Perm-unlocking",
	"Invalid user of register $0",
	"Invalid CA handle provided",
/*80*/	"Exrecheads realloction malloc failed",
	"Odd register pair allocated",
	"Attempt to call illegal negative id",
	"Reassignment to Regvar already on Estack",
	"Use of unclaimed register varaible",
	"64-bit integer operands not supported for this operator",
	"Trampoline calls may not ne nested or recursive"

};
/***/
/***/
/**************************************************************************/
/**                                                                      **/
/**                  Global data                                         **/
/**                                                                      **/
/**************************************************************************/
/***/
extern struct Stkfmt Stk [Stklimit+1];
extern int Elevel;
extern int ModifyCC;
/***/
extern int GlobCodeReport;
/***/

/***/
static int swrecheads [ubswrecheads+1];
static int labadheads [ublabadheads+1];
/***/
static struct paramfmt ParamInfo [20+1];	/* 0 unused - 19 nested calls */

static struct paramfmt *ParI;
int calllevel;
static int *Parwords;
static int FreeParword;
int FirstDisplayLevel;
int MainFrameOffset=-1;
int UnkCntrlFlow;
int CheckOverflow=0;
/**/

/***/
static int report;
static int cgoptions;	/*as passed in by ftncomp or gccompile*/
#define CHKOFLOW (0x200000)	/* bit for soft overflow checks                  */
static int ProcNum;
static int setdbx;
static int setlineno;
static int diagnostics;
static int profile;
static int Lineprof;
static int primecodelisting;
static int FPUtraps;
static int paramchecks;
static int codelisting;
static int PLToffset;
extern int Pic;	/*0 => defaults/ 1 => call pic libs / >1 => generate pic*/
static int fixedca;
/***/
static int LinePrefixAddr;
static int LinePrefixIndex;
/***/
#define Firstuserexname 11
static int Numexnames;
static int Numswkeys;
static int Numareakeys;
static int Numconstrecs;
static int Numlabadkeys;
/***/
static int Nextlabtag;
static int Nextplabel;
int Labadjust;
#define INITLABTAG 250000
#define INITPLABEL 66000
/***/
int currentPIaddr;
static struct procfmt ProcInfo [19+1];
static struct procfmt *PI;	/* points to current ProcInfo entry */
/***/
static int UnassignedWords[2] ={UnassignedPattern,UnassignedPattern};
static int UnassignedDisp;	/*displacement in Gla of the unassigned pattern*/
/***/

#if(Target==PENTIUM) 
int Maxareakey;
static char ProfileName [8]="_mcount";	/* Pentium non standard here too!*/

#else
static char ProfileName [8]="mcount";

#endif
static int ProfileId=0;	/*Mprockey Id for ProfileName*/
static int bufaddr=0;
static int	/* Here for Mreinitialise to reset */ buftop=-1;
/***/
int GOTareaId=PLT;	/*Mprockey Id for GOTname*/
/*%OWNSTRING(20) GOTname = "GLOBAL_OFFSET_TABLE_"                            */
/***/
/**************************************************************************/
/**                                                                      **/
/**               Switch record management                               **/
/**                                                                      **/
/**************************************************************************/
/***/
static int swrecad(int index) {
	/****************************************************************/
	/** Provide the address of the switch record with given index  **/
	/****************************************************************/
	int Scale,I,J;
	Scale=3;
	I=(unsigned)index>>9;	/* units of 512 entries (4K bytes)                    */
	if (I>ubswrecheads)  Mabort(48);	/* swrecheads table overflow */
	J=swrecheads [I];
	if (J==0) {
		J=(int)BMalloc(4096,1,MASWRECADAREA);
		swrecheads [I]=J;
	}
	return J+((index&0x1FF)<<Scale);
}	/* swrecad  */
/***/
int Mswtabad(int Switchid) {
	/***********************************************************************/
	/**  return the address of the switch table record for Switchid              */
	/***********************************************************************/
	int i;
	struct Swrecfmt *swrec;

	for (i=Numswkeys; i>=1; i--) {
		swrec=(struct Swrecfmt*)(swrecad(i));
		if (swrec->key==Switchid)  return swrec->tab;
	}
	Mabort(22);
      return 0;
}	/*M swtabad*/
/***/
static void reclaimswspace(int oldkey) {
	/*************************************************************************/
	/** Free the space used by any switches in the current proc             **/
	/*************************************************************************/
	int i;
	struct Swrecfmt *swrec;

	for (i=Numswkeys; i>=oldkey+1; i--) {
		/* oldkey is last sw in prev proc                                            */
		swrec=(struct Swrecfmt*)(swrecad(i));
		BFree((void *)swrec->tab);
		memset(swrec,0,sizeof( struct Swrecfmt));
	}
	Numswkeys=oldkey;
}
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
/**************************************************************************/
/**                                                                      **/
/**               External proc record management                        **/
/**                                                                      **/
/**************************************************************************/
/***/
/***/
struct Exdatafmt *exrecad(int index) {
	/****************************************************************/
	/** Provide the address of the record for an external record   **/
	/** with given index                                           **/
	/****************************************************************/
	int I,J,oldsize,newsize,adr;
	I=(unsigned)index>>6;	/* units of 64 entries (64*Exdatasize bytes)          */
	if (I>ubexrecheads) {
		if ((I!=(ubexrecheads+1))||(I>=maxexrecheads))  Mabort(49);	/* exrecheads table overflow */
		/**/
		oldsize=4*(ubexrecheads+1);
		newsize=2*oldsize;
		if (report!=0) {
			printf(" Expand exrecheads from %d to %d entries\n",
				ubexrecheads+1,(unsigned)newsize>>2);	 
		}
		adr=(int)BMalloc(newsize,1,MAEXRECADAREA);
		if (adr==0)  Mabort(81);
		/**/
		memcpy( (void *)adr, &exrecheads [0],oldsize);
		memset( (void *)(adr+oldsize),0,newsize-oldsize);
		BFree((void *)&exrecheads [0]);
		exrecheads=((int *)(adr));
		ubexrecheads=((unsigned)newsize>>2)-1;
	}
	/**/
	J=exrecheads [I];
	if (J==0) {
		J=(int)BMalloc(64*Exdatasize,1,MAEXRECADAREA);
		exrecheads [I]=J;
		memset((void *)J,0,64*Exdatasize);
	}
	return (struct Exdatafmt *)(J+((index&0x3F)*Exdatasize));
}	/* exrecad */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
void TidyMcode(int Level,int *PLTsize) {
	*PLTsize=PLToffset;
}	/* Tidy Mcode */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
/***/
/**************************************************************************/
/**                                                                      **/
/**            switch processing                                         **/
/**                                                                      **/
/**************************************************************************/
/***/
/***/
int Mprivatelabel() {
	/****************************************************************/
	/** provide the next private label index                       **/
	/****************************************************************/
	int I;
	I=Nextplabel;
	Nextplabel++;
	return I;
}	/* Mprivatelabel */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
static void Switchdef(int Mode,int Lower,int Entries,int Switchid,int Errlab,int *Swtabad) {
	/****************************************************************/
	/** define a switch - mode is as follows:                      **/
	/**     1 - NO INDEX JUMP                                      **/
	/**     2 - INDEX JUMP     (to generate code to jump to the    **/
	/**                         switch label)                      **/
	/**     3 - SPARSE SWITCH  (for sparse switches)               **/
	/**                        (Entries actual label used)         **/
	/****************************************************************/
	int I,J;
	struct Swtabfmt *Tab;
	struct Swrecfmt *swrec;


#if((Language==FORTRAN)&&(LanguageVariant==FORTRAN77)) 
	Switchid+=Labadjust;
#endif
	Numswkeys++;
	swrec=(struct Swrecfmt*)(swrecad(Numswkeys));
	swrec->key=Switchid;
	if (Entries<=3)  Mode=SPARSESWITCH;
	if ((Target==PENTIUM)&&(Entries<=5))  Mode=SPARSESWITCH;
	if (Mode!=SPARSESWITCH) 	/* claim space for full table */{
		*Swtabad=(int)BMalloc((Entries*4)+swtabbasesize,1,MADENSESWITCHTABLE);
	} else {
		*Swtabad=(int)BMalloc((Entries*8)+swtabbasesize,1,MASPARSESWITCHTABLE);
	}
	Tab=(struct Swtabfmt*)(*Swtabad);
	swrec->tab=*Swtabad;
	Tab->Reffrag=(int)PI->curfrag;
	Tab->SlotsUsed=0;
	Tab->Mode=Mode;
	Tab->Lower=Lower;
	Tab->Labbase=Nextplabel;
	Tab->SwitchId=Switchid;
	/* we want to reserve as few labels as possible for the switch */
	Nextplabel=(Nextplabel+Entries)+1;
	Tab->Entries=Entries;
	if (Errlab>0) {
		J=BLocateLabel(Errlab+Labadjust,0);
		if (J<0)  J=-J;
	} else J=-1;
	if (Mode!=SPARSESWITCH) 	/* set up labels to jump to default */{
		for (I=0; I<=Entries-1; I++) {
			Tab->u0.R [I]=J;
		}
	}
	Tab->Rangelab=J;
}	/* Switchdef */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
void Mswitch(int Mode,int Lower,int Entries,int Switchid,int Errlab) {
	/****************************************************************/
	/** define a switch, and if Mode# 1 then generate the code to  **/
	/** jump to the switch label                                   **/
	/****************************************************************/
	int Swtabad;

	/*********************************************************/
	/*     define the switch                                **/
	/*********************************************************/
	/**/
	Switchdef(Mode,Lower,Entries,Switchid,Errlab,&Swtabad);

	/*********************************************************/
	/*     generate the index-checking and jumping code     **/
	/*********************************************************/
	/**/
	Cswitch(Switchid,Swtabad);
}	/* Mswitch  */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
void Mfswitch(int Lower,int Entries,int Switchid,int Errlab,struct Stkfmt *Stk) {
	/****************************************************************/
	/** define a switch, load (ETOS), perform optional range       **/
	/** checking, and generate code to jump to the switch label.   **/
	/** Negative entries mean use SPARSE variant.                  **/
	/** On most machines SPARSE is faster for up to 3 labels as    **/
	/** Range check is had for free.                               **/
	/****************************************************************/
	int Swtabad;

	/*********************************************************/
	/*     define the switch                                **/
	/*********************************************************/
	/**/
	if (Entries<=3) {
		Switchdef(SPARSESWITCH,Lower,abs(Entries),Switchid,Errlab,&Swtabad);
	} else {
		Switchdef(NOINDEXJUMP,Lower,Entries,Switchid,Errlab,&Swtabad);
	}

	/*********************************************************/
	/*     generate the index-checking                      **/
	/*********************************************************/
	/**/
	Cswitchjump(Switchid,Swtabad,Stk);

	/*********************************************************/
	/*     generate the switch jump                         **/
	/*********************************************************/
	/**/
	Cswitch(Switchid,Swtabad);

}	/* Mfswitch  */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
void Mswitchjump(int Switchid,struct Stkfmt *Stk) {
	/****************************************************************/
	/** transfer to switch code with given index                   **/
	/****************************************************************/
	struct Swrecfmt *swrec;
	int I;

	for (I=1; I<=Numswkeys; I++) {
		swrec=(struct Swrecfmt*)(swrecad(I));
		if (swrec->key==Switchid) {
			Cswitchjump(Switchid,swrec->tab,Stk);
			return ;
		}
	}
	Mabort(1);	/*Mswitchjump fails to find switchid*/

}	/* Mswitchjump */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
static void DumpSwitchTable(struct Swtabfmt *Tab) {
	int i,used,Mode;
	Mode=Tab->Mode;
	if (Mode==SPARSESWITCH) {
		used=Tab->SlotsUsed-1;
		for (i=0; i<=used; i++) {
			printf("%d : Entry = %d, label = %d\n/",i,Tab->u0.S [i].Entry,Tab->u0.S [i].Label);
		}
	}
}	/* routine DumpSwitchTable */
/***/
/**/
/* Copyright (c) 1990 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
void Mswitchentry(int Switchid,int Entry) {
	/****************************************************************/
	/** define the current point as a switch label                 **/
	/****************************************************************/
	struct Swrecfmt *swrec;
	int I,lrecndx,Index;
	struct lrecfmt *lrec;
	struct Swtabfmt *Tab;
	struct fragfmt *f;
	Index=Entry;
	for (I=1; I<=Numswkeys; I++) {
		swrec=(struct Swrecfmt*)(swrecad(I));
		if (swrec->key==Switchid) {
			Tab=(struct Swtabfmt*)(swrec->tab);
			if (report!=0)  DumpSwitchTable(Tab);
			if (Tab->Mode!=SPARSESWITCH) {

				Entry-=Tab->Lower;

				/* sparse switches check if already given as default */
			} else {
				Entry=-1;
				for (I=0; I<=Tab->SlotsUsed-1; I++) {
					if (Tab->u0.S [I].Entry==Index) {
						Entry=I;  
						break ;
					}
				}
				if (Entry==-1) {
					Entry=Tab->SlotsUsed;
					Tab->SlotsUsed=Tab->SlotsUsed+1;
				}
			}
			lrecndx=BLocateLabel(((Tab->Labbase+Entry)+1)+Labadjust,0);
			lrec=BLabRecAd(lrecndx);
			if (lrec->frag!=NULL) {
				f=lrec->frag;		/* forget previous definition of */
				f->labindex=NULL;	/* this switch entry             */
				lrec->frag=NULL;
			}
			Mlabel((Tab->Labbase+Entry)+1);
			if (Tab->Mode==SPARSESWITCH) {
				/* for a sparse switch we build a table of constant/label pairs */
				/* and then later use these to plant a series of IF THEN GOTOs  */
				Tab->u0.S [Entry].Entry=Index;	/* X in case X: */
				Tab->u0.S [Entry].Label=((Tab->Labbase+Entry)+1)+Labadjust;
				/* non-sparse table */
			} else {
				Tab->u0.R [Entry]=lrecndx;
			}
			return ;
		}
	}
	Mabort(2);
}	/* Mswitchentry*/
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
void Mswitchlabel(int Switchid,int Entry,int Labelid) {
	/****************************************************************/
	/** define the switch entry as the nominated label             **/
	/****************************************************************/
	struct Swrecfmt *swrec;
	int I,J;
	struct Swtabfmt *Tab;

#if((Language==FORTRAN)&&(LanguageVariant==FORTRAN77)) 
	Switchid+=Labadjust;
#endif
	for (I=1; I<=Numswkeys; I++) {
		swrec=(struct Swrecfmt*)(swrecad(I));
		if (swrec->key==Switchid) {
			Tab=(struct Swtabfmt*)(swrec->tab);
			if (Tab->Mode==SPARSESWITCH) {
				J=Tab->SlotsUsed;
				Tab->SlotsUsed=Tab->SlotsUsed+1;
				Tab->u0.S [J].Entry=Entry;
				Tab->u0.S [J].Label=Labelid+Labadjust;
			} else {
				if (Entry<Tab->Lower) {
					/* do unsigned subtract */
					Entry=(Entry&0x7FFFFFFF)-Tab->Lower;
					if (Entry<0)  Entry&=0x7FFFFFFF;
				} else {
					Entry-=Tab->Lower;
				}
				Tab->u0.R [Entry]=BLocateLabel(Labelid+Labadjust,0);
			}
			return ;
		}
	}
	Mabort(3);
}	/* Mswitchlabel  */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
/***/
/**************************************************************************/
/**                                                                      **/
/**            label and line number processing                          **/
/**                                                                      **/
/**************************************************************************/
/***/
/***/
void Mlabel(int label) {
	/****************************************************************/
	/** define the current point as the nominated label            **/
	/****************************************************************/
	struct fragfmt *Frag;

	Frag=PI->curfrag;
	if ((Frag->labindex!=0)||(PI->fragsize!=0))  BBreakFrag(0);
	Frag=PI->curfrag;
	Frag->labindex=BLocateLabel(label+Labadjust,1);
	/**/
	rclearregs(1);	/* update register memory */
}	/* Mlabel  */
/***/
void Mgloballabel(int Label) {
	/*************************************************************************/
	/**  define the current point as the nominated global label Ie one      **/
	/**  that can be reached by out of block jump or exception              **/
	struct fragfmt *Frag;

	Frag=PI->curfrag;
	if ((Frag->labindex!=0)||(PI->fragsize!=0))  BBreakFrag(0);
	Frag=PI->curfrag;
	Frag->labindex=BLocateLabel(Label+Labadjust,1);
	Frag->props|=GLOBALLABFRAG;
	/**/
	rclearregs(1);	/* update register memory */
}	/* Mgloballabel  */
/*************************************************************************/
/***/
void Mfrlabel(int label,int count) {
	/****************************************************************/
	/** define the current point as the nominated label            **/
	/** as Mlabel but only used for "count" forward refs           **/
	/** consequently may not have to discard 100 of register      **/
	/** tracking information                                       **/
	/****************************************************************/
	struct fragfmt *Frag,*LFrag;
	struct lrecfmt *lrec;
	int index;

	Frag=PI->curfrag;
	if ((Frag->labindex!=0)||(PI->fragsize!=0))  BBreakFrag(0);
	Frag=PI->curfrag;
	index=BLocateLabel(label+Labadjust,1);
	Frag->labindex=index;
	lrec=BLabRecAd(index);
	/**/
	/*RT   %IF Language # CCOMP %OR LanguageVariant # USLC %THENSTART            */
	if (count<=0) {
		count=0;	 
		LFrag=lrec->freffrag;
		while ((int)LFrag!=0) {
			if (index==LFrag->labref)  count++;
			LFrag=(struct fragfmt*)(LFrag->nextfrag);
		}
	}
	/*RT   %FINISH                                                               */
	/**/
	if (((Language!=CCOMP)||(LanguageVariant!=USLC))&&(count==0))  return ;	/* never referenced*/
	/* The above restriction is due to a bug in USLC which has been fixed        */
	/* on some platforms. There are code advantages in restoring this line       */
	/* if working with a corrected C front end                                   */

	if ((count>0)&&(count<3)) {

#if((Target==RS6)||(Target==MIPS)||(Target==SPARC)||(Target==PENTIUM)) 
		ARCH(frlabel(Frag->labindex,count,(int)PI->curfrag));
		return ;
#endif
	}
	/**/
	/*if no target dependent routine provided clear all register tracking        */
	/**/
	rclearregs(1);	/* update register memory */
}	/* Mfrlabel  */
/***/
void MonetimeLabel(int label) {
	/*************************************************************************/
	/** Here is a label that the Front End warrants is used only once       **/
	/** If it is a forward ref do an Mfrlabel else Mlabel                   **/
	/*************************************************************************/
	struct fragfmt *Frag;
	struct lrecfmt *lrec;
	int index;
	Frag=PI->curfrag;
	if ((Frag->labindex!=0)||(PI->fragsize!=0))  BBreakFrag(0);
	Frag=PI->curfrag;
	index=BLocateLabel(label+Labadjust,1);
	Frag->labindex=index;
	lrec=BLabRecAd(index);

	if (lrec->freffrag!=PI->curfrag) {
		ARCH(frlabel(Frag->labindex,1,(int)PI->curfrag));
	} else {
		rclearregs(1);	/* update register memory  lose all tracking*/
	}
}	/*Monetimelabel*/
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
static int labadad(int index) {
	/****************************************************************/
	/** Provide the address of the label reference record with     **/
	/** given index                                                **/
	/****************************************************************/
	int Scale,I,J;
	Scale=16;
	I=(unsigned)index>>6;	/* units of 64 entries (1024 bytes)                   */
	if (I>ublabadheads)  Mabort(47);	/* labadheads table overflow */
	J=labadheads [I];
	if (J==0) {
		J=(int)BMalloc(1024,1,MALABADADAREA);
		labadheads [I]=J;
	}
	return J+((index&0x3F)*Scale);
}	/* labadad */
/***/
/**/
/* Copyright (c) 1991 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
void Maddrlabel(int label,int area,int offset) {
	/****************************************************************/
	/** note a location to be fixed up with a label address        **/
	/****************************************************************/
	struct labadfmt *labad;
	Numlabadkeys++;
	labad=(struct labadfmt*)(labadad(Numlabadkeys));
	labad->labkey=BLocateLabel(label+Labadjust,0);
	labad->area=area;
	labad->offset=offset;
	labad->reffrag=(int)PI->curfrag;
}	/* Maddrlabel  */
/***/
int Maddressedlabel(int labkey) {
	/****************************************************************/
	/** Return 1 if labkey refers to a label which has had its                   */
	/** address taken, else return 0.                                            */
	/****************************************************************/
	struct labadfmt *labad;
	int i;

	if (Numlabadkeys>0) {
		for (i=1; i<=Numlabadkeys; i++) {
			labad=(struct labadfmt*)(labadad(i));
			if (labad->labkey==labkey)  return 1;
		}
	}

	return 0;

}	/* M addressed label */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
void Mplabel(int label) {
	/****************************************************************/
	/** define the current point as the nominated private label    **/
	/** this is used only when no register memory can be affected  **/
	/****************************************************************/
	struct fragfmt *Frag;

	Frag=PI->curfrag;
	if ((Frag->labindex!=0)||(PI->fragsize!=0))  BBreakFrag(0);
	Frag=PI->curfrag;
	Frag->labindex=BLocateLabel(label+Labadjust,1);
}	/* Mplabel */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
void Mline(int lineno,int prefix) {
	/****************************************************************/
	/** note that the current point is the start of nominated line **/
	/****************************************************************/
	struct instrfmt *instr;

	if (lineno!=0) {
		codelisting=primecodelisting;	/*if IMP switch on after preamble*/
		instr=BNewInstr();
		instr->group=LINENUMBER;
		instr->u1.immval=lineno;
		instr->u0.offset=prefix;
		/**/
		if ((PI->proclevel>0)&&(setlineno!=0)) {
			estklit(lineno);
			estkdir(STACK,PI->markerad-12,0,4);
			eop(ESTORE);
		}
		/**/
	}
}	/* Mline */
/***/
/**/
/* Copyright (c) 1993 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
void MPrintLine(int line,int prefix) {
	/****************************************************************/
	/** Prints the given line number with the given line prefix    **/
	/****************************************************************/
	CPrintLine(line,prefix);
}	/*MPrintLine*/
/***/
/**/
/* Copyright (c) 1993 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
int MAddLinePrefix(int line,int prefix) {
	/****************************************************************/
	/** Creates a new line prefix out of the given line number and **/
	/** an existing prefix. Returns the address of the prefix      **/
	/** record.                                                    **/
	/****************************************************************/
	struct LinePrefixFmt *LinePrefix;

	if ((LinePrefixAddr==0)||((LinePrefixIndex+SIZELINEPREFIXFMT)>SIZELINEPREFIXCHUNK)) {
		LinePrefixAddr=(int)BMalloc(SIZELINEPREFIXCHUNK,1,MALINEPREFIXES);
		LinePrefixIndex=0;
	}
	LinePrefix=(struct LinePrefixFmt*)(LinePrefixAddr+LinePrefixIndex);
	LinePrefix->line=line;
	LinePrefix->parent=prefix;
	LinePrefixIndex+=SIZELINEPREFIXFMT;
	return (int)LinePrefix;
}	/* MAddLinePrefix  */
/***/
/**/
/* Copyright (c) 1993 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
void Mlinedebug(int Lineno) {
	/********************************************************************/
	/** note that the nominated line requires debugging info generated **/
	/********************************************************************/
	struct instrfmt *instr;

	if (Lineno!=0) {
		instr=BNewInstr();
		instr->group=LINEDEBUG;
		instr->u1.immval=Lineno;
	}
}	/*Mlinedebug*/
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
/***/
/**************************************************************************/
/**                                                                      **/
/**            code fragment processing                                  **/
/**                                                                      **/
/**************************************************************************/
/***/
/***/
static void tidyfrags(int proclevel,int procfrag) {
	/****************************************************************/
	/** process all the fragments for the current procedure and    **/
	/** generate the code and fixups as requested                  **/
	/****************************************************************/
	static int procbaseca;
	struct fragfmt *frag;
	struct Swtabfmt *Tab;
	int K,passes,nextfrag;

	if (PI->fragsize!=0)  BBreakFrag(0);
	passes=0;

#if(Target==MIPS) 
	if (fixedca==0)  ARCH(abiinit(&fixedca));	/* put ABI specific marker at head of code */
#endif
	Cprocessproc();
	/***/
	/** extra pass - procedure peephole optimisations and scheduling             */
	/***/
	COptimiseProc();
	/***/
	/** update the procedure descriptor with the new frame size - this may have been*/
	/** altered by the optimisations                                             */
	/***/
	PI->framesize=(PARAMBASE+PI->saveareasize)+PI->localsize;

#if(Target!=PENTIUM) 
	/* outgoing parameters pushed on stack so not included in stack */
	/* frame size on pentium                                        */
	PI->framesize=PI->framesize+PI->outparsize;
#endif
	PI->framesize=(PI->framesize+7)&(-8);
	if ((Target==RS6)) {
		PI->framesize=(PI->framesize+15)&(-16);
	}
	PI->ffsize=PARAMBASE+PI->saveareasize;

#if(Target!=PENTIUM) 
	/* outgoing parameters pushed on stack so not included in stack */
	/* frame size on pentium                                        */
	PI->ffsize=PI->ffsize+PI->outparsize;
#endif
	PI->ffsize=(PI->ffsize+7)&(-8);

#if((Target==RS6)&&(TargetABI==SunsoftABI)) 
	if (proclevel>0)  CgenerateTBT(&fixedca,codelisting);	/* o-p IBM traceback table*/
#endif
	procbaseca=fixedca;
	/***/
	/** first pass - fixing all label addresses                                  */
	/***/
again:

	nextfrag=procfrag;	/*first fragment for this procedure*/
	while (nextfrag!=0) {
		frag=(struct fragfmt*)(nextfrag);
		nextfrag=(int)frag->nextfrag;

#if(Target==MIPS) 
		if (passes==0)  eliminatehazards(frag);
#endif
		Cestablishca(frag,&fixedca	/*updating fixedca*/);
		/**/
		/* if switch tables go into text segment allow the space                     */
		/**/
		if ((Target!=MIPS)&&(frag->switchtab!=0)) {
			Tab=(struct Swtabfmt*)(frag->switchtab);
			if (Tab->Mode!=SPARSESWITCH) {
				fixedca=((fixedca+(Tab->Entries<<2))+3)&(-4);	/*word align*/
			}
		}
	}
	/***/
	/** extra pass for targets with short jumps check all jumps will reach       */
	/***/
	K=0;
	nextfrag=procfrag;
	while (nextfrag!=0) {
		frag=(struct fragfmt*)(nextfrag);
		nextfrag=(int)frag->nextfrag;
		K+=Cvalidatejumps(frag);
	}
	if (K>0) {
		/* some jumps have been expanded                                             */
		fixedca=procbaseca;	/* Must reestablish address and check again             */
		passes++;	 
		goto again;
	}
	/***/
	/** second pass - fill in all the jumps and request fixups                   */
	/***/
	/***/
	nextfrag=procfrag;	/*first fragment for this procedure*/
	while (nextfrag!=0) {
		frag=(struct fragfmt*)(nextfrag);
		nextfrag=(int)frag->nextfrag;

#if((Target==SPARC)||(OutputASSEMBLER==Negative)) 
		Cgeneratefrag(frag);
#endif
		if (((Target!=SPARC)&&(OutputASSEMBLER==Positive))||(codelisting!=0)) {
			Cdisasfrag(frag);
		}
	}

#if(Target==RS6) 
	if (((TargetABI==AIXABI)||(TargetABI==ADIABI))&&(proclevel>0))  CgenerateTBT(&fixedca,codelisting);	/* 
	o-p IBM traceback table                                                      */
#endif

#if(Language==FORTRAN) 
	if ((Target==MIPS)&&(setdbx!=0)) 	/*SL update*/{
		struct lrecfmt *Lrec;
		int lindex,I;
		for (I=1; I<=NumEntrys; I++) {
			lindex=BLocateLabel(EntryRecs [I].lab+Labadjust,0);
			Lrec=BLabRecAd(lindex);	/*label record for jump back*/
			EntryRecs [I].labad=Lrec->frag->address;
		}
		NumEntrys=0;
	};

#endif
	/***/
	/** reclaim fragment and instruction record space                            */
	/***/
	BFreeAllocation();

}	/* tidy frags  */
/***/
int MGetProcOffset(int Id) {
	struct Exdatafmt *Exdata;

#if(!((OutputASSEMBLER==Positive)&&(Language==CCOMP))) 
	Exdata=exrecad(Id);
	if (Exdata->PutId==0) {

		Exdata->PutId=pxname(Exdata->flags,Exdata->Name);
	}
	return Exdata->PutId;
#endif
}	/* MGetProcOffset  */
/***/
void MEndProcs() {
	/******************************************************************/
	/** Generates code for any outstanding level 0 instructions - no **/
	/** further code should be generated after this call             **/
	/******************************************************************/
	struct fragfmt *Level0;
	int PIaddr,rangeproc;

	Level0=(struct fragfmt*)(ProcInfo [0].procfrag);
	if (((int)Level0!=0)&&(Level0->firstinstr!=0)) {
		PI=&ProcInfo [0];
		PIaddr=(int)&ProcInfo [0];
		currentPIaddr=PIaddr;
		CsetPI(PI);
		BSetPI(PIaddr);
		rangeproc=BGetTraceProc();
		if ((rangeproc==0)||(rangeproc==PI->procnum)) {
			Creport(GlobCodeReport);
		} else {
			Creport(0);
		}
		tidyfrags(0,(int)ProcInfo [0].procfrag);
		ProcInfo [0].procfrag=0;
		ProcInfo [0].curfrag=0;
	}
}	/* MEndProcs */
/***/
void Mtidyend(int *codesize) {
	/****************************************************************/
	/** Generate fixups for referenced procedures                  **/
	/** Set codesize                                               **/
	/****************************************************************/
	struct fragfmt *labelfrag,*Level0;
	struct Exdatafmt *Exdata,*Exfix;
	struct labadfmt *labad;
	struct lrecfmt *Lrec;
	int I,PIaddr,rangeproc;

	/* generate any code passed in level 0 after the last Eprocend */
	Level0=(struct fragfmt*)(ProcInfo [0].procfrag);
	if (((int)Level0!=0)&&(Level0->firstinstr!=0)) {
		PI=&ProcInfo [0];
		PIaddr=(int)&ProcInfo [0];
		currentPIaddr=PIaddr;
		CsetPI(PI);
		BSetPI(PIaddr);
		rangeproc=BGetTraceProc();
		if ((rangeproc==0)||(rangeproc==PI->procnum)) {
			Creport(GlobCodeReport);
		} else {
			Creport(0);
		}
		tidyfrags(0,(int)ProcInfo [0].procfrag);
	}
	*codesize=fixedca;
	/***/

#if(!((OutputASSEMBLER==Positive)&&(Language==CCOMP))) 
	for (I=Firstuserexname; I<=Numexnames; I++) {
		Exfix=exrecad(I);
		Exdata=Exfix;
		if (Exfix->backlink!=0)  Exdata=exrecad(Exfix->backlink);
		/**/
		/* If the symbol not defined to put and not defined by use (ca set)          */
		/* then define it as an external symbol                                      */
		/**/
		if ((Exdata->PutId==0)&&
			((Language==FORTRAN)||((Exdata->Props&0x100)!=0)||
			(Exdata->Refad!=0)||(Exdata->Desrefad!=0)||(Exfix->backlink!=0))) {
			/* Avoid putting a redundant symbol into symtable */

			Exdata->PutId=pxname(Exdata->flags,Exdata->Name);
		}
		if (Exfix->Refad!=0) {
			if (Exdata->Ca>0) {
				pfix2(Exfix->Area,Exfix->Refad,CODE,Exdata->Ca,0);
			} else {
				pfix2(Exfix->Area,Exfix->Refad,Exdata->PutId,0,0);
			}
		}
		/**/
		/* the next block is not required unless descriptors are used for formal procedures*/
		/**/
		if ((Target==RS6)&&(Exfix->Desrefad!=0)) {
			if (Exdata->DesId==0) {

				Exdata->DesId=pxname(1,Exdata->Name);	/* no dot              */
				pfix2(GLA,Exfix->Desrefad,Exdata->DesId,0,0);
			}
		}
	};

#endif
	/***/
	/***/
	/** Output any special symbols required                                      */
	/***/

#if(Target==RS6) 
	ARCH(outspecialsyms());
#endif
	/***/
	/***/
	/** fix up any label addresses                                               */
	/***/
	/***/
#if (OutputASSEMBLER!=Positive || Language!=CCOMP)
	if (Numlabadkeys>0) {
		for (I=1; I<=Numlabadkeys; I++) {
			labad=(struct labadfmt*)(labadad(I));
			Lrec=BLabRecAd(labad->labkey);

			/* check if dummy to prevent optimisation */
			if (!((labad->area==0)&&(labad->offset==0))) {
				labelfrag=Lrec->frag;
				pd4(labad->area,labad->offset,0);
				pfix2(labad->area,labad->offset,1,labelfrag->address,0);
			}

		}
	}
#endif

}	/* Mtidyend  */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
/***/
/**************************************************************************/
/**                                                                      **/
/**            setmarker support                                         **/
/**                                                                      **/
/**************************************************************************/
/***/
/***/
struct instrfmt *Mmarker() {
	/****************************************************************/
	/** note the current instruction to relate subsequent call of  **/
	/** msetopd                                                    **/
	/****************************************************************/
	struct instrfmt *instr;
	instr=BNewInstr();
	instr->group=MARKER;
	return instr;
}	/* Mmarker */
/***/
int Mbrac(int type,int privateinfo) {
	/*************************************************************************/
	/** Puts a private marker in the code for updating sdb-dbx tables       **/
	/*************************************************************************/
	struct instrfmt *instr;
	instr=BNewInstr();
	instr->opcode=type;
	instr->group=DBXINFO;
	instr->u1.immval=privateinfo;
	return (int)instr;
}	/* Mbrac */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
int Mnotecodefix(int area,int offset,int toffset) {
	/*************************************************************************/
	/** Put a marker into code so as to be able to fix area & offset        **/
	/** to point to current address + toffset                               **/
	/*************************************************************************/
	struct instrfmt *instr;
	instr=BNewInstr();
	instr->area=area;
	instr->u0.offset=offset;
	instr->u1.immval=toffset;
	instr->group=FIXUPPOINT;
	return (int)instr;
}	/* Mnotecodefix  */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
void Msetopd(struct instrfmt *Markerinstr,int NewValue) {
	/****************************************************************/
	/** substitute or add the new value for the lit in the         **/
	/** instruction following markerid.                            **/
	/** If the procedure has side entries their must be a chain of **/
	/** markers linked by _immval. Other _immval must be zero.     **/
	/****************************************************************/
	struct instrfmt *instr;
	int origval,nextid,Markerid;

	Markerid=(int)Markerinstr;
	if (Markerid<0)  {
		printf("Dangerous and unsupported Code Gen Facility called \n");
		Markerinstr=(struct instrfmt*)(-Markerid);
	}
	instr=Markerinstr;
	nextid=instr->u1.immval;
	origval=NewValue;	/* save for chain */
	if (instr->group!=MARKER)  Mabort(999);
	instr=instr->nextinstr;

#if(Target==SPARC) 
	if (instr->opcode==SETHI) {
		struct instrfmt *nextinstr;
		/**/
		nextinstr=instr->nextinstr;
		if (Markerid<0) {
			/* add to existing                                                           */
			NewValue=(NewValue+(instr->u1.immval<<10))+nextinstr->u1.immval;
		}
		/**/
		if ((-4096<=NewValue)&&(NewValue<=4095)) {
			nextinstr->u1.immval=NewValue;
			nextinstr->rs1=0;	/*%g0*/
			BDeleteInstr(instr,1);
		} else {
			instr->u1.immval=(unsigned)NewValue>>10;
			if ((NewValue&0x3FF)==0)  BDeleteInstr(nextinstr,1); 
			else nextinstr->u1.immval=NewValue&0x3FF;
			;
		}
		BDeleteInstr(Markerinstr,1);	 
		if (nextid!=0)  Msetopd((struct instrfmt *)nextid,origval);
		return;
	}
	if (instr->opcode==SAVE) {
		/* default instructions are: */
		/*  sethi %hi(0), %g2        */
		/*  or        %g2, 0, %g2    */
		/*  marker                   */
		/*  save  %sp, %g2, %sp      */
		if (NewValue<-4096) {
			instr=instr->previnstr;	/* marker */
			instr=instr->previnstr;	/* or     */
			instr=instr->previnstr;	/* sethi  */
			instr->u1.immval=(unsigned)NewValue>>10;
			NewValue&=0x3FF;
			if (NewValue==0)  BDeleteInstr(instr->nextinstr,1); 
			else {
				instr=instr->nextinstr;
				instr->u1.immval=NewValue;
			}
			BDeleteInstr(instr->nextinstr,1)	/* throw marker away */;
		} else {
			BDeleteInstr(instr->previnstr,1)	/* throw marker away */;
			BDeleteInstr(instr->previnstr,1)	/* throw or     away */;
			BDeleteInstr(instr->previnstr,1)	/* throw sethi  away */;
			instr->variant=REGOPIMM;	/* convert to immed. */
			instr->u1.immval=NewValue;	/* and plug          */
			instr->rref=(1<<STACKPOINTER)|0xFFFFFF00;
		}
		if (nextid!=0)  Msetopd((struct instrfmt *)nextid,origval);
		return;
	};
	/* Target=sparc*/

#endif


#if(Target==RS6) 
	if (instr->opcode==cau) {
		struct instrfmt *nextinstr;
		/**/
		/* rs6000 32 bit operand as used to claim stack frames                       */
		/* cut down to immval if possible                                            */
		/**/
		nextinstr=instr->nextinstr;
		if (Markerid<0)  NewValue+=(instr->u1.immval<<16)|nextinstr->u1.immval;
		/**/
		if ((-32768<=NewValue)&&(NewValue<=32767)) {
			BDeleteInstr(instr,1);	/*throw away cau                                */
			nextinstr->opcode=cal;	 
			nextinstr->u1.immval=NewValue;
			nextinstr->rs1=0;	/* may not have been correc*/
			nextinstr->group=10;
			instr=(struct instrfmt*)(nextinstr->nextinstr);
			if (instr->opcode==stux) {
				BDeleteInstr(nextinstr,1);	/*throw away cal                            */
				instr->opcode=stu;	/*change to immediate form                               */
				instr->u1.immval=NewValue;
				instr->rdef=1<<instr->rs1;
				instr->rref=(1<<instr->rs1)|(1<<instr->rd);
			}
		} else {
			instr->u1.immval=(unsigned)NewValue>>16;
			nextinstr->u1.immval=NewValue&0xFFFF;
		}
		BDeleteInstr(Markerinstr,1);	 
		if (nextid!=0)  Msetopd((struct instrfmt *)nextid,origval);
		return;
	};
	/* Traget=rs6000*/

#endif

#if(Target==MIPS) 
	if (instr->opcode==lui) {
		struct instrfmt *nextinstr;
		/**/
		/* MIPS 32 stack frame claim is used cut down if possible                    */
		/**/
		nextinstr=instr->nextinstr;
		if (Markerid<0)  NewValue+=(instr->u1.immval<<16)|nextinstr->u1.immval;
		/**/
		if ((-32768<=NewValue)&&(NewValue<=32767)) {
			BDeleteInstr(instr,1);	/*throw away lui  */
			struct instrfmt *instr;
			nextinstr->opcode=addi;	 
			nextinstr->u1.immval=NewValue;
			nextinstr->rs1=0;	/* may not have been correct*/
			nextinstr->group=6;
			instr=(struct instrfmt*)(nextinstr->nextinstr);
			if (instr->opcode==add) {
				BDeleteInstr(nextinstr,1);	/*throw away cal                            */
				instr->opcode=addiu;	/*change to immediate form                             */
				instr->group=INTOPSu;
				instr->u1.immval=NewValue;
				instr->rdef=1<<instr->rs1;
				instr->rref=(1<<instr->rs1)|(1<<instr->rd);
			}
		} else {
			instr->u1.immval=(unsigned)NewValue>>16;
			nextinstr->u1.immval=NewValue&0xFFFF;
		}
		BDeleteInstr(Markerinstr,1);	 
		if (nextid!=0)  Msetopd((struct instrfmt *)nextid,origval);
		return;
	};
	/* Target = mips */

#endif
	/**/
	if (Markerid<0) {
		/* add to existing                                                           */
		instr->u1.immval=instr->u1.immval+NewValue;
	} else {
		instr->u1.immval=NewValue;
	}
	BDeleteInstr(Markerinstr,1);

	if (nextid!=0)  Msetopd((struct instrfmt *)nextid,origval);
}	/* Msetopd */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
/***/
/**************************************************************************/
/**                                                                      **/
/**            procedure administration                                  **/
/**                                                                      **/
/**************************************************************************/
/***/
/***/
int Mgetuniqueprockey(char * S,int area,int offset,int Id) {
	/****************************************************************/
	/** Set up a unique fixup to proc with name S                  **/
	/** It has to be unique because int *fn() = fred can be        **/
	/** re-assigned later in the program.                          **/
	/** However the proc is not unique and its name may be Known   **/
	/** Id > 0. Return the Id (exrecad index) given or created     **/
	/****************************************************************/
	struct Exdatafmt *Exdata;
	Numexnames++;
	Exdata=exrecad(Numexnames);
	memset(Exdata,0,sizeof( struct Exdatafmt));
	strcpy(Exdata->Name,S);
	Exdata->Refad=offset;
	Exdata->Area=area;
	Exdata->Ca=-1;	/*will be >=0 when entry address is known*/
	Exdata->Props=0x100;	/* means do not re-use */
	if (Id<0)  Id=Numexnames; 
	else Exdata->backlink=Id;
	return Id;
}	/* Mgetuniqueprockey */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
int Mgetprockey(int Flags,char * S) {
	/****************************************************************/
	/** S # ""  return a unique index, possibly already assigned,  **/
	/**         through which to reference this external procedure **/
	/**   = ""  providing a key in advance for an internal proc    **/
	/**                                                            **/
	/** Flags = 0 if S is allowed to be subsequently modified in   **/
	/**           accordance with normal UNIX naming conventions   **/
	/** Flags = 1 if S may not be changed (by PUT or anyone else)  **/
	/** Flags&2 must be zero nonzero means a data xref(AIX)        **/
	/** Flags&4 set if internal                                    **/
	/** Flags&8 set if symbol has no self aliases                  **/
	/** Flags&16 set if symbol is refernced in call on AIX         **/
	/** Flags&32 set if symbol is an entry point                   **/
	/** Flags&64 set if symbol is data item requiring a TOC entry  **/
	/** Flags&128 set if proc has no GOT refs in PIC               **/
	/** Flags&256 set if proc has been entered after GOT setup     **/
	/****************************************************************/
	struct Exdatafmt *Exdata;
	int I;
	if ((Numexnames>0)&&(strcmp(S,"")!=0)&&((Flags&4)==0)) 	/*not internal*/{
		for (I=1; I<=Numexnames; I++) {
			Exdata=exrecad(I);
			if ((strcmp(Exdata->Name,S)==0)&&((Exdata->flags&7)==Flags)&&
				((Exdata->Props&0x100)==0)) {
				return I;
			}
		}
	}
	Numexnames++;
	Exdata=exrecad(Numexnames);
	memset(Exdata,0,sizeof( struct Exdatafmt));
	strcpy(Exdata->Name,S);
	Exdata->Refad=0;	/*no space for reference allocated until required*/
	Exdata->Ca=-1;	/*will be >=0 when entry address is known*/
	if (strcmp(S,"")==0)  Flags|=4;	/* call from Enextproc                       */
	Exdata->flags=Flags;
	return Numexnames;
}	/* Mgetprockey */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
void Mnoteentry(char * S,int Id) {
	/****************************************************************/
	/** record that Id, obtained by Mgetprockey(""), is S          **/
	/****************************************************************/
	struct Exdatafmt *Exdata;
	Exdata=exrecad(Id);
	strcpy(Exdata->Name,S);
	if ((Language==CCOMP)&&(LanguageVariant==USLC)&&(S[1-1]=='.'))  Exdata->flags=Exdata->flags|4;
}	/* Mnoteentry  */
/***/
void Mareaalign(int Id,int Align) {
	/*************************************************************************/
	/**    Specify the alignment needs of area Id                           **/
	/*************************************************************************/
	struct Exdatafmt *exdata;
	exdata=exrecad(Id);
	if ((Align<=0)||((Align&(Align-1))!=0))  Align=1;
	exdata->align=Align;
}	/*M area align*/
/***/
int MSetEntityProps(int Id,int type,int vector) {
	/*************************************************************************/
	/** Specify the properties of of external symbol or procedure. If type  **/
	/** is 0 then the following procedure properties may be added to the    **/
	/** procedure using the following bits in vector. If type is 1 then the **/
	/** properties may be removed. This should only be used on ids          **/
	/** representing internal or external procedures:                       **/
	/**    2**0     Set if external                                         **/
	/**    2**1     Set if main entry                                       **/
	/**    2**2     Set if display not required (Implied for FORTRAN & C)   **/
	/**    2**3     Set if there are no local variables                     **/
	/**    2**4     Set if this is a side entry                             **/
	/**    2**5     Set if there are no internal blocks or procedures       **/
	/**    2**6     Set to fill the stack with the unassigned pattern       **/
	/**    2**7     Set if this procedure contains side entries             **/
	/**    2**8     Used by Mtidyend for pfix calls                         **/
	/**    2**9     Set if this procedure returns an aggregate              **/
	/**    2**10    Set if there are no pointers or aliases to locals       **/
	/**    2**11    Set if this proc is to be called from .init             **/
	/**    2**12    Set if this proc is to be called from .fini             **/
	/**    2**13    Set if proc contains calls with unknown control flow    **/
	/**    2**14    Set is proc has unknown return flow                     **/
	/**    2**15    Set if proc is a special buffer handling function       **/
	/**                                                                     **/
	/** If type is 2 then the following symbol flags may be added to the    **/
	/** symbol. If type is 3 then the flags may be removed:                 **/
	/**    2**0     Set if symbol name not to be changed by PUT             **/
	/**    2**1     Set if symbol is data external reference on AIX         **/
	/**    2**2     Set if symbol is internal                               **/
	/**    2**3     Set if symbol has no self aliases for internal pointers **/
	/**    2**4     Set if symbol represents a called function on AIX       **/
	/**    2**5     Set if symbol defined as an entry point                 **/
	/**    2**6     Set if symbol is data item requiring a TOC entry on AIX **/
	/**                                                                     **/
	/** The new set of procedure properties or symbol flags are returned.   **/
	/*************************************************************************/
	struct Exdatafmt *exdata;

	exdata=exrecad(Id);
	if (type==0) {
		exdata->Props|=vector&0xFFFF;
		return exdata->Props;
	} else if (type==1) {
		exdata->Props&=~(vector&0xFFFF);
		return exdata->Props;
	} else if (type==2) {
		exdata->flags=exdata->flags|vector;
		return exdata->flags;
	} else if (type==3) {
		exdata->flags=exdata->flags&(~vector);
		return exdata->flags;
	};
	Mabort(80);
	return 0;



}	/*M SetEntityProps*/
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
int MgetAreaAlign(int Id) {
	/*************************************************************************/
	/**    Returns the mininum alignment essential for are Id               **/
	/*************************************************************************/
	struct Exdatafmt *exdata;
	exdata=exrecad(Id);
	return exdata->align;
}	/*M get areaalign */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
void Mgetprocaddr(char * S) {
	/****************************************************************/
	/** stack a location which will contain the procedure address  **/
	/** this procedure ignores the protocol for procedure arguments**/
	/****************************************************************/
	int Id;
	struct Exdatafmt *exdata;
	Id=Mgetprockey(0,S);
	exdata=exrecad(Id);
	if (exdata->Refad==0) {
		exdata->Refad=epermspace(4,4); 
		exdata->Area=GLA;
	}
	estkdir(exdata->Area,exdata->Refad,0,4);
}	/* Mgetprocaddr  */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
int Msetprocref(int area,int offset,char * S,int Id) {
	return Mgetuniqueprockey(S,area,offset,Id);
}	/* Msetprocref */
/***/

#if((Language==CCOMP)&&(LanguageVariant==USLC)) 
char * Mgetname2(int id) {
	/*************************************************************************/
	/** Return the name of an external symbol for use by front end          **/
	/** outputting assembler. Prepend prefix for externals                  **/
	/*************************************************************************/
	struct Exdatafmt *exdata;
	unsigned char Firstchar;
	exdata=exrecad(id);
	Firstchar=(*(unsigned char  *)((int)exdata->Name+1));
	if ((Firstchar=='.')||(Firstchar=='@'))  return exdata->Name;
	return imp_concat(exnameprepend,exdata->Name);
};	/*Mgetname2*/

#endif
/***/
char * Mgetname(int id) {
	/*************************************************************************/
	/** Return the address of the name of an external symbol for use        **/
	/** by front end outputting assembler                                   **/
	/*************************************************************************/
	struct Exdatafmt *exdata;
	exdata=exrecad(id);
	return exdata->Name;
}	/*Mgetname*/
/***/
char * Mexname(char * stname) {
	static char S[256];
	if (Target==SPARC || OutputASSEMBLER==Negative || stname[0]==64 || stname[0]=='.') {
		return stname;
	} else {
		strcpy(exnameprepend,S);
		strcat(S,stname);
		return S;
	}
}	/* Mexname */
/***/

#if((Target==RS6)&&(TargetABI==AIXABI)) 
/* version for procedure descriptors RS6 (AIX) and EMAS are the only candidates*/
void Mgetprocref(int Id,int Level) {
	/****************************************************************/
	/** stack a location which will contain the procedure address  **/
	/** this procedure takes account of the protocol for procedure **/
	/** arguments                                                  **/
	/** All languages have to use the protocol because of the TOC  **/
	/** Short cuts used by C and Fortran etc may  well not work    **/
	/****************************************************************/
	int refoff,refarea;
	struct Exdatafmt *Exdata;

	Exdata=exrecad(Id);
	if ((Level<=(FirstDisplayLevel-1))&&((Exdata->flags&4)==0)) {
		/* passing external                                                          */
		if (Exdata->Desrefad==0)  Exdata->Desrefad=epermspace(4,4);
		pd4(GLA,Exdata->Desrefad,0);
		estkdir(GLA,Exdata->Desrefad,0,4);	/* return desc ptr                       */
		return ;
	}
	/**/
	/* section for internal procs also externals with forward references(specs)  */
	/**/
	if (Exdata->Refad==0) {
		Exdata->Refad=epermspace(4,4); 
		Exdata->Area=GLA;
	}
	estkdir(Exdata->Area,Exdata->Refad,0,4);

	if (Level<=(FirstDisplayLevel-1)) {
		refoff=epermspace(12,4);
		refarea=GLA;	/* put in GLA so it persists                                   */
	} else {
		refoff=etempspace(12,4)	/* Others need a 3-word struct with : */;
		refarea=STACK;
	}
	estkdir(refarea,refoff,0,4);
	eop(ESTORE);	/* .entrypoint address in word 1      */

	Level++;	/* %spec level -> body level          */
	if (Level<=FirstDisplayLevel) {
		estklit(0);
	} else {
		PI->privprops|=CALLSINTERNAL;
		estkaddr(STACK,-(((Level-FirstDisplayLevel)+1)<<2),0,4);
	}
	Cstackr(TOCREG,4)	/* Toc register */;
	estkdir(refarea,refoff+4,0,4);
	eop(ESTORE);	/* TOC pointer in word 2     */
	estkdir(refarea,refoff+8,0,4);
	eop(ESTORE);	/* .zero or display pointer in word 3 */

	estkaddr(refarea,refoff,0,4)	/* leave address of struct on Estack  */;
}	/* Mgetprocref */
/***/
/*not RS6*/

#else
/***/
void Mgetprocref(int Id,int Level) {
	/****************************************************************/
	/** stack a location which will contain the procedure address  **/
	/** this procedure takes account of the protocol for procedure **/
	/** arguments                                                  **/
	/****************************************************************/
	int refoff;
	struct Exdatafmt *Exdata;

	Exdata=exrecad(Id);

#if((Language==CCOMP)&&(LanguageVariant==USLC)) 
	estkaddr(Id,0,0,4);
	return ;

#else
	if (Exdata->Refad==0) {
		Exdata->Refad=epermspace(4,4);
		Exdata->Area=GLA;
		pd4(GLA,Exdata->Refad,0);
	}
	estkdir(Exdata->Area,Exdata->Refad,0,4);

	/* PASCAL, MODULA, C and C++ just need the address of entrypoint */
	if ((Language==IMP)) {
		refoff=etempspace(8,4)	/* Others need a 2-word struct with : */;

		estkdir(STACK,refoff,0,4);
		eop(ESTORE);	/* .entrypoint address in word 1      */

		Level++;	/* %spec level -> body level          */
		if (Level<=FirstDisplayLevel) {
			estklit(0);
		} else {
			PI->privprops|=CALLSINTERNAL;
#if(Target==PENTIUM) 
			estkaddr(STACK,0,0,4)	/* Hardware copies display  */;

#else
		estkaddr(STACK,-(((Level-FirstDisplayLevel)+1)<<2),0,4);

#endif
		}
		estkdir(STACK,refoff+4,0,4);
		eop(ESTORE);	/* .zero or display pointer in word 2 */
		estkaddr(STACK,refoff,0,4)	/* leave address of struct on Estack  */;
	}

#if (Language==FORTRAN && LanguageVariant==FORTRAN90)
	if (Exdata->flags&4) PI->privprops|=CALLSINTERNAL;
#endif

#endif
}	/* Mgetprocref */
/***/
/*non RS6 version*/

#endif
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
void Mprecall(int Aparamprops) {
	/****************************************************************/
	/** perform any actions necessary prior to planting parameters **/
	/** note param properties                                      **/
	/** param info is preserved for nested calls                   **/
	/****************************************************************/
	int i,hidden,parbits;

	if (calllevel>0) {
		/* a nested Mprecall - maybe need to save already-loaded param regs */
		/**/
		/**/
		/* There is a nasty problem with deeply nested calls when the parameters are */
		/* constructed in the callers space. New space is required for each set      */
		/* of parameters unless NONE(not just the last) of the outer calls have      */
		/* any parameters placed. Consequently we always allocate new space unless   */
		/* calllevel=1 (First level of nesting) and no parameters have yet been passed*/
		/* There is an optimisation for deeper nesting but it occurs too rarely      */
		/* for it to be worth implementing                                           */
		/**/

#if(Target==SPARC) 
		if ((calllevel>1)||(ParI->loadedpars!=0)) {
			i=((*(int  *)(Aparamprops+4))+11)&(~7);
			if (i<32)  i=32;	/* May be varargs rt which spills 6 always */
			ARCH(oplit(SUB,STACKPOINTER,i,STACKPOINTER))	/*    preserve the*/;
			ParI->stackadj=i;	/*   current param*/
		};

#endif
		/**/

#if(Target==RS6) 
		if (((calllevel>1)||(ParI->loadedpars!=0))) {
			i=((*(int  *)(Aparamprops+4))+7)&(-8);
			if (i<32)  i=32;
			ARCH(oplit(addi,STACKPOINTER,-(i+24)),STACKPOINTER);
			ARCH(storeri(st,FRAMEPOINTER,STACKPOINTER,0));
			PI->privprops|=NESTEDCALLS;
			ParI->stackadj=i+24;
		};

#endif
		/**/

		/**/

#if(Target==MIPS) 
                if (((calllevel>1)||(ParI->loadedpars!=0))) {
                        i=((*(int  *)(Aparamprops+4))+7)&(-8);
                        if (i<16)  i=16;
                        ARCH(oplit(addiu,STACKPOINTER,-i,STACKPOINTER));
                        ARCH(modinstrprops(0,FRAMEMODIFY,0,0));
                        ParI->stackadj=i;
                        PI->privprops|=NESTEDCALLS;
                };

#endif
	}

	calllevel+=1;
	ParI=&ParamInfo [calllevel];
	CsetParI(ParI);
	hidden=0;	 
	parbits=0;
	memset(ParI,0,sizeof( struct paramfmt));
	ParI->numpars=(*(int  *)(Aparamprops));
	ParI->paramsize=(*(int  *)(Aparamprops+4));
	ParI->firstpar=FreeParword;
	ParI->nextpar=FreeParword;

#if(Target==PENTIUM) 
	/* but discriptor array is Fward */
	i=ParI->numpars-1;
	while (i>=0) {
		Parwords [FreeParword]=(*(int  *)((Aparamprops+8)+(i<<2)));
		parbits|=1<<(((unsigned)Parwords [FreeParword]>>24)&15);
		i--;
		FreeParword++;
	}

#else
	i=0;
	while (i<ParI->numpars) {
		Parwords [FreeParword]=(*(int  *)((Aparamprops+8)+(i<<2)));
		parbits|=1<<(((unsigned)Parwords [FreeParword]>>24)&15);
		i++;
		FreeParword++;
	}

#endif
	if (((Target==RS6)||(Target==MIPS)||(Target==PENTIUM)) &&
		((parbits&((1<<ResAddrval)|(1<<ResLenval)))==(1<<ResAddrval)))  hidden=1;
	ParI->hidden=hidden;
	if (TargetABI!=SunsoftABI) ParI->offset=4*hidden;	/*normally hidden pushes all to right */

#if(Target==RS6) 
	ParI->nextireg=3+hidden;	/* first int to r3 or r4 if hidden                 */
	ParI->nextfpreg=33;	/* first real goes to fp1                               */
#endif

#if(Target==MIPS) 
	i=((unsigned)Parwords [ParI->firstpar]>>24)&15;
	ParI->nextfpreg=FOUTPARAM1REG+6;	/* No fp regs used */
	if (i==Realval || i==Floatval ||i==Cmplxval)  ParI->nextfpreg=FOUTPARAM1REG;	/* 1+ FP regs used */
#endif
}	/* Mprecall                                        */
/***/

#if((Target==RS6)||(Target==MIPS)) 
/**/
/* This routine is needed only if floating parameters are passed in registers*/
/* and there is a different file of registers for floating and integers      */
/* rs6000 and MIPS are the only known targets like this                      */
/**/
int Mgetfpparamoffset(int n) {
	/*************************************************************************/
	/**    returns the offset of the Nth real parameter                     **/
	/**    can be called any time between precall and call but is           **/
	/**    mainly required for parameter reloading in nested calls          **/
	/*************************************************************************/
	int par,offset,i,nextpar,type,size,align;

	nextpar=ParI->firstpar;
	offset=4*ParI->hidden;	 
	i=0;
	/**/
	do {
		par=Parwords [nextpar];
		type=((unsigned)par>>24)&15;
		size=par&0xFFFFFF;
		align=(unsigned)par>>28;

#if(Target==MIPS) 
		if ((((type==Realval)||(type==Floatval))& &(
			(size==8)||(size==16)))||((type==Cmplxval)&&(size==16))) align=8;
#endif
		if (par==-1) {
			nextpar++;
			if ((Target==MIPS)&&(ParI->hidden!=0)&&((offset&7)==0))   continue ;
			offset+=4;
			continue ;
		} else if (align>0) {
			offset=((offset+align)-1)&(-align);
		};

		if ((Target==RS6)&&(type==ResAddrval)) {
			i++; 
			nextpar++;  
			continue ;
		}
		if (type==Realval) {
			n--;
			if (n==0)  return offset|(size<<24);
		}
		if (type==Floatval) {
			/* C floating parameters if special rules apply                              */
			n--;
			if (n==0)  return (offset|(size<<24))|0x800000;	/*Flag it for load out reg etc */
		}
		if (type==Cmplxval) {
			n--;	 
			size=(unsigned)size>>1;	/* item size not complex size                 */
			if (n==0)  return offset|(size<<24);
			offset+=size;
			n--;
			if (n==0)  return offset|(size<<24);
		}
		offset=((offset+size)+3)&(-4);
		i++;	 
		nextpar++;
		if (i>=ParI->numpars)   break ;
	} while (1) /* FOR EVER */;
	return 0;	/*less than N fp params                                           */
}	/*Mgetfpparamoffset*/
/***/
int Mgetholeoffset(int n) {
	/*************************************************************************/
	/**    returns the offset of the Nth hole in the  parameters            **/
	/**    can be called any time between precall and call but is           **/
	/**    mainly required for parameter reloading in nested calls          **/
	/*************************************************************************/
	int par,offset,i,nextpar,type,size,align;

	nextpar=ParI->firstpar;
	offset=4*ParI->hidden;	 
	i=0;
	do {
		par=Parwords [nextpar];
		type=((unsigned)par>>24)&15;
		size=par&0xFFFFFF;
		align=(unsigned)par>>28;

#if(Target==MIPS) 
		if ((((type==Realval)||(type==Floatval))&&((size==8)||(size==16)))| |(
			(type==Cmplxval)&&(size==16)))	align=8;
#endif
		if (align>0)  offset=((offset+align)-1)&(-align);
		if (par==-1) {
			if ((Target==MIPS)&&(ParI->hidden!=0)&&((offset&7)==0))  size=0; 
			else {
				n--;
				if (n==0)  return offset;
				size=4;
			}
		}
		offset=((offset+size)+3)&(-4);
		i++;	 
		nextpar++;
		if (i>=ParI->numpars)   break ;
	} while (1) /* FOR EVER */;
	return 0;	/*less than N fp params                                           */
}	/*Mgetholeoffset */
/**/
int Mgetloadedpars() {
	/*************************************************************************/
	/** Returns the mask of parameter registers loaded at this point in the **/
	/** call. The use of the bits is target dependent and they are set in   **/
	/** Cpushparam in cprocs. NB Sparc & M88k us this field differently     **/
	/** and hence this function is not compiled in for these targets        **/
	/**************************************************************************/
	return ParI->loadedpars;
};

#endif
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
void Mparaminfo2(int *len,int *parindex,int *type,int *offset,int *align,int *reg) {
	/****************************************************************/
	/** provides info to code generating procs about cur param     **/
	/****************************************************************/
	int par;
	do {
		if ((ParI->nextpar-ParI->firstpar)>=ParI->numpars)  Mabort(38);
		par=Parwords [ParI->nextpar];
		ParI->nextpar=ParI->nextpar+1;
		if (par==-1) 	/* a hole */{
			if ((Target==MIPS)&&(ParI->hidden!=0)&&((ParI->offset&7)==0))   continue ;

#if((Target==RS6)&&(TargetABI==SunsoftABI)) 
			continue ;
#endif	/* Sunsoft alignment only applies to oflow area */
			/* and this is done in the following code       */
			ParI->offset=ParI->offset+4;
			continue ;
		}
		*len=par&0xFFFFFF;
		*parindex=(ParI->nextpar-ParI->firstpar)-1;
		*type=((unsigned)par>>24)&15;
		/**/

#if((Target==SPARC)||(Target==MIPS)||(Target==RS6)) 
		*align=4;
#endif
		/**/

#if((Target==MIPS)) 
		*align=((unsigned)par>>28)&15;

#if(Target==MIPS) 
		if ((((*type==Realval)||(*type==Floatval))&&((*len==8)||(*len==16)))| |(
			(*type==Cmplxval)&&(*len==16)))  *align=8;
		if (*align!=0)  ParI->offset=((ParI->offset+*align)-1)&(-*align);
#endif
#endif

#if((Target==MIPS)||(Target==RS6))
		if ((ParI->hidden==0)&&(*type==ResAddrval)) {
			*offset=0;	 
			*reg=OUTPARAM1REG;	  
			break ;
		}
#endif

		/**/
		*offset=ParI->offset;
		/**/

#if(Target==RS6) 
		if (((*type==Realval)||(*type==Floatval)||(*type==Cmplxval))) {
			if ((*type==Cmplxval)&&(ParI->nextfpreg<=(HIGHPARAMFREG-1))) {
				*reg=ParI->nextfpreg;
				ParI->nextfpreg=ParI->nextfpreg+2;
			} else if ((*type!=Cmplxval)&&(ParI->nextfpreg<=HIGHPARAMFREG)) {
				*reg=ParI->nextfpreg;	 
				ParI->nextfpreg=ParI->nextfpreg+1;
			} else {

#if(TargetABI==SunsoftABI) 
				ParI->offset=(ParI->offset+7)&(-8);
#endif
				*offset=ParI->offset;
				*reg=-1;
			};

			/* type for Int register */
		} else {
			if (ParI->nextireg<=10) {
				*reg=ParI->nextireg;
				ParI->nextireg=ParI->nextireg+1;
			} else {
				*reg=-1;
			}
		};

#endif
		/**/

#if(Target==MIPS) 
		if (((*type==Realval)||(*type==Floatval)||(*type==Cmplxval)) &&
			(ParI->nextfpreg<(FOUTPARAM1REG+4))&&(*offset<=8)) {
			*reg=ParI->nextfpreg;	 
			ParI->nextfpreg=ParI->nextfpreg+2;
			if ((*type==Cmplxval)||(*len==16))  ParI->nextfpreg=ParI->nextfpreg+2;
		} else {
			ParI->nextfpreg=FOUTPARAM1REG+4;	/* No more after an int */
			if (*offset>16)  *reg=-1; 
			else *reg=((unsigned)*offset>>2)+OUTPARAM1REG;
			;
		};

#endif
		/**/
		/**/
		/* Sunsoft does not allocate space for params in regs                        */
		/**/
		if (!((Target==RS6)&&(TargetABI==SunsoftABI)&&(*reg>0)))  ParI->offset=((ParI->offset+*len)+3)&(-4)
			;
		break ;
	} while (1) /* FOR EVER */;
}	/* Mparaminfo  */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
#if (Target==PENTIUM)
void Mtrampcall(int Id,int extlevel,int numpars,int paramsize,int proctype) {
	/*****************************************************************/
	/** perform trampoline procedure call and related administration**/
	/**    > 0  procedure identifier                                **/
	/**                                                             **/
	/** proctype = 0  always a regular procedure                    **/
	/*****************************************************************/
	struct Exdatafmt *exdata;
	int callprops;

	if (Id<0)  Mabort(85);
	/**/
#if(Target!=PENTIUM)
	if (ParI->offset>PI->outparsize) {
		PI->outparsize=ParI->offset;
	}
#endif
	/**/
	/*****************************************************/
	/* clear any register memory and contents necessary **/
	/*****************************************************/
	/**/

#if((Target==SPARC)||(Target==PENTIUM)) 
	if (proctype!=0) {
		releaseleafcallregs(proctype);
	} else {
		releasecallregs();
	};

#endif
	/**/

#if((Target==RS6)||(Target==MIPS)) 
	releasecallregs();
#endif
	/**/

	callprops=proctype<<24;

#if(Target==PENTIUM) 
	if (ParI->hidden!=0)  callprops|=0x40000;

#else
	if (ParI->paramsize<0)  callprops|=0x20000;

#endif
	if (Id!=0) {
		/* determine if called procedure has unknown return flow */
		exdata=exrecad(Id);
		if ((exdata->Props&(1<<14))!=0) {
			callprops|=1;
		}
	}
	/**/

	/*****************************************************/
	/* generate call                                    **/
	/*****************************************************/
	/**/

#if((Target==SPARC)&&(Language==CCOMP)) 
	/* preserve floating point register variables on SPARC */
	CStoreRegvars();
	;
#endif
	/**/
	Ctrampcall(Id,numpars,paramsize,callprops);
	/**/

#if(Target==SPARC) 
	if (proctype!=0) {
		rclearleafcallregs(proctype);
	} else if (UnkCntrlFlow!=0) {
		rclearregs(0);
	} else {
		rclearcallregs();
	};

	;
#endif
	/***/

#if((Target==RS6)||(Target==MIPS)||(Target==PENTIUM)) 
	if (UnkCntrlFlow!=0) {
		rclearregs(0);
	} else {
		rclearcallregs();
	};

#endif
	/**/

	/**/

#if((Target==SPARC)&&(Language==CCOMP)) 
	/* reload floating point register variables on SPARC */
	CLoadRegvars();
	;
#endif
	/**/

#if(Target==RS6) 

#if(TargetABI==AIXABI) 
	if ((Id!=0)&&((exdata->flags&4)==0)) 	/*external*/{
		/* will be changed to a TOC reload if required by linker */
		ARCH(rr(cror,31,31,31));
		ARCH(modinstrprops(0,0,0,SCHRESTRICTINSTR));
	};

#endif
	;
#endif
	/**/

#if(Target==MIPS) 
	if (Pic!=0) {
		/* In Pic mode need to reload GOT here */
		ARCH(access(LoadIntVal,GOTREG,STACK,PI->GOTsave,4,0,0));
		ARCH(modinstrprops(0,0,0,GOTREDTAPE|SCHRESTRICTINSTR));
	};

#endif
	/**/
	/*****************************************************/
	/* recover parameter space if appropriate           **/
	/*****************************************************/
	/**/
	FreeParword=ParI->firstpar;
	calllevel-=1;
	ParI=&ParamInfo [calllevel];
	CsetParI(ParI);
	if (ParI->stackadj!=0) 	/*reclaim nested call param save area*/{
		Mabort(97);
	}

}	/* Mtrampcall */
#endif

void Mcall(int Id,int extlevel,int numpars,int paramsize,int callprops) {
	/*****************************************************************/
	/** perform procedure call and related administration           **/
	/** id = 0  procedure address is on the stack                   **/
	/**    > 0  procedure identifier                                **/
	/**                                                             **/
	/** proctype = 0  regular procedure                             **/
	/**          = 1  an integer leaf procedure (no floating point) **/
	/**          = 2  a floating point leaf procedure               **/
	/** callprops bits signify:-                                    **/
	/** 2**0       call may not return                              **/
	/** 2**16      display registers passed also                    **/
	/** 2**17      Intel Extra param passed in EDX (_mcount)        **/
	/**            non Intel Procedure may have Varargs             **/
	/** 2**18      Procedure has hidden parameter                   **/
	/** 2**24 up    Proctype                                        **/
	/*****************************************************************/
	struct Exdatafmt *exdata;
	struct Stkfmt Disp;
	struct fragfmt *Frag;
	int proctype;
#if(Target!=PENTIUM) 
	int Reg;
#endif

	if (Id<0)  Mabort(83);
	proctype=callprops>>24;
	/**/
	/* detect if call recursive and if so protect the tail recursion             */
	/* label (PI_returnlab+2)                                                    */
	Frag=PI->procfrag;
	if (Id==Frag->entryid) 	/* recursive call       */{
		if ((PI->privprops&DCALLSSELF)==0) 	/* first recursive call */{
			PI->privprops|=DCALLSSELF;
			Maddrlabel(PI->returnlab+2,0,0)	/* Stop label being discarded*/;
		}
	}
#if(Target!=PENTIUM)
	if (ParI->offset>PI->outparsize) {
		PI->outparsize=ParI->offset;
	}
#endif
	/**/
	/*****************************************************/
	/* clear any register memory and contents necessary **/
	/*****************************************************/
	/**/

#if((Target==SPARC)||(Target==PENTIUM)) 
	if (proctype!=0) {
		releaseleafcallregs(proctype);
	} else {
		releasecallregs();
	};

#endif
	/**/

#if((Target==RS6)||(Target==MIPS)) 
	releasecallregs();
#endif
	/**/

	/**/

#if(Target==PENTIUM) 
	if (ParI->hidden!=0)  callprops|=0x40000;

#else
	if (ParI->paramsize<0)  callprops|=0x20000;

#endif
	if (Id!=0) {
		/* determine if called procedure has unknown return flow */
		exdata=exrecad(Id);
		if ((exdata->Props&(1<<14))!=0) {
			callprops|=1;
		}
	}
	/**/
	if (!(extlevel<=FirstDisplayLevel)) {
		/*****************************************************/
		/* load address of display in appropriate register  **/
		/*****************************************************/
		/**/
		memset(&Disp,0,sizeof( struct Stkfmt));
		Disp.Form=AddrDir;
		Disp.Base=STACK;
		Disp.Offset=-(((extlevel-FirstDisplayLevel)<<2)+4);

#if(Target==RS6) 
		Disp.Offset=Disp.Offset+Saveareasize;
#endif

#if(Target!=PENTIUM) 
		Reg=LoadIntRW(&Disp,DISPLAYREG);
		notereguse(DISPLAYREG,0,0)	/*transient use only*/;
		;
#endif
		callprops|=0x10000;
		PI->privprops|=CALLSINTERNAL;
		/**/
		/*****************************************************/
	}

	/*****************************************************/
	/* generate call                                    **/
	/*****************************************************/
	/**/

#if((Target==SPARC)&&(Language==CCOMP)) 
	/* preserve floating point register variables on SPARC */
	CStoreRegvars();
	;
#endif
	/**/
	Ccall(Id,numpars,paramsize,callprops);
	/**/

#if(Target==SPARC) 
	if (proctype!=0) {
		rclearleafcallregs(proctype);
	} else if (UnkCntrlFlow!=0) {
		rclearregs(0);
	} else {
		rclearcallregs();
	};

	;
#endif
	/***/

#if((Target==RS6)||(Target==MIPS)||(Target==PENTIUM)) 
	if (UnkCntrlFlow!=0) {
		rclearregs(0);
	} else {
		rclearcallregs();
	};

#endif
	/**/

	/**/

#if((Target==SPARC)&&(Language==CCOMP)) 
	/* reload floating point register variables on SPARC */
	CLoadRegvars();
	;
#endif
	/**/

#if(Target==RS6) 

#if(TargetABI==AIXABI) 
	if ((Id!=0)&&((exdata->flags&4)==0)) 	/*external*/{
		/* will be changed to a TOC reload if required by linker */
		ARCH(rr(cror,31,31,31));
		ARCH(modinstrprops(0,0,0,SCHRESTRICTINSTR));
	};

#endif
	;
#endif
	/**/

#if(Target==MIPS) 
	if (Pic!=0) {
		/* In Pic mode need to reload GOT here */
		ARCH(access(LoadIntVal,GOTREG,STACK,PI->GOTsave,4,0,0));
		ARCH(modinstrprops(0,0,0,GOTREDTAPE|SCHRESTRICTINSTR));
	};

#endif
	/**/
	/*****************************************************/
	/* recover parameter space if appropriate           **/
	/*****************************************************/
	/**/
	FreeParword=ParI->firstpar;
	calllevel-=1;
	ParI=&ParamInfo [calllevel];
	CsetParI(ParI);
	if (ParI->stackadj!=0) 	/*reclaim nested call param save area*/{
		/**/

#if(Target==SPARC) 
		ARCH(oplit(ADD,STACKPOINTER,ParI->stackadj,STACKPOINTER));
		ARCH(modinstrprops(0,FRAMEMODIFY,0,0));
		;
#endif
		/**/

#if((Target==RS6)||(Target==MIPS)) 
		ARCH(oplit(addi,STACKPOINTER,ParI->stackadj,STACKPOINTER));
		ARCH(modinstrprops(0,FRAMEMODIFY,0,0));
		;
#endif


		/**/
		ParI->stackadj=0;
	}

}	/* Mcall */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
void MAdjustPar(struct Stkfmt *Par,int ParamOffset) {
	/******************************************************************************/
	/** This is the code generator's chance to alter the Estack entry 'Par'      **/
	/** created by Estkpar - ie to fiddle dummy parameters                       **/
	/** 'Param Offset' is the current value of the Eprocs variable Param Offset  **/
	/******************************************************************************/


	/**/
	if (((Target==RS6)||(Target==PENTIUM))&&((PI->procprops&PP_RETURNSAG)!=0)) {
		/* Returns struct all visble params shifted up 4 bytes                       */
		/* F77 makes this change itself                                              */

#if(!((Language==FORTRAN)&&(LanguageVariant==FORTRAN77))) 
		Par->Offset=Par->Offset+4;
#endif
	}
	/**/
	/* mips adjusting may mean realignment of parameters if doubles or quads are involved*/
	/* there is a target routine to do this. This routine assumes the par is at the*/
	/* the current level (for C). Extensions would be needed if pascal or Modula */
	/* were to pass global parameters and use ABI standards for returning structs*/
	/* Currently P&M return structs by a private method                          */
	/**/

#if(Target==MIPS) 
	Par->Offset=targetadjustpar(Par->Offset,PI);
#endif
}	/* MAdjustPar */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
void Mstartproc(int Id,int Props,int Proclevel,int Aparamprops) {
	/*************************************************************************/
	/** generate code at procedure entry                                    **/
	/**    props are as follows:                                            **/
	/**                                                                     **/
	/**    2**0     Set if external                                         **/
	/**    2**1     Set if main entry       (2**31 is used by FORTRAN!)     **/
	/**    2**2     Set if display not required (Implied for FORTRAN & C)   **/
	/**    2**3     Set if there are no local variables                     **/
	/**    2**4     Set if this is a side entry                             **/
	/**    2**5     Set if there are no internal blocks or procedures       **/
	/**    2**6     Set to fill the stack with the unassigned pattern       **/
	/**    2**7     Set if this procedure contains side entries             **/
	/**    2**8     Used by Mtidyend for pfix calls                         **/
	/**    2**9     Set if this procedure returns an aggregate              **/
	/**    2**10    Set if there are no pointers or aliases to locals       **/
	/**    2**11    Set if this  proc is to be called from .init            **/
	/**    2**12    Set if this  proc is to be called from .fini            **/
	/**    2**13    Set if proc contains calls with unknown control flow    **/
	/**    2**14    Set is proc has unknown return flow                     **/
	/**    2**15    Set if proc is a special buffer handling function       **/
	/*************************************************************************/
	struct fragfmt *frag;
	struct Exdatafmt *exdata;
	int insmarker,markerad,curdisplay,I,PIaddr,label,profiledataoffset,displayextra,savefpflag
	,rangeproc;

	exdata=exrecad(Id);

#if((Language==CCOMP)||((Language==FORTRAN)&&(LanguageVariant!=FORTRAN90))) 
	Props|=32|4;
#endif	/* No display no inners but watch || Ftran*/
	exdata->Props=(exdata->Props&0xFFFF0100)|(Props&0xFEFF);	/*will be used to determine visibility*/
	/*dont disturb prockey bits*/
	/***/
	/* Mark the symbol as being defined as a procedure which is local (for tail recursion)*/
	exdata->flags=(exdata->flags|32)|4;
	/***/
	/*****************************************************/
	/* save state of dynamic procedure information      **/
	/*****************************************************/
	/**/

#if(Target==SPARC) 
	PI->lowreg=*clowregmap();
#endif
	/**/

	/**/
	Cstartproc(Props);
	PI->labadjust=Labadjust;
	/***/
	/**    initialise procedure information table                                */
	/***/
	ProcNum++;
	UnkCntrlFlow=Props&(1<<13);
	PI=&ProcInfo [Proclevel];
	PIaddr=(int)&ProcInfo [Proclevel];
	currentPIaddr=PIaddr;
	memset(PI,0,sizeof( struct procfmt));
	PI->proclevel=Proclevel;
	PI->procprops=Props;
	PI->procnum=ProcNum;

#if((Target==RS6)||(Target==MIPS)||(Target==PENTIUM)) 
	PI->swmark=Numswkeys;
#endif
	/**/

	/**/
	CsetPI(PI);
	BSetPI(PIaddr);
	/***/
	/**    determine if code tracing is required                                 */
	/***/
	rangeproc=BGetTraceProc();
	if ((rangeproc==0)||(rangeproc==ProcNum)) {
		Creport(GlobCodeReport);
	} else {
		Creport(0);
	}
	/***/
	/**    start a new chain of fragment records                                 */
	/***/
	BNewFrag();
	PI->procfrag=PI->curfrag;
	frag=PI->procfrag;
	frag->entryid=Id;
	/***/
	BPrintProcBanner();
	/***/
	Labadjust=Nextlabtag;
	PI->labadjust=Labadjust;
	Nextlabtag+=INITLABTAG;

#if((Target==RS6)||(Target==MIPS)||(Target==PENTIUM)||(Target==SPARC)) 
	PI->returnlab=Mprivatelabel();
	/* label returns jump to                                                     */

#if((Target==RS6)||(Target==MIPS)||(Target==PENTIUM)||(Target==SPARC)) 
	I=Mprivatelabel();	/* extra label(=PI_returnlab+1) for                      */
	/* use in soft overflow checks                                               */
	I=Mprivatelabel();	/* extra lab(=PI_returnlab+2) for tail recursion         */
#endif
#endif

	/***/
	/*****************************************************/
	/* clear register use                               **/
	/*****************************************************/
	/**/
	rclearregs(0);

	/**/
	/*****************************************************/
	/***/
	if ((Language==FORTRAN)&&(paramchecks!=0)) {
		/*******************************************************/
		/* save previous frame pointer for parameter checking **/
		/*******************************************************/
		/**/
		savefpflag=0;

#if(Target==SPARC) 
		if ((Props&2)==0) {
			if ((Props&0x40)==0) {
				ARCH(storeri(ST,FRAMEPOINTER,STACKPOINTER,-16));
			} else {
				/******************************************************/
				/* filling the stack frame with the unassigned pattern**/
				/* will corrupt FRAMEPOINTER+16 - save the caller's fp**/
				/* in SAVEFGREG and then store it in FRAMEPOINTER+16  **/
				/* after the stack frame has been filled              **/
				/******************************************************/
				ARCH(rr(OR,FRAMEPOINTER,rZERO,SAVEFPREG));
				savefpflag=1;
			}
		};
		/* Target=sparc*/

#endif
		/**/

		/**/
		/* RS/6000: old frame pointer at sp-0 by convention                          */
		/* MIPS: can not do this till after frame claim                              */
	}
	/**/
	/*****************************************************/
	/* generate stack frame generation code             **/
	/*****************************************************/
	/**/

#if(Target==SPARC) 
	PI->framemark=ARCH(framesetup());
	if (Pic>0) {
		frag=PI->curfrag;
		frag->props|=NOOPTIMFRAG;
		ARCH(GOTfix(GOTREG));
	}
	Mlabel(PI->returnlab+2);	/* for tail recursion */
#endif
	/**/

	/**/

#if(Target==RS6) 
	frag=PI->curfrag;
	frag->props|=NOCOALESCEHEAD;	/* so wrappers at the back of frag*/
	BBreakFrag(0);	/* Wrappers will go in here */
	if ((TargetABI==SunsoftABI)&&(Pic!=0)) {
		ARCH(GOTfix(GOTREG));
	}
	Mlabel(PI->returnlab+2);	/* For tail recursion */
	Ccountparams((int *)Aparamprops,0);
#endif


#if(Target==MIPS) 
	if (Pic>0) 	/*In Pic mode load GOT here*/{
		frag=PI->curfrag;
		if (Pic==1)  frag->props|=NOOPTIMFRAG;
		ARCH(GOTfix(GOTREG));
	}
	PI->framemark=Mmarker();
	ARCH(loadlit(0x10010,rWORK));
	ARCH(rr(add,STACKPOINTER,rWORK,STACKPOINTER));
	ARCH(modinstrprops(0,FRAMEMODIFY,0,0));
	BBreakFrag(0);	/* Wrappers instructions inserted here                       */
	if ((Language==FORTRAN)&&(paramchecks!=0)) {
		PI->privprops|=NONVIRTUALFP;	/* Actual code added in do wrappings*/
	}
	if (Pic!=0) {
		PI->GOTsave=etempspace(4,4);
		ARCH(access(StoreIntVal,GOTREG,STACK,PI->GOTsave,4,0,0));
		ARCH(modinstrprops(0,0,0,GOTREDTAPE));
	}
	/**/
	/* Plant a label to jump to for tail recursion elimination (PI_returnlab+2)  */
	/* it will be discarded by ccountfrag if never accessed(The normal case)     */
	/**/
	Mplabel(PI->returnlab+2);
	Ccountparams((int *)Aparamprops,0);
#endif


#if(Target==PENTIUM) 
	BBreakFrag(0);	/* wrapper instructions instructions inserted here */
	Mplabel(PI->returnlab+2);
	Ccountparams((int *)Aparamprops,0);
	if (Pic!=0) 	/*In Pic mode load GOT here*/{
		frag=PI->curfrag;
		frag->props|=NOOPTIMFRAG;
		ARCH(GOTfix(GOTREG));
	};

#endif

	/*****************************************************/
	/* load GLA register                                **/
	/*****************************************************/
	/**/

#if((Target==SPARC)||(Target==RS6)||(Target==MIPS)) 
	ARCH(ldfix(GLA,0,GLAREG));
#endif

	/* save the MAIN program frame pointer in GLA for global jumps */
	if ((Language==PASCAL)&&((Props&2)!=0)) {
		if (MainFrameOffset==-1)  MainFrameOffset=epermspace(4,4);
		/**/

#if(Target==SPARC) 
		ARCH(access(StoreUintVal,FRAMEPOINTER,GLA,MainFrameOffset,4,0,0));
#endif
		/**/

#if((Target==RS6)||(Target==MIPS)) 
		estkaddr(STACK,0,0,4);
		estkdir(GLA,MainFrameOffset,0,4);
		eop(ESTORE);
#endif
		/**/
	}
	/**/
	if ((profile!=0)&&((Proclevel==FirstDisplayLevel)&&((Language!=IMP)||((Props&1)==1)))) {
		/*****************************************************/
		/* produce profiling information                    **/
		/* No profiling code is generated for local IMP     **/
		/* procedures at the top level - this cuts out      **/
		/* all the private routines at the beginning        **/
		/* of a compilation                                 **/
		/*****************************************************/
		/**/
		profiledataoffset=epermspace(4,4);
		if ((LanguageVariant==FORTRAN90)&&(diagnostics!=0)) {
			pd4(GLA,profiledataoffset,0);
			/*when compiling with unassigned variable checking */
			/*on Fortran90 will pre-fill GLA to the unassigned */
			/*pattern - thus this location has to be explicitly*/
			/*initialised to zero.                             */
		}
		/**/

#if(Target==SPARC) 

		if (Pic!=0) {
			ARCH(ldfix(GLA,0,OUTPARAM1REG));
			if ((profiledataoffset<-4096)||(profiledataoffset>4095)) {
				ARCH(loadlit(profiledataoffset,L0REG));
				ARCH(rr(ADD,OUTPARAM1REG,L0REG,OUTPARAM1REG));
			} else {
				ARCH(rlit(ADD,OUTPARAM1REG,profiledataoffset,OUTPARAM1REG));
			}
		} else {
			ARCH(ldfix(GLA,profiledataoffset,OUTPARAM1REG));
		}
		ARCH(call(ProfileId,-4,0));
		rclearcallregs();
#endif
		/**/

#if((Target==RS6)||(Target==MIPS)) 
		{
			struct Stkfmt Lstk;
			gladir(&Lstk,profiledataoffset,4);
			Lstk.Form=AddrDir;
			ARCH(stkaccess(LoadIntVal,OUTPARAM1REG,&Lstk));	/* addr profiledata as param*/
		}
		ARCH(modinstrprops(DESTROYABLE,0,0,0));
		ARCH(call(ProfileId,-4,0));

#if(Target==RS6) 
		/* will be changed to a TOC reload if required by linker */
		ARCH(rr(cror,31,31,31));
		ARCH(modinstrprops(0,0,0,SCHRESTRICTINSTR));
#endif
		rclearcallregs();
#endif
		/**/

		/**/

#if(Target==PENTIUM) 
		ARCH(oprfixmem(LEA,GLA,profiledataoffset,EDX,4));
		ARCH(modinstrprops(DESTROYABLE,0,0,0))	/* remove destroyable*/;
		Ccall(ProfileId,0,0,0);
#endif
		/**/
	}

	if (Lineprof!=0) {
		/*****************************************************/
		/* produce line-profiling information - generate    **/
		/* code to perform initialisation if required       **/
		/*****************************************************/
	}

	if ((Props&0x40)!=0) {
		/*****************************************************/
		/* Fill the Stack Frame with the Unassigned Pattern **/
		/*****************************************************/
		/**/

#if(Target==SPARC) 
		PI->unassignmark=Mmarker();
		ARCH(loadlit(0x7FFF	/*reserve for a large constant*/,L0REG));
		ARCH(floadri(LDDF,GLAREG,UnassignedDisp,F0REG));
		{
			int labindex;
			label=Mprivatelabel();
			Mplabel(label);
			ARCH(oplit(ADDcc,L0REG,8,L0REG));
			labindex=BLocateLabel(label+Labadjust,0);
			ARCH(ibcc(NE,labindex,Annul));
			ARCH(fstorerr(STDF,F0REG,FRAMEPOINTER,L0REG));
			BTerminateFrag(labindex,1);
		}
		/**/
		/* GENERATES:     OR    %G0,-count,%L0                                       */
		/*                LDDF  [%L7+x],%F0                                          */
		/*             A: ADDcc %L0,8,%L0                                            */
		/*                BNE,A A                                                    */
		/*                STDF  %F0,[%FP+%L0]                                        */

#if(Language==FORTRAN) 
		if ((paramchecks!=0)&&(savefpflag!=0)) {
			ARCH(storeri(ST,SAVEFPREG,FRAMEPOINTER,-16));
		};

#endif
#endif
		/**/

#if(Target==RS6) 
		PI->unassignmark=Mmarker();
		ARCH(loadlit(0x1000	/*reserve for a large constant*/,rZERO));
		ARCH(rr(mtspr,rZERO,0,CTR));
			cnstdir(&Lstk,UnassignedDisp,8);
		{
			struct Stkfmt Lstk;
			ARCH(stkaccess(LoadRealVal,F0REG,&Lstk));
		}
			ARCH(oplit(addi,STACKPOINTER,16,	/*R*/12));
		}
			int labindex;
			label=Mprivatelabel();
			Mplabel(label);
			ARCH(fstoreri(stfdu,F0REG,	/*R*/12,8));
			labindex=BLocateLabel(label+Labadjust,0);
			ARCH(bcc(BCTNZ,labindex,0));
			BTerminateFrag(labindex,0);
		}
		/**/
		/* GENERATES:     OR    %G0,-count,%G0    */
		/*                LDDF  [%L7+x],%F0       */
		/*                mtspf G0,CTR            */
		/*                addi  %SP,8,12          */
	        /*             A: stfdu %F0,12            */
	        /*                bctnz A                 */
#endif
		/***/

#if(Target==MIPS) 
		if ((Language==FORTRAN)&&(paramchecks!=0)) {
			ARCH(loadri(LD,FRAMEPOINTER,-16,3	/*$3 undefined here*/));
		}
		{
			int labindex;
			PI->unassignmark=Mmarker();
			label=Mprivatelabel();
			labindex=BLocateLabel(label+Labadjust,0);
			ARCH(unassfill(label,labindex));
		}
		if ((Language==FORTRAN)&&(paramchecks!=0)) {
			ARCH(storeri(ST,3,FRAMEPOINTER,-16));
		}
		if (Pic!=0) {
			/* Destroyed by unassfill but the earlier copy is ABI reqmnt */
			ARCH(access(StoreIntVal,GOTREG,STACK,PI->GOTsave,4,0,0));
		}
		ARCH(modinstrprops(0,0,0,GOTREDTAPE));
#endif
		/***/

#if(Target==PENTIUM) 
		PI->unassignmark=Mmarker();
		label=Mprivatelabel();
		ARCH(unassfill(label,Proclevel,0));
#endif
		/***/
	}
	/***/
	if ((((Language==PASCAL)||(Language==MODULA))&&(Proclevel==2))||(diagnostics!=0)) {
		/*****************************************************/
		/* stack GLA address                                **/
		/*****************************************************/
		/**/

#if((Target==SPARC)||(Target==MIPS)) 
		ARCH(storeri(ST,GLAREG,FRAMEPOINTER,-4));
#endif
		/**/

#if(Target==RS6) 
		ARCH(storeri(st,GLAREG,FRAMEPOINTER,(-4)+Saveareasize));
#endif
		/**/

		/**/

#if(Target==PENTIUM) 
		estkaddr(GLA,0,0,4);
		estkdir(STACK,(-(4*(Proclevel-FirstDisplayLevel)))-8,0,4);
		eop(ESTORE);
#endif
		/**/
	}
	/***/
	if ((diagnostics!=0)||((Props&4)==0)) {
		curdisplay=-8;
		if (Proclevel>FirstDisplayLevel) {
			/*****************************************************/
			/* copy display                                     **/
			/*****************************************************/
			/**/

#if(Target==SPARC) 
			for (I=(Proclevel-FirstDisplayLevel)-1; I>=0; I--) {
				ARCH(loadri(LD,DISPLAYREG,I*4,OUTERREG));
				ARCH(storeri(ST,OUTERREG,FRAMEPOINTER,curdisplay));
				curdisplay-=4;
			};

#endif
			/**/

#if(Target==RS6) 
			for (I=(Proclevel-FirstDisplayLevel)-1; I>=0; I--) {
				ARCH(loadri(ld,DISPLAYREG,I*4,rZERO));
				ARCH(storeri(st,rZERO,FRAMEPOINTER,curdisplay+Saveareasize));
				curdisplay-=4;
			};

#endif

			/**/

#if(Target==MIPS) 
			ARCH(copydisplay((Proclevel-FirstDisplayLevel))-1,&curdisplay);
#endif
			/**/
			/*****************************************************/
		}
		/***/
		if ((diagnostics!=0)||((Props&32)==0)) 	/*there are internal blocks or procs*/{
			/*****************************************************/
			/* stack current frame pointer                      **/
			/*****************************************************/
			/**/

#if(Target==SPARC) 
			ARCH(storeri(ST,FRAMEPOINTER,FRAMEPOINTER,curdisplay));
#endif
			/**/

#if((Target==RS6)||(Target==MIPS)) 
			estkaddr(STACK,0,0,4);
			estkdir(STACK,curdisplay,0,4);
			eop(ESTORE);
#endif
			/**/
			/**/
			/* on RS6000 we need a further item to access parameters when these exist    */
			/**/

#if(Target==RS6) 
			if ((PI->ipcnt|PI->fpcnt)!=0) {

#if(TargetABI!=SunsoftABI) 
				int reg=FRAMEPOINTER;
				/**/
				/* if this proc has a hidden parameter then adjust the pointer to ignore     */
				/* it and make no other adjustments. the alternatine is to have a variant    */
				/* of madjustparam for globals and this will be needed if any Language       */
				/* allows aggregate results to be returned from within an inner proc         */
				/* variable size aggregate results defeat the RS6000 scheme anyway           */
				/**/
				if ((PI->procprops&PP_RETURNSAG)!=0) {
					ARCH(oplit(addi,FRAMEPOINTER,4,rZERO));	/* rZERO is junkhole                */
					reg=rZERO;
				}
				ARCH(storeri(st,reg,FRAMEPOINTER,(curdisplay-4)+Saveareasize));

#else
				estkaddr(STACK,PI->pseudoparams+(4*(((unsigned)PI->procprops>>9)&1)),0,4);
				estkdir(STACK,curdisplay-4,0,4);
				eop(ESTORE);

#endif
				PI->privprops|=NONVIRTUALFP;
			};
			/* Target=rs6*/

#endif
			/*****************************************************/
		}
	}
	/***/
	if (diagnostics!=0) {

#if(Target==RS6) 
		displayextra=4;
#else
		displayextra=0;
#endif
		/* rs6 has extra word in display for param access even at top level          */

#if(Language==IMP) 
		insmarker=1229211969;
		markerad=-(((Proclevel*4)+8)+displayextra);

#else

#if(Language==FORTRAN) 
		if ((Language==FORTRAN)&&(paramchecks!=0)) {
			insmarker=1178880322;
		} else {
			insmarker=1178880321;
		}
		markerad=-12;

#else

#if(Language==PASCAL) 
		insmarker=1346652481;
		if (Proclevel<FirstDisplayLevel)  markerad=-12; 
		else markerad=-(((Proclevel*4)+4)+displayextra);
		;

#else

#if(Language==MODULA) 
		insmarker=1296320833;
		if (Proclevel<FirstDisplayLevel)  markerad=-12; 
		else markerad=-(((Proclevel*4)+4)+displayextra);
		;

#else
		insmarker=1480870209;
		markerad=-8;

#endif
#endif
#endif
#endif
		/**/

#if(Target==SPARC) 
		ARCH(loadlit(insmarker,OUTPARAM1REG));
		ARCH(storeri(ST,OUTPARAM1REG,FRAMEPOINTER,markerad));
#endif
		/**/

#if((Target==RS6)||(Target==MIPS)||(Target==PENTIUM)) 
		estklit(insmarker);
		estkdir(STACK,markerad,0,4)	/*stack marker word*/;
		eop(ESTORE);
#endif
		/**/
		PI->markerad=markerad;
		/**/
		if (setlineno==0) {

#if(Target==SPARC) 
			ARCH(storeri(ST,rZERO,FRAMEPOINTER,markerad-12));

#else
			estklit(0);	/*zero out the line number */
			estkdir(STACK,markerad-12,0,4)	/*     word if no dynamic  */;
			eop(ESTORE);	/*     line-number updating*/

#endif
		}
		/**/

#if((Language==FORTRAN)||(Language==PASCAL)||(Language==MODULA)) 
		/********************************************************/
		/* generate a sequence for noting the diag displacement**/
		/********************************************************/
		/**/
		PI->setdiag=Mmarker();
		/**/

#if(Target==SPARC) 
		ARCH(loadlit(0x7FFF	/*to reserve space for a large const*/,OUTPARAM1REG+1));
		ARCH(access(StoreIntVal,OUTPARAM1REG+1,STACK,markerad-8,4,0,0));
#endif
		/**/

		/**/

#if((Target==RS6)||(Target==MIPS)||(Target==PENTIUM)) 
		ARCH(notediagdisp(0x10001,markerad-8));
#endif
		/**/
#endif
	}
	/**/
	if ((Language==FORTRAN)&&(paramchecks!=0)) {
		/************************************************/
		/* Set up frame pointer if not already done so **/
		/************************************************/
		/**/

		/**/
	}
	/**/
	/*****************************************************/
	/* reset register memory                            **/
	/*****************************************************/
	/**/

#if(Target==SPARC) 
	Ccountparams((int *)Aparamprops,0);
	/* safeguards the parameters either by offloading them                       */
	/* into the parameter area and updating register memory                      */
	/* (if IMP, PASCAL, Optimising FORTRAN) or by never                          */
	/* allocating the associated registers (non-optimising                       */
	/* FORTRAN).                                                                 */
#endif
	/**/

	/**/
	if (((Target==RS6)||(FPUtraps!=0)||(Language==IMP))&&((Props&2)!=0)) {
		/*****************************************************/
		/* initialise floating point traps                  **/
		/*****************************************************/
		/**/
		CsetFPUtraps();
	}
	/*****************************************************/
	/***/
}	/* Mstartproc  */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
void Msideentry(int Id,int Eindx,int Aparamprops,int Localsize,int Diagdisp) {
	/*************************************************************************/
	/** generate code at FORTRAN side entry                                 **/
	/**                                                                     **/
	/**    if Eindx = 0 then this is the call for the subroutine or         **/
	/**    function name and most of the code has already been generated    **/
	/**    in Mstartproc -- only the parameter register handling is         **/
	/**    relevant here                                                    **/
	/**                                                                     **/
	/**    Eindx > 0 implies a real side entry                              **/
	/*************************************************************************/
	struct fragfmt *frag;
	struct instrfmt *instr,*prevdiaginstr;
	struct Exdatafmt *exdata;
	int prevframe,diamarker,profiledataoffset,savefpflag;

	if (Eindx>0) {
		BNewFrag();
		frag=PI->curfrag;
		frag->entryid=Id;
		exdata=exrecad(Id);
		exdata->Props=PP_EXTERNAL;	/* external */
		PI->procprops|=PP_HASSIDEE;	/* This bit is vital for tidyproc       */

		/* Mark the symbol as being defined as a procedure entry */
		exdata->flags=exdata->flags|32;

	}

	/*****************************************************/
	/* clear register use                               **/
	/*****************************************************/
	/**/
	rclearregs(0);
	PI->procprops|=PP_HASSIDEE;	/*force in side entry bit               */
	/*clean up routine need to know                                              */
	/**/
	if (Eindx>0) {
		/**/
		/*****************************************************/
		/* generate stack frame creation code               **/
		/*****************************************************/
		/**/
		if ((Language==FORTRAN)&&(paramchecks!=0)) {
			/******************************************************/
			/* save previous frame pointer for parameter checking**/
			/******************************************************/
			/**/
			savefpflag=0;

#if(Target==SPARC) 
			if ((PI->procprops&PP_SETUNASS)==0) {
				ARCH(storeri(ST,FRAMEPOINTER,STACKPOINTER,-16));
			} else {
				/*******************************************************/
				/* filling the stack frame with the unassigned pattern**/
				/* will corrupt FRAMEPOINTER+16 - save the caller's fp**/
				/* in SAVEFGREG and then store it in FRAMEPOINTER+16  **/
				/* after the stack frame has been filled              **/
				/*******************************************************/
				/**/
				ARCH(rr(OR,FRAMEPOINTER,rZERO,SAVEFPREG));
				savefpflag=1;
			};

#endif
			/**/

			/**/
			/* MIPS: can not do this till after frame claim                              */
			/**/
		}
		/**/
		prevframe=(int)PI->framemark;
		/**/

#if(Target==SPARC) 
		PI->framemark=ARCH(framesetup());
		if (Pic>0) {
			frag=PI->curfrag;
			frag->props|=NOOPTIMFRAG;
			ARCH(GOTfix(GOTREG));
		};

#endif
		/**/



#if(Target==RS6) 
		BBreakFrag(0);	/* Wrappers will go in here */
		if ((TargetABI==SunsoftABI)&&(Pic!=0)) {
			ARCH(GOTfix(GOTREG));
		}
		Ccountparams((int *)Aparamprops,1);
#endif
		/**/

#if(Target==MIPS) 
		if (Pic!=0) 	/*In Pic mode load GOT here*/{
			frag=PI->curfrag;
			if (Pic==1)  frag->props|=NOOPTIMFRAG;
			ARCH(GOTfix(GOTREG));
		}
		PI->framemark=Mmarker();
		ARCH(loadlit(0x10010,rWORK));
		ARCH(rr(add,STACKPOINTER,rWORK,STACKPOINTER));
		ARCH(modinstrprops(0,FRAMEMODIFY,0,0));
		BBreakFrag(0);	/* Wrappers instructions inserted here                       */
		if ((Language==FORTRAN)&&(paramchecks!=0)) {
			PI->privprops|=NONVIRTUALFP;	/* Code planting deferred into do wrapping */
		}
		Ccountparams((int *)Aparamprops,1);
		if (Pic!=0) {
			ARCH(access(StoreIntVal,GOTREG,STACK,PI->GOTsave,4,0,0));
			ARCH(modinstrprops(0,0,0,GOTREDTAPE));
		};

#endif
		/**/

#if(Target==PENTIUM) 
		BBreakFrag(0);	/* wrapper instructions inserted here */
		Ccountparams((int *)Aparamprops,1);
		if (Pic!=0) 	/*In Pic mode load GOT here*/{
			frag=PI->curfrag;
			frag->props|=NOOPTIMFRAG;
			ARCH(GOTfix(GOTREG));
		};

#endif
		/**/
		if (PI->framemark!=NULL) 	/* check we are keeping framemarks */{
			instr=PI->framemark;
			instr->u1.immval=prevframe;	/* chain in previous entrypoint */
		}
		/**/
		/*****************************************************/
		/* load GLA register                                **/
		/*****************************************************/
		/**/

#if((Target==SPARC)||(Target==MIPS)||(Target==RS6)) 
		ARCH(ldfix(GLA,0,GLAREG));
#endif
		/**/
		if (profile!=0) {
			/*****************************************************/
			/* produce profiling information                    **/
			/* No profiling code is generated for local IMP     **/
			/* procedures at the top level - this cuts out      **/
			/* all the private routines at the beginning        **/
			/* of a compilation                                 **/
			/*****************************************************/
			/**/
			profiledataoffset=epermspace(4,4);
			if ((LanguageVariant==FORTRAN90)&&(diagnostics!=0)) {
				pd4(GLA,profiledataoffset,0);
				/*when compiling with unassigned variable checking */
				/*on Fortran90 will pre-fill GLA to the unassigned */
				/*pattern - thus this location has to be explicitly*/
				/*initialised to zero.                             */
			}
			/**/
			/**/

#if(Target==SPARC) 
			if (Pic!=0) {
				ARCH(ldfix(GLA,0,OUTPARAM1REG));
				if ((profiledataoffset<-4096)||(profiledataoffset>4095)) {
					ARCH(loadlit(profiledataoffset,L0REG));
					ARCH(rr(ADD,OUTPARAM1REG,L0REG,OUTPARAM1REG));
				} else {
					ARCH(rlit(ADD,OUTPARAM1REG,profiledataoffset,OUTPARAM1REG));
				}
			} else {
				ARCH(ldfix(GLA,profiledataoffset,OUTPARAM1REG));
			}
			ARCH(call(ProfileId,-4,0));
			rclearcallregs();
#endif
			/**/

#if((Target==RS6)||(Target==MIPS)) 
			{
				struct Stkfmt Lstk;
				gladir(&Lstk,profiledataoffset,4);
				Lstk.Form=AddrDir;
				ARCH(stkaccess(StoreIntVal,OUTPARAM1REG,&Lstk));	/* addr profiledata as param*/
			}
			ARCH(call(ProfileId,-4,0));

#if(Target==RS6) 
			/* will be changed to a TOC reload if required by linker */
			ARCH(rr(cror,31,31,31));
			ARCH(modinstrprops(0,0,0,SCHRESTRICTINSTR));
#endif
			rclearcallregs();
#endif
			/**/

			/**/

#if(Target==PENTIUM) 
			ARCH(oprfixmem(LEA,GLA,profiledataoffset,EDX,4));
			ARCH(modinstrprops(DESTROYABLE,0,0,0))  /* remove destroyable*/;
			Ccall(ProfileId,0,0,0);
#endif
			/**/
		}
		/**/
		if (Lineprof!=0) {
			/*****************************************************/
			/* produce line-profiling information - generate    **/
			/* code to perform initialisation if required       **/
			/*****************************************************/
			/**/
		}
		/**/
		if ((PI->procprops&PP_SETUNASS)!=0) {
			/*****************************************************/
			/* Fill the Stack Frame with the Unassigned Pattern **/
			/*****************************************************/
			/**/

#if(Target==SPARC) 
			int labEindx,label;
			int prevunassignmark=(int)PI->unassignmark;
			PI->unassignmark=Mmarker();
			instr=(struct instrfmt*)(PI->unassignmark);
			instr->u1.immval=prevunassignmark;

			ARCH(loadlit(0x7FFF	/*reserve for a large constant*/,L0REG));
			ARCH(floadri(LDDF,GLAREG,UnassignedDisp,F0REG));
			label=Mprivatelabel();
			Mplabel(label);
			ARCH(oplit(ADDcc,L0REG,8,L0REG));
			labEindx=BLocateLabel(label+Labadjust,0);
			ARCH(ibcc(NE,labEindx,Annul));
			ARCH(fstorerr(STDF,F0REG,FRAMEPOINTER,L0REG));
			/**/
			/* GENERATES:     OR    %G0,-count,%L0                                       */
			/*                LDDF  [%L7+x],%F0                                          */
			/*             A: ADDCC %L0,8,%L0                                            */
			/*                BNE,A A                                                    */
			/*                STDF  %F0,[%FP+%L0]                                        */

#if(Language==FORTRAN) 
			if ((paramchecks!=0)&&(savefpflag!=0)) {
				ARCH(storeri(ST,SAVEFPREG,FRAMEPOINTER,-16));
			};

#endif
#endif
			/**/
		}
		/**/
		if (diagnostics!=0) {
			/*****************************************************/
			/* stack gla address                                **/
			/*****************************************************/
			/**/

#if((Target==SPARC)||(Target==MIPS)) 
			ARCH(storeri(ST,GLAREG,FRAMEPOINTER,-4));
#endif
			/**/

			/**/
		}

		if ((diagnostics!=0)||
			((Language==FORTRAN)&&(LanguageVariant==FORTRAN90)&&((PI->procprops&(PP_NODISPLAY|PP_NOINTERNAL))==0))) {
			/*****************************************************/
			/* stack current frame pointer                      **/
			/*****************************************************/
			/**/

#if(Target==SPARC) 
			ARCH(storeri(ST,FRAMEPOINTER,FRAMEPOINTER,-8));
#endif
			/**/

			/**/
			if (((Language!=FORTRAN)&&(LanguageVariant!=FORTRAN90))||(diagnostics!=0)) {

				if ((Language==FORTRAN)&&(paramchecks!=0)) {
					diamarker=1178880322;
				} else {
					diamarker=1178880321;
				}
				/**/

#if(Target==SPARC) 
				ARCH(loadlit(diamarker,OUTPARAM1REG));
				ARCH(storeri(ST,OUTPARAM1REG,FRAMEPOINTER,-12));
#endif
				/**/

#if((Target==RS6)||(Target==MIPS)||(Target==PENTIUM)) 
				estklit(diamarker);
				estkdir(STACK,-12,0,4)	/*stack marker word*/;
				eop(ESTORE);
#endif
				/**/
				if (setlineno==0) {

#if(Target==SPARC) 
					ARCH(storeri(ST,rZERO,FRAMEPOINTER,-24));

#else
					estklit(0);	/*zero out the line number */
					estkdir(STACK,-24,0,4)	/*     word if no dynamic  */;
					eop(ESTORE);	/*     line-number updating*/

#endif
				}

				/********************************************************/
				/* stack the diag displacement                         **/
				/********************************************************/
				/**/
				prevdiaginstr=PI->setdiag;
				PI->setdiag=Mmarker();
				instr=(struct instrfmt*)(PI->setdiag);
				instr->u1.linkedinstr=prevdiaginstr;
				/**/

#if(Target==SPARC) 
				ARCH(loadlit(0x7FFFF,OUTPARAM1REG+1));
				ARCH(access(StoreIntVal,OUTPARAM1REG+1,STACK,-20,4,0,0));

#else

				ARCH(notediagdisp(0x1000,-20));
#endif

			}
			/**/
		}

	}

	/*****************************************************/
	/* reset register memory                            **/
	/*****************************************************/
	/**/

#if(Target==SPARC) 
	Csideentry(Eindx);
	Ccountparams((int *)Aparamprops,1);
#endif
	/**/

	/**/

}	/* Msideentry */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
int Mtidyproc(int Proclevel,int Localsize,int Diagdisp) {
	/********************************************************************/
	/** Process the current procedure after the body as been generated **/
	/********************************************************************/
	struct fragfmt *Level0,*lastuserfrag;
	struct instrfmt *instr,*lastuserinstr;
	int PIaddr;
	int Level0gen,framesize,rangeproc;
#if (Target==SPARC || Target==RS6)
	int ^unassignfilllen,offset;
	struct instrfmt *unassignmarkinst;
#endif
#if((Target==MIPS))
	int imask,fmask,I;
#endif


#if((Language==FORTRAN)||(Language==PASCAL)||(Language==MODULA)) 

#if(Language==FORTRAN) 
	Localsize=-Localsize;
#endif
	if (diagnostics!=0) {
		Msetopd(PI->setdiag,Diagdisp);
	};

#endif
	Localsize=(Localsize+7)&(-8);
	PI->localsize=Localsize;
	lastuserfrag=PI->curfrag;
	lastuserinstr=(struct instrfmt*)(lastuserfrag->lastinstr);
	/***/

#if((Target==RS6)||(Target==MIPS)||(Target==PENTIUM)) 
	Mplabel(PI->returnlab);	/*returns to here also breaksfrag                   */
	/*and hence integrates reguse bit strips                                     */
#endif
	/**/
	/* For RS6000 generate complex return code here. In line returns jump        */
	/* to end since the code is too complex to generate inline                   */
	/**/
	if (diagnostics!=0) {
		lockreg(RESULTREG);
		estklit(0);
		estkdir(STACK,PI->markerad,0,4);
		eop(ESTORE);	/* remove IDIA,FDIA etc                                        */
		unlockreg(RESULTREG);
	}
	/**/

#if((Target==MIPS)||(Target==RS6)) 
	ARCH(regreduction());
#endif
	/**/


	/**/

#if(Target==RS6) 
	/**/
	/* now work out the saveareasize          */
	/**/
	{
		int maxoffset,lowreg,I;
		maxoffset=0;
		for (I=14; I<=31; I++) {
			if ((((1<<I)&PI->fdef))!=(0)) {
			/*this one has been used        */
				maxoffset=-(8*(32-I));
				break ;
			}
		}
		lowreg=13;
		while ((lowreg<32)&&(((1<<lowreg)&(PI->rdef|PI->rref))==0))  lowreg++;
		PI->saveareasize=abs(maxoffset-(4*(32-lowreg)));
		if ((PI->saveareasize&7)!=0)  PI->saveareasize=PI->saveareasize+4;
	}
	/* special for RS6 returns*/
#endif
	/**/

#if(Target==MIPS) 
	imask=(PI->rdef&CALLEESAVEDREGS)&0x7FFFFFFF;
	fmask=PI->fdef&CALLEESAVEDFREGS;
	if ((PI->privprops&(NONVIRTUALFP|NESTEDCALLS))!=0) {
		imask|=1<<FRAMEPOINTER;
		PI->rdef=PI->rdef|(1<<FRAMEPOINTER);
	}
	if ((PI->privprops&NOTLEAFRT)!=0) {
		imask|=0x80000000;	/* 1 << 31 */
	}
	if (Pic!=0)  PI->saveareasize=4; 
	else PI->saveareasize=0;
	;
	/* allow 1 extra word in case of action by improve GOT reloads               */
	for (I=0; I<=31; I++) {
		if ((imask&(1<<I))!=0) {
			PI->saveareasize=PI->saveareasize+4;
		}
		if ((fmask&(1<<I))!=0) {
			PI->saveareasize=PI->saveareasize+8;
		}
	}
	PI->saveareasize=(PI->saveareasize+7)&(-8);
#endif
	/**/
	/*****************************************************/
	/* adjust the size of the parameter save area       **/
	/*****************************************************/
	/**/

#if(Target==SPARC) 
	if ((PI->outparsize!=0)&&(PI->outparsize<24)) {
		PI->outparsize=24;
	}
	PI->outparsize=(PI->outparsize+7)&(-8);
#endif
	/**/

	/**/

#if(Target==RS6) 
	if (((TargetABI==AIXABI)||(TargetABI==ADIABI))&&((PI->cdef&(1<<LR))!=0)&&(PI->outparsize<32)) {
		PI->outparsize=32;
	}
	/* Next line only till sun C compiler abi compliant                          */
	if ((TargetABI==SunsoftABI)&&((PI->cdef&(1<<LR))!=0)&&(PI->outparsize<32))  PI->outparsize=32;
	PI->outparsize=(PI->outparsize+7)&(-8);
#endif
	/**/

#if(Target==MIPS) 
	if (PI->outparsize<16)  PI->outparsize=16;
	PI->outparsize=(PI->outparsize+7)&(-8);
#endif
	/**/
	/*****************************************************/
	/* adjust frame reservation size                    **/
	/*****************************************************/
	/**/
	PI->framesize=(PARAMBASE+PI->saveareasize)+PI->localsize;
	PI->ffsize=PARAMBASE+PI->saveareasize;

#if(Target!=PENTIUM) 
	/* outgoing parameters pushed on stack so not included in stack */
	/* frame size on pentium                                        */
	PI->framesize=PI->framesize+PI->outparsize;
	PI->ffsize=PI->ffsize+PI->outparsize;
#endif
	PI->framesize=(PI->framesize+7)&(-8);
	if ((Target==RS6)) {
		PI->framesize=(PI->framesize+15)&(-16);
	}
	PI->ffsize=(PI->ffsize+7)&(-8);
	/**/
	/* handle stack reaches bigger than 64K on M88K */

	/**/
	/* handle stack frames bigger than 32K on RS/6000 */

#if(Target==RS6) 
	/* if the frame size exceeds 32K then we do not shrink the save area */
	/* since the gain is less than 0.5% and the complications enormous   */
	/* with the integer offsets being optimised by loadlit               */
	if ((PI->framesize&0xFFFF8000)!=0) {
		PI->saveareasize=-Saveareasize;
		PI->framesize=((PARAMBASE+PI->outparsize)-Saveareasize)+PI->localsize;
		PI->framesize=(PI->framesize+15)&(-16);
		PI->ffsize=(PARAMBASE+PI->outparsize)-Saveareasize;
		PI->ffsize=(PI->ffsize+7)&(-8);
		PI->privprops|=NONVIRTUALFP;
	}
	if ((PI->privprops&PARAMSSPILLED)!=0) 	/* Only set with SunsoftABI*/{
		PI->framesize=PI->framesize+96;
		PI->ffsize=PI->ffsize+96;	/* Allow for spilling at call time */
	};

#endif
	/**/
	/* handle cases on MIPS where the reach required from the stack pointer  */
	/* is more than 32K - we need to access the incoming parameters from our */
	/* stack pointer                                                         */

#if(Target==MIPS) 
	/* we pretend that we have to save all the registers when seeing       */
	/* if the required reach is bigger than 32K - this is in case the size */
	/* of the register save area increases due to global scheduling        */

	{
		int reachreq,potensize;
	reachreq=(((PARAMBASE+PI->outparsize)+MAXSAVESIZE)+PI->localsize)+PI->inparsize;
		reachreq=(reachreq+7)&(-8);
		if (reachreq>32767) {
			/* we set up a proper frame pointer if the reach is too big */
			if (((PI->privprops&(NESTEDCALLS|NONVIRTUALFP))==0)&&((imask&(1<<FRAMEPOINTER))==0)) {
				PI->rdef=PI->rdef|(1<<FRAMEPOINTER);
				PI->saveareasize=(PI->saveareasize+11)&(-8);
				PI->framesize=((PARAMBASE+PI->outparsize)+PI->saveareasize)+PI->localsize;
				PI->framesize=(PI->framesize+7)&(-8);
				PI->ffsize=(PARAMBASE+PI->outparsize)+PI->saveareasize;
				PI->ffsize=(PI->ffsize+7)&(-8);
			}
			PI->privprops|=NONVIRTUALFP;
		}
		potensize=((PARAMBASE+PI->outparsize)+MAXSAVESIZE)+PI->localsize;
		potensize=(potensize+7)&(-8);
		if ((potensize>32767)||((PI->privprops&(NESTEDCALLS|NONVIRTUALFP))!=0)) 
			PI->privprops|=NOREGEXPAN;
	};

#endif


#if((Target==MIPS)||(Target==PENTIUM)||(Target==RS6)) 
	ARCH(dowrapping(Localsize,cgoptions));
#endif


#if((Target==MIPS)||(Target==SPARC)) 
	Msetopd(PI->framemark,-PI->framesize);
#endif


#if(Target==SPARC) 
	if (PI->unassignmark!=NULL) {
		/*********************************************************/
		/* adjust count for filling the stack with Unassigned's **/
		/*********************************************************/
		/**/
		unassignfilllen=(PI->framesize-0x40)+8;	/* window dump area*/
		Msetopd(PI->unassignmarkinstr,-unassignfilllen);
	};

#endif


#if(Target==RS6) 
	if ((PI->fdef!=0)&&((cgoptions&CHKOFLOW)!=0)) {
		Mplabel(PI->returnlab+1);	/* soft error exit                                */
		ARCH(rr(trp,rZERO,rZERO,31));	/* always traps                               */
	}
	unassignmarkinstr=PI->unassignmark;
	if (unassignmarkinstr!=NULL) {

#if(((TargetABI==AIXABI)||(TargetABI==ADIABI))) 
		unassignfilllen=Localsize-24;	/* Dont tramp on idia */
		offset=16+PI->outparsize;
		/* No dummped param regs */

#else
		if (PI->pseudoparams==0) {
			unassignfilllen=Localsize-24;
			offset=PI->framesize-(Localsize+PI->saveareasize);
		} else {
			offset=(((PI->framesize+PI->pseudoparams)+PI->inparsize)-PI->saveareasize)-8;
			unassignfilllen=PI->framesize-offset-PI->saveareasize-24;	/*idia*/
		}
#endif
		offset=(offset+7)&(-8);
		while (unassignmarkinstr!=NULL) {
			instr=unassignmarkinstr;
			unassignmarkinstr=instr->u1.linkedinstr;
			while ((instr->nextinstr!=0)&&(instr->opcode!=addi))  instr=instr->nextinstr;
			if (instr->opcode==addi)  instr->u1.immval=offset;
		}
		unassignfilllen=(unsigned)unassignfilllen>>3;
		if (unassignfilllen<=0)  unassignfilllen=1;
		Msetopd(PI->unassignmark,unassignfilllen);	/*in double words on rs6000      */
	};

#endif


#if(Target==MIPS) 
	/**/
	/* if the last instr planted was DBXINFO for end of fn then move it          */
	/* so it is after any wrappers that have been added in this routine          */
	/**/
	if (((int)lastuserinstr!=0)&&(lastuserinstr->group==DBXINFO)) {
		BMoveAfter(lastuserfrag,(struct fragfmt *)PI->curfrag,lastuserinstr,BCurInstr());
	}
	if (PI->unassignmark!=NULL) {
		Msetopd(PI->unassignmark,((unsigned)(Localsize-8)>>3));	/*in double words on MIPS*/
	};

#endif


#if(Target==PENTIUM) 
	/**/
	/* if the last instr planted was DBXINFO for end of fn then move it          */
	/* so it is after any wrappers that have been added in this routine          */
	/**/
	if (((int)lastuserinstr!=0)&&(lastuserinstr->group==DBXINFO)) {
		BMoveAfter(lastuserfrag,(struct fragfmt *)PI->curfrag,lastuserinstr,BCurInstr());
	}
	if (PI->unassignmark!=NULL)  Msetopd(PI->unassignmark,((unsigned)((Localsize-(4*Proclevel))-4)>>2));	/*in 
	words on PENTIUM                                                             */
#endif


	/* check if code is required to  */
	if ((PI->auxstacklab!=0)&&(PI->auxstacklab!=-1)) 	/* receive a jump from an EAUXADD*/	/* or EAUXRES when the generated */{
		Mplabel(PI->auxstacklab);	/* code dynamically detects an   */
		estklit(1);	/*param to s#auxst*/
		/* error                         */
		Mspcall(21);	/*s#auxst*/
		eop(DISCARD);	/*discard ESTKRESULT*/
	}
	/* check for code emitted */

	/*****************************************************/
	/* add procedure end record to frag                 **/
	/*****************************************************/
	/**/
	Level0=(struct fragfmt*)(ProcInfo [0].procfrag);	/* outwith Eproc/Eprocend */
	Level0gen=0;
	/**/
	/* remove and DBXinfo on back of level 0 frags to stact of current proc      */
	/**/
	while (((int)Level0!=0)&&(Level0->lastinstr!=0)) {
		instr=(struct instrfmt*)(Level0->lastinstr);
		if (!(instr->group==DBXINFO))   break ;
		BMoveAfter(Level0,(struct fragfmt *)PI->procfrag,Level0->lastinstr,NULL);/* after NULL == At the very front!!*/
	}
	if (((int)Level0!=0)&&(Level0->firstinstr!=0)) 	/* and generate it */{
		PI=&ProcInfo [0];
		PIaddr=(int)&ProcInfo [0];
		currentPIaddr=PIaddr;
		CsetPI(PI);
		BSetPI(PIaddr);
		rangeproc=BGetTraceProc();
		if ((rangeproc==0)||(rangeproc==PI->procnum)) {
			Creport(GlobCodeReport);
		} else {
			Creport(0);
		}
		tidyfrags(0,(int)ProcInfo [0].procfrag);
		ProcInfo [0].procfrag=0;
		ProcInfo [0].curfrag=0;
		Level0gen=1;
		PI=&ProcInfo [Proclevel];
		PIaddr=(int)&ProcInfo [Proclevel];
		currentPIaddr=PIaddr;
		CsetPI(PI);
		BSetPI(PIaddr);
		if ((rangeproc==0)||(rangeproc==PI->procnum)) {
			Creport(GlobCodeReport);
		} else {
			Creport(0);
		}
	}

	/* generate code for this procedure - note that this may modify the */
	/* stack frame size                                                 */
	tidyfrags(Proclevel,(int)PI->procfrag);
	framesize=PI->framesize;


#if((Target==RS6)||(Target==MIPS)||(Target==PENTIUM)) 
	reclaimswspace(PI->swmark);
#endif

	if (Level0gen!=0) {
		PI=&ProcInfo [0];
		PIaddr=(int)&ProcInfo [0];
		currentPIaddr=PIaddr;
		CsetPI(PI);
		BSetPI(PIaddr);
		BNewFrag();
		PI->procfrag=PI->curfrag;
	}

	PI=&ProcInfo [Proclevel-1];
	PIaddr=(int)&ProcInfo [Proclevel-1];
	currentPIaddr=PIaddr;
	CsetPI(PI);
	BSetPI(PIaddr);
	rangeproc=BGetTraceProc();
	if ((rangeproc==0)||(rangeproc==PI->procnum)) {
		Creport(GlobCodeReport);
	} else {
		Creport(0);
	}
	/**/
	/*****************************************************/
	/* restore state of dynamic procedure information   **/
	/*****************************************************/
	/**/
	rclearregs(0);
	/**/
	Labadjust=PI->labadjust;
	PI->procprops&=~PP_NOINTERNAL;	/* Inners found unset no inners bit */
	/**/

#if(Target==SPARC) 
	*clowregmap()=PI->lowreg;
#endif
	/**/

	/**/
	return framesize;	/* return adjusted stack frame size */
}	/* Mtidyproc */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
/***/
/**************************************************************************/
/**                                                                      **/
/**            call support procedures                                   **/
/**                                                                      **/
/**************************************************************************/
/***/
#if(Target==SPARC) 
static int CheckAlignment(struct Stkfmt *Stk) {
	/*******************************************************************/
	/** determines whether the Estack entry represents a item which   **/
	/** is doubleword aligned - the Estack entry must be known to be  **/
	/** of type Real or Complex                                       **/
	/**                                                               **/
	/** returns: 0 for no/not doubleword aligned                      **/
	/**          1 for yes/doubleword aligned                         **/
	/*******************************************************************/
	if ((Stk->Type==MisRealType)||((Stk->Form==DirVal)&&((Stk->Offset&7)!=0)))  return 0;
	return 1;
}	/* Check Alignment */
#endif

void Mexpcall(int Proc) {
	/*************************************************************************/
	/** call a library routine                                              **/
	/*************************************************************************/
	int I,J,T,Proctype,Paramcnt,ParamsSize,Parndx;
	char S [32];



#if(Target==SPARC) 
	if ((Proc==5)||(Proc==13)) 	/*f_powzi*/	/*f_powzz*/{
		if ((CheckAlignment(&Stk [Elevel-2])==0)||(CheckAlignment(&Stk [Elevel-1])==0)||((Proc==13)&&(CheckAlignment
		    (&Stk [Elevel])==0))) {
			if (Proc==5)  Proc=28; 
			else Proc=29;
			;
		}
	};

#endif
	T=Expproctype [Proc];
	J=Expprocref [Proc];
	if (J==0) {
		strcpy(S,Expprocs [Proc]);
		if (Language==PASCAL && S[1]=='_' && S[0]=='f')
			S[0]='p';
		/* Byte 1 of expproctype has the information on whether the name is          */
		/* a normal unix name (underscores to be appended) or special(dont tamper)   */
		/* unfortunately it is inverted!                                             */
		/**/

#if((Language==CCOMP)&&(LanguageVariant==USLC)) 
		strcpy(S,imp_concat(S,imp_tostring(0)));
		J=Iextname((int)S+1);

#else
		J=ecxname(((((unsigned)T>>16)&1)^1),S);

#endif
		Expprocref [Proc]=J;
	}
	I=Expprocpdesc [Proc];
	ParamsSize=I&0xFFFF;
	Paramcnt=(unsigned)I>>16;
	I=Paramcnt;
	/*      %IF Target=SPARC %AND T&x'ffff'=x'1002'  %START                      */	/*longlongfn*/
	/*         Spparams(0) = I+1                                                 */
	/*         Spparams(1) = ParamsSize+4                                        */
	/*         Spparams(I+2) = x'0e000004'                                       */
	/*         %WHILE I > 0 %CYCLE                                               */
	/*            Spparams(I+1) = Expparaminfo((Proc*MAXEXPPARAM) + I - 1)                 */
	/*         %IF Spparams(I+1) = x'02000010' %THEN Spparams(I+1) = x'4'        */
	/*            I = I - 1                                                      */
	/*         %REPEAT                                                           */
	/*      %ELSE                                                                */
	Spparams [0]=I;
	while (I>0) {
		Spparams [I+1]=Expparaminfo [(((Proc*MAXEXPPARAM)+I)-1)];
		if ((Target==SPARC)&&(Spparams [I+1]==0x2000010)) {
			Spparams [I+1]=0x4; 
			ParamsSize-=12;
		}
		I--;
		Spparams [1]=ParamsSize;
	}
	/*     %FINISH                                                               */
	eprecall2(J,(int)&Spparams [0]);
	I=Paramcnt;
	while (I>0) {

#if(ParamDirection==Positive) 
		epromote(I);
#endif
		if (Stk [Elevel].Size<4) {
			estklit(4);
			eop(CVTII);
		}

#if(Target==PENTIUM) 
		Parndx=((Proc*MAXEXPPARAM)+I)-1;

#else
		Parndx=((Proc*MAXEXPPARAM)+Paramcnt)-I;

#endif
		if ((((unsigned)Expparaminfo [Parndx]>>24)==0)||((Target==SPARC)&&(Expparaminfo [Parndx]==0x2000010)
		    )) 	/*longlongfn*/{
			Caddress(&Stk [Elevel]);
			Stk [Elevel].Size=4;
		}
		eop(PUSHVAL);
		I--;
	}
	if ((Target==SPARC)&&((T&0xFFFF)==0x1002)) 	/*longlongfn*/{
		I=etempspace(16,8);
		esetstructresult(I,16,8);
	}
	Proctype=(unsigned)T>>24;
	Mcall(J,1,Paramcnt,ParamsSize,Proctype<<24);
	if ((T&7)!=0) {
		/* function                                                                  */
		if ((Target==SPARC)&&((T&0xFFFF)==0x1002)) 	/*longlongfn*/{
			estkresult(0,StructType,(((unsigned)T>>8)&255));
			erefer(0,0x2000010);
		} else {
			estkresult(0,T&7,(((unsigned)T>>8)&255));
		}
	}
}	/* Mexpcall  */
/**/
/* Copyright (c) 1987 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
void Mspcall(int Proc) {
	/*************************************************************************/
	/** call a support procedure                                            **/
	/*************************************************************************/
	int I,J,T;
	char S [32] ,pre [32] ,rest [32] ;
	T=Spproctype [Proc];
	J=Spprocref [Proc];
	if (J==0) {
		strcpy(S,Spprocs [Proc]);
		if ((Language==PASCAL)&&(imp_resolve(S,pre,"f_",rest)==0)&&(strlen(pre)==0))  strcpy(S,imp_concat("p_",rest
		    ));

#if((Language==CCOMP)&&(LanguageVariant==USLC)) 
		strcpy(S,imp_concat(S,imp_tostring(0)));
		J=Iextname((int)S+1);

#else
		J=ecxname(((((unsigned)T>>16)&1)^1),S)	/* See comment in Mexpcall at corresponding point*/;

#endif
		Spprocref [Proc]=J;
	}
	I=(unsigned)Spprocpdesc [Proc]>>16;
	Spparams [0]=I;	/* numpars   */
	Spparams [1]=Spprocpdesc [Proc]&0xFFFF;	/* paramsize */
	while (I>0) {
		Spparams [I+1]=0x4;	/* ptrval / 4*/
		I--;
	}
	eprecall2(J,(int)&Spparams [0]);
	I=(unsigned)Spprocpdesc [Proc]>>16;
	while (I>0) {

#if(ParamDirection==Positive) 
		epromote(I);
#endif
		if ((Proc==27)||(Proc==28))  eop(PUSHADDR); 
		else eop(PUSHVAL);
		I--;
	}
	I=Spprocpdesc [Proc];
	Mcall(J,1,(unsigned)I>>16,I&0xFF,T&0xff000000);
	if ((T&7)!=0) {
		/* function                                                                  */
		estkresult(0,T&7,(((unsigned)T>>8)&255));
	}
}	/* Mspcall */
/**/
/* Copyright (c) 1987 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
/***/
/**************************************************************************/
/**                                                                      **/
/**            provide storage for a constant                            **/
/**                                                                      **/
/**************************************************************************/
/***/

#if((Target==SPARC)||(OutputASSEMBLER==Negative)||(Language!=CCOMP)) 
/***/
void Msetconst(int Ad,int Len,int *Area,int *Offset) {
	/*************************************************************************/
	/** Store away a const remembering a few to obtain better caching       **/
	/*************************************************************************/
	static const int bufmax=255;
	static const int recsize=16;
	struct bfmt{
		int offset;
		int len;
		int p1;
		int p2;
	};

	struct bfmt init;
	static struct bfmt *ba;
	int align,i;

	if (bufaddr==0) {
		bufaddr=(int)BMalloc(recsize*(bufmax+1),1,MACONSTCACHEAREA);
		ba=(struct bfmt*)((struct bfmt *)(bufaddr));
	}
	if ((Len&7)==0)  align=8; 
	else align=4;
	;
	*Area=CNST;
	memset(&init,0,sizeof( struct bfmt));
	if ((Len==4)||(Len==8)) {
		for (i=0; i<=Len-1; i++) {
			(*(unsigned char  *)((int)&init.p1+i))=(*(unsigned char  *)(Ad+i));
		}
		for (i=0; i<=buftop; i++) {
			if ((ba [i].p1==init.p1)&&(ba [i].p2==init.p2)&&(Len<=ba [i].len)) {
				*Offset=ba [i].offset; 
				return ;
			}
		}
	}
	*Offset=epermspace((((unsigned)(Len+3)>>2)<<2),align);
	pdbytes(GLA,*Offset,Len,(void *)Ad);
	if ((buftop<bufmax)&&((Len==4)||(Len==8))) {
		buftop++;
		init.offset=*Offset;
		init.len=Len;
		ba [buftop]=init;
	}
	return ;
}	/* Msetconst */

#else
/* assembler outputting version of Msetconst is currently with */
/* other data planting routines in the USLC front end          */

#endif
/***/
/***/
/**************************************************************************/
/**                                                                      **/
/**            initialisation                                            **/
/**                                                                      **/
/**************************************************************************/
/***/
/***/
void Minitialise(int lang,int *paramdisp) {
	/****************************************************************/
	/** called by Einitialise                                      **/
	/****************************************************************/
	struct lrecfmt *lrec;
	struct Exdatafmt *exdata;
	char s [32] ;
	int I,PIaddr,rangeproc;

	if (Language!=lang)  Mabort(55);

#if(Language==IMP) 
	codelisting=0;
#else
	codelisting=primecodelisting;
#endif

	lrec=BLabRecAd(0);
	lrec->labnum=-1;	/* to avoid use of this entry                              */
	lrec->chain=0;
	ubexrecheads=31;
	exrecheads=((int *)(BMalloc(((ubexrecheads+1)*4),1,MAEXRECADAREA)));
	exrecheads [0]=0;
	/**/
	for (I=1; I<=ublabadheads; I++) {
		lrec=BLabRecAd(I);
		memset(lrec,0,sizeof( struct lrecfmt));
	}

	for (I=1; I<=ubexrecheads; I++) {
		exrecheads [I]=0;
	}

	for (I=0; I<=10; I++) {
		exdata=exrecad(I);
		memset(exdata,0,sizeof( struct Exdatafmt));
		strcpy(s,FixedAreaNames [I]);
		Mnoteentry(s,I);
		Mareaalign(I,8);	/* all EPC areas 8 byte aligned                            */
	}
	PLToffset=8;
	fixedca=0;
	Parwords=((void *)(BMalloc(8192,1,MAEXRECADAREA)));

#if((Target==SPARC)||((Target==RS6)&&(TargetABI!=SunsoftABI))||(Target==PENTIUM)) 
	*paramdisp=PARAMBASE;

#else
	*paramdisp=0;

#endif
	/***/
	PI=&ProcInfo [0];
	PIaddr=(int)&ProcInfo [0];
	ProcNum=1;
	memset(PI,0,sizeof( struct procfmt));
	PI->procnum=1;
	CsetPI(PI);
	BSetPI(PIaddr);
	/***/
	rangeproc=BGetTraceProc();
	if ((rangeproc==0)||(rangeproc==1)) {
		Creport(GlobCodeReport);
	} else {
		Creport(0);
	}

	BNewFrag();
	PI->procfrag=PI->curfrag;	/* Level 0 proc info for IMP unass check, etc */
	/***/
	BPrintProcBanner();
	/***/
	calllevel=0;
	FreeParword=0;
	/***/
	Numexnames=Firstuserexname-1;
	Numswkeys=0;
	Numareakeys=0;
	Numconstrecs=0;
	Numlabadkeys=0;
	Nextlabtag=INITLABTAG;
	Nextplabel=INITPLABEL;
	Labadjust=0;
	/**/
	LinePrefixAddr=0;
	/**/

	/***/

#if(Language==FORTRAN) 
	NumEntrys=0;	/* number of entries for dwarf generation*/
	/*SL update*/
#endif
	/**/
	/***/
	for (I=0; I<=Nexpprocs; I++) {
		Expprocref [I]=0;
	}
	for (I=0; I<=Spprocnum; I++) {
		Spprocref [I]=0;
	}


#if(((Language==PASCAL)||(Language==MODULA))) 
	FirstDisplayLevel=2;

#else
	FirstDisplayLevel=1;

#endif

	if ((Language!=PASCAL)&&((Language!=CCOMP)||(LanguageVariant!=USLC))&&(diagnostics!=0)) {
		UnassignedDisp=epermspace(8,8);
		pdbytes(GLA,UnassignedDisp,8,UnassignedWords);
		/*generate the unassigned pattern in GLA*/
	}

	if (profile!=0) {
		if (targetvariant==SUNOS) {
			ProfileId=Mgetprockey(1,ProfileName)	/* Sunos dont add _ */;
		} else {
			ProfileId=Mgetprockey(0,ProfileName);
		}
	}

	/*      %IF Pic # 0 %AND (Target # MIPS %OR Pic = 2) %THENSTART              */
	/*         GOTareaId = Mgetprockey(2,GOTname)                                */
	/*      %FINISH                                                              */

	Cinitialise(Language,cgoptions,UnassignedDisp);

}	/* Minitialise */
/***/
void MReinitialise() {
	/****************************************************************/
	/** called by EReinitialise                                    **/
	/****************************************************************/
	struct lrecfmt *lrec;
	struct Exdatafmt *exdata;
	char s [32] ;
	int I,PIaddr,rangeproc;


#if(Language==IMP) 
	codelisting=0;
#else
	codelisting=primecodelisting;
#endif

	bufaddr=0;
	buftop=-1;
	/* see Msetconst  where these were originally local                          */
	/**/
	/**/
	/* Bterminate will have freed the root arena so reinitialise everything      */
	/**/
	exrecheads=((int *)(BMalloc(((ubexrecheads+1)*4),1,MAEXRECADAREA)));
	for (I=0; I<=ubexrecheads; I++) {
		exrecheads [I]=0;
	}

	for (I=0; I<=ubswrecheads; I++) {
		swrecheads [I]=0;
	}

	for (I=0; I<=ublabadheads; I++) {
		lrec=BLabRecAd(I);
		memset(lrec,0,sizeof( struct lrecfmt));
		labadheads [I]=0;
	}
	Parwords=((void *)(BMalloc(8192,1,MAEXRECADAREA)));

	for (I=0; I<=10; I++) {
		exdata=exrecad(I);
		memset(exdata,0,sizeof( struct Exdatafmt));
		strcpy(s,FixedAreaNames [I]);
		Mnoteentry(s,I);
		Mareaalign(I,8);	/* all EPC areas 8 byte aligned                            */
	}

	fixedca=0;
	/***/
	PI=&ProcInfo [0];
	PIaddr=(int)&ProcInfo [0];
	ProcNum=1;
	memset(PI,0,sizeof( struct procfmt));
	PI->procnum=1;
	CsetPI(PI);
	BSetPI(PIaddr);
	/***/
	rangeproc=BGetTraceProc();
	if ((rangeproc==0)||(rangeproc==1)) {
		Creport(GlobCodeReport);
	} else {
		Creport(0);
	}

	BNewFrag();
	PI->procfrag=PI->curfrag;	/* Level 0 proc info for IMP unass check, etc */
	/***/
	BPrintProcBanner();
	/***/
	calllevel=0;
	FreeParword=0;
	/***/
	Numexnames=Firstuserexname-1;
	/**/
	/* there is no need to free and realloc space for these next items           */
	/* resetting the global counts should be good enough and the                 */
	/* original space can be reused                                              */
	Numswkeys=0;
	Numareakeys=0;
	Numconstrecs=0;
	Numlabadkeys=0;
	Nextlabtag=INITLABTAG;
	Nextplabel=INITPLABEL;
	Labadjust=0;
	/**/
	LinePrefixAddr=0;

	/***/

#if(Language==FORTRAN) 
	NumEntrys=0;	/* number of entries for dwarf generation*/
	/*SL update*/
#endif
	/**/
	/***/
	for (I=0; I<=Nexpprocs; I++) {
		Expprocref [I]=0;
	}
	for (I=0; I<=Spprocnum; I++) {
		Spprocref [I]=0;
	}


	if ((Language!=PASCAL)&&((Language!=CCOMP)||(LanguageVariant!=USLC))&&(diagnostics!=0)) {
		UnassignedDisp=epermspace(8,8);
		pdbytes(GLA,UnassignedDisp,8,UnassignedWords);
		/*generate the unassigned pattern in GLA*/
	}

	if (profile!=0) {
		ProfileId=Mgetprockey(0,ProfileName);
	}

	Creinitialise(UnassignedDisp);

	/* and in mipscode module which has no initialise routine                    */

#if((Target==MIPS)||(Target==SPARC)||(Target==PENTIUM)) 
	Maxareakey=-1;
#endif

	ARCH(reinit());

}	/* MReinitialise */

/***/
int MInTraceRegion() {
	/***************************************************************************/
	/** Returns non-zero if currently in a procedure for which tracing should **/
	/** be generated                                                          **/
	/***************************************************************************/
	int rangeproc;

	rangeproc=BGetTraceProc();
	if ((rangeproc==0)||(rangeproc==PI->procnum))  return 1;
	return 0;
}	/* MInTraceRegion  */
/***/
/*%EXTERNALROUTINE Mcodeon                                                   */
/*! now redundant once all calls removed. Done via cgoptions                 */
/*      codelisting=1                                                        */
/*%END;! Mcodeon                                                             */
void mcodeon() {
	/* now redundant once all calls removed. Done via cgoptions                  */
	codelisting=1;
}	/* mcodeon */
/***/
void Msetoptions2(int options) {
	/***************************************************************************/
	/** called by compilation outer control routine                           **/
	/** options have bit value significance                                   **/
	/**   x'00000001'  enable miscellaneous architecture specific tracing     **/
	/**   x'00000002'  generate assembly listing for each frag                **/
	/**   x'00000004'  enable peephole optimisation tracing                   **/
	/**   x'00000008'  parameters are independent (FORTRAN only)              **/
	/**   x'00000010'  enable put memory allocation tracing                   **/
	/**   x'00000080'  enable put file monitoring                             **/
	/**   x'00000100'  enable global scheduling                               **/
	/**   x'00000200'  enable leaf routine optimisation                       **/
	/**   x'00000400'  enable peephole optimisation                           **/
	/**   x'00010000'  profiling                                              **/
	/**   x'00020000'  enable DBX/SDB information generation                  **/
	/**   x'00040000'  minimum diags preparation                              **/
	/**   x'00080000'  dynamic line number updating                           **/
	/**   x'00100000'  prepare static line no table (later)                   **/
	/**   x'00200000'  support overflow checking                              **/
	/**   x'00400000'  allow compiler allocation of registers (FORTRAN only)  **/
	/**   x'00800000'  set FPU traps if compiling a main program              **/
	/**   x'01000000'  enable basic block instruction scheduling              **/
	/**   x'02000000'  prepare for FORTRAN argument checking                  **/
      	/**   x'04000000'  M-C dependent (-qnomaf on PPC)                         **/
	/**   x'08000000'  Now only used on PPC                                   **/
	/**   x'10000000'  Now only used on PPC                                   **/
	/**   x'20000000'  line profiling                                         **/
	/**   x'40000000'  leave external symbol names in mixed case              **/
	/**                                                                       **/
	/** Additionally, bits 12-15 give the architecture variant for which      **/
	/** backend optimisation should be performed                              **/
	/***************************************************************************/
	cgoptions=options;
	report=options&0x1;
	primecodelisting=options&0x2;
	profile=options&0x10000;
	setdbx=options&0x20000;
	diagnostics=options&0x40000;
	setlineno=options&0x80000;
	CheckOverflow=options&0x200000;
	FPUtraps=options&0x800000;
	paramchecks=options&0x2000000;
	Lineprof=options&0x20000000;
	if (CheckOverflow!=0)  ModifyCC=1;
	if ((report!=0)||((options&4)!=0)) {
		printf("options= %x Pic set to %c\n",options,Pic);	 
	}

#if(!((OutputASSEMBLER==Positive)&&(Language==CCOMP))) 
	psetoptions(options);
#endif
	/**/
	ARCH(init(options));

}	/* Msetoptions */
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/
void MAdjustOptions(int mask,int values) {
	/*************************************************************************/
	/** Similar to Msetoptions, but can be called in the middle of          **/
	/** code generation rather than just at the beginning.                  **/
	/** Only deals with flag(s) for which it is called. Can be extended     **/
	/** on as needed basis.                                                 **/
	/*************************************************************************/
	if ((mask&0x200000)!=0) {
		CheckOverflow=values&0x200000;
		if (CheckOverflow==0)  ModifyCC=0; 
		else ModifyCC=1;
		;
	}
}	/*MAdjustOptions*/
/***/
/**/
/* Copyright (c) 1989 Edinburgh Portable Compilers Ltd.  All Rights Reserved.*/
/**/
/***/

#if((Language==FORTRAN)&&(LanguageVariant!=FORTRAN90)) 

void NoteEntryInfo(char * name,int labid) {
	/*****************************************************************************/
	/** This routine records information for any Fortran side ENTRY              */
	/** found in the current routine. Called from ftnend if -g                   */
	/****************************************************************************/

	char S [256] ;

	strcpy(S,name);
	if (NumEntrys==MAXENTRYS) {
		printf("*internal compiler error* Note Entry Info - tabel overflow\n");
		imp_stop();
	}
	NumEntrys++;	/*start from 1*/
	strcpy(EntryRecs [NumEntrys].name,S);
	EntryRecs [NumEntrys].lab=labid;

}	/* Note Entry Info */

void noteentryinfo(int maxlen, char*impstring, int labid) {
	char s[256];
	strcpy(s,eimpstringtoc(impstring));
	NoteEntryInfo(s,labid);
}

void NoteEntryCodead(int codead,char * S) {
	/*****************************************************************************/
	/** This routine records information for any Fortran side ENTRY              */
	/** prolog start address. Called from cgenerate instr in m88kprocs           */
	/** S is the entry point name                                                */
	/****************************************************************************/

	int i;

	for (i=1; i<=NumEntrys; i++) {
		if (strcmp(EntryRecs [i].name,S)==0) {
			EntryRecs [i].codead=codead;
			break ;
		}
	}

}	/* Note Entry Codead */

void outputdbxentrys(int EntryId) {
	/*************************************************************************/
	/** called by ftnend if -g. Calls put to output the given entry info via     */
	/** the Generate Entry DIE.                                                  */
	/*************************************************************************/


#if(TargetABI==Vdot4ABI) 
	extern void GenerateEntryDIE( char * ,int ,int );

	GenerateEntryDIE(EntryRecs [EntryId].name,EntryRecs [EntryId].labad,EntryRecs [EntryId].codead);

#endif
}	/* Output DBX Entrys */


#endif
/***/
int MGetFuncCA() {
	/***************************************************************************/
	/** Function to return the code address of the current function (for DBX) **/
	/***************************************************************************/
	return fixedca;
}	/* MGetFuncCA  */
/***/
void Mabort(int abortcode) {
	/* ****call on untranslateable imp support routine**** */;
	printf("\n");
	if (abortcode==50) {
		printf("%s \n\n",Text [abortcode-1]);
	} else {
		printf("\nINTERNAL (B-E) COMPILER ERROR  %d",abortcode);
		if (abortcode<=curmax) {
			printf(": %s",Text [abortcode-1]);
		}
		printf("\n\n");
		if (GlobCodeReport!=0) {
			Cdumpestack();
			;
		}
	}
	imp_stop();
}	/* Mabort  */
/***/
/***/
/** here are some constants global to the Mcurrentvalue family               */
/***/
static const unsigned char CanBeModifier [32] = {
	1,
	1,1,0,1,1,1,1,
	1,1,1,1,1,1,0,0,
	0,0,0,0,0,0,0,0,
	0,0,0,1,0,0,0,0
};	/* 1 means can be a Modform */


static const unsigned char NewForm [32] =	/* basic form after substitution */ {
       /*LitVal         */  RegVal,             /*ConstVal       */  RegVal,
       /*RegVal         */  RegVal,             /*FregVal        */  FregVal,
       /*TempVal        */  RegVal,             /*DirVal         */  RegVal,
       /*IndRegVal      */  RegVal,             /*IndTempVal     */  IndRegVal,
       /*IndDirVal      */  IndRegVal,          /*AddrConst      */  RegAddr,
       /*AddrDir        */  RegAddr,            /*RegAddr        */  RegAddr,
       /*TempAddr       */  RegAddr,            /*DirAddr        */  RegAddr,
       /*AddrDirMod     */  RegModAddr,         /*RegModAddr     */  RegModAddr,
       /*TempModAddr    */  RegModAddr,         /*DirModAddr     */  RegModAddr,
       /*IndRegModVal   */  IndRegModVal,       /*IndTempModVal  */  IndRegModVal,
       /*IndDirModVal   */  IndRegModVal,       /*AddrDirModVal  */  RegModAddr,
       /*RegBitAddr     */  RegBitAddr,         /*RegBitModAddr  */  RegBitModAddr,
       /*IndDispModVal  */  IndRegModVal,       /*AddrDispModVal */  RegModAddr,
       /*DispModAddr    */  RegModAddr,         /*Regvar         */  RegVal,
       /*Fregvar        */  FregVal,            /*Flitval        */  FregVal,
       /*DirBitModAddr  */  RegModAddr,                            0};


static const unsigned char Unmodified [32] =	/* form without 'Mod' */ {
       /*LitVal         */  LitVal,             /*ConstVal       */  ConstVal,
       /*RegVal         */  RegVal,             /*FregVal        */  FregVal,
       /*TempVal        */  TempVal,            /*DirVal         */  DirVal,
       /*IndRegVal      */  IndRegVal,          /*IndTempVal     */  IndTempVal,
       /*IndDirVal      */  IndDirVal,          /*AddrConst      */  AddrConst,
       /*AddrDir        */  AddrDir,            /*RegAddr        */  RegAddr,
       /*TempAddr       */  TempAddr,           /*DirAddr        */  DirAddr,
       /*AddrDirMod     */  AddrDir,            /*RegModAddr     */  RegAddr,
       /*TempModAddr    */  TempVal,            /*DirModAddr     */  DirVal,
       /*IndRegModVal   */  IndRegVal,          /*IndTempModVal  */  IndTempVal,
       /*IndDirModVal   */  IndDirVal,          /*AddrDirModVal  */  DirVal,
       /*RegBitAddr     */  RegBitAddr,         /*RegBitModAddr  */  RegBitAddr,
       /*IndDispModVal  */  255,                /*AddrDispModVal */  255,
       /*DispModAddr    */  255,                /*Regvar         */  Regvar,
       /*Fregvar        */  Fregvar,            /*Flitval        */  Flitval,
       /*DirBitModAddr  */  255,                                   0};
/*LitVal         */

static const unsigned char Indirect [32] =	/* Form with added indirection */ {
       /*LitVal         */  255,            /*ConstVal       */  255,
       /*RegVal         */  IndRegVal,      /*FregVal        */  255,
       /*TempVal        */  IndTempVal,     /*DirVal         */  IndDirVal,
       /*IndRegVal      */  255,            /*IndTempVal     */  255,
       /*IndDirVal      */  255,            /*AddrConst      */  ConstVal,
       /*AddrDir        */  DirVal,         /*RegAddr        */  IndRegVal,
       /*TempAddr       */  IndTempVal,     /*DirAddr        */  IndDirVal,
       /*AddrDirMod     */  AddrDirModVal,  /*RegModAddr     */  IndRegModVal,
       /*TempModAddr    */  IndTempModVal,  /*DirModAddr     */  IndDirModVal,
       /*IndRegModVal   */  255,            /*IndTempModVal  */  255,
       /*IndDirModVal   */  255,            /*AddrDirModVal  */  255,
       /*RegBitAddr     */  255,            /*RegBitModAddr  */  255,
       /*IndDispModVal  */  255,            /*AddrDispModVal */  255,
       /*DispModAddr    */  255,            /*Regvar         */  IndRegVal,
       /*Fregvar        */  255,            /*Flitval        */  255,
       /*DirBitModAddr  */  255,                               0};
static const unsigned char AddrregForm [32] = {
	0,
	0,0,0,0,0,0,0,
	0,0,1,1,1,1,0,1,
	1,1,0,0,0,0,1,1,
	0,0,1,0,0,0,1,0
};

#define SAll 0
#define SReg 1
#define SMreg 2
#define SDir 3
#define SMod 4

static void SetupStk(struct Stkfmt *New,struct Stkfmt *Old) {
	/***********************************************************************/
	/** Set up a clean stk record at 'New' from the info in 'Old'.        **/
	/***********************************************************************/

	memset(New,0,sizeof( struct Stkfmt));	/* clean record */
	New->Form=Old->Form;
	New->Size=Old->Size;
	New->Type=Old->Type;
	New->Domain=Old->Domain;
	New->Cmval=Old->Cmval;
	switch (New->Form&31) {
	default:
		Mabort(63);
		return ;

	case LitVal:
		New->Intvalue=Old->Intvalue;
		break;
	case Flitval:
		if (New->Size==8)  New->Rlval=Old->Rlval;
		else New->Rval=Old->Rval;
		break;

	case RegVal:
	case FregVal:
	case IndRegVal:
	case RegAddr:
	case RegModAddr:
	case IndRegModVal:
	case Regvar:
	case Fregvar:
		New->Reg=Old->Reg;
		break;

	case TempVal:
	case DirVal:
	case IndTempVal:
	case IndDirVal:
	case AddrDir:
	case TempAddr:
	case DirAddr:
	case AddrDirMod:
	case TempModAddr:
	case DirModAddr:
	case DispModAddr:
	case IndTempModVal:
	case IndDirModVal:
	case IndDispModVal:
	case AddrDirModVal:
		New->Base=Old->Base;
		New->Offset=Old->Offset;
	}

	if (IsModForm [New->Form&31]==0)  return ;

	New->Modform=Old->Modform;
	New->Scale=Old->Scale;

	switch (New->Modform&31)	{
	default:
		Mabort(37);
		return ;

	case LitVal:
		New->Modintval=Old->Modintval;
		return ;

	case RegVal:
	case IndRegVal:
	case RegAddr:
	case Regvar:
		New->Modreg=Old->Modreg;
		return ;

	case TempVal:
	case DirVal:
	case IndTempVal:
	case IndDirVal:
	case AddrDir:
	case TempAddr:
	case DirAddr:
		New->ModBase=Old->ModBase;
		New->Modoffset=Old->Modoffset;
		return ;
	}
}	/* SetupStk */

static int CompareStk(struct Stkfmt *Stk1,struct Stkfmt *Stk2) {
	/***********************************************************************/
	/** Return 1 if Stk1 = Stk2, otherwise return 0.                      **/
	/***********************************************************************/
	if ((Stk1->Form&31)!=(Stk2->Form&31) || Stk1->Type!=Stk2->Type ||
		Stk1->Reg!=Stk2->Reg || Stk1->Modreg!=Stk2->Modreg ||
		Stk1->Base!=Stk2->Base || Stk1->ModBase!=Stk2->ModBase ||
		Stk1->BitSize!=Stk2->BitSize || Stk1->Scale!=Stk2->Scale ||
		(Stk1->Modform&31)!=(Stk2->Modform&31) ||
		Stk1->Offset!=Stk2->Offset || Stk1->Modoffset!=Stk2->Modoffset ||
		Stk1->Modintval!=Stk2->Modintval ||
		Stk1->Size!=Stk2->Size || Stk1->Cmval!=Stk2->Cmval)  return 0;
	else 
		return 1;
}	/* CompareStk */


static void Substitute(struct Stkfmt *Item,struct Stkfmt *Entry,int Level,int Field,int *Ireg) {
	/***********************************************************************/
	/** Substitute the current value of 'Item' into 'Entry', which is at  **/
	/** Estack level 'Level'. 'Field' specifies the part of 'Entry' to be **/
	/** altered -- all, reg, modreg, direct or modifier.                  **/
	/***********************************************************************/
	int Isize,Iform,Itype,Ireal;
	struct Stkfmt TempStk;

	Isize=Item->Size;
	Iform=Item->Form&31;
	Itype=Item->Type;
	if (((Itype==RealType)||(Itype==MisRealType))&&(AddrregForm [Iform]==0))  Ireal=1;
	else Ireal=0;

	TempStk= (*Item);
		/* InDirVals in the SDir position are problematical. The logic
		    assumes these are DirVals so indirection is repeated!    */
		if (Field==SDir && Iform==IndDirVal) {
			TempStk.Form=DirVal;
		}
	if (*Ireg==-1) {
		/* Item needs to be loaded into a code-generator register */
		/* Must force copy of Regvars                         */
		if ((Ireal==1)) {
			if (SimpleRegForm [Iform]==0)  *Ireg=LoadRealRO(&TempStk,Isize);
			else *Ireg=LoadRealRW(&TempStk,-1,Isize);
			;
		} else {
			if (SimpleRegForm [Iform]==0)  *Ireg=LoadIntRO(&TempStk);
			else *Ireg=LoadIntRW(&TempStk,-1);
			;
		}
#if (Target!=PENTIUM)
		notereguse(*Ireg,-Level,Isize)	/* lock it to 'Entry' */;
#else
		{
			extern int currentFSP;
			unlockregister(*Ireg);
			currentFSP-=1;
			lockregister(*Ireg,Level,Isize);
		}
#endif

	} else if (*Ireg>0) {
		/* second substitution -- create a temp */

		Mabort(37);	/* actually, just give up for now */

	};


	/* now substitute Ireg in appropriate part of 'Entry' */
	switch (Field) {
	case SAll:	/* the whole entry becomes a RegVal */

		if ((Ireal==1))  Entry->Form=FregVal|Regflag;
		else Entry->Form=RegVal|Regflag;
		Entry->Reg=*Ireg;
		return ;

	case SDir:	/* the basic _Form gets changed to a register form */

		Entry->Form=NewForm [Entry->Form&31];
		if ((Ireal==1)&&(Entry->Form==RegVal))  Entry->Form=FregVal;
		Entry->Form=Entry->Form|Regflag;
		/* fall through */
	case SReg:	/* just the _Reg field needs changed */

		/* But the result should not be a Regvar*/
		Entry->Reg=*Ireg;
		if ((Entry->Form&31)==Regvar)  Entry->Form=RegVal|Regflag;
		if ((Entry->Form&31)==Fregvar)  Entry->Form=FregVal|Regflag;
		return ;

	case SMod:	/* the whole modifier gets changed to a RegVal */

		Entry->Modform=RegVal|Regflag;
		/* fall through */
	case SMreg:	/* just the _Modreg field needs changed */

		if ((Entry->Modform&31)==Regvar)  Entry->Modform=RegVal|Regflag;
		if ((Entry->Modform&31)==Fregvar)  Entry->Modform=FregVal|Regflag;
		Entry->Modreg=*Ireg;
		return ;

	}
}	/* Substitute */
/***/
void MCurrentvalue(struct Stkfmt *Item,int Alevel) {
	/***************************************************************************/
	/** The item at ETOS is about to be post-incremented or post-decremented. **/
	/** If the item is used further down the Estack then evaluate it now and  **/
	/** substitute its current value in those entries where it is used.       **/
	/** Alevel is the highest level at which to look                          **/
	/***************************************************************************/
	int Reg,Form,Lev,Tform,Ireg,Mform;
	struct Stkfmt *Test;
	struct Stkfmt Istk,Tstk;
	/***/

	if (Alevel<1)  return ;	/* nothing to do */
	Ireg=-1;
	Form=Item->Form&31;
	SetupStk(&Istk,Item);

	if (CanBeModifier [Form]==0) {
		/* look for an exact match between Item and other Estack entries */
		for (Lev=Alevel; Lev>=1; Lev--) {
			Test=&Stk [Lev];
			SetupStk(&Tstk,Test);
			if (CompareStk(&Istk,&Tstk)==1)  Substitute(Item,Test,Lev,SAll,&Ireg);
		}
	} else {
		/* see whether Item affects basic or modifier fields in other entries */
		if (SimpleRegForm [Form]==1) {
			Reg=Item->Reg;
			for (Lev=Alevel; Lev>=1; Lev--) {
				Test=&Stk [Lev];
				Tform=Test->Form&31;
				if ((IsRegForm [Tform]==1)&&(Reg==Test->Reg))  Substitute(Item,Test,Lev,SReg,&Ireg);

				if ((IsModForm [Tform]==1)&&(IsRegForm [Test->Modform&31]==1)&&(Reg==Test->Modreg))  Substitute(Item
				    ,Test,Lev,SMreg,&Ireg);
			}
		} else if (Form==IndRegVal) {
			Reg=Item->Reg;
			for (Lev=Alevel; Lev>=1; Lev--) {
				Test=&Stk [Lev];
				Tform=Test->Form&31;

				if ((Tform==IndRegVal)&&(Reg==Test->Reg))  Substitute(Item,Test,Lev,SDir,&Ireg);

				if ((IsModForm [Tform]==1)&&((Test->Modform&31)==IndRegVal)&&(Reg==Test->Modreg))  Substitute(Item,
				    Test,Lev,SMod,&Ireg);

			}
		} else {
			for (Lev=Alevel; Lev>=1; Lev--) {
				Test=&Stk [Lev];
				Tform=Test->Form&31;
				if (((Form==Unmodified [Tform])||(Tform==Indirect [Form]))&&(Item->Base==Test->Base)&&(Item->Offset
				    ==Test->Offset))  Substitute(Item,Test,Lev,SDir,&Ireg);

				Mform=Test->Modform&31;

				if ((IsModForm [Tform]==1)&&((Form==Mform)||(Mform==Indirect [Form]))&&(Item->Base==Test->ModBase)&&(Item
				    ->Offset==Test->Modoffset))  Substitute(Item,Test,Lev,SMod,&Ireg);

			}
		};

	}
}	/* CCurrentValue */
