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