1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
5 -- I N T E R F A C E S . P A C K E D _ D E C I M A L --
8 -- (Version for IBM Mainframe Packed Decimal Format) --
10 -- Copyright (C) 1992-2024, Free Software Foundation, Inc. --
12 -- GNAT is free software; you can redistribute it and/or modify it under --
13 -- terms of the GNU General Public License as published by the Free Soft- --
14 -- ware Foundation; either version 3, or (at your option) any later ver- --
15 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE. --
19 -- As a special exception under Section 7 of GPL version 3, you are granted --
20 -- additional permissions described in the GCC Runtime Library Exception, --
21 -- version 3.1, as published by the Free Software Foundation. --
23 -- You should have received a copy of the GNU General Public License and --
24 -- a copy of the GCC Runtime Library Exception along with this program; --
25 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
26 -- <http://www.gnu.org/licenses/>. --
28 -- GNAT was originally developed by the GNAT team at New York University. --
29 -- Extensive contributions were provided by Ada Core Technologies Inc. --
31 ------------------------------------------------------------------------------
33 -- This unit defines the packed decimal format used by GNAT in response to
34 -- a specification of Machine_Radix 10 for a decimal fixed-point type. The
35 -- format and operations are completely encapsulated in this unit, so all
36 -- that is necessary to compile using different packed decimal formats is
37 -- to replace this single unit.
39 -- Note that the compiler access the spec of this unit during compilation
40 -- to obtain the data length that needs allocating, so the correct version
41 -- of the spec must be available to the compiler, and must correspond to
42 -- the spec and body made available to the linker, and all units of a given
43 -- program must be compiled with the same version of the spec and body.
44 -- This consistency will be enforced automatically using the normal binder
45 -- consistency checking, since any unit declaring Machine_Radix 10 types or
46 -- containing operations on such data will implicitly with Packed_Decimal.
50 package Interfaces
.Packed_Decimal
is
52 ------------------------
53 -- Format Description --
54 ------------------------
56 -- IBM Mainframe packed decimal format uses a byte string of length one
57 -- to 10 bytes, with the most significant byte first. Each byte contains
58 -- two decimal digits (with the high order digit in the left nibble, and
59 -- the low order four bits contain the sign, using the following code:
61 -- 16#A# 2#1010# positive
62 -- 16#B# 2#1011# negative
63 -- 16#C# 2#1100# positive (preferred representation)
64 -- 16#D# 2#1101# negative (preferred representation)
65 -- 16#E# 2#1110# positive
66 -- 16#F# 2#1011# positive
68 -- In this package, all six sign representations are interpreted as
69 -- shown above when an operand is read, when an operand is written,
70 -- the preferred representations are always used. Constraint_Error
71 -- is raised if any other bit pattern is found in the sign nibble,
72 -- or if a digit nibble contains an invalid digit code.
74 -- Some examples follow:
78 -- 00 04 4E +44 (non-standard sign)
79 -- 00 00 00 invalid (incorrect sign nibble)
80 -- 0A 01 1C invalid (bad digit)
86 -- The following array must be declared in exactly the form shown, since
87 -- the compiler accesses the associated tree to determine the size to be
88 -- allocated to a machine radix 10 type, depending on the number of digits.
90 subtype Byte_Length
is Positive range 1 .. 10;
91 -- Range of possible byte lengths
93 Packed_Size
: constant array (1 .. 18) of Byte_Length
:=
94 [01 => 01, -- Length in bytes for digits 1
95 02 => 02, -- Length in bytes for digits 2
96 03 => 02, -- Length in bytes for digits 2
97 04 => 03, -- Length in bytes for digits 2
98 05 => 03, -- Length in bytes for digits 2
99 06 => 04, -- Length in bytes for digits 2
100 07 => 04, -- Length in bytes for digits 2
101 08 => 05, -- Length in bytes for digits 2
102 09 => 05, -- Length in bytes for digits 2
103 10 => 06, -- Length in bytes for digits 2
104 11 => 06, -- Length in bytes for digits 2
105 12 => 07, -- Length in bytes for digits 2
106 13 => 07, -- Length in bytes for digits 2
107 14 => 08, -- Length in bytes for digits 2
108 15 => 08, -- Length in bytes for digits 2
109 16 => 09, -- Length in bytes for digits 2
110 17 => 09, -- Length in bytes for digits 2
111 18 => 10]; -- Length in bytes for digits 2
113 -------------------------
114 -- Conversion Routines --
115 -------------------------
117 subtype D32
is Positive range 1 .. 9;
118 -- Used to represent number of digits in a packed decimal value that
119 -- can be represented in a 32-bit binary signed integer form.
121 subtype D64
is Positive range 10 .. 18;
122 -- Used to represent number of digits in a packed decimal value that
123 -- requires a 64-bit signed binary integer for representing all values.
125 function Packed_To_Int32
(P
: System
.Address
; D
: D32
) return Integer_32
;
126 -- The argument P is the address of a packed decimal value and D is the
127 -- number of digits (in the range 1 .. 9, as implied by the subtype).
128 -- The returned result is the corresponding signed binary value. The
129 -- exception Constraint_Error is raised if the input is invalid.
131 function Packed_To_Int64
(P
: System
.Address
; D
: D64
) return Integer_64
;
132 -- The argument P is the address of a packed decimal value and D is the
133 -- number of digits (in the range 10 .. 18, as implied by the subtype).
134 -- The returned result is the corresponding signed binary value. The
135 -- exception Constraint_Error is raised if the input is invalid.
137 procedure Int32_To_Packed
(V
: Integer_32
; P
: System
.Address
; D
: D32
);
138 -- The argument V is a signed binary integer, which is converted to
139 -- packed decimal format and stored using P, the address of a packed
140 -- decimal item of D digits (D is in the range 1-9). Constraint_Error
141 -- is raised if V is out of range of this number of digits.
143 procedure Int64_To_Packed
(V
: Integer_64
; P
: System
.Address
; D
: D64
);
144 -- The argument V is a signed binary integer, which is converted to
145 -- packed decimal format and stored using P, the address of a packed
146 -- decimal item of D digits (D is in the range 10-18). Constraint_Error
147 -- is raised if V is out of range of this number of digits.
149 end Interfaces
.Packed_Decimal
;