Google
 

Trailing-Edge - PDP-10 Archives - BB-D480F-BB_1985_short - tables.bli
There are 13 other files named tables.bli in the archive. Click here to see a list.
!COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1972, 1985
!ALL RIGHTS RESERVED.
!
!THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
!ONLY  IN  ACCORDANCE  WITH  THE  TERMS  OF  SUCH LICENSE AND WITH THE
!INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR ANY  OTHER
!COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
!OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF THE  SOFTWARE  IS  HEREBY
!TRANSFERRED.
!
!THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT  NOTICE
!AND  SHOULD  NOT  BE  CONSTRUED  AS A COMMITMENT BY DIGITAL EQUIPMENT
!CORPORATION.
!
!DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY  OF  ITS
!SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.

!AUTHOR: S. MURPHY/HPW/DCE/SJW/TFV/CKS/CDM/AHM/RVM/PLB/TJK/MEM

GLOBAL BIND TABLEV = #10^24 + 0^18 + #2475;	! Version Date: 5-Nov-84

%(

***** Begin Revision History *****

134	-----	-----	DEFINE FIELDS FOR E1LISTCALL AND
			E2LISTCALL NODES
135	-----	-----	DEFINE DIMSUBSIZE
136	-----	-----	MODIFY DEFINITION OF DIMENSION TABLE ENTRIES
			TO MAKE ROOM FOR "ARADLBL" FIELD
137	-----	-----	COMPLETE DEFINITIONS FOR I/O OPTIMIZATIONS
138	-----	-----	DEFINE NEW OPERSP EALISTCALL UNDER OPRCLS
			IOLSCLS AND MOVE E2INCR FIELD
140	----	-----	DEFINE THE MACROS "ADDRETREG" AND "REMRETREG" TO
			ADD/REMOVE THE FN-VALUE RETURN REGISTERS TO A SET
			OF FREE REGISTERS
141	-----	-----	CHANGE RGCENTBENTRY TO MAKE REGCANDIDATES
			TABLES INTO A LINKED LIST
142	-----	-----	ADDITIONAL DEFINITIONS OF FIELDS
			FOR IOLSCLS NODES
143	-----	-----	DEFINE OPRS FOR OPRCLS AND SRCID AND
			OPERS MACRO TO DEFINE FIELDS FOR STATEMENT
			NODES
			FOR EACH STATEMENT TYPE APPROPRAITE BIND IS
			CALLED XXXOS WHERE XXXX IS ID MNEMONIC
144	-----	-----	REWRITE MACROS ILFIX AND ILF1IX TO GENERATE
			DABS IN LINE
145	-----	-----	ADDITIONAL DEFINITIONS TO GENERATE CMPLX
			IN LINE
146	-----	-----	ADDITIONAL DEFINITIONS FOR CORRECT FOLDING
			OF NESTED IMPLIED DO LOOPS WITH
			DOUBLE AND SINGLE WORD DATA ITEMS

147	-----	-----	MODIFY THE MACRO "CLBNXREG" TO CALL THE
			ROUTINE "CLOBBNX" - WE WERE NOT CATCHING
			DIVISION OF LOGICALS AS CLOBBERING THE NEXT REG
148	-----	-----	ADD DVARFLGS TO THE DIMENSION TABLE ENTRY SO
			THAT ACT1 WILL CLEAR THEM PROPERLY
149	-----	-----	REMOVE ALL REFERENCES TO "SQROP","CUBOP","P4OP"
			(SINCE THEY ARE NOW UNDER EXPCIOP) - 
			DEFINE THE MACRO "KEXPIX" TO
			DO EXPONEN OF CONSTS AT COMPILE TIME
150	-----	-----	DEFINE MACRO "POWEROF2" - TO USE IN REG
			ALLOCATION OF INTEGER EXPONEN
151	-----	-----	REMOVE REFERENCE TO "CUBOP" FROM THE
			DEFINITION OF "SPECOPIX"
152	-----	-----	RENAME THE MACRO "POWEROF2" TO "POWOF2" (HAD
			A CONFLICT WITH A ROUTINE IN P2S2)
153	253	15425	ADD PUSHJOCD AND DIVOCD DEFINITIONS
154	261	15772	ADD XCTOCD DEFINITION

***** Begin Version 5A *****

155	551	21826	FIX DISPATCH FOR TYPE CONVERSION TO OCTAL/LOGICAL, (DCE)
156	571	22378	ADD ARALINK DEFINITION, (SJW)

***** Begin Version 5B *****

157	724	-----	MAKE TEST FOR N-ARY TREE TEST TYPE FIELD TOO, (DCE)
158	733	-----	FIX NOTCNST MACRO DEFINITION, (DCE)

***** Begin Version 6 *****

159	760	TFV	1-OCT-79	------
	Add keyword field definition and values for argument blocks in
	I/O and OPEN/CLOSE statements

160	761	TFV	1-Mar-80	-----
	Fix structure accesses removing KA code and adding /GFLOATING

161	1002	TFV	1-Jul-80	------
	Add a new structure to translate internal data type to
	FOROTS argtype in arg block.  It is used with EVALU.

162	1027	DCE	25-Nov-80	-----
	Add various definitions pertaining to zero-trip DO loops (for V7).

***** Begin Version 7 *****

163	1212	TFV	29-Apr-81	------
	Add compile time data structures for CHARACTER data.

164     1214    CKS	11-May-81
	Add data structures for DO/IF stack

165	1216	DCE	28-May-81	-----
	Add OTSSLIST77 and OTSELIST77 entries for zero trip FOROTS calls.

166	----	SRM	16-June-81
	Add comments specifying OPERATOR values for  arith ops

167     1240	CKS	28-Jul-81
	Add BPADD macro to generate ADJBP instruction

168	1243	CKS/TFV	1-Aug-81
	Change OPERSPs for CONCATENATION to CONCTF, CONCTM, and CONCTV.
	(My full name is Thomas Francis Michael Vasak.)

169	1245	TFV	3-Aug-81	------
	Add CHARCONST for character constant operator fields.  It is used
	the same way as LITCONST is.  Make ARASIZ a full word since character
	data arrays have a size in characters.

170	1252	CDM	10-Aug-81	-----
	Add inline functions op's (CMPDOP, CMPIOP, DBLCOP, DBLIOP, INTCOP,
	REALIOP) for new generic functions.

171	1270	CDM	6-Oct-81
	Add ATTSPGEN for bit to flag that function is generic but not
	specific (octal argument is illegal).

172	1401	AHM	6-Oct-81	------
	Define OTSIFIW, OTSEIND, OPENGFIELD for arg block words.
	Widen OTSKEY from 5 to 7 bits so there are no unnamed fields.
	Narrow OTSIDN from 9 to 7 bits to leave room for the IFIW bits.
	Delete OTSUNIT, OTSFORM, OTSARRFMTFLG for never being used.

173	1413	CDM/AHM	4-Nov-81
	Add some argument node macros and increased the size of the argument
	structure from 2 headers to 3 word headers.

174	1406	TFV	27-Oct-81	------
	Create the macro BPGEN to generate byte pointers that are output to
	the  .REL file.   It  will be used to generate one word global byte
	pointers for  extended addressing.   Create the macro  CHWORDLEN to
	compute the number  of  words  needed  for a given length character
	variable or constant.

175	1431	CKS	15-Dec-81
	Add temporary CANTCONCAT macro to use as placeholder in CASE statements

1510	RVM	14-Mar-82
	Add the flag ASSUMESIZFLG to identify assumed-size arrays.

1522	TFV	29-Mar-82
	Remove CANTCONCAT macro.

1530	TFV	4-May-82
	Add the and  IOLSTATEMENT to  IOLSCLS nodes.  It  points to  the
	parent I/O  statement.  Move  E1INCR, ECNTPTR,  and  ELPFVLCHAIN
	down by one word.   They are used  in E1LISTCALL and  E2LISTCALL
	nodes.  Add the  field ARGMARK  to argument list  nodes.  It  is
	non-zero  if  the  argument  list  contains  CONCTV  nodes.   It
	contains the  pointer to  the  argument list  for the  calls  to
	CHMRK. and  CHUNW.  Also  change the  definitions for  ARGLABEL,
	ARGLINK, ARGPARENT, ARGCOUNT, ARGCHBLOCK, and ARGCALL.   Finally
	remove GETCORE  macro  and replace  it  in-line in  SKSTMN  (the
	routine GETCORE in LISTNG does a CORE UUO).

1535	CDM	21-May-82
	Change lots  to  enlarge OPERSP  field  from  3 to  5  bits  for
	additional inline functions and type conversions needed.

1573	CKS	1-Jul-82
	Add fields of WHILE node in DOIFSTK

***** End V7 Development *****

1766	CDM	4-Aug-83
	Compiler puts constant array ref offset calculations in TARGADDR
	whenever possible.  TARGADDR  is a  half word  quantity (17  bit
	plus 1 bit for sign) which can not store large numbers.  A large
	positive number will be  truncated and appear  to be a  negative
	number when  retrieved,  since  the  retrieved  offset  is  sign
	extended.  (Also negative numbers can appear to be positive  the
	same way.)  Before  storing into TARGADDR,  check if the  offset
	will fit.
	Add STORETARGADDR, returns true if TARGADDR can be stored into.

1770	CDM	25-Jul-83
	Perform argument checking for length of numeric arrays when  the
	length is known at  compile time. Create  SECDESC to return  the
	length needed  for  a secondary  descriptor  (or 0  if  none  is
	needed).
	Add ARRAYFL.

2007	CDM	6-Oct-83
	Add DYNCONCAT for detecting dynamic concatenations.

2043	TJK	24-Feb-84
	Have OPEN and CLOSE recognize  the LIMIT= keyword once  again.
	This keyword takes an integer expression.  Entries were  added
	to the tables OPNKWD and IOCKVEC in OPENCLOSE, and KEYWFLAG in
	CFCHECK.  LIMIT= is illegal for INQUIRE and is flagged as both
	an ANSI and a  VAX incompatibility.  Note  that this edit  was
	somewhat different for V7A and  V10.  Among other things,  V7A
	didn't have to change TABLES but V10 did.


***** Begin Version 10 *****

2200	TFV	11-Mar-83
	Add INQUOS and IOCxxxx keywords for INQUIRE statement.

2202	CDM	7-Apr-83
	Make use of  DIMSUBSIZE in  the dimension  macro's.  Also  added
	much  needed  comments  about  how  subscripts  are  stored  TWO
	DIFFERENT WAYS!!

2205	CDM	21-JUN-83
	Add symbols for EFIW table processing.

2216	PLB	27-Sep-83
	Change BPGEN to generate OWG byte pointers to the section
	given in OWGBPSECTION iff OWGBPSECTION NEQ 0.  Removed
	definition of BPADD MACRO, mad into a routine in OUTMOD.BLI

2230	CDM	1-Nov-83
	Move DO node flags from TABLES to FIRST where they belong.

2244	CDM	13-Dec-83
	Eliminate AOBJN  DO  loop  register indexes  into  large  arrays
	(arrays in  .LARG.)   during  code  generation.   Create  a  new
	STORECLS node,  STRHAOBJN to  copy the  right hand  half of  the
	AOBJN register into another  register.  Otherwise, the  negative
	left half of  the AOBJN register  will appear to  be an  invalid
	section number.  This is  to catch the  cases that the  skeleton
	optimizer (edit 2243) can not.

2276	AlB	26-Jan-84
	Added definitions which specify incompatibilities between Fortran-10/20
	intrinsic functions & subroutines, and those for VAX and/or Fortran-77.
	These new flags bits are placed in the table CFTABLEV in routine
	CFSRCLIB, and are checked in various places by the compatibility
	flagger feature.

2314	AHM	25-Feb-84
	Eliminate immediate arguments for OTSKFSIZ (format size)
	FOROTS arguments because size of large arrays don't fit in 18
	bits.  Add field named ARACONSIZ to dimension table entries,
	which points to a constant table entry for ARASIZ.  Also, put
	dimension table declarations in the structure memory order,
	and add a box for documentation.

2322	CDM	18-Apr-84
	Fix array subscript calculations for /EXTEND.  In PROCEQUIV  and
	BLDDIM, correct  maximum  size of  an  array of  a  legal  array
	declaration /EXTEND.   In BLDDIM,  call  CNSTCM for  array  size
	calculations to  give  proper  underflow/overflow  messages  for
	illegal declarations.  Otherwise arrays that are too  large  may
	not be detected.

2330	AHM	28-Mar-84
	Remove reference to OWGBPSECTION in BPGEN macro - use IF
	EXTENDED to decide when to generate OWGBPs.  Also, define new
	field macros for the P&S and address fields of OWGBPs.

2334	AHM	5-Apr-84
	Define symbol ENTVECSIZE for the size of the object program's
	entry vector under /EXTEND.  Set it to 2 for now (start
	instruction plus reenter instruction).

2336	CDM	8-Apr-84
	Insert  EXTERNAL  command  for   external  variables  in   marco
	MAKECNST.  This insures that they cannot be locals accidentally.

2352	CDM	1-May-84
	Make intrinsic functions  IAND, IOR, and  IEOR inline functions.   They
	are converted to  Fortran .AND.,  .OR., AND .XOR.  within the  skeleton
	optimizer.

2355	AHM	1-May-84
	Redefine ENTVECSIZE in order to make room for a version number
	in the entry vector created under /EXTEND.  Also, define
	STARTOFF, REENTOFF, VERSIONOFF, ENTAUXSIZE and REEINDOFF to
	describe the entry vector structure.

2371	TJK	14-Jun-84
	Move defintions of  DEFPT1 and DEFPT2  from OPTMAC to  TABLES.
	Also add definition of DEFPTSS, used to hold definition points
	for substrings.   These  are all  in  TABLES to  avoid  hiding
	overlapping fields.

2400	TJK	18-Jun-84
	Add OTSNSLIST, OTSNELIST, OTSNSLIST77, and OTSNELIST77.  These
	are new IOLST. argument types for FOROTS.  They are equivalent
	in form  to OTSSLIST,  OTSELIST, OTSSLIST77,  and  OTSELIST77.
	However,  the  interpretation  of   the  increment  field   is
	different.  The old  interpretation is that  the increment  is
	the number  of array  elements to  advance through  each  time
	around.  The new interpretation is  that the increment is  the
	number of  words  (or bytes  for  CHARACTER data)  to  advance
	through each time around.  These  new argument types are  only
	used by E1 and E2 lists.  SLISTs still use the old types.

2413	MEM	5-Jul-84
	Define OPNCTAPEFO to be the number of the keyword TAPEFORMAT

2423	AHM	19-Jul-84
	Define more field names for parts of a byte pointer (prefix is
	OWLBP).  Also, define a symbol for the correct number of bits
	in a word.

2426	MEM	16-Jul-84
	Define OPNCNEDIALOG to be the number of the keyword DIALOG
	(without =).

2455	MEM	30-Aug-84
	Replace all occurrences of VAX with VMS.

2463	AHM	8-Oct-84
	Define OPERSPs ARREFSMALL and ARREFBIG under OPRCLS ARRAYREF.

2475	MEM	5-Nov-84
	Fix bugs with combinations of neg and not with double precision
	octal constants.

***** End V10 Development *****

***** End Revision History *****

)%


BIND DEBUGFLG = 1;	! Compile switch to leave consistency checks in

	!***************************************************************
	! To optimally test whole word flags for true and false
	!***************************************************************

BIND
	TRUE = -1,
	FALSE = 0;

MACRO
	TRUTH(X) = ((X) NEQ 0)$,
	FALSITY(X) = ((X) EQL 0)$;

BIND
	AOBINCR = #1000001;	! Increment for AOBJN

	!***************************************************************
	! Define bytes for whole, left half, and right half
	!***************************************************************

MACRO 	WHOLE=0,36$;

		
	!***************************************************************
	! Structure for an expression node
	!***************************************************************

	!***************************************************************
	! Define the fields and subfields in an expression node
	!***************************************************************

BIND EXOPWD = 1;	! Word in  which the  operator field  and  flags
			! field are contained.  When this number changes
			! a large number of subfield definitions must be
			! changed

	!***************************************************************
	! Define main fields
	!***************************************************************

MACRO
	FIRSTWORD = 0,0,FULL$,
	PARENT = 0,0,RIGHT$,		! Pointer to parent node
	OPERATOR = 0,EXOPWD,RIGHT$,	! Operator field
	EXPFLAGS = 0,EXOPWD,LEFT$,	! Flags
	OPERWORD = 0,EXOPWD,WHOLE$,
	TARGET = 0,2,WHOLE$,		! Address word
	ARGWD = 0,3,WHOLE$,		! Word holding pointers to the 2 args
	ARGWDOFFSET = 3$,
	ARG1PTR = 0,3,LEFT$,
	ARG2PTR = 0,3,RIGHT$,
	ARG3PTR = 0,4,LEFT$,
	ARG4PTR = 0,4,RIGHT$,
	COMPLEXITY = 0,0,30,6$,		! This field is used only during
					! register    allocation.     It
					! indicates   the   number    of
					! registers needed  to  evaluate
					! this expression.
	SONNXTUSE = 0,0,18,12$,		! ISN of the statment where  the
					! variable under this expression
					! is next  used (in  this  basic
					! block)  used  by  BB  register
					! allocator

%2371%	! Fields of an  expression node  used to  hold the  definition
%2371%	! points of  the  arguments.  WARNING:  These  fields  overlap
%2371%	! other fields of expression nodes.
%2371%
%2371%	DEFPT1	= CW2L$,	! Definition point of ARG1PTR
%2371%	DEFPT2	= CW0L$,	! Definition point of ARG2PTR
%2371%	DEFPTSS	= ARG3PTR$;	! Definition point of ARG4PTR (for SUBSTRINGs)

	!***************************************************************
	! Subfields in operator field
	!
	!	18	      22 23	      27 28	      32 33 35
	!	+---------------+---------------+---------------+----+
	!	| VALTYPE	| OPRCLS	| OPERSP	|    |
	!	+---------------+---------------+---------------+----+
	!
	!***************************************************************
MACRO
	VALTYPE = 0,EXOPWD,13,5$,	! Type for value
	OPRCLS = 0,EXOPWD,8,5$,		! Class of operator
