Google
 

Trailing-Edge - PDP-10 Archives - bb-4157j-bm_fortran20_v11_16mt9 - fortran-compiler/regutl.bli
There are 12 other files named regutl.bli in the archive. Click here to see a list.
!COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1974, 1987
!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.

!AUTHORS: NORMA ABEL AND SARA MURPHY/HPW/TFV/AHM/TJK/CDM

MODULE REGUTL(RESERVE(0,1,2,3),SREG=#17,VREG=#15,FREG=#16,DREGS=4,GLOROUTINES)=
BEGIN

GLOBAL BIND REGUTV = #11^24 + 0^18 + #4527;	! Version Date: 1-Jan-86


%(

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

17	-----	-----	CREATE MODULE
18	-----	-----	TAKE LASTONE OUT AND PUR IT BACK IN UTIL
19	-----	-----	MAKE ALODIMCONSTS ALLOCATE CONSTANTS FOR PROTECTED
			ARRAYS WHEN "DEBUG" SWITCH NOT SET
20	-----	-----	MODIFY ALODIMCONSTS TO ALLOCATE CONSTS FOR
			ARRAY DIMENSIONS WHEN EITHER THE "BOUNDS" SWITCH
			OR THE "DEBUG" SWITCH IS SET (WE NO LONGER PROTECT
			INDIVIDUAL ARRAYS - ONLY ALL ARRAYS)
21	-----	-----	CHANGE REF TO THE FLAG "DEBUG" TO REF TO "DBGDIMN"

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

22	1274	TFV	20-Oct-81	------
	Rewrite NXTTMP, its arg is now the size of the .Qnnnn variable to 
	allocate.  Write NEWQTMP to generate a new .Qnnnn variable.

1552	AHM	6-Jun-82
	Make NEWQTMP set the  IDPSECT and IDPSCHARS  fields of the  .Q
	temp being  created to  PSDATA  so that  we can  generate  the
	address of the .Q temp in HSDDESC in OUTMOD.

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

2006	TJK	6-Oct-83
	Add ENDSMZTRIP to see if the current statement (pointed to  by
	CSTMNT) ends a MAYBEZTRIP DO-loop.

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

2227	TJK	21-Oct-83
	Add ENDSBBLOCK to see if the current statement (pointed to  by
	CSTMNT) ends a basic block.  Returns one of several values  to
	indicate how the block is ended  (if it is ended).  Also  made
	ENDSMZTRIP non-global and fixed some comments.

2364	TJK	6-Jun-84
	Make ENDSMZTRIP global for use by ALCIOLST.

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

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

***** Begin Version 11 *****

4527	CDM	1-Jan-86
	VMS Long symbols phase II.  Convert all internal symbols from
	one word of Sixbit to [length,,pointer].  The lengths will be one
	(word) until a later edit, which will store and use long symbols.

ENDV11
)%

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

EXTERNAL
	CORMAN,		! Routine to get space for the entry
%4527%	CPYSYM,		! Copy [length,,pointer] to permanent location
%2006%	BASE CSTMNT,	! Pointer to current statement being processed
	BASE LASTQ,	! Pointer to the last .Q used by the current statement
%4527%	ONEWPTR,	! Create [1,,pointer] to Sixbit symbol passed
	QANCHOR,	! Pointer to start of linked .Q list
	QCNT,		! Value to use for .Qnnnn
%2227%	QLOC,		! Next location in .Q space to be used by the
			! current statement
	QMAX;		! Maximum size of .Q space for all statements
GLOBAL ROUTINE ENDSMZTRIP =	![2364] Made global

!++
! FUNCTIONAL DESCRIPTION:
!
!	This routine looks to see if the current statement (e.g.,  the
!	statement node pointed to by CSTMNT) terminates a DO-loop with
!	the MAYBEZTRIP flag set.
!
! FORMAL PARAMETERS:
!
!	NONE
!
! IMPLICIT INPUTS:
!
!	CSTMNT	points to the current statement node.
!
! IMPLICIT OUTPUTS:
!
!	NONE
!
! ROUTINE VALUE:
!
!	TRUE	if the current statement terminates some MAYBEZTRIP DO-loop
!	FALSE	if the current statement terminates no MAYBEZTRIP DO-loop
!
! SIDE EFFECTS:
!
!	NONE
!
!--


![2006] Routine added in this edit
BEGIN
	REGISTER BASE LAB;	! LAB points to the stmnt number table entry
	REGISTER BASE LINK;	! LINK points to the DO-node links
	REGISTER BASE CURDO;	! CURDO points to the DO-nodes

	IF F77					! Only check if compiling F77
	THEN IF (LAB = .CSTMNT[SRCLBL]) NEQ 0	! and statement is labeled
	THEN
	BEGIN	! Labeled F77 statement

		! We're compiling F77 and  this statement is  labeled.
		! Look for a MAYBEZTRIP DO-loop terminated by it,  and
		! return  immediately  with  TRUE  if  we  find   one.
		! Otherwise fall through and return FALSE.

		LINK = .LAB[SNDOLNK];	! Set LINK to first link (if any)

		UNTIL .LINK EQL 0	! Loop until end of list
		DO
		BEGIN	! For each DO statement

			CURDO = .LINK[LEFTP];	! CURDO points to DO-node
			IF .CURDO[MAYBEZTRIP]	! Is DO-node MAYBEZTRIP?
			THEN RETURN TRUE;	! Yes, found a MAYBEZTRIP loop
			LINK = .LINK[RIGHTP];	! Otherwise move to next link

		END;	! For each DO statement

	END;	! Labeled F77 statement

	RETURN FALSE;	! We didn't find a MAYBEZTRIP DO-node

END;	! of ENDSMZTRIP
GLOBAL ROUTINE ENDSBBLOCK =	![2227] Routine added in this edit

!++
! FUNCTIONAL DESCRIPTION:
!
!	This routine looks to see if the current statement (i.e.,  the
!	statement node pointed to by CSTMNT) is the last statement  in
!	a basic block.  CSTMNT must not be zero.  The routine  returns
!	one of several values to indicate  how the block is ended  (if
!	it is ended).
!
!
!	A basic block is terminated after (i.e., CSTMNT points to):
!
!		1.  A STATEMENT FUNCTION statement
!
!		2.  A CALL  statement  (since any  CALL  statement  is
!		    assumed to clobber all registers)
!
!		3.  A LOGICAL IF statement whose consequent is a  CALL
!		    statement
!
!		4.  A DO statement (since  control may be  transferred
!		    to the  following statement  from the  end of  the
!		    loop)
!
!		5.  A statement which terminates at least one  DO-loop
!		    whose MAYBEZTRIP flag  is set (i.e.,  the loop  is
!		    potentially zero-trip,  and control  may  transfer
!		    directly to the statement following the loop)
!
!		6.  The last statement node in the encoded source tree
!
!
!	A basic block is terminated before (i.e., CSTMNT[SRCLINK] points to):
!
!		1.  A STATEMENT FUNCTION statement
!
!		2.  An ENTRY statement
!
!		3.  A labeled  statement  whose  label  is  referenced
!		    other  than  as  a  DO-loop  terminator  (i.e.,  a
!		    statement which  has control  transferred to  it);
!		    note that FORMAT statements  do not appear in  the
!		    encoded source tree
!
!
! FORMAL PARAMETERS:
!
!	NONE
!
! IMPLICIT INPUTS:
!
!	CSTMNT	points to the current statement node.  CSTMNT must not
!		be  zero.    The   statement  node   pointed   to   by
!		CSTMNT[SRCLINK]   may    also    be    examined,    if
!		CSTMNT[SRCLINK] isn't zero.
!
! IMPLICIT OUTPUTS:
!
!	NONE
!
! ROUTINE VALUE:
!
!	0	if the current statement isn't the last statement in a
!		basic block.
!
!	1	if the current  statement is the  last statement in  a
!		basic block, for  at least one  reason other than  the
!		current statement being a DO statement.
!
!	2	if the current  statement is the  last statement in  a
!		basic block,  for the  sole  reason that  the  current
!		statement is a DO statement.
!
!	If the current statement  is a DO statement  then return 1  if
!	and only if the  next statement is  a labeled statement  whose
!	label is referenced other than as a DO-loop terminator.   This
!	is the only other condition  for basic block termination  when
!	the current statement is a DO statement.  In such a case don't
!	return 2  because the  the  DO-variable might  not be  in  its
!	allocated register upon a branch to the labeled statement.
!
!
! SIDE EFFECTS:
!
!	NONE
!
!--


BEGIN
	REGISTER BASE NEXTSTMNT;	! NEXTSTMNT points to the next stmnt
	REGISTER BASE TMPBASE;		! TMPBASE is a temporary pointer

	IF .CSTMNT[SRCID] EQL SFNID	! Is curr stmnt a STATEMENT FUNCTION?
	THEN RETURN 1;			! Yes, end basic block normally

	IF .CSTMNT[SRCID] EQL CALLID	! Is curr stmnt a CALL?
	THEN RETURN 1;			! Yes, end basic block normally

	IF .CSTMNT[SRCID] EQL IFLID	! Is curr stmnt a LOGICAL IF?
	THEN
	BEGIN	! LOGICAL IF case

		TMPBASE = .CSTMNT[LIFSTATE];	! TMPBASE points to consequent
		IF .TMPBASE[SRCID] EQL CALLID	! Is consequent a CALL?
		THEN RETURN 1;			! Yes, end basic block normally

	END;	! LOGICAL IF case

	IF (NEXTSTMNT = .CSTMNT[SRCLINK]) EQL 0	! Is this the last statement of
						! the current program unit
						! (i.e., the END statement)?
	THEN RETURN 1;				! Yes, end basic block normally

	IF .NEXTSTMNT[SRCID] EQL SFNID	! Is next stmnt a STATEMENT FUNCTION?
	THEN RETURN 1;			! Yes, end basic block normally

	IF .NEXTSTMNT[SRCID] EQL ENTRID	! Is next stmnt an ENTRY?
	THEN RETURN 1;			! Yes, end basic block normally

	! See if the  next statement is  labeled.  If it  is, look  at
	! SNREFNO minus  1 (since  the actual  label is  counted as  a
	! reference), and  if  this  is greater  than  the  number  of
	! DO-loops terminated  by  the  label,  then  control  may  be
	! transferred to this  statement.  In this  case, the  current
	! statement is the  last statement of  the basic block.   Note
	! that FORMAT statements do not  appear in the encoded  source
	! tree.

	IF (TMPBASE = .NEXTSTMNT[SRCLBL]) NEQ 0		  ! Next stmnt labeled?
	THEN IF .TMPBASE[SNREFNO]-1 GTR .TMPBASE[SNDOLVL] ! Yes, check the use
	THEN RETURN 1;	! Control may be transferred to this label, so
			! end basic block normally

	! Now call ENDSMZTRIP, which will  return TRUE if the  current
	! statement ends at  least one  MAYBEZTRIP (i.e.,  potentially
	! zero-trip) DO-loop.   In this  case we  terminate the  basic
	! block after the  current statement, since  control could  be
	! transferred directly  to  the  following  statement  in  the
	! zero-trip case.

	IF ENDSMZTRIP()	! Does curr stmnt end at least one MAYBEZTRIP DO-loop?
	THEN RETURN 1;	! Yes, end basic block normally

	! If we  made  it this  far,  then  the only  reason  left  to
	! terminate the basic block is  if the current statement is  a
	! DO statement.  In this case,  control may be transferred  to
	! the following statement from the end of the loop, so we must
	! end the basic block.  However, we may be able to access  the
	! DO-variable from a register, so we return a special value to
	! indicate this.

	IF .CSTMNT[SRCID] EQL DOID	! Is curr stmnt a DO?
	THEN RETURN 2;			! Yes, end basic block and indicate why

	! If we made it to here, then there is no reason to  terminate
	! the basic block after the current statement.

	RETURN 0;	! Continue basic block

END;	! of ENDSBBLOCK
GLOBAL ROUTINE MAKRC0(VTYPE)=
%(***************************************************************************
	ROUTINE TO MAKE A REGCONTENTS NODE FOR REG 0 HAVING TYPE "VTYPE".
	 THESE NODES WILL BE SUBSTITUTED FOR THE LHS OF ALL STMNT
	FNS (SUBSTITUTION IS DONE DURING REG ALLOC PASS).
***************************************************************************)%
BEGIN
	EXTERNAL NAME,CORMAN;	!USED TO GET SOME FREE CORE

	OWN PEXPRNODE REGC0;

	NAME<LEFT>_EXSIZ;	!NUMBER OF WDS IN AN EXPRESSION NODE
	REGC0_CORMAN();		!GET FREE STORAGE FOR THE NODE

	REGC0[VALTYPE]_.VTYPE;
	REGC0[OPRCLS]_REGCONTENTS;
	REGC0[INREGFLG]_1;
	REGC0[TARGTAC]_RETREG;	!THE REG USED FOR RETURNING FN VALS (REG 0)
	REGC0[TARGADDR]_RETREG;
	RETURN .REGC0		!RETURN A PTR TO THE NODE
END;
GLOBAL ROUTINE ALODIMCONSTS=
%(***************************************************************************
	ROUTINE TO ALLOCATE CORE FOR ALL CONSTANTS THAT OCCUR IN
	SPECIFICATIONS OF DIMENSION INFORMATION FOR 
	ARRAYS  WHEN THE "BOUNDS" SWITCH OR THE "DEBUG" SWITCH IS SET.
***************************************************************************)%
BEGIN
	EXTERNAL SYMTBL;
	EXTERNAL ALDIM1;
	REGISTER BASE SYMPTR;

	IF NOT (.FLGREG<BOUNDS> OR .FLGREG<DBGDIMN>) THEN RETURN;	!WILL ALLOCATE THE DIM CONSTS IF
					! THE USER SPECIFIED ARRAY BOUNDS CHECKING TO BE DONE
					! OR DEBUGGING INFO TO BE PASSED TO FORDDT


	%(***WALK THRU THE SYMBOL TABLE AND FOR EACH ENTRY WHICH IS
		AN ARRAY NAME, PROCESS THE DIMENSION INFO FOR THAT ARRAY.
		THIS IS ECESSARY BECAUSE THERE IS NO WAY TO DIRECTLY WALK
		THRU THE DIMENSION TABLE
	****)%
	DECR I FROM SSIZ-1 TO 0
	DO
	BEGIN
		SYMPTR_.SYMTBL[.I];
		UNTIL .SYMPTR EQL 0	!LOOK AT EACH SYMBOL THAT HASHED
					! TO ENTRY "I"
		DO
		BEGIN
			IF .SYMPTR[OPRSP1] EQL ARRAYNM1	!IF THIS AN ENTRY FOR AN ARRAY NAME
			THEN
			 ALDIM1(.SYMPTR[IDDIM]);	! ALLOCATE ALL CONSTS IN ITS DIM TABLE ENTRY
			SYMPTR_.SYMPTR[CLINK]
		END
	END
END;
GLOBAL ROUTINE ALDIM1(DIMPTR)=
%(***************************************************************************
	ROUTINE TO GO THRU A DIMENSION TABLE ENTRY ALLOCATING CORE FOR ALL CONSTANTS
	USED IN THAT ENTRY. THIS ROUTINE IS CALLED:
		1. WHEN THE USER HAS SPECIFIED THE "DEBUG" SWITCH
			INDICATING THAT ALL DIMENSION TABLE INFORMATION
			SHOULD BE OUTPUT.
		2. WHEN THE USER HAS SPECIFIED THAT THIS PARTICULAR ARRAY
		   SHOULD BE "PROTECTED".
***************************************************************************)%
BEGIN
	EXTERNAL ALOCONST;	!ROUTINE TO SET FLAG IN CONST TABLE
				! ENTRY INDICATING THAT CORE SHOULD BE ALLOCATED
				! FOR THIS CONST
	MAP BASE DIMPTR;	!PTR TO THE DIMENSION TABLE ENTRY
	REGISTER DIMSUBENTRY DIMLSTPTR;	!PTR TO THE SUBENTRY FOR A GIVEN DIMENSION

	IF NOT .DIMPTR[ADJDIMFLG]	!IF THIS ARRAY HAS NO ADJUSTABLE DIMENSIONS
	THEN ALOCONST(.DIMPTR[ARAOFFSET]);	! THEN THE "OFFSET" WILL BE CONST - ALLOCATE CORE FOR IT


	DIMLSTPTR_DIMPTR[FIRSTDIM];	!PTR TO SUBENTRY FOR 1ST DIMENSION

	DECR CT FROM (.DIMPTR[DIMNUM] - 1) TO 0	!LOOK AT THE SUBENTRY FOR EACH DIMENSION
	DO
	BEGIN
		IF NOT .DIMLSTPTR[VARLBFLG]	!IF THE LOWER BOUND IS A CONST
		THEN ALOCONST(.DIMLSTPTR[DIMLB]);	! ALLOCATE CORE FOR IT
		IF NOT .DIMLSTPTR[VARUBFLG]	!IF THE UPPER BOUND IS A CONST
		THEN ALOCONST(.DIMLSTPTR[DIMUB]);
		IF NOT .DIMLSTPTR[VARFACTFLG]	!IF THE FACTOR FOR THIS DIMENSION IS A CONST
		THEN ALOCONST(.DIMLSTPTR[DIMFACTOR]);

		DIMLSTPTR_.DIMLSTPTR+DIMSUBSIZE
	END
END;
GLOBAL ROUTINE ALOCONST(CNODE)=
%(***************************************************************************
	ROUTINE TO SET A FLAG INDICATING THAT THIS CONSTANT SHOULD HAVE CORE
	ALLOCATED FOR IT.
	THIS SHOULD PROBABLY BE MADE A MACRO AT SOME POINT.
***************************************************************************)%
BEGIN
	MAP BASE CNODE;

	CNODE[CNTOBEALCFLG]_1;
	.CNODE
END;
GLOBAL ROUTINE NEWQTMP=
!++
! Create a new .Q variable entry
!--
BEGIN

%1274%	! Written by TFV on 20-Oct-81

	REGISTER PEXPRNODE QVAR;	! Pointer to entry
%4527%	REGISTER BASE QNAME;		! Name of .Qnnnn


	NAME<LEFT> = IDSIZ;		! Use a symbol table like entry
	QVAR = CORMAN();		! Get space for new .Q variable

	QVAR[OPRCLS] = DATAOPR;		! Data operator OPRCLS
	QVAR[OPERSP] = TEMPORARY;	! Specific operator is temporary
	QVAR[IDADDR] = .QLOC;		! Set address to offset in .Q space
%1552%	QVAR[IDPSECT] = QVAR[IDPSCHARS] = PSDATA; ! Temps live in the lowseg

%4527%	QNAME = SIXBIT'.Q0000' +	! Make the .Qnnnn name
		(.QCNT<9,3>)^18 +
		(.QCNT<6,3>)^12 +
		(.QCNT<3,3>)^6 +
		(.QCNT<0,3>);

%4527%	QVAR[IDSYMBOL] = CPYSYM( ONEWPTR(.QNAME) );

	QCNT = .QCNT + 1;	! Increment QCNT

	RETURN .QVAR;

END;	! NEWQTMP
GLOBAL ROUTINE NXTTMP(SIZE)=
BEGIN
%1274%	! Rewritten by TFV on  20-Oct-81	
	! Get or create the next .Qnnnn variable
	! They are kept as a linked list, the IDADDR field points to 
	! the offset into .Q space	

	REGISTER
		BASE	CURRQ,	! Pointer to the current .Q variable we created or reused
		NEXTQ;		! Pointer to the next .Q variable in the .Q list

	LABEL	FINDIT;		! Used when we are searching down the .Q list

	IF .LASTQ EQL 0
	THEN
	BEGIN	! This is the first .Q variable for this statement

		IF .QANCHOR EQL 0
		THEN
		BEGIN	! First ever - create it

			CURRQ = NEWQTMP();
			QANCHOR  = .CURRQ;	! First ever created

		END	! First ever - create it

		ELSE	CURRQ = .QANCHOR;	! Start at beginning of .Q list

	END	! This is the first .Q variable for this statement
	ELSE
FINDIT:
	BEGIN	! Search down .Q list to find a .Q variable at QLOC

		WHILE (CURRQ = .LASTQ[CLINK]) NEQ 0 DO
		BEGIN

			IF .CURRQ[IDADDR] EQL .QLOC THEN LEAVE FINDIT;	! One exists, we are done

			IF .CURRQ[IDADDR] GTR .QLOC
			THEN
			BEGIN	! There is none, create a new one and link it in

				NEXTQ = .CURRQ;		! Insert before CURRQ
				CURRQ = NEWQTMP();	! Make a new .Q variable
				LASTQ[CLINK] = .CURRQ;	! Last points to new .Q variable
				CURRQ[CLINK] = .NEXTQ;	! New points to next .Q variable

				LEAVE FINDIT;		! We create a new one, we are done

			END;	! There is none, create a new one and link it in

			LASTQ = .CURRQ;		! Look at next exntry in .Q list
		END;	! WHILE (CURRQ = .LASTQ[CLINK] NEQ 0 DO

		! We walked off the end of the list - create a new .Q and link it at the end

		CURRQ = NEWQTMP();	! Create it
		LASTQ[CLINK] = .CURRQ;	! Link it in

	END;	! FINDIT - Search down .Q list to find a .Q variable at QLOC

	QLOC = .QLOC + .SIZE;		! QLOC points after this entry

	IF .QLOC GTR .QMAX THEN QMAX = .QLOC;	! Update QMAX if it grew

	LASTQ = .CURRQ;		! LASTQ is now the one we just created or reused
	RETURN .LASTQ;		! Return the pointer to it

END;	! NXTTMP

END
ELUDOM