Google
 

Trailing-Edge - PDP-10 Archives - AP-5471B-BM - sources/algser.mac
There are 8 other files named algser.mac in the archive. Click here to see a list.
;
;
;
;
;
;
;	COPYRIGHT (C) 1975,1976,1977,1978
;	DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;
;
;	THIS SOFTWARE IS FURNISHED UNDER A LICENSE FOR USE ONLY ON A
;	SINGLE COMPUTER SYSTEM AND MAY BE COPIED ONLY WITH THE INCLUSION
;	OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE, OR ANY OTHER
;	COPIES THEREOF, MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE
;	TO ANY OTHER PERSON EXCEPT FOR USE ON SUCH SYSTEM AND TO ONE WHO
;	AGREES TO THESE LICENSE TERMS.  TITLE TO AND OWNERSHIP OF THE
;	SOFTWARE SHALL AT ALL TIMES REMAIN IN DEC.
;
;	THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT
;	NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL
;	EQUIPMENT CORPORATION.
;
;	DEC ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;	SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DEC.
;
;SUBTTL TEMPCODE SERVICE

; COPYRIGHT 1971,1972,1973,1974 DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.

; WRITTEN BY A. N. HABERMANN, C.M.U.
; EDITED BY R. M. DE MORGAN.

	HISEG

	SEARCH ALGPRM,ALGMAC	; SEARCH PARAMETER FILES
MODULE MSER;
$PLEVEL=1;
BEGIN
EXTERN PRASE;
EXTERN PRLIB;
EXTERN SYMHT;
EXTERN	KIOPS,OPMOVE;
EXPROC ERRLEX;
EXPROC CON1;
EXPROC CON2;
EXPROC COMBLEX;
EXPROC CONVERT;
EXPROC FAIL;
EXPROC MABS;
EXPROC MREL;
EXPROC MREL0; [E144]
EXPROC RAFIX;
EXPROC ADRFIX;
EXPROC ABSFIX;
EXPROC ADDFIX;
EXPROC TOFIX;
EXPROC EXTFIX;
EXPROC TYPE0,BHDR
SUBTTL	TEMPCODE SERVICE	* EVAL *

;EVAL TRANSFORMS A PROCEDURE IDENTIFIER USED IN A FUNCTION DESIGNATOR
;OR A FORMAL IDENTIFIER FROM AN OBJECT IN THE SYMBOL TABLE INTO A
;AN EXPRESSION IN AN ACCUMULATOR AND GENERATES THE APPROPRIATE
;INSTRUCTIONS .THE ONLY EXCEPTION IS THE FORMAL ARRAY IDENTIFIER
;SINCE ITS FORMAL LOCATIONS CONTAIN A COPY OF THE ARRAY DESCRIPTOR
;OF THE ACTUAL ARRAY IDENTIFIER,WHICH CAN NOT BE CHANGED ANYWAY.
;"SWITCH" IS CODED AS "LABEL PROCEDURE";A SWITCH IDENTIFIER CANNOT
;EVALUATE IN ITS OWN RIGHT INTO AN EXPRESSION.
;THE RESULT OF A FORMAL LABEL IS IN A2,OF EXPRESSIONS IN A0.

PROCEDURE EVAL;
BEGIN
IF  KIND =PROCEDURE
				T.PRO
THEN
  BEGIN
    IF STATUS = FORMAL BY NAME
				T.FON
    THEN
      ;T_'XCT 0,0'
				HRLZI	T,(XCT 0,0)
    ELSE
      ;T_'PUSHJ SP,0'
				HRLZI	T,(PUSHJ SP,0)
    FI;

      ;TC[IN+]_T,SYM<TAD>;..TAD IN SYM;
				PLUNKI(SYM);
      ;..BOOK ALL ACCS USED;
				HRROI	T,0
				HLLM	T,HANDLE
    IF TYPE NEQ LABEL
				TN.L
    THEN
    BEGIN
      ;TC[IN+]_'TCTYDES 0,0';
				HRLZI	T,(TCTYDES 0,0)
				PLUNKI
      ;TC[IN+]_TYPE,1;
				HLLZ	T,SYM
				TLZ	T,$AM
				ADDI	T,1
				PLUNKI
   CLOSE;

    IF  DEL NEQ PAROPEN
				CAMN	DEL,ZLPAR
				GOTO	FALSE
    THEN
	IF # OF FORMALS NEQ 0 NOR ARBITRARY
				MOVE	T3,STW1
				TLNN	T3,$AM-1
				GOTO	FALSE
	THEN
	  FAIL(61,FRIED,SYM,WRONG NUMBER OF PARAMETERS)
	FI;
    FI
       ;SYM<LHS>_'EXP,SAME,SIMPLE,ACC';
				TLZ	SYM,$KIND!$STATUS!$AM
				TLO	SYM,$EXP!$STMT!$ACC
      ;SYM<RHS>_A0
				HRRI	SYM,0
    ENDD
  ELSE
      FAIL(82,FRIED,SYM,SWITCH IDENTIFIER NOT PERMITTED HERE)
    FI
  ENDD
ELSE
  IF STATUS = FORMAL
				T.FORM
  THEN
    IF TYPE = LABEL OR SWITCH
				T.L
    THEN
      BEGIN
	  ;TC[IN+]_'XCT 0,SYM';
				HRLZI	T,(XCT 0,0)
				PLUNKI(SYM);
	CLOSE;
        ;SYM<RHS>_A2;
				HRRI	SYM,2
        ;SYM<LHS>_SIMPLE,PTR
				TLZ	SYM,$AM!$STATUS
				TLO	SYM,$PTR
      ENDD
    ELSE
          IF KIND=VAR  AND  STATUS = FORMAL BY NAME
				TLNE	SYM,$STATUS-$FOV
				T.VAR
          THEN
              IF DEL = ASSIGN
				CAME	DEL,ZASS
				GOTO	FALSE
              THEN
                BEGIN
		;TC[IN+]_'XCT 1,SYM';
				MOVSI	T,(XCT 1,0)
		PLUNKI(SYM);
		;..BOOK ALL REGS USED
				HRROI	T,0
				HLLM	T,HANDLE
		CLOSE
              ENDD
              ELSE
                BEGIN
		  ;TC[IN+]_'XCT 0,SYM';
				HRLZI	T,(XCT 0,0)
				PLUNKI(SYM);
		  ;..BOOK ALL ACCS USED;
				HRROI	T,0
				HLLM	T,HANDLE
		  ;SYM<LHS>_'EXPR,SAME,SIMPLE,ACC';
				TLZ	SYM,$KIND!$STATUS!$AM
				TLO	SYM,$EXP!$SIM!$ACC
		  ;SYM<RHS>_'A0';
				HRRI	SYM,0
		  CLOSE
                ENDD
              FI
	  FI
	FI
      FI
   FI
ENDD
SUBTTL	TEMPCODE SERVICE	* REOPEN *

;A PORTION ENDS WITH A PORTION POINTER WHICH CAN BE RECOGNIZED BY 77
;IN THE MOST SIGNIFICANT BITS.THE ADDRESS PART OF A POTION POINTER
;POINTS TO THE FIRST INSTRUCTION OF THE PORTION AND SO A PORTION IS
;IMPLEMENTED AS A CIRCULAR LIST.
;BITS 29 THROUGH 18 REPRESENT THE USED REGISTERS OF THIS PORTION.
;REOPEN PLACES THE PORTION POINTER BACK IN HANDLE AND RESETS
;INDEX TO POINT TO THE FIRST FREE LOCATION IN TEMPCODE WHERE
;THE PORTION CAN BE EXTENDED.



PROCEDURE REOPEN;
BEGIN
 ;T_ABS(T);
				ANDI  T,3
 ;T3_HANDLE(U);
				HRRZ  T3,LEXEX(T)

IF PORTION IN TEMPCODE AND PORTION POINTER
				JUMPE	T3,FALSE
				SETCM	T1,(T3)
				TLNE	T1,770000
				GOTO	FALSE
THEN
  BEGIN
    ;HANDLE_PORTION POINTER;
				SETCAM	T1,HANDLE
    ;INDEX_INDEX-1
				SOS	T1,INDEX
    IF HANDLE NOT EQL INDEX
				CAIN	T3,(T1)
				GOTO	FALSE
    THEN
      BEGIN
        ;INDEX_INDEX+1;
				AOS	T1,INDEX
	;PORTION PTR<RHS>_INDEX;
				HRRM	T1,(T3)
      ENDD
    FI
  ENDD
FI
ENDD
SUBTTL	TEMPCODE SERVICE	* CLOSE *

;WHILE A PORTION IS OPEN, THE CURRENT PORTION POINTER IS BEING BUILD
;UP IN HANDLE, AND INDEX POINTS TO THE FIRST FREE LOCATION IN TEMPCODE.
;TO CLOSE A PORTION , THE CONTENTS OF HANDLE ARE ADDED TO THE CURRENTLY
;OPEN PORTION, AND HANDLE AND INDEX ARE SET TO REPRESENT A NEW OPEN, BUT
;ENTIRELY EMPTY, PORTION.

PROCEDURE CLOSE;
  ;ASSUMES OFFSET IN T
BEGIN
  ;T_ABS(T);
				ANDI	T,3
  ;T3_INDEX;
				MOVE	T3,INDEX
  ;HANDLE(U)_INDEX;
				HRRM	T3,LEXEX(T)
  ;T2_HANDLE;
				MOVE	T2,HANDLE
  ;TC[IN+]_T2;
				MOVEM	T2,(T3)
				AOS	T3,INDEX
  IF  INDEX=TCMAX
				CAME	T3,TCMAX
				GOTO	FALSE
  THEN
    FAIL(83,FATAL,DEL,TEMPCODEOVERFLOW)
  FI;
  ;HANDLE<LHS>_0;
  ;HANDLE<RHS>_INDEX;..TO OPEN NEW PORTION;
				HRLI	T3,770000;$
				MOVEM	T3,HANDLE;$
ENDD
SUBTTL	TEMPCODE SERVICE	* EMITCODE *

;EMITCODE ADDS AN INSTRUCTION TO THE CURRENTLY OPEN PORTION. IT BOOKS
;IN HANDLE THE USED REGISTERS ACCORDING TO THE LENGTH OF THE OPERAND
;(ONE WORD FOR INTEGER,BOOLEAN AND REAL,TWO WORDS FOR STRING AND
;THREE WORDS FOR LONG REAL).
;EMITCODE TAKES CARE OF THE OPCODE MODIFICATION FOR IMMEDIATE CON-
;STANTS.
;A LONG REAL IS TREATED AS A THREE WORD OPERAND IN ORDER TO AVOID
;PROBLEMS WITH ARITHMETIC WHICH USES THREE ACCUMULATORS.HENCE, THERE
;ARE FOUR "FLOATING" ACCUMULATORS:
;	F0:	A0,A1,A2
;	F1:	A3,A4,A5
;	F3:	A6,A7,A10
;	F4:	A11,A12,A13
;THE OTHER REGISTERS ARE USED FOR SPECIAL PURPOSES (STACKPOINTER ETC).

 ;..T CONTAINS THE OPCODE LEFT ADJUSTED
 ;..T1 CONTAINS THE PAIR #,ACC ,BOTH RIGHT ADJUSTED
 ;..T2 CONTAINS TAD (TEMPADDRESS)
PROCEDURE EMITCODE;
BEGIN
IF  #=2 OR #=3
				TLNE	T1,2
				TLOE	T1,5
  ;T1_6 OR 7
				GOTO	FALSE
