home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-01-26 | 47.9 KB | 1,528 lines |
- (*************************************************************************
-
- $RCSfile: OCE.mod $
- Description: Code selection for expressions
-
- Created by: fjc (Frank Copeland)
- $Revision: 5.8 $
- $Author: fjc $
- $Date: 1995/01/26 00:17:17 $
-
- Copyright © 1990-1993, ETH Zuerich
- Copyright © 1993-1995, Frank Copeland
- This module forms part of the OC program
- See OC.doc for conditions of use and distribution
-
- Log entries are at the end of the file.
-
- *************************************************************************)
-
- <* STANDARD- *> <* MAIN- *> <*$ LongVars+ *>
-
- MODULE OCE;
-
- IMPORT SYS := SYSTEM, OCM, OCS, OCT, OCC, OCI;
-
-
- (* --- Local declarations ----------------------------------------------- *)
-
- CONST
-
- (* Symbols *)
-
- null = OCS.null; times = OCS.times; slash = OCS.slash; div = OCS.div;
- mod = OCS.mod; and = OCS.and; plus = OCS.plus; minus = OCS.minus;
- or = OCS.or; eql = OCS.eql; neq = OCS.neq; lss = OCS.lss;
- leq = OCS.leq; gtr = OCS.gtr; geq = OCS.geq; not = OCS.not;
-
- (* object modes *)
- Var = OCM.Var; VarX = OCM.VarX; Ind = OCM.Ind; IndX = OCM.IndX;
- RegI = OCM.RegI; RegX = OCM.RegX; Lab = OCM.Lab; LabI = OCM.LabI;
- Con = OCM.Con; Push = OCM.Push; Pop = OCM.Pop; Coc = OCM.Coc;
- Reg = OCM.Reg; Fld = OCM.Fld; Typ = OCM.Typ; Abs = OCM.Abs;
- XProc = OCM.XProc; RList = OCM.RList;
-
- (* System flags *)
-
- OberonFlag = OCM.OberonFlag; M2Flag = OCM.M2Flag; CFlag = OCM.CFlag;
- BCPLFlag = OCM.BCPLFlag; AsmFlag = OCM.AsmFlag;
-
- (* structure forms *)
- Undef = OCT.Undef; Byte = OCT.Byte; Bool = OCT.Bool; Char = OCT.Char;
- SInt = OCT.SInt; Int = OCT.Int; LInt = OCT.LInt; Real = OCT.Real;
- LReal = OCT.LReal; Set = OCT.Set; String = OCT.String;
- NilTyp = OCT.NilTyp; NoTyp = OCT.NoTyp; Pointer = OCT.Pointer;
- ProcTyp = OCT.ProcTyp; Array = OCT.Array; DynArr = OCT.DynArr;
- Record = OCT.Record; PtrTyp = OCT.PtrTyp; AdrTyp = OCT.AdrTyp;
- BPtrTyp = OCT.BPtrTyp; BSet = OCT.BSet; WSet = OCT.WSet;
- Word = OCT.Word; Longword = OCT.Longword; TagTyp = OCT.TagTyp;
-
- intSet = {SInt, Int, LInt};
- realSet = {Real, LReal};
- setSet = {BSet, WSet, Set};
- ptrSet = {Pointer, PtrTyp, AdrTyp, BPtrTyp};
- uptrSet = {AdrTyp, BPtrTyp};
- allSet = {0 .. 31};
- adrSet = {LInt, Pointer, PtrTyp, AdrTyp, Longword};
-
- (* CPU Registers *)
-
- D0 = 0; D1 = 1; D7 = 7; A0 = 8; A1 = 9; A3 = 11; A4 = 12; A5 = 13;
- A6 = 14; A7 = 15; BP = A4; FP = A5; SP = A7;
- DataRegs = {D0 .. D7};
- AdrRegs = {A0 .. A7};
-
- (* Data sizes *)
-
- B = 1; W = 2; L = 4;
-
- (* mathffp.library function offsets *)
-
- SPFix = -30; SPFlt = -36; SPCmp = -42; SPTst = -48; SPAbs = -54;
- SPNeg = -60; SPAdd = -66; SPSub = -72; SPMul = -78; SPDiv = -84;
- SPFloor = -90; SPCeil = -96;
-
- VAR
- log : LONGINT; (* side effect of mant () *)
-
- (* CONST mname = "OCE"; *)
-
- (* --- Procedure declarations ------------------------------------------- *)
-
- PROCEDURE^ Op *
- (op : INTEGER; VAR lhs, rhs : OCT.Item; freeRegs : BOOLEAN);
-
- (*------------------------------------*)
- PROCEDURE mant (x : LONGINT) : LONGINT; (* x DIV 2 ^ log *)
-
- BEGIN (* mant *)
- log := 0;
- IF x > 0 THEN WHILE ~ODD (x) DO x := x DIV 2; INC (log) END END;
- RETURN x
- END mant;
-
- (*------------------------------------*)
- PROCEDURE MultiplyInts (
- VAR lhs, rhs : OCT.Item; size : LONGINT; freeRegs : BOOLEAN);
-
- (* CONST pname = "MultiplyInts"; *)
-
- VAR R : SET;
-
- BEGIN (* MultiplyInts *)
- (* OCM.TraceIn (mname, pname); *)
- IF (lhs.mode = Con) & (mant (lhs.a0) = 1) THEN
- IF log = 1 THEN
- OCI.Load (rhs); OCC.PutF5 (OCC.ADD, size, rhs, rhs)
- ELSIF log # 0 THEN
- lhs.a0 := log; lhs.typ := OCT.sinttyp;
- IF log > 8 THEN OCI.Load (lhs) END;
- OCI.Load (rhs); OCC.Shift (OCC.ASL, size, lhs, rhs);
- IF log > 8 THEN OCC.FreeReg (lhs) END;
- END;
- lhs := rhs; rhs.mode := Undef
- ELSIF (rhs.mode = Con) & (mant (rhs.a0) = 1) THEN
- IF log = 1 THEN
- OCI.Load (lhs); OCC.PutF5 (OCC.ADD, size, lhs, lhs)
- ELSIF log # 0 THEN
- rhs.a0 := log; rhs.typ := OCT.sinttyp;
- IF log > 8 THEN OCI.Load (rhs) END;
- OCI.Load (lhs); OCC.Shift (OCC.ASL, size, rhs, lhs)
- END
- ELSE
- IF size = OCM.LIntSize THEN
- OCC.LoadRegParams2 (R, lhs, rhs);
- OCC.CallKernel (OCC.kMul32);
- OCC.RestoreRegisters (R, lhs);
- ELSE
- OCI.Load (lhs); OCC.PutF2 (OCC.MULS, rhs, lhs.a0)
- END
- END;
- IF freeRegs THEN OCI.Unload (rhs) END
- (* ;OCM.TraceOut (mname, pname); *)
- END MultiplyInts;
-
- (*------------------------------------*)
- PROCEDURE DivideInts (
- VAR lhs, rhs : OCT.Item; size : LONGINT; freeRegs : BOOLEAN);
-
- (* CONST pname = "DivideInts"; *)
-
- VAR R : SET;
-
- BEGIN (* DivideInts *)
- (* OCM.TraceIn (mname, pname); *)
- IF (rhs.mode = Con) & (mant (rhs.a0) = 1) THEN
- rhs.a0 := log; rhs.typ := OCT.sinttyp;
- IF log > 8 THEN OCI.Load (rhs) END;
- OCI.Load (lhs);
- OCC.Shift (OCC.ASR, size, rhs, lhs);
- ELSE
- IF size = OCM.LIntSize THEN
- OCC.LoadRegParams2 (R, lhs, rhs);
- OCC.CallKernel (OCC.kDiv32);
- OCC.RestoreRegisters (R, lhs);
- ELSE
- OCI.Load (lhs);
- IF lhs.typ^.form = OCT.SInt THEN OCI.EXT (W, lhs.a0) END;
- OCI.EXT (L, lhs.a0);
- IF rhs.typ^.form = OCT.SInt THEN
- OCI.Load (rhs); OCI.EXT (W, rhs.a0)
- END;
- OCC.PutF2 (OCC.DIVS, rhs, lhs.a0);
- (*IF OCS.pragma [OCS.ovflChk] THEN OCC.OutOp0 (TRAPV) END;*)
- END
- END;
- IF freeRegs THEN OCI.Unload (rhs) END;
- (* ;OCM.TraceOut (mname, pname); *)
- END DivideInts;
-
- (*------------------------------------*)
- PROCEDURE ModulusInts (
- VAR lhs, rhs : OCT.Item; size : LONGINT; freeRegs : BOOLEAN);
-
- (* CONST pname = "ModulusInts"; *)
-
- VAR R : SET;
-
- BEGIN (* ModulusInts *)
- (* OCM.TraceIn (mname, pname); *)
- IF (rhs.mode = Con) & (mant (rhs.a0) = 1) THEN
- rhs.a0 := ASH (1, log) - 1; OCI.Load (lhs);
- OCC.PutF6 (OCC.ANDI, size, rhs, lhs)
- ELSE
- IF size = OCM.LIntSize THEN
- OCC.LoadRegParams2 (R, lhs, rhs);
- OCC.CallKernel (OCC.kDiv32);
- OCC.PutWord (-3EBFH); (* EXG D0,D1 *)
- OCC.RestoreRegisters (R, lhs)
- ELSE
- OCI.Load (lhs);
- IF lhs.typ^.form = OCT.SInt THEN OCI.EXT (W, lhs.a0) END;
- OCI.EXT (L, lhs.a0);
- IF rhs.typ^.form = OCT.SInt THEN
- OCI.Load (rhs); OCI.EXT (L, rhs.a0)
- END;
- OCC.PutF2 (OCC.DIVS, rhs, lhs.a0);
- OCC.PutWord (OCC.SWAP + SHORT (lhs.a0))
- END
- END;
- IF freeRegs THEN OCI.Unload (rhs) END
- (* ;OCM.TraceOut (mname, pname); *)
- END ModulusInts;
-
- (*------------------------------------*)
- PROCEDURE ConvertInts * (VAR x : OCT.Item; typ : OCT.Struct);
-
- (* CONST pname = "ConvertInts"; *)
-
- BEGIN (* ConvertInts *)
- (* OCM.TraceIn (mname, pname); *)
- IF x.mode # Con THEN
- OCI.Load (x);
- IF (typ.form = LInt) & (x.typ.form = SInt) THEN OCI.EXT (W, x.a0) END;
- OCI.EXT (typ.size, x.a0)
- END;
- x.typ := typ
- (* ;OCM.TraceOut (mname, pname); *)
- END ConvertInts;
-
-
- (*------------------------------------*)
- PROCEDURE RealMath (op : INTEGER; VAR lhs, rhs : OCT.Item);
-
- (* CONST pname = "RealMath"; *)
-
- VAR proc : INTEGER; R : SET;
-
- BEGIN (* RealMath *)
- (* OCM.TraceIn (mname, pname); *)
- OCC.LoadRegParams2 (R, lhs, rhs);
- CASE op OF
- times : proc := OCC.kSPMul | slash : proc := OCC.kSPDiv |
- plus : proc := OCC.kSPAdd | minus : proc := OCC.kSPSub
- ELSE
- OCS.Mark (1009); OCS.Mark (op)
- END;
- OCC.CallKernel (proc); OCC.RestoreRegisters (R, lhs)
- (* ;OCM.TraceOut (mname, pname); *)
- END RealMath;
-
- (*------------------------------------*)
- PROCEDURE CmpReals (VAR lhs, rhs : OCT.Item);
-
- (* CONST pname = "CmpReals"; *)
-
- VAR R : SET; proc : INTEGER;
-
- BEGIN (* CmpReals *)
- (* OCM.TraceIn (mname, pname); *)
- IF (rhs.mode = Con) & (rhs.a0 = 0) THEN
- OCC.LoadRegParams1 (R, lhs); proc := OCC.kSPTst
- ELSE
- OCC.LoadRegParams2 (R, lhs, rhs); proc := OCC.kSPCmp
- END;
- OCC.CallKernel (proc); OCC.RestoreRegisters (R, lhs)
- (* ;OCM.TraceOut (mname, pname); *)
- END CmpReals;
-
- (*------------------------------------*)
- PROCEDURE ConvertReals (VAR x : OCT.Item; typ : OCT.Struct);
-
- (* CONST pname = "ConvertReals"; *)
-
- VAR r0 : OCT.Item; R : SET; f : INTEGER;
-
- BEGIN (* ConvertReals *)
- (* OCM.TraceIn (mname, pname); *)
- f := x.typ.form;
- IF f IN intSet THEN
- IF x.mode = Con THEN x.typ := OCT.linttyp; f := LInt END;
- r0.mode := Reg; r0.a0 := D0;
- OCC.LoadRegParams1 (R, x);
- IF f = SInt THEN OCI.EXT (W, r0.a0); f := Int END;
- IF f = Int THEN OCI.EXT (L, r0.a0) END;
- OCC.CallKernel (OCC.kSPFlt);
- OCC.RestoreRegisters (R, x)
- END;
- x.typ := typ
- (* ;OCM.TraceOut (mname, pname); *)
- END ConvertReals;
-
- (*------------------------------------*)
- PROCEDURE NegReal (VAR x : OCT.Item);
-
- (* CONST pname = "NegReal"; *)
-
- VAR R : SET;
-
- BEGIN (* NegReal *)
- (* OCM.TraceIn (mname, pname); *)
- OCC.LoadRegParams1 (R, x);
- OCC.CallKernel (OCC.kSPNeg);
- OCC.RestoreRegisters (R, x)
- (* ;OCM.TraceOut (mname, pname); *)
- END NegReal;
-
- (*------------------------------------*)
- PROCEDURE loadB (VAR x : OCT.Item); (* Coc-Mode *)
-
- (* CONST pname = "loadB"; *)
-
- VAR op, L0 : INTEGER;
-
- BEGIN (* loadB *)
- (* OCM.TraceIn (mname, pname); *)
- IF ((x.a1 = 0) & (x.a2 = 0)) OR (x.a0 IN {OCC.T, OCC.F}) THEN
- op := OCC.Scc + (SHORT (x.a0) * 100H);
- OCC.GetDReg (x); OCC.PutF3 (op, x) (* Scc Dn *)
- ELSE
- op := OCC.Bcc + (OCC.invertedCC (x.a0) * 100H);
- OCC.PutWord (op); OCC.PutWord (x.a2); (* Bcc 1$ *)
- L0 := OCC.pc - 2; OCC.FixLink (x.a1);
- OCC.GetDReg (x); OCC.PutF3 (OCC.ST, x); (* ST Dn *)
- OCC.PutWord (6002H); (* BRA 2$ *)
- OCC.FixLink (L0); OCC.PutF3 (OCC.SF, x); (* 1$ SF Dn *)
- END (* 2$ *)
- (* ;OCM.TraceOut (mname, pname); *)
- END loadB;
-
- (*------------------------------------*)
- PROCEDURE setCC * (VAR x: OCT.Item; cc : LONGINT);
-
- BEGIN (* setCC *)
- x.typ := OCT.booltyp; x.mode := Coc; x.a0 := cc; x.a1 := 0; x.a2 := 0
- END setCC;
-
- (*------------------------------------*)
- PROCEDURE cmp (VAR lhs, rhs : OCT.Item; freeX : BOOLEAN);
-
- (* CONST pname = "cmp"; *)
-
- VAR size : LONGINT;
-
- BEGIN (* cmp *)
- (* OCM.TraceIn (mname, pname); *)
- size := lhs.typ.size; IF size > L THEN size := L END;
- IF rhs.mode = Con THEN
- IF lhs.mode = Con THEN OCI.Load (lhs)
- ELSIF lhs.mode = Coc THEN loadB (lhs)
- END;
- IF rhs.a0 = 0 THEN OCC.PutF1 (OCC.TST, size, lhs)
- ELSE OCC.PutF6 (OCC.CMPI, size, rhs, lhs)
- END
- ELSE
- IF lhs.mode = Coc THEN loadB (lhs)
- ELSE OCI.Load (lhs)
- END;
- OCC.PutF5 (OCC.CMP, size, rhs, lhs);
- END;
- IF freeX THEN OCI.Unload (lhs) END
- (* ;OCM.TraceOut (mname, pname); *)
- END cmp;
-
- (*------------------------------------*)
- PROCEDURE test (VAR x : OCT.Item);
-
- (* CONST pname = "test"; *)
-
- BEGIN (* test *)
- (* OCM.TraceIn (mname, pname); *)
- OCC.PutF1 (OCC.TST, x.typ.size, x); OCI.Unload (x); setCC (x, OCC.NE)
- (* ;OCM.TraceOut (mname, pname); *)
- END test;
-
- (*------------------------------------*)
- PROCEDURE SetIntType * (VAR x : OCT.Item);
-
- (* CONST pname = "SetIntType"; *)
-
- VAR v : LONGINT;
-
- BEGIN (* SetIntType *)
- (* OCM.TraceIn (mname, pname); *)
- v := x.a0;
- IF (LONG (OCM.MinSInt) <= v) & (v <= LONG (OCM.MaxSInt)) THEN
- x.typ := OCT.sinttyp
- ELSIF (LONG (OCM.MinInt) <= v) & (v <= LONG (OCM.MaxInt)) THEN
- x.typ := OCT.inttyp
- ELSE
- x.typ := OCT.linttyp
- END;
- (* ;OCM.TraceOut (mname, pname); *)
- END SetIntType;
-
- (*------------------------------------*)
- PROCEDURE SetSetType (VAR x : OCT.Item);
-
- (* CONST pname = "SetSetType"; *)
-
- VAR s : SET;
-
- BEGIN (* SetSetType *)
- (* OCM.TraceIn (mname, pname); *)
- s := SYS.VAL (SET, x.a0);
- IF (s - {OCM.MinSet .. OCM.MaxBSet}) = {} THEN
- x.typ := OCT.bsettyp
- ELSIF (s - {OCM.MinSet .. OCM.MaxWSet}) = {} THEN
- x.typ := OCT.wsettyp
- ELSE
- x.typ := OCT.settyp
- END
- (* ;OCM.TraceOut (mname, pname); *)
- END SetSetType;
-
- (*------------------------------------*)
- PROCEDURE AssReal * (VAR x : OCT.Item; y : REAL);
-
- BEGIN (* AssReal *)
- SYS.PUT (SYS.ADR (x.a0), y)
- END AssReal;
-
- (*------------------------------------*)
- PROCEDURE AssLReal * (VAR x : OCT.Item; y : LONGREAL);
-
- BEGIN (* AssLReal *)
- SYS.PUT (SYS.ADR (x.a0), y)
- END AssLReal;
-
- (*------------------------------------*)
- PROCEDURE Index * (VAR x, y : OCT.Item);
-
- (* CONST pname = "Index"; *)
-
- VAR
- f, m, r, L0 : INTEGER; i, n : LONGINT;
- eltyp : OCT.Struct; br, y1, z : OCT.Item;
- desc : OCT.Desc; wordSize, calcSize : BOOLEAN;
-
- BEGIN (* Index *)
- (* OCM.TraceIn (mname, pname); *)
- f := y.typ.form;
- IF ~(f IN intSet) THEN OCS.Mark (80); y.typ := OCT.inttyp END;
- IF x.typ = NIL THEN OCS.Mark (80); HALT (80) END;
- IF x.typ.form = Array THEN
- eltyp := x.typ.BaseTyp; n := x.typ.n;
- wordSize := (x.typ.size <= 32767);
- IF eltyp = NIL THEN OCS.Mark (81); HALT (81) END;
- IF y.mode = Con THEN
- IF (0 <= y.a0) & (y.a0 < n) THEN i := y.a0 * eltyp.size
- ELSE OCS.Mark (81); i := 0
- END;
- IF x.mode = Var THEN
- INC (x.a0, i)
- ELSIF (x.mode = Ind) OR (x.mode = RegI) THEN
- INC (x.a1, i); x.obj := NIL
- ELSE
- OCI.LoadAdr (x); x.a1 := i
- END
- ELSE
- OCI.Load (y);
- IF f = SInt THEN OCI.EXT (W, y.a0); y.typ := OCT.inttyp; f := Int END;
-
- IF OCS.pragma [OCS.indexChk] THEN (* z = bound descr *)
- z.mode := Con; z.a0 := n - 1;
- IF f = Int THEN z.typ := OCT.inttyp; OCC.PutCHK (z, y.a0)
- ELSE
- OCC.PutF1 (OCC.TST, L, y); (* TST.L Dy *)
- L0 := OCC.pc; OCC.PutWord (6B00H); (* BMI.S 1$ *)
- z.typ := OCT.linttyp;
- cmp (y, z, FALSE); (* CMP.L #z,Dy *)
- OCC.TrapLink (OCC.IndexCheck, OCC.GT, L0);
- (* BLE.S 2$ *)
- (* 1$ TRAP #IndexCheck *)
- END (* 2$ *)
- END;
-
- m := x.mode;
- IF m = Var THEN
- x.mode := VarX; x.wordIndex := wordSize; x.a1 := 0;
- x.a2 := SHORT (y.a0); calcSize := eltyp.size > 1
- ELSIF m = Ind THEN
- x.mode := IndX; x.wordIndex := wordSize; x.a2 := SHORT (y.a0);
- calcSize := eltyp.size > 1;
- ELSIF m = RegI THEN
- x.mode := RegX; x.wordIndex := wordSize; x.a2 := SHORT (y.a0);
- calcSize := eltyp.size > 1;
- ELSIF m IN {VarX, IndX, RegX} THEN
- IF eltyp.size > 1 THEN
- z.mode := Con; z.a0 := eltyp.size;
- IF x.wordIndex THEN z.typ := OCT.inttyp
- ELSE z.typ := OCT.linttyp
- END;
- Op (times, y, z, FALSE)
- END;
- z := y; y.mode := Reg; y.a0 := x.a2;
- IF x.wordIndex THEN y.typ := OCT.inttyp
- ELSE y.typ := OCT.linttyp
- END;
- Op (plus, y, z, TRUE);
- calcSize := FALSE;
- ELSE OCS.Mark (322)
- END;
- IF calcSize THEN
- z.mode := Con; z.a0 := eltyp.size;
- IF x.wordIndex THEN z.typ := OCT.inttyp
- ELSE z.typ := OCT.linttyp
- END;
- Op (times, y, z, FALSE)
- END
- END; (* ELSE *)
- x.typ := eltyp
- ELSIF x.typ.form = DynArr THEN
- IF f # LInt THEN ConvertInts (y, OCT.linttyp)
- ELSIF y.mode # Con THEN OCI.Load (y)
- END;
-
- IF OCS.pragma [OCS.indexChk] THEN
- IF (y.mode = Con) & (y.a0 < 0) THEN OCS.Mark (81)
- ELSE
- (* z = bound descr *)
- OCI.DescItem (z, x.desc, x.typ.adr);
- IF y.mode # Con THEN
- OCC.PutF1 (OCC.TST, L, y); (* TST.L y *)
- L0 := OCC.pc; OCC.PutWord (6B00H); (* BMI.S 1$ *)
- cmp (y, z, FALSE); (* CMP.L z,Dy *)
- OCC.TrapLink (OCC.IndexCheck, OCC.GE, L0);
- (* BLT.S 2$ *)
- (* 1$ TRAP #IndexCheck *)
- (* 2$ *)
- ELSE
- cmp (z, y, FALSE); (* CMP.L y,z *)
- OCC.TrapCC (OCC.IndexCheck, OCC.LE); (* BGT.S 1$ *)
- (* TRAP #IndexCheck *)
- (* 1$ *)
- END;
- OCI.UpdateDesc (z, x.typ.adr)
- END (* ELSE *)
- END; (* IF *)
-
- IF x.mode = Var THEN (* Value parameter *)
- IF y.mode = Con THEN x.mode := Ind; x.a1 := y.a0
- ELSE
- x.mode := IndX; x.a1 := 0; x.a2 := SHORT (y.a0);
- x.wordIndex := FALSE
- END
- ELSIF x.mode = Ind THEN (* Variable parameter, or dereferenced ptr *)
- IF y.mode = Con THEN x.a1 := y.a0
- ELSE x.mode := IndX; x.a2 := SHORT (y.a0); x.wordIndex := FALSE
- END
- ELSIF x.mode = RegI THEN (* Dereferenced ptr *)
- IF y.mode = Con THEN x.a1 := y.a0
- ELSE x.mode := RegX; x.a2 := SHORT (y.a0); x.wordIndex := FALSE
- END
- ELSIF x.mode IN {IndX, RegX} THEN (* Indexed open array *)
- IF ~OCS.pragma [OCS.indexChk] THEN (* z = bound descr *)
- OCI.DescItem (z, x.desc, x.typ.adr);
- END;
- y1.mode := Reg; y1.a0 := x.a2; y1.typ := OCT.linttyp;
- Op (times, y1, z, FALSE); Op (plus, y1, y, TRUE); y := y1;
- OCI.UpdateDesc (z, x.typ.adr)
- ELSE OCS.Mark (322)
- END;
-
- x.typ := x.typ.BaseTyp;
- IF x.typ # NIL THEN
- IF (x.typ.form # DynArr) THEN
- IF x.typ.size > 1 THEN
- z.mode := Con; z.a0 := x.typ.size; SetIntType (z);
- Op (times, y, z, FALSE)
- END;
- IF y.mode = Con THEN x.a1 := y.a0 END
- ELSIF (y.mode = Con) & (y.a0 # 0) THEN
- OCI.Load (y); x.a1 := 0; x.a2 := SHORT (y.a0); x.wordIndex := FALSE;
- IF x.mode = Ind THEN x.mode := IndX
- ELSIF x.mode = RegI THEN x.mode := RegX
- ELSE OCS.Mark (322)
- END
- END
- END
- ELSE
- OCS.Mark (82)
- END
- (* ;OCM.TraceOut (mname, pname); *)
- END Index;
-
- (*------------------------------------*)
- PROCEDURE Field * (VAR x : OCT.Item; y : OCT.Object);
-
- (* CONST pname = "Field"; *)
-
- BEGIN (* Field *)
- (* OCM.TraceIn (mname, pname); *)
- IF x.mode = Var THEN INC (x.a0, y.a0)
- ELSIF (x.mode = Ind) OR (x.mode = RegI) THEN INC (x.a1, y.a0)
- ELSE OCI.LoadAdr (x); x.mode := RegI; x.a1 := y.a0
- END;
- x.typ := y.typ; x.obj := NIL;
- IF x.lev < 0 THEN x.rdOnly := x.rdOnly OR (y.visible = OCT.RdOnly) END
- (* ;OCM.TraceOut (mname, pname); *)
- END Field;
-
- (*------------------------------------*)
- PROCEDURE DeRef * (VAR x : OCT.Item);
-
- (* CONST pname = "DeRef"; *)
-
- VAR y, z : OCT.Item; flg : INTEGER; desc : OCT.Desc; freeY : BOOLEAN;
-
- BEGIN (* DeRef *)
- (* OCM.TraceIn (mname, pname); *)
- IF (x.mode <= RegX) & (x.typ.form = Pointer) THEN
- flg := x.typ.sysflg;
- IF flg = BCPLFlag THEN
- y := x; OCC.GetDReg (z);
- OCC.Move (L, y, z); OCI.Unload (y); (* MOVE.L x,Dm *)
- IF OCS.pragma [OCS.nilChk] THEN OCC.TrapCC (OCC.NilCheck, OCC.EQ) END;
- OCC.PutF5 (OCC.ADD, L, z, z); (* ADD.L Dm, Dm *)
- OCC.PutF5 (OCC.ADD, L, z, z); (* ADD.L Dm, Dm *)
- OCC.GetAReg (x); OCC.Move (L, z, x); (* MOVEA.L Dm,An *)
- OCI.Unload (z); x.mode := RegI
- ELSE
- OCI.UnloadDesc (x); y.mode := Undef;
- IF
- (flg = OberonFlag) & (x.typ.BaseTyp # NIL)
- & (x.typ.BaseTyp.form = DynArr)
- THEN
- desc := x.desc; IF desc = NIL THEN desc := OCT.AllocDesc() END;
- desc.lev := x.lev; desc.mode := x.mode; desc.a0 := x.a0;
- desc.a1 := x.a1; desc.a2 := x.a2; x.desc := desc;
- freeY := ~(desc.mode IN {VarX, IndX, RegI, RegX})
- ELSE
- freeY := TRUE
- END;
- IF x.mode = Var THEN
- IF OCS.pragma [OCS.nilChk] THEN
- y := x;
- OCC.PutF1 (OCC.TST, L, y); (* TST.L x *)
- OCC.TrapCC (OCC.NilCheck, OCC.EQ);
- END;
- x.mode := Ind
- ELSE
- y := x; y.typ := OCT.ptrtyp; OCC.GetAReg (x);
- IF OCS.pragma [OCS.nilChk] THEN
- OCC.GetDReg (z); OCC.Move (L, y, z); (* MOVE.L x,Dn *)
- OCC.TrapCC (OCC.NilCheck, OCC.EQ);
- OCC.Move (L, z, x); OCI.Unload (z) (* MOVEA.L Dn, An *)
- ELSE
- OCC.Move (L, y, x); (* MOVEA.L x, An *)
- END;
- IF freeY THEN OCI.Unload (y) END; x.mode := RegI
- END
- END;
- (*x.a2 := flg;*) x.a2 := 0;
- x.typ := x.typ.BaseTyp; x.obj := OCC.wasderef; x.rdOnly := FALSE
- ELSE
- OCS.Mark (84)
- END;
- x.a1 := 0
- (* ;OCM.TraceOut (mname, pname); *)
- END DeRef;
-
- (*------------------------------------*)
- PROCEDURE TypTest * (VAR x, y : OCT.Item; test : BOOLEAN);
-
- (* CONST pname = "TypTest"; *)
-
- (*------------------------------------*)
- PROCEDURE GTT (t0, t1 : OCT.Struct; varpar : BOOLEAN);
-
- (* CONST pname = "GTT"; *)
-
- VAR t : OCT.Struct; xt, tdes, p : OCT.Item; R : SET;
-
- BEGIN (* GTT *)
- (* OCM.TraceIn (mname, pname); *)
- IF t0 # t1 THEN
- t := t1;
- IF t0.form = Record THEN
- REPEAT t := t.BaseTyp UNTIL (t = NIL) OR (t = t0);
- END;
- IF t # NIL THEN
- x.typ := y.typ;
- IF OCS.pragma [OCS.typeChk] OR test THEN
- R := OCC.RegSet; xt := x;
- IF varpar THEN
- xt.mode := Ind; xt.a0 := x.a0 + 4
- ELSE
- p := xt; p.typ := OCT.ptrtyp; OCC.GetAReg (xt);
- IF OCS.pragma [OCS.nilChk] THEN
- OCI.Load (p); (* MOVE.L p,Dn *)
- OCC.TrapCC (OCC.NilCheck, OCC.EQ);
- END;
- OCC.Move (L, p, xt); (* MOVE.L p,An *)
- p := xt; p.mode := RegI; p.a1 := -4;
- OCC.Move (L, p, xt); xt.mode := RegI; (* MOVE.L -4(An),An *)
- END;
- xt.a1 := (t1.n + 1) * 4;
- tdes.mode := LabI; tdes.a0 := 0; tdes.a1 := 4;
- tdes.label := t1.label;
- OCC.PutF5 (OCC.CMP, L, tdes, xt); (* CMP.L #tdes,<xt> *)
- IF ~test THEN OCC.TrapCC (OCC.TypeCheck, OCC.NE)
- ELSE setCC (x, OCC.EQ)
- END;
- OCC.FreeRegs (R)
- END
- ELSE OCS.Mark (85); IF test THEN x.typ := OCT.booltyp END
- END
- ELSIF test THEN setCC (x, OCC.T)
- END
- (* ;OCM.TraceOut (mname, pname); *)
- END GTT;
-
- BEGIN (* TypTest *)
- (* OCM.TraceIn (mname, pname); *)
- IF (x.typ.form = Pointer) & (x.typ.sysflg = OberonFlag) THEN
- IF (y.typ.form = Pointer) & (y.typ.sysflg = OberonFlag) THEN
- GTT (x.typ.BaseTyp, y.typ.BaseTyp, FALSE)
- ELSE OCS.Mark (86)
- END
- ELSIF x.typ.form = PtrTyp THEN
- IF
- (y.typ.form = Pointer) & (y.typ.sysflg = OberonFlag)
- & (y.typ.BaseTyp # NIL) & (y.typ.BaseTyp.form # DynArr)
- THEN
- GTT (x.typ, y.typ.BaseTyp, FALSE)
- ELSE OCS.Mark (86)
- END
- ELSIF
- (x.typ.form = Record) & (x.typ.sysflg = OberonFlag)
- & (x.mode = Ind) & (x.obj # NIL) & (x.obj # OCC.wasderef)
- & (y.typ.form = Record) & (y.typ.sysflg = OberonFlag)
- THEN
- GTT (x.typ, y.typ, TRUE)
- ELSE OCS.Mark (87)
- END
- (* ;OCM.TraceOut (mname, pname); *)
- END TypTest;
-
- (*------------------------------------*)
- PROCEDURE In * (VAR lhs, rhs : OCT.Item);
-
- (* CONST pname = "In"; *)
-
- VAR f, g, L0 : INTEGER; bnd, br : OCT.Item;
-
- BEGIN (* In *)
- (* OCM.TraceIn (mname, pname); *)
- f := lhs.typ.form; g := rhs.typ.form;
- IF (f IN intSet) & (g IN setSet) THEN
- IF (lhs.mode = Con) & (rhs.mode = Con) THEN
- IF (lhs.a0 >= 0) & (lhs.a0 < 32) THEN
- IF lhs.a0 IN SYS.VAL (SET, rhs.a0) THEN setCC (lhs, OCC.T)
- ELSE setCC (lhs, OCC.F)
- END
- ELSE
- OCS.Mark (91); setCC (lhs, OCC.F)
- END
- ELSIF lhs.mode = Con THEN
- IF
- (lhs.a0 < 0)
- OR ((g = BSet) & (lhs.a0 > 7))
- OR ((g = WSet) & (lhs.a0 > 15))
- OR ((g = Set) & (lhs.a0 > 31))
- THEN
- OCS.Mark (91); setCC (lhs, OCC.F)
- ELSE
- OCI.Load (rhs); OCC.Bit (OCC.BTST, lhs, rhs);
- OCI.Unload (rhs); setCC (lhs, OCC.NE)
- END; (* ELSE *)
- ELSE
- IF rhs.mode = Con THEN rhs.typ := OCT.settyp; g := Set END;
- OCI.Load (lhs);
-
- IF OCS.pragma [OCS.rangeChk] THEN
- IF lhs.typ.form = SInt THEN OCI.EXT (W, lhs.a0) END;
- bnd.mode := Con;
- IF g = BSet THEN bnd.a0 := 7
- ELSIF g = WSet THEN bnd.a0 := 15
- ELSE bnd.a0 := 31
- END;
- IF lhs.typ.form = LInt THEN
- bnd.typ := OCT.linttyp;
- OCC.PutF1 (OCC.TST, L, lhs); (* TST.L <lhs> *)
- L0 := OCC.pc; OCC.PutWord (6B00H); (* BMI.S 1$ *)
- cmp (lhs, bnd, FALSE); (* CMP #<bnd>,<lhs>*)
- OCC.TrapLink (OCC.IndexCheck, OCC.GT, L0);
- (* BLE.S 2$ *)
- (* 1$ TRAP #IndexCheck *)
- ELSE (* 2$ *)
- bnd.typ := OCT.inttyp; OCC.PutCHK (bnd, lhs.a0)
- END
- END;
-
- OCI.Load (rhs); OCC.Bit (OCC.BTST, lhs, rhs);
- OCI.Unload (lhs); OCI.Unload (rhs); setCC (lhs, OCC.NE)
- END
- ELSE OCS.Mark (92); setCC (lhs, OCC.F)
- END
- (* ;OCM.TraceOut (mname, pname); *)
- END In;
-
- (*------------------------------------*)
- PROCEDURE Set0 * (VAR x, y : OCT.Item);
-
- (* CONST pname = "Set0"; *)
-
- VAR one : LONGINT;
-
- BEGIN (* Set0 *)
- (* OCM.TraceIn (mname, pname); *)
- x.mode := Reg; x.a0 := D0; x.typ := OCT.settyp;
- IF y.typ.form IN intSet THEN
- IF y.mode = Con THEN
- x.mode := Con;
- IF (0 <= y.a0) & (y.a0 < 32) THEN
- one := 1; x.a0 := SYS.LSH (one, y.a0); SetSetType (x)
- ELSE
- OCS.Mark (202)
- END
- ELSE
- x.mode := Con; x.a0 := 1; OCI.Load (x); OCI.Load (y);
- OCC.Shift (OCC.LSL, L, y, x); OCI.Unload (y)
- END
- ELSE OCS.Mark (93)
- END
- (* ;OCM.TraceOut (mname, pname); *)
- END Set0;
-
- (*------------------------------------*)
- PROCEDURE Set1 * (VAR x, y, z : OCT.Item);
-
- (* CONST pname = "Set1"; *)
-
- VAR s : LONGINT;
-
- BEGIN (* Set1 *)
- (* OCM.TraceIn (mname, pname); *)
- x.mode := Reg; x.a0 := D0; x.typ := OCT.settyp;
- IF
- (y.typ.form IN intSet) & (z.typ.form IN intSet)
- THEN
- IF y.mode = Con THEN
- IF (0 <= y.a0) & (y.a0 < 32) THEN
- y.typ := OCT.settyp; s := -1; y.a0 := SYS.LSH (s, y.a0);
- IF z.mode = Con THEN
- x.mode := Con;
- IF (y.a0 <= z.a0) & (z.a0 < 32) THEN
- s := -2; x.a0 := y.a0 - SYS.LSH (s, z.a0); SetSetType (x)
- ELSE
- OCS.Mark (202); x.a0 := 0
- END
- ELSIF y.a0 = -1 THEN
- x.mode := Con; x.a0 := -2; OCI.Load (x); OCI.Load (z);
- OCC.Shift (OCC.LSL, L, z, x); OCC.PutF1 (OCC.NOT, L, x);
- OCC.FreeReg (z)
- ELSE
- x := y; y.mode := Con; y.a0 := -2; OCI.Load (y); OCI.Load (z);
- OCC.Shift (OCC.LSL, L, z, y); OCC.FreeReg (z);
- OCC.PutF1 (OCC.NOT, L, y); OCI.Load (x);
- OCC.PutF5 (OCC.AND, L, y, x); OCC.FreeReg (y)
- END
- ELSE
- OCS.Mark (202)
- END
- ELSE
- x.mode := Con; x.a0 := -1; OCI.Load (x); OCI.Load (y);
- OCC.Shift (OCC.LSL, L, y, x); OCC.FreeReg (y);
- y.mode := Con; y.typ := NIL;
- IF z.mode = Con THEN
- IF (0 <= z.a0) & (z.a0 < 32) THEN
- s := -2;
- y.a0 := SYS.VAL (LONGINT, allSet - SYS.VAL (SET, SYS.LSH(s, z.a0)));
- OCC.PutF6 (OCC.ANDI, L, y, x)
- ELSE
- OCS.Mark (202)
- END
- ELSE
- y.a0 := -2; OCI.Load (y); OCI.Load (z);
- OCC.Shift (OCC.LSL, L, z, y); OCC.FreeReg (z);
- OCC.PutF1 (OCC.NOT, L, y); OCC.PutF5 (OCC.AND, L, y, x);
- OCC.FreeReg (y)
- END
- END (* ELSE *)
- ELSE
- OCS.Mark (93)
- END
- (* ;OCM.TraceOut (mname, pname); *)
- END Set1;
-
- (*------------------------------------*)
- PROCEDURE MOp * (op : INTEGER; VAR x : OCT.Item);
-
- (* CONST pname = "MOp"; *)
-
- VAR f, opcode : INTEGER; a : LONGINT; y : OCT.Item; freeY : BOOLEAN;
-
- BEGIN (* MOp *)
- (* OCM.TraceIn (mname, pname); *)
- f := x.typ.form;
- CASE op OF
- and :
- IF (x.typ.form = Bool) & (x.mode = Con) THEN
- IF x.a0 = 0 THEN setCC (x, OCC.F) ELSE setCC (x, OCC.T) END
- END;
- IF x.mode = Coc THEN
- IF x.a0 # OCC.T THEN
- IF x.a0 = OCC.F THEN opcode := OCC.BRA
- ELSE opcode := OCC.Bcc + (OCC.invertedCC (x.a0) * 100H)
- END;
- OCC.PutWord (opcode); OCC.PutWord (x.a2); x.a2 := OCC.pc - 2
- END;
- OCC.FixLink (x.a1)
- ELSIF x.typ.form = Bool THEN
- test (x); OCC.PutWord (OCC.BEQ); OCC.PutWord (x.a2);
- x.a2 := OCC.pc - 2; OCC.FixLink (x.a1)
- ELSE
- OCS.Mark (94); x.mode := Con; x.typ := OCT.booltyp; x.a0 := 0
- END
- |
- plus :
- IF ~(f IN intSet + realSet) THEN OCS.Mark (96) END
- |
- minus :
- IF f IN intSet THEN
- IF x.mode = Con THEN x.a0 := -x.a0; SetIntType (x)
- ELSE OCI.Load (x); OCC.PutF1 (OCC.NEG, x.typ.size, x)
- END
- ELSIF f IN realSet THEN
- NegReal (x)
- ELSIF f IN setSet THEN
- IF x.mode = Con THEN
- x.a0 := SYS.VAL (LONGINT, allSet - SYS.VAL (SET, x.a0))
- ELSE
- OCI.Load (x); OCC.PutF1 (OCC.NOT, x.typ.size, x)
- END
- ELSE
- OCS.Mark (97)
- END
- |
- or :
- IF (x.typ.form = Bool) & (x.mode = Con) THEN
- IF x.a0 = 0 THEN setCC (x, OCC.F) ELSE setCC (x, OCC.T) END
- END; (* IF *)
- IF x.mode = Coc THEN
- IF x.a0 # OCC.F THEN
- IF x.a0 = OCC.T THEN opcode := OCC.BRA
- ELSE opcode := OCC.Bcc + (SHORT (x.a0) * 100H)
- END;
- OCC.PutWord (opcode); OCC.PutWord (SHORT (x.a1));
- x.a1 := OCC.pc - 2
- END;
- OCC.FixLink (x.a2)
- ELSIF x.typ.form = Bool THEN
- test (x); OCC.PutWord (OCC.BNE); OCC.PutWord (SHORT (x.a1));
- x.a1 := OCC.pc - 2; OCC.FixLink (x.a2)
- ELSE
- OCS.Mark (94); x.mode := Con; x.typ := OCT.booltyp; x.a0 := 1
- END
- |
- eql .. geq : (* relations *)
- IF x.mode = Coc THEN loadB (x) END
- |
- not :
- IF x.typ.form = Bool THEN
- IF x.mode = Con THEN
- IF x.a0 = 0 THEN x.a0 := 1 ELSE x.a0 := 0 END
- ELSIF x.mode = Coc THEN
- x.a0 := OCC.invertedCC (x.a0); a := x.a1; x.a1 := x.a2;
- x.a2 := SHORT (a)
- ELSE
- y := x;
- OCC.PutF1 (OCC.TST, B, y); setCC (x, OCC.EQ);
- END
- ELSE
- OCS.Mark (98)
- END
- |
- ELSE
- OCS.Mark (1010); OCS.Mark (op)
- END; (* CASE op *)
- (* ;OCM.TraceOut (mname, pname); *)
- END MOp;
-
- (*------------------------------------*)
- PROCEDURE CheckOverflow (op : INTEGER; VAR lhs, rhs : OCT.Item);
-
- (* CONST pname = "CheckOverflow"; *)
-
- CONST min = OCM.MinLInt; max = OCM.MaxLInt;
-
- BEGIN (* CheckOverflow *)
- (* OCM.TraceIn (mname, pname); *)
- CASE op OF
- times :
- IF lhs.a0 < 0 THEN
- IF (rhs.a0 < 0) & (lhs.a0 < max DIV rhs.a0) THEN
- OCS.Mark (109); rhs.a0 := -1
- ELSIF (rhs.a0 > 0) & (lhs.a0 < min DIV rhs.a0) THEN
- OCS.Mark (109); rhs.a0 := 1
- END
- ELSE
- IF (rhs.a0 < 0) & (lhs.a0 > min DIV rhs.a0) THEN
- OCS.Mark (109); rhs.a0 := -1
- ELSIF (rhs.a0 > 0) & (lhs.a0 > max DIV rhs.a0) THEN
- OCS.Mark (109); rhs.a0 := 1
- END
- END
- |
- plus :
- IF lhs.a0 < 0 THEN
- IF (rhs.a0 < 0) & (lhs.a0 < min - rhs.a0) THEN
- OCS.Mark (109); rhs.a0 := 0
- END
- ELSE
- IF (rhs.a0 > 0) & (lhs.a0 > max - rhs.a0) THEN
- OCS.Mark (109); rhs.a0 := 0
- END
- END
- |
- minus :
- IF lhs.a0 < 0 THEN
- IF (rhs.a0 > 0) & (lhs.a0 < min + rhs.a0) THEN
- OCS.Mark (109); rhs.a0 := 0
- END
- ELSE
- IF (rhs.a0 < 0) & (lhs.a0 > max + rhs.a0) THEN
- OCS.Mark (109); rhs.a0 := 0
- END
- END
- |
- ELSE
- OCS.Mark (1011); OCS.Mark (op)
- END; (* CASE op *)
- (* ;OCM.TraceOut (mname, pname); *)
- END CheckOverflow;
-
- (*------------------------------------*)
- PROCEDURE Op * (op : INTEGER; VAR lhs, rhs : OCT.Item; freeRegs : BOOLEAN);
-
- (* CONST pname = "Op"; *)
-
- CONST
- eqSet = { Undef, Char .. LInt, BSet .. Set,
- NilTyp, PtrTyp .. ProcTyp, TagTyp };
- nilSet = { Pointer, PtrTyp, AdrTyp, BPtrTyp, ProcTyp, TagTyp };
-
- VAR f, g : INTEGER; p, q, r : OCT.Struct; size : LONGINT;
-
- (*------------------------------------*)
- PROCEDURE strings () : BOOLEAN;
-
- BEGIN (* strings *)
- RETURN
- ((((f = Array) OR (f = DynArr)) & (lhs.typ.BaseTyp.form = Char))
- OR (f = String))
- & ((((g = Array) OR (g = DynArr)) & (rhs.typ.BaseTyp.form = Char))
- OR (g = String))
- END strings;
-
- (*------------------------------------*)
- PROCEDURE CompStrings (cc : INTEGER; testNul : BOOLEAN);
-
- (* CONST pname = "CompStrings"; *)
-
- VAR br, len, ch : OCT.Item; L0, L1 : INTEGER; d : OCT.Desc;
-
- BEGIN (* CompStrings *)
- (* OCM.TraceIn (mname, pname); *)
- IF (g = String) & (rhs.a1 = 1) THEN
- IF (f = String) & (lhs.a1 <= 2) THEN
- OCC.AllocStringFromChar (lhs)
- END;
- IF cc = OCC.CS THEN setCC (lhs, OCC.F)
- ELSIF cc = OCC.CC THEN setCC (lhs, OCC.T)
- ELSE
- OCC.PutF1 (OCC.TST, B, lhs); (* TST.B <lhs> *)
- OCI.Unload (lhs); setCC (lhs, cc)
- END
- ELSIF (f = String) & (lhs.a1 = 1) THEN
- IF cc = OCC.CS THEN cc := OCC.HI
- ELSIF cc = OCC.HI THEN cc := OCC.CS
- ELSIF cc = OCC.CC THEN cc := OCC.LS
- ELSIF cc = OCC.LS THEN cc := OCC.CC
- END;
- IF cc = OCC.CS THEN setCC (lhs, OCC.F)
- ELSIF cc = OCC.CC THEN setCC (lhs, OCC.T)
- ELSE
- OCC.PutF1 (OCC.TST, B, rhs); (* TST.B <rhs> *)
- setCC (lhs, cc)
- END
- ELSE
- IF f = String THEN
- IF lhs.a1 = 2 THEN OCC.AllocStringFromChar (lhs) END;
- len.mode := Con; len.a0 := lhs.a1 - 1; len.typ := OCT.inttyp
- ELSIF f = DynArr THEN
- OCI.DescItem (len, lhs.desc, lhs.typ.adr)
- ELSE
- len.mode := Con; len.a0 := lhs.typ.n - 1; len.typ := OCT.inttyp
- END;
- IF (g = String) & (rhs.a1 = 2) THEN OCC.AllocStringFromChar (rhs) END;
- OCI.Load (len); (* MOVE.Z <len>,Dc *)
- OCI.LoadAdr (lhs); lhs.mode := Pop; (* LEA <lhs>,Aa *)
- OCI.LoadAdr (rhs); rhs.mode := Pop; (* LEA <rhs>,Ab *)
- OCC.GetDReg (ch); OCC.Move (B, lhs, ch); (* MOVE.B (Aa)+,Dd *)
- OCC.PutF5 (OCC.CMP, B, rhs, ch); (* CMP.B (Ab)+,Dd *)
- L0 := OCC.pc; OCC.PutWord (6600H); (* 1$ BNE.S 2$ *)
- OCC.PutF1 (OCC.TST, B, ch); (* TST.B Dd *)
- L1 := OCC.pc; OCC.PutWord (6700H); (* BEQ.S 2$ *)
- OCC.PutWord (OCC.DBF + SHORT (len.a0));
- OCC.PutWord (-12); (* DBF.W Dc,1$ *)
- IF testNul THEN
- lhs.mode := RegI; lhs.a1 := 0;
- OCC.PutF1 (OCC.TST, B, lhs); (* TST.B (Aa) *)
- END; (* 2$ *)
- OCC.PatchWord (L0, OCC.pc - L0 - 2);
- OCC.PatchWord (L1, OCC.pc - L1 - 2);
- OCI.Unload (lhs); OCI.Unload (len); OCI.Unload (ch);
- setCC (lhs, cc)
- END
- (* ;OCM.TraceOut (mname, pname); *)
- END CompStrings;
-
- (*------------------------------------*)
- PROCEDURE CompBool (cc : INTEGER);
-
- (* CONST pname = "CompBool"; *)
- VAR swap : OCT.Item; result : BOOLEAN;
-
- BEGIN (* CompBool *)
- (* OCM.TraceIn (mname, pname); *)
-
- IF (lhs.mode = Con) & (rhs.mode = Con) THEN
- IF cc = OCC.EQ THEN result := (lhs.a0 = rhs.a0)
- ELSE result := (lhs.a0 # rhs.a0)
- END;
- IF result THEN setCC (lhs, OCC.T)
- ELSE setCC (lhs, OCC.F)
- END;
- ELSE
- IF lhs.mode = Con THEN (* swap operands *)
- swap := rhs; rhs := lhs; lhs := swap
- END;
- IF rhs.mode = Coc THEN loadB (rhs)
- ELSIF (rhs.mode = Con) & (rhs.a0 # 0) THEN
- (* Comparing with TRUE.
- ** Invert the CC so that a TST can be used.
- *)
- cc := OCC.invertedCC (cc); rhs.a0 := 0
- END;
- cmp (lhs, rhs, freeRegs); setCC (lhs, cc)
- END; (* IF *)
-
- (* ;OCM.TraceOut (mname, pname); *)
- END CompBool;
-
- BEGIN (* Op *)
- (* OCM.TraceIn (mname, pname); *)
- IF lhs.typ # rhs.typ THEN
- f := lhs.typ.form; g := rhs.typ.form;
- CASE f OF
- Undef :
- |
- SInt :
- IF g = Int THEN ConvertInts (lhs, rhs.typ)
- ELSIF g = LInt THEN ConvertInts (lhs, rhs.typ)
- ELSIF g = Real THEN ConvertReals (lhs, rhs.typ)
- ELSIF g = LReal THEN ConvertReals (lhs, rhs.typ)
- ELSE OCS.Mark (100)
- END
- |
- Int :
- IF g = SInt THEN ConvertInts (rhs, lhs.typ)
- ELSIF g = LInt THEN ConvertInts (lhs, rhs.typ)
- ELSIF g = Real THEN ConvertReals (lhs, rhs.typ)
- ELSIF g = LReal THEN ConvertReals (lhs, rhs.typ)
- ELSE OCS.Mark (100)
- END
- |
- LInt :
- IF g = SInt THEN ConvertInts (rhs, lhs.typ)
- ELSIF g = Int THEN ConvertInts (rhs, lhs.typ)
- ELSIF g = Real THEN ConvertReals (lhs, rhs.typ)
- ELSIF g = LReal THEN ConvertReals (lhs, rhs.typ)
- ELSE OCS.Mark (100)
- END
- |
- Real :
- IF g IN intSet THEN ConvertReals (rhs, lhs.typ)
- ELSIF g = LReal THEN ConvertReals (lhs, rhs.typ)
- ELSE OCS.Mark (100)
- END
- |
- LReal :
- IF g IN intSet THEN ConvertReals (rhs, lhs.typ)
- ELSIF g = Real THEN ConvertReals (rhs, lhs.typ)
- ELSE OCS.Mark (100)
- END
- |
- BSet, WSet, Set :
- IF g IN setSet THEN
- IF (lhs.mode = Con) & (rhs.mode = Con) THEN
- IF g >= f THEN lhs.typ := rhs.typ
- ELSE rhs.typ := lhs.typ
- END
- ELSIF lhs.mode = Con THEN
- SetSetType (lhs);
- IF g >= lhs.typ.form THEN lhs.typ := rhs.typ
- ELSE OCS.Mark (100)
- END
- ELSIF rhs.mode = Con THEN
- SetSetType (rhs);
- IF f >= rhs.typ.form THEN rhs.typ := lhs.typ
- ELSE OCS.Mark (100)
- END
- ELSE OCS.Mark (100)
- END
- ELSE OCS.Mark (100)
- END
- |
- NilTyp :
- IF ~(g IN nilSet) THEN OCS.Mark (100) END
- |
- Pointer :
- IF (g = Pointer) & (OCT.Tagged (lhs.typ) = OCT.Tagged (rhs.typ)) THEN
- p := lhs.typ.BaseTyp; q := rhs.typ.BaseTyp;
- IF (p.form = Record) & (q.form = Record) THEN
- IF p.n < q.n THEN r := p; p := q; q := r END;
- WHILE (p # q) & (p # NIL) DO p := p.BaseTyp END;
- IF p = NIL THEN OCS.Mark (100) END
- ELSE
- OCS.Mark (100)
- END
- ELSIF OCT.Address (lhs.typ) THEN
- IF ~(g IN {AdrTyp, NilTyp}) THEN OCS.Mark (100) END
- ELSIF g # NilTyp THEN
- OCS.Mark (100)
- END
- |
- AdrTyp :
- IF ~OCT.Address (rhs.typ) THEN OCS.Mark (100) END
- |
- PtrTyp, BPtrTyp, ProcTyp, TagTyp :
- IF g # NilTyp THEN OCS.Mark (100) END
- |
- Char :
- IF (g = String) & (rhs.a1 <= 2) THEN
- rhs.a0 := rhs.a2; rhs.typ := OCT.chartyp; g := Char
- ELSE OCS.Mark (100)
- END
- |
- String :
- IF (g = Char) & (lhs.a1 <= 2) THEN
- lhs.a0 := lhs.a2; lhs.typ := OCT.chartyp; f := Char
- ELSIF (g = String) & (lhs.a1 <= 2) & (rhs.a1 <= 2) THEN
- lhs.a0 := lhs.a2; lhs.typ := OCT.chartyp; f := Char;
- rhs.a0 := rhs.a2; rhs.typ := OCT.chartyp; g := Char
- END
- |
- Byte, Bool, NoTyp, Record, Word, Longword :
- OCS.Mark (100);
- |
- Array, DynArr :
- |
- ELSE
- OCS.Mark (1012); OCS.Mark (f)
- END; (* CASE f *)
- END; (* IF *)
-
- f := lhs.typ.form; g := rhs.typ.form; size := lhs.typ.size;
- IF lhs.mode = RList THEN (* lhs is a function procedure result *)
- IF f # Pointer THEN OCS.Mark (956) END;
- OCC.FreeReg (lhs); lhs.mode := Reg; lhs.a0 := D0; OCC.ReserveReg (D0)
- END;
- IF rhs.mode = RList THEN (* rhs is a function procedure result *)
- IF f # Pointer THEN OCS.Mark (956) END;
- OCC.FreeReg (rhs); rhs.mode := Reg; rhs.a0 := D0; OCC.ReserveReg (D0)
- END;
-
- CASE op OF
- times :
- IF f IN intSet THEN
- IF (lhs.mode = Con) & (rhs.mode = Con) THEN
- CheckOverflow (times, lhs, rhs);
- lhs.a0 := lhs.a0 * rhs.a0; SetIntType (lhs)
- ELSE
- MultiplyInts (lhs, rhs, size, freeRegs)
- END
- ELSIF f IN realSet THEN
- RealMath (times, lhs, rhs)
- ELSIF f IN setSet THEN
- IF (lhs.mode = Con) & (rhs.mode = Con) THEN
- lhs.a0 :=
- SYS.VAL (LONGINT, SYS.VAL (SET, lhs.a0) * SYS.VAL (SET, rhs.a0))
- ELSIF lhs.mode = Con THEN
- OCI.Load (rhs); OCC.PutF6 (OCC.ANDI, size, lhs, rhs); lhs := rhs;
- rhs.mode := Undef
- ELSE
- OCI.Load (lhs); OCC.PutF5 (OCC.AND, size, rhs, lhs)
- END
- ELSIF f # Undef THEN OCS.Mark (101)
- END
- |
- slash :
- IF f IN realSet THEN
- RealMath (slash, lhs, rhs)
- ELSIF f IN intSet THEN
- ConvertReals (lhs, OCT.realtyp); ConvertReals (rhs, OCT.realtyp);
- RealMath (slash, lhs, rhs)
- ELSIF f IN setSet THEN
- IF (lhs.mode = Con) & (rhs.mode = Con) THEN
- lhs.a0 :=
- SYS.VAL (LONGINT, SYS.VAL (SET, lhs.a0) / SYS.VAL (SET, rhs.a0))
- ELSIF rhs.mode = Con THEN
- OCI.Load (lhs); OCC.PutF6 (OCC.EORI, size, rhs, lhs)
- ELSIF lhs.mode = Con THEN
- OCI.Load (rhs); OCC.PutF6 (OCC.EORI, size, lhs, rhs);
- lhs := rhs; rhs.mode := Undef
- ELSE
- OCI.Load (lhs); OCI.Load (rhs);
- OCC.PutF5 (OCC.EOR, size, rhs, lhs)
- END
- ELSIF f # Undef THEN OCS.Mark (102)
- END
- |
- div :
- IF f IN intSet THEN
- IF (rhs.mode = Con) & (rhs.a0 = 0) THEN
- OCS.Mark (205); rhs.a0 := 1
- END;
- IF (lhs.mode = Con) & (rhs.mode = Con) THEN
- lhs.a0 := lhs.a0 DIV rhs.a0; SetIntType (lhs);
- ELSE
- DivideInts (lhs, rhs, size, freeRegs);
- END
- ELSIF f # Undef THEN OCS.Mark (103)
- END
- |
- mod :
- IF f IN intSet THEN
- IF (rhs.mode = Con) & (rhs.a0 = 0) THEN
- OCS.Mark (205); rhs.a0 := 1
- END;
- IF (lhs.mode = Con) & (rhs.mode = Con) THEN
- lhs.a0 := lhs.a0 MOD rhs.a0; lhs.typ := rhs.typ
- ELSE
- ModulusInts (lhs, rhs, size, freeRegs)
- END
- ELSIF f # Undef THEN OCS.Mark (104)
- END
- |
- and :
- IF rhs.mode # Coc THEN
- IF rhs.mode = Con THEN
- IF rhs.a0 = 1 THEN setCC (rhs, OCC.T) ELSE setCC (rhs, OCC.F) END
- ELSIF rhs.mode <= Reg THEN test (rhs);
- ELSE OCS.Mark (94); setCC (rhs, OCC.EQ)
- END
- END;
- IF lhs.mode = Con THEN
- IF lhs.a0 = 0 THEN
- OCC.FixLink (rhs.a1); OCC.FixLink (rhs.a2); setCC (rhs, OCC.F)
- END;
- setCC (lhs, OCC.EQ)
- END;
- IF rhs.a2 # 0 THEN lhs.a2 := SHORT (OCC.MergedLinks (lhs.a2, rhs.a2))
- END;
- lhs.a0 := rhs.a0; lhs.a1 := rhs.a1
- |
- plus :
- IF f IN intSet THEN
- IF (lhs.mode = Con) & (rhs.mode = Con) THEN
- CheckOverflow (plus, lhs, rhs); INC (lhs.a0, rhs.a0);
- SetIntType (lhs)
- ELSE
- OCI.Load (lhs); OCC.PutF5 (OCC.ADD, size, rhs, lhs);
- IF OCS.pragma [OCS.ovflChk] THEN OCC.Trap (OCC.OverflowCheck) END
- END
- ELSIF f IN realSet THEN
- RealMath (plus, lhs, rhs)
- ELSIF f IN setSet THEN
- IF (lhs.mode = Con) & (rhs.mode = Con) THEN
- lhs.a0 :=
- SYS.VAL (LONGINT, SYS.VAL (SET, lhs.a0) + SYS.VAL (SET, rhs.a0))
- ELSIF lhs.mode = Con THEN
- OCI.Load (rhs); OCC.PutF6 (OCC.ORI, size, lhs, rhs); lhs := rhs;
- rhs.mode := Undef
- ELSE
- OCI.Load (lhs); OCC.PutF5 (OCC.iOR, size, rhs, lhs)
- END
- ELSIF f # Undef THEN OCS.Mark (105)
- END
- |
- minus :
- IF f IN intSet THEN
- IF (lhs.mode = Con) & (rhs.mode = Con) THEN
- CheckOverflow (minus, lhs, rhs); DEC (lhs.a0, rhs.a0);
- SetIntType (lhs)
- ELSE
- OCI.Load (lhs); OCC.PutF5 (OCC.SUB, size, rhs, lhs);
- IF OCS.pragma [OCS.ovflChk] THEN OCC.Trap (OCC.OverflowCheck) END
- END
- ELSIF f IN realSet THEN
- RealMath (minus, lhs, rhs)
- ELSIF f IN setSet THEN
- IF (lhs.mode = Con) & (rhs.mode = Con) THEN
- lhs.a0 :=
- SYS.VAL (LONGINT, SYS.VAL (SET, lhs.a0) - SYS.VAL (SET, rhs.a0));
- ELSIF rhs.mode = Con THEN
- rhs.a0 := SYS.VAL (LONGINT, allSet - SYS.VAL (SET, rhs.a0));
- OCI.Load (lhs); OCC.PutF6 (OCC.ANDI, size, rhs, lhs)
- ELSIF lhs.mode = Con THEN
- OCI.Load (rhs); OCC.PutF1 (OCC.NOT, size, rhs);
- IF ~(lhs.a0 = -1) THEN OCC.PutF6 (OCC.ANDI, size, lhs, rhs) END;
- lhs := rhs; rhs.mode := Undef
- ELSE
- OCI.Load (lhs); OCI.Load (rhs); OCC.PutF1 (OCC.NOT, size, rhs);
- OCC.PutF5 (OCC.AND, size, rhs, lhs)
- END
- ELSIF f # Undef THEN OCS.Mark (106)
- END
- |
- or :
- IF rhs.mode # Coc THEN
- IF rhs.mode = Con THEN
- IF rhs.a0 = 1 THEN setCC (rhs, OCC.T) ELSE setCC (rhs, OCC.F) END
- ELSIF rhs.mode <= Reg THEN test (rhs)
- ELSE OCS.Mark (95); setCC (rhs, OCC.EQ)
- END
- END;
- IF lhs.mode = Con THEN
- IF lhs.a0 = 1 THEN
- OCC.FixLink (rhs.a1); OCC.FixLink (rhs.a2); setCC (rhs, OCC.T)
- END;
- setCC (lhs, OCC.EQ)
- END;
- IF rhs.a1 # 0 THEN lhs.a1 := OCC.MergedLinks (lhs.a1, rhs.a1) END;
- lhs.a0 := rhs.a0; lhs.a2 := rhs.a2
- |
- eql :
- IF f IN eqSet THEN cmp (lhs, rhs, freeRegs); setCC (lhs, OCC.EQ)
- ELSIF f IN realSet THEN CmpReals (lhs, rhs); setCC (lhs, OCC.EQ)
- ELSIF f = Bool THEN CompBool (OCC.EQ)
- ELSIF strings () THEN CompStrings (OCC.EQ, TRUE)
- ELSE OCS.Mark (107)
- END
- |
- neq :
- IF f IN eqSet THEN cmp (lhs, rhs, freeRegs); setCC (lhs, OCC.NE)
- ELSIF f IN realSet THEN CmpReals (lhs, rhs); setCC (lhs, OCC.NE)
- ELSIF f = Bool THEN CompBool (OCC.NE)
- ELSIF strings () THEN CompStrings (OCC.NE, TRUE)
- ELSE OCS.Mark (107)
- END
- |
- lss :
- IF f IN intSet THEN cmp (lhs, rhs, freeRegs); setCC (lhs, OCC.LT)
- ELSIF f = Char THEN cmp (lhs, rhs, freeRegs); setCC (lhs, OCC.CS)
- ELSIF f IN realSet THEN CmpReals (lhs, rhs); setCC (lhs, OCC.LT)
- ELSIF strings () THEN CompStrings (OCC.CS, FALSE)
- ELSE OCS.Mark (108)
- END
- |
- leq :
- IF f IN intSet THEN cmp (lhs, rhs, freeRegs); setCC (lhs, OCC.LE)
- ELSIF f = Char THEN cmp (lhs, rhs, freeRegs); setCC (lhs, OCC.LS)
- ELSIF f IN realSet THEN CmpReals (lhs, rhs); setCC (lhs, OCC.LE)
- ELSIF strings () THEN CompStrings (OCC.LS, TRUE)
- ELSE OCS.Mark (108)
- END
- |
- gtr :
- IF f IN intSet THEN cmp (lhs, rhs, freeRegs); setCC (lhs, OCC.GT)
- ELSIF f = Char THEN cmp (lhs, rhs, freeRegs); setCC (lhs, OCC.HI)
- ELSIF f IN realSet THEN CmpReals (lhs, rhs); setCC (lhs, OCC.GT)
- ELSIF strings () THEN CompStrings (OCC.HI, TRUE)
- ELSE OCS.Mark (108)
- END
- |
- geq :
- IF f IN intSet THEN cmp (lhs, rhs, freeRegs); setCC (lhs, OCC.GE)
- ELSIF f = Char THEN cmp (lhs, rhs, freeRegs); setCC (lhs, OCC.CC)
- ELSIF f IN realSet THEN CmpReals (lhs, rhs); setCC (lhs, OCC.GE)
- ELSIF strings () THEN CompStrings (OCC.CC, FALSE)
- ELSE OCS.Mark (108)
- END
- |
- ELSE
- OCS.Mark (1013); OCS.Mark (op)
- END; (* CASE op *)
-
- IF freeRegs THEN OCI.Unload (rhs) END;
- (* ;OCM.TraceOut (mname, pname); *)
- END Op;
-
- END OCE.
-
- (***************************************************************************
-
- $Log: OCE.mod $
- Revision 5.8 1995/01/26 00:17:17 fjc
- - Release 1.5
-
- Revision 5.7 1995/01/03 21:19:32 fjc
- - Changed OCG to OCM.
-
- Revision 5.6 1994/12/16 17:29:27 fjc
- - Changed Symbol to Label.
- - Minor modifications to type tests.
-
- Revision 5.5 1994/10/23 16:10:52 fjc
- - All calls to the RTS now made through OCC.CallKernel().
-
- Revision 5.4 1994/09/25 17:49:43 fjc
- - Changed to reflect new object modes and system flags.
-
- Revision 5.3 1994/09/15 10:33:02 fjc
- - Replaced switches with pragmas.
- - Fixed register reservation bug in DeRef when NIL checking.
- was on.
-
- Revision 5.2 1994/09/08 10:49:29 fjc
- - Changed to use pragmas/options.
-
- Revision 5.1 1994/09/03 19:29:08 fjc
- - Bumped version number
-
- ***************************************************************************)
-