Google
 

Trailing-Edge - PDP-10 Archives - AP-D480B-SB_1978 - doxpn.bli
There are 12 other files named doxpn.bli in the archive. Click here to see a list.


!THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
!  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.

!COPYRIGHT (C) 1972,1977 BY DIGITAL EQUIPMENT CORPORATION
!AUTHOR: NORMA ABEL/HPW/JNG
MODULE DOXPN(RESERVE(0,1,2,3),SREG=#17,VREG=#15,FREG=#16,DREGS=4,GLOROUTINES)=
BEGIN

GLOBAL BIND DOXPV = 5^31 + 0^18 + 81;	!VERSION DATE: 24-Aug-76


%(
REVISION HISTORY

75	-----	-----	FIX ADJGEN TO CORRSPOND TO NEW DIMENSION ENTRY
76	-----	-----	FIX EDIT 75
77	-----	-----	REMOVE CODE THAT KEEPS ARRAY DIMENSIONS ASSOCIATED
			WITH ADJUSTABLE DIMENSIONS ACROSS ENTRIES
78	-----	-----	IN ADJGEN, SET THE "IDLIBFNFLG" IN THE SYMBOL TABLE
			ENTRIES FOR "ADJG." AND "ADJ1." (SO THAT CAN KNOW
			THAT THEY DONT CLOBBER ALL REGS AS OTHER CALLS DO)
79	-----	-----	DO NOT BUILD A REGCONTENTS NODE IN DOXPN
			(CLEVER BUT A BUMMER)

80	-----	-----	CLEAR THE NOALLOC BIT FOR PHASE 1, WHEN GENERATING TEMPORARIES
81	19130	433	IF ALL DO PARAMS KNOWN AT COMPILE TIME AND
			LOOP WILL BE XCT'D NEG OR ZERO TIMES, DO IT ONCE

)%

SWITCHES NOLIST;
REQUIRE FIRST.BLI;
REQUIRE TABLES.BLI;
SWITCHES LIST;

%*****
	TAKE A NUMBER AND MAKE 4 SIXBIT DIGITS OUT OF IT
	USED TO GENERATE TEMPORARY NAMES
*****%

MACRO MAKNAME(NUMB)=
	(.NUMB<9,3>+16)^18 + (.NUMB<6,3>+16)^12 + (.NUMB<3,3>+16)^6
	+ (.NUMB<0,3>+16)$;
FORWARD INITLTEMP,SSIZTMP;
GLOBAL ROUTINE DOXPN(CNODE)=
BEGIN


	EXTERNAL CORMAN,KARIAB,KARIIB;
	EXTERNAL C1L,C1H,C2L,C2H,TBLSEARCH,CNVNODE;
	EXTERNAL COPRIX,SPKABA,CNSTCM,EXPRTYPER,MAKPR1;
	EXTERNAL KDPRL;
	!CREATE DO LOOP CONTROL EXPRESSION
	!CNODE POINTS TO DO STATEMENT ENCODED SOURCE
	MAP BASE CNODE;
	OWN	DOINITL,					!POINTER TO INITIAL VALUE
	DOULIM,						!POINTER TO UPPER LIMIT
	DOSTEPSIZ,					!POINTER TO STEP SIZE;0 IF STEP SIZE IS 1
	DOSYMBOL,					!POINTER TO INDUCTION VARABLE
	DOCESSOR,					!PREDECESSOR OF DO STATEMENT
	OPEXPR,						!TEMPORARY
	PEXPR;						!TEMPORARY
	OWN SSIZMINUSONEFLG;	!SET THIS FLAG IF STEP SIZE IS MINUS ONE
	OWN BASE T;		!TEMPORARY
	MAP PEXPRNODE DOCESSOR;
	MAP PEXPRNODE DOSYMBOL:DOINITL:DOULIM:DOSTEPSIZ:PEXPR:OPEXPR;

	!MACRO WILL MOVE LABEL ON THE DO STATEMENT ITSELF (IF ANY)
	!BACK TO THE STEP SIZE COMPUTATION OR INITIAL VALUE
	!COMPUTATION IF THESE ARE PRESENT
	MACRO ADJLAB=
		IF .CNODE[SRCLBL] NEQ 0 THEN
		BEGIN
			LOCAL BASE TMP;
			OPEXPR[SRCLBL]_.CNODE[SRCLBL];
			CNODE[SRCLBL]_0;
			TMP_.OPEXPR[SRCLBL];
			TMP[SNHDR]_.OPEXPR;
		END$;

	DOSYMBOL_.CNODE[DOSYM];
	!SET SYMBOL TABLE BIT TO INDICATE THIS VARIABLE IS
	!STORED INTO IN CASE IT IS AN ARGUMENT THAT NEEDS
	!STORING BACK
	DOSYMBOL[IDATTRIBUT(STORD)]_1;
	DOINITL_.CNODE[DOM1];
	DOULIM_.CNODE[DOM2];
	DOSTEPSIZ_.CNODE[DOM3];
	DOCESSOR_.CNODE[DOPRED];
	CNODE[NEDSMATRLZ]_1;		!SET BIT OPTIMIZER WILL RESET


	!IF EITHER OF THE LIMITS OR THE STEP SIZE IS A NEGATIVE OF A CONSTANT,
	! FOLD THAT NEGATION HERE SO THAT THE GENERATED CODE FOR
	!       DO 10 I=10,1,-1
	! WILL NOT TREAT THE -1 AS AN ARBITRARY EXPRESSION(SRM-FEB 9,1973)
	IF .DOINITL[OPR1] EQL NEGFL
	THEN
	BEGIN
		T_.DOINITL[ARG2PTR];	!ARG UNDER THE NEG
		IF .T[OPR1] EQL CONSTFL THEN DOINITL_NEGCNST(T);
	END;
	IF .DOULIM[OPR1] EQL NEGFL
	THEN
	BEGIN
		T_.DOULIM[ARG2PTR];	!ARG UNDER THE NEG
		IF .T[OPR1] EQL CONSTFL THEN DOULIM_NEGCNST(T);
	END;
	IF .DOSTEPSIZ[OPR1] EQL NEGFL
	THEN
	BEGIN
		T_.DOSTEPSIZ[ARG2PTR];	!ARG UNDER THE NEG
		IF .T[OPR1] EQL CONSTFL THEN DOSTEPSIZ_NEGCNST(T);
	END;


	!IF EITHER OF THE LIMITS OR THE STEP SIZE HAS A DIFFERENT VAL-TYPE FROM
	! THE INDUCTION VARIABLE, MUST PERFORM TYPE CONVERSION (SRM-OCT 6,1972)
	IF .DOINITL[VALTP2] NEQ .DOSYMBOL[VALTP2] THEN DOINITL_CNVNODE(.DOINITL,.DOSYMBOL[VALTYPE],0);
	IF .DOULIM[VALTP2] NEQ .DOSYMBOL[VALTP2] THEN DOULIM_CNVNODE(.DOULIM,.DOSYMBOL[VALTYPE],0);
	IF .DOSTEPSIZ[VALTP2] NEQ .DOSYMBOL[VALTP2] THEN DOSTEPSIZ_CNVNODE(.DOSTEPSIZ,.DOSYMBOL[VALTYPE],0);




	IF .DOSYMBOL[VALTP1] NEQ INTEG1
	THEN
		 CNODE[REALARITH]_1;


	!LOOK AT THE STEP SIZE


	SSIZMINUSONEFLG_FALSE;		!FLAG FOR STEP SIZE = -1, INIT TO FALSE

	IF .DOSTEPSIZ[OPR1] EQL CONSTFL THEN
	BEGIN
		!CHECK FOR STEP SIZES ONE AND MINUS ONE
		IF .DOSTEPSIZ[VALTYPE] EQL REAL THEN
		BEGIN
			%(***FOR REALS- MUST ROUND FROM 2 WDS OF PREC TO ONE BEFORE
				EXAMINING THE VALUE (KEEP THEM AS UNROUNDED 2 WD VALS
				INSIDE THE COMPILER) ***)%
			C1H_.DOSTEPSIZ[CONST1];	!SET GLOBALS FOR THE ASSEMBLY LANG
			C1L_.DOSTEPSIZ[CONST2];		! THAT ROUNDS THE CONST
			COPRIX_KDPRL;
			CNSTCM();			!ROUND - LEAVE RESULT IN C2H

			IF .C2H EQL #201400000000 THEN
				CNODE[SSIZONE]_1
			ELSE IF .C2H EQL #576400000000
			THEN
				SSIZMINUSONEFLG_TRUE
		END ELSE
		IF .DOSTEPSIZ[VALTP1] EQL INTEG1 THEN
		BEGIN
			IF .DOSTEPSIZ[CONST2] EQL 1 THEN
				CNODE[SSIZONE]_1
			ELSE IF .DOSTEPSIZ[CONST2] EQL -1 THEN
				SSIZMINUSONEFLG_TRUE
		END
		ELSE
		%(***FOR DOUBLE PRECISION AND COMPLEX - DONT BOTHER OPTIMIZING THE -1 CASE***)%
		BEGIN
			IF .DOSTEPSIZ[CONST1] EQL #201400000000 AND .DOSTEPSIZ[CONST2] EQL 0
			THEN CNODE[SSIZONE]_1
		END;

	END;		!STEP SIZE NOT A CONSTANT
	IF .DOSTEPSIZ[OPRCLS] NEQ DATAOPR THEN
	BEGIN
		!STEP SIZE REALLY REQUIRES A COMPUTATION.
		!MAKE AN ASSIGNMENT STATEMENT FOR IT AND PUT
		!IT IN FRONT OF THE DO STATEMENT
		NAME<LEFT>_ASGNSIZ+SRCSIZ;
		OPEXPR_CORMAN();
		!LINK IT IN
		DOCESSOR[SRCLINK]_.OPEXPR;
		OPEXPR[SRCLINK]_.CNODE;
		!SET VAL FLG IN STATEMENT NODE
		OPEXPR[A1VALFLG]_1;
		OPEXPR[OPRCLS]_STATEMENT;
		OPEXPR[SRCID]_ASGNID;
		OPEXPR[LHEXP]_SSIZTMP(.DOSTEPSIZ[VALTYPE]);
		DOSTEPSIZ[PARENT]_.OPEXPR;
		OPEXPR[RHEXP]_.DOSTEPSIZ;
		!FIX FIELDS IN DO STATMENT NODE
		CNODE[DOPRED]_.OPEXPR;
		!FIX LOCALS
		DOCESSOR_.OPEXPR;
		DOSTEPSIZ_.OPEXPR[LHEXP];
		!SET FLAG
		CNODE[SSIZINTMP]_1;
		!MOVE THE LABEL BACK
		ADJLAB;
	END;


		CNODE[DOSSIZE]_.DOSTEPSIZ;
		CNODE[DOCTLVAR]_SSIZTMP(INTEGER);






	PEXPR_0;

	%(***SET "PEXPR" TO POINT TO AN EXPRESSION NODE FOR "M2-M1"
		THIS WILL BE USED IN THE COMPUTATION OF THE LOOP ITERATION CT***)%
	IF .DOULIM[OPR1] EQL CONSTFL AND .DOINITL[OPR1] EQL CONSTFL THEN
	BEGIN
		COPRIX_KKARITHOP(.DOINITL[VALTP1],SUBOP);
		C1H_.DOULIM[CONST1];
		C1L_.DOULIM[CONST2];
		C2H_.DOINITL[CONST1];
		C2L_.DOINITL[CONST2];
		CNSTCM();
		PEXPR_MAKECNST(.DOINITL[VALTYPE],.C2H,.C2L);
	END

	ELSE
	!IF NOT BOTH CONSTANTS, BUILD EXPRESSION
	BEGIN
		!BUILD AN EXPRESSION NODE
		!CHECK THE PROPERTIES OF THE INITIAL VALUE
		!BAD RESULTS (IN CODE) IF IT IS A CONSTANT EXPRESSION
		!AS WE WILL NOT FOLD IT HERE

		!IF INITIAL VAL IS AN EXPRESSION, BUILD AN ASSIGNMENT
		!STMNT TO A TEMPORARY FOR THAT EXPRESSION
		!INSERT THAT ASSIGNMENT STMNT BEFORE THE DO STMNT
		IF .DOINITL[OPRCLS] NEQ DATAOPR THEN
		BEGIN
			CNODE[INITLTMP]_1;	!SET FLAG
			!MAKE AN ASSIGNMENT STATEMENT FOR IT
			!OPEXPR IS USED AS A TEMPORARY
			NAME<LEFT>_ASGNSIZ+SRCSIZ;
			OPEXPR_CORMAN();
			!LINK IT IN FRONT OF THE DO STATEMENT
			DOCESSOR[SRCLINK]_.OPEXPR;
			OPEXPR[SRCLINK]_.CNODE;
			!SET APPROPRIATE FLAGS
			OPEXPR[A1VALFLG]_1;		!THE TEMP
			OPEXPR[OPRCLS]_STATEMENT;
			OPEXPR[SRCID]_ASGNID;
							!GENERATE TEMPORARY
							!FOR INITIAL
							!VALUE
			OPEXPR[LHEXP]_INITLTEMP(.DOINITL[VALTYPE]);
			OPEXPR[RHEXP]_.DOINITL;
			DOINITL[PARENT]_.OPEXPR;
			!RESET DOPRED  IN THE DO STATEMENT
			CNODE[DOPRED]_.OPEXPR;
			!RESET MY LOCALS FOR THE RIGHT THING
			DOINITL_.OPEXPR[LHEXP];
			DOCESSOR_.OPEXPR;
			!MOVE THE LABEL BACK IF THERE IS ONE
			ADJLAB;
		END;


		%(***MAKE EXPRESSION NODE FOR FINAL VALUE(POSSIBLY AN EXPRESSION)
			MINUS INITIAL VALUE (ALWAYS EITHER A DATAOPR OR THE REGCONTENTS
			NODE JUST BUILT) ****)%
		PEXPR_MAKPR1(.CNODE,ARITHMETIC,SUBOP,.DOULIM[VALTYPE],.DOULIM,.DOINITL);

		PEXPR[A2VALFLG]_1;	!ARG2 OF THE SUBTRACT IS EITHER A DATAOPR OR A REGCONTENTS
					! HENCE SHOULD ALWAYS HAVE VALFLG SET ABOVE IT
		OPEXPR_.PEXPR[ARG1PTR];	!IF ARG1 IS A DATAOPR, SET THE VALFLG ABOVE IT

		PEXPR[A1VALFLG]_.OPEXPR[OPRCLS] EQL DATAOPR;
	END;


	!NOW MAKE THE LOOP CONTROL EXPRESSION

	IF NOT .CNODE[SSIZONE] THEN
	BEGIN
		OPEXPR_.PEXPR;
		IF .DOSTEPSIZ[OPR1] EQL CONSTFL AND .PEXPR[OPR1] EQL CONSTFL
			AND .PEXPR[VALTYPE] NEQ COMPLEX   !CANNOT FOLD COMPLEX DIVIDE
		 THEN
		BEGIN
			!CONSTANTS OF SAME TYPE
			COPRIX_KKARITHOP(.PEXPR[VALTP1],DIVOP);
			C1H_.PEXPR[CONST1];
			C1L_.PEXPR[CONST2];
			C2H_.DOSTEPSIZ[CONST1];
			C2L_.DOSTEPSIZ[CONST2];
			CNSTCM();
			PEXPR_MAKECNST(.PEXPR[VALTYPE],.C2H,.C2L);
		END
		ELSE
		IF .SSIZMINUSONEFLG
		THEN
		BEGIN
			!FOR STEP SIZE EQUAL TO MINUS 1, NEGATE THE DIFFERENCE BETWEEN
			! THE BOUNDS RATHER THAN DIVIDING IT BY -1
			PEXPR_MAKPR1(.CNODE,NEGNOT,NEGOP,.PEXPR[VALTYPE],0,.PEXPR);
			IF .OPEXPR[OPR1] EQL DATAOPR 
			THEN PEXPR[A2VALFLG]_1
			ELSE OPEXPR[PARENT]_.PEXPR;
		END
		ELSE
		BEGIN
			PEXPR_MAKPR1(.CNODE,ARITHMETIC,DIVOP,.PEXPR[VALTYPE],.PEXPR,.DOSTEPSIZ);
			IF .OPEXPR[OPRCLS] NEQ DATAOPR	!(IF OPEXPR IS A SCALAR VARIABLE,
			THEN				! DO NOT SET PARENT PTR IN IT - SRM)
			OPEXPR[PARENT]_.PEXPR;
			!CHECK OUT THE VALFLAGS
			OPEXPR_.PEXPR[ARG1PTR];
			PEXPR[A1VALFLG]_.OPEXPR[OPRCLS] EQL DATAOPR;
			OPEXPR_.PEXPR[ARG2PTR];
			PEXPR[A2VALFLG]_.OPEXPR[OPRCLS] EQL DATAOPR;
		END;
	END;

	!CONVERT THE QUOTIENT(WHICH IS TO BE USED AS A LOOP COUNT) TO INTEGER
	! IF IT IS NOT INTEGER
	IF .PEXPR[VALTYPE] NEQ INTEGER THEN
	PEXPR_CNVNODE(.PEXPR,INTEGER,0);

	!ADD ONE TO THE QUOTIENT (WHICH HAS BEEN CONVERTED TO INTEGER)
	IF .PEXPR[OPR1] EQL CONSTFL
!**;[433] Insert @ line 3457 in DOXPN	JNG	24-Aug-76
%[433]%	THEN
%[433]%	BEGIN
%[433]%		!MAKE DO LOOPS LIKE I=10,1,1 BE EXECUTED ONCE
%[433]%		IF .PEXPR[CONST2] LSS 0 THEN PEXPR[CONST2]_0;
%[433]%		PEXPR_MAKECNST(INTEGER,0,.PEXPR[CONST2]+1)
%[433]%	END
	ELSE
	BEGIN
		OPEXPR_MAKECNST(INTEGER,0,1);
		PEXPR_MAKPR1(.CNODE,ARITHMETIC,ADDOP,INTEGER,.PEXPR,.OPEXPR);
	END;



!IF LOOP CAN BE HANDLED WITH AN AOBJN, MAKE LOOP CONTROL CONSTANT
IF .PEXPR[OPR1] EQL CONSTFL		!NUMBER OF ITERATIONS A COMPILE TIME CONSTANT
	 AND NOT .CNODE[REALARITH]	! LOOP INDEX MUST BE INTEGER 
	 AND .CNODE[SSIZONE]		!STEP SIZE MUST BE ONE
	AND .DOINITL[CONST2] LEQ #377777	!LOWER BOUND ON INDEX MUST BE LESS THAN 17 BITS
	AND .DOINITL[CONST2] GEQ 0		! AND MUST BE POSITIVE
	AND .DOULIM[CONST2] LEQ #377777		!UPPER BOUND ON INDEX MUST BE LESS THAN 17 BITS
	AND .DOULIM[CONST2] GEQ 0		! AND MUST BE POSITIVE
THEN
BEGIN
!**;[433] Replace @ line 3476 in DOXPN	JNG	24-Aug-76
%[433]%	PEXPR_MAKECNST(INTEGER,0,-.PEXPR[CONST2]^18+.DOINITL[CONST2]);
	CNODE[SSIZONE]_0;		!RESET ALL OTHER FLAGS
	CNODE[FLCWD]_1;
END ELSE
	!SET SOME OTHER FLAGS DESCRIBING THE CONTROL WORD (IF ITS CONSTANT)
	IF .PEXPR[OPR1] EQL CONSTFL THEN
	BEGIN
		%(***IF THE NUMBER OF TIMES THAT THE LOOP IS TO BE EXECUTED IS A POS
			NUMBER THAT CAN BE USED IMMEDIATE MODE, DO SO. FOR A NEG
			ITERATION COUNT, DONT BOTHER. (NOTE THAT CAN COUNT ON THE CT BEING 
			AN INTEGER***)%
!**;[433] Change @ line 3489 in DOXPN	JNG	24-Aug-76
%[433]%		IF .PEXPR[CONST2] LEQ #777777
		THEN
			CNODE[CTLIMMED]_1;
		CNODE[CTLNEG]_1;
	END ELSE
		IF .PEXPR[OPRCLS] EQL DATAOPR THEN
			CNODE[CTLNEG]_1
		ELSE
	!INSERT THE NEGATE NODE NEEDED
	PEXPR_MAKPR1(.CNODE,NEGNOT,NEGOP,INTEGER,0,.PEXPR);




CNODE[DOLPCTL]_.PEXPR;
CNODE[DOM1]_.DOINITL;		!INITIAL VALUE FOR LOOP INDEX
END;

EXTERNAL
	SSIZTC,			!COUNTER FOR STEP SIZE TEMPS
				!GENERATED FOR DO LOOPS
	INTLTC;			!COUNTER FOR TEMPS GENERATED
				!FOR DO LOOP INITIAL VALUES
%*****
	NOTE THAT THE NAMES WILL NOT BE UNIQUE OR VALID IF THERE
	ARE MORE THAN 9999 FOR EACH
*****%


!************************************

GLOBAL ROUTINE SSIZTMP(SSIZ)=
BEGIN
EXTERNAL TBLSEARCH;

!CREATE A STEP SIZ TEMPORARY FOR DO LOOPS

LOCAL STPTMP;
MAP BASE STPTMP;

	NAME_IDTAB;
	ENTRY[0]_SIXBIT'.S'+MAKNAME(SSIZTC);
	SSIZTC_.SSIZTC+1;		!ADD A SIXBIT 1
	STPTMP_TBLSEARCH();		!LOOK UP
	STPTMP[VALTYPE]_.SSIZ;
	! CLEAR THE NOALLOC BIT FOR PHASE 1
	STPTMP[IDATTRIBUT(NOALLOC)] _ 0;
	!SET THE VALUE TYPE OF THE VARIABLE
	.STPTMP
END;

!***************************************

GLOBAL ROUTINE INITLTEMP(IVAL)=

BEGIN
EXTERNAL TBLSEARCH;

!MAKE AN INITIAL VALUE TEMPORARY

LOCAL ITLTMP;
MAP BASE ITLTMP;

!IVAL POINTS TO THE DO NODE INITIAL VALUE

	NAME_IDTAB;
	ENTRY[0]_SIXBIT'.I'+MAKNAME(INTLTC);
	INTLTC_.INTLTC+1;		!ADD SIX BIT ONE
	ITLTMP_TBLSEARCH();
	ITLTMP[VALTYPE]_.IVAL;
	!CLEAR THE NOALLOC BIT FOR PHASE 1
	ITLTMP[IDATTRIBUT(NOALLOC)] _ 0;
	.ITLTMP
END;



GLOBAL ROUTINE IODOXPN(IOSTMNT)=
%(***************************************************************************
	ROUTINE TO WALK THRU AN IOLIST AND PERFORM DOXPN ON ALL IMPLICIT
	DO STMNT NODES. SETS THE "DOPRED" FIELD OF EACH DO STMNT NODE
	BEFORE CALLING DOXPN.
	CALLED WITH A PTR TO THE IO STMNT FOR WHICH THE IOLIST IS TO BE
	PROCESSED.
***************************************************************************)%
BEGIN
	EXTERNAL CORMAN;
	MAP BASE IOSTMNT;
	OWN PEXPRNODE IOLPTR;
	OWN PEXPRNODE PRVELEM;	!PTR TO THE ELEMENT IN THE IOLIST PRECEEDING
					! THE ELEMENT POINTED TO BY IOLPTR


	!PHASE ONE IS NOT COUNTING END=,ERR= LABEL REFERENCES
	!SO WE WILL COUNT THEM NOW
	IF (IOLPTR_.IOSTMNT[IOEND]) NEQ 0 THEN
		IOLPTR[SNREFNO]_.IOLPTR[SNREFNO]+1;

	IF (IOLPTR_.IOSTMNT[IOERR]) NEQ 0 THEN
		IOLPTR[SNREFNO]_.IOLPTR[SNREFNO]+1;

	IF (IOLPTR_.IOSTMNT[IOLIST]) EQL 0
	THEN RETURN;		!IF STMNT HAS NO IOLIST

	%(***IF THE FIRST ELEMENT IN THE IOLIST IS A DO-STMNT, INSERT A 
		CONTINUE STMNT IN FRONT OF IT FOR THE "DOPRED" FIELD
		OF THE DO STMNT TO POINT BACK TO***)%
	IF .IOLPTR[OPERATOR] EQL DOSTATEMENT
	THEN
	BEGIN
		NAME_CONTDATA;
		PRVELEM_CORMAN();
		PRVELEM[OPERATOR]_CONTSTATEMENT;
		PRVELEM[CLINK]_.IOLPTR;
		IOSTMNT[IOLIST]_.PRVELEM;
	END;


	%(***WALK THRU SUCCESSIVE ELEMS OF THE IOLIST. SET THE "DOPRED" FIELD
		OF EACH DO-STMNT NODE TO PT TO THE NODE PRECEEDING IT. CALL
		DOXPN FOR EACH DO STMNT NODE***)%
	%(** IF HAVE AN EXPRESSION NODE UNDER A DATACALL, FILL
		IN THE PARENT POINTER)%
	UNTIL .IOLPTR EQL 0
	DO
	BEGIN
		IF .IOLPTR[OPERATOR] EQL DOSTATEMENT
		THEN
		BEGIN
			IOLPTR[DOPRED]_.PRVELEM;
			DOXPN(.IOLPTR);
		END
		ELSE
		IF .IOLPTR[OPERATOR] EQL DATACLFL
		THEN
		BEGIN
			OWN PEXPRNODE T;
			T _ .IOLPTR[DCALLELEM];

			IF .T NEQ 0		!IF THERE WAS AN ERROR FOUND WHEN
						! PROCESSING THIS DATA ELEMNT (EG
						! AN ILLEGAL ARRAYREF)
			THEN
			BEGIN
				IF .T[OPRCLS] NEQ DATAOPR
				THEN
				T[PARENT] _ .IOLPTR
			END;
		END;

		%(***GO ON TO THE NEXT ELEMENT***)%
		PRVELEM_.IOLPTR;
		IOLPTR_.IOLPTR[CLINK];
	END;
END;
FORWARD ALLONES;


ROUTINE ADJGEN(DTABB,ARY)=
BEGIN
	!GENERATE ACTUAL FN(CALL STATEMENT)
	!NODE FOR CALL TO RUN-TIME
	!ROUTINES FOR ADJUSTABLE DIMENSIONS

	LABEL ARGDO;
	OWN BASE CALNODE;
	EXTERNAL CSTMNT,CORMAN,ONEPLIT;
	MAP BASE CSTMNT;
	EXTERNAL TBLSEARCH;
	MAP BASE DTABB: ARY;
	OWN BASE G:ROUT:DNUM:J;
	OWN DIMSUBENTRY DSUBETRY;
	OWN ARGUMENTLIST CLNODLST;

	BTTMSTFNFLG_FALSE;	!IF INSERT A CALL TO ADJUST, THIS ROUTINE IS NO LONGER "BOTTOMMOST"

	NAME<LEFT>_CALLSIZ+SRCSIZ;
	CALNODE_CORMAN();
	CALNODE[SRCLINK]_.CSTMNT[SRCLINK];
	CSTMNT[SRCLINK]_.CALNODE;
	CALNODE[OPRCLS]_STATEMENT;
	CALNODE[SRCID]_CALLID;
	G_ALLONES(.DTABB);

	!THE SPECIAL PURPOSE ROUTINE FOR ALL LOWER BOUND OF
	!ONE WILL BE CALLED ONLY IF IT IS ALSO TRUE THAT
	!ALL DIMENSIONS ARE ADJUSTABLE. WE NOW DETERMINE THAT FACT
	!BY SEEING IF THE SECOND ONE IS ADJUSTABLE. THE
	!FIRST ONE ALWAYS HAS A FACTOR OF ONE .

	IF .DTABB[DIMNUM] GTR 1 THEN
	BEGIN
		DSUBETRY_DTABB[FIRSTDIM]+DIMSUBSIZE;	!SECOND ONE
		IF NOT .DSUBETRY[VARFACTFLG] THEN G_0;
	END;

	IF .G THEN
	ENTRY_SIXBIT'ADJ1. '
	ELSE
	ENTRY_SIXBIT'ADJG. ';

	NAME_IDTAB;
	ROUT_TBLSEARCH();
	!FILL IN THE POINTER TO THE FUNCTION NAME
	CALNODE[CALSYM]_.ROUT;
	IF .FLAG THEN
	ELSE	!IF HAVE JUST CREATED A NEW SYMBOL TABLE ENTRY
	(ROUT[OPERSP]_FNNAME; ROUT[IDLIBFNFLG]_1);
	DNUM_.DTABB[DIMNUM];

	!COMPOSE THE ARGUMENT LIST FOR A CALL TO
	!ADJ1.OR ADJG.


	!FIRST GET THE CORE FOR THE LIST
	NAME<LEFT>_(3-.G)*(.DNUM)+6;
	!FOR EACH DIMENSION
	!ONE WORD FOR U(I)			!MAYBE ONE FDR L(I)
	!ONE WORD FOR MULT(I)
	!=(2 OR 3)*DNUM
	!+
	!ONE WORD FOR OFFSET
	!+
	!ONE WORD FOR NUMBER OF DIMENSIONS
	!+
	!WORD THAT CONTAINS NUMBER OF PARAMETERS
	!+
	!ZERO HEADER WORD (FILLED IN IN CODE
	!+
	!WORD FOR ARRAY SIZE
	!+
	!WORD FOR BASE ADDRESS OF ARRAY
	!GENERATION WITH LABEL FOR GENERATED
	!ARG LIST

	CLNODLST_CALNODE[CALLIST]_CORMAN();
	!FILL IN ARG LIST
	!FIRST THE NUMBER OF ARGUMENTS

	CLNODLST[ARGCOUNT]_.NAME<LEFT>-2;

	!NOW FILL IN THE ARGUMENT LIST.
	!J POINTS TO ARG ENTRY WHILE THE INCR LOOP
	!GOES THROUGH ALL DIMENSIONS
	!THE FIRST ARGUMENT WE WILL FIRST FILL IN IS UB(1)
	!WHUCH IS THE FOURTH ARGUMENT,THUS J=4.
	!THEN MULT(2) WHICH IS THE DIMFACTOR FROM THE
	!DIMENSION SUBENTRY AFTER THE ONE CONTAINING UB(1).
	J_6;
	DSUBETRY_DTABB[FIRSTDIM];
	!IN ORDER FOR THE LOOP TO OPERATE CORRECTLY, WE ARE
	!NOT DOING WHAT IT APPEARS WE ARE DOING. WE WILL
	!FILL IN MULT(1), UB(1),.....MULT(N),UB(N) AND
	!THEN SINCE MULT(1) IS SPECIAL REALLY FILL IT IT LATER
	!ROUT WILL BE USED AS A TEMP TO
	!HELP US SAVE THE RIGHT THING TO PUT INTO MULT(1)
	!LATER.
	!A DOUBLE PRECISION OR COMPLEX ARRAY STARTS OUT AT TWO
	IF .ARY[DBLFLG] THEN ROUT_MAKECNST(INTEGER,0,2)
	ELSE
	ROUT_.ONEPLIT;

	ARGDO:
	INCR I FROM 1 TO .DNUM DO
	BEGIN
			!HOLE FOR PARTIALLY CONSTANT ONES
			CLNODLST[.J,ARGNPTR]_.DSUBETRY[DIMUB];
			CLNODLST[.J,AVALFLG]_1;
			IF NOT .G THEN
			BEGIN
			!ALL LOWER BOUNDS ARE NOT 1
				J_.J+1;
				CLNODLST[.J,ARGNPTR]_.DSUBETRY[DIMLB];
				CLNODLST[.J,AVALFLG]_1;
			END;
			!DONT PUT OUT FACTOR FOR LAST ONE
			IF .I EQL .DNUM THEN LEAVE ARGDO;
			DSUBETRY_.DSUBETRY+DIMSUBSIZE;
			J_.J+1;
			CLNODLST[.J,ARGNPTR]_.DSUBETRY[DIMFACTOR];
			CLNODLST[.J,AVALFLG]_1;
			J_.J+1;
	END;							!INCR LOOP

	!FILL IN ARGUMENT 1, THE NUMBER
	!OF DIMENSIONS
	
	CLNODLST[1,ARGNPTR]_MAKECNST(INTEGER,0,.DNUM);
	CLNODLST[1,AVALFLG]_1;
	!FILL IN ARRAY SIZE
	CLNODLST[2,ARGNPTR]_.DTABB[ARASIZ];
	CLNODLST[2,AVALFLG]_1;
	!FILL IN ARGUMENT 2, BASE ADDRESS OF ARRAY
	CLNODLST[3,ARGNPTR]_.ARY;
	CLNODLST[3,AVALFLG]_1;
	!FILL IN ARGUMENT 4, THE ARRAY OFFSET
	CLNODLST[4,ARGNPTR]_.DTABB[ARAOFFSET];
	CLNODLST[4,AVALFLG]_1;
	!FILL IN MULT(1)
	CLNODLST[5,ARGNPTR]_.ROUT;
	CLNODLST[5,AVALFLG]_1;
	
END;

ROUTINE ALLONES(DTABB)=

BEGIN
	!LOOK THROUGH DIMENSION TABLE ENTRY
	!TO SEE IF ALL LOWER BOUNDS ARE 1.
	!RETURN 1 (TRUE) IF THEY ARE AND
	!0 (FALSE) IF NOT
	EXTERNAL ONEPLIT;
	OWN DNUM,DSUBETRY;
	MAP PEXPRNODE DTABB;
	MAP DIMSUBENTRY DSUBETRY;
	DNUM_.DTABB[DIMNUM];
	DSUBETRY_DTABB[FIRSTDIM];			!POINT TO FIRST SUBENTRY
	INCR I FROM 1 TO .DNUM DO
	BEGIN
		IF .DSUBETRY[DIMLB] NEQ .ONEPLIT
		THEN
		RETURN(0)
		ELSE
		DSUBETRY_.DSUBETRY+DIMSUBSIZE;
	END;
	RETURN 1
END;


GLOBAL ROUTINE ADJCALL=
BEGIN
	!INSERT CALL STATEMENT NODES FOR ADJUSTABLY DIMENSIONED
	!ARRAYS TO CALL THE OBJECT TIME ROUTINES
	!ADJ1. OR ADJG. TO COMPUTE FACTORS AND OFFSET
	EXTERNAL CSTMNT,CHOSEN,ENTRY,NAME,CORMAN;
	EXTERNAL VERYFRST,QQ;
	OWN DTABB,CLST,CALNODE,CLNODLST,G,CLSTARG;
	MAP ARGUMENTLIST CLNODLST:CLST;
	MAP BASE CSTMNT:DTABB:CLSTARG;

	VERYFRST_0;
	CSTMNT_.SORCPTR<LEFT>;
	WHILE .CSTMNT NEQ 0 DO
	BEGIN
		!IF ITS AN ENTRY
		IF .CSTMNT[SRCID] EQL ENTRID THEN
		!IF THERE ARE PARAMETERS
		IF .CSTMNT[CALLIST] NEQ 0 THEN
		BEGIN
			CLST_.CSTMNT[CALLIST];
			INCR I FROM 1 TO .CLST[ARGCOUNT] DO
			BEGIN
				CLSTARG_.CLST[.I,ARGNPTR];
				!IF AN ARRAY LOOK TO SEE
				!IF IT IS ADJUSTABLE

				IF .CLSTARG[OPR1] EQL
				OPR1C(DATAOPR,FORMLARRAY)
				THEN
				BEGIN
					DTABB_.CLSTARG[IDDIM];
					!LOOK TO SEE IF IT IS
					!ADJUSTABLY DIMENSIONED
					IF .DTABB[ADJDIMFLG] THEN
						ADJGEN(.DTABB,.CLSTARG);
				END;
			END;
		END;
		CSTMNT_.CSTMNT[SRCLINK];
	END;
END;