%1535%	OPERSP = 0,EXOPWD,3,5$,		! Specific operator within class

	!***************************************************************
	! Note that of the 3 free bits at the right end of the  operator
	! field, bit 35 is used as a special flag bit in type-conversion
	! nodes - flag for no conversion
	!***************************************************************

	!***************************************************************
	! Subfields of OPERSP field
	!***************************************************************

%1535%	OPRSP1 = 0,EXOPWD,4,2$,		! Third  2 bits of  OPERSP (this
					! field is 00 for  add and  sub,
					! 01 for mul and div.
%1535%	OPRSP2 = 0,EXOPWD,3,2$,		! Last 2 bits of OPERSP field  -
					! used  to  differentiate   add,
					! sub, mul,  div  also  used  in
					! type   conversion   nodes   to
					! differentiate         FROMINT,
					! FROMREL, FROMDBLPRC, FROMCMPLX
%1535%	OPRSMIDBIT = 0,EXOPWD,5,1$,	! Third  bit of OPERSP  field  -
					! for an arith node, this bit is
					! set only  for OPERSP  exponen.
					! For  a  type-conversion   node
					! this bit is  set for  FROMINT,
					! FROMREAL,          FROMDBLPRC,
					! FROMCMPLX  and  not  set   for
					! FROMOCT,   FROMCTL,   FROMLIT,
					! FROMDOCT
%1535%	OPRSLASTBIT = 0,EXOPWD,3,1$,	! Last  bit  of OPERSP  field  -
					! for an arith node, this bit is
					! set only for sub and div.

	!***************************************************************
	! Concatenation of OPRCLS and OPERSP
	!***************************************************************

%1535%	OPR1 = 0,EXOPWD,3,10$,		! OPRCLS   and   OPERSP   fields
					! concatenated
%1535%	OPR2 = 0,EXOPWD,4,9$;		! OPRCLS field and first 4  bits
					! of OPERSP field

	!***************************************************************
	! Subfields of the above "main" subfields
	!***************************************************************

MACRO
	VALTP1 = 0,EXOPWD,15,2$,	! Middle 2 bits  of VALTYPE  are
					! all thats needed for GETA1OPIX
					! and ARITHOPIX
	VALTP2 = 0,EXOPWD,15,3$,	! First 3 bits  of  VALTYPE  are
					! identical to the OPERSP  field
					! for a typecnv node to  convert
					! from that VALTYPE
	DBLFLG = 0,EXOPWD,16,1$,	! The second bit of valtype is a
					! flag  for  second  word  value
					! (double prec or complex)
%1535%	SDBLFLG = 0,EXOPWD,4,1$;	! The fourth bit of OPERSP for a
					! typeconv  node  is  flag   for
					! source is a two word value

MACRO
%1535%	BOOLOPR=0,EXOPWD,3,2$,		! Boolean operator is  specified
					! by  right  2  bits  of  OPERSP
					! field
%1535%	BOOLCLS=0,EXOPWD,4,1$,		! Boolean   class   (AND/OR   or
					! XOR/EQV) is  specified by  the
					! leftmost of these 2 bits
%1535%	BOPRFLG=0,EXOPWD,3,1$;		! The last divides booleans into
					! 2 other classes  - OR/XOR  and
					! AND/EQV

MACRO
%1535%	PARENLSTFLG=0,EXOPWD,5,1$;	!Flag for name which should have
					! an arglist following (this bit
					! is 3rd bit of OPERSP field  of
					! a data item)
MACRO
%1535%	FORMLFLG=0,EXOPWD,3,1$;		! In OPERSP  field  for  a  data
					! item, flag for "formal"  (note
					! however that this bit is  also
					! set in the  OPERSP field of  a
					! temporary)

	!***************************************************************
	! Macro to construct "OPR1" and "OPR2" fields
	!***************************************************************
MACRO
%1535%	OPR1C(OPCLS,OPSP)=(OPCLS^5 OR OPSP)$;
MACRO
%1535%	OPR2C(OPCLS,OPSP)=(OPCLS^4 OR OPSP^(-1))$;

	! Constructs an  operator field  for  the entire  operator  half
	! word.

MACRO	OPERC(VTYP,OPCLS,OPSP)=
%1535%		(VTYP^13 OR OPCLS^8 OR OPSP^3)$;


	%(*** To get a VALTP1 field from a VALTYPE ****)%
MACRO	VTP1(VLTP)=(VLTP^(-2) AND (#3))$;


	%(*** To get a VALTP2 field (first 3 bits) from a VALTYPE ***)%
MACRO	VTP2(VLTP)=(VLTP^(-2))$;







%(*******FLAGS IN EXPFLAG FIELD (THESE ARE SET BY PHASE 2 SKEL AND USED BY PHASE 3*******)%
MACRO
	PARENFLG=0,EXOPWD,35,1$,		!FLAG FOR PARENS AROUND THIS NODE (IN SOURCE)
	PAIRMODEFLG=PARENFLG$,		!IN ALL STATEMENTS TO INDICATE
					!DOUBLE PRECISION
	SAVREGFLG=0,EXOPWD,34,1$,		!"SAVE THE REG CONTAINING THE VAL OF THE VAR
						! UNDER THIS NODE FOR USE LATER IN THIS BASIC BLOCK"
	RVRSFLG=0,EXOPWD,33,1$,			!"VAL OF 2ND SON SHOULD BE
						! COMPUTED BEFORE 1ST SON
	STOREFLG=0,EXOPWD,32,1$,		!RESULT MUST BE STORED AFTER IT IS COMPUTED
	RESRFFLG=0,EXOPWD,31,1$,		!FLAG FOR "UNDER THIS NODE THERE IS A
						! REFERENCE TO THE VAR INTO WHICH THE RESULT
						! OF THE WHOLE EXPRESSION WILL BE STORED
	USRFNREF=RESRFFLG$,			!STATEMENT CONTAINS A USER
						!FUNCTION REFERENCE. ONLY ON 
						!A STATEMENT NODE.
	FNCALLSFLG=0,EXOPWD,30,1$,		!FLAG FOR "FN CALLS OCCUR UNDER THIS
						! NODE
	ALCRETREGFLG=0,EXOPWD,29,1$,		!VAL OF THIS NODE IS TO BE COMPUTED
						! IN THE "FN RETURN REG" 
	A1VALFLG=0,EXOPWD,28,1$,		!FIRST ARG IS A COMMON SUBEXPR THAT 
						! WAS ALREADY COMPUTED ELSEWHERE
						! OR A LEAF
	VALINR0=A1VALFLG$,			!SET IN ENTRY STATEMENT
						!BY GLOBAL ALLOCATOR TO INDICATE
						!FUNCTION VALUE IS ALREADY IN
						!REGISTER ZERO
	LABLARGS=A1VALFLG$,			!SET ON A CALL STATEMENT
						!ONLY TO  INDICATE THERE
						!ARE LABEL ARGS
	TRUEISBR=A1VALFLG$,			!SET ONLY ON LOGICAL IF
						!TO INDICATE THE THE TRUE
						!BRANCH IS A BRANCH.
	A1NOTFLG=0,EXOPWD,27,1$,		!APPLY 'NOT' TO 1ST ARG
	A1NEGFLG=0,EXOPWD,26,1$,		!NEGATE 1ST ARG
	A1SAMEFLG=0,EXOPWD,25,1$,		!LOC OF COMPUTATION FOR PARENT EQLS
						! LOC OF VALUE OF FIRST ARG
	A1IMMEDFLG=0,EXOPWD,24,1$,		!1ST ARG IS IMMED CONSTANT
	A2VALFLG=0,EXOPWD,23,1$,		!2ND ARG IS A COMMON SUBEXPR THAT WAS ALREADY
						! COMPUTED ELSEWHERE
						! OR A LEAF
	A2NOTFLG=0,EXOPWD,22,1$,		! APPLY NOT TO 2ND ARG
	NOLBLLST=A2NOTFLG$,			!USED BY OPTIMIZER ON AN
						!ASSIGNED GO TO TO INDICATE 
						!THAT THE PROGRAMMER DID NOT
						!SUPPLY A BRANCH LIST
	A2NEGFLG=0,EXOPWD,21,1$,		!NEGATE 2ND ARG
	A2SAMEFLG=0,EXOPWD,20,1$,		!LOC OF COMPUTATION FOR PARENT EQLS 
						! LOC OF VALUE OF 2ND ARG
	OPTCONFLG=A2SAMEFLG$,		!FLAG ON THE "CONTINUE" THAT WAS INSERTED BY THE OPTIMIZER
					! AT THE END OF THE PROGRAM
	A2IMMEDFLG=0,EXOPWD,19,1$,		!2ND ARG IS AN IMMED CONSTANT
	OPTOBOTHFLG=A2IMMEDFLG$,		!IF THIS BIT IS SET **AND** MEMCMPFLG IS
						! ALSO SET, THEN PERFORM OPERATION TO "BOTH"
	MEMCMPFLG=0,EXOPWD,18,1$;		!VALUE COMPUTED TO MEMORY

MACRO	CSFULLWDFLG=RVRSFLG$;		!IN A COMMON SUBEXPR NODEWHERE THE
					! COMMON-SUBEXPR IS A SINGLE VARIABLE (EG A
					! VAR USED IN RELATIONALS OR SUBSCRIPTS)
					! THIS FLAG IS SET IF THE WHOLE VARIABLE MUST BE LOADED
					! (EG IT IS USED IN A RELATIONAL), RATHER
					! THAN THE RIGHT-HALF BEING USABLE REGARDLESS OF
					! WHATS IN THE LEFT HALF (EG IT IS USED AS A SS ONLY)
MACRO	CSSSFLG=A1NOTFLG$;	!IN A COMMON SUBEXPR NODE, THIS FLAG IS SET IF THE
				! COMMON SUB IS EVER USED AS A SUBSCRIPT


	%(***DEFINE SUBFIELDS OF THE FLAGS FIELD***)%

	%(*****FLAGS FOR EACH OF THE 2 ARGS***)%
MACRO
	A1FLGS=0,EXOPWD,24,5$,
	A2FLGS=0,EXOPWD,19,5$;

	%(****LAST 4 FLAGS - NEG, NOT, SAME, IMMED****)%
	MACRO
		A1FLG1=0,EXOPWD,24,4$,
		A2FLG1=0,EXOPWD,19,4$;
	%(***A2IMMEDFLG CONCATENATED WITH MEMCMPFLG***)%
	MACRO A2IMMEMCMPFLGS=0,EXOPWD,18,2$;

	%(***NEG AND NOT FLAGS******************)%
	MACRO
		A1NGNTFLGS=0,EXOPWD,26,2$,
		A2NGNTFLGS=0,EXOPWD,21,2$;

	%(****TO CLEAR THE FLAGS FOR ARG1, OR FOR ARG2*****)%
	MACRO CLRA1FLGS(ANODE)=
		ANODE[EXPFLAGS]_.ANODE[EXPFLAGS] AND (NOT #003700)$;

	MACRO CLRA2FLGS(ANODE)=
		ANODE[EXPFLAGS]_.ANODE[EXPFLAGS] AND (NOT  #000076)$;

	%(******TO SWAP THE FLAGS FOR ARG1 AND ARG2 (WHEN ARE ALSO SWAPPIG THE 2 ARGS******)%

	%(***VALUE FOR A1FLGS OR A2FLGS FIELD WHEN ONLY THE VAL FLG IS SET***)%
BIND	VLFLSET=#20;

MACRO
	SWAPFLGS(NODE) =
	BEGIN
		REGISTER T1;
		T1_.NODE[A1FLGS];
		NODE[A1FLGS]_.NODE[A2FLGS];
		NODE[A2FLGS]_.T1;
	END $;

	%(****TO SET THE FLAGS FOR ARG1 TO THOSE FOR ARG2 AND CLEAR THOSE FOR ARG2 ****)% 
	MACRO A2TOA1FLGS(NODE)=
	BEGIN
		NODE[A1FLGS]_.NODE[A2FLGS];
		CLRA2FLGS(NODE);
	END$;

	%(***TO MOVE FLAGS FOR A SON INTO THE FLAG FIELD OF ITS PARENT (WHEN
		LINKING THE SON DIRECTLY UP TO THE PARENT'S PARENT***)%
MACRO
	RAISEFLGS(PARFLGS,SONFLGS)=
	BEGIN
		REGISTER T1;
		T1_(PARFLGS XOR SONFLGS) AND NGNTFLGMSK;	!TAKE XOR OF NEGFLGS AND 
								! NOTFLGS OF PARENT AND SON
		.T1 OR (SONFLGS AND VLIMSMMSK)		!USE VALFLG, SAMEFLG 
								! AND IMMEDFLG FOR SON
	END$;

	%(***MASK FOR NEG AND NOT FLAGS WITHIN A1FLGS/A2FLGS FIELDS***)%
BIND	NGNTFLGMSK=#14;

	%(***MASK FOR VALFLG,SAMEFLG, AND IMMEDFLG FIELDS WITHIN A1FLG/A2FLG FIELDS***)%
BIND	VLIMSMMSK=#23;




%(*********SUBFIELDS OF TARGET FIELD***********)%
MACRO
	INREGFLG=0,2,35,1$,		!FLAG FOR VAL LEFT IN A REG
	TARGTAC=0,2,23,4$,		!AC TO BE COMPUTED IN
	TARGAUX=0,2,27,4$,		!EXTRA AC TO COMPUTE IN, USED FOR
					! RELATIONALS (WHICH ARE "COMPUTED" IN A DIFFERENT
					! REG FROM THE ONE THAT HOLDS THE VALUE)
	TARGTMEM=0,2,0,23$,		!MEMORY REF TO GET AT FINAL RESULT
	TARGADDR=0,2,0,18$,		!ADDRESS FIELD FOR RETRIEVING RESULT
%1766%	STORETARGADDR(OFFS) = (ABS(OFFS) LSS #400000)$,
%1766%					! Checks if  we can  store  this
%1766%					! offset  in  TARGADDR.   Offset
%1766%					! stored in TARGADDR has 17 bits
%1766%					! of data and 1 bit of sign.

	TARGXF=0,2,18,4$,		!INDEX FIELD FOR RETRIEVING RESULT
	TARGIF=0,2,22,1$,		!INDIRECT FIELD FOR RETRIEVING RESULT
	TARGIXF=0,2,18,5$;		!INDIRECT AND INDEX FIELDS
%(***TO GET TARGTAC, TARGXF,  OR TARGAUX FIELD FROM A TARGET WD INTO THE AC BITS OF AN INSTR***)%
%(****OR TO GET TARGET-REG FOR AN ASSIGNMENT-STATEMENT NODE INTO THE AC BITS OF AN INSTR***)%
MACRO	GETTAC(NODE)=(.NODE[TARGET] AND #17^23)$,
	GETTXF(NODE)=((.NODE[TARGET] AND #17^18)^5)$,
	GETTAUX(NODE)= ((.NODE[TARGET] AND #17^27)^(-4))$,
	GETASMNREG(STMNTNODE)= (.STMNTNODE[CW4] AND #17^23)$,
	GETAIFREG(AIFNODE)=(.AIFNODE[CW5] AND #17^23)$;

	%(***GET THE INDEX AND INDIRECT BITS OF A TARGET WD***)%
MACRO GETTXFI(NODE)=(.NODE[TARGET] AND #37^18)$;


MACRO	IXFLD(REG)=REG^18$;



%(************************************************************
	DEFINE THE STRUCTURE FOR AN EXPRESSION NODE
************************************************************)%
STRUCTURE PEXPRNODE[FTP,WD,POS,SIZE]=

	%(***THE ARG "FTP" SELECTS THE ACCESSING ALGORITHM***)%
	CASE .FTP OF SET

		%(****FOR MOST FIELDS****)%
		(@.PEXPRNODE+.WD)<.POS,.SIZE>


		TES;





%(********************************************************
	VALUES FOR SUBFIELDS OF OPERATOR FIELD
************************************************************)%

%(*******VALUES FOR VALTYPE FIELD*****)%

![1212], Replace LITERAL with HOLLERITH and add CHARACTER

BIND
	OCTAL=0,		!00000
	LOGICAL=1,		!00001
	CONTROL=4,		!00100 - CONTROL-TYPE BOOLEAN
	DOUBLOCT=8,		!01000
%1212%	HOLLERITH=12,		!01100 - nHccc form
%1212%	CHARACTER=13,		!01101 - 'ccc' form
	INTEGER=16,		!10000
	BYTE=17,		!10001
	INDEX=18,		!10010
	REAL=20,		!10100
	DOUBLPREC=24,		!11000
	COMPLEX=28;		!11100 

	%(**NOTE THAT IN THE ABOVE THE 2ND BIT IS A FLAG FOR
		DOUBLE WD***)%
	%(***NOTE ALSO THAT THE 2ND AND 3RD  BITS DETERMINE THE CODE TO BE
		GENERATED IN MANY CASES (WHERE INDEX,BYTE,LOG ARE 
		TREATED AS INTEGER); AND THAT THESE 2 BITS ARE
		REFERENCED AS THE FIELD "VALTP1" *******)%
	%(***NOTE ALSO THAT IF THE FIRST 3 BITS OF THE VALTYPES OF 2 NODES
		ARE IDENTICAL, NO TYPE-CONVERSION OPERATION IS  NECESSARY
		WHEN COMBINING THE 2 NODES ARITHMETICALLY 
	*****)%
	%(***NOTE ALSO THAT THE OPERSP FIELD FOR A TYPE CONVERSION NODE IS EQUAL
		TO THE FIRST 3 BITS OF THE ORIGINAL TYPE
	****)%


	%(***VALUES FOR VALTP1 FIELD (BITS 2 AND 3  OF VALTYPE)***)%
BIND
	INTEG1=VTP1(INTEGER);	!00

	%(***VALUES FOR VALTP2 FIELD (BITS 1,2,3 OF VALTYPE)***)%
BIND
	COMPLEX2=COMPLEX^(-2), %[1027]%
	LOGICAL2=LOGICAL^(-2),
	REAL2=REAL^(-2);


	%(***TO TEST WHETHER A GIVEN VALTYPE IS DOUBLE-WD***)%
MACRO	DBLFROMVAL(VLTP)=
	(VLTP^(-3) AND 1)$;


	%(***TO TEST WHETHER A VALTYPE IS ONE THAT IS NEVER "CONVERTED", 
		IE IS ALWAYS USED AS A BIT PATTERN. THE TYPES THAT THIS IS TRUE
		OF  ARE:  LOGICAL,OCTAL,DOUBLE-OCTAL,LITERAL, AND CONTROL***)%
MACRO	BITPTNVALTYP(VLTP)=
	VLTP LSS INTEGER$;




%(******VALUES FOR OPRCLS FIELD********)%


![1212], Add SUBSTRING and CONCATENATION nodes for CHARACTER data.

BIND
	BOOLEAN=0,		!00000
	DATAOPR=1,		!00001
	RELATIONAL=2,		!00010
	FNCALL=3,		!00011 (OPERATOR=nn1400)
	ARITHMETIC=4,		!00100 (OPERATOR=nn2nnn)
	TYPECNV=5,		!00101
	ARRAYREF=6,		!00110		(OPERATOR=nn3000)
	CMNSUB=7,		!00111
	NEGNOT=8,		!01000
	SPECOP=9,		!01001		A SPECIAL CASE TO BE OPTIMIZED
				!		(P2MUL,SQUARE,...)
	FIELDREF=10,		!01010
	STORECLS=11,		!01011	Storeclass node.
				!	ARG2PTR> expression node to store.
	REGCONTENTS=12,		!01100	Variable lives in a register
				!	across some region of a program.
				!	ARG2PTR points to symbol table ref.
	LABOP=13,		!01101
	STATEMENT=14,		!01110
	IOLSCLS=15,		!01111	Element in an IOLIST
	INLINFN=16,		!10000	A function to be generated in line
%1212%	SUBSTRING=17,		!10001	Character substrings.
				!	ARG1PTR> Upper bound expression
				!	ARG2PTR> Lower bound expression
				!	ARG4PTR> ARRAYREF or DATAOPR
%1212%	CONCATENATION=18,	!10010	CHARACTER CONCATENATIONs
				!	ARG1PTR> Length of concatenation
				!	ARG2PTR> Argument list for concat
%2205%	EFIWREF=19;		!10011	EFIW reference

!***********************************************************************
! Values for OPERSP field
!***********************************************************************

	%(****FOR OPRCLS BOOLEAN****)%
BIND
	ANDOP=0,		!000
	OROP=1,			!001
	EQVOP=2,		!010
	XOROP=3;		!011

	%(***BIT 35 OF EXOPWD IS USED AS A FLAG IN A BOOLEAN NODE FOR "ARG2HAS VALTYPE
		CONTROL, ARG1 IS A MASK" ****)%



	%(****FOR OPRCLS DATA ITEM****)%
BIND
	CONSTANT=0,		!000
	TEMPORARY=1,		!001
	VARIABLE=2,		!010
	FORMLVAR=3,		!011
	ARRAYNAME=4,		!100
	FORMLARRAY=5,		!101
	FNNAME=6,		!110
	FORMLFN=7;		!111

	%(***DEFINE SUBFIELD OF OPERSP FOR DATA-ITEMS THAT DIFFERENTIATES
		FN AND FORMAL FN FROM ARRAY AND FORML ARRAY FROM VAR AND FORML VAR***)%
	MACRO	DATOPS1=OPRSP1$;	!FIRST 2 BITS OF OPERSP

	%(***DEFINE VALUES OF DATOPS1 FIELD***)%
BIND	VARIABL1=1,
	ARRAYNM1=2,
	FNNAME1=3;

	%(***TO TEST FOR AN DATA ITEM AN ENTRY IN THE SYMBOL TABLE (AS OPPOSED TO A 
		CONSTANT OR TEMPORARY*****)%
MACRO	SYMBOL(NODE)=(.NODE[OPERSP] GEQ VARIABLE)$;

	%(****FOR OPRCLS RELATIONAL****)%
BIND
	L=1,			!001
	E=2,			!010
	LE=3,			!011
	GE=5,			!101
	N=6,			!110
	G=7;			!111

MACRO
	EQREL(MODE) = (MODE AND #1) EQL 0$;		!E AND N  HAVE LAST BIT=0

MACRO
	REVREL(M) = M XOR #6$;			!"REVERSE" RELATIONAL FROM M (EG FOR
						! REVREL(GE) GET LE )
MACRO
	CMREL(M)= M XOR 4$;			!TO GET "COMPLEMENT" OF A CONDITION

	%(****FOR OPRCLS FNCALL****)%
BIND
	NONLIBARY=0,		!NOT A LIBRARY FUNCTION
	LIBARY=1;		!A LIBARY FUNCTION

	%(****FOR OPRCLS ARITHMETIC****)%
BIND
	ADDOP=0,		!000 (OPERATOR=nn2000
				!     where nn is the data type)
	SUBOP=1,		!001 (OPERATOR=nn2040)
	MULOP=2,		!010 (OPERATOR=nn2100)
	DIVOP=3,		!011 (OPERATOR=nn2140)
	EXPONOP=4;		!100 (OPERATOR=nn2200)


	! To transform ADD to SUB, SUB to  ADD; MUL to DIV, DIV to  MUL,
	! change the rightmost bit of OPERSP.

MACRO	CMPLSP(NODE)=
%1535%		(NODE[OPERSP] = .NODE[OPERSP] XOR #1)$;


	%(***TEST FOR OPERATOR EITHER ADD OR SUB****)%
MACRO
	ADDORSUB(NODE) = .NODE[OPR2] EQL OPR2C(ARITHMETIC,ADDOP)$;
	%(***TEST FOR OPERATOR FIELD EITHER MUL OR DIV***)%
MACRO
	MULORDIV(NODE) = .NODE[OPR2] EQL OPR2C(ARITHMETIC,MULOP)$;

	%(***TO TEST FOR OPERATOR (*KNOWN TO BE ARITH*) EQUAL TO EXPONENTIATION***)%
MACRO
%1535%	EXPONEN(NODE) = .NODE[OPRSMIDBIT]$;	!SECOND BIT OF OPERSP FIELD

	%(***TO TEST FOR OPERATOR (KNOWN TO BE ARITH) EQUAL TO SUB OR DIV****)%
MACRO
%1535%	SUBORDIV(NODE)= (.NODE[OPRSLASTBIT])$;	!LAST BIT OF OPERSP FIELD IS
						! SET FOR DIV AND SUB


	! Tests  for  an  operator (of unknown OPRCLS)  equal to ADD  or
	! MUL. OPRCLS must be ARITHMETIC,  OPERSP must have its 3rd  and
	! 5th bits 0.

MACRO 	ADDORMUL(NODE) =
%1535%		( (.NODE[OPERWORD] AND OPERC(0,#37,#35)) 
%1535%			EQL OPERC(0,ARITHMETIC,0) )$;


	%(*****TO TEST FOR A NODE OF UNKNOWN OPRCLS TO BE COMMUTATIVE - 
		VAL IS TRUE FOR ALL BOOLEANS AND FOR ADD AND MUL*********)%
MACRO	COMMUTATIVE(NODE)=
	(.NODE[OPRCLS] EQL BOOLEAN OR ADDORMUL(NODE) )$;
 


	%(****FOR OPRCLS TYPECNV****)%
BIND
	FROMOCT=0,		!000
	FROMCTL=1,		!001
	FROMDOCT=2,		!010
	FROMLIT=3,		!011
	FROMINT=4,		!100
	FROMREAL=5,		!101
	FROMDBLPRC=6,		!110
	FROMCMPLX=7,		!111
%1535%	FROMCHAR=8;		!1000


	%(***NOTE THAT THIS FIELD IS EQUAL TO THE FIRST 3 BITS OF THE VALTYPE
		FIELD FOR THE VALUE BEING CONVERTED FROM(THE VALTYPE FIELD 
		ON THIS NODE SPECIFIES THE TYPE TO CONVERT TO)****)%


MACRO	NOCNVFLG=0,EXOPWD,0,1$;		! BIT 35 OF EXOPWD IS USED AS  A
					! FLAG FOR "NO ACTUAL CONVERSION
					! TAKES PLACE"

	%(***TEST WHETHER ANY CODE MUST BE GENERATED FOR A GIVEN TYPE-CONVERSION NODE***)%
	MACRO NOCNV(TPCNODE)=
	BEGIN
		(
		(.TPCNODE[NOCNVFLG])		!IF FLAG WAS SET TO NOT ACTUALLY CONVERT
		OR
		(.TPCNODE[VALTP2] EQL .TPCNODE[OPERSP])
		OR
		(	(.TPCNODE[OPERSP] LSS FROMINT)	!CONVERTING FROM LOGICAL/OCTAL
							! OR DOUBLE-OCTAL OR CONTROL OR LITERAL
			AND
			( (NOT .TPCNODE[DBLFLG]) OR .TPCNODE[SDBLFLG])	!AND IF THE DESTIN IS
									!DBL WD, SO IS THE SRC
		)
		)
		AND (NOT .TPCNODE[A2IMMEDFLG])	!IF THE ARG UNDER THE TYPE-CNV
						! IS THE RIGHT HALF OF AN AOBJN VAR,
						! MUST LOAD IT
	END$;

	%(***** For OPRCLS ARRAYREF *****)%

BIND
%2463%	ARREFSMALL = 0,		! TARGADDR is actual offset for Y field
%2463%	ARREFBIG = 1,		! TARGADDR points to CTE for offset

	%(***FOR OPRCLS NEGNOT***************************)%

	NEGOP=0,
	NOTOP=1;

	%(****FOR OPRCLS SPECOP (SPECIAL OPS INTRODUCED BY PHASE 2 SKEL)***)%
BIND
	P2MULOP=0,		!MULTIPLY BY A POWER OF 2
	P2DIVOP=1,		!DIVIDE BY A POWER OF 2
	P2PL1OP=2,		!MULTIPLY BY A POWER OF 2 PLUS 1
	EXPCIOP=6;		!RAISE TO A  CONSTANT INTEGER POWER
				! (NOT HANDLED IN RELEASE 1)


	%(***FOR OPRCLS STORECLS****************************)%
BIND
	STARVAL=0,		!STORE CONTENTS OF AN ARRAY ELEM
	STARADDR=1,		!STORE PTR TO AN ARRAY ELEMENT
%2244%	STRHAOBJN=2;		!Store right hand half of AOBJN AC
%2244%				! into another AC.

	%(***FOR OPRCLS IOLSCLS (FOR IOLIST ELEMENTS)***)%
BIND
	DATACALL=0,		!SINGLE DATA ITEM
	SLISTCALL=1,		!ARRAY REFERENCED WITHOUT SUBSCRIPTS
	IOLSTCALL=2,		!GROUP OF OTHER IOLSTCALL NODES
	E1LISTCALL=3,		!FOLDED IMPLIED DO LOOPS CREATED
	E2LISTCALL=4,		!BY GLOBAL OPTIMIZER ONLY DURING PHASE2
	ESNGLELEM=5,		!SINGLE WORD ITEM UNDER AN ELISTCALL
	EDBLELEM=6;		!DOUBLE WORD ITEM UNDER AN ELISTCALL


	%(***FOR OPRCLS INLINFN (FNS TO BE GENERATED IN LINE)****)%
BIND
	ABSFN=0,
	CMPLXFN=1,
	SIGNFN=2,
	DIMFN=3,
	MODFN=4,
	MAXFN=5,
	MINFN=6,
%1567%	CHARFN=7,
%1567%	LENFN=8,
%1567%	ICHARFN=9,
%2352%	IORFN=10,
%2352%	IANDFN=11,
%2352%	ISHFTFN=12,	!** NOT YET IMPLIMENTED
%2352%	ISHFTCFN=13,	!** NOT YET IMPLIMENTED
%2352%	IBITSFN=14,	!** NOT YET IMPLIMENTED
%2352%	NOTFN=15,	!** NOT YET IMPLIMENTED
%2352%	IEORFN=16,
%2352%	BTESTFN=17,	!** NOT YET IMPLIMENTED
%2352%	IBSETFN=18,	!** NOT YET IMPLIMENTED
%2352%	IBCLRFN=19;	!** NOT YET IMPLIMENTED


	! *** Macro to determine for a given in-line-fn whether the  arg
	! should be put into the  reg-for-computation before the val  is
	! computed (for ABS, IABS, SIGN, and LEN do not want to load the
	! arg in advance).

	MACRO ILFINRFC(OPSP)=( (OPSP GEQ DIMFN)
%1535%		AND (OPSP LSS LENFN) )$;


![1212], Add OPERSP definitions for CONCATENATION

	%(***FOR OPRCLS CONCATENATION***)%
BIND

%1243%	CONCTF = 1,	! Length of result is known to compiler
%1243%	CONCTM = 2,	! Maximum length of result is known to compiler
%1243%	CONCTV = 3;	! Length of result is calculated at runtime

	%(****VALS FOR OPR1 FIELD FOR SOME OF THE OPERATORS*****)%
BIND
%2352%	ANDOPFL	=OPR1C(BOOLEAN,ANDOP),
%2352%	OROPFL	=OPR1C(BOOLEAN,OROP),
%2352%	XOROPFL	=OPR1C(BOOLEAN,XOROP),
	ADDOPF=OPR1C(ARITHMETIC,ADDOP),
	SUBOPF=OPR1C(ARITHMETIC,SUBOP),
	MULOPF=OPR1C(ARITHMETIC,MULOP),
	DIVOPF=OPR1C(ARITHMETIC,DIVOP),
	EXPONOPF=OPR1C(ARITHMETIC,EXPONOP),

	CONSTFL=OPR1C(DATAOPR,CONSTANT),
	VARFL=OPR1C(DATAOPR,VARIABLE),
	FMLVARFL=OPR1C(DATAOPR,FORMLVAR),
%1770%	ARRAYFL=OPR1C(DATAOPR,ARRAYNAME),
	FMLARRFL=OPR1C(DATAOPR,FORMLARRAY),
%2205%	FNNAMFL=OPR1C(DATAOPR,FNNAME),
	NEGFL	=OPR1C(NEGNOT,NEGOP),
%1567%	CHARFNFL=OPR1C(INLINFN,CHARFN),
%1567%	ICHARFNFL=OPR1C(INLINFN,ICHARFN),
%1567%	LENFNFL=OPR1C(INLINFN,LENFN),
	MODFNFL=OPR1C(INLINFN,MODFN),
	STARVLFL=OPR1C(STORECLS,STARADDR);

BIND
	P2MULOPF=OPR1C(SPECOP,P2MULOP),
	P2DIVOPF=OPR1C(SPECOP,P2DIVOP),
	P2PL1OPF=OPR1C(SPECOP,P2PL1OP);
BIND
	EXPCIF=OPR1C(SPECOP,EXPCIOP);
BIND
%2007%	DYNCONCAT = OPR1C(CONCATENATION,CONCTV);	! Dynamic Concatenation

	%(***VALUES OF OPERATOR FIELD FOR SOME OF THE OPERATORS***)%

BIND
	REALCONST=OPERC(REAL,DATAOPR,CONSTANT),
	INTCONST=OPERC(INTEGER,DATAOPR,CONSTANT),
	DOUBLCONST=OPERC(DOUBLPREC,DATAOPR,CONSTANT),
	CPLXCONST=OPERC(COMPLEX,DATAOPR,CONSTANT),

%1212%	HOLLCONST=OPERC(HOLLERITH,DATAOPR,CONSTANT),
%1245%	CHARCONST=OPERC(CHARACTER,DATAOPR,CONSTANT),
	INTVAR=OPERC(INTEGER,DATAOPR,VARIABLE),
	INDEXVAR=OPERC(INDEX,DATAOPR,VARIABLE);
BIND	INTDIVIDE=OPERC(INTEGER,ARITHMETIC,DIVOP);
BIND	INTADD=OPERC(INTEGER,ARITHMETIC,ADDOP);
BIND	CMPMUL=OPERC(COMPLEX,ARITHMETIC,MULOP),
	CMPDIV=OPERC(COMPLEX,ARITHMETIC,DIVOP);

	! Inline functions
BIND	ABSFNOP=OPERC(REAL,INLINFN,ABSFN),
	AMAXFNOP=OPERC(REAL,INLINFN,MAXFN),
	AMINFNOP=OPERC(REAL,INLINFN,MINFN),
%1567%	CHARFNOP=OPERC(CHARACTER,INLINFN,CHARFN),
	CMPLXFNOP=OPERC(COMPLEX,INLINFN,CMPLXFN),
	DABSFNOP=OPERC(DOUBLPREC,INLINFN,ABSFN),
	DIMFNOP=OPERC(REAL,INLINFN,DIMFN),
	IABSFNOP=OPERC(INTEGER,INLINFN,ABSFN),
%2352%	IANDFNOP=OPERC(LOGICAL,INLINFN,IANDFN),	
%1567%	ICHARFNOP=OPERC(INTEGER,INLINFN,ICHARFN),
	IDIMFNOP=OPERC(INTEGER,INLINFN,DIMFN),
%2352%	IEORFNOP=OPERC(LOGICAL,INLINFN,IEORFN),
%2352%	IORFNOP	=OPERC(LOGICAL,INLINFN,IORFN),
	ISIGNFNOP=OPERC(INTEGER,INLINFN,SIGNFN),
%1535%	LENFNOP=OPERC(INTEGER,INLINFN,LENFN),
	MODFNOP=OPERC(INTEGER,INLINFN,MODFN),
	MAXFNOP=OPERC(INTEGER,INLINFN,MAXFN),
	MINFNOP=OPERC(INTEGER,INLINFN,MINFN),
	SIGNFNOP=OPERC(REAL,INLINFN,SIGNFN);

BIND	! Type conversion

%1252%	CMPIOP=OPERC(COMPLEX,TYPECNV,FROMINT),
%1252%	CMPDOP=OPERC(COMPLEX,TYPECNV,FROMDBLPRC),
	CMPLXOP=OPERC(COMPLEX,TYPECNV,FROMREAL),
%1252%	DBLCOP=OPERC(DOUBLPREC,TYPECNV,FROMCMPLX),
	DBLEOP=OPERC(DOUBLPREC,TYPECNV,FROMREAL),
%1252%	DBLIOP=OPERC(DOUBLPREC,TYPECNV,FROMINT),
	DFLOATOP=OPERC(DOUBLPREC,TYPECNV,FROMINT),
	FLOATOP=OPERC(REAL,TYPECNV,FROMINT),
	IDINTOP=OPERC(INTEGER,TYPECNV,FROMDBLPRC),
%1252%	INTCOP=OPERC(INTEGER,TYPECNV,FROMCMPLX),
	INTOP=OPERC(INTEGER,TYPECNV,FROMREAL),
	IFIXOP=OPERC(INTEGER,TYPECNV,FROMREAL),
%1252%	REALIOP=OPERC(REAL,TYPECNV,FROMINT),
	REALOP=OPERC(REAL,TYPECNV,FROMCMPLX),
	SNGLOP=OPERC(REAL,TYPECNV,FROMDBLPRC);


BIND	LTOP=OPERC(CONTROL,RELATIONAL,L),
	EQOP=OPERC(CONTROL,RELATIONAL,E),
	LEOP=OPERC(CONTROL,RELATIONAL,LE),
	GEOP=OPERC(CONTROL,RELATIONAL,GE),
	NEOP=OPERC(CONTROL,RELATIONAL,N),
	GTOP=OPERC(CONTROL,RELATIONAL,G);

BIND	FIXOP=OPERC(INTEGER,TYPECNV,FROMREAL);
BIND
	DATACLFL=OPERC(0,IOLSCLS,DATACALL),
	SLISTCLFL=OPR1C(IOLSCLS,SLISTCALL),
	IOLSTCFL=OPERC(0,IOLSCLS,IOLSTCALL),
	E1LISTCFL=OPERC(0,IOLSCLS,E1LISTCALL),
	E2LISTCFL=OPERC(0,IOLSCLS,E2LISTCALL);

BIND	DOSTATEMENT=STOPERC(STATEMENT,DOID);
BIND	CONTSTATEMENT=STOPERC(STATEMENT,CONTID);

%(***DEFINE OPRCLS+SRCID FOR STATEMENTS***)%

MACRO
	OPERS(OPCLS,SORCID)=(OPCLS^7+SORCID)$,	!DEFINE CONCATENATED FIELDS
	OPRS=0,EXOPWD,1,12$;			!DEFINE OPRS FIELD

BIND
	ASGNOS=OPERS(STATEMENT,ASGNID),
	ASSIOS=OPERS(STATEMENT,ASSIID),
	CALLOS=OPERS(STATEMENT,CALLID),
	CONTOS=OPERS(STATEMENT,CONTID),
	DOOS=OPERS(STATEMENT,DOID),
	ENTROS=OPERS(STATEMENT,ENTRID),
	COMNOS=OPERS(STATEMENT,COMNSUB),
	GOTOOS=OPERS(STATEMENT,GOTOID),
	AGOOS=OPERS(STATEMENT,AGOID),
	CGOOS=OPERS(STATEMENT,CGOID),
	IFAOS=OPERS(STATEMENT,IFAID),
	IFLOS=OPERS(STATEMENT,IFLID),
	RETUOS=OPERS(STATEMENT,RETUID),
	STOPOS=OPERS(STATEMENT,STOPID),
	READOS=OPERS(STATEMENT,READID),
	WRITOS=OPERS(STATEMENT,WRITID),
	DECOOS=OPERS(STATEMENT,DECOID),
	ENCOOS=OPERS(STATEMENT,ENCOID),
	REREDOS=OPERS(STATEMENT,REREDID),
	FINDOS=OPERS(STATEMENT,FINDID),
	CLOSOS=OPERS(STATEMENT,CLOSID),
!	INPUOS=OPERS(STATEMENT,INPUID),
!	OUTPOS=OPERS(STATEMENT,OUTPID),
	BACKOS=OPERS(STATEMENT,BACKID),
	BKFILOS=OPERS(STATEMENT,BKFILID),
	REWDOS=OPERS(STATEMENT,REWDID),
	SKFILOS=OPERS(STATEMENT,SKFILID),
	SKRECOS=OPERS(STATEMENT,SKRECID),
	UNLODOS=OPERS(STATEMENT,UNLODID),
!	RELSOS=OPERS(STATEMENT,RELSID),
	ENDFOS=OPERS(STATEMENT,ENDFID),
	ENDOS=OPERS(STATEMENT,ENDID),
	PAUSOS=OPERS(STATEMENT,PAUSID),
	OPENOS=OPERS(STATEMENT,OPENID),
	SFNOS=OPERS(STATEMENT,SFNID),
	FORMOS=OPERS(STATEMENT,FORMID),
!	BLTOS=OPERS(STATEMENT,BLTID),
	REGOS=OPERS(STATEMENT,REGMASK),
%2200%	INQUOS=OPERS(STATEMENT,INQUID);

%(********VALUES FOR SPECIAL OPERATOR SUBFIELDS***********)%

	%(****USED FOR OPRCLS BOOLEAN*****)%
BIND
	ANDORCLS=0,		!VALUE OF BOOLCLS FOR AND/OR NODES
	ANDOPF=0,		!VALUE OF BOPRFLG FOR AND/EQV NODES
	XOROROPF=1;		!VALUE OF BOPRFLG FOR OR/XOR NODES



%(****************************************
	TO CHECK FOR VALUES THAT FIT IN SINGLE WD
****************************************)%
MACRO	SINGLWD(NODE)= NOT (.NODE[DBLFLG])$;


%(***************************************************************************
	TO TEST A CONSTANT NODE FOR BEING AN IMMEDIATE-SIZE CONSTANT
***************************************************************************)%


MACRO IMMEDCNST(NODE)=
BEGIN
	EXTERNAL KDPRL;		!THESE GLOBALS ARE USED IN CALLING THE MACRO MODULE
%[761]%	EXTERNAL KGFRL;		! For folding /GFLOATING DP to SP
	EXTERNAL C1H,C1L,C2H,COPRIX;	! THAT ROUNDS REAL NUMBERS
	EXTERNAL CNSTCM;

	CASE .NODE[VALTP1] OF SET
	%(***INTEGER CONSTANTS ARE IMMED SIZE IFF LH OF ABSOLUTE VAL IS 0***)%
	((ABS(.NODE[CONST2]) AND #777777000000) EQL 0);
	%(***REAL CONSTANTS ARE IMMED SIZE IFF THE RIGHT HALF WD IS
		ALL 0'S*******)%
	BEGIN
		%(***BECAUSE WE KEEP 2 WDS OF PRECISION THRUOUT COMPILE TIME,
			WE MUST EXAMINE WHAT THE ROUNDED CONSTANT WILL BE***)%
		C1H_.NODE[CONST1]; C1L_.NODE[CONST2];
![761] Round DP based on /GFLOATING flag
%[761]%		IF .GFLOAT THEN COPRIX_KGFRL ELSE COPRIX_KDPRL;	!ROUND THE NUMBER IN C1H-C1L
		CNSTCM();						! LEAVING THE RESULT IN C2H
		(.C2H AND #777777) EQL 0
	END;
	%(***DOUBLE-PREC CONSTANTS CAN NOT BE TREATED IMMED MODE***)%
	FALSE;
	%(***COMPLEX CONSTANTS CAN BE TREATED IMMED MODE IFF THE REAL PART IS
		IMMED SIZE AND THE IMAGINARY PART IS 0***)%
	((.NODE[CONST1] AND #777777) EQL 0) AND (.NODE[CONST2] EQL 0)
	TES
END$;

%(***TO TEST FOR A CONSTANT NEGATIVE***********)%
MACRO NEGATIVC(CNNODE)=
	BEGIN
		IF .CNNODE[VALTP1] EQL INTEG1
		THEN
		.CNNODE[CONST2] LSS 0
		ELSE
		.CNNODE[CONST1] LSS 0
	END$;







%(*****************OPCODE FIELDS USED EXPLICITLY***************************)%
BIND
	JRSTOC=#254^27,
	JUMPOC=#320^27,
	SKIPOC=#330^27,
	SKIPGEOC=#335^27;
BIND
	INDBIT=1^22;		!INDIRECT BIT

BIND	
	ADDBOCD=#273,
	ADDIOCD=#271,
	ADDMOCD=#272,
	AOJAOCD=#344,
	AOSOCD=#350,
	ASHOCD=#240,
	CAIOCD=#300,
	CAMOCD=#310,
	DMOVEOCD=#120,
	DMOVEMOCD=#124,
	FADRBOCD=#147,
	FADRMOCD=#146,
	FDVRMOCD=#176,
	FIXOCD=#122,
	FLTROCD=#127,
	FSCOCD=#132,
	HRLZIOCD=#515,
	IDIVMOCD=#232,
	IMULMOCD=#222,
	JRSTOCD=#254,
	JUMPOCD=#320,
	JUMPGEOCD=#325,
	JUMPLOCD=#321,
	MOVEIOCD=#201,
	MOVEOCD=#200,
	MOVEMOCD=#202,
	MOVNOCD=#210,
	MOVNIOCD=#211,
	MOVNMOCD=#212,
	MOVNSOCD=#213,
	MOVSIOCD=#205,
	SETCAMOCD=#452,
	SETCMOCD=#460,
	SETCMBOCD=#463,
	SETZBOCD=#403,
	SETOBOCD=#477,
	SKIPOCD=#330,
	SOJAOCD=#364,
	SOSOCD=#370,
	SUBIOCD=#275,
	PUSHJOCD=#260,
	DIVOCD=#230,
	XCTOCD=#256,
	SUBMOCD=#276;

	!***************************************************************
	! Define the fields for IOLSCLS nodes. DATACALLs and  SLISTCALLs
	! have 4 words, IOLISTCALLs, E1LISTCALLs, and E2LISTCALLs have 6
	! words.  The fields are:
	!
	! 	-------------------------------------------------
	! 0	! IOLSTLBL AND IOLCMPLX	! CLINK			!
	!	-------------------------------------------------
	! 1	! DCALLELEM		! OPERATOR		!
	!	! SCALLELEM		!			!
	!	! IOLSTPTR		!			!
	!	! ELSTPTR		!			!
	!	-------------------------------------------------
	! 2	! IOLALTCMPLX		! SCALLCT		!
	!	!			! IOLCOMNSUB		!
	!	-------------------------------------------------
	! 3	! IOLFLAGS		! IOLSTATEMENT		!
	!	! IOLDYNFLG		!			!
	!	-------------------------------------------------
	! 4	! E1INCR 		! ECNTPTR		!
	!	-------------------------------------------------
	! 5	! (not used)		! ELPFVLCHAIN		!
	!	-------------------------------------------------
	!
	! The fields under ELSTPTR are:
	!
	!	-------------------------------------------------
	! 0	! E2INCR 		! CLINK			!
	!	-------------------------------------------------
	! 1	! E2ARREFPTR		! OPERATOR		!
	!	-------------------------------------------------
	!
	!***************************************************************

	! Fields in all IOLSCLS nodes
MACRO
	IOLSTLBL = 0,0,LEFT$,		! Pointer to the label  used for the
					! argument list to the  IOLST.  call
%1530%	IOLFLAGS = 0,3,LEFT$,		! Flags field
%1530%	IOLDYNFLG = 0,3,35,1$,		! Flag for this IOLST. call has
%1530%					! dynamic concatenations under it
%1530%	IOLSTATEMENT = 0,3,RIGHT$,	! Pointer to the I/O statement above
%1530%					! this IOLSCLS node

	! Fields in DATACALL nodes

	DCALLELEM = 0,1,LEFT$,		! Pointer to the expression

	! Fields in SLISTCALL nodes

	SCALLELEM = 0,1,LEFT$,		! Pointer to the arrayname
	SCALLCT = 0,2,RIGHT$,		! Number of elements in the array

	! Fields in IOLSTCALL nodes

	IOLSTPTR = 0,1,LEFT$,		! Pointer to linked list of subnodes
	IOLCMPLX = SRCCMPLX$,		! Complexity for this iolist
	IOLCOMNSUB = SRCCOMNSUB$,	! Pointer to common subexpressions
	IOLALTCMPLX = 0,2,LEFT$,	! Alternate complexity in E1LISTCALL
					! and E2LISTCALL nodes

	! Fields in E1LISTCALL and E2LISTCALL nodes

%1530%	ECNTPTR = 0,4,RIGHT$,		! Pointer to expression for number of
					! elements of each array
	ELSTPTR = 0,1,LEFT$,		! Pointer to linked list of ARRAYREFs
%1530%	ELPFVLCHAIN = 0,5,RIGHT$,	! Pointer to linked list of statements
					! setting up final loop index values

	! Fields in E1LISTCALL nodes

%1530%	E1INCR = 0,4,LEFT$,		! Pointer to the increment expression

	! Fields of the elements of the linked list under an E2LISTCALL

	E2INCR = 0,0,LEFT$,		! Pointer to the increment expression
	E2ARREFPTR = 0,1,LEFT$;		! Pointer to the ARRAYREF node

! Define names for fields of a one word local byte pointer

! !=========================================================================!
! !     P     !     S     !G!I!   X    !            Y (Address)             !
! !=========================================================================!

MACRO
%2423%	OWLBPP = 30,6 $,		! Position field
%2423%	OWLBPS = 24,6 $,		! Size field
					! Local/global flag (unused)
					! Indirect bit (unused)
					! Index field (unused)
%2423%	OWLBPADDR = 0,18 $,		! Address field

! Define names for fields of a one word global byte pointer

! !=========================================================================!
! !    P&S    !                         Y (Address)                         !
! !=========================================================================!

%2330%	OWGBPADDR = 0,30 $,		! Address field
%2330%	OWGBPP&S = 30,6 $;		! Combination P&S field


! Object program's entry vector:

! !=========================================================================!
! !           JRST (254000)            !   Object program's start address   !
! !-------------------------------------------------------------------------!
! !          JRST @ (254020)           !      Address of EFIW (below)       !
! !-------------------------------------------------------------------------!
! !        Space for a version number (compiler leaves it 0 for now)        !
! !=========================================================================!
! !                             .EFIW REENT.##                              !
! !=========================================================================!

BIND					! Object program entry vector
%2355%	STARTOFF = 0,			! Start entry
%2355%	REENTOFF = 1,			! Reenter entry
%2355%	VERSIONOFF = 2,			! Version number entry
%2355%	ENTVECSIZE = 3,			! Size of the entry vector
%2355%	REEINDOFF = ENTVECSIZE+0,	! First word of the auxiliary block
					!  (indirect word for REENT.##)
%2355%	ENTAUXSIZE = 1;			! Size of the auxiliary block after
					!  the entry vector

%(***************************************************************************
	DEFINE AN OBJECT-CODE WORD AS A STRUCTURE.
	DEFINE THE FIELDS OF THAT WORD FOR FOROTS ARG BLOCKS.
***************************************************************************)%

STRUCTURE OBJECTCODE[WD,POS,SIZE]=
   (.OBJECTCODE+.WD)<.POS,.SIZE> ;



	%(***DEFINE THE FIELDS OF AN INSTRUCTION***)%
MACRO
	OBJADDR=0,0,18$,		! Address field
	OBJIXF=0,18,5$,			! Indirect and index fields
	OBJREG=0,23,4$,			! Register field
	OBJOPCOD=0,27,9$;		! Opcode
	%(***DEFINE THE FIELDS USED FOR ARG BLOCKS***)%
MACRO
	OTSWHOLE=0,0,36$,		! Field for the whole word
	OTSCNT=0,27,9$,			! Dimensions in a NAMELIST variable
	OTSTYPE=0,23,4$,		! Value-type always goes in bits 9-12
	OTSINX=0,18,4$,			! Index field
	OTSIND=0,22,1$,			! Indirect bit
	OTSADDR=0,0,18$,		! Address field
%1401%	OTSFSIZ=0,18,18$,		! FORMAT size
%1401%	OTSIDN=0,27,7$,			! Identifies IOLIST element class
%1401%	OPENGFIELD=0,27,7$,		! Differentiates OPEN statement args
	OTSMEMRF=0,0,23$,		! All 23 bits for memory references
%1401%	OTSIFIW=0,35,1$,		! 0=>I+X+33 bit Y, 1=>I+X+18 bit Y
%1401%	OTSEIND=0,34,1$,		! Indirect bit for EFIW, 0 for IFIW

![760] Field definitions and values for I/O keywords
%1401%	OTSKEY=0,27,7$;			! Differentiates I/O arguments
%[760]%
%[760]%	%(***Define values for OTSKEY field in I/O arg blocks***)%
%[760]%
%[760]%	BIND
%[760]%		OTSKUNIT = 1,	! UNIT=
%[760]%		OTSKFMT  = 2,	! FMT=
%[760]%		OTSKFSIZ = 3,	! format length in words
%[760]%		OTSKEND  = 4,	! END=
%[760]%		OTSKERR  = 5,	! ERR=
%[760]%		OTSKIOS  = 6,	! IOSTAT=
%[760]%		OTSKREC  = 7,	! REC=
%[760]%		OTSKNAME = #10,	! namelist name
%[760]%		OTSKMTOP = #11, ! magtape opcode for REWIND, UNLOAD, etc.
%[760]%		OTSKEDARR = #12, ! ENCODE/DECODE array name
%[760]%		OTSKEDSIZ = #13; ! ENCODE/DECODE count


	%(***DEFINE VALUES FOR IDN FIELD FOR IOLIST ELEMENTS***)%

![1216]		Add OTSSLIST77 and OTSELIST77
BIND
	OTSZER=0,	! Illegal
	OTSDATA=1,	! DATA call
	OTSSLIST=2,	! F66 SLIST (one-trip loops)
	OTSELIST=3,	! F66 ELIST (one-trip loops)
	OTSFIN=4,	! FIN call (end-of-list)
%1216%	OTSSLIST77=5,	! F77 SLIST (potential zero trip)
%1216%	OTSELIST77=6,	! F77 ELIST (potential zero trip)
%2400%	OTSNSLIST=7,	! New F66 SLIST (one-trip loops) E1 lists only
%2400%	OTSNELIST=8,	! New F66 ELIST (one-trip loops) E2 lists only
%2400%	OTSNSLIST77=9,	! New F77 SLIST (potential zero-trip) E1 lists only
%2400%	OTSNELIST77=10;	! New F77 ELIST (potential zero-trip) E2 lists only


BIND
	OTSZERWD=OTSZER^27,
	OTSFINWD=OTSFIN^27;


	%(***DEFINE ARG TYPE CODES THAT ARE USED FOR FOROTS CALLS***)%
BIND	ADDRTYPE=#7,		!TYPE CODE FOR A LABEL
	IMMEDTYPE=0;		!TYPE CODE INDICATING TO PICK UP ARG IMMED MODE


%(***************************************************************************
	SPECIFIC VALUES FOR FIELDS IN AN ARITHMETIC-IF NODE
***************************************************************************)%

	%(***VALUES FOR AIFLBEQV FIELD****)%
BIND
	NOLBEQV=0,
	LELBEQV=1,		!LSS LABEL SAME AS EQL LABEL
	LGLBEQV=2,		!LSS LABEL SAME AS GTR LABEL
	GELBEQV=3;		!GTR LABEL SAME AS EQL LABEL

	%(***VALUES FOR AIFLBNXT FIELD*******)%
BIND
	NOLBNXT=0,
	LLBNXT=1,		!LSS LABEL IS NEXT STMNT
	ELBNXT=2,		!EQL LABEL IS NEXT STMNT
	GLBNXT=3;		!GTR LABEL IS NEXT STMNT


	%(***WHEN SWAP THE GTR AND LESS LABELS (BECAUSE MULTIPLY BY -1), USE THE
		FOLLOWING MACRO TO ADJUST THE "AIFLBNXT" AND "AIFLBEQV"  FIELDS***)%
	MACRO SWPAIFFLGS(STMNT)=
	BEGIN
		IF .STMNT[AIFLBNXT]		!IF LAST BIT OF AIFLBNXT IS ON
		THEN
		STMNT[AIFLBNXT]_.STMNT[AIFLBNXT] XOR #2;	!THEN COMPLEMENT 1ST BIT
		IF .STMNT[AIFLBEQV]				!IF LAST BIT OF AIFLBEQV ON
		THEN
		STMNT[AIFLBEQV]_.STMNT[AIFLBEQV] XOR #2;	!THEN COMPLEMENT 1ST BIT
	END$;

	!***************************************************************
	! Define the  structure  of  an argument  list.   Certain  fixed
	! fields on the list will be referenced simply by name.   Fields
	! corresponding to the  nth arg will be referenced by  [n,name].
	! Note that the first arg has N = 1  (not!!!! 0).  Note that the
	! count field of  the list  will be  positive and  equal to  the
	! number of args.
	!***************************************************************

%1530%	BIND	ARGHDRSIZ = 4;	! The fixed size of the argument list

	STRUCTURE ARGUMENTLIST[ARGINDEX,WD,POS,SIZE]=
%1413%	(@.ARGUMENTLIST+ARGHDRSIZ+(.ARGINDEX-1)+.WD)<.POS,.SIZE>;

	!***************************************************************
	! This macro defines the number of words necessary in an ARGLIST
	! in terms of the number of args.
	!***************************************************************

%1413%	MACRO	ARGLSTSIZE(ARGCNT)=(ARGHDRSIZ+(ARGCNT))$;

	!***************************************************************
	! Define the  fixed fields  that  occur at  the start  of  every
	! argument list - Define all these fields in terms of a negative
	! number of words from the  entry for the first argument  (hence
	! have the ARGINDEX field be 1).
	!
	! 	---------------------------------
	! -4	! ARGLABEL	! ARGLINK	!
	!	---------------------------------
	! -3	! ARGPARENT	! ARGCOUNT	!
	!	---------------------------------
	! -2	! ARGCHBLOCK	! ARGCALL	!
	!	---------------------------------
	! -1	! ARGMARK	! unused	!
	!	---------------------------------
	!  0	! AVALFLG	! ARGNPTR	!	(first argument)
	!	---------------------------------
	!  1	! AVALFLG	! ARGNPTR	!	(second argument)
	!	---------------------------------
	!  etc.
	!
	!***************************************************************

MACRO
%1530%	ARGLABEL = 1,-4,LEFT$,		! Pointer to label table for arguments
%1530%	ARGLINK = 1,-4,RIGHT$,		! Link to next arg node
%1530%	ARGPARENT = 1,-3,LEFT$,		! Pointer to parent subroutine/function
%1530%	ARGCOUNT = 1,-3,RIGHT$,		! Count of number of args
%1530%	ARGCHBLOCK = 1,-2,35,1$,	! Flag - "Create arg check block for 
					! this arg list"
%1530%	ARGCALL = 1,-2,RIGHT$,		! Address in object code of last call
%1530%	ARGMARK = 1,-1,LEFT$,		! Pointer to the argument list for the
					! calls to CHMRK. and CHUNW. for calls
	 				! with CONCTV nodes as arguments

	!***************************************************************
	! Define the fields that are  repeated for each argument.   Will
	! always  reference  these  fields  by   a  ref  of  the   form:
	! ALIST[N,FIELDNAME] where  N  is  the number  of  the  argument
	! desired.
	!***************************************************************

%1413%	ARGFULL = 0,FULL$,		! Full argument field
	AFLGFLD = 0,LEFT$,		! Argument flags
	AVALFLG = 0,35,1$,		! Flag for argument is a DATAOPR
					! or a common subexpression.
	ARGNPTR = 0,RIGHT$,		! Pointer to the expression node
					! for the argument
	P1AVALFLG = 0,0,35,1$;		! Field to reference the AVALFLG
					! by using the BASE structure on
					! a given word. Used in PHAS1.

%(*******DEFINE FIELDS USED IN THE ARGUMENT LIST AT AN ENTRY STATEMENT*****)%
MACRO	ENTGALLOCFLG=0,35,1$,	!FLAG FOR "GLOBAL ALLOCATOR HAS ASSIGNED THIS
				! VAR TO LIVE IN A REGISTER"
	ENTSAVREGFLG=0,34,1$,	!FLAG INDICATING THAT IT WILL BE USEFUL TO
				! HAVE THIS VAR IN A REG LATER IN THIS BASIC
				! BLOCK (FLAG IS SET BY BASIC BLOCK ALLOCATOR)
	ENTNOCOPYFLG=0,33,1$,	!FLAG INDICATING THAT NO LOCAL COPY OF THE ARG
				! SHOULD BE MADE
	ENTSONNXTUSE=0,22,11$,	!BLOCK-INTERNAL-SEQ-NUMBER OF THE STMNT
				! WHERE THIS VAR IS NEXT USED (0 IF IT IS
				! NOT USED IN THE 1ST BASIC BLOCK)
	ENTAC=0,18,4$;		!AC TO BE USED WHEN PICKING
				! UP THIS ARG


%(***************************************************************************
	DEFINE THE STRUCTURE THAT WILL BE MAPPED ON THE LIBRARY FN ATTRIBUTE
	TABLE.
	FOR EACH LIBRARY-FN WILL HAVE A "LIBRARY-FN-INDEX" THAT INDICATES ITS
	POSITION IN THIS TABLE. THE FIRST ENTRY HAS INDEX =0.
***************************************************************************)%
STRUCTURE LIBATTSTR[FNINDEX,WD,POS,SIZE,CODE,ARGTYP1]=
	%(***FOR MOST FIELDS BOTH "CODE" AND "ARGTYP1" ARE 0***)%
	IF .CODE EQL 0
	THEN
	(.LIBATTSTR+2*.FNINDEX+.WD)<.POS,.SIZE>

	%(***FOR GENERIC FUNCTIONS ONLY - TO PICK UP THE NAME OF THE ACTUAL
		FUNCTION TO USE FOR A GIVEN ARG-TYPE.
		HAVE "CODE" EQUAL TO 1, "ARGTYP1" EQUAL TO THE VALTP1
		FIELD OF THE ARGUMENT.
	**********)%
	ELSE
	%(***GO INDIRECT THRU  THE "ATTGENPTR" FIELD - ADD "ARGTYP1" TO
		THE PTR IN THAT FIELD TO GET A PTR TO THE WD THAT
		INDICATES THE ACTUAL FN TO USE (THAT WD WILL ITSELF CONTAIN
		A PTR BACK TO A FUNCTION-TABLE ENTRY)
	*******)%
	(.(.LIBATTSTR+2*.FNINDEX+.WD)<.POS,.SIZE> + .ARGTYP1)<0,36>;

	%(***DEFINE MACROS THAT DESCRIBE THE FIELDS FOR A GIVEN FUNCTION INDEX***)%
MACRO
	ATTFNATTRIB=0,0,36,0,0$,	!THE FIRST WORD OF THE ENTRY WILL BE
					! COPIED INTO THE SYMBOL TABLE ENTRY
					! FOR THE FUNCTION NAME (INTO THE IDFNATTRIB FIELD)
	ATTINLINFLG=0,35,1,0,0$,	!BIT 0 OF 1ST WD IS FLAG FOR IN-LINE-FN
	ATTGENERFLG=0,33,1,0,0$,	! GENERIC FN FLAG
	ATTARGTYP=0,28,5,0,0$,	! VALTYPE FOR EXPECTED ARG
	ATTRESTYPE=0,23,5,0,0$,	! VALTYPE OF RESULT
	ATTARGCT=0,18,5,0,0$,	! NUMBER OF ARGS EXPECTED
	ATTNEWOPR=0,0,18,0,0$,	!OPERATOR TO BE SUBSTITUTED FOR FN CALL
				! IF THIS FN IS TO BE GENERATED IN LINE
%1270%	ATTSPGEN=1,35,1,0,0$,	! Bit 0 of 2nd word is flag for  generic
				! but  not  specfic  function.    (octal
				! argument is illegal)
%1567%	ATTFNFOLD=1,34,1,0,0$,	! May be  able to  fold fn  call into  a
				! constant.
	ATTGENPTR=1,0,18,0,0$,	! For generic fns only - ptr to subtable
				! describing which fns  to use for  each
				! arg type
	ATTACTFN=1,0,18,1$;	! For generic fns only - to get a ptr to
				! the actual fn to use will go  indirect
				! thru the  "ATTGENPTR" field  and  then
				! add on the type of the arg


	BIND	ILGARGTYPE=-1;	! For generic fns - If a given arg  type
				! is illegal  the "ATTACTFN"  field  for
				! that type will contain this code
	BIND	VARGCTFLG=#37;	! Functions that can  take an  arbitrary
				! number of args  (eg MAX,MIN) have  the
				! "ATTARGCT" set to this val



%(*************************************************************************
	Define the bits in CFTABLEV which describe the differences
	between Fortran-10/20 intrinsic functions and subroutines
	and those of VMS and the Fortran-77 standard.

	These bits are used in compatibility flagging.

	These definitions were added in edit [2276]
*************************************************************************)%

	BIND
%2455%		CFFNVMS=1^0,	! Intrinsic function on VMS, but not us
%2455%		CFNOTFNVMS=1^1,	! Intrinsic function for us, but not VMS
		CFNOTFNF77=1^2,	! Intrinsic function for us, but not Fortran-77
%2455%		CFSBVMS=1^3,	! Subroutine on VMS, but not for us
%2455%		CFNOTSBVMS=1^4,	! Subroutine for us, but not VMS
		CFNOTSBF77=1^5,	! Subroutine for us, but not Fortran-77
%2455%		CFNOTGNUS=1^6,	! Function is generic on VMS, but not us
%2455%		CFNOTGNVMS=1^7,	! Function is generic for us, but not VMS
		CFNOTGNF77=1^8,	! Function is generic for us, but not Fortran-77
%2455%		CFSBDIFF=1^9;	! Subroutine supplied by VMS, but is not
				!	entirely compatible with us

%(***************************************************************************
	DEFINE THE STRUCTURE TO BE MAPPED ON THE LIST OF ARGTYPES
	TO GET THE VALUES THAT OCCUR IN AN ARGBLOCK
***************************************************************************)%

%[1002]%	STRUCTURE EVALTAB[IDX]=
%[1002]%		IF .GFLOAT
%[1002]%		THEN (.EVALTAB + .IDX + 32)<WHOLE>
%[1002]%		ELSE (.EVALTAB + .IDX)<WHOLE>;

%(***************************************************************************
	DEFINE THE STRUCTURE TO BE MAPPED ON THE LIST OF ARG-CODES
	AND CORRESPONDING  VALUES THAT OCCURS UNDER AN OPEN STATEMENT
***************************************************************************)%

STRUCTURE OPENLIST[ARGINDEX,WD,POS,SIZE]=
	(@.OPENLIST+.ARGINDEX+.WD)<.POS,.SIZE>;


	%(***DEFINE THE FIELDS USED FOR A GIVEN INDEX***)%
MACRO	OPENLCODE=0,LEFT$,	!CODE FOR FOROTS FOR THIS ARG
	OPENLPTR=0,RIGHT$;	!PTR TO THE CONSTANT TABLE OR SYMBOLTABLE
				! ENTRY FOR THE VALUE FOR THIS ARG TO FOROTS

	%(***DEFINE VALUES FOR OPENLCODE***)%
BIND	OPNCDIALOG=#53,		!DIALOG
%2426%	OPNCNEDIALOG=#1,	! dialog without =
	OPNCACCESS=#2,		!ACCESS
	OPNCDEVICE=#3,		!DEVICE
	OPNCBUFCOUNT=#4,	!BUFFER COUNT
	OPNCBLOCKSIZE=#5,	!BLOCK SIZE
	OPNCFILE=#6,		!FILE
	OPNCPROTECTION=#7,	!PROTECTION
	OPNCDIRECT=#10,		!DIRECT
%2043%	OPNCLIMIT=#11,		!LIMIT - back again
	OPNCMODE=#12,		!MODE
	OPNCFILESIZE=#13,	!FILE SIZE
	OPNCRECORDSIZE=#14,	!RECORD SIZE
	OPNCDISPOSE=#15,	!DISPOSE
	OPNCVERSION=#16,	!VERSION
!	OPNCREELS=#17,		!REELS - gone
!	OPNCMOUNT=#20,		!MOUNT - gone

![760] Values for new keys on OPEN/CLOSE
%[760]%	OPNCIOSTAT=#21,		! iostat
	OPNCASSOCIATE=#22,	! associate variable
%[760]%	OPNCPARITY=#23,		! parity
%[760]%	OPNCDENSITY=#24,	! density
%[760]%	OPNCBLANK=#25,		! blank
%[760]%	OPNCCARRIAGE=#26,	! carriage control
%[760]%	OPNCFORM=#27,		! format
!%760%	OPNCLABELS=#30,		! labels - gone
%[760]%	OPNCPADCHAR=#31,	! padchar
%[760]%	OPNCRECTYPE=#32,	! rectype
%[760]%	OPNCSTATUS=#33,		! status
%2413%	OPNCTAPEFO=#34,		! tape format
%[760]%	OPNCREADONLY=#35,	! readonly
%[760]%	OPNCUNIT=#36,		! unit
%[760]%	OPNCERREQ=#37,		! err=
%2200%	IOCEXIST=#40,		! exist
%2200%	IOCFORMATTED=#41,	! formatted
%2200%	IOCNAMED=#42,		! named
%2200%	IOCNEXTREC=#43,		! nextrec
%2200%	IOCNUMBER=#44,		! number
%2200%	IOCOPENED=#45,		! opened
%2200%	IOCSEQUENTIAL=#46,	! sequential
%2200%	IOCUNFORMATTED=#47,	! unformatted
%2200%	IOCNAME=#50;		! name

BIND
%2426%	MAXOTSKWD=#53;		! maximum keyword number in above list

%(***************************************************************************
	DEFINE THE STRUCTURE OF THE SYMBOL TABLE
***************************************************************************)%
STRUCTURE SYMTABENTRY[DMY,WD,POS,SIZE]=
	(@.SYMTABENTRY+.WD)<.POS,.SIZE>;
!	Define the structures for the dimension table
!		(DIMENTRY and DIMSUBENTRY)
!
![2314]	Pretty things up

!   !=========================================================================!
! 0 !ADJ!ASS!           DIMNUM           !             ARACONSIZ              !
!   !-------------------------------------------------------------------------!
! 1 !             ARAOFFSET              !             ARADDRVAR              !
!   !-------------------------------------------------------------------------!
! 2 !              ARADLBL               !              ARALINK               !
!   !-------------------------------------------------------------------------!
! 3 !                                 ARASIZ                                  !
!   !=========================================================================!
! 4 !               DIMLB                !               DIMUB                !
!   !-------------------------------------------------------------------------!
! 5 !F!L!U!                              !             DIMFACTOR              !
!   !-------------------------------------------------------------------------!
!   \                                                                         \
!   \                         More subscript entries                          \
!   \                                                                         \
!   !=========================================================================!

STRUCTURE DIMENTRY[DMY,WD,POS,SIZE] = (@.DIMENTRY+.WD)<.POS,.SIZE>;

BIND	DIMSUBSIZE=2;	! Number of words in each subscript entry

MACRO	ADJDIMFLG=0,0,35,1 $,		       !Flag for adjustably dimensioned
%1510%	ASSUMESIZFLG=0,0,34,1 $,	       !Flag for Assumed Size Array
	DIMNUM=0,0,18,16 $,		       !NUMBER OF DIMENSIONS
%2314%	ARACONSIZ = 0,0,RIGHT$,	! If not adjustably dimensioned, pointer to a
				! constant table entry containing the value of
				! ARASIZ.  Used for OTSKFSIZ FOROTS argument.
				! Valid only after complexity walk sees array
				! used for Hollerith array format.

	ARAOFFSET=0,1,LEFT$,	! VALUE OF  OFFSET  FOR  THIS  ARRAY  IF
				! DIMENSIONS ARE  CONSTANT;  POINTER  TO
				! LOC IN WHICH THE OFFSET WILL BE STORED
				! IF DIMENSIONS ARE VARIABLE

	ARADDRVAR=0,1,RIGHT$,	! FOR  FORMAL   ARRAYS  THAT   ARE   NOT
				! ADJUSTABLY  DIMENSIONED,  THIS   FIELD
				! POINTS  TO  A  "PSEUDO"  SYMBOL  TABLE
				! ENTRY FOR THE ARRAY NAME WITH THE TYPE
				! FIELD SET  TO  INTEGER.   IT  IS  THIS
				! SYMBOL THAT  IS  USED IN  THE  ADDRESS
				! CALC

	ARADLBL=0,2,LEFT$,	! PTR TO LABEL TABLE ENTRY FOR LABEL  ON
				! THE    ARG-BLOCK    DESCRIBING     THE
				! DIMENSIONS OF THIS ARRAY THAT WILL  BE
				! OUTPUT IF THE  ARRAY WAS PROTECTED  OR
				! THE USER SPECIFIED THE DEBUG SWITCH

	ARALINK = 0,2,RIGHT$,	! LINK TO  NEXT DIM  TABLE ENTRY  GLOBAL
				! DTABPTR IS HEAD OF LIST

%1245%	! Move ARASIZ to word 3 since character array size is in characters

 	ARASIZ=0,3,FULL$,	! Number of words  or characters in  the
				! array.    If   array   is   adjustably
				! dimensioned, have ptr  to a tmp  table
				! entry.

%1245%	! Dimension info starts in word 4;  ARASIZ is now word 3.

	FIRSTDIM=0,4,WHOLE$,	! First dimension's subscript.

	! *** Note  that   THIS  INFORMATION   IS  DUPLICATED   in   the
	! *** DIMSUBENTRY structure  definition BELOW!!!!   Any  changes
	! *** here MUST be made there also!!!!

	! X is the subscript number.

%2202%	DIMENS(X)=0,4+DIMSUBSIZE*X,FULL$,	!X's dimensions (up & lower)
%2202%	DIMENL(X)=0,4+DIMSUBSIZE*X,LEFT$,	!Ptr to X's lower bound
%2202%	DIMENU(X)=0,4+DIMSUBSIZE*X,RIGHT$,	!Ptr to X's upper bound
%2202%	DVARFLGS(X)=0,5+DIMSUBSIZE*X,LEFT$,	!Used to clear flags
%2202%	DVARLBFLG(X)=0,5+DIMSUBSIZE*X,34,1$,	!Flag: lower bound a  variable
%2202%	DVARUBFLG(X)=0,5+DIMSUBSIZE*X,33,1$,	! upper bound a variable
%2202%	DVARFACTFLG(X)=0,5+DIMSUBSIZE*X,35,1$,	! factor a variable
%2202%	DFACTOR(X)=0,5+DIMSUBSIZE*X,RIGHT$;	!Factor  that  subscript
						! for this dimension  is
						! multiplied  by.   This
						! is a ptr to a constant
						! table     entry     if
						! preceeding  dimensions
						! were constant,  a  ptr
						! to  a   symbol   table
						! entry  for  a  var  in
						! which   the   val   is
						! stored if variable.

	! The subscript entry for a given dimension

STRUCTURE DIMSUBENTRY[WD,POS,SIZE]=
	(@.DIMSUBENTRY+.WD)<.POS,.SIZE>;

	! *** Note that THIS INFORMATION IS DUPLICATED DIRECTLY ABOVE in
	! *** the DIMENTRY  structure  references!!!!   Any  changes  in
	! *** these macro's MUST be made  to the other dimension  macros
	! *** too!!!!
MACRO
	DIMLB=0,LEFT$,		!Ptr to lower bound
	DIMUB=0,RIGHT$,		!Ptr to upper bound
	VARFACTFLG=1,35,1$,	!Factor for this dimension a variable
	VARLBFLG=1,34,1$,	!Flag for "lower bound on this dimension
				! is a variable.
	VARUBFLG=1,33,1$,	!Upper bound a variable
	DIMFACTOR=1,RIGHT$;	!Factor to multiply ss of this dimension
!***********************************************************************
![1214], Add structure for DO/IF stack
!***********************************************************************

STRUCTURE DINODE [OFFS, P, S] =	[1] (@.DINODE+.OFFS)<.P,.S>;

! FIELDS IN ALL NODES

MACRO DILINK = 0,RIGHT$,		! LINK TO ENCLOSING DINODE
      DIBLINK = 0,LEFT$,		! BACK LINK (TO NEXT INNER DINODE)
      DISTMT = 1,LEFT$,                 ! POINTER BACK TO STMT NODE OF DO OR IF
      DITYPE = 1,RIGHT$;		! DO OR IF OR WHILE

BIND DISIZE = 4;                        ! NODE SIZE, WORDS

! DITYPE VALUES

BIND DIIFTYPE = 0,                      ! BLOCK IF
     DIDOTYPE = 1,                      ! DO
     DIWHILETYPE = 2;                   ! DO WHILE

! IF NODE

MACRO THENLBL = 2,LEFT$,	! LABEL IN THE GOTO GENERATED BY THE
				! MOST RECENT THEN		
      ENDLBL = 2,RIGHT$;	! LABEL TO BE ATTACHED TO THE CONTINUE
				! GENERATED BY THE ENDIF

! DO NODE

MACRO LASTDOLBL = 2,RIGHT$,	! LASDOLABEL
      CURDONDX = 3,FULL$;	! CURDOINDEX


! WHILE NODE

MACRO TOPLBL = 2,LEFT$,		! nM label on IF stmt at top of loop
      BOTLBL = 2,RIGHT$,	! nM label on CONTINUE after bottom of loop
      BOTSTMT = 3,LEFT$;	! label of terminal statement (DO 10 WHILE)


%(*********
	DEFINE VALUES OF LABEL TABLE FIELDS USED FOR PEEPHOLING
**********)%

	%(***VALUES FOR SNSTATUS FIELD***)%
BIND	OUTPBUFF=2,			!LABEL IS OUT OF THE PEEPHOLE BUFFER
	INPBUFF=1,			!LABEL IS STILL IN THE PEEPHOLE BUFFER
	UNRESOLVED=0;			!LABEL IS UNRESOLVED
BIND	LBTBENDMK=0;				!VALUE OF NXTLAB FIELD
						! FOR LAST LINK




%(**************
	DEFINE STRUCTURE FOR PEEPHOLE BUFFER
****************)%

	%(***SIZE OF PEEPHOLE BUFFER ENTRIES****)%
BIND PBFENTSIZE=3;			!NUMBER OF WORDS IN EACH PEEPHOLE BUFFER ENTRY
BIND PBFENTCT=50;			!NUMBER OF ENTRIES IN THE PEEPHOLE BUFFER
BIND PBFOUTCT=25;	!NUMBER OF ENTRIES FROM THE BUFFER THAT WE OUTPUT
			! AT A TIME. WHEN THE 50 ENTRIES ARE FULL, WE OUTPUT
			! THE 1ST 25 INSTRS, AND LEAVE THE REMAINING 25
			! TO BE PEEPHOLED WITH ANY FURTHER INSTRS THAT WIL
			! BE ENTERED
BIND PBFOUTSIZ=PBFOUTCT*PBFENTSIZE;	!SIZE OF THE BLOCK OF ENTRIES
			! AT THE TOP OF THE BUFFER THAT WE
			! OUTPUT AT A ONE TIME
BIND PBFSIZE=PBFENTCT*PBFENTSIZE + 2;		!NUMBER OF WORDS IN THE PEEPHOLE BUFFER
					! (KEEP 1 WD AFTER THE LAST ENTRY TO HOLD
					! A POSSIBLE LABEL AND A POSSIBLE ISN)


	%(****STRUCTURE FOR LOOKING AT A PEEPHOLE*******)%
	%(*******THE ARG INST INDICATES WHICH INSTRUCTION OF THE PEEPHOLE***)%
STRUCTURE	PEEPHOLE[INST,WD,POS,SIZE]=
	(@.PEEPHOLE + PBFENTSIZE*.INST +.WD)<.POS,.SIZE>;


	%(****STRUCTURE FOR A PEEPHOLE BUFFER ENTRY***)%
STRUCTURE PEEPFRAME[WD,POS,SIZE]=
	(.PEEPFRAME+.WD)<.POS,.SIZE>;

	%(***STRUCTURE FOR A PTR TO  A PEEPHOLE BUFFER ENTRY*****)%
STRUCTURE PPEEPFRAME[WD,POS,SIZE]=
	(@.PPEEPFRAME+.WD)<.POS,.SIZE>;


%(*****DEFINE FIELDS FOR PEEPHOLE BUFFER FRAME*****)%
MACRO	PBFISN=0,WHOLE$,		!ISN FOR STMNT BEGUN BY THIS INSTR
					! -1 FOR INSTRS THAT DO NOT START STMNTS
	 PBFLABEL=1,LEFT$,			!PTR TO LABEL TABLE ENTRY FOR THE 1ST
						!  LABEL ASSOCIATED WITH THIS
						! LOC
	PBFSYMPTR=1,RIGHT$,			!0 IF ADDR FIELD IS A LABEL
						!1 IF ADDR FIELD HAS NO SYMBOLIC REPR
						!2 IF ADDR FIED IS A PTR TO THE SIXBIT
						! FOR AN IMPLICITLY CALLED FUNCTION
						!3 IF ADDR IS A PTR TO A SYMBOL TABLE ENTRY
						! FOR AN EXPLICITLY CALLED FN
						! OTHERWISE A PTR TO THE SYMBOL TABLE,CONSTANT
						! TABLE OR TEMP TABLE ENTRY FOR THIS ADDR FIELD
	PBFINSTR=2,WHOLE$,
	PBFADDR=2,RIGHT$,		!ADDRESS FIELD OF THE INSTR
	PBFOPCOD=2,27,9$,		! OP-CODE
	PBFOPKEY=2,27,5$,		! LAST 5 BITS OF OPCODE, USED AS
					! KEY IN PEEPHOLE OPTIMIZER
	PBFREG=2,23,4$,			!REG FIELD
	PBFINDEX=2,18,4$,		!INDEX AND INDIRECT FIELDS
	PBFMEMREF=2,0,23$;		!ADDRESS,INDIRECT, AND INDEX FIELDS
BIND	NOLABEL=0;				!FLAG FOR "NO LABEL YET ASSOCIATED
						! WITH THIS LOC"
BIND	NOISN=-1;		!CODE FOR "NO ISN ASSOCIATED WITH THIS INSTR"
				! (IE THE INSTR IS IN THE MIDDLE OF A STMNT)

%(*******SPECIAL VALS FOR PBFSYMPTR FIELD*******)%
BIND
	PBFLABREF=0,			!ADDRESS FIELD IS A LABEL, RH IS AN INSTRUCTION
	PBFNOSYM=1,			!ADDRESS FIELD IS AN OCTAL CONSTANT, RH IS AN INSTR
	PBFIMFN=2,			!ADDR FIELD IS A PTR TO AN IMPLICITLY CALLED FN
	PBFEXFN=3,			!ADDR FIELD IS A PTR TO AN EXPLICITLY CALLED FN
	PBF2LABREF=4,			!BOTH HALVES OF WD ARE PTRS TO LABEL TABLE
					! ENTRIES
	PBF2NOSYM=5,			!BOTH HALVES OF WD ARE OCTAL CONSTANTS WITH
					! NO SYMBOLIC REPRESENTATION
	PBFFORMAT=6,			!RIGHT HALF WORD IS FORMAT ADDRESS
	PBFLLABREF=7,			!LEFT HALF IS A LABEL REFERENCE
					!USED PRIMARILY FOR ARGUMENT BLOCKS TO
					!FOROTS FOR THE END=,ERR= WORD
	PBFENTRY=8;			!FOR A GLOBAL ENTRY (AS SUBROUTINE
					!OR ENTRY NAME).


BIND	PBFCODMAX=16;		!CAN NEVER USE ANY NUMBER GTR THAN 16 AS A SPECIAL
				! CODE VALUE FOR PSYMPTR, BECAUSE ANY NUMBER GTR
				! THAN 16 MIGHT BE THE ADDRESS OF A NODE


%(***************************************************************************
	TO GENERATE A JRST INSTRUCTION
***************************************************************************)%
MACRO JRSTGEN(ADDR)=
BEGIN
	PBOPWD_JRSTOC OR ADDR;
	PSYMPTR_PBFLABREF;			!FLAG FOR "ADDRESS FIELD OF THIS INSTR IS
						! A LABEL"
	OBUFF();
END$;


	%(***TO GENERATE JRST INDIRECT***)%
MACRO JRSTIGEN(ADDR)=
BEGIN
	PBOPWD_JRSTOC OR INDBIT OR ADDR;
	PSYMPTR_PBFLABREF;
	OBUFF();
END$;
%(***************************************************************************
	DEFINE THE VARIOUS WAYS OF BUILDING INDICES INTO THE OPGENDISPATCH TABLE.
	EACH KIND OF INDEX IS COMPOSED OF SOME COMBINATION OF THE FLAG AND OPERATOR
	FIELDS OF THE NODES FOR WHICH CODE IS TO BE GENERATED.
***************************************************************************)%


	%(****TO GET THE VAL OF AN ARGNODE INTO THE REG FOR COMPUTATION OF THE PARENT (WHEN
		THE VAL OF THE SON IS WITHIN REACH OF 1 INSTR.
		DEPENDS ON THE VALS OF NEGFLG,NOTFLG,SAMEFLG,IMMEDFLG
		FOR THE ARG INVOLVED, ALSO ON THE VALUE-TYPE OF THE ARG.
	*******)%
MACRO	GETA1OPIX(PNODE,ANODE)=
	BEGIN
		(.PNODE[A1FLG1]^2 + .ANODE[VALTP1] + OPGETI)
	END$;

MACRO	GETA2OPIX(PNODE,ANODE)=
	BEGIN
		(.PNODE[A2FLG1]^2 + .ANODE[VALTP1] + OPGETI)
	END$;

	%(***FOR DO-LOOPS - DONT ACTUALLY HAVE AN EXPRESSION NODE BUT WANT TO GET VAL
		HOW TO DO SO DEPENDS ON VAL OF IMMEDFLG, VALTYPE AND NEGATE FLAG***)%
MACRO	DOGETAOPIX(IMFLG,VLTP,NEGFLAG)=
	(NEGFLAG^4+IMFLG^2 + VLTP + OPGETI)$;





	%(****TO COMPUTE THE VALUE OF A NON-CONTROL BOOLEAN NODE. CODE TO BE GENERATED
		DEPENDS ON A2NOTFLG, A2IMMEDFLG, AND MEMCMPFLG AND THE OPERSP***)%
MACRO	BOOLOPIX(PNODE)=
	(.PNODE[A2NOTFLG]^4 + .PNODE[A2IMMEMCMPFLGS]^2 + .PNODE[OPERSP] + OPGBOO)$;


	%(******TO SKIP THE NEXT INSTRUCTION WHEN A RELATIONAL HAS THE VAL INDICATED
		BY 'SKPCND'. CODE TO BE GENERATED DEPENDS ON WHETHER THE ARGS
		OF THE RELATIONAL ARE SINGLE OR DOUBLE WD AND WHETHER
		THE 2ND ARG IS IMMED*******)%
	%(*****(NOTE THAT IF THIS IS EVER CHANGED, THEN DPIMMRELOPIX DEFINED
		BELOW SHOULD ALSO BE CHANGED)***)%
	MACRO RELOPIX(PNODE,ANODE,SKPCND)=
	BEGIN
		REGISTER MODE;			!MODE ON WHICH TO SKIP
		MODE_.PNODE[OPERSP];		!MODE SPECIFIED IN RELATIONAL
		IF FALSITY(SKPCND)
		THEN MODE_CMREL(.MODE);		!IF WANT TO SKIP ON REL FALSE

		.ANODE[DBLFLG]^4 + .PNODE[A2IMMEDFLG]^3 + .MODE + OPGREL
	END$;


	%(****FOR A RELATIONAL BETWEEN A DOUBLE-PREC AND ZERO. CAN USE SAME
		CODE AS USE TO COMPARE A REAL TO ZERO (SEE RELOPIX ABOVE)***)%
	MACRO	DPIMMRELOPIX(PNODE,SKPCND)=
	BEGIN
		REGISTER MODE;	!MODE ON WHICH TO SKIP
		MODE_.PNODE[OPERSP];
		IF FALSITY(SKPCND)
		THEN MODE_CMREL(.MODE);	!IF WANT TO SKIP ON RELATIONAL FALSE

		1^3 + .MODE + OPGREL	!HAVE A2IMMEDFLG (SINCE COMPARE TO 0)
					! AND DO NOT HAVE DOUBLE-WD COMPARE)
	END$;



	%(*****TO COMPUTE THE VAL OF AN ARITHMETIC NODE.
		DEPENDS ON THE VALS A2IMMEDFLG,MEMCMPFLG,VALTYPE, AND OPERSP OF THE PARENT
		NOTE THAT EXPONENTIATION NODES WERE CONVERTED TO FUNCTION-CALLS DURING
		THE COMPLEXITY WALK. HENCE NEVER HAVE TO GET OPGNTA INDEX FOR EXPONEN
	********)%
MACRO	ARITHOPIX(PNODE)=
	BEGIN
		(.PNODE[A2IMMEMCMPFLGS]^4+.PNODE[OPRSP2]^2+.PNODE[VALTP1]+
![761] Choose index based on /GFLOATING
%[761]%			(IF .GFLOAT THEN OPGARG ELSE OPGARI))
	END$;


	%(*********FOR THE ADD TO THE INDEX FOR A DO-LOOP********)%
MACRO	DOARITHOPIX(VLTP,MCPFLG,IMFLG,NEGFLAG)=
		%(***HAVE A2IMMEDFLG=IMFLG,  MEMCMPFLG=MCPFLG,
			OPERATOR IS ADD IF NEGFLAG IS 0, SUB IF NEGFLAG IS 1***)%
	(IMFLG^5 + MCPFLG^4 + (ADDOP+NEGFLAG)^2 + VLTP +
![761] Choose index based on /GFLOATING
%[761]%	 (IF .GFLOAT THEN OPGARG ELSE OPGARI))$;

	%(***FOR THE ADD TO BOTH AT THE END OF A MATERIALIZED DO LOOP
		WHEN THE INDEX IS REAL OR INTEGER***)%
MACRO	DOARBOTHOPIX(VLTP)=
	(3^4		!SET BITS FOR MEMCMPFLG AND OPTOBOTHFLG
	  +ADDOP^2	! ADD
	  +VLTP		! INTEGER OR REAL
	   +OPGARI	! BASE OF TABLE FOR CODE FOR KI10 (SINCE NO DP,
			! CAN ALWAYS USE KI10 CODE)
	)$;


%1431%	%(***FOR THE SUBTRACT IN SUBSTRING CALCULATION***)%

MACRO
	SSSUBOPIX(CNODE)=  (.CNODE[A2IMMEDFLG]^5 + (1-.CNODE[A2NEGFLG])^2
			   	+ VTP1(INTEGER) + OPGARI)$,

	SSADDOPIX(CNODE)=  (.CNODE[A2IMMEDFLG]^5 + .CNODE[A2NEGFLG]^2
				+ VTP1(INTEGER) + OPGARI)$;


	%(*****TO COMPUTE THE VAL OF A TYPE CONVERSION NODE.
		WILL BE GENERATING CODE ONLY WHEN  DESTIN  TYPE
		IS REAL,INTEGER,DOUBLEPREC,OR COMPLEX (IE NEVER HAVE
		TO DEAL WITH OCTAL,DOUBLE-OCTAL,LOGICAL,LITERAL,OR CONTROL)
		THUS ONLY NEED TO DIFFERENTIATE BETWEEN THESE 4 TYPES
		THE TYPE TO BE CONVERTED TO (SPECIFIED BY THE VALTYPE FIELD OF THE
		TYPE-CONVERION NODE).
		THE OPERSP FIELD OF THE TYPE CONVERSION NODE, INDICATES
		THE ORIGINAL TYPE BEING CONVERTED.
	*******)%
	MACRO	TPCNVIX(PNODE)= (.PNODE[OPERSP]^2 +
	!WHEN CONVERTING TO OCTAL/LOGICAL, MUST BE MORE CAREFUL
			(IF .PNODE[OPERSP] GTR 4 !COMING FROM REAL, DP, COMPLEX
			AND .PNODE[VALTP2] EQL 0 !GOING TO OCTAL, LOGICAL
			THEN .PNODE[OPRSP2]      !MATCH TYPES TO GET NO CONVERSION
			ELSE .PNODE[VALTP1])+    !ELSE DISPATCH NORMALLY
![761] Choose index based on /GFLOATING
%[761]%			(IF .GFLOAT THEN OPGTCG ELSE OPGTCI))$;




	%(****TO COMPUTE THE VALUE OF A NEGNOT NODE.  WHEN PHASE 2 SKELETON IS PRESENT,
		THERE WILL BE FEW OF THESE. (EG FOR F(-X), NOT(-X))*********)%

	%(***WHEN A2NEG,A2NOT, OR A2SAMEFLG IS SET, WILL USE GETA2OPIX TO GET THE ARG
		INTO A REG, AND THEN USE THE FOLLOWING INDEX*****)%
MACRO	NEGNOT1IX(PNODE)=
	(.PNODE[MEMCMPFLG]^3 + .PNODE[OPERSP]^2 + .PNODE[VALTP1] + OPGN1I)$;

	%(***OTHERWISE, USE AN INDEX BASED ON A2IMMED, MEMCMP, OPERSP, VALTP1****)%
MACRO	NEGNOT2IX(PNODE)=
	(.PNODE[A2IMMEMCMPFLGS]^3 + .PNODE[OPERSP]^2 + .PNODE[VALTP1] + OPGN2I)$;

	%(***TO COMPUTE THE VALUE OF A P2MUL OR P2PL1MUL  -
		CODE TO BE GENERATED DEPENDS ON VALTYPE OF THE NODE AND
		ON WHICH OP IS TO BE PERFORMED****)%
MACRO	SPECOPIX(PNODE)=
	BEGIN
		%(***IF ARG IS IMMEDIATE AND OPERATION IS P2PLUS1-MULTIPLY , HAVE A
			SPECIAL CASE***)%
		IF .PNODE[A1IMMEDFLG]
		THEN
		BEGIN
			IF .PNODE[OPERSP] EQL P2PL1OP
			THEN (.PNODE[A1NEGFLG]^2 + .PNODE[VALTP1] + OPP21I)
			ELSE
			(.PNODE[OPERSP]^3 + .PNODE[A1NEGFLG]^2 +.PNODE[VALTP1]
![761] Choose index based on /GFLOATING
%[761]%				+(IF .GFLOAT THEN OPGSPG ELSE OPGSPI))
		END
		ELSE
		(.PNODE[OPERSP]^3 + .PNODE[A1NEGFLG]^2 +.PNODE[VALTP1]
			+(IF .PNODE[MEMCMPFLG] THEN OPGSPM		!FOR OPS DONE TO MEMORY DONT CARE
									! WHETHER ARE KA OR KI
![761] Choose index based on /GFLOATING
%[761]%				ELSE IF .GFLOAT THEN OPGSPG ELSE OPGSPI))
	END$;



	%(***TO GENERATE CODE FOR AN IN-LINE FUNCTION WHEN ARG1 FOR THAT FN IS ALREADY IN REGFORC**)%
MACRO	ILFIX(PNODE)=
	BEGIN
		IF .PNODE[A2IMMEDFLG]
		THEN
		.PNODE[OPERSP] + OPGILI
		ELSE
		IF .PNODE[OPERATOR] EQL DABSFNOP
		 THEN OPGDBF ELSE .PNODE[OPERSP]+OPGILF
	END$;

	%(***TO GENERATE CODE FOR AN IN-LINE FN WHEN ARG IS NOT IN REGFORCOMP (USED FOR
		ABS,IABS (NOT IN RELEASE 1), AND SIGN ***)%
MACRO	ILF1IX(PNODE)=
	IF .PNODE[OPERATOR] EQL DABSFNOP
	 THEN OPGDB1 ELSE .PNODE[OPERSP]+OPGIL1$;


	%(*****TO PERFORM THE ACTION SPECIFIED FOR A "STORECLS" NODE (WHICH IS USED
		WHEN EITHER A PTR TO AN ARRAY ENTRY OR THE CONTENTS OF THAT
		ENTRY MUST BE STORED IN A TEMPORARY************)%
MACRO	STCLSOPIX(PNODE)=
	(IF .PNODE[DBLFLG] AND (.PNODE[OPERSP] EQL STARVAL)	!FOR STORING A DOUBL-WD VAL
	THEN (.PNODE[A2SAMEFLG] + OPGSTD)
	ELSE (.PNODE[OPERSP]^1 + .PNODE[A2SAMEFLG] + OPGSTC))$;


	%(*****TO STORE A VALUE THAT HAS BEEN COMPUTED****)%
MACRO	STOROPIX(PNODE)=
	BEGIN
		.PNODE[DBLFLG] + OPGSTI
	END$;

	%(******TO STORE THE VALUE OF THE RHS OF AN ASSIGNMENT STMNT
		INTO THE LHS. CODE TO BE GENERATED DEPENDS ON WHETHER THE VAL MUST
		BE NEGATED OR COMPLEMENTED, AND ON THE VALTYPE*****)%
	MACRO ASNOPIX(PNODE,LHSNODE)=
	BEGIN
		%(***IF THIS STATEMENT HAS A2IMMEDFLG AND A2SAMEFLG BOTH SET, IT
			MUST BE THAT THE RHS IS A REGCONTENTS NODE FROM WHICH WE
			ONLY WANT TO USE THE RIGHT HALF (BECAUSE IT IS AN AOBJN WD).***)%
		IF .PNODE[A2IMMEDFLG] AND .PNODE[A2SAMEFLG]
		THEN
		OPGASR

		ELSE
		.PNODE[A1NGNTFLGS]^2 + .LHSNODE[VALTP1] + OPGASI
	END$;


	%(****TO GENERATE CODE FOR AN ARITHMETIC-IF STATEMENT**********)%

MACRO
	AIFIX(STMNODE,CNEXPR)=
		(.STMNODE[AIFFLGS]^1 +
			.STMNODE[A1SAMEFLG]
			+ OPGAIF)$;

	%(***TO INIT A LOGICAL VALUE TO TRUE OR FALSE (-1 OR 0). CODE
		TO BE GENERATED DEPENDS ON WHETHER VAL IS TO BE LEFT IN A REG AND
		ON THE VAL TO BE STORED
		NOTE THAT "LOGVAL" IS EXPECTED TO BE 777777777777 FOR "TRUE"
	*****)%
MACRO	SETLOGIX(PNODE,LOGVAL)=
	((LOGVAL AND #2) + .PNODE[INREGFLG] + OPGSET)$;


	%(*****TO TRANSFER CONTROL WHEN ARG1 UNDER PNODE HAS THE SPECIFIED VAL TRUE OR FALSE.
		JMPCND WIL BE 777777777777 WHEN TRANSFER ON "TRUE" IS DESIRED, 0
		FOR TRANSFER ON FALSE.
	********)%
MACRO TSTARGTRIX(PNODE,JMPCND)=
	((JMPCND AND #2) + .PNODE[A1SAMEFLG] + OPGVTS)$;	!IF PNODE A1SAMEFLG IS SET
						! THEN THE ARG IS IN A REG

	%(*****TO TRANSFER CONTROL WHEN A SPECIFIED VAR HAS THE SPECIFIED VAL TRUE OR FALSE.
		CODE TO BE GENERATED DEPENDS ON WHICH CONDITION TRANSFER IS DESIRED
		AND ON WHETHER THE VAL IS IN A REG
		NOTE THAT "JMPCND" IS EXPECTED TO BE 777777777777 FOR "TRUE"
****)%
MACRO	CNDVTRIX(NODE,JMPCND)=
	BEGIN
		IF .NODE[OPRCLS] EQL DATAOPR
		THEN
		((JMPCND AND #2) + OPGVTS)
		ELSE
		((JMPCND AND #2) + .NODE[INREGFLG] + OPGVTS)
	END$;


	%(*******TO TRANSFER TO ONE LABEL IF A SPECIFIED VALUE IS TRUE
		AND TO ANOTHER IF THE VAL IS FALSE.
		CODE TO BE GENERATED DEPENDS ON WHETHER THE VAL TO BE GENERATED
		IS IN A REG.
	********)%
MACRO	ALTTRIX(NODE)=
	BEGIN
		IF .NODE[OPRCLS] EQL DATAOPR
		THEN
		OPGALT
		ELSE
		(.NODE[INREGFLG] + OPGALT)
	END$;



%(**************************************************
	DEFINE STRUCTURE FOR OPGENTABLE ENTRY - 
	FOR A GIVEN TYPE OF NODE, WILL HAVE A SERIES OF SUCH ENTRIES, ONE
	FOR EACH INSTRUCTION TO BE GENERATED
******************************************************)%


STRUCTURE OPGENTRY[WD,POS,SIZE]=
	(@.OPGENTRY+.WD)<.POS,.SIZE>;

%(**************FIELDS FOR AN OPGENTRY***********)%
MACRO
	REGSPEC=0,LEFT$,			!SPECIFIES WHERE TO GET
						! REG TO BE USED
	MEMSPEC=0,RIGHT$,			!SPECIFIES WHERE TO GET
						! MEMREF TO BE USED
	PATTERN=1,WHOLE$;		!PATTERN WORD FOR INSTR TO
						! BE GENERATED

%(*********DEFINE VALUES FOR REGSPEC AND MEMSPEC FIELDS*********)%
BIND
	FRPTN=0,		!REG OR MEMREF FIELD USED AS IS IN WD 1 OF OPGENTABLE ENTRY
	FRRFC=1,		!REG FIELD IN THE GLOBAL "REGFORCOMP" SHOULD BE
				! ADDED IN TO THE REG FIELD IN WD 1
				! (OR THE REG SPECIFIED BY "REGFORCOMP" 
				! SHOULD BE USED AS THE MEMREF FIELD
	IMFN=2,			!USE THE IMPLICIT FN NAME PTED TO BY TREEPTR
	WD1IMF=3,		!USE THE IMPLICIT-FN NAME POINTED TO BY THE RH OF THE PATTERN WD
	RGIMFN=4,		!USE THE IMPLICIT-FN NAME POINTED TO BY THE RH OF
				! THE PATTERN WD INDEXED BY THE "REGFORCOMP"
	A1CNST=5,		!ARG1 IS IMMED CNST
	A2CNST=6,		!ARG2 IS IMMED CNST
	A1CNNG=7,		!USE NEG OF THE IMMED CNST ARG1
	A2CNNG=10,		!USE NEG OF THE IMMED CNST ARG2
	PTRA2=#11,		!USE THE ARG2PTR FIELD IN THE PARENT
	NGPTR2=#12,		!USE THE NEG OF THE ARG2PTR FIELD OF THE PARENT
	P2PTR2=#13,		!USE 2**(VAL OF ARG2PTR) MINUS 1
				! (THIS IS USED FOR P2DIV)
	A1LAB=#14,		!USE THE LABEL INDICATED BY A1LABEL
	A2LAB=#15,		!USE THE LABEL INDICATED BY A2LABEL
	A3LAB=#16,		!USE THE LABEL INDICATED BY A3LABEL
	FROMC1H=#17,		!USE THE CONTENTS OF THE GLOBAL C1H,
				! THERE IS NO SYMBOL ASSOCIATED WITH THIS ADDR FIELD
	PARTMP=#20,		!USE THE TMP POINTED TO BY THE ADDR PART
				! OF THE TARGET WD OF THE PARENT NODE (IE THE NODE
				! POINTED TO BY TREEPTR); IGNORE THE INDIRECT BIT
				! OF THE TARGET WD
	FROMA1=#21,		!TARGET FIELD OF ARG1 IS MEMREF FIELD
	FROMA2=#22,		!TARGET FIELD OF ARG2
	FROMPAR=#23;		!TARGET FIELD OF PARENT (IE NODE PTED TO BY TREEPTR)




%(***********************************************************************
	TO GET REG OR MEMREF OR OPERATOR FIELD FROM EITHER A TARGET WD IN AN EXPRESSION
	NODE OR A PATTERN WORD IN AN OPGENTABLE ENTRY
*****************************************************************)%

MACRO
	OPFLD(WORD) = WORD AND #777^27$,
	REGFLD(WORD) = WORD AND #17^23$,

	MEMFLD(WORD) = WORD AND #37777777$;


	%(****DEFINES SPECIFIC REGS USED FOR COMPILED CODE*****)%
BIND RETREG=0;			!REG IN WHICH THE VAL OF A FN IS RETURNED
BIND STKREG=17;		!STACK REG FOR FNS/SUBRS
BIND ARGREG=16;			!CONTAINS PTR TO ARGLIST FOR FNS/SUBRS





%(*********MACROS USED FOR REGISTER ALLOCATION***********************)%



%(*****TO DETERMINE WHETHER A NODE IS EVALUATED BY MEANS OF A CALL TO A LIBRARY FN,
	(IF SO THEN IF THE 2ND ARG IS A CONSTANT WILL HAVE TO ALLOCATE CORE FOR IT)***)%
MACRO USEFNCALL(PNODE)=
BEGIN
	%(***COMPLEX MUL AND DIV ARE EVALUATED BY LIBRARY FNS**)%
	.PNODE[OPERATOR] EQL OPERC(COMPLEX,ARITHMETIC,MULOP) OR.PNODE[OPERATOR] EQL OPERC(COMPLEX,ARITHMETIC,DIVOP)
	OR
	%(****EXPONENTIATION IS PERFORMED BY LIBRARY FNS***)%
	(.PNODE[OPR1] EQL EXPONOPF)
END$;

%(****TO DETERMINE WHETHER THE REGISTER AFTER THE REGISTER RG IS
	FREE. BITS 0-15 OF 'BSYRS' REPRESENT REGISTERS  0-15.
	THE BIT FOR A REGISTER IS SET IFF THAT REG IS FREE*******)%
MACRO NXREGFREE(BSYRS,RG)=BITSET(BSYRS,RG+1)$;


%(****TO TEST WHETHER AN OPERATION 'CLOBBERS' THE REGISTER FOLLOWING THE ONE IN
	WHICH IS IS PERFORMED.
	THIS TEST DOES NOT INCLUDE DOUBLE-PREC (OR COMPLEX) OPERATIONS,
	WHICH THE REGISTER ALLOCATOR HANDLES BY SIMPLY NEVER 
	ASSIGNING ODD REGISTERS WHEN IN "DOUBLE-WD MODE"
********)%
MACRO CLBNXREG(NODE)=
	(CLOBBNX(.NODE))$;	!(THIS TEST GOT SO COMPILICATED WE MADE IT A ROUTINE)

%(******MACROS FOR GOING BETWEEN "DOUBLE-WD MODE" REGISTER ALLOCATION AND
	"SINGLE-WD MODE" REGISTER ALLOCATION.
	FOR DOUBLE-WORD OPERATIONS, NEVER ASSIGN ODD REGISTERS TO
	ANY COMPUTATIONS.
	THE "SET OF BUSY REGS" MAY NEED TO HAVE THESE TRANSFORMATIONS PERFORMED ON IT
		1. ACROSS A TYPE CONVERSION NODE (WHEN CONVERTING BETWEEN DOUBLE-WD
			AND SINGLE-WD VALUES
		2. ACROSS A RELATIONAL NODE THAT COMPARES DOUBLE-WD VALUES (BUT
			HAS A SINGLE-WD RESULT)
		3. ACROSS AN ARRAY-REF NODE FOR A DOUBLE-PREC ARRAY (THE ADDRESS ARITHMETIC 
			IS SINGLE-WD)
		4. ACROSS A BOOLEAN  WHOSE ARGS ARE DOUBLE-WD (RESULT IS ALWAYS SINGLE-WD
*************)%

	%(******WHEN GOING DOWN FROM SINGLE-WD CALCULATIONS TO DOUBLE-WD CALCULATIONS
		THE SET OF REGISTERS THAT CANNOT BE ASSIGNED MUST
		NOW INCLUDE
			1. ANY REGISTER THAT PRECEEDS A REGISTER HOLDING A VAL TO
				BE PRESERVED (SINCE A DOUBLE-WD COMPUTATION
				ON THE PRECEEDING REG CLOBBERS THE FOLLOWING ONE)
			2. ANY ODD REGISTER.
	***********)%

	MACRO DPBSYREGS(SPBSYRS)=
		((SPBSYRS AND SPBSYRS^1) AND #525252525252)$;



	%(*********WHEN GOING DOWN FROM DOUBLE-WD CALCULATION TO SINGLE-WD
		CALCULATIONS.
		THE SET OF REGISTERS AVAILABLE ONCE AGAIN CAN INCLUDE
		THEN ODD REGISTERS EXCEPT FOR THOSE REGISTERS CONTAINING THE RIGHT-HALF
		OF A DOUBLE-WD RESULT WHICH WAS BEING SAVED.
	************)%
	MACRO SPBSYREGS(DPBSYRS)=
		((DPBSYRS OR #252525252525) AND ((DPBSYRS OR #252525252525)^(-1) OR #400000000000))$;


	%(***TO ADD THE FN RETURN REGISTER TO THE SET OF REGS AVAILABLE***)%
	MACRO ADDRETREG(BSYR)=(BSYR OR  #600000000000)$;	!SET BITS FOR REGS 0 AND 1

	%(***TO REMOVE THE FN RETURN REG FROM THE SET OF REGS AVAILABLE**)%
	MACRO REMRETREG(BSYR)=(BSYR AND #177777777777)$;	!CLEAR BITS FOR REGS 0 AND 1

%(***TO TEST WHETHER A POSITIVE INTEGER IS A POWER OF 2***)%
MACRO POWOF2(NUM)=((NUM AND -NUM) EQL NUM)$;






%(****TO SWAP HALVES OF A WORD IN MEMORY****)%
MACHOP MOVSS=#207;
MACHOP MOVE=#200;


%(*****TO SWAP THE 2 ARGS UNDER AN EXPRESSION NODE**************)%
MACRO
	SWAPARGS(NODE)=
	BEGIN
		REGISTER T1;
		MOVE(T1,NODE);
		MOVSS(0,ARGWDOFFSET,T1);
		SWAPFLGS(NODE);
	END$;




%(****TO PERFORM A BLOCK TRANSFER *******)%
MACHOP BLT=#251;

MACRO BLOCKTR(SRCLOC,DESTIN,BLLNTH)=
BEGIN
	REGISTER T1;
	T1<LEFT>_SRCLOC;
	T1<RIGHT>_DESTIN;
	BLT(T1,(DESTIN)<0,0>+BLLNTH-1);
END$;


%(****TO PICK UP A HALF-WD VAL WITH SIGN EXTENDED****)%
MACHOP HRREI=#571;

MACRO	EXTSIGN(VAL)=
BEGIN
	REGISTER AA1;
	AA1_VAL;
	HRREI(AA1,0,AA1)
END$;


%(***TO DO AN ARITHMETIC SHIFT BY A COMPILE TIME CONSTANT***)%
MACHOP ASH=#240;

MACRO ARITHSHIFT(VAL,BITCT)=
BEGIN
	REGISTER T1;
	T1_VAL;
	ASH(T1,(BITCT AND #777777))
END$;


%[1240] (***TO INCREMENT A BYTE POINTER N TIMES BY DOING AN ADJBP***)%

%2216%	! BPADD MACRO moved to OUTMOD.BLI

%1406%	! To generate a byte pointer that is output to the .REL file

MACRO BPGEN(ADDR)=

%1406%	! Written by TFV on 27-Oct-81

	!Examples:	SYMPTR[IDCHBP] = BPGEN(.SYMPTR[IDADDR]);
	!		SYMPTR[IDCHBP] = BPGEN(.LOWLOC);

(
%2330%	(IF EXTENDED		! Compiling /EXTEND?
%2330%	THEN	#61^30		! Yes, make one word globals
	ELSE	#4407^24	! Local byte pointer
	) OR (ADDR)		! Address
)$;

%1406%	! To compute the number of words needed for a character variable
%1406%	! or constant of  length  CHARS.  Also define the number of bits
%1406%	! per character and the number of characters per word.

%1406%	! Written by TFV on 27-Oct-81
%2423%	! Parens added around macro formal by AHM on 19-Jul-84

BIND	CHARSPERWORD = 5,	! Number of characters per word
	BITSPERCHAR  = 7,	! Number of bits per character
%2423%	BITSPERWORD = 36;	! If your computer doesn't have 36 bits,
				! you're not playing with a full DEC

MACRO
%2423%	CHWORDLEN(CHARS)= (((CHARS) + CHARSPERWORD - 1) / CHARSPERWORD)$;


%(****TO COUNT THE NUMBER OF BITS THAT ARE ON IN A GIVEN WORD****)%
MACRO ONESCOUNT(WD)=
BEGIN
	REGISTER COUNT;
	REGISTER T1;
	T1_WD;
	COUNT_0;
	UNTIL .T1 EQL 0
	DO
	BEGIN
		T1_.T1 AND (NOT(-.T1));
		COUNT_.COUNT+1;
	END;
	.COUNT
END$;

%(*******TO CLEAR A GIVEN BIT IN A GIVEN WORD (THE ARG IX INDICATES THE BIT
	TO BE CLEARED, PTN1 IS THE WORD TO CLEAR IT FROM********)%
MACRO
	CLRBIT(PTN1,IX)=BEGIN
				EXTERNAL CLRWDS;
				 PTN1 AND .CLRWDS[IX]
			END $;

%(*******TO SET A GIVEN BIT IN A GIVEN WD*******)%
MACRO
	SETBIT(PTN1,IX) =BEGIN
				EXTERNAL CLRWDS;
				 PTN1 OR NOT(.CLRWDS[IX])
			END $;

%(****TO TEST A GIVEN BIT OF A GIVEN WD***********)%
MACRO
	BITSET(PTN1,IX)=BEGIN
				EXTERNAL CLRWDS;
				 ((IX GEQ 0) AND (PTN1 AND NOT(.CLRWDS[IX])) NEQ 0)
			END$;





%(*****TO MAKE AN ENTRY IN THE CONSTANT TABLE - SET UP GLOBALS FOR
	TBLSEARCH AND CALL IT ****************)%

MACRO MAKECNST(TYPE,CNH,CNL) =
BEGIN
	EXTERNAL TBLSEARCH;
%2336%	EXTERNAL NAME, ENTRY, SYMTYPE;
	NAME_CONTAB;	! Constant table entry
	ENTRY[0]_CNH;	! High order word of constant
	ENTRY[1]_CNL;	! Low order word of constant
	SYMTYPE_TYPE;	! Type of constant
	TBLSEARCH()	! Get a constant
END$;

%(**********TO MAKE A CONSTANT TABLE ENTRY FOR THE NEGATIVE OR THE
		COMPLEMENT("NOT") OF SOME OTHER CONSTANT TABLE ENTRY*****)%

MACRO NEGCNST(CNNODE)=
	BEGIN
		IF .CNNODE[VALTYPE] EQL DOUBLPREC OR .CNNODE[VALTYPE] EQL REAL
%2475%		OR .CNNODE[VALTYPE] EQL DOUBLOCT
		THEN
		%(***FOR DOUBLE-PREC NEG - USE ASSEMBLY LANG ROUTINE**)%
		BEGIN
			EXTERNAL C1H,C1L,C2H,C2L,COPRIX,KDNEGB,CNSTCM;
			C1H_.CNNODE[CONST1];
			C1L_.CNNODE[CONST2];
			COPRIX_KDNEGB;
			CNSTCM();
			MAKECNST(.CNNODE[VALTYPE],.C2H,.C2L)
		END
		ELSE
		 MAKECNST(.CNNODE[VALTYPE], -.CNNODE[CONST1], -.CNNODE[CONST2])
	END$;

%[733]% MACRO NOTCNST(CNNODE)=
%[733]%		IF .CNNODE[VALTYPE] EQL DOUBLPREC OR .CNNODE[VALTYPE] EQL REAL
%2475%		OR .CNNODE[VALTYPE] EQL DOUBLOCT
%[733]%		THEN
%[733]%		%(***FOR DOUBLE-PREC NOT - USE ASSEMBLY LANG ROUTINE**)%
%[733]%		BEGIN
%[733]%			EXTERNAL C1H,C1L,C2H,C2L,COPRIX,KDPRL,KGFRL,CNSTCM;
%[733]%			C1H_.CNNODE[CONST1];
%[733]%			C1L_.CNNODE[CONST2];
![761] Choose index based on /GFLOATING
%[761]%			IF .GFLOAT THEN COPRIX_KGFRL ELSE COPRIX_KDPRL; !ROUND TO SINGLE
%[733]%			CNSTCM();
%[733]%			MAKECNST(LOGICAL,0, NOT .C2H)
%[733]%		END
%[733]%		ELSE MAKECNST(.CNNODE[VALTYPE], NOT .CNNODE[CONST1], NOT .CNNODE[CONST2])$;

%(****TO MAKE CONSTANT TABLE ENTRY FOR NOT(-X) - "NTNGCNST"
	OR -(NOT X) - "NGNTCNST"*********)%
MACRO NTNGCNST(CNNODE)=
	BEGIN
		IF .CNNODE[VALTYPE] EQL DOUBLPREC OR .CNNODE[VALTYPE] EQL REAL
%2475%		OR .CNNODE[VALTYPE] EQL DOUBLOCT
		THEN
		%(***FOR DOUBLE-PREC USE ASSEMBLY LANG ROUTINE TO GET NEG**)%
		BEGIN
			%(***DNEGCNST GETS ITS ARG IN THE GLOBALS C1H,C1L***)%
			C1H_ .CNNODE[CONST1];
			C1L_.CNNODE[CONST2];
			COPRIX_KDNEGB;
			CNSTCM();
			MAKECNST(.CNNODE[VALTYPE],NOT .C2H, NOT .C2L)
		END
		ELSE
		MAKECNST(.CNNODE[VALTYPE], NOT (-.CNNODE[CONST1]), NOT (-.CNNODE[CONST2]))
	END$;

MACRO NGNTCNST(CNNODE)=
	BEGIN
		IF .CNNODE[VALTYPE] EQL DOUBLPREC OR .CNNODE[VALTYPE] EQL REAL
%2475%		OR .CNNODE[VALTYPE] EQL DOUBLOCT
		THEN
		BEGIN
			%(***DNEGCNST GETS ITS ARG IN THE GLOBALS C1H,C1L***)%
			C1H_NOT .CNNODE[CONST1];
			C1L_NOT .CNNODE[CONST2];
			COPRIX_KDNEGB;
			CNSTCM();
			MAKECNST(.CNNODE[VALTYPE],.C1H,.C1L)
		END
		ELSE
		MAKECNST(.CNNODE[VALTYPE],-(NOT .CNNODE[CONST1]), -(NOT .CNNODE[CONST2]))
	END$;



%(******************************
	MACROS TO FORM INDICES  INTO THE TABLE FOR CONSTANT FOLDING
********************************)%

	%(***TO FOLD BOOLEAN OPERATIONS***)%
MACRO	KBOOLOPIX(PNODE)=
	(.PNODE[OPERSP] + KBOOLBASE)$;

	%(***TO FOLD ARITHMETIC OPERATIONS****)%
MACRO	KARITHOPIX(PNODE)=
	(.PNODE[OPRSP2]^2 + .PNODE[VALTP1] + 
![761] Choose index based on /GFLOATING
%[761]%	(IF .GFLOAT THEN KARIGB  ELSE KARIIB) )$;

	%(*******TO FOLD AN ARITH OP, WHEN NO EXPRESSION NODE WAS BUILT (VLTP IS THE VALTP1 FIELD)***)%
MACRO	KKARITHOP(VLTP,OPSP)=
	(
%2322%		EXTERNAL KARIGB, KARIIB;
		OPSP^2 + VLTP + 
			![761] Choose index based on /GFLOATING
%[761]%			(IF .GFLOAT THEN KARIGB ELSE KARIIB)
	)$;


	%(****TO CONVERT A CONSTANT OF ONE VALUE TYPE TO ANOTHER****)%
MACRO KTPCNVIX(TPCNODE)=
	(.TPCNODE[OPERSP]^3 + .TPCNODE[VALTP2] 
![761] Choose index based on /GFLOATING
%[761]%		+ (IF .GFLOAT THEN KTYPCG ELSE KTYPCB))$;


	%(****TO CONVERT A CONSTANT FROM ONE VALTYPE TO ANOTHER WHEN NO EXPRESSION
		NODE WAS BUILT FOR THE TYPE CONVERSION. (VLTP IS THE VALTP2 FIELD)***)%
MACRO	KKTPCNVIX(VLTP,OPSP)=
![761] Choose index based on /GFLOATING
%[761]%	(OPSP^3 + VLTP + (IF .GFLOAT THEN KTYPCG ELSE KTYPCB))$;


	%(***TO FOLD SPECIAL OPERATORS (P2MUL,P2DIV)  - USED ONLY BY PHASE 2***)%
MACRO	KSPECOPIX(PNODE)=
![761] Choose index based on /GFLOATING
%[761]%	(.PNODE[OPERSP]^2 + .PNODE[VALTP1] + (IF .GFLOAT THEN KSPECG ELSE KSPECB))$;

MACRO	KEXPIX(VLTP1)=		!TO FOLD AN INTEGER EXPONENTIATION
![761] Choose index based on /GFLOATING
%[761]%	(EXPCIOP^2 + VLTP1 + (IF .GFLOAT THEN KSPECG ELSE KSPECB))$;	! ("VLTP1" IS THE VALTP1 OF THE BASE)


	%(***TO FOLD IN-LINE FNS********)%
MACRO	KILFOPIX(PNODE)=
	(.PNODE[OPERSP] + (IF .PNODE[VALTP1] EQL INTEG1 THEN KILFBA ELSE 
		(IF .gfloat THEN KILFBG ELSE KILFBR)))$;

	%(*****FOR CNODE ARITHMETIC OR BOOLEAN
		CHECK TO SEE IF A SKEWED TREE IS AN NARYNODE*****)%

	MACRO NARYNODE(CNODE,AR1NODE)=
%[724]%	(.CNODE[OPERATOR] EQL .AR1NODE[OPERATOR]
	AND
	.CNODE[OPR1] LSS DIVOPF
	AND
	NOT .CNODE[A1NEGFLG] AND NOT .CNODE[A1NOTFLG]
	AND
	NOT .AR1NODE[PARENFLG])$;


%(***************************************************************************
	MACROS USED FOR CONSISTENCY CHECKING - FOR DEBUGGING THE COMPILER
***************************************************************************)%


%(***TO CHECK WHETHER ARE WALKING DOWN ONTO A LEGAL NODE***)%
MACRO DEBGNODETST(NODE)=
BEGIN
	EXTERNAL NODERR;
	IF DEBUGFLG			!A COMPILE TIME CONSTANT 
	THEN
	BEGIN
		IF .NODE EQL 0
		THEN NODERR();
	END;
END$;




!***********************************************************************
!MACROS FOR THE FLAGS ASSOCIATED WITH A DO LOOP
!***********************************************************************

	!***************************************************************
	! To  access  right  and  left  halves  of  a  word  through   a
	! CASE,WD,POS,SIZ structure.  used on DOSP and SNDOLNK list.
	!***************************************************************
MACRO
	RIGHTP = 0,0,RIGHT$,
	LEFTP =0,0,LEFT$;

	!***************************************************************
	! Fields in DOWDP used to determine  if it is valid to keep  the
	! DO index variable  in a  register throughout  the loop.   Used
	! during the skeleton optimization.
	!***************************************************************

MACRO
	DOISUBS=0,35,1$,	! Set FALSE if both loop index and count
				! must be  materialized.   Set  TRUE  if
				! index substitutions are performed.
	DONOAOBJN=0,34,1$,	! Flag for  "don't  use AOBJN  for  this
				! loop"  if   val   of  index   is   not
				! materialized.
	DOMTRLZIX=0,33,1$,	! Flag   for   "loop   index   must   be
				! materialized".  This gets set if index
				! is an  arg  to a  fn  or if  loop  has
				! transfers out
	DOINDUC=0,0,18$,	! Induction variable, pointer to  symbol
				! table reference.
	DOREGPTR=0,18,18$;	! Point  to   regcontents  node   to  be
				! substitued.



%(*****DEFINE THE REGISTER TO BE USED FOR THE LOOP INDEX FOR ALL INNER DO
	LOOPS****)%
BIND DOIXREG=2;

%(*****SOME FLAGS TO HELP THE GLOBAL ALLOCATOR. THESE FLAGS ARE IN THE
GLOBREG WORD OF AN ALLOCATED VARIABLE. SEE PH3G FOR DETAILS FOR THE
FLAGS)****%
MACRO
	USED4ASGND=28,1$,	!VARIABLE IS USED BEFORE ASSIGNED IN THIS LOOP
	ASGND4USED=27,1$;	!VARIABLE IS ASSIGNED BEFORE ITS FIRST USE

%(***************************************************************************
	DEFINE THE TABLES USED BY THE BASIC BLOCK REGISTER ALLOCATOR
***************************************************************************)%


%(*****DEFINE THE STRUCTURE OF  THE "REGCANDIDATES" TABLE. THIS TABLE IS USED
	IN THE FIRST PASS OVER A BASIC BLOCK TO KEEP TRACK OF VARIABLES AND CONSTANTS
	WHOSE VALUES ARE LEFT IN REGS BY RGE EVALUATION OF STMNTS IN THE BLOCK
********)%

STRUCTURE RGCTBL[ENTRIX,WD,POS,SIZE]=
	(.RGCTBL + (.ENTRIX-1) + .WD)<.POS,.SIZE>;	!1ST ENTRY HAS IX 1

MACRO
	RGBAK=0,LEFT$,
	RGFOR=0,RIGHT$,
	RGVAR=1,LEFT$,	!PTR TO THE SYMBOL/CONST TABLE ENTRY FOR A VAR/CONST
				! WHOSE VAL IS LEFT IN A REG
	RGINITUSE=1,RIGHT$;	!PTR TO THE EXPRESSION/STMNT WHOSE EVALUATION LEFT THE VAR
				! IN A REG


	%(***DEFINE THE STRUCTURE FOR A POINTER TO A GIVEN ENTRY IN THE REGCANDIDATES TABLE**)%
STRUCTURE RGCTBLENTRY[WD,POS,SIZE]=
	(@.RGCTBLENTRY+.WD)<.POS,.SIZE>;


BIND RGCENTSIZE=1;	!NUMBER OF WDS IN EACH REGCANDIDATES TABLE ENTRY




%(**********DEFINE THE STRUCTURE OF THE "REGSTATE" TABLE. THIS TABLE IS USED
	IN THE 2ND PASS OF TE BASIC BLOCK REG ALLOCATOR TO KEEP TRACK OF THE
	CONTENTS OF EACH REG WHOSE VALUE IS OF FUTURE USE IN THE BASIC BLOCK
*************)%
STRUCTURE RGSTBL[REG,WD,POS,SIZE]=
	(.RGSTBL + 2*.REG + .WD)<.POS,.SIZE>;	!ENTRIES ARE INDEXED FROM 0 (FOR REG 0)

MACRO
	RGVAR1=0,LEFT$,	!PTR TO SYMBOL/CONST TABLE ENTRY FOR THE VAR/CONST
				! WHOSE VAL IS IN THIS REG
	RGVAR2=0,RIGHT$,	!PTR TO A POSSIBLE 2ND SYMBOL/CONST TABLE ENTRY FOR A
				! 2ND VAR WHOSE VAL IS IN THIS REG (EG FOR
				! "A=B" BOTH A AND B ARE IN THE SAME REG)
	RGNXUSE=1,WHOLE$;	!THE BASIC-BLOCK SEQ NUMBER OF THE STMNT WHERE THE
				! CONTENTS OF THE REG WILL NEXT BE USED. -1 IF THERE
				! IS NO FUTURE USE