[M3commit] CVS Update: cm3
Antony Hosking
hosking at elego.de
Thu Feb 18 03:33:15 CET 2010
CVSROOT: /usr/cvs
Changes by: hosking at birch. 10/02/18 03:33:15
Modified files:
cm3/m3-sys/m3middle/src/: M3CG_BinRd.m3 M3CG_Rd.m3 TInt.i3
TInt.m3 TWord.i3 TWord.m3 Target.i3
Target.m3
cm3/m3-sys/m3back/src/: Codex86.m3 M3x86.m3 M3x86Rep.i3
Stackx86.m3 Wrx86.m3
cm3/m3-sys/m3front/src/builtinAtomic/: AtomicModule.mg
cm3/m3-sys/m3front/src/builtinInfo/: InfoThisLine.m3
cm3/m3-sys/m3front/src/builtinOps/: BitSize.m3 Dec.m3 Number.m3
cm3/m3-sys/m3front/src/builtinWord/: And.mg Divide.mg Extract.mg
GE.mg GT.mg Insert.mg LE.mg
LT.mg Minus.mg Mod.mg
Module.mg Not.mg Or.mg
Plus.mg Rotate.mg Shift.mg
Times.mg Xor.mg
cm3/m3-sys/m3front/src/exprs/: AddExpr.m3 AddressExpr.m3
ArrayExpr.m3 Expr.m3
IntegerExpr.m3 ModExpr.m3
ReelExpr.m3 SetExpr.m3
SubtractExpr.m3
cm3/m3-sys/m3front/src/misc/: CG.m3 Scanner.m3 TipeDesc.m3
cm3/m3-sys/m3front/src/stmts/: CaseStmt.m3
cm3/m3-sys/m3front/src/types/: ArrayType.m3 EnumType.m3
OpenArrayType.m3 SubrangeType.m3
Type.m3
cm3/m3-sys/m3tools/src/: M3Builtin.m3 M3Const.m3 M3Lexer.m3
M3Type.m3
Log message:
Drastic simplification of TInt/TWord. These no longer simulate INTEGER
arithmetic directly, but simply provide support for arithmetic up to the
precision of any target. As a result, users of these interfaces must
explicitly ensure that their results do not exceed the bounds of their target
integer precision. One side-effect has been fixes to some remaining bugs in
range-checking for CARDINAL/LONGCARD.
Index: m3middle/src/M3CG_BinRd.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3middle/src/M3CG_BinRd.m3,v
retrieving revision 1.9
diff -c -r1.9 M3CG_BinRd.m3
*** m3middle/src/M3CG_BinRd.m3 11 Jan 2010 22:04:48 -0000 1.9
--- m3middle/src/M3CG_BinRd.m3 18 Feb 2010 02:30:47 -0000
***************
*** 407,426 ****
| M3CG_Binary.Int8 => n_bytes := 8; sign := +1;
| M3CG_Binary.NInt8 => n_bytes := 8; sign := -1;
ELSE
! ok := TInt.FromInt (i, NUMBER (val.x), val); <*ASSERT ok*>
RETURN val;
END;
val := TInt.Zero; shift := 0;
FOR i := 0 TO n_bytes-1 DO
! ok := TInt.FromInt (GetByte (s), NUMBER (byte.x), byte); <*ASSERT ok*>
TWord.Shift (byte, shift, byte);
TWord.Or (val, byte, val);
INC (shift, 8);
END;
! IF (sign < 0) THEN
! TWord.Subtract (TInt.Zero, val, val);
! END;
RETURN val;
END Scan_Tint;
--- 407,424 ----
| M3CG_Binary.Int8 => n_bytes := 8; sign := +1;
| M3CG_Binary.NInt8 => n_bytes := 8; sign := -1;
ELSE
! ok := TInt.FromInt (i, val); <*ASSERT ok*>
RETURN val;
END;
val := TInt.Zero; shift := 0;
FOR i := 0 TO n_bytes-1 DO
! ok := TInt.FromInt (GetByte (s), byte); <*ASSERT ok*>
TWord.Shift (byte, shift, byte);
TWord.Or (val, byte, val);
INC (shift, 8);
END;
! IF (sign < 0) THEN TWord.Subtract (TInt.Zero, val, val); END;
RETURN val;
END Scan_Tint;
Index: m3middle/src/M3CG_Rd.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3middle/src/M3CG_Rd.m3,v
retrieving revision 1.7
diff -c -r1.7 M3CG_Rd.m3
*** m3middle/src/M3CG_Rd.m3 30 Jan 2010 21:28:34 -0000 1.7
--- m3middle/src/M3CG_Rd.m3 18 Feb 2010 02:30:48 -0000
***************
*** 364,377 ****
result, tmp: Target.Int; value, used: INTEGER;
BEGIN
value := Convert.ToInt (SUBARRAY (buf, 0, len), used);
! IF (used = len) AND TInt.FromInt (value, NUMBER (result.x), result) THEN
RETURN result;
ELSIF (buf[0] # '-') THEN
! IF TInt.New (SUBARRAY (buf, 0, len), NUMBER (result.x), result) THEN
! RETURN result;
! END;
ELSE (* Target doesn't handle negative values *)
! IF TInt.New (SUBARRAY (buf, 1, len-1), NUMBER (tmp.x), tmp)
AND TInt.Subtract (TInt.Zero, tmp, result) THEN
RETURN result;
END;
--- 364,375 ----
result, tmp: Target.Int; value, used: INTEGER;
BEGIN
value := Convert.ToInt (SUBARRAY (buf, 0, len), used);
! IF (used = len) AND TInt.FromInt (value, result) THEN
RETURN result;
ELSIF (buf[0] # '-') THEN
! IF TInt.New (SUBARRAY (buf, 0, len), result) THEN RETURN result END;
ELSE (* Target doesn't handle negative values *)
! IF TInt.New (SUBARRAY (buf, 1, len-1), tmp)
AND TInt.Subtract (TInt.Zero, tmp, result) THEN
RETURN result;
END;
Index: m3middle/src/TInt.i3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3middle/src/TInt.i3,v
retrieving revision 1.25
diff -c -r1.25 TInt.i3
*** m3middle/src/TInt.i3 8 Feb 2010 16:42:41 -0000 1.25
--- m3middle/src/TInt.i3 18 Feb 2010 02:30:49 -0000
***************
*** 10,74 ****
(* Modula-3 target description
! This interface provides simulations of the target machine's
! signed integer operations.
Unless otherwise specified, the arithmetic operations defined
! below return TRUE if they succeed in producing a new target value,
otherwise they return FALSE.
*)
! FROM Target IMPORT Int, IBytes;
CONST
! Zero = Int{NUMBER (IBytes), IBytes{ 0,0,..}};
! One = Int{NUMBER (IBytes), IBytes{ 1,0,..}};
! Two = Int{NUMBER (IBytes), IBytes{ 2,0,..}};
! Three = Int{NUMBER (IBytes), IBytes{ 3,0,..}};
! Four = Int{NUMBER (IBytes), IBytes{ 4,0,..}};
! Eight = Int{NUMBER (IBytes), IBytes{ 8,0,..}};
! Ten = Int{NUMBER (IBytes), IBytes{10,0,..}};
! ThirtyOne = Int{NUMBER (IBytes), IBytes{31,0,..}};
! ThirtyTwo = Int{NUMBER (IBytes), IBytes{32,0,..}};
! SixtyThree= Int{NUMBER (IBytes), IBytes{63,0,..}};
! SixtyFour = Int{NUMBER (IBytes), IBytes{64,0,..}};
! F3FF = Int{NUMBER (IBytes), IBytes{16_FF,16_F3,0,..}};
! x0400 = Int{NUMBER (IBytes), IBytes{0,4,0,..}};
! x0800 = Int{NUMBER (IBytes), IBytes{0,8,0,..}};
! x0F00 = Int{NUMBER (IBytes), IBytes{0,16_F,0,..}};
!
! (* 'M' for Minus (negative) *)
!
! MOne = Int{NUMBER (IBytes), IBytes{16_FF,..}};
! MThirtyOne = Int{NUMBER (IBytes), IBytes{16_E1,16_FF,..}};
! MSixtyThree= Int{NUMBER (IBytes), IBytes{16_C1,16_FF,..}};
! PROCEDURE FromInt (x: INTEGER; n: CARDINAL; VAR i: Int): BOOLEAN;
(* converts a host integer 'x' to a target integer 'i' *)
- PROCEDURE IntI (READONLY x: Int; n: CARDINAL; VAR i: Int): BOOLEAN;
- (* converts a target integer 'x' to a target integer 'i' *)
-
PROCEDURE ToInt (READONLY i: Int; VAR x: INTEGER): BOOLEAN;
(* converts a target integer 'i' to a host integer 'x' *)
! PROCEDURE New (READONLY chars: ARRAY OF CHAR; n: CARDINAL;
! VAR i: Int): BOOLEAN;
(* converts the string of decimal characters in 'chars' to an integer
value in 'i' *)
- PROCEDURE Abs (READONLY a: Int; VAR r: Int): BOOLEAN;
- (* returns a if a >= 0, -a if a < 0, or overflow *)
-
PROCEDURE Add (READONLY a, b: Int; VAR i: Int): BOOLEAN;
(* returns 'a + b' unless there's an overflow *)
PROCEDURE Subtract (READONLY a, b: Int; VAR i: Int): BOOLEAN;
(* returns 'a - b' unless there's an overflow *)
- PROCEDURE Negate (READONLY a: Int; VAR r: Int): BOOLEAN;
- (* returns '-a' unless there's an overflow *)
-
PROCEDURE Multiply (READONLY a, b: Int; VAR i: Int): BOOLEAN;
(* returns 'a * b' unless there's an overflow *)
--- 10,48 ----
(* Modula-3 target description
! This interface provides simulations of signed integer operations,
! at the maximum precision supported by any target.
Unless otherwise specified, the arithmetic operations defined
! below return TRUE if they succeed in producing a new value,
otherwise they return FALSE.
*)
! FROM Target IMPORT Int;
!
! CONST Size = BITSIZE(Int);
CONST
! Zero = Int{ 0, 0,..};
! One = Int{ 1, 0,..};
! MOne = Int{16_FF,..};
! PROCEDURE FromInt (x: INTEGER; VAR i: Int): BOOLEAN;
(* converts a host integer 'x' to a target integer 'i' *)
PROCEDURE ToInt (READONLY i: Int; VAR x: INTEGER): BOOLEAN;
(* converts a target integer 'i' to a host integer 'x' *)
! PROCEDURE New (READONLY chars: ARRAY OF CHAR; VAR i: Int): BOOLEAN;
(* converts the string of decimal characters in 'chars' to an integer
value in 'i' *)
PROCEDURE Add (READONLY a, b: Int; VAR i: Int): BOOLEAN;
(* returns 'a + b' unless there's an overflow *)
PROCEDURE Subtract (READONLY a, b: Int; VAR i: Int): BOOLEAN;
(* returns 'a - b' unless there's an overflow *)
PROCEDURE Multiply (READONLY a, b: Int; VAR i: Int): BOOLEAN;
(* returns 'a * b' unless there's an overflow *)
***************
*** 81,101 ****
PROCEDURE EQ (READONLY a, b: Int): BOOLEAN;
(* returns 'a = b' *)
- PROCEDURE NE (READONLY a, b: Int): BOOLEAN;
- (* returns 'a # b' *)
-
PROCEDURE LT (READONLY a, b: Int): BOOLEAN;
(* returns 'a < b' *)
- PROCEDURE GT (READONLY a, b: Int): BOOLEAN;
- (* returns 'a > b' *)
-
PROCEDURE LE (READONLY a, b: Int): BOOLEAN;
(* returns 'a <= b' *)
- PROCEDURE GE (READONLY a, b: Int): BOOLEAN;
- (* returns 'a >= b' *)
-
PROCEDURE ToText (READONLY i: Int): TEXT;
(* converts 'i' to a printable string. *)
--- 55,66 ----
***************
*** 103,111 ****
(* converts 'i' to a printable string in 'buf'. Returns the
number of characters in the string. Returns -1 if 'buf' is too short. *)
! PROCEDURE ToBytes (READONLY i: Int; VAR buf: ARRAY OF [0..255]): INTEGER;
(* converts 'i' to the shortest sequence of bytes in little-endian order
which when sign-extended equal 'i'. Returns the number of
! significant bytes in the result. Returns -1 if 'buf' is too short. *)
END TInt.
--- 68,79 ----
(* converts 'i' to a printable string in 'buf'. Returns the
number of characters in the string. Returns -1 if 'buf' is too short. *)
! PROCEDURE ToBytes (READONLY i: Int; VAR buf: ARRAY OF [0..255]): CARDINAL;
(* converts 'i' to the shortest sequence of bytes in little-endian order
which when sign-extended equal 'i'. Returns the number of
! significant bytes in the result. Returns 0 if 'buf' is too short. *)
!
! PROCEDURE Chop (VAR i: Int; n: CARDINAL);
! (* Extract the low-order 'n' bytes of 'i', sign extended. *)
END TInt.
Index: m3middle/src/TInt.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3middle/src/TInt.m3,v
retrieving revision 1.22
diff -c -r1.22 TInt.m3
*** m3middle/src/TInt.m3 10 Feb 2010 13:09:59 -0000 1.22
--- m3middle/src/TInt.m3 18 Feb 2010 02:30:49 -0000
***************
*** 9,15 ****
MODULE TInt;
IMPORT Word, TWord, Text;
! FROM Target IMPORT Int, IByte, IBytes;
CONST (* IMPORTS *)
RShift = Word.RightShift;
--- 9,15 ----
MODULE TInt;
IMPORT Word, TWord, Text;
! FROM Target IMPORT Int, IByte;
CONST (* IMPORTS *)
RShift = Word.RightShift;
***************
*** 17,109 ****
And = Word.And;
CONST
! Mask = 16_FF;
! SignMask = 16_80;
! Base = 16_100;
Digits = ARRAY [0..9] OF CHAR { '0','1','2','3','4','5','6','7','8','9'};
! PROCEDURE FromInt (x: INTEGER; n: CARDINAL; VAR r: Int): BOOLEAN =
BEGIN
! <*ASSERT n # 0*>
! r.n := n;
! FOR i := 0 TO n-1 DO
! r.x[i] := And (x, Mask);
x := x DIV Base;
END;
! RETURN (n > 0) AND (x = 0 OR x = -1);
END FromInt;
! TYPE Sign = {Bad, Neg, Pos};
!
! PROCEDURE CheckSign (READONLY r: Int; n: CARDINAL): Sign =
BEGIN
! <*ASSERT n # 0*>
! IF And (r.x[r.n-1], SignMask) = 0 THEN
! IF n < r.n THEN
! IF And (r.x[n-1], SignMask) # 0 THEN RETURN Sign.Bad END;
! FOR i := n TO r.n-1 DO
! IF r.x[i] # 0 THEN RETURN Sign.Bad END;
! END;
! END;
! RETURN Sign.Pos;
! ELSE
! IF n < r.n THEN
! IF And (r.x[n-1], SignMask) = 0 THEN RETURN Sign.Bad END;
! FOR i := n TO r.n-1 DO
! IF r.x[i] # Mask THEN RETURN Sign.Bad END;
! END;
! END;
! RETURN Sign.Neg;
END;
- END CheckSign;
- PROCEDURE IntI (READONLY r: Int; n: CARDINAL; VAR x: Int): BOOLEAN =
- VAR sign := CheckSign (r, n); j := 0; result := TRUE;
- BEGIN
- CASE sign OF
- | Sign.Bad => result := FALSE;
- | Sign.Pos => j := 0;
- | Sign.Neg => j := Mask;
- END;
- x.n := n;
- FOR i := 0 TO r.n-1 DO x.x[i] := r.x[i] END;
- FOR i := r.n TO n-1 DO x.x[i] := j END;
- RETURN result;
- END IntI;
-
- PROCEDURE ToInt (READONLY r: Int; VAR x: INTEGER): BOOLEAN =
- VAR sign := CheckSign (r, BITSIZE (INTEGER) DIV BITSIZE (IByte));
- result := TRUE;
- BEGIN
(* ensure the result has the right sign extension *)
! CASE sign OF
! | Sign.Bad => result := FALSE;
! | Sign.Pos => x := 0;
! | Sign.Neg => x := Word.Not (0);
END;
(* finally, pack the bits *)
! FOR i := r.n-1 TO 0 BY -1 DO
! x := Word.Or (LShift (x, BITSIZE (IByte)), r.x[i]);
END;
! RETURN result;
END ToInt;
! PROCEDURE New (READONLY x: ARRAY OF CHAR; n: CARDINAL; VAR r: Int): BOOLEAN =
CONST ZERO = ORD ('0'); ZEROZERO = 10 * ZERO + ZERO;
VAR tmp, digit: Int;
BEGIN
! <*ASSERT n # 0*>
! r := Int{n};
IF (NUMBER (x) = 1) THEN
! r.x[0] := ORD (x[0]) - ZERO;
ELSIF (NUMBER (x) = 2) THEN
! r.x[0] := 10 * ORD (x[0]) + ORD (x[1]) - ZEROZERO;
ELSE
! digit := Int{n};
FOR i := FIRST (x) TO LAST (x) DO
! digit.x[0] := ORD (x[i]) - ZERO;
IF NOT Multiply (r, Ten, tmp) THEN RETURN FALSE; END;
IF NOT Add (tmp, digit, r) THEN RETURN FALSE; END;
END;
--- 17,74 ----
And = Word.And;
CONST
! Mask = RShift (Word.Not (0), Word.Size - BITSIZE (IByte));
! SignMask = LShift (1, BITSIZE (IByte) - 1);
! Base = Mask + 1;
Digits = ARRAY [0..9] OF CHAR { '0','1','2','3','4','5','6','7','8','9'};
+ Ten = Int{10,0,..};
! PROCEDURE FromInt (x: INTEGER; VAR r: Int): BOOLEAN =
BEGIN
! FOR i := 0 TO LAST(Int) DO
! r [i] := And (x, Mask);
x := x DIV Base;
END;
! RETURN (x = 0 OR x = -1);
END FromInt;
! PROCEDURE ToInt (READONLY r: Int; VAR x: INTEGER): BOOLEAN =
! CONST Extras = BITSIZE (INTEGER) DIV BITSIZE (IByte);
! VAR j := 0; sign_chunk := MIN (Extras - 1, LAST(Int));
BEGIN
! (* check that any extra bits are the same as the sign bit *)
! IF And (r [sign_chunk], SignMask) # 0 THEN j := Mask; END;
! FOR i := Extras TO LAST(Int) DO
! IF r [i] # j THEN RETURN FALSE; END;
END;
(* ensure the result has the right sign extension *)
! IF j = 0
! THEN x := 0;
! ELSE x := Word.Not (0);
END;
(* finally, pack the bits *)
! FOR i := LAST(Int) TO 0 BY -1 DO
! x := Word.Or (LShift (x, BITSIZE (IByte)), r[i]);
END;
! RETURN TRUE;
END ToInt;
! PROCEDURE New (READONLY x: ARRAY OF CHAR; VAR r: Int): BOOLEAN =
CONST ZERO = ORD ('0'); ZEROZERO = 10 * ZERO + ZERO;
VAR tmp, digit: Int;
BEGIN
! r := Zero;
IF (NUMBER (x) = 1) THEN
! r[0] := ORD (x[0]) - ZERO;
ELSIF (NUMBER (x) = 2) THEN
! r[0] := 10 * ORD (x[0]) + ORD (x[1]) - ZEROZERO;
ELSE
! digit := Zero;
FOR i := FIRST (x) TO LAST (x) DO
! digit [0] := ORD (x[i]) - ZERO;
IF NOT Multiply (r, Ten, tmp) THEN RETURN FALSE; END;
IF NOT Add (tmp, digit, r) THEN RETURN FALSE; END;
END;
***************
*** 113,206 ****
PROCEDURE Add (READONLY a, b: Int; VAR r: Int): BOOLEAN =
(* It is safe for r to alias a or b *)
! VAR n := MIN (a.n, b.n); carry := 0; r_sign := Sign.Bad;
! a_sign := CheckSign (a, n); b_sign := CheckSign (b, n);
! BEGIN
! IF (a_sign = Sign.Bad) OR (b_sign = Sign.Bad) THEN
! RETURN FALSE
! END;
! r.n := n;
! FOR i := 0 TO n-1 DO
! carry := a.x[i] + b.x[i] + carry;
! r.x[i] := And (carry, Mask);
carry := RShift (carry, BITSIZE (IByte));
END;
! r_sign := CheckSign (r, n); <*ASSERT r_sign # Sign.Bad*>
RETURN (a_sign # b_sign) OR (a_sign = r_sign);
END Add;
PROCEDURE Subtract (READONLY a, b: Int; VAR r: Int): BOOLEAN =
(* It is safe for r to alias a or b *)
! VAR n := MIN (a.n, b.n); borrow := 0; r_sign := Sign.Bad;
! a_sign := CheckSign (a, n); b_sign := CheckSign (b, n);
! BEGIN
! IF (a_sign = Sign.Bad) OR (b_sign = Sign.Bad) THEN
! RETURN FALSE
! END;
! r.n := n;
! FOR i := 0 TO n-1 DO
! borrow := a.x[i] - b.x[i] - borrow;
! r.x[i] := And (borrow, Mask);
borrow := And (RShift (borrow, BITSIZE (IByte)), 1);
END;
! r_sign := CheckSign (r, n); <*ASSERT r_sign # Sign.Bad*>
RETURN (a_sign = b_sign) OR (a_sign = r_sign);
END Subtract;
- PROCEDURE Negate (READONLY a: Int; VAR r: Int): BOOLEAN =
- (* It is safe for r to alias a *)
- BEGIN
- RETURN Subtract(Zero, a, r);
- END Negate;
-
- PROCEDURE Abs (READONLY a: Int; VAR r: Int): BOOLEAN =
- (* It is safe for r to alias a *)
- BEGIN
- IF GE(a, Zero) THEN
- r := a;
- RETURN TRUE;
- END;
- RETURN Negate(a, r);
- END Abs;
-
PROCEDURE Multiply (READONLY a, b: Int; VAR r: Int): BOOLEAN =
VAR
! n := MIN (a.n, b.n); k, carry: INTEGER; q: Int;
! p := ARRAY [0.. 2 * NUMBER (IBytes) - 1] OF IByte {0, ..};
! a_sign := CheckSign (a, n); b_sign := CheckSign (b, n);
BEGIN
! IF (a_sign = Sign.Bad) OR (b_sign = Sign.Bad) THEN
! RETURN FALSE
! END;
! FOR i := 0 TO n-1 DO
! FOR j := 0 TO n-1 DO
k := i + j;
! carry := Word.Times (a.x[i], b.x[j]);
WHILE carry # 0 DO
! carry := carry + p[k];
! p[k] := And (carry, Mask);
carry := RShift (carry, BITSIZE (IByte));
INC (k);
END;
END;
END;
! r.n := n; FOR i := 0 TO n-1 DO r.x[i] := p[i]; END;
! q.n := n; FOR i := 0 TO n-1 DO q.x[i] := p[i+n]; END;
(* compute the top half *)
! IF And (a.x[n-1], SignMask) # 0 THEN EVAL Subtract (q, b, q); END;
! IF And (b.x[n-1], SignMask) # 0 THEN EVAL Subtract (q, a, q); END;
(* there is overflow if the top half is not equal to
to the sign bit of the low half *)
! CASE CheckSign (r, n) OF
! | Sign.Bad => <*ASSERT FALSE*>
! | Sign.Pos => carry := 0;
! | Sign.Neg => carry := Mask;
! END;
! FOR i := 0 TO n-1 DO
! IF q.x[i] # carry THEN RETURN FALSE; END;
END;
RETURN TRUE;
--- 78,145 ----
PROCEDURE Add (READONLY a, b: Int; VAR r: Int): BOOLEAN =
(* It is safe for r to alias a or b *)
! VAR carry := 0;
! a_sign := And (a [LAST(Int)], SignMask);
! b_sign := And (b [LAST(Int)], SignMask);
! r_sign : Word.T;
! BEGIN
! FOR i := 0 TO LAST(Int) DO
! carry := a [i] + b [i] + carry;
! r [i] := And (carry, Mask);
carry := RShift (carry, BITSIZE (IByte));
END;
! r_sign := And (r [LAST(Int)], SignMask);
RETURN (a_sign # b_sign) OR (a_sign = r_sign);
END Add;
PROCEDURE Subtract (READONLY a, b: Int; VAR r: Int): BOOLEAN =
(* It is safe for r to alias a or b *)
! VAR borrow := 0;
! a_sign := And (a [LAST(Int)], SignMask);
! b_sign := And (b [LAST(Int)], SignMask);
! r_sign : Word.T;
! BEGIN
! FOR i := 0 TO LAST(Int) DO
! borrow := a [i] - b [i] - borrow;
! r [i] := And (borrow, Mask);
borrow := And (RShift (borrow, BITSIZE (IByte)), 1);
END;
! r_sign := And (r [LAST(Int)], SignMask);
RETURN (a_sign = b_sign) OR (a_sign = r_sign);
END Subtract;
PROCEDURE Multiply (READONLY a, b: Int; VAR r: Int): BOOLEAN =
VAR
! k, carry: INTEGER;
! q: Int;
! p := ARRAY [0.. 2 * NUMBER(Int) - 1] OF IByte {0, ..};
BEGIN
! FOR i := 0 TO LAST(Int) DO
! FOR j := 0 TO LAST(Int) DO
k := i + j;
! carry := Word.Times (a [i], b [j]);
WHILE carry # 0 DO
! carry := carry + p [k];
! p [k] := And (carry, Mask);
carry := RShift (carry, BITSIZE (IByte));
INC (k);
END;
END;
END;
! FOR i := 0 TO LAST(Int) DO r[i] := p[i]; END;
! FOR i := 0 TO LAST(Int) DO q[i] := p[i+NUMBER(Int)]; END;
(* compute the top half *)
! IF And (a [LAST(Int)], SignMask) # 0 THEN EVAL Subtract (q, b, q); END;
! IF And (b [LAST(Int)], SignMask) # 0 THEN EVAL Subtract (q, a, q); END;
(* there is overflow if the top half is not equal to
to the sign bit of the low half *)
! carry := 0;
! IF And (r [LAST(Int)], SignMask) # 0 THEN carry := Mask; END;
! FOR i := 0 TO LAST(Int) DO
! IF q[i] # carry THEN RETURN FALSE; END;
END;
RETURN TRUE;
***************
*** 224,250 ****
VAR
num := a;
den := b;
! num_neg: BOOLEAN;
! den_neg: BOOLEAN;
! n := MIN (a.n, b.n);
! a_sign := CheckSign (a, n);
! b_sign := CheckSign (b, n);
! min: Int;
BEGIN
- IF (a_sign = Sign.Bad) OR (b_sign = Sign.Bad) THEN
- RETURN FALSE
- END;
-
IF EQ (b, Zero) THEN RETURN FALSE; END;
IF EQ (a, Zero) THEN q := Zero; r := Zero; RETURN TRUE; END;
(* grab the signs *)
! num_neg := a_sign = Sign.Neg;
! den_neg := b_sign = Sign.Neg;
! (* check for the only possible overflow: FIRST DIV -1 *)
IF num_neg AND den_neg THEN
! TWord.Shift (MOne, n * BITSIZE (IByte) - 1, min);
IF EQ (a, min) AND EQ (b, MOne) THEN
RETURN FALSE;
END;
--- 163,182 ----
VAR
num := a;
den := b;
! num_neg : BOOLEAN;
! den_neg : BOOLEAN;
! min : Int;
BEGIN
IF EQ (b, Zero) THEN RETURN FALSE; END;
IF EQ (a, Zero) THEN q := Zero; r := Zero; RETURN TRUE; END;
(* grab the signs *)
! num_neg := And (a [LAST(Int)], SignMask) # 0;
! den_neg := And (b [LAST(Int)], SignMask) # 0;
! (* check for the only possible overflow: FIRST(Int) DIV -1 *)
IF num_neg AND den_neg THEN
! TWord.Shift (MOne, Size - 1, min);
IF EQ (a, min) AND EQ (b, MOne) THEN
RETURN FALSE;
END;
***************
*** 296,327 ****
*)
PROCEDURE EQ (READONLY a, b: Int): BOOLEAN =
- VAR n := MIN (a.n, b.n);
BEGIN
! IF (CheckSign (a, n) = Sign.Bad) OR (CheckSign (b, n) = Sign.Bad) THEN
! RETURN FALSE;
! END;
! FOR i := 0 TO n-1 DO
! IF a.x[i] # b.x[i] THEN RETURN FALSE; END;
END;
RETURN TRUE;
END EQ;
PROCEDURE LT (READONLY a, b: Int): BOOLEAN =
! VAR a_sign := CheckSign (a, a.n);
! b_sign := CheckSign (b, b.n);
! n := MIN (a.n, b.n);
! BEGIN
! <*ASSERT a_sign # Sign.Bad*>
! <*ASSERT b_sign # Sign.Bad*>
! IF (a_sign # b_sign) THEN RETURN (a_sign = Sign.Neg); END;
!
! IF CheckSign (a, n) = Sign.Bad THEN RETURN a_sign = Sign.Neg END;
! IF CheckSign (b, n) = Sign.Bad THEN RETURN b_sign = Sign.Pos END;
!
! FOR i := n-1 TO 0 BY -1 DO
! IF a.x[i] < b.x[i] THEN RETURN TRUE;
! ELSIF a.x[i] > b.x[i] THEN RETURN FALSE;
END;
END;
--- 228,249 ----
*)
PROCEDURE EQ (READONLY a, b: Int): BOOLEAN =
BEGIN
! FOR i := 0 TO LAST(Int) DO
! IF a[i] # b[i] THEN RETURN FALSE; END;
END;
RETURN TRUE;
END EQ;
PROCEDURE LT (READONLY a, b: Int): BOOLEAN =
! VAR a_sign := And (a [LAST(Int)], SignMask);
! b_sign := And (b [LAST(Int)], SignMask);
! BEGIN
! IF (a_sign # b_sign) THEN RETURN (a_sign # 0); END;
!
! FOR i := LAST(Int) TO 0 BY -1 DO
! IF a [i] < b [i] THEN RETURN TRUE;
! ELSIF a [i] > b [i] THEN RETURN FALSE;
END;
END;
***************
*** 333,355 ****
RETURN EQ (a, b) OR LT (a, b);
END LE;
- PROCEDURE NE (READONLY a, b: Int): BOOLEAN =
- BEGIN
- RETURN NOT EQ (a, b);
- END NE;
-
- PROCEDURE GT (READONLY a, b: Int): BOOLEAN =
- BEGIN
- RETURN LT (b, a);
- END GT;
-
- PROCEDURE GE (READONLY a, b: Int): BOOLEAN =
- BEGIN
- RETURN LE(b, a);
- END GE;
-
PROCEDURE ToText (READONLY r: Int): TEXT =
! VAR result : ARRAY [0..BITSIZE (IByte) * NUMBER (IBytes)] OF CHAR;
BEGIN
RETURN Text.FromChars(SUBARRAY(result, 0, ToChars(r, result)));
END ToText;
--- 255,262 ----
RETURN EQ (a, b) OR LT (a, b);
END LE;
PROCEDURE ToText (READONLY r: Int): TEXT =
! VAR result: ARRAY [0..BITSIZE (Int)] OF CHAR;
BEGIN
RETURN Text.FromChars(SUBARRAY(result, 0, ToChars(r, result)));
END ToText;
***************
*** 360,369 ****
minus : BOOLEAN := FALSE;
bump : BOOLEAN := FALSE;
i, j : INTEGER;
! result : ARRAY [0..BITSIZE (IByte) * NUMBER (IBytes)] OF CHAR;
rr := r;
! quo, rem, min: Int;
! n := r.n;
BEGIN
IF EQ (r, Zero) THEN
result [0] := '0';
--- 267,276 ----
minus : BOOLEAN := FALSE;
bump : BOOLEAN := FALSE;
i, j : INTEGER;
! result : ARRAY [0..Size] OF CHAR;
rr := r;
! quo, rem: Int;
! min : Int;
BEGIN
IF EQ (r, Zero) THEN
result [0] := '0';
***************
*** 372,381 ****
ELSE (* handle a non-zero number *)
(* get rid of negative numbers *)
! IF And (r.x[n-1], SignMask) # 0 THEN
! TWord.Shift (MOne, n * BITSIZE (IByte) - 1, min);
IF EQ (r, min) THEN
! (* 2's complement makes FIRST a special case *)
bump := TRUE;
EVAL Add (rr, One, rr);
END;
--- 279,288 ----
ELSE (* handle a non-zero number *)
(* get rid of negative numbers *)
! IF And (r [LAST(Int)], SignMask) # 0 THEN
! TWord.Shift (MOne, Size - 1, min);
IF EQ (r, min) THEN
! (* 2's complement makes FIRST(Int) a special case *)
bump := TRUE;
EVAL Add (rr, One, rr);
END;
***************
*** 386,397 ****
(* convert the bulk of the digits *)
WHILE LT (Zero, rr) DO
TWord.DivMod (rr, Ten, quo, rem);
! result [nDigits] := Digits [rem.x [0]];
rr := quo;
INC (nDigits);
END;
! (* fixup FIRST *)
IF (bump) THEN
result [nDigits] := '0';
j := 0;
--- 293,304 ----
(* convert the bulk of the digits *)
WHILE LT (Zero, rr) DO
TWord.DivMod (rr, Ten, quo, rem);
! result [nDigits] := Digits [rem [0]];
rr := quo;
INC (nDigits);
END;
! (* fixup FIRST (Int) *)
IF (bump) THEN
result [nDigits] := '0';
j := 0;
***************
*** 399,405 ****
i := ORD (result [j]) - ORD ('0');
INC (i);
IF (i < 10) THEN
! result [j] := Digits [i];
EXIT;
END;
result [j] := '0';
--- 306,312 ----
i := ORD (result [j]) - ORD ('0');
INC (i);
IF (i < 10) THEN
! result [j] := Digits [i];
EXIT;
END;
result [j] := '0';
***************
*** 416,422 ****
(* build the result buffer *)
j := 0;
! IF (minus) THEN
buf [0] := '-';
j := 1; END;
FOR k := nDigits-1 TO 0 BY -1 DO
--- 323,329 ----
(* build the result buffer *)
j := 0;
! IF (minus) THEN
buf [0] := '-';
j := 1; END;
FOR k := nDigits-1 TO 0 BY -1 DO
***************
*** 426,447 ****
RETURN j;
END ToChars;
! PROCEDURE ToBytes (READONLY r: Int; VAR buf: ARRAY OF [0..255]): INTEGER =
! VAR n := r.n; j := 0; k := n;
BEGIN
(* strip the sign extension *)
! IF And (r.x[n-1], SignMask) # 0 THEN j := Mask END;
! FOR i := n-1 TO 0 BY -1 DO
! IF r.x[i] # j THEN EXIT END;
! DEC (k);
! END;
! <* ASSERT (k = 0) = (EQ(r, Zero) OR EQ(r, MOne)) *>
! INC(k, ORD(k = 0)); (* increment if 0 *)
! IF k > NUMBER (buf) THEN RETURN -1 END;
(* unpack the bytes *)
! FOR i := 0 TO k-1 DO buf[i] := r.x[i] END;
! RETURN k;
END ToBytes;
BEGIN
END TInt.
--- 333,365 ----
RETURN j;
END ToChars;
! PROCEDURE ToBytes (READONLY r: Int; VAR buf: ARRAY OF [0..255]): CARDINAL =
! VAR j := NUMBER(Int);
BEGIN
(* strip the sign extension *)
! DEC (j);
! IF (r[j] = 0) THEN
! WHILE (j > 0) AND (r[j] = 0) AND (r[j-1] < 16_80) DO DEC (j); END;
! ELSIF (r[j] = 16_ff) THEN
! WHILE (j > 0) AND (r[j] = 16_ff) AND (r[j-1] >= 16_80) DO DEC (j); END;
! END;
! INC (j);
!
! IF j > NUMBER (buf) THEN RETURN 0 END;
!
(* unpack the bytes *)
! FOR i := 0 TO j-1 DO buf[i] := r[i] END;
!
! RETURN j;
END ToBytes;
+ PROCEDURE Chop (VAR r: Int; n: CARDINAL) =
+ BEGIN
+ IF And (r [n-1], SignMask) = 0
+ THEN FOR i := n TO LAST(Int) DO r [i] := 0 END;
+ ELSE FOR i := n TO LAST(Int) DO r [i] := Mask END;
+ END;
+ END Chop;
+
BEGIN
END TInt.
Index: m3middle/src/TWord.i3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3middle/src/TWord.i3,v
retrieving revision 1.8
diff -c -r1.8 TWord.i3
*** m3middle/src/TWord.i3 24 Jan 2010 12:29:14 -0000 1.8
--- m3middle/src/TWord.i3 18 Feb 2010 02:30:49 -0000
***************
*** 10,17 ****
(* Modula-3 target description
! This interface provides simulations of the target machine's
! unsigned integer operations.
Unless otherwise specified, the arithmetic operations defined
below return TRUE if they succeed in producing a new target value,
--- 10,17 ----
(* Modula-3 target description
! This interface provides simulations of unsigned integer operations, at the
! maximum precision supported by any target.
Unless otherwise specified, the arithmetic operations defined
below return TRUE if they succeed in producing a new target value,
***************
*** 20,26 ****
FROM Target IMPORT Int;
! PROCEDURE New (READONLY chars: ARRAY OF CHAR; base: [2..16]; n: CARDINAL;
VAR i: Int): BOOLEAN;
(* converts the string of characters in 'chars' representing a base 'base'
number to an integer value in 'i' *)
--- 20,28 ----
FROM Target IMPORT Int;
! CONST Size = BITSIZE(Int);
!
! PROCEDURE New (READONLY chars: ARRAY OF CHAR; base: [2..16];
VAR i: Int): BOOLEAN;
(* converts the string of characters in 'chars' representing a base 'base'
number to an integer value in 'i' *)
***************
*** 43,54 ****
PROCEDURE DivMod (READONLY x, y: Int; VAR q, r: Int);
(* returns 'q = x DIV y', and 'r = x MOD y', but assumes that 'y # 0' *)
! PROCEDURE LT (READONLY a, b: Int): BOOLEAN; (* a < b *)
! PROCEDURE LE (READONLY a, b: Int): BOOLEAN; (* a <= b *)
! PROCEDURE EQ (READONLY a, b: Int): BOOLEAN; (* a = b *)
! PROCEDURE NE (READONLY a, b: Int): BOOLEAN; (* a # b *)
! PROCEDURE GE (READONLY a, b: Int): BOOLEAN; (* a >= b *)
! PROCEDURE GT (READONLY a, b: Int): BOOLEAN; (* a > b *)
PROCEDURE And (READONLY a, b: Int; VAR i: Int);
(* returns 'Word.And (a, b)' *)
--- 45,55 ----
PROCEDURE DivMod (READONLY x, y: Int; VAR q, r: Int);
(* returns 'q = x DIV y', and 'r = x MOD y', but assumes that 'y # 0' *)
! PROCEDURE LT (READONLY a, b: Int): BOOLEAN;
! (* returns 'Word.LT (a, b)' *)
!
! PROCEDURE LE (READONLY a, b: Int): BOOLEAN;
! (* returns 'Word.LE (a, b)' *)
PROCEDURE And (READONLY a, b: Int; VAR i: Int);
(* returns 'Word.And (a, b)' *)
***************
*** 62,83 ****
PROCEDURE Not (READONLY a: Int; VAR i: Int);
(* returns 'Word.Not (a)' *)
! PROCEDURE Shift (READONLY x: Int; n: INTEGER; VAR r: Int);
! (* returns 'Word.Shift (x, n)' *)
! PROCEDURE LeftShift (READONLY x: Int; n: CARDINAL; VAR r: Int);
! (* returns 'Word.LeftShift (x, n)' *)
! PROCEDURE RightShift (READONLY x: Int; n: CARDINAL; VAR r: Int);
! (* returns 'Word.RightShift (x, n)' *)
! PROCEDURE Rotate (READONLY x: Int; n: INTEGER; VAR r: Int);
! (* returns 'Word.Rotate (x, n)' *)
! PROCEDURE Extract (READONLY x: Int; i, n: CARDINAL; VAR r: Int): BOOLEAN;
! (* returns 'Word.Extract (x, i, n)' *)
! PROCEDURE Insert (READONLY x, y: Int; i, n: CARDINAL; VAR r: Int): BOOLEAN;
! (* returns 'Word.Insert (x, y, i, n)' *)
END TWord.
--- 63,84 ----
PROCEDURE Not (READONLY a: Int; VAR i: Int);
(* returns 'Word.Not (a)' *)
! PROCEDURE Shift (READONLY a: Int; b: INTEGER; VAR r: Int);
! (* returns 'Word.Shift (a, b)' *)
! PROCEDURE LeftShift (READONLY a: Int; b: [0..Size-1]; VAR r: Int);
! (* returns 'Word.LeftShift (a, b)' *)
! PROCEDURE RightShift (READONLY a: Int; b: [0..Size-1]; VAR r: Int);
! (* returns 'Word.RightShift (a, b)' *)
! PROCEDURE Rotate (READONLY a: Int; b: INTEGER; n: CARDINAL; VAR r: Int);
! (* returns 'Word.Rotate (a, b)' *)
! PROCEDURE Extract (READONLY a: Int; b, c: CARDINAL; VAR r: Int): BOOLEAN;
! (* returns 'Word.Extract (a, b, c)' *)
! PROCEDURE Insert (READONLY a, b: Int; c, d: CARDINAL; VAR r: Int): BOOLEAN;
! (* returns 'Word.Insert (a, b, c, d)' *)
END TWord.
Index: m3middle/src/TWord.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3middle/src/TWord.m3,v
retrieving revision 1.15
diff -c -r1.15 TWord.m3
*** m3middle/src/TWord.m3 10 Feb 2010 16:33:10 -0000 1.15
--- m3middle/src/TWord.m3 18 Feb 2010 02:30:49 -0000
***************
*** 9,32 ****
MODULE TWord;
IMPORT Word, TInt;
! FROM Target IMPORT Int, IByte, IBytes;
CONST (* IMPORTS *)
RShift = Word.RightShift;
LShift = Word.LeftShift;
CONST
! Mask = 16_FF;
! Base = 16_100;
(*------------------------------------------- unsigned integer operations ---*)
! PROCEDURE New (READONLY x: ARRAY OF CHAR; base: [2..16]; n: CARDINAL;
! VAR r: Int): BOOLEAN =
! VAR rr: IBytes; digit: INTEGER; ch: CHAR;
BEGIN
! <*ASSERT n # 0*>
! r := Int{n};
FOR i := FIRST (x) TO LAST (x) DO
ch := x [i];
IF ('0' <= ch) AND (ch <= '9') THEN digit := ORD (ch) - ORD ('0');
--- 9,30 ----
MODULE TWord;
IMPORT Word, TInt;
! FROM Target IMPORT Int, IByte;
CONST (* IMPORTS *)
RShift = Word.RightShift;
LShift = Word.LeftShift;
CONST
! Mask = RShift (Word.Not (0), Word.Size - BITSIZE (IByte));
! Base = Mask + 1;
(*------------------------------------------- unsigned integer operations ---*)
! PROCEDURE New (READONLY x: ARRAY OF CHAR; base: [2..16]; VAR r: Int): BOOLEAN =
! VAR rr: Int; digit: INTEGER; ch: CHAR;
BEGIN
! r := TInt.Zero;
FOR i := FIRST (x) TO LAST (x) DO
ch := x [i];
IF ('0' <= ch) AND (ch <= '9') THEN digit := ORD (ch) - ORD ('0');
***************
*** 36,49 ****
END;
(* rr := r * base *)
! rr := IBytes {0,..};
! FOR i := 0 TO n-1 DO
! VAR carry := Word.Times (r.x[i], base);
BEGIN
! FOR j := i TO n-1 DO
IF carry = 0 THEN EXIT END;
! INC (carry, rr[j]);
! rr[j] := Word.And (carry, Mask);
carry := RShift (carry, BITSIZE (IByte));
END;
IF carry # 0 THEN RETURN FALSE END;
--- 34,47 ----
END;
(* rr := r * base *)
! rr := TInt.Zero;
! FOR i := 0 TO LAST(Int) DO
! VAR carry := Word.Times (r[i], base);
BEGIN
! FOR j := i TO LAST(Int) DO
IF carry = 0 THEN EXIT END;
! INC (carry, rr [j]);
! rr [j] := Word.And (carry, Mask);
carry := RShift (carry, BITSIZE (IByte));
END;
IF carry # 0 THEN RETURN FALSE END;
***************
*** 53,61 ****
(* r := rr + digit *)
VAR carry := digit;
BEGIN
! FOR i := 0 TO n-1 DO
! INC (carry, rr[i]);
! r.x[i] := Word.And (carry, Mask);
carry := RShift (carry, BITSIZE (IByte));
END;
IF carry # 0 THEN RETURN FALSE END;
--- 51,59 ----
(* r := rr + digit *)
VAR carry := digit;
BEGIN
! FOR i := 0 TO LAST(Int) DO
! INC (carry, rr [i]);
! r[i] := Word.And (carry, Mask);
carry := RShift (carry, BITSIZE (IByte));
END;
IF carry # 0 THEN RETURN FALSE END;
***************
*** 66,106 ****
END New;
PROCEDURE Add (READONLY a, b: Int; VAR r: Int) =
! VAR carry := 0; n := MIN (a.n, b.n);
BEGIN
! <*ASSERT n # 0*>
! r.n := n;
! FOR i := 0 TO n-1 DO
! carry := a.x[i] + b.x[i] + carry;
! r.x[i] := Word.And (carry, Mask);
carry := RShift (carry, BITSIZE (IByte));
END;
END Add;
PROCEDURE Subtract (READONLY a, b: Int; VAR r: Int) =
! VAR borrow := 0; n := MIN (a.n, b.n);
BEGIN
! <*ASSERT n # 0*>
! r.n := n;
! FOR i := 0 TO n-1 DO
! borrow := a.x[i] - b.x[i] - borrow;
! r.x[i] := Word.And (borrow, Mask);
borrow := Word.And (RShift (borrow, BITSIZE (IByte)), 1);
END;
END Subtract;
PROCEDURE Multiply (READONLY a, b: Int; VAR r: Int) =
! VAR carry: INTEGER; n := MIN (a.n, b.n);
BEGIN
! <*ASSERT n # 0*>
! r := Int{n};
! FOR i := 0 TO n-1 DO
! FOR j := 0 TO n-1 DO
! carry := Word.Times (a.x[i], b.x[j]);
! FOR k := i + j TO n-1 DO
IF carry = 0 THEN EXIT END;
! carry := carry + r.x[k];
! r.x[k] := Word.And (carry, Mask);
carry := RShift (carry, BITSIZE (IByte));
END;
END;
--- 64,99 ----
END New;
PROCEDURE Add (READONLY a, b: Int; VAR r: Int) =
! VAR carry := 0;
BEGIN
! FOR i := 0 TO LAST(Int) DO
! carry := a[i] + b[i] + carry;
! r[i] := Word.And (carry, Mask);
carry := RShift (carry, BITSIZE (IByte));
END;
END Add;
PROCEDURE Subtract (READONLY a, b: Int; VAR r: Int) =
! VAR borrow := 0;
BEGIN
! FOR i := 0 TO LAST(Int) DO
! borrow := a [i] - b [i] - borrow;
! r [i] := Word.And (borrow, Mask);
borrow := Word.And (RShift (borrow, BITSIZE (IByte)), 1);
END;
END Subtract;
PROCEDURE Multiply (READONLY a, b: Int; VAR r: Int) =
! VAR carry: INTEGER;
BEGIN
! r := TInt.Zero;
! FOR i := 0 TO LAST(Int) DO
! FOR j := 0 TO LAST(Int) DO
! carry := Word.Times (a[i], b[j]);
! FOR k := i + j TO LAST(Int) DO
IF carry = 0 THEN EXIT END;
! carry := carry + r[k];
! r[k] := Word.And (carry, Mask);
carry := RShift (carry, BITSIZE (IByte));
END;
END;
***************
*** 136,168 ****
quo_est : INTEGER;
num_hi : INTEGER;
x1,x2,x3: INTEGER;
! num, den: ARRAY [0..NUMBER (IBytes)+1] OF INTEGER;
! n := MIN (x.n, y.n);
BEGIN
- <*ASSERT n # 0*>
(* initialize the numerator and denominator,
and find the highest non-zero digits *)
! FOR i := 0 TO n-1 DO
! num[i] := x.x[i]; IF num[i] # 0 THEN max_num := i END;
! den[i] := y.x[i]; IF den[i] # 0 THEN max_den := i END;
! END;
! FOR i := n TO LAST (num) DO
! num[i] := 0;
! den[i] := 0;
END;
! q := Int{n};
! r := Int{n};
IF max_den = 0 THEN
(* single digit denominator case *)
carry := 0;
FOR j := max_num TO 0 BY -1 DO
tmp := carry * Base + num [j];
! q.x [j] := tmp DIV den[0];
carry := tmp MOD den[0];
END;
! r.x[0] := carry;
RETURN;
END;
--- 129,155 ----
quo_est : INTEGER;
num_hi : INTEGER;
x1,x2,x3: INTEGER;
! num, den := ARRAY [0..NUMBER (Int)+1] OF INTEGER {0,..};
BEGIN
(* initialize the numerator and denominator,
and find the highest non-zero digits *)
! FOR i := 0 TO LAST(Int) DO
! num[i] := x[i]; IF num[i] # 0 THEN max_num := i; END;
! den[i] := y[i]; IF den[i] # 0 THEN max_den := i; END;
END;
! q := TInt.Zero;
! r := TInt.Zero;
IF max_den = 0 THEN
(* single digit denominator case *)
carry := 0;
FOR j := max_num TO 0 BY -1 DO
tmp := carry * Base + num [j];
! q [j] := tmp DIV den[0];
carry := tmp MOD den[0];
END;
! r[0] := carry;
RETURN;
END;
***************
*** 237,243 ****
END;
(* store the quotient digit. *)
! q.x [i - 1] := quo_est;
END;
(* finally, compute the remainder *)
--- 224,230 ----
END;
(* store the quotient digit. *)
! q [i - 1] := quo_est;
END;
(* finally, compute the remainder *)
***************
*** 246,420 ****
END DivMod;
PROCEDURE LT (READONLY a, b: Int): BOOLEAN =
- VAR n := MIN (a.n, b.n);
BEGIN
! <*ASSERT n # 0*>
! FOR i := n TO a.n-1 DO IF a.x[i] # 0 THEN RETURN FALSE END END;
! FOR i := n TO b.n-1 DO IF b.x[i] # 0 THEN RETURN TRUE END END;
! FOR i := n-1 TO 0 BY -1 DO
! IF a.x[i] < b.x[i] THEN RETURN TRUE;
! ELSIF a.x[i] > b.x[i] THEN RETURN FALSE;
END;
END;
RETURN FALSE;
END LT;
PROCEDURE LE (READONLY a, b: Int): BOOLEAN =
- VAR n := MIN (a.n, b.n);
BEGIN
! <*ASSERT n # 0*>
! FOR i := n TO a.n-1 DO IF a.x[i] # 0 THEN RETURN FALSE END END;
! FOR i := n TO b.n-1 DO IF b.x[i] # 0 THEN RETURN TRUE END END;
! FOR i := n-1 TO 0 BY -1 DO
! IF a.x[i] < b.x[i] THEN RETURN TRUE;
! ELSIF a.x[i] > b.x[i] THEN RETURN FALSE;
END;
END;
RETURN TRUE;
END LE;
- PROCEDURE xEQ (READONLY a, b: Int): BOOLEAN =
- VAR n := MIN (a.n, b.n);
- BEGIN
- <*ASSERT n # 0*>
- FOR i := n-1 TO 0 BY -1 DO
- IF a.x[i] # b.x[i] THEN
- RETURN FALSE;
- END;
- END;
- FOR i := n TO a.n-1 DO IF a.x[i] # 0 THEN RETURN FALSE END END;
- FOR i := n TO b.n-1 DO IF b.x[i] # 0 THEN RETURN FALSE END END;
- RETURN TRUE;
- END xEQ;
-
- PROCEDURE EQ (READONLY a, b: Int): BOOLEAN =
- VAR x := xEQ(a, b);
- BEGIN
- <* ASSERT x = xEQ(b, a) *>
- <* ASSERT x = (LE(a, b) AND LE(b, a)) *>
- RETURN x;
- END EQ;
-
- PROCEDURE NE (READONLY a, b: Int): BOOLEAN =
- VAR x := NOT xEQ(a, b);
- BEGIN
- <* ASSERT x = (NOT xEQ(b, a)) *>
- <* ASSERT x = (LT(a, b) OR LT(b, a)) *>
- RETURN x;
- END NE;
-
- PROCEDURE GE (READONLY a, b: Int): BOOLEAN =
- BEGIN
- RETURN LE(b, a);
- END GE;
-
- PROCEDURE GT (READONLY a, b: Int): BOOLEAN =
- BEGIN
- RETURN LT(b, a);
- END GT;
-
PROCEDURE And (READONLY a, b: Int; VAR r: Int) =
- VAR n := MIN (a.n, b.n);
BEGIN
! <*ASSERT n # 0*>
! r.n := n;
! FOR i := 0 TO n-1 DO
! r.x[i] := Word.And (a.x[i], b.x[i]);
END;
END And;
PROCEDURE Or (READONLY a, b: Int; VAR r: Int) =
- VAR n := MIN (a.n, b.n);
BEGIN
! r.n := n;
! FOR i := 0 TO n-1 DO
! r.x[i] := Word.Or (a.x[i], b.x[i]);
END;
END Or;
PROCEDURE Xor (READONLY a, b: Int; VAR r: Int) =
- VAR n := MIN (a.n, b.n);
BEGIN
! <*ASSERT n # 0*>
! r.n := n;
! FOR i := 0 TO n-1 DO
! r.x[i] := Word.Xor (a.x[i], b.x[i]);
END;
END Xor;
PROCEDURE Not (READONLY a: Int; VAR r: Int) =
- VAR n := a.n;
BEGIN
! <*ASSERT n # 0*>
! r.n := n;
! FOR i := 0 TO n-1 DO
! r.x[i] := Word.And (Word.Not (a.x[i]), Mask);
END;
END Not;
! PROCEDURE LeftShift (READONLY a: Int; b: CARDINAL; VAR r: Int) =
VAR w, i, j, z, x1, x2: INTEGER;
- n := a.n; size := n * BITSIZE (IByte);
BEGIN
! <*ASSERT n # 0*>
! IF b >= size THEN
! r := Int{n};
! ELSIF b = 0 THEN (* no shift *)
r := a;
ELSE
w := b DIV BITSIZE (IByte);
i := b MOD BITSIZE (IByte);
j := BITSIZE (IByte) - i;
! FOR k := n-1 TO 0 BY -1 DO
z := k - w; x1 := 0; x2 := 0;
! IF z >= 0 THEN x1 := LShift (a.x[z], i); END;
! IF z-1 >= 0 THEN x2 := RShift (a.x[z-1], j); END;
! r.x[k] := Word.And (Word.Or (x1, x2), Mask);
END;
- r.n := a.n;
END;
END LeftShift;
! PROCEDURE RightShift (READONLY a: Int; b: CARDINAL; VAR r: Int) =
VAR w, i, j, z, x1, x2: INTEGER;
- n := a.n; size := n * BITSIZE (IByte);
BEGIN
! <*ASSERT n # 0*>
! IF b >= size THEN
! r := Int{n};
! ELSIF b = 0 THEN (* no shift *)
r := a;
ELSE
w := b DIV BITSIZE (IByte);
i := b MOD BITSIZE (IByte);
j := BITSIZE (IByte) - i;
! FOR k := 0 TO n-1 DO
z := k + w; x1 := 0; x2 := 0;
! IF z <= n-1 THEN x1 := RShift (a.x[z], i); END;
! IF z+1 <= n-1 THEN x2 := LShift (a.x[z+1], j); END;
! r.x[k] := Word.And (Word.Or (x1, x2), Mask);
END;
- r.n := a.n;
END;
END RightShift;
! PROCEDURE Shift (READONLY a: Int; b: INTEGER; VAR r: Int) =
! BEGIN
! IF b > 0 THEN (* left shift *)
! LeftShift(a, b, r);
! ELSE (* right shift *)
! RightShift(a, -b, r);
! END;
! END Shift;
!
! PROCEDURE Rotate (READONLY a: Int; b: INTEGER; VAR r: Int) =
VAR
w, i, j, z, x1, x2: INTEGER;
! tmp: IBytes;
! n := a.n; size := n * BITSIZE (IByte);
BEGIN
- <*ASSERT n # 0*>
b := b MOD size;
IF b = 0 THEN
--- 233,338 ----
END DivMod;
PROCEDURE LT (READONLY a, b: Int): BOOLEAN =
BEGIN
! FOR i := LAST(Int) TO 0 BY -1 DO
! IF a [i] < b [i] THEN RETURN TRUE;
! ELSIF a [i] > b [i] THEN RETURN FALSE;
END;
END;
RETURN FALSE;
END LT;
PROCEDURE LE (READONLY a, b: Int): BOOLEAN =
BEGIN
! FOR i := LAST(Int) TO 0 BY -1 DO
! IF a [i] < b [i] THEN RETURN TRUE;
! ELSIF a [i] > b [i] THEN RETURN FALSE;
END;
END;
RETURN TRUE;
END LE;
PROCEDURE And (READONLY a, b: Int; VAR r: Int) =
BEGIN
! FOR i := 0 TO LAST(Int) DO
! r [i] := Word.And (a [i], b[i]);
END;
END And;
PROCEDURE Or (READONLY a, b: Int; VAR r: Int) =
BEGIN
! FOR i := 0 TO LAST(Int) DO
! r [i] := Word.Or (a [i], b[i]);
END;
END Or;
PROCEDURE Xor (READONLY a, b: Int; VAR r: Int) =
BEGIN
! FOR i := 0 TO LAST(Int) DO
! r [i] := Word.Xor (a [i], b[i]);
END;
END Xor;
PROCEDURE Not (READONLY a: Int; VAR r: Int) =
BEGIN
! FOR i := 0 TO LAST(Int) DO
! r [i] := Word.And (Word.Not (a [i]), Mask);
END;
END Not;
! PROCEDURE Shift (READONLY a: Int; b: INTEGER; VAR r: Int) =
! BEGIN
! IF ABS (b) >= Size THEN
! r := TInt.Zero;
! ELSIF b > 0
! THEN LeftShift(a, b, r);
! ELSE RightShift(a, -b, r);
! END;
! END Shift;
!
! PROCEDURE LeftShift (READONLY a: Int; b: [0..Size-1]; VAR r: Int) =
VAR w, i, j, z, x1, x2: INTEGER;
BEGIN
! IF b = 0 THEN (* no shift *)
r := a;
ELSE
w := b DIV BITSIZE (IByte);
i := b MOD BITSIZE (IByte);
j := BITSIZE (IByte) - i;
! FOR k := LAST(Int) TO 0 BY -1 DO
z := k - w; x1 := 0; x2 := 0;
! IF z >= 0 THEN x1 := LShift (a[z], i); END;
! IF z-1 >= 0 THEN x2 := RShift (a[z-1], j); END;
! r[k] := Word.And (Word.Or (x1, x2), Mask);
END;
END;
END LeftShift;
! PROCEDURE RightShift (READONLY a: Int; b: [0..Size-1]; VAR r: Int) =
VAR w, i, j, z, x1, x2: INTEGER;
BEGIN
! IF b = 0 THEN (* no shift *)
r := a;
ELSE
w := b DIV BITSIZE (IByte);
i := b MOD BITSIZE (IByte);
j := BITSIZE (IByte) - i;
! FOR k := 0 TO LAST(Int) DO
z := k + w; x1 := 0; x2 := 0;
! IF z <= LAST(Int) THEN x1 := RShift (a[z], i); END;
! IF z+1 <= LAST(Int) THEN x2 := LShift (a[z+1], j); END;
! r[k] := Word.And (Word.Or (x1, x2), Mask);
END;
END;
END RightShift;
! PROCEDURE Rotate (READONLY a: Int; b: INTEGER; n: CARDINAL; VAR r: Int) =
VAR
w, i, j, z, x1, x2: INTEGER;
! tmp: Int;
! size := n * BITSIZE (IByte);
BEGIN
b := b MOD size;
IF b = 0 THEN
***************
*** 426,436 ****
j := BITSIZE (IByte) - i;
FOR k := 0 TO n-1 DO
z := k - w; x1 := 0; x2 := 0;
! x1 := LShift (a.x[z MOD n], i);
! x2 := RShift (a.x[(z-1) MOD n], j);
tmp[k] := Word.And (Word.Or (x1, x2), Mask);
END;
! r := Int {a.n, tmp};
ELSE (* right rotate *)
w := (-b) DIV BITSIZE (IByte);
--- 344,354 ----
j := BITSIZE (IByte) - i;
FOR k := 0 TO n-1 DO
z := k - w; x1 := 0; x2 := 0;
! x1 := LShift (a[z MOD n], i);
! x2 := RShift (a[(z-1) MOD n], j);
tmp[k] := Word.And (Word.Or (x1, x2), Mask);
END;
! r := tmp;
ELSE (* right rotate *)
w := (-b) DIV BITSIZE (IByte);
***************
*** 438,485 ****
j := BITSIZE (IByte) - i;
FOR k := 0 TO n-1 DO
z := k + w; x1 := 0; x2 := 0;
! x1 := RShift (a.x[z MOD n], i);
! x2 := LShift (a.x[(z+1) MOD n], j);
tmp[k] := Word.And (Word.Or (x1, x2), Mask);
END;
! r := Int {a.n, tmp};
END;
END Rotate;
PROCEDURE Extract (READONLY x: Int; i, n: CARDINAL; VAR r: Int): BOOLEAN =
VAR w, b: INTEGER;
- size := x.n * BITSIZE (IByte);
BEGIN
! IF i + n > size THEN RETURN FALSE; END;
! RightShift (x, i, r);
w := n DIV BITSIZE (IByte);
b := n MOD BITSIZE (IByte);
! r.x[w] := Word.And (r.x[w], RShift (Mask, BITSIZE (IByte) - b));
! FOR k := w + 1 TO LAST (IBytes) DO r.x[k] := 0; END;
RETURN TRUE;
END Extract;
PROCEDURE Insert (READONLY x, y: Int; i, n: CARDINAL; VAR r: Int): BOOLEAN =
VAR yy, yyy, yyyy: Int;
- size := x.n * BITSIZE (IByte);
BEGIN
! IF i + n > size THEN RETURN FALSE; END;
! RightShift (x, i + n, yy);
! LeftShift (yy, n, r);
! LeftShift (y, size - n, yy);
! RightShift (yy, size - n, yyy);
Or (r, yyy, r);
! LeftShift (r, i, yyyy);
r := yyyy;
! LeftShift (x, size - i, yy);
! RightShift (yy, size - i, yyy);
Or (r, yyy, r);
RETURN TRUE;
--- 356,401 ----
j := BITSIZE (IByte) - i;
FOR k := 0 TO n-1 DO
z := k + w; x1 := 0; x2 := 0;
! x1 := RShift (a[z MOD n], i);
! x2 := LShift (a[(z+1) MOD n], j);
tmp[k] := Word.And (Word.Or (x1, x2), Mask);
END;
! r := tmp;
END;
END Rotate;
PROCEDURE Extract (READONLY x: Int; i, n: CARDINAL; VAR r: Int): BOOLEAN =
VAR w, b: INTEGER;
BEGIN
! IF i + n > Size THEN RETURN FALSE; END;
! Shift (x, -i, r);
w := n DIV BITSIZE (IByte);
b := n MOD BITSIZE (IByte);
! r[w] := Word.And (r[w], RShift (Mask, BITSIZE (IByte) - b));
! FOR k := w + 1 TO LAST(Int) DO r[k] := 0; END;
RETURN TRUE;
END Extract;
PROCEDURE Insert (READONLY x, y: Int; i, n: CARDINAL; VAR r: Int): BOOLEAN =
VAR yy, yyy, yyyy: Int;
BEGIN
! IF i + n > Size THEN RETURN FALSE; END;
! Shift (x, -(i + n), yy);
! Shift (yy, n, r);
! Shift (y, Size - n, yy);
! Shift (yy, -(Size - n), yyy);
Or (r, yyy, r);
! Shift (r, i, yyyy);
r := yyyy;
! Shift (x, Size - i, yy);
! Shift (yy, -(Size - i), yyy);
Or (r, yyy, r);
RETURN TRUE;
Index: m3middle/src/Target.i3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3middle/src/Target.i3,v
retrieving revision 1.49
diff -c -r1.49 Target.i3
*** m3middle/src/Target.i3 8 Feb 2010 16:00:54 -0000 1.49
--- m3middle/src/Target.i3 18 Feb 2010 02:30:49 -0000
***************
*** 191,210 ****
(*-------------------------------------------------------- integer values ---*)
! (* The bits of a target INTEGER (in 2's complement) are stored in
an array of small host values, with the low order bits in the first
element of the array. *)
TYPE
! Int = (* OPAQUE *) RECORD
! n: CARDINAL; (* only bytes [0..n-1] contain valid bits *)
! x := IBytes{0,..}; (* default is Zero *)
! END;
! IBytes = ARRAY [0..7] OF IByte;
IByte = BITS 8 FOR [0..16_ff];
- PROCEDURE TargetIntToDiagnosticText(a: Int): TEXT;
-
TYPE
Int_type = RECORD
cg_type : CGType; (* representation *)
--- 191,204 ----
(*-------------------------------------------------------- integer values ---*)
! (* The bits of a target integer (in 2's complement) are stored in
an array of small host values, with the low order bits in the first
element of the array. *)
TYPE
! Int = (* OPAQUE *) ARRAY [0..7] OF IByte;
IByte = BITS 8 FOR [0..16_ff];
TYPE
Int_type = RECORD
cg_type : CGType; (* representation *)
Index: m3middle/src/Target.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3middle/src/Target.m3,v
retrieving revision 1.85
diff -c -r1.85 Target.m3
*** m3middle/src/Target.m3 8 Feb 2010 07:17:14 -0000 1.85
--- m3middle/src/Target.m3 18 Feb 2010 02:30:49 -0000
***************
*** 8,33 ****
MODULE Target;
! IMPORT Text, TargetMap, M3RT, TextUtils, Fmt;
VAR (*CONST*)
CCs : REF ARRAY OF CallingConvention;
- PROCEDURE TargetIntToDiagnosticText(a: Int): TEXT =
- VAR t: TEXT;
- BEGIN
- t := "n:";
- t := t & Fmt.Unsigned(a.n);
- t := t & ",x:";
- FOR i := 0 TO 7 DO
- t := t & Fmt.Unsigned(a.x[i]);
- IF i # 7 THEN
- t := t & ",";
- END;
- END;
- RETURN t;
- END TargetIntToDiagnosticText;
-
PROCEDURE Init64 () =
BEGIN
Integer := Int64;
--- 8,18 ----
MODULE Target;
! IMPORT Text, TargetMap, M3RT, TextUtils;
VAR (*CONST*)
CCs : REF ARRAY OF CallingConvention;
PROCEDURE Init64 () =
BEGIN
Integer := Int64;
***************
*** 82,131 ****
Int8.cg_type := CGType.Int8;
Int8.size := 8;
Int8.align := 8;
! Int8.min := Int{NUMBER(IBytes), IBytes{16_80,FF,..}};
! Int8.max := Int{NUMBER(IBytes), IBytes{16_7f,00,..}};
Int16.cg_type := CGType.Int16;
Int16.size := 16;
Int16.align := 16;
! Int16.min := Int{NUMBER(IBytes), IBytes{00,16_80,FF,..}};
! Int16.max := Int{NUMBER(IBytes), IBytes{FF,16_7f,00,..}};
Int32.cg_type := CGType.Int32;
Int32.size := 32;
Int32.align := 32;
! Int32.min := Int{NUMBER(IBytes), IBytes{00,00,00,16_80,FF,..}};
! Int32.max := Int{NUMBER(IBytes), IBytes{FF,FF,FF,16_7f,00,..}};
Int64.cg_type := CGType.Int64;
Int64.size := 64;
Int64.align := 64;
! Int64.min := Int{NUMBER(IBytes), IBytes{00,00,00,00,00,00,00,16_80}};
! Int64.max := Int{NUMBER(IBytes), IBytes{FF,FF,FF,FF,FF,FF,FF,16_7f}};
Word8.cg_type := CGType.Word8;
Word8.size := 8;
Word8.align := 8;
! Word8.min := Int{NUMBER(IBytes), IBytes{00,00,..}};
! Word8.max := Int{NUMBER(IBytes), IBytes{FF,00,..}};
Word16.cg_type := CGType.Word16;
Word16.size := 16;
Word16.align := 16;
! Word16.min := Int{NUMBER(IBytes), IBytes{00,00,00,..}};
! Word16.max := Int{NUMBER(IBytes), IBytes{FF,FF,00,..}};
Word32.cg_type := CGType.Word32;
Word32.size := 32;
Word32.align := 32;
! Word32.min := Int{NUMBER(IBytes), IBytes{00,00,00,00,00,..}};
! Word32.max := Int{NUMBER(IBytes), IBytes{FF,FF,FF,FF,00,..}};
Word64.cg_type := CGType.Word64;
Word64.size := 64;
Word64.align := 64;
! Word64.min := Int{NUMBER(IBytes), IBytes{00,00,00,00,00,00,00,00}};
! Word64.max := Int{NUMBER(IBytes), IBytes{FF,FF,FF,FF,FF,FF,FF,FF}};
Integer := Int32; (* default for the 32-bit platforms *)
Longint := Int64;
--- 67,116 ----
Int8.cg_type := CGType.Int8;
Int8.size := 8;
Int8.align := 8;
! Int8.min := Int{16_80,FF,..};
! Int8.max := Int{16_7f,00,..};
Int16.cg_type := CGType.Int16;
Int16.size := 16;
Int16.align := 16;
! Int16.min := Int{00,16_80,FF,..};
! Int16.max := Int{FF,16_7f,00,..};
Int32.cg_type := CGType.Int32;
Int32.size := 32;
Int32.align := 32;
! Int32.min := Int{00,00,00,16_80,FF,..};
! Int32.max := Int{FF,FF,FF,16_7f,00,..};
Int64.cg_type := CGType.Int64;
Int64.size := 64;
Int64.align := 64;
! Int64.min := Int{00,00,00,00,00,00,00,16_80};
! Int64.max := Int{FF,FF,FF,FF,FF,FF,FF,16_7f};
Word8.cg_type := CGType.Word8;
Word8.size := 8;
Word8.align := 8;
! Word8.min := Int{00,00,..};
! Word8.max := Int{FF,00,..};
Word16.cg_type := CGType.Word16;
Word16.size := 16;
Word16.align := 16;
! Word16.min := Int{00,00,00,..};
! Word16.max := Int{FF,FF,00,..};
Word32.cg_type := CGType.Word32;
Word32.size := 32;
Word32.align := 32;
! Word32.min := Int{00,00,00,00,00,..};
! Word32.max := Int{FF,FF,FF,FF,00,..};
Word64.cg_type := CGType.Word64;
Word64.size := 64;
Word64.align := 64;
! Word64.min := Int{00,00,00,00,00,00,00,00};
! Word64.max := Int{FF,FF,FF,FF,FF,FF,FF,FF};
Integer := Int32; (* default for the 32-bit platforms *)
Longint := Int64;
***************
*** 137,144 ****
Void.cg_type := CGType.Void;
Void.size := 0;
Void.align := Byte;
! Void.min := Int{0};
! Void.max := Int{0};
Real.cg_type := CGType.Reel;
Real.pre := Precision.Short;
--- 122,129 ----
Void.cg_type := CGType.Void;
Void.size := 0;
Void.align := Byte;
! Void.min := Int{0,..};
! Void.max := Int{0,..};
Real.cg_type := CGType.Reel;
Real.pre := Precision.Short;
Index: m3back/src/Codex86.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3back/src/Codex86.m3,v
retrieving revision 1.79
diff -c -r1.79 Codex86.m3
*** m3back/src/Codex86.m3 15 Feb 2010 17:48:57 -0000 1.79
--- m3back/src/Codex86.m3 18 Feb 2010 02:30:50 -0000
***************
*** 9,15 ****
MODULE Codex86;
IMPORT Fmt, TargetMap, M3x86Rep, M3ID, M3CG_Ops, Word, M3ObjFile, Wrx86, Target;
! IMPORT TInt, TWord;
FROM TargetMap IMPORT CG_Bytes;
--- 9,15 ----
MODULE Codex86;
IMPORT Fmt, TargetMap, M3x86Rep, M3ID, M3CG_Ops, Word, M3ObjFile, Wrx86, Target;
! IMPORT TInt, TWord, Text;
FROM TargetMap IMPORT CG_Bytes;
***************
*** 18,24 ****
FROM M3CG_Ops IMPORT ErrorHandler;
FROM M3x86Rep IMPORT Operand, MVar, Regno, OLoc, VLoc, x86Var, x86Proc, NRegs, OperandSize, GetOperandSize;
! FROM M3x86Rep IMPORT RegistersForByteOperations, RegName, SplitOperand, Is64, SplitImm, OperandPart, GetTypeSize, TZero;
FROM M3x86Rep IMPORT EAX, EDX, ESP, EBP, ECX;
FROM M3ObjFile IMPORT Seg;
--- 18,24 ----
FROM M3CG_Ops IMPORT ErrorHandler;
FROM M3x86Rep IMPORT Operand, MVar, Regno, OLoc, VLoc, x86Var, x86Proc, NRegs, OperandSize, GetOperandSize;
! FROM M3x86Rep IMPORT RegistersForByteOperations, RegName, SplitOperand, Is64, SplitImm, OperandPart, GetTypeSize;
FROM M3x86Rep IMPORT EAX, EDX, ESP, EBP, ECX;
FROM M3ObjFile IMPORT Seg;
***************
*** 252,258 ****
op.reg[0] IN RegistersForByteOperations ) OR
(op.loc = OLoc.mem AND CG_Bytes[op.mvar.mvar_type] = 1) *>
IF op.loc = OLoc.register THEN
! movImmT(t, op, TZero);
END;
build_modrm(t, op, t.opcode[0], ins);
ins.escape := TRUE;
--- 252,258 ----
op.reg[0] IN RegistersForByteOperations ) OR
(op.loc = OLoc.mem AND CG_Bytes[op.mvar.mvar_type] = 1) *>
IF op.loc = OLoc.register THEN
! movImmT(t, op, TInt.Zero);
END;
build_modrm(t, op, t.opcode[0], ins);
ins.escape := TRUE;
***************
*** 379,392 ****
PROCEDURE immOp1 (t: T; op: Op; READONLY dest: Operand; READONLY imm: Target.Int) =
VAR ins: Instruction;
BEGIN
<* ASSERT dest.loc = OLoc.register OR dest.loc = OLoc.mem *>
! IF (NOT TInt.ToInt(imm, ins.imm)) AND (NOT TWord.LE(imm, Target.Word32.max)) THEN
! t.Err("immOp1: unable to convert immediate to INTEGER:" & Target.TargetIntToDiagnosticText(imm));
END;
! IF TInt.GE(imm, Target.Int8.min) AND TInt.LE(imm, Target.Int8.max) THEN
ins.imsize := 1;
ELSE
ins.imsize := 4;
--- 379,395 ----
PROCEDURE immOp1 (t: T; op: Op; READONLY dest: Operand; READONLY imm: Target.Int) =
VAR ins: Instruction;
+ buf: ARRAY [0..BITSIZE(Target.Int)] OF CHAR;
BEGIN
<* ASSERT dest.loc = OLoc.register OR dest.loc = OLoc.mem *>
! IF (NOT TInt.ToInt(imm, ins.imm))
! AND (NOT TWord.LE(imm, Target.Word32.max)) THEN
! t.Err("immOp1: unable to convert immediate to INTEGER: " &
! Text.FromChars (SUBARRAY(buf, 0, TInt.ToChars(imm, buf))));
END;
! IF TInt.LE(Target.Int8.min, imm) AND TInt.LE(imm, Target.Int8.max) THEN
ins.imsize := 1;
ELSE
ins.imsize := 4;
***************
*** 465,473 ****
t.set_label(compare_label);
| Op.oSHL =>
! IF TInt.GE(imm, TInt.ThirtyTwo) THEN
! IF TInt.NE(imm, TInt.ThirtyTwo) THEN
! EVAL TInt.Subtract(imm, TInt.ThirtyTwo, immMinus32);
(* Ideally we'd do a virtual move in the register alloator. *)
movOp1(t, destA[1], destA[0]);
immOp1(t, op, destA[1], immMinus32);
--- 468,476 ----
t.set_label(compare_label);
| Op.oSHL =>
! IF TInt.LE(Target.Int{32,0,..}, imm) THEN
! IF NOT TInt.EQ(imm, Target.Int{32,0,..}) THEN
! EVAL TInt.Subtract(imm, Target.Int{32,0,..}, immMinus32);
(* Ideally we'd do a virtual move in the register alloator. *)
movOp1(t, destA[1], destA[0]);
immOp1(t, op, destA[1], immMinus32);
***************
*** 482,490 ****
END
| Op.oSHR =>
! IF TInt.GE(imm, TInt.ThirtyTwo) THEN
! IF TInt.NE(imm, TInt.ThirtyTwo) THEN
! EVAL TInt.Subtract(imm, TInt.ThirtyTwo, immMinus32);
(* Ideally we'd do a virtual move in the register alloator. *)
movOp1(t, destA[0], destA[1]);
immOp1(t, op, destA[0], immMinus32);
--- 485,493 ----
END
| Op.oSHR =>
! IF TInt.LE(Target.Int{32,0,..}, imm) THEN
! IF NOT TInt.EQ(imm, Target.Int{32,0,..}) THEN
! EVAL TInt.Subtract(imm, Target.Int{32,0,..}, immMinus32);
(* Ideally we'd do a virtual move in the register alloator. *)
movOp1(t, destA[0], destA[1]);
immOp1(t, op, destA[0], immMinus32);
***************
*** 513,518 ****
--- 516,522 ----
PROCEDURE binOp1WithShiftCount (t: T; op: Op; READONLY dest, src: Operand; READONLY shiftCount: Operand) =
VAR ins: Instruction;
+ buf: ARRAY [0..BITSIZE(Target.Int)] OF CHAR;
BEGIN
<* ASSERT NOT Is64(src.optype) *>
***************
*** 549,559 ****
<* ASSERT src.loc = OLoc.register *>
<* ASSERT shiftCount.loc = OLoc.register OR shiftCount.loc = OLoc.imm *>
<* ASSERT shiftCount.loc # OLoc.register OR shiftCount.reg[0] = ECX *>
! <* ASSERT shiftCount.loc # OLoc.imm OR (TInt.GE(shiftCount.imm, Target.Int8.min) AND TInt.LE(shiftCount.imm, Target.Int8.max)) *>
IF shiftCount.loc = OLoc.imm THEN
IF NOT TInt.ToInt(shiftCount.imm, ins.imm) THEN
! t.Err("binOp: unable to convert immediate to INTEGER:" & Target.TargetIntToDiagnosticText(shiftCount.imm));
END;
ins.imsize := 1;
ELSE
--- 553,564 ----
<* ASSERT src.loc = OLoc.register *>
<* ASSERT shiftCount.loc = OLoc.register OR shiftCount.loc = OLoc.imm *>
<* ASSERT shiftCount.loc # OLoc.register OR shiftCount.reg[0] = ECX *>
! <* ASSERT shiftCount.loc # OLoc.imm OR (TInt.LE(Target.Int8.min, shiftCount.imm) AND TInt.LE(shiftCount.imm, Target.Int8.max)) *>
IF shiftCount.loc = OLoc.imm THEN
IF NOT TInt.ToInt(shiftCount.imm, ins.imm) THEN
! t.Err("binOp: unable to convert immediate to INTEGER:" &
! Text.FromChars (SUBARRAY(buf, 0, TInt.ToChars(shiftCount.imm, buf))));
END;
ins.imsize := 1;
ELSE
***************
*** 908,916 ****
PROCEDURE movImmT (t: T; READONLY dest: Operand; imm: Target.Int) =
VAR ins: Instruction;
BEGIN
! IF (NOT TInt.ToInt(imm, ins.imm)) AND (NOT TWord.LE(imm, Target.Word32.max)) THEN
! t.Err("movImmT: unable to convert immediate to INTEGER:" & Target.TargetIntToDiagnosticText(imm));
END;
IF dest.loc # OLoc.register THEN
<* ASSERT dest.loc = OLoc.mem *>
--- 913,924 ----
PROCEDURE movImmT (t: T; READONLY dest: Operand; imm: Target.Int) =
VAR ins: Instruction;
+ buf: ARRAY [0..BITSIZE(Target.Int)] OF CHAR;
BEGIN
! IF (NOT TInt.ToInt(imm, ins.imm))
! AND (NOT TWord.LE(imm, Target.Word32.max)) THEN
! t.Err("movImmT: unable to convert immediate to INTEGER: " &
! Text.FromChars (SUBARRAY(buf, 0, TInt.ToChars(imm, buf))));
END;
IF dest.loc # OLoc.register THEN
<* ASSERT dest.loc = OLoc.mem *>
***************
*** 921,927 ****
ins.imsize := CG_Bytes[dest.mvar.mvar_type];
writecode(t, ins);
log_global_var(t, dest.mvar, -4 - CG_Bytes[dest.mvar.mvar_type]);
! ELSIF TInt.EQ(imm, TZero) THEN
binOp(t, Op.oXOR, dest, dest);
ELSE
ins.opcode := 16_B8 + dest.reg[0];
--- 929,935 ----
ins.imsize := CG_Bytes[dest.mvar.mvar_type];
writecode(t, ins);
log_global_var(t, dest.mvar, -4 - CG_Bytes[dest.mvar.mvar_type]);
! ELSIF TInt.EQ(imm, TInt.Zero) THEN
binOp(t, Op.oXOR, dest, dest);
ELSE
ins.opcode := 16_B8 + dest.reg[0];
***************
*** 934,940 ****
PROCEDURE movImmI (t: T; READONLY dest: Operand; imm: INTEGER) =
VAR immT: Target.Int;
BEGIN
! IF NOT TInt.FromInt(imm, BYTESIZE(imm), immT) THEN
t.Err("movImmI: unable to convert INTEGER to Target.Int");
END;
t.movImmT(dest, immT);
--- 942,948 ----
PROCEDURE movImmI (t: T; READONLY dest: Operand; imm: INTEGER) =
VAR immT: Target.Int;
BEGIN
! IF NOT TInt.FromInt(imm, immT) THEN
t.Err("movImmI: unable to convert INTEGER to Target.Int");
END;
t.movImmT(dest, immT);
***************
*** 942,954 ****
PROCEDURE pushOp1 (t: T; READONLY src: Operand) =
VAR ins: Instruction;
BEGIN
Mn(t, "PUSH"); MnOp(t, src);
CASE src.loc OF
| OLoc.imm =>
ins.opcode := 16_68;
! IF (NOT TInt.ToInt(src.imm, ins.imm)) AND (NOT TWord.LE(src.imm, Target.Word32.max)) THEN
! t.Err("pushOp: unable to convert immediate to INTEGER:" & Target.TargetIntToDiagnosticText(src.imm));
END;
ins.imsize := 4;
writecode(t, ins);
--- 950,966 ----
PROCEDURE pushOp1 (t: T; READONLY src: Operand) =
VAR ins: Instruction;
+ buf: ARRAY [0..BITSIZE(Target.Int)] OF CHAR;
BEGIN
Mn(t, "PUSH"); MnOp(t, src);
CASE src.loc OF
| OLoc.imm =>
ins.opcode := 16_68;
! IF (NOT TInt.ToInt(src.imm, ins.imm))
! AND (NOT TWord.LE(src.imm, Target.Word32.max))
! THEN
! t.Err("pushOp: unable to convert immediate to INTEGER: " &
! Text.FromChars (SUBARRAY(buf, 0, TInt.ToChars(src.imm, buf))));
END;
ins.imsize := 4;
writecode(t, ins);
***************
*** 1073,1079 ****
unOp1(t, op, destA[1]);
| Op.oNEG =>
unOp1(t, op, destA[0]);
! t.binOp(Op.oADC, destA[1], Operand {loc := OLoc.imm, imm := TZero, optype := Type.Word32});
unOp1(t, op, destA[1]);
ELSE
<* ASSERT FALSE *>
--- 1085,1091 ----
unOp1(t, op, destA[1]);
| Op.oNEG =>
unOp1(t, op, destA[0]);
! t.binOp(Op.oADC, destA[1], Operand {loc := OLoc.imm, imm := TInt.Zero, optype := Type.Word32});
unOp1(t, op, destA[1]);
ELSE
<* ASSERT FALSE *>
***************
*** 1104,1109 ****
--- 1116,1122 ----
PROCEDURE imulOp (t: T; READONLY dest, src: Operand) =
VAR ins: Instruction;
+ buf: ARRAY [0..BITSIZE(Target.Int)] OF CHAR;
BEGIN
<* ASSERT dest.loc = OLoc.register *>
<* ASSERT src.loc # OLoc.mem OR CG_Bytes[src.mvar.mvar_type] = 4 *>
***************
*** 1111,1118 ****
IF src.loc = OLoc.imm THEN
build_modrm(t, t.reg[dest.reg[0]], dest, ins);
ins.opcode := 16_69;
! IF (NOT TInt.ToInt(src.imm, ins.imm)) AND (NOT TWord.LE(src.imm, Target.Word32.max)) THEN
! t.Err("imulOp: unable to convert immediate to INTEGER:" & Target.TargetIntToDiagnosticText(src.imm));
END;
ins.imsize := 4;
writecode(t, ins);
--- 1124,1134 ----
IF src.loc = OLoc.imm THEN
build_modrm(t, t.reg[dest.reg[0]], dest, ins);
ins.opcode := 16_69;
! IF (NOT TInt.ToInt(src.imm, ins.imm))
! AND (NOT TWord.LE(src.imm, Target.Word32.max))
! THEN
! t.Err("imulOp: unable to convert immediate to INTEGER: " &
! Text.FromChars (SUBARRAY(buf, 0, TInt.ToChars(src.imm, buf))));
END;
ins.imsize := 4;
writecode(t, ins);
***************
*** 1195,1201 ****
set_label(t, diffsignlab); (* .diffsignlab *)
noargOp(t, Op.oCDQ); (* CDQ *)
idivOp(t, divisor); (* IDIV EAX, divisor *)
! immOp(t, Op.oCMP, t.reg[EDX], TZero); (* CMP EDX, #0 *)
brOp(t, Cond.E, endlab); (* JE endlab *)
decOp(t, t.reg[EAX]); (* DEC EAX *)
set_label(t, endlab); (* .endlab *)
--- 1211,1217 ----
set_label(t, diffsignlab); (* .diffsignlab *)
noargOp(t, Op.oCDQ); (* CDQ *)
idivOp(t, divisor); (* IDIV EAX, divisor *)
! immOp(t, Op.oCMP, t.reg[EDX], TInt.Zero); (* CMP EDX, #0 *)
brOp(t, Cond.E, endlab); (* JE endlab *)
decOp(t, t.reg[EAX]); (* DEC EAX *)
set_label(t, endlab); (* .endlab *)
***************
*** 1221,1227 ****
set_label(t, diffsignlab); (* .diffsignlab *)
noargOp(t, Op.oCDQ); (* CDQ *)
idivOp(t, divisor); (* IDIV EAX, divisor *)
! immOp(t, Op.oCMP, t.reg[EDX], TZero); (* CMP EDX, #0 *)
brOp(t, Cond.E, endlab); (* JE endlab *)
binOp(t, Op.oADD, t.reg[EDX], divisor); (* ADD EDX, divisor *)
set_label(t, endlab); (* .endlab *)
--- 1237,1243 ----
set_label(t, diffsignlab); (* .diffsignlab *)
noargOp(t, Op.oCDQ); (* CDQ *)
idivOp(t, divisor); (* IDIV EAX, divisor *)
! immOp(t, Op.oCMP, t.reg[EDX], TInt.Zero); (* CMP EDX, #0 *)
brOp(t, Cond.E, endlab); (* JE endlab *)
binOp(t, Op.oADD, t.reg[EDX], divisor); (* ADD EDX, divisor *)
set_label(t, endlab); (* .endlab *)
***************
*** 1479,1492 ****
PROCEDURE store_ind1 (t: T; READONLY val, ind: Operand; offset: ByteOffset; type: MType) =
VAR ins: Instruction;
BEGIN
<* ASSERT ind.loc = OLoc.register AND val.loc # OLoc.mem *>
ins.opcode := 16_88;
IF val.loc = OLoc.imm THEN
ins.opcode := 16_C6;
! IF (NOT TInt.ToInt(val.imm, ins.imm)) AND (NOT TWord.LE(val.imm, Target.Word32.max)) THEN
! t.Err("store_ind1: unable to convert immediate to INTEGER:" & Target.TargetIntToDiagnosticText(val.imm));
END;
ins.imsize := CG_Bytes[type];
END;
--- 1495,1512 ----
PROCEDURE store_ind1 (t: T; READONLY val, ind: Operand; offset: ByteOffset; type: MType) =
VAR ins: Instruction;
+ buf: ARRAY [0..BITSIZE(Target.Int)] OF CHAR;
BEGIN
<* ASSERT ind.loc = OLoc.register AND val.loc # OLoc.mem *>
ins.opcode := 16_88;
IF val.loc = OLoc.imm THEN
ins.opcode := 16_C6;
! IF (NOT TInt.ToInt(val.imm, ins.imm))
! AND (NOT TWord.LE(val.imm, Target.Word32.max))
! THEN
! t.Err("store_ind1: unable to convert immediate to INTEGER: " &
! Text.FromChars (SUBARRAY(buf, 0, TInt.ToChars(val.imm, buf))));
END;
ins.imsize := CG_Bytes[type];
END;
***************
*** 2324,2330 ****
WHILE f_lit # NIL DO
FOR i := 0 TO f_lit.flit_size - 1 DO
! EVAL TInt.FromInt(f_lit.arr[i], Target.Integer.bytes, tint);
t.parent.init_int(f_lit.loc + i, tint, Type.Word8);
END;
--- 2344,2350 ----
WHILE f_lit # NIL DO
FOR i := 0 TO f_lit.flit_size - 1 DO
! EVAL TInt.FromInt(f_lit.arr[i], tint);
t.parent.init_int(f_lit.loc + i, tint, Type.Word8);
END;
***************
*** 2332,2338 ****
END;
WHILE abscall # NIL DO
! t.parent.init_int(abscall.loc, TZero, Type.Int32);
t.obj.relocate(intvar.symbol, abscall.loc, abscall.sym);
abscall := abscall.link;
END;
--- 2352,2358 ----
END;
WHILE abscall # NIL DO
! t.parent.init_int(abscall.loc, TInt.Zero, Type.Int32);
t.obj.relocate(intvar.symbol, abscall.loc, abscall.sym);
abscall := abscall.link;
END;
Index: m3back/src/M3x86.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3back/src/M3x86.m3,v
retrieving revision 1.126
diff -c -r1.126 M3x86.m3
*** m3back/src/M3x86.m3 15 Feb 2010 17:58:21 -0000 1.126
--- m3back/src/M3x86.m3 18 Feb 2010 02:30:50 -0000
***************
*** 1105,1117 ****
pad_init(u, o);
len := TInt.ToBytes(value, bytes);
- IF NOT (len <= NUMBER(bytes) AND len <= CG_Bytes[t] AND len > 0) THEN
- u.Err("init_int: len:" & Fmt.Int(len) & " type:" & Target.TypeNames[t] & " value:" & Target.TargetIntToDiagnosticText(value));
- END;
<* ASSERT len > 0 *>
<* ASSERT len <= NUMBER(bytes) *>
<* ASSERT len <= CG_Bytes[t] *>
! IF TInt.LT(value, TZero) THEN
FOR i := len TO CG_Bytes[t] - 1 DO
bytes[i] := 16_FF;
END;
--- 1105,1114 ----
pad_init(u, o);
len := TInt.ToBytes(value, bytes);
<* ASSERT len > 0 *>
<* ASSERT len <= NUMBER(bytes) *>
<* ASSERT len <= CG_Bytes[t] *>
! IF TInt.LT(value, TInt.Zero) THEN
FOR i := len TO CG_Bytes[t] - 1 DO
bytes[i] := 16_FF;
END;
***************
*** 1506,1512 ****
u.wr.NL ();
END;
! u.vstack.doimm (Op.oCMP, TZero, FALSE);
u.cg.brOp (Cond.NZ, label);
END if_true;
--- 1503,1509 ----
u.wr.NL ();
END;
! u.vstack.doimm (Op.oCMP, TInt.Zero, FALSE);
u.cg.brOp (Cond.NZ, label);
END if_true;
***************
*** 1520,1526 ****
u.wr.NL ();
END;
! u.vstack.doimm (Op.oCMP, TZero, FALSE);
u.cg.brOp (Cond.Z, label);
END if_false;
--- 1517,1523 ----
u.wr.NL ();
END;
! u.vstack.doimm (Op.oCMP, TInt.Zero, FALSE);
u.cg.brOp (Cond.Z, label);
END if_false;
***************
*** 1802,1808 ****
END;
u.vstack.unlock();
! u.vstack.pushimmT(TZero, Type.Addr);
END load_nil;
PROCEDURE load_integer (u: U; t: IType; READONLY i: Target.Int) =
--- 1799,1805 ----
END;
u.vstack.unlock();
! u.vstack.pushimmT(TInt.Zero, Type.Addr);
END load_nil;
PROCEDURE load_integer (u: U; t: IType; READONLY i: Target.Int) =
***************
*** 2166,2172 ****
pop_param(u, Type.Addr);
pop_param(u, Type.Addr);
call_int_proc (u, proc);
! u.vstack.pushimmT(TZero, Type.Word32);
condset(u, CompareOpCond [op], t);
ELSE
proc := CompareOpProc [op];
--- 2163,2169 ----
pop_param(u, Type.Addr);
pop_param(u, Type.Addr);
call_int_proc (u, proc);
! u.vstack.pushimmT(TInt.Zero, Type.Word32);
condset(u, CompareOpCond [op], t);
ELSE
proc := CompareOpProc [op];
***************
*** 2323,2336 ****
TWord.And(u.vstack.op(stack0).imm, MaximumShift[t], and);
u.vstack.set_imm(stack0, and);
! IF TInt.NE(u.vstack.op(stack0).imm, TZero) THEN
u.vstack.find(stack1, Force.anytemp);
u.cg.immOp(Op.oSHL, u.vstack.op(stack1), u.vstack.op(stack0).imm);
u.vstack.newdest(u.vstack.op(stack1));
END
END
ELSE
! IF (u.vstack.loc(stack1) # OLoc.imm) OR TInt.NE(u.vstack.op(stack1).imm, TZero) THEN
(* shift non-constant *)
--- 2320,2333 ----
TWord.And(u.vstack.op(stack0).imm, MaximumShift[t], and);
u.vstack.set_imm(stack0, and);
! IF NOT TInt.EQ(u.vstack.op(stack0).imm, TInt.Zero) THEN
u.vstack.find(stack1, Force.anytemp);
u.cg.immOp(Op.oSHL, u.vstack.op(stack1), u.vstack.op(stack0).imm);
u.vstack.newdest(u.vstack.op(stack1));
END
END
ELSE
! IF (u.vstack.loc(stack1) # OLoc.imm) OR NOT TInt.EQ(u.vstack.op(stack1).imm, TInt.Zero) THEN
(* shift non-constant *)
***************
*** 2385,2391 ****
TWord.And(u.vstack.op(stack0).imm, MaximumShift[t], and);
u.vstack.set_imm(stack0, and);
! IF TInt.NE(u.vstack.op(stack0).imm, TZero) THEN
u.vstack.find(stack1, Force.anytemp);
u.cg.immOp(Op.oSHR, u.vstack.op(stack1), u.vstack.op(stack0).imm);
u.vstack.newdest(u.vstack.op(stack1));
--- 2382,2388 ----
TWord.And(u.vstack.op(stack0).imm, MaximumShift[t], and);
u.vstack.set_imm(stack0, and);
! IF NOT TInt.EQ(u.vstack.op(stack0).imm, TInt.Zero) THEN
u.vstack.find(stack1, Force.anytemp);
u.cg.immOp(Op.oSHR, u.vstack.op(stack1), u.vstack.op(stack0).imm);
u.vstack.newdest(u.vstack.op(stack1));
***************
*** 2395,2401 ****
(* shift a non-constant or non-zero *)
! IF ((u.vstack.loc(stack1) # OLoc.imm) OR (TInt.NE(u.vstack.op(stack1).imm, TZero))) THEN
IF Is64(t) THEN
do_custom_calling_convention_shift_64 (u, Builtin.shift_right_64);
RETURN;
--- 2392,2398 ----
(* shift a non-constant or non-zero *)
! IF ((u.vstack.loc(stack1) # OLoc.imm) OR (NOT TInt.EQ(u.vstack.op(stack1).imm, TInt.Zero))) THEN
IF Is64(t) THEN
do_custom_calling_convention_shift_64 (u, Builtin.shift_right_64);
RETURN;
***************
*** 2452,2458 ****
IF NOT TInt.ToInt(u.vstack.op(stack0).imm, rotateCount) THEN
u.Err("unable to convert rotate count to host integer");
END;
! TWord.Rotate(u.vstack.op(stack1).imm, rotateCount, rotate);
u.vstack.set_imm(stack1, rotate);
ELSE
TWord.And(u.vstack.op(stack0).imm, MaximumShift[t], and);
--- 2449,2456 ----
IF NOT TInt.ToInt(u.vstack.op(stack0).imm, rotateCount) THEN
u.Err("unable to convert rotate count to host integer");
END;
! TWord.Rotate(u.vstack.op(stack1).imm, rotateCount,
! Target.Integer.bytes, rotate);
u.vstack.set_imm(stack1, rotate);
ELSE
TWord.And(u.vstack.op(stack0).imm, MaximumShift[t], and);
***************
*** 2505,2511 ****
IF NOT TInt.ToInt(u.vstack.op(stack0).imm, rotateCount) THEN
u.Err("unable to convert rotate count to host integer");
END;
! TWord.Rotate(u.vstack.op(stack1).imm, -rotateCount, rotate);
u.vstack.set_imm(stack1, rotate);
ELSE
TWord.And(u.vstack.op(stack0).imm, MaximumShift[t], and);
--- 2503,2510 ----
IF NOT TInt.ToInt(u.vstack.op(stack0).imm, rotateCount) THEN
u.Err("unable to convert rotate count to host integer");
END;
! TWord.Rotate(u.vstack.op(stack1).imm, -rotateCount,
! Target.Integer.bytes, rotate);
u.vstack.set_imm(stack1, rotate);
ELSE
TWord.And(u.vstack.op(stack0).imm, MaximumShift[t], and);
***************
*** 2749,2757 ****
u.vstack.unlock();
CASE CG_Bytes[t] OF
! 2 => shift := TInt.One;
! | 4 => shift := TInt.Two;
! | 8 => shift := TInt.Three;
ELSE
u.Err("Unknown MType size in copy_n");
END;
--- 2748,2756 ----
u.vstack.unlock();
CASE CG_Bytes[t] OF
! 2 => shift := Target.Int{1,0,..};
! | 4 => shift := Target.Int{2,0,..};
! | 8 => shift := Target.Int{3,0,..};
ELSE
u.Err("Unknown MType size in copy_n");
END;
***************
*** 2806,2815 ****
IF forward THEN
u.cg.noargOp(Op.oCLD);
ELSE
! IF NOT TInt.FromInt(n, Target.Integer.bytes, tn) THEN
u.Err("string_copy: unable to convert n to target int");
END;
! IF NOT TInt.FromInt(size, Target.Integer.bytes, tsize) THEN
u.Err("string_copy: unable to convert size to target int");
END;
IF NOT TInt.Subtract(tn, TInt.One, tNMinus1) THEN
--- 2805,2814 ----
IF forward THEN
u.cg.noargOp(Op.oCLD);
ELSE
! IF NOT TInt.FromInt(n, tn) THEN
u.Err("string_copy: unable to convert n to target int");
END;
! IF NOT TInt.FromInt(size, tsize) THEN
u.Err("string_copy: unable to convert size to target int");
END;
IF NOT TInt.Subtract(tn, TInt.One, tNMinus1) THEN
***************
*** 2940,2948 ****
u.vstack.find(stack0, Force.anyreg);
CASE CG_Bytes[t] OF
! 2 => shift := TInt.One;
! | 4 => shift := TInt.Two;
! | 8 => shift := TInt.Three;
ELSE
u.Err("Unknown MType size in zero_n");
END;
--- 2939,2947 ----
u.vstack.find(stack0, Force.anyreg);
CASE CG_Bytes[t] OF
! 2 => shift := Target.Int{1,0,..};
! | 4 => shift := Target.Int{2,0,..};
! | 8 => shift := Target.Int{3,0,..};
ELSE
u.Err("Unknown MType size in zero_n");
END;
***************
*** 2953,2959 ****
start_int_proc (u, Builtin.memset);
pop_param (u, z);
! u.vstack.pushimmT (TZero, Type.Word32);
pop_param (u, Type.Word32);
pop_param (u, Type.Addr);
call_int_proc (u, Builtin.memset);
--- 2952,2958 ----
start_int_proc (u, Builtin.memset);
pop_param (u, z);
! u.vstack.pushimmT (TInt.Zero, Type.Word32);
pop_param (u, Type.Word32);
pop_param (u, Type.Addr);
call_int_proc (u, Builtin.memset);
***************
*** 3013,3019 ****
stop0 = u.vstack.op(stack0) DO
u.vstack.find(stack0, Force.anyreg, RegSet {}, TRUE);
FOR i := 0 TO n - 1 DO
! u.cg.store_ind(Operand { loc := OLoc.imm, imm := TZero, optype := t },
stop0, i * size, faketype[size]);
END
END
--- 3012,3018 ----
stop0 = u.vstack.op(stack0) DO
u.vstack.find(stack0, Force.anyreg, RegSet {}, TRUE);
FOR i := 0 TO n - 1 DO
! u.cg.store_ind(Operand { loc := OLoc.imm, imm := TInt.Zero, optype := t },
stop0, i * size, faketype[size]);
END
END
***************
*** 3155,3168 ****
u.vstack.unlock();
WITH stack0 = u.vstack.pos(0, "check_nil") DO
IF u.vstack.loc(stack0) = OLoc.imm THEN
! IF TInt.EQ(u.vstack.op(stack0).imm, TZero) THEN
reportfault(u, code);
END
ELSE
u.vstack.find(stack0, Force.anyreg, RegSet {}, TRUE);
IF NOT u.vstack.non_nil(u.vstack.reg(stack0)) THEN
! u.cg.immOp(Op.oCMP, u.vstack.op(stack0), TZero);
safelab := u.cg.reserve_labels(1, TRUE);
u.cg.brOp(Cond.NE, safelab);
reportfault(u, code);
--- 3154,3167 ----
u.vstack.unlock();
WITH stack0 = u.vstack.pos(0, "check_nil") DO
IF u.vstack.loc(stack0) = OLoc.imm THEN
! IF TInt.EQ(u.vstack.op(stack0).imm, TInt.Zero) THEN
reportfault(u, code);
END
ELSE
u.vstack.find(stack0, Force.anyreg, RegSet {}, TRUE);
IF NOT u.vstack.non_nil(u.vstack.reg(stack0)) THEN
! u.cg.immOp(Op.oCMP, u.vstack.op(stack0), TInt.Zero);
safelab := u.cg.reserve_labels(1, TRUE);
u.cg.brOp(Cond.NE, safelab);
reportfault(u, code);
***************
*** 3194,3200 ****
END
ELSE
u.vstack.find(stack0, Force.anyreg);
! IF TInt.GE(u.vstack.lower(u.vstack.reg(stack0)), i) THEN
(* ok *)
ELSIF TInt.LT(u.vstack.upper(u.vstack.reg(stack0)), i) THEN
reportfault(u, code);
--- 3193,3199 ----
END
ELSE
u.vstack.find(stack0, Force.anyreg);
! IF TInt.LE(i, u.vstack.lower(u.vstack.reg(stack0))) THEN
(* ok *)
ELSIF TInt.LT(u.vstack.upper(u.vstack.reg(stack0)), i) THEN
reportfault(u, code);
***************
*** 3232,3238 ****
u.vstack.find(stack0, Force.anyreg);
IF TInt.LE(u.vstack.upper(u.vstack.reg(stack0)), i) THEN
(* ok *)
! ELSIF TInt.GT(u.vstack.lower(u.vstack.reg(stack0)), i) THEN
reportfault(u, code);
ELSE
u.cg.immOp(Op.oCMP, u.vstack.op(stack0), i);
--- 3231,3237 ----
u.vstack.find(stack0, Force.anyreg);
IF TInt.LE(u.vstack.upper(u.vstack.reg(stack0)), i) THEN
(* ok *)
! ELSIF TInt.LT(i, u.vstack.lower(u.vstack.reg(stack0))) THEN
reportfault(u, code);
ELSE
u.cg.immOp(Op.oCMP, u.vstack.op(stack0), i);
***************
*** 3279,3287 ****
reportfault(u, code);
ELSIF TInt.LE(hi, b) THEN
check_lo(u, t, a, code);
! ELSIF TInt.GE(lo, a) THEN
check_hi(u, t, b, code);
! ELSIF TInt.EQ(a, TZero) THEN
(* 0 <= x <= b ==> UNSIGNED(x) <= b *)
safelab := u.cg.reserve_labels(1, TRUE);
u.cg.immOp(Op.oCMP, u.vstack.op(stack0), b);
--- 3278,3286 ----
reportfault(u, code);
ELSIF TInt.LE(hi, b) THEN
check_lo(u, t, a, code);
! ELSIF TInt.LE(a, lo) THEN
check_hi(u, t, b, code);
! ELSIF TInt.EQ(a, TInt.Zero) THEN
(* 0 <= x <= b ==> UNSIGNED(x) <= b *)
safelab := u.cg.reserve_labels(1, TRUE);
u.cg.immOp(Op.oCMP, u.vstack.op(stack0), b);
***************
*** 3457,3463 ****
u.wr.NL ();
END;
! IF NOT TInt.FromInt(i, Target.Integer.bytes, ti) THEN
u.Err("add_offset: failed to convert i to target integer");
END;
--- 3456,3462 ----
u.wr.NL ();
END;
! IF NOT TInt.FromInt(i, ti) THEN
u.Err("add_offset: failed to convert i to target integer");
END;
***************
*** 3642,3650 ****
IF Target.FloatType [t] THEN
<* ASSERT depth = 0 *>
IF t = Type.Reel THEN
! u.cg.immOp(Op.oSUB, u.cg.reg[ESP], TInt.Four);
ELSE
! u.cg.immOp(Op.oSUB, u.cg.reg[ESP], TInt.Eight);
END;
u.cg.f_storeind(u.cg.reg[ESP], 0, t);
ELSE
--- 3641,3649 ----
IF Target.FloatType [t] THEN
<* ASSERT depth = 0 *>
IF t = Type.Reel THEN
! u.cg.immOp(Op.oSUB, u.cg.reg[ESP], Target.Int{4,0,..});
ELSE
! u.cg.immOp(Op.oSUB, u.cg.reg[ESP], Target.Int{8,0,..});
END;
u.cg.f_storeind(u.cg.reg[ESP], 0, t);
ELSE
***************
*** 3694,3706 ****
WITH stack0 = u.vstack.pos(0, "pop_struct") DO
! IF NOT TInt.FromInt(s, Target.Integer.bytes, ts) THEN
u.Err("pop_struct: unable to convert s to target int");
END;
(* if the struct is "large", use rep mov to copy it to the machine stack *)
! IF TInt.GT(ts, TInt.ThirtyTwo) THEN
u.cg.immOp(Op.oSUB, u.cg.reg[ESP], ts);
u.vstack.find(stack0, Force.regset, RegSet { ESI });
--- 3693,3705 ----
WITH stack0 = u.vstack.pos(0, "pop_struct") DO
! IF NOT TInt.FromInt(s, ts) THEN
u.Err("pop_struct: unable to convert s to target int");
END;
(* if the struct is "large", use rep mov to copy it to the machine stack *)
! IF TInt.LT(Target.Int{32,0,..}, ts) THEN
u.cg.immOp(Op.oSUB, u.cg.reg[ESP], ts);
u.vstack.find(stack0, Force.regset, RegSet { ESI });
***************
*** 3880,3886 ****
IF (NOT realproc.stdcall) (* => caller cleans *)
AND u.call_param_size[u.in_proc_call - 1] > 0 THEN
! IF NOT TInt.FromInt(u.call_param_size[u.in_proc_call - 1], Target.Integer.bytes, call_param_size) THEN
u.Err("call_direct: unable to convert param_size to target integer");
END;
u.cg.immOp(Op.oADD, u.cg.reg[ESP], call_param_size);
--- 3879,3885 ----
IF (NOT realproc.stdcall) (* => caller cleans *)
AND u.call_param_size[u.in_proc_call - 1] > 0 THEN
! IF NOT TInt.FromInt(u.call_param_size[u.in_proc_call - 1], call_param_size) THEN
u.Err("call_direct: unable to convert param_size to target integer");
END;
u.cg.immOp(Op.oADD, u.cg.reg[ESP], call_param_size);
***************
*** 3939,3945 ****
(* caller-cleans calling convention *)
! IF NOT TInt.FromInt(u.call_param_size[u.in_proc_call - 1], Target.Integer.bytes, call_param_size) THEN
u.Err("call_indirect: unable to convert param_size to target integer");
END;
--- 3938,3944 ----
(* caller-cleans calling convention *)
! IF NOT TInt.FromInt(u.call_param_size[u.in_proc_call - 1], call_param_size) THEN
u.Err("call_indirect: unable to convert param_size to target integer");
END;
***************
*** 4027,4033 ****
u.vstack.unlock();
IF realproc.lev = 0 THEN
! u.vstack.pushimmT(TZero, Type.Word32);
ELSE
u.vstack.pushnew(Type.Addr, Force.anyreg);
u.cg.get_frame(u.vstack.op(u.vstack.pos(0, "load_static_link")).reg[0],
--- 4026,4032 ----
u.vstack.unlock();
IF realproc.lev = 0 THEN
! u.vstack.pushimmT(TInt.Zero, Type.Word32);
ELSE
u.vstack.pushnew(Type.Addr, Force.anyreg);
u.cg.get_frame(u.vstack.op(u.vstack.pos(0, "load_static_link")).reg[0],
***************
*** 4047,4053 ****
IF realproc.lev = 0 THEN
u.vstack.corrupt(ECX, operandPart := 0);
! u.cg.movImmT(u.cg.reg[ECX], TZero);
ELSE
u.vstack.unlock();
u.vstack.corrupt(ECX, operandPart := 0);
--- 4046,4052 ----
IF realproc.lev = 0 THEN
u.vstack.corrupt(ECX, operandPart := 0);
! u.cg.movImmT(u.cg.reg[ECX], TInt.Zero);
ELSE
u.vstack.unlock();
u.vstack.corrupt(ECX, operandPart := 0);
***************
*** 4060,4066 ****
PROCEDURE intregcmp (u: U; tozero: BOOLEAN; type: Type): BOOLEAN =
BEGIN
IF tozero THEN
! u.vstack.doimm(Op.oCMP, TZero, FALSE);
RETURN FALSE;
ELSE
RETURN u.vstack.dobin(Op.oCMP, TRUE, FALSE, type);
--- 4059,4065 ----
PROCEDURE intregcmp (u: U; tozero: BOOLEAN; type: Type): BOOLEAN =
BEGIN
IF tozero THEN
! u.vstack.doimm(Op.oCMP, TInt.Zero, FALSE);
RETURN FALSE;
ELSE
RETURN u.vstack.dobin(Op.oCMP, TRUE, FALSE, type);
Index: m3back/src/M3x86Rep.i3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3back/src/M3x86Rep.i3,v
retrieving revision 1.28
diff -c -r1.28 M3x86Rep.i3
*** m3back/src/M3x86Rep.i3 14 Feb 2010 08:35:08 -0000 1.28
--- m3back/src/M3x86Rep.i3 18 Feb 2010 02:30:50 -0000
***************
*** 146,161 ****
PROCEDURE GetOperandSize(READONLY op: Operand): OperandSize;
PROCEDURE GetTypeSize(type: Type): OperandSize;
! CONST TZero = TInt.Zero;
! CONST UnsignedType = ARRAY IType OF IType { Type.Word32, Type.Word32,
! Type.Word64, Type.Word64 };
! CONST MaximumShift = ARRAY IType OF Target.Int { TInt.ThirtyOne, TInt.ThirtyOne,
! TInt.SixtyThree, TInt.SixtyThree };
!
! CONST MinimumShift = ARRAY IType OF Target.Int { TInt.MThirtyOne, TInt.MThirtyOne,
! TInt.MSixtyThree, TInt.MSixtyThree };
CONST BitCountMask = MaximumShift;
--- 146,162 ----
PROCEDURE GetOperandSize(READONLY op: Operand): OperandSize;
PROCEDURE GetTypeSize(type: Type): OperandSize;
! CONST UnsignedType = ARRAY IType OF IType {
! Type.Word32, Type.Word32,
! Type.Word64, Type.Word64 };
! CONST MaximumShift = ARRAY IType OF Target.Int {
! Target.Int{31,0,..}, Target.Int{31,0,..},
! Target.Int{63,0,..}, Target.Int{63,0,..}};
! CONST MinimumShift = ARRAY IType OF Target.Int {
! Target.Int{31,0,..}, Target.Int{31,0,..},
! Target.Int{63,0,..}, Target.Int{63,0,..}};
CONST BitCountMask = MaximumShift;
Index: m3back/src/Stackx86.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3back/src/Stackx86.m3,v
retrieving revision 1.93
diff -c -r1.93 Stackx86.m3
*** m3back/src/Stackx86.m3 14 Feb 2010 13:23:42 -0000 1.93
--- m3back/src/Stackx86.m3 18 Feb 2010 02:30:51 -0000
***************
*** 16,22 ****
FROM M3CG IMPORT Type, MType, ZType, IType, Sign, Label, ByteOffset;
FROM M3CG_Ops IMPORT ErrorHandler;
! FROM M3x86Rep IMPORT Operand, MVar, Regno, OLoc, VLoc, NRegs, Force, Is64, OperandPart, RegName, OperandSize, TZero;
FROM M3x86Rep IMPORT RegistersForByteOperations, RegSet, FlToInt, x86Var, x86Proc, NoStore, SplitOperand, SplitMVar, GetTypeSize, GetOperandSize;
FROM M3x86Rep IMPORT IsInt, IsWord, EAX, ECX, EDX, EBX, ESI, EDI, UnsignedType, MaximumShift, MinimumShift, BitCountMask, IntType;
--- 16,22 ----
FROM M3CG IMPORT Type, MType, ZType, IType, Sign, Label, ByteOffset;
FROM M3CG_Ops IMPORT ErrorHandler;
! FROM M3x86Rep IMPORT Operand, MVar, Regno, OLoc, VLoc, NRegs, Force, Is64, OperandPart, RegName, OperandSize;
FROM M3x86Rep IMPORT RegistersForByteOperations, RegSet, FlToInt, x86Var, x86Proc, NoStore, SplitOperand, SplitMVar, GetTypeSize, GetOperandSize;
FROM M3x86Rep IMPORT IsInt, IsWord, EAX, ECX, EDX, EBX, ESI, EDI, UnsignedType, MaximumShift, MinimumShift, BitCountMask, IntType;
***************
*** 101,107 ****
Register = RECORD
stackp : INTEGER := -1;
last_store : MVar := NoStore;
! last_imm : Target.Int := TZero;
lowbound : Target.Int;
upbound : Target.Int;
imm : BOOLEAN := FALSE;
--- 101,107 ----
Register = RECORD
stackp : INTEGER := -1;
last_store : MVar := NoStore;
! last_imm : Target.Int := TInt.Zero;
lowbound : Target.Int;
upbound : Target.Int;
imm : BOOLEAN := FALSE;
***************
*** 780,786 ****
PROCEDURE pushimmI (t: T; immI: INTEGER; type: Type) =
VAR immT: Target.Int;
BEGIN
! IF NOT TInt.FromInt(immI, Target.Integer.bytes, immT) THEN
t.Err("pushimmI: unable to convert to target integer");
END;
t.pushimmT(immT, type);
--- 780,786 ----
PROCEDURE pushimmI (t: T; immI: INTEGER; type: Type) =
VAR immT: Target.Int;
BEGIN
! IF NOT TInt.FromInt(immI, immT) THEN
t.Err("pushimmI: unable to convert to target integer");
END;
t.pushimmT(immT, type);
***************
*** 974,983 ****
WITH stop0 = t.vstack[pos(t, 0, "doloadaddress")] DO
IF v.loc = VLoc.temp AND v.parent # t.current_proc THEN
t.cg.get_frame(stop0.reg[0], v.parent, t.current_proc);
! IF NOT TInt.FromInt(o, Target.Integer.bytes, to) THEN
t.Err("doloadaddress: unable to convert o");
END;
! IF NOT TInt.FromInt(v.offset, Target.Integer.bytes, tvoffset) THEN
t.Err("doloadaddress: unable to convert v.offset");
END;
IF NOT TInt.Add(to, tvoffset, ti) THEN
--- 974,983 ----
WITH stop0 = t.vstack[pos(t, 0, "doloadaddress")] DO
IF v.loc = VLoc.temp AND v.parent # t.current_proc THEN
t.cg.get_frame(stop0.reg[0], v.parent, t.current_proc);
! IF NOT TInt.FromInt(o, to) THEN
t.Err("doloadaddress: unable to convert o");
END;
! IF NOT TInt.FromInt(v.offset, tvoffset) THEN
t.Err("doloadaddress: unable to convert v.offset");
END;
IF NOT TInt.Add(to, tvoffset, ti) THEN
***************
*** 1234,1240 ****
IF (a = Sign.Positive AND b = Sign.Negative) OR
(a = Sign.Negative AND b = Sign.Positive) THEN
! t.cg.immOp(Op.oCMP, t.cg.reg[EDX], TZero);
neglabel := t.cg.reserve_labels(1, TRUE);
--- 1234,1240 ----
IF (a = Sign.Positive AND b = Sign.Negative) OR
(a = Sign.Negative AND b = Sign.Positive) THEN
! t.cg.immOp(Op.oCMP, t.cg.reg[EDX], TInt.Zero);
neglabel := t.cg.reserve_labels(1, TRUE);
***************
*** 1294,1300 ****
IF (a = Sign.Positive AND b = Sign.Negative) OR
(a = Sign.Negative AND b = Sign.Positive) THEN
! t.cg.immOp(Op.oCMP, t.cg.reg[EDX], TZero);
neglabel := t.cg.reserve_labels(1, TRUE);
--- 1294,1300 ----
IF (a = Sign.Positive AND b = Sign.Negative) OR
(a = Sign.Negative AND b = Sign.Positive) THEN
! t.cg.immOp(Op.oCMP, t.cg.reg[EDX], TInt.Zero);
neglabel := t.cg.reserve_labels(1, TRUE);
***************
*** 1323,1329 ****
IF (stop0.loc = OLoc.mem AND
((overwritesdest AND NOT stop0.mvar.var.stack_temp) OR
CG_Bytes[stop0.mvar.mvar_type] = 2 OR
! (CG_Bytes[stop0.mvar.mvar_type] = 1 AND (TInt.GT(imm, Target.Int8.max) OR TInt.LT(imm, Target.Int8.min)))))
OR stop0.loc = OLoc.imm THEN
find(t, stack0, Force.anyreg);
ELSE
--- 1323,1329 ----
IF (stop0.loc = OLoc.mem AND
((overwritesdest AND NOT stop0.mvar.var.stack_temp) OR
CG_Bytes[stop0.mvar.mvar_type] = 2 OR
! (CG_Bytes[stop0.mvar.mvar_type] = 1 AND (TInt.LT(Target.Int8.max, imm) OR TInt.LT(imm, Target.Int8.min)))))
OR stop0.loc = OLoc.imm THEN
find(t, stack0, Force.anyreg);
ELSE
***************
*** 1347,1353 ****
WITH stack0 = pos(t, 0, "doneg"),
stop0 = t.vstack[stack0] DO
IF stop0.loc = OLoc.imm THEN
! IF NOT TInt.Negate(stop0.imm, neg) THEN
t.Err("doneg: Negate overflowed");
END;
stop0.imm := neg;
--- 1347,1353 ----
WITH stack0 = pos(t, 0, "doneg"),
stop0 = t.vstack[stack0] DO
IF stop0.loc = OLoc.imm THEN
! IF NOT TInt.Subtract(TInt.Zero, stop0.imm, neg) THEN
t.Err("doneg: Negate overflowed");
END;
stop0.imm := neg;
***************
*** 1367,1380 ****
WITH stack0 = pos(t, 0, "doabs"),
stop0 = t.vstack[stack0] DO
IF stop0.loc = OLoc.imm THEN
! IF NOT TInt.Abs(stop0.imm, stop0.imm) THEN
! t.Err("doabs: Abs overflowed");
END;
ELSE
find(t, stack0, Force.anytemp);
IF (stop0.loc = OLoc.mem) OR (GetOperandSize(stop0) > 1) THEN
! t.cg.immOp(Op.oCMP, stop0, TZero);
lab := t.cg.reserve_labels(1, TRUE);
--- 1367,1382 ----
WITH stack0 = pos(t, 0, "doabs"),
stop0 = t.vstack[stack0] DO
IF stop0.loc = OLoc.imm THEN
! IF TInt.LT (stop0.imm, TInt.Zero) THEN
! IF NOT TInt.Subtract (TInt.Zero, stop0.imm, stop0.imm) THEN
! t.Err("doabs: Abs overflowed");
! END;
END;
ELSE
find(t, stack0, Force.anytemp);
IF (stop0.loc = OLoc.mem) OR (GetOperandSize(stop0) > 1) THEN
! t.cg.immOp(Op.oCMP, stop0, TInt.Zero);
lab := t.cg.reserve_labels(1, TRUE);
***************
*** 1426,1452 ****
(* shift non-constant by a constant *)
! IF TInt.NE(stop0.imm, TZero) THEN
(* shift non-constant by a non-zero constant *)
find(t, stack1, Force.anytemp);
! IF TInt.GT(stop0.imm, MaximumShift[type])
OR TInt.LT(stop0.imm, MinimumShift[type]) THEN
(* shifting "too far" just yields zero *)
t.cg.binOp(Op.oXOR, stop1, stop1);
! ELSIF TInt.GT(stop0.imm, TZero) THEN
(* positive shift is left shift *)
t.cg.immOp(Op.oSHL, stop1, stop0.imm);
ELSE
! IF NOT TInt.Negate(stop0.imm, tShiftCount) THEN
t.Err("doshift: Negate overflowed");
END;
--- 1428,1454 ----
(* shift non-constant by a constant *)
! IF NOT TInt.EQ(stop0.imm, TInt.Zero) THEN
(* shift non-constant by a non-zero constant *)
find(t, stack1, Force.anytemp);
! IF TInt.LT(MaximumShift[type], stop0.imm)
OR TInt.LT(stop0.imm, MinimumShift[type]) THEN
(* shifting "too far" just yields zero *)
t.cg.binOp(Op.oXOR, stop1, stop1);
! ELSIF TInt.LT(TInt.Zero, stop0.imm) THEN
(* positive shift is left shift *)
t.cg.immOp(Op.oSHL, stop1, stop0.imm);
ELSE
! IF NOT TInt.Subtract(TInt.Zero, stop0.imm, tShiftCount) THEN
t.Err("doshift: Negate overflowed");
END;
***************
*** 1461,1467 ****
END
ELSE
! IF ((stop1.loc # OLoc.imm) OR (TInt.NE(stop1.imm, TZero))) THEN
(* shift by a non-constant *)
--- 1463,1469 ----
END
ELSE
! IF ((stop1.loc # OLoc.imm) OR (NOT TInt.EQ(stop1.imm, TInt.Zero))) THEN
(* shift by a non-constant *)
***************
*** 1476,1482 ****
find(t, stack1, Force.anyreg);
END;
! t.cg.immOp(Op.oCMP, stop0, TZero);
leftlab := t.cg.reserve_labels(1, TRUE);
ovflshift := t.cg.reserve_labels(1, TRUE);
--- 1478,1484 ----
find(t, stack1, Force.anyreg);
END;
! t.cg.immOp(Op.oCMP, stop0, TInt.Zero);
leftlab := t.cg.reserve_labels(1, TRUE);
ovflshift := t.cg.reserve_labels(1, TRUE);
***************
*** 1484,1490 ****
t.cg.brOp(Cond.GE, leftlab);
t.cg.unOp(Op.oNEG, stop0);
! t.cg.immOp(Op.oCMP, stop0, TInt.ThirtyTwo);
t.cg.brOp(Cond.GE, ovflshift);
t.cg.unOp(Op.oSHR, stop1);
t.cg.brOp(Cond.Always, endlab);
--- 1486,1492 ----
t.cg.brOp(Cond.GE, leftlab);
t.cg.unOp(Op.oNEG, stop0);
! t.cg.immOp(Op.oCMP, stop0, Target.Int{32,0,..});
t.cg.brOp(Cond.GE, ovflshift);
t.cg.unOp(Op.oSHR, stop1);
t.cg.brOp(Cond.Always, endlab);
***************
*** 1494,1500 ****
t.cg.brOp(Cond.Always, endlab);
t.cg.set_label(leftlab);
(* .leftlab *)
! t.cg.immOp(Op.oCMP, stop0, TInt.ThirtyTwo);
t.cg.brOp(Cond.GE, ovflshift);
t.cg.unOp(Op.oSHL, stop1);
t.cg.set_label(endlab);
--- 1496,1502 ----
t.cg.brOp(Cond.Always, endlab);
t.cg.set_label(leftlab);
(* .leftlab *)
! t.cg.immOp(Op.oCMP, stop0, Target.Int{32,0,..});
t.cg.brOp(Cond.GE, ovflshift);
t.cg.unOp(Op.oSHL, stop1);
t.cg.set_label(endlab);
***************
*** 1528,1536 ****
IF NOT TInt.ToInt(stop0.imm, rotateCount) THEN
t.Err("dorotate: failed to convert rotateCount to host integer");
END;
! TWord.Rotate(stop1.imm, rotateCount, stop1.imm);
ELSE
! IF TInt.NE(stop0.imm, TZero) THEN
IF is64 THEN (* needs work *)
RETURN FALSE;
--- 1530,1539 ----
IF NOT TInt.ToInt(stop0.imm, rotateCount) THEN
t.Err("dorotate: failed to convert rotateCount to host integer");
END;
! TWord.Rotate(stop1.imm, rotateCount,
! Target.Integer.bytes, stop1.imm);
ELSE
! IF NOT TInt.EQ(stop0.imm, TInt.Zero) THEN
IF is64 THEN (* needs work *)
RETURN FALSE;
***************
*** 1538,1548 ****
find(t, stack1, Force.anytemp);
! IF TInt.GT(stop0.imm, TZero) THEN
TWord.And(stop0.imm, BitCountMask[type], stop0.imm);
t.cg.immOp(Op.oROL, stop1, stop0.imm);
ELSE
! IF NOT TInt.Negate(stop0.imm, stop0.imm) THEN
t.Err("dorotate: negate overflowed");
END;
TWord.And(stop0.imm, BitCountMask[type], stop0.imm);
--- 1541,1551 ----
find(t, stack1, Force.anytemp);
! IF TInt.LT(TInt.Zero, stop0.imm) THEN
TWord.And(stop0.imm, BitCountMask[type], stop0.imm);
t.cg.immOp(Op.oROL, stop1, stop0.imm);
ELSE
! IF NOT TInt.Subtract(TInt.Zero, stop0.imm, stop0.imm) THEN
t.Err("dorotate: negate overflowed");
END;
TWord.And(stop0.imm, BitCountMask[type], stop0.imm);
***************
*** 1554,1560 ****
END
ELSE
! IF ((stop0.loc # OLoc.imm) OR (TInt.NE(stop0.imm, TZero))) THEN
IF is64 THEN (* needs work *)
RETURN FALSE;
--- 1557,1563 ----
END
ELSE
! IF ((stop0.loc # OLoc.imm) OR (NOT TInt.EQ(stop0.imm, TInt.Zero))) THEN
IF is64 THEN (* needs work *)
RETURN FALSE;
***************
*** 1567,1573 ****
find(t, stack1, Force.anyreg);
END;
! t.cg.immOp(Op.oCMP, stop0, TZero);
leftlab := t.cg.reserve_labels(1, TRUE);
endlab := t.cg.reserve_labels(1, TRUE);
--- 1570,1576 ----
find(t, stack1, Force.anyreg);
END;
! t.cg.immOp(Op.oCMP, stop0, TInt.Zero);
leftlab := t.cg.reserve_labels(1, TRUE);
endlab := t.cg.reserve_labels(1, TRUE);
***************
*** 1705,1715 ****
find(t, stack0, Force.anyreg);
END;
! IF NOT TInt.FromInt(n, Target.Integer.bytes, tn) THEN
t.Err("doextract_n: failed to convert n to target integer");
END;
! IF NOT TInt.Subtract(TInt.ThirtyTwo, tn, t32MinusN) THEN
t.Err("doextract_n: Subtract overflowed");
END;
--- 1708,1718 ----
find(t, stack0, Force.anyreg);
END;
! IF NOT TInt.FromInt(n, tn) THEN
t.Err("doextract_n: failed to convert n to target integer");
END;
! IF NOT TInt.Subtract(Target.Int{32,0,..}, tn, t32MinusN) THEN
t.Err("doextract_n: Subtract overflowed");
END;
***************
*** 1759,1765 ****
IF sign THEN
TWord.Shift(TInt.One, n - 1, tint);
TWord.And(stop0.imm, tint, tint);
! IF TInt.NE(tint, TZero) THEN
TWord.Shift(Target.Word32.max, n, tint);
TWord.Or(stop0.imm, tint, stop0.imm);
END;
--- 1762,1768 ----
IF sign THEN
TWord.Shift(TInt.One, n - 1, tint);
TWord.And(stop0.imm, tint, tint);
! IF NOT TInt.EQ(tint, TInt.Zero) THEN
TWord.Shift(Target.Word32.max, n, tint);
TWord.Or(stop0.imm, tint, stop0.imm);
END;
***************
*** 1770,1783 ****
IF sign THEN
find(t, stack0, Force.anyreg);
IF (m + n) < 32 THEN
! IF NOT TInt.FromInt(32 - (m + n), Target.Integer.bytes, tint) THEN
t.Err("doextract_mn: failed to convert 32 - (m + n) to target integer");
END;
t.cg.immOp(Op.oSHL, stop0, tint);
END;
IF n < 32 THEN
! IF NOT TInt.FromInt(32 - n, Target.Integer.bytes, tint) THEN
t.Err("doextract_mn: failed to convert 32 - n to target integer");
END;
t.cg.immOp(Op.oSAR, stop0, tint);
--- 1773,1786 ----
IF sign THEN
find(t, stack0, Force.anyreg);
IF (m + n) < 32 THEN
! IF NOT TInt.FromInt(32 - (m + n), tint) THEN
t.Err("doextract_mn: failed to convert 32 - (m + n) to target integer");
END;
t.cg.immOp(Op.oSHL, stop0, tint);
END;
IF n < 32 THEN
! IF NOT TInt.FromInt(32 - n, tint) THEN
t.Err("doextract_mn: failed to convert 32 - n to target integer");
END;
t.cg.immOp(Op.oSAR, stop0, tint);
***************
*** 1790,1796 ****
END;
IF m > 0 THEN
! IF NOT TInt.FromInt(m, Target.Integer.bytes, tint) THEN
t.Err("doextract_mn: failed to m to target integer");
END;
t.cg.immOp(Op.oSHR, stop0, tint);
--- 1793,1799 ----
END;
IF m > 0 THEN
! IF NOT TInt.FromInt(m, tint) THEN
t.Err("doextract_mn: failed to m to target integer");
END;
t.cg.immOp(Op.oSHR, stop0, tint);
***************
*** 1858,1864 ****
t.cg.binOp(Op.oAND, stop2, t.cg.reg[maskreg]);
IF stop1.loc = OLoc.imm THEN
! IF TInt.NE(stop1.imm, TZero) THEN
t.cg.immOp(Op.oSHL, stop2, stop1.imm);
t.cg.immOp(Op.oADD, stop0, stop1.imm);
END
--- 1861,1867 ----
t.cg.binOp(Op.oAND, stop2, t.cg.reg[maskreg]);
IF stop1.loc = OLoc.imm THEN
! IF NOT TInt.EQ(stop1.imm, TInt.Zero) THEN
t.cg.immOp(Op.oSHL, stop2, stop1.imm);
t.cg.immOp(Op.oADD, stop0, stop1.imm);
END
***************
*** 1997,2003 ****
END;
IF m # 0 THEN
! IF NOT TInt.FromInt(m, Target.Integer.bytes, tint_m) THEN
t.Err("doinsert_mn: unable to convert m to target integer");
END;
t.cg.immOp(Op.oSHL, stop0, tint_m);
--- 2000,2006 ----
END;
IF m # 0 THEN
! IF NOT TInt.FromInt(m, tint_m) THEN
t.Err("doinsert_mn: unable to convert m to target integer");
END;
t.cg.immOp(Op.oSHL, stop0, tint_m);
***************
*** 2008,2014 ****
TWord.Shift(uint_type.max, m + n - uint_type.size, mask_m_n);
TWord.Xor(mask_m, mask_m_n, mask);
! IF TWord.NE(mask, uint_type.max) THEN
IF stop1.loc = OLoc.imm THEN
TWord.And(stop1.imm, mask, stop1.imm);
ELSE
--- 2011,2017 ----
TWord.Shift(uint_type.max, m + n - uint_type.size, mask_m_n);
TWord.Xor(mask_m, mask_m_n, mask);
! IF NOT TInt.EQ(mask, uint_type.max) THEN
IF stop1.loc = OLoc.imm THEN
TWord.And(stop1.imm, mask, stop1.imm);
ELSE
***************
*** 2021,2032 ****
TWord.Or(stop1.imm, stop0.imm, stop1.imm);
ELSE
swap(t);
! IF stop0.loc # OLoc.imm OR TInt.NE(stop0.imm, TZero) THEN
t.cg.binOp(Op.oOR, stop1, stop0);
END
END
ELSE
! IF stop0.loc # OLoc.imm OR TInt.NE(stop0.imm, TZero) THEN
t.cg.binOp(Op.oOR, stop1, stop0);
END
END;
--- 2024,2035 ----
TWord.Or(stop1.imm, stop0.imm, stop1.imm);
ELSE
swap(t);
! IF stop0.loc # OLoc.imm OR NOT TInt.EQ(stop0.imm, TInt.Zero) THEN
t.cg.binOp(Op.oOR, stop1, stop0);
END
END
ELSE
! IF stop0.loc # OLoc.imm OR NOT TInt.EQ(stop0.imm, TInt.Zero) THEN
t.cg.binOp(Op.oOR, stop1, stop0);
END
END;
***************
*** 2209,2215 ****
find(t, stack1, Force.anyreg, RegSet {}, TRUE);
IF stop0.loc = OLoc.imm THEN
! IF NOT TInt.FromInt(size, Target.Integer.bytes, tsize) THEN
t.Err("doindex_address: failed to convert size to target integer");
END;
IF NOT TInt.Multiply(stop0.imm, tsize, tint) THEN
--- 2212,2218 ----
find(t, stack1, Force.anyreg, RegSet {}, TRUE);
IF stop0.loc = OLoc.imm THEN
! IF NOT TInt.FromInt(size, tsize) THEN
t.Err("doindex_address: failed to convert size to target integer");
END;
IF NOT TInt.Multiply(stop0.imm, tsize, tint) THEN
***************
*** 2244,2250 ****
END
ELSIF shift > 0 THEN
! IF NOT TInt.FromInt(shift, Target.Integer.bytes, tshift) THEN
t.Err("doindex_address: failed to convert size to target integer");
END;
t.cg.immOp(Op.oSHL, stop0, tshift);
--- 2247,2253 ----
END
ELSIF shift > 0 THEN
! IF NOT TInt.FromInt(shift, tshift) THEN
t.Err("doindex_address: failed to convert size to target integer");
END;
t.cg.immOp(Op.oSHL, stop0, tshift);
***************
*** 2383,2391 ****
t.cg.memFOp(FOp.fSTCW, statusop.mvar);
t.cg.movOp(t.cg.reg[statreg], statusop);
! t.cg.immOp(Op.oAND, t.cg.reg[statreg], TInt.F3FF);
! IF TInt.NE(t.rmode[mode], TZero) THEN
t.cg.immOp(Op.oOR, t.cg.reg[statreg], t.rmode[mode]);
END;
--- 2386,2394 ----
t.cg.memFOp(FOp.fSTCW, statusop.mvar);
t.cg.movOp(t.cg.reg[statreg], statusop);
! t.cg.immOp(Op.oAND, t.cg.reg[statreg], Target.Int{16_FF,16_F3,0,..});
! IF NOT TInt.EQ(t.rmode[mode], TInt.Zero) THEN
t.cg.immOp(Op.oOR, t.cg.reg[statreg], t.rmode[mode]);
END;
***************
*** 2540,2546 ****
END;
t.rmode := ARRAY FlToInt OF Target.Int
! { TZero, TInt.x0400, TInt.x0800, TInt.x0F00 };
t.lowset_table := NIL;
t.highset_table := NIL;
END init;
--- 2543,2552 ----
END;
t.rmode := ARRAY FlToInt OF Target.Int
! { Target.Int{0,0,0,..},
! Target.Int{0,4,0,..},
! Target.Int{0,8,0,..},
! Target.Int{0,16_F,0,..}};
t.lowset_table := NIL;
t.highset_table := NIL;
END init;
***************
*** 2633,2639 ****
IF r.last_store # NoStore THEN
wr.OutT (" mvar: "); DebugMVar (r.last_store, wr);
END;
! IF (NOT TInt.EQ(r.last_imm, TZero)) THEN
wr.OutT (" imm: "); wr.OutT (TInt.ToText (r.last_imm));
END;
IF (NOT TInt.EQ(r.lowbound, Target.Integer.min)) THEN
--- 2639,2645 ----
IF r.last_store # NoStore THEN
wr.OutT (" mvar: "); DebugMVar (r.last_store, wr);
END;
! IF (NOT TInt.EQ(r.last_imm, TInt.Zero)) THEN
wr.OutT (" imm: "); wr.OutT (TInt.ToText (r.last_imm));
END;
IF (NOT TInt.EQ(r.lowbound, Target.Integer.min)) THEN
Index: m3back/src/Wrx86.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3back/src/Wrx86.m3,v
retrieving revision 1.6
diff -c -r1.6 Wrx86.m3
*** m3back/src/Wrx86.m3 15 Feb 2010 17:45:22 -0000 1.6
--- m3back/src/Wrx86.m3 18 Feb 2010 02:30:51 -0000
***************
*** 153,164 ****
PROCEDURE TInt (t: T; READONLY i: Target.Int) =
VAR
buf : ARRAY [0..BITSIZE (Target.Integer)] OF CHAR;
- len := TargetInt.ToChars (i, buf);
BEGIN
OutC (t, ' ');
! OutS (t, SUBARRAY (buf, 0, len));
! OutC (t, ' ');
! OutT (t, Target.TargetIntToDiagnosticText(i));
END TInt;
PROCEDURE BInt (t: T; i: INTEGER) =
--- 153,161 ----
PROCEDURE TInt (t: T; READONLY i: Target.Int) =
VAR
buf : ARRAY [0..BITSIZE (Target.Integer)] OF CHAR;
BEGIN
OutC (t, ' ');
! OutS (t, SUBARRAY (buf, 0, TargetInt.ToChars (i, buf)));
END TInt;
PROCEDURE BInt (t: T; i: INTEGER) =
Index: m3front/src/builtinAtomic/AtomicModule.mg
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinAtomic/AtomicModule.mg,v
retrieving revision 1.2
diff -c -r1.2 AtomicModule.mg
*** m3front/src/builtinAtomic/AtomicModule.mg 4 Feb 2010 02:11:30 -0000 1.2
--- m3front/src/builtinAtomic/AtomicModule.mg 18 Feb 2010 02:30:51 -0000
***************
*** 10,20 ****
Fence,
FetchInc, FetchDec, FetchOr, FetchXor, FetchAnd);
! IMPORT Scope, Tipe, Module, TInt;
IMPORT Field, M3ID, Value, RecordType;
IMPORT EnumType, EnumExpr, EnumElt;
PROCEDURE Initialize (name: TEXT) =
VAR zz, elts: Scope.T; rep: Field.Info; cs: Value.CheckState;
BEGIN
M := Module.NewDefn (name, TRUE, NIL);
--- 10,26 ----
Fence,
FetchInc, FetchDec, FetchOr, FetchXor, FetchAnd);
! IMPORT Scope, Tipe, Module, Target;
IMPORT Field, M3ID, Value, RecordType;
IMPORT EnumType, EnumExpr, EnumElt;
PROCEDURE Initialize (name: TEXT) =
+ CONST
+ Zero = Target.Int{0,0,..};
+ One = Target.Int{1,0,..};
+ Two = Target.Int{2,0,..};
+ Three = Target.Int{3,0,..};
+ Four = Target.Int{4,0,..};
VAR zz, elts: Scope.T; rep: Field.Info; cs: Value.CheckState;
BEGIN
M := Module.NewDefn (name, TRUE, NIL);
***************
*** 40,55 ****
elts := Scope.PushNew (FALSE, M3ID.NoID);
Order := EnumType.New (5, elts);
! Scope.Insert (EnumElt.New (M3ID.Add ("Relaxed"), TInt.Zero, Order));
! Scope.Insert (EnumElt.New (M3ID.Add ("Release"), TInt.One, Order));
! Scope.Insert (EnumElt.New (M3ID.Add ("Acquire"), TInt.Two, Order));
! Scope.Insert (EnumElt.New (M3ID.Add ("AcquireRelease"), TInt.Three, Order));
! Scope.Insert (EnumElt.New (M3ID.Add ("Sequential"), TInt.Four, Order));
Scope.PopNew ();
Scope.TypeCheck (elts, cs);
Tipe.Define ("Order", Order, FALSE);
! Sequential := EnumExpr.New (Order, TInt.Four);
IsLockFree.Initialize ();
Store.Initialize ();
--- 46,61 ----
elts := Scope.PushNew (FALSE, M3ID.NoID);
Order := EnumType.New (5, elts);
! Scope.Insert (EnumElt.New (M3ID.Add ("Relaxed"), Zero, Order));
! Scope.Insert (EnumElt.New (M3ID.Add ("Release"), One, Order));
! Scope.Insert (EnumElt.New (M3ID.Add ("Acquire"), Two, Order));
! Scope.Insert (EnumElt.New (M3ID.Add ("AcquireRelease"), Three, Order));
! Scope.Insert (EnumElt.New (M3ID.Add ("Sequential"), Four, Order));
Scope.PopNew ();
Scope.TypeCheck (elts, cs);
Tipe.Define ("Order", Order, FALSE);
! Sequential := EnumExpr.New (Order, Four);
IsLockFree.Initialize ();
Store.Initialize ();
Index: m3front/src/builtinInfo/InfoThisLine.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinInfo/InfoThisLine.m3,v
retrieving revision 1.4
diff -c -r1.4 InfoThisLine.m3
*** m3front/src/builtinInfo/InfoThisLine.m3 18 Sep 2007 20:25:21 -0000 1.4
--- m3front/src/builtinInfo/InfoThisLine.m3 18 Feb 2010 02:30:51 -0000
***************
*** 28,34 ****
BEGIN
Scanner.Here (file, line);
line := MAX (0, line);
! b := TInt.FromInt (line, Target.Integer.bytes, val); <*ASSERT b*>
RETURN IntegerExpr.New (Int.T, val);
END Fold;
--- 28,34 ----
BEGIN
Scanner.Here (file, line);
line := MAX (0, line);
! b := TInt.FromInt (line, val); <*ASSERT b*>
RETURN IntegerExpr.New (Int.T, val);
END Fold;
Index: m3front/src/builtinOps/BitSize.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinOps/BitSize.m3,v
retrieving revision 1.3
diff -c -r1.3 BitSize.m3
*** m3front/src/builtinOps/BitSize.m3 18 Sep 2007 20:25:35 -0000 1.3
--- m3front/src/builtinOps/BitSize.m3 18 Feb 2010 02:30:51 -0000
***************
*** 111,121 ****
IF (info.class = Type.Class.OpenArray) THEN RETURN NIL END;
END;
t := Type.CheckInfo (t, info);
! IF TInt.FromInt (info.size, Target.Integer.bytes, size)
! AND TInt.FromInt (unit, Target.Integer.bytes, a)
! AND TInt.FromInt (unit - 1, Target.Integer.bytes, b)
AND TInt.Add (size, b, c)
AND TInt.Div (c, a, d)
THEN RETURN IntegerExpr.New (Int.T, d);
ELSE RETURN NIL;
END;
--- 111,123 ----
IF (info.class = Type.Class.OpenArray) THEN RETURN NIL END;
END;
t := Type.CheckInfo (t, info);
! IF TInt.FromInt (info.size, size)
! AND TInt.FromInt (unit, a)
! AND TInt.FromInt (unit - 1, b)
AND TInt.Add (size, b, c)
AND TInt.Div (c, a, d)
+ AND NOT TInt.LT (d, Target.Integer.min)
+ AND NOT TInt.LT (Target.Integer.max, d)
THEN RETURN IntegerExpr.New (Int.T, d);
ELSE RETURN NIL;
END;
Index: m3front/src/builtinOps/Dec.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinOps/Dec.m3,v
retrieving revision 1.12
diff -c -r1.12 Dec.m3
*** m3front/src/builtinOps/Dec.m3 10 Jan 2010 10:46:35 -0000 1.12
--- m3front/src/builtinOps/Dec.m3 18 Feb 2010 02:30:51 -0000
***************
*** 71,77 ****
dec : Expr.T;
check : [0..3] := 0;
lvalue : CG.Val;
! bmin, bmax: Target.Int;
cg_type: CG.Type;
BEGIN
tlhs := Type.CheckInfo (tlhs, info);
--- 71,77 ----
dec : Expr.T;
check : [0..3] := 0;
lvalue : CG.Val;
! tmin, tmax, bmin, bmax: Target.Int;
cg_type: CG.Type;
BEGIN
tlhs := Type.CheckInfo (tlhs, info);
***************
*** 79,100 ****
THEN tlhs := LInt.T; cg_type := Target.Longint.cg_type;
ELSE tlhs := Int.T; cg_type := Target.Integer.cg_type;
END;
IF (NUMBER (ce.args^) > 1)
THEN dec := ce.args[1];
! ELSIF tlhs = LInt.T
! THEN dec := IntegerExpr.New (LInt.T, TInt.One); Expr.Prep (dec);
! ELSE dec := IntegerExpr.New (Int.T, TInt.One); Expr.Prep (dec);
END;
Expr.GetBounds (lhs, bmin, bmax);
IF Host.doRangeChk THEN
! IF tlhs = LInt.T THEN
! IF TInt.LT (Target.Longint.min, bmin) THEN INC (check) END;
! IF TInt.LT (bmax, Target.Longint.max) THEN INC (check, 2) END;
! ELSE
! IF TInt.LT (Target.Integer.min, bmin) THEN INC (check) END;
! IF TInt.LT (bmax, Target.Integer.max) THEN INC (check, 2) END;
! END;
END;
Expr.CompileLValue (lhs, traced := FALSE);
--- 79,94 ----
THEN tlhs := LInt.T; cg_type := Target.Longint.cg_type;
ELSE tlhs := Int.T; cg_type := Target.Integer.cg_type;
END;
+ EVAL Type.GetBounds (tlhs, tmin, tmax);
IF (NUMBER (ce.args^) > 1)
THEN dec := ce.args[1];
! ELSE dec := IntegerExpr.New (tlhs, TInt.One); Expr.Prep (dec);
END;
Expr.GetBounds (lhs, bmin, bmax);
IF Host.doRangeChk THEN
! IF TInt.LT (tmin, bmin) THEN INC (check) END;
! IF TInt.LT (bmax, tmax) THEN INC (check, 2) END;
END;
Expr.CompileLValue (lhs, traced := FALSE);
Index: m3front/src/builtinOps/Number.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinOps/Number.m3,v
retrieving revision 1.4
diff -c -r1.4 Number.m3
*** m3front/src/builtinOps/Number.m3 18 Sep 2007 20:25:36 -0000 1.4
--- m3front/src/builtinOps/Number.m3 18 Feb 2010 02:30:51 -0000
***************
*** 64,70 ****
e := ce.args[0];
t, index, element: Type.T;
min, max, tmp, num: Target.Int;
- One := Target.Int{Target.Integer.bytes, Target.IBytes{1,0,..}};
BEGIN
IF NOT TypeExpr.Split (e, t) THEN t := Expr.TypeOf (e) END;
IF ArrayType.Split (t, index, element) THEN t := index END;
--- 64,69 ----
***************
*** 77,83 ****
IF TInt.LT (max, min) THEN
CG.Load_integer (Target.Integer.cg_type, TInt.Zero);
ELSIF TInt.Subtract (max, min, tmp)
! AND TInt.Add (tmp, One, num) THEN
CG.Load_integer (Target.Integer.cg_type, num);
ELSE
Error.Warn (2, "result of NUMBER too large");
--- 76,83 ----
IF TInt.LT (max, min) THEN
CG.Load_integer (Target.Integer.cg_type, TInt.Zero);
ELSIF TInt.Subtract (max, min, tmp)
! AND TInt.Add (tmp, TInt.One, num)
! AND NOT TInt.LT (Target.Integer.max, num) THEN
CG.Load_integer (Target.Integer.cg_type, num);
ELSE
Error.Warn (2, "result of NUMBER too large");
***************
*** 90,96 ****
PROCEDURE Fold (ce: CallExpr.T): Expr.T =
VAR min, max, tmp, num: Target.Int; t, index, elem: Type.T; e: Expr.T;
- One := Target.Int{Target.Integer.bytes, Target.IBytes{1,0,..}};
BEGIN
e := ce.args[0];
IF NOT TypeExpr.Split (e, t) THEN
--- 90,95 ----
***************
*** 102,108 ****
IF (e = NIL) THEN RETURN NIL END;
IF ArrayExpr.GetBounds (e, min, max)
AND TInt.Subtract (max, min, tmp)
! AND TInt.Add (tmp, One, num)
THEN RETURN IntegerExpr.New (Int.T, num);
ELSE RETURN NIL;
END;
--- 101,109 ----
IF (e = NIL) THEN RETURN NIL END;
IF ArrayExpr.GetBounds (e, min, max)
AND TInt.Subtract (max, min, tmp)
! AND TInt.Add (tmp, TInt.One, num)
! AND NOT TInt.LT (num, Target.Integer.max)
! AND NOT TInt.LT (Target.Integer.max, num)
THEN RETURN IntegerExpr.New (Int.T, num);
ELSE RETURN NIL;
END;
***************
*** 114,120 ****
IF TInt.LT (max, min) THEN
RETURN IntegerExpr.New (Int.T, TInt.Zero);
ELSIF TInt.Subtract (max, min, tmp)
! AND TInt.Add (tmp, One, num) THEN
RETURN IntegerExpr.New (Int.T, num);
ELSE
RETURN NIL;
--- 115,122 ----
IF TInt.LT (max, min) THEN
RETURN IntegerExpr.New (Int.T, TInt.Zero);
ELSIF TInt.Subtract (max, min, tmp)
! AND TInt.Add (tmp, TInt.One, num)
! AND NOT TInt.LT (Target.Integer.max, num) THEN
RETURN IntegerExpr.New (Int.T, num);
ELSE
RETURN NIL;
Index: m3front/src/builtinWord/And.mg
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinWord/And.mg,v
retrieving revision 1.1
diff -c -r1.1 And.mg
*** m3front/src/builtinWord/And.mg 4 Feb 2010 20:00:45 -0000 1.1
--- m3front/src/builtinWord/And.mg 18 Feb 2010 02:30:51 -0000
***************
*** 7,17 ****
IMPORT CG, CallExpr, Expr, ExprRep, Procedure, Type, ProcType;
IMPORT IntegerExpr, Formal, Value, Target, TWord, TInt;
FROM Rep IMPORT T;
! FROM TargetMap IMPORT Integer_types;
VAR Z: CallExpr.MethodList;
VAR formals: Value.T;
! VAR rep: [FIRST (Integer_types) .. LAST (Integer_types)];
PROCEDURE Check (ce: CallExpr.T; VAR cs: Expr.CheckState) =
BEGIN
--- 7,17 ----
IMPORT CG, CallExpr, Expr, ExprRep, Procedure, Type, ProcType;
IMPORT IntegerExpr, Formal, Value, Target, TWord, TInt;
FROM Rep IMPORT T;
! FROM TargetMap IMPORT Word_types;
VAR Z: CallExpr.MethodList;
VAR formals: Value.T;
! VAR rep: [FIRST (Word_types) .. LAST (Word_types)];
PROCEDURE Check (ce: CallExpr.T; VAR cs: Expr.CheckState) =
BEGIN
***************
*** 23,29 ****
BEGIN
Expr.Compile (ce.args[0]);
Expr.Compile (ce.args[1]);
! CG.And (Integer_types[rep].cg_type);
END Compile;
PROCEDURE Fold (ce: CallExpr.T): Expr.T =
--- 23,29 ----
BEGIN
Expr.Compile (ce.args[0]);
Expr.Compile (ce.args[1]);
! CG.And (Word_types[rep].cg_type);
END Compile;
PROCEDURE Fold (ce: CallExpr.T): Expr.T =
***************
*** 31,36 ****
--- 31,37 ----
BEGIN
IF GetArgs (ce.args, w0, w1) THEN
TWord.And (w0, w1, result);
+ TInt.Chop (result, Word_types[rep].bytes);
RETURN IntegerExpr.New (T, result);
END;
RETURN NIL;
Index: m3front/src/builtinWord/Divide.mg
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinWord/Divide.mg,v
retrieving revision 1.1
diff -c -r1.1 Divide.mg
*** m3front/src/builtinWord/Divide.mg 4 Feb 2010 20:00:45 -0000 1.1
--- m3front/src/builtinWord/Divide.mg 18 Feb 2010 02:30:51 -0000
***************
*** 42,49 ****
BEGIN
e0 := Expr.ConstValue (args[0]);
e1 := Expr.ConstValue (args[1]);
! RETURN (e0 # NIL) AND IntegerExpr.Split (e0, w0, t) AND
! (e1 # NIL) AND IntegerExpr.Split (e1, w1, t);
END GetArgs;
PROCEDURE Initialize (r: INTEGER) =
--- 42,56 ----
BEGIN
e0 := Expr.ConstValue (args[0]);
e1 := Expr.ConstValue (args[1]);
! IF (e0 # NIL) AND IntegerExpr.Split (e0, w0, t)
! AND (e1 # NIL) AND IntegerExpr.Split (e1, w1, t)
! THEN
! TWord.And (w0, Word_types[rep].max, w0);
! TWord.And (w1, Word_types[rep].max, w1);
! RETURN TRUE;
! ELSE
! RETURN FALSE;
! END;
END GetArgs;
PROCEDURE Initialize (r: INTEGER) =
Index: m3front/src/builtinWord/Extract.mg
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinWord/Extract.mg,v
retrieving revision 1.1
diff -c -r1.1 Extract.mg
*** m3front/src/builtinWord/Extract.mg 4 Feb 2010 20:00:45 -0000 1.1
--- m3front/src/builtinWord/Extract.mg 18 Feb 2010 02:30:51 -0000
***************
*** 8,18 ****
IMPORT IntegerExpr, Type, ProcType, Host, Card;
IMPORT Target, TInt, TWord, Value, Formal, CheckExpr, Error;
FROM Rep IMPORT T;
! FROM TargetMap IMPORT Integer_types;
VAR Z: CallExpr.MethodList;
VAR formals: Value.T;
! VAR rep: [FIRST (Integer_types) .. LAST (Integer_types)];
PROCEDURE Check (ce: CallExpr.T; VAR cs: Expr.CheckState) =
BEGIN
--- 8,18 ----
IMPORT IntegerExpr, Type, ProcType, Host, Card;
IMPORT Target, TInt, TWord, Value, Formal, CheckExpr, Error;
FROM Rep IMPORT T;
! FROM TargetMap IMPORT Word_types;
VAR Z: CallExpr.MethodList;
VAR formals: Value.T;
! VAR rep: [FIRST (Word_types) .. LAST (Word_types)];
PROCEDURE Check (ce: CallExpr.T; VAR cs: Expr.CheckState) =
BEGIN
***************
*** 32,67 ****
IF x1 AND x2 THEN
(* we can use the extract_mn operator *)
! IF (i1 + i2 > Integer_types[rep].size) THEN
Error.Warn (2, "Word.Extract: i+n value out of range");
CG.Load_integer (Target.Integer.cg_type, TInt.One);
CG.Check_hi (Target.Integer.cg_type, TInt.Zero,
CG.RuntimeError.ValueOutOfRange);
ELSE
Expr.Compile (ce.args[0]);
! CG.Extract_mn (Integer_types[rep].cg_type, FALSE, i1, i2);
END;
ELSIF x2 THEN
(* we can use the extract_n operator *)
! b := TInt.FromInt (Integer_types[rep].size - i2, Target.Integer.bytes, max);
! <*ASSERT b*>
Expr.Compile (ce.args[0]);
CheckExpr.EmitChecks (ce.args[1], TInt.Zero, max,
CG.RuntimeError.ValueOutOfRange);
! CG.Extract_n (Integer_types[rep].cg_type, FALSE, i2);
ELSIF x1 THEN
(* we need the general purpose extract operator, but can simplify
the range checking code *)
! b := TInt.FromInt (Integer_types[rep].size - i1, Target.Integer.bytes, max);
! <*ASSERT b*>
Expr.Compile (ce.args[0]);
CG.Force ();
CG.Load_intt (i1);
CheckExpr.EmitChecks (ce.args[2], TInt.Zero, max,
CG.RuntimeError.ValueOutOfRange);
! CG.Extract (Integer_types[rep].cg_type, sign := FALSE);
ELSE
(* we need the general purpose extract operator *)
--- 32,65 ----
IF x1 AND x2 THEN
(* we can use the extract_mn operator *)
! IF (i1 + i2 > Word_types[rep].size) THEN
Error.Warn (2, "Word.Extract: i+n value out of range");
CG.Load_integer (Target.Integer.cg_type, TInt.One);
CG.Check_hi (Target.Integer.cg_type, TInt.Zero,
CG.RuntimeError.ValueOutOfRange);
ELSE
Expr.Compile (ce.args[0]);
! CG.Extract_mn (Word_types[rep].cg_type, FALSE, i1, i2);
END;
ELSIF x2 THEN
(* we can use the extract_n operator *)
! b := TInt.FromInt (Word_types[rep].size - i2, max); <*ASSERT b*>
Expr.Compile (ce.args[0]);
CheckExpr.EmitChecks (ce.args[1], TInt.Zero, max,
CG.RuntimeError.ValueOutOfRange);
! CG.Extract_n (Word_types[rep].cg_type, FALSE, i2);
ELSIF x1 THEN
(* we need the general purpose extract operator, but can simplify
the range checking code *)
! b := TInt.FromInt (Word_types[rep].size - i1, max); <*ASSERT b*>
Expr.Compile (ce.args[0]);
CG.Force ();
CG.Load_intt (i1);
CheckExpr.EmitChecks (ce.args[2], TInt.Zero, max,
CG.RuntimeError.ValueOutOfRange);
! CG.Extract (Word_types[rep].cg_type, sign := FALSE);
ELSE
(* we need the general purpose extract operator *)
***************
*** 72,79 ****
CG.RuntimeError.ValueOutOfRange);
t2 := CG.Pop ();
IF Host.doRangeChk THEN
! b := TInt.FromInt (Integer_types[rep].size, Target.Integer.bytes, max);
! <*ASSERT b*>
CG.Push (t1);
CG.Push (t2);
CG.Add (Target.Integer.cg_type);
--- 70,76 ----
CG.RuntimeError.ValueOutOfRange);
t2 := CG.Pop ();
IF Host.doRangeChk THEN
! b := TInt.FromInt (Word_types[rep].size, max); <*ASSERT b*>
CG.Push (t1);
CG.Push (t2);
CG.Add (Target.Integer.cg_type);
***************
*** 85,91 ****
CG.Force ();
CG.Push (t1);
CG.Push (t2);
! CG.Extract (Integer_types[rep].cg_type, sign := FALSE);
CG.Free (t1);
CG.Free (t2);
END;
--- 82,88 ----
CG.Force ();
CG.Push (t1);
CG.Push (t2);
! CG.Extract (Word_types[rep].cg_type, sign := FALSE);
CG.Free (t1);
CG.Free (t2);
END;
***************
*** 95,115 ****
BEGIN
e := Expr.ConstValue (e);
IF (e = NIL) THEN RETURN FALSE END;
! RETURN IntegerExpr.ToInt (e, i) AND (0 <= i) AND (i <= Integer_types[rep].size);
END GetBitIndex;
PROCEDURE Fold (ce: CallExpr.T): Expr.T =
! VAR e0, e1, e2: Expr.T; w0, result: Target.Int; i1, i2: INTEGER; t: Type.T;
BEGIN
e0 := Expr.ConstValue (ce.args[0]);
! e1 := Expr.ConstValue (ce.args[1]);
! e2 := Expr.ConstValue (ce.args[2]);
! IF (e0 = NIL) OR (NOT IntegerExpr.Split (e0, w0, t)) OR
! (e1 = NIL) OR (NOT IntegerExpr.ToInt (e1, i1)) OR
! (e2 = NIL) OR (NOT IntegerExpr.ToInt (e2, i2)) OR
! NOT TWord.Extract (w0, i1, i2, result) THEN
RETURN NIL;
END;
RETURN IntegerExpr.New (T, result);
END Fold;
--- 92,114 ----
BEGIN
e := Expr.ConstValue (e);
IF (e = NIL) THEN RETURN FALSE END;
! RETURN IntegerExpr.ToInt (e, i)
! AND (0 <= i) AND (i <= Word_types[rep].size);
END GetBitIndex;
PROCEDURE Fold (ce: CallExpr.T): Expr.T =
! VAR e0: Expr.T; w0, result: Target.Int; i1, i2: INTEGER; t: Type.T;
BEGIN
e0 := Expr.ConstValue (ce.args[0]);
! IF (e0 = NIL)
! OR NOT IntegerExpr.Split (e0, w0, t)
! OR NOT GetBitIndex (ce.args[1], i1)
! OR NOT GetBitIndex (ce.args[2], i2)
! OR i1 + i2 > Word_types[rep].size
! OR NOT TWord.Extract (w0, i1, i2, result) THEN
RETURN NIL;
END;
+ TInt.Chop (result, Word_types[rep].bytes);
RETURN IntegerExpr.New (T, result);
END Fold;
***************
*** 117,123 ****
VAR min_bits, max_bits: Target.Int; i: INTEGER;
BEGIN
Expr.GetBounds (ce.args[2], min_bits, max_bits);
! IF TInt.ToInt (max_bits, i) AND i < Integer_types[rep].size THEN
IF NOT TWord.Extract (TInt.MOne, 0, i, max) THEN
EVAL Type.GetBounds (T, min, max);
END;
--- 116,122 ----
VAR min_bits, max_bits: Target.Int; i: INTEGER;
BEGIN
Expr.GetBounds (ce.args[2], min_bits, max_bits);
! IF TInt.ToInt (max_bits, i) AND i < Word_types[rep].size THEN
IF NOT TWord.Extract (TInt.MOne, 0, i, max) THEN
EVAL Type.GetBounds (T, min, max);
END;
Index: m3front/src/builtinWord/GE.mg
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinWord/GE.mg,v
retrieving revision 1.1
diff -c -r1.1 GE.mg
*** m3front/src/builtinWord/GE.mg 4 Feb 2010 20:00:45 -0000 1.1
--- m3front/src/builtinWord/GE.mg 18 Feb 2010 02:30:51 -0000
***************
*** 49,56 ****
BEGIN
e0 := Expr.ConstValue (args[0]);
e1 := Expr.ConstValue (args[1]);
! RETURN (e0 # NIL) AND IntegerExpr.Split (e0, w0, t) AND
! (e1 # NIL) AND IntegerExpr.Split (e1, w1, t);
END GetArgs;
PROCEDURE Initialize (r: INTEGER) =
--- 49,63 ----
BEGIN
e0 := Expr.ConstValue (args[0]);
e1 := Expr.ConstValue (args[1]);
! IF (e0 # NIL) AND IntegerExpr.Split (e0, w0, t)
! AND (e1 # NIL) AND IntegerExpr.Split (e1, w1, t)
! THEN
! TWord.And (w0, Word_types[rep].max, w0);
! TWord.And (w1, Word_types[rep].max, w1);
! RETURN TRUE;
! ELSE
! RETURN FALSE;
! END;
END GetArgs;
PROCEDURE Initialize (r: INTEGER) =
Index: m3front/src/builtinWord/GT.mg
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinWord/GT.mg,v
retrieving revision 1.1
diff -c -r1.1 GT.mg
*** m3front/src/builtinWord/GT.mg 4 Feb 2010 20:00:45 -0000 1.1
--- m3front/src/builtinWord/GT.mg 18 Feb 2010 02:30:51 -0000
***************
*** 49,56 ****
BEGIN
e0 := Expr.ConstValue (args[0]);
e1 := Expr.ConstValue (args[1]);
! RETURN (e0 # NIL) AND IntegerExpr.Split (e0, w0, t) AND
! (e1 # NIL) AND IntegerExpr.Split (e1, w1, t);
END GetArgs;
PROCEDURE Initialize (r: INTEGER) =
--- 49,63 ----
BEGIN
e0 := Expr.ConstValue (args[0]);
e1 := Expr.ConstValue (args[1]);
! IF (e0 # NIL) AND IntegerExpr.Split (e0, w0, t)
! AND (e1 # NIL) AND IntegerExpr.Split (e1, w1, t)
! THEN
! TWord.And (w0, Word_types[rep].max, w0);
! TWord.And (w1, Word_types[rep].max, w1);
! RETURN TRUE;
! ELSE
! RETURN FALSE;
! END;
END GetArgs;
PROCEDURE Initialize (r: INTEGER) =
Index: m3front/src/builtinWord/Insert.mg
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinWord/Insert.mg,v
retrieving revision 1.1
diff -c -r1.1 Insert.mg
*** m3front/src/builtinWord/Insert.mg 4 Feb 2010 20:00:46 -0000 1.1
--- m3front/src/builtinWord/Insert.mg 18 Feb 2010 02:30:51 -0000
***************
*** 8,18 ****
IMPORT IntegerExpr, Type, ProcType, CheckExpr, Card;
IMPORT Target, TInt, TWord, Value, Formal, Host;
FROM Rep IMPORT T;
! FROM TargetMap IMPORT Integer_types;
VAR Z: CallExpr.MethodList;
VAR formals: Value.T;
! VAR rep: [FIRST (Integer_types) .. LAST (Integer_types)];
PROCEDURE Check (ce: CallExpr.T; VAR cs: Expr.CheckState) =
BEGIN
--- 8,18 ----
IMPORT IntegerExpr, Type, ProcType, CheckExpr, Card;
IMPORT Target, TInt, TWord, Value, Formal, Host;
FROM Rep IMPORT T;
! FROM TargetMap IMPORT Word_types;
VAR Z: CallExpr.MethodList;
VAR formals: Value.T;
! VAR rep: [FIRST (Word_types) .. LAST (Word_types)];
PROCEDURE Check (ce: CallExpr.T; VAR cs: Expr.CheckState) =
BEGIN
***************
*** 30,37 ****
CG.RuntimeError.ValueOutOfRange);
t3 := CG.Pop ();
IF Host.doRangeChk THEN
! b := TInt.FromInt (Integer_types[rep].size, Target.Integer.bytes, max);
! <*ASSERT b*>
CG.Push (t2);
CG.Push (t3);
CG.Add (Target.Integer.cg_type);
--- 30,36 ----
CG.RuntimeError.ValueOutOfRange);
t3 := CG.Pop ();
IF Host.doRangeChk THEN
! b := TInt.FromInt (Word_types[rep].size, max); <*ASSERT b*>
CG.Push (t2);
CG.Push (t3);
CG.Add (Target.Integer.cg_type);
***************
*** 45,70 ****
CG.Force ();
CG.Push (t2);
CG.Push (t3);
! CG.Insert (Integer_types[rep].cg_type);
CG.Free (t2);
CG.Free (t3);
END Compile;
PROCEDURE Fold (ce: CallExpr.T): Expr.T =
! VAR e0, e1, e2, e3: Expr.T; w0, w1, result: Target.Int; i2, i3: INTEGER;
! t: Type.T;
BEGIN
e0 := Expr.ConstValue (ce.args[0]);
e1 := Expr.ConstValue (ce.args[1]);
! e2 := Expr.ConstValue (ce.args[2]);
! e3 := Expr.ConstValue (ce.args[3]);
! IF (e0 = NIL) OR (NOT IntegerExpr.Split (e0, w0, t)) OR
! (e1 = NIL) OR (NOT IntegerExpr.Split (e1, w1, t)) OR
! (e2 = NIL) OR (NOT IntegerExpr.ToInt (e2, i2)) OR
! (e3 = NIL) OR (NOT IntegerExpr.ToInt (e3, i3)) OR
! NOT TWord.Insert (w0, w1, i2, i3, result) THEN
RETURN NIL;
END;
RETURN IntegerExpr.New (T, result);
END Fold;
--- 44,77 ----
CG.Force ();
CG.Push (t2);
CG.Push (t3);
! CG.Insert (Word_types[rep].cg_type);
CG.Free (t2);
CG.Free (t3);
END Compile;
+ PROCEDURE GetBitIndex (e: Expr.T; VAR i: INTEGER): BOOLEAN =
+ BEGIN
+ e := Expr.ConstValue (e);
+ IF (e = NIL) THEN RETURN FALSE END;
+ RETURN IntegerExpr.ToInt (e, i)
+ AND (0 <= i) AND (i <= Word_types[rep].size);
+ END GetBitIndex;
+
PROCEDURE Fold (ce: CallExpr.T): Expr.T =
! VAR e0, e1: Expr.T; w0, w1, result: Target.Int; i2, i3: INTEGER; t: Type.T;
BEGIN
e0 := Expr.ConstValue (ce.args[0]);
e1 := Expr.ConstValue (ce.args[1]);
! IF (e0 = NIL) OR (e1 = NIL)
! OR NOT IntegerExpr.Split (e0, w0, t)
! OR NOT IntegerExpr.Split (e1, w1, t)
! OR NOT GetBitIndex (ce.args[2], i2)
! OR NOT GetBitIndex (ce.args[3], i3)
! OR i2 + i3 > Word_types[rep].size
! OR NOT TWord.Insert (w0, w1, i2, i3, result) THEN
RETURN NIL;
END;
+ TInt.Chop (result, Word_types[rep].bytes);
RETURN IntegerExpr.New (T, result);
END Fold;
Index: m3front/src/builtinWord/LE.mg
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinWord/LE.mg,v
retrieving revision 1.1
diff -c -r1.1 LE.mg
*** m3front/src/builtinWord/LE.mg 4 Feb 2010 20:00:46 -0000 1.1
--- m3front/src/builtinWord/LE.mg 18 Feb 2010 02:30:51 -0000
***************
*** 49,56 ****
BEGIN
e0 := Expr.ConstValue (args[0]);
e1 := Expr.ConstValue (args[1]);
! RETURN (e0 # NIL) AND IntegerExpr.Split (e0, w0, t) AND
! (e1 # NIL) AND IntegerExpr.Split (e1, w1, t);
END GetArgs;
PROCEDURE Initialize (r: INTEGER) =
--- 49,63 ----
BEGIN
e0 := Expr.ConstValue (args[0]);
e1 := Expr.ConstValue (args[1]);
! IF (e0 # NIL) AND IntegerExpr.Split (e0, w0, t)
! AND (e1 # NIL) AND IntegerExpr.Split (e1, w1, t)
! THEN
! TWord.And (w0, Word_types[rep].max, w0);
! TWord.And (w1, Word_types[rep].max, w1);
! RETURN TRUE;
! ELSE
! RETURN FALSE;
! END;
END GetArgs;
PROCEDURE Initialize (r: INTEGER) =
Index: m3front/src/builtinWord/LT.mg
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinWord/LT.mg,v
retrieving revision 1.1
diff -c -r1.1 LT.mg
*** m3front/src/builtinWord/LT.mg 4 Feb 2010 20:00:46 -0000 1.1
--- m3front/src/builtinWord/LT.mg 18 Feb 2010 02:30:51 -0000
***************
*** 49,56 ****
BEGIN
e0 := Expr.ConstValue (args[0]);
e1 := Expr.ConstValue (args[1]);
! RETURN (e0 # NIL) AND IntegerExpr.Split (e0, w0, t) AND
! (e1 # NIL) AND IntegerExpr.Split (e1, w1, t);
END GetArgs;
PROCEDURE Initialize (r: INTEGER) =
--- 49,63 ----
BEGIN
e0 := Expr.ConstValue (args[0]);
e1 := Expr.ConstValue (args[1]);
! IF (e0 # NIL) AND IntegerExpr.Split (e0, w0, t)
! AND (e1 # NIL) AND IntegerExpr.Split (e1, w1, t)
! THEN
! TWord.And (w0, Word_types[rep].max, w0);
! TWord.And (w1, Word_types[rep].max, w1);
! RETURN TRUE;
! ELSE
! RETURN FALSE;
! END;
END GetArgs;
PROCEDURE Initialize (r: INTEGER) =
Index: m3front/src/builtinWord/Minus.mg
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinWord/Minus.mg,v
retrieving revision 1.1
diff -c -r1.1 Minus.mg
*** m3front/src/builtinWord/Minus.mg 4 Feb 2010 20:00:46 -0000 1.1
--- m3front/src/builtinWord/Minus.mg 18 Feb 2010 02:30:51 -0000
***************
*** 5,11 ****
GENERIC MODULE Minus (Rep);
IMPORT CG, CallExpr, Expr, ExprRep, Procedure, Type, ProcType;
! IMPORT IntegerExpr, Value, Formal, Target, TWord;
FROM Rep IMPORT T;
FROM TargetMap IMPORT Word_types;
--- 5,11 ----
GENERIC MODULE Minus (Rep);
IMPORT CG, CallExpr, Expr, ExprRep, Procedure, Type, ProcType;
! IMPORT IntegerExpr, Value, Formal, Target, TWord, TInt;
FROM Rep IMPORT T;
FROM TargetMap IMPORT Word_types;
***************
*** 31,36 ****
--- 31,37 ----
BEGIN
IF GetArgs (ce.args, w0, w1) THEN
TWord.Subtract (w0, w1, result);
+ TInt.Chop (result, Word_types[rep].bytes);
RETURN IntegerExpr.New (T, result);
END;
RETURN NIL;
Index: m3front/src/builtinWord/Mod.mg
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinWord/Mod.mg,v
retrieving revision 1.1
diff -c -r1.1 Mod.mg
*** m3front/src/builtinWord/Mod.mg 4 Feb 2010 20:00:46 -0000 1.1
--- m3front/src/builtinWord/Mod.mg 18 Feb 2010 02:30:51 -0000
***************
*** 32,37 ****
--- 32,38 ----
VAR w0, w1, result: Target.Int;
BEGIN
IF GetArgs (ce.args, w0, w1) AND TWord.Mod (w0, w1, result) THEN
+ TInt.Chop (result, Word_types[rep].bytes);
RETURN IntegerExpr.New (T, result);
END;
RETURN NIL;
***************
*** 42,49 ****
BEGIN
e0 := Expr.ConstValue (args[0]);
e1 := Expr.ConstValue (args[1]);
! RETURN (e0 # NIL) AND IntegerExpr.Split (e0, w0, t) AND
! (e1 # NIL) AND IntegerExpr.Split (e1, w1, t);
END GetArgs;
PROCEDURE GetBounds (ce: CallExpr.T; VAR min, max: Target.Int) =
--- 43,57 ----
BEGIN
e0 := Expr.ConstValue (args[0]);
e1 := Expr.ConstValue (args[1]);
! IF (e0 # NIL) AND IntegerExpr.Split (e0, w0, t)
! AND (e1 # NIL) AND IntegerExpr.Split (e1, w1, t)
! THEN
! TWord.And (w0, Word_types[rep].max, w0);
! TWord.And (w1, Word_types[rep].max, w1);
! RETURN TRUE;
! ELSE
! RETURN FALSE;
! END;
END GetArgs;
PROCEDURE GetBounds (ce: CallExpr.T; VAR min, max: Target.Int) =
***************
*** 56,61 ****
--- 64,70 ----
ELSE
min := TInt.Zero;
TWord.Subtract (max_b, TInt.One, max);
+ TInt.Chop (max, Word_types[rep].bytes);
END;
END GetBounds;
Index: m3front/src/builtinWord/Module.mg
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinWord/Module.mg,v
retrieving revision 1.1
diff -c -r1.1 Module.mg
*** m3front/src/builtinWord/Module.mg 4 Feb 2010 20:00:46 -0000 1.1
--- m3front/src/builtinWord/Module.mg 18 Feb 2010 02:30:51 -0000
***************
*** 15,22 ****
PROCEDURE SetRep (): INTEGER =
VAR min, max: Target.Int; b: BOOLEAN;
BEGIN
! b := Type.GetBounds (T, min, max);
! <*ASSERT b*>
FOR i := FIRST (Word_types) TO LAST (Word_types) DO
WITH t = Word_types[i] DO
IF TWord.LE (max, t.max) THEN
--- 15,21 ----
PROCEDURE SetRep (): INTEGER =
VAR min, max: Target.Int; b: BOOLEAN;
BEGIN
! b := Type.GetBounds (T, min, max); <*ASSERT b*>
FOR i := FIRST (Word_types) TO LAST (Word_types) DO
WITH t = Word_types[i] DO
IF TWord.LE (max, t.max) THEN
***************
*** 30,37 ****
PROCEDURE Initialize (name: TEXT) =
VAR zz: Scope.T; size: Target.Int; b: BOOLEAN; rep := SetRep ();
BEGIN
! b := TInt.FromInt (Word_types[rep].size, Target.Integer.bytes, size);
! <*ASSERT b*>
M := Module.NewDefn (name, TRUE, NIL);
(* WARNING: The following list must be in the same order
--- 29,35 ----
PROCEDURE Initialize (name: TEXT) =
VAR zz: Scope.T; size: Target.Int; b: BOOLEAN; rep := SetRep ();
BEGIN
! b := TInt.FromInt (Word_types[rep].size, size); <*ASSERT b*>
M := Module.NewDefn (name, TRUE, NIL);
(* WARNING: The following list must be in the same order
Index: m3front/src/builtinWord/Not.mg
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinWord/Not.mg,v
retrieving revision 1.1
diff -c -r1.1 Not.mg
*** m3front/src/builtinWord/Not.mg 4 Feb 2010 20:00:46 -0000 1.1
--- m3front/src/builtinWord/Not.mg 18 Feb 2010 02:30:51 -0000
***************
*** 5,11 ****
GENERIC MODULE Not (Rep);
IMPORT CG, CallExpr, Expr, ExprRep, Procedure, Target, TWord;
! IMPORT IntegerExpr, Value, Formal, Type, ProcType;
FROM Rep IMPORT T;
FROM TargetMap IMPORT Integer_types;
--- 5,11 ----
GENERIC MODULE Not (Rep);
IMPORT CG, CallExpr, Expr, ExprRep, Procedure, Target, TWord;
! IMPORT IntegerExpr, Value, Formal, Type, ProcType, TInt;
FROM Rep IMPORT T;
FROM TargetMap IMPORT Integer_types;
***************
*** 31,36 ****
--- 31,37 ----
e := Expr.ConstValue (ce.args[0]);
IF (e # NIL) AND IntegerExpr.Split (e, w, t) THEN
TWord.Not (w, result);
+ TInt.Chop (result, Integer_types[rep].bytes);
RETURN IntegerExpr.New (T, result);
END;
RETURN NIL;
Index: m3front/src/builtinWord/Or.mg
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinWord/Or.mg,v
retrieving revision 1.1
diff -c -r1.1 Or.mg
*** m3front/src/builtinWord/Or.mg 4 Feb 2010 20:00:46 -0000 1.1
--- m3front/src/builtinWord/Or.mg 18 Feb 2010 02:30:51 -0000
***************
*** 5,17 ****
GENERIC MODULE Or (Rep);
IMPORT CG, CallExpr, Expr, ExprRep, Procedure, Type, ProcType;
! IMPORT IntegerExpr, Value, Formal, Target, TWord;
FROM Rep IMPORT T;
! FROM TargetMap IMPORT Integer_types;
VAR Z: CallExpr.MethodList;
VAR formals: Value.T;
! VAR rep: [FIRST (Integer_types) .. LAST (Integer_types)];
PROCEDURE Check (ce: CallExpr.T; VAR cs: Expr.CheckState) =
BEGIN
--- 5,17 ----
GENERIC MODULE Or (Rep);
IMPORT CG, CallExpr, Expr, ExprRep, Procedure, Type, ProcType;
! IMPORT IntegerExpr, Value, Formal, Target, TWord, TInt;
FROM Rep IMPORT T;
! FROM TargetMap IMPORT Word_types;
VAR Z: CallExpr.MethodList;
VAR formals: Value.T;
! VAR rep: [FIRST (Word_types) .. LAST (Word_types)];
PROCEDURE Check (ce: CallExpr.T; VAR cs: Expr.CheckState) =
BEGIN
***************
*** 23,29 ****
BEGIN
Expr.Compile (ce.args[0]);
Expr.Compile (ce.args[1]);
! CG.Or (Integer_types[rep].cg_type);
END Compile;
PROCEDURE Fold (ce: CallExpr.T): Expr.T =
--- 23,29 ----
BEGIN
Expr.Compile (ce.args[0]);
Expr.Compile (ce.args[1]);
! CG.Or (Word_types[rep].cg_type);
END Compile;
PROCEDURE Fold (ce: CallExpr.T): Expr.T =
***************
*** 31,36 ****
--- 31,37 ----
BEGIN
IF GetArgs (ce.args, w0, w1) THEN
TWord.Or (w0, w1, result);
+ TInt.Chop (result, Word_types[rep].bytes);
RETURN IntegerExpr.New (T, result);
END;
RETURN NIL;
Index: m3front/src/builtinWord/Plus.mg
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinWord/Plus.mg,v
retrieving revision 1.1
diff -c -r1.1 Plus.mg
*** m3front/src/builtinWord/Plus.mg 4 Feb 2010 20:00:46 -0000 1.1
--- m3front/src/builtinWord/Plus.mg 18 Feb 2010 02:30:51 -0000
***************
*** 4,10 ****
GENERIC MODULE Plus (Rep);
! IMPORT CG, CallExpr, Expr, ExprRep, Procedure, Target, TWord;
IMPORT IntegerExpr, Value, Formal, Type, ProcType;
FROM Rep IMPORT T;
FROM TargetMap IMPORT Word_types;
--- 4,10 ----
GENERIC MODULE Plus (Rep);
! IMPORT CG, CallExpr, Expr, ExprRep, Procedure, Target, TWord, TInt;
IMPORT IntegerExpr, Value, Formal, Type, ProcType;
FROM Rep IMPORT T;
FROM TargetMap IMPORT Word_types;
***************
*** 31,36 ****
--- 31,37 ----
BEGIN
IF GetArgs (ce.args, w0, w1) THEN
TWord.Add (w0, w1, result);
+ TInt.Chop (result, Word_types[rep].bytes);
RETURN IntegerExpr.New (T, result);
END;
RETURN NIL;
Index: m3front/src/builtinWord/Rotate.mg
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinWord/Rotate.mg,v
retrieving revision 1.1
diff -c -r1.1 Rotate.mg
*** m3front/src/builtinWord/Rotate.mg 4 Feb 2010 20:00:46 -0000 1.1
--- m3front/src/builtinWord/Rotate.mg 18 Feb 2010 02:30:51 -0000
***************
*** 7,17 ****
IMPORT CG, CallExpr, Expr, ExprRep, Procedure, Formal, Type, SubrangeType;
IMPORT Int, IntegerExpr, Value, ProcType, CheckExpr, Target, TInt, TWord;
FROM Rep IMPORT T;
! FROM TargetMap IMPORT Integer_types;
VAR Z, ZL, ZR: CallExpr.MethodList;
VAR formals, formalsL, formalsR: Value.T;
! VAR rep: [FIRST (Integer_types) .. LAST (Integer_types)];
PROCEDURE Check (ce: CallExpr.T; VAR cs: Expr.CheckState) =
BEGIN
--- 7,18 ----
IMPORT CG, CallExpr, Expr, ExprRep, Procedure, Formal, Type, SubrangeType;
IMPORT Int, IntegerExpr, Value, ProcType, CheckExpr, Target, TInt, TWord;
FROM Rep IMPORT T;
! FROM TargetMap IMPORT Word_types;
VAR Z, ZL, ZR: CallExpr.MethodList;
VAR formals, formalsL, formalsR: Value.T;
! VAR rep: [FIRST (Word_types) .. LAST (Word_types)];
! VAR max : Target.Int;
PROCEDURE Check (ce: CallExpr.T; VAR cs: Expr.CheckState) =
BEGIN
***************
*** 35,63 ****
BEGIN
Expr.Compile (ce.args[0]);
Expr.Compile (ce.args[1]);
! CG.Rotate (Integer_types[rep].cg_type);
END Compile;
PROCEDURE CompileL (ce: CallExpr.T) =
- VAR max: Target.Int;
- b := TInt.FromInt (Integer_types[rep].size-1, Target.Integer.bytes, max);
BEGIN
- <* ASSERT b *>
Expr.Compile (ce.args[0]);
CheckExpr.EmitChecks (ce.args[1], TInt.Zero, max,
CG.RuntimeError.ValueOutOfRange);
! CG.Rotate_left (Integer_types[rep].cg_type);
END CompileL;
PROCEDURE CompileR (ce: CallExpr.T) =
- VAR max: Target.Int;
- b := TInt.FromInt (Integer_types[rep].size-1, Target.Integer.bytes, max);
BEGIN
- <* ASSERT b *>
Expr.Compile (ce.args[0]);
CheckExpr.EmitChecks (ce.args[1], TInt.Zero, max,
CG.RuntimeError.ValueOutOfRange);
! CG.Rotate_right (Integer_types[rep].cg_type);
END CompileR;
PROCEDURE Fold (ce: CallExpr.T): Expr.T =
--- 36,58 ----
BEGIN
Expr.Compile (ce.args[0]);
Expr.Compile (ce.args[1]);
! CG.Rotate (Word_types[rep].cg_type);
END Compile;
PROCEDURE CompileL (ce: CallExpr.T) =
BEGIN
Expr.Compile (ce.args[0]);
CheckExpr.EmitChecks (ce.args[1], TInt.Zero, max,
CG.RuntimeError.ValueOutOfRange);
! CG.Rotate_left (Word_types[rep].cg_type);
END CompileL;
PROCEDURE CompileR (ce: CallExpr.T) =
BEGIN
Expr.Compile (ce.args[0]);
CheckExpr.EmitChecks (ce.args[1], TInt.Zero, max,
CG.RuntimeError.ValueOutOfRange);
! CG.Rotate_right (Word_types[rep].cg_type);
END CompileR;
PROCEDURE Fold (ce: CallExpr.T): Expr.T =
***************
*** 68,74 ****
IF (e0 # NIL) AND IntegerExpr.Split (e0, w0, t)
AND (e1 # NIL) AND IntegerExpr.ToInt (e1, i1)
THEN
! TWord.Rotate (w0, i1, result);
RETURN IntegerExpr.New (T, result);
END;
RETURN NIL;
--- 63,71 ----
IF (e0 # NIL) AND IntegerExpr.Split (e0, w0, t)
AND (e1 # NIL) AND IntegerExpr.ToInt (e1, i1)
THEN
! TWord.And (w0, Word_types[rep].max, w0);
! TWord.Rotate (w0, i1, Word_types[rep].bytes, result);
! TInt.Chop (result, Word_types[rep].bytes);
RETURN IntegerExpr.New (T, result);
END;
RETURN NIL;
***************
*** 81,89 ****
e1 := Expr.ConstValue (ce.args[1]);
IF (e0 # NIL) AND IntegerExpr.Split (e0, w0, t)
AND (e1 # NIL) AND IntegerExpr.ToInt (e1, i1)
! AND 0 <= i1 AND i1 < Integer_types[rep].size
THEN
! TWord.Rotate (w0, i1, result);
RETURN IntegerExpr.New (T, result);
END;
RETURN NIL;
--- 78,88 ----
e1 := Expr.ConstValue (ce.args[1]);
IF (e0 # NIL) AND IntegerExpr.Split (e0, w0, t)
AND (e1 # NIL) AND IntegerExpr.ToInt (e1, i1)
! AND 0 <= i1 AND i1 < Word_types[rep].size
THEN
! TWord.And (w0, Word_types[rep].max, w0);
! TWord.Rotate (w0, i1, Word_types[rep].bytes, result);
! TInt.Chop (result, Word_types[rep].bytes);
RETURN IntegerExpr.New (T, result);
END;
RETURN NIL;
***************
*** 96,104 ****
e1 := Expr.ConstValue (ce.args[1]);
IF (e0 # NIL) AND IntegerExpr.Split (e0, w0, t)
AND (e1 # NIL) AND IntegerExpr.ToInt (e1, i1)
! AND 0 <= i1 AND i1 < Integer_types[rep].size
THEN
! TWord.Rotate (w0, -i1, result);
RETURN IntegerExpr.New (T, result);
END;
RETURN NIL;
--- 95,105 ----
e1 := Expr.ConstValue (ce.args[1]);
IF (e0 # NIL) AND IntegerExpr.Split (e0, w0, t)
AND (e1 # NIL) AND IntegerExpr.ToInt (e1, i1)
! AND 0 <= i1 AND i1 < Word_types[rep].size
THEN
! TWord.And (w0, Word_types[rep].max, w0);
! TWord.Rotate (w0, -i1, Word_types[rep].bytes, result);
! TInt.Chop (result, Word_types[rep].bytes);
RETURN IntegerExpr.New (T, result);
END;
RETURN NIL;
***************
*** 106,113 ****
PROCEDURE Initialize (r: INTEGER) =
VAR
! max : Target.Int;
! b := TInt.FromInt (Integer_types[r].size-1, Target.Integer.bytes, max);
sub := SubrangeType.New (TInt.Zero, max, Int.T, FALSE);
f0 := Formal.NewBuiltin ("x", 0, T);
--- 107,113 ----
PROCEDURE Initialize (r: INTEGER) =
VAR
! b := TInt.FromInt (Word_types[r].size-1, max);
sub := SubrangeType.New (TInt.Zero, max, Int.T, FALSE);
f0 := Formal.NewBuiltin ("x", 0, T);
Index: m3front/src/builtinWord/Shift.mg
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinWord/Shift.mg,v
retrieving revision 1.1
diff -c -r1.1 Shift.mg
*** m3front/src/builtinWord/Shift.mg 4 Feb 2010 20:00:46 -0000 1.1
--- m3front/src/builtinWord/Shift.mg 18 Feb 2010 02:30:51 -0000
***************
*** 7,17 ****
IMPORT CG, CallExpr, Expr, ExprRep, Procedure, Type, SubrangeType, Formal;
IMPORT Int, IntegerExpr, Value, ProcType, CheckExpr, Target, TInt, TWord;
FROM Rep IMPORT T;
! FROM TargetMap IMPORT Integer_types;
VAR Z, ZL, ZR: CallExpr.MethodList;
VAR formals, formalsL, formalsR: Value.T;
! VAR rep: [FIRST (Integer_types) .. LAST (Integer_types)];
PROCEDURE Check (ce: CallExpr.T; VAR cs: Expr.CheckState) =
BEGIN
--- 7,18 ----
IMPORT CG, CallExpr, Expr, ExprRep, Procedure, Type, SubrangeType, Formal;
IMPORT Int, IntegerExpr, Value, ProcType, CheckExpr, Target, TInt, TWord;
FROM Rep IMPORT T;
! FROM TargetMap IMPORT Word_types;
VAR Z, ZL, ZR: CallExpr.MethodList;
VAR formals, formalsL, formalsR: Value.T;
! VAR rep: [FIRST (Word_types) .. LAST (Word_types)];
! VAR max: Target.Int;
PROCEDURE Check (ce: CallExpr.T; VAR cs: Expr.CheckState) =
BEGIN
***************
*** 35,63 ****
BEGIN
Expr.Compile (ce.args[0]);
Expr.Compile (ce.args[1]);
! CG.Shift (Integer_types[rep].cg_type);
END Compile;
PROCEDURE CompileL (ce: CallExpr.T) =
- VAR max: Target.Int;
- b := TInt.FromInt (Integer_types[rep].size-1, Target.Integer.bytes, max);
BEGIN
- <* ASSERT b *>
Expr.Compile (ce.args[0]);
CheckExpr.EmitChecks (ce.args[1], TInt.Zero, max,
CG.RuntimeError.ValueOutOfRange);
! CG.Shift_left (Integer_types[rep].cg_type);
END CompileL;
PROCEDURE CompileR (ce: CallExpr.T) =
- VAR max: Target.Int;
- b := TInt.FromInt (Integer_types[rep].size-1, Target.Integer.bytes, max);
BEGIN
- <* ASSERT b *>
Expr.Compile (ce.args[0]);
CheckExpr.EmitChecks (ce.args[1], TInt.Zero, max,
CG.RuntimeError.ValueOutOfRange);
! CG.Shift_right (Integer_types[rep].cg_type);
END CompileR;
PROCEDURE Fold (ce: CallExpr.T): Expr.T =
--- 36,58 ----
BEGIN
Expr.Compile (ce.args[0]);
Expr.Compile (ce.args[1]);
! CG.Shift (Word_types[rep].cg_type);
END Compile;
PROCEDURE CompileL (ce: CallExpr.T) =
BEGIN
Expr.Compile (ce.args[0]);
CheckExpr.EmitChecks (ce.args[1], TInt.Zero, max,
CG.RuntimeError.ValueOutOfRange);
! CG.Shift_left (Word_types[rep].cg_type);
END CompileL;
PROCEDURE CompileR (ce: CallExpr.T) =
BEGIN
Expr.Compile (ce.args[0]);
CheckExpr.EmitChecks (ce.args[1], TInt.Zero, max,
CG.RuntimeError.ValueOutOfRange);
! CG.Shift_right (Word_types[rep].cg_type);
END CompileR;
PROCEDURE Fold (ce: CallExpr.T): Expr.T =
***************
*** 68,74 ****
--- 63,71 ----
IF (e0 # NIL) AND IntegerExpr.Split (e0, w0, t)
AND (e1 # NIL) AND IntegerExpr.ToInt (e1, i1)
THEN
+ TWord.And (w0, Word_types[rep].max, w0);
TWord.Shift (w0, i1, result);
+ TInt.Chop (result, Word_types[rep].bytes);
RETURN IntegerExpr.New (T, result);
END;
RETURN NIL;
***************
*** 81,89 ****
e1 := Expr.ConstValue (ce.args[1]);
IF (e0 # NIL) AND IntegerExpr.Split (e0, w0, t)
AND (e1 # NIL) AND IntegerExpr.ToInt (e1, i1)
! AND 0 <= i1 AND i1 < Integer_types[rep].size
THEN
TWord.Shift (w0, i1, result);
RETURN IntegerExpr.New (T, result);
END;
RETURN NIL;
--- 78,88 ----
e1 := Expr.ConstValue (ce.args[1]);
IF (e0 # NIL) AND IntegerExpr.Split (e0, w0, t)
AND (e1 # NIL) AND IntegerExpr.ToInt (e1, i1)
! AND 0 <= i1 AND i1 < Word_types[rep].size
THEN
+ TWord.And (w0, Word_types[rep].max, w0);
TWord.Shift (w0, i1, result);
+ TInt.Chop (result, Word_types[rep].bytes);
RETURN IntegerExpr.New (T, result);
END;
RETURN NIL;
***************
*** 96,104 ****
e1 := Expr.ConstValue (ce.args[1]);
IF (e0 # NIL) AND IntegerExpr.Split (e0, w0, t)
AND (e1 # NIL) AND IntegerExpr.ToInt (e1, i1)
! AND 0 <= i1 AND i1 < Integer_types[rep].size
THEN
TWord.Shift (w0, -i1, result);
RETURN IntegerExpr.New (T, result);
END;
RETURN NIL;
--- 95,105 ----
e1 := Expr.ConstValue (ce.args[1]);
IF (e0 # NIL) AND IntegerExpr.Split (e0, w0, t)
AND (e1 # NIL) AND IntegerExpr.ToInt (e1, i1)
! AND 0 <= i1 AND i1 < Word_types[rep].size
THEN
+ TWord.And (w0, Word_types[rep].max, w0);
TWord.Shift (w0, -i1, result);
+ TInt.Chop (result, Word_types[rep].bytes);
RETURN IntegerExpr.New (T, result);
END;
RETURN NIL;
***************
*** 106,113 ****
PROCEDURE Initialize (r: INTEGER) =
VAR
! max : Target.Int;
! b := TInt.FromInt (Integer_types[r].size-1, Target.Integer.bytes, max);
sub := SubrangeType.New (TInt.Zero, max, Int.T, FALSE);
f0 := Formal.NewBuiltin ("x", 0, T);
--- 107,113 ----
PROCEDURE Initialize (r: INTEGER) =
VAR
! b := TInt.FromInt (Word_types[r].size-1, max);
sub := SubrangeType.New (TInt.Zero, max, Int.T, FALSE);
f0 := Formal.NewBuiltin ("x", 0, T);
Index: m3front/src/builtinWord/Times.mg
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinWord/Times.mg,v
retrieving revision 1.1
diff -c -r1.1 Times.mg
*** m3front/src/builtinWord/Times.mg 4 Feb 2010 20:00:46 -0000 1.1
--- m3front/src/builtinWord/Times.mg 18 Feb 2010 02:30:51 -0000
***************
*** 5,11 ****
GENERIC MODULE Times (Rep);
IMPORT CG, CallExpr, Expr, ExprRep, Procedure, Type, ProcType;
! IMPORT IntegerExpr, Value, Formal, Target, TWord;
FROM Rep IMPORT T;
FROM TargetMap IMPORT Word_types;
--- 5,11 ----
GENERIC MODULE Times (Rep);
IMPORT CG, CallExpr, Expr, ExprRep, Procedure, Type, ProcType;
! IMPORT IntegerExpr, Value, Formal, Target, TWord, TInt;
FROM Rep IMPORT T;
FROM TargetMap IMPORT Word_types;
***************
*** 31,36 ****
--- 31,37 ----
BEGIN
IF GetArgs (ce.args, w0, w1) THEN
TWord.Multiply (w0, w1, result);
+ TInt.Chop (result, Word_types[rep].bytes);
RETURN IntegerExpr.New (T, result);
END;
RETURN NIL;
***************
*** 41,48 ****
BEGIN
e0 := Expr.ConstValue (args[0]);
e1 := Expr.ConstValue (args[1]);
! RETURN (e0 # NIL) AND IntegerExpr.Split (e0, w0, t) AND
! (e1 # NIL) AND IntegerExpr.Split (e1, w1, t);
END GetArgs;
PROCEDURE Initialize (r: INTEGER) =
--- 42,56 ----
BEGIN
e0 := Expr.ConstValue (args[0]);
e1 := Expr.ConstValue (args[1]);
! IF (e0 # NIL) AND IntegerExpr.Split (e0, w0, t)
! AND (e1 # NIL) AND IntegerExpr.Split (e1, w1, t)
! THEN
! TWord.And (w0, Word_types[rep].max, w0);
! TWord.And (w1, Word_types[rep].max, w1);
! RETURN TRUE;
! ELSE
! RETURN FALSE;
! END;
END GetArgs;
PROCEDURE Initialize (r: INTEGER) =
Index: m3front/src/builtinWord/Xor.mg
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/builtinWord/Xor.mg,v
retrieving revision 1.1
diff -c -r1.1 Xor.mg
*** m3front/src/builtinWord/Xor.mg 4 Feb 2010 20:00:46 -0000 1.1
--- m3front/src/builtinWord/Xor.mg 18 Feb 2010 02:30:51 -0000
***************
*** 5,17 ****
GENERIC MODULE Xor (Rep);
IMPORT CG, CallExpr, Expr, ExprRep, Procedure, Type, ProcType;
! IMPORT IntegerExpr, Value, Formal, Target, TWord;
FROM Rep IMPORT T;
! FROM TargetMap IMPORT Integer_types;
VAR Z: CallExpr.MethodList;
VAR formals: Value.T;
! VAR rep: [FIRST (Integer_types) .. LAST (Integer_types)];
PROCEDURE Check (ce: CallExpr.T; VAR cs: Expr.CheckState) =
BEGIN
--- 5,17 ----
GENERIC MODULE Xor (Rep);
IMPORT CG, CallExpr, Expr, ExprRep, Procedure, Type, ProcType;
! IMPORT IntegerExpr, Value, Formal, Target, TWord, TInt;
FROM Rep IMPORT T;
! FROM TargetMap IMPORT Word_types;
VAR Z: CallExpr.MethodList;
VAR formals: Value.T;
! VAR rep: [FIRST (Word_types) .. LAST (Word_types)];
PROCEDURE Check (ce: CallExpr.T; VAR cs: Expr.CheckState) =
BEGIN
***************
*** 23,29 ****
BEGIN
Expr.Compile (ce.args[0]);
Expr.Compile (ce.args[1]);
! CG.Xor (Integer_types[rep].cg_type);
END Compile;
PROCEDURE Fold (ce: CallExpr.T): Expr.T =
--- 23,29 ----
BEGIN
Expr.Compile (ce.args[0]);
Expr.Compile (ce.args[1]);
! CG.Xor (Word_types[rep].cg_type);
END Compile;
PROCEDURE Fold (ce: CallExpr.T): Expr.T =
***************
*** 31,36 ****
--- 31,37 ----
BEGIN
IF GetArgs (ce.args, w0, w1) THEN
TWord.Xor (w0, w1, result);
+ TInt.Chop (result, Word_types[rep].bytes);
RETURN IntegerExpr.New (T, result);
END;
RETURN NIL;
Index: m3front/src/exprs/AddExpr.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/AddExpr.m3,v
retrieving revision 1.4
diff -c -r1.4 AddExpr.m3
*** m3front/src/exprs/AddExpr.m3 10 Jan 2010 05:12:05 -0000 1.4
--- m3front/src/exprs/AddExpr.m3 18 Feb 2010 02:30:51 -0000
***************
*** 172,178 ****
EVAL Type.GetBounds (p.type, min, max);
Expr.GetBounds (p.a, min_a, max_a);
Expr.GetBounds (p.b, min_b, max_b);
! IF TInt.Add (min_a, min_b, smin) AND TInt.Add (max_a, max_b, smax) THEN
IF TInt.LT (min, smin) THEN min := smin END;
IF TInt.LT (smax, max) THEN max := smax END;
END;
--- 172,181 ----
EVAL Type.GetBounds (p.type, min, max);
Expr.GetBounds (p.a, min_a, max_a);
Expr.GetBounds (p.b, min_b, max_b);
! IF TInt.Add (min_a, min_b, smin)
! AND NOT TInt.LT (smin, min) AND NOT TInt.LT (max, smin)
! AND TInt.Add (max_a, max_b, smax)
! AND NOT TInt.LT (smax, min) AND NOT TInt.LT (max, smax) THEN
IF TInt.LT (min, smin) THEN min := smin END;
IF TInt.LT (smax, max) THEN max := smax END;
END;
Index: m3front/src/exprs/AddressExpr.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/AddressExpr.m3,v
retrieving revision 1.8
diff -c -r1.8 AddressExpr.m3
*** m3front/src/exprs/AddressExpr.m3 8 Feb 2010 12:03:30 -0000 1.8
--- m3front/src/exprs/AddressExpr.m3 18 Feb 2010 02:30:52 -0000
***************
*** 39,45 ****
PROCEDURE New (READONLY value: Target.Int): Expr.T =
VAR p: P;
BEGIN
- IF TWord.LT (Target.Address.max, value) THEN RETURN NIL END;
p := NEW (P);
ExprRep.Init (p);
p.value := value;
--- 39,44 ----
***************
*** 66,72 ****
IF NOT IntegerExpr.Split (b, i, t) THEN RETURN FALSE END;
TYPECASE a OF
| NULL => RETURN FALSE;
! | P(p) => TWord.Add (p.value, i, j); c := New (j); RETURN c # NIL;
ELSE RETURN FALSE;
END;
END Add;
--- 65,75 ----
IF NOT IntegerExpr.Split (b, i, t) THEN RETURN FALSE END;
TYPECASE a OF
| NULL => RETURN FALSE;
! | P(p) =>
! TWord.Add (p.value, i, j);
! TInt.Chop (j, Target.Address.bytes);
! c := New (j);
! RETURN TRUE;
ELSE RETURN FALSE;
END;
END Add;
***************
*** 82,102 ****
IF IntegerExpr.Split (b, j, t) THEN
TWord.Subtract (i, j, k);
c := New (k);
ELSE (* address - address *)
TYPECASE b OF
| NULL => RETURN FALSE;
! | P(p) => TWord.Subtract (i, p.value, k); c := IntegerExpr.New (t, k);
ELSE RETURN FALSE;
END;
END;
! RETURN c # NIL;
END Subtract;
PROCEDURE Compare (a, b: Expr.T; VAR sign: INTEGER): BOOLEAN =
VAR x, y: Target.Int;
BEGIN
IF NOT SplitPair (a, b, x, y) THEN RETURN FALSE END;
IF TWord.LT (x, y) THEN
sign := -1
ELSIF TWord.LT (y, x) THEN
--- 85,111 ----
IF IntegerExpr.Split (b, j, t) THEN
TWord.Subtract (i, j, k);
+ TInt.Chop (k, Target.Address.bytes);
c := New (k);
ELSE (* address - address *)
TYPECASE b OF
| NULL => RETURN FALSE;
! | P(p) =>
! TWord.Subtract (i, p.value, k);
! TInt.Chop (k, Target.Address.bytes);
! c := IntegerExpr.New (t, k);
ELSE RETURN FALSE;
END;
END;
! RETURN TRUE;
END Subtract;
PROCEDURE Compare (a, b: Expr.T; VAR sign: INTEGER): BOOLEAN =
VAR x, y: Target.Int;
BEGIN
IF NOT SplitPair (a, b, x, y) THEN RETURN FALSE END;
+ TWord.And (x, Target.Address.max, x);
+ TWord.And (y, Target.Address.max, y);
IF TWord.LT (x, y) THEN
sign := -1
ELSIF TWord.LT (y, x) THEN
Index: m3front/src/exprs/ArrayExpr.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/ArrayExpr.m3,v
retrieving revision 1.6
diff -c -r1.6 ArrayExpr.m3
*** m3front/src/exprs/ArrayExpr.m3 18 Sep 2007 20:25:54 -0000 1.6
--- m3front/src/exprs/ArrayExpr.m3 18 Feb 2010 02:30:52 -0000
***************
*** 103,117 ****
END;
IF p.index = NIL THEN
min := TInt.Zero (* FIRST (p.args^) *);
! b := TInt.FromInt (LAST (p.args^), Target.Integer.bytes, max);
! <* ASSERT b *>
ELSE
EVAL Type.GetBounds (p.index, min, max);
END;
(* correct for the base index of the array *)
IF NOT TInt.Subtract (int, min, offs) THEN RETURN FALSE END;
! IF TInt.LT (offs, TInt.Zero) THEN RETURN FALSE END;
b := TInt.ToInt (offs, i); <* ASSERT b *>
n := LAST (p.args^);
--- 103,116 ----
END;
IF p.index = NIL THEN
min := TInt.Zero (* FIRST (p.args^) *);
! b := TInt.FromInt (LAST (p.args^), max); <* ASSERT b *>
ELSE
EVAL Type.GetBounds (p.index, min, max);
END;
(* correct for the base index of the array *)
IF NOT TInt.Subtract (int, min, offs) THEN RETURN FALSE END;
! IF TInt.LT (offs, TInt.Zero) THEN RETURN FALSE END;
b := TInt.ToInt (offs, i); <* ASSERT b *>
n := LAST (p.args^);
***************
*** 125,140 ****
BEGIN
TYPECASE array OF
| NULL => RETURN FALSE;
! | P(p) => IF p.index = NIL THEN
! (* open array type *)
! min := TInt.Zero (* FIRST (p.args^) *);
! b := TInt.FromInt (LAST (p.args^), Target.Integer.bytes, max);
! <*ASSERT b*>
! RETURN TRUE;
! ELSE
! RETURN Type.GetBounds (p.index, min, max);
! END;
! ELSE RETURN FALSE;
END;
END GetBounds;
--- 124,140 ----
BEGIN
TYPECASE array OF
| NULL => RETURN FALSE;
! | P(p) =>
! IF p.index = NIL THEN
! (* open array type *)
! min := TInt.Zero (* FIRST (p.args^) *);
! b := TInt.FromInt (LAST (p.args^), max); <*ASSERT b*>
! RETURN TRUE;
! ELSE
! RETURN Type.GetBounds (p.index, min, max);
! END;
! ELSE
! RETURN FALSE;
END;
END GetBounds;
***************
*** 214,220 ****
END;
IF (solidElt # NIL)
! AND TInt.FromInt (LAST (p.args^), Target.Integer.bytes, nn) THEN
p.kind := Kind.FixedOpen;
index := SubrangeType.New (TInt.Zero, nn, Int.T, FALSE);
p.solidType := ArrayType.New (index, solidElt);
--- 214,222 ----
END;
IF (solidElt # NIL)
! AND TInt.FromInt (LAST (p.args^), nn)
! AND NOT TInt.LT (nn, Target.Integer.min)
! AND NOT TInt.LT (Target.Integer.max, nn) THEN
p.kind := Kind.FixedOpen;
index := SubrangeType.New (TInt.Zero, nn, Int.T, FALSE);
p.solidType := ArrayType.New (index, solidElt);
***************
*** 335,341 ****
EVAL Type.CheckInfo (p.tipe, info);
align := info.alignment;
b := TInt.ToInt (nn_elts, n_elts); <*ASSERT b*>
! b := TInt.FromInt (n_args, Target.Integer.bytes, nn_args); <*ASSERT b*>
(* If this is a direct structure assignment, the LHS has already
* been prepped and compiled -- save it.
--- 337,343 ----
EVAL Type.CheckInfo (p.tipe, info);
align := info.alignment;
b := TInt.ToInt (nn_elts, n_elts); <*ASSERT b*>
! b := TInt.FromInt (n_args, nn_args); <*ASSERT b*>
(* If this is a direct structure assignment, the LHS has already
* been prepped and compiled -- save it.
Index: m3front/src/exprs/Expr.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/Expr.m3,v
retrieving revision 1.8
diff -c -r1.8 Expr.m3
*** m3front/src/exprs/Expr.m3 25 Sep 2009 02:42:12 -0000 1.8
--- m3front/src/exprs/Expr.m3 18 Feb 2010 02:30:52 -0000
***************
*** 98,104 ****
GetBounds (t, min, max);
IF TInt.LE (TInt.Zero, min) THEN RETURN CG.Sign.Positive;
ELSIF TInt.LE (max, TInt.Zero) THEN RETURN CG.Sign.Negative;
! ELSE RETURN CG.Sign.Unknown;
END;
END GetSign;
--- 98,104 ----
GetBounds (t, min, max);
IF TInt.LE (TInt.Zero, min) THEN RETURN CG.Sign.Positive;
ELSIF TInt.LE (max, TInt.Zero) THEN RETURN CG.Sign.Negative;
! ELSE RETURN CG.Sign.Unknown;
END;
END GetSign;
Index: m3front/src/exprs/IntegerExpr.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/IntegerExpr.m3,v
retrieving revision 1.9
diff -c -r1.9 IntegerExpr.m3
*** m3front/src/exprs/IntegerExpr.m3 8 Feb 2010 13:02:20 -0000 1.9
--- m3front/src/exprs/IntegerExpr.m3 18 Feb 2010 02:30:52 -0000
***************
*** 38,58 ****
VAR cache := ARRAY BOOLEAN, [-7 .. 64] OF P {ARRAY [-7 .. 64] OF P{NIL, ..},..};
PROCEDURE New (type: Type.T; READONLY value: Target.Int): Expr.T =
! VAR p: P; n: INTEGER; v: Target.Int; t := type = LInt.T;
BEGIN
IF TInt.ToInt (value, n)
AND (FIRST (cache[t]) <= n) AND (n <= LAST (cache[t])) THEN
p := cache[t][n];
IF (p # NIL) THEN RETURN p; END;
END;
! IF type = Int.T THEN
! IF NOT TInt.IntI (value, Target.Integer.bytes, v) THEN RETURN NIL END;
! ELSIF type = LInt.T THEN
! IF NOT TInt.IntI (value, Target.Longint.bytes, v) THEN RETURN NIL END;
! ELSE RETURN NIL END;
p := NEW (P);
ExprRep.Init (p);
! p.value := v;
p.type := type;
p.checked := TRUE;
IF TInt.ToInt (value, n)
--- 38,59 ----
VAR cache := ARRAY BOOLEAN, [-7 .. 64] OF P {ARRAY [-7 .. 64] OF P{NIL, ..},..};
PROCEDURE New (type: Type.T; READONLY value: Target.Int): Expr.T =
! VAR p: P; n: INTEGER; t := Type.IsSubtype (type, LInt.T);
! min, max: Target.Int;
BEGIN
IF TInt.ToInt (value, n)
AND (FIRST (cache[t]) <= n) AND (n <= LAST (cache[t])) THEN
p := cache[t][n];
IF (p # NIL) THEN RETURN p; END;
END;
! IF NOT Type.GetBounds (type, min, max)
! OR TInt.LT (value, min)
! OR TInt.LT (max, value) THEN
! <*ASSERT FALSE*>
! END;
p := NEW (P);
ExprRep.Init (p);
! p.value := value;
p.type := type;
p.checked := TRUE;
IF TInt.ToInt (value, n)
***************
*** 94,127 ****
END Compare;
PROCEDURE Add (a, b: Expr.T; VAR c: Expr.T): BOOLEAN =
! VAR x, y, res: Target.Int; t: Type.T;
BEGIN
IF NOT SplitPair (a, b, x, y, t) THEN RETURN FALSE END;
IF NOT TInt.Add (x, y, res) THEN RETURN FALSE END;
c := New (t, res);
! RETURN c # NIL;
END Add;
PROCEDURE Subtract (a, b: Expr.T; VAR c: Expr.T): BOOLEAN =
! VAR x, y, res: Target.Int; t: Type.T;
BEGIN
IF NOT SplitPair (a, b, x, y, t) THEN RETURN FALSE END;
IF NOT TInt.Subtract (x, y, res) THEN RETURN FALSE END;
c := New (t, res);
! RETURN c # NIL;
END Subtract;
PROCEDURE Multiply (a, b: Expr.T; VAR c: Expr.T): BOOLEAN =
! VAR x, y, res: Target.Int; t: Type.T;
BEGIN
IF NOT SplitPair (a, b, x, y, t) THEN RETURN FALSE END;
IF NOT TInt.Multiply (x, y, res) THEN RETURN FALSE END;
c := New (t, res);
! RETURN c # NIL;
END Multiply;
PROCEDURE Div (a, b: Expr.T; VAR c: Expr.T): BOOLEAN =
! VAR x, y, res: Target.Int; t: Type.T;
BEGIN
IF NOT SplitPair (a, b, x, y, t) THEN RETURN FALSE END;
IF TInt.EQ (y, TInt.Zero) THEN
--- 95,134 ----
END Compare;
PROCEDURE Add (a, b: Expr.T; VAR c: Expr.T): BOOLEAN =
! VAR x, y, min, max, res: Target.Int; t: Type.T;
BEGIN
IF NOT SplitPair (a, b, x, y, t) THEN RETURN FALSE END;
IF NOT TInt.Add (x, y, res) THEN RETURN FALSE END;
+ IF NOT Type.GetBounds (t, min, max) THEN RETURN FALSE END;
+ IF TInt.LT (res, min) OR TInt.LT (max, res) THEN RETURN FALSE END;
c := New (t, res);
! RETURN TRUE;
END Add;
PROCEDURE Subtract (a, b: Expr.T; VAR c: Expr.T): BOOLEAN =
! VAR x, y, min, max, res: Target.Int; t: Type.T;
BEGIN
IF NOT SplitPair (a, b, x, y, t) THEN RETURN FALSE END;
IF NOT TInt.Subtract (x, y, res) THEN RETURN FALSE END;
+ IF NOT Type.GetBounds (t, min, max) THEN RETURN FALSE END;
+ IF TInt.LT (res, min) OR TInt.LT (max, res) THEN RETURN FALSE END;
c := New (t, res);
! RETURN TRUE;
END Subtract;
PROCEDURE Multiply (a, b: Expr.T; VAR c: Expr.T): BOOLEAN =
! VAR x, y, min, max, res: Target.Int; t: Type.T;
BEGIN
IF NOT SplitPair (a, b, x, y, t) THEN RETURN FALSE END;
IF NOT TInt.Multiply (x, y, res) THEN RETURN FALSE END;
+ IF NOT Type.GetBounds (t, min, max) THEN RETURN FALSE END;
+ IF TInt.LT (res, min) OR TInt.LT (max, res) THEN RETURN FALSE END;
c := New (t, res);
! RETURN TRUE;
END Multiply;
PROCEDURE Div (a, b: Expr.T; VAR c: Expr.T): BOOLEAN =
! VAR x, y, min, max, res: Target.Int; t: Type.T;
BEGIN
IF NOT SplitPair (a, b, x, y, t) THEN RETURN FALSE END;
IF TInt.EQ (y, TInt.Zero) THEN
***************
*** 129,140 ****
RETURN FALSE;
END;
IF NOT TInt.Div (x, y, res) THEN RETURN FALSE END;
c := New (t, res);
! RETURN c # NIL;
END Div;
PROCEDURE Mod (a, b: Expr.T; VAR c: Expr.T): BOOLEAN =
! VAR x, y, res: Target.Int; t: Type.T;
BEGIN
IF NOT SplitPair (a, b, x, y, t) THEN RETURN FALSE END;
IF TInt.EQ (y, TInt.Zero) THEN
--- 136,149 ----
RETURN FALSE;
END;
IF NOT TInt.Div (x, y, res) THEN RETURN FALSE END;
+ IF NOT Type.GetBounds (t, min, max) THEN RETURN FALSE END;
+ IF TInt.LT (res, min) OR TInt.LT (max, res) THEN RETURN FALSE END;
c := New (t, res);
! RETURN TRUE;
END Div;
PROCEDURE Mod (a, b: Expr.T; VAR c: Expr.T): BOOLEAN =
! VAR x, y, min, max, res: Target.Int; t: Type.T;
BEGIN
IF NOT SplitPair (a, b, x, y, t) THEN RETURN FALSE END;
IF TInt.EQ (y, TInt.Zero) THEN
***************
*** 142,190 ****
RETURN FALSE;
END;
IF NOT TInt.Mod (x, y, res) THEN RETURN FALSE END;
c := New (t, res);
! RETURN c # NIL;
END Mod;
PROCEDURE Negate (a: Expr.T; VAR c: Expr.T): BOOLEAN =
! VAR res: Target.Int;
BEGIN
! TYPECASE a OF
! | NULL => RETURN FALSE;
! | P(p) => IF NOT TInt.Subtract (TInt.Zero, p.value, res) THEN
! RETURN FALSE;
! END;
! c := New (p.type, res); RETURN c # NIL;
! ELSE RETURN FALSE;
! END;
END Negate;
PROCEDURE Abs (a: Expr.T; VAR c: Expr.T): BOOLEAN =
! VAR res: Target.Int;
BEGIN
! TYPECASE a OF
! | NULL => RETURN FALSE;
! | P(p) => IF TInt.LE (TInt.Zero, p.value) THEN
! c := a; RETURN TRUE;
! END;
! IF NOT TInt.Subtract (TInt.Zero, p.value, res) THEN
! RETURN FALSE;
! END;
! c := New (p.type, res); RETURN c # NIL;
! ELSE RETURN FALSE;
END;
END Abs;
PROCEDURE ToInt (a: Expr.T; VAR i: INTEGER): BOOLEAN =
BEGIN
! TYPECASE a OF
! | NULL => RETURN FALSE;
! | P(p) => IF NOT TInt.ToInt (p.value, i) THEN
! RETURN FALSE;
! END;
! RETURN TRUE;
! ELSE RETURN FALSE;
! END;
END ToInt;
PROCEDURE SplitPair (a, b: Expr.T; VAR x, y: Target.Int; VAR t: Type.T):
--- 151,194 ----
RETURN FALSE;
END;
IF NOT TInt.Mod (x, y, res) THEN RETURN FALSE END;
+ IF NOT Type.GetBounds (t, min, max) THEN RETURN FALSE END;
+ IF TInt.LT (res, min) OR TInt.LT (max, res) THEN RETURN FALSE END;
c := New (t, res);
! RETURN TRUE;
END Mod;
PROCEDURE Negate (a: Expr.T; VAR c: Expr.T): BOOLEAN =
! VAR x, min, max, res: Target.Int; t: Type.T;
BEGIN
! IF NOT Split (a, x, t) THEN RETURN FALSE END;
! IF NOT TInt.Subtract (TInt.Zero, x, res) THEN RETURN FALSE END;
! IF NOT Type.GetBounds (t, min, max) THEN RETURN FALSE END;
! IF TInt.LT (res, min) OR TInt.LT (max, res) THEN RETURN FALSE END;
! c := New (t, res);
! RETURN TRUE;
END Negate;
PROCEDURE Abs (a: Expr.T; VAR c: Expr.T): BOOLEAN =
! VAR x, min, max, res: Target.Int; t: Type.T;
BEGIN
! IF NOT Split (a, x, t) THEN RETURN FALSE END;
! IF TInt.LT (x, TInt.Zero) THEN
! IF NOT TInt.Subtract (TInt.Zero, x, res) THEN RETURN FALSE END;
! IF NOT Type.GetBounds (t, min, max) THEN RETURN FALSE END;
! IF TInt.LT (res, min) OR TInt.LT (max, res) THEN RETURN FALSE END;
! c := New (t, res);
! ELSE
! c := a;
END;
+ RETURN TRUE;
END Abs;
PROCEDURE ToInt (a: Expr.T; VAR i: INTEGER): BOOLEAN =
+ VAR x: Target.Int; t: Type.T;
BEGIN
! IF NOT Split (a, x, t) THEN RETURN FALSE END;
! IF NOT TInt.ToInt (x, i) THEN RETURN FALSE END;
! RETURN TRUE;
END ToInt;
PROCEDURE SplitPair (a, b: Expr.T; VAR x, y: Target.Int; VAR t: Type.T):
Index: m3front/src/exprs/ModExpr.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/ModExpr.m3,v
retrieving revision 1.5
diff -c -r1.5 ModExpr.m3
*** m3front/src/exprs/ModExpr.m3 4 May 2008 11:03:46 -0000 1.5
--- m3front/src/exprs/ModExpr.m3 18 Feb 2010 02:30:52 -0000
***************
*** 181,202 ****
END Fold;
PROCEDURE GetBounds (p: P; VAR min, max: Target.Int) =
! VAR min_b, max_b: Target.Int;
! OneI := Target.Int{Target.Integer.bytes, Target.IBytes{1,0,..}};
! OneL := Target.Int{Target.Longint.bytes, Target.IBytes{1,0,..}};
! One := ARRAY[Class.cINT..Class.cLINT] OF Target.Int { OneI, OneL };
! MaxI := Target.Integer.max;
! MaxL := Target.Longint.max;
! Max := ARRAY [Class.cINT..Class.cLINT] OF Target.Int { MaxI, MaxL };
BEGIN
IF (p.class = Class.cINT) OR (p.class = Class.cLINT) THEN
Expr.GetBounds (p.b, min_b, max_b);
IF TInt.LT (min_b, TInt.Zero) OR TInt.LT (max_b, TInt.Zero) THEN
ExprRep.NoBounds (p, min, max);
ELSE
min := TInt.Zero;
! IF NOT TInt.Subtract (max_b, One[p.class], max) THEN
! max := Max[p.class];
END;
END;
ELSE
--- 181,198 ----
END Fold;
PROCEDURE GetBounds (p: P; VAR min, max: Target.Int) =
! VAR tmin, tmax, min_b, max_b: Target.Int;
BEGIN
IF (p.class = Class.cINT) OR (p.class = Class.cLINT) THEN
+ EVAL Type.GetBounds (p.type, tmin, tmax);
Expr.GetBounds (p.b, min_b, max_b);
IF TInt.LT (min_b, TInt.Zero) OR TInt.LT (max_b, TInt.Zero) THEN
ExprRep.NoBounds (p, min, max);
ELSE
min := TInt.Zero;
! IF NOT TInt.Subtract (max_b, TInt.One, max)
! OR TInt.LT (max, tmin) OR TInt.LT (tmax, max) THEN
! max := tmax;
END;
END;
ELSE
Index: m3front/src/exprs/ReelExpr.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/ReelExpr.m3,v
retrieving revision 1.6
diff -c -r1.6 ReelExpr.m3
*** m3front/src/exprs/ReelExpr.m3 8 Feb 2010 12:03:31 -0000 1.6
--- m3front/src/exprs/ReelExpr.m3 18 Feb 2010 02:30:52 -0000
***************
*** 9,15 ****
MODULE ReelExpr;
IMPORT M3, CG, Expr, ExprRep, Type, Target, TInt, TFloat;
! IMPORT M3Buf, Int, LInt, Reel, LReel, EReel, IntegerExpr;
TYPE
P = Expr.T OBJECT
--- 9,15 ----
MODULE ReelExpr;
IMPORT M3, CG, Expr, ExprRep, Type, Target, TInt, TFloat;
! IMPORT M3Buf, Reel, LReel, EReel, IntegerExpr;
TYPE
P = Expr.T OBJECT
***************
*** 172,222 ****
END Abs;
PROCEDURE Floor (a: Expr.T; t: Type.T; VAR c: Expr.T): BOOLEAN =
! VAR x: Target.Float; res: Target.Int; n: CARDINAL;
BEGIN
- IF t = Int.T THEN n := Target.Integer.bytes;
- ELSIF t = LInt.T THEN n := Target.Longint.bytes;
- ELSE RETURN FALSE END;
IF NOT Split (a, x) THEN RETURN FALSE END;
! IF NOT TInt.FromInt (TFloat.Floor (x), n, res) THEN RETURN FALSE END;
c := IntegerExpr.New (t, res);
! RETURN c # NIL;
END Floor;
PROCEDURE Ceiling (a: Expr.T; t: Type.T; VAR c: Expr.T): BOOLEAN =
! VAR x: Target.Float; res: Target.Int; n: CARDINAL;
BEGIN
- IF t = Int.T THEN n := Target.Integer.bytes;
- ELSIF t = LInt.T THEN n := Target.Longint.bytes;
- ELSE RETURN FALSE END;
IF NOT Split (a, x) THEN RETURN FALSE END;
! IF NOT TInt.FromInt (TFloat.Ceiling (x), n, res) THEN RETURN FALSE END;
c := IntegerExpr.New (t, res);
! RETURN c # NIL;
END Ceiling;
PROCEDURE Trunc (a: Expr.T; t: Type.T; VAR c: Expr.T): BOOLEAN =
! VAR x: Target.Float; res: Target.Int; n: CARDINAL;
BEGIN
- IF t = Int.T THEN n := Target.Integer.bytes;
- ELSIF t = LInt.T THEN n := Target.Longint.bytes;
- ELSE RETURN FALSE END;
IF NOT Split (a, x) THEN RETURN FALSE END;
! IF NOT TInt.FromInt (TFloat.Trunc (x), n, res) THEN RETURN FALSE END;
c := IntegerExpr.New (t, res);
! RETURN c # NIL;
END Trunc;
PROCEDURE Round (a: Expr.T; t: Type.T; VAR c: Expr.T): BOOLEAN =
! VAR x: Target.Float; res: Target.Int; n: CARDINAL;
BEGIN
- IF t = Int.T THEN n := Target.Integer.bytes;
- ELSIF t = LInt.T THEN n := Target.Longint.bytes;
- ELSE RETURN FALSE END;
IF NOT Split (a, x) THEN RETURN FALSE END;
! IF NOT TInt.FromInt (TFloat.Round (x), n, res) THEN RETURN FALSE END;
c := IntegerExpr.New (t, res);
! RETURN c # NIL;
END Round;
PROCEDURE Float (a: Expr.T; t: Type.T; VAR c: Expr.T): BOOLEAN =
--- 172,218 ----
END Abs;
PROCEDURE Floor (a: Expr.T; t: Type.T; VAR c: Expr.T): BOOLEAN =
! VAR x: Target.Float; min, max, res: Target.Int;
BEGIN
IF NOT Split (a, x) THEN RETURN FALSE END;
! IF NOT TInt.FromInt (TFloat.Floor (x), res) THEN RETURN FALSE END;
! IF NOT Type.GetBounds (t, min, max) THEN RETURN FALSE END;
! IF TInt.LT (res, min) OR TInt.LT (max, res) THEN RETURN FALSE END;
c := IntegerExpr.New (t, res);
! RETURN TRUE;
END Floor;
PROCEDURE Ceiling (a: Expr.T; t: Type.T; VAR c: Expr.T): BOOLEAN =
! VAR x: Target.Float; min, max, res: Target.Int;
BEGIN
IF NOT Split (a, x) THEN RETURN FALSE END;
! IF NOT TInt.FromInt (TFloat.Ceiling (x), res) THEN RETURN FALSE END;
! IF NOT Type.GetBounds (t, min, max) THEN RETURN FALSE END;
! IF TInt.LT (res, min) OR TInt.LT (max, res) THEN RETURN FALSE END;
c := IntegerExpr.New (t, res);
! RETURN TRUE;
END Ceiling;
PROCEDURE Trunc (a: Expr.T; t: Type.T; VAR c: Expr.T): BOOLEAN =
! VAR x: Target.Float; min, max, res: Target.Int;
BEGIN
IF NOT Split (a, x) THEN RETURN FALSE END;
! IF NOT TInt.FromInt (TFloat.Trunc (x), res) THEN RETURN FALSE END;
! IF NOT Type.GetBounds (t, min, max) THEN RETURN FALSE END;
! IF TInt.LT (res, min) OR TInt.LT (max, res) THEN RETURN FALSE END;
c := IntegerExpr.New (t, res);
! RETURN TRUE;
END Trunc;
PROCEDURE Round (a: Expr.T; t: Type.T; VAR c: Expr.T): BOOLEAN =
! VAR x: Target.Float; min, max, res: Target.Int;
BEGIN
IF NOT Split (a, x) THEN RETURN FALSE END;
! IF NOT TInt.FromInt (TFloat.Round (x), res) THEN RETURN FALSE END;
! IF NOT Type.GetBounds (t, min, max) THEN RETURN FALSE END;
! IF TInt.LT (res, min) OR TInt.LT (max, res) THEN RETURN FALSE END;
c := IntegerExpr.New (t, res);
! RETURN TRUE;
END Round;
PROCEDURE Float (a: Expr.T; t: Type.T; VAR c: Expr.T): BOOLEAN =
Index: m3front/src/exprs/SetExpr.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/SetExpr.m3,v
retrieving revision 1.6
diff -c -r1.6 SetExpr.m3
*** m3front/src/exprs/SetExpr.m3 2 Jan 2010 21:31:48 -0000 1.6
--- m3front/src/exprs/SetExpr.m3 18 Feb 2010 02:30:52 -0000
***************
*** 10,16 ****
IMPORT M3, CG, Expr, ExprRep, Type, Error, IntegerExpr, EnumExpr;
IMPORT RangeExpr, KeywordExpr, SetType, AssignStmt, CheckExpr;
! IMPORT M3ID, Target, TInt, TWord, Bool, M3Buf, Module;
TYPE
Node = REF RECORD
--- 10,16 ----
IMPORT M3, CG, Expr, ExprRep, Type, Error, IntegerExpr, EnumExpr;
IMPORT RangeExpr, KeywordExpr, SetType, AssignStmt, CheckExpr;
! IMPORT M3ID, Target, TInt, TWord, Bool, M3Buf, Module, Text;
TYPE
Node = REF RECORD
***************
*** 564,579 ****
END;
END Compile;
- PROCEDURE TargetIntToDiagnosticText(name: TEXT; a: Target.Int): TEXT =
- VAR t := "";
- b: INTEGER;
- BEGIN
- IF NOT TInt.ToInt(a, b) THEN
- t := "**";
- END;
- RETURN t & name & ":" & Target.TargetIntToDiagnosticText(a);
- END TargetIntToDiagnosticText;
-
PROCEDURE CompileBig (p: P; VAR info: Type.Info): CG.Var =
VAR
range : Type.T;
--- 564,569 ----
***************
*** 590,603 ****
n : Node;
b : BOOLEAN;
tmp : Target.Int;
BEGIN
b := SetType.Split (p.tipe, range); <* ASSERT b *>
EVAL Type.GetBounds (range, min_T, max_T);
IF NOT TInt.ToInt (min_T, minT)
OR NOT TInt.ToInt (max_T, maxT) THEN
! Error.Msg ("set domain too large ("
! & TargetIntToDiagnosticText("min", min_T)
! & "," & TargetIntToDiagnosticText("max", max_T) & ")");
minT := FIRST (INTEGER);
maxT := LAST (INTEGER);
END;
--- 580,594 ----
n : Node;
b : BOOLEAN;
tmp : Target.Int;
+ buf: ARRAY [0..TInt.Size] OF CHAR;
BEGIN
b := SetType.Split (p.tipe, range); <* ASSERT b *>
EVAL Type.GetBounds (range, min_T, max_T);
IF NOT TInt.ToInt (min_T, minT)
OR NOT TInt.ToInt (max_T, maxT) THEN
! Error.Msg ("set domain too large (" &
! Text.FromChars (SUBARRAY(buf, 0, TInt.ToChars(min_T, buf))) & ".." &
! Text.FromChars (SUBARRAY(buf, 0, TInt.ToChars(max_T, buf))) & ")");
minT := FIRST (INTEGER);
maxT := LAST (INTEGER);
END;
***************
*** 659,666 ****
PROCEDURE EmitAssign (set: CG.Var; index: INTEGER;
READONLY value: Target.Int) =
BEGIN
! CG.Load_integer (Target.Integer.cg_type, value);
CG.Store_int (Target.Integer.cg_type, set, index * Grain);
<* ASSERT Grain = Target.Integer.size *>
END EmitAssign;
--- 650,659 ----
PROCEDURE EmitAssign (set: CG.Var; index: INTEGER;
READONLY value: Target.Int) =
+ VAR tmp := value;
BEGIN
! TInt.Chop (tmp, Target.Integer.bytes);
! CG.Load_integer (Target.Integer.cg_type, tmp);
CG.Store_int (Target.Integer.cg_type, set, index * Grain);
<* ASSERT Grain = Target.Integer.size *>
END EmitAssign;
***************
*** 689,694 ****
--- 682,688 ----
n : Node;
b : BOOLEAN;
tmp : Target.Int;
+ buf: ARRAY [0..TInt.Size] OF CHAR;
BEGIN
Type.Compile (p.tipe);
nWords := info.size DIV Grain;
***************
*** 699,707 ****
EVAL Type.GetBounds (range, min_T, max_T);
IF NOT TInt.ToInt (min_T, minT)
OR NOT TInt.ToInt (max_T, maxT) THEN
! Error.Msg ("set domain too large ("
! & TargetIntToDiagnosticText("min", min_T)
! & "," & TargetIntToDiagnosticText("max", max_T) & ")");
minT := FIRST (INTEGER);
maxT := LAST (INTEGER);
END;
--- 693,701 ----
EVAL Type.GetBounds (range, min_T, max_T);
IF NOT TInt.ToInt (min_T, minT)
OR NOT TInt.ToInt (max_T, maxT) THEN
! Error.Msg ("set domain too large (" &
! Text.FromChars (SUBARRAY(buf, 0, TInt.ToChars(min_T, buf))) & ".." &
! Text.FromChars (SUBARRAY(buf, 0, TInt.ToChars(max_T, buf))) & ")");
minT := FIRST (INTEGER);
maxT := LAST (INTEGER);
END;
***************
*** 793,800 ****
IF (w1 # curWord) THEN
(* write the mask we've accumulated *)
IF NOT TInt.EQ (curMask, TInt.Zero) THEN
CG.Init_int (offset + curWord*Target.Integer.pack,
! Target.Integer.size, curMask, is_const);
END;
curWord := w1;
curMask := TInt.Zero;
--- 787,796 ----
IF (w1 # curWord) THEN
(* write the mask we've accumulated *)
IF NOT TInt.EQ (curMask, TInt.Zero) THEN
+ tmp := curMask;
+ TInt.Chop (tmp, Target.Integer.bytes);
CG.Init_int (offset + curWord*Target.Integer.pack,
! Target.Integer.size, tmp, is_const);
END;
curWord := w1;
curMask := TInt.Zero;
***************
*** 802,812 ****
IF (w1 # w2) THEN
(* write the full words [w1..w2-1] *)
TWord.Or (curMask, left [b1], tmp);
CG.Init_int (offset + w1 * Target.Integer.pack, Target.Integer.size,
tmp, is_const);
FOR i := w1 + 1 TO w2 - 1 DO
CG.Init_int (offset + i * Target.Integer.pack, Target.Integer.size,
! full, is_const);
END;
curWord := w2;
curMask := right [b2];
--- 798,811 ----
IF (w1 # w2) THEN
(* write the full words [w1..w2-1] *)
TWord.Or (curMask, left [b1], tmp);
+ TInt.Chop (tmp, Target.Integer.bytes);
CG.Init_int (offset + w1 * Target.Integer.pack, Target.Integer.size,
tmp, is_const);
FOR i := w1 + 1 TO w2 - 1 DO
+ tmp := full;
+ TInt.Chop (tmp, Target.Integer.bytes);
CG.Init_int (offset + i * Target.Integer.pack, Target.Integer.size,
! tmp, is_const);
END;
curWord := w2;
curMask := right [b2];
***************
*** 819,837 ****
(* write the last mask *)
IF NOT TInt.EQ (curMask, TInt.Zero) THEN
CG.Init_int (offset + curWord * Target.Integer.pack,
! Target.Integer.size, curMask, is_const);
END;
END GenLiteral;
PROCEDURE Init () =
- VAR Zero := Target.Int{Target.Integer.bytes, Target.IBytes{0,..}};
BEGIN
Grain := MAX (Target.Integer.size, Target.Set_grain);
! TWord.Not (Zero, full);
FOR i := 0 TO Grain - 1 DO
TWord.Shift (full, i + 1 - Grain, right [i]);
TWord.Shift (full, i, left [i]);
END;
END Init;
--- 818,840 ----
(* write the last mask *)
IF NOT TInt.EQ (curMask, TInt.Zero) THEN
+ tmp := curMask;
+ TInt.Chop (tmp, Target.Integer.bytes);
CG.Init_int (offset + curWord * Target.Integer.pack,
! Target.Integer.size, tmp, is_const);
END;
END GenLiteral;
PROCEDURE Init () =
BEGIN
Grain := MAX (Target.Integer.size, Target.Set_grain);
! TWord.Not (TInt.Zero, full);
! TWord.And (full, Target.Word.max, full);
FOR i := 0 TO Grain - 1 DO
TWord.Shift (full, i + 1 - Grain, right [i]);
+ TWord.And (right[i], Target.Word.max, right[i]);
TWord.Shift (full, i, left [i]);
+ TWord.And (left[i], Target.Word.max, left[i]);
END;
END Init;
Index: m3front/src/exprs/SubtractExpr.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/exprs/SubtractExpr.m3,v
retrieving revision 1.5
diff -c -r1.5 SubtractExpr.m3
*** m3front/src/exprs/SubtractExpr.m3 10 Jan 2010 05:12:18 -0000 1.5
--- m3front/src/exprs/SubtractExpr.m3 18 Feb 2010 02:30:52 -0000
***************
*** 62,68 ****
VAR ta: Type.T;
BEGIN
ta := Type.Base (Expr.TypeOf (p.a));
! IF (p.extended) THEN
ta := Int.T;
ELSIF Type.IsSubtype (ta, Addr.T) AND
Type.IsSubtype (Type.Base (Expr.TypeOf (p.b)), Addr.T) THEN
--- 62,68 ----
VAR ta: Type.T;
BEGIN
ta := Type.Base (Expr.TypeOf (p.a));
! IF (p.extended) AND EnumType.Is (ta) THEN
ta := Int.T;
ELSIF Type.IsSubtype (ta, Addr.T) AND
Type.IsSubtype (Type.Base (Expr.TypeOf (p.b)), Addr.T) THEN
***************
*** 189,195 ****
ELSIF (p.extended)
AND EnumExpr.Split (e1, x1, t1)
AND IntegerExpr.Split (e2, x2, t1)
! AND TInt.Subtract (x1, x2, x3) THEN
e3 := IntegerExpr.New (t1, x3);
ELSIF ReelExpr.Subtract (e1, e2, e3) THEN
ELSIF AddressExpr.Subtract (e1, e2, e3) THEN
--- 189,197 ----
ELSIF (p.extended)
AND EnumExpr.Split (e1, x1, t1)
AND IntegerExpr.Split (e2, x2, t1)
! AND TInt.Subtract (x1, x2, x3)
! AND NOT TInt.LT (x3, Target.Integer.min)
! AND NOT TInt.LT (Target.Integer.max, x3) THEN
e3 := IntegerExpr.New (t1, x3);
ELSIF ReelExpr.Subtract (e1, e2, e3) THEN
ELSIF AddressExpr.Subtract (e1, e2, e3) THEN
***************
*** 205,211 ****
Expr.GetBounds (p.a, min_a, max_a);
Expr.GetBounds (p.b, min_b, max_b);
IF TInt.Subtract (min_a, max_b, smin)
! AND TInt.Subtract (max_a, min_b, smax) THEN
IF TInt.LT (min, smin) THEN min := smin END;
IF TInt.LT (smax, max) THEN max := smax END;
END;
--- 207,215 ----
Expr.GetBounds (p.a, min_a, max_a);
Expr.GetBounds (p.b, min_b, max_b);
IF TInt.Subtract (min_a, max_b, smin)
! AND NOT TInt.LT (smin, min) AND NOT TInt.LT (max, smin)
! AND TInt.Subtract (max_a, min_b, smax)
! AND NOT TInt.LT (smax, min) AND NOT TInt.LT (max, smax) THEN
IF TInt.LT (min, smin) THEN min := smin END;
IF TInt.LT (smax, max) THEN max := smax END;
END;
Index: m3front/src/misc/CG.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/CG.m3,v
retrieving revision 1.35
diff -c -r1.35 CG.m3
*** m3front/src/misc/CG.m3 15 Feb 2010 05:07:07 -0000 1.35
--- m3front/src/misc/CG.m3 18 Feb 2010 02:30:53 -0000
***************
*** 940,946 ****
(* send out some number of bytes *)
EVAL FindInitType (n_bytes, init_pc, t);
size := TargetMap.CG_Size[t];
! excess := Target.Longint.size - size;
IF (excess = 0) THEN
cg.init_int (init_pc DIV Target.Byte, init_bits, t);
init_bits := TInt.Zero;
--- 940,946 ----
(* send out some number of bytes *)
EVAL FindInitType (n_bytes, init_pc, t);
size := TargetMap.CG_Size[t];
! excess := TWord.Size - size;
IF (excess = 0) THEN
cg.init_int (init_pc DIV Target.Byte, init_bits, t);
init_bits := TInt.Zero;
***************
*** 984,1001 ****
PROCEDURE Init_int (o: Offset; s: Size; READONLY value: Target.Int;
is_const: BOOLEAN) =
! VAR bit_offset: CARDINAL; itype: Type; v, tmp: Target.Int;
BEGIN
IF (NOT in_init) THEN
PushPending (NEW (IntNode, o := o, s := s, v := value), is_const);
RETURN;
END;
- EVAL TInt.IntI (value, Target.Longint.bytes, v);
AdvanceInit (o);
IF Target.Little_endian
THEN bit_offset := o - init_pc;
! ELSE bit_offset := Target.Longint.size - (o - init_pc) - s;
END;
IF (o = init_pc)
--- 984,1000 ----
PROCEDURE Init_int (o: Offset; s: Size; READONLY value: Target.Int;
is_const: BOOLEAN) =
! VAR bit_offset: CARDINAL; itype: Type; tmp: Target.Int;
BEGIN
IF (NOT in_init) THEN
PushPending (NEW (IntNode, o := o, s := s, v := value), is_const);
RETURN;
END;
AdvanceInit (o);
IF Target.Little_endian
THEN bit_offset := o - init_pc;
! ELSE bit_offset := TWord.Size - (o - init_pc) - s;
END;
IF (o = init_pc)
***************
*** 1003,1010 ****
AND (FindInitType (s DIV Target.Byte, init_pc, itype))
AND (TargetMap.CG_Size[itype] = s) THEN
(* simple, aligned integer initialization *)
! cg.init_int (o DIV Target.Byte, v, itype);
! ELSIF TWord.Insert (init_bits, v, bit_offset, s, tmp) THEN
init_bits := tmp;
ELSE
Err ("unable to stuff bit field value??");
--- 1002,1009 ----
AND (FindInitType (s DIV Target.Byte, init_pc, itype))
AND (TargetMap.CG_Size[itype] = s) THEN
(* simple, aligned integer initialization *)
! cg.init_int (o DIV Target.Byte, value, itype);
! ELSIF TWord.Insert (init_bits, value, bit_offset, s, tmp) THEN
init_bits := tmp;
ELSE
Err ("unable to stuff bit field value??");
***************
*** 1013,1021 ****
END Init_int;
PROCEDURE Init_intt (o: Offset; s: Size; value: INTEGER; is_const: BOOLEAN) =
! VAR val: Target.Int; b := TInt.FromInt (value, Target.Integer.bytes, val);
BEGIN
! IF NOT b THEN ErrI (value, "integer const not representable") END;
Init_int (o, s, val, is_const);
END Init_intt;
--- 1012,1023 ----
END Init_int;
PROCEDURE Init_intt (o: Offset; s: Size; value: INTEGER; is_const: BOOLEAN) =
! VAR val: Target.Int; b := TInt.FromInt (value, val);
BEGIN
! IF NOT b
! OR TInt.LT (val, Target.Integer.min)
! OR TInt.LT (Target.Integer.max, val)
! THEN ErrI (value, "integer const not representable") END;
Init_int (o, s, val, is_const);
END Init_intt;
***************
*** 1807,1815 ****
END Load_byte_address;
PROCEDURE Load_intt (i: INTEGER) =
! VAR val: Target.Int; b := TInt.FromInt (i, Target.Integer.bytes, val);
BEGIN
! IF NOT b THEN ErrI (i, "integer not representable") END;
Load_integer (Target.Integer.cg_type, val);
END Load_intt;
--- 1809,1820 ----
END Load_byte_address;
PROCEDURE Load_intt (i: INTEGER) =
! VAR val: Target.Int; b := TInt.FromInt (i, val);
BEGIN
! IF NOT b
! OR TInt.LT (val, Target.Integer.min)
! OR TInt.LT (Target.Integer.max, val)
! THEN ErrI (i, "integer not representable") END;
Load_integer (Target.Integer.cg_type, val);
END Load_intt;
***************
*** 2760,2768 ****
END AsBytes;
PROCEDURE Push_int (i: INTEGER) =
! VAR val: Target.Int; b := TInt.FromInt (i, Target.Integer.bytes, val);
BEGIN
! IF NOT b THEN ErrI (i, "integer not representable") END;
cg.load_integer (Target.Integer.cg_type, val);
END Push_int;
--- 2765,2776 ----
END AsBytes;
PROCEDURE Push_int (i: INTEGER) =
! VAR val: Target.Int; b := TInt.FromInt (i, val);
BEGIN
! IF NOT b
! OR TInt.LT (val, Target.Integer.min)
! OR TInt.LT (Target.Integer.max, val)
! THEN ErrI (i, "integer not representable") END;
cg.load_integer (Target.Integer.cg_type, val);
END Push_int;
Index: m3front/src/misc/Scanner.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/Scanner.m3,v
retrieving revision 1.7
diff -c -r1.7 Scanner.m3
*** m3front/src/misc/Scanner.m3 4 May 2008 11:03:47 -0000 1.7
--- m3front/src/misc/Scanner.m3 18 Feb 2010 02:30:53 -0000
***************
*** 509,515 ****
IF (ch = '_') THEN
(* scan a based integer *)
! IF NOT TInt.New (SUBARRAY (buf, 0, len), Target.Integer.bytes, val)
OR NOT TInt.ToInt (val, base)
OR (base < 2)
OR (16 < base) THEN
--- 509,515 ----
IF (ch = '_') THEN
(* scan a based integer *)
! IF NOT TInt.New (SUBARRAY (buf, 0, len), val)
OR NOT TInt.ToInt (val, base)
OR (base < 2)
OR (16 < base) THEN
***************
*** 524,542 ****
END;
IF (ch = 'l') OR (ch = 'L') THEN
GetCh (); (* eat the precision character *)
! IF (len = 0) OR NOT (TWord.New (SUBARRAY (buf, 0, len), base,
! Target.Long.bytes, val)) THEN
Error.Msg ("illegal based LONGINT literal, zero used");
val := TInt.Zero;
END;
cur.token := TK.tLONGINTCONST;
cur.int := val;
ELSE
! IF (len = 0) OR NOT (TWord.New (SUBARRAY (buf, 0, len), base,
! Target.Word.bytes, val)) THEN
Error.Msg ("illegal based INTEGER literal, zero used");
val := TInt.Zero;
END;
cur.token := TK.tINTEGERCONST;
cur.int := val;
END;
--- 524,546 ----
END;
IF (ch = 'l') OR (ch = 'L') THEN
GetCh (); (* eat the precision character *)
! IF (len = 0)
! OR NOT (TWord.New (SUBARRAY (buf, 0, len), base, val))
! OR TWord.LT (Target.Long.max, val) THEN
Error.Msg ("illegal based LONGINT literal, zero used");
val := TInt.Zero;
END;
+ TInt.Chop (val, Target.Longint.bytes);
cur.token := TK.tLONGINTCONST;
cur.int := val;
ELSE
! IF (len = 0)
! OR NOT TWord.New (SUBARRAY (buf, 0, len), base, val)
! OR TWord.LT (Target.Word.max, val) THEN
Error.Msg ("illegal based INTEGER literal, zero used");
val := TInt.Zero;
END;
+ TInt.Chop (val, Target.Integer.bytes);
cur.token := TK.tINTEGERCONST;
cur.int := val;
END;
***************
*** 551,558 ****
(***** Rd.UnGetChar (input); *****)
DEC (input_ptr); input_buf[input_ptr] := ORD ('.');
! IF NOT TInt.New (SUBARRAY (buf, 0, len-1),
! Target.Integer.bytes, val) THEN
Error.Msg ("illegal INTEGER literal, zero used");
val := TInt.Zero;
END;
--- 555,563 ----
(***** Rd.UnGetChar (input); *****)
DEC (input_ptr); input_buf[input_ptr] := ORD ('.');
! IF NOT TInt.New (SUBARRAY (buf, 0, len-1), val)
! OR TInt.LT (val, Target.Integer.min)
! OR TInt.LT (Target.Integer.max, val) THEN
Error.Msg ("illegal INTEGER literal, zero used");
val := TInt.Zero;
END;
***************
*** 617,632 ****
(* already scanned a decimal integer *)
IF (ch = 'l') OR (ch = 'L') THEN
GetCh (); (* eat the precision character *)
! IF NOT TInt.New (SUBARRAY (buf, 0, len),
! Target.Longint.bytes, val) THEN
Error.Msg ("illegal LONGINT literal, zero used");
val := TInt.Zero;
END;
cur.token := TK.tLONGINTCONST;
cur.int := val;
ELSE
! IF NOT TInt.New (SUBARRAY (buf, 0, len),
! Target.Integer.bytes, val) THEN
Error.Msg ("illegal INTEGER literal, zero used");
val := TInt.Zero;
END;
--- 622,639 ----
(* already scanned a decimal integer *)
IF (ch = 'l') OR (ch = 'L') THEN
GetCh (); (* eat the precision character *)
! IF NOT TInt.New (SUBARRAY (buf, 0, len), val)
! OR TInt.LT (val, Target.Longint.min)
! OR TInt.LT (Target.Longint.max, val) THEN
Error.Msg ("illegal LONGINT literal, zero used");
val := TInt.Zero;
END;
cur.token := TK.tLONGINTCONST;
cur.int := val;
ELSE
! IF NOT TInt.New (SUBARRAY (buf, 0, len), val)
! OR TInt.LT (val, Target.Integer.min)
! OR TInt.LT (Target.Integer.max, val) THEN
Error.Msg ("illegal INTEGER literal, zero used");
val := TInt.Zero;
END;
***************
*** 675,681 ****
THEN Error.Msg ("missing closing quote on character literal");
ELSE GetCh ();
END;
! IF NOT TInt.FromInt (val, Target.Integer.bytes, cur.int) THEN
Error.Msg ("illegal character literal");
END;
END ScanChar;
--- 682,688 ----
THEN Error.Msg ("missing closing quote on character literal");
ELSE GetCh ();
END;
! IF NOT TInt.FromInt (val, cur.int) THEN
Error.Msg ("illegal character literal");
END;
END ScanChar;
Index: m3front/src/misc/TipeDesc.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/misc/TipeDesc.m3,v
retrieving revision 1.5
diff -c -r1.5 TipeDesc.m3
*** m3front/src/misc/TipeDesc.m3 1 Apr 2008 00:02:58 -0000 1.5
--- m3front/src/misc/TipeDesc.m3 18 Feb 2010 02:30:53 -0000
***************
*** 145,155 ****
PROCEDURE AddBigX (READONLY ii: Target.Int) =
CONST Sign = ARRAY BOOLEAN OF INTEGER { 16_40, 16_c0 };
! VAR x: ARRAY [0..LAST (Target.IBytes)] OF [0..255];
key, n_bytes: INTEGER; i := ii;
BEGIN
key := Sign [TInt.LT (i, TInt.Zero)];
! IF (key # 16_40) THEN TWord.Subtract (TInt.Zero, ii, i); END;
(* extract the bytes *)
n_bytes := TInt.ToBytes (i, x);
--- 145,158 ----
PROCEDURE AddBigX (READONLY ii: Target.Int) =
CONST Sign = ARRAY BOOLEAN OF INTEGER { 16_40, 16_c0 };
! VAR x: ARRAY [0..LAST (Target.Int)] OF [0..255];
key, n_bytes: INTEGER; i := ii;
BEGIN
key := Sign [TInt.LT (i, TInt.Zero)];
! IF (key # 16_40) THEN
! TWord.Subtract (TInt.Zero, ii, i);
! TInt.Chop (i, Target.Integer.bytes);
! END;
(* extract the bytes *)
n_bytes := TInt.ToBytes (i, x);
Index: m3front/src/stmts/CaseStmt.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/stmts/CaseStmt.m3,v
retrieving revision 1.4
diff -c -r1.4 CaseStmt.m3
*** m3front/src/stmts/CaseStmt.m3 4 May 2008 11:03:48 -0000 1.4
--- m3front/src/stmts/CaseStmt.m3 18 Feb 2010 02:30:53 -0000
***************
*** 247,253 ****
PROCEDURE CompleteTree (t: Tree; min, max: Target.Int): BOOLEAN =
VAR x, y: Target.Int;
- One := Target.Int{Target.Integer.bytes, Target.IBytes{1,0,..}};
BEGIN
WHILE (t # NIL) DO
IF TInt.LT (t.max, min) OR TInt.LT (max, t.min) THEN
--- 247,252 ----
***************
*** 256,273 ****
IF TInt.Subtract (t.min, min, x)
AND TInt.Subtract (max, t.max, y)
AND TInt.LT (y, x) THEN
! IF TInt.Add (t.max, One, x) THEN
IF NOT CompleteTree (t.greater, x, max) THEN RETURN FALSE END;
END;
! IF NOT TInt.Subtract (t.min, One, max) THEN
RETURN TRUE;
END;
t := t.less;
ELSE
! IF TInt.Subtract (t.min, One, x) THEN
IF NOT CompleteTree (t.less, min, x) THEN RETURN FALSE END;
END;
! IF NOT TInt.Add (t.max, One, min) THEN
RETURN TRUE;
END;
t := t.greater;
--- 255,280 ----
IF TInt.Subtract (t.min, min, x)
AND TInt.Subtract (max, t.max, y)
AND TInt.LT (y, x) THEN
! IF TInt.Add (t.max, TInt.One, x)
! AND NOT TInt.LT (x, Target.Integer.min)
! AND NOT TInt.LT (Target.Integer.max, x) THEN
IF NOT CompleteTree (t.greater, x, max) THEN RETURN FALSE END;
END;
! IF NOT TInt.Subtract (t.min, TInt.One, max)
! OR TInt.LT (x, Target.Integer.min)
! OR TInt.LT (Target.Integer.max, x) THEN
RETURN TRUE;
END;
t := t.less;
ELSE
! IF TInt.Subtract (t.min, TInt.One, x)
! AND NOT TInt.LT (x, Target.Integer.min)
! AND NOT TInt.LT (Target.Integer.max, x) THEN
IF NOT CompleteTree (t.less, min, x) THEN RETURN FALSE END;
END;
! IF NOT TInt.Add (t.max, TInt.One, min)
! OR TInt.LT (x, Target.Integer.min)
! OR TInt.LT (Target.Integer.max, x) THEN
RETURN TRUE;
END;
t := t.greater;
***************
*** 458,464 ****
next: Target.Int;
oc, xc: Stmt.Outcomes;
l_bodies, l_else, l_end: INTEGER;
- One := Target.Int{Target.Integer.bytes, Target.IBytes{1,0,..}};
BEGIN
p.tree := CollapseTree (p.tree);
l_bodies := CG.Next_label (p.nCases);
--- 465,470 ----
***************
*** 485,491 ****
CG.Push (x);
CG.Load_integer (Target.Integer.cg_type, t.max);
CG.If_compare (Target.Integer.cg_type, CG.Cmp.LE, l_bodies+t.body, CG.Maybe);
! IF NOT TInt.Add (t.max, One, next) THEN
IF (t.greater # NIL) THEN Error.Msg ("case label too large") END;
next := t.max;
END;
--- 491,499 ----
CG.Push (x);
CG.Load_integer (Target.Integer.cg_type, t.max);
CG.If_compare (Target.Integer.cg_type, CG.Cmp.LE, l_bodies+t.body, CG.Maybe);
! IF NOT TInt.Add (t.max, TInt.One, next)
! OR TInt.LT (next, Target.Integer.min)
! OR TInt.LT (Target.Integer.max, next) THEN
IF (t.greater # NIL) THEN Error.Msg ("case label too large") END;
next := t.max;
END;
Index: m3front/src/types/ArrayType.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/types/ArrayType.m3,v
retrieving revision 1.5
diff -c -r1.5 ArrayType.m3
*** m3front/src/types/ArrayType.m3 4 May 2008 11:03:48 -0000 1.5
--- m3front/src/types/ArrayType.m3 18 Feb 2010 02:30:53 -0000
***************
*** 309,315 ****
VAR n, m, res: Target.Int; x: INTEGER;
BEGIN
x := Type.InitCost (p.element, zeroed);
! IF NOT TInt.FromInt (x, Target.Integer.bytes, m) THEN
RETURN LAST (INTEGER);
END;
n := Type.Number (p.index);
--- 309,315 ----
VAR n, m, res: Target.Int; x: INTEGER;
BEGIN
x := Type.InitCost (p.element, zeroed);
! IF NOT TInt.FromInt (x, m) THEN
RETURN LAST (INTEGER);
END;
n := Type.Number (p.index);
Index: m3front/src/types/EnumType.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/types/EnumType.m3,v
retrieving revision 1.7
diff -c -r1.7 EnumType.m3
*** m3front/src/types/EnumType.m3 4 May 2008 11:03:49 -0000 1.7
--- m3front/src/types/EnumType.m3 18 Feb 2010 02:30:53 -0000
***************
*** 44,50 ****
n := Ident.ParseList ();
j := Ident.top - n;
FOR i := 0 TO n - 1 DO
! b := TInt.FromInt (i, Target.Integer.bytes, val); <*ASSERT b*>
Scope.Insert (EnumElt.New (Ident.stack[j + i], val, p));
END;
DEC (Ident.top, n);
--- 44,50 ----
n := Ident.ParseList ();
j := Ident.top - n;
FOR i := 0 TO n - 1 DO
! b := TInt.FromInt (i, val); <*ASSERT b*>
Scope.Insert (EnumElt.New (Ident.stack[j + i], val, p));
END;
DEC (Ident.top, n);
***************
*** 70,76 ****
BEGIN
p := Create (Scope.PushNew (FALSE, M3ID.NoID));
FOR i := 0 TO LAST (elt_nms) DO
! b := TInt.FromInt (i, Target.Integer.bytes, val); <*ASSERT b*>
Scope.Insert (EnumElt.New (M3ID.Add (elt_nms[i]), val, p));
END;
Scope.PopNew ();
--- 70,76 ----
BEGIN
p := Create (Scope.PushNew (FALSE, M3ID.NoID));
FOR i := 0 TO LAST (elt_nms) DO
! b := TInt.FromInt (i, val); <*ASSERT b*>
Scope.Insert (EnumElt.New (M3ID.Add (elt_nms[i]), val, p));
END;
Scope.PopNew ();
***************
*** 121,127 ****
PROCEDURE SetRep (p: P) =
VAR max: Target.Int;
BEGIN
! IF NOT TInt.FromInt (p.n_elts-1, Target.Integer.bytes, max) THEN
Error.Msg ("enumeration type too large");
END;
FOR i := FIRST (Rep) TO LAST (Rep) DO
--- 121,129 ----
PROCEDURE SetRep (p: P) =
VAR max: Target.Int;
BEGIN
! IF NOT TInt.FromInt (p.n_elts-1, max)
! OR TInt.LT (max, Target.Integer.min)
! OR TInt.LT (Target.Integer.max, max) THEN
Error.Msg ("enumeration type too large");
END;
FOR i := FIRST (Rep) TO LAST (Rep) DO
***************
*** 158,164 ****
p.info.hash := hash;
END Check;
-
PROCEDURE CheckAlign (p: P; offset: INTEGER): BOOLEAN =
VAR
sz := TargetMap.Word_types [p.rep].size;
--- 160,165 ----
***************
*** 172,178 ****
RETURN (offset + sz) <= (z0 + Target.Integer.size);
END CheckAlign;
-
PROCEDURE Compiler (p: P) =
VAR v := Scope.ToList (p.scope);
BEGIN
--- 173,178 ----
***************
*** 222,230 ****
VAR max: Target.Int;
BEGIN
IF (p.n_elts <= 0) OR (zeroed) THEN RETURN 0; END;
! IF NOT TInt.FromInt (p.n_elts-1, Target.Integer.bytes, max) THEN
! RETURN 1;
! END;
IF TInt.EQ (TargetMap.Word_types[p.rep].max, max)
THEN RETURN 0;
ELSE RETURN 1;
--- 222,228 ----
VAR max: Target.Int;
BEGIN
IF (p.n_elts <= 0) OR (zeroed) THEN RETURN 0; END;
! IF NOT TInt.FromInt (p.n_elts-1, max) THEN RETURN 1 END;
IF TInt.EQ (TargetMap.Word_types[p.rep].max, max)
THEN RETURN 0;
ELSE RETURN 1;
Index: m3front/src/types/OpenArrayType.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/types/OpenArrayType.m3,v
retrieving revision 1.4
diff -c -r1.4 OpenArrayType.m3
*** m3front/src/types/OpenArrayType.m3 18 Sep 2007 20:26:11 -0000 1.4
--- m3front/src/types/OpenArrayType.m3 18 Feb 2010 02:30:53 -0000
***************
*** 209,217 ****
PROCEDURE InitCoster (p: P; zeroed: BOOLEAN): INTEGER =
VAR n, m, res: Target.Int; x: INTEGER;
BEGIN
! IF TInt.FromInt (Type.InitCost (p.element, zeroed),
! Target.Integer.bytes, m)
! AND TInt.FromInt (20, Target.Integer.bytes, n) (* guess 20 elements *)
AND TInt.Multiply (m, n, res)
AND TInt.ToInt (res, x)
THEN RETURN x;
--- 209,216 ----
PROCEDURE InitCoster (p: P; zeroed: BOOLEAN): INTEGER =
VAR n, m, res: Target.Int; x: INTEGER;
BEGIN
! IF TInt.FromInt (Type.InitCost (p.element, zeroed), m)
! AND TInt.FromInt (20, n) (* guess that there are 20 elements *)
AND TInt.Multiply (m, n, res)
AND TInt.ToInt (res, x)
THEN RETURN x;
Index: m3front/src/types/SubrangeType.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/types/SubrangeType.m3,v
retrieving revision 1.7
diff -c -r1.7 SubrangeType.m3
*** m3front/src/types/SubrangeType.m3 15 Jan 2010 21:50:12 -0000 1.7
--- m3front/src/types/SubrangeType.m3 18 Feb 2010 02:30:53 -0000
***************
*** 78,91 ****
PROCEDURE SetRep (p: P) =
BEGIN
- IF Type.IsSubtype (p.baseType, LInt.T)
- THEN p.rep := Target.Longint.cg_type;
- ELSE p.rep := Target.Integer.cg_type;
- END;
-
IF TInt.LT (p.max, p.min) THEN
p.min := TInt.Zero;
p.max := TInt.MOne;
RETURN;
END;
--- 78,90 ----
PROCEDURE SetRep (p: P) =
BEGIN
IF TInt.LT (p.max, p.min) THEN
p.min := TInt.Zero;
p.max := TInt.MOne;
+ IF Type.IsSubtype (p.baseType, LInt.T)
+ THEN p.rep := Target.Longint.cg_type;
+ ELSE p.rep := Target.Integer.cg_type;
+ END;
RETURN;
END;
***************
*** 102,109 ****
(* look for a signed type *)
FOR i := FIRST (TargetMap.Integer_types) TO LAST (TargetMap.Integer_types) DO
WITH z = TargetMap.Integer_types[i] DO
! IF TInt.LE (z.min, p.min)
! AND TInt.LE (p.max, z.max) THEN
p.rep := z.cg_type; RETURN;
END;
END;
--- 101,107 ----
(* look for a signed type *)
FOR i := FIRST (TargetMap.Integer_types) TO LAST (TargetMap.Integer_types) DO
WITH z = TargetMap.Integer_types[i] DO
! IF TInt.LE (z.min, p.min) AND TInt.LE (p.max, z.max) THEN
p.rep := z.cg_type; RETURN;
END;
END;
***************
*** 277,283 ****
END BitWidth;
VAR (*CONST*)
! power : ARRAY [0..BITSIZE (Target.Int)] OF Target.Int;
powers_done := FALSE;
PROCEDURE BuildPowerTables () =
--- 275,281 ----
END BitWidth;
VAR (*CONST*)
! power : ARRAY [0..TInt.Size] OF Target.Int;
powers_done := FALSE;
PROCEDURE BuildPowerTables () =
***************
*** 306,312 ****
rep_max := Target.Integer.max;
END;
! IF zeroed AND TInt.LE (p.min, TInt.Zero)
AND TInt.LE (TInt.Zero, p.max) THEN
RETURN 0;
END;
--- 304,311 ----
rep_max := Target.Integer.max;
END;
! IF zeroed
! AND TInt.LE (p.min, TInt.Zero)
AND TInt.LE (TInt.Zero, p.max) THEN
RETURN 0;
END;
***************
*** 340,347 ****
VAR info: Type.Info;
BEGIN
EVAL Type.CheckInfo (p, info);
! IF TInt.LT (TInt.Zero, p.min)
! OR TInt.LT (p.max, TInt.Zero) THEN
CG.Load_integer (info.stk_type, p.min);
CG.Store_indirect (info.stk_type, 0, info.size);
ELSIF zeroed THEN
--- 339,345 ----
VAR info: Type.Info;
BEGIN
EVAL Type.CheckInfo (p, info);
! IF TInt.LT (TInt.Zero, p.min) OR TInt.LT (p.max, TInt.Zero) THEN
CG.Load_integer (info.stk_type, p.min);
CG.Store_indirect (info.stk_type, 0, info.size);
ELSIF zeroed THEN
Index: m3front/src/types/Type.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3front/src/types/Type.m3,v
retrieving revision 1.8
diff -c -r1.8 Type.m3
*** m3front/src/types/Type.m3 4 May 2008 11:03:49 -0000 1.8
--- m3front/src/types/Type.m3 18 Feb 2010 02:30:53 -0000
***************
*** 392,399 ****
IF (c = Class.Subrange) THEN
b := SubrangeType.Split (u, min, max); <*ASSERT b*>
ELSIF (c = Class.Enum) THEN
! b := TInt.FromInt (EnumType.NumElts (u), Target.Integer.bytes, max);
! <*ASSERT b*>
RETURN max;
ELSIF (c = Class.Integer) THEN
min := Target.Integer.min;
--- 392,398 ----
IF (c = Class.Subrange) THEN
b := SubrangeType.Split (u, min, max); <*ASSERT b*>
ELSIF (c = Class.Enum) THEN
! b := TInt.FromInt (EnumType.NumElts (u), max); <*ASSERT b*>
RETURN max;
ELSIF (c = Class.Integer) THEN
min := Target.Integer.min;
***************
*** 411,417 ****
END;
IF TInt.Subtract (max, min, tmp)
AND TInt.Add (tmp, TInt.One, max)
! AND TInt.LE (max, Target.Integer.max) THEN
RETURN max;
END;
Error.Msg ("type has too many elements");
--- 410,417 ----
END;
IF TInt.Subtract (max, min, tmp)
AND TInt.Add (tmp, TInt.One, max)
! AND NOT TInt.LT (max, Target.Integer.min)
! AND NOT TInt.LT (Target.Integer.max, max) THEN
RETURN max;
END;
Error.Msg ("type has too many elements");
***************
*** 425,432 ****
b := SubrangeType.Split (u, min, max); <*ASSERT b*>
RETURN TRUE;
ELSIF (c = Class.Enum) THEN
! b := TInt.FromInt (EnumType.NumElts (u), Target.Integer.bytes, min);
! <*ASSERT b*>
b := TInt.Subtract (min, TInt.One, max); <*ASSERT b*>
min := TInt.Zero;
RETURN TRUE;
--- 425,431 ----
b := SubrangeType.Split (u, min, max); <*ASSERT b*>
RETURN TRUE;
ELSIF (c = Class.Enum) THEN
! b := TInt.FromInt (EnumType.NumElts (u), min); <*ASSERT b*>
b := TInt.Subtract (min, TInt.One, max); <*ASSERT b*>
min := TInt.Zero;
RETURN TRUE;
Index: m3tools/src/M3Builtin.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3tools/src/M3Builtin.m3,v
retrieving revision 1.5
diff -c -r1.5 M3Builtin.m3
*** m3tools/src/M3Builtin.m3 18 Sep 2007 20:26:30 -0000 1.5
--- m3tools/src/M3Builtin.m3 18 Feb 2010 02:30:54 -0000
***************
*** 111,117 ****
val.type := M3Type.Integer;
val.class := M3Const.Class.Integer;
MustBe (info.size >= 0);
! MustBe (TInt.FromInt (info.size, Target.Integer.bytes, val.int));
END;
ELSE
NotImpl ("BYTESIZE(expr)");
--- 111,117 ----
val.type := M3Type.Integer;
val.class := M3Const.Class.Integer;
MustBe (info.size >= 0);
! MustBe (TInt.FromInt (info.size, val.int));
END;
ELSE
NotImpl ("BYTESIZE(expr)");
Index: m3tools/src/M3Const.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3tools/src/M3Const.m3,v
retrieving revision 1.6
diff -c -r1.6 M3Const.m3
*** m3tools/src/M3Const.m3 16 Jan 2010 02:29:10 -0000 1.6
--- m3tools/src/M3Const.m3 18 Feb 2010 02:30:54 -0000
***************
*** 861,868 ****
Err ("bad operand for subscript operation");
ELSIF (b.class = Class.Integer) THEN
(* ok *)
! ELSIF (b.class = Class.Enum)
! AND TInt.FromInt (b.info, Target.Integer.bytes, b.int) THEN
(* ok *)
ELSE
Err ("bad operand for subscript operation");
--- 861,867 ----
Err ("bad operand for subscript operation");
ELSIF (b.class = Class.Integer) THEN
(* ok *)
! ELSIF (b.class = Class.Enum) AND TInt.FromInt (b.info, b.int) THEN
(* ok *)
ELSE
Err ("bad operand for subscript operation");
***************
*** 1161,1167 ****
BEGIN
val.class := Class.Integer;
val.type := M3Type.Integer;
! IF NOT TInt.FromInt (s.info, Target.Integer.bytes, val.int) THEN
Err ("illegal integer value");
END;
END EvalInt;
--- 1160,1166 ----
BEGIN
val.class := Class.Integer;
val.type := M3Type.Integer;
! IF NOT TInt.FromInt (s.info, val.int) THEN
Err ("illegal integer value");
END;
END EvalInt;
***************
*** 1171,1177 ****
BEGIN
val.class := Class.Integer;
val.type := M3Type.Longint;
! IF NOT TInt.FromInt (s.info, Target.Longint.bytes, val.int) THEN
Err ("illegal integer value");
END;
END EvalLInt;
--- 1170,1176 ----
BEGIN
val.class := Class.Integer;
val.type := M3Type.Longint;
! IF NOT TInt.FromInt (s.info, val.int) THEN
Err ("illegal integer value");
END;
END EvalLInt;
Index: m3tools/src/M3Lexer.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3tools/src/M3Lexer.m3,v
retrieving revision 1.4
diff -c -r1.4 M3Lexer.m3
*** m3tools/src/M3Lexer.m3 18 Sep 2007 20:26:30 -0000 1.4
--- m3tools/src/M3Lexer.m3 18 Feb 2010 02:30:54 -0000
***************
*** 89,96 ****
SUPER.next (t);
CASE t.token OF
| TK_Ident => FixID (t);
! | TK_Card_const => FixInt (t, Target.Integer.bytes);
! | TK_Long_const => FixInt (t, Target.Longint.bytes);
| TK_Real_const => FixFloat (t, Target.Precision.Short);
| TK_Longreal_const => FixFloat (t, Target.Precision.Long);
| TK_Extended_const => FixFloat (t, Target.Precision.Extended);
--- 89,96 ----
SUPER.next (t);
CASE t.token OF
| TK_Ident => FixID (t);
! | TK_Card_const => FixInt (t);
! | TK_Long_const => FixInt (t);
| TK_Real_const => FixFloat (t, Target.Precision.Short);
| TK_Longreal_const => FixFloat (t, Target.Precision.Long);
| TK_Extended_const => FixFloat (t, Target.Precision.Extended);
***************
*** 108,114 ****
t.id := M3ID.FromStr (SUBARRAY (t.buffer^, t.offset, t.length));
END FixID;
! PROCEDURE FixInt (t: T; bytes: CARDINAL) =
VAR break := -1; base: INTEGER;
BEGIN
FOR i := t.offset TO t.offset + t.length - 1 DO
--- 108,114 ----
t.id := M3ID.FromStr (SUBARRAY (t.buffer^, t.offset, t.length));
END FixID;
! PROCEDURE FixInt (t: T) =
VAR break := -1; base: INTEGER;
BEGIN
FOR i := t.offset TO t.offset + t.length - 1 DO
***************
*** 120,135 ****
END;
IF (break < 0) THEN (* scan a simple integer *)
! IF NOT TInt.New (SUBARRAY (t.buffer^, t.offset, t.length), bytes, t.int) THEN
Err (t, "illegal integer literal");
END;
! ELSIF NOT TInt.New (SUBARRAY (t.buffer^, t.offset, break - t.offset), bytes, t.int)
OR NOT TInt.ToInt (t.int, base)
OR (base < 2) OR (16 < base) THEN
Err (t, "illegal base for integer literal");
ELSIF NOT TWord.New (SUBARRAY (t.buffer^, break+1,
t.offset + t.length - break - 1),
! base, bytes, t.int) THEN
Err (t, "illegal based integer literal");
END;
END FixInt;
--- 120,135 ----
END;
IF (break < 0) THEN (* scan a simple integer *)
! IF NOT TInt.New (SUBARRAY (t.buffer^, t.offset, t.length), t.int) THEN
Err (t, "illegal integer literal");
END;
! ELSIF NOT TInt.New (SUBARRAY (t.buffer^, t.offset, break - t.offset), t.int)
OR NOT TInt.ToInt (t.int, base)
OR (base < 2) OR (16 < base) THEN
Err (t, "illegal base for integer literal");
ELSIF NOT TWord.New (SUBARRAY (t.buffer^, break+1,
t.offset + t.length - break - 1),
! base, t.int) THEN
Err (t, "illegal based integer literal");
END;
END FixInt;
Index: m3tools/src/M3Type.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-sys/m3tools/src/M3Type.m3,v
retrieving revision 1.6
diff -c -r1.6 M3Type.m3
*** m3tools/src/M3Type.m3 16 Jan 2010 02:29:11 -0000 1.6
--- m3tools/src/M3Type.m3 18 Feb 2010 02:30:54 -0000
***************
*** 45,55 ****
PROCEDURE Number (t: T): Target.Int =
VAR min, max, tmp: Target.Int;
- One := Target.Int{Target.Integer.bytes, TInt.One.x};
BEGIN
IF t.get_bounds (min, max)
AND TInt.Subtract (max, min, tmp)
! AND TInt.Add (tmp, One, max) THEN
RETURN max;
END;
RETURN Target.Integer.max;
--- 45,54 ----
PROCEDURE Number (t: T): Target.Int =
VAR min, max, tmp: Target.Int;
BEGIN
IF t.get_bounds (min, max)
AND TInt.Subtract (max, min, tmp)
! AND TInt.Add (tmp, TInt.One, max) THEN
RETURN max;
END;
RETURN Target.Integer.max;
***************
*** 248,254 ****
PROCEDURE GetEnumInfo (self: Enum; VAR x: Info) RAISES {Error} =
VAR n_elts := NUMBER (self.elements^); max: Target.Int; rep: EnumRep;
BEGIN
! IF NOT TInt.FromInt (n_elts-1, Target.Integer.bytes, max) THEN
Err ("enumeration type too large");
END;
rep := FindEnumRep (max);
--- 247,253 ----
PROCEDURE GetEnumInfo (self: Enum; VAR x: Info) RAISES {Error} =
VAR n_elts := NUMBER (self.elements^); max: Target.Int; rep: EnumRep;
BEGIN
! IF NOT TInt.FromInt (n_elts-1, max) THEN
Err ("enumeration type too large");
END;
rep := FindEnumRep (max);
***************
*** 289,296 ****
VAR b: BOOLEAN;
BEGIN
min := TInt.Zero;
! b := TInt.FromInt (NUMBER (self.elements^) - 1, Target.Integer.size, max);
! <*ASSERT b*>
RETURN TRUE;
END EnumBounds;
--- 288,294 ----
VAR b: BOOLEAN;
BEGIN
min := TInt.Zero;
! b := TInt.FromInt (NUMBER (self.elements^) - 1, max); <*ASSERT b*>
RETURN TRUE;
END EnumBounds;
More information about the M3commit
mailing list