summaryrefslogtreecommitdiff
path: root/gcc/ada/s-bignum.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/s-bignum.adb')
-rw-r--r--gcc/ada/s-bignum.adb40
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;