Replace alignment constants with calcualted alignment.

This commit is contained in:
David Brown 2016-08-20 23:41:49 +01:00
parent 899ab6ff3f
commit c1228e4ae0
34 changed files with 618 additions and 1084 deletions

View file

@ -108,18 +108,6 @@ MODULE OPB; (* RC 6.3.89 / 21.2.94 *) (* object model 17.1.93 *)
(* Integer size support *)
PROCEDURE SignedMaximum(bytecount: LONGINT): LONGINT;
VAR result: LONGINT;
BEGIN
result := 1;
result := SYSTEM.LSH(result, bytecount*8-1);
RETURN result - 1;
END SignedMaximum;
PROCEDURE SignedMinimum(bytecount: LONGINT): LONGINT;
BEGIN RETURN -SignedMaximum(bytecount) - 1
END SignedMinimum;
PROCEDURE SignedByteSize(n: LONGINT): INTEGER;
(* Returns number of bytes required to represent signed value n *)
VAR b: INTEGER;
@ -1016,7 +1004,7 @@ MODULE OPB; (* RC 6.3.89 / 21.2.94 *) (* object model 17.1.93 *)
| OPM.Char: x := NewIntConst(0); x^.typ := OPT.chartyp
| OPM.SInt,
OPM.Int,
OPM.LInt: x := NewIntConst(SignedMinimum(x.typ.size))
OPM.LInt: x := NewIntConst(OPM.SignedMinimum(x.typ.size))
| OPM.Set: x := NewIntConst(0); x^.typ := OPT.inttyp
| OPM.Real: x := NewRealConst(OPM.MinReal, OPT.realtyp)
| OPM.LReal: x := NewRealConst(OPM.MinLReal, OPT.lrltyp)
@ -1031,7 +1019,7 @@ MODULE OPB; (* RC 6.3.89 / 21.2.94 *) (* object model 17.1.93 *)
| OPM.Char: x := NewIntConst(0FFH); x^.typ := OPT.chartyp
| OPM.SInt,
OPM.Int,
OPM.LInt: x := NewIntConst(SignedMaximum(x.typ.size))
OPM.LInt: x := NewIntConst(OPM.SignedMaximum(x.typ.size))
| OPM.Set: x := NewIntConst(OPM.MaxSet); x^.typ := OPT.inttyp
| OPM.Real: x := NewRealConst(OPM.MaxReal, OPT.realtyp)
| OPM.LReal: x := NewRealConst(OPM.MaxLReal, OPT.lrltyp)

View file

@ -574,6 +574,7 @@ MODULE OPC; (* copyright (c) J. Templ 12.7.95 / 3.7.96 *)
END
END Align;
(*
PROCEDURE Base0(typ: OPT.Struct): LONGINT;
BEGIN
CASE typ^.form OF
@ -594,39 +595,42 @@ MODULE OPC; (* copyright (c) J. Templ 12.7.95 / 3.7.96 *)
ELSE OPM.LogWStr("unhandled case in OPC.BaseAlignment, typ^form = "); OPM.LogWNum(typ^.form, 0); OPM.LogWLn;
END
END Base0;
*)
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 align, result: LONGINT;
VAR alignment: LONGINT;
BEGIN
IF typ.form = OPM.Comp THEN
IF typ.comp = OPM.Record THEN
result := typ.align MOD 10000H
alignment := typ.align MOD 10000H
ELSE
result := BaseAlignment(typ.BaseTyp)
alignment := BaseAlignment(typ.BaseTyp)
END
ELSE
(* Not a compound type *)
result := Base0(typ);
(* Now determine alignment from size *)
IF typ.size < OPM.Alignment THEN
(* Round up to next power of 2 *)
align := 1; WHILE align < typ.size DO align := align * 2 END;
ELSE
align := OPM.Alignment
END;
IF align # result THEN
(* Not a compound type, determine alignment from size *)
alignment := SizeAlignment(typ.size)
(*
IF alignment # Base0(typ) THEN
OPM.LogWStr("BaseAlignment. typ.form "); OPM.LogWNum(typ.form,1);
OPM.LogWStr(", typ.size "); OPM.LogWNum(typ.size,1);
OPM.LogWStr(", old alignment "); OPM.LogWNum(result,1);
OPM.LogWStr(", old alignment "); OPM.LogWNum(alignment,1);
OPM.LogWStr(", alignment based on size "); OPM.LogWNum(align,1); OPM.LogWLn
END;
ASSERT(align = result)
*)
END;
RETURN result
RETURN alignment
END BaseAlignment;

