Google
 

Trailing-Edge - PDP-10 Archives - BB-4172H-BM - language-sources/h2addr.bli
There are 18 other files named h2addr.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,1973,1974,1977,1978 DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. 01754
!FILENAME:	H2ADDR.BLI
!DATE:		30 MAY 73	MGM/FLD

%3.2%	GLOBAL BIND H2ADV=1;	!MODULE VERSION NUMBER
!			GENERAL DOCUMENTATION FOR ADDRESS.BLI
!	
!		THE PRIMARY PURPOSE OF THIS MODULE IS THE COMPUTATION OF THE ADDRESS
!	PORTION OF AN INSTRUCTION.  THERE ARE ALSO SEVERAL PREDICATES RELATING TO
!	THE KIND OF ADDRESSABILITY PRESENT IN A LEXEME.   THE ROUTINES WHICH
!	CALCULATE ADDRESSES RETURN THEIR VALUES IN CODE-3 FORMAT AS PICTURED BELOW:
!	
!		CODE-3 FORMAT
!	
!
!............................................................................................................
!\ !              !\  \  \ !           !  !           !                                                     !
! \!              ! \  \  \!           !  !           !                                                     !
!  !              !  \  \  !           !  !           !                                                     !
!\ !    RELOCF    !\  \  \ !   RELRF   ! I!     X     !                          Y                          !
! \!              ! \  \  \!           !  !           !                                                     !
!  !              !  \  \  !           !  !           !                                                     !
!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!
!                30                24                18                12                 6
!	
!	
!		FIELDS:
!	
!		RELOCF:	5-BIT CODE FOR THE LOADER INTERFACE
!	
!		RELRF:	IF NON-ZERO, THIS IS THE ADDRESS OF A REGISTER WHOSE USE
!			IS TO BE DECREASED WHEN THE INSTRUCTION IS GENERATED
!			WHICH USES THIS ADDRESS.
!	
!		I:	THE INDIRECT BIT
!		X:	THE INDEX REGISTER
!		Y:	"ADDRESS" SUBJECT TO RELOCATION BY LOADER IF RELOCF NEQ 0
!		THE FOLLOWING TABLE EXPRESSES THE RELATIONSHIP BETWEEN SYMBOL TABLE
!	TYPES, THEIR RELOCATION TYPES, AND WHETHER THESE TYPES CAN VALIDLY FILTER
!	DOWN TO THE CODE GENERATION ROUTINES.
!	
!	
!		TYPE		TYPE #	VALID	RELOCTYPE
!	
!		DELMT		#00	NO	N.A.
!		UNDEDT		#01	NO	N.A.
!		GLOBALT		#02	YES	GLORELOC
!		OWNT		#03	YES	OWNRELOC
!		EXTRNT		#04	YES	EXTRELOC
!		LOCALT		#05	YES	LOCRELOC
!		BINDT		#06	YES	LOCRELOC
!		FORMALT		#07	YES	NORELOC
!		ROUTINET	#10	YES	CTRELOC
!		EXPRT		#11	YES	EXPRELOC
!		GROUTINET	#12	YES	CTRELOC
!		FUNCT		#13	YES	CTRELOC
!		STFORMT		#14	YES	NORELOC
!		PLITT		#15	YES	PLRELOC
!		LABELT		#16	NO	N.A.
!		FORWT		#17	YES	CTRELOC
!		REGT		#20	NO	N.A.
!		GABSOLUTET	#21	NO	N.A.
!		GPLITT		#22	YES	PLRELOC
!		STRT		#30	YES	CTRELOC
!		MACROT		#31	NO	N.A.
!		LEXEMT		#32	NO	N.A.
!		MACHOPT		#40	NO	N.A.
!		SPLFT		#41	NO	N.A.
!		ABSOLUTET	#42	NO	N.A.
!		SPUNOPT		#43	NO	N.A.
!	
!	




FORWARD COPTR,FSA;
FORWARD GLTM,GMA,GPA,MADRIR;
FORWARD READY;
GLOBAL ROUTINE GPA(X)=



