SLAA534A June 2013 – June 2020
The compiler generates calls to helper functions to perform operations that need to be supported by the compiler, but are not supported directly by the architecture, such as floating-point operations on devices that lack dedicated hardware. These helper functions must be implemented in the RTS library of any toolchain that conforms to the ABI.
Helper functions are named using the prefix _ _MSP430_. Any identifier with this prefix is reserved for the ABI.
The helper functions adhere to the standard calling conventions, except as indicated in Section 6.4.
The following tables specify the helper functions using C notation and syntax. The types in the table correspond to the generic data types specified in Section 2.2.
The functions in Table 6-1 convert between various floating-point and integer formats, in accordance with C's conversion rules and the floating-point behavior specified by Section 6.2.
Signature | Description |
---|---|
float32 _ _MSP430_cvtdf(float64 x); | Convert double-precision float to single-precision float |
float64 _ _MSP430_cvtfd(float32 x); | Convert single-precision float to double-precision float |
int16 _ _MSP430_fixdi(float64 x); | Convert double-precision float to int |
int32 _ _MSP430_fixdli(float64 x); | Convert double-precision float to long int |
int64 _ _MSP430_fixdlli(float64 x); | Convert double-precision float to long long int |
uint16 _ _MSP430_fixdu(float64 x); | Convert double-precision float to unsigned int |
uint32 _ _MSP430_fixdul(float64 x); | Convert double-precision float to unsigned long int |
uint64 _ _MSP430_fixdull(float64 x); | Convert double-precision float to unsigned long long int |
int16 _ _MSP430_fixfi(float32 x); | Convert single-precision float to int |
int32 _ _MSP430_fixfli(float32 x); | Convert single-precision float to long int |
int64 _ _MSP430_fixflli(float32 x); | Convert single-precision float to long long int |
uint16 _ _MSP430_fixfu(float32 x); | Convert single-precision float to unsigned int |
uint32 _ _MSP430_fixful(float32 x); | Convert single-precision float to unsigned long int |
uint64 _ _MSP430_fixfull(float32 x); | Convert single-precision float to unsigned long long int |
float64 _ _MSP430_fltid(int16 x); | Convert int to double-precision float |
float32 _ _MSP430_fltif(int16 x); | Convert int to single-precision float |
float64 _ _MSP430_fltlid(int32 x); | Convert long int to double-precision float |
float32 _ _MSP430_fltlif(int32 x); | Convert long int to single-precision float |
float64 _ _MSP430_fltud(uint16 x); | Convert unsigned int to double-precision float |
float32 _ _MSP430_fltuf(uint16 x); | Convert unsigned int to single-precision float |
float64 _ _MSP430_fltuld(uint32 x); | Convert unsigned long int to double-precision float |
float32 _ _MSP430_fltulf(uint32 x); | Convert unsigned long int to single-precision float |
The functions in Table 6-2 perform floating-point comparisons in accordance with C semantics and the floating-point behavior specified by Section 6.2.
The _ _MSP430_cmp functions return an integer less than 0 if x is less than y, 0 if the values are equal, or an integer greater than 0 of x is greater than y. If either operand is NaN, the result is undefined.
The remaining comparison functions are currently unsupported, but the names are reserved for possible future use.
Signature | Description |
---|---|
int16 _ _MSP430_cmpd(float64 x, float64 y); | Double-precision comparison |
int16 _ _MSP430_cmpf(float32 x, float32 y); | Single-precision comparison |
int16 _ _MSP430_eqd(float64 x, float64 y); | Double-precision comparison: x == y (Not currently supported) |
int16 _ _MSP430_geqdfloat64 x, float64 y); | Double-precision comparison: x >= y (Not currently supported) |
int16 _ _MSP430_gtrd(float64 x, float64 y); | Double-precision comparison: x > y (Not currently supported) |
int16 _ _MSP430_leqd(float64 x, float64 y); | Double-precision comparison: x <= y (Not currently supported) |
int16 _ _MSP430_lssd(float64 x, float64 y); | Double-precision comparison: x < y (Not currently supported) |
int16 _ _MSP430_neqd(float64 x, float64 y); | Double-precision comparison: x != y (Not currently supported) |
The functions in Table 6-3 perform floating-point arithmetic in accordance with C semantics and the floating-point behavior specified by Section 6.2.
Signature | Description |
---|---|
float64 _ _MSP430_addd(float64 x, float64 y); | Add double-precision to double-precision |
float32 _ _MSP430_addf(float32 x, float32 y); | Add single-precision to single-precision |
float64 _ _MSP430_divd(float64 x, float64 y); | Divide double-precision by double-precision |
float32 _ _MSP430_divf(float32 x, float32 y); | Divide single-precision by single-precision |
float64 _ _MSP430_mpyd(float64 x, float64 y); | Multiply double-precision by double-precision |
float32 _ _MSP430_mpyf(float32 x, float32 y); | Multiply single-precision by single-precision |
float64 _ _MSP430_subd(float64 x, float64 y); | Subtract double-precision from double-precision |
float32 _ _MSP430_subf(float32 x, float32 y); | Subtract single-precision from single-precision |
float64 _ _MSP430_negd(float64 x); | Negate double-precision |
float32 _ _MSP430_negf(float32 x); | Negate single-precision |
The integer arithmetic functions in Table 6-4 operate according to C semantics.
Signature | Description |
---|---|
Multiplication | |
int16 _ _MSP430_mpyi(int16 x, int16 y); | Multiply int by int. |
int16 _ _MSP430_mpyi_hw(int16 x, int16 y); | Multiply int by int. Uses hardware MPY16. |
int16 _ _MSP430_mpyi_f5hw(int16 x, int16 y); | Multiply int by int. Uses hardware MPY32 (F5xx devices and up). |
int32 _ _MSP430_mpyl(int32 x, int32 y); | Multiply long by long. |
int32 _ _MSP430_mpyl_hw(int32 x, int32 y); | Multiply long by long. Uses hardware MPY16. |
int32 _ _MSP430_mpyl_hw32(int32 x, int32 y); | Multiply long by long. Uses hardware MPY32 (F4xx devices). |
int32 _ _MSP430_mpyl_f5hw(int32 x, int32 y); | Multiply long by long. Uses hardware MPY32 (F5xx devices and up). |
int64 _ _MSP430_mpyll(int64 x, int64 y); | Multiply long long by long long. |
int64 _ _MSP430_mpyll_hw(int64 x, int64 y); | Multiply long long by long long. Uses hardware MPY16. |
int64 _ _MSP430_mpyll_hw32(int64 x, int64 y); | Multiply long long by long long. Uses hardware MPY32 (F4xx devices). |
int64 _ _MSP430_mpyll_f5hw(int64 x, int64 y); | Multiply long long by long long. Uses hardware MPY32 (F5xx devices and up). |
int32 _ _MSP430_mpysl(int16 x, int16 y); | Multiply int by int; result is long. |
int32 _ _MSP430_mpysl_hw(int16 x, int16 y); | Multiply int by int; result is long. Uses hardware MPY16. |
int32 _ _MSP430_mpysl_f5hw(int16 x, int16 y); | Multiply int by int; result is long. Uses hardware MPY32 (F5xx devices and up). |
int64 _ _MSP430_mpysll(int32 x, int32 y); | Multiply long by long; result is long long. |
int64 _ _MSP430_mpysll_hw(int32 x, int32 y); | Multiply long by long; result is long long. Uses hardware MPY16. |
int64 _ _MSP430_mpysll_hw32(int32 x, int32 y); | Multiply long by long; result is long long. Uses hardware MPY32 (F4xx devices). |
int64 _ _MSP430_mpysll_f5hw(int32 x, int32 y); | Multiply long by long; result is long long. Uses hardware MPY32 (F5xx devices and up). |
uint32 _ _MSP430_mpyul(uint16 x, uint16 y); | Multiply unsigned int by unsigned int; result is unsigned long. |
uint32 _ _MSP430_mpyul_hw(uint16 x, uint16 y); | Multiply unsigned int by unsigned int; result is unsigned long. Uses hardware MPY16. |
uint32 _ _MSP430_mpyul_f5hw(uint16 x, uint16 y); | Multiply unsigned int by unsigned int; result is unsigned long. Uses hardware MPY32 (F5xx devices and up). |
uint64 _ _MSP430_mpyull(uint32 x, uint32 y); | Multiply unsigned long by unsigned long; result is unsigned long long. |
uint64 _ _MSP430_mpyull_hw(uint32 x, uint32 y); | Multiply unsigned long by unsigned long; result is unsigned long long. Uses hardware MPY16. |
uint64 _ _MSP430_mpyull_hw32(uint32 x, uint32 y); | Multiply unsigned long by unsigned long; result is unsigned long long. Uses hardware MPY32 (F4xx devices). |
uint64 _ _MSP430_mpyull_f5hw(uint32 x, uint32 y); | Multiply unsigned long by unsigned long; result is unsigned long long. Uses hardware MPY32 (F5xx devices and up). |
Division | |
int16 _ _MSP430_divi(int16 x, int16 y); | Divide int by int. |
int32 _ _MSP430_divli(int32 x, int32 y); | Divide long by long. |
int64 _ _MSP430_divlli(int64 x, int64 y); | Divide long long by long long. |
uint16 _ _MSP430_divu(uint16 x, uint16 y); | Divide unsigned lint by unsigned lint. |
uint32 _ _MSP430_divlu(uint32 x, uint32 y); | Divide unsigned long by unsigned long. |
uint64 _ _MSP430_divllu(uint64 x, uint64 y); | Divide unsigned long long by unsigned long long. |
Remainder (Modulus) | |
int16 _ _MSP430_remi(int16 x, int16 y); | Remainder of int divided by int (x mod y) |
int32 _ _MSP430_remli(int32 x, int32 y); | Remainder of long divided by long (x mod y) |
int64 _ _MSP430_remlli(int64x. int64 y); | Remainder of long long divided by long long (x mod y) |
uint16 _ _MSP430_remu(uint16 x, uint16 y); | Remainder of unsigned int divided by unsigned int (x mod y) |
uint32 _ _MSP430_remul(uint32, uint32); | Remainder of unsigned long divided by unsigned long (x mod y) |
uint64 _ _MSP430_remull(uint64, uint64); | Remainder of unsigned long long divided by unsigned long long (x mod y) |
The bitwise operator functions are listed in Table 6-5. These functions are used by MSP430 and MSP430X.
Rotate left operations are performed with no carry. The most-significant bit is moved to the least-significant bit (LSB), and all other bits are shifted left. There is no rotation function for the long long data type.
Logical left shift operations are the same as an arithmetic left shift; a zero is shifted into the LSB.
Arithmetic right shift operations shift the most-significant bit (MSB), to the right and copy the old MSB into the new MSB. This preserves the sign in a signed value. The LSB is discarded.
Logical right shift operations insert a value of 0 in the MSB and discard the LSB.
The shift or rotation count in functions that accept a second argument may not be less than zero, even though it is handled as a signed int.
Signature | Description |
---|---|
Rotation | |
uint16 _ _MSP430_rlli(uint16 x, int16 n); | Rotate bits of an int left by n bits, where n can be up to 16. |
uint16 _ _MSP430_rlli_1(uint16 x); . . . uint16 _ _MSP430_rlli_15(uint16 x); | Rotate bits of an int left by specified number of bits. |
uint32 _ _MSP430_rlll(uint32 x, int16 n); | Rotate bits of a long left by n bits, where n can be up to 32. |
Logical Left Shift | |
uint16 _ _MSP430_slli(uint16 x, int16 n); | Perform a logical left shift on an int. Shift by n bits, where n can be up to 16. |
uint16 _ _MSP430_slli_1(uint16 x); . . . uint16 _ _MSP430_slli_15(uint16 x); | Perform a logical left shift on an int. Shift left by specified number of bits. |
uint32 _ _MSP430_slll(uint32 x, int16 n); | Perform a logical left shift on a long. Shift by n bits, where n can be up to 32. |
uint32 _ _MSP430_slll_1(uint32 x); . . . uint32 _ _MSP430_slll_15(uint32 x); | Perform a logical left shift on a long. Shift left by specified number of bits. Shift counts above 15 use _ _MSP430_slll. |
uint64 _ _MSP430_sllll(uint64 x, int16 n); | Perform a logical left shift on a long long. Shift by n bits, where n can be up to 64. |
Arithmetic Right Shift | |
int16 _ _MSP430_srai(int16 x, int16 n); | Perform an arithmetic right shift on an int. Shift by n bits, where n can be up to 16. |
int16 _ _MSP430_srai_1(int16 x); . . . int32 _ _MSP430_srai_15(int16 x); | Perform an arithmetic right shift on an int. Shift by specified number of bits. |
int16 _ _MSP430_sral(int32 x, int16 n); | Perform an arithmetic right shift on a long. Shift by n bits, where n can be up to 32. |
int32 _ _MSP430_sral_1(int32 x); . . . int32 _ _MSP430_sral_15(int32 x); | Perform an arithmetic right shift on a long. Shift by specified number of bits. Shift counts above 15 use _ _MSP430_sral. |
int64 _ _MSP430_srall(int64 x, int16 n); | Perform an arithmetic right shift on a long long. Shift by n bits, where n can be up to 64. |
Logical Right Shift | |
uint16 _ _MSP430_srli(uint16 x, int16 n); | Perform a logical right shift on an int. Shift by n bits, where n can be up to 16. |
uint16 _ _MSP430_srli_1(uint16 x); . . . uint16 _ _MSP430_srli_15(uint16 x); | Perform a logical right shift on an int. Shift right by specified number of bits. |
uint32 _ _MSP430_srll(uint32 x, int16 n); | Perform a logical right shift on a long. Shift by n bits, where n can be up to 32. |
uint32 _ _MSP430_srll_1(uint32 x); . . . uint32 _ _MSP430_srll_15(uint32 x); | Perform a logical right shift on a long. Shift right by specified number of bits. Shift counts above 15 use _ _MSP430_srll. |
uint64 _ _MSP430_srlll(uint64 x, int16 n); | Perform a logical right shift on a long long. Shift by n bits, where n can be up to 64. |
The helper functions in Table 6-6 optimize restoring callee-saved registers. These functions are used by MSP430, but not MSP430X .
Signature | Description |
---|---|
void _ _MSP430_epilog_1(void); | POP R10 and return. |
void _ _MSP430_epilog_2(void); | POP R10 through R9 and return. |
void _ _MSP430_epilog_3(void); | POP R10 through R8 and return. |
void _ _MSP430_epilog_4(void); | POP R10 through R7 and return. |
void _ _MSP430_epilog_5(void); | POP R10 through R6 and return. |
void _ _MSP430_epilog_6(void); | POP R10 through R5 and return. |
void _ _MSP430_epilog_7(void); | POP R10 through R4 and return. |
The miscellaneous helper functions in Table 6-7 are described in the sections that follow.
Signature | Description |
---|---|
void _abort_msg(const char *string); | Report failed assertion |
_abort_msg
The function _abort_msg is generated to print a diagnostic message when a run-time assertion (for example, the C assert macro) fails. It must not return. That is, it must call abort or terminate the program by other means.