View file

@ -210,11 +210,16 @@ MODULE OPM; (* RC 6.3.89 / 28.6.89, J.Templ 10.7.89 / 22.7.96 *)
ByteSize*, CharSize*, BoolSize*, SIntSize*, IntSize*,
LIntSize*, SetSize*, RealSize*, LRealSize*, PointerSize*, ProcSize*, RecSize*,
(*
CharAlign*, BoolAlign*, SIntAlign*, IntAlign*,
LIntAlign*, SetAlign*, RealAlign*, LRealAlign*, PointerAlign*, ProcAlign*, RecAlign*,
*)
MaxSet*: INTEGER;
MinSInt*, MinInt*, MinLInt*, MaxSInt*, MaxInt*, MaxLInt*, MaxIndex*: LONGINT;
(*
MinSInt*, MinInt*, MinLInt*, MaxSInt*, MaxInt*, MaxLInt*,
*)
MaxIndex*: LONGINT;
MinReal*, MaxReal*, MinLReal*, MaxLReal*: LONGREAL;
@ -645,27 +650,30 @@ MODULE OPM; (* RC 6.3.89 / 28.6.89, J.Templ 10.7.89 / 22.7.96 *)
BEGIN
LogWLn;
LogWStr("Type Size Alignement"); LogWLn;
LogWStr("CHAR "); LogWNum(CharSize, 4); LogWNum(CharAlign, 5); LogWLn;
LogWStr("BOOLEAN "); LogWNum(BoolSize, 4); LogWNum(BoolAlign, 5); LogWLn;
LogWStr("SHORTINT "); LogWNum(SIntSize, 4); LogWNum(SIntAlign, 5); LogWLn;
LogWStr("INTEGER "); LogWNum(IntSize, 4); LogWNum(IntAlign, 5); LogWLn;
LogWStr("LONGINT "); LogWNum(LIntSize, 4); LogWNum(LIntAlign, 5); LogWLn;
LogWStr("SET "); LogWNum(SetSize, 4); LogWNum(SetAlign, 5); LogWLn;
LogWStr("REAL "); LogWNum(RealSize, 4); LogWNum(RealAlign, 5); LogWLn;
LogWStr("LONGREAL "); LogWNum(LRealSize, 4); LogWNum(LRealAlign, 5); LogWLn;
LogWStr("PTR "); LogWNum(PointerSize, 4); LogWNum(PointerAlign, 5); LogWLn;
LogWStr("PROC "); LogWNum(ProcSize, 4); LogWNum(ProcAlign, 5); LogWLn;
LogWStr("RECORD "); LogWNum(RecSize, 4); LogWNum(RecAlign, 5); LogWLn;
LogWStr("CHAR "); LogWNum(CharSize, 4); (* LogWNum(CharAlign, 5); *) LogWLn;
LogWStr("BOOLEAN "); LogWNum(BoolSize, 4); (* LogWNum(BoolAlign, 5); *) LogWLn;
LogWStr("SHORTINT "); LogWNum(SIntSize, 4); (* LogWNum(SIntAlign, 5); *) LogWLn;
LogWStr("INTEGER "); LogWNum(IntSize, 4); (* LogWNum(IntAlign, 5); *) LogWLn;
LogWStr("LONGINT "); LogWNum(LIntSize, 4); (* LogWNum(LIntAlign, 5); *) LogWLn;
LogWStr("SET "); LogWNum(SetSize, 4); (* LogWNum(SetAlign, 5); *) LogWLn;
LogWStr("REAL "); LogWNum(RealSize, 4); (* LogWNum(RealAlign, 5); *) LogWLn;
LogWStr("LONGREAL "); LogWNum(LRealSize, 4); (* LogWNum(LRealAlign, 5); *) LogWLn;
LogWStr("PTR "); LogWNum(PointerSize, 4); (* LogWNum(PointerAlign, 5); *) LogWLn;
LogWStr("PROC "); LogWNum(ProcSize, 4); (* LogWNum(ProcAlign, 5); *) LogWLn;
LogWStr("RECORD "); LogWNum(RecSize, 4); (* LogWNum(RecAlign, 5); *) LogWLn;
(*LogWStr("ENDIAN "); LogWNum(ByteOrder, 4); LogWNum(BitOrder, 5); LogWLn;*)
LogWLn;
(*
LogWStr("Min shortint "); LogWNum(MinSInt, 4); LogWLn;
LogWStr("Max shortint "); LogWNum(MaxSInt, 4); LogWLn;
LogWStr("Min integer "); LogWNum(MinInt, 4); LogWLn;
LogWStr("Max integer "); LogWNum(MaxInt, 4); LogWLn;
LogWStr("Min longint "); LogWNum(MinLInt, 4); LogWLn;
*)
END VerboseListSizes;
(*
PROCEDURE AlignSize*(size: LONGINT): INTEGER;
VAR align: INTEGER;
BEGIN
@ -680,10 +688,25 @@ MODULE OPM; (* RC 6.3.89 / 28.6.89, J.Templ 10.7.89 / 22.7.96 *)
END;
RETURN align
END AlignSize;
*)
PROCEDURE SignedMaximum*(bytecount: LONGINT): LONGINT;
VAR result: LONGINT;
BEGIN
result := 1;
result := SYSTEM.LSH(result, bytecount*8-1);
RETURN result - 1;
END SignedMaximum;
PROCEDURE SignedMinimum*(bytecount: LONGINT): LONGINT;
BEGIN RETURN -SignedMaximum(bytecount) - 1
END SignedMinimum;
PROCEDURE GetProperties();
VAR
base: LONGINT;
(* VAR base: LONGINT; *)
BEGIN
(* Fixed and Configuration.Mod based sizes have been initialised in
the module startup code, and maybe overridden by the -Bnnn bootstrap
@ -695,6 +718,7 @@ MODULE OPM; (* RC 6.3.89 / 28.6.89, J.Templ 10.7.89 / 22.7.96 *)
SetSize := LIntSize;
(* Calculate all type alignments *)
(*
CharAlign := AlignSize(CharSize);
BoolAlign := AlignSize(BoolSize);
SIntAlign := AlignSize(SIntSize);
@ -706,8 +730,9 @@ MODULE OPM; (* RC 6.3.89 / 28.6.89, J.Templ 10.7.89 / 22.7.96 *)
IntAlign := AlignSize(IntSize);
LIntAlign := AlignSize(LIntSize);
SetAlign := AlignSize(SetSize);
*)
(* and I'd like to calculate it, not hardcode constants *)
(*
base := -2;
MinSInt := ASH(base, SIntSize*8-2);
MaxSInt := minusop(MinSInt + 1);
@ -717,6 +742,7 @@ MODULE OPM; (* RC 6.3.89 / 28.6.89, J.Templ 10.7.89 / 22.7.96 *)
MinLInt := ASH(base, LIntSize*8-2);
MaxLInt := minusop(MinLInt +1);
*)
IF RealSize = 4 THEN MaxReal := 3.40282346D38
ELSIF RealSize = 8 THEN MaxReal := 1.7976931348623157D307 * 9.999999
@ -732,16 +758,17 @@ MODULE OPM; (* RC 6.3.89 / 28.6.89, J.Templ 10.7.89 / 22.7.96 *)
MinLReal := -MaxLReal;
MaxSet := SetSize * 8 - 1;
(*
MaxIndex := MaxLInt; (* shouldn't it be like max(int)? so that for loop will be safe, noch *)
*)
MaxIndex := SignedMaximum(PointerSize);
IF Verbose THEN VerboseListSizes END;
END GetProperties;
(* ------------------------- Read Symbol File ------------------------- *)
PROCEDURE SymRCh*(VAR ch: CHAR);
BEGIN Files.Read(oldSF, ch)
END SymRCh;
@ -863,7 +890,7 @@ MODULE OPM; (* RC 6.3.89 / 28.6.89, J.Templ 10.7.89 / 22.7.96 *)
PROCEDURE WriteInt* (i: LONGINT);
VAR s: ARRAY 20 OF CHAR; i1, k: LONGINT;
BEGIN
IF (i = MinInt) OR (i = MinLInt) THEN
IF (i = SignedMinimum(IntSize)) OR (i = SignedMinimum(LIntSize)) THEN
(* abs(minint) is one more than maxint, causing problems representing the value as a minus sign
followed by absoute value. Therefore represent as -maxint - 1. For INTEGER this avoids a
compiler warning 'this decimal constant is unsigned only in ISO C90', for LONGINT it is the
@ -881,7 +908,7 @@ MODULE OPM; (* RC 6.3.89 / 28.6.89, J.Templ 10.7.89 / 22.7.96 *)
VAR W: Texts.Writer; T: Texts.Text; R: Texts.Reader; s: ARRAY 32 OF CHAR; ch: CHAR; i: INTEGER;
BEGIN
(*should be improved *)
IF (r < MaxLInt) & (r > MinLInt) & (r = ENTIER(r)) THEN
IF (r < SignedMaximum(LIntSize)) & (r > SignedMinimum(LIntSize)) & (r = ENTIER(r)) THEN
IF suffx = "f" THEN WriteString("(REAL)") ELSE WriteString("(LONGREAL)") END ;
WriteInt(ENTIER(r))
ELSE

View file

@ -76,7 +76,7 @@ MODULE OPV; (* J. Templ 16.2.95 / 3.7.96
ELSIF typ^.size = -1 THEN
f := typ^.form; c := typ^.comp;
IF c = OPM.Record THEN btyp := typ^.BaseTyp;
IF btyp = NIL THEN offset := 0; base := OPM.RecAlign;
IF btyp = NIL THEN offset := 0; base := (*OPM.RecAlign*)OPC.SizeAlignment(OPM.RecSize);
ELSE TypSize(btyp); offset := btyp^.size - btyp^.sysflag DIV 100H; base := btyp^.align;
END;
fld := typ^.link;
@ -90,7 +90,7 @@ MODULE OPV; (* J. Templ 16.2.95 / 3.7.96
END ;
off0 := offset;
IF offset = 0 THEN offset := 1 END ; (* 1 byte filler to avoid empty struct *)
IF OPM.RecSize = 0 THEN base := NaturalAlignment(offset, OPM.RecAlign) END ;
IF OPM.RecSize = 0 THEN base := NaturalAlignment(offset, (*OPM.RecAlign*)OPC.SizeAlignment(OPM.RecSize)) END ;
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;
@ -303,7 +303,7 @@ MODULE OPV; (* J. Templ 16.2.95 / 3.7.96
IF OPM.ranchk IN OPM.opt THEN OPM.WriteString("__SHORT");
IF SideEffects(n) THEN OPM.Write("F") END ;
OPM.Write(OpenParen); Entier(n, MinPrec);
OPM.WriteString(Comma); OPM.WriteInt(OPM.MaxInt + 1); OPM.Write(CloseParen)
OPM.WriteString(Comma); OPM.WriteInt(OPM.SignedMaximum(OPM.IntSize) + 1); OPM.Write(CloseParen)
ELSE OPM.WriteString("(int)"); Entier(n, 9)
END
END
@ -311,7 +311,7 @@ MODULE OPV; (* J. Templ 16.2.95 / 3.7.96
IF OPM.ranchk IN OPM.opt THEN OPM.WriteString("__SHORT");
IF SideEffects(n) THEN OPM.Write("F") END ;
OPM.Write(OpenParen); Entier(n, MinPrec);
OPM.WriteString(Comma); OPM.WriteInt(OPM.MaxSInt + 1); OPM.Write(CloseParen)
OPM.WriteString(Comma); OPM.WriteInt(OPM.SignedMaximum(OPM.SIntSize) + 1); OPM.Write(CloseParen)
ELSE OPM.WriteString("(int)"); Entier(n, 9)
END
ELSIF form = OPM.Char THEN
@ -475,7 +475,7 @@ MODULE OPV; (* J. Templ 16.2.95 / 3.7.96
IF (mode = OPM.VarPar) & (n^.class = OPM.Nmop) & (n^.subcl = OPM.val) THEN
expr(n^.left, prec) (* avoid cast in lvalue *)
ELSIF (form = OPM.LInt) & (n^.class = OPM.Nconst)
& (n^.conval^.intval <= OPM.MaxInt) & (n^.conval^.intval >= OPM.MinInt) THEN
& (n^.conval^.intval <= OPM.SignedMaximum(OPM.IntSize)) & (n^.conval^.intval >= OPM.SignedMinimum(OPM.IntSize)) THEN
OPM.WriteString("((LONGINT)("); expr(n, prec); OPM.WriteString("))");
ELSE
expr(n, prec)