home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-01-26 | 68.0 KB | 2,366 lines |
- (*************************************************************************
-
- $RCSfile: OCC.mod $
- Description: Code generation
-
- Created by: fjc (Frank Copeland)
- $Revision: 5.11 $
- $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- *>
-
- MODULE OCC;
-
- IMPORT SYS := SYSTEM, Files, Str := Strings, OCM, OCS, OCT;
-
-
- (* --- Exported declarations ------------------------------------------ *)
-
-
- CONST
-
- (* Condition codes *)
-
- T * = 0; F * = 1; HI * = 2; LS * = 3; CC * = 4; CS * = 5;
- NE * = 6; EQ * = 7; VC * = 8; VS * = 9; PL * = 10; MI * = 11;
- GE * = 12; LT * = 13; GT * = 14; LE * = 15;
-
- (* Instruction mnemonics *)
-
- Bcc * = 6000H; DBcc * = 50C8H; Scc * = 50C0H;
-
- ADD * = -3000H; ADDI * = 0600H; ADDQ * = 5000H; AND * = -4000H;
- ANDI * = 0200H; ASL * = -1F00H; ASR * = -2000H; BCC * = 6400H;
- BCLR * = 0080H; BCS * = 6500H; BEQ * = 6700H; BGE * = 6C00H;
- BGT * = 6E00H; BHI * = 6200H; BLE * = 6F00H; BLS * = 6300H;
- BLT * = 6D00H; BMI * = 6B00H; BNE * = 6600H; BPL * = 6A00H;
- BRA * = 6000H; BSET * = 00C0H; BSR * = 6100H; BTST * = 0000H;
- BVC * = 6800H; BVS * = 6900H; CHK * = 4180H; CLR * = 4200H;
- CMP * = -5000H; CMPI * = 0C00H; DBCC * = 54C8H; DBCS * = 55C8H;
- DBEQ * = 57C8H; DBF * = 51C8H; DBGE * = 5CC8H; DBGT * = 5EC8H;
- DBHI * = 52C8H; DBLE * = 5FC8H; DBLS * = 53C8H; DBLT * = 5DC8H;
- DBMI * = 5BC8H; DBNE * = 56C8H; DBPL * = 5AC8H; DBRA * = 50C8H;
- DBT * = 50C8H; DBVC * = 58C8H; DBVS * = 59C8H; DIVS * = -7E40H;
- EOR * = -4F00H; EORI * = 0A00H; EXG * = -3EC0H; EXTW * = 4880H;
- EXTL * = 48C0H; JMP * = 4EC0H; JSR * = 4E80H; LEA * = 41C0H;
- LINK * = 4E50H; LSL * = -1EF8H; LSR * = -1FF8H; MOVEQ* = 7000H;
- MULS * = -3E40H; NEG * = 4400H; NOP * = 4E71H; NOT * = 4600H;
- iOR * = -8000H; ORI * = 0000H; PEA * = 4840H; ROL * = -1EE8H;
- ROR * = -1FE8H; RTE * = 4E73H; RTS * = 4E75H; SCS * = 55C0H;
- SEQ * = 57C0H; SF * = 51C0H; SGE * = 5CC0H; SGT * = 5EC0H;
- SHI * = 52C0H; SLE * = 5FC0H; SLS * = 53C0H; SLT * = 5DC0H;
- SMI * = 5BC0H; SNE * = 56C0H; SPL * = 5AC0H; SRA * = 50C0H;
- ST * = 50C0H; SVC * = 58C0H; SVS * = 59C0H; SUB * = -7000H;
- SUBI * = 0400H; SUBQ * = 5100H; SWAP * = 4840H; TRAP * = 4E40H;
- TRAPV* = 4E76H; TST * = 4A00H; UNLK * = 4E58H;
-
- (* Trap numbers *)
-
- OverflowCheck * = -1;
- IndexCheck * = 0;
- TypeCheck * = 1;
- NilCheck * = 2;
- CaseCheck * = 3;
- ReturnCheck * = 4;
- StackCheck * = 5;
-
- (* CPU Registers *)
-
- D0 = 0; D1 = 1; D2 = 2; D7 = 7; A0 = 8; A1 = 9; A3 = 11; A4 = 12; A5 = 13;
- A6 = 14; A7 = 15; BP = A4 - 8; FP = A5 - 8; SP = A7 - 8;
- DataRegs = {D0 .. D7};
- AdrRegs = {A0 .. A7};
-
- (* Register masks for SaveRegisters () *)
-
- ScratchRegs * = {D0, D1, A0, A1};
- AllRegs * = {D0 .. A3};
-
- (* Procedures in Kernel *)
-
- kHalt * = 0;
- kNewRecord * = 1;
- kNewArray * = 2;
- kNewSysBlk * = 3;
- kDispose * = 4;
- kInitGC * = 5;
- kMove * = 6;
- kStackChk * = 7;
- kMul32 * = 8;
- kDiv32 * = 9;
- kSPFix * = 10;
- kSPFlt * = 11;
- kSPCmp * = 12;
- kSPTst * = 13;
- kSPNeg * = 14;
- kSPAdd * = 15;
- kSPSub * = 16;
- kSPMul * = 17;
- kSPDiv * = 18;
- kSPAbs * = 19;
- kInit * = 20;
- kEnd * = 21;
- numKProcs = 22;
-
- VAR
- pc *, level * : INTEGER;
- wasderef * : OCT.Object;
- RegSet * : SET;
-
-
- (* --- Local declarations ----------------------------------------------- *)
-
- CONST
- MaxBufferSize = 32000;
- MaxCodeLength = MaxBufferSize DIV SIZE (INTEGER);
- MaxConstLength = MaxBufferSize DIV SIZE (CHAR);
- CodeLength = MaxCodeLength;
- ConstLength = MaxConstLength;
- NumTypes = 64;
-
- (* Object file hunk types *)
- hunkUnit = 999; hunkName = 1000; hunkCode = 1001;
- hunkData = 1002; hunkBSS = 1003; hunkReloc32 = 1004;
- hunkExt = 1007; hunkSymbol = 1008; hunkEnd = 1010;
-
- (* External symbol types *)
- extDef = 1; extRef32 = 129; extRef16 = 131; extSymb = 0;
-
- (* Addressing mode flag values *)
-
- DReg = 0; (* Data Register *)
- ARDir = 1; (* Address Register Direct *)
- ARInd = 2; (* Address Register Indirect *)
- ARPost = 3; (* Address Register with Post-Increment *)
- ARPre = 4; (* Address Register with Pre-Decrement *)
- ARDisp = 5; (* Address Register with Displacement *)
- ARDisX = 6; (* Address Register with Disp. & Index *)
- Mode7 = 7;
- AbsW = 0; (* Absolute Short (16-bit Address) *)
- AbsL = 1; (* Absolute Long (32-bit Address) *)
- PCDisX = 3; (* Program Counter Relative, with Disp. & Index *)
- Imm = 4; (* Immediate *)
- PCDisp = 5; (* Program Counter Relative, with Displacement *)
-
- B = 1; W = 2; L = 4; (* Size types *)
-
- (* 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;
- Abs = OCM.Abs; Con = OCM.Con; Push = OCM.Push; Pop = OCM.Pop;
- Coc = OCM.Coc; Reg = OCM.Reg; Fld = OCM.Fld; Typ = OCM.Typ;
- LProc = OCM.LProc; XProc = OCM.XProc; SProc = OCM.SProc;
- LibCall = OCM.LibCall; TProc = OCM.TProc; Mod = OCM.Mod;
- Head = OCM.Head; RList = OCM.RList; M2Proc = OCM.M2Proc;
- CProc = OCM.CProc; AProc = OCM.AProc;
-
- (* structure forms *)
- Undef = OCT.Undef; Pointer = OCT.Pointer; Array = OCT.Array;
- Record = OCT.Record; ProcTyp = OCT.ProcTyp; PtrTyp = OCT.PtrTyp;
-
- (* System flags *)
-
- OberonFlag = OCM.OberonFlag; M2Flag = OCM.M2Flag; CFlag = OCM.CFlag;
- AsmFlag = OCM.AsmFlag;
-
- TYPE
-
- CodeHunk = POINTER TO CodeHunkDesc;
- Def = POINTER TO DefDesc;
- Ref = POINTER TO RefDesc;
- Offset = POINTER TO OffsetDesc;
-
- CodeHunkDesc = RECORD
- next : CodeHunk;
- start,
- length : INTEGER;
- defs : Def;
- refs : Ref;
- END; (* CodeHunkDesc *)
-
- DefDesc = RECORD
- next : Def;
- object : OCT.Object;
- offset : LONGINT;
- END; (* DefDesc *)
-
- RefDesc = RECORD
- next : Ref;
- size : INTEGER;
- label : OCT.Label;
- count : LONGINT;
- offsets : Offset;
- END; (* RefDesc *)
-
- OffsetDesc = RECORD
- next : Offset;
- n : LONGINT;
- END; (* OffsetDesc *)
-
- VAR
- (* Labels in Module Kernel *)
- kernelLab : ARRAY numKProcs OF OCT.Label;
- i : INTEGER;
-
- FirstCodeHunk, CurrCodeHunk, InitCodeHunk, Prologue : CodeHunk;
- codex, conx, typex, dataCount : INTEGER;
- numPtrs : LONGINT;
- constant : ARRAY ConstLength OF CHAR;
- type : ARRAY NumTypes OF OCT.Struct;
- code : ARRAY CodeLength OF INTEGER;
-
- TYPE
-
- Arg = RECORD
- form : INTEGER;
- data : LONGINT;
- label : OCT.Label;
- END; (* Arg *)
-
- CONST
- (* Arg forms *)
- none = 0; word = 1; long = 2; wordRef = 3; longRef = 4;
-
- CONST mname = "OCC";
-
- (* --- Procedure declarations ------------------------------------------- *)
-
- (*------------------------------------*)
- PROCEDURE Init * ();
-
- (* CONST pname = "Init"; *)
-
- BEGIN (* Init *)
- (* OCM.TraceIn (mname, pname); *)
- pc := 0; level := 0; RegSet := {}; conx := 0; codex := 0; typex := 0;
- OCT.ModuleInit ("Kernel", kernelLab [kInit]);
- (* ;OCM.TraceOut (mname, pname); *)
- END Init;
-
- (*------------------------------------*)
- PROCEDURE Close * ();
-
- VAR i : INTEGER;
-
- BEGIN (* Close *)
- FirstCodeHunk := NIL; CurrCodeHunk := NIL; InitCodeHunk := NIL;
- Prologue := NIL;
- i := 0; WHILE i < NumTypes DO type [i] := NIL; INC (i) END
- END Close;
-
- (*------------------------------------*)
- PROCEDURE StartModule* (name : ARRAY OF CHAR);
- VAR i : INTEGER; ch : CHAR;
- <*$CopyArrays-*>
- BEGIN (* StartModule *)
- i := 0;
- REPEAT
- IF conx >= ConstLength THEN OCS.Mark (230); conx := 0 END;
- ch := name [i]; constant [conx] := ch; INC (i); INC (conx)
- UNTIL ch = 0X;
- END StartModule;
-
- (*------------------------------------*)
- PROCEDURE StartPrologue * ();
-
- (* CONST pname = "StartPrologue"; *)
-
- VAR codeHunk : CodeHunk;
-
- BEGIN (* StartPrologue *)
- (* OCM.TraceIn (mname, pname); *)
- NEW (codeHunk);
- FirstCodeHunk := codeHunk; CurrCodeHunk := codeHunk;
- codeHunk.next := NIL; codeHunk.start := codex; codeHunk.length := 0;
- codeHunk.defs := NIL; codeHunk.refs := NIL;
- Prologue := codeHunk
- (* ;OCM.TraceOut (mname, pname); *)
- END StartPrologue;
-
- (*------------------------------------*)
- PROCEDURE StartCodeHunk * (initProc : BOOLEAN);
-
- (* CONST pname = "StartCodeHunk"; *)
-
- VAR codeHunk : CodeHunk;
-
- BEGIN (* StartCodeHunk *)
- (* OCM.TraceIn (mname, pname); *)
- NEW (codeHunk);
- IF FirstCodeHunk = NIL THEN
- FirstCodeHunk := codeHunk; CurrCodeHunk := codeHunk
- ELSE
- CurrCodeHunk.next := codeHunk; CurrCodeHunk := codeHunk;
- END; (* ELSE *)
- codeHunk.next := NIL; codeHunk.start := codex; codeHunk.length := 0;
- codeHunk.defs := NIL; codeHunk.refs := NIL;
- IF initProc THEN InitCodeHunk := codeHunk END;
- (* ;OCM.TraceOut (mname, pname); *)
- END StartCodeHunk;
-
- (*------------------------------------*)
- PROCEDURE StartProcedure * (proc : OCT.Object);
-
- (* CONST pname = "StartProcedure"; *)
-
- VAR def : Def;
-
- BEGIN (* StartProcedure *)
- (* OCM.TraceIn (mname, pname); *)
- NEW (def);
- def.next := CurrCodeHunk.defs; CurrCodeHunk.defs := def;
- def.object := proc; def.offset := pc - (CurrCodeHunk.start * 2)
- (* ;OCM.TraceOut (mname, pname); *)
- END StartProcedure;
-
- (*------------------------------------*)
- PROCEDURE EndCodeHunk * ();
-
- (* CONST pname = "EndCodeHunk"; *)
-
- BEGIN (* EndCodeHunk *)
- (* OCM.TraceIn (mname, pname); *)
- CurrCodeHunk.length := codex - CurrCodeHunk.start;
- (* ;OCM.TraceOut (mname, pname); *)
- END EndCodeHunk;
-
- (*------------------------------------*)
- PROCEDURE AllocString *
- (VAR s : ARRAY OF CHAR; len : LONGINT; VAR x : OCT.Item);
-
- (* CONST pname = "AllocString"; *)
-
- VAR i : INTEGER;
-
- BEGIN (* AllocString *)
- (* OCM.TraceIn (mname, pname); *)
- IF len = 0 THEN
- x.lev := 0; x.a0 := -1; x.a1 := 1; x.a2 := 0; x.label := NIL
- ELSIF len = 1 THEN
- x.lev := 0; x.a0 := -1; x.a1 := 2; x.a2 := ORD (s [0]); x.label := NIL
- ELSE
- i := 0;
- IF (conx + len) >= ConstLength THEN OCS.Mark (230); conx := 0 END;
- REPEAT
- constant [conx] := s [i]; INC (i); INC (conx)
- UNTIL i = len + 1;
- x.lev := 0; x.a0 := conx - i; x.a1 := i; x.a2 := 0;
- x.label := OCT.ConstLabel
- END;
- x.obj := NIL
- (* ;OCM.TraceOut (mname, pname); *)
- END AllocString;
-
- (*------------------------------------*)
- PROCEDURE AllocStringFromChar * (VAR x : OCT.Item);
-
- (* CONST pname = "AllocStringFromChar"; *)
-
- BEGIN (* AllocStringFromChar *)
- (* OCM.TraceIn (mname, pname); *)
- IF x.a1 > 2 THEN OCS.Mark (212)
- ELSIF x.a0 < 0 THEN
- IF x.a1 = 1 THEN
- IF conx = 0 THEN constant [0] := 0X; conx := 1 END;
- x.a0 := conx - 1; x.label := OCT.ConstLabel
- ELSIF x.a1 = 2 THEN
- IF conx >= ConstLength - 1 THEN OCS.Mark (230); conx := 0 END;
- x.a0 := conx; constant [conx] := CHR (x.a2); INC (conx);
- constant [conx] := 0X; INC (conx); x.label := OCT.ConstLabel
- END;
- IF x.obj # NIL THEN x.obj.a0 := x.a0; x.obj.label := x.label END
- END
- (* ;OCM.TraceOut (mname, pname); *)
- END AllocStringFromChar;
-
- (*------------------------------------*)
- PROCEDURE ConcatString *
- (VAR s : ARRAY OF CHAR; len : LONGINT; VAR x : OCT.Item);
-
- (* CONST pname = "ConcatString"; *)
-
- VAR i : INTEGER; newLen : LONGINT;
-
- BEGIN (* ConcatString *)
- (* OCM.TraceIn (mname, pname); *)
- IF len > 0 THEN
- newLen := len + x.a1 - 1;
- IF len + x.a1 = 2 THEN
- x.a1 := 2; x.a2 := ORD (s [0])
- ELSIF x.a1 = 1 THEN
- AllocString (s, len, x)
- ELSE
- IF x.a1 = 2 THEN AllocStringFromChar (x) END;
- i := 0; DEC (conx);
- IF (conx + len) >= ConstLength THEN OCS.Mark (230); conx := 0 END;
- REPEAT
- constant [conx] := s [i]; INC (i); INC (conx)
- UNTIL i = len + 1;
- INC (x.a1, len)
- END
- END
- (* ;OCM.TraceOut (mname, pname); *)
- END ConcatString;
-
- (*------------------------------------*)
- PROCEDURE AllocTypDesc * (typ : OCT.Struct);
-
- (* CONST pname = "AllocTypDesc"; *)
-
- VAR t : INTEGER;
-
- BEGIN (* AllocTypDesc *)
- (* OCM.TraceIn (mname, pname); *)
- IF typ.form = Pointer THEN
- t := 0;
- WHILE t < typex DO
- IF (type [t].form = Pointer) & (type [t].size = typ.size) THEN
- typ.adr := t; typ.mno := 0; typ.label := type [t].label;
- RETURN
- END;
- INC (t)
- END
- END;
- IF typex >= NumTypes THEN OCS.Mark (233); typex := 0 END;
- type [typex] := typ; typ.adr := typex; INC (typex);
- typ.mno := 0; OCT.MakeTypeLabel (typ)
- (* ;OCM.TraceOut (mname, pname); *)
- END AllocTypDesc;
-
- (*------------------------------------*)
- PROCEDURE GetDReg * (VAR x : OCT.Item);
-
- (* CONST pname = "GetDReg"; *)
-
- VAR i : INTEGER;
-
- BEGIN (* GetDReg *)
- (*OCM.TraceIn (mname, pname);*)
- i := D7; x.mode := Reg;
- LOOP
- IF ~(i IN RegSet) THEN x.a0 := i; INCL (RegSet, i); EXIT END;
- IF i = D2 THEN x.a0 := D0; OCS.Mark (215); EXIT ELSE DEC (i) END
- END
- (*;OCM.TraceOut (mname, pname);*)
- END GetDReg;
-
- (*------------------------------------*)
- PROCEDURE GetAReg * (VAR x : OCT.Item);
-
- (* CONST pname = "GetAReg"; *)
-
- VAR i : INTEGER;
-
- BEGIN (* GetAReg *)
- (*OCM.TraceIn (mname, pname);*)
- i := A3; x.mode := Reg;
- LOOP
- IF ~(i IN RegSet) THEN x.a0 := i; INCL (RegSet, i); EXIT END;
- IF i = A0 THEN x.a0 := A0; OCS.Mark (215); EXIT ELSE DEC (i) END
- END; (* LOOP *)
- (*;OCM.TraceOut (mname, pname);*)
- END GetAReg;
-
- (*------------------------------------*)
- PROCEDURE GetAnyReg * (VAR x : OCT.Item);
-
- (* CONST pname = "GetAnyReg"; *)
-
- VAR i : INTEGER;
-
- BEGIN (* GetAnyReg *)
- (*OCM.TraceIn (mname, pname);*)
- x.mode := Reg;
- i := D7;
- LOOP
- IF ~(i IN RegSet) THEN x.a0 := i; INCL (RegSet, i); RETURN END;
- IF i = D0 THEN EXIT ELSE DEC (i) END
- END; (* LOOP *)
- i := A3;
- LOOP
- IF ~(i IN RegSet) THEN x.a0 := i; INCL (RegSet, i); EXIT END;
- IF i = A0 THEN x.a0 := A0; OCS.Mark (215); EXIT ELSE DEC (i) END
- END; (* LOOP *)
- (*;OCM.TraceOut (mname, pname);*)
- END GetAnyReg;
-
- (*------------------------------------*)
- PROCEDURE ReserveReg * (reg : INTEGER);
-
- (* CONST pname = "ReserveReg"; *)
-
- BEGIN (* ReserveReg *)
- (*OCM.TraceIn (mname, pname);*)
- IF ~(reg IN RegSet) THEN
- INCL (RegSet, reg)
- ELSE
- OCS.Mark (215)
- END; (* ELSE *)
- (*;OCM.TraceOut (mname, pname);*)
- END ReserveReg;
-
- (*------------------------------------*)
- PROCEDURE UnReserveReg * (reg : INTEGER);
-
- (* CONST pname = "UnReserveReg"; *)
-
- BEGIN (* UnReserveReg *)
- (*OCM.TraceIn (mname, pname);*)
- IF (reg IN RegSet) THEN
- EXCL (RegSet, reg)
- ELSE
- OCS.Mark (951)
- END; (* ELSE *)
- (*;OCM.TraceOut (mname, pname);*)
- END UnReserveReg;
-
- (*------------------------------------*)
- PROCEDURE FreeRegs * (r : SET);
-
- (* CONST pname = "FreeRegs"; *)
-
- BEGIN (* FreeRegs *)
- (*OCM.TraceIn (mname, pname);*)
- RegSet := r
- (*;OCM.TraceOut (mname, pname);*)
- END FreeRegs;
-
- (*------------------------------------*)
- PROCEDURE FreeReg * (VAR x : OCT.Item);
-
- (* CONST pname = "FreeReg"; *)
-
- VAR R : SET;
-
- BEGIN (* FreeReg *)
- (*OCM.TraceIn (mname, pname);*)
- IF x.mode IN {Reg, RegI, RegX, Push, Pop} THEN
- IF x.a0 IN RegSet THEN EXCL (RegSet, x.a0) ELSE OCS.Mark (951) END;
- IF x.mode = RegX THEN
- IF x.a2 IN RegSet THEN EXCL (RegSet, x.a2) ELSE OCS.Mark (951) END
- END
- ELSIF x.mode IN {VarX, IndX} THEN
- IF x.a2 IN RegSet THEN EXCL (RegSet, x.a2) ELSE OCS.Mark (951) END
- ELSIF x.mode = RList THEN
- R := SYS.VAL (SET, x.a0);
- IF (R * RegSet) = R THEN RegSet := RegSet - R ELSE OCS.Mark (951) END
- ELSE OCS.Mark (216)
- END;
- x.mode := Undef
- (*;OCM.TraceOut (mname, pname);*)
- END FreeReg;
-
- (*------------------------------------*)
- PROCEDURE PutWord * (w : INTEGER);
-
- BEGIN (* PutWord *)
- IF codex >= CodeLength THEN OCS.Mark (231); codex := 0 END;
- code [codex] := w; INC (codex); INC (pc, 2)
- END PutWord;
-
- (*------------------------------------*)
- PROCEDURE PatchWord * (loc, w : INTEGER);
-
- (* CONST pname = "PatchWord"; *)
-
- BEGIN (* PatchWord *)
- (*OCM.TraceIn (mname, pname);*)
- IF loc >= pc THEN OCS.Mark (961); loc := 0 END;
- loc := loc DIV 2; code [loc] := SYS.LOR (code [loc], w)
- (*;OCM.TraceOut (mname, pname);*)
- END PatchWord;
-
- (*------------------------------------*)
- PROCEDURE PutLong * (l : LONGINT);
-
- BEGIN (* PutLong *)
- IF codex >= CodeLength - 1 THEN OCS.Mark (231); codex := 0 END;
- code [codex] := SHORT (l DIV 10000H); INC (codex);
- code [codex] := SHORT (l MOD 10000H); INC (codex);
- INC (pc, 4)
- END PutLong;
-
- (*------------------------------------*)
- PROCEDURE FindRef (label : OCT.Label; size : LONGINT) : Ref;
-
- (* CONST pname = "FindRef"; *)
-
- VAR ref : Ref;
-
- BEGIN (* FindRef *)
- (*OCM.TraceIn (mname, pname);*)
- ref := CurrCodeHunk.refs;
- WHILE (ref # NIL) & ((ref.label^ # label^) OR (ref.size # size)) DO
- ref := ref.next
- END; (* WHILE *)
- (*;OCM.TraceOut (mname, pname);*)
- RETURN ref
- END FindRef;
-
- (*------------------------------------*)
- PROCEDURE MakeRef (ref : Ref; label : OCT.Label; size : INTEGER);
-
- (* CONST pname = "MakeRef"; *)
-
- VAR offset : Offset;
-
- BEGIN (* MakeRef *)
- (*OCM.TraceIn (mname, pname);*)
- IF ref = NIL THEN
- NEW (ref);
- ref.next := CurrCodeHunk.refs; CurrCodeHunk.refs := ref;
- ref.size := size; ref.label := label; ref.count := 0;
- ref.offsets := NIL;
- END;
-
- NEW (offset);
- offset.next := ref.offsets; ref.offsets := offset; INC (ref.count);
- offset.n := pc - (CurrCodeHunk.start * 2);
- (*;OCM.TraceOut (mname, pname);*)
- END MakeRef;
-
- (*------------------------------------*)
- PROCEDURE PutWordRef * (offset : INTEGER; label : OCT.Label);
-
- (* CONST pname = "PutWordRef"; *)
-
- BEGIN (* PutWordRef *)
- (*OCM.TraceIn (mname, pname);*)
- IF label # NIL THEN
- MakeRef (FindRef (label, 2), label, 2); PutWord (offset)
- ELSE
- OCS.Mark (964)
- END
- (*;OCM.TraceOut (mname, pname);*)
- END PutWordRef;
-
- (*------------------------------------*)
- PROCEDURE PutLongRef * (offset : LONGINT; label : OCT.Label);
-
- (* CONST pname = "PutLongRef"; *)
-
- BEGIN (* PutLongRef *)
- (*OCM.TraceIn (mname, pname);*)
- IF label # NIL THEN
- MakeRef (FindRef (label, 4), label, 4); PutLong (offset)
- ELSE
- OCS.Mark (964)
- END
- (*;OCM.TraceOut (mname, pname);*)
- END PutLongRef;
-
- (*------------------------------------*)
- PROCEDURE PutArg (VAR arg : Arg);
-
- (* CONST pname = "PutArg"; *)
-
- BEGIN (* PutArg *)
- (*OCM.TraceIn (mname, pname);*)
- CASE arg.form OF
- none : |
- word : PutWord (SHORT (arg.data)) |
- long : PutLong (arg.data) |
- wordRef :
- MakeRef (FindRef (arg.label, 2), arg.label, 2);
- PutWord (SHORT (arg.data))
- |
- longRef :
- MakeRef (FindRef (arg.label, 4), arg.label, 4);
- PutLong (arg.data)
- |
- ELSE
- OCS.Mark (1008); OCS.Mark (arg.form)
- END; (* CASE arg.form *)
- (*;OCM.TraceOut (mname, pname);*)
- END PutArg;
-
- (*------------------------------------*)
- PROCEDURE Argument
- ( VAR op : INTEGER; size : LONGINT; ea05 : BOOLEAN;
- VAR item : OCT.Item; VAR arg : Arg );
-
- (* CONST pname = "Argument"; *)
-
- VAR
- form, mode, itemMode, reg, op2 : INTEGER; regItem : OCT.Item;
- data : LONGINT; label : OCT.Label;
-
- (*------------------------------------*)
- PROCEDURE downlevel ();
-
- (* CONST pname = "downlevel"; *)
-
- VAR diff, op : INTEGER;
-
- BEGIN (* downlevel *)
- (*OCM.TraceIn (mname, pname);*)
- diff := level - item.lev;
- GetAReg (regItem); reg := SHORT (regItem.a0-8);
-
- op := 206DH + SYS.LSH (reg, 9); (* MOVEA.L 8(A5), An *)
- PutWord (op); PutWord (8);
-
- op := 2068H + SYS.LSH (reg, 9) + reg; (* MOVEA.L 8(An), An *)
- WHILE diff > 1 DO
- PutWord (op); PutWord (8);
- DEC (diff)
- END; (* WHILE *)
-
- mode := ARDisp; form := word; data := item.a0
- (*;OCM.TraceOut (mname, pname);*)
- END downlevel;
-
- BEGIN (* Argument *)
- (*OCM.TraceIn (mname, pname);*)
- form := none;
- CASE item.mode OF
- Var, VarX, Ind, IndX :
- itemMode := item.mode;
- IF item.lev = 0 THEN (* Global variable of local module *)
- IF
- OCS.pragma [OCS.longVars] OR (item.a0 > 32767) OR (A4 IN RegSet)
- THEN
- mode := Mode7; reg := AbsL; form := longRef;
- label := OCT.VarLabel; data := item.a0
- ELSIF item.a0 = 0 THEN
- mode := ARInd; reg := BP; form := none
- ELSE
- mode := ARDisp; reg := BP; form := word; data := item.a0
- END
- ELSIF item.lev < 0 THEN (* Global variable of imported module *)
- mode := Mode7; reg := AbsL; form := longRef;
- label := OCT.GlbMod [-item.lev-1].varLab; data := item.a0
- ELSIF item.lev = level THEN (* Local variable in procedure *)
- IF item.a0 = 0 THEN
- mode := ARInd; reg := FP; form := none
- ELSE
- mode := ARDisp; reg := FP; form := word; data := item.a0
- END
- ELSE (* Local variable in surrounding context *)
- downlevel ();
- IF itemMode = Var THEN
- item.mode := RegI; item.a1 := item.a0; item.a0 := reg + 8;
- Argument (op, size, ea05, item, arg);
- RETURN
- END; (* IF *)
- END; (* ELSE *)
-
- arg.form := form; arg.data := data; arg.label := label;
- IF itemMode = VarX THEN
- GetAReg (regItem);
- op2 :=
- LEA + SYS.LSH (mode, 3) + reg
- + SYS.LSH (SHORT (regItem.a0)-8, 9); (* LEA <item>, An *)
- PutWord (op2); PutArg (arg);
- item.mode := RegX; item.a0 := regItem.a0; item.a1 := 0;
- Argument (op, size, ea05, item, arg);
- RETURN
- ELSIF itemMode # Var THEN
- GetAReg (regItem);
- op2 :=
- 2040H + SYS.LSH (mode, 3) + reg
- + SYS.LSH (SHORT (regItem.a0)-8, 9);
- PutWord (op2); PutArg (arg); (* MOVEA.L, <item>, An *)
- reg := SHORT (regItem.a0) - 8;
- IF itemMode = IndX THEN
- IF item.a1 # 0 THEN
- arg.form := word; arg.data := item.a1;
- op2 := LEA + SYS.LSH (mode, 3) + reg + SYS.LSH (reg, 9);
- PutWord (op2); PutArg (arg); (* LEA d(An), An *)
- END; (* IF *)
- item.mode := RegX; item.a0 := regItem.a0; item.a1 := 0;
- Argument (op, size, ea05, item, arg);
- RETURN
- ELSE
- item.mode := RegI; item.a0 := regItem.a0;
- Argument (op, size, ea05, item, arg);
- RETURN
- END
- END
- |
- RegI :
- IF ~(item.a0 IN AdrRegs) THEN
- OCS.Mark (215);
- OCS.Mark (op); OCS.Mark (SHORT (size)); OCS.Mark (SHORT (item.a0));
- item.a0 := A0
- END;
- reg := SHORT (item.a0) - 8;
- IF item.a1 = 0 THEN mode := ARInd; form := none
- ELSIF (item.a1 < -32768) OR (item.a1 > 32767) THEN
- GetAnyReg (regItem);
- IF regItem.a0 < A0 THEN (* MOVE.L #offset, Dn *)
- op2 := 203CH + SYS.LSH (SHORT (regItem.a0), 9)
- ELSE (* MOVEA.L #offset, An *)
- op2 := 207CH + SYS.LSH (SHORT (regItem.a0) - 8, 9)
- END; (* ELSE *)
- PutWord (op2); PutLong (item.a1);
- item.mode := RegX; item.a1 := 0; item.a2 := SHORT(regItem.a0);
- item.wordIndex := FALSE;
- Argument (op, size, ea05, item, arg);
- RETURN
- ELSE
- mode := ARDisp; form := word; data := item.a1
- END
- |
- RegX :
- IF ~(item.a0 IN AdrRegs) THEN OCS.Mark (215); item.a0 := A0 END;
- mode := ARDisX; reg := SHORT (item.a0) - 8;
- IF (item.a1 < -128) OR (item.a1 > 127) THEN
- IF item.a2 < A0 THEN (* ADDI.z #offset, Rn *)
- IF item.wordIndex THEN op2 := 0640H + item.a2
- ELSE op2 := 0680H + item.a2
- END
- ELSE (* ADDA.Z #offset, Rn *)
- IF item.wordIndex THEN op2 := -2F04H + SYS.LSH (item.a2 - 8, 9)
- ELSE op2 := -2E04H + SYS.LSH (item.a2 - 8, 9)
- END
- END; (* ELSE *)
- PutWord (op2);
- IF item.wordIndex THEN PutWord (SHORT (item.a1))
- ELSE PutLong (item.a1)
- END;
- item.a1 := 0
- END; (* IF *)
- form := word;
- data := SYS.AND (item.a1, 0FFH); (* Displacement *)
- data := SYS.LOR (data, SYS.LSH (LONG (item.a2) MOD 8, 12));
- (* Index reg. *)
- IF item.a2 >= A0 THEN data := SYS.LOR (data, -8000H)
- END; (* Addr. Reg. *)
- IF ~item.wordIndex THEN data := SYS.LOR (data, 800H) (* Long reg. *)
- END;
- |
- Lab, LabI :
- mode := Mode7;
- IF item.mode = Lab THEN reg := AbsL ELSE reg := Imm END;
- IF item.a1 = W THEN form := wordRef
- ELSIF item.a1 = L THEN form := longRef
- ELSE OCS.Mark (957); form := longRef
- END;
- data := item.a0; label := item.label
- |
- Abs :
- mode := Mode7;
- IF (-32768 <= item.a0) & (item.a0 <= 32767) THEN
- reg := AbsW; form := word
- ELSE
- reg := AbsL; form := long
- END;
- data := item.a0
- |
- Con :
- IF item.typ = OCT.stringtyp THEN
- IF item.a0 < 0 THEN OCS.Mark (962) END;
- mode := Mode7; reg := AbsL; form := longRef; data := item.a0;
- label := item.label
- ELSE
- mode := Mode7; reg := Imm;
- IF size < L THEN form := word ELSE form := long END;
- data := item.a0
- END
- |
- Push, Pop :
- IF ~(item.a0 IN AdrRegs) THEN OCS.Mark (215); item.a0 := A0 END;
- IF item.mode = Push THEN mode := ARPre ELSE mode := ARPost END;
- reg := SHORT (item.a0) - 8; form := none
- |
- Reg :
- IF item.a0 IN DataRegs THEN
- mode := DReg; reg := SHORT (item.a0); form := none
- ELSE
- mode := ARDir; reg := SHORT (item.a0) - 8; form := none
- END
- |
- XProc, LProc :
- mode := Mode7; data := 0; label := item.obj.label;
- IF item.lev < 0 THEN reg := AbsL; form := longRef (* Imported proc. *)
- ELSE reg := AbsW; form := wordRef
- END
- |
- M2Proc, CProc, AProc :
- mode := Mode7; data := 0; label := item.obj.label;
- reg := AbsL; form := longRef
- |
- RList :
- arg.form := word; arg.data := item.a0;
- RETURN
- |
- ELSE
- form := none; OCS.Mark (126);
- RETURN
- END; (* CASE item.mode *)
-
- arg.form := form; arg.data := data; arg.label := label;
- IF ea05 THEN op := op + SYS.LSH (mode, 3) + reg
- ELSE op := op + SYS.LSH (mode, 6) + SYS.LSH (reg, 9)
- END
- (*;OCM.TraceOut (mname, pname);*)
- END Argument;
-
- (*------------------------------------*)
- PROCEDURE PutF1 * (op : INTEGER; size : LONGINT; VAR item : OCT.Item);
- (*
- Instruction format #1: xxxxxxxxsseeeeee
-
- Instructions: CLR, NEG, NOT, TST
- *)
-
- (* CONST pname = "PutF1"; *)
-
- VAR arg : Arg;
-
- BEGIN (* PutF1 *)
- (* OCM.TraceIn (mname, pname); *)
- op := op + SYS.LSH ((SHORT (size) DIV 2), 6);
- Argument (op, size, TRUE, item, arg);
- PutWord (op); PutArg (arg)
- (* ;OCM.TraceOut (mname, pname); *)
- END PutF1;
-
- (*------------------------------------*)
- PROCEDURE PutF2 * (op : INTEGER; VAR src : OCT.Item; reg : LONGINT);
- (*
- Instruction format #2: xxxxrrrxxxeeeeee
-
- Instructions: LEA, DIVS, MULS, CHK
- *)
-
- (* CONST pname = "PutF2"; *)
-
- VAR arg : Arg;
-
- BEGIN (* PutF2 *)
- (* OCM.TraceIn (mname, pname); *)
- op := op + SYS.LSH (SHORT (reg) MOD 8, 9);
- Argument (op, W, TRUE, src, arg);
- PutWord (op); PutArg (arg)
- (* ;OCM.TraceOut (mname, pname); *)
- END PutF2;
-
- (*------------------------------------*)
- PROCEDURE PutF3 * (op : INTEGER; VAR item : OCT.Item);
-
- (*
- Instruction format #3: xxxxxxxxxxeeeeee
-
- Instructions: PEA, JSR, JMP, Scc
- *)
-
- (* CONST pname = "PutF3"; *)
-
- VAR arg : Arg;
-
- BEGIN (* PutF3 *)
- (* OCM.TraceIn (mname, pname); *)
- Argument (op, W, TRUE, item, arg);
- PutWord (op); PutArg (arg)
- (* ;OCM.TraceOut (mname, pname); *)
- END PutF3;
-
- (*------------------------------------*)
- PROCEDURE Bit * (op : INTEGER; VAR src, dst : OCT.Item);
-
- (*
- Instruction format #2: xxxxrrrxxxeeeeee
- Instruction format #3: xxxxxxxxxxeeeeee
-
- Instructions: BTST, BCLR, BSET
- *)
-
- (* CONST pname = "Bit"; *)
-
- VAR arg : Arg;
-
- BEGIN (* Bit *)
- (* OCM.TraceIn (mname, pname); *)
- IF src.mode = Reg THEN
- op := SYS.LOR (op, SYS.LOR (100H, SYS.LSH (SHORT (src.a0), 9)))
- ELSE
- op := SYS.LOR (op, 800H)
- END;
- Argument (op, W, TRUE, dst, arg);
- PutWord (op); IF src.mode = Con THEN PutWord (SHORT (src.a0)) END;
- PutArg (arg)
- (* ;OCM.TraceOut (mname, pname); *)
- END Bit;
-
- (*------------------------------------*)
- PROCEDURE Move * (size : LONGINT; VAR src, dst : OCT.Item);
-
- (* CONST pname = "Move"; *)
-
- VAR arg1, arg2 : Arg; op, reg : INTEGER; rlist1, rlist2 : SYS.WORDSET;
-
- BEGIN (* Move *)
- (* OCM.TraceIn (mname, pname); *)
- IF (src.mode = Reg) & (dst.mode = Reg) & (src.a0 = dst.a0) THEN
- (* ;OCM.TraceOut (mname, pname); *)
- RETURN
- END;
- IF src.mode = RList THEN (* MOVEM Registers to EA *)
- IF size = L THEN op := 48C0H ELSE op := 4880H END;
- Argument (op, size, TRUE, dst, arg1);
- IF dst.mode = Push THEN
- (* Reverse the register list first *)
- reg := 0;
- rlist1 := SYS.VAL (SYS.WORDSET, SHORT (src.a0)); rlist2 := {};
- WHILE reg <= A7 DO
- IF reg IN rlist1 THEN INCL (rlist2, 15 - reg) END;
- INC (reg)
- END;
- src.a0 := SYS.VAL (LONGINT, LONG (rlist2))
- END;
- PutWord (op); PutWord (SHORT (src.a0)); PutArg (arg1)
- ELSIF dst.mode = RList THEN (* MOVEM EA to Registers *)
- IF size = L THEN op := 4CC0H ELSE op := 4C80H END;
- Argument (op, size, TRUE, src, arg1);
- PutWord (op); PutWord (SHORT (dst.a0)); PutArg (arg1)
- ELSIF (dst.mode = Reg) & (dst.a0 IN AdrRegs) THEN
- IF (src.mode = Con) & (src.a0 = 0) THEN (* SUBA.Z <dst>, <dst> *)
- reg := SHORT (dst.a0) - 8; op := -6F38H;
- IF size = L THEN op := SYS.LOR (op, 100H)
- ELSIF size = B THEN OCS.Mark (957)
- END;
- op := SYS.LOR (op, SYS.LOR (SYS.LSH (reg, 9), reg));
- PutWord (op)
- ELSE (* MOVEA.Z <src>, <dst> *)
- IF size = L THEN
- op := SYS.LOR (2040H, SYS.LSH (SHORT (dst.a0) MOD 8, 9))
- ELSIF size = W THEN
- op := SYS.LOR (3040H, SYS.LSH (SHORT (dst.a0) MOD 8, 9))
- ELSE
- OCS.Mark (957); op := 3040H
- END;
- Argument (op, size, TRUE, src, arg1); PutWord (op); PutArg (arg1)
- END
- ELSIF
- (dst.mode = Reg) & (dst.a0 IN DataRegs) & (src.mode = Con)
- & (src.a0 >= -128) & (src.a0 <= 127)
- THEN (* MOVEQ #<src>, <dst> *)
- op := SYS.LOR (7000H, SYS.LSH (SHORT (dst.a0), 9));
- op := SYS.LOR (op, SYS.AND (SHORT (src.a0), 0FFH));
- PutWord (op)
- ELSIF (src.mode = Con) & (src.a0 = 0) THEN (* CLR.z <dst> *)
- PutF1 (CLR, size, dst)
- ELSE (* MOVE.z <src>, <dst> *)
- IF size = L THEN op := 2000H
- ELSIF size = W THEN op := 3000H
- ELSIF size = B THEN op := 1000H
- ELSE
- OCS.Mark (957); op := 1000H
- END;
- Argument (op, size, TRUE, src, arg1);
- Argument (op, size, FALSE, dst, arg2);
- PutWord (op); PutArg (arg1); PutArg (arg2)
- END
- (* ;OCM.TraceOut (mname, pname); *)
- END Move;
-
- (*------------------------------------*)
- PROCEDURE PutF7 * (op : INTEGER; size, src : LONGINT; VAR dst : OCT.Item);
- (*
- Instruction format #7: xxxxdddxsseeeeee
-
- Instructions: ADDQ, SUBQ
- *)
-
- (* CONST pname = "PutF7"; *)
-
- VAR arg : Arg;
-
- BEGIN (* PutF7 *)
- (* OCM.TraceIn (mname, pname); *)
- IF (src > 0) & (src <= 8) THEN
- op := SYS.LOR (op, SYS.LSH ((SHORT (size) DIV 2), 6));
- op := SYS.LOR (op, SYS.LSH (SHORT (src) MOD 8, 9));
- Argument (op, size, TRUE, dst, arg); PutWord (op); PutArg (arg)
- ELSE
- OCS.Mark (957)
- END; (* ELSE *)
- (* ;OCM.TraceOut (mname, pname); *)
- END PutF7;
-
- (*------------------------------------*)
- PROCEDURE PutF6 * (op : INTEGER; size : LONGINT; VAR src, dst : OCT.Item);
- (*
- Instruction format #6: xxxxxxxxsseeeeee
-
- Instructions: ORI, SUBI, CMPI, EORI, ANDI, ADDI
- Instructions: ADDQ, SUBQ
- *)
-
- (* CONST pname = "PutF6"; *)
-
- VAR arg : Arg;
-
- BEGIN (* PutF6 *)
- (* OCM.TraceIn (mname, pname); *)
- IF ((op = ADDI) OR (op = SUBI)) & (src.a0 > 0) & (src.a0 < 9) THEN
- IF op = ADDI THEN op := ADDQ ELSE op := SUBQ END;
- PutF7 (op, size, src.a0, dst)
- ELSE
- op := SYS.LOR (op, SYS.LSH ((SHORT (size) DIV 2), 6));
- Argument (op, size, TRUE, dst, arg); PutWord (op);
- IF src.mode = LabI THEN PutLongRef (src.a0, src.label)
- ELSIF size = L THEN PutLong (src.a0)
- ELSE PutWord (SHORT (src.a0))
- END;
- PutArg (arg)
- END
- (* ;OCM.TraceOut (mname, pname); *)
- END PutF6;
-
- (*------------------------------------*)
- PROCEDURE PutF5 * (op : INTEGER; size : LONGINT; VAR src, dst : OCT.Item);
- (*
- Instruction format #5: xxxxrrrmmmeeeeee
-
- Instructions: OR, SUB, SUBA, CMP, CMPA, EOR, AND, ADD, ADDA, ORI,
- SUBI, CMPI, EORI, ANDI, ADDI, ADDQ, SUBQ
- *)
-
- (* CONST pname = "PutF5"; *)
-
- VAR arg : Arg;
-
- BEGIN (* PutF5 *)
- (* OCM.TraceIn (mname, pname); *)
- IF (dst.mode = Reg) & (dst.a0 IN AdrRegs) THEN
- IF size = L THEN op := SYS.LOR (op, 1C0H)
- ELSIF size = W THEN op := SYS.LOR (op, 0C0H)
- ELSE OCS.Mark (957)
- END;
- op := SYS.LOR (op, SYS.LSH (SHORT (dst.a0) - 8, 9));
- Argument (op, size, TRUE, src, arg)
- ELSIF (src.mode = Con) OR (src.mode = LabI) THEN
- IF op = iOR THEN op := ORI
- ELSIF op = SUB THEN op := SUBI
- ELSIF op = CMP THEN op := CMPI
- ELSIF op = EOR THEN op := EORI
- ELSIF op = AND THEN op := ANDI
- ELSIF op = ADD THEN op := ADDI
- ELSE OCS.Mark (956)
- END;
- PutF6 (op, size, src, dst);
- RETURN
- ELSIF (op # EOR) & (dst.mode = Reg) & (dst.a0 IN DataRegs) THEN
- op := SYS.LOR (op, SYS.LSH (SHORT (size) DIV 2, 6));
- op := SYS.LOR (op, SYS.LSH (SHORT (dst.a0), 9));
- Argument (op, size, TRUE, src, arg)
- ELSE
- op := SYS.LOR (op, SYS.LSH (SHORT (size) DIV 2, 6));
- op := SYS.LOR (SYS.LOR (op, 100H), SYS.LSH (SHORT (src.a0), 9));
- Argument (op, size, TRUE, dst, arg)
- END;
- PutWord (op); PutArg (arg)
- (* ;OCM.TraceOut (mname, pname); *)
- END PutF5;
-
- (*------------------------------------*)
- PROCEDURE Shift * (op : INTEGER; size : LONGINT; VAR count, reg : OCT.Item);
-
- (*
- Instruction format #5: xxxxrrrxssxxxrrr
-
- Instructions: ASL, ASR, LSL, LSR, ROL, ROR
- *)
-
- (* CONST pname = "Shift"; *)
-
- VAR arg : Arg;
-
- BEGIN (* Shift *)
- (* OCM.TraceIn (mname, pname); *)
- IF (reg.mode = Reg) & (reg.a0 IN DataRegs) THEN
- op := SYS.LOR (op, SYS.LSH ((SHORT (size) DIV 2), 6));
- op := SYS.LOR (op, SHORT (reg.a0));
- IF (count.mode = Reg) & (count.a0 IN DataRegs) THEN
- op := SYS.LOR (op, 20H);
- op := SYS.LOR (op, SYS.LSH (SHORT (count.a0), 9))
- ELSIF count.mode = Con THEN
- IF (count.a0 > 0) & (count.a0 <= 8) THEN
- op := SYS.LOR (op, SYS.LSH (SHORT (count.a0) MOD 8, 9))
- ELSE OCS.Mark (957)
- END;
- ELSE OCS.Mark (956)
- END;
- PutWord (op)
- ELSE OCS.Mark (956)
- END;
- (* ;OCM.TraceOut (mname, pname); *)
- END Shift;
-
- (*------------------------------------*)
- PROCEDURE SaveRegisters0 (regs : SET);
-
- (* CONST pname = "SaveRegisters0"; *)
-
- VAR numRegs, reg, lastReg, op : INTEGER; rlist : SYS.WORDSET;
-
- BEGIN (* SaveRegisters0 *)
- (* OCM.TraceIn (mname, pname); *)
- IF regs # {} THEN
- numRegs := 0; reg := 0;
- WHILE reg <= A7 DO
- IF reg IN regs THEN lastReg := reg; INC (numRegs) END;
- INC (reg)
- END;
- IF numRegs = 1 THEN
- IF lastReg IN DataRegs THEN (* MOVE.L Dn, -(A7) *)
- op := SYS.LOR (2F00H, lastReg)
- ELSE (* MOVE.L An, -(A7) *)
- op := SYS.LOR (2F08H, lastReg - 8)
- END;
- PutWord (op)
- ELSE (* MOVEM.L <regs>, -(A7) *)
- (* Reverse the register list first *)
- reg := 0; rlist := {};
- WHILE reg <= lastReg DO
- IF reg IN regs THEN INCL (rlist, 15 - reg) END;
- INC (reg)
- END;
- PutWord (48E7H); PutWord (SYS.VAL (INTEGER, rlist))
- END
- END
- (* ;OCM.TraceOut (mname, pname); *)
- END SaveRegisters0;
-
- (*------------------------------------*)
- PROCEDURE SaveRegisters *
- ( VAR regs : SET;
- VAR x : OCT.Item;
- mask : SET );
-
- (* CONST pname = "SaveRegisters"; *)
-
- VAR temp : SET;
-
- BEGIN (* SaveRegisters *)
- (* OCM.TraceIn (mname, pname); *)
- (* Temporarily reserve A4 and/or A5 if in mask *)
- RegSet := RegSet + (mask * {A4,A5});
- temp := RegSet; RegSet := RegSet * mask;
- IF x.mode IN {Reg, RegI, RegX} THEN EXCL (RegSet, x.a0) END;
- IF x.mode IN {VarX, IndX, RegX} THEN EXCL (RegSet, x.a2) END;
- SaveRegisters0 (RegSet);
- regs := RegSet; RegSet := temp - RegSet;
- (* ;OCM.TraceOut (mname, pname); *)
- END SaveRegisters;
-
- (*------------------------------------*)
- PROCEDURE LoadRegParams1 * (VAR regs : SET; VAR x : OCT.Item);
-
- (* CONST pname = "LoadRegParams1"; *)
-
- VAR d0 : OCT.Item; inD0 : BOOLEAN;
-
- BEGIN (* LoadRegParams1 *)
- (* OCM.TraceIn (mname, pname); *)
- inD0 := (x.mode = Reg) & (x.a0 = D0);
- regs := RegSet * ScratchRegs; IF inD0 THEN EXCL (regs, D0) END;
- SaveRegisters0 (regs); RegSet := RegSet - regs;
- IF ~inD0 THEN
- d0.mode := Reg; d0.a0 := D0; Move (x.typ^.size, x, d0)
- END; (* IF *)
- (* ;OCM.TraceOut (mname, pname); *)
- END LoadRegParams1;
-
- (*------------------------------------*)
- PROCEDURE LoadRegParams2 * (VAR regs : SET; VAR x, y : OCT.Item);
-
- (* CONST pname = "LoadRegParams2"; *)
-
- VAR d0, d1, t : OCT.Item;
-
- BEGIN (* LoadRegParams2 *)
- (* OCM.TraceIn (mname, pname); *)
- regs := RegSet * ScratchRegs;
- IF (x.mode = Reg) & (x.a0 IN {D0, D1}) THEN EXCL (regs, x.a0) END;
- IF (y.mode = Reg) & (y.a0 IN {D0, D1}) THEN EXCL (regs, y.a0) END;
- SaveRegisters0 (regs); RegSet := RegSet - regs;
- d0.mode := Reg; d0.a0 := D0; d1.mode := Reg; d1.a0 := D1;
- IF (y.mode = Reg) & (y.a0 = D0) THEN
- IF (x.mode = Reg) & (x.a0 = D1) THEN
- GetDReg (t); Move (x.typ^.size, x, t); x.a0 := t.a0;
- EXCL (RegSet, D1)
- END; (* IF *)
- Move (y.typ^.size, y, d1); y.a0 := D1;
- EXCL (RegSet, D0); INCL (RegSet, D1)
- END; (* IF *)
- IF ~((x.mode = Reg) & (x.a0 = D0)) THEN Move (x.typ^.size, x, d0) END;
- IF ~((y.mode = Reg) & (y.a0 = D1)) THEN Move (y.typ^.size, y, d1) END
- (* ;OCM.TraceOut (mname, pname); *)
- END LoadRegParams2;
-
- (*------------------------------------*)
- PROCEDURE CallKernel * ( proc : INTEGER );
- BEGIN (* CallKernel *)
- PutWord (4EB9H); PutLongRef (0, kernelLab [proc])
- END CallKernel;
-
- (*------------------------------------*)
- PROCEDURE RestoreRegisters * (regs : SET; VAR x : OCT.Item);
-
- (* CONST pname = "RestoreRegisters"; *)
-
- VAR
- numRegs, op, reg, lastReg : INTEGER; y : OCT.Item; rlist : SET;
- restyp : OCT.Struct;
-
- BEGIN (* RestoreRegisters *)
- (* OCM.TraceIn (mname, pname); *)
- RegSet := RegSet + regs;
- IF x.mode IN {XProc, LProc, TProc, M2Proc, CProc, AProc} THEN
- restyp := x.typ
- ELSIF (x.mode IN {Var..RegX}) & (x.typ.form = ProcTyp) THEN
- restyp := x.typ.BaseTyp
- ELSE
- restyp := NIL
- END;
- IF
- (restyp # NIL) & (restyp.form = Pointer) & (restyp.size > OCM.PtrSize)
- THEN (* PROCEDURE return type is POINTER TO ARRAY OF ... *)
- reg := 0; rlist := {};
- WHILE (reg * 4) < restyp.size DO INCL (rlist, reg); INC (reg) END;
- IF (rlist * RegSet) # {} THEN OCS.Mark (967) END;
- RegSet := RegSet + rlist;
- x.mode := RList; x.a0 := SYS.VAL (LONGINT, rlist)
- ELSE
- y := x; x.mode := Reg; x.a0 := D0;
- IF (D0 IN regs) OR (y.mode = Reg) THEN
- IF (y.mode # Reg) OR ~(y.a0 IN DataRegs) THEN
- GetDReg (y)
- END;
- IF y.a0 # 0 THEN Move (L, x, y); x.a0 := y.a0 END;
- ELSE
- INCL (RegSet, D0);
- END
- END;
- IF regs # {} THEN
- numRegs := 0; reg := 0;
- WHILE reg <= A7 DO
- IF reg IN regs THEN lastReg := reg; INC (numRegs) END;
- INC (reg)
- END; (* WHILE *)
- IF numRegs = 1 THEN
- IF lastReg IN DataRegs THEN (* MOVE.L (A7)+, Dn *)
- op := SYS.LOR (201FH, SYS.LSH (lastReg, 9))
- ELSE (* MOVEA.L (A7)+, An *)
- op := SYS.LOR (205FH, SYS.LSH (lastReg - 8, 9))
- END;
- PutWord (op)
- ELSE (* MOVEM.L (A7)+, <regs> *)
- PutWord (4CDFH); PutWord (SYS.VAL (INTEGER, SHORT (regs)))
- END
- END; (* IF *)
- RegSet := RegSet - {A4,A5} (* Mask out system registers *)
- (* ;OCM.TraceOut (mname, pname); *)
- END RestoreRegisters;
-
- (*------------------------------------*)
- PROCEDURE fixup * (loc : LONGINT); (* enter pc at loc *)
-
- BEGIN (* fixup *)
- code [loc DIV 2] := pc - SHORT (loc)
- END fixup;
-
- (*------------------------------------*)
- PROCEDURE FixLink * (L : LONGINT);
-
- (* CONST pname = "FixLink"; *)
-
- VAR L1 : LONGINT;
-
- BEGIN (* FixLink *)
- (* OCM.TraceIn (mname, pname); *)
- WHILE L # 0 DO
- L1 := code [L DIV 2]; fixup (L); L := L1
- END; (* WHILE *)
- (* ;OCM.TraceOut (mname, pname); *)
- END FixLink;
-
- (*------------------------------------*)
- PROCEDURE FixupWith * (L, val : LONGINT);
-
- VAR x : LONGINT;
-
- BEGIN (* FixupWith *)
- code [L DIV 2] := SHORT (val)
- END FixupWith;
-
- (*------------------------------------*)
- PROCEDURE FixLinkWith * (L, val : LONGINT);
-
- (* CONST pname = "FixLinkWith"; *)
-
- VAR L1 : LONGINT;
-
- BEGIN (* FixLinkWith *)
- (* OCM.TraceIn (mname, pname); *)
- WHILE L # 0 DO
- L1 := code [L DIV 2];
- FixupWith (L, val - L); L := L1
- END; (* WHILE *)
- (* ;OCM.TraceOut (mname, pname); *)
- END FixLinkWith;
-
- (*------------------------------------*)
- PROCEDURE MergedLinks * (L0, L1 : LONGINT): LONGINT;
-
- (* CONST pname = "MergedLinks"; *)
-
- VAR L2, L3 : LONGINT;
-
- BEGIN (* MergedLinks *)
- (* OCM.TraceIn (mname, pname); *)
- (* merge chains of the two operands of AND and OR *)
- IF L0 # 0 THEN
- L2 := L0;
- LOOP
- L3 := code [L2 DIV 2];
- IF L3 = 0 THEN EXIT END;
- L2 := L3
- END; (* LOOP *)
- code [L2 DIV 2] := SHORT (L1);
- RETURN L0
- ELSE
- RETURN L1
- END; (* ELSE *)
- (* ;OCM.TraceOut (mname, pname); *)
- END MergedLinks;
-
- (*------------------------------------*)
- PROCEDURE invertedCC * (cc : LONGINT) : INTEGER;
-
- BEGIN (* invertedCC *)
- IF ODD (cc) THEN RETURN SHORT (cc - 1)
- ELSE RETURN SHORT (cc + 1)
- END
- END invertedCC;
-
- (*------------------------------------*)
- PROCEDURE Trap * (n : INTEGER);
-
- (* CONST pname = "Trap"; *)
-
- BEGIN (* Trap *)
- (* OCM.TraceIn (mname, pname); *)
- IF n = OverflowCheck THEN
- PutWord (TRAPV); (* TRAPV *)
- PutWord (06008H); (* BRA.S 1$ *)
- ELSE
- PutWord (TRAP + n) (* TRAP #n *)
- END;
- PutLongRef (0, OCT.ConstLabel); (* DC.L ModuleName *)
- PutWord (OCS.line); (* DC.W line *)
- PutWord (OCS.col); (* DC.W col *)
- (* 1$ *)
- (* ;OCM.TraceOut (mname, pname); *)
- END Trap;
-
- (*------------------------------------*)
- PROCEDURE TrapCC * (n, cc : INTEGER);
-
- (* CONST pname = "TrapCC"; *)
-
- BEGIN (* TrapCC *)
- (* OCM.TraceIn (mname, pname); *)
- IF cc # T THEN
- (* Branch over the following TRAP instruction (10 bytes) *)
- PutWord (Bcc + (invertedCC (cc) * 100H) + 10)
- END;
- Trap (n)
- (* ;OCM.TraceOut (mname, pname); *)
- END TrapCC;
-
- (*------------------------------------*)
- PROCEDURE TrapLink * ( n, cc, L : INTEGER );
-
- (* CONST pname = "TrapLink"; *)
-
- BEGIN (* TrapLink *)
- (* OCM.TraceIn (mname, pname); *)
- IF cc # T THEN
- (* Branch over the following TRAP instruction (10 bytes) *)
- PutWord (Bcc + (invertedCC (cc) * 100H) + 10)(* Bcc 2$ *)
- END;
- PatchWord (L, pc - L - 2); PutWord (TRAP + n); (* 1$ TRAP #n *)
- PutLongRef (0, OCT.ConstLabel); (* DC.L ModuleName *)
- PutWord (OCS.line); (* DC.W line *)
- PutWord (OCS.col); (* DC.W col *)
- (* ;OCM.TraceOut (mname, pname); *) (* 2$ *)
- END TrapLink;
-
- (*------------------------------------*)
- PROCEDURE TypeTrap * ( L : INTEGER );
-
- (* CONST pname = "TypeTrap"; *)
-
- BEGIN (* TypeTrap *)
- (* OCM.TraceIn (mname, pname); *)
- PutWord (600AH); (* BRA.S 1$ *)
- FixLink (L); PutWord (TRAP + TypeCheck); (* L: TRAP #TypeCheck *)
- PutLongRef (0, OCT.ConstLabel); (* DC.L ModuleName *)
- PutWord (OCS.line); (* DC.W line *)
- PutWord (OCS.col); (* DC.W col *)
- (* 1$ *)
- (* ;OCM.TraceOut (mname, pname); *)
- END TypeTrap;
-
- (*------------------------------------*)
- PROCEDURE PutCHK* ( VAR bound : OCT.Item; reg : LONGINT );
- BEGIN (* PutCHK *)
- PutF2 (CHK, bound, reg);
- PutWord (06008H); (* BRA.S 1$ *)
- PutLongRef (0, OCT.ConstLabel); (* DC.L ModuleName *)
- PutWord (OCS.line); (* DC.W line *)
- PutWord (OCS.col); (* DC.W col *)
- (* 1$ *)
- END PutCHK;
-
- (*------------------------------------*)
- PROCEDURE GlobalPtrs * () : BOOLEAN;
-
- (* CONST pname = "GlobalPtrs"; *)
-
- VAR obj : OCT.Object;
-
- (*------------------------------------*)
- PROCEDURE FindPtrs (typ : OCT.Struct);
-
- (* CONST pname = "FindPtrs"; *)
-
- VAR btyp : OCT.Struct; fld : OCT.Object; i, n : LONGINT;
-
- BEGIN (* FindPtrs *)
- (* OCM.TraceIn (mname, pname); *)
- IF
- ((typ.form = Pointer) & (typ.sysflg = OberonFlag))
- OR (typ.form = PtrTyp)
- THEN
- INC (numPtrs)
- ELSIF (typ.form = Record) & (typ.sysflg = OberonFlag) THEN
- btyp := typ.BaseTyp; IF btyp # NIL THEN FindPtrs (btyp) END;
- fld := typ.link;
- WHILE fld # NIL DO
- IF fld.mode = Fld THEN
- IF fld.name < 0 THEN INC (numPtrs) (* Hidden pointer field *)
- ELSE FindPtrs (fld.typ)
- END;
- END;
- fld := fld.left
- END
- ELSIF typ.form = Array THEN
- btyp := typ.BaseTyp; n := typ.n;
- WHILE btyp.form = Array DO n := btyp.n * n; btyp := btyp.BaseTyp END;
- IF btyp.form IN {Pointer, PtrTyp, Record} THEN
- i := 0; WHILE i < n DO FindPtrs (btyp); INC (i) END
- END
- END
- (* ;OCM.TraceOut (mname, pname); *)
- END FindPtrs;
-
- BEGIN (* GlobalPtrs *)
- (* OCM.TraceIn (mname, pname); *)
- numPtrs := 0; obj := OCT.topScope.right;
- WHILE obj # NIL DO
- IF obj.mode = Var THEN FindPtrs (obj.typ) END;
- obj := obj.link
- END;
- (* ;OCM.TraceOut (mname, pname); *)
- RETURN (numPtrs # 0)
- END GlobalPtrs;
-
- (*------------------------------------*)
- PROCEDURE NumProcs (typ : OCT.Struct) : LONGINT;
-
- (* CONST pname = "NumProcs"; *)
-
- VAR n : LONGINT; obj : OCT.Object;
-
- BEGIN (* NumProcs *)
- (* OCM.TraceIn (mname, pname); *)
- n := 0;
- REPEAT
- obj := typ.link;
- WHILE obj # NIL DO
- IF (obj.mode = TProc) & (obj.a0 > n) THEN n := obj.a0 END;
- obj := obj.left
- END;
- typ := typ.BaseTyp
- UNTIL typ = NIL;
- (* ;OCM.TraceOut (mname, pname); *)
- RETURN n
- END NumProcs;
-
- (*------------------------------------*)
- PROCEDURE ProcLab (typ : OCT.Struct; pno : LONGINT) : OCT.Label;
-
- (* CONST pname = "ProcLab"; *)
-
- VAR obj : OCT.Object;
-
- BEGIN (* ProcLab *)
- (* OCM.TraceIn (mname, pname); *)
- LOOP
- obj := typ.link;
- WHILE obj # NIL DO
- IF (obj.mode = TProc) & (obj.a0 = pno) THEN
- (* OCM.TraceOut (mname, pname); *)
- RETURN obj.label
- END;
- obj := obj.left
- END;
- typ := typ.BaseTyp;
- IF typ = NIL THEN HALT (929) END
- END;
- END ProcLab;
-
-
- (*------------------------------------*)
- PROCEDURE AllocSlots*;
-
- VAR
- slot, nextSlot : LONGINT; obj : OCT.Object; typ : OCT.Struct;
- i, pos1, pos2, offset : INTEGER;
-
- PROCEDURE FindSlot ( typ : OCT.Struct; name : LONGINT ) : LONGINT;
- VAR obj : OCT.Object;
- BEGIN (* FindSlot *)
- LOOP
- IF typ = NIL THEN RETURN -1 END;
- obj := typ.link;
- WHILE obj # NIL DO
- IF (obj.mode = TProc) & (obj.name = name) THEN RETURN obj.a0 END;
- obj := obj.left
- END;
- typ := typ.BaseTyp
- END
- END FindSlot;
-
- BEGIN (* AllocSlots *)
- FOR i := 0 TO typex - 1 DO
- typ := type [i];
- IF (typ.form = Record) & (typ.sysflg = OberonFlag) THEN
- nextSlot := OCT.NextProc (typ);
- obj := typ.link;
- WHILE obj # NIL DO
- IF (obj.mode = TProc) & (obj.a0 < 0) THEN
- slot := FindSlot (typ.BaseTyp, obj.name);
- IF slot < 0 THEN slot := nextSlot; INC (nextSlot) END;
- obj.a0 := slot; offset := SHORT (slot * (-4));
- pos1 := obj.a2;
- WHILE pos1 # 1 DO
- pos2 := code [pos1 DIV 2]; code [pos1 DIV 2] := offset;
- pos1 := pos2
- END; (* WHILE *)
- END; (* IF *)
- obj := obj.left
- END; (* WHILE *)
- END; (* IF *)
- END (* FOR *)
- END AllocSlots;
-
-
- (*------------------------------------*)
- PROCEDURE OutCode * (FName : ARRAY OF CHAR; key, datasize : LONGINT);
-
- (* CONST pname = "OutCode"; *)
-
- VAR
- ObjFile : Files.File;
- out : Files.Rider;
- blockType, res, N : LONGINT;
- codeHunk : CodeHunk;
-
- (* ---------------------------------- *)
- PROCEDURE OutName (type : INTEGER; name : ARRAY OF CHAR);
-
- (* CONST pname = "OutName"; *)
-
- VAR len, char, pad : INTEGER;
-
- <*$CopyArrays-*>
- BEGIN (* OutName *)
- (* OCM.TraceIn (mname, pname); *)
- len := SHORT (SYS.STRLEN (name));
- pad := (((len + 3) DIV 4) * 4) - len;
- N := SYS.LSH (LONG (type), 24) + ((len + 3) DIV 4);
- Files.WriteBytes (out, N, 4);
- char := 0;
- WHILE char < len DO
- Files.Write (out, name [char]);
- INC (char);
- END; (* WHILE *)
- WHILE pad > 0 DO Files.Write (out, 0X); DEC (pad) END;
- (* ;OCM.TraceOut (mname, pname); *)
- END OutName;
-
- (* ---------------------------------- *)
- PROCEDURE OutHunkUnit ();
-
- (* CONST pname = "OutHunkUnit"; *)
-
- BEGIN (* OutHunkUnit *)
- (* OCM.TraceIn (mname, pname); *)
- blockType := hunkUnit;
- Files.WriteBytes (out, blockType, 4);
- OutName (0, OCT.ModuleName);
- (* ;OCM.TraceOut (mname, pname); *)
- END OutHunkUnit;
-
- (*------------------------------------*)
- PROCEDURE OutHunkName ();
-
- (* CONST pname = "OutHunkName"; *)
-
- BEGIN (* OutHunkName *)
- (* OCM.TraceIn (mname, pname); *)
- blockType := hunkName;
- Files.WriteBytes (out, blockType, 4);
- OutName (0, OCT.ModuleName);
- (* ;OCM.TraceOut (mname, pname); *)
- END OutHunkName;
-
- (*------------------------------------*)
- PROCEDURE OutDef0 (label : ARRAY OF CHAR; offset : LONGINT);
-
- (* CONST pname = "OutDef0"; *)
-
- <*$CopyArrays-*>
- BEGIN (* OutDef0 *)
- (* OCM.TraceIn (mname, pname); *)
- OutName (extDef, label);
- Files.WriteBytes (out, offset, 4)
- (* ;OCM.TraceOut (mname, pname); *)
- END OutDef0;
-
- (*------------------------------------*)
- PROCEDURE OutDef (def : Def);
-
- (* CONST pname = "OutDef"; *)
-
- BEGIN (* OutDef *)
- (* OCM.TraceIn (mname, pname); *)
- OutDef0 (def.object.label^, def.offset)
- (* ;OCM.TraceOut (mname, pname); *)
- END OutDef;
-
- (*------------------------------------*)
- PROCEDURE OutRef (ref : Ref);
-
- (* CONST pname = "OutRef"; *)
-
- VAR type : INTEGER; offset : Offset;
-
- BEGIN (* OutRef *)
- (* OCM.TraceIn (mname, pname); *)
- IF ref.size = 4 THEN type := extRef32
- ELSIF ref.size = 2 THEN type := extRef16
- (*ELSIF ref.size = 1 THEN type := extRef8*)
- ELSE OCS.Mark (959)
- END;
- OutName (type, ref.label^);
- Files.WriteBytes (out, ref.count, 4);
- offset := ref.offsets;
- WHILE offset # NIL DO
- Files.WriteBytes (out, offset.n, 4);
- offset := offset.next
- END
- (* ;OCM.TraceOut (mname, pname); *)
- END OutRef;
-
- (*------------------------------------*)
- PROCEDURE OutCodeHunk (codeHunk : CodeHunk);
-
- (* CONST pname = "OutCodeHunk"; *)
-
- (*------------------------------------*)
- PROCEDURE OutHunkCode ();
-
- (* CONST pname = "OutHunkCode"; *)
-
- VAR pos, len, pad : INTEGER;
-
- BEGIN (* OutHunkCode *)
- (* OCM.TraceIn (mname, pname); *)
- blockType := hunkCode;
- Files.WriteBytes (out, blockType, 4);
-
- N := (codeHunk.length + 1) DIV 2;
- Files.WriteBytes (out, N, 4);
-
- pos := codeHunk.start; len := codeHunk.length;
- WHILE len > 0 DO
- Files.WriteBytes (out, code [pos], 2);
- INC (pos); DEC (len);
- END; (* WHILE *)
-
- IF ODD (codeHunk.length) THEN
- pad := 04E71H; (* Output a NOP, purely for the benefit of ninfo *)
- Files.WriteBytes (out, pad, 2);
- END; (* IF *)
- (* ;OCM.TraceOut (mname, pname); *)
- END OutHunkCode;
-
- (*------------------------------------*)
- PROCEDURE OutHunkExt ();
-
- (* CONST pname = "OutHunkExt"; *)
-
- VAR ref : Ref; def : Def;
-
- BEGIN (* OutHunkExt *)
- (* OCM.TraceIn (mname, pname); *)
- blockType := hunkExt; Files.WriteBytes (out, blockType, 4);
- IF codeHunk = InitCodeHunk THEN OutDef0 (OCT.InitLabel^, 0) END;
- def := codeHunk.defs;
- WHILE def # NIL DO OutDef (def); def := def.next END;
- ref := codeHunk.refs;
- WHILE ref # NIL DO OutRef (ref); ref := ref.next END;
- N := 0; Files.WriteBytes (out, N, 4)
- (* ;OCM.TraceOut (mname, pname); *)
- END OutHunkExt;
-
- (*------------------------------------*)
- PROCEDURE OutHunkSymbol ();
-
- (* CONST pname = "OutHunkSymbol"; *)
-
- VAR
- def : Def; obj : OCT.Object;
- name, symbol : ARRAY 256 OF CHAR;
-
- BEGIN (* OutHunkSymbol *)
- (* OCM.TraceIn (mname, pname); *)
- IF OCM.Debug & ((codeHunk = InitCodeHunk) OR (codeHunk.defs # NIL)) THEN
- blockType := hunkSymbol; Files.WriteBytes (out, blockType, 4);
- IF codeHunk = InitCodeHunk THEN
- COPY (OCT.ModuleName, symbol); Str.Append ("_INIT-CODE", symbol);
- OutName (extSymb, symbol);
- N := 0; Files.WriteBytes (out, N, 4);
- END;
- def := codeHunk.defs;
- WHILE def # NIL DO
- obj := def.object;
- IF obj.mode = TProc THEN
- COPY (OCT.ModuleName, symbol); Str.Append ("_", symbol);
- OCT.GetName (obj.link.typ.strobj.name, name);
- Str.Append (name, symbol); Str.Append ("_", symbol);
- OCT.GetName (obj.name, name); Str.Append (name, symbol);
- OutName (extSymb, symbol)
- ELSIF obj.a0 = 0 THEN
- OutName (extSymb, obj.label^)
- ELSE
- COPY (obj.label^, symbol); Str.Append ("_", symbol);
- OCT.GetName (obj.name, name); Str.Append (name, symbol);
- OutName (extSymb, symbol)
- END;
- Files.WriteBytes (out, def.offset, 4);
- def := def.next
- END;
- N := 0; Files.WriteBytes (out, N, 4)
- END;
- (* OCM.TraceOut (mname, pname); *)
- END OutHunkSymbol;
-
- BEGIN (* OutCodeHunk *)
- (* OCM.TraceIn (mname, pname); *)
- OutHunkUnit ();
- OutHunkName ();
- OutHunkCode ();
- OutHunkExt ();
- OutHunkSymbol ();
- blockType := hunkEnd;
- Files.WriteBytes (out, blockType, 4);
- (* ;OCM.TraceOut (mname, pname); *)
- END OutCodeHunk;
-
- (*------------------------------------*)
- PROCEDURE OutConstants ();
-
- (* CONST pname = "OutConstants"; *)
-
- (*------------------------------------*)
- PROCEDURE OutHunkData ();
-
- (* CONST pname = "OutHunkData"; *)
-
- VAR pos, len , pad : INTEGER;
-
- BEGIN (* OutHunkData *)
- (* OCM.TraceIn (mname, pname); *)
- blockType := hunkData;
- Files.WriteBytes (out, blockType, 4);
-
- N := (conx + 3) DIV 4;
- Files.WriteBytes (out, N, 4);
-
- pos := 0; len := conx;
- WHILE pos < len DO
- Files.Write (out, constant [pos]);
- INC (pos);
- END; (* WHILE *)
-
- pad := (((len + 3) DIV 4) * 4) - len;
- WHILE pad > 0 DO
- Files.Write (out, 0X);
- DEC (pad);
- END; (* WHILE *)
- (* ;OCM.TraceOut (mname, pname); *)
- END OutHunkData;
-
- (*------------------------------------*)
- PROCEDURE OutHunkExt ();
-
- (* CONST pname = "OutHunkExt"; *)
-
- VAR ref : Ref;
-
- BEGIN (* OutHunkExt *)
- (* OCM.TraceIn (mname, pname); *)
- blockType := hunkExt;
- Files.WriteBytes (out, blockType, 4);
- OutDef0 (OCT.ConstLabel^, 0);
- N := 0;
- Files.WriteBytes (out, N, 4);
- (* ;OCM.TraceOut (mname, pname); *)
- END OutHunkExt;
-
- (*------------------------------------*)
- PROCEDURE OutHunkSymbol ();
-
- (* CONST pname = "OutHunkSymbol"; *)
-
- BEGIN (* OutHunkSymbol *)
- (* OCM.TraceIn (mname, pname); *)
- IF OCM.Debug THEN
- blockType := hunkSymbol;
- Files.WriteBytes (out, blockType, 4);
- OutName (extSymb, OCT.ConstLabel^);
- N := 0; Files.WriteBytes (out, N, 4);
- Files.WriteBytes (out, N, 4);
- END;
- (* ;OCM.TraceOut (mname, pname); *)
- END OutHunkSymbol;
-
- BEGIN (* OutConstants *)
- (* OCM.TraceIn (mname, pname); *)
- IF conx > 0 THEN
- OutHunkUnit ();
- OutHunkName ();
- OutHunkData ();
- OutHunkExt ();
- OutHunkSymbol ();
- blockType := hunkEnd;
- Files.WriteBytes (out, blockType, 4);
- END; (* IF *)
- (* ;OCM.TraceOut (mname, pname); *)
- END OutConstants;
-
- (*------------------------------------*)
- PROCEDURE FindPtrs
- ( typ : OCT.Struct; adr : LONGINT; VAR offset : LONGINT );
-
- (* CONST pname = "FindPtrs"; *)
-
- VAR btyp : OCT.Struct; fld : OCT.Object; i, n, s : LONGINT;
-
- BEGIN (* FindPtrs *)
- (* OCM.TraceIn (mname, pname); *)
- IF
- ((typ.form = Pointer) & (typ.sysflg = OberonFlag))
- OR (typ.form = PtrTyp)
- THEN
- Files.WriteBytes (out, adr, 4); DEC (offset, 4); INC (dataCount)
- ELSIF (typ.form = Record) & (typ.sysflg = OberonFlag) THEN
- btyp := typ.BaseTyp;
- IF btyp # NIL THEN FindPtrs (btyp, adr, offset) END;
- fld := typ.link;
- WHILE fld # NIL DO
- IF fld.mode = Fld THEN
- IF fld.name < 0 THEN (* Hidden pointer field *)
- n := fld.a0 + adr; Files.WriteBytes (out, n, 4);
- DEC (offset, 4); INC (dataCount)
- ELSE
- FindPtrs (fld.typ, fld.a0 + adr, offset)
- END
- END;
- fld := fld.left
- END;
- ELSIF typ.form = Array THEN
- btyp := typ.BaseTyp; n := typ.n;
- WHILE btyp.form = Array DO
- n := btyp.n * n; btyp := btyp.BaseTyp
- END;
- IF (btyp.form IN {Pointer, PtrTyp, Record}) THEN
- i := 0; s := btyp.size;
- WHILE i < n DO
- FindPtrs (btyp, i * s + adr, offset); INC (i)
- END
- END
- END
- (* ;OCM.TraceOut (mname, pname); *)
- END FindPtrs;
-
- (*------------------------------------*)
- PROCEDURE OutTypeDescs ();
-
- (* CONST pname = "OutTypeDescs"; *)
-
- VAR i : INTEGER; numProcs : LONGINT;
-
- (*------------------------------------*)
- PROCEDURE OutHunkData (typ : OCT.Struct);
-
- (* CONST pname = "OutHunkData"; *)
-
- VAR
- pos1, pos2, N, i, nameLen : LONGINT;
- name, objName : ARRAY 256 OF CHAR;
- ch : CHAR;
-
- BEGIN (* OutHunkData *)
- (* OCM.TraceIn (mname, pname); *)
- blockType := hunkData; Files.WriteBytes (out, blockType, 4);
- pos1 := Files.Pos (out);
- N := 0; Files.WriteBytes (out, N, 4);
- numProcs := NumProcs (typ); INC (dataCount, SHORT(numProcs));
- i := numProcs;
- WHILE i > 0 DO Files.WriteBytes (out, N, 4); DEC (i) END;
- N := typ.size; Files.WriteBytes (out, N, 4);
- i := 0; N := 0;
- WHILE i < 8 DO Files.WriteBytes (out, N, 4); INC (i) END;
- INC (dataCount, 9);
- N := -36; FindPtrs (typ, 0, N); Files.WriteBytes (out, N, 4);
- IF typ.strobj # NIL THEN
- COPY (OCT.ModuleName, name); nameLen := SYS.STRLEN (name);
- name [nameLen] := "."; INC (nameLen);
- OCT.GetName (typ.strobj.name, objName);
- i := 0;
- REPEAT
- ch := objName [i]; name [nameLen] := ch;
- INC (i); INC (nameLen)
- UNTIL ch = 0X
- ELSE
- name := ""; nameLen := 1
- END;
- FOR i := 0 TO nameLen - 1 DO
- Files.Write (out, name [i]);
- END;
- WHILE (nameLen MOD 4) # 0 DO
- Files.Write (out, 0X); INC (nameLen)
- END;
- INC (dataCount, SHORT (nameLen DIV 4));
- pos2 := Files.Pos (out);
- Files.Set (out, ObjFile, pos1);
- N := ((-N + nameLen) DIV 4) + numProcs + 1;
- Files.WriteBytes (out, N, 4);
- Files.Set (out, ObjFile, pos2);
- (* ;OCM.TraceOut (mname, pname); *)
- END OutHunkData;
-
- (*------------------------------------*)
- PROCEDURE OutHunkExt (typ : OCT.Struct);
-
- (* CONST pname = "OutHunkExt"; *)
-
- VAR N, i : LONGINT; lab : OCT.Label;
-
- BEGIN (* OutHunkExt *)
- (* OCM.TraceIn (mname, pname); *)
- N := hunkExt; Files.WriteBytes (out, N, 4);
- i := numProcs;
- WHILE i > 0 DO
- lab := ProcLab (typ, i); OutName (extRef32, lab^);
- N := 1; Files.WriteBytes (out, N, 4);
- N := (numProcs - i) * 4; Files.WriteBytes (out, N, 4);
- DEC (i)
- END;
- OutDef0 (typ.label^, numProcs * 4);
- IF typ.form = Record THEN
- WHILE (typ # NIL) & (typ.n >= 0) DO
- OutName (extRef32, typ.label^);
- N := 1; Files.WriteBytes (out, N, 4);
- N := (numProcs + typ.n + 1) * 4; Files.WriteBytes (out, N, 4);
- typ := typ.BaseTyp
- END;
- END;
- N := 0; Files.WriteBytes (out, N, 4)
- (* ;OCM.TraceOut (mname, pname); *)
- END OutHunkExt;
-
- (*------------------------------------*)
- PROCEDURE OutHunkSymbol (typ : OCT.Struct);
-
- (* CONST pname = "OutHunkSymbol"; *)
-
- VAR N, i : LONGINT; name, symbol : ARRAY 256 OF CHAR;
-
- BEGIN (* OutHunkSymbol *)
- (* OCM.TraceIn (mname, pname); *)
- IF OCM.Debug THEN
- N := hunkSymbol; Files.WriteBytes (out, N, 4);
- IF (typ.form = Record) & (typ.strobj # NIL) THEN
- COPY (OCT.ModuleName, symbol); Str.Append ("_", symbol);
- OCT.GetName (typ.strobj.name, name); Str.Append (name, symbol);
- OutName (extSymb, symbol)
- ELSE
- OutName (extSymb, typ.label^)
- END;
- N := numProcs * 4; Files.WriteBytes (out, N, 4);
- N := 0; Files.WriteBytes (out, N, 4)
- END;
- (* ;OCM.TraceOut (mname, pname); *)
- END OutHunkSymbol;
-
- BEGIN (* OutTypeDescs *)
- (* OCM.TraceIn (mname, pname); *)
- dataCount := 0;
- IF typex > 0 THEN
- i := 0;
- WHILE i < typex DO
- OutHunkUnit ();
- OutHunkName ();
- OutHunkData (type [i]);
- OutHunkExt (type [i]);
- OutHunkSymbol (type [i]);
- blockType := hunkEnd;
- Files.WriteBytes (out, blockType, 4);
- INC (i)
- END
- END
- (* ;OCM.TraceOut (mname, pname); *)
- END OutTypeDescs;
-
- (*------------------------------------*)
- PROCEDURE OutGC ();
-
- (* CONST pname = "OutGC"; *)
-
- VAR i : INTEGER;
-
- (*------------------------------------*)
- PROCEDURE OutHunkData ();
-
- (* CONST pname = "OutHunkData"; *)
-
- VAR i, N : LONGINT; obj : OCT.Object;
-
- BEGIN (* OutHunkData *)
- (* OCM.TraceIn (mname, pname); *)
- N := hunkData; Files.WriteBytes (out, N, 4);
- N := numPtrs + 3; Files.WriteBytes (out, N, 4);
- N := 0; Files.WriteBytes (out, N, 4); Files.WriteBytes (out, N, 4);
- N := -8; obj := OCT.topScope.right;
- WHILE obj # NIL DO
- IF obj.mode = Var THEN FindPtrs (obj.typ, obj.a0, N) END;
- obj := obj.link
- END;
- Files.WriteBytes (out, N, 4);
- (* ;OCM.TraceOut (mname, pname); *)
- END OutHunkData;
-
- (*------------------------------------*)
- PROCEDURE OutHunkExt ();
-
- (* CONST pname = "OutHunkExt"; *)
-
- VAR N : LONGINT;
-
- BEGIN (* OutHunkExt *)
- (* OCM.TraceIn (mname, pname); *)
- N := hunkExt; Files.WriteBytes (out, N, 4);
- OutDef0 (OCT.GCLabel^, 0);
- OutName (extRef32, OCT.VarLabel^);
- N := 1; Files.WriteBytes (out, N, 4);
- N := 4; Files.WriteBytes (out, N, 4);
- N := 0; Files.WriteBytes (out, N, 4)
- (* ;OCM.TraceOut (mname, pname); *)
- END OutHunkExt;
-
- (*------------------------------------*)
- PROCEDURE OutHunkSymbol ();
-
- (* CONST pname = "OutHunkSymbol"; *)
-
- BEGIN (* OutHunkSymbol *)
- (* OCM.TraceIn (mname, pname); *)
- IF OCM.Debug THEN
- blockType := hunkSymbol; Files.WriteBytes (out, blockType, 4);
- OutName (extSymb, OCT.GCLabel^);
- N := 0; Files.WriteBytes (out, N, 4);
- Files.WriteBytes (out, N, 4);
- END;
- (* ;OCM.TraceOut (mname, pname); *)
- END OutHunkSymbol;
-
- BEGIN (* OutGC *)
- (* OCM.TraceIn (mname, pname); *)
- IF numPtrs > 0 THEN
- OutHunkUnit ();
- OutHunkName ();
- OutHunkData ();
- OutHunkExt ();
- OutHunkSymbol ();
- blockType := hunkEnd;
- Files.WriteBytes (out, blockType, 4);
- END
- (* ;OCM.TraceOut (mname, pname); *)
- END OutGC;
-
- (*------------------------------------*)
- PROCEDURE OutVars ();
-
- (* CONST pname = "OutVars"; *)
-
- BEGIN (* OutVars *)
- (* OCM.TraceIn (mname, pname); *)
- OutHunkUnit ();
- OutHunkName ();
-
- blockType := hunkBSS;
- Files.WriteBytes (out, blockType, 4);
-
- N := (datasize + 3) DIV 4;
- Files.WriteBytes (out, N, 4);
-
- blockType := hunkExt;
- Files.WriteBytes (out, blockType, 4);
- OutDef0 (OCT.VarLabel^, 0);
- N := 0; Files.WriteBytes (out, N, 4);
-
- IF OCM.Debug THEN
- blockType := hunkSymbol; Files.WriteBytes (out, blockType, 4);
- OutName (extSymb, OCT.VarLabel^);
- N := 0; Files.WriteBytes (out, N, 4);
- Files.WriteBytes (out, N, 4);
- END;
-
- blockType := hunkEnd;
- Files.WriteBytes (out, blockType, 4);
- (* ;OCM.TraceOut (mname, pname); *)
- END OutVars;
-
- <*$CopyArrays-*>
- BEGIN (* OutCode *)
- (* OCM.TraceIn (mname, pname); *)
- IF OCM.Force OR ~OCS.scanerr THEN
- ObjFile := Files.New (FName);
- IF ObjFile # NIL THEN
- Files.Set (out, ObjFile, 0);
-
- codeHunk := FirstCodeHunk;
- WHILE codeHunk # NIL DO
- OutCodeHunk (codeHunk);
- codeHunk := codeHunk.next;
- END; (* WHILE *)
- OutConstants ();
- OutTypeDescs ();
- OutGC ();
- OutVars ();
-
- Files.Set (out, NIL, 0); Files.Register (ObjFile);
- OCM.MakeIcon (FName, OCM.iconObj)
- ELSE
- OCS.Mark (153)
- END
- END;
- (* ;OCM.TraceOut (mname, pname); *)
- END OutCode;
-
- (*------------------------------------*)
- PROCEDURE DataSize * () : LONGINT;
-
- (* CONST pname = "DataSize"; *)
-
- VAR size : LONGINT;
-
- BEGIN (* DataSize *)
- (* OCM.TraceIn (mname, pname); *)
- size := dataCount * 4 + conx;
- (* ;OCM.TraceOut (mname, pname); *)
- RETURN size;
- END DataSize;
-
- BEGIN (* OCC *)
- FirstCodeHunk := NIL; CurrCodeHunk := NIL; InitCodeHunk := NIL;
- Prologue := NIL; NEW (wasderef);
-
- FOR i := 0 TO (numKProcs - 1) DO NEW (kernelLab [i], 20) END;
- COPY ("Kernel_Halt", kernelLab [kHalt]^);
- COPY ("Kernel_NewRecord", kernelLab [kNewRecord]^);
- COPY ("Kernel_NewArray", kernelLab [kNewArray]^);
- COPY ("Kernel_NewSysBlk", kernelLab [kNewSysBlk]^);
- COPY ("Kernel_Dispose", kernelLab [kDispose]^);
- COPY ("Kernel_InitGC", kernelLab [kInitGC]^);
- COPY ("Kernel_Move", kernelLab [kMove]^);
- COPY ("Kernel_StackChk", kernelLab [kStackChk]^);
- COPY ("Kernel_Mul32", kernelLab [kMul32]^);
- COPY ("Kernel_Div32", kernelLab [kDiv32]^);
- COPY ("Kernel_SPFix", kernelLab [kSPFix]^);
- COPY ("Kernel_SPFlt", kernelLab [kSPFlt]^);
- COPY ("Kernel_SPCmp", kernelLab [kSPCmp]^);
- COPY ("Kernel_SPTst", kernelLab [kSPTst]^);
- COPY ("Kernel_SPNeg", kernelLab [kSPNeg]^);
- COPY ("Kernel_SPAdd", kernelLab [kSPAdd]^);
- COPY ("Kernel_SPSub", kernelLab [kSPSub]^);
- COPY ("Kernel_SPMul", kernelLab [kSPMul]^);
- COPY ("Kernel_SPDiv", kernelLab [kSPDiv]^);
- COPY ("Kernel_SPAbs", kernelLab [kSPAbs]^);
- COPY ("Kernel_END", kernelLab [kEnd]^);
- END OCC.
-
- (*************************************************************************
-
- $Log: OCC.mod $
- Revision 5.11 1995/01/26 00:17:17 fjc
- - Release 1.5
-
- Revision 5.10 1995/01/09 13:54:08 fjc
- - Added call to OCM.MakeIcon().
-
- Revision 5.9 1995/01/05 11:32:29 fjc
- - Changed to force output of object files if OCM.Force is TRUE.
-
- Revision 5.8 1995/01/03 21:16:57 fjc
- - Changed OCG to OCM.
-
- Revision 5.7 1994/12/16 17:15:03 fjc
- - Changed to accomodate renaming OCT.Symbol to OCT.Label.
- - Added AllocSlots() to fix a serious bug that caused the
- wrong slots to be allocated for type-bound procedures.
- - Symbols output in object file are now different to the
- corresponding linker labels in some cases.
-
- Revision 5.6 1994/11/13 11:23:46 fjc
- - Added kSPAbs.
-
- Revision 5.5 1994/10/23 15:51:42 fjc
- - Added kernelLab array and CallKernel().
- - Fixed bug that made SYSTEM.PTR variables untraced.
-
- Revision 5.4 1994/09/25 17:43:15 fjc
- - Changed to reflect new object modes and system flags.
-
- Revision 5.3 1994/09/15 10:24:29 fjc
- - Replaced switches with pragmas.
-
- Revision 5.2 1994/09/08 10:47:13 fjc
- - Changed to use pragmas/options.
-
- Revision 5.1 1994/09/03 19:29:08 fjc
- - Bumped version number
-
- *************************************************************************)
-