THEN
  ;T1_3
				HRLI	T1,3
FI;

 ;T3<LHS>_T1<LHS>;
				HLLZ	T3,T1
 ;T3^(T1);..SHIFT OVER 'ACC' BIT POSITIONS;
				ANDI	T1,SP
				LSH	T3,(T1)

 ;..BOOK USED REGS;
				IORM	T3,HANDLE
IF ADRMODE = IMMEDIATE
				TLNN	T2,36
				TLNN	T2,$IMM
				GOTO	FALSE
THEN
  IF OPCODE BEGINS WITH 1 OR 2 OR 4 OR 5
				TLNN	T,500000
				GOTO	TRUE
				TLNE	T,200000
				GOTO	FALSE
  THEN
    ;T_T+1;..IMMEDIATE MODIFICATION;
				TLO	T,1000
  ELSE
    ;IF  OPCODE = CAM THEN OPCODE_CAI;
				TLNN	T,460000
				TLZ	T,10000
  FI
FI;

XPLU:  ;T1^23;..SHIFT ACC IN ACCFIELD;
				ANDI	T1,SP
				ROT	T1,-15
 ;T_T OR T1;..COMBINE OPCODE AND ACC;
				IOR	T,T1
XIPL:  ;T2_T2<TAD>;
				TLZ	T2,777777-$AM
 ;T_T OR T2;..PLACE TEMPADDRESS;
				IOR	T,T2
 ;T1_INDEX;
 ;T[T1]_T;..PLACE INSTR. IN TEMPCODE;
				MOVE	T1,INDEX
				MOVEM	T,(T1)
 ;T1_INDEX_INDEX+1;
				AOS	T1,INDEX

IF T1=TCMAX
				CAME	T1,TCMAX
				GOTO	FALSE
THEN
    FAIL(83,FATAL,DEL, TEMPCODE OVERFLOW)
FI
ENDD
SUBTTL	TEMPCODE SERVICE	* PLUNK *	* IPLUNK *

;PLUNK IS A SIMPLIFIED VERSION OF EMITCODE. IT IS USED WHEN IT IS
;NOT NECESSARY TO BOOK THE USED ACCUMULATORS NOR TO MODIFY THE OPCODE
;FOR AN IMMEDIATE INSTRUCTION.

PROCEDURE PLUNK;
BEGIN
				GOTO	XPLU
ENDD



;IPLUNK IS USED WHEN THE INSTRUCTION IS READY IN T TO BE
;PLACED IN TEMPCODE.IF T2#0 , THE TEMPORARY ADDRESS OF THE SOURCE IS
;TAKEN FROM THERE.

PROCEDURE IPLUNK;
BEGIN
				GOTO	XIPL
ENDD
SUBTTL	TEMPCODE SERVICE	* LOAD *

;LOAD TRANSFORMS ITS INPUT OBJECT INTO A CLOSED PORTION IN TEMPCODE
;REPRESENTING AN EXPRESSION IN  AN ACCUMULATOR.IT USUALLY WILL GENERATE
;A MOVE (OR DMOVE) INSTRUCTION TO ACHIEVE THIS, BUT WHEN THE INPUT IS
;ALREADY AN EXPRESSION IN AN ACCUMULATOR IT WILL AVOID UNNECESSARY MOVE
;INSTRUCTIONS.AS A SIDE EFFECT LOAD KEEPS TRACK OF THE USE OF ACCUMU-
;LATORS.LAC POINTS TO THE LAST ALLOCATED ACCUMULATOR. ACCS ARE ALLOCATED
;TO START WITH A13 DOWN TO A1.

PROCEDURE LOAD;	;..T1 CONTAINS (KEY,ACC) PLACED BY MACRO;
BEGIN
  IF KEY = BLANK
				TLZN	T1,1
				GOTO	FALSE
  THEN
    ;REV_-ADR(SYM)
				MOVNI	REV,SYM
  FI;
  ;KA_T1;..SAVE (KEY,ACC)
				MOVEM	T1,KA
  ;T_2*(KEY+REV);
				HLRZ	T,T1
				ANDI	T,SYM
				ADD	T,REV
  ;REOPEN;
				PUSHJ	SP,.REOPEN
  ;T<LHS>_KA<LHS>;..OPCODE AND ADR(LEXEME) IN T;
				HLLZ	T,KA
  ;T1<RHS>_KA<RHS>;..ACC IN T1;
				HRRZ	T1,KA
XLOAD:  ;T2_LEXEME;
				HLRZ	T2,T
				ANDI	T2,SYM
				MOVE	T2,(T2)
  IF T2=ERROR LEXEME
				JUMPG	T2,FALSE
  THEN
    ERRLEX
  ELSE
  BEGIN
  IF TWO WORD OPERAND OR T2<TYPE>=INTDIV
				TLNN	T2,$TYPE-$IDI
				GOTO	TRUE
				T.TWO(T2)
  THEN
    ;T3_2
				MOVEI	T3,2		;T3 CONTAINS #
  ELSE
    IF ONE WORD OPERAND
				T.ONE(T2)
    THEN
      ;T3_1
				MOVEI	T3,1
    FI
  FI;

  IF LONG REAL OPERAND
				T.LR(T2)
  THEN
    ;T3_3
				MOVEI	T3,3
  FI;..T3 CONTAINS #;


IF T2<AM>=PTR OR ACC  AND  ACC=13 0R T2<RHS>
				CAIE	T1,(T2)
				CAIN	T1,15
				T.ACC(T2)
THEN
  IF  T3=1 OR T2<AM>=ACC AND T3#2
				TLNN	T2,$AM-$ACC
				CAIE	T3,2
				CAIE	T3,1
				GOTO FALSE
  THEN
    ;T1<RHS>_T2<RHS>
				HRRZ	T1,T2
  ELSE
    BEGIN
      IF T2<RHS>=LAC
				MOVE	T4,LAC
				CAIE	T4,(T2)
				GOTO FALSE
      THEN
	;IF #=3 THEN LAC+3 ELSE LAC+1;
				CAIE	T3,3
				AOSA	LAC
				ADDM	T3,LAC
      FI;
      IF ACC GEQ 2
				TRNN	T1,16
				GOTO FALSE
      THEN
	;T1<RHS>_13
				HRRZI	T1,15
      ELSE
	;T1<RHS>_0
				HRRZI	T1,0
      FI
    ENDD
  FI
