1079 lines
42 KiB
OpenEdge ABL
1079 lines
42 KiB
OpenEdge ABL
~>|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
|