DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 Tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ B T ┃
Length: 4321 (0x10e1) Types: TextFile Names: »B«
└─⟦5829e5ed5⟧ Bits:30000534 8mm tape, Rational 1000, RCI 2_0_5 └─ ⟦c9a165082⟧ »DATA« └─⟦2162db02b⟧ └─⟦this⟧
with Unchecked_Conversion; package body Generic_Bit_Operations is pragma Suppress (Division_Check); pragma Suppress (Index_Check); pragma Suppress (Overflow_Check); pragma Suppress (Range_Check); type Booleans is array (Integer range 0 .. Integer_Type'Size - 1) of Boolean; pragma Pack (Booleans); Clear_Sign_Bit : Integer_Type := Integer_Type'Last / 2 - Integer_Type'First / 2; Shift_Right_Sign_Bit : Integer_Type := Clear_Sign_Bit - Clear_Sign_Bit / 2; -- Masks used to clear the sign bit and to shift it to the right First_Bit : Integer; -- Offset of the first bit within integer_type function Bits is new Unchecked_Conversion (Integer_Type, Booleans); function Int is new Unchecked_Conversion (Booleans, Integer_Type); function Get_First_Bit_Location return Integer is Quotient : Integer := 0; Number : Integer_Type := Clear_Sign_Bit; -- Abs max that can be held in integer_type First_Bit_Location : Integer := 0; begin while Number /= 0 loop Number := Number / 2; Quotient := Quotient + 1; end loop; First_Bit_Location := Integer_Type'Size - Quotient - 1; -- Offset at which the first bit starts return First_Bit_Location; end Get_First_Bit_Location; function Mask (Start, Length : Natural) return Booleans is M : Booleans := (others => False); begin for I in 0 .. Length - 1 loop -- just to see M (I + Start + First_Bit) := True; end loop; return M; end Mask; function Extract (W : Integer_Type; Start : Natural; Length : Natural) return Integer_Type is begin return Int (Bits (W) and Mask (Start, Length)); end Extract; function Test_Bit (W : Integer_Type; B : Natural) return Boolean is begin return Bits (W) (B + First_Bit); end Test_Bit; function Insert (W, Into : Integer_Type; Start : Natural; Length : Natural) return Integer_Type is begin return Int ((Bits (Into) and not Mask (Start, Length)) or Bits (Logical_Shift (Extract (W, Booleans'Last - Length + 1, Length), (Booleans'Last - Length + 1) - Start))); end Insert; procedure Set_Bit_To_One (W : in out Integer_Type; B : Natural) is X : Booleans := Bits (W); begin X (B + First_Bit) := True; W := Int (X); end Set_Bit_To_One; procedure Set_Bit_To_Zero (W : in out Integer_Type; B : Natural) is X : Booleans := Bits (W); begin X (B + First_Bit) := False; W := Int (X); end Set_Bit_To_Zero; function Logical_And (X, Y : Integer_Type) return Integer_Type is begin return Int (Bits (X) and Bits (Y)); end Logical_And; function Logical_Or (X, Y : Integer_Type) return Integer_Type is begin return Int (Bits (X) or Bits (Y)); end Logical_Or; function Logical_Xor (X, Y : Integer_Type) return Integer_Type is begin return Int (Bits (X) xor Bits (Y)); end Logical_Xor; function Logical_Not (X : Integer_Type) return Integer_Type is begin return Int (not Bits (X)); end Logical_Not; function Logical_Shift (X : Integer_Type; Amount : Integer) return Integer_Type is W : Integer_Type := X; Shift_Amount : Integer := Amount; begin if Shift_Amount > 0 then -- shift left for I in 1 .. Shift_Amount loop W := W * 2; end loop; elsif Shift_Amount < 0 then if W < 0 then W := Logical_Or (Logical_And (W, Clear_Sign_Bit) / 2, Shift_Right_Sign_Bit); Shift_Amount := Shift_Amount + 1; -- Perform one logical shift end if; if Shift_Amount < 0 then for I in 1 .. -Shift_Amount loop W := W / 2; end loop; -- Perform the remaining logical shifts end if; end if; return W; end Logical_Shift; begin First_Bit := Get_First_Bit_Location; end Generic_Bit_Operations;