[M3devel] m3cg shift value/count types

Jay K jay.krell at cornell.edu
Sat Sep 22 20:39:23 CEST 2012


Correction, I don't think 64bit targets have:

Shift(Word32, Int64);
ShiftLeft or Right(Word32, Word64);

And historically, without LONGINT the differences were smaller, it was:
32bit:Shift(Word32, Int32);
ShiftLeft or Right(Word32, Word32);
64bit:Shift(Word64, Int64);
ShiftLeft or Right(Word64, Word64);
The differences were only in signed-ness, not size.And, oh, I might have the input-signedness to shift_left/right wrong here.

Anyway, I'll likely adjust the comments in M3CG_Ops.i3 and my code in M3C.m3.And maybe review the other backends.There isn't any sort of runtime stack imbalance implied by these mixed up sizes.I'm not sure the sign mixups matter or not.I'd have to do some experiments.
Certainly I'm more nervous about signedness mixups now.I had this code, which is very wrong:

#define m3_shift_T(T) static T m3_shift_##T(T value,INTEGER shift){if((shift>=(sizeof(T)*8))||(shift<=-(sizeof(T)*8)))...

shift is signedsizeof is unsignedshift got treated as unsignedsmall negative numbers got treated as large positive numbersshifting by, e.g. -1, resulted in 0, instead of a right shift by 1.

 - Jay



From: jay.krell at cornell.edu
To: m3devel at elegosoft.com
Date: Sat, 22 Sep 2012 18:28:14 +0000
Subject: Re: [M3devel] m3cg shift value/count types




It looks like what I have (shown) is correct.The shift count is always an INTEGER.32bit targets have:

Shift(Word32, Int32);
Shift(Word64, Int32);


64bit targets have:Shift(Word32, Int64);
Shift(Word64, Int64);


I might have something wrong where I didn't show.The M3CG_Ops.i3 comment is wrong.The type of the value to shift and the count are never the same.

The only place the frontend uses this is builtinWord/Shift.mg.Everywhere else, when I looked quickly, is explicit ShiftLeft or ShiftRight.For those the count is unsigned.Oh. Those look wrong too.The front end uses an integer-based subrange for the parameter:
m3front/builtinWord/Shift.mg:PROCEDURE Initialize (r: INTEGER) =...    sub := SubrangeType.New (TInt.Zero, max, Int.T, FALSE);

So it is:

32bit targets:ShiftLeft or Right(Word32, Word32);
ShiftLeft or Right(Word64, Word32);


64bit targets:ShiftLeft or Right(Word32, Word64);
ShiftLeft or Right(Word64, Word64);


which also doesn't agree with M3CG_Ops.i3.

Possibly "Rep" should abstract out the shift count type and not just the value to shift.Perhaps it should be:
32bit and 64 bit targets:ShiftLeft or Right(Word32, Word32);
ShiftLeft or Right(Word64, Word64);

and perhaps it should be:
32bit:Shift(Word32, Int32);
Shift(Word64, Int64);


64bit:Shift(Word32, Int64);
Shift(Word64, Int64);


there are arguments for various combinations and what we have isn't crazy.It just disagrees with comments in M3CG_Ops.i3.  The shift count doesn't really need to be widened to match the value.   If this were C with its prevalent "int", shift could remain just 32 bits always. (or even 16)   But Modula-3 favors INTEGER/ptrdiff_t and widening even when 32bits is plenty.


 - Jay
From: jay.krell at cornell.edu
To: m3devel at elegosoft.com
Date: Sat, 22 Sep 2012 18:00:36 +0000
Subject: [M3devel] m3cg shift value/count types




M3CG_Ops.i3:
shift        (t: IType);  (* s1.t := Word.Shift  (s1.t, s0.t); pop *)rotate       (t: IType);  (* s1.t := Word.Rotate (s1.t, s0.t); pop *)

This doesn't seem right to me.
s0 is signed.s1 is not
I have it implemented as:
#define m3_shift_T(T) static T m3_shift_##T(T value,INTEGER shift)...
where T is UINT32 or UINT64.
"shift" can vary..I'll look at the frontend...
 - Jay 		 	   		   		 	   		   		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20120922/8c8bef3b/attachment-0002.html>


More information about the M3devel mailing list