! NOTE NEW VERSION OF THIS GLOBAL ARRY ! %CONSTSTRING(10)%ARRAY LT(0:7)=" !???! "," IMP "," FORTRAN ", " IMPS "," ASMBLR "," ALGOL(E) ", " OPTCODE "," PASCAL " !* ! LAYOUT OF DIAGNOSIC TABLES !****** ** ********* ****** ! THE BOUND FIELD OF PLT DESCRIPTOR STORED AT (LNB+3 & LNB+4) IF ! USED TO CONTAIN A DISPLACEMENT RELATIVE TO THE START OF SST OF THE ! DIAGNOSTIC TABLES FOR THE BLOCK OR ROUTINE BEING EXECUTED. ! A ZERO BOUND MEANS NO DIAGNOSTIC REQUESTED.(NB THIS MAY MEAN A DUMMY ! FIRST WORD IN THE SST). ! THE ABSOLUTE ADDRESS OF THE SST FOR THE CURRENT CODE SEGMENT WILL ! ALWAYS BE FOUND IN THE STANDARD 10 WORDS OF THE GLA/PLT ! FORM OF THE TABLES:- ! WORD 0 = LINE OF RT IN SOURCE PROG <<16 ! LINE NO POSN(FROM LNB) ! WORD 1 = (12 LANG DEPENDENT BITS)<<20 ! ENVIRONMENT ! WORD 2 = DISPLAY POSN (FROM LNB)<<16 ! RT TYPE INFO ! WORD 3 = ZERO FOR BLKS OR STRING(<=11BYTES) BEING THE ! RT NAME. THIS WILL TAKE WORDS 4 AND 5 IF NEEDED ! WORD 6 = LANGUAGE DEPENDENT INFO . IMP ON CONDITIONS ETC ! THE REST IS MADE UP OF VARIABLE ENTRIES AND THE SECTION IS TERMINATED BY ! A WORD OF X'FFFFFFFF' ! EACH VARIABLE ENTRY CONSISTS OF THE VARIABLE WORD FOLLOWED BY ! THE VARIABLE NAME AS A STRING. THE WORD CONSISTS OF ! BITS 2**31 TO 2**20 TYPE INFORMATION (MAY BE LANGUAGE DEPENDENT ! BIT 2**19 =0 UNDER LNB =1 IN GLA ! BITS 2**18 TO 2**0 DISPLACEMENT FROM LNB(GLA) IN BYTES ! THE ENVIRONMENT IS A POINTER (RELATIVE TO SST) OF THE NEXT OUTERMOST ! BLOCK OR A POINTER TO GLOBAL OWNS, EXTERNAL OR COMMON AREAS ! A ZERO MEANS NO ENCLOSING BLOCK. WORD1=WORD3=0 IS AN ! IMP MAIN PROGRAM AND WILL TERMINATE THE DIAGNOSTICS. %SYSTEMROUTINE INDIAG(%INTEGER OLDLNB, LANG, PCOUNT,MODE,DIAG,ASIZE, %C %INTEGERNAME FIRST,NEWLNB) !*********************************************************************** !* THE DIAGNOSTIC ROUTINE FOR IMP %AND ALGOL(LANG=5) * !* THE ALGOL SYMBOL TABLES ARE SET UP AS FOR IMP * !* MODE = 0 FOR JOBBER&EMAS2900, =1 FOR OPEH IN VMEB&VMEK * !* DIAG = DIAGNOSTIC LEVEL * !* 1 = ROUTE SUMMARY ONLY (ASIZE)=ADDR MODULE NAME FROM OPEH * !* 2 = DIAGNOSTICS AS TRADITIONALLY PERFORMED * !* ASIZE IS NO OF ELEMENTS OF EACH ARRAY TO BE PRINTED(DIAG>1) * !*********************************************************************** %ROUTINESPEC PRINT LOCALS(%INTEGER ADATA,%STRING(15)LOC) %ROUTINESPEC PRINT SCALAR(%RECORDNAME VAR) %ROUTINESPEC PRINT ARR(%RECORDNAME VAR,%INTEGER ASIZE) %ROUTINESPEC PRINT VAR(%INTEGER TYPE,PREC,NAM,LANG,FORM,VADDR) %INTEGER GLAAD, FLINE, NAM, TYPE, PREC, TSTART, PREV BLK, %C WORD0, WORD1, WORD2, WORD3, I %RECORDFORMAT F(%INTEGER VAL,%STRING(11)VNAME) %OWNINTEGERARRAY GLOBAD(0:20) %OWNINTEGER GLOBPTR %STRING (10) STMNT %STRING (20) PROC %STRING (50) NAME %CONSTINTEGER ALGOL=5;! LANGUAGE CODE %IF FIRST=1 %THEN GLOBPTR=0 %IF LANG#ALGOL %THEN STMNT=" LINE" %C %AND PROC=" ROUTINE/FN/MAP " %C %ELSE STMNT=" STATEMENT" %AND PROC=" PROCEDURE " GLAAD=INTEGER(OLDLNB+16); ! ADDR OF GLA/PLT TSTART=INTEGER(OLDLNB+12)&X'FFFFFF' %IF TSTART=0 %THEN %START PRINTSTRING(" ".PROC."COMPILED WITHOUT DIAGNOSTICS ") ASSDUMP(PCOUNT,OLDLNB) NEWLNB=INTEGER(OLDLNB) %RETURN %FINISH %UNTIL PREVBLK=0 %CYCLE TSTART=TSTART+INTEGER(GLAAD+12) WORD0=INTEGER(TSTART) WORD1=INTEGER(TSTART+4) WORD2=INTEGER(TSTART+8) WORD3=INTEGER(TSTART+12) %IF WORD1&X'C0000000'=X'40000000' %AND COMREG(25)#0 %C %THEN NEWLNB=INTEGER(OLDLNB) %AND %RETURN ! SYSTEM ROUTINE NAME=STRING(TSTART+12) I=WORD0&X'FFFF'; ! LINE NO DISP %IF I=0 %THEN FLINE=-1 %ELSE FLINE=INTEGER(OLDLNB+I) NEWLINE %IF MODE=1 %THEN PRINTSTRING(LT(LANG)) %ELSE %START %IF FIRST=1 %THEN FIRST=0 %AND PRINTSTRING("DIAGNOSTICS ") PRINTSTRING("ENTERED FROM") %FINISH %IF WORD0>>16=0 %THENSTART %IF MODE=0 %THEN PRINTSTRING(LT(LANG)) PRINTSTRING("ENVIRONMENTAL BLOCK ") %FINISHELSESTART %IF FLINE>=0 %AND FLINE#WORD0>>16 %THEN %START PRINTSTRING(STMNT) WRITE(FLINE,4) PRINTSTRING(" OF") %FINISH %IF WORD3=0 %THEN PRINTSTRING(" BLOCK") %C %ELSE PRINT STRING(PROC.NAME) PRINTSTRING(" STARTING AT".STMNT) WRITE(WORD0>>16,2) %IF MODE=1 %AND DIAG=1 %THENSTART PRINTSTRING("(MODULE ".STRING(ASIZE).")") %FINISH NEWLINE %IF LANG#ALGOL %THEN I=20 %ELSE I=16 %IF MODE=0 %OR DIAG>1 %THEN %START PRINT LOCALS(TSTART+I+(WORD3>>26)<<2,"LOCAL") %IF WORD1&X'C0000000'#0 %THEN %START;! EXTERNAL(ETC) ROUTINE I=WORD1&X'3FFFF'+INTEGER(GLAAD+12)+I PRINT LOCALS(I,"GLOBAL") %FINISH %FINISH %IF WORD3#0 %START NEWLNB=INTEGER(OLDLNB) %UNLESS DIAG=1 %THEN NEWLINE %RETURN %FINISH %FINISH PREV BLK=WORD1&X'FFFF' TSTART=PREV BLK %REPEAT NEWLNB=0 NEWLINE; %RETURN %ROUTINE QSORT(%RECORDARRAYNAME A,%INTEGER I,J) %RECORDSPEC A(F) %RECORD D(F) %INTEGER L,U %IF I>=J %THEN %RETURN L=I; U=J; D=A(J); ->FIND UP: L=L+1 %IF L=U %THEN ->FOUND FIND: %UNLESS A(L)_VNAME>D_VNAME %THEN ->UP A(U)=A(L) DOWN: U=U-1 %IF L=U %THEN ->FOUND %UNLESS A(U)_VNAMEDOWN A(L)=A(U); ->UP FOUND: A(U)=D QSORT(A,I,L-1) QSORT(A,U+1,J) %END %ROUTINE PRINT LOCALS(%INTEGER ADATA,%STRING(15)LOC) !*********************************************************************** !* ADATA POINTS TO THE FIRST ENTRY FOR LOCALS IN THE SYMBOL TABLES* !*********************************************************************** %INTEGER I,NRECS,SADATA %IF LOC="GLOBAL" %THEN %START I=0 %WHILE I0 %CYCLE NRECS=NRECS+1 ADATA=ADATA+8+BYTE INTEGER(ADATA+4)&(-4) %REPEAT %RETURN %IF NRECS=0 %BEGIN %RECORDARRAY VARS(1:NRECS)(F) %INTEGER I ADATA=SADATA %CYCLE I=1,1,NRECS VARS(I)<-RECORD(ADATA) ADATA=ADATA+8+BYTEINTEGER(ADATA+4)&(-4) %REPEAT QSORT(VARS,1,NRECS) %CYCLE I=1,1,NRECS %IF VARS(I)_VAL>>28&3=0 %THEN PRINT SCALAR(VARS(I)) %REPEAT %IF ASIZE>0 %THEN %START %CYCLE I=1,1,NRECS %IF VARS(I)_VAL>>28&3#0 %THEN PRINT ARR(VARS(I),ASIZE) %REPEAT %FINISH %END %END %ROUTINE PRINT SCALAR(%RECORDNAME VAR) !*********************************************************************** !* OUTPUT THE NEXT VARIABLE IN THE CURRENT BLOCK. * !* A VARIABLE ENTRY IN THE TABLES IS:- * !* FLAG<<20!VBREG<<18!DISP * !* WHERE:- * !* VBREG IS VARIABLE'S BASE REGISTER, DISP IS IT'S OFFSET * !* AND FLAGS=NAM<<6!PREC<<3!TYPE * !*********************************************************************** %RECORDSPEC VAR(F) %INTEGER I, K, VADDR %STRING(11)LNAME I=VAR_VAL K=I>>20 TYPE=K&7 PREC=K>>4&7 NAM=K>>10&1 LNAME<-VAR_VNAME." " PRINT STRING(LNAME."=") %IF I&X'40000'=0 %THEN VADDR=OLDLNB %ELSE VADDR=GLAAD VADDR=VADDR+I&X'3FFFF' PRINT VAR(TYPE,PREC,NAM,LANG,0,VADDR) NEWLINE %END %ROUTINE PRINT VAR(%INTEGER TYPE,PREC,NAM,LANG,FORM,VADDR) !*********************************************************************** !* OUTPUT A VARIABLE. FIXED FORMAT(FORM#0) TAKE 14 PLACES FOR * !* VARIABLES UP TO 32 BITS AND 21 PLACES THEREAFTER * !*********************************************************************** %INTEGER K,I,J %CONSTINTEGER UNASSI=X'81818181' %SWITCH INTV,REALV(3:7) ! USE VALIDATE ADDRESS HERE TO CHECK ACR LEVELS ETC *LDTB_X'18000010' *LDA_VADDR *VAL_(%LNB+1) *JCC_3, %IF NAM#0 %OR (TYPE=5 %AND FORM=0) %THEN %START %IF INTEGER(VADDR)>>24=X'E5' %THEN ->ESC VADDR=INTEGER(VADDR+4) ->NOT ASS %IF VADDR=UNASSI *LDTB_X'18000010' *LDA_VADDR *VAL_(%LNB+1) *JCC_3, %FINISH ->ILL ENT %IF PREC<3; ! BITS NOT IMPLEMENTED %IF TYPE=1 %THEN ->INTV(PREC) %IF TYPE=2 %THEN ->REALV(PREC) %IF TYPE=3 %AND PREC=5 %THEN ->BOOL %IF TYPE=5 %THEN ->STR INTV(4): ! 16 BIT INTEGER K=BYTEINTEGER(VADDR)<<8!BYTEINTEGER(VADDR+1) ->NOT ASS %IF K=UNASSI>>16 WRITE(K,12*FORM+1) %RETURN INTV(7): ! 128 BIT INTEGER REALV(3): ! 8 BIT REAL REALV(4): ! 16 BIT REAL ILL ENT: ! SHOULD NOT OCCURR PRINTSTRING("UNKNOWN TYPE OF VARIABLE") %RETURN INTV(5): ! 32 BIT INTEGER ->NOT ASS %IF INTEGER(VADDR)=UN ASSI WRITE(INTEGER(VADDR),1+12*FORM) %UNLESS LANG=ALGOL %OR FORM=1 %OR -255<=INTEGER(VADDR)<=255 %START PRINTSTRING(" (X'") PRHEX(INTEGER(VADDR),8); PRINTSTRING("')") %FINISH %RETURN INTV(3): ! 8 BIT INTEGER WRITE(BYTEINTEGER(VADDR),1+12*FORM); %RETURN REALV(5): ! 32 BIT REAL ->NOT ASS %IF INTEGER(VADDR)=UN ASSI PRINT FL(REAL(VADDR), 7) %RETURN INTV(6): ! 64 BIT INTEGER ->NOT ASS %IF UN ASSI=INTEGER(VADDR)=INTEGER(VADDR+4) PRINTSTRING("X'") PRHEX(INTEGER(VADDR),8); SPACES(2) PRHEX(INTEGER(VADDR+4),8) PRINTSYMBOL('''') %RETURN REALV(6): ! 64 BIT REAL ->NOT ASS %IF UNASSI=INTEGER(VADDR)=INTEGER(VADDR+4) PRINT FL(LONG REAL(VADDR), 14) %RETURN REALV(7): ! 128 BIT REAL ->NOT ASS %IF UNASSI=INTEGER(VADDR)=INTEGER(VADDR+4) PRINT FL(LONGREAL(VADDR),14) %IF FORM=0 %THEN %START PRINTSTRING(" (R'"); PRHEX(INTEGER(VADDR),8) PRHEX(INTEGER(VADDR+4),8) SPACE; PRHEX(INTEGER(VADDR+8),8) PRHEX(INTEGER(VADDR+12),8) PRINTSTRING("')") %FINISH %RETURN BOOL: ! BOOLEAN ->NOT ASS %IF INTEGER(VADDR)=UNASSI %IF INTEGER(VADDR)=0 %THEN PRINTSTRING(" 'FALSE' ") %C %ELSE PRINTSTRING(" 'TRUE' ") %RETURN STR: I=BYTEINTEGER(VADDR) ->NOT ASS %IF BYTE INTEGER(VADDR+1)=UNASSI&255=I K=1 %WHILE K<=I %CYCLE J=BYTE INTEGER(VADDR+K) ->NPRINT %UNLESS 32<=J<=126 %OR J=10 K=K+1 %REPEAT PRINTSTRING("""") PRINTSTRING(STRING(VADDR)); PRINTSTRING("""") %RETURN ESC: ! ESCAPE DESCRIPTOR PRINTSTRING("ESCAPE ROUTINE") ->AIGN INVALID: PRINTSTRING("INVALID ADDRSS") ->AIGN NPRINT: PRINT STRING(" CONTAINS UNPRINTABLE CHARS") %RETURN NOT ASS: PRINTSTRING(" NOT ASSIGNED") AIGN: %IF PREC>=6 %AND FORM=1 %THEN SPACES(7) %END; ! PRINT VAR %INTEGERFN CHECK DUPS(%INTEGER REFADDR,VADDR,ELSIZE) !*********************************************************************** !* CHECK IF VAR THE SAME AS PRINTED LAST TIME * !*********************************************************************** ELSIZE=ELSIZE!X'18000000' *LDTB_ELSIZE; *LDA_REFADDR *CYD_0; *LDA_VADDR *CPS_%L=%DR *JCC_8, %RESULT=0 ADUP: %RESULT=1 %END %ROUTINE DCODEDV(%LONGINTEGER DV,%INTEGERARRAYNAME LB,UB) !*********************************************************************** !* WORK DOWN A DOPE VECTOR DESCRIBED BY WORD DESCRIPTOR DV AND * !* RETURN SIZE,DIMENIONALITY AND SUBSCRIPT RANGES IN DATA * !*********************************************************************** %INTEGER I,ND,AD,U,T ND=(DV>>32)&255; ND=ND//3 LB(0)=ND; UB(0)=ND AD=INTEGER(ADDR(DV)+4)+12*(ND-1) T=1 %CYCLE I=1,1,ND U=INTEGER(AD+8)//INTEGER(AD+4) UB(I)=U LB(I)=INTEGER(AD) T=T*(UB(I)-LB(I)+1) AD=AD-12 %REPEAT UB(ND+1)=0 LB(ND+1)=0 %END %ROUTINE PRINT ARR(%RECORDNAME VAR,%INTEGER ASIZE) !*********************************************************************** !* PRINT THE FIRST ASIZE ELEMENTS OF THE ARRAY DEFINED BY VAR * !* ARRAYNAMES PRINTED ALSO AT PRESENT. UP TO COMPILERS TO AVOID THIS* !*********************************************************************** %RECORDSPEC VAR(F) %INTEGER I,J,K,TYPE,PREC,ELSIZE,ND,VADDR,HDADDR,BASEADDR,ELSPERLINE,%C M1,REFADDR,ELSONLINE,DUPSEEN %LONGINTEGER ARRD,DOPED %INTEGERARRAY LBS,UBS,SUBS(0:13) I=VAR_VAL K=I>>20 PREC=K>>4&7 TYPE=K&7 PRINTSTRING(" ARRAY ".VAR_VNAME) %IF I&X'40000'#0 %THEN VADDR=GLAAD %ELSE VADDR=OLDLNB HDADDR=VADDR+I&X'3FFFF' ! ! VALIDATE HEADER ADDRESS AND THE 2 DESCRIPTORS ! *LDTB_X'18000010' *LDA_HDADDR *VAL_(%LNB+1) *JCC_3, ARRD=LONG INTEGER(HDADDR) DOPED=LONG INTEGER(HDADDR+8) *LD_ARRD *VAL_(%LNB+1) *JCC_3, *LD_DOPED *VAL_(%LNB+1) *JCC_3, BASEADDR=INTEGER(ADDR(ARRD)+4) DCODEDV(DOPED,LBS,UBS) ND=LBS(0) %IF TYPE#5 %THEN ELSIZE=1<<(PREC-3) %ELSE %START I=INTEGER(ADDR(DOPED)+4) ELSIZE=INTEGER(I+12*(ND-1)+4) %FINISH ! ! PRINT OUT AND CHECK ARRAYS BOUND PAIR LIST ! PRINT SYMBOL('('); J=0 %CYCLE I=1,1,ND SUBS(I)=LBS(I); ! SET UP SUBS TO FIRST EL WRITE(LBS(I),1) PRINT SYMBOL(':') WRITE(UBS(I),1) PRINT SYMBOL(',') %UNLESS I=ND J=1 %IF LBS(I)>UBS(I) %REPEAT PRINT SYMBOL(')') NEWLINE %IF J#0 %THEN PRINTSTRING("BOUND PAIRS INVALID") %AND %RETURN ! ! WORK OUT HOW MANY ELEMENTS TO PRINT ON A LINE ! %IF TYPE=5 %THEN ELSPERLINE=1 %ELSE %START %IF ELSIZE<=4 %THEN ELSPERLINE=6 %ELSE ELSPERLINE=4 %FINISH %CYCLE; ! THROUGH ALL THE COLUMNS ! ! PRINT COLUMN HEADER EXCEPT FOR ONE DIMENSION ARRAYS ! %IF ND>1 %THEN %START PRINT STRING(" COLUMN (*,") %CYCLE I=2,1,ND WRITE(SUBS(I),1) PRINT SYMBOL(',') %UNLESS I=ND %REPEAT PRINT SYMBOL(')') %FINISH ! ! COMPUTE THE ADDRESS OF FIRST ELEMENT OF THE COLUMN ! K=0; M1=1; I=1 %WHILE I<=ND %CYCLE K=K+M1*(SUBS(I)-LBS(I)) M1=M1*(UBS(I)-LBS(I)+1) I=I+1 %REPEAT VADDR=BASEADDR+K*ELSIZE REFADDR=0; ! ADDR OF LAST ACTUALLY PRINTED DUPSEEN=0; ELSONLINE=99; ! FORCE FIRST EL ONTO NEW LINE ! ! CYCLE DOWN THE COLUMN AND PRINT THE ELEMENTS. SEQUENCES OF REPEATED ! ELEMENTS ARE REPLACED BY "(RPT)". AT THE START OF EACH LINE THE ! CURRENT VALUE OF THE FIRST SUBSCRIPTED IS PRINTED FOLLOWED BY A APAREN ! %CYCLE I=LBS(1),1,UBS(1) %IF REFADDR#0 %THEN %START; ! CHK LAST PRINTED IN THIS COL K=CHECK DUPS(REFADDR,VADDR,ELSIZE) %IF K#0 %THEN %START PRINT STRING("(RPT)") %IF DUPSEEN=0 DUPSEEN=DUPSEEN+1 ->SKIP %FINISH %FINISH ! ! START A NEW LINE AND PRINT SUBSCRIPT VALUE IF NEEDED ! %IF DUPSEEN#0 %OR ELS ON LINE>=ELS PER LINE %START NEWLINE; WRITE(I,3); PRINT STRING(")") DUPSEEN=0; ELS ON LINE=0 %FINISH PRINT VAR(TYPE,PREC,0,LANG,1,VADDR); ELSONLINE=ELSONLINE+1 REFADDR=VADDR SKIP: VADDR=VADDR+ELSIZE ASIZE=ASIZE-1 %EXIT %IF ASIZE<0 %REPEAT; ! UNTIL COLUMN FINISHED NEWLINE %EXIT %IF ASIZE<=0 %OR ND=1 ! ! UPDATE SECOND SUBSCRIPT TO NEXT COLUMN. CHECK FOR AND DEAL WITH ! OVERFLOW INTO NEXT OR FURTHER CLOUMNS ! I=2; SUBS(1)=LBS(1) %CYCLE SUBS(I)=SUBS(I)+1 %EXIT %UNLESS SUBS(I)>UBS(I) SUBS(I)=LBS(I); ! RESET TO LOWER BOUND I=I+1 %REPEAT %EXIT %IF I>ND; ! ALL DONE %REPEAT; ! FOR FURTHER CLOMUNS %RETURN HINV: PRINTSTRING(" HAS INVALID HEADER ") %END; ! OF RT PRINT ARR %END; ! OF RT IDIAGS %ENDOFFILE