[M3devel] tangential 64 bit...

Jay jayk123 at hotmail.com
Tue Feb 26 21:56:31 CET 2008


Well I was lazy and did some math in the debugger and indeed one bit of carry or overflow is adequate, for addition and subtraction. You can do better with multiplicatio..and division I'd have to think a lot more about.
It is an odd inconsistency between the Add and Subtract code below though.. I guess the reason is that carry will be 0 or 1, but borrow will be 0 or -1 and you want to convert -1 to +1.
 As well, carry/borrow should be sign extended if you run out of bits, so the -1 is used.
 
It probably could be:
add:
<
      r.x[i] := And (carry, Mask);     carry := RShift (carry, BITSIZE (IByte));
>
   carry := ORD (carry # 0);
   r.x[i] := carry;
subtract:
<
      r.x[i] := And (borrow, Mask);      borrow := And (RShift (borrow, BITSIZE (IByte)), 1);>
  if borrow # 0 then
     r.x[i] := Mask;
     borrow := 1;
   end
 
no major difference.
?
 
 - Jay


From: jayk123 at hotmail.comTo: hosking at cs.purdue.eduCC: m3devel at elegosoft.comSubject: RE: [M3devel] tangential 64 bit...Date: Tue, 26 Feb 2008 20:34:51 +0000


Tony..are you sure..I'm not sure what I said is true.It seems clear that the host integer size is well abstracted while interpreting target numbers. I am more certain that [-1 .. 1] is empty, and this is likely a problem in TInt.Subtract.. 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 THEN RETURN FALSE END;    IF 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 THEN RETURN FALSE END;    IF 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;Is it not adequate to treat carry and borrow as one it, zero or non-zero?Thinking in decimal about addition -- 9 + 9 = 18.You can never overflow to 20, 30, 40, etc. For substraction 0 - 9 = -9, never -10 or lower. However "1" is a full decimal digit, not a bit.In this case, the digits are bytes. Aha, so maybe the problem is the "and"? Let's check pm3 and decm3 3.6 again..No, pm3 has the and too.. hm. I have to refresh some of my bit twiddling algorithms..  - Jay


CC: m3devel at elegosoft.comFrom: hosking at cs.purdue.eduTo: jayk123 at hotmail.comSubject: Re: [M3devel] tangential 64 bit...Date: Tue, 26 Feb 2008 15:14:18 -0500


Indeed, on a 32-bit platform [16_0 .. 16_ffffffff] is an empty type, because 16_ffffffff is interpreted as an INTEGER constant with value -1, so the subrange is [0..-1].

This implies that one should not be using a 32-bit compiler to compile the 64-bit version of BasicCtypes.i3 in the first place.

Of course, this also implies that one cannot directly cross-compile to 64-bit targets from 32-bit hosts, which is kind of broken.  I suppose we could use LONGINT as necessary, realizing that LONGINT and INTEGER are distinct types that happen to have the same representation on 64-bit machines but different representation on 32-bit machines.  Does anyone know if it was *ever* possible in the old PM3 to cross-compile from 32-bit to 64-bit?  Presumably one needs an intermediate step where the C types used on the cross-compile host match those of the host instead of the target.


On Feb 26, 2008, at 1:53 PM, Jay wrote:

alpha/osf doesn't work because basictypes/ctypes has a problem with the 32bit or 64bit types.specifically "unsigned long" is "empty" for some reason and many errors cascade from that. if you change:  unsigned_int       = [16_0 .. 16_ffffffff];to  unsigned_int       = [16_0 .. 16_fffffffe]; you get:  ****** runtime error:***    An array subscript was out of range.***    file "../src/TWord.m3", line 199***Presumably fixing this first problem is the first step in any "real" 64 bit target (SPARC64, PPC64, AMD64, IA64), and the second problem should just be fixed as a matter of course. I know this is the least of anyone's concerns..  - Jay

Connect and share in new ways with Windows Live. Get it now!

Climb to the top of the charts! Play the word scramble challenge with star power. Play now! 
_________________________________________________________________
Connect and share in new ways with Windows Live.
http://www.windowslive.com/share.html?ocid=TXT_TAGHM_Wave2_sharelife_012008
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20080226/2a252ebe/attachment-0002.html>


More information about the M3devel mailing list