* * S Y S T E M A P % I L * * THIS SYSTEM DEFINES THE IMPLEMENTATION LANGUAGE FOR THE XEROX * ASSEMBLY PROGRAM (AP). IT DOES NOT CONTAIN THE DEFINITIONS * FOR INTERFACE WITH AN OPERATING SYSTEM. * * * E N V I R O N M E N T * OPEN BC,I,META,P# * SYSTEM SIG5 MACHINE INSTRUCTION DEFINITIONS * OPEN BIL,BOL SOME HAVE 'EM - SOME DON'T BIL S:SIN,1 X'689' BRANCH IN LIMITS (AFTER CLM W/ DBLWD BOL S:SIN,1 X'699' BRANCH OUT OF LIMITS / IN MEM LO-HI) * META EQU 1**128 PATCH FOR META BUG (AP OKAY) P# SET S:UFV(P#)+1 1 = PASS 1, 2 = PASS 2 * * * S : S * SELECTION (CASE) PROCEDURE * S:S FNAME PROC PEND AF(AF(1)+2) * * * A B O R T * PROCEDURE FOR GENERATING A CALL TO ABORT * * CALL LINE: LABEL ABORT PROCESS NUMBER * ABORT CNAME PROC LF LI,AR AF(1) LOAD PROCESS NUMBER B ABORT BRANCH TO ROUTINE IN THE ROOT PEND * * * B C * SET UP BRANCH TYPE AND APPROPRIATE CONDITION MASK FOR THE * CONDITION KEYWORD SPECIFIED IN 'AF(2)'. * * AF(1) IS 0 FOR A TRUE BRANCH TO THAT * CONDITION, 1 FOR A FALSE. * OPEN I * BC FNAME X'680',X'690' BRANCH ON CONDITION PROC I SET 0 DO NUM(AF(2))=1 I SET SCOR(AF(2),GE,LE,EQ,AZ,,,,,IL,,,,,,,,L,G,NE,ANZ,,,,,OL) DO I=0 I SET SCOR(AF(2),GEZ,LEZ,EZ,FZ,,,,,,,,,,,,,LZ,GZ,NZ,FNZ) ERROR,3,I=0 'UNDEFINED CONDITION' FIN FIN PEND S:S(AF(1)>0,NAME)||I * CLOSE I * * * B F Z & B F N Z * BRANCH IF FIELD ZERO, AND BRANCH IF FIELD NON-ZERO * * FORM OF TYPICAL REFERENCE LINE: * BFZ,R,C MASK,*ADDRESS,INDEX * WHERE R IS THE REGISTER CONTAINING THE FIELD TO TEST. * C IS NON-ZERO IF THE CONDITION CODE HAS BEEN CHANGED * ADDRESS IS THE BRANCH ADDRESS IF CONDITION IS MET. * * COMPARE IS NOT EXECUTED IF THE MASK IS X'80000000', UNLESS * C IS NON-ZERO. E.G., BFNZ,R,1 X'80000000',ADDRESS * WILL GENERATE THE COMPARE. * OPEN I * BFZ CNAME X'68' BRANCH IF FIELD ZERO BFNZ CNAME X'69' BRANCH IF FIELD NON-ZERO PROC BOUND 4 LF RES 0 I DO (AF(1)~=X'80000000')|(CF(3)~=0) CV,CF(2) AF(1) FIN DO AFA(2)&(AF(3)=0)&(S:UFV(AF(2))<=7) GEN,8,4,3,17 NAME,I*3+1,AF(2),0 ELSE GEN,1,7,4,3,17 AFA(2),NAME,I*3+1,AF(3),AF(2) FIN PEND * CLOSE I * * * C A L L P R O C E D U R E * GENERATE A 'BAL' USING THE STANDARD LINK REGISTER * CALL COM,1,7,4,20 AFA,X'6A',RL,WA(AF(1)) * * OPEN I,IAL,IAN,INL,IN1,IN2 * * E X I T P R O C E D U R E * GENERATE A RETURN BRANCH FROM A SUBROUTINE. * * FORM OF A REFERENCE LINE: * LBL EXIT,COND REG * WHERE: COND IS ANZ,AZ,EQ,EZ,G,GE,GEZ,GZ,IL,L,LE,LEZ,LZ, * NE,NZ, OR OL. * REG IS THE REGISTER CONTAINING THE RETURN ADDRESS * (DEFAULT IS 'RL' IF REG IS NOT SPECIFIED) * * 'COND' MAY ALSO BE FZ OR FNZ (A LA BFZ/BFNZ PROCS), IN * WHICH CASE THE 'EXIT' CALL IS OF THE FORM: * * EXIT,COND MASK,R,C * EXIT CNAME PROC DO (INL-META)>0 DISP INL**8+X'0FEFFF00' FIN DO SCOR(CF(2),FZ,FNZ)=0 BOUND 4 I SET S:S(NUM(AF)=1,RL,AF) LF GEN,1,11,3,17 I>7,BC(0,CF(2)),I*(I<8),I*(I>7) ELSE DO SCOR(CF(2),FZ) LF BFZ,AF(2),AF(3) AF(1),*RL ELSE LF BFNZ,AF(2),AF(3) AF(1),*RL FIN FIN PEND * * * I F / E L S / F I * * THESE PROCEDURES DEFINE THE STANDARD IF-THEN/ELSE COMPOUNDS. * THE CLAUSES MAY BE NESTED; IT IS ONLY REQUIRED THAT 'FI' * STATICALLY BALANCE THE ASSOCIATED 'IF'. 'ELS', AS USUAL, * IS OPTIONAL, AND IS PAIRED WITH THE LAST UN-FI'ED 'IF'. * * 'ELSF' & 'THEF' ARE ALSO DEFINED. A SEPARATE 'FI' IS NOT * REQUIRED TO TERMINATE (NEXT 'ELSF', 'ELS', OR 'FI'). * * WHERE 'IF P ... THEF Q' CAN BE CONSIDERED TO BE * FUNCTIONALLY EQUIVALENT TO 'IF P AND Q', THE FUNCTIONAL * EQUIVALENT OF 'IF P OR Q' IS NOT EASILY IMPLEMENTED IN * THE SAME STYLE. IT IS AVAILABLE, HOWEVER, BY APPENDING * A TRAILING 'OR' KEYWORD TO ANY 'IF', 'ELSF', OR 'THEF' * ('IF P,OR ... IF Q'). * * USE: * IF,COND (VAL(,R)) * BLOCK1 * ELS * BLOCK2 * FI * * WHERE 'COND' IS ANY ACCEPTED BY BC. IF CONDITION IS TRUE, * BLOCK1 IS EXECUTED, ELSE IT IS SKIPPED. IF CONDITION IS * NOT TRUE, BLOCK2 IS EXECUTED, IF IT APPEARS. * * THE OPTIONAL 'VAL,R' IMPLIES THAT A 'CV,R VAL' IS * TO BE EXECUTED PRIOR TO THE TEST. IF 'R' IS OMITTED, * THE 'R' FROM THE LAST SUCH 'IF' WILL BE USED. * * 'COND' MAY ALSO BE FZ OR FNZ (A LA BFZ/BFNZ PROCS), IN * WHICH CASE THE 'IF' CALL IS OF THE FORM: * * IF,COND MASK,R * * PRELUDE: * OPEN %ELS%,%ELSF%,%IF%,%NORM%,%OR% OPEN :IF,:FI,:SC,:TY OPEN #ELS,#IF OPEN BT,CT,DR,ENL,NXTIN,OE,SE * * FIXED INDICES FOR IAN * :TY EQU 1 TYPE CODE :SC EQU 2 SUCCESS ADDRESS :IF EQU 3 INITIAL FAIL ADDRESS (FOR 'IF') :FI EQU 4 'FI' OR SECOND FAIL ADDRESS * * TYPE CODES (FOR 'IAN(INL,:TY)') * %NORM% EQU 0 NO CONTROL SEQUENCE IN EFFECT %IF% EQU 1 'IF' HIT - NEED 'ELSF','ELS','FI' %ELSF% EQU 2 'ELSF' HIT - NEED 'ELS' OR 'FI' %ELS% EQU 3 'ELS' HIT - ONLY 'FI' LEGAL %OR% EQU X'80' 'OR'-CHAIN CURRENT * * ERROR MESSAGES * OE EQU '''OR''-GROUP MUST TERMINATE ON ''IF''' SE EQU 'CONTROL SEQUENCE ERROR' * * CONTROL LISTS AND INDICES * DR SET -1 DEFAULT REGISTER FOR CHAINED 'IF'S' ENL SET :SC ELS-NESTING LEVEL IAL SET S:S(P#,,,S:UFV(IAL)) KEEP ONLY PASS 1 ADDRS IN LIST. IAN SET %NORM% INDICES TO IAL INL SET 0+META IF-NESTING LEVEL IN1 SET 1 INDEX #1 IN IF-ADDRESS-LIST IN2 SET 1 INDEX #2 IN IF-ADDRESS-LIST * ************************************************************************ * * * THE IAN LIST IS ARRANGED IN THE FOLLOWING FASHION AT ANY ONE * * 'INL' LEVEL (WITH EACH ELEMENT HOLDING AN INDEX TO THE * * 'IAL' LIST, WHICH IS JUST A RUNNING ADDRESS TABLE): * * * * IAN(INL,1) - TYPE CODE FOR CURRENT ENVIRONMENT. USED FOR * * ERROR CHECKING AND REPORTING. * * IAN(INL,2) - 'SUCCESS' BRANCH ADDRESS. USED TEMPORARILY * * DURING AN 'OR' GROUP - SATISFIED BY FIRST * * NON-'OR' COMMAND. * * IAN(INL,3) - 'FAIL' BRANCH ADDRESS(1). INITIALLY, * * WHERE A PLAIN 'IF' SHOULD BRANCH IF THE * * CONDITION IS NOT SATISFIED. * * IAN(INL,4) - 'FAIL' BRANCH ADDRESS(2), WHICH IS ALWAYS * * THE ADDRESS OF THE TERMINAL 'FI' FOR A GROUP * * WHICH CONTAINS 'ELS' OR 'ELSF'. * * IAN(INL,5) - SUBSEQUENT 'FAIL' BRANCH ADDRESSES. THESE * * . ARE CREATED AS 'ELSF'S PILE UP WITHIN A * * . SINGLE GROUP, RATHER THAN GOING UP TO A * * IAN(INL,N) NEW 'INL' LEVEL FOR THE 'ELSF'S 'IF'. * * * ************************************************************************ * IF CNAME 0 #IF CNAME 1 THEF CNAME 2 * OPEN DSA * DSA SET 0 DEFINE SUCCESS ADDRESS * PROC BOUND 4 LF RES 0 BT SET 1 DEFAULT BRANCH IS 'FALSE' CT SET IAN(INL+((INL-META)=0),:TY)&~%OR% TYPE (W/O 'OR') DR SET S:S(NUM(AF(2))=1,DR,AF(2)) DO (IAN(INL+((INL-META)=0),:TY)&%OR%)>0 DOIF IN OR-CHAIN GOTO,NAME+SCOR(AF(NUM(AF)|1),OR)*3 PEND,#2,#3,PEND,#5 #0 BOUND 1 IF IN 'OR'-CHAIN DSA SET 1 DEFINE SUCCESS ADDRESS IAN(INL,:TY) SET %IF% CLEAR %OR% - SET %IF% MODE GOTO ESAC #2 BOUND 1 THEF IN 'OR'-CHAIN IAL(IAN(INL,:SC)) SET WA(%) DEFINE SUCCESS ADDRESS GOTO EXIT1 #3 BOUND 1 IF ..,OR IN 'OR'-CHAIN BT SET 0 GENERATE TRUE BRANCH IAN(INL,:TY) SET %IF%|%OR% SET %IF% MODE UNDER 'OR'-CHAIN GOTO ESAC #5 BOUND 1 THEF ..,OR IN 'OR'-CHAIN IAL(IAN(INL,:SC)) SET WA(%) DEFINE SUCCESS ADDRESS IAN(INL,:SC) SET NXTIN EXIT1 ERROR,3 OE GOTO,(CT~=%IF%)&(CT~=%ELSF%) EXIT0 ESAC BOUND 1 END CASE ELSE NOT IN 'OR'-CHAIN GOTO,NAME+SCOR(AF(NUM(AF)|1),OR)*3 #1,#2,#3,#4,#5 #0 BOUND 1 IF ENL SET :SC (FI WILL RE-CALCULATE) DISP (INL-META)**8+X'001F0000' INL SET INL+1 BUMP NESTING LEVEL IAN(INL,:TY) SET %IF% SET %IF% MODE GOTO EXIT2 #1 BOUND 1 #IF (INTERNAL IF) IAN(INL,:TY) SET %ELSF% SET %ELSF% MODE GOTO EXIT2 #2 BOUND 1 THEF GOTO,(CT~=%IF%)&(CT~=%ELSF%) EXIT0 DISP (INL-META)**8+X'00AEFF00' (READ THEF AS 'AND-IF') GOTO ESAC #3 BOUND 1 IF ..,OR ENL SET :SC (FI WILL RE-CALCULATE) DISP (INL-META)**8+X'001F0000' INL SET INL+1 BUMP NESTING LEVEL IAN(INL,:TY) SET %IF%|%OR% SET 'IF' MODE IN 'OR'-CHAIN GOTO EXIT3 #4 BOUND 1 #IF ..,OR IAN(INL,:TY) SET %ELSF%|%OR% SET 'ELSF' MODE IN 'OR'-CHAIN GOTO EXIT3 #5 BOUND 1 THEF ..,OR GOTO,(CT~=%IF%)&(CT~=%ELSF%) EXIT0 BT SET 0 GENERATE 'TRUE' BRANCH IAN(INL,:SC) SET NXTIN RESERVE NEW 'SUCCESS' ADDRESS IAN(INL,:TY) SET IAN(INL,:TY)|%OR% SET START OF 'OR'-CHAIN DISP (INL-META)**8+X'00AEFF00' (READ THEF AS 'AND-IF') GOTO ESAC EXIT3 BOUND 1 BT SET 0 GENERATE 'TRUE' BRANCH IAN(INL,:SC) SET NXTIN RESERVE NEW 'SUCCESS' ADDRESS EXIT2 BOUND 1 ENL SET ENL+1 EXIT1 BOUND 1 IAN(INL,ENL) SET NXTIN SAVE INDICES AT THIS LEVEL ESAC BOUND 1 FIN I SET S:S(BT,IAN(INL,:SC),IAN(INL,ENL)) SET BRANCH ADDRESS DO (SCOR(CF(2),FZ,FNZ)>0)|(NUM(AF)>1)|(SCOR(AF(1),OR,)=0) CV,DR AF(1) FIN GEN,12,20 BC(BT,CF(2)),IAL(I) BRANCH ON APPROPRIATE CONDITION DO DSA DOIF AT END OF 'OR'-CHAIN IAL(IAN(INL,:SC)) SET WA(%) DSA SET 0 FIN GOTO PEND EXIT0 ERROR,3 SE PEND PEND * CLOSE DSA * ELS CNAME 1 #ELS CNAME 0 PROC BOUND 4 CT SET IAN(INL,:TY)&~%OR% CURRENT TYPE (W/O 'OR' FLAG) DO (CT=%IF%)|(CT=%ELSF%) IAL(IAN(INL,ENL)) SET WA(%)+1 LAST 'IF' FAIL GOES TO AFTER BRANCH ENL SET ENL+1 IAN(INL,ENL) SET NXTIN SAVE NEW INDICES AT THIS LEVEL DO NAME(1) DISP (INL-META)**8+X'000DFF00' IAN(INL,:TY) SET %ELS% FIN LF GEN,12,20 X'680',IAL(IAN(INL,:FI)) ELSE ERROR,3 SE FIN PEND * FI CNAME PROC CT SET IAN(INL,:TY)&~%OR% CURRENT TYPE (W/O 'OR' FLAG) DO (INL-META)>0 IAL(IAN(INL,ENL)) SET WA(%) HERE FROM LAST 'IF', 'ELS', OR 'ELSF' DO ENL>:FI 'ELSF' ONLY IAL(IAN(INL,:FI)) SET WA(%) 'ELSF' ONLY FIN IAN(INL) SET INL SET INL-1 DO (INL-META)>0 ENL SET NUM(IAN(INL)) ELSE ENL SET :SC FIN DISP (INL-META)**8+X'00F10000' ELSE INL SET 0+META ERROR,3 SE FIN PEND * ELSF CNAME PROC CT SET IAN(INL,:TY) CURRENT TYPE (WITH 'OR' FLAG) DO (CT=%IF%)|(CT=%ELSF%) DISP (INL-META)**8+X'00EEFF00' #ELS #IF,CF(2) AF ELSE ERROR,3 S:S((CT&%OR%)>0,SE,OE) FIN PEND * NXTIN CNAME HELPER PROCEDURE NXTIN FNAME NEXT IAL INDICES PROC IN1 SET IN1+(IN2>=255) IN2 SET S:S(IN2>=255,IN2+1,2) PEND IN1,IN2 * CLOSE BT,CT,DR,ENL,NXTIN,OE,SE CLOSE #ELS,#IF CLOSE %ELS%,%ELSF%,%IF%,%NORM%,%OR% CLOSE :IF,:FI,:SC,:TY CLOSE I,IAL,IAN,INL,IN1,IN2 * * * LOAD,COMPARE, AND ADD A VALUE. * THE VALUE MUST BE DEFINED BY A PRIOR 'EQU' OR 'SET' * THE PROC GENERATES AN IMMEDIATE OR LITERAL ADDRESS * LV CNAME X'22' LOAD VALUE CV CNAME X'21' COMPARE VALUE AV CNAME X'20' ADD VALUE PROC DO ((AF(1)&X'FFF80000')=0)|((AF(1)&X'FFF80000')=X'FFF80000') LF GEN,8,4,20 NAME,CF(2),AF(1)&X'FFFFF' ELSE LF GEN,8,4,3,17 NAME+X'10',CF(2),0,=AF(1) FIN PEND * * PROCEDURE FOR LOADING NEXT ENCODED TEXT ITEM * * NXTENC[,REG] [INDEX[,NOINC]] * NXTENC CNAME PROC I SET S:S(NUM(AF(1))>0,XW,AF(1)) DEFAULT INDEX TO XW LF LH,S:S(NUM(CF)>1,XT,CF(2)) *XWBASE,I DEFAULT REG TO XT DO SCOR(AF(2),NOINC)=0 DON'T GENERATE THE ADD IMMEDIATE AI,I 1 IF 'NOINC' SPECIFIED IN AF(2) FIN PEND * * * PROCEDURE FOR GENERATING SINGLE LENGTH LOCICAL SHIFTS * * SHIFT,R FROM,TO * SHIFT CNAME PROC DO AF(1)~=AF(2) DON'T GENERATE A SHIFT OF ZERO DO AF(1)-AF(2)>16 IF SHIFT IS MORE THAN 16 LEFT, LF SCS,CF(2) AF(1)-AF(2)-32 GENERATE A RIGHT CIRCULAR INSTEAD ELSE DO AF(2)-AF(1)>16 IF SHIFT IS MORE THAN 16 RIGHT. LF SCS,CF(2) 32-AF(2)+AF(1) GENERATE A LEFT CIRCULAR INSTEAD ELSE LF SLS,CF(2) AF(1)-AF(2) GENERATE A LOGICAL SHIFT OF 16 OR FIN LESS FIN FIN PEND * * PROCEDURE FOR GENERATING INTEGER DATA IN SPECIAL INTEGER FORMAT * SPECINT CNAME PROC BOUND 4 LF GEN,1,1,1,1,2,2,2,22 1,1,0,0,3,0,0,AF(1) PEND * * COM FOR GENERATING EXPRESSION CONTROL TABLE ITEMS OF SPECIAL * INTEGER TYPE * SPIECT COM,7,1,7,17 X'24',CF(2),0,AF(1) * * BYTE AND HALF PROC * GENERATES A BYTE OR HALFWORD TO BE USED IN A BRANCH TABLE * * THE FIRST ENTRY IN THE TABLE MUST HAVE THE TABLE BASE * ADDRESS AS THE CF(2) ENTRY. ALL OTHER REFERENCES MUST NOT * USE CF(2). A BOUND 4 SHOULD FOLLOW THE LAST REFERENCE. * * REFERENCE ONE: BYTE,BASE BRANCH%LOCATION%1 * REFERENCE N: BYTE BRANCH%LOCATION%N * OPEN TABLE%BASE * BYTE CNAME 8 HALF CNAME 16 PROC DO1 NUM(CF)=2 TABLE%BASE SET S:UFV(CF(2)) LF GEN,NAME AF(1)-S:S(S:UFV(AF(1))=0,TABLE%BASE) PEND * CLOSE TABLE%BASE * CLOSE BC,I,META,P# * END SYSTEM AP%IL