FI;
  IF  ACC=13
				CAIE	T1,15		;T1 CONTAINS ACC
				GOTO	FALSE
  THEN
    BEGIN
    ;T1_(IF #GEQ LAC THEN 12 ELSE LAC)-#;
				MOVE	T1,LAC
				CAML	T3,LAC		;LAST ALLOC.ACC
				MOVEI	T1,14
				SUB	T1,T3
    IF #=3
				CAIE	T3,3
				GOTO	FALSE
    THEN
      BEGIN
	;T4<RHS>_T1<RHS>
				HRRZ	T4,T1
	WHILE T4GEQ 3
				CAIGE	T4,3
				GOTO	FALSE
	DO
	  ;T4_T4-3
				SUBI	T4,3
	OD;
	;T1_T1-T4
				SUB	T1,T4
      ENDD
    FI;
    ;LAC_T1
				MOVEM	T1,LAC
    ENDD
  FI;

 ;T1<LHS>_#;
				HRL	T1,T3
 ;T4<RHS>_ADR(LEXEME);
				HLRZ	T4,T
				ANDI	T4,SYM
  ;T<ADR(LEXME)>_0;
				TLZ	T,SYM
  ;LEXEME<RHS>_RESULTACC;
				HRRZM T1,(T4)
 ;T4<TYPE>_T2<TYPE>;
				HLL	T4,T2
 ;T4<LHS>_EPR,SAME,SIMPLE,ACC;
				TLZ	T4,$KIND!$STATUS!$AM
				TLO	T4,$EXP!$SIM!$ACC
  ;LEXEME<LHS>_T4<LHS>;
				HLLM	T4,(T4)
IF T2<TYPE>=REAL AND T2<AM>=IMM
				TLNN	T2,$TYPE+$AM-$R-$IMM
				TLNN	T2,10000
				GOTO	FALSE
THEN
  BEGIN
    IF OPCODE = MOVM AND CONSTANT IS NEGATIVE
				HLRZ	T4,T
				ANDI	T4,777000
				CAIN	T4,(MOVM 0,0)
				TRNN	T2,400000
				GOTO	FALSE
    THEN
    ; TAKE MAGNITUDE & CONVERT CONSTANT
				MOVNI	T4,(T2)
				HRRI	T2,(T4)
    FI
  ;OPCODE_HRLZI'
				TLZ	T,$KIND!$TYPE
				TLO	T,(HRLZI 0,0)
  ENDD
ELSE
IF # GTR 1   AND T2<TYPE> NEQ INTDIV
				TLNE	T2,$TYPE-$IDI
				CAIG	T3,1
				GOTO	FALSE
THEN
  ;DOUBLE THE OPCODE
				TLO	T,700000
ELSE
  IF T2=ONEWORD CONST IN CT WITH LEFTHANDSIDE=-1 AND OPCODE=MOVE
				TLNN	T2,$VAR!$CONST
				TLNN	T2,$CT-$IMM
				GOTO	FALSE
				HLRZ	T4,T
				ANDI	T4,777000
				CAIE	T4,(MOVE 0,0)
				GOTO	FALSE
				HRRZ	T4,T2
				ADD	T4,CONTAB
				SETCM	T4,1(T4)
				TLNE	T4,777777
				GOTO	FALSE
  THEN
    BEGIN
      ;T2<AM>_IMM;
				TLZ	T2,$CT-$IMM
      ;T2<RHS>_CONSTANT<RHS>;
				SETCA	T4,T4
				HRR	T2,T4
      ;OPCODE_'HRROI';
				TLZ	T,777000
				TLO	T,(HRROI 0,0)
    ENDD
  FI
FI
FI;
IF T2<AM> NEQ ACC  OR  T2<RHS> NEQ T1<RHS>
				HRRZ	T3,T2
				XORI	T3,(T1)
				TLNN	T2,$AM-$ACC
				JUMPE	T3,FALSE
THEN
 ;EMITCODE
				PUSHJ	SP,.EMITCODE
FI;

IF NOT GLOAD
				HRRO	T,KA
				AOJE	T,FALSE
THEN
  BEGIN
  ;T_2*(KEY+REV);
				HLRZ	T,KA
				ANDI	T,SYM
				ADD	T,REV
  ;CLOSE
				PUSHJ	SP,.CLOSE
  ENDD
FI
ENDD
FI;
ZERO(KA)
ENDD




;GLOAD IS A KLUDGE TO PLEASE FILE ALGCOD

PROCEDURE GLOAD;
BEGIN
  ;KA_T<LHS>,777777;..TO INDICATE GLOAD;
				HLLOM	T,KA
  GOTO XLOAD
ENDD
SUBTTL	TEMPCODE SERVICE	* TOCT1/2 *




;TOCT1 AND 2 TRANSFORM AN IMMEDIATE CONSTANT INTO A CONSTANT TABLE
;CONSTANT.

;..TOCT1 ASSUMES ONE WORD CONSTANT IN T3
;..TOCT2 ASSUMES TWO WORD CONSTANT IN (T3;T4)
;..RESULT 23-BIT TAD IN T2;REGISTERS T;T1;T5 ARE NOT AFFECTED
PROCEDURE TOCT1;
BEGIN
  ;SAVE(T,T5);
				PUSH	SP,T
				PUSH	SP,T5
  CON1;(T3);
  ;T2<AM>_$CT;
				HRRZI	T2,(T2)
				TLO	T2,$CT
  ;RESTORE(T,T5);..CONS1 DOES NOT AFFECT T1;
				POP	SP,T5
				POP	SP,T
ENDD




PROCEDURE TOCT2;
BEGIN
  ;SAVE(T,T5);
				PUSH	SP,T
				PUSH	SP,T5
  CON2;(T3,T4);
  ;T2<AM>_$CT;
				HRRZI	T2,(T2)
				TLO	T2,$CT
  ;RESTORE(T5,T);..T1 IS UNAFFECTED BY CONS2;
				POP	SP,T5
				POP	SP,T
ENDD
SUBTTL	TEMPCODE SERVICE	* UNSTACK *

;THE PURPOSE OF UNSTACK IS TO AVOID A SEQUENCE OF POP INSTRUCTIONS
;CORRESPONDING TO  PUSH INSTRUCTIONS GENERATED  TO SAVE INTERMEDIATE
;RESULTS.INSTEAD, THE STACK OPERANDS ARE USED AS STORAGE OPERANDS
;INDEXED BY  THE STACK POINTER AND WHEN NECESSARY THE STACK POINTER IS
;UPDATED WITH A SUB INSTRUCTION WHICH IS GENERATED BY UNSTACK.

PROCEDURE UNSTACK;
BEGIN
  ;T3<SA>_LEXEX<SA>;
				HLRZ	T3,LEXEX
				TRZ	T3,777000
  IF SOMETHING SAVED IN STACK
				JUMPL	SYM,FALSE
				JUMPE	T3,FALSE
  THEN
    BEGIN
      REOPEN;
      ;T3<SA>_LEXEX<SA>;
				HLRZ	T3,LEXEX
				TRZ	T3,777000
      ;LEXEX<SA>_0;
				HRLOI	T2,777000
				ANDM	T2,LEXEX
      ;T3<LHS_T3<RHS>
				HRL	T3,T3
      TOCT(1);
      ;TC[IN+]_'SUB  SP,T2';
				HRLZI	T,(SUB  SP,0)
				PUSHJ	SP,.IPLUNK
      CLOSE
    ENDD
  FI
ENDD
SUBTTL	TEMPCODE SERVICE	* FETCH *

;FETCH IS A VARIATION ON LOAD. IT IS USED TO LOAD AN OPERAND OF A
;BINARY OPERATION OF WHICH THE OTHER OPERAND IS PRESENT IN THE FORM OF
; A SUB EXPRESSION IN TEMPCODE.OTHER THAN LOAD, FETCH WILL FOR INSTANCE
;PUSH THE OPERAND IF IT FINDS THAT THE OTHER OPERAND USES ALL REGS.
;IT ALSO TRIES TO OPTIMIZE THE USE OF ACCUMULATORS  BY LOOKING AT
;ACCUMULATOR CONFLICTS IN THE OPERANDS.

PROCEDURE FETCH;
BEGIN
  REOPEN(LOP);
  IF ONE WORD OPERAND  AND LOP<TYPE> NEQ INTDIV
				TLNE	LOP,$TYPE-$IDI
				T.ONE(LOP)
  THEN
    ;T3_1
				MOVEI	T3,1
  ELSE
    IF LONG REAL
				T.LR(LOP)
    THEN
      ;T3_3
				MOVEI	T3,3
    ELSE
      ;T3_2
				MOVEI	T3,2
    FI
  FI;..T3 CONTAINS NOW #;

  ;T1_(IF  # GEQ LAC THEN 12 ELSE LAC)-#;..T1<RHS> CONTAINS NOW ACC;
				MOVE	T1,LAC
				CAML	T3,LAC
				MOVEI	T1,14
				SUB	T1,T3
IF #=3 
				CAIE	T3,3
				GOTO	FALSE
THEN
  BEGIN
    ;T4<RHS>_T1<RHS>;
				HRRZ	T4,T1
    WHILE T4 GEQ 3
				CAIGE	T4,3
				GOTO	FALSE
    DO
      ;T4_T4-3
				SUBI	T4,3
    OD;
    ;T1_T1-T4
				SUB	T1,T4
  ENDD
FI
  ;T1<LHS>_#;
				HRL	T1,T3

  IF #=2 OR #=3
				TRNE	T3,2
    ;T3_6 OR 7
				TROE	T3,5
				GOTO	FALSE
  THEN
    ;CHANGE 2 INTO 3
				HRRI	T3,3
  FI;..T3 CONTAINS NOW PATTERN;

  ;T3_IF LOP<TYPE>=INTDIV THEN 1 ELSE T3;
				TLNN	LOP,$TYPE-$IDI
				MOVEI	T3,1

  ;T3^(T1);..SHIFT PATTERN OVER 'ACC' BIT POSITIONS;
				LSH	T3,(T1)
  ;T4<RHS>_HANDLE(SYM);
				HRRZ	T4,LEXEX+SYM(REV)
  ;T4<RHS>_TC[HANDLE(SYM)]<LHS>;..USEDACCS(SYM);
				HLRZ	T4,(T4)
				MOVE	T2,LOP
  ;LOP<LHS>_LOP<TYPE>;
				TLZ	LOP,$KIND!$STATUS!$AM	;CLEAR
  ;..BOOK USED REGISTERS;			;
				HRLZ	T3,T3;$	;
				IORM	T3,HANDLE;$
  ;LAC_T1<RHS>;..LAC _ ACC;
				HRRM	T1,LAC;$;
  IF NO ACC CONFLICT
				TLNE	T3,(T4) ;
				GOTO	FALSE
  THEN
    BEGIN
      ;LOP<RHS>_T1<RHS>;..PUT RESULT ACC IN RESULT LEXEME;
				HRR	LOP,T1
      ;T_'MOVE ACC,0';
				LSH	T1,5
				HRLZI	T,<MOVE 0,0>_-22(T1)
            IF # GTR 1  AND LOP<TYPE> NEQ INTDIV
				TLNE	LOP,$TYPE-$IDI
				TLNN	T1,100
				GOTO	FALSE
            THEN
  	;DOUBLE THE OPCODE
				TLO	T,700000
            FI;
      ;LOP<LHS>_EXP,SAME,SIMPLE,ACC
				TLO	LOP,$EXP!$SIM!$ACC
    ENDD
  ELSE
    BEGIN
      ;LOP<LHS>_EXP,SAME,SIMPLE,SP;
				TLO	LOP,$EXP!$SIM!$SP
      ;T3_SA(SYM);
				HLRZ	T3,LEXEX+SYM(REV)
				TRZ	T3,777000
      ;T3_T3-(# LEQ 1 OR LOP<TYPE>=INTDIV);
				TLNE	LOP,$TYPE-$IDI
				TLNN	T1,2
				SUBI	T3,1

      ;LOP<RHS>_2^18-(T3+1);..OFFSET FROM STACKTOP IS RESULT ADDRESS;
				MOVNI	T3,(T3)
				ADDI	T3,777777
				HRR	LOP,T3
      ;T3<RHS>_SA(LOP);
				MOVNI	T,LOP(REV)
				HLRZ	T3,LEXEX(T)
EDIT(024); IF TYPE IS INTDIV, ONLY ALLOCATE ONE WORD !
      ;T3_T3+1+(# GEQ 2 AND LOP<TYPE> NEQ INTDIV); [E024]
				TLNE	LOP,$TYPE-$IDI	; [E024]
				TLNN	T1,2
				AOJA	T3,.+2
				ADDI	T3,2
      ;SA(LOP)_T3;
				HRLM	T3,LEXEX(T)
      ;T_'PUSH SP,0';
				HRLZI	T,(PUSH SP,0)

	IF # GTR 1 AND LOP<TYPE> NEQ INTDIV
				TLNE	LOP,$TYPE-$IDI
				TLNN	T1,2
				GOTO	FALSE
      THEN
        ;DOUBLE OPCODE
				TLO	T,700000
				TLZ	T,060000
      FI;

    ENDD
  FI;
  IF LAST INSTR OF LOP PORTION=MOVE OR DMOVE
				MOVNI	T1,LOP(REV)
				HRRZ	T1,LEXEX(T1)
				HLRZ	T4,-1(T1)
				TRNE	T4,577000
				SUBI	T4,500000
				TRNE	T4,577000
				GOTO	FALSE
  THEN
    ;LAST INSTR<OPCODE,ACC>_T<LHS>
				ANDI	T4,$AM
				TLO	T,(T4)
				HLLM	T,-1(T1)
  ELSE
    ;PLUNKI(LOP)
				PUSHJ	SP,.IPLUNK
  FI;
  CLOSE(LOP)
ENDD
SUBTTL	TEMPCODE SERVICE	* MERGEPORTIONS *

;MERGE PORTIONS GETS AS INPUT TWO PORTIONS IN TEMPCODE AND CONCATENATES
; THOSE INTO ONE AS IS DONE WITH TWO CIRCULAR LISTS.
;WHICH OF THE PORTIONS IS HEAD AND WHICH IS TAIL DEPENDS ON THE RESULT
;OF REVORDER WHICH RESULT IS REFLECTED IN THE VALUE OF REV.
;REV=SYM MEANS ORDER NOT REVERSED,REV=LOP MEANS ORDER REVERSED.
;IF THE RESULT REG OF THE HEAD IS USED IN THE TAIL, AN APPROPRIATE
;SAVE INSTRUCTION IS INSERTED.THE RESULT OF MERGEPORTIONS IS ONE OPEN
;PORTION WHICH CAN BE EXTENDED WITH THE BINARY OPERATION.
;THE MEMOS EXPLAIN THIS IN MORE DETAIL.

PROCEDURE MERGEPORTIONS;		;..DEPENDS ON THE VALUE OF REV;
  BEGIN
   IF ERROR LEXEME
				SKIPL	SYM
				JUMPG	LOP,FALSE
   THEN
     ERRLEX
   ELSE
    BEGIN
    IF  ONE WORD OPERAND OR POINTER
				TLNN	LOP,20000
				GOTO TRUE
				T.PTR(LOP)
    THEN
      ;T3_1;..PATTERN OF USED ACCS(LOP);
				HRLZI T3,1
    ELSE
      IF  LONGREAL OPERAND
				T.LR(LOP)
      THEN
	;T3_7;..3ACCS USED(LOP);
				HRLZI T3,7
      ELSE 
	;T3_3;..2 ACCS USED(LOP);
				HRLZI T3,3
      FI
    FI;
    IF  ADMODE(LOP)=ACC OR PTR
				T.ACC(LOP)
    THEN
      BEGIN
	;T3^(LOP);..SHIFT OVER 'ACC' BIT POSITIONS;
				LSH  T3,(LOP)
				TLZ  T3,770000
	;T1_HANDLE(SYM);
				HRRZ	T1,LEXEX+SYM(REV)
	IF ACC CONFLICT
				AND	T3,(T1)
				JUMPE	T3,FALSE
	THEN
	  BEGIN
	    IF ADMODE=PTR
				T.PTR(LOP)
	    THEN
	      BEGIN
		;..SAVE LOP<KIND,TYPE,STATUS>;
				TLZ	LOP,$AM
				HLLZM	LOP,KA
		;LOP<LHS>_EXPR,INT,SIM,ACC;
				HRLI	LOP,$EXP!$I!$SIM!$DECL!$ACC
		;FETCH;..PLACES RESULT LEXEME IN LOP;
				PUSHJ	SP,.FETCH
		  ; LOP<AM>_IF ACC THEN PTR ELSE ISP;
				TLO	LOP,30
		;..RESTORE LOP<KIND,TYPE,STATUS>;
				TLZ	LOP,777777-$AM
				IOR	LOP,KA
		 ZERO(KA)
	      ENDD
	    ELSE
	      ;FETCH
				PUSHJ	SP,.FETCH
	    FI;
	  ENDD
	FI
      ENDD
    FI;
				MOVNI	T,LOP(REV)
INTERCHANGE:  ;T1_HANDLE(LOP);
				HRRZ	T1,LEXEX(T)
    ;T2_HANDLE(SYM);
				HRRZ	T2,LEXEX+SYM(REV)
    ;T3_PORTION POINTER(LOP);
				MOVE	T3,(T1)
    ;T3#PORTION POINTER(SYM);
				EXCH	T3,(T2)
    ;T3#PORTION POINTER(LOP);
				EXCH	T3,(T1)
    ;T3<LHS>_USEDACCS(LOP) OR USEDACCS(SYM);
				IOR	T3,(T1)
				HRRI	T3,0
    ;PORTION POINTER(SYM)<LHS>_T3;
				HLLM	T3,(T2)
    REOPEN(SYM)
  ENDD
FI
ENDD
SUBTTL	TEMPCODE SERVICE	* CGELSE *

;CGELSE COMBINES THE THEN AND ELSE EXPRESSIONS INTO ONE AND INSERTS
;THE NECESSRAY TYPE CONVERSIONS.IT ALSO TAKES CARE OF UNEQUAL STACK
;LENGTHS AND DIFFERENT RESULT ACCUMULATORS. FURTHERMORE IT MODIFIES
;ONE OF THE EXPRESSIONS IF NECESSARY  SUCH THAT BOTH HAVE THE SAME
;ADDRESSMODE.FOR INSTANCE   IF BE THEN A ELSE A+1   WILL RESULT
;IN AN EXPRESSION IN AN ACCUMULATOR BECAUSE OF   A+1  AND SO CGELSE
;WILL INSERT A LOAD(A) INTO THE SAME REG AS IS USED BY A+1.

PROCEDURE CGELSE;
BEGIN
IF LOP=ERRLEX OR SYM=ERRLEX
				CAIL	LOP,0
				JUMPG	SYM,FALSE
THEN
  ERRLEX
ELSE
  BEGIN
;REV_-SYM;
				MOVNI	REV,SYM
;T3_LOP<TYPE>;
				HLRZ	T3,LOP
				ANDI	T3,$TYPE
;T4_SYM<TYPE>;
				HLRZ	T4,SYM
				ANDI	T4,$TYPE

IF LOP<TYPE> NEQ SYM<TYPE>
				CAIN	T3,(T4)
				GOTO	FALSE
THEN
  BEGIN
    IF LOP<TYPE> GTR SYM<TYPE>
				CAIG	T3,(T4)
				GOTO	FALSE
    THEN
      ;REVERSE;
				MOVNI	REV,SYM+LOP(REV)
				EXCH	LOP,SYM
				EXCH	T3,T4
    FI;
    IF SYM<TYPE> OR LOP<TYPE> NOT ARITHMETIC
				TRNE	T3,$ARC
				GOTO	TRUE
				TRNN	T4,$ARC
				GOTO	FALSE
    THEN
      FAIL(65,HARD,DEL,TYPES DO NOT MATCH)	;
    FI;
    ;LOAD(LOP,A0);
				HRLZI	T1,(<MOVE 0,(LOP)>)
				PUSHJ	SP,.LOAD
    REOPEN(LOP);
    ;T_JSP AX,0($ST)';
				HRLZI	T,(<JSP AX,($ST)>)
    KILLAX;


    IF SYM<TYPE>=REAL
				TLNE	SYM,$TYPE-$R
				GOTO	FALSE
    THEN
      BEGIN
	  ;T<RHS>_PRLIB+15;
				HRRI	T,PRLIB+17
	;LOP<LHS>_'EXP,REAL,SIMPLE,ACC';
	;LOP<RHS>_0;
				HRLZI	LOP,$EXP!$R!$SIM!$DECL!$ACC
      ENDD
    ELSE
      IF SYM<TYPE>=LONGREAL
				TLNE	SYM,$TYPE-$LR
				GOTO	FALSE
      THEN
	IF LOP<TYPE>=INTEGER
				TLNE	LOP,$TYPE-$I
				GOTO	FALSE
	THEN
	  BEGIN
	    ;T<RHS>_PRLIB+18;
				HRRI	T,PRLIB+22
	    ;LOP_'EXP,LR,SIM,ACC;
				HRLZI	LOP,$EXP!$LR!$SIM!$DECL!$ACC
	  ENDD
	ELSE
	  BEGIN
	    ;T<RHS>_PRLIB+24;
				HRRI	T,PRLIB+30
	    ;LOP_'EXP,LONGREAL,SIMPLE,ACC
				HRLZI	LOP,$EXP!$LR!$SIM!$DECL!$ACC
	  ENDD
	FI
      FI
    FI;
    PLUNKI;
    CLOSE(LOP)
  ENDD
FI;
;T3_LOP<AM>;
				HLRZ	T3,LOP
				ANDI	T3,$AM
;T4_SYM<AM>;
				HLRZ	T4,SYM
				ANDI	T4,$AM

IF T3 NEQ ACC
				CAIN	T3,$ACC
				GOTO	FALSE
THEN
  BEGIN
    IF T4=ACC OR T3 LESS T4
				CAIN	T4,$ACC
				GOTO	TRUE
				CAIL	T3,(T4)
				GOTO	FALSE
    THEN
      ;REVERSE
				MOVNI	REV,SYM+LOP(REV)
				EXCH	LOP,SYM
				EXCH	T3,T4
    FI;
    IF T4 NEQ PTR
				CAIN	T4,$PTR
				GOTO	FALSE
    THEN
	LOAD(LOP,15)
     FI
  ENDD
FI;
IF LOP<AM>=SYM<AM>
				HLLZ	T3,LOP
				XOR	T3,SYM
				TLNE	T3,$AM
				GOTO	FALSE
THEN
  IF LOP<RHS> NEQ SYM<RHS>
				HRRZ	T3,LOP
				CAIN	T3,(SYM)
				GOTO	FALSE
  THEN
    BEGIN
      IF  LOP<RHS>=0
				JUMPN	T3,FALSE
      THEN
	;REVERSE
				MOVNI	REV,LOP+SYM(REV)
				EXCH	LOP,SYM
      FI;
      ;SYM<AM>_ACC;
				TLZ	SYM,$AM
				TLO	SYM,$ACC
      ;T1_LOP<RHS>;
				HRRZ	T1,LOP
      LOAD(SYM, );
      ;SYM_LOP;
				MOVE	SYM,LOP
    ENDD
  FI
ELSE
  BEGIN
    ;T1_LOP<RHS>;
				HRRZ	T1,LOP
    LOAD(SYM, );
    ;SYM_LOP;
				MOVE	SYM,LOP
  ENDD
FI;

IF REV=-LOP
				TRNE	REV,2
				GOTO	FALSE
THEN
  ;REVERSE
				MOVNI	REV,LOP+SYM(REV)
				EXCH	LOP,SYM
FI;
REOPEN(LOP);
IF LEXEX<SA> NEQ LLEXEX<SA>
				HLRZ	T3,LEXEX+2
				ANDI	T3,777
				HLRZ	T4,LEXEX
				ANDI	T4,777
				CAIN	T4,(T3)
				GOTO FALSE
THEN
  ;UNSTACK(LOP)
				HRLOI	T2,777000
				ANDM	T2,LEXEX+2
				JUMPE	T3,.+5
				HRLI	T3,(T3)
				TOCT(1)
				HRLZI	T,(SUB SP,0)
				PUSHJ	SP,.IPLUNK
FI;
;TC[IN+]_'JRST 0,0';
				HRLZI	T,(JRST 0,0)
				PLUNKI
;TC[IN+]_'TCELSE 0,0';
				HRLZI	T,(TCELSE 0,0)
				PLUNKI
;TC[IN+]_'TCOT;
				HRLZI	T,(TCOT 0,0)
				PLUNKI

CLOSE(LOP);

IF LEXEX<SA> NEQ LLEXEX<SA>
				HLRZ	T3,LEXEX+2
				ANDI	T3,777
								HRLOI	T4,777000
				ANDM	T4,LEXEX+2
HLRZ	T4,LEXEX
				ANDI	T4,777
				CAIN	T4,(T3)
				GOTO FALSE
THEN 
UNSTACK
FI;

;LOP<AM>_SP;
				TLZ	LOP,$AM
				TLO	LOP,$SP
MERGEPORTIONS;
;LOP_SYM;
				TLO	SYM,$EXP!$DECL
				MOVE	LOP,SYM
;TC[IN+]_'TCFI 0,0';
				HRLZI	T,(TCFI 0,0)
				PLUNKI
CLOSE(SYM);
COMBLEX

ENDD
FI
ENDD
SUBTTL	TEMPCODE SERVICE	* REVORDER *

;THE GENERAL RULE FOR OPTIMIZATION IS: EVALUATE THE MORE COMPLI-
;CATED EXPRESSION FIRST. BUT THAT IS NOT ALWAYS ALLOWED BECAUSE OF THE
;LEFT TO RIGHT EVALUATION RULE.REVORDER INVESTIGATES IF IT IS DESIRABLE
;TO REVERSE, AND IF SO IT CHECKS THAT IT IS ALLOWED.
;IT IS DESIRABLE TO REVERSE IF LOP REPRESENTS A VARIABLE OR CONSTANT
;AND SYM A V-EXPR(I.E. AN EXPR WITHOUT ANY PROCIDENTIFIERS OR FORMALS)
;OR IF LOP IS A  VARIABLE OR V-EXPR AND SYM IS A P-EXPR (I.E. AN EXPR
;WHICH CONTAINS A PROC IDENTIFIER OR FORMAL.
;THE ROUTINE IS BASED ON SOME CAREFULLY ANALYZED DESIGN, WHICH IS 
;DESCRIBED COMPLETELY IN THE MEMOS

PROCEDURE REVORDER;
BEGIN
;T3_0;..T3 INDICATES WHETHER OR NOT REVERSE WAS ALLOWED;
				SETZ	T3,
IF SYM=ERRORLEX. OR LOP=ERRORLEX.
				CAIL	LOP,0
				JUMPG	SYM,FALSE
THEN
  ERRLEX
ELSE
  IF LOP<KIND>=ARRAY AND SYM<AM> NEQ SINGLE
				T.ARR(LOP)
				TN.SINGLE(SYM)
  THEN
    ;REVERSE ORDER
				MOVNI	REV,SYM+LOP(REV)
				EXCH	LOP,SYM
 ELSE
IF LOP<LEX>GEQ 0 AND SYM<AM> NEQ SINGLE
				MOVEI	T,LOP(REV)
				ANDI	T,2
				SKIPL	T1,LEXEX(T)
				T.COGE(SYM)
THEN
  IF SYM<LEXEX> GEQ 0 OR LOP<AM>=CONST
				TLNN	LOP,$AM-$CT
				GOTO	TRUE
				SKIPGE	T2,LEXEX+SYM(REV)
				GOTO	FALSE
THEN
    IF LOP<AM> = SINGLE
				T.SINGLE(LOP)
    THEN
      ;REVERSEORDER
				MOVNI	REV,SYM+LOP(REV)
				EXCH	LOP,SYM
    ELSE
      BEGIN
        IF LOP<AM>=ACC  AND  LOP<TYPE>TWO WORD OPERAND
				HLRZ	T,LOP
				ANDI	T,$AM
				CAIN	T,$ACC
				T.TWO(LOP)
        THEN
          ;T_3
				MOVEI	T,3
        ELSE
          ;T_1
				MOVEI	T,1
        FI;
        ;T^LOP<ACC>;..SHIFT OVER 'ACC' BIT POSITIONS;
				LSH	T,(LOP)
          IF LOP<ACC> AND SYM<USED ACCS> NEQ 0  OR  OP=ASSIGN
				MOVE	T2,(T2)			;..GET SYM<PORTION PTR>
				TLNE	T2,(T)
				GOTO TRUE
				MOVE	T,OP
				CAME	T,ZASS
				GOTO	FALSE
          THEN
            ;REVERSEORDER;
				MOVNI	REV,SYM+LOP(REV)
				EXCH	LOP,SYM
          FI
      ENDD
   FI
  ELSE
    IF LOP<BL>+SYM<BL> GEQ 0 AND (LOP<COMPNAME>AND SYM<COMPNAME>)=0
				TLZ	T1,777
				ADD	T1,T2
				JUMPL	T1,FALSE
				MOVE	T2,COMPNAME(T)
				XORI	T,2
				AND	T2,COMPNAME(T)
				JUMPN	T2,FALSE
    THEN
      ;REVERSEORDER
				MOVNI	REV,SYM+LOP(REV)
				EXCH	LOP,SYM
    ELSE
      ;T3_1;..INDICATE REVERSE WAS NOT ALLOWED;
				MOVEI	T3,1
    FI
  FI
 ELSE
    ;T3_SYM<LEXEX> LESS ZERO;
				SKIPGE	LEXEX+SYM(REV)
				MOVEI	T3,1
FI
FI
FI
ENDD
SUBTTL	TEMPCODE SERVICE	* CGINT *

;CGINT HANDLES THE INTEGRATION OF SUBSCRIPT EXPRESSIONS
PROCEDURE CGINT;	;..LEXEME IS IN SYM;
BEGIN
;REV_SYM;
				MOVEI	REV,SYM
IF SYM<TYPE> NEQ INTEGER
				TLNN	SYM,$TYPE-$I
				GOTO	FALSE
THEN
  BEGIN
    ;T_'INTEGER';
				HRRZI	T,$I
    CONVERT
  ENDD
FI
ENDD;
SUBTTL	OBCODE SERVICE	* MOB *



;MOB (MOVE TO OBCODE) TRANSFERS A PORTION TO THE OUTPUT BUFFER
;BY CALLING MPS (MOVE PSEUDO).SUCH A PORTION IS USUALLY THE RESULTING
;INSTRUCTION SEQUENCE OF A COMPLETE STATEMENT.
PROCEDURE MOB;
BEGIN
 REGISTER TX;
 OWN TCSTART,TCMIN,TOLINK;
FORMAL ISTHUNK;

IF NOT ERROR FOUND
				TNGB(ERRF)
THEN
BEGIN
IF THIS IS FIRST EXPR. PORTION SINCE THUNKS WERE PUT OUT
				HRRZ	T,ISTHUNK
				JUMPN	T,FALSE
				SKIPN	T,THUNK
				GOTO	FALSE
THEN
  BEGIN
    ;RESTORE NON LOCAL REGISTER AX TO WHAT IT WAS BEFORE JRST;
    ;CAX_THUNK<LHS>;
				HLRZM	T,CAX
    ;..FIX UP THE JRST OVER THE THUNKS;
    FIXREL;

    ZERO(THUNK);
  ENDD
FI;

 ;TCSTART_TX_SYM<HANDLE>;
				HRRZ	TX,LEXEX;$
				MOVEM	TX,TCSTART;$
 ;TCMIN_TC[TX]<RHS>;
				HRRZ	T,(TX);$
				MOVEM	T,TCMIN;$
 ;..LOOP IS ENTERED WITH TX POINTING TO THE PORTION POINTER;
 LOOP
  BEGIN
    ;..SET TX TO POINT TO TOP OF NEXT PORTION;
    ;INDEX_TX_TC[TX]<RHS>;
				HRRZ	TX,(TX);$
				HRRZM	TX,INDEX
    IF TX LSS TCMIN
				CAML	TX,TCMIN;$
				GOTO	FALSE;$
      THEN
	 ;TCMIN_TX;
				MOVEM	TX,TCMIN;$
    FI;
    ;..WHILE IS ENTERED POINTING AT THE TOP OF A PORTION AND WILL
    ;..PROCESS ONE ENTIRE PORTION;
    WHILE PORTION POINTER NE (T_TC[TX])
				MOVE	T,(TX);$
				SETCM	T1,T;$
				TLNN	T1,770000;$
				GOTO	FALSE;$
       DO
	 BEGIN
	   MPS;
	   ;TX_INDEX_TX+1;
				AOS	TX,INDEX;$
	 ENDD
       OD;
   ENDD;
 AS TCSTART NE TX
				CAME	TX,TCSTART;$
				GOTO	TRUE;$
 SA;
 ;INDEX_TCMIN;
 ;HANDLE_770000,TCMIN;
				MOVE	T,TCMIN;$
				MOVEM	T,INDEX;$
				HRLI	T,770000;$
				MOVEM	T,HANDLE;$
ENDD
FI;
 LACINIT
ENDD
SUBTTL	OBCODE SERVICE	* MPS *

;MPS HANDLES AN INSTRUCTION IN TWO STEPS.
;STEP 1: IF THE OPCODE IS A PSEUDO OPCODE, IT IS DECODE BY CALLING
;THE APPROPRIATE ROUTINE (FOR INSTANCE QDMOVE FOR A DOUBLE MOVE)
;STEP2: DEPENDING ON  ADDRESS MODE $AM,MPS CALLS A ROUTINE TO DECODE THE
;SYMBOLIC ADDRESS PART.
;THE TABLES FOLLOWING MPS REFLECT THE VARIOUS ADDRESS MODES AND
;PSEUDO OPCODES
PROCEDURE MPS;..INSTRUCTION IS IN T;
BEGIN
  IF  PSEUDOOPCODE
				SETCM	T1,T
				TLNE	T1,700000
				GOTO	FALSE
  THEN
	BEGIN
	; T1<RHS>_T<OPCODE>;
				HLRZ	T1,T
				LSH	T1,-11
				TRZ	T1,700
				CAIL	T1,22
	GOTO	@PSTABLE(T1)
				MOVE	T1,KIOPS(T1)
				DPB	T,[
				POINT	27,T1,35]
				MOVE	T,T1
				SETCM	T1,T
				TLNE	T1,700000
				GOTO	.+5
				HLRZ	T1,T
				LSH	T1,-11
				TRZ	T1,700
				GOTO	@PSTABLE(T1)
    ENDD
  FI;

.MTAD:    ;T4_0;..NO OFFSET;
				SETZ	T4,

.MOFF:      ;T4_T4+KA;
				ADD	T4,KA
   ; T1<RHS>_T<AM>;
				HLRZ	T1,T
				ANDI	T1,$AM
  ;..CLEAR INDIRECT BIT AND INDEX FIELD OF T;
				TLZ	T,$AM
  ; IF T<AM>=FIX OR IMM OR CT DO AMCT;
				CAIG	T1,$CT
				GOTO	.AMCT
  ; IF ADMODE GEQ 16 THEN COMPLEMENT;..THIS IS A PREPARATION FOR THE JUMPTABLE;
				CAIL	T1,20
				TRC	T1,$AM
  GOTO @AMSEL(T1)
ENDD
; AM HAS BEEN CLEARED;T4=OFFSET;
AMSEL:	XWD 0,.AMAX
	XWD 0,.AMRA
	XWD 0,.MREL
	XWD 0,.AMPTR
	XWD 0,.AMNEXT
	XWD 0,.AMISP
	XWD 0,.AMPVAL
	XWD 0,.AMST
	XWD 0,.AMSELF
	XWD 0,.AMPRV
	XWD 0,.AMOF2
	XWD 0,.AMOF3
	XWD 0,.AMACC
	XWD 0,.AMSP

PSTABLE:XWD 0,.QDMOVE	;700
	XWD 0,.QDPUSH	;701
	XWD 0,.QDMOVEM	;702
	XWD 0,.QTCTHEN	;703
	XWD 0,.QTCELSE	;704
	XWD 0,.QTCFI	;705
	XWD 0,0	;706
	XWD 0,0	;707
	XWD 0,.DMVN	;710
	XWD 0,.QTCTYDES ;711
	XWD 0,.DMVNM	;712
	XWD 0,.QTCSF	;713
	XWD 0,.QDMOVE	;714
	XWD 0,0       	;715
	XWD 0,.QLF	;716
	XWD 0,.QLF	;717
	XWD 0,.QLF	;720
	XWD 0,.QLF	;721
	XWD 0,.QLF	;722
	XWD 0,.QLF	;723
	XWD 0,.POWCONV	;724
	XWD 0,.POWCONV	;725
	XWD 0,.POWCONV	;726
	XWD 0,.POWCONV	;727
	XWD 0,.POWCONV	;730
	XWD 0,.POWCONV	;731
	XWD 0,.POWCONV	;732
	XWD 0,.POWCONV	;733
	XWD 0,.POWCONV	;734
	XWD 0,.POWCONV	;735
	XWD 0,.POWCONV	;736
	XWD 0,.POWCONV	;737
        XWD 0,.QTCAD    ;740
SUBTTL	OBCODE SERVICE	* QDPUSH *



;TO PUSH A DOUBLE WORD OPERAND. A LONG REAL IS HERE TREATED AS A
;TWO WORD OPERAND.SPECIAL CARE MUST BE TAKEN FOR THE CASE OF A
;POINTER IN A0 SINCE THIS REGISTER CANNOT BE USED AS AN INDEX REG.

PROCEDURE QDPUSH;
BEGIN
  OWN INSTR;
    ; T<OPCODE>_PUSH;
				TLZ	T,777000
				TLO	T,(PUSH	0,0)
    ; INSTR_T;
				MOVEM	T,INSTR
    ; MTAD;
				PUSHJ	SP,.MTAD
    IF T<AM>=PTR AND T<RHS>=0
				HRLZI	T1,$PTR
				XOR	T1,T
				TLNN	T1,$AM
				TRNE	T,777777
				GOTO	FALSE
    THEN
      BEGIN
	;T_ADDI A0,1;
				HRLZI	T,(ADDI 0,0)
				ADDI	T,1
	MABS;
	;T4_0;..NO OFFSET;
				MOVEI	T4,0
      ENDD
    ELSE
      ;T4_1;
				MOVEI	T4,1
    FI;

    ;T_INSTR;
				MOVE	T,INSTR
    ;MOFF
				PUSHJ	SP,.MOFF

ENDD
SUBTTL	OBCODE SERVICE	* QDMOVE *

;DOUBLE MOVE MUST ALSO HANDLE A POINTER IN A0 IN A SPECIAL WAY
;BECAUSE A0 CANNOT BE USED AS INDEX REG.
;IF THE ADDRESS MODE IS SELF , THE NEXT REG MUST BE LOADED BEFORE
;THE REG ITSELF IN ORDER NOT TO OVERWRITE THE POINTER.

PROCEDURE QDMOVE;
BEGIN
  OWN INSTR;
  IF T<AM> NEQ ACC OR T<ACC> NEQ T<RHS>
				HLRZ	T1,T
				ANDI	T1,777-$AM
				LSH	T1,-5
				SUBI	T1,(T)
				TLNN	T,$AM-$ACC
				JUMPE	T1,FALSE
  THEN
    BEGIN
      ; T<OPCODE>_'MOVE';
				TLZ	T,500000
    IF T<AM>=PTR AND T<ACC>=T<RHS>
				HRLZI	T3,(T)
				LSH	T3,5
				XOR	T3,T
				HLRZ	T1,T
				ANDI	T1,$AM
				CAIN	T1,$PTR
				TLNE	T3,777-$AM
    				GOTO	FALSE
    THEN
      BEGIN
	;T<RHS>_0;
				HLLZ	T,T
	;T<AM>_SELF;
				MOVEI	T1,$SELF
				TLZ	T,$AM
				TLO	T,(T1)
      ENDD
    FI;

 ;   INSTR_T;..SAVE INSTRUCTION;
				MOVEM	T,INSTR

    IF T<AM> = SELF AND T<ACC> = 0
				CAIN	T1,$SELF
				TLNE	T,777-$AM
				GOTO	FALSE
    THEN
      BEGIN
	;T<AM>_NEXT
				TLZ	T,$AM
				MOVEI	T1,$NEXT
				TLO	T,(T1)
	;INSTR_T
				MOVEM	T,INSTR
	;T<LHS>_'MOVE A1,A0'
				HRLI	T,(MOVE A1,A0)
	MABS;
	;T_INSTR;..POINTER NOW IN A1;
				MOVE	T,INSTR
      ENDD
    FI;
    IF T<AM> NEQ SELF
				CAIN	T1,$SELF
				GOTO	FALSE
    THEN
      BEGIN
	;MTAD;
				PUSHJ	SP,.MTAD
	;T_INSTR;
				MOVE	T,INSTR
     ENDD
    FI;
  ; T<ACC>_ACC+1;
				HRLZI	T4,40
				ADD	T,T4
      ; OFFSET_1;
				HRRZI	T4,1
    IF T<AM>=NEXT
				HLRZ	T1,T
				ANDI	T1,$AM
				CAIE	T1,$NEXT
				GOTO	FALSE
    THEN
      ;T<AM>_SELF
				HRRZI	T1,$SELF
				TLZ	T,$AM
				TLO	T,(T1)
    ELSE
      IF T<AM>=SELF
				CAIE	T1,$SELF
				GOTO	FALSE
      THEN
	;T<AM>_PRV
        			HRRZI	T1,$PRV
				TLZ	T,$AM
				TLO	T,(T1)
      FI
    FI;
      ; MOFF;
				PUSHJ	SP,.MOFF
    ;T_INSTR;
				MOVE	T,INSTR
    IF T<AM>=SELF
				HLRZ	T1,T
				ANDI	T1,$AM
				CAIE	T1,$SELF
				GOTO	FALSE
    THEN
      ;MTAD
				PUSHJ	SP,.MTAD
    FI
    ENDD
  FI

ENDD
SUBTTL	OBCODE SERVICE	* QTCTHEN *

;THEN MUST PRESERVE THE LOCATION IN OBCODE (POINTED AT BY RA)
;WHICH CONTAINS THE JUMP INSTRUCTION OVER THE THEN PART.

PROCEDURE QTCTHEN;
BEGIN
  ;TC[INDEX]<RHS>_TOLINK;
				HRRZ	T,TOLINK
				HRRM	T,(TX)
  ;TOLINK_INDEX;
				HRRM	TX,TOLINK
  ;TX_INDEX_INDEX+1;
				AOS	TX,INDEX
  ;TC[INDEX]<LHS>_CAX;..SAVE CURRENT AX OF IFEXPR;
				HRLZ	T,CAX
				HLLM	T,(TX)
  ; TC[INDEX]<RHS>_RA-1;..THE LOC TO BE FIXED UP AT ELSE;
				HRRZ	T,RA
				SUBI	T,1
				HRRM	T,(TX)

ENDD
SUBTTL	OBCODE SERVICE	* QTCELSE *

;ELSE FIXES UP THE JUMP OVER THE THEN PART AND PRESERVES THE 
;LOCATION IN OBCODE THAT CONTAINS THE JUMP OVER THE ELSE PART

PROCEDURE QTCELSE;
BEGIN
  ; T3_TOLINK;
				HRRZ	T3,TOLINK
  ; TOLINK_INDEX;
				HRRZM	TX,TOLINK
  ;TC[INDEX]<RHS>_TC[T3]<RHS>;..TRANSFER OLD TOLINK;
				HRRZ	T2,(T3)
				HRRM	T2,(TX)
  ; INDEX_TX_INDEX+1;
				AOS	TX,INDEX
  ; TC[INDEX]<LHS>_CAX;..SAVE CURRENT AX OF THEN EXPR;
				HRLZ	T,CAX
				HLLM	T,(TX)
  ; CAX_TC[T3+1]<LHS>;..RESTORE CURRENT AX OF IF EXPR;
				HLRZ	T,1(T3)
				HRRZM	T,CAX
  ; TC[INDEX]<RHS>_RA-1;..THE LOC TO BE FIXED UP AT FI;
				HRRZ	T,RA
				SUBI	T,1
				HRRM	T,(TX)
  ; T_TC[T3+1]<RHS>;..THE LOC TO BE FIXED UP NOW;
				HRRZ	T,1(T3)
RAFIX
ENDD
SUBTTL	OBCODE SERVICE	* QTCFI *

;FI FIXES UP THE JUMP OVER THE ELSE PART

PROCEDURE QTCFI;
BEGIN
  ; T3_TOLINK;
				HRRZ	T3,TOLINK
  ; TOLINK_TC[T3]<RHS>;..RESTORE OLD TOLINK;
				HRRZ	T2,(T3)
				HRRM	T2,TOLINK
  ; T2_TC[T3+1]<LHS>;..GET CURRENT AX OF THEN EXPR;
				HRRZ	T2,1(T3)
IF  T2 NEQ CAX
				CAMN	T2,CAX
				GOTO	FALSE
THEN
  ; CAX_0;
				SETZM	CAX
FI;
  ; T_TC[T3+1]<RHS>;..THE LOC TO BE FIXED UP NOW;
				HRRZ	T,1(T3)
RAFIX

ENDD
SUBTTL	OBCODE SERVICE	* QTCTYDES *

;TYDES PROCESSES THE ACTUAL PARAMETER DESCRIPTORS THAT FOLLOW A
;PROCEDURE CALL. IT FILLS IN THE SYMBOLIC (P,Q)-ADDRESS FOR PARAM,
;MORE EXTENSIVELY DESCRIBED IN THE MEMOS

PROCEDURE QTCTYDES;
BEGIN
REGISTER TX;
OWN STOP;
  ;TX_INDEX;
				HRRZ	TX,INDEX;$
  ;STOP_T<RHS>+TX<RHS>;
				HRRZ	T2,1(TX)
				ADD	T2,TX
				HRRZM	T2,STOP

WHILE TX LESS STOP
			CAML	TX,STOP
			GOTO	FALSE
DO
BEGIN
  ;TX_ADDRESS(NEXT INSTR);
  ;T_TC[TX];
				MOVEI	T,1(TX)
				HRRZI	TX,(T)
				MOVE	T,(TX)
				TLC	T,770000
				TLCN	T,770000
				JRST	.-4
				MOVEM	TX,INDEX
  ;CLEAR DECL.BIT;
				TLZ	T,$DECL
  ;T<STATUS>_T<STATUS>*(T<STATUS> NEQ STMT);
				TLC	T,$STATUS
				TLNE	T,$STMT
				TLC	T,$STATUS

IF T<$X>=DYNAMIC
				TLNN	T,$X
				GOTO	FALSE
  THEN
    ;T<AM>_0;
				TLZ	T,$AM
    MREL
  ELSE
  IF T<AM> NEQ ST
				TLC	T,$ST
				TLNN	T,$AM
				GOTO	FALSE
				TLC	T,$ST
  THEN
    BEGIN
    IF T<AM>=CT
				TLNE	T,2
				T.CONST(T)
    THEN
      ;T<STATUS>_REGULAR;
				TLO	T,100
    FI;
    ;MTAD
				PUSHJ	SP,.MTAD
    ENDD
  ELSE
    BEGIN
      ;T<DECL,AM>_PROCLEV;
				HLRZ	T4,(T)
				ANDI	T4,$DECL!$AM
				CAIE	T4,0
				TLO	T,-1(T4)
      IF PROCLEV=1 AND T<KIND>=VAR OR ARRAY AND T<STATUS>=SIMPLE AND T<TYPE> NEQ LABEL
				SOJN	T4,FALSE
				TN.L(T)
				TLNE	T,$EXP!$STATUS
				GOTO FALSE
      THEN
	;T<STATUS>_OWN;
				TLO	T,$OWN
      FI;
      IF PRASE LEQ T<RHS> AND T<RHS> LESS PRLIB
				HRRZ	T1,T
				CAIL	T1,PRASE
				CAIL	T1,PRLIB
				GOTO	FALSE
      THEN
	  AMOF2
      ELSE
	BEGIN
	  INCR(THUNK);
	  ;T4_0;..NO OFFSET;..ALLREADY DONE;
				SETZ	T4,
	SETT(KA);
	  AMST;
	ZERO(KA);
	  DECR(THUNK)
	ENDD
      FI
    ENDD
  FI
FI
ENDD
OD
ENDD
SUBTTL	OBCODE SERVICE	* QTCADDFIX *

;TO PUT OUT A FIXUP FOR JUMPS OVER THEN OR ELSE PART

PROCEDURE QTCADDFIX;
BEGIN
  ;T<LHS>_'JSP  AX,@0';
				 HRLI	 T,(JSP  AX,@0)
  MABS;
				MOVE	 T,RA;$
				SUBI	T,1;$
  FIXADD;
  KILLAX
ENDD
SUBTTL	OBCODE SERVICE	* DMVNM *

PROCEDURE DMVNM;..DOUBLE STORE NEGATIVE
BEGIN
  OWN DINSTR;
    ; DINSTR_T;..INCLUDING RIGHTHAND!!!;
				MOVEM	T,DINSTR
    ; T_'DMOVN ACC,ACC'
				TLZ	T,777000!$AM
				HLRZ	T4,T
				LSH	T4,-5
				HRRI	T,(T4)
				TLO	T,(DMOVN 0,0)
  MABS;
    ; T_DINSTR;..KILL NEGATION;
				MOVE	T,DINSTR
				TLZ	T,010000
  QDMOVEM
ENDD
SUBTTL	OBCODE SERVICE	* DMVN *

PROCEDURE DMVN;..DOUBLE LOAD NEGATIVE
BEGIN
  OWN DINSTR;
    ; DINSTR<LHS>_T<LHS>;..SAVE DESTINATION ACC;
				HLLZM	T,DINSTR
    ;..KILL NEGATION;
				TLZ	T,010000
  QDMOVE
    ; T_DINSTR;
				HLLZ	T,DINSTR
    ; T_'DFN ACC,ACC+1'; KA10
    ; T_'DMOVN ACC,ACC'; KI10
				TLZ	T,777000!$AM
				HLRZ	T4,T
				LSH	T4,-5
				HRRI	T,(T4)
				TLO	T,(DMOVN 0,0) ;
  MABS;
ENDD
SUBTTL	OBCODE SERVICE	* AMPTR *

;SOURCE IS A POINTER (F.I. A SUBSCRIPTED VARIABLE).
;SPECIAL CASE OF A POINTER IN A0

PROCEDURE AMPTR;
BEGIN
  OWN INSTR;
  IF PTR=A0 AND OFFSET NEQ 0
				TRNN	T,SP
				CAIN T4,0
				GOTO	FALSE
  THEN
    BEGIN
      ;INSTR_T;
				MOVEM	T,INSTR
      ;T_'ADDI A0,OFFSET';
				HRLZI	T,(ADDI 0,0)
				ADDI	T,(T4)
      MABS;
      ;T_INSTR;
				MOVE	T,INSTR
      ;OFFSET_0;
				SETZ	T4,
    ENDD
  FI;
    ;T<AM>_T<RHS>;
    ;T<RHS>_0;
				TLO	T,(T)
				HRRI	T,0
    ;IF T<INDEX>=A0 THEN SET INDIRECT BIT;
				TLNN	T,SP
				TLO	T,20
    ;T_T+T4;..ADD OFFSET;
				ADDI	T4,(T)
				HRRI	T,(T4)
    MABS
ENDD
SUBTTL	OBCODE SERVICE	* AMACC *	* AMRA *

PROCEDURE AMACC;..SOURCE IS AN ACC; GENERATION OF MOVE A,A IS AVOIDED
BEGIN
  IF T<ACC> NEQ T<RHS> OR T<OPCODE> NEQ MOVE OR OFFSET NEQ 0
				HLRZ	T1,T
				SUBI	T1,(MOVE	0,0)
				LSH	T1,-5
				SUBI	T1,(T)
				ADDI	T1,(T4)
				JUMPE	T1,FALSE

  THEN
      BEGIN
	;T_T+T4;
				ADDI	T4,(T)
				HRRI	T,(T4)
	MABS
      ENDD
  FI
ENDD





PROCEDURE AMRA;..ADDRESS OF SOURCE RELATIVE TO PROGRAM COUNTER RA
BEGIN
  ;T<RHS>_T<RHS>+RA;
				ADD	T,RA
  MREL
ENDD
SUBTTL	OBCODE SERVICE	* AMNEXT *	* AMPRV *	* AMSELF *

PROCEDURE AMNEXT;..SOURCE INDEXED BY ACC +1
BEGIN
  ;T1<ACC>_T<ACC>+1;
				HLRZ	T1,T
				ADDI	T1,40
SAMEN:				ANDI	T1,$STATUS!$DECL
  ;T1^-5;..BRING ACC IN  INDEX FIELD;
				LSH	T1,-5
      ;T<AM>_T1;
				TLO	T,(T1)
      ;T_T+T4;..ADD OFFSET;
				ADDI	T4,(T)
				HRRI	T,(T4)
      MABS
ENDD






PROCEDURE AMPRV;..SOURCE INDEXED BY ACC-1
BEGIN
  ;T1<ACC>_T<ACC>-1;
				HLRZ	T1,T
				SUBI	T1,40
  GOTO	SAMEN
ENDD




PROCEDURE AMSELF;..SOURCE INDEXED BY ACC
BEGIN
  ;T<AM>_T<ACCFIELD>;
				HLRZ	T1,T
				LSH	T1,-5
				ANDI	T1,17
				TLO	T,(T1)
  ; T_T+T4;..ADD OFFSET;
				ADDI	T4,(T)
				HRRI	T,(T4)
  MABS
ENDD
SUBTTL	OBCODE SERVICE	* AMISP *

PROCEDURE AMISP;..SOURCE IS POINTER  SAVED IN STACK
BEGIN
  OWN INSTR;
  IF OFFSET=0
				JUMPN	T4,FALSE
  THEN
    ; T<AM>_@SP;
				TLO	T,SP!20
    MABS
  ELSE
    BEGIN
      ; INSTR<RHS>_T<LHS>;
				HLLM	T,INSTR
      ; T<OPCODE,INDEX>_'MOVE,SP';
				TLZ	T,777000
				TLO	T,(<MOVE 0,(SP)>)
    MABS;
    				MOVEI	T4,1
				MOVE	T,INSTR
      AMSELF
    ENDD
  FI;
ENDD
SUBTTL	OBCODE SERVICE	* AMDL *	* AMSP *	* AMAX *

PROCEDURE AMDL;..SOURCE IS LOCAL OF PROC,I.E. INDEXED BY DL
BEGIN
  ;IF KA=0 THEN  T<AM>_DL;
				SKIPN	KA
				TLO	T,DL
  ; T_T+T4;..ADD OFFSET;
				ADDI	T4,(T)
				HRRI	T,(T4)
  MABS
ENDD

PROCEDURE AMSP;..SOURCE IS EXPR SAVED IN STACK
BEGIN
  ;T<AM>_SP;
				TLO	T,SP
  ; T_T+T4;..ADD OFFSET;
				ADDI	T4,(T)
				HRRI	T,(T4)
  MABS
ENDD


PROCEDURE AMAX;..SOURCE IS NON-LOCAL OF PROC,THUS INDEXED BY AX
BEGIN
  ;IF KA=0 THEN  T<AM>_AX;
				SKIPN	KA
				TLO	T,AX
  ;T_T+T4;..ADD OFFSET;
				ADDI	T4,(T)
				HRRI	T,(T4)
  MABS
ENDD
SUBTTL	OBCODE SERVICE	* AMPVAL *

PROCEDURE AMPVAL;..SOURCE IS PROCEDURE VALUE
BEGIN
  LOCAL INSTR,OFS;
  IF PROCLEV NEQ FNLEVEL AND PROCLEVEL NEQ CAX AND THUNK=0
				HLRZ	T2,(T)
				ANDI	T2,77
				ADDI	T2,1
				SKIPN	KA
				CAMN	T2,FNLEVEL
				GOTO	FALSE
				HRRO	T4,T4
				CAMN	T2,CAX
				GOTO	FALSE
  THEN
  BEGIN
    ;INSTR_T
				MOVEM	T,INSTR
    ;OFS_T4
				MOVEM	T4,OFS
    ;CAX_T2
				MOVEM	T2,CAX
    ;T_'MOVEI AX,@PROCLEV(DL)';
				HRLZI	T,(<MOVEI AX,@(DL)>)
				ADDI	T,-1(T2)
    MABS;
    ;T_INSTR
				MOVE	T,INSTR
    ;T4_OFS
				MOVE	T4,OFS
    ;T2_CAX
				MOVE	T2,CAX
  ENDD;
  FI;
  ;T<RH>_OFFSET
				HRRI	T,1(T2)
  IF NONLOCAL
				JUMPGE	T4,FALSE
				HRRZ	T4,T4
  THEN
    AMAX
  ELSE
    AMDL
  FI
ENDD;
SUBTTL	OBCODE SERVICE	* AMCT *

;SOURCE IS A CONSTANT
;AMCT OPTIMIZES SEQUENCES SUCH AS
;	ADDI	AC,N
;	OPC	REG,(AC)
;INTO	OPC	REG,N(AC)
;WHICH IS LIKELY TO OCCUR IN CODE FOR SUBSCRIPTED VARIABLES:
;A[3]  OR  A[I+3]. EVEN SUBSCRIPTED VARIABLES OF TYPE LONG REAL
;ARE OPTIMIZED IN THIS SENSE

PROCEDURE AMCT;
BEGIN
IF T<AM>=IMM OR FIX
				CAIL	T1,$CT
				GOTO	FALSE
THEN
  IF T<OPCODE>='ADDI' OR 'SUBI'
				HLRZ	T2,T
				SUBI	T2,(ADDI 0,0)
				TRNE	T2,773000
				GOTO	FALSE
  THEN
    BEGIN
      ;TX_ADR<NET INSTR>;
      ;T2_NEXT INSTR;
				MOVEI	T2,1(TX)
				HRRZ	TX,T2
				MOVE	T2,(TX)
				TLC	T2,770000
				TLCN	T2,770000
				JRST	.-4
      ;T4_
      IF T2<AM>=PTR
				HLRZ	T3,T2
				ANDI	T3,$AM
				CAIE	T3,$PTR
				GOTO	FALSE
      THEN
	;T2<RHS>
				HRLZI	T4,(T2)
				LSH	T4,5
      ELSE
	IF T2<AM>=SELF
				CAIE	T3,$SELF
				GOTO	FALSE
	THEN
	  ;T2<ACC>
				HLLZ	T4,T2
	ELSE
	  IF T2<AM>=NEXT
				CAIE	T3,$NEXT
				GOTO	FALSE
	  THEN
	    ;T2<ACC>+1
				HRLZI	T4,40
				ADD	T4,T2
	  ELSE
	    ;ZERO
				MOVEI	T4,0
	  FI
	FI
      FI;
      IF T<ACC> NEQ 0  AND  T<ACC>=T4<ACC>
				XOR	T4,T
				TLNE	T,$STATUS!$DECL
				TLNE	T4,$STATUS!$DECL
				GOTO	FALSE
      THEN
	BEGIN
	  ;INDEX_TX;
				MOVEM	TX,INDEX
	  ;KA_T4_ IF ADDI THEN T<RHS> ELSE -T<RHS>;
				TLNE	T,4000
				MOVN	T,T
				HRRZI	T4,(T)
				HRRZM	T4,KA
	  ;T_T2;..T_NEXT INSTR;
				MOVE	T,T2
	MPS;
	ZERO(KA)
	ENDD
      ELSE
	IF T2<OPCODE>=ADD OR SUB  AND  T2<ACC>=T<ACC> AND T<ACC>#0 AND 
	   ; T2<AM>#ACC OR  T2<ACC>#T2<RHS>
				HLLO	T3,T
				TLO	T3,$AM
				SUB	T3,T2
				TLNE	T3,1000
				TLNE	T3,772740
				GOTO	FALSE
				TLNE	T2,$AM-$ACC
				GOTO	TRUE
				HLRZ	T3,T2
				LSH	T3,-5
				XORI	T3,(T2)
				TRNE	T3,17
				TLNN	T,$STATUS!$DECL
				GOTO	FALSE
	THEN
	  BEGIN
	    ;TC[TX]_T;..POSTPONE IMMEDIATE INSTRUCTION;
				MOVEM	T,(TX)
	    ;T_T2;..DO NEXT INSTRUCTION FIRST;
				MOVE	T,T2
	    ;TX_INDEX;
				MOVE	TX,INDEX
	    EDIT(051) ; REWRITE ORIGINAL INSTRUCTION INTO TEMPCODE
				MOVEM	T,(TX)	; [E051]
	    GOTO .MTAD;
	  ENDD
	ELSE
	BEGIN
	  ;TX_INDEX;
				MOVE	TX,INDEX
	  MABS
	ENDD
       FI
      FI
      ENDD
    ELSE
      MABS
    FI
  ELSE
BEGIN
  ;T_T+CONTAB;
				ADD	T,CONTAB
  ;T1_CONSTTABLEADDRESS;
				HRRZI	T1,(T)
 IF  T4=1
				JUMPE	T4,FALSE
  THEN
    BEGIN
      ; T1_T1+T4;
				ADD	T1,T4
      GOTO OFALL
    ENDD
  FI;
  ;T<RHS>_LINK;
				HLR	T,(T1)
  ;LINK_RA;
				HRL	T1,RA
				HLLM	T1,(T1)
  MREL
ENDD
 FI
 ENDD
SUBTTL	OBCODE SERVICE	* AMOF1/2/3 *

PROCEDURE AMOF1;..TO BUILD FIXUP CHAIN IN VALUE FIELD OF ST-ENTRY
BEGIN
  ;T1_SYMTABLEADDRESS;
				HRRZI	T1,1(T)
OFALL: ;T<RHS>_LINK;
				HRR	T,(T1)
  ;LINK_RA;
				HRL	T1,RA
				HLRM	T1,(T1)
  MREL
ENDD



PROCEDURE AMOF2;..TO BUILD FIXUP IN FIRST EXTENSION WORD OF ST-ENTRY
BEGIN
  ;T1_ADDRESS OF EXTENSION;
				MOVE	T1,2(T)
				ANDI	T1,77
				ADDI	T1,1
				IDIVI	T1,6
				ADDI	T1,3(T)
  GOTO OFAUX
ENDD



PROCEDURE AMOF3;..TO BUILD FIXUP CHAIN IN SECOND EXTENSION WORD
BEGIN
  ;T1_ADDRESS OF AUX.EXTENSION;
				MOVE	T1,2(T);..FIRST WORD OF NAME
				ANDI	T1,77
				ADDI    T1,1
				IDIVI   T1,6
				ADDI	T1,4(T)
  ;IF AUX=0 THEN AUX<LHS>_RA;
  OFAUX:			HRLZ	T2,RA
				SKIPN	(T1)
				HLLZM	T2,(T1)
  GOTO OFALL
ENDD
SUBTTL	OBCODE SERVICE	* NOCHAIN *

;NOCHAIN HANDLES THE ST-SOURCE OF WHICH THE ADDRESS IS KNOWN AT
;COMPILE TIME.FOR INSTANCE THE ADDRESS OF A LOCAL OF A PROC BODY IS
;KNOWN AT COMPILE TIME AS Q(DL),WHERE DL IS THE DYNAMIC LEVEL
;POINTER.FOR A NON-LOCAL IT MAY BE NECESSARY TO INSERT AN INSTRUCTION
;TO LOAD THE AUXILIARY ADDRESS MODIFIER AX WITH THE APPROPRIATE DISPLAY
;ELEMENT. THIS IS DESCRIBED MORE PRECISELY IN THE MEMOS

PROCEDURE NOCHAIN;
BEGIN
OWN INSTR,OFS;
IF PROCLEV NEQ FNLEVEL AND PROCLEVEL NEQ CAX AND THUNK=0
				HLRZ	T2,(T)
				ANDI	T2,77
				SKIPN	KA
				CAMN	T2,FNLEVEL
				GOTO	FALSE
				HRRO	T4,T4
				CAMN	T2,CAX
				GOTO	FALSE
THEN
  BEGIN
    ;INSTR_T;
				MOVEM	T,INSTR
    ;OFS_T4;
				MOVEM	T4,OFS
    ;CAX_T2
				MOVEM	T2,CAX
    ;T_'MOVEI AX,@PROCLEV(DL)';
				HRLZI	T,(<MOVEI AX,@(DL)>)
				ADDI	T,-1(T2)
    MABS;
    ;T_INSTR;
				MOVE	T,INSTR
    ;T4_OFS;
				MOVE	T4,OFS
  ENDD
FI;

  ;T<RHS>_VALUE;
				HRR	T,1(T)
IF NONLOCAL
				JUMPGE	T4,FALSE
				HRRZ	T4,T4
THEN
  AMAX
ELSE
  AMDL
FI
ENDD
SUBTTL	OBCODE SERVICE	* AMST *

;..T CONTAINS THE INSTRUCTION;
;..AMFIELD MAY CONTAIN PROCLEV FOR TYPEDESCRIPTOR;
;..T4 CONTAINS OFFSET;

;AMST DEALS WITH A SOURCE IN THE SYMBOL TABLE.
;THE MEMOS DESCRIBE IN DETAIL HOW LABELS ARE TREATED IN THE ONE PASS
;COMPILER AND HOW THE FIRST AND SECOND EXTENSION WORDS ARE USED TO BUILD
;FIXUP CHAINS FOR CURRENT AND INNER REFERENCES.
;GLOBALS AND OWN VARIABLES CANNOT BE USED RECURSIVELY. THAT ALLOWS A
;PROGRAM TO ADDRESS THESE DIRECTLY, BUT IT IMPLIES THAT THE ADDRESSES
;ARE NOT KNOWN AT COMPILE TIME. HENCE A FIXUP CHAIN FOR EACH OF THOSE
;MUST BE GENERATED

PROCEDURE AMST;
BEGIN
REGISTER TV;
;;TV_T<TYPE,VALUE>;
				MOVE	TV,1(T)
;T1_PROCLEV;
				HLRZ	T1,(T)
				ANDI	T1,77

IF TV<KIND>=VAR OR ARRAY
				TLNE	TV,$EXP
				GOTO	FALSE
THEN
  IF TV<TYPE>=LABEL
				T.L(TV)
  THEN
    IF TV<DECL>=UNDECL OR TV<STATUS>=FORWARD
				TLNN	TV,$DECL
				GOTO	TRUE
				T.FOW(TV)
    THEN
      IF THUNK=0
				SKIPE	THUNK
				GOTO FALSE
      THEN
	AMOF3
      ELSE
	AMOF2
      FI
    ELSE
      IF TV<STATUS>=SIMPLE
				TLNE	TV,$STATUS
				GOTO	FALSE
      THEN
	BEGIN
	  IF THUNK=0
				SKIPE	THUNK
				GOTO FALSE
	  THEN
	  ;T<RHS>_TV<VALUE>+2;..LOCAL LABEL;
				HRRI	T,2(TV)
	  ELSE
	    ;T<RHS>_TV<VALUE>
				HRRI	T,(TV)
	  FI;
	  MREL
	ENDD
      ELSE
	BEGIN
	  ;T4_0;..NO OFFSET;
				SETZ	T4,
	  NOCHAIN;..FORMAL LABEL
	ENDD
      FI
    FI
  ELSE
    IF GLOBAL OR OWN
				TLNN	TV,$STATUS
				SOJE	T1,TRUE
				T.OWN(TV)
    THEN
      IF T4=0
				JUMPN	T4,FALSE
      THEN
	AMOF1
      ELSE
	  AMOF2
      FI
    ELSE
      NOCHAIN
    FI
  FI
ELSE    ;..REMAIN PROCEDURE IDENTIFIERS;
  IF TV<STATUS>=EXTERN
				HLRZ	T2,TV
				ANDI	T2,$STATUS
				CAIE	T2,$EXT
				GOTO	FALSE
  THEN
      AMOF1
  ELSE
    IF TV<STATUS>=SIMPLE OR REGULAR
				TLNE	TV,$FOV
				GOTO	FALSE
    THEN
      BEGIN
	;T<RHS>_TV<VALUE>;
				HRR	T,TV
Edit(144) ; Ensure procedure call is relocated
	MREL0	; [E144]
      ENDD
    ELSE
      IF TV<STATUS>=FORWARD
				T.FOW(TV)
      THEN
	AMOF1
      ELSE    ;..REMAIN FORMAL PROCEDURES;
	BEGIN
	  ;T4_0;..NO OFFSET;
				SETZ	T4,
	  NOCHAIN
	ENDD
      FI
    FI
  FI
FI;
;IF TV<KIND,STATUS>=PROC OR FORMAL THEN KILLAX;
				TLC	TV,$PRO!$FON
				TLNE	TV,$PRO
				TLNN	TV,$FON
				SETOM	CAX
ENDD
SUBTTL	OBCODE SERVICE	* QTCSF *	* POWCONV *

PROCEDURE QTCSF;..TO STORE INTO A FORMAL (SEE THE MEMOS)
BEGIN
;T<LHS>_'XCT 0';
				HRLI	T,(XCT 0,0)
;T4_1;OFFSET
				MOVEI	T4,1
NOCHAIN
KILLAX
ENDD











;POWCONV GENERATES THE APPROPRIATE ADDRESS OF POWER OR CONVERT
;ROUTINES

PROCEDURE POWCONV;	;..ADR<VALUE>=3*(OPCODE-724)+PRLIB+1;
BEGIN
  KILLAX;
  ;T1_ADDRESS<VALUE FIELD>;
				LSH	T,-33
				SUBI	T,724
				MOVE	T1,T
				LSH	T,1
				ADDI	T1,PRLIB+1(T)
  ;T_INSTR;
				HRLZI	T,(JSP AX,0)
  GOTO OFALL
ENDD;
SUBTTL	OBCODE SERVICE	* QLF *

;THERE ARE FOUR GROUPS OF SIX DOUBLE FLOATING OPERATIONS.
;THE GROUPS REFLECT THE ACCUMULATOR-DESTINATION OPERAND (IN ACCFIELD)
;A0,A3,A6 OR A11, WHILE EACH GROUP HAS SIX OPERATIONS:
;FAD,FSUB,FMP,FDIV,RFSUB AND RFDIV.
;QLF GENERATES AN INSTRUCTION TO LOAD THE ADDRESS OF THE SOURCE IN
; REGISTER AX AND AN INSTRUCTION THAT CALLS THE APPROPRIATE OPERATION

PROCEDURE QLF;
BEGIN
  OWN INSTR;
    ; INSTR<LHS>_T<LHS>;
				HLLZM	T,INSTR
      ;T<0PCODE,ACCFIELD>_'MOVEI AX,0'
				TLZ	T,777777-$AM
				TLO	T,(MOVEI AX,0)
    ; MTAD;
				PUSHJ	SP,.MTAD
    ; T<RHS>_INSTR<ACCFIELD>;
				HLRZ	T,INSTR
				ANDI	T,777-$AM
    ; T_T:3 ;
				IDIVI	T,60
    ; T1<RHS>_INSTR<OPCODE FIELD>;
				HLRZ	T1,INSTR
  ;T<RHS>_STADR<FLROUTINE>;..=3*(OPCODE-720+C+2*ACC)+PRLIB
				;WHERE 3*C=DFAD0-PRLIB;
				LSH	T1,-11
				SUBI	T1,702
				IMULI	T1,3
				IMULI	T,11
				ADDI	T,PRLIB(T1)
  ;T_'PUSHJ SP,0';
				HRLI	T,(PUSHJ SP,0)
  AMOF1
  KILLAX
ENDD
SUBTTL BACKCHAIN FIXUP AND ST DECREASE AT BLOCKEXIT


;BEXIT DELETES FROM THE SYMBOL TABLE THE SET OF ST-ENTRIES OF THE
;CURRENT BLOCK. IT HAS TO DO SPECIAL THINGS FOR UNDECLARED LABELS
;LABELS ARE HANDLED IN TWO STEPS:
;STEP1: THE CURRENT CHAIN IS LINKED ONTO THE INNER CHAIN
;STEP2: IF THERE IS A LABEL OF THE SAME NAME IN THE OUTER BLOCK,
;THIS ONE IS HOOKED ONTO IT AND THE ST-ENTRY OF THE CURRENT ONE
;IS DELETED;IF NOT,THEN THE ST-ENTRY OF THE CURRENT LABEL IS MOVED
;TO THE OUTER BLOCK.
;ANOTHER OBLIGATION OF BEXIT IS TO PRESENT THE VARIOUS FIXUP CHAINS
;TO THE OUTPUT

PROCEDURE BEXIT;
BEGIN
REGISTER BX,TV,EXT;
OWN NNASTE;
;BX_STBB;..FIRST ENTRY OF THIS BLOCK;
				HRRZ	BX,STBB
;NNASTE_BX-1;..NEXT NEW AVAILABLE ENTRY;
				MOVEM	BX,NNASTE
				SOS	NNASTE
;STBB_OLD STBB;
				MOVE	T,@NNASTE
				MOVEM	T,STBB
	IF NOT PRODUCTION SWI