ZHCADC5A June 2013 – June 2020
编译器生成对辅助函数的调用以执行编译器需要支持但架构不直接支持的运算,例如在缺少专用硬件的设备上执行浮点运算。这些辅助函数必须在符合 ABI 的任何工具链的 RTS 库中实现。
辅助函数使用前缀 _ _MSP430 命名。具有此前缀的任何标识符都将保留供 ABI 使用。
辅助函数遵守标准调用约定,节 6.3中指定的约定除外。
下表使用 C 表示法和语法指定辅助函数。表中的类型对应于节 2.1中指定的通用数据类型。
表 6-1 中的函数根据 C 语言的转会规则以及节 6.1指定的浮点行为在各种浮点和 int 格式之间进行转换。
签名 | 说明 |
---|---|
float32 _ _MSP430_cvtdf(float64 x); | 将双精度浮点型转换为单精度浮点型 |
float64 _ _MSP430_cvtfd(float32 x); | 将单精度浮点型转换为双精度浮点型 |
int16 _ _MSP430_fixdi(float64 x); | 将双精度浮点型转换为 int |
int32 _ _MSP430_fixdli(float64 x); | 将双精度浮点型转换为 long int |
int64 _ _MSP430_fixdlli(float64 x); | 将双精度浮点型转换为 long long int |
uint16 _ _MSP430_fixdu(float64 x); | 将双精度浮点型转换为 unsigned int |
uint32 _ _MSP430_fixdul(float64 x); | 将双精度浮点型转换为 unsigned long int |
uint64 _ _MSP430_fixdull(float64 x); | 将双精度浮点型转换为 unsigned long long int |
int16 _ _MSP430_fixfi(float32 x); | 将单精度浮点型转换为 int |
int32 _ MSP430_fixfli (float32 x); | 将单精度浮点型转换为 long int |
int64 _ _MSP430_fixflli(float32 x); | 将单精度浮点型转换为 long long int |
uint16 _ _MSP430_fixfu(float32 x); | 将单精度浮点型转换为 unsigned int |
uint32 _ _MSP430_fixful(float32 x); | 将单精度浮点型转换为 unsigned long int |
uint64 _ _MSP430_fixfull(float32 x); | 将单精度浮点型转换为 unsigned long long int |
float64 _ _MSP430_fltid(int16 x); | 将 int 转换为双精度浮点型 |
float32 _ _MSP430_fltif(int16 x); | 将 int 转换为单精度浮点型 |
float64 _ _MSP430_fltlid(int32 x); | 将 long int 转换为双精度浮点型 |
float32 _ _MSP430_fltlif(int32 x); | 将 long int 转换为单精度浮点型 |
float64 _ _MSP430_fltud(uint16 x); | 将 unsigned int 转换为双精度浮点型 |
float32 _ _MSP430_fltuf(uint16 x); | 将 unsigned int 转换为单精度浮点型 |
float64 _ _MSP430_fltuld(uint32 x); | 将 unsigned long int 转换为双精度浮点型 |
float32 _ _MSP430_fltulf(uint32 x); | 将 unsigned long int 转换为单精度浮点型 |
表 6-2 中的函数根据 C 语言的语义和节 6.1指定的浮点行为执行浮点比较。
如果 x 小于 y,则MSP430_cmp 函数返回一个小于 0 的整数;如果 x 等于 y,则返回 0;如果 x 大于 y,则返回一个大于 0 的整数。如果任一操作数为 NaN,则结果未定义。
其余的比较函数当前不受支持,但保留了名称以供将来使用。
签名 | 说明 |
---|---|
int16 _ _MSP430_cmpd(float64 x, float64 y); | 双精度比较 |
int16 _ _MSP430_cmpf(float32 x, float32 y); | 单精度比较 |
int16 _ _MSP430_eqd(float64 x, float64 y); | 双精度比较:x == y(当前不受支持) |
int16 _MSP430_geqdfloat64 x、float64 y); | 双精度比较:x >= y(当前不受支持) |
int16 _ _MSP430_gtrd(float64 x, float64 y); | 双精度比较:x > y(当前不受支持) |
int16 _ _MSP430_leqd(float64 x, float64 y); | 双精度比较:x <= y(当前不受支持) |
int16 _ _MSP430_lssd(float64 x, float64 y); | 双精度比较:x < y(当前不受支持) |
int16 _ _MSP430_neqd(float64 x, float64 y); | 双精度比较:x!= y(当前不受支持) |
表 6-3 中的函数根据 C 语言的语义和节 6.1指定的浮点行为执行浮点运算。
签名 | 说明 |
---|---|
float64 _ _MSP430_addd(float64 x, float64 y); | 双精度与双精度相加 |
float32 _ _MSP430_addf(float32 x, float32 y); | 单精度与单精度相加 |
float64 _ _MSP430_divd(float64 x, float64 y); | 双精度除以双精度 |
float32 _ _MSP430_divf(float32 x, float32 y); | 单精度除以单精度 |
float64 _ _MSP430_mpyd(float64 x, float64 y); | 双精度与双精度相乘 |
float32 _ _MSP430_mpyf(float32 x, float32 y); | 单精度与单精度相乘 |
float64 _ _MSP430_subd(float64 x, float64 y); | 从双精度中减去双精度 |
float32 _ _MSP430_subf(float32 x, float32 y); | 从单精度中减去单精度 |
float64 _ _MSP430_negd(float64 x); | 将双精度数取反 |
float32 _ _MSP430_negf(float32 x); | 将单精度数取反 |
表 6-4 中的整数算术函数根据 C 语言的语义进行运算。
签名 | 说明 |
---|---|
乘法 | |
int16 _ _MSP430_mpyi(int16 x, int16 y); | int 与 int 相乘。 |
int16 _ _MSP430_mpyi_hw(int16 x, int16 y); | int 与 int 相乘。使用硬件 MPY16。 |
int16 _ _MSP430_mpyi_f5hw(int16 x, int16 y); | int 与 int 相乘。使用硬件 MPY32(F5xx 器件及更高版本)。 |
int32 _ _MSP430_mpyl(int32 x, int32 y); | long 与 long 相乘。 |
int32 _ _MSP430_mpyl_hw(int32 x, int32 y); | long 与 long 相乘。使用硬件 MPY16。 |
int32 _ _MSP430_mpyl_hw32(int32 x, int32 y); | long 与 long 相乘。使用硬件 MPY32(F4xx 器件)。 |
int32 _ _MSP430_mpyl_f5hw(int32 x, int32 y); | long 与 long 相乘。使用硬件 MPY32(F5xx 器件及更高版本)。 |
int64 _ _MSP430_mpyll(int64 x, int64 y); | long long 与 long long 相乘。 |
int64 _ _MSP430_mpyll_hw(int64 x, int64 y); | long long 与 long long 相乘。使用硬件 MPY16。 |
int64 _ _MSP430_mpyll_hw32(int64 x, int64 y); | long long 与 long long 相乘。使用硬件 MPY32(F4xx 器件)。 |
int64 _ _MSP430_mpyll_f5hw(int64 x, int64 y); | long long 与 long long 相乘。使用硬件 MPY32(F5xx 器件及更高版本)。 |
int32 _ _MSP430_mpysl(int16 x, int16 y); | int 与 int 相乘;结果为 long。 |
int32 _ _MSP430_mpysl_hw(int16 x, int16 y); | int 与 int 相乘;结果为 long。使用硬件 MPY16。 |
int32 _ _MSP430_mpysl_f5hw(int16 x, int16 y); | int 与 int 相乘;结果为 long。使用硬件 MPY32(F5xx 器件及更高版本)。 |
int64 _ _MSP430_mpysll(int32 x, int32 y); | long 与 long 相乘;结果为 long long。 |
int64 _ _MSP430_mpysll_hw(int32 x, int32 y); | long 与 long 相乘;结果为 long long。使用硬件 MPY16。 |
int64 _ _MSP430_mpysll_hw32(int32 x, int32 y); | long 与 long 相乘;结果为 long long。使用硬件 MPY32(F4xx 器件)。 |
int64 _ _MSP430_mpysll_f5hw(int32 x, int32 y); | long 与 long 相乘;结果为 long long。使用硬件 MPY32(F5xx 器件及更高版本)。 |
uint32 _ _MSP430_mpyul(uint16 x, uint16 y); | 将 unsigned int 与 unsigned int 相乘;结果为 unsigned long。 |
uint32 _ _MSP430_mpyul_hw(uint16 x, uint16 y); | 将 unsigned int 与 unsigned int 相乘;结果为 unsigned long。使用硬件 MPY16。 |
uint32 _ _MSP430_mpyul_f5hw(uint16 x, uint16 y); | 将 unsigned int 与 unsigned int 相乘;结果为 unsigned long。使用硬件 MPY32(F5xx 器件及更高版本)。 |
uint64 _ _MSP430_mpyull(uint32 x, uint32 y); | 将 unsigned long 与 unsigned long 相乘;结果为 unsigned long long。 |
uint64 _ _MSP430_mpyull_hw(uint32 x, uint32 y); | 将 unsigned long 与 unsigned long 相乘;结果为 unsigned long long。使用硬件 MPY16。 |
uint64 _ _MSP430_mpyull_hw32(uint32 x, uint32 y); | 将 unsigned long 与 unsigned long 相乘;结果为 unsigned long long。使用硬件 MPY32(F4xx 器件)。 |
uint64 _ _MSP430_mpyull_f5hw(uint32 x, uint32 y); | 将 unsigned long 与 unsigned long 相乘;结果为 unsigned long long。使用硬件 MPY32(F5xx 器件及更高版本)。 |
除法 | |
int16 _ _MSP430_divi(int16 x, int16 y); | int 除以 int。 |
int32 _ _MSP430_divli(int32 x, int32 y); | long 除以 long。 |
int64 _ _MSP430_divlli(int64 x, int64 y); | long long 除以 long long。 |
uint16 _ _MSP430_divu(uint16 x, uint16 y); | unsigned lint 除以 unsigned lint。 |
uint32 _ _MSP430_divlu(uint32 x, uint32 y); | unsigned long 除以 unsigned long。 |
uint64 _ _MSP430_divllu(uint64 x, uint64 y); | unsigned long long 除以 unsigned long long。 |
余数(模数) | |
int16 _ _MSP430_remi(int16 x, int16 y); | int 除以 int 的余数 (x mod y) |
int32 _ _MSP430_remli(int32 x, int32 y); | long 除以 long 的余数 (x mod y) |
int64 _ _MSP430_remlli(int64x. int64 y); | long long 除以 long long 的余数 (x mod y) |
uint16 _ _MSP430_remu(uint16 x, uint16 y); | unsigned int 除以 unsigned int 的余数 (x mod y) |
uint32 _ _MSP430_remul(uint32, uint32); | unsigned long 除以 unsigned long 的余数 (x mod y) |
uint64 _ _MSP430_remull(uint64, uint64); | unsigned long long 除以 unsigned long long 的余数 (x mod y) |
表 6-5 列出了按位运算符函数。这些函数由 MSP430 和 MSP430X 使用。
循环左移运算不带进位执行。最高有效位被移至最低有效位 (LSB),所有其他位左移。对于 long long 数据类型,没有循环函数。
逻辑左移运算与算术左移相同;一个零被移入 LSB。
算术右移运算将最高有效位 (MSB) 向右移动并将旧 MSB 复制到新 MSB 中。这会将符号保留在有符号值中。LSB 被丢弃。
逻辑右移运算在 MSB 中插入值 0 并丢弃 LSB。
接受第二个实参的函数中的移位或循环计数不能小于零,即使按 signed int 处理它也不例外。
签名 | 说明 |
---|---|
旋转 | |
uint16 _ _MSP430_rlli(uint16 x, int16 n); | 将 int 的位向左循环移动 n 位,其中 n 最多可以是 16。 |
uint16 _ _MSP430_rlli_1(uint16 x); ... uint16 _ _MSP430_rlli_15(uint16 x); | 将 int 的位向左循环移动指定的位数。 |
uint32 _ _MSP430_rlll(uint32 x, int16 n); | 将 long 的位向左循环移动 n 位,其中 n 最多可以是 32。 |
逻辑左移 | |
uint16 _ _MSP430_slli(uint16 x, int16 n); | 对 int 执行逻辑左移。移动 n 位,其中 n 最多可以是 16。 |
uint16 _ _MSP430_slli_1(uint16 x); ... uint16 _ _MSP430_slli_15(uint16 x); | 对 int 执行逻辑左移。向左移位指定的位数。 |
uint32 _ _MSP430_slll(uint32 x, int16 n); | 对 long 执行逻辑左移。移动 n 位,其中 n 最多可以是 32。 |
uint32 _ _MSP430_slll_1(uint32 x); ... uint32 _ _MSP430_slll_15(uint32 x); | 对 long 执行逻辑左移。向左移位指定的位数。高于 15 的移位数使用 _ _MSP430_slll。 |
uint64 _ _MSP430_sllll(uint64 x, int16 n); | 对 long long 执行逻辑左移。移动 n 位,其中 n 最多可以是 64。 |
算术右移 | |
int16 _ _MSP430_srai(int16 x, int16 n); | 对 int 执行算术右移。移动 n 位,其中 n 最多可以是 16。 |
int16 _ _MSP430_srai_1(int16 x); ... int32 _ _MSP430_srai_15(int16 x); | 对 int 执行算术右移。移动指定的位数。 |
int16 _ _MSP430_sral(int32 x, int16 n); | 对 long 执行算术右移。移动 n 位,其中 n 最多可以是 32。 |
int32 _ _MSP430_sral_1(int32 x); ... int32 _ _MSP430_sral_15(int32 x); | 对 long 执行算术右移。移动指定的位数。高于 15 的移位数使用 _ _MSP430_sral。 |
int64 _ _MSP430_srall(int64 x, int16 n); | 对 long long 执行算术右移。移动 n 位,其中 n 最多可以是 64。 |
逻辑右移 | |
uint16 _ _MSP430_srli(uint16 x, int16 n); | 对 int 执行逻辑右移。移动 n 位,其中 n 最多可以是 16。 |
uint16 _ _MSP430_srli_1(uint16 x); ... uint16 _ _MSP430_srli_15(uint16 x); | 对 int 执行逻辑右移。向右移动指定的位数。 |
uint32 _ _MSP430_srll(uint32 x, int16 n); | 对 long 执行逻辑右移。移动 n 位,其中 n 最多可以是 32。 |
uint32 _ _MSP430_srll_1(uint32 x); ... uint32 _ _MSP430_srll_15(uint32 x); | 对 long 执行逻辑右移。向右移动指定的位数。高于 15 的移位数使用 _ _MSP430_srll。 |
uint64 _ _MSP430_srlll(uint64 x, int16 n); | 对 long long 执行逻辑右移。移动 n 位,其中 n 最多可以是 64。 |
表 6-6 中的辅助函数可优化恢复被调用者保存的寄存器。MSP430 使用这些函数,但 MSP430X 不使用这些函数。
签名 | 说明 |
---|---|
void _ _MSP430_epilog_1(void); | 弹出 R10 并返回。 |
void _ _MSP430_epilog_2(void); | 弹出 R10 到 R9 并返回。 |
void _ _MSP430_epilog_3(void); | 弹出 R10 到 R8 并返回。 |
void _ _MSP430_epilog_4(void); | 弹出 R10 到 R7 并返回。 |
void _ _MSP430_epilog_5(void); | 弹出 R10 到 R6 并返回。 |
void _ _MSP430_epilog_6(void); | 弹出 R10 到 R5 并返回。 |
void _ _MSP430_epilog_7(void); | 弹出 R10 到 R4 并返回。 |
下面的章节将介绍表 6-7 中的其他辅助函数。
签名 | 说明 |
---|---|
void _abort_msg(const char *string); | 报告断言失败 |
_abort_msg
生成函数 _abort_msg 是为了在运行时断言(例如 C 断言宏)失败时输出诊断消息。该函数不得返回。也就是说,该函数必须调用中止或通过其他方式终止程序。