1------------------------------------------------------------------------------ 2-- -- 3-- GNAT COMPILER COMPONENTS -- 4-- -- 5-- I N T E R F A C E S . P A C K E D _ D E C I M A L -- 6-- -- 7-- S p e c -- 8-- (Version for IBM Mainframe Packed Decimal Format) -- 9-- -- 10-- Copyright (C) 1992-2019, Free Software Foundation, Inc. -- 11-- -- 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. -- 18-- -- 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. -- 22-- -- 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/>. -- 27-- -- 28-- GNAT was originally developed by the GNAT team at New York University. -- 29-- Extensive contributions were provided by Ada Core Technologies Inc. -- 30-- -- 31------------------------------------------------------------------------------ 32 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. 38 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. 47 48with System; 49 50package Interfaces.Packed_Decimal is 51 52 ------------------------ 53 -- Format Description -- 54 ------------------------ 55 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: 60 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 67 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. 73 74 -- Some examples follow: 75 76 -- 05 76 3C +5763 77 -- 00 01 1D -11 78 -- 00 04 4E +44 (non-standard sign) 79 -- 00 00 00 invalid (incorrect sign nibble) 80 -- 0A 01 1C invalid (bad digit) 81 82 ------------------ 83 -- Length Array -- 84 ------------------ 85 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. 89 90 subtype Byte_Length is Positive range 1 .. 10; 91 -- Range of possible byte lengths 92 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 112 113 ------------------------- 114 -- Conversion Routines -- 115 ------------------------- 116 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. 120 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. 124 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. 130 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. 136 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. 142 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. 148 149end Interfaces.Packed_Decimal; 150