!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) 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) 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 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,0,COPTR(.X,.X,.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); OR 2) (N+@R). 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) WHICH IT FIRST GENERATES; HOWEVER THE POINTER IS UNINDEXED SO THAT ACCESS TO THE BYTE MAY BE POSTPONED.% BEGIN X_0; IF PTRTYPP(.X) THEN RETURN MCOPTRFRPTRTYP(.X); IF .X EQL ZERO THEN X_0; !! HERE WE SEE IF X IS A REGISTER LEXEME SO GMA CAN SIMPLY CALL REGAR IF REGP(.X) THEN IF NOT(.RT[.X] AND .X) 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 STINDEX, ! .X SWITCH; ! 0 --> STACK VAR./SAME FLEVEL, 1 --> STACK VAR./DIFF. FLEVEL, ! 2 --> NOT STACK VAR. IF (NAME_.X) NEQ 0 THEN BEGIN IF .X AND .RT[.NAME] 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],0,36,1); DUM(.NAME); RETURN GMA(.X) END; REG_RELOADTEMP(0,.NAME); TEMP_1 END ELSE BEGIN REG_.RT[.NAME]; TEMP_TVRP(LEXRN(.NAME)) END END ELSE REG_0; STINDEX_.X; ADDRESS_ IF .X THEN BEGIN CHECKEXTER(.STINDEX); TYPE_.ST[.STINDEX,0]; IF (1^.TYPE AND VALIDTYPE) EQL 0 THEN PUNT(ERINVLEX); FSA(.STINDEX) END ELSE BEGIN TYPE_0; LITV(.X) AND RIGHTM END; SWITCH_ IF STACKVAR^(-.TYPE) THEN (FLEVEL_.ST[.STINDEX,0]) NEQ .FUNCTIONLEVEL ELSE 2; IF .X 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 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 EQL 0 THEN !!! NOW WE HANDEL CASE(2) WHERE P AND S ARE ZERO RETURN( IF .REG EQL 0 AND .X EQL 0 THEN IF .X 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 AND (.SWITCH EQL 0)) THEN REG_MOVEDEC(.REG); IF .X 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 EQL 0 THEN RETURN COPTR(.X,.X,.ADDRESS); IF USABLEINDEXREG(.ADDRESS) AND (.LOADECREG LSS 0) THEN REG_.ADDRESS ELSE CODE(HRRZI,REG_GETREG(),.ADDRESS,1); CODE(HRLI,.REG,.X^12 OR .X^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]; ADDRESS_.RELOCBITS[.SYMTYPE]; ADDRESS_ IF (1^RTNT OR 1^GROUTINET OR 1^FUNCT OR 1^STRT OR 1^FORWT)^(-.SYMTYPE) THEN .ST[.STINDEX,1] ELSE IF (1^EXTRNT OR 1^EXPRT)^(-.SYMTYPE) THEN .STINDEX ELSE .ST[.STINDEX,1]; ADDRESS_.(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 ! 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 ! 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 %2.22% POINTER_(.P AND #77)^30 OR (.S AND #77)^24 OR (.Y AND NOTPSMASK); IF (YRELOC_.Y) EQL NORELOC THEN BEGIN H_RMA(.Y,0,LTINSERT(.POINTER)); H_LTRELOC; RETURN .H END; H_((.P XOR .S XOR .YRELOC)*.Y) 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]_.YRELOC; PT[.H,1]_.POINTER; EXITLOOP .H END; IF .P1 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_PTRELOC; H_.Y; .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 THEN RETURN 0; IF .X THEN RETURN 0; IF NOT .X THEN RETURN 1; IF .X EQL 36 THEN RETURN 1; IF .X EQL 0 THEN IF .X 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 THEN CODE(MOVNS,0,GMA(X_GABS(.X)),0) ELSE IF .X 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_.R; R_.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 EQL .X THEN TVRP(LEXRA(.X)) 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 THEN .ST[.X,0] 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 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]_PTRT; ST[.STINDEX,0]_.BLOCKLEVEL; ST[.STINDEX,0]_.GENSYMS; ST[.STINDEX,1]_.IXYPART; ST[.STINDEX,1]_.X; 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) AND (1^22-1); ADDRESS_.ST[.X,1]; .ADDRESS END; GLOBAL ROUTINE MCOPTRFRPTRTYP(X)= ! MAKES UP COPTR-TYPE CODE-3 ADDRESS FROM A PTRT SYMBOL X BEGIN LOCAL ADDRESS; ADDRESS_.ST[.X,1]<16,14>; ADDRESS_ IF .ST[.X,1] 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); LEXNPSD( .ST[.X,1] OR (IF .PTR<18,4> NEQ 0 THEN LEXRA(.PTR<18,4>)), .PTR<30,6>, .PTR<24,6>,0) END; ! END OF H2ADDR.BLI