ZHCUAV8W january 1998 – march 2023 66AK2E05 , 66AK2H06 , 66AK2H12 , 66AK2H14 , AM1705 , AM1707 , AM1802 , AM1806 , AM1808 , AM1810 , AM5K2E04 , OMAP-L132 , OMAP-L137 , OMAP-L138 , SM470R1B1M-HT , TMS470R1A288 , TMS470R1A384 , TMS470R1A64 , TMS470R1B1M , TMS470R1B512 , TMS470R1B768
可使用下表中的内在函数生成汇编指令。表 5-3 显示了不同 ARM 目标上可用的内在函数。表 5-4 显示了每个内在函数的调用语法,以及相应的汇编指令和说明。节 6.8.1 中提供了用于获取和设置 CPSR 寄存器、启用/禁用中断的其他内在函数。
| C/C++ 编译器内在函数 | ARM V5e (ARM9E) | ARM V6 (ARM11) | ARM V6M0 (Cortex-M0) | ARM V7M3 (Cortex-M3) | ARM V7M4 (Cortex-M4) | ARM V7R (Cortex-R4) | ARM V7A8 (Cortex-A8) |
|---|---|---|---|---|---|---|---|
| _ _clz | 是 | 是 | 是 | 是 | 是 | 是 | |
| _ _delay_cycles | 是 | 是 | 是 | 是 | |||
| _ _get_MSP | 是 | 是 | 是 | ||||
| _ _get_PRIMASK | 是 | 是 | 是 | ||||
| _ _ldrex | 是 | 是 | 是 | 是 | 是 | ||
| _ _ldrexb | 是 | 是 | 是 | 是 | 是 | ||
| _ _ldrexd | 是 | 是 | 是 | ||||
| _ _ldrexh | 是 | 是 | 是 | 是 | 是 | ||
| _ _MCR | 是 | 是 | 是 | 是 | 是 | 是 | |
| _ _MRC | 是 | 是 | 是 | 是 | 是 | 是 | |
| _ _ nop | 是 | 是 | 是 | 是 | 是 | 是 | 是 |
| _norm | 是 | 是 | 是 | 是 | 是 | 是 | |
| _ _rev | 是 | 是 | 是 | 是 | 是 | ||
| _ _rev16 | 是 | 是 | 是 | 是 | 是 | ||
| _ _revsh | 是 | 是 | 是 | 是 | 是 | ||
| _ _rbit | 是 | 是 | 是 | 是 | |||
| _ _ror | 是 | 是 | 是 | 是 | 是 | 是 | 是 |
| _pkhbt | 是 | 是 | 是 | 是 | |||
| _pkhtb | 是 | 是 | 是 | 是 | |||
| _qadd16 | 是 | 是 | 是 | 是 | |||
| _qadd8 | 是 | 是 | 是 | 是 | |||
| _qaddsubx | 是 | 是 | 是 | 是 | |||
| _qsub16 | 是 | 是 | 是 | 是 | |||
| _qsub8 | 是 | 是 | 是 | 是 | |||
| _qsubaddx | 是 | 是 | 是 | 是 | |||
| _sadd | 是 | 是 | 是 | 是 | 是 | ||
| _sadd16 | 是 | 是 | 是 | 是 | |||
| _sadd8 | 是 | 是 | 是 | 是 | |||
| _saddsubx | 是 | 是 | 是 | 是 | |||
| _sdadd | 是 | 是 | 是 | 是 | 是 | ||
| _sdsub | 是 | 是 | 是 | 是 | 是 | ||
| _sel | 是 | 是 | 是 | 是 | |||
| _ _set_MSP | 是 | 是 | 是 | ||||
| _ _set_PRIMASK | 是 | 是 | 是 | ||||
| _shadd16 | 是 | 是 | 是 | 是 | |||
| _shadd8 | 是 | 是 | 是 | 是 | |||
| _shsub16 | 是 | 是 | 是 | 是 | |||
| _shsub8 | 是 | 是 | 是 | 是 | |||
| _smac | 是 | 是 | 是 | 是 | 是 | ||
| _smlabb | 是 | 是 | 是 | 是 | 是 | ||
| _smlabt | 是 | 是 | 是 | 是 | 是 | ||
| _smlad | 是 | 是 | 是 | 是 | |||
| _smladx | 是 | 是 | 是 | 是 | |||
| _smlalbb | 是 | 是 | 是 | 是 | 是 | ||
| _smlalbt | 是 | 是 | 是 | 是 | 是 | ||
| _smlald | 是 | 是 | 是 | 是 | |||
| _smlaldx | 是 | 是 | 是 | 是 | |||
| _smlaltb | 是 | 是 | 是 | 是 | 是 | ||
| _smlaltt | 是 | 是 | 是 | 是 | 是 | ||
| _smlatb | 是 | 是 | 是 | 是 | 是 | ||
| _smlatt | 是 | 是 | 是 | 是 | 是 | ||
| _smlawb | 是 | 是 | 是 | 是 | 是 | ||
| _smlawt | 是 | 是 | 是 | 是 | 是 | ||
| _smlsd | 是 | 是 | 是 | 是 | |||
| _smlsdx | 是 | 是 | 是 | 是 | |||
| _smlsld | 是 | 是 | 是 | 是 | |||
| _smlsldx | 是 | 是 | 是 | 是 | |||
| _smmla | 是 | 是 | 是 | 是 | |||
| _smmlar | 是 | 是 | 是 | 是 | |||
| _smmls | 是 | 是 | 是 | 是 | |||
| _smmlsr | 是 | 是 | 是 | 是 | |||
| _smmul | 是 | 是 | 是 | 是 | |||
| _smmulr | 是 | 是 | 是 | 是 | |||
| _smuad | 是 | 是 | 是 | 是 | |||
| _smuadx | 是 | 是 | 是 | 是 | |||
| _smusd | 是 | 是 | 是 | 是 | |||
| _smusdx | 是 | 是 | 是 | 是 | |||
| _smpy | 是 | 是 | 是 | 是 | 是 | ||
| _smsub | 是 | 是 | 是 | 是 | 是 | ||
| _smulbb | 是 | 是 | 是 | 是 | 是 | ||
| _smulbt | 是 | 是 | 是 | 是 | 是 | ||
| _smultb | 是 | 是 | 是 | 是 | 是 | ||
| _smultt | 是 | 是 | 是 | 是 | 是 | ||
| _smulwb | 是 | 是 | 是 | 是 | 是 | ||
| _smulwt | 是 | 是 | 是 | 是 | 是 | ||
| _ _sqrt | 是 | 是 | 是 | 是 | |||
| _ _sqrtf | 是 | 是 | 是 | 是 | 是 | ||
| _ssat16 | 是 | 是 | 是 | 是 | |||
| _ssata | 是 | 是 | 是 | 是 | 是 | 是 | |
| _ssatl | 是 | 是 | 是 | 是 | 是 | 是 | |
| _ssub | 是 | 是 | 是 | 是 | 是 | ||
| _ssub16 | 是 | 是 | 是 | 是 | |||
| _ssub8 | 是 | 是 | 是 | 是 | |||
| _ssubaddx | 是 | 是 | 是 | 是 | |||
| _ _strex | 是 | 是 | 是 | 是 | 是 | ||
| _ _strexb | 是 | 是 | 是 | 是 | 是 | ||
| _ _strexd | 是 | 是 | 是 | ||||
| _ _strexh | 是 | 是 | 是 | 是 | 是 | ||
| _subc | 是 | 是 | 是 | 是 | 是 | ||
| _sxtab | 是 | 是 | 是 | 是 | |||
| _sxtab16 | 是 | 是 | 是 | 是 | |||
| _sxtah | 是 | 是 | 是 | 是 | |||
| _sxtb | 是 | 是 | 是 | 是 | 是 | 是 | |
| _sxtb16 | 是 | 是 | 是 | 是 | |||
| _sxth | 是 | 是 | 是 | 是 | 是 | 是 | |
| _uadd16 | 是 | 是 | 是 | 是 | |||
| _uadd8 | 是 | 是 | 是 | 是 | |||
| _uaddsubx | 是 | 是 | 是 | 是 | |||
| _uhadd16 | 是 | 是 | 是 | 是 | |||
| _uhadd8 | 是 | 是 | 是 | 是 | |||
| _uhsub16 | 是 | 是 | 是 | 是 | |||
| _uhsub8 | 是 | 是 | 是 | 是 | |||
| _umaal | 是 | 是 | 是 | 是 | |||
| _uqadd16 | 是 | 是 | 是 | 是 | |||
| _uqadd8 | 是 | 是 | 是 | 是 | |||
| _uqaddsubx | 是 | 是 | 是 | 是 | |||
| _uqsub16 | 是 | 是 | 是 | 是 | |||
| _uqsub8 | 是 | 是 | 是 | 是 | |||
| _uqsubaddx | 是 | 是 | 是 | 是 | |||
| _usad8 | 是 | 是 | 是 | 是 | |||
| _usat16 | 是 | 是 | 是 | 是 | |||
| _usata | 是 | 是 | 是 | 是 | 是 | 是 | |
| _usatl | 是 | 是 | 是 | 是 | 是 | 是 | |
| _usub16 | 是 | 是 | 是 | 是 | |||
| _usub8 | 是 | 是 | 是 | 是 | |||
| _usubaddx | 是 | 是 | 是 | 是 | |||
| _uxtab | 是 | 是 | 是 | 是 | |||
| _uxtab16 | 是 | 是 | 是 | 是 | |||
| _uxtah | 是 | 是 | 是 | 是 | |||
| _uxtb | 是 | 是 | 是 | 是 | 是 | 是 | |
| _uxtb16 | 是 | 是 | 是 | 是 | |||
| _uxth | 是 | 是 | 是 | 是 | 是 | 是 | |
| _ _wfe | 是 | 是 | 是 | 是 | 是 | ||
| _ _wfi | 是 | 是 | 是 | 是 | 是 |
表 5-4 显示了每个内在函数的调用语法,以及相应的汇编指令和说明。请参阅表 5-3,以查看有关不同 ARM 目标的可用内在函数列表。节 6.8.1 中提供了用于获取和设置 CPSR 寄存器、启用/禁用中断的其他内在函数。
| C/C++ 编译器内在函数 | 汇编 指令 | 说明 |
|---|---|---|
| int count = _ _clz(int src ); | CLZcount , src | 返回前导零的计数。 |
| void _ _delay_cycles( unsigned int cycles ); | 不尽相同 | 将执行指定周期数的延迟。周期数必须是常数。 __delay_cycles 内在函数会插入代码,以精确地使用指定的周期数,而不会产生任何副作用。延迟的周期数必须是编译时间常量。 注意:循环计时基于 0 个等待状态。结果因其他等待状态而异。该实现方案不考虑动态预测。鉴于流水线清除行为,较低的延迟周期计数可能不太准确。 |
| unsigned int dst = _ _get_MSP(void ); | MRS dst, MSP | 返回主栈指针的当前值。 |
| unsigned int dst = _ _get_PRIMASK(void ); | MRS dst, PRIMASK | 返回优先级屏蔽寄存器的当前值。如果该值为 1,则禁止激活具有可配置优先级的所有异常。 |
| unsigned int dest = _ _ldrex(void* src ); | LDREXdst , src | 从包含文字(32 位)数据的内存地址加载数据 |
| unsigned int dest= _ _ldrexb(void* src ); | LDREXBdst , src | 从包含字节数据的内存地址加载数据 |
| unsigned long long dest = _ _ldrexd(void* src ); | LDREXDdst , src | 从支持 long-long 的内存地址加载数据 |
| unsigned int dest = _ _ldrexh(void* src ); | LDREXHdst , src | 从包含半字(16 位)数据的内存地址加载数据 |
| void __MCR (unsigned int coproc, unsigned int opc1, unsigned int src, unsigned int coproc_reg1, unsigned int coproc_reg2, unsigned int opc2); | MCRcoproc, opc1, src, CR<coproc_reg1>, CR<coproc_reg2>, opc2 | 访问协处理器寄存器 |
| unsigned int __MRC(unsigned int coproc, unsigned int opc1, unsigned int coproc_reg1, unsigned int coproc_reg2, unsigned int opc2); | MRCcoproc, opc1, src, CR<coproc_reg1>, CR<coproc_reg2>, opc2 | 访问协处理器寄存器 |
| void _ _nop( void ); | NOP | 执行不做任何事情的指令。 |
| int dst = _norm(int src ); | CLZ dst , src | 计算前导零位数。在实现整数规范化时,可以使用此内在函数。 |
| int dst = _pkhbt(int src1 , int src2 , int shift ); | PKHBTdst , src1 , src2 , #shift | 组合 src1 的底部半字和 src2 的移位顶部半字 |
| nt dst = _pkhtb(int src1 , int src2 , int shift ); | PKHTBdst , src1 , src2 , #shift | 组合 src1 的顶部半字和 src2 的移位底部半字 |
| int dst = _qadd16(int src1 , int src2 ); | QADD16dst , src1 , src2 | 执行两个有符号半字饱和加法 |
| int dst = _qadd8(int src1 , int src2 ); | QADD8dst , src1 , src2 | 执行四个有符号饱和 8 位加法 |
| int dst = _qaddsubx(int src1 , int src2 ); | QASXdst , src1 , src2 | 交换 src2 的半字,对顶部半字执行有符号饱和加法,对底部半字执行有符号饱和减法。 |
| int dst = _qsub16(int src1 , int src2 ); | QSUB16dst , src1 , src2 | 执行两个有符号饱和半字减法 |
| int dst = _qsub8(int src1 , int src2 ); | QSUB8dst , src1 , src2 | 执行四个有符号饱和 8 位减法 |
| int dst = _qsubaddx(int src1 , int src2 ); | QSAXdst , src1 , src2 | 交换 src2 的半字,对顶部半字执行有符号饱和减法,对底部半字执行有符号饱和加法。 |
| int dst = _ _rbit(int src ); | RBITdst , src | 反转文字中的位顺序。 |
| int dst = _ _rev(int src ); | REVdst , src | 反转文字中的字节顺序。也就是说,在大端字节序和小端字节序之间转换 32 位数据,反之亦然。 |
| int dst = _ _rev16(int src ); | REV16dst , src | 独立反转文字中每个字节的字节顺序。也就是说,在大端字节序和小端字节序之间转换 16 位数据,反之亦然。 |
| int dst = _ _revsh(int src ); | REVSHdst , src | 反转文字的低位字节的字节顺序,并将符号扩展到 32 位。也就是说,将 16 位有符号数据转换为 32 位有符号数据,同时在大端字节序和小端字节序之间进行转换,反之亦然。 |
| int dst = _ _ror(int src , int shift ); | RORdst , src , shift | 将值向右旋转指定的位数。从右端旋转的位放入左端的空位。 |
| int dst =_sadd(int src1 , int src2 ); | QADDdst , src1 , src2 | 饱和加法 |
| int dst = _sadd16(int src1 , int src2 ); | SADD16 dst , src1 , src2 | 执行两个有符号半字加法 |
| int dst = _sadd8(int src1 , int src2 ); | SADD8dst , src1 , src2 | 执行四个有符号 8 位加法 |
| int dst = _saddsubx(int src1 , int src2 ); | SASXdst , src1 , src2 | 交换 src2 的半字,添加顶部半字并减去底部半字 |
| int dst =_sdadd(int src1 , int src2 ); | QDADDdst , src1 , src2 | 饱和双加 |
| int dst =_sdsub(int src1 , int src2 ); | QDSUBdst , src1 , src2 | 饱和双减 |
| int dst = _sel(int src1 , int src2 ); | SELdst , src1 , src2 | 如果设置了 GE 位 n,则从 src1 选择字节 n;如果未设置 GE 位 n,则从 src2 选择字节 n,其中 n 的范围为 0 到 3。 |
| void _ _set_MSP(unsigned int src); | MSR MSP,src | 将主栈指针的值设置为 src。 |
| unsigned int dst = _ _set_PRIMASK(unsigned int src); | MRSdst , PRIMASK (optional) MSR PRIMASK, src | 将优先级屏蔽寄存器设置为 src 值,并返回设置为 dst 之前的值。将此寄存器设置为 1 可防止激活具有可配置优先级的所有异常。 |
| int dst = _shadd16(int src1 , int src2 ); | SHADD16dst , src1 , src2 | 执行两个带符号的半字加法并将结果减半 |
| int dst = _shadd8(int src1 , int src2 ); | SHADD8 dst , src1 , src2 | 执行四个带符号的 8 位加法并将结果减半 |
| int dst = _shsub16(int src1 , int src2 ); | SHSUB16dst , src1 , src2 | 执行两个带符号的半字减法并将结果减半 |
| int dst = _shsub8int src1 , int src2 ); | SHSUB8dst , src1 , src2 | 执行四个带符号的 8 位减法并将结果减半 |
| int dst =_smac(int dst, int src1 , int src2 ); | SMULBB tmp , src1 , src2 QDADD dst, dst , tmp | 饱和乘法累加 |
| int dst =_smlabb(int dst , short src1 , short src2 ); | SMLABB dst , src1 , src2 | 有符号乘法累加底部半字 |
| int dst =_smlabt(int dst , short src1 , int src2 ); | SMLABT dst , src1 , src2 | 有符号乘法累加底部半字和顶部半字 |
| int dst _smlad(int src1 , int src2 , int acc ); | SMLADdst , src1 , src2 , acc | 对 src1 和 src2 的顶部半字和底部半字执行两次有符号 16 位乘法,并将结果添加到 acc。 |
| int dst _smladx(int src1 , int src2 , int acc ); | SMLADXdst , src1 , src2 , acc | 与 _smlad 相同,只是 src2 中的半字在乘法之前交换。 |
| long long dst =_smlalbb(long long dst , short src1 , short src2 ); | SMLALBB dstlo , dsthi , src1 , src2 | 有符号长整数乘法并累加底部半字 |
| long long dst =_smlalbt(long long dst , short src1 , int src2 ); | SMLALBT dstlo , dsthi , src1 , src2 | 有符号长整数乘法并累加底部半字和顶部半字 |
| long long dst _smlald(long long acc , int src1 , int src2 ); | SMLALDdst , src1 , src2 | 对 src1 和 src2 的顶部半字和底部半字执行两次 16 位乘法,并将结果添加到 64 位 acc 操作数 |
| long long dst _smlaldx(long long acc , int src1 , int src2 ); | SMLALDX dst , src1 , src2 | 与 _smlald 相同,只是 src2 中的半字已交换。 |
| long long dst =_smlaltb(long long dst , int src1 , short src2 ); | SMLALTB dstlo , dsthi , src1 , src2 | 有符号长整数乘法并累加顶部半字和底部半字 |
| long long dst =_smlaltt(long long dst , int src1 , int src2 ); | SMLALTT dstlo , dsthi , src1 , src2 | 有符号长整数乘法并累加顶部半字 |
| int dst =_smlatb(int dst , int src1 , short src2 ); | SMLATB dst , src1 , src2 | 有符号乘法累加顶部半字和底部半字 |
| int dst =_smlatt(int dst , int src1 , int src2 ); | SMLATT dst , src1 , src2 | 有符号乘法累加顶部半字 |
| int dst _smlawb(int src1 , short src2 , int acc ); | SMLAWB dst , src1 , src2 | 有符号乘法累加文字和底部半字 |
| int dst _smlawt(int src1 , short src2 , int acc ); | SMLAWT dst , src1 , src2 | 有符号乘法累加文字和顶部半字 |
| int dst _smlsd(int src1 , int src2 , int acc ); | SMLSDdst , src1 , src2 , acc | 对 src1 和 src2 的顶部半字和底部半字执行两次有符号 16 位乘法,并将结果差异添加到 acc。 |
| int dst _smlsdx(int src1 , int src2 , int acc ); | SMLSDXdst , src1 , src2 , acc | 与 _smlsd 相同,只是 src2 中的半字在乘法之前交换。 |
| long long dst _smlsld(long long acc , int src1 , int src2 ); | SMLSLDdst , src1 , src2 | 对 src1 和 src2 的顶部半字和底部半字执行两次 16 位乘法,并将结果差异添加到 64 位 acc 操作数。 |
| long long dst _smlsldx(long long acc , int src1 , int src2 ); | SMLSLDX dst , src1 , src2 | 与 _smlsld 相同,只是 src2 中的半字已交换。 |
| int dst _smmla(int src1 , int src2 , int acc ); | SMMLAdst , src1 , src2 , acc | 对 src1 和 src2 执行有符号乘法,提取结果的最高有效 32 位,并添加累积值。 |
| int dst _smmlar(int src1 , int src2 , int acc ); | SMMLARdst , src1 , src2 , acc | 与 _smmla 相同,只是结果是四舍五入的,而不是被截断的。 |
| int dst _smmls(int src1 , int src2 , int acc ); | SMMLSdst , src1 , src2 , acc | 对 src1 和 src2 执行有符号乘法,从左移 32 位的累积值中减去结果,并提取减法结果的最高有效 32 位。 |
| int dst _smmlsr(int src1 , int src2 , int acc ); | SMMLSRdst , src1 , src2 , acc | 与 _smmls 相同,只是结果是四舍五入的,而不是被截断的。 |
| int dst _smmul(int src1 , int src2 , int acc ); | SMMULdst , src1 , src2 , acc | 对 src1 和 src2 执行有符号 32 位乘法,并提取结果的最高有效 32 位。 |
| int dst _smmulr(int src1 , int src2 , int acc ); | SMMULRdst , src1 , src2 , acc | 与 _smmul 相同,只是结果是四舍五入的,而不是被截断的。 |
| int dst =_smpy(int src1 , int src2 ); | SMULBB dst , src1 , src2 QADD dst, dst , dst | 饱和乘法 |
| int dst =_smsub(int src1 , int src2 ); | SMULBB tmp , src1 , src2 QDSUB dst, dst , tmp | 饱和乘减 |
| int dst _smuad(int src1 , int src2 ); | SMUADdst , src1 , src2 | 对顶部半字和底部半字执行两次有符号 16 位乘法,并将乘积相加。 |
| int dst _smuadx(int src1 , int src2 ); | SMUADXdst , src1 , src2 | 与 _smuad 相同,只是 src2 中的半字在乘法之前交换。 |
| int dst =_smulbb(int src1 , int src2 ); | SMULBB dst , src1 , src2 | 有符号乘法底部半字 |
| int dst =_smulbt(int src1 , int src2 ); | SMULBT dst , src1 , src2 | 有符号乘法底部半字和顶部半字 |
| int dst =_smultb(int src1 , int src2 ); | SMULTB dst , src1 , src2 | 有符号乘法顶部半字和底部半字 |
| int dst =_smultt(int src1 , int src2 ); | SMULTT dst , src1 , src2 | 有符号乘法顶部半字 |
| int dst _smulwb(int src1 , short src2 , int acc ); | SMULWB dst , src1 , src2 | 有符号乘法文字和底部半字 |
| int dst _smulwt(int src1 , short src2 , int acc ); | SMULWT dst , src1 , src2 | 有符号乘法文字和顶部半字 |
| int dst _smusd(int src1 , int src2 ); | SMUSDdst , src1 , src2 | 对顶部半字和底部半字执行两次有符号 16 位乘法,并减去乘积。 |
| int dst _smusdx(int src1 , int src2 ); | SMUSDXdst , src1 , src2 | 与 _smusd 相同,只是 src2 中的半字在乘法之前交换。 |
| double __sqrt( double ); | VSQRTdst , src1 | 返回指定双精度值的平方根。如果 --fp_mode=relaxed,则直接使用 VSQRT 指令替换此内在函数。如果使用严格浮点模式并且发生域错误,函数还必须设置 errno。 |
| float __sqrtf( float ); | VSQRTdst , src1 | 返回指定浮点值的平方根。如果 --fp_mode=relaxed,则直接使用 VSQRT 指令替换此内在函数。如果使用严格浮点模式并且发生域错误,函数还必须设置 errno。 |
| int dst =_ssat16(int src , int bitpos ); | SSAT16dst , #bitpos | 对 bitpos 指定的可选有符号范围执行两个半字饱和 |
| int dst =_ssata(int src , int shift , int bitpos ); | SSAT dst , #bitpos, src, ASR #shift | 右移 src 并饱和到 bitpos 指定的可选有符号范围 |
| int dst =_ssatl(int src , int shift , int bitpos ); | SSAT dst , #bitpos, src, LSL #shift | 左移 src 并饱和到 bitpos 指定的可选有符号范围 |
| int dst =_ssub(int src1 , int src2 ); | QSUBdst , src1 , src2 | 饱和减法 |
| int dst = _ssub16(int src1 , int src2 ); | SSUB16 dst , src1 , src2 | 执行两个有符号半字减法 |
| int dst = _ssub8(int src1 , int src2 ); | SSUB8dst , src1 , src2 | 执行四个有符号 8 位减法 |
| int dst = _ssubaddx(int src1 , int src2 ); | SSAXdst , src1 , src2 | 交换 src2 的半字,减去顶部半字并添加底部半字 |
| int status = _ _strex(unsigned int src, void* dst ); | STREXstatus , src , dest | 在内存地址中存储文字(32 位)数据 |
| int status = _ _strexb(unsigned char src, void* dst ); | STREXBstatus , src , dest | 在内存地址中存储字节数据 |
| int status = _ _strexd(unsigned long long src, void* dst ); | STREXDstatus , src , dest | 在内存地址中存储超长整型数据 |
| int status = _ _strexh(unsigned short src, void* dst ); | STREXHstatus , src , dest | 在内存地址中存储半字(16 位)数据 |
| int dst = _subc(int src1 , int src2 ); | SUBCdst , src1 , src2 | 带进位的减法 |
| int dst _sxtab(int src1 , int src2 , int rotamt ); | SXTABdst , src1 , src2 , ROR #rotamt | 从 src2 中提取一个可选的旋转 8 位值,并将其符号扩展到 32 位,然后将该值添加到 src1。旋转量可以是 0、8、16 或 24。 |
| int dst _sxtab16(int src1 , int src2 , int rotamt ); | SXTAB16 dst , src1 , src2 , ROR #rotamt | 从 src2 中提取两个可选的旋转 8 位值,并将其符号扩展到每个 16 位,然后将这些值添加到 src1 中的两个 16 位值。旋转量应为 0、8、16 或 24。 |
| int dst _sxtah(int src1 , int src2 , int rotamt ); | SXTAHdst , src1 , src2 , ROR #rotamt | 从 src2 中提取一个可选的旋转 16 位值,并将其符号扩展到 32 位,然后将结果添加到 src1。旋转量可以是 0、8、16 或 32。 |
| int dst _sxtb(int src1 , int rotamt ); | SXTB dst , src1 , ROR #rotamt | 从 src1 中提取一个可选的旋转 8 位值,并将其符号扩展到 32 位。旋转量可以是 0、8、16 或 24。 |
| int dst _sxtb16(int src1 , int rotamt ); | SXTAB16 dst , src1 , ROR #rotamt | 从 src1 中提取两个可选的旋转 8 位值,并将其符号扩展到 16 位。旋转量可以是 0、8、16 或 24。 |
| int dst _sxth(int src1 , int rotamt ); | SXTHdst , src1 , ROR #rotamt | 从 src2 中提取一个可选的旋转 16 位值,并将其符号扩展到 32 位。旋转量可以是 0、8、16 或 24。 |
| int dst = _uadd16(int src1 , int src2 ); | UADD16 dst , src1 , src2 | 执行两个无符号半字加法 |
| int dst = _uadd8(int src1 , int src2 ); | UADD8dst , src1 , src2 | 执行四个无符号 8 位加法 |
| int dst = _uaddsubx(int src1 , int src2 ); | UASXdst , src1 , src2 | 交换 src2 的半字,添加顶部半字并减去底部半字 |
| int dst = _uhadd16(int src1 , int src2 ); | UHADD16dst , src1 , src2 | 执行两个无符号的半字加法并将结果减半 |
| int dst = _uhadd8(int src1 , int src2 ); | UHADD8 dst , src1 , src2 | 执行四个无符号的 8 位加法并将结果减半 |
| int dst = _uhsub16(int src1 , int src2 ); | UHSUB16dst , src1 , src2 | 执行两个无符号的半字减法并将结果减半 |
| int dst = _uhsub8(int src1 , int src2 ); | UHSUB8 dst , src1 , src2 | 执行四个无符号的 8 位减法并将结果减半 |
| int dst = _umaal(long long acc , int src1 , int src2 ); | UMAALdst1 , dst2 , src1 , src2 | 对 src1 和 src2 执行无符号 32 位乘法,然后在 acc 中添加两个无符号 32 位值。 |
| int dst = _uqadd16(int src1 , int src2 ); | UQADD16dst , src1 , src2 | 执行两个无符号半字饱和加法 |
| int dst = _uqadd8(int src1 , int src2 ); | UQADD8 dst , src1 , src2 | 执行四个无符号饱和 8 位加法 |
| int dst = _uqaddsubx(int src1 , int src2 ); | UQASXdst , src1 , src2 | 交换 src2 的半字,对顶部半字执行无符号饱和加法,对底部半字执行无符号饱和减法。 |
| int dst = _uqsub16(int src1 , int src2 ); | UQSUB16dst , src1 , src2 | 执行两个无符号饱和半字减法 |
| int dst = _uqsub8(int src1 , int src2 ); | UQSUB8 dst , src1 , src2 | 执行四个无符号饱和 8 位减法 |
| int dst = _uqsubaddx(int src1 , int src2 ); | UQSAXdst , src1 , src2 | 交换 src2 的半字,对顶部半字执行无符号饱和减法,对底部半字执行无符号饱和加法。 |
| int dst = _usad8(int src1 , int src2 ); | USAD8dst , src1 , src2 | 执行四个无符号 8 位减法,并将差值的绝对值相加。 |
| int dst =_usat16(int src , int bitpos ); | USAT16 dst , #bitpos | 对 bitpos 指定的可选无符号范围执行两个半字饱和 |
| int dst =_usata(int src , int shift , int bitpos ); | USAT dst , #bitpos, src, ASR #shift | 右移 src 并饱和到 bitpos 指定的可选无符号范围 |
| int dst =_usatl(int src , int shift , int bitpos ); | USAT dst , #bitpos, src, LSL #shift | 左移 src 并饱和到 bitpos 指定的可选无符号范围 |
| int dst = _usub16(int src1 , int src2 ); | USUB16 dst , src1 , src2 | 执行两个无符号半字减法 |
| int dst = _usub8(int src1 , int src2 ); | USUB8dst , src1 , src2 | 执行四个无符号 8 位减法 |
| int dst = _usubaddx(int src1 , int src2 ); | USAXdst , src1 , src2 | 交换 src2 的半字,减去顶部半字并添加底部半字 |
| int dst _uxtab(int src1 , int src2 , int rotamt ); | UXTABdst , src1 , src2 , ROR #rotamt | 从 src2 中提取一个可选的旋转 8 位值,并将 0 扩展到 32 位,然后将该值添加到 src1。旋转量可以是 0、8、16 或 24。 |
| int dst _uxtab16(int src1 , int src2 , int rotamt ); | UXTAB16 dst , src1 , src2 , ROR #rotamt | 从 src2 中提取两个可选的旋转 8 位值,并将 0 扩展到每个 16 位,然后将这些值添加到 src1 中的两个 16 位值。旋转量应为 0、8、16 或 24。 |
| int dst _uxtah(int src1 , int src2 , int rotamt ); | UXTAHdst , src1 , src2 , ROR #rotamt | 从 src2 中提取一个可选的旋转 16 位值,并将 0 扩展到 32 位,然后将结果添加到 src1。旋转量可以是 0、8、16 或 32。 |
| int dst _uxtb(int src1 , int rotamt ); | UXTBdst , src1 , ROR #rotamt | 从 src2 中提取一个可选的旋转 8 位值,并将 0 扩展到 32 位。旋转量可以是 0、8、16 或 24。 |
| int dst _uxtb16(int src1 , int rotamt ); | UXTB16dst , src1 , ROR #rotamt | 从 src1 中提取两个可选的旋转 8 位值,并将 0 扩展到 16 位。旋转量可以是 0、8、16 或 24。 |
| int dst _uxth(int src1 , int rotamt ); | UXTHdst , src1 , ROR #rotamt | 从 src2 中提取一个可选的旋转 16 位值,并将 0 扩展到 32 位。旋转量可以是 0、8、16 或 24。 |
| void _ _wfe( void ); | WFE | 等待事件。通过等待异常或事件来节省电源。 |
| void _ _wfi( void ); | WFI | 等待中断。进入待机、休眠或关机模式,在此类模式中,需要中断才能将处理器唤醒。 |
此外,编译器还支持 ARM C 语言扩展 (ACLE) 规范中所述的许多内在函数。这些内在函数适用于 Cortex-M 和 Cortex-R 处理器变体。实现 ACLE 内在函数以支持源代码开发,这些源代码可以使用多个供应商提供的 ACLE 兼容编译器为各种 ARM 处理器进行编译。许多内在函数与上表中列出的内在函数重复,但名称略有不同(例如一个与两个前导下划线)。
编译器不支持 ACLE 规格中列出的所有 ACLE 内在函数。例如,CLS 指令在 Cortex-M 或 Cortex-R 架构上不可用,因此不支持 __cls、__clsl 和 __clsll ACLE 内在函数。
为了使用 ACLE 内在函数,您的代码必须包含提供的 arm_acle.h 头文件。有关 ACLE 内在函数的详细信息,请参阅 ACLE 规格。有关支持哪些 ACLE 内在函数的信息,请参阅 arm_acle.h 文件。在适用的情况下,不受支持的 ACLE 内在函数声明将包含在该头文件中的注释中,并简要说明不支持该内在函数的原因,以及包含对 ACLE 规格中描述该内在函数的相应章节的引用。