!  (GENERATE POINTER ADDRESS)
  %X IS A LEXEME OF THE FORM .(N+@R)<P,S> WHERE EITHER N XOR @R
   MAY BE ABSENT AND P,S HAVE NO SPECIAL VALUES AND MAY EVEN BE
   UNSET. GPA GENERATES CODE TO GENERATE THE POINTER (N+@R)<P,S>
   ASSUMING THAT GENERATION OF A LDB FOLLOWS IMMEDIATELY SO THAT
   THE POINTER MAY BE INDEXED.  THE VALUE OF GPA IS THE ADDRESS
   OF THE POINTER IN CODE-3 FORMAT%



  BEGIN LOCAL Y;
    IF .X<POSNSIZEF> EQL 0 THEN RETURN GMA(.X AND NOT COPM);
    Y_GMA(.X);
%2.22%	!WE MUST TURN OFF THE BIT IN .Y WHICH IS NOT USED
%2.22%	!IN THE STD 10 BYTE POINTER SINCE COPTR WILL LEAVE IT ON.
%2.22%	!THIS IS BIT 40,,0.
    RMA(.Y<RELRF>,0,COPTR(.X<POSNF>,.X<SIZEF>,.Y AND NOT(#40^18)))
  END;
GLOBAL ROUTINE GMA(X)=


!  (GENERATE MACHINE ADDRESS)
  %X IS A LEXEME.  IT MAY TAKE THE SPECIAL FORM @R, IN WHICH CASE
   GMA IS LIKE REGAR.  OTHERWISE X TAKES ONE OF TWO FORMS: EITHER
   1) .(N+@R)<P,S>; OR 2) (N+@R)<P,S>.  IN BOTH CASES EITHER N XOR
   @R MAY BE ABSENT.  IN NEITHER CASE IS THE NEG OR NOT BIT SET.
   IN EITHER CASE GMA PRODUCES FOR ITS VALUE AN ADDRESS IN CODE-3
   FORMAT, POSSIBLY GENERATING CODE FIRST.
      IN CASE (1):  GMA ASSUMES THAT THE LOAD INSTRUCTION WILL BE
   CODED PROMPTLY AFTER RETURN FROM GMA, SO THAT IT MAY RETURN AN
   INDEXED ADDRESS.  IT FURTHER ASSUMES THAT THE P,S FIELDS ARE TO
   BE HANDLED OUTSIDE GMA SO THAT IT NEED ONLY RETURN THE ADDRESS
   (N+@R) WITH 18 BIT ADDITION.
      IN CASE (2):  GMA PRODUCES THE ADDRESS OF THE POINTER
   (N+@R)<P,S> WHICH IT FIRST GENERATES; HOWEVER THE POINTER IS
   UNINDEXED SO THAT ACCESS TO THE BYTE MAY BE POSTPONED.%



  BEGIN
    X<NGNTF>_0;
    IF PTRTYPP(.X) THEN RETURN MCOPTRFRPTRTYP(.X);
    IF .X<LSSTEF> EQL ZERO THEN X<LSSTEF>_0;
    !! HERE WE SEE IF X IS A REGISTER LEXEME SO GMA CAN SIMPLY CALL REGAR

    IF REGP(.X) THEN IF
      NOT(.RT[.X<RTEF>]<RSF> AND .X<DTF>) THEN
	RETURN REGAR(.X);

    BEGIN

      ROUTINE MOVEDEC(R)=
	! MOVES DECLARED OR MULTIPLY USEFUL REGISTER TO A TEMPORARY

	BEGIN REGISTER D;
	  D_.R;
	  R_IF .LOADECREG GEQ 0 THEN .LOADECREG ELSE ACQUIRE(-1,1);
	  IF .R NEQ .D THEN CODE(MOVE,.R,REGAR(LEXRA(.D)),1);
	  .R
	END;
      ROUTINE GETREG=
		IF .LOADECREG GEQ 0 THEN .LOADECREG
		   ELSE ACQUIRE(-1,1);

      LOCAL REG,TEMP,ADDRESS,TYPE,FLEVEL;
      REGISTER
	NAME,	! .X<RTEF>
	STINDEX,	! .X<STEF>
	SWITCH;	! 0 --> STACK VAR./SAME FLEVEL, 1 --> STACK VAR./DIFF. FLEVEL,
		! 2 --> NOT STACK VAR.

      IF (NAME_.X<RTEF>) NEQ 0 THEN
	BEGIN
	  IF .X<DTF> AND .RT[.NAME]<RSF> THEN
	    BEGIN
		! RTEF OF X POINTS TO TEMPORARY MEMORY. IF X IS A REGISTER-
		! TYPE LEXEME THEN WE GENERATE THE ADDRESS OF THE LOCAL.
		! OTHERWISE THE RTEF IS GOING TO BE USED IN AN INDEXING
		! OPERATION AND SO IT MUST BE RELOADED INTO A REGISTER.

	      IF REGP(.X) THEN
		BEGIN
		  X_LEXNPSD(.RT[.NAME]<LSSTEF>,0,36,1);
		  DUM(.NAME);
		  RETURN GMA(.X)
		END;
	      REG_RELOADTEMP(0,.NAME);
	      TEMP_1
	    END
	  ELSE
	    BEGIN
	      REG_.RT[.NAME]<ARTEF>;
	      TEMP_TVRP(LEXRN(.NAME))
	    END
	END
      ELSE REG_0;
      STINDEX_.X<STEF>;
      ADDRESS_
	IF .X<LSF> THEN
	  BEGIN
	    CHECKEXTER(.STINDEX);
	    TYPE_.ST[.STINDEX,0]<TYPEF>;
	    IF (1^.TYPE AND VALIDTYPE) EQL 0 THEN PUNT(ERINVLEX);
	    FSA(.STINDEX)
	  END
	ELSE
	  BEGIN
	    TYPE_0;
	    LITV(.X<LSSTEF>) AND RIGHTM
	  END;
      SWITCH_
	IF STACKVAR^(-.TYPE) THEN
	  (FLEVEL_.ST[.STINDEX,0]<FLF>) NEQ .FUNCTIONLEVEL
	ELSE 2;
      IF .X<COPF> THEN
	!!! NOW WE HANDLE CASE (1)

	RETURN(
	  IF .REG EQL 0 THEN
	    CASE .SWITCH OF SET
	      .FREG^18 OR .ADDRESS;
	      BEGIN
		REG_GETREG();
		CODE(MOVE,.REG,.FREG^18 OR (.FLEVEL+1),1);
		RMA(.REG,.REG,.ADDRESS)
	      END;
	      IF .ADDRESS LSS 16 AND NOT .X<LSF> THEN
		RMA(.ADDRESS,0,.ADDRESS)
	      ELSE .ADDRESS
	    TES ELSE
	  IF .SWITCH NEQ 2 THEN
	    BEGIN
	      IF NOT .TEMP AND (.REG NEQ .LOADECREG) THEN
		REG_MOVEDEC(.REG);
	      CODE(ADD,.REG,
		   IF .SWITCH THEN .FREG^18 OR (.FLEVEL+1) ELSE .FREG,
		   1);
	      RMA(.REG,.REG,.ADDRESS)
	    END
	  ELSE RMA(.REG,.REG,.ADDRESS));
      IF .X<POSNSIZEF> EQL 0 THEN
	!!! NOW WE HANDEL CASE(2) WHERE P AND S ARE ZERO

	RETURN(
	  IF .REG EQL 0 AND .X<RTEF> EQL 0 THEN
	    IF .X<LSF> THEN
	      IF .SWITCH LEQ 1 THEN
		BEGIN
		  REG_GETREG();
		  IF .SWITCH EQL 0 THEN
		    CODE(HRRZI,.REG,.FREG^18 OR .ADDRESS,1)
		  ELSE
		    BEGIN
		      CODE(MOVE,.REG,.FREG^18 OR (.FLEVEL+1),1);
		      CODE(HRRZI,.REG,.REG^18 OR .ADDRESS,1)
		    END;
		  RMA(.REG,0,.REG)
		END
	      ELSE COPTR(0,0,.ADDRESS)
	    ELSE LITA(.X)
	  ELSE
	    BEGIN
	      IF NOT .TEMP THEN IF .REG NEQ .LOADECREG THEN
		IF NOT (.X<LSF> AND (.SWITCH EQL 0)) THEN
		REG_MOVEDEC(.REG);
	      IF .X<LSF> THEN
		CASE .SWITCH OF SET
		  BEGIN
		    TEMP_ACQUIRE(-1,1);
		    CODE(HRRZI,.TEMP,.FREG^18 OR .ADDRESS,1);
		    CODE(HRLI,.TEMP,36^6,1);
		    CODE(ADD,.TEMP,RMA(.REG,0,.REG),1);
		    REG_.TEMP
		  END;
		  BEGIN
		    CODE(ADD,.REG,.FREG^18 OR (.FLEVEL+1),1);
		    CODE(ADD,.REG,COPTR(0,36,.ADDRESS),1)
		  END;
		  CODE(ADD,.REG,COPTR(0,36,.ADDRESS),1)
		TES
	      ELSE FALR(.REG,.X);
	      RMA(.REG,0,.REG)
	    END);
      !!! CASE(2) NOW WITH P+S NEQ 0

      ADDRESS_GMA(.X OR DOTM);
      IF .ADDRESS<INDXF> EQL 0 THEN
	RETURN COPTR(.X<POSNF>,.X<SIZEF>,.ADDRESS);
      IF USABLEINDEXREG(.ADDRESS) AND (.LOADECREG LSS 0) THEN
	REG_.ADDRESS<INDXF>
      ELSE CODE(HRRZI,REG_GETREG(),.ADDRESS,1);
      CODE(HRLI,.REG,.X<POSNF>^12 OR .X<SIZEF>^6,1);
      RMA(.REG,0,.REG)
    END
  END;
GLOBAL ROUTINE FSA(STINDEX)=
!  (FIND SYMBOL ADDRESS)
!  STINDEX IS THE ST INDEX OF A SYMBOL;  FSA PRODUCES THE ADDRESS
!  OF THE SYMBOL IN CODE-3 FORMAT.  RELOCATION COMES FROM THE SIX WORD
!  (SIX SIX-BIT BYTES PER WORD) VECTOR RELOCBITS.
  BEGIN LOCAL SYMTYPE,ADDRESS;
    STRUCTURE RELOCVEC[I]=(.RELOCVEC +.I/6)<.I MOD 6 *6,6>;
    BIND RELOCVEC RELOCBITS=PLIT(
	GLORELOC^(GLOBALT MOD 6 *6) OR
	OWNRELOC^(OWNT MOD 6 *6) OR
	EXTRELOC^(EXTRNT MOD 6 *6) OR
	LOCRELOC^(LOCALT MOD 6 *6) ,
	LOCRELOC^(BINDT MOD 6 *6) OR
	NORELOC^(FORMALT MOD 6 *6) OR
	CTRELOC^(ROUTINET MOD 6 *6) OR
	EXPRELOC^(EXPRT MOD 6 *6) OR
	CTRELOC^(GROUTINET MOD 6 *6) OR
	CTRELOC^(FUNCT MOD 6 *6) ,
	NORELOC^(STFORMT MOD 6 *6) OR
	PLRELOC^(PLITT MOD 6 *6) OR
	CTRELOC^(FORWT MOD 6 *6) ,
	PLRELOC^(GPLITT MOD 6*6) ,
	CTRELOC^(STRT MOD 6 *6) ,
	0 );
%2.12%	CHECKEXTER(.STINDEX);	!IF UNDECLARED, WARN & DECLARE EXTERNAL
    SYMTYPE_.ST[.STINDEX,0]<TYPEF>;
    ADDRESS<RELOCF>_.RELOCBITS[.SYMTYPE];
    ADDRESS_
      IF (1^RTNT OR 1^GROUTINET OR 1^FUNCT OR 1^STRT OR 1^FORWT)^(-.SYMTYPE) THEN
	.ST[.STINDEX,1]<STEF> ELSE
      IF (1^EXTRNT OR 1^EXPRT)^(-.SYMTYPE) THEN .STINDEX
      ELSE .ST[.STINDEX,1]<ADDRESSF>;
    ADDRESS<RELOCF>_.(RELOCBITS+.SYMTYPE/6)<.SYMTYPE MOD 6*6,6>;
    .ADDRESS
  END;
!	POINTERS WHICH NEED RELOCATION BY THE LOADER ARE PUT IN A VECTOR
!	OF TWO-WORD CELLS CALLED PT.  A CELL LOOKS LIKE:
!
!............................................................................................................
!\ !              !\  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \ !
! \!              ! \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \!
!  !              !  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  !
!\ !    RELOCF    !\  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \ !
! \!              ! \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \!
!  !              !  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  \  !
!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!
!                 !                 !\ !  !           !                                                     !
!                 !                 ! \!  !           !                                                     !
!                 !                 !  !  !           !                                                     !
!        P        !        S        !\ ! I!     X     !                          Y                          !
!                 !                 ! \!  !           !                                                     !
!                 !                 !  !  !           !                                                     !
!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!..!
!                30                24                18                12                 6
GLOBAL ROUTINE COPTR(P,S,Y)=


!  (CONSTANT POINTER)
!  A CONSTANT POINTER IS AN EXPRESSION OF THE FORM N<P,S>
!  WHERE P,S ARE BOTH COMPILE-TIME CONSTANTS.   Y MUST BE
!  AN ADDRESS IN CODE-3 FORMAT AND P,S MUST BE INTEGERS IN
!  THE RANGE 0 TO 36.   COPTR GENERATES THE POINTER Y<P,S>
!  ENTERING IT IN THE LT IF Y REQUIRES NO FURTHER
!  RELOCATING AND IN THE PT OTHERWISE.   IN EITHER CASE
!   HASHING ASSURES NO DUPLICATION.   THE VALUE OF COPTR
!  IS THE ADDRESS OF THE POINTER IN CODE-3 FORMAT.



  BEGIN
    LOCAL
	H,	! INDEX OF LT OR PT ENTRY/ RETURN VALUE
	P1,P2;	! COPIES OF TWO-WORD PT ENTRY

    REGISTER
	POINTER,! 36-BIT POINTER
	YRELOC;	! .Y<RELOCF>

%2.22%    POINTER_(.P AND #77)^30 OR (.S AND #77)^24 OR (.Y AND NOTPSMASK);
    IF (YRELOC_.Y<RELOCF>) EQL NORELOC THEN
      BEGIN
	H_RMA(.Y<RELRF>,0,LTINSERT(.POINTER));
	H<RELOCF>_LTRELOC;
	RETURN .H
      END;
    H_((.P XOR .S XOR .YRELOC)*.Y<IXYF>) AND PTMASK;
    H_
      DECR I FROM PTMASK TO 0 DO
		BEGIN
                    IF (P1_.PT[.H,0]) EQL 0 AND
                        (P2_.PT[.H,1]) EQL 0 THEN
                      BEGIN
                        PT[.H,0]<RELOCF>_.YRELOC;
                        PT[.H,1]_.POINTER;
                        EXITLOOP .H
                      END;
                    IF .P1<RELOCF> EQL .YRELOC THEN
			IF .P2 EQL .POINTER THEN EXITLOOP .H;
                    H_(.H+PRIME) AND PTMASK
		END;
    IF .H LSS 0 THEN RETURN(ERROR(.NSYM,#775));
    H<RELOCF>_PTRELOC;
    H<RELRF>_.Y<RELRF>;
    .H
  END;
GLOBAL ROUTINE READY(X)=
  %1 IF THE LEXEME X REPRESENTS AN EXPRESSION WHICH CAN BE ACCESSED
   BY MEANS OF THE ADDRESS FIELD OF AN ORDINARY INSTRUCTION THUS
   AVOIDING LOADING THE VALUE INTO A TEMPORARY REGISTER. 0 OTHERWISE%
  BEGIN
    IF .X<NEGF> THEN RETURN 0;
    IF .X<NOTF> THEN RETURN 0;
    IF NOT .X<COPF> THEN RETURN 1;
    IF .X<POSNSIZEF> EQL 36 THEN RETURN 1;
    IF .X<POSNSIZEF> EQL 0 THEN IF .X<RTEF> EQL 0 THEN RETURN 1;
    0
  END;




GLOBAL ROUTINE GLTM(X)=
!  (GENERATE LOAD TEMPORARY MEMORY)
!  X MUST BE A LEXEME SATISFYING TVMP.   GLTM GENERATES
!  CODE TO EVALUATE A UNARY - OR NOT THUS REDUCING THE
!  LEXEME TO A STRAIGHT @R.
  BEGIN
    IF .X<NEGF> THEN CODE(MOVNS,0,GMA(X_GABS(.X)),0) ELSE
    IF .X<NOTF> THEN CODE(SETCMM,0,GMA(X_GYES(.X)),0);
    .X
  END;
GLOBAL ROUTINE MADRIR(R,L)=
  ! (MACHINE-ADDRESS-RELEASE-INDEX-REGISTER)

  BEGIN
    R_REGAR(.R);
    R<INDXF>_.R;
    R<RIGHTF>_.L;
    .R
  END;




GLOBAL ROUTINE MEMORYA(Y)=
  ! (MEMORY-ADDRESS)

  IF READY(.Y) THEN GMA(.Y)
  ELSE REGAR(GLTR(.Y));



GLOBAL ROUTINE USABLEINDEXREG(X)=
  ! (USEABLE-INDEX-REGISTER) X IS IN CODE-3 FORMAT

  IF (.X AND NOT(INDXM OR RELRM)) EQL 0 THEN
    IF .X<INDXF> EQL .X<RELRF> THEN
      TVRP(LEXRA(.X<INDXF>))
    ELSE 0
  ELSE 0;



GLOBAL ROUTINE VALPTRTYP(X)=

  ! RETURNS THE 36-BIT POINTER REPRESENTED BY THE SYMBOL WHOSE ST-INDEX
  ! IS X.  X IS ALWAYS A PTRT

  IF NORELOCPTRTYPP(.X)
	THEN GETLITVAL(.ST[.X,1]<16,14>)
	ELSE .PT[.ST[.X,1]<16,14>,1];


GLOBAL ROUTINE PTRTYPP(X)=

  ! PREDICATE INDICATING THAT THE LEXEME X IS A PTRT

  IF .X<LSF> THEN .ST[.X<STEF>,0]<TYPEF> EQL PTRT;
GLOBAL ROUTINE MPTRTYP(L,X)=

  ! MAKES A PTRT ST-ENTRY ON GENSYMS WITH LEFTHALF FROM L AND RIGHT
  ! FROM LSSTEF OF X

  BEGIN LOCAL IXYPART,PTLTINDEX,STINDEX;
    IXYPART_
	IF .X<LSF> THEN GMA((.X AND LSSTEM) OR DOTM)
	ELSE LITV(.X AND LSSTEM) AND RIGHTM;
%2.26%    IXYPART_.IXYPART OR (.L^18 AND #77^18);
    PTLTINDEX_COPTR(.L<12,6>,.L<6,6>,.IXYPART) AND RIGHTM;
    STINDEX_GETSPACE(1);
    ST[.STINDEX,0]<TYPEF>_PTRT;
    ST[.STINDEX,0]<BLF>_.BLOCKLEVEL;
    ST[.STINDEX,0]<LINKF>_.GENSYMS;
    ST[.STINDEX,1]<RELOCF>_.IXYPART<RELOCF>;
    ST[.STINDEX,1]<LSSTEF>_.X<LSSTEF>;
    ST[.STINDEX,1]<16,14>_.PTLTINDEX;
    GENSYMS_.STINDEX;
    .STINDEX OR (LSM OR #7777^21)
  END;


GLOBAL ROUTINE MADDRFRPTRTYP(X)=

  ! MAKES UP AN ADDRESS IN CODE-3 FORMAT FROM A PTRT SYMBOL X

  BEGIN LOCAL ADDRESS;
    ADDRESS_VALPTRTYP(.X<STEF>) AND (1^22-1);
    ADDRESS<RELOCF>_.ST[.X<STEF>,1]<RELOCF>;
    .ADDRESS
  END;


GLOBAL ROUTINE MCOPTRFRPTRTYP(X)=

  ! MAKES UP COPTR-TYPE CODE-3 ADDRESS FROM A PTRT SYMBOL X

  BEGIN LOCAL ADDRESS;
    ADDRESS_.ST[.X<STEF>,1]<16,14>;
    ADDRESS<RELOCF>_
      IF .ST[.X<STEF>,1]<RELOCF> EQL NORELOC THEN LTRELOC
      ELSE PTRELOC;
    .ADDRESS
  END;



GLOBAL ROUTINE MLEXFRPTRTYP(X)=

	!MAKES UP A LEXEME FROM THE PTRT SYMBOL X

	BEGIN	LOCAL PTR;

	PTR_ VALPTRTYP(.X<STEF>);
	LEXNPSD(  .ST[.X<STEF>,1]<LSSTEF> OR
		  (IF .PTR<18,4> NEQ 0 THEN LEXRA(.PTR<18,4>)),
		  .PTR<30,6>, .PTR<24,6>,0)

	END;



! END OF H2ADDR.BLI