home *** CD-ROM | disk | FTP | other *** search
Oberon Text | 1994-10-17 | 17.7 KB | 496 lines |
- Syntax10.Scn.Fnt
- MODULE OBH; (*NW 7.6.87 / 11.7.93*)
- IMPORT OBS, OBT, OBC;
- CONST
- (*instruction format prefixes*)
- F6 = 4EH; F7 = 0CEH; F9 = 3EH; F11 = 0BEH;
- (*object and item modes*)
- Var = 1; VarX = 2; Ind = 3; IndX = 4; RegI = 5;
- RegX = 6; Abs = 7; Con = 8; Stk = 9; Stk0 = 10; Coc = 11; Reg = 12;
- Fld = 13; LProc = 15; CProc = 17; IProc = 18; Mod = 19;
- (*structure forms*)
- Undef = 0; Byte = 1; Bool = 2; Char = 3; SInt = 4; Int = 5; LInt = 6;
- Real = 7; LReal = 8; Set = 9; String = 10; NilTyp = 11; NoTyp = 12;
- Pointer = 13; ProcTyp = 14; Array = 15; DynArr = 16; Record = 17;
- TYPE LabelRange* = RECORD low*, high*: INTEGER; label*: INTEGER END ;
- VAR clrchk*, stkchk*: BOOLEAN;
- lengcode: ARRAY 18 OF INTEGER;
- PROCEDURE setCC(VAR x: OBT.Item; cc: LONGINT);
- BEGIN
- x.typ := OBT.booltyp; x.mode := Coc; x.a0 := cc; x.a1 := 0; x.a2 := 0
- END setCC;
- PROCEDURE AdjustSP*(n: LONGINT);
- BEGIN (*ADJSPB n*)
- IF n <= 127 THEN OBC.PutF3(-5A84H); OBC.PutByte(n)
- ELSE OBC.PutF3(-5A83H); OBC.PutWord(n)
- END
- END AdjustSP;
- PROCEDURE move(L: INTEGER; VAR x, y: OBT.Item);
- BEGIN
- IF (y.mode = Con) & (y.a0 <= 7) & (y.a0 >= -8) THEN OBC.PutF2(L+5CH, y.a0, x) (*MOVQi*)
- ELSE OBC.PutF4(L+14H, x, y) (*MOVi*)
- END
- END move;
- PROCEDURE load(VAR x: OBT.Item);
- VAR y: OBT.Item;
- BEGIN IF x.mode # Reg THEN y := x; OBC.GetReg(x); move(lengcode[x.typ.form], x, y) END
- END load;
- PROCEDURE moveBW(VAR x, y: OBT.Item);
- BEGIN
- IF (y.mode = Con) & (y.a0 <= 7) & (y.a0 >= -8) THEN OBC.PutF2(5DH, y.a0, x)
- ELSE OBC.Put(F7, 10H, x, y) (*MOVXBW*)
- END
- END moveBW;
- PROCEDURE moveBD(VAR x, y: OBT.Item);
- BEGIN
- IF (y.mode = Con) & (y.a0 <= 7) & (y.a0 >= -8) THEN OBC.PutF2(5FH, y.a0, x)
- ELSE OBC.Put(F7, 1CH, x, y) (*MOVXBD*)
- END
- END moveBD;
- PROCEDURE moveWD(VAR x, y: OBT.Item);
- BEGIN
- IF (y.mode = Con) & (y.a0 <= 7) & (y.a0 >= -8) THEN OBC.PutF2(5FH, y.a0, x)
- ELSE OBC.Put(F7, 1DH, x, y) (*MOVXWD*)
- END
- END moveWD;
- PROCEDURE Leng(VAR x: OBT.Item; L: LONGINT);
- VAR y: OBT.Item;
- BEGIN
- IF L <= 7 THEN OBC.PutF2(5FH, L, x) (*MOVQD*)
- ELSE y.mode := Con; y.a0 := L; y.typ := OBT.linttyp; OBC.PutF4(17H, x, y)
- END
- END Leng;
- PROCEDURE MoveBlock(VAR x, y: OBT.Item; s: LONGINT; param: BOOLEAN);
- VAR L: INTEGER; z: OBT.Item;
- BEGIN
- IF s > 0 THEN
- IF param THEN s := (s+3) DIV 4 * 4; AdjustSP(s) END ;
- IF s <= 16 THEN
- OBC.Put(F7, 0, x, y); OBC.PutDisp(s-1) (*MOVMB*)
- ELSE
- z.mode := Reg; z.a0 := 1; OBC.PutF4(27H, z, y); (*ADDR y,R1*)
- z.a0 := 2; OBC.PutF4(27H, z, x); z.a0 := 0; (*ADDR x,R2*)
- IF s MOD 4 = 0 THEN L := 3; s := s DIV 4
- ELSIF s MOD 2 = 0 THEN L := 1; s := s DIV 2
- ELSE L := 0
- END ;
- Leng(z, s);
- OBC.PutF1(14); OBC.PutByte(L); OBC.PutByte(0) (*MOVS*)
- END
- END
- END MoveBlock;
- PROCEDURE DynArrBnd(ftyp, atyp: OBT.Struct; lev: INTEGER; adr: LONGINT; varpar: BOOLEAN);
- VAR f: INTEGER; x, y, z: OBT.Item;
- BEGIN (* ftyp.form = DynArr *)
- x.mode := Stk; y.mode := Var;
- IF varpar & (ftyp.BaseTyp.form = Byte) THEN
- IF atyp.form # DynArr THEN
- IF (atyp.form # Array) OR (atyp.BaseTyp.size > 1) THEN OBS.Mark(-1) END ;
- Leng(x, atyp.size)
- ELSE y.lev := lev; y.a0 := adr + atyp.adr; y.typ := OBT.linttyp;
- atyp := atyp.BaseTyp;
- IF atyp.form # DynArr THEN
- IF atyp.size > 1 THEN
- OBS.Mark(-1); z.mode := Con; z.typ := OBT.linttyp; z.a0 := atyp.size;
- load(y); OBC.Put(F7, 23H, y, z); (* MULD z, Ry *)
- z.mode := Con; z.typ := OBT.linttyp; z.a0 := atyp.size
- END
- ELSE OBS.Mark(-1); load(y); OBC.PutF2(0FH, 1, y);
- REPEAT z.mode := Var; z.lev := lev; z.a0 := atyp.adr + adr; z.typ := OBT.linttyp;
- load(z); OBC.Put(F7, 23H, y, z); (* MULD Rz, Ry *)
- atyp := atyp.BaseTyp
- UNTIL atyp.form # DynArr;
- IF atyp.size > 1 THEN
- z.mode := Con; z.typ := OBT.linttyp; z.a0 := atyp.size;
- OBC.Put(F7, 23H, y, z) (* MULD z, Ry *)
- END
- END ;
- OBC.PutF4(17H, x, y) (* MOVD apdynarrlen, TOS *)
- END
- ELSE
- LOOP f := atyp.form;
- IF f = Array THEN Leng(x, atyp.size DIV atyp.BaseTyp.size)
- ELSIF f = DynArr THEN y.lev := lev; y.a0 := atyp.adr + adr; OBC.PutF4(17H, x, y)
- ELSE OBS.Mark(66); EXIT
- END ;
- ftyp := ftyp.BaseTyp; atyp := atyp.BaseTyp;
- IF ftyp.form # DynArr THEN
- IF ftyp # atyp THEN
- IF ~varpar & (ftyp.form = Pointer) & (atyp.form = Pointer) THEN
- ftyp := ftyp.BaseTyp; atyp := atyp.BaseTyp;
- IF (ftyp.form = Record) & (atyp.form = Record) THEN
- WHILE (ftyp # atyp) & (atyp # NIL) DO atyp := atyp.BaseTyp END ;
- IF atyp = NIL THEN OBS.Mark(113) END
- ELSE OBS.Mark(67)
- END
- ELSE OBS.Mark(67)
- END
- END ;
- EXIT
- END
- END
- END
- END DynArrBnd;
- PROCEDURE Trap*(n: INTEGER);
- BEGIN OBC.PutF1(0F2H); OBC.PutByte(n) (*BPT n*)
- END Trap;
- PROCEDURE CompareParLists*(x, y: OBT.Object);
- VAR xt, yt: OBT.Struct;
- BEGIN
- WHILE x # NIL DO
- IF y # NIL THEN
- xt := x.typ; yt := y.typ;
- WHILE (xt.form = DynArr) & (yt.form = DynArr) DO
- xt := xt.BaseTyp; yt := yt.BaseTyp
- END ;
- IF x.mode # y.mode THEN OBS.Mark(115)
- ELSIF xt # yt THEN
- IF (xt.form = ProcTyp) & (yt.form = ProcTyp) THEN
- CompareParLists(xt.link, yt.link)
- ELSE OBS.Mark(115)
- END
- END ;
- y := y.next
- ELSE OBS.Mark(116)
- END ;
- x := x.next
- END ;
- IF (y # NIL) & (y.mode <= Ind) & (y.a0 > 0) THEN OBS.Mark(117) END
- END CompareParLists;
- PROCEDURE Assign*(VAR x, y: OBT.Item; param: BOOLEAN);
- VAR f, g, L, u: INTEGER; s, vsz: LONGINT;
- p, q: OBT.Struct;
- tag, tdes: OBT.Item;
- BEGIN f := x.typ.form; g := y.typ.form;
- IF x.mode = Con THEN OBS.Mark(56)
- ELSIF (x.mode IN {Var, VarX}) & (x.lev < 0) THEN OBS.Mark(-3)
- END ;
- CASE f OF
- Undef, String:
- | Byte: IF g IN {Undef, Byte, Char, SInt} THEN
- IF param THEN moveBD(x, y) ELSE move(0, x, y) END
- ELSE OBS.Mark(113)
- END
- | Bool: IF param THEN u := 3 ELSE u := 0 END ;
- IF y.mode = Coc THEN
- IF (y.a1 = 0) & (y.a2 = 0) THEN OBC.PutF2(u+3CH, y.a0, x)
- ELSE
- IF ODD(y.a0) THEN OBC.PutF0(y.a0-1) ELSE OBC.PutF0(y.a0+1) END ;
- OBC.PutWord(y.a2); y.a2 := OBC.pc-2;
- OBC.FixLink(y.a1); OBC.PutF2(u+5CH, 1, x);
- OBC.PutF0(14); L := OBC.pc; OBC.PutWord(0);
- OBC.FixLink(y.a2); OBC.PutF2(u+5CH, 0, x); OBC.fixup(L)
- END
- ELSIF g = Bool THEN
- IF y.mode = Con THEN OBC.PutF2(u+5CH, y.a0, x)
- ELSIF param THEN OBC.Put(F7, 18H, x, y) (*MOVZBD*)
- ELSE OBC.PutF4(14H, x, y)
- END
- ELSE OBS.Mark(113)
- END
- | Char, SInt:
- IF g = f THEN
- IF param THEN moveBD(x, y) ELSE move(0, x, y) END
- ELSE OBS.Mark(113)
- END
- | Int: IF g = Int THEN
- IF param THEN moveWD(x, y) ELSE move(1, x, y) END
- ELSIF g = SInt THEN
- IF param THEN moveBD(x, y) ELSE moveBW(x, y) END
- ELSE OBS.Mark(113)
- END
- | LInt: IF g = LInt THEN move(3, x, y)
- ELSIF g = Int THEN moveWD(x, y)
- ELSIF g = SInt THEN moveBD(x, y)
- ELSE OBS.Mark(113)
- END
- | Real: IF g = Real THEN OBC.Put(F11, 5, x, y)
- ELSIF (SInt <= g) & (g <= LInt) THEN OBC.Put(F9, lengcode[g]+4, x, y)
- ELSE OBS.Mark(113)
- END
- | LReal:IF g = LReal THEN OBC.Put(F11, 4, x, y)
- ELSIF g = Real THEN OBC.Put(F9, 1BH, x, y)
- ELSIF (SInt <= g) & (g <= LInt) THEN OBC.Put(F9, lengcode[g], x, y)
- ELSE OBS.Mark(113)
- END
- | Set: IF g = f THEN move(3, x, y) ELSE OBS.Mark(113) END
- | Pointer:
- IF x.typ = y.typ THEN move(3, x, y)
- ELSIF g = NilTyp THEN OBC.PutF2(5FH, 0, x)
- ELSIF g = Pointer THEN
- p := x.typ.BaseTyp; q := y.typ.BaseTyp;
- IF (p.form = Record) & (q.form = Record) THEN
- WHILE (q # p) & (q # NIL) DO q := q.BaseTyp END ;
- IF q # NIL THEN move(3, x, y) ELSE OBS.Mark(113) END
- ELSE OBS.Mark(113)
- END
- ELSE OBS.Mark(113)
- END
- | Array: s := x.typ.size;
- IF x.typ = y.typ THEN MoveBlock(x, y, s, param)
- ELSIF (g = String) & (x.typ.BaseTyp.form = Char) THEN
- s := y.a1; vsz := x.typ.size; (*check length of string*)
- IF s > vsz THEN OBS.Mark(114) END ;
- IF param THEN
- vsz := (vsz+3) DIV 4 - (s+3) DIV 4;
- IF vsz > 0 THEN AdjustSP(vsz*4) END
- END ;
- MoveBlock(x, y, s, param)
- ELSE OBS.Mark(113)
- END
- | DynArr: s := x.typ.size;
- IF param THEN (*formal parameter is open array*)
- IF (g = String) & (x.typ.BaseTyp.form = Char) THEN Leng(x, y.a1)
- ELSIF y.mode >= Abs THEN OBS.Mark(59)
- ELSE DynArrBnd(x.typ, y.typ, y.lev, y.a0, FALSE)
- END ;
- IF g = DynArr THEN OBC.DynArrAdr(x, y)
- ELSE OBC.PutF4(27H, x, y)
- END
- ELSE OBS.Mark(113)
- END
- | Record: s := x.typ.size;
- IF x.typ # y.typ THEN
- IF g = Record THEN
- q := y.typ.BaseTyp;
- WHILE (q # NIL) & (q # x.typ) DO q := q.BaseTyp END ;
- IF q = NIL THEN OBS.Mark(113) END
- ELSE OBS.Mark(113)
- END
- END;
- IF OBC.typchk & ~param &
- ( ((x.mode = Ind) OR (x.mode = RegI)) & (x.obj = OBC.wasderef) (* p^ := *)
- OR (x.mode = Ind) & (x.obj # NIL) & (x.obj # OBC.wasderef) ) (* varpar := *) THEN
- tag := x; tdes.mode := Var; tdes.lev := -x.typ.mno; tdes.a0 := x.typ.adr;
- IF x.obj = OBC.wasderef THEN tag.a1 := - 4
- ELSE tag.mode := Var; INC(tag.a0, 4)
- END;
- OBC.PutF4(7, tdes, tag); (* CMPD tag, tdes *)
- OBC.PutF0(0); OBC.PutDisp(4); (* BEQ continue *)
- OBC.PutF1(0F2H); OBC.PutByte(19) (* BPT 19 *)
- END;
- MoveBlock(x, y, s, param)
- | ProcTyp:
- IF (x.typ = y.typ) OR (y.typ.form = NilTyp) THEN OBC.PutF4(17H, x, y)
- ELSIF (y.mode = LProc) & (y.lev <= 0) OR (y.mode = IProc) THEN
- (*procedure y to proc. variable x; check compatibility*)
- IF x.typ.BaseTyp = y.typ THEN
- CompareParLists(x.typ.link, y.obj.dsc);
- IF (y.a0 = 0) & (y.lev >= 0) THEN OBS.Mark(235) (*forward*) END ;
- y.mode := Var; OBC.PutF4(27H, x, y) (*ADDR*)
- ELSE OBS.Mark(118)
- END
- ELSE OBS.Mark(111)
- END
- | NoTyp, NilTyp: OBS.Mark(111)
- END
- END Assign;
- PROCEDURE FJ*(VAR loc: INTEGER);
- BEGIN OBC.PutF0(14); OBC.PutWord(loc); loc := OBC.pc-2
- END FJ;
- PROCEDURE CFJ*(VAR x: OBT.Item; VAR loc: INTEGER);
- BEGIN
- IF x.typ.form = Bool THEN
- IF x.mode # Coc THEN OBC.PutF2(1CH, 1, x); setCC(x, 0) END
- ELSE OBS.Mark(120); setCC(x, 0)
- END ;
- IF ODD(x.a0) THEN OBC.PutF0(x.a0-1) ELSE OBC.PutF0(x.a0+1) END ;
- loc := OBC.pc; OBC.PutWord(x.a2); OBC.FixLink(x.a1)
- END CFJ;
- PROCEDURE BJ*(loc: INTEGER);
- BEGIN OBC.PutF0(14); OBC.PutDisp(loc - OBC.pc + 1)
- END BJ;
- PROCEDURE CBJ*(VAR x: OBT.Item; loc: INTEGER);
- BEGIN
- IF x.typ.form = Bool THEN
- IF x.mode # Coc THEN OBC.PutF2(1CH, 1, x); setCC(x,0) END
- ELSE OBS.Mark(120); setCC(x, 0)
- END ;
- IF ODD(x.a0) THEN OBC.PutF0(x.a0-1) ELSE OBC.PutF0(x.a0+1) END ;
- OBC.PutDisp(loc - OBC.pc + 1);
- OBC.FixLinkWith(x.a2, loc); OBC.FixLink(x.a1)
- END CBJ;
- PROCEDURE LFJ*(VAR loc: INTEGER);
- BEGIN OBC.PutF0(14); OBC.PutWord(-4000H); OBC.PutWord(0); loc := OBC.pc-4
- END LFJ;
- PROCEDURE PrepCall*(VAR x: OBT.Item; VAR fpar: OBT.Object);
- BEGIN
- IF (x.mode = LProc) OR (x.mode = CProc) THEN
- fpar := x.obj.dsc
- ELSIF (x.typ # NIL) & (x.typ.form = ProcTyp) THEN
- fpar := x.typ.link
- ELSE OBS.Mark(121); fpar := NIL; x.typ := OBT.undftyp
- END
- END PrepCall;
- PROCEDURE Param*(VAR ap: OBT.Item; f: OBT.Object);
- VAR q: OBT.Struct; fp, tag: OBT.Item;
- BEGIN fp.mode := Stk; fp.typ := f.typ;
- IF f.mode = Ind THEN (*VAR parameter*)
- IF ap.mode >= Con THEN OBS.Mark(122) END ;
- IF fp.typ.form = DynArr THEN
- DynArrBnd(fp.typ, ap.typ, ap.lev, ap.a0, TRUE);
- IF ap.typ.form = DynArr THEN OBC.DynArrAdr(fp, ap)
- ELSE OBC.PutF4(27H, fp, ap)
- END
- ELSIF (fp.typ.form = Record) & (ap.typ.form = Record) THEN
- q := ap.typ;
- WHILE (q # fp.typ) & (q # NIL) DO q := q.BaseTyp END ;
- IF q # NIL THEN
- IF (ap.mode = Ind) & (ap.obj # NIL) & (ap.obj # OBC.wasderef) THEN
- (*actual par is VAR-par*)
- ap.mode := Var; ap.a0 := ap.a0 + 4; OBC.PutF4(17H, fp, ap);
- ap.a0 := ap.a0 - 4; OBC.PutF4(17H, fp, ap)
- ELSIF ((ap.mode = Ind) OR (ap.mode = RegI)) & (ap.obj = OBC.wasderef) THEN
- (*actual par is p^*)
- ap.a1 := - 4; OBC.PutF4(17H, fp, ap);
- IF ap.mode = Ind THEN ap.mode := Var ELSE ap.mode := Reg END;
- OBC.PutF4(17H, fp, ap)
- ELSE
- tag.mode := Var; tag.lev := -ap.typ.mno; tag.a0 := ap.typ.adr;
- OBC.PutF4(17H, fp, tag); OBC.PutF4(27H, fp, ap)
- END
- ELSE OBS.Mark(111)
- END
- ELSIF (ap.typ = fp.typ) OR ((fp.typ.form = Byte) & (ap.typ.form IN {Char, SInt})) THEN
- IF (ap.mode = Ind) & (ap.a1 = 0) THEN (*actual var par*)
- ap.mode := Var; OBC.PutF4(17H, fp, ap)
- ELSE OBC.PutF4(27H, fp, ap)
- END
- ELSE OBS.Mark(123)
- END
- ELSE Assign(fp, ap, TRUE)
- END
- END Param;
- PROCEDURE Call*(VAR x: OBT.Item);
- VAR stk, sL: OBT.Item;
- BEGIN
- IF x.mode = LProc THEN
- IF x.lev >= 0 THEN
- IF x.lev > 0 THEN
- sL.mode := Var; sL.typ := OBT.linttyp; sL.lev := x.lev; sL.a0 := 0;
- stk.mode := Stk; OBC.PutF4(27H, stk, sL) (*static link*)
- END ;
- OBC.PutF1(2); (*BSR*)
- IF x.a0 = 0 THEN OBC.PutWord(x.a1); x.obj.a1 := OBC.pc - 2 (*forward link*)
- ELSE OBC.PutDisp(x.a0 - OBC.pc + 1)
- END
- ELSE OBC.PutF1(2); OBC.PutExtAdr(-x.lev, x.a0) (*BSR*)
- END
- ELSIF (x.mode < Con) & (x.typ.form # Undef) THEN
- IF (x.mode = Var) & (x.lev > 0) & (x.lev = OBC.level) THEN x.mode := Ind
- ELSE load(x); x.mode := RegI
- END ;
- x.a1 := 0; OBC.PutF2(7FH, 12, x); x.typ := x.typ.BaseTyp (*JSRD*)
- ELSIF x.mode = CProc THEN
- OBC.PutF1(0E2H); OBC.PutByte(x.a0) (*SVC n*)
- ELSE OBS.Mark(121)
- END
- (*function result is marked when restoring registers*)
- END Call;
- PROCEDURE Enter*(mode: SHORTINT; VAR L: INTEGER);
- BEGIN OBC.CheckCodeSize; OBC.PutF1(82H); (*ENTER*)
- IF mode = IProc THEN OBC.PutByte(0C0H) ELSE OBC.PutByte(0) END ;
- IF mode = Mod THEN OBC.PutByte(0)
- ELSIF stkchk & (mode # IProc) THEN (*check SP against stack limit*)
- L := OBC.pc; OBC.PutWord(0);
- OBC.PutF3(-47D9H); OBC.PutF3(547H); OBC.PutDisp(3FF0H); (*ADDR TOS, R0; CMPD R0, lim*)
- OBC.PutF0(4); OBC.PutDisp(4); OBC.PutF1(0F2H); OBC.PutByte(14); (*BHI *+4 BPT 14*)
- ELSIF clrchk THEN (*clear local frame*)
- OBC.PutByte(0); OBC.PutF3(-57D9H); L := OBC.pc; OBC.PutWord(0); (*ADDR @n, R0*)
- OBC.PutF3(-47A1H); OBC.PutF3(64DH); OBC.PutDisp(-2) (*MOVQD 0, TOS; ACBW -4, R0, -2*)
- ELSE L := OBC.pc; OBC.PutWord(0)
- END
- END Enter;
- PROCEDURE CopyDynArray*(adr: LONGINT; typ: OBT.Struct);
- VAR size, ptr, m2, tos: OBT.Item;
- PROCEDURE DynArrSize(typ: OBT.Struct);
- VAR len: OBT.Item;
- BEGIN
- IF typ.form = DynArr THEN DynArrSize(typ.BaseTyp);
- len.mode := Var; len.lev := OBC.level; len.typ := OBT.linttyp;
- len.a0 := adr + typ.adr; load(len);
- IF size.a0 # 1 THEN OBC.Put(F7, 23H, len, size) (* MULD size, len *) END;
- size := len
- ELSE size.mode := Con; size.typ := OBT.linttyp; size.a0 := typ.size
- END
- END DynArrSize;
- BEGIN
- DynArrSize(typ); (* load total byte size of dyn array *)
- OBC.PutF2(0FH, 3, size); (* ADDQD 3, size *)
- m2.mode := Con; m2.typ := OBT.sinttyp;
- m2.a0 := -2; OBC.Put(F6, 7, size, m2); (* ASHD -2, size *)
- ptr.mode := Var; ptr.lev := OBC.level; ptr.typ := OBT.linttyp;
- ptr.a0 := adr; load(ptr);
- ptr.mode := RegX; ptr.a1 := -4; ptr.a2 := size.a0; tos.mode := Stk;
- OBC.PutF4(17H, tos, ptr); (* loop: MOVD -4(ptr)[size:D], TOS *)
- OBC.PutF2(4FH, -1, size); OBC.PutDisp(-4); (* ACBD -1, size, loop *)
- OBC.PutF3(-31D9H); OBC.PutDisp(0); OBC.PutDisp(adr); (* ADDR 0(SP), adr(FP) *)
- OBC.FreeRegs({})
- END CopyDynArray;
- PROCEDURE Result*(VAR x: OBT.Item; typ: OBT.Struct);
- VAR res: OBT.Item;
- BEGIN res.mode := Reg; res.typ := typ; res.a0 := 0;
- Assign(res, x, FALSE)
- END Result;
- PROCEDURE Return*(mode: INTEGER; psize: LONGINT);
- BEGIN OBC.PutF1(92H); (*EXIT*)
- IF mode = LProc THEN
- OBC.PutByte(0); OBC.PutF1(12H); OBC.PutDisp(psize-8) (*RET*)
- ELSIF mode = IProc THEN
- OBC.PutByte(3); OBC.PutF1(42H); OBC.PutDisp(0) (*RETT 0*)
- END
- END Return;
- PROCEDURE CaseIn*(VAR x: OBT.Item; VAR L0, L1: INTEGER);
- VAR f: INTEGER; x0, z: OBT.Item;
- BEGIN f := x.typ.form;
- IF f = LInt THEN load(x)
- ELSIF f = Int THEN x0 := x; OBC.GetReg(x); OBC.Put(F7, 1DH, x, x0) (*MOVXWD*)
- ELSIF f = Char THEN x0 := x; OBC.GetReg(x); OBC.Put(F7, 18H, x, x0) (*MOVZBD*)
- ELSIF f = SInt THEN x0 := x; OBC.GetReg(x); OBC.Put(F7, 1CH, x, x0) (*MOVXBD*)
- ELSE OBS.Mark(125)
- END ;
- z.mode := Con; z.typ := OBT.linttyp; z.a0 := 0; OBC.PutF4(23H, x, z); (*SUBi*)
- L0 := OBC.pc; OBC.PutF4(7, z, x); (*CMPi*)
- OBC.PutF0(11); OBC.PutWord(0); (*BHS*)
- L1 := OBC.pc; OBC.PutF3(-1083H); OBC.PutByte(x.a0+0D8H); OBC.PutWord(0) (*CASE*)
- END CaseIn;
- PROCEDURE CaseOut*(L0, L1, L2, L3, n: INTEGER;
- VAR tab: ARRAY OF LabelRange);
- VAR i, j, lim, len: INTEGER; k: LONGINT;
- BEGIN (*generate jump table*)
- IF ODD(OBC.pc) THEN OBC.PutByte(0A2H) END ;
- IF n > 0 THEN len := tab[n-1].high - tab[0].low + 1 ELSE len := 0 END ;
- OBC.PutByte(6); OBC.PutF3(len); (*for decoder*)
- OBC.FixupImm(L0, tab[0].low); (*SUB*)
- OBC.FixupImm(L1-3, len); (*CMP*)
- OBC.FixupWith(L1-2, L2-L1+3); (*out of bounds jump addr*)
- OBC.FixupWith(L1+3, OBC.pc-L1); (*jump address to table*)
- i := 0; j := tab[0].low;
- WHILE i < n DO
- lim := tab[i].high;
- WHILE j < tab[i].low DO OBC.PutF3(L2-L1); INC(j) END ;
- WHILE j <= lim DO OBC.PutF3(tab[i].label-L1); INC(j) END ;
- INC(i)
- END ;
- OBC.FixLink(L3)
- END CaseOut;
- BEGIN
- lengcode[Undef] := 0;
- lengcode[Byte] := 0;
- lengcode[Bool] := 0;
- lengcode[Char] := 0;
- lengcode[SInt] := 0;
- lengcode[Int] := 1;
- lengcode[LInt] := 3;
- lengcode[Real] := 1;
- lengcode[LReal] := 0;
- lengcode[Set] := 3;
- lengcode[String] := 0;
- lengcode[NilTyp] := 3;
- lengcode[ProcTyp] := 3;
- lengcode[Pointer] := 3;
- lengcode[Array] := 1;
- lengcode[DynArr] := 1;
- lengcode[Record] := 1;
- END OBH.
-