Binary-Coded Decimal Built-In Functions
Binary-coded decimal (BCD) values are compressed; each decimal digit
and sign bit occupies 4 bits. Digits are ordered right-to-left in the order
of significance. The final 4 bits encode the sign. A valid encoding must
have a value in the range 0–9 in each of its 31 digits, and a value in
the range 10–15 for the sign field.
Source operands with sign codes of 0b1010, 0b1100, 0b1110, or 0b1111
are interpreted as positive values. Source operands with sign codes of
0b1011 or 0b1101 are interpreted as negative values.
BCD arithmetic operations encode the sign of their result as follows:
A value of 0b1101 indicates a negative value, while 0b1100 and 0b1111
indicate positive values or zero, depending on the value of the positive
sign (PS) bit.
These built-in functions can operate on values of at most 31 digits.
BCD values are stored in memory as contiguous arrays of 1–16
bytes.
BCD built-in functions are valid only when -march or
-qarch is set to target POWER8 processors or
later.
summarizes the BCD built-in
functions. Functions are grouped by type. Within type, functions are listed
alphabetically. Prototypes are provided for each function.
Binary-Coded Decimal Built-In Functions
Group
Description of Binary-Coded Decimal
Built-In Functions (with Prototypes)
BCD Add and Subtract
___BUILTIN_BCDADD (a, b, ps)
Purpose:
Returns the result of the addition of the BCD values a and
b.
The sign of the result is determined as follows:
If the result is a nonnegative value and
ps is 0, the sign is set to 0b1100
(0xC).
If the result is a nonnegative value and
ps is 1, the sign is set to 0b1111
(0xF).
If the result is a negative value, the sign is set to
0b1101 (0xD).
Parameters:
The ps parameter selects the numeric format for the
positive-signed BCD numbers. It must be set to one of the values
defined in
.
vector unsigned char __builtin_bcdadd (vector unsigned
char, vector unsigned char, const int);
__BUILTIN_BCDSUB (a, b, ps)
Purpose
Returns the result of the subtraction of the BCD values a
and b. Sets the sign of the nonnegative result to 0b1100 if
ps is 0. Otherwise, sets the sign of the
nonnegative result to 0b1111.
The sign of the result is determined as follows:
If the result is a nonnegative value and
ps is 0, the sign is set to 0b1100
(0xC).
If the result is a nonnegative value and
L is 1, the sign is set to 0b1111
(0xF).
If the result is a negative value, the sign is set to
0b1101 (0xD).
Parameters:
The ps parameter selects the numeric format for the
positive-signed BCD numbers. It must be set to one of the values
defined in
vector unsigned char __builtin_bcdsub (vector unsigned
char, vector unsigned char, long);
BCD Predicates
__BUILTIN_BCDADD_OFL (a, b)
Purpose:
Returns one if the corresponding BCD add operation results
in an overflow. Otherwise, returns zero.
int __ builtin_bcdadd_ofl (vector unsigned char, vector
unsigned char);
__BUILTIN_BCDSUB_OFL (a, b)
Purpose:
Returns one if the corresponding BCD subtract operation
results in an overflow. Otherwise, returns zero.
int __ builtin_bcdsub_ofl (vector unsigned char, vector
unsigned char);
__ BUILTIN_BCD_INVALID (a)
Purpose:
Returns one if
a is an invalid encoding of a BCD value.
Otherwise, returns zero.
int __ builtin_bcd_invalid (vector unsigned char);
BCD Comparison
__ BUILTIN_BCDCMPEQ (a, b)
Purpose:
Returns one if the BCD value
a is equal to
b. Otherwise, returns zero.
int __ builtin_bcdcmpeq (vector unsigned char, vector
unsigned char);
__ BUILTIN_BCDCMPGE (a, b)
Purpose:
Returns one if the BCD value
a is greater than or equal to
b. Otherwise, returns zero.
int __ builtin_bcdcmpge (vector unsigned char, vector
unsigned char);
__BUILTIN_BCDCMPGT (a, b)
Purpose:
Returns one if the BCD value
a is greater than
b. Otherwise, returns zero.
int __ builtin_bcdcmpgt (vector unsigned char, vector
unsigned char);
__BUILTIN_BCDCMPLE (a, b)
Purpose:
Returns one if the BCD value
a is less than or equal to
b. Otherwise, returns zero.
int __ builtin_bcdcmple (vector unsigned char, vector
unsigned char);
__ BUILTIN_BCDCMPLT (a, b)
Purpose:
Returns one if the BCD value
a is less than
b. Otherwise, returns zero.
int __ builtin_bcdcmplt (vector unsigned char, vector
unsigned char);
BCD Load and Store
__ BUILTIN_BCD2DFP (a)
Purpose:
Converts a signed BCD value stored as a vector of unsigned
characters to a 128-bit decimal floating-point format.
Parameter value a is a 128-bit vector that is treated
as a signed BCD 31-digit value.
The return value is a doubleword floating-point pair in
a decimal 128 floating-point format.
_Decimal128 __ builtin_bcd2dfp (vector unsigned
char);
__ BUILTIN_BCDMUL10 (ARG1)
Purpose:
Multiplies the BCD number in ARG1 by 10. The sign indicator
remains unmodified.
vector unsigned char __builtin_bcdmul10 (vector unsigned
char);
__ BUILTIN_BCDDIV10 (ARG1)
Purpose:
Divides the BCD number in ARG1 by 10. The sign indicator
remains unmodified.
vector unsigned char __builtin_bcddiv10 (vector unsigned
char);
BCD Header Functions
These functions are being phased in for POWER8, and might
not be available on all implementations. Phased-in functions are
optional for the current generation of compliant systems.
The bcd.h header file defines a BCD data type and the interfaces to
efficiently compute the BCD functions listed in
. These interfaces can be
implemented as macros or by another method, such as static inline
functions.
shows one suggested
implementation using macros and the built-in operators shown in
. A sample bcd.h listing is shown
in
.
The bcd data type is defined as follows in the bcd.h:
typedef bcd vector unsigned char;
The header file also defines a bcd_default_format as follows:
#ifndef bcd_default_format
#define bcd_default_format __BCD_SIGN_IBM
#endif
BCD Functions Defined by bcd.h
MacroOr static inline function.
Macro Definition
bcd_add(a,b)
(bcd)__builtin_bcdadd (a,b, bcd_default_format)
bcd_sub(a,b)
(bcd)__builtin_bcdsub (a,b, bcd_default_format)
bcd_add_ofl(a,b)
(_Bool)__builtin_bcdadd_ofl (a,b)
bcd_sub_ofl(a,b)
(_Bool)__builtin_bcdsub_ofl (a,b)
bcd_invalid(a)
(_Bool)__builtin_bcd_invalid (a)
bcd_cmpeq(a,b)
(_Bool)__builtin_bcdcmpeq (a,b)
bcd_cmpge(a,b)
(_Bool)__builtin_bcdcmpge (a,b)
bcd_cmpgt(a,b)
(_Bool)__builtin_bcdcmpgt (a,b)
bcd_cmple(a,b)
(_Bool)__builtin_bcdcmple (a,b)
bcd_cmplt(a,b)
(_Bool)__builtin_bcdcmplt (a,b)
bcd_cmpne(a,b)
!(_Bool)__builtin_bcdcmpeq (a,b)
bcd_xl(a,b)
(bcd)vec_xl_len_r(a,b)Optionally, __builtin_ldrmb (a,b) for previous
generations of XL compilers.
bcd_xst(a,b)
(bcd)vec_xst_len_r(a,b)Optionally, __builtin_strmb (a,b) for previous
generations of XL compilers.
bcd_quantize(d)
__builtin_bcdquantize (d)
bcd_dfp(a)
__builtin_bcd2dfp (a)
bcd_dfp2bcd(dfp)
(bcd)__builtin_vec_DFP2BCD (_Decimal128 dfp)
bcd_string2bcd(string)
(bcd) __bcd_string2bcd (string, bcd_default_format)
bcd_mul10(a)
(bcd) __builtin_bcdmul10 (a)
bcd_div10(a)
(bcd) __builtin_bcddiv10 (a)
bcd_mul(a,b)
(bcd) __bcd_mul (a,b,bcd_default_format)
bcd_div(a,b)
(bcd) __bcd_div (a,b,bcd_default_format)
In addition, the bcd.h file provides access to the library functions
shown in
. These functions may be provided
either as a static inline function by bcd.h or in a system library that is
linked with an application which uses such functions.
BCD Support Functions
Function Name
Description of BCD Support Functions
(with Prototypes)
__BCD_MUL (A,B,F)
Purpose:
Two signed 31-digit values are multiplied, and the lower 31
digits of the product are returned. Overflow is ignored.
Parameter A is a 128-bit vector that is treated as a
signed BCD 31-digit value.
Parameter B is a 128-bit vector that is treated as a
signed BCD 31-digit value.
Parameter F specifies the format of the BCD number
result.
This function returns a 128-bit vector that is the lower 31
digits of (a × b).
bcd __bcd_mul (bcd, bcd, long)
__BCD_DIV (A,B,F)
Purpose:
One signed 31-digit value is divided by a second 31-digit
value. The quotient is returned.
Parameter A is a 128-bit vector that is treated as a
signed BCD 31-digit value.
Parameter B is a 128-bit vector that is treated as a
signed BCD 31-digit value.
Parameter F specifies the format of the BCD number
result.
This function returns a 128-bit vector that is the lower 31
digits of (a / b).
bcd __builtin_bcddiv (bcd, bcd, long);
__BCD_STRING2BCD(S,F)
Purpose:
The received ASCII string is converted to a BCD number and
returned as a BCD type.
Parameter S is the string to be converted.
Parameter F specifies the format of the BCD number
result.
This function returns a 128-bit vector that consists of 31
BCD digits and a sign.
bcd __bcd_string2bcd (char *, long);
BCD API Named Constants
The BCD header file, bcd.h, defines named constants.
defines constants for use in
conjunction with the BCD format representation. They can be used for
format specification and to set the bcd_default_format.
Constants Used with BCD_FORMAT
Constants
#define BCD_FORMAT_IBM 0
#define BCD_FORMAT_Z 0
#define BCD_FORMAT_POWER 0
#define BCD_FORMAT_IBMi 1
#define BCD_FORMAT_I 1
#define BCD_FORMAT_NCR 1
Exemplary Implementation for bcd.h
shows an exemplary
implementation of the bcd.h with the interfaces shown in
, using the macros and the
built-in operators shown in
, and the functions shown in
.
Sample bcd.h Listing
#ifndef __BCD_H
#define __BCD_H
typedef bcd vector unsigned char;
#define BCD_FORMAT_IBM 0
#define BCD_FORMAT_Z 0
#define BCD_FORMAT_POWER 0
#define BCD_FORMAT_IBMi 1
#define BCD_FORMAT_I 1
#define BCD_FORMAT_NCR 1
#ifndef bcd_default_format
#define bcd_default_format __BCD_SIGN_IBM
#endif
#define bcd_add(a,b) ((bcd)__builtin_bcdadd (a,b,bcd_default_format))
#define bcd_sub(A,b) ((bcd)__builtin_bcdsub (a,b,bcd_default_format))
#define bcd_add_ofl(a,b) ((_Bool)__builtin_bcdadd_ofl (a,b))
#define bcd_add_ofl(a,b) ((_Bool)__builtin_bcdsub_ofl (a,b))
#define bcd_invalid(a) ((_Bool)__builtin_bcd_invalid (a))
#define bcd_cmpeq(a,b) ((_Bool)__builtin_bcdcmpeq (a,b))
#define bcd_cmpge(a,b) ((_Bool)__builtin_bcdcmpge (a,b))
#define bcd_cmpgt(a,b) ((_Bool)__builtin_bcdcmpgt (a,b))
#define bcd_cmple(a,b) ((_Bool)__builtin_bcdcmple (a,b))
#define bcd_cmplt(a,b) ((_Bool)__builtin_bcdcmplt (a,b))
#define bcd_cmpne(a,b) (!(_Bool)__builtin_bcdcmpeq (a,b))
#define bcd_xl(a,b) ((bcd)vec_xl_len_r(a,b))
#define bcd_xst(a,b) ((bcd)vec_xst_len_r(a,b))
#define bcd_quantize(d) (__builtin_bcdquantize(d))
#define bcd_dfp(a) (__builtin_bcd2dfp (a))
#define bcd_dfp2bcd(DFP) ((bcd)__builtin_vec_DFP2BCD (_Decimal128 dfp))
#define bcd_string2bcd(string) ((bcd) __bcd_string2bcd (string, bcd_default_format)
#define bcd_mul10(a) ((bcd) __builtin_bcdmul10 (a))
#define bcd_div10(a) ((bcd) __builtin_bcddiv10 (a))
#define bcd_mul(a,b) ((bcd) __bcd_mul (a,b,bcd_default_format))
#define bcd_div(a,b) ((bcd) __bcd_div (a,b,bcd_default_format))
#endif /* __BCD_H */