Using milicode routines

The milicode routines contain machine-dependent and performance-critical functions.

All of the fixed-point divide instructions, and some of the multiply instructions, are different for POWER® family and PowerPC®. To allow programs to run on systems based on either architecture, a set of special routines is provided by the operating system. These are called milicode routines and contain machine-dependent and performance-critical functions. Milicode routines are located at fixed addresses in the kernel segment. These routines can be reached by a bla instruction. All milicode routines use the link register.

Note:
  1. No unnecessary registers are destroyed. Refer to the definition of each milicode routine for register usage information.
  2. Milicode routines do not alter any floating-point register, count register, or general-purpose registers (GPRs) 10-12. The link register can be saved in a GPR (for example, GPR 10) if the call appears in a leaf procedure that does not use nonvolatile GPRs.
  3. Milicode routines do not make use of a TOC.

The following milicode routines are available:

Item Description
__mulh Calculates the high-order 32 bits of the integer product arg1 * arg2.
Input
R3 = arg1 (signed integer)
R4 = arg2 (signed integer)
Output
R3 = high-order 32 bits of arg1*arg2
POWER® family Register Usage
GPR3, GPR4, MQ
PowerPC® Register Usage
GPR3, GPR4
__mull Calculates 64 bits of the integer product arg1 * arg2, returned in two 32-bit registers.
Input
R3 = arg1 (signed integer)
R4 = arg2 (signed integer)
Output
R3 = high-order 32 bits of arg1*arg2
R4 = low-order 32 bits of arg1*arg2
POWER® family Register Usage
GPR3, GPR4, MQ
PowerPC® Register Usage
GPR0, GPR3, GPR4
__divss Calculates the 32-bit quotient and 32-bit remainder of signed integers arg1/arg2. For division by zero and overflow, the quotient and remainder are undefined and may vary by implementation.
Input
R3 = arg1 (dividend) (signed integer)
R4 = arg2 (divisor) (signed integer)
Output
R3 = quotient of arg1/arg2 (signed integer)
R4 = remainder of arg1/arg2 (signed integer)
POWER® family Register Usage
GPR3, GPR4, MQ
PowerPC® Register Usage
GPR0, GPR3, GPR4
__divus Calculated the 32-bit quotient and 32-bit remainder of unsigned integers arg1/arg2. For division by zero and overflow, the quotient and remainder are undefined and may vary by implementation.
Input
R3 = arg1 (dividend) (unsigned integer)
R4 = arg2 (divisor) (unsigned integer)
Output
R3 = quotient of arg1/arg2 (unsigned integer)
R4 = remainder of arg1/arg2 (unsigned integer)
POWER® family Register Usage
GPR0, GPR3, GPR4, MQ, CR0 and CR1 of CR
PowerPC® Register Usage
GPR0, GPR3, GPR4
__quoss Calculates the 32-bit quotient of signed integers arg1/arg2. For division by zero and overflow, the quotient and remainder are undefined and may vary by implementation.
Input
R3 = arg1 (dividend) (signed integer)
R4 = arg2 (divisor) (signed integer)
Output
R3 = quotient of arg1/arg2 (signed integer)
POWER® family Register Usage
GPR3, GPR4, MQ
PowerPC® Register Usage
GPR3, GPR4
__quous Calculates the 32-bit quotient of unsigned integers arg1/arg2. For division by zero and overflow, the quotient and remainder are undefined and may vary by implementation.
Input
R3 = arg1 (dividend) (unsigned integer)
R4 = arg2 (divisor) (unsigned integer)
Output
R3 = quotient of arg1/arg2 (unsigned integer)
POWER® family Register Usage
GPR0, GPR3, GPR4, MQ, CR0 and CR1 of CR
PowerPC® Register Usage
GPR3, GPR4
The following example uses the mulh milicode routine in an assembler program:

li R3, -900
li R4, 50000
bla .__mulh
...
.extern .__mulh