Google
 

Trailing-Edge - PDP-10 Archives - bb-jr93g-bb - 7,6/ap018/relbuf.c18
There are 10 other files named relbuf.c18 in the archive. Click here to see a list.
 REP 24/1	;18C1
	GLOBAL BIND RELBUV = #11^24 + 0^18 + #4572; ! Version Date: 17-Aug-87
 WIT
	GLOBAL BIND RELBUV = #11^24 + 0^18 + #4577; ! Version Date: 11-Nov-87
 INS 270/1	;18C2
	4577	DCE	11-Nov-87
		Rewrite ZSAVEOUT.  There were many problems.  Buffer switching caused
		the count word to be incorrect.  A bare SAVE with labelled common 
		blocks present caused the compiler to die.  We could no longer put 
		out short variable names in a single word.  Old code took two passes 
		over the named COMMON block list - only one pass is necessary.  
		Simplify the algorithm to treat linked list and table cases together.

 REP 1/20	;18C3
	GLOBAL ROUTINE ZSAVEOUT=	! [1511] New [1566] Rewritten
	!++
	! Processing to output a SAVE  writable link overlay block.  Block  type
	! 1045 is put out.  It  is assumed that if  this routine is called  that
	! processing is necessary (the caller has determined this).
 WIT
	GLOBAL ROUTINE ZSAVEOUT=	! [4577] Rewritten again
	!++
	! Processing to output a SAVE  writable link overlay block.  Block  type
	! 1045 blocks are put out.  It  is assumed that if  this routine is called
	! that processing is necessary (the caller has determined this).
 REP 40/20	;18C4
			SAVLOC,		! SAVE local variables
			SAVNED;		! SAVE rel block is needed
 WIT
			SAVLOC;		! SAVE local variables
 REP 46/20	;18C5
			BASE OLDCOMPTR,	! Old pointer to common
	%4530%		NAM,		! Common block name
	%4530%		COUNT;		! Number of words in relblock
 WIT
			BASE SLENGTH,	! Length of COMMON block name (words)
			BASE SWORDS;	! Number of words for symbol [ + count word ]
 REP 60/20	;18C6
		DMPMAINRLBF();

		! If any named commons specified in a SAVE haven't been declared
		! in a COMMON statement in the program unit, then don't put them
		! out into the rel block.  The standard requires that to SAVE  a
		! named common, all units using said common must SAVE it, so  if
		! this unit doesn't use it, it will be ignored.

	%4530%	COUNT = 1;

		! Walk through the list of common blocks.  If we  remove
		! the common name, we must also decrement the count  put
		! out to the rel block before the MAINRLBF can be output
		! (in case we have more than 18 blocks to SAVE).

		OLDCOMPTR = PTRSAVCOMMON;	! Init to delete the first

		DECR CNT FROM .NUMSAVCOMMON TO 1
		DO
		BEGIN	! For each common name SAVE

			COMPTR = .OLDCOMPTR[CLINK];	! Pointer to look at
			COMSYM = .COMPTR[CW0L];	! common symbol table entry

	%4530%		IF NOT .SAVALL	! blank SAVE not specified
	%4530%		THEN IF NOT .COMSYM[IDATTRIBUT(COMBL)]
			THEN
			BEGIN	! Block not declared COMMON - delete it

				COMPTR  = .COMPTR[CLINK];
				OLDCOMPTR[CLINK] = .COMPTR;
				NUMSAVCOMMON = .NUMSAVCOMMON - 1;

			END	! Block not declared COMMON - delete it
			ELSE
			BEGIN	! Block declared COMMON

	%4530%			! Increment count by 1 (length) + length of name
	%4530%			COMSYM = .COMPTR[CW0L];
	%4530%			COUNT = .COUNT + 1 + .COMSYM[IDSYMLENGTH];

				OLDCOMPTR = .COMPTR;	! Save for next delete
				COMPTR = .COMPTR[CLINK]; ! Next common

			END;	! Block declared COMMON

		END;	! For each common name SAVE

		! If we don't have any common blocks left, and there were
		! not any local variables delclared in SAVE or blank common
		! blocks in the program, then return now and don't bother
		! outputting a rel block.

	%2022%	IF (.NUMSAVCOMMON EQL 0)		! No commns left
	%2075%	THEN IF NOT (.SAVLOC OR .SAVBLC)	! No locals or blk comm
	%2022%	THEN RETURN;				! SAVE not needed.

 WIT

		DMPMAINRLBF();
 REP 120/20	;18C7
		MAINRLBF[SVTYPE] = RWRITELINK;		! Block type

	%4530%	MAINRLBF[SVCOUNT] = .COUNT;	! Number of words in rel block

		IF .SAVBLC THEN		! Extra for blank common
		IF NOT .SAVALL		! Included in common walk
		THEN MAINRLBF[SVCOUNT] = .MAINRLBF[SVCOUNT] + 1;
 WIT
		MAINRLBF[SVTYPE] = RWRITELINK;		! Block type 1045
 REP 132/20	;18C8
		THEN	MAINRLBF[SVLOCAL] = 1;	! Yes, save it

 WIT
		THEN	MAINRLBF[SVLOCAL] = 1;	! Yes, save locals
 REP 138/20	;18C9
		THEN			! must SAVE it from the devil!!
 WIT
		AND NOT .SAVALL		! but not a bare SAVE statement.
		THEN			! Must SAVE it from the devil!!
 REP 144/20	;18C10
		! Ouput any COMMON blocks specified

		IF NOT .SAVALL
		THEN
		BEGIN	! Use SAVE linked list
		
			COMPTR = .PTRSAVCOMMON;	! Ptr to common

			DECR CNT FROM .NUMSAVCOMMON TO 1
			DO
			BEGIN	! For each COMMON to be SAVE-d

				COMSYM = .COMPTR[CW0L];  ! Common symbol table entry

				! If offset  > 20  then  dump buffer  and  start
				! refilling it again.

				BOFFSET = .BOFFSET + 1;
	%4530%			IF .BOFFSET GEQ RBLKSIZ - .COMSYM[IDSYMLENGTH] - 1
				THEN
				BEGIN
					DMPRLBLOCK(MAINRLBF,RBLKSIZ);
					BOFFSET = 0;
				END;
 WIT
		! Initialize for a walk through the labelled COMMON blocks

		COMPTR = IF .SAVALL
		THEN .FIRCOMBLK		! Through the entire COMMON block table.
		ELSE .PTRSAVCOMMON;	! Through the SAVEd linked list specified.

		! We now walk through the entire named COMMON table (if a bare
		! SAVE statement was used), or through the created linked list of
		! named COMMON blocks (if a bare SAVE statement was not seen).
		! Make sure in the latter case that the name appeared in a COMMON
		! statement!

		IF .NUMSAVCOMMON NEQ 0	! Any at all?
		THEN
		WHILE .COMPTR NEQ 0 DO
		BEGIN	! The large walk...

			! Get COMMON block name length

			IF .SAVALL
			THEN SLENGTH = .COMPTR[COMNLEN]
			ELSE
			BEGIN
				COMSYM = .COMPTR[CW0L];
				SLENGTH = .COMSYM[IDSYMLENGTH]
			END;

			! Was this COMMON block actually declared (as opposed
			! to there just being a SAVE /X/ statement)?
			! If any named commons specified in a SAVE haven't been declared
			! in a COMMON statement in the program unit, then don't put them
			! out into the rel block.  The standard requires that to SAVE  a
			! named common, all units using said common must SAVE it, so  if
			! this unit doesn't use it, it will be ignored.

			IF ( IF .SAVALL THEN TRUE
				ELSE .COMSYM[IDATTRIBUT(COMBL)] )
			THEN ! Process this COMMON block name
			BEGIN

				BOFFSET = .BOFFSET + 1;

				! Do we need to flush the buffer yet?

				IF .SLENGTH GTR 1
				THEN SWORDS = .SLENGTH + 1 ! Count word in rel block.
				ELSE SWORDS = .SLENGTH;	! No count word.

				IF (.BOFFSET + .SWORDS) GTR RBLKSIZ
				THEN ! Flush necessary
				BEGIN
					MAINRLBF[SVCOUNT] = .BOFFSET - 1;
					DMPRLBLOCK(MAINRLBF,.BOFFSET);
					BOFFSET = 2; ! For next time
				END;

				! The COMMON block name will now fit in the buffer.
				! Do we need to put out a long or short name?

				IF .SWORDS EQL 1
				THEN BOFFSET = .BOFFSET - 1	! No count word needed.
				ELSE MAINRLBF[.BOFFSET,FULL] = .SWORDS; ! Put out count.
 REP 171/20	;18C11
	%4530%			MAINRLBF[.BOFFSET,FULL] = .COMSYM[IDSYMLENGTH] + 1;
	%4530%			INCR I FROM 0 TO .COMSYM[IDSYMLENGTH] - 1
	%4530%			DO
	%4530%			BEGIN
	%4530%				BOFFSET = .BOFFSET + 1;
	%4530%				MAINRLBF[.BOFFSET,FULL] = @(.COMSYM[IDSYMPOINTER] + .I);
	%4530%			END;
				COMPTR = .COMPTR[CLINK]; ! New pointer for next common

			END;	! For each COMMON to be SAVE-d

		END	! Use SAVE linked list
		ELSE
		BEGIN	! Save all COMMON-s

			! This is a  walk through  all common  blocks to  output
			! their names into the rel buffer.

			BOFFSET = 1;
			COMPTR = .FIRCOMBLK;	! First common block

			DECR CNT FROM .NUMSAVCOMMON TO 1
			DO
			BEGIN	! For all COMMON blocks

				COMSYM = .COMPTR[CW0L];  ! Common symbol table entry

				! If offset  > 20  then  dump buffer  and  start
				! refilling it again.

				BOFFSET = .BOFFSET + 1;
	%4530%			IF .BOFFSET GEQ RBLKSIZ - .COMSYM[IDSYMLENGTH] - 1
				THEN
				BEGIN
					DMPRLBLOCK(MAINRLBF,RBLKSIZ);
					BOFFSET = 0;
				END;

				! Put sixbit symbol into rel file.

	%4530%			MAINRLBF[.BOFFSET,FULL] = .COMSYM[IDSYMLENGTH] + 1;
	%4530%			INCR I FROM 0 TO .COMSYM[IDSYMLENGTH] - 1
	%4530%			DO
	%4530%			BEGIN
	%4530%				BOFFSET = .BOFFSET + 1;
	%4530%				MAINRLBF[.BOFFSET,FULL] = @(.COMSYM[IDSYMPOINTER] + .I);
	%4530%			END;
				COMPTR = .COMPTR[NEXCOMBLK];	! New pointer

			END;	! For all COMMON blocks

		END;	! Save all Commons


		! Put out remaining rel block
		DMPRLBLOCK(MAINRLBF,.BOFFSET+1);

 WIT
				INCR I FROM 0 TO .SLENGTH - 1
				DO
				BEGIN
					BOFFSET = .BOFFSET + 1;

					! Symbol name location depends upon
					! which table we are walking.

					MAINRLBF[.BOFFSET,FULL] = IF .SAVALL
					THEN @(.COMPTR[COMNPTR] + .I)
					ELSE @(.COMSYM[IDSYMPOINTER] + .I);

				END	! Of COMMON block name

			END;	! Of this COMMON block name 

			! Done with this named COMMON block - on to the next

			COMPTR = IF .SAVALL
			THEN .COMPTR[NEXCOMBLK]
			ELSE .COMPTR[CLINK];	! Next COMMON block

		END;	! Of COMMON block loop

		! Put out remaining rel block if necessary

		IF .BOFFSET GTR 1 OR .SAVLOC	! Need to flush rest of buffer
		THEN
		BEGIN
			MAINRLBF[SVCOUNT] = .BOFFSET;
			DMPRLBLOCK(MAINRLBF,.BOFFSET+1);
		END;
 SUM 22210