Move alignment and type size code from OPC to OPT. Remove search path in bootstrap compiler.

This commit is contained in:
David Brown 2016-09-23 19:04:26 +01:00
parent 8017aa445c
commit fb002de0dd
202 changed files with 1628 additions and 1590 deletions

View file

@ -9,7 +9,6 @@ MODULE OPB; (* RC 6.3.89 / 21.2.94 *) (* object model 17.1.93 *)
VAR
typSize*: PROCEDURE(typ: OPT.Struct);
exp: INTEGER; (* side effect of log*)
maxExp: SYSTEM.INT64; (* max n in ASH(1, n) on this machine *)
@ -1037,7 +1036,7 @@ MODULE OPB; (* RC 6.3.89 / 21.2.94 *) (* object model 17.1.93 *)
IF x^.class # OPT.Ntype THEN err(110); x := NewIntConst(1)
ELSIF (f IN {OPT.Byte..OPT.Set, OPT.Pointer, OPT.ProcTyp})
OR (x^.typ^.comp IN {OPT.Array, OPT.Record}) THEN
typSize(x^.typ); x^.typ^.pvused := TRUE; x := NewIntConst(x^.typ^.size)
OPT.TypSize(x^.typ); x^.typ^.pvused := TRUE; x := NewIntConst(x^.typ^.size)
ELSE err(111); x := NewIntConst(1)
END
|OPT.ccfn: (*SYSTEM.CC*)

View file

@ -553,46 +553,6 @@ MODULE OPC; (* copyright (c) J. Templ 12.7.95 / 3.7.96 *)
IF typ^.strobj # NIL THEN InitTProcs(typ^.strobj, typ^.link) END
END InitTDesc;
PROCEDURE Align*(VAR adr: LONGINT; base: LONGINT);
BEGIN
CASE base OF
| 2: INC(adr, adr MOD 2)
| 4: INC(adr, (-adr) MOD 4)
| 8: INC(adr, (-adr) MOD 8)
| 16: INC(adr, (-adr) MOD 16)
ELSE (*1*) (*OPM.LogWStr("unhandled case at OPC.Align, base = "); OPM.LogWNum(base, 0); OPM.LogWLn;*)
END
END Align;
PROCEDURE SizeAlignment*(size: LONGINT): LONGINT;
VAR alignment: LONGINT;
BEGIN
IF size < OPM.Alignment THEN
(* Round up to next power of 2 *)
alignment := 1; WHILE alignment < size DO alignment := alignment * 2 END;
ELSE
alignment := OPM.Alignment
END;
RETURN alignment
END SizeAlignment;
PROCEDURE BaseAlignment*(typ: OPT.Struct): LONGINT;
VAR alignment: LONGINT;
BEGIN
IF typ.form = OPT.Comp THEN
IF typ.comp = OPT.Record THEN
alignment := typ.align MOD 10000H
ELSE
alignment := BaseAlignment(typ.BaseTyp)
END
ELSE
alignment := SizeAlignment(typ.size)
END;
RETURN alignment
END BaseAlignment;
PROCEDURE FillGap(gap, off, align: LONGINT; VAR n, curAlign: LONGINT);
(* gap: Required gap - already calculated based on alignment requirements
off: Current offset - where gap begins
@ -602,7 +562,7 @@ MODULE OPC; (* copyright (c) J. Templ 12.7.95 / 3.7.96 *)
*)
VAR adr: LONGINT;
BEGIN
adr := off; Align(adr, align);
adr := off; OPT.Align(adr, align);
IF (curAlign < align) & (gap - (adr - off) >= align) THEN (* preserve alignment of the enclosing struct! *)
DEC(gap, (adr - off) + align);
BegStat;
@ -640,8 +600,8 @@ MODULE OPC; (* copyright (c) J. Templ 12.7.95 / 3.7.96 *)
ELSE
(* mimic OPV.TypSize to detect gaps caused by private fields *)
adr := off;
fldAlign := BaseAlignment(fld^.typ);
Align(adr, fldAlign);
fldAlign := OPT.BaseAlignment(fld^.typ);
OPT.Align(adr, fldAlign);
gap := fld.adr - adr;
IF fldAlign > curAlign THEN curAlign := fldAlign END;
IF gap > 0 THEN

View file

@ -149,7 +149,6 @@ CONST
FirstRef = Comp + 1;
VAR
typSize*: PROCEDURE(typ: Struct);
topScope*: Object;
undftyp*,
@ -205,10 +204,11 @@ VAR
newsf, findpc: BOOLEAN;
extsf, sfpresent: BOOLEAN;
symExtended, symNew: BOOLEAN;
recno: LONGINT; (* number of anonymous record types *)
PROCEDURE InitRecno*; BEGIN recno := 0 END InitRecno;
PROCEDURE err(n: INTEGER); BEGIN OPM.err(n) END err;
@ -250,6 +250,96 @@ BEGIN
END ShorterOrLongerType;
PROCEDURE Align*(VAR adr: LONGINT; base: LONGINT);
BEGIN
CASE base OF
| 2: INC(adr, adr MOD 2)
| 4: INC(adr, (-adr) MOD 4)
| 8: INC(adr, (-adr) MOD 8)
| 16: INC(adr, (-adr) MOD 16)
ELSE (*1*) (*OPM.LogWStr("unhandled case at OPC.Align, base = "); OPM.LogWNum(base, 0); OPM.LogWLn;*)
END
END Align;
PROCEDURE SizeAlignment*(size: LONGINT): LONGINT;
VAR alignment: LONGINT;
BEGIN
IF size < OPM.Alignment THEN
(* Round up to next power of 2 *)
alignment := 1; WHILE alignment < size DO alignment := alignment * 2 END;
ELSE
alignment := OPM.Alignment
END;
RETURN alignment
END SizeAlignment;
PROCEDURE BaseAlignment*(typ: Struct): LONGINT;
VAR alignment: LONGINT;
BEGIN
IF typ.form = Comp THEN
IF typ.comp = Record THEN
alignment := typ.align MOD 10000H
ELSE
alignment := BaseAlignment(typ.BaseTyp)
END
ELSE
alignment := SizeAlignment(typ.size)
END;
RETURN alignment
END BaseAlignment;
PROCEDURE TypSize*(typ: Struct);
VAR
f, c: INTEGER;
offset, size, base, fbase, off0: LONGINT;
fld: Object; btyp: Struct;
BEGIN
IF typ = undftyp THEN OPM.err(58)
ELSIF typ.size = -1 THEN
f := typ.form;
c := typ.comp;
IF c = Record THEN btyp := typ.BaseTyp;
IF btyp = NIL THEN offset := 0; base := 1;
ELSE TypSize(btyp); offset := btyp.size - btyp.sysflag DIV 100H; base := btyp.align;
END;
fld := typ.link;
WHILE (fld # NIL) & (fld.mode = Fld) DO
btyp := fld.typ; TypSize(btyp);
size := btyp.size;
fbase := BaseAlignment(btyp);
Align(offset, fbase);
fld.adr := offset; INC(offset, size);
IF fbase > base THEN base := fbase END;
fld := fld.link
END;
(* base is now the largest alignment of any field *)
off0 := offset;
IF offset = 0 THEN offset := 1 END; (* 1 byte filler to avoid empty struct *)
Align(offset, base);
IF (typ^.strobj = NIL) & (typ^.align MOD 10000H = 0) THEN INC(recno); INC(base, recno * 10000H) END;
typ.size := offset;
typ.align := base;
(* encode the trailing gap into the symbol table to allow dense packing of extended records *)
typ^.sysflag := typ^.sysflag MOD 100H + SHORT((offset - off0)*100H)
ELSIF c = Array THEN
TypSize(typ.BaseTyp);
typ.size := typ.n * typ.BaseTyp.size;
ELSIF f = Pointer THEN
typ.size := OPM.AddressSize;
IF typ.BaseTyp = undftyp THEN OPM.Mark(128, typ.n)
ELSE TypSize(typ.BaseTyp)
END
ELSIF f = ProcTyp THEN
typ.size := OPM.AddressSize;
ELSIF c = DynArr THEN
btyp := typ.BaseTyp; TypSize(btyp);
IF btyp.comp = DynArr THEN typ.size := btyp.size + 4 (* describes dim not size *)
ELSE typ.size := 8
END
END
END
END TypSize;
PROCEDURE NewConst*(): Const;
VAR const: Const;
@ -766,14 +856,14 @@ BEGIN
typ^.n := 0; InStruct(typ^.BaseTyp)
| Sarr: typ^.form := Comp; typ^.comp := Array;
InStruct(typ^.BaseTyp); typ^.n := OPM.SymRInt();
typSize(typ) (* no bounds address !! *)
TypSize(typ) (* no bounds address !! *)
| Sdarr: typ^.form := Comp; typ^.comp := DynArr; InStruct(typ^.BaseTyp);
IF typ^.BaseTyp^.comp = DynArr THEN
typ^.n := typ^.BaseTyp^.n + 1
ELSE
typ^.n := 0
END;
typSize(typ)
TypSize(typ)
| Srec: typ^.form := Comp; typ^.comp := Record;
InStruct(typ^.BaseTyp);
IF typ^.BaseTyp = notyp THEN typ^.BaseTyp := NIL END;

View file

@ -47,62 +47,14 @@ MODULE OPV; (* J. Templ 16.2.95 / 3.7.96
VAR
stamp: INTEGER; (* unique number for nested objects *)
recno: LONGINT; (* number of anonymous record types *)
exit: ExitInfo; (* to check if EXIT is simply a break *)
nofExitLabels: INTEGER;
PROCEDURE TypSize*(typ: OPT.Struct);
VAR f, c: INTEGER; offset, size, base, fbase, off0: LONGINT;
fld: OPT.Object; btyp: OPT.Struct;
BEGIN
IF typ = OPT.undftyp THEN OPM.err(58)
ELSIF typ^.size = -1 THEN
f := typ^.form; c := typ^.comp;
IF c = OPT.Record THEN btyp := typ^.BaseTyp;
IF btyp = NIL THEN offset := 0; base := 1;
ELSE TypSize(btyp); offset := btyp^.size - btyp^.sysflag DIV 100H; base := btyp^.align;
END;
fld := typ^.link;
WHILE (fld # NIL) & (fld^.mode = OPT.Fld) DO
btyp := fld^.typ; TypSize(btyp);
size := btyp^.size; fbase := OPC.BaseAlignment(btyp);
OPC.Align(offset, fbase);
fld^.adr := offset; INC(offset, size);
IF fbase > base THEN base := fbase END ;
fld := fld^.link
END;
(* base is now the largest alignment of any field *)
off0 := offset;
IF offset = 0 THEN offset := 1 END ; (* 1 byte filler to avoid empty struct *)
OPC.Align(offset, base);
IF (typ^.strobj = NIL) & (typ^.align MOD 10000H = 0) THEN INC(recno); INC(base, recno * 10000H) END ;
typ^.size := offset; typ^.align := base;
(* encode the trailing gap into the symbol table to allow dense packing of extended records *)
typ^.sysflag := typ^.sysflag MOD 100H + SHORT((offset - off0)*100H)
ELSIF c = OPT.Array THEN
TypSize(typ^.BaseTyp);
typ^.size := typ^.n * typ^.BaseTyp^.size;
ELSIF f = OPT.Pointer THEN
typ^.size := OPM.AddressSize;
IF typ^.BaseTyp = OPT.undftyp THEN OPM.Mark(128, typ^.n)
ELSE TypSize(typ^.BaseTyp)
END
ELSIF f = OPT.ProcTyp THEN
typ^.size := OPM.AddressSize;
ELSIF c = OPT.DynArr THEN
btyp := typ^.BaseTyp; TypSize(btyp);
IF btyp^.comp = OPT.DynArr THEN typ^.size := btyp^.size + 4 (* describes dim not size *)
ELSE typ^.size := 8
END
END
END
END TypSize;
PROCEDURE Init*;
BEGIN
stamp := 0; recno := 0; nofExitLabels := 0;
stamp := 0; nofExitLabels := 0;
END Init;
PROCEDURE ^Traverse (obj, outerScope: OPT.Object; exported: BOOLEAN);
@ -150,11 +102,11 @@ MODULE OPV; (* J. Templ 16.2.95 / 3.7.96
obj^.linkadr := UndefinedType;
mode := obj^.mode;
IF (mode = OPT.Typ) & ((obj^.vis # OPT.internal) = exported) THEN
typ := obj^.typ; TypSize(obj^.typ);
typ := obj^.typ; OPT.TypSize(obj^.typ);
IF typ^.form = OPT.Pointer THEN typ := typ^.BaseTyp END ;
IF typ^.comp = OPT.Record THEN TraverseRecord(typ) END
ELSIF mode = OPT.TProc THEN GetTProcNum(obj)
ELSIF mode = OPT.Var THEN TypSize(obj^.typ)
ELSIF mode = OPT.Var THEN OPT.TypSize(obj^.typ)
END ;
IF ~exported THEN (* do this only once *)
IF (mode IN {OPT.LProc, OPT.Typ}) & (obj^.mnolev > 0) THEN Stamp(obj^.name) END ;
@ -769,7 +721,7 @@ MODULE OPV; (* J. Templ 16.2.95 / 3.7.96
ELSE OPM.WriteString("NIL")
END ;
OPM.WriteString(", "); OPM.WriteInt(base.size);
OPM.WriteString(", "); OPM.WriteInt(OPC.BaseAlignment(base)); (* element alignment *)
OPM.WriteString(", "); OPM.WriteInt(OPT.BaseAlignment(base)); (* element alignment *)
OPM.WriteString(", "); OPM.WriteInt(nofdim); (* total number of dimensions = number of additional parameters *)
OPM.WriteString(", "); OPM.WriteInt(nofdyn); (* number of dynamic dimensions *)
WHILE typ # base DO

View file

@ -15,6 +15,7 @@ MODULE Vishap; (* J. Templ 3.2.95 *)
OPP.Module(p, OPM.opt);
IF OPM.noerr THEN
OPV.Init;
OPT.InitRecno;
OPV.AdrAndSize(OPT.topScope);
OPT.Export(ext, new);
IF OPM.noerr THEN
@ -129,7 +130,5 @@ BEGIN
Platform.SetInterruptHandler(Trap);
Platform.SetQuitHandler(Trap);
Platform.SetBadInstructionHandler(Trap);
OPB.typSize := OPV.TypSize;
OPT.typSize := OPV.TypSize;
Translate
END Vishap.

View file

@ -69,6 +69,7 @@ int addressSize = 0;
int intsize = 0;
int bsd = 0;
int termux = 0;
int bootstrap = 0; // 1 iff generating a bootstrap compiler.
@ -161,28 +162,32 @@ void determineCCompiler() {
void determineInstallDirectory() {
char *env = getenv("INSTALLDIR");
if (env) {
strncpy(installdir, env, sizeof(installdir));
if (bootstrap) {
installdir[0] = 0;
} else {
#if defined(_MSC_VER) || defined(__MINGW32__)
if (sizeof (void*) == 8) {
snprintf(installdir, sizeof(installdir), "%s\\%s", getenv("ProgramFiles"), oname);
} else {
snprintf(installdir, sizeof(installdir), "%s\\%s", getenv("ProgramFiles(x86)"), oname);
}
#if defined(__MINGW32__)
int i; for(i=0; installdir[i]; i++) if (installdir[i] == '\\') installdir[i] = '/';
char *env = getenv("INSTALLDIR");
if (env) {
strncpy(installdir, env, sizeof(installdir));
} else {
#if defined(_MSC_VER) || defined(__MINGW32__)
if (sizeof (void*) == 8) {
snprintf(installdir, sizeof(installdir), "%s\\%s", getenv("ProgramFiles"), oname);
} else {
snprintf(installdir, sizeof(installdir), "%s\\%s", getenv("ProgramFiles(x86)"), oname);
}
#if defined(__MINGW32__)
int i; for(i=0; installdir[i]; i++) if (installdir[i] == '\\') installdir[i] = '/';
#endif
#else
if (bsd) {
snprintf(installdir, sizeof(installdir), "/usr/local/share/%s", oname);
} else if (termux) {
snprintf(installdir, sizeof(installdir), "/data/data/com.termux/files/opt/%s", oname);
} else {
snprintf(installdir, sizeof(installdir), "/opt/%s", oname);
}
#endif
#else
if (bsd) {
snprintf(installdir, sizeof(installdir), "/usr/local/share/%s", oname);
} else if (termux) {
snprintf(installdir, sizeof(installdir), "/data/data/com.termux/files/opt/%s", oname);
} else {
snprintf(installdir, sizeof(installdir), "/opt/%s", oname);
}
#endif
}
}
}
@ -431,8 +436,12 @@ int main(int argc, char *argv[])
oname = getenv("ONAME"); if (!oname) oname = macrotostring(O_NAME);
if (argc>1) {
ReportSizesAndAlignments();
exit(0);
if (strncasecmp(argv[1], "rep", 3) == 0) {
ReportSizesAndAlignments();
exit(0);
} else {
bootstrap = 1;
}
}
getcwd(cwd, sizeof(cwd));
@ -447,9 +456,15 @@ int main(int argc, char *argv[])
testSystemDotH();
snprintf(versionstring, sizeof(versionstring),
"%s [%s] for %s %s on %s",
version, builddate, compiler, dataModel, os);
if (bootstrap) {
snprintf(versionstring, sizeof(versionstring),
"%s [%s]. Bootstrapping compiler for address size %d, alignment %d.",
version, builddate, addressSize, alignment);
} else {
snprintf(versionstring, sizeof(versionstring),
"%s [%s] for %s %s on %s",
version, builddate, compiler, dataModel, os);
}
writeConfigurationMod();
writeMakeParameters();