[M3devel] [Fwd: Sanity check request regarding CT arithmetic]

Tony Hosking hosking at cs.purdue.edu
Thu Jan 31 18:44:05 CET 2008


Hi Rodney,

Yes, you are missing one crucial thing.  Namely, that the front-end  
compiler *carefully* uses these target integer simulations only with  
values that are *explicitly* the same length.  LONGINT and INTEGER  
are different types.  INTEGER is the *representation* type for all  
values 32 bits or less.  LONGINT is the representation type for only  
LONGINT values.  You cannot mix LONGINT with INTEGER in source code  
expressions.  They need to be converted explicitly using ORD/VAL.   
Indeed, you are right that the interfaces should document that  
behavior explicitly, or alternatively, perhaps the implementations  
should <*ASSERT a.n=b.n*>.  The change from the way PM3 does things  
was necessary for the introduction of LONGINT.

Hope this helps and sorry for the imprecision of documentation.

On Jan 31, 2008, at 11:22 AM, Rodney M. Bates wrote:

> Whenever I run across something this unbelievable, I figure I must
> be missing something.  Can anybody tell me what?
>
> While working on making Pickles work on LONGINT, I have noted the
> following code snippets for doing target arithmetic at compile time:
>
> From m3-sys/m3middle/src/Target.i3:
>
> (* 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];
>
> From m3-sys/m3middle/src/TWord.m3:
>
> 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;
>
> Unless the two values have equal numbers of bytes, Subtract just
> throws away the high bytes of the longer operand.  It looks like
> pretty much all the CT target arithmetic in TWord.m3 and TInt.m3
> does this.
>
> It seems just about inconceivable that the arithmetic could be this
> broken and not have created many impossible-to-ignore bugs.  SRC
> and pm3 do it differently.  They have a single global variable that
> gives the used size of all CT target values.
>
> The only possible explanation I can think of is that the cm3 compiler
> happens never to pass two Target.Int values with different values  
> of n.
> The relevant declarations give no hint of such a counter-intuitive
> requirement.  If this is an essential precondition, it should be
> documented in the interfaces.
>
> -- 
> -------------------------------------------------------------
> Rodney M. Bates, retired assistant professor
> Dept. of Computer Science, Wichita State University
> Wichita, KS 67260-0083
> 316-978-3922
> rodney.bates at wichita.edu
>
>




More information about the M3devel mailing list