diff options
Diffstat (limited to 'gcc/ada/s-bignum.adb')
-rw-r--r-- | gcc/ada/s-bignum.adb | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/gcc/ada/s-bignum.adb b/gcc/ada/s-bignum.adb index b3af4796136..cb7a4f6c1be 100644 --- a/gcc/ada/s-bignum.adb +++ b/gcc/ada/s-bignum.adb @@ -233,14 +233,27 @@ package body System.Bignums is pragma Import (Ada, BD); -- Expose a writable view of discriminant BD.Len so that we can - -- initialize it. + -- initialize it. We need to use the exact layout of the record + -- to ensure that the Length field has 24 bits as expected. - BL : Length; - for BL'Address use BD.Len'Address; - pragma Import (Ada, BL); + type Bignum_Data_Header is record + Len : Length; + Neg : Boolean; + end record; + + for Bignum_Data_Header use record + Len at 0 range 0 .. 23; + Neg at 3 range 0 .. 7; + end record; + + BDH : Bignum_Data_Header; + for BDH'Address use BD'Address; + pragma Import (Ada, BDH); + + pragma Assert (BDH.Len'Size = BD.Len'Size); begin - BL := Len; + BDH.Len := Len; return B; end; end if; @@ -728,8 +741,9 @@ package body System.Bignums is -- The complex full multi-precision case. We will employ algorithm -- D defined in the section "The Classical Algorithms" (sec. 4.3.1) - -- of Donald Knuth's "The Art of Computer Programming", Vol. 2. The - -- terminology is adjusted for this section to match that reference. + -- of Donald Knuth's "The Art of Computer Programming", Vol. 2, 2nd + -- edition. The terminology is adjusted for this section to match that + -- reference. -- We are dividing X.Len digits of X (called u here) by Y.Len digits -- of Y (called v here), developing the quotient and remainder. The @@ -775,12 +789,12 @@ package body System.Bignums is v (J) := Y.D (J); end loop; - -- [Division of nonnegative integers]. Given nonnegative integers u + -- [Division of nonnegative integers.] Given nonnegative integers u -- = (ul,u2..um+n) and v = (v1,v2..vn), where v1 /= 0 and n > 1, we -- form the quotient u / v = (q0,ql..qm) and the remainder u mod v = -- (r1,r2..rn). - pragma Assert (v (1) /= 0); + pragma Assert (v1 /= 0); pragma Assert (n > 1); -- Dl. [Normalize.] Set d = b/(vl + 1). Then set (u0,u1,u2..um+n) @@ -789,7 +803,7 @@ package body System.Bignums is -- u0 at the left of u1; if d = 1 all we need to do in this step is -- to set u0 = 0. - d := b / DD (v1 + 1); + d := b / (DD (v1) + 1); if d = 1 then u0 := 0; @@ -826,15 +840,15 @@ package body System.Bignums is -- D2. [Initialize j.] Set j = 0. The loop on j, steps D2 through D7, -- will be essentially a division of (uj, uj+1..uj+n) by (v1,v2..vn) - -- to get a single quotient digit qj; + -- to get a single quotient digit qj. j := 0; -- Loop through digits loop - -- D3. [Calculate qhat] If uj = v1, set qhat to b-l; otherwise set - -- qhat to (uj,uj+1)/v1. + -- D3. [Calculate qhat.] If uj = v1, set qhat to b-l; otherwise + -- set qhat to (uj,uj+1)/v1. if u (j) = v1 then qhat := -1; |