Trailing-Edge
-
PDP-10 Archives
-
bb-jr93i-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