-- ----------------------------------------------------------------------- -- Title: float_representation -- Last Mod: Mon Jun 11 12:55:30 1990 -- Author: Vincent Broman -- Copyright 1990 Vincent Broman -- Permission granted to copy, modify, or compile this software for -- one's own use, provided that this copyright notice is preserved intact. -- Permission granted to distribute compiled binary copies of this -- software which are linked in with some other application. -- Permission granted to distribute other copies of this software, -- provided that (1) any copy which is not source code, i.e. not in the -- form in which the software is usually maintained, must be accompanied -- by a copy of the source code from which it was compiled, and (2) the -- one distributing it must refrain from imposing on the recipient -- further restrictions on the distribution of this software. -- -- Visibility: withed by generic_primitive_functions only -- Description: -- Types and functions which are needed by -- generic_primitive_functions and are dependent on -- the floating point hardware. -- Bit-level representation specs describe the layout -- of the parts of a floating point number. -- Subpackages single and double duplicate -- the information for both of the precisions available. -- -- This is for VAX-11 f_float, g_float, and h_float arithmetic, -- for which the hardware is littleendian and non IEEE 754. -- The VAX-VMS compiler from DEC handles this. -- -- Exceptions: none -- ----------------------------------------------------------------------- with unchecked_conversion; with system; with float_types; use float_types; package float_representation is -- gradual_underflow: constant boolean := false; -- compiler generates code supporting gradual underflow -- may be true for IEEE 754 arithmetic. type bit is new boolean; for bit'size use 1; mantissa_word_size: constant := 16; short_units: constant := mantissa_word_size / system.storage_unit; -- the number of storage_units in a 16bit short word. subtype mantissa_word_bitno is integer range 0 .. mantissa_word_size - 1; type mantissa_word is array( mantissa_word_bitno) of bit; pragma pack( mantissa_word); for mantissa_word'size use mantissa_word_size; -- for some strange reason, mantissa_word'size is not a static expression. -- similarly, the mantissa_head'size defined in the packages below. why? zero_word: constant mantissa_word := mantissa_word'( others => false); -- here are bit masks for clearing the bottom N bits of a mantissa_word type wd_masks is array( mantissa_word_bitno) of mantissa_word; truncate_mask_wd: constant wd_masks := wd_masks'( mantissa_word'( others => true), mantissa_word'( 0 => false, others => true), mantissa_word'( 0 .. 1 => false, others => true), mantissa_word'( 0 .. 2 => false, others => true), mantissa_word'( 0 .. 3 => false, others => true), mantissa_word'( 0 .. 4 => false, others => true), mantissa_word'( 0 .. 5 => false, others => true), mantissa_word'( 0 .. 6 => false, others => true), mantissa_word'( 0 .. 7 => false, others => true), mantissa_word'( 0 .. 8 => false, others => true), mantissa_word'( 0 .. 9 => false, others => true), mantissa_word'( 0 .. 10 => false, others => true), mantissa_word'( 0 .. 11 => false, others => true), mantissa_word'( 0 .. 12 => false, others => true), mantissa_word'( 0 .. 13 => false, others => true), mantissa_word'( 0 .. 14 => false, others => true)); -- this array maps bigendian bit numbers (0 bit is most significant) -- to subscripts for a mantissa_word type bitno_wd_map is array( mantissa_word_bitno) of mantissa_word_bitno; bitno_wd: constant bitno_wd_map := bitno_wd_map'( 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); -- -- next are internal packages encapsulating the properties of the -- various floating point types in some types and constants. -- package single_rep is -- -- VAX-11 f_float single precision on a littleendian machine. -- mant: constant := 24; -- incl hidden bit two_to_mant: constant := 2.0 ** mant; largest_non_int: constant := 0.5 * two_to_mant - 1.0 + 0.5; type biased_exp is range 0 .. 2 ** 8 - 1; for biased_exp'size use 8; mantissa_head_size: constant := 7; subtype mantissa_head_bitno is integer range 0 .. mantissa_head_size - 1; type mantissa_head is array( mantissa_head_bitno) of bit; pragma pack( mantissa_head); for mantissa_head'size use mantissa_head_size; zero_head: constant mantissa_head := mantissa_head'( others => false); -- here are bit masks for clearing the bottom N bits of a mantissa_head type hd_masks is array( mantissa_head_bitno) of mantissa_head; truncate_mask_hd: constant hd_masks := hd_masks'( mantissa_head'( others => true), mantissa_head'( 0 => false, others => true), mantissa_head'( 0 .. 1 => false, others => true), mantissa_head'( 0 .. 2 => false, others => true), mantissa_head'( 0 .. 3 => false, others => true), mantissa_head'( 0 .. 4 => false, others => true), mantissa_head'( 0 .. 5 => false, others => true)); -- this array maps bigendian bit numbers (0 bit is most significant) -- to subscripts for a mantissa_head type bitno_hd_map is array( mantissa_head_bitno) of mantissa_head_bitno; bitno_hd: constant bitno_hd_map := bitno_hd_map'( 6, 5, 4, 3, 2, 1, 0); sign_place: constant := mantissa_word_size - 1; -- at end of word type float_fields is record mant_1: mantissa_head; exp: biased_exp; sign: bit; mant_2: mantissa_word; -- less significant end record; for float_fields use record at mod 2; mant_1 at 0 range 0 .. mantissa_head_size - 1; exp at 0 range mantissa_head_size .. sign_place - 1; sign at 0 range sign_place .. sign_place; mant_2 at short_units range 0 .. mantissa_word_size - 1; end record; for float_fields'size use 32; function split_fields is new unchecked_conversion( single, float_fields); function join_fields is new unchecked_conversion( float_fields, single); end single_rep; package double_rep is -- -- VAX-11 g_float double precision on a littleendian machine. -- mant: constant := 53; -- incl hidden bit two_to_mant: constant := 2.0 ** mant; largest_non_int: constant := 0.5 * two_to_mant - 1.0 + 0.5; type biased_exp is range 0 .. 2 ** 11 - 1; for biased_exp'size use 11; mantissa_head_size: constant := 4; subtype mantissa_head_bitno is integer range 0 .. mantissa_head_size - 1; type mantissa_head is array( mantissa_head_bitno) of bit; pragma pack( mantissa_head); for mantissa_head'size use mantissa_head_size; zero_head: constant mantissa_head := mantissa_head'( others => false); -- here are bit masks for clearing the bottom N bits of a mantissa_head type hd_masks is array( mantissa_head_bitno) of mantissa_head; truncate_mask_hd: constant hd_masks := hd_masks'( mantissa_head'( others => true), mantissa_head'( 0 => false, others => true), mantissa_head'( 0 .. 1 => false, others => true), mantissa_head'( 0 .. 2 => false, others => true)); -- this array maps bigendian bit numbers (0 bit is most significant) -- to subscripts for a mantissa_head type bitno_hd_map is array( mantissa_head_bitno) of mantissa_head_bitno; bitno_hd: constant bitno_hd_map := bitno_hd_map'( 3, 2, 1, 0); sign_place: constant := mantissa_word_size - 1; -- at end of word type float_fields is record mant_1: mantissa_head; exp: biased_exp; sign: bit; mant_2: mantissa_word; mant_3: mantissa_word; mant_4: mantissa_word; -- least significant end record; for float_fields use record at mod 2; mant_1 at 0 range 0 .. mantissa_head_size - 1; exp at 0 range mantissa_head_size .. sign_place - 1; sign at 0 range sign_place .. sign_place; mant_2 at 1*short_units range 0 .. mantissa_word_size - 1; mant_3 at 2*short_units range 0 .. mantissa_word_size - 1; mant_4 at 3*short_units range 0 .. mantissa_word_size - 1; end record; for float_fields'size use 64; function split_fields is new unchecked_conversion( double, float_fields); function join_fields is new unchecked_conversion( float_fields, double); end double_rep; package longest_float_rep is -- -- VAX-11 h_float quadruple precision on a littleendian machine. -- mant: constant := 113; -- incl hidden bit two_to_mant: constant := 2.0 ** mant; largest_non_int: constant := 0.5 * two_to_mant - 1.0 + 0.5; type biased_exp is range 0 .. 2 ** 15 - 1; for biased_exp'size use 15; mantissa_head_size: constant := 16; subtype mantissa_head_bitno is integer range 0 .. mantissa_head_size - 1; type mantissa_head is array( mantissa_head_bitno) of bit; pragma pack( mantissa_head); for mantissa_head'size use mantissa_head_size; zero_head: constant mantissa_head := mantissa_head'( others => false); -- here are bit masks for clearing the bottom N bits of a mantissa_head type hd_masks is array( mantissa_head_bitno) of mantissa_head; truncate_mask_hd: constant hd_masks := hd_masks'( mantissa_head'( others => true), mantissa_head'( 0 => false, others => true), mantissa_head'( 0 .. 1 => false, others => true), mantissa_head'( 0 .. 2 => false, others => true), mantissa_head'( 0 .. 3 => false, others => true), mantissa_head'( 0 .. 4 => false, others => true), mantissa_head'( 0 .. 5 => false, others => true), mantissa_head'( 0 .. 6 => false, others => true), mantissa_head'( 0 .. 7 => false, others => true), mantissa_head'( 0 .. 8 => false, others => true), mantissa_head'( 0 .. 9 => false, others => true), mantissa_head'( 0 .. 10 => false, others => true), mantissa_head'( 0 .. 11 => false, others => true), mantissa_head'( 0 .. 12 => false, others => true), mantissa_head'( 0 .. 13 => false, others => true), mantissa_head'( 0 .. 14 => false, others => true)); -- this array maps bigendian bit numbers (0 bit is most significant) -- to subscripts for a mantissa_head type bitno_hd_map is array( mantissa_head_bitno) of mantissa_head_bitno; bitno_hd: constant bitno_hd_map := bitno_hd_map'( 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); sign_place: constant := mantissa_word_size - 1; -- at end of word type float_fields is record exp: biased_exp; sign: bit; mant_1: mantissa_head; mant_2: mantissa_word; mant_3: mantissa_word; mant_4: mantissa_word; mant_5: mantissa_word; mant_6: mantissa_word; mant_7: mantissa_word; -- least significant end record; for float_fields use record at mod 2; exp at 0 range 0 .. sign_place - 1; sign at 0 range sign_place .. sign_place; mant_1 at 1*short_units range 0 .. mantissa_head_size - 1; mant_2 at 2*short_units range 0 .. mantissa_word_size - 1; mant_3 at 3*short_units range 0 .. mantissa_word_size - 1; mant_4 at 4*short_units range 0 .. mantissa_word_size - 1; mant_5 at 5*short_units range 0 .. mantissa_word_size - 1; mant_6 at 6*short_units range 0 .. mantissa_word_size - 1; mant_7 at 7*short_units range 0 .. mantissa_word_size - 1; end record; for float_fields'size use 128; function split_fields is new unchecked_conversion( longest_float, float_fields); function join_fields is new unchecked_conversion( float_fields, longest_float); end longest_float_rep; end float_representation; -- $Header: vxg_float_representation_s.a,v 3.17 90/06/13 15:20:51 broman Stab $