Decimal instructions

Hardware packed-decimal instructions are available to C/C++ programs in the form of built-in functions. These hardware built-in functions are intended to provide access to decimal instructions that are not normally generated by the compiler.

Decimal instructions of SS format carry one or two length fields. Each length field is encoded with a binary length, that is the actual length - 1. In the function prototypes, the length parameters need to be specified as the actual length - 1. Argument names and order reflects the description of the hardware instructions in z/Architecture® Principles of Operation (that is, op1, op2, op3, etc.) Additional arguments provide required information for setting up the actual hardware instruction. For detailed description of each decimal instruction, see Chapter 8. Decimal Instructions of the z/Architecture Principles of Operation.

If you want to use any of the decimal functions, your program must include builtins.h and be compiled with either the LANGLVL(EXTENDED) option or the LANGLVL(LIBEXT) option.

Table 1. Decimal instruction prototypes
PROTOTYPE and Notes Sample Pseudo Assembly MIN ARCH
int __ap (unsigned char *op1, unsigned char len1, unsigned char *op2, unsigned char len2 );
Operands:
  • op1 represents the first operand in the hardware instruction. It points to the first operand location. The result replaces the first operand.
  • len1 specifies the length encoded in the machine instruction (that is, the number of additional bytes to the left of the first operand). The value is between 0 and 15.
  • op2 represents the second operand in the hardware instruction. It points to the second operand location.
  • len2 specifies the length encoded in the machine instruction (that is, the number of additional bytes to the left of the second operand). The value is between 0 and 15.
    Note: When either len1 or len2 is not specified as a literal, an EX instruction is generated to execute a target AP instruction with length encoded in the register used by the EX instruction.

The return value is the condition code set by the AP instruction.

AP Op1D(len1, Op1B), Op2D(len2, Op2B) ARCH(0)
int __cp (unsigned char *op1, unsigned char len1, unsigned char *op2, unsigned char len2 );
Operands:
  • op1 represents the first operand in the hardware instruction. It points to the first operand location.
  • len1 specifies the length encoded in the machine instruction (that is, the number of additional bytes to the left of the first operand). The value is between 0 and 15.
  • op2 represents the second operand in the hardware instruction. It points to the second operand location.
  • len2 specifies the length encoded in the machine instruction (that is, the number of additional bytes to the left of the second operand). The value is between 0 and 15.
    Note: When either len1 or len2 is not specified as a literal, an EX instruction is generated to execute a target CP instruction with length encoded in the register used by the EX instruction.

The return value is the condition code set by the CP instruction.

CP Op1D(len1, Op1B), Op2D(len2, Op2B) ARCH(0)
void __dp (unsigned char *op1, unsigned char len1, unsigned char *op2, unsigned char len2 );
Operands:
  • op1 represents the first operand (dividend) in the hardware instruction. It points to the first operand location. The result replaces the first operand. The quotient is placed leftmost in this location. The number of bytes in the quotient field is equal to the difference between the dividend and divisor lengths (len1 - len2). The remainder is placed rightmost in this location and has a length equal to the divisor length len2.
  • len1 specifies the length encoded in the machine instruction (that is, the number of additional bytes to the left of the first operand). The value must be greater than len2 and not greater than 15.
  • op2 represents the second operand (divisor) in the hardware instruction. It points to the second operand location.
  • len2 specifies the length encoded in the machine instruction (that is, the number of additional bytes to the left of the second operand). The value is between 0 and 7 and must be less than the value of len1.
    Note: When either len1 or len2 is not specified as a literal, an EX instruction is generated to execute a target DP instruction with length encoded in the register used by the EX instruction.
DP Op1D(len1, Op1B), Op2D(len2, Op2B) ARCH(0)
int __ed (unsigned char *OP1, unsigned char *OP2, unsigned char length);
Operands:
  • op2 (the source), which normally contains one or more decimal numbers in the signed-packed-decimal or unsigned-packed-decimal format, is changed to the zoned format and modified under the control of op1 (the pattern). The edited result replaces op1.
  • len specifies the length encoded in the machine instruction (that is, the number of additional bytes to the right of the first operand).
  • The length of op2 is determined by the operation according to the contents of the pattern. The leftmost four bits of each source byte must specify a decimal-digit code (0000-1001); a sign code (1010-1111) is recognized as a data exception. The rightmost four bits may specify either a sign code or a decimal-digit code. Access and data exceptions are recognized only for those bytes in op2 which are actually required.

The return value is the condition code.

ED Op1D(len,Op1B), Op2D(Op2B) ARCH(0)
int __edmk (unsigned char *OP1, unsigned char *OP2, unsigned char length, unsigned char **R1);
Operands:
  • op2 (the source), which normally contains one or more decimal numbers in the signed-packed-decimal or unsigned-packed-decimal format, is changed to the zoned format and modified under the control of op1 (the pattern). The edited result replaces op1.
  • len specifies the length encoded in the machine instruction (that is, the number of additional bytes to the right of the first operand).
  • __edmk is identical to __ed except for the additional function of inserting the address of the result byte in general register 1 if the result byte is a zoned source digit and the significance indicator was off before the examination. If no result byte meets the criteria, general register 1 remains unchanged; if more than one result byte meets the criteria, the address of the rightmost such result byte is inserted.
  • In the 24-bit addressing mode, the address replaces bits 40-63 of general register 1, and bits 0-39 of the register are not changed. In the 31-bit addressing mode, the address replaces bits 33-63 of general register 1, bit 32 of the register is set to zero, and bits 0-31 of the register remain unchanged. In the 64-bit addressing mode, the address replaces bits 0-63 of general register 1.

The return value is the condition code.

EDMK Op1D(len,Op1B), Op2D(Op2B) ARCH(0)
void __mp (unsigned char *op1, unsigned char len1, unsigned char *op2, unsigned char len2 );
Operands:
  • op1 represents the first operand (multiplicand) in the hardware instruction. It points to the first operand location. The result replaces the first operand. The multiplicand must have at least as many bytes of leftmost zeros as the number of bytes in the multiplier.
  • len1 specifies the length encoded in the machine instruction (that is, the number of additional bytes to the left of the first operand). The value must be greater than len2 and not greater than 15.
  • op2 represents the second operand (multiplier) in the hardware instruction. It points to the second operand location.
  • len2 specifies the length encoded in the machine instruction (that is, the number of additional bytes to the left of the second operand). The value is between 0 and 7 and must be less than the value of len1.
    Note: When either len1 or len2 is not specified as a literal, an EX instruction is generated to execute a target MP instruction with length encoded in the register used by the EX instruction.
MP Op1D(len1, Op1B), Op2D(len2, Op2B) ARCH(0)
int __sp (unsigned char *op1, unsigned char len1, unsigned char *op2, unsigned char len2 );
Operands:
  • op1 represents the first operand in the hardware instruction. It points to the first operand location. The result replaces the first operand.
  • len1 specifies the length encoded in the machine instruction (that is, the number of additional bytes to the left of the first operand). The value is between 0 and 15.
  • op2 represents the second operand in the hardware instruction. It points to the source location.
  • len2 specifies the length encoded in the machine instruction (that is, the number of additional bytes to the left of the second operand). The value is between 0 and 15.
    Note: When either len1 or len2 is not specified as a literal, an EX instruction is generated to execute a target SP instruction with length encoded in the register used by the EX instruction.

The return value is the condition code set by the SP instruction.

SP Op1D(len1, Op1B), Op2D(len2, Op2B) ARCH(0)
int __srp (unsigned char *op1, unsigned char len1, signed char op2, unsigned char op3 );
Operands:
  • op1 represents the first operand in the hardware instruction. It points to the source location. The result replaces the first operand.
  • len1 specifies the length encoded in the machine instruction (that is, the number of additional bytes to the left of the first operand). The value is between 0 and 15.
  • op2 represents the second operand in the hardware instruction. It is a shift value between -32 and 31. Positive shift values specify shifting to the left. Negative shift values specify shifting to the right.
  • op3 represents the third operand in the hardware instruction. It is used as a decimal rounding digit.
    Note: When either len1 or op3 is not specified as a literal, an EX instruction is generated to execute a target SRP instruction with len1 or op3 encoded in the register used by the EX instruction.

The return value is the condition code set by the SRP instruction.

SRP Op1D(len1, Op1B), Op2D(Op2B), Op3 ARCH(0)
int __tp(char *op1, unsigned char op1_len);
Operands:
  • op1 points to a byte string to be tested for a valid packed-decimal value.
  • op1_len specifies the length encoded in the machine instruction (than is, the number of additional bytes to the left of the first operand used in the machine instruction). The value is between 0 and 15.
    Note: When op1_len is not specified as a literal, an EX instruction is generated to execute a target TP instruction with op1_len encoded in the register used by the EX instruction.

The return value is the condition code set by the TP instruction.

TP Op1D(Op1_len, Op1B) ARCH(6)
int __zap (unsigned char *op1, unsigned char len1, unsigned char *op2, unsigned char len2 );
Operands:
  • op1 represents the first operand in the hardware instruction. It points to the location to receive the result.
  • len1 specifies the length encoded in the machine instruction (that is, the number of additional bytes to the left of the sign byte of the first operand). The value is between 0 and 15.
    Note: When len1 is not specified as a literal, an EX instruction is generated to execute a target ZAP instruction with len1 encoded in the register used by the EX instruction.
  • op2 represents the second operand in the hardware instruction. It points to the start location.
  • len2 specifies the length encoded in the machine instruction (that is, the number of additional bytes to the left of the sign byte of the second operand). The value is between 0 and 15.
    Note: When len2 is not specified as a literal, an EX instruction is generated to execute a target ZAP instruction with len2 encoded in the register used by the EX instruction.

The return value is the condition code set by the ZAP instruction.

ZAP Op1D(len1, Op1B), Op2D(len2, Op2B) ARCH(0)