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 Macro Or 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) Optionaly, __builtin_ldrmb (a,b) for previous generations of XL compilers. bcd_xst(a,b) (bcd)vec_xst_len_r(a,b) Optionaly, __builti_strmb (a,b) for previous generatoin f 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 */