ack/lang/a68s/aem/perqce.p

1079 lines
42 KiB
OpenEdge ABL
Raw Normal View History

1988-10-04 10:56:50 +00:00
~>|sed -e '/ *$/s/ *$/~~~~/' -e '/~~~~/s///' >a68s1ce.pp
00100 (*CODE EMITTER*)
00110 (**************)
00111 Things needing attention
00112 OCVIMMPTR and OCVIMMLONG (see PARAM and EMITOP)
00120 (**)
00130 (*+01() (*$T-+) ()+01*)
00140 (*+02() (*$T-+) ()+02*)
00150 (*-05()
00160 PROCEDURE LOAD (WHERE:SBTTYP; SB:PSB); FORWARD;
00170 PROCEDURE EMITEND; FORWARD;
00180 PROCEDURE EMITX1 (OPCOD:POP;TYP1:OPDTYP;OPND1:ADDRINT); FORWARD;
00190 PROCEDURE EMITX2 (OPCOD:POP;TYP1:OPDTYP;OPND1:ADDRINT;TYP2:OPDTYP;OPND2:ADDRINT); FORWARD;
00200 FUNCTION GENLCLGBL (VAR OPCOD:POP; SB:PSB):OFFSETR; FORWARD;
00210 PROCEDURE FIXUPF(ALABL:LABL);FORWARD;
00220 FUNCTION FIXUPM: LABL; FORWARD;
00230 PROCEDURE UNSTKP1(TYP:OPDTYP; OPND:PSB); FORWARD;
00240 ()-05*)
00250 PROCEDURE EMITOP (OPCOD:POP); FORWARD;
00260 PROCEDURE GENDENOT (OPCOD:POP; SB:PSB); FORWARD;
00270 FUNCTION GETNEXTLABEL: LABL;
00280 BEGIN GETNEXTLABEL := NEXTLABEL; NEXTLABEL := NEXTLABEL+1 END;
00290 (**)
00300 (**)
00310 (*+32()
00320 (*-01() PROCEDURE HALT; VAR I,K: INTEGER; BEGIN I:=0;K := K DIV I END; ()-01*)
00330 PROCEDURE ASSERT (ASSERTION:BOOLEAN; REASON:ALFA);
00340 BEGIN
00350 IF NOT (ASSERTION) THEN
00360 BEGIN
00370 WRITELN(OUTPUT,' ASSERT FAILED ',REASON);
00380 (*+01() PUTSEG(OUTPUT); ()+01*)
00390 EMITEND;
00400 HALT
00410 END
00420 END;
00430 (**)
00440 ()+32*)
00450 (* PERQ CODE EMITTER *)
00460 (*********************)
00470 (*+05()
00480 PROCEDURE PARAM(TYP:OPDTYP; OPND:INTEGER; OPCOD: POP; ALIGN: INTEGER; FIRSTIME: BOOLEAN); FORWARD;
00490 PROCEDURE EMITOPRAND(TYP:OPDTYP;OPERAND:ADDRINT);
00500 VAR REC: RECORD CASE SEVERAL OF
00510 1: (INT:ADDRINT);
00520 2: (LEX:PLEX);
00530 3,4,5,6,7,8,9,10: ()
00540 END;
00550 I:INTEGER;
00560 BEGIN
00570 CASE TYP OF
00580 OCVIMMED: WRITE(LGO[ROUTNL^.RNLEVEL],' ',OPERAND:1);
00590 OCVFREF,OCVMEM,OCVFIM:
00600 WRITE(LGO[ROUTNL^.RNLEVEL],' L',OPERAND:1);
00610 OCVEXT: BEGIN
00620 REC.INT := OPERAND;
00630 WRITE(LGO[ROUTNL^.RNLEVEL], '_');
00640 FOR I := 1 TO 7 DO
00650 (*IF REC.LEX^.S10[I]<>' ' THEN WRITE(LGO[ROUTNL^.RNLEVEL], CHR(ORD(REC.LEX^.S10[I])+32));*)
00660 WRITE(LGO[ROUTNL^.RNLEVEL], REC.LEX^.S10[I]);
00670 END
00680 END;
00690 END;
00700 (**)
00710 PROCEDURE EMITXWORD(TYP:OPDTYP;OPERAND:ADDRINT);
00720 VAR REC: RECORD CASE SEVERAL OF
00730 1: (INT:ADDRINT);
00740 2: (LEX:PLEX);
00750 3,4,5,6,7,8,9,10: ()
00760 END;
00770 I:INTEGER;
00780 BEGIN
00790 (*+32() ASSERT(TYP<>OCVFIM, 'EMITXWORD '); ()+32*)
00800 IF TYP=OCVIMMED THEN WRITE(LGO[ROUTNL^.RNLEVEL],' int ')
00810 ELSE WRITE(LGO[ROUTNL^.RNLEVEL], ' ptrw ');
00820 EMITOPRAND(TYP,OPERAND);
00830 WRITELN(LGO[ROUTNL^.RNLEVEL]);
00840 END;
00850 (**)
00860 PROCEDURE EMITXPROC(TYP:OPDTYP;OPERAND:ADDRINT);
00870 VAR REC: RECORD CASE SEVERAL OF
00880 1: (INT:ADDRINT);
00890 2: (LEX:PLEX);
00900 3,4,5,6,7,8,9,10: ()
00910 END;
00920 I:INTEGER;
00930 BEGIN
00940 WRITE(LGO[ROUTNL^.RNLEVEL],' ptrf ');EMITOPRAND(TYP,OPERAND);
00950 WRITELN(LGO[ROUTNL^.RNLEVEL]);
00960 END;
00970 (**)
00980 PROCEDURE EMITALF(OPERAND: ALFA);
00990 VAR I: INTEGER;
01000 BEGIN
01010 IF DATASTATE=STARTDATA THEN
01020 BEGIN WRITELN(LGO[ROUTNL^.RNLEVEL], 'data'); DATASTATE := INDATA END;
01030 WRITE(LGO[ROUTNL^.RNLEVEL], ' byte '); FOR I := 1 TO 9 DO WRITE(LGO[ROUTNL^.RNLEVEL], ORD(OPERAND[I]):3, ',');
01040 WRITELN(LGO[ROUTNL^.RNLEVEL], ORD(OPERAND[10]):3);
01050 END;
01060 (**)
01070 (**)
01080 PROCEDURE EMITOP (* (OPCOD:POP) *);
01090 VAR I,COUNT:INTEGER; JUMPOVER:LABL;
01100 TEMP:INTEGER; OP:MNEMONICS;
01110 PARAMNOTUSED: BOOLEAN;
01120 BEGIN
01130 IF DATASTATE<>OUTDATA THEN
01140 BEGIN DATASTATE := OUTDATA; WRITELN(LGO[ROUTNL^.RNLEVEL], 'text') END;
01150 COUNT := 0; PARAMNOTUSED := TRUE;
01160 WHILE OPCOD <> 0 DO WITH CODETABLE[OPCOD] DO
01170 BEGIN
01180 IF INLINE THEN
01190 BEGIN
01200 IF PERQCOD='CI ' THEN
01210 IF OCV=OCVFIM THEN WRITE(LGO[ROUTNL^.RNLEVEL], ' cil ')
01220 ELSE IF (OCV=OCVMEM) OR (OCV=OCVFREF) OR (OCV=OCVEXT) THEN WRITE(LGO[ROUTNL^.RNLEVEL], ' lga ')
01230 ELSE WRITE(LGO[ROUTNL^.RNLEVEL], ' ci ')
01240 ELSE IF OPCOD<>PNOOP THEN
01242 BEGIN
01250 WRITE(LGO[ROUTNL^.RNLEVEL],' ');
01260 FOR i := 1 TO 8 DO
01270 WRITE(LGO[ROUTNL^.RNLEVEL],CHR(ORD(PERQCOD[I])+32*ORD(ORD(PERQCOD[I])>63)));
01280 END;
01290 CASE PARTYP OF
01300 WOP,ACP: (* OPERAND SUPPLIED BY CODETABLE *)
01310 WRITE(LGO[ROUTNL^.RNLEVEL], ' ', PARM:1);
01320 WNP,ANP: (*NEGATIVE OPERAND SUPPLIED BY CODETABLE*)
01330 WRITE(LGO[ROUTNL^.RNLEVEL], ' ', -PARM:1);
01340 OPX,ACX: (* OPERAND IS SUPPLIED BY CODE GENERATOR *)
01350 BEGIN EMITOPRAND(OCV, OPRAND+PARM); PARAMNOTUSED := FALSE END;
01360 ONX,ANX: (* NEGATIVE OPERAND SUPPLIED BY CODE GENERATOR*)
01370 BEGIN EMITOPRAND(OCV, -OPRAND-PARM); PARAMNOTUSED := FALSE END;
01380 JMP: (* P-OP GENERATES ITS OWN LABELS FOR LOOPS ETC. *)
01390 BEGIN
01400 COUNT := PARM;
01410 JUMPOVER := GETNEXTLABEL;
01420 WRITE(LGO[ROUTNL^.RNLEVEL],' L',JUMPOVER:1);
01430 END;
01440 NON: (* NO OPERAND *);
01450 GBX: (* GLOBAL LABEL EXPECTED *)
01460 BEGIN WRITE(LGO[ROUTNL^.RNLEVEL],' L',OPRAND:1); PARAMNOTUSED := FALSE END;
01470 LCX: (* INSTRUCTION LABEL EXPECTED *)
01480 BEGIN WRITE(LGO[ROUTNL^.RNLEVEL],' L',OPRAND:1); PARAMNOTUSED := FALSE END;
01490 MOR: (* LONG OPERAND FOLLOWS IN NEXT OPCOD *)
01500 BEGIN OPCOD := NEXT;
01510 WRITE(LGO[ROUTNL^.RNLEVEL], CODETABLE[OPCOD].PERQCOD);
01520 END;
01530 END; (* OF CASE *)
01540 IF PARTYP>=ACP THEN BEGIN ADJUSTSP := ADJUSTSP+SZWORD; PARAMNOTUSED := FALSE END;
01550 IF OPCOD<>PNOOP THEN WRITELN(LGO[ROUTNL^.RNLEVEL]);
01560 IF (PERQCOD[1]=' ') AND (REGSINUSE.ECOUNT<>0) THEN EMITOP(PDISCARD);
01570 OPCOD := CODETABLE[OPCOD].NEXT;
01572 IF COUNT = 1 THEN WRITELN(LGO[ROUTNL^.RNLEVEL],' L',JUMPOVER: 1,':');
01574 COUNT := COUNT-1;
01580 END
01590 ELSE
01600 BEGIN
01610 IF PARAMNOTUSED THEN PARAM(OCVNONE, 0, OPCOD, 0, FALSE);
01620 WRITE(LGO[ROUTNL^.RNLEVEL],' ','call _',ROUTINE); WRITELN(LGO[ROUTNL^.RNLEVEL]) ;
01630 OPCOD := 0;
01640 (*+32() ASSERT((RTSTKDEPTH+ADJUSTSP) MOD 4 = 0, 'EMITOP - A'); ()+32*)
01650 IF COUNT = 1 THEN WRITELN(LGO[ROUTNL^.RNLEVEL],' L',JUMPOVER: 1,':');
01700 COUNT := COUNT-1;
01702 IF ADJUSTSP<>0 THEN EMITX1(PASP, OCVIMMED, ADJUSTSP);
01710 END;
01750 END;
01760 END;
01770 (**)
01780 PROCEDURE FIXUPF (*+05() (ALABL:LABL) ()+05*);
01790 BEGIN
01800 IF DATASTATE=STARTDATA THEN
01810 BEGIN WRITELN(LGO[ROUTNL^.RNLEVEL], 'data'); WRITELN(LGO[ROUTNL^.RNLEVEL], 'align4'); DATASTATE := INDATA END
01820 ELSE IF DATASTATE=ENDDATA THEN
01830 BEGIN WRITELN(LGO[ROUTNL^.RNLEVEL], 'text'); DATASTATE := OUTDATA END;
01840 WRITELN(LGO[ROUTNL^.RNLEVEL],'L',ALABL:1,':');
01850 END;
01860 (**)
01870 FUNCTION FIXUPM:LABL;
01880 VAR L:LABL;
01890 BEGIN
01900 IF DATASTATE=STARTDATA THEN
01910 BEGIN WRITELN(LGO[ROUTNL^.RNLEVEL], 'data'); WRITELN(LGO[ROUTNL^.RNLEVEL], 'align4'); DATASTATE := INDATA END
01920 ELSE IF DATASTATE=ENDDATA THEN
01930 BEGIN WRITELN(LGO[ROUTNL^.RNLEVEL], 'text'); DATASTATE := OUTDATA END;
01940 L := GETNEXTLABEL;
01950 FIXUPM := L;
01960 WRITELN(LGO[ROUTNL^.RNLEVEL],'L',L:1,':');
01970 END;
01980 (**)
01990 PROCEDURE FIXUPFIM(ALABL:LABL;VALUE:A68INT);
02000 BEGIN
02010 WRITELN(LGO[ROUTNL^.RNLEVEL], ' constant L', ALABL:1, ' ', VALUE: 1);
02020 END;
02030 (**)
02040 PROCEDURE FIXLABL(OLDLABL,NEWLABL:LABL; KNOWN:BOOLEAN);
02050 VAR JUMPOVER: LABL;
02060 BEGIN
02070 JUMPOVER := GETNEXTLABEL;
02080 WRITELN(LGO[ROUTNL^.RNLEVEL], ' jump L', JUMPOVER:1);
02090 WRITELN(LGO[ROUTNL^.RNLEVEL], 'L',OLDLABL:1, ':');
02100 WRITELN(LGO[ROUTNL^.RNLEVEL], ' jump L', NEWLABL:1);
02110 WRITELN(LGO[ROUTNL^.RNLEVEL], 'L',JUMPOVER:1, ':');
02120 END;
02130 FUNCTION NORMAL(SB: PSB): SBTTYP;
02140 (*RETURNS THE SBTTYP IN WHICH VALUES OF MODE SB^.SBMODE SHOULD BE STORED DURING BALANCES*)
02150 BEGIN WITH SB^ DO WITH SBMODE^.MDV DO
02160 IF SBTYP=SBTDL THEN NORMAL := SBTDL
02170 ELSE IF SBUNION IN SBINF THEN NORMAL := SBTSTKN
02180 ELSE IF SBNAKED IN SBINF THEN NORMAL := SBTFPR0
02190 ELSE IF MDPILE THEN NORMAL := SBTE
02200 ELSE CASE MDLEN OF
02210 0: NORMAL := SBTVOID;
02220 2: NORMAL := SBTE;
02230 4: NORMAL := SBTFPR0;
02240 END;
02250 END;
02260 (**)
02270 FUNCTION LENOF(SB: PSB): INTEGER;
02280 BEGIN
02290 WITH SB^,SBMODE^.MDV DO
02300 IF SBUNION IN SBINF THEN LENOF := SBLEN
02310 ELSE IF SBNAKED IN SBINF THEN LENOF := SZNAKED
02320 ELSE IF MDPILE THEN LENOF := SZADDR
02330 ELSE LENOF := MDLEN;
02340 END;
02350 (**)
02360 PROCEDURE LOADSTK(SB: PSB);
02370 BEGIN
02380 (*+21() WRITELN(OUTPUT, 'LOADSTK ', ORD(SB)); ()+21*)
02390 IF NOT(SB^.SBTYP IN [SBTSTKN,SBTDL]) THEN
02400 CASE LENOF(SB) OF
02410 0: LOAD(SBTVOID, SB);
02420 2: LOAD(SBTSTK, SB);
02430 4: LOAD(SBTSTK4, SB);
02440 END;
02450 END;
02460 (**)
02470 PROCEDURE TWIST;
02480 VAR TEMPPTR : PSB;
02490 NORM: SBTTYP;
02500 BEGIN
02510 (*+21() WRITELN(OUTPUT, 'TWIST'); ()+21*)
02520 IF [RTSTACK^.SBRTSTK^.SBTYP , RTSTACK^.SBTYP] * [SBTVOID..SBTDEN] = [] THEN
02530 (*NEITHER SB IS A FAKE*)
02540 BEGIN
02550 IF RTSTACK^.SBTYP IN [SBTSTK..SBTDL] THEN
02560 LOAD(NORMAL(RTSTACK),RTSTACK); (*GET IT INTO REGISTER 3*)
02570 TEMPPTR := RTSTACK^.SBRTSTK;
02580 RTSTACK^.SBRTSTK := TEMPPTR^.SBRTSTK;
02590 TEMPPTR^.SBRTSTK := RTSTACK;
02600 RTSTACK := TEMPPTR;
02610 IF RTSTACK^.SBTYP IN [SBTSTK..SBTDL] THEN
02620 BEGIN
02630 NORM := NORMAL(RTSTACK);
02640 IF NORM IN [SBTFPR0..SBTFPR3] THEN IF NORM IN REGSINUSE.FPR THEN NORM := SBTFPR1;
02650 LOAD(NORM,RTSTACK) (*GET IT INTO A REGISTER TOO*)
02660 END
02670 ELSE IF (RTSTACK^.SBTYP IN [SBTE,SBTER0]) AND (RTSTACK^.SBRTSTK^.SBTYP IN [SBTE,SBTER0]) THEN
02680 EMITOP(PSWAP)
02690 END
02700 ELSE BEGIN
02710 TEMPPTR := RTSTACK^.SBRTSTK;
02720 RTSTACK^.SBRTSTK := TEMPPTR^.SBRTSTK;
02730 TEMPPTR^.SBRTSTK := RTSTACK;
02740 RTSTACK := TEMPPTR
02750 END
02760 END;
02770 (**)
02780 PROCEDURE HOIST(HOISTLEN, LEN:INTEGER; ALIGN: BOOLEAN);
02782 (*HOISTLEN IS AMOUNT ALREADY STACKED; LEN IS TOTAL AMOUNT TO BE STACKED*)
02790 BEGIN
02800 IF ((RTSTKDEPTH-HOISTLEN+LEN) MOD 4 = 0) = ALIGN THEN
02810 BEGIN
02820 IF HOISTLEN=0 THEN EMITOP(PALIGN)
02830 ELSE
02840 BEGIN
02850 HOISTLEN := HOISTLEN-RTSTKDEPTH; CLEAR(RTSTACK); HOISTLEN := HOISTLEN+RTSTKDEPTH;
02860 EMITX1(PHEAVE, OCVIMMED, HOISTLEN);
02870 END;
02880 ADJUSTSP := ADJUSTSP+SZWORD;
02890 END;
02900 END;
02910 (**)
02920 PROCEDURE PROC1OP(OPCOD:POP;TYP:OPDTYP;OPND:INTEGER;NOTINL:BOOLEAN;ALIGN:INTEGER);
02930 VAR SB, SB1: PSB;
02940 HOISTLEN,LEN: INTEGER;
02950 BEGIN
02960 SB:=ASPTR(OPND);
02962 SB^.SBINF := SB^.SBINF-[SBSTKDELAY];
02970 IF RTSTACK<>SB THEN TWIST;
02972 WITH CODETABLE[OPCOD] DO
02974 BEGIN
02980 IF NOTINL THEN WITH SB^ DO
02990 BEGIN
03000 IF SBSTKDELAY IN SBRTSTK^.SBINF THEN LOADSTK(SBRTSTK)
03010 ELSE CLEAR(SBRTSTK);
03020 IF TYP=OCVSBS THEN
03030 BEGIN
03040 HOISTLEN := SUBSTLEN([SBTSTK..SBTDL]);
03050 LEN := HOISTLEN+LENOF(SB)*ORD(NOT(SB^.SBTYP IN [SBTSTK..SBTDL]));
03060 END
03070 ELSE BEGIN
03080 LEN := LENOF(SB)*ORD(P1 IN [SBTSTK..SBTDL,SBTPR1,SBTPR2]);
03090 HOISTLEN := SBLEN*ORD(SB^.SBTYP IN [SBTSTK..SBTDL]);
03100 END;
03110 HOIST(HOISTLEN, LEN, NOT ODD(ALIGN+APARAMS));
03120 END;
03150 REPEAT
03151 IF PR IN (REGSINUSE.FPR-[P1]) THEN
03152 BEGIN SB1 := RTSTACK;
03153 WHILE NOT(SB1^.SBTYP IN (REGSINUSE.FPR-[P1])) DO SB1 := SB1^.SBRTSTK;
03155 CLEAR(SB1);
03156 END;
03157 LOAD(P1, SB);
03158 UNTIL P1 IN [SBTSTKN,SBTPR1,SBTPR2,SBTXN,SB^.SBTYP]; (*ESTACK MAY HAVE OVERFLOWED*)
03160 UNSTKP1(TYP,SB);
03180 END;
03190 OCV := OCVNONE; (*FOR 1ST CALL OF PARAM*)
03200 END;
03210 (**)
03220 PROCEDURE PROC2OP(OPCOD:POP;TYP1:OPDTYP;OPND1:INTEGER;TYP2:OPDTYP;OPND2:INTEGER;NOTINL:BOOLEAN;ALIGN:INTEGER);
03230 VAR SB1, SB2, SB3: PSB;
03240 HOISTLEN,LEN1,LEN2: INTEGER;
03250 BEGIN
03260 SB1:=ASPTR(OPND1);
03262 SB1^.SBINF := SB1^.SBINF-[SBSTKDELAY];
03270 SB2:=ASPTR(OPND2);
03271 SB2^.SBINF := SB2^.SBINF-[SBSTKDELAY];
03272 WITH CODETABLE[OPCOD] DO
03274 BEGIN
03280 IF NOTINL THEN WITH RTSTACK^.SBRTSTK^ DO
03290 BEGIN
03300 IF SBSTKDELAY IN SBRTSTK^.SBINF THEN LOADSTK(SBRTSTK)
03310 ELSE CLEAR(SBRTSTK);
03312 IF TYP1=OCVSBS THEN
03314 HOIST(SUBSTLEN([SBTSTK..SBTDL]), SUBSTLEN([SBTID..SBTFPR1]), ODD(ALIGN+APARAMS))
03316 ELSE
03318 BEGIN
03320 LEN1 := LENOF(SB1)*ORD(P1 IN [SBTSTK..SBTDL,SBTPR1,SBTPR2]);
03322 LEN2 := LENOF(SB2)*ORD(P2 IN [SBTSTK..SBTDL,SBTPR1,SBTPR2]);
03330 HOISTLEN := SB1^.SBLEN*ORD(SB1^.SBTYP IN [SBTSTK..SBTDL])
03340 +SB2^.SBLEN*ORD(SB2^.SBTYP IN [SBTSTK..SBTDL]);
03350 HOIST(HOISTLEN, LEN1+LEN2, ODD(ALIGN+APARAMS));
03352 END;
03360 END;
03370 IF RTSTACK<>SB2 THEN TWIST;
03400 IF (SB2^.SBTYP IN [SBTSTK..SBTSTKN,SBTVAR]) OR ((P1 IN REGSINUSE.FPR) AND (P1<>SB1^.SBTYP)) THEN
03410 LOAD(P2,SB2);
03412 REPEAT
03413 IF PR IN (REGSINUSE.FPR-[P1,P2]) THEN
03414 BEGIN SB3 := RTSTACK;
03415 WHILE NOT(SB3^.SBTYP IN (REGSINUSE.FPR-[P1,P2])) DO SB3 := SB3^.SBRTSTK;
03416 CLEAR(SB3);
03418 END;
03420 LOAD(P1, SB1);
03430 LOAD(P2, SB2);
03432 UNTIL (P1 IN [SBTSTKN,SBTPR1,SBTPR2,SBTXN,SB1^.SBTYP]) AND
03434 (P2 IN [SBTSTKN,SBTPR1,SBTPR2,SBTXN,SB2^.SBTYP]); (*ESTACK MAY HAVE OVERFLOWED*)
03440 UNSTKP1(TYP2,SB2);
03450 UNSTKP1(TYP1,SB1);
03470 END;
03480 OCV := OCVNONE; (*FOR 1ST CALL OF PARAM*)
03490 END;
03500 (**)
03510 PROCEDURE FILL (WHERE:SBTTYP; SB:PSB);
03520 BEGIN
03530 WITH SB^ DO WITH REGSINUSE DO
03540 BEGIN
03550 IF SBTYP IN [SBTER0..SBTFPR3] THEN FPR := FPR-[SBTYP];
03560 IF SBTYP IN [SBTE,SBTER0] THEN ECOUNT := ECOUNT-1
03570 ELSE IF SBTYP IN [SBTSTK..SBTDL] THEN RTSTKDEPTH := RTSTKDEPTH-SBLEN;
03572 SBTYP:=WHERE;
03580 IF NOT(WHERE IN [SBTSTKN,SBTDL,SBTXN]) THEN SBLEN := LENARRAY[WHERE];
03590 IF WHERE IN [SBTSTK..SBTDL] THEN
03600 BEGIN
03610 RTSTKDEPTH := RTSTKDEPTH+SBLEN;
03620 WITH ROUTNL^ DO
03630 IF RTSTKDEPTH>RNLENSTK THEN RNLENSTK:=RTSTKDEPTH
03640 END
03650 ELSE
03654 BEGIN
03660 IF WHERE IN [SBTE,SBTER0] THEN
03662 BEGIN ECOUNT := ECOUNT+1; IF ECOUNT>=6 THEN CLEAR(RTSTACK) END;
03670 IF WHERE IN [SBTER0..SBTFPR3] THEN FPR := FPR+[WHERE];
03674 END;
03690 END
03700 END;
03710 (**)
03720 FUNCTION SETINLINE (OPCOD:POP):BOOLEAN;
03730 VAR INL:BOOLEAN;
03740 BEGIN
03750 APARAMS := 0;
03760 OCV := OCVNONE; (*FOR 1ST CALL OF PARAM*)
03770 REPEAT WITH CODETABLE[OPCOD] DO
03780 BEGIN
03790 APARAMS := APARAMS+ORD(PARTYP IN [ACP,ANP]); (*NUMBER OF SECRET PARAMETERS*)
03800 INL := INLINE;
03810 OPCOD := NEXT
03820 END
03830 UNTIL NOT(INL) OR (OPCOD=0);
03840 SETINLINE := INL
03850 END;
03860 (**)
03870 (**)
03880 PROCEDURE LOAD (*+05() (WHERE:SBTTYP; SB:PSB) ()+05*);
03890 (*EMITS CODE TO MOVE SB TO WHERE: CALLS FILL TO RECORD THE MOVE*)
03900 VAR TEMPOP: POP;
03910 TOFFSET: INTEGER;
03920 TEMPTYP: SBTTYP;
03930 OCVFIX: OPDTYP;
03940 TWISTED: BOOLEAN;
03950 TYPS: SET OF SBTTYP;
03960 SB1, SB2: PSB;
03970 SAVE, EC:INTEGER;
03980 BEGIN
03990 (*+21() WRITELN(OUTPUT, 'LOAD ',ORD(SB):5,ORD(SB^.SBTYP):3,' TO ', ORD(WHERE):3, SB=RTSTACK); ()+21*)
04000 WITH SB^ DO
04010 BEGIN
04012 SBINF := SBINF-[SBSTKDELAY];
04020 IF SBRTSTK<>NIL THEN
04030 IF SBSTKDELAY IN SBRTSTK^.SBINF THEN
04040 LOADSTK(SBRTSTK);
04050 IF (WHERE IN [SBTSTK..SBTDL]) THEN CLEAR(SBRTSTK);
04060 TWISTED := FALSE;
04070 IF WHERE IN [SBTSTKN,SBTPR1,SBTPR2] THEN
04080 LOADSTK(SB)
04090 ELSE IF WHERE=SBTXN THEN LOAD(NORMAL(SB),SB)
04100 ELSE
04110 IF WHERE <> SBTVOID THEN
04120 BEGIN
04140 IF WHERE IN [SBTER0..SBTFPR3] THEN
04150 IF (WHERE IN REGSINUSE.FPR) AND (WHERE<>SBTYP) THEN
04160 BEGIN
04170 SB1 := RTSTACK;
04180 WHILE NOT(SB1^.SBTYP IN REGSINUSE.FPR) DO SB1 := SB1^.SBRTSTK;
04190 LOADSTK(SB1);
04200 END;
04240 TYPS := [WHERE, RTSTACK^.SBTYP];
04250 IF (RTSTACK<>SB) THEN
04260 IF (TYPS <= [SBTSTK..SBTDL]) AND NOT(SBTYP IN [SBTSTK..SBTDL]) OR (TYPS<=[SBTE,SBTER0]) THEN
04270 BEGIN TWISTED:=TRUE; TWIST;
04280 (*+32() ASSERT (RTSTACK =SB,'LOAD-B '); ()+32*)
04290 END;
04310 TEMPOP := POPARRAY[WHERE,SBTYP];
04320 (*+32() ASSERT(TEMPOP<>PNONE, 'LOAD-C '); ()+32*)
04330 IF (TEMPOP<>PNOOP) OR (SBTYP=SBTSTKR0) THEN
04340 CASE SBTYP OF
04350 SBTRPROC,SBTPROC,SBTVAR: BEGIN
04360 SAVE := ADJUSTSP; ADJUSTSP := 0;
04370 RTSTKDEPTH := RTSTKDEPTH+SAVE;
04380 IF WHERE <> SBTE THEN BEGIN LOAD(SBTE,SB); LOAD(WHERE,SB) END
04390 ELSE BEGIN TOFFSET:=GENLCLGBL(TEMPOP,SB);
04400 IF SBTYP=SBTVAR THEN
04410 EMITX2(TEMPOP,OCVIMMED,SBLOCRG,OCVIMMED,TOFFSET)
04420 ELSE BEGIN (*SBTPROC OR SBTRPROC*)
04430 IF SBTYP=SBTPROC THEN OCVFIX := OCVMEM
04440 ELSE (* SBTRPROC *) OCVFIX := OCVFREF;
04450 EMITX2(TEMPOP,OCVFIX,SBXPTR,OCVIMMED,TOFFSET);
04460 END;
04470 END;
04480 RTSTKDEPTH := RTSTKDEPTH-SAVE;
04490 ADJUSTSP := SAVE;
04500 END;
04510 (**)
04520 SBTID,SBTIDV: BEGIN TOFFSET:=GENLCLGBL(TEMPOP,SB);
04530 EMITX1(TEMPOP,OCVIMMED,TOFFSET) END;
04540 SBTLIT: EMITX1(TEMPOP, OCVIMMED, SBVALUE);
04550 SBTDEN: GENDENOT(TEMPOP,SB);
04560 SBTPR1,SBTPR2,
04570 SBTSTK,SBTSTK4,SBTDL,SBTER0: EMITOP(TEMPOP);
04580 SBTE: WITH REGSINUSE DO
04600 BEGIN
04610 (*ATTEMPT TO STACK E MUST FORCE STACKING OF ALL E'S ABOVE IT;
04612 THESE ARE THE EXTRAS*)
04620 SB1 := RTSTACK; EEXTRA := 0; EC := ECOUNT; TEMPOP := TEMPOP+ORD(EC=2)+ORD(EC>2);
04630 REPEAT WITH SB1^ DO (*PREVENT CLEAR IF TEMPOP IS AN OCODE*)
04632 BEGIN
04634 IF SBTYP=SBTE THEN
04636 BEGIN FILL(SBTSTK, SB1); EEXTRA := EEXTRA+1 END
04637 ELSE IF SBTYP=SBTER0 THEN
04638 BEGIN FILL(SBTSTKR0, SB1); EEXTRA := 0 END
04639 ELSE IF SBTYP IN [SBTFPR0,SBTFPR1] THEN EEXTRA := 0;
04640 SB2 := SB1; SB1 := SBRTSTK;
04642 END
04644 UNTIL SB2=SB;
04650 EMITX1(TEMPOP, OCVIMMED, ECOUNT);
04660 EEXTRA := EC-EEXTRA;
04661 (*NO. OF E'S OR ER0'S ABOVE FIRST FPR, OR ABOVE & INCL. FIRST ER0*)
04662 END;
04670 SBTSTKR0,SBTFPR0,SBTFPR1: WITH REGSINUSE DO
04680 BEGIN
04690 IF EEXTRA<>0 THEN
04700 BEGIN
04710 EMITX1(PSTKTOE+ORD(EEXTRA=2)+ORD(EEXTRA>2), OCVIMMED, EEXTRA);
04720 SB1 := RTSTACK;
04722 WHILE EEXTRA>0 DO WITH SB1^ DO
04723 BEGIN
04724 IF SBTYP=SBTSTK THEN
04725 BEGIN FILL(SBTE, SB1); EEXTRA := EEXTRA-1 END
04726 ELSE IF SBTYP=SBTSTKR0 THEN
04727 BEGIN FILL(SBTER0, SB1); EEXTRA := EEXTRA-1 END;
04728 SB1 := SBRTSTK;
04729 END;
04730 END;
04740 EMITOP(TEMPOP);
04750 END;
04760 END;
04770 FILL(WHERE,SB);
04780 END;
04790 IF TWISTED THEN TWIST;
04800 END;
04810 END;
04820 (**)
04830 PROCEDURE PARAM (*(TYP:OPDTYP; OPND:INTEGER; OPCOD: POP; ALIGN: INTEGER; FIRSTIME: BOOLEAN)*);
04840 VAR TEMPOP:POP;
04850 OPERANDUSED, INL: BOOLEAN;
04860 BEGIN
04870 IF OCV<>OCVNONE THEN
04880 BEGIN
04890 TEMPOP := PPUSHIM;
04900 EMITOP(TEMPOP) ; ADJUSTSP := ADJUSTSP+SZWORD;
04910 END;
04920 IF FIRSTIME AND (((RTSTKDEPTH+ADJUSTSP) MOD 4 = 0) = ODD(ALIGN+APARAMS)) THEN
04930 BEGIN EMITOP(PALIGN); ADJUSTSP := ADJUSTSP+SZWORD END;
04940 OPRAND:=OPND; OCV := TYP;
04950 END;
04960 (**)
04970 ()+05*)
04980 (**)
04990 (*+01() (*+31() (*$T+ +) ()+31+) ()+01*)
05000 (*+05() (*+31() (*$T+ +) ()+31+) ()+05*)
05010 (**)
05020 (**)
05030 (**)
05040 PROCEDURE CLEAR (SB:PSB);
05050 (*ENSURES THAT NOTHING ON RTSTACK FROM SB DOWNWARDS IS IN A REGISTER*)
05060 LABEL 9;
05070 VAR TEMPPTR: PSB;
05080 BEGIN
05090 (*INVARIANT: IF SBTYP IN [SBTSTK..SBTSTKN], NOTHING BELOW SB IS IN A REGISTER*)
05100 TEMPPTR:=SB;
05110 WHILE TEMPPTR<>NIL DO WITH TEMPPTR^ DO
05120 IF SBTYP>SBTSTKN THEN
05130 BEGIN LOADSTK(TEMPPTR); GOTO 9 END
05140 ELSE IF SBTYP>=SBTSTK THEN GOTO 9 (*BECAUSE OF INVARIANT*)
05150 ELSE TEMPPTR := SBRTSTK;
05160 9:
05170 END;
05180 (**)
05190 (*-23()
05200 ()-23*)
05210 PROCEDURE UNSTKP1 (*+05() (TYP:OPDTYP; OPND:PSB) ()+05*);
05220 BEGIN
05230 IF TYP = OCVSBS THEN
05240 (*ASSERT: OPND = RTSTACK*)
05250 REPEAT
05260 OPND := RTSTACK;
05270 UNSTACKSB;
05280 IF OPND^.SBTYP IN [SBTSTK..SBTDL] THEN ADJUSTSP := ADJUSTSP+OPND^.SBLEN;
05290 OPND^.SBTYP := SBTVOID;
05300 UNTIL OPND=SRSTK[SRSUBP+1].SB
05310 ELSE IF TYP <> OCVSBP THEN
05320 BEGIN UNSTACKSB;
05330 IF OPND^.SBTYP IN [SBTSTK..SBTDL] THEN ADJUSTSP := ADJUSTSP+OPND^.SBLEN;
05340 OPND^.SBTYP:=SBTVOID;
05350 END
05360 (*+02() ELSE (*TYP=OCVSBP*) ADJUSTSP := ADJUSTSP-LENOF(OPND); ()+02*)
05370 END;
05380 (**)
05390 (*-23()
05400 ()-23*)
05410 (**)
05420 PROCEDURE EMITX0(OPCOD: POP);
05430 BEGIN IF NOT SETINLINE(OPCOD) THEN BEGIN ADJUSTSP := 0; CLEAR(RTSTACK) END;
05440 (*+05() PARAM(OCVNONE,0,OPCOD,0,NOT SETINLINE(OPCOD)); ()+05*)
05450 EMITOP(OPCOD);
05460 END;
05470 (**)
05480 (**)
05490 PROCEDURE EMITX1 (*+05() (OPCOD:POP; TYP1:OPDTYP;OPND1:ADDRINT) ()+05*);
05500 VAR SB1:PSB; NOTINL:BOOLEAN;
05510 BEGIN
05520 (*-24()(*+23() WRITELN(LGO[ROUTNL^.RNLEVEL]); ()+23*) ()-24*)
05530 IF TYP1 = OCVRES THEN
05540 BEGIN
05550 SB1 := ASPTR(OPND1);
05560 EMITX0 (OPCOD);
05570 (*+32() ASSERT(CODETABLE[OPCOD].PR<>SBTVOID,'EMITX1-A ');
05580 ASSERT(SB1^.SBTYP=SBTVOID,'EMITX1-B '); ()+32*)
05590 FILL(CODETABLE[OPCOD].PR,SB1);
05600 SB1^.SBRTSTK:=RTSTACK; RTSTACK:=SB1;
05610 END
05620 ELSE
05630 BEGIN
05640 NOTINL := NOT(SETINLINE(OPCOD));
05650 IF NOTINL THEN ADJUSTSP := 0;
05660 IF TYP1 >= OCVSB THEN
05670 PROC1OP(OPCOD,TYP1,OPND1,NOTINL(*+05(),1()+05*))
05680 ELSE
05690 BEGIN
05700 IF NOTINL THEN CLEAR(RTSTACK);
05710 (*+01() NEXTREG := 0; ()+01*)
05720 PARAM(TYP1,OPND1,OPCOD(*+05(),1,NOTINL()+05*));
05730 END;
05740 EMITOP(OPCOD)
05750 END
05760 END;
05770 (**)
05780 (**)
05790 PROCEDURE EMITX2 (*+05() (OPCOD:POP; TYP1:OPDTYP;OPND1:ADDRINT;
05800 TYP2:OPDTYP; OPND2:ADDRINT) ()+05*);
05810 VAR SB2:PSB; NOTINL:BOOLEAN;
05820 BEGIN
05830 (*+23() WRITELN(LGO[ROUTNL^.RNLEVEL]); ()+23*)
05840 IF TYP2 = OCVRES THEN
05850 BEGIN
05860 SB2 := ASPTR(OPND2);
05870 EMITX1 (OPCOD, TYP1,OPND1);
05880 (*+32() ASSERT(CODETABLE[OPCOD].PR<>SBTVOID,'EMITX2-A ');
05890 ASSERT(SB2^.SBTYP=SBTVOID,'EMITX2-B '); ()+32*)
05900 FILL(CODETABLE[OPCOD].PR,SB2);
05910 SB2^.SBRTSTK:=RTSTACK; RTSTACK:=SB2;
05920 END
05930 ELSE
05940 BEGIN
05950 NOTINL := NOT(SETINLINE(OPCOD));
05960 IF NOTINL THEN ADJUSTSP := 0;
05970 IF TYP1 >= OCVSB THEN
05980 IF TYP2 >= OCVSB THEN PROC2OP(OPCOD,TYP1,OPND1,TYP2,OPND2,NOTINL(*+05(),2()+05*))
05990 ELSE BEGIN PROC1OP(OPCOD,TYP1,OPND1,NOTINL(*+05(),2()+05*));
06000 PARAM(TYP2,OPND2,OPCOD(*+05(),1,FALSE()+05*)) END
06010 ELSE
06020 BEGIN
06030 IF NOTINL THEN CLEAR(RTSTACK);
06040 (*+01() NEXTREG:=0; ()+01*)
06050 PARAM(TYP1,OPND1,OPCOD(*+05(),2,NOTINL()+05*));
06060 PARAM(TYP2,OPND2,OPCOD(*+05(),1,FALSE()+05*))
06070 END;
06080 EMITOP(OPCOD)
06090 END
06100 END;
06110 (**)
06120 (**)
06130 PROCEDURE EMITX3 (OPCOD:POP; TYP1:OPDTYP;OPND1:ADDRINT; TYP2:OPDTYP;OPND2:ADDRINT;
06140 TYP3:OPDTYP; OPND3:ADDRINT);
06150 VAR SB3:PSB; NOTINL:BOOLEAN;
06160 BEGIN
06170 (*+23() WRITELN(LGO[ROUTNL^.RNLEVEL]); ()+23*)
06180 IF TYP3 = OCVRES THEN
06190 BEGIN
06200 SB3 := ASPTR(OPND3);
06210 EMITX2 (OPCOD, TYP1,OPND1, TYP2,OPND2);
06220 (*+32() ASSERT(CODETABLE[OPCOD].PR<>SBTVOID,'EMITX3-A ');
06230 ASSERT(SB3^.SBTYP=SBTVOID,'EMITX3-B '); ()+32*)
06240 FILL(CODETABLE[OPCOD].PR,SB3);
06250 SB3^.SBRTSTK:=RTSTACK; RTSTACK:=SB3;
06260 END
06270 ELSE
06280 BEGIN
06290 NOTINL := NOT(SETINLINE(OPCOD));
06300 IF NOTINL THEN ADJUSTSP := 0;
06310 IF TYP1 >= OCVSB THEN
06320 IF TYP2 >= OCVSB THEN PROC2OP(OPCOD,TYP1,OPND1,TYP2,OPND2,NOTINL(*+05(),3()+05*))
06330 ELSE BEGIN PROC1OP(OPCOD,TYP1,OPND1,NOTINL(*+05(),3()+05*));
06340 PARAM(TYP2,OPND2,OPCOD(*+05(),2,FALSE()+05*)) END
06350 ELSE
06360 BEGIN
06370 IF NOTINL THEN CLEAR(RTSTACK);
06380 (*+01() NEXTREG:=0; ()+01*)
06390 PARAM(TYP1,OPND1,OPCOD(*+05(),3,NOTINL()+05*));
06400 PARAM(TYP2,OPND2,OPCOD(*+05(),2,FALSE()+05*))
06410 END;
06420 PARAM(TYP3,OPND3,OPCOD(*+05(),1,FALSE()+05*));
06430 EMITOP(OPCOD)
06440 END
06450 END;
06460 (**)
06470 (**)
06480 PROCEDURE EMITX4 (OPCOD:POP; TYP1:OPDTYP;OPND1:ADDRINT; TYP2:OPDTYP;OPND2:ADDRINT;
06490 TYP3:OPDTYP; OPND3:ADDRINT; TYP4:OPDTYP;OPND4:ADDRINT);
06500 VAR SB4:PSB; NOTINL:BOOLEAN;
06510 BEGIN
06520 (*+23() WRITELN(LGO[ROUTNL^.RNLEVEL]); ()+23*)
06530 IF TYP4 = OCVRES THEN
06540 BEGIN
06550 SB4 := ASPTR(OPND4);
06560 EMITX3 (OPCOD, TYP1,OPND1, TYP2,OPND2, TYP3,OPND3);
06570 (*+32() ASSERT(CODETABLE[OPCOD].PR<>SBTVOID,'EMITX4-A ');
06580 ASSERT(SB4^.SBTYP=SBTVOID,'EMITX4-B '); ()+32*)
06590 FILL(CODETABLE[OPCOD].PR,SB4);
06600 SB4^.SBRTSTK:=RTSTACK; RTSTACK:=SB4;
06610 END
06620 ELSE
06630 BEGIN
06640 NOTINL := NOT(SETINLINE(OPCOD));
06650 IF NOTINL THEN ADJUSTSP := 0;
06660 IF TYP1 >= OCVSB THEN
06670 IF TYP2 >= OCVSB THEN PROC2OP(OPCOD,TYP1,OPND1,TYP2,OPND2,NOTINL(*+05(),4()+05*))
06680 ELSE BEGIN PROC1OP(OPCOD,TYP1,OPND1,NOTINL(*+05(),4()+05*));
06690 PARAM(TYP2,OPND2,OPCOD(*+05(),3,FALSE()+05*)) END
06700 ELSE
06710 BEGIN
06720 IF NOTINL THEN CLEAR(RTSTACK);
06730 (*+01() NEXTREG:=0; ()+01*)
06740 PARAM(TYP1,OPND1,OPCOD(*+05(),4,NOTINL()+05*));
06750 PARAM(TYP2,OPND2,OPCOD(*+05(),3,FALSE()+05*))
06760 END;
06770 PARAM(TYP3,OPND3,OPCOD(*+05(),2,FALSE()+05*));
06780 PARAM(TYP4,OPND4,OPCOD(*+05(),1,FALSE()+05*));
06790 EMITOP(OPCOD)
06800 END
06810 END;
06820 (**)
06830 (**)
06840 PROCEDURE EMITX5 (OPCOD:POP; TYP1:OPDTYP;OPND1:ADDRINT; TYP2:OPDTYP;OPND2:ADDRINT;
06850 TYP3:OPDTYP;OPND3:ADDRINT;TYP4:OPDTYP;OPND4:ADDRINT;TYP5:OPDTYP;OPND5:ADDRINT);
06860 VAR SB5:PSB; NOTINL:BOOLEAN;
06870 BEGIN
06880 (*+23() WRITELN(LGO[ROUTNL^.RNLEVEL]); ()+23*)
06890 IF TYP5 = OCVRES THEN
06900 BEGIN
06910 SB5 := ASPTR(OPND5);
06920 EMITX4 (OPCOD, TYP1,OPND1, TYP2,OPND2, TYP3,OPND3,TYP4,OPND4);
06930 (*+32() ASSERT(CODETABLE[OPCOD].PR<>SBTVOID,'EMITX5-A ');
06940 ASSERT(SB5^.SBTYP=SBTVOID,'EMITX5-B '); ()+32*)
06950 FILL(CODETABLE[OPCOD].PR,SB5);
06960 SB5^.SBRTSTK:=RTSTACK; RTSTACK:=SB5;
06970 END
06980 ELSE
06990 BEGIN
07000 NOTINL := NOT(SETINLINE(OPCOD));
07010 IF NOTINL THEN ADJUSTSP := 0;
07020 IF TYP1 >= OCVSB THEN
07030 IF TYP2 >= OCVSB THEN PROC2OP(OPCOD,TYP1,OPND1,TYP2,OPND2,NOTINL(*+05(),5()+05*))
07040 ELSE BEGIN PROC1OP(OPCOD,TYP1,OPND1,NOTINL(*+05(),5()+05*));
07050 PARAM(TYP2,OPND2,OPCOD(*+05(),4,FALSE()+05*)) END
07060 ELSE
07070 BEGIN
07080 IF NOTINL THEN CLEAR(RTSTACK);
07090 (*+01() NEXTREG:=0; ()+01*)
07100 PARAM(TYP1,OPND1,OPCOD(*+05(),5,NOTINL()+05*));
07110 PARAM(TYP2,OPND2,OPCOD(*+05(),4,FALSE()+05*))
07120 END;
07130 PARAM(TYP3,OPND3,OPCOD(*+05(),3,FALSE()+05*));
07140 PARAM(TYP4,OPND4,OPCOD(*+05(),2,FALSE()+05*));
07150 PARAM(TYP5,OPND5,OPCOD(*+05(),1,FALSE()+05*));
07160 EMITOP(OPCOD)
07170 END
07180 END;
07190 (**)
07200 (**)
07210 (*-23()
07220 ()-23*) (* MORE PERQ DEPENDENT ROUTINES *)
07230 (**) (********************************)
07240 (*+05()
07250 PROCEDURE EMITBEG;
07260 VAR TEMP : PLEX;
07270 S: ARGSTRING;
07280 I,J: INTEGER;
07290 PROCEDURE NAMEFILE(S: ARGSTRING; SU, SL: INTEGER; VAR F: ANYFILE); EXTERN;
07300 FUNCTION GETARG(VAR S: ARGSTRING; SU, SL: INTEGER; I: INTEGER): BOOLEAN; EXTERN;
07310 BEGIN
07320 NEXTLABEL := 1;
07330 DATASTATE := ENDDATA;(* ??? *)
07340 ADJUSTSP := 0;
07350 WITH REGSINUSE DO
07360 BEGIN
07370 ECOUNT := 0;
07380 EEXTRA := 0;
07390 FPR := [];
07400 END;
07410 IF GETARG(S, 50, 1, 2) THEN
07420 BEGIN
07430 J := 1; WHILE S[J]<>CHR(0) DO J := J+1; S[J+1] := CHR(0);
07440 FOR I := 0 TO LASTRNLEVEL DO
07450 BEGIN S[J] := CHR(I+ORD('0')); NAMEFILE(S, 50, 1, LGO[I]); REWRITE(LGO[I]) END;
07460 END;
07470 (*+33() WRITELN(LGO[ROUTNL^.RNLEVEL], 'stab "a68",8#44,0,0,_AL68_'); ()+33*)
07480 WRITELN(LGO[ROUTNL^.RNLEVEL],'global _AL68_');
07490 WRITELN(LGO[ROUTNL^.RNLEVEL],'function _AL68_');
07492 ROUTNL^.RNADDRESS := GETNEXTLABEL;
07494 WRITELN(LGO[ROUTNL^.RNLEVEL],'function L', ROUTNL^.RNADDRESS:1);
07500 ROUTNL^.RNPROCBLK := GETNEXTLABEL;
07502 WRITELN(LGO[ROUTNL^.RNLEVEL], 'data');
07504 WRITELN(LGO[ROUTNL^.RNLEVEL], 'int 1,1,1,1');
07506 (*so that no dblock has address < maxsize of undressed value*)
07510 EMITX1(PASP, OCVFIM, ROUTNL^.RNPROCBLK);
07520 EMITX0(PPBEGIN+1);
07530 EMITX0(PPBEGIN);
07540 END;
07550 (**)
07560 (**)
07570 FUNCTION EMITRTNHEAD: LABL;
07580 VAR L: LABL;
07590 BEGIN
07600 L := GETNEXTLABEL;
07610 (*+33() WRITELN(LGO[ROUTNL^.RNLEVEL], 'stab "a68",8#44,0,0,L', L:1); ()+33*)
07620 WRITELN(LGO[ROUTNL^.RNLEVEL], 'function L', L:1);
07630 EMITRTNHEAD := L;
07640 END;
07650 (**)
07660 (**)
07670 PROCEDURE EMITEND;
07680 BEGIN
07690 WITH ROUTNL^ DO IF (RNLENIDS MOD 4) = 0 THEN RNLENIDS := RNLENIDS+SZWORD;
07700 FIXUPFIM(ROUTNL^.RNPROCBLK, -(ROUTNL^.RNLENIDS+SIZIBTOP+SZWORD+FIRSTIBOFFSET));
07710 RTSTKDEPTH := 0;
07720 EMITX0(PPEND);
07730 WRITELN(LGO[ROUTNL^.RNLEVEL],' return');
07740 END;
07750 ()+05*)
07760 (**)
07770 (*+05()
07780 PROCEDURE GENDENOT (* (OPCOD: POP; SB: PSB) *) ;
07790 VAR I: INTEGER;
07800 ALABL: LABL;
07810 THING: OBJECT;
07820 BEGIN WITH SB^ DO
07830 WITH SBLEX^ (*A LEXEME*) DO
07840 IF SBLEX=LEXFALSE THEN
07850 EMITX1(OPCOD, OCVIMMED, 0)
07860 ELSE IF SBLEX=LEXTRUE THEN
07870 EMITX1(OPCOD, OCVIMMED, TRUEVALUE)
07880 ELSE IF ((SBMODE=MDINT) OR (SBMODE=MDBITS) OR (SBMODE=MDCHAR))
07890 AND (LXTOKEN=TKDENOT) THEN
07900 EMITX1(OPCOD, OCVIMMED, LXDENRP)
07910 ELSE
07920 BEGIN
07930 IF LXV.LXPYPTR=0 THEN
07940 BEGIN
07950 DATASTATE := STARTDATA; ALABL := FIXUPM;
07960 LXV.LXPYPTR := ALABL;
07970 IF SBMODE^.MDV.MDPILE THEN WITH THING DO
07980 BEGIN
07990 FIRSTWORD := 0; PCOUNT := 255;
08000 EMITXWORD(OCVIMMED, FIRSTWORD);
08010 EMITXWORD(OCVIMMED, 0);
08012 EMITXWORD(OCVIMMED, 0);
08014 EMITXWORD(OCVIMMED, 0);
08020 EMITXWORD(OCVIMMED, LXDENRP);
08030 FOR I := 3 TO LXCOUNT DO
08040 EMITXWORD(OCVIMMED, INTEGERS[I])
08050 END
08060 ELSE IF SBMODE^.MDV.MDID IN [MDIDCHAN,MDIDPASC] THEN
08070 BEGIN
08080 EMITXWORD(OCVIMMED, -2);
08090 EMITXPROC(OCVEXT, ORD(SBLEX));
08100 END
08110 ELSE
08120 BEGIN
08130 EMITXWORD(OCVIMMED,INTEGERS[2]);
08140 EMITXWORD(OCVIMMED,INTEGERS[3]);
08150 END;
08160 END;
08170 EMITX1(OPCOD+1, OCVMEM, LXV.LXPYPTR)
08180 END;
08190 END;
08200 (**)
08210 PROCEDURE GENDP(M: MODE);
08220 (*FUNCTION: RETURNS THE ADDRESS OF THE DBLOCK FOR MODE M, OR THE VALULENGTH,
08230 IN GLOBAL VARIABLE GENDPVAL, WITH CORRESPONDING OPDTYP IN GENDPOCV.
08240 *)
08250 VAR OFFSET: 0..127;
08260 PROCEDURE DBLOCK(M: MODE);
08270 VAR I, J: INTEGER;
08280 BEGIN WITH M^ DO
08290 FOR I := 0 TO MDV.MDCNT-1 DO
08300 WITH MDSTRFLDS[I] DO WITH MDSTRFMD^.MDV DO
08310 IF MDDRESSED THEN
08320 BEGIN EMITXWORD(OCVIMMED, OFFSET); OFFSET := OFFSET+MDLEN END
08330 ELSE IF MDID=MDIDSTRUCT THEN
08340 DBLOCK(MDSTRFMD)
08350 ELSE OFFSET := OFFSET+MDLEN
08360 END;
08370 PROCEDURE DBLOCKM(M: MODE);
08380 VAR I: INTEGER; X: XTYPE;
08390 BEGIN WITH M^ DO
08400 FOR I := 0 TO MDV.MDCNT-1 DO
08410 WITH MDSTRFLDS[I] DO
08420 BEGIN X := TX(MDSTRFMD);
08430 IF X=12 THEN DBLOCKM(MDSTRFMD)
08440 ELSE EMITXWORD(OCVIMMED, X+1)
08450 END
08460 END;
08470 BEGIN WITH M^ DO
08480 IF MDV.MDID=MDIDROW THEN GENDP(MDPRRMD)
08490 ELSE IF MDV.MDID=MDIDSTRUCT THEN
08500 BEGIN
08510 IF MDSTRSDB=0 THEN (*DBLOCK MUST BE CREATED*)
08520 BEGIN
08530 DATASTATE := STARTDATA; MDSTRSDB := FIXUPM;
08540 EMITXWORD(OCVIMMED, MDV.MDLEN);
08550 OFFSET := 0; DBLOCK(M);
08560 EMITXWORD(OCVIMMED, -1);
08570 DBLOCKM(M);
08580 END;
08590 GENDPOCV := OCVMEM; GENDPVAL :=MDSTRSDB
08600 END
08610 ELSE IF MDV.MDDRESSED THEN
08620 BEGIN GENDPVAL:=0; GENDPOCV:=OCVIMMED END
08630 ELSE
08640 BEGIN GENDPVAL := MDV.MDLEN; GENDPOCV := OCVIMMED END;
08650 END;
08660 (**)
08670 (**)
08680 ()+05*)
08690 (**)
08700 (**)
08710 (*-01() (*-02() (*-05()
08720 (*MODEL EMITBEG AND EMITEND FOR THOSE WHO HAVE NOT WRITTEN THEIR OWN YET*)
08730 PROCEDURE EMITBEG;
08740 BEGIN
08750 NEXTLABEL := 1;
08760 REWRITE(LGO);
08770 (*NOW INITIALIZE YOUR CODE BUFFER, OR WHATEVER, AND EMIT INIAL CODE*)
08780 END;
08790 (**)
08800 (**)
08810 PROCEDURE EMITEND;
08820 BEGIN
08830 (*EMIT YOUR FINAL CODE*)
08840 (*FLUSH YOUR CODE BUFFER, OR WHATEVER*)
08850 END;
08860 ()-05*) ()-02*) ()-01*)
08870 (**)
08880 (*-02() (*-05()
08890 (**)
08900 PROCEDURE GENDP(M: MODE);
08910 (*FUNCTION: RETURNS THE ADDRESS OF THE DBLOCK FOR MODE M, OR THE VALULENGTH,
08920 IN GLOBAL VARIABLE GENDPVAL, WITH CORRESPONDING OPDTYP IN GENDPOCV.
08930 *)
08940 VAR JUMPOVER: LABL;
08950 OFFSET: 0..127;
08960 PROCEDURE DBLOCK(M: MODE);
08970 VAR I, J: INTEGER;
08980 BEGIN WITH M^ DO
08990 FOR I := 0 TO MDV.MDCNT-1 DO
09000 WITH MDSTRFLDS[I] DO WITH MDSTRFMD^.MDV DO
09010 IF MDDRESSED THEN
09020 BEGIN EMITXWORD(OCVIMMED, OFFSET); OFFSET := OFFSET+MDLEN END
09030 ELSE IF MDID=MDIDSTRUCT THEN
09040 DBLOCK(MDSTRFMD)
09050 ELSE OFFSET := OFFSET+MDLEN
09060 END;
09070 PROCEDURE DBLOCKM(M: MODE);
09080 VAR I: INTEGER; X: XTYPE;
09090 BEGIN WITH M^ DO
09100 FOR I := 0 TO MDV.MDCNT-1 DO
09110 WITH MDSTRFLDS[I] DO
09120 BEGIN X := TX(MDSTRFMD);
09130 IF X=12 THEN DBLOCKM(MDSTRFMD)
09140 ELSE EMITXWORD(OCVIMMED, X+1)
09150 END
09160 END;
09170 BEGIN WITH M^ DO
09180 IF MDV.MDID=MDIDROW THEN GENDP(MDPRRMD)
09190 ELSE IF MDV.MDID=MDIDSTRUCT THEN
09200 BEGIN
09210 IF MDSTRSDB=0 THEN (*DBLOCK MUST BE CREATED*)
09220 BEGIN
09230 JUMPOVER := GETNEXTLABEL; EMITX1(PJMP, OCVFREF, JUMPOVER);
09240 MDSTRSDB := FIXUPM;
09250 EMITXWORD(OCVIMMED, MDV.MDLEN);
09260 OFFSET := 0; DBLOCK(M);
09270 EMITXWORD(OCVIMMED, -1);
09280 DBLOCKM(M);
09290 FIXUPF(JUMPOVER)
09300 END;
09310 GENDPOCV := OCVMEM; GENDPVAL :=MDSTRSDB
09320 END
09330 ELSE IF MDV.MDDRESSED THEN
09340 BEGIN GENDPVAL:=0; GENDPOCV:=OCVIMMED END
09350 ELSE
09360 BEGIN GENDPVAL := MDV.MDLEN; GENDPOCV := OCVIMMED END
09370 END;
09380 (**)
09390 ()-05*) ()-02*)
09400 (**)
09410 FUNCTION GETCASE(M: MODE; OLST: OLSTTYP; SB: PSB): STATE;
09420 (*FUNCTION: COMPUTES AN ADDITION TO SOME OPCOD.
09430 THE SB HERE AND IN RELATED PLACES IS A TEMPORARY KLUDGE ??????
09440 *)
09450 VAR WHICH: STATE;
09460 WEAKREF: BOOLEAN;
09470 BEGIN WITH M^ DO
09480 BEGIN
09490 IF SB<>NIL THEN WEAKREF:=(SBWEAKREF IN SB^.SBINF) ELSE WEAKREF:=FALSE;
09500 IF NOT MDV.MDPILE THEN
09510 IF MDV.MDLEN=SZINT THEN WHICH := 0 ELSE WHICH := 1
09520 ELSE IF WEAKREF THEN WHICH:=2
09530 ELSE IF MDV.MDID=MDIDROW THEN WHICH:=3
09540 ELSE IF MDV.MDDRESSED THEN WHICH:=4
09550 ELSE WHICH:=5;
09560 NEEDDP := OLST[WHICH].DP;
09570 GETCASE := OLST[WHICH].OVAL
09580 END
09590 END;
09600 (**)
09610 (**)
09620 PROCEDURE GENOP(VAR OPCOD: POP; M: MODE; VAR OLIST: OLSTTYP; SB: PSB);
09630 (*USES GETCASE TO MODIFY OPCOD AND DOES GENDP IF NECESSARY*)
09640 BEGIN
09650 OPCOD := OPCOD+GETCASE(M, OLIST, SB);
09660 IF NEEDDP THEN
09670 BEGIN
09680 IF SB<>NIL THEN
09690 IF SBWEAKREF IN SB^.SBINF THEN M := M^.MDPRRMD;
09700 GENDP(M);
09710 END
09720 ELSE BEGIN GENDPOCV:=OCVNONE; GENDPVAL:=0 END
09730 END;
09740 (**)
09750 (**)
09760 FUNCTION GENLCLGBL (*+05() (VAR OPCOD: POP; SB: PSB):INTEGER ()+05*) ;
09770 VAR I,X: INTEGER;
09780 VP : SBTTYP;
09790 BEGIN WITH SB^ DO
09800 BEGIN
09810 (*-05() GENLCLGBL:=SBOFFSET; ()-05*)
09820 (*+05() GENLCLGBL:=-SBOFFSET; ()+05*)
09830 IF (SBLEVEL = 0) (*+05() AND (SBLEVEL<>ROUTNL^.RNLEVEL) ()+05*) THEN (*GLOBAL*)
09840 BEGIN X:=1; (*-05() GENLCLGBL:=SBOFFSET+FIRSTIBOFFSET; ()-05*)
09850 END
09860 ELSE IF SBLEVEL = ROUTNL^.RNLEVEL THEN (*LOCAL*) X := 0
09870 ELSE (*INTERMEDIATE*) BEGIN
09880 (*-02() EMITX0(PENVCHAIN);
09890 FOR I:=1 TO ROUTNL^.RNLEVEL-SBLEVEL-1 DO
09900 BEGIN
09910 EMITX0(PENVCHAIN+1);
09920 END;
09930 ()-02*)
09940 (*+02() EMITX1(PENVCHAIN,OCVIMMED,ROUTNL^.RNLEVEL-SBLEVEL); ()+02*)
09950 X := 2 END;
09960 OPCOD := OPCOD+X;
09970 END
09980 END;
09990 (**)
10000 (**)
10010 (*-05()
10020 PROCEDURE GENDENOT (* (OPCOD: POP; SB: PSB) *) ;
10030 VAR THING: OBJECT; I: INTEGER;
10040 JUMPOVER: LABL;
10050 BEGIN WITH SB^ DO
10060 WITH SBLEX^ (*A LEXEME*) DO
10070 IF SBMODE^.MDV.MDID IN [MDIDCHAN,MDIDPASC] THEN
10080 EMITX1(OPCOD, OCVEXT, ORD(SBLEX))
10090 ELSE IF SBLEX=LEXFALSE THEN
10100 EMITX1(OPCOD, OCVIMMED, 0)
10110 ELSE IF ((LXDENMD=MDINT) OR (LXDENMD=MDBITS) OR (LXDENMD=MDCHAR))
10120 (*+01() AND (LXDENRP<400000B) ()+01*) AND (LXTOKEN=TKDENOT) THEN
10130 EMITX1(OPCOD, OCVIMMED, LXDENRP)
10140 ELSE
10150 BEGIN
10160 IF LXV.LXPYPTR=0 THEN
10170 BEGIN
10180 JUMPOVER := GETNEXTLABEL; EMITX1(PJMP, OCVFREF, JUMPOVER);
10190 LXV.LXPYPTR := FIXUPM;
10200 IF SBLEX=LEXTRUE THEN
10210 EMITXWORD(OCVIMMED, TRUEVALUE)
10220 ELSE IF LXDENMD^.MDV.MDPILE THEN WITH THING DO
10230 BEGIN
10240 FIRSTWORD := 0; PCOUNT := 255;
10250 LENGTH := (*-04() LXDENRP; ()-04*)(*+04() SHRINK(LXDENRP); ()+04*)
10260 EMITXWORD(OCVIMMED, FIRSTWORD);
10270 FOR I := 3 TO LXCOUNT DO
10280 EMITXWORD(OCVIMMED, INTEGERS[I])
10290 END
10300 ELSE EMITXWORD(OCVIMMED, LXDENRP);
10310 FIXUPF(JUMPOVER)
10320 END;
10330 IF LXTOKEN=TKDENOT THEN (*NOT LEXTRUE*)
10340 IF LXDENMD^.MDV.MDPILE THEN OPCOD := OPCOD-1;
10350 EMITX1(OPCOD+1, OCVMEM, LXV.LXPYPTR)
10360 END
10370 END;
10380 ()-05*)
~>
####S