ARM 内部函数
Microsoft C++ 编译器 (MSVC) 使以下内部函数可用于 ARM 体系结构。 有关 ARM 的详细信息,请参阅 ARM 开发人员文档网站的体系结构和软件开发工具部分。
NEON
ARM 的 NEON 向量指令集扩展提供 Single Instruction Multiple Data (SIMD) 功能,类似于 x86 和 x64 架构处理器通用的 MMX 和 SSE 向量指令集中的功能。
根据头文件 arm_neon.h
,霓虹灯内部函数受到支持。 MSVC 对 NEON 内部函数的支持类似于 ARM 编译器的相应支持,ARM 信息中心网站上的 ARM 编译器工具链,版本 4.1 编译器参考的附录 G 中记录了相关内容。
MSVC 和 ARM 编译器之间的主要区别在于 MSVC 添加了 vldX
和 vstX
矢量加载和存储指令的 _ex
变体。 _ex
变量采用附加参数,该参数指定指针参数的对齐情况但在其他方面与其非 _ex
对应项相同。
特定于 ARM 的内部函数列表
函数名称 | 说明 | 函数原型 |
---|---|---|
_arm_smlal | SMLAL | __int64 _arm_smlal(__int64 _RdHiLo, int _Rn, int _Rm) |
_arm_umlal | UMLAL | unsigned __int64 _arm_umlal(unsigned __int64 _RdHiLo, unsigned int _Rn, unsigned int _Rm) |
_arm_clz | CLZ | unsigned int _arm_clz(unsigned int _Rm) |
_arm_qadd | QADD | int _arm_qadd(int _Rm, int _Rn) |
_arm_qdadd | QDADD | int _arm_qdadd(int _Rm, int _Rn) |
_arm_qdsub | QDSUB | int _arm_qdsub(int _Rm, int _Rn) |
_arm_qsub | QSUB | int _arm_qsub(int _Rm, int _Rn) |
_arm_smlabb | SMLABB | int _arm_smlabb(int _Rn, int _Rm, int _Ra) |
_arm_smlabt | SMLABT | int _arm_smlabt(int _Rn, int _Rm, int _Ra) |
_arm_smlatb | SMLATB | int _arm_smlatb(int _Rn, int _Rm, int _Ra) |
_arm_smlatt | SMLATT | int _arm_smlatt(int _Rn, int _Rm, int _Ra) |
_arm_smlalbb | SMLALBB | __int64 _arm_smlalbb(__int64 _RdHiLo, int _Rn, int _Rm) |
_arm_smlalbt | SMLALBT | __int64 _arm_smlalbt(__int64 _RdHiLo, int _Rn, int _Rm) |
_arm_smlaltb | SMLALTB | __int64 _arm_smlaltb(__int64 _RdHiLo, int _Rn, int _Rm) |
_arm_smlaltt | SMLALTT | __int64 _arm_smlaltt(__int64 _RdHiLo, int _Rn, int _Rm) |
_arm_smlawb | SMLAWB | int _arm_smlawb(int _Rn, int _Rm, int _Ra) |
_arm_smlawt | SMLAWT | int _arm_smlawt(int _Rn, int _Rm, int _Ra) |
_arm_smulbb | SMULBB | int _arm_smulbb(int _Rn, int _Rm) |
_arm_smulbt | SMULBT | int _arm_smulbt(int _Rn, int _Rm) |
_arm_smultb | SMULTB | int _arm_smultb(int _Rn, int _Rm) |
_arm_smultt | SMULTT | int _arm_smultt(int _Rn, int _Rm) |
_arm_smulwb | SMULWB | int _arm_smulwb(int _Rn, int _Rm) |
_arm_smulwt | SMULWT | int _arm_smulwt(int _Rn, int _Rm) |
_arm_sadd16 | SADD16 | int _arm_sadd16(int _Rn, int _Rm) |
_arm_sadd8 | SADD8 | int _arm_sadd8(int _Rn, int _Rm) |
_arm_sasx | SASX | int _arm_sasx(int _Rn, int _Rm) |
_arm_ssax | SSAX | int _arm_ssax(int _Rn, int _Rm) |
_arm_ssub16 | SSUB16 | int _arm_ssub16(int _Rn, int _Rm) |
_arm_ssub8 | SSUB8 | int _arm_ssub8(int _Rn, int _Rm) |
_arm_shadd16 | SHADD16 | int _arm_shadd16(int _Rn, int _Rm) |
_arm_shadd8 | SHADD8 | int _arm_shadd8(int _Rn, int _Rm) |
_arm_shasx | SHASX | int _arm_shasx(int _Rn, int _Rm) |
_arm_shsax | SHSAX | int _arm_shsax(int _Rn, int _Rm) |
_arm_shsub16 | SHSUB16 | int _arm_shsub16(int _Rn, int _Rm) |
_arm_shsub8 | SHSUB8 | int _arm_shsub8(int _Rn, int _Rm) |
_arm_qadd16 | QADD16 | int _arm_qadd16(int _Rn, int _Rm) |
_arm_qadd8 | QADD8 | int _arm_qadd8(int _Rn, int _Rm) |
_arm_qasx | QASX | int _arm_qasx(int _Rn, int _Rm) |
_arm_qsax | QSAX | int _arm_qsax(int _Rn, int _Rm) |
_arm_qsub16 | QSUB16 | int _arm_qsub16(int _Rn, int _Rm) |
_arm_qsub8 | QSUB8 | int _arm_qsub8(int _Rn, int _Rm) |
_arm_uadd16 | UADD16 | unsigned int _arm_uadd16(unsigned int _Rn, unsigned int _Rm) |
_arm_uadd8 | UADD8 | unsigned int _arm_uadd8(unsigned int _Rn, unsigned int _Rm) |
_arm_uasx | UASX | unsigned int _arm_uasx(unsigned int _Rn, unsigned int _Rm) |
_arm_usax | USAX | unsigned int _arm_usax(unsigned int _Rn, unsigned int _Rm) |
_arm_usub16 | USUB16 | unsigned int _arm_usub16(unsigned int _Rn, unsigned int _Rm) |
_arm_usub8 | USUB8 | unsigned int _arm_usub8(unsigned int _Rn, unsigned int _Rm) |
_arm_uhadd16 | UHADD16 | unsigned int _arm_uhadd16(unsigned int _Rn, unsigned int _Rm) |
_arm_uhadd8 | UHADD8 | unsigned int _arm_uhadd8(unsigned int _Rn, unsigned int _Rm) |
_arm_uhasx | UHASX | unsigned int _arm_uhasx(unsigned int _Rn, unsigned int _Rm) |
_arm_uhsax | UHSAX | unsigned int _arm_uhsax(unsigned int _Rn, unsigned int _Rm) |
_arm_uhsub16 | UHSUB16 | unsigned int _arm_uhsub16(unsigned int _Rn, unsigned int _Rm) |
_arm_uhsub8 | UHSUB8 | unsigned int _arm_uhsub8(unsigned int _Rn, unsigned int _Rm) |
_arm_uqadd16 | UQADD16 | unsigned int _arm_uqadd16(unsigned int _Rn, unsigned int _Rm) |
_arm_uqadd8 | UQADD8 | unsigned int _arm_uqadd8(unsigned int _Rn, unsigned int _Rm) |
_arm_uqasx | UQASX | unsigned int _arm_uqasx(unsigned int _Rn, unsigned int _Rm) |
_arm_uqsax | UQSAX | unsigned int _arm_uqsax(unsigned int _Rn, unsigned int _Rm) |
_arm_uqsub16 | UQSUB16 | unsigned int _arm_uqsub16(unsigned int _Rn, unsigned int _Rm) |
_arm_uqsub8 | UQSUB8 | unsigned int _arm_uqsub8(unsigned int _Rn, unsigned int _Rm) |
_arm_sxtab | SXTAB | int _arm_sxtab(int _Rn, int _Rm, unsigned int _Rotation) |
_arm_sxtab16 | SXTAB16 | int _arm_sxtab16(int _Rn, int _Rm, unsigned int _Rotation) |
_arm_sxtah | SXTAH | int _arm_sxtah(int _Rn, int _Rm, unsigned int _Rotation) |
_arm_uxtab | UXTAB | unsigned int _arm_uxtab(unsigned int _Rn, unsigned int _Rm, unsigned int _Rotation) |
_arm_uxtab16 | UXTAB16 | unsigned int _arm_uxta16b(unsigned int _Rn, unsigned int _Rm, unsigned int _Rotation) |
_arm_uxtah | UXTAH | unsigned int _arm_uxtah(unsigned int _Rn, unsigned int _Rm, unsigned int _Rotation) |
_arm_sxtb | SXTB | int _arm_sxtb(int _Rn, unsigned int _Rotation) |
_arm_sxtb16 | SXTB16 | int _arm_sxtb16(int _Rn, unsigned int _Rotation) |
_arm_sxth | SXTH | int _arm_sxth(int _Rn, unsigned int _Rotation) |
_arm_uxtb | UXTB | unsigned int _arm_uxtb(unsigned int _Rn, unsigned int _Rotation) |
_arm_uxtb16 | UXTB16 | unsigned int _arm_uxtb16(unsigned int _Rn, unsigned int _Rotation) |
_arm_uxth | UXTH | unsigned int _arm_uxth(unsigned int _Rn, unsigned int _Rotation) |
_arm_pkhbt | PKHBT | int _arm_pkhbt(int _Rn, int _Rm, unsigned int _Lsl_imm) |
_arm_pkhtb | PKHTB | int _arm_pkhtb(int _Rn, int _Rm, unsigned int _Asr_imm) |
_arm_usad8 | USAD8 | unsigned int _arm_usad8(unsigned int _Rn, unsigned int _Rm) |
_arm_usada8 | USADA8 | unsigned int _arm_usada8(unsigned int _Rn, unsigned int _Rm, unsigned int _Ra) |
_arm_ssat | SSAT | int _arm_ssat(unsigned int _Sat_imm, _int _Rn, _ARMINTR_SHIFT_T _Shift_type, unsigned int _Shift_imm) |
_arm_usat | USAT | int _arm_usat(unsigned int _Sat_imm, _int _Rn, _ARMINTR_SHIFT_T _Shift_type, unsigned int _Shift_imm) |
_arm_ssat16 | SSAT16 | int _arm_ssat16(unsigned int _Sat_imm, _int _Rn) |
_arm_usat16 | USAT16 | int _arm_usat16(unsigned int _Sat_imm, _int _Rn) |
_arm_rev | REV | unsigned int _arm_rev(unsigned int _Rm) |
_arm_rev16 | REV16 | unsigned int _arm_rev16(unsigned int _Rm) |
_arm_revsh | REVSH | unsigned int _arm_revsh(unsigned int _Rm) |
_arm_smlad | SMLAD | int _arm_smlad(int _Rn, int _Rm, int _Ra) |
_arm_smladx | SMLADX | int _arm_smladx(int _Rn, int _Rm, int _Ra) |
_arm_smlsd | SMLSD | int _arm_smlsd(int _Rn, int _Rm, int _Ra) |
_arm_smlsdx | SMLSDX | int _arm_smlsdx(int _Rn, int _Rm, int _Ra) |
_arm_smmla | SMMLA | int _arm_smmla(int _Rn, int _Rm, int _Ra) |
_arm_smmlar | SMMLAR | int _arm_smmlar(int _Rn, int _Rm, int _Ra) |
_arm_smmls | SMMLS | int _arm_smmls(int _Rn, int _Rm, int _Ra) |
_arm_smmlsr | SMMLSR | int _arm_smmlsr(int _Rn, int _Rm, int _Ra) |
_arm_smmul | SMMUL | int _arm_smmul(int _Rn, int _Rm) |
_arm_smmulr | SMMULR | int _arm_smmulr(int _Rn, int _Rm) |
_arm_smlald | SMLALD | __int64 _arm_smlald(__int64 _RdHiLo, int _Rn, int _Rm) |
_arm_smlaldx | SMLALDX | __int64 _arm_smlaldx(__int64 _RdHiLo, int _Rn, int _Rm) |
_arm_smlsld | SMLSLD | __int64 _arm_smlsld(__int64 _RdHiLo, int _Rn, int _Rm) |
_arm_smlsldx | SMLSLDX | __int64 _arm_smlsldx(__int64 _RdHiLo, int _Rn, int _Rm) |
_arm_smuad | SMUAD | int _arm_smuad(int _Rn, int _Rm) |
_arm_smuadx | SMUADX | int _arm_muadxs(int _Rn, int _Rm) |
_arm_smusd | SMUSD | int _arm_smusd(int _Rn, int _Rm) |
_arm_smusdx | SMUSDX | int _arm_smusdx(int _Rn, int _Rm) |
_arm_smull | SMULL | __int64 _arm_smull(int _Rn, int _Rm) |
_arm_umull | UMULL | unsigned __int64 _arm_umull(unsigned int _Rn, unsigned int _Rm) |
_arm_umaal | UMAAL | unsigned __int64 _arm_umaal(unsigned int _RdLo, unsigned int _RdHi, unsigned int _Rn, unsigned int _Rm) |
_arm_bfc | BFC | unsigned int _arm_bfc(unsigned int _Rd, unsigned int _Lsb, unsigned int _Width) |
_arm_bfi | BFI | unsigned int _arm_bfi(unsigned int _Rd, unsigned int _Rn, unsigned int _Lsb, unsigned int _Width) |
_arm_rbit | RBIT | unsigned int _arm_rbit(unsigned int _Rm) |
_arm_sbfx | SBFX | int _arm_sbfx(int _Rn, unsigned int _Lsb, unsigned int _Width) |
_arm_ubfx | UBFX | unsigned int _arm_ubfx(unsigned int _Rn, unsigned int _Lsb, unsigned int _Width) |
_arm_sdiv | SDIV | int _arm_sdiv(int _Rn, int _Rm) |
_arm_udiv | UDIV | unsigned int _arm_udiv(unsigned int _Rn, unsigned int _Rm) |
__cps | CPS | void __cps(unsigned int _Ops, unsigned int _Flags, unsigned int _Mode) |
__dmb | DMB | void __dmb(unsigned int _Type )将一个内存屏障操作插入指令流中。 参数 _Type 指定屏障强制执行的限制类型。要详细了解可以强制执行的限制类型,请参阅内存屏障限制。 |
__dsb | DSB | void __dsb(unsigned int _Type) 将一个内存屏障操作插入指令流中。 参数 _Type 指定屏障强制执行的限制类型。要详细了解可以强制执行的限制类型,请参阅内存屏障限制。 |
__isb | ISB | void __isb(unsigned int _Type) 将一个内存屏障操作插入指令流中。 参数 _Type 指定屏障强制执行的限制类型。要详细了解可以强制执行的限制类型,请参阅内存屏障限制。 |
__emit | void __emit(unsigned __int32 opcode) 将指定指令插入由编译器输出的指令流中。 opcode 的值必须是在编译时已知的常量表达式。 指令字大小为 16 位且忽略 opcode 最重要的 16 位。编译器在执行插入的指令前不尝试解释 opcode 的内容且不保证 CPU 或内存状态。编译器假定 CPU 和内存状态在执行插入的指令后保持不变。 因此,更改状态的指令会对由编译器生成的正常代码产生不利影响。 出于此原因,仅使用 emit 插入影响编译未正常处理的 CPU 状态(如协处理器状态)的指令或实现使用 declspec(naked) 声明的函数。 |
|
__hvc | HVC | unsigned int __hvc(unsigned int, ...) |
__iso_volatile_load16 | __int16 __iso_volatile_load16(const volatile __int16 *) 有关详细信息,请参阅 __iso_volatile_load/store 内部函数。 |
|
__iso_volatile_load32 | __int32 __iso_volatile_load32(const volatile __int32 *) 有关详细信息,请参阅 __iso_volatile_load/store 内部函数。 |
|
__iso_volatile_load64 | __int64 __iso_volatile_load64(const volatile __int64 *) 有关详细信息,请参阅 __iso_volatile_load/store 内部函数。 |
|
__iso_volatile_load8 | __int8 __iso_volatile_load8(const volatile __int8 *) 有关详细信息,请参阅 __iso_volatile_load/store 内部函数。 |
|
__iso_volatile_store16 | void __iso_volatile_store16(volatile __int16 *, __int16) 有关详细信息,请参阅 __iso_volatile_load/store 内部函数。 |
|
__iso_volatile_store32 | void __iso_volatile_store32(volatile __int32 *, __int32) 有关详细信息,请参阅 __iso_volatile_load/store 内部函数。 |
|
__iso_volatile_store64 | void __iso_volatile_store64(volatile __int64 *, __int64) 有关详细信息,请参阅 __iso_volatile_load/store 内部函数。 |
|
__iso_volatile_store8 | void __iso_volatile_store8(volatile __int8 *, __int8) 有关详细信息,请参阅 __iso_volatile_load/store 内部函数。 |
|
__ldrexd | LDREXD | __int64 __ldrexd(const volatile __int64 *) |
__prefetch | PLD | void __cdecl __prefetch(const void *) 为系统提供一个 PLD 内存提示,便可很快访问指定地址处或指定地址附近的内存。 某些系统可能会选择优化此内存访问模式以提高运行时性能。 但是,从 c + + 语言的角度来看,此功能没有明显的影响,可能不执行任何操作。 |
__rdpmccntr64 | unsigned __int64 __rdpmccntr64(void) | |
__sev | SEV | void __sev(void) |
__static_assert | void __static_assert(int, const char *) | |
__swi | SVC | unsigned int __swi(unsigned int, ...) |
__trap | BKPT | int __trap(int, ...) |
__wfe | WFE | void __wfe(void) |
__wfi | WFI | void __wfi(void) |
_AddSatInt | QADD | int _AddSatInt(int, int) |
_CopyDoubleFromInt64 | double _CopyDoubleFromInt64(__int64) | |
_CopyFloatFromInt32 | float _CopyFloatFromInt32(__int32) | |
_CopyInt32FromFloat | __int32 _CopyInt32FromFloat(float) | |
_CopyInt64FromDouble | __int64 _CopyInt64FromDouble(double) | |
_CountLeadingOnes | unsigned int _CountLeadingOnes(unsigned long) | |
_CountLeadingOnes64 | unsigned int _CountLeadingOnes64(unsigned __int64) | |
_CountLeadingSigns | unsigned int _CountLeadingSigns(long) | |
_CountLeadingSigns64 | unsigned int _CountLeadingSigns64(__int64) | |
_CountLeadingZeros | unsigned int _CountLeadingZeros(unsigned long) | |
_CountLeadingZeros64 | unsigned int _CountLeadingZeros64(unsigned __int64) | |
_CountTrailingZeros | unsigned _CountTrailingZeros(unsigned long) | |
_CountTrailingZeros64 | unsigned _CountTrailingZeros64(unsigned __int64) | |
_CountOneBits | unsigned int _CountOneBits(unsigned long) | |
_CountOneBits64 | unsigned int _CountOneBits64(unsigned __int64) | |
_DAddSatInt | QDADD | int _DAddSatInt(int, int) |
_DSubSatInt | QDSUB | int _DSubSatInt(int, int) |
_isunordered | int _isunordered(double, double) | |
_isunorderedf | int _isunorderedf(float, float) | |
_MoveFromCoprocessor | MRC | unsigned int _MoveFromCoprocessor(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) 使用协处理器数据传输指令,读取 ARM 协处理器中的数据。 有关详细信息,请参阅 _MoveFromCoprocessor、_MoveFromCoprocessor2。 |
_MoveFromCoprocessor2 | MRC2 | unsigned int _MoveFromCoprocessor2(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) 使用协处理器数据传输指令,读取 ARM 协处理器中的数据。 有关详细信息,请参阅 _MoveFromCoprocessor、_MoveFromCoprocessor2。 |
_MoveFromCoprocessor64 | MRRC | unsigned __int64 _MoveFromCoprocessor64(unsigned int, unsigned int, unsigned int) 使用协处理器数据传输指令,读取 ARM 协处理器中的数据。 有关详细信息,请参阅 _MoveFromCoprocessor64。 |
_MoveToCoprocessor | MCR | void _MoveToCoprocessor(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) 使用协处理器数据传输指令,读取 ARM 协处理器中的数据。 有关详细信息,请参阅 _MoveToCoprocessor、_MoveToCoprocessor2。 |
_MoveToCoprocessor2 | MCR2 | void _MoveToCoprocessor2(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) 使用协处理器数据传输指令,读取 ARM 协处理器中的数据。 有关详细信息,请参阅 _MoveToCoprocessor、_MoveToCoprocessor2。 |
_MoveToCoprocessor64 | MCRR | void _MoveToCoprocessor64(unsigned __int64, unsigned int, unsigned int, unsigned int) 使用协处理器数据传输指令,读取 ARM 协处理器中的数据。 有关详细信息,请参阅 _MoveToCoprocessor64。 |
_MulHigh | long _MulHigh(long, long) | |
_MulUnsignedHigh | unsigned long _MulUnsignedHigh(unsigned long, unsigned long) | |
_ReadBankedReg | MRS | int _ReadBankedReg(int _Reg) |
_ReadStatusReg | MRS | int _ReadStatusReg(int) |
_SubSatInt | QSUB | int _SubSatInt(int, int) |
_WriteBankedReg | MSR | void _WriteBankedReg(int _Value, int _Reg) |
_WriteStatusReg | MSR | void _WriteStatusReg(int, int, int) |
[返回顶部]
内存屏障限制
内部函数 __dmb
(数据内存屏障)、__dsb
(数据同步屏障)和 __isb
(指令同步屏障)使用以下预定义值以根据共享域和受操作影响的访问类型对内存屏障限制进行指定。
限制值 | 说明 |
---|---|
_ARM_BARRIER_SY | 完整系统,读取和写入操作。 |
_ARM_BARRIER_ST | 完整系统,只写操作。 |
_ARM_BARRIER_ISH | 内部可共享,读取和写入操作。 |
_ARM_BARRIER_ISHST | 内部可共享,只写操作。 |
_ARM_BARRIER_NSH | 不可共享,读取和写入操作。 |
_ARM_BARRIER_NSHST | 不可共享,只写操作。 |
_ARM_BARRIER_OSH | 外部可共享,读取和写入操作。 |
_ARM_BARRIER_OSHST | 外部可共享,只写操作。 |
对于 __isb
内部函数,当前有效的唯一限制是 _ARM_BARRIER_SY;其他所有值由体系结构进行保留。
__iso_volatile_load/store 内部函数
这些内部函数显式执行不进行编译器优化的加载和存储。
__int16 __iso_volatile_load16(const volatile __int16 * Location);
__int32 __iso_volatile_load32(const volatile __int32 * Location);
__int64 __iso_volatile_load64(const volatile __int64 * Location);
__int8 __iso_volatile_load8(const volatile __int8 * Location);
void __iso_volatile_store16(volatile __int16 * Location, __int16 Value);
void __iso_volatile_store32(volatile __int32 * Location, __int32 Value);
void __iso_volatile_store64(volatile __int64 * Location, __int64 Value);
void __iso_volatile_store8(volatile __int8 * Location, __int8 Value);
参数
位置
要从中读取或为其写入的内存位置的地址。
值
要写入指定内存位置的值(仅存储内部函数)。
返回值(仅加载内部函数)
由 Location
指定的内存位置的值。
备注
你可以使用 __iso_volatile_load8/16/32/64
和 __iso_volatile_store8/16/32/64
内部函数显式执行不进行编译器优化的内存访问。 编译器不能移除、同步或更改这些操作的相对顺序,但不会生成隐式硬件内存屏障。 因此,硬件仍可能对跨多个线程的可观察内存访问进行重新排序。 更准确地说,这些内部函数等效于在 /volatile:iso 下编译的以下表达式。
int a = __iso_volatile_load32(p); // equivalent to: int a = *(const volatile __int32*)p;
__iso_volatile_store32(p, a); // equivalent to: *(volatile __int32*)p = a;
请注意内部函数采用易失性指针来适应易失性变量。 但是,没有关于使用可变指针作为参数的要求或建议。 如果使用常规的非易失类型,这些操作的语义完全相同。
有关 /volatile:iso 命令行参数的详细信息,请参阅 /volatile(volatile 关键字解释)。
_MoveFromCoprocessor、_MoveFromCoprocessor2
这些内部函数通过使用协处理器数据传输指令从 ARM 协处理器读取数据。
int _MoveFromCoprocessor(
unsigned int coproc,
unsigned int opcode1,
unsigned int crn,
unsigned int crm,
unsigned int opcode2
);
int _MoveFromCoprocessor2(
unsigned int coproc,
unsigned int opcode1,
unsigned int crn,
unsigned int crm,
unsigned int opcode2
);
参数
coproc
0 到 15 之间的协处理器编号。
opcode1
0 到 7 之间特定于协处理器的操作码
crn
协处理器寄存器编号,在 0 到 15 之间,用于向指令指定第一个操作数。
crm
协处理器寄存器编号,在 0 到 15 之间,用于指定附加的源或目标操作数。
opcode2
0 到 7 之间特定于附加协处理器的操作码。
返回值
从协处理器中读取的值。
注解
此内部函数的所有五个参数的值必须是在编译时已知的常数表达式。
_MoveFromCoprocessor
使用 MRC 指令;_MoveFromCoprocessor2
使用 MRC2。 此参数对应于直接编码到指令字中的位字段。 参数的解释与协处理器相关。 有关详细信息,请参见有问题的协处理器的手册。
_MoveFromCoprocessor64
使用协处理器数据传输指令,读取 ARM 协处理器中的数据。
unsigned __int64 _MoveFromCoprocessor64(
unsigned int coproc,
unsigned int opcode1,
unsigned int crm,
);
参数
coproc
0 到 15 之间的协处理器编号。
opcode1
0 到 15 之间特定于协处理器的操作码。
crm
协处理器寄存器编号,在 0 到 15 之间,用于指定附加的源或目标操作数。
返回值
从协处理器中读取的值。
注解
此内部函数的所有三个参数的值必须是在编译时已知的常数表达式。
_MoveFromCoprocessor64
使用 MRRC 指令。 此参数对应于直接编码到指令字中的位字段。 参数的解释与协处理器相关。 有关详细信息,请参见有问题的协处理器的手册。
_MoveToCoprocessor、_MoveToCoprocessor2
这些内部函数通过使用协处理器数据传输指令将数据写入到 ARM 协处理器。
void _MoveToCoprocessor(
unsigned int value,
unsigned int coproc,
unsigned int opcode1,
unsigned int crn,
unsigned int crm,
unsigned int opcode2
);
void _MoveToCoprocessor2(
unsigned int value,
unsigned int coproc,
unsigned int opcode1,
unsigned int crn,
unsigned int crm,
unsigned int opcode2
);
参数
value
要写入到协处理器的值。
coproc
0 到 15 之间的协处理器编号。
opcode1
0 到 7 之间特定于协处理器的操作码。
crn
协处理器寄存器编号,在 0 到 15 之间,用于向指令指定第一个操作数。
crm
协处理器寄存器编号,在 0 到 15 之间,用于指定附加的源或目标操作数。
opcode2
0 到 7 之间特定于附加协处理器的操作码。
返回值
无。
备注
此内部函数的 coproc
、opcode1
、crn
、crm
和 opcode2
参数的值必须是在编译时已知的常数表达式。
_MoveToCoprocessor
使用 MCR 指令;_MoveToCoprocessor2
使用 MCR2。 此参数对应于直接编码到指令字中的位字段。 参数的解释与协处理器相关。 有关详细信息,请参见有问题的协处理器的手册。
_MoveToCoprocessor64
这些内部函数通过使用协处理器数据传输指令将数据写入到 ARM 协处理器。
void _MoveFromCoprocessor64(
unsigned __int64 value,
unsigned int coproc,
unsigned int opcode1,
unsigned int crm,
);
参数
coproc
0 到 15 之间的协处理器编号。
opcode1
0 到 15 之间特定于协处理器的操作码。
crm
协处理器寄存器编号,在 0 到 15 之间,用于指定附加的源或目标操作数。
返回值
无。
备注
内部函数的 coproc
、opcode1
和 crm
参数的值必须是在编译时已知的常数表达式。
_MoveFromCoprocessor64
使用 MCRR 指令。 此参数对应于直接编码到指令字中的位字段。 参数的解释与协处理器相关。 有关详细信息,请参见有问题的协处理器的手册。
ARM 支持来自其他体系结构的内部函数
下表列出了来自在 ARM 平台上受支持的其他体系结构的内部函数。 如果 ARM 上的内部函数行为不同于它在其他硬件体系结构上的行为,则记录其他详细信息。
函数名称 | 函数原型 |
---|---|
__assume | void __assume(int) |
__code_seg | void __code_seg(const char *) |
__debugbreak | void __cdecl __debugbreak(void) |
__fastfail | __declspec(noreturn) void __fastfail(unsigned int) |
__nop | void __nop(void) 注意:如果在目标体系结构中实现了一个指令,则该函数会在 ARM 平台上生成一条 NOP 指令;否则,将生成一条不会改变程序或 CPU 状态的替代指令,例如 MOV r8, r8 。 它在功能上等同于其他硬件体系结构的 __nop 内部函数。 因为对项目或 CPU 的状态无影响的指令可能会因优化而被目标体系结构忽略,所以指令不一定消耗 CPU 周期。 因此,不要使用 __nop 内部函数来操作代码序列的执行时间,除非确信 CPU 的运行方式。 相反,你可以使用 __nop 内部函数将下一个指令对齐到特定的 32 位边界地址。 |
__yield | void __yield(void) 注意:在 ARM 平台上,此函数生成 YIELD 指令,这表明线程正在执行可以暂时暂停执行的任务(如旋转锁),而不会对该程序产生不利影响。 它使 CPU 能够在执行周期内执行其他任务,这些任务如果不执行则会被浪费掉。 |
_AddressOfReturnAddress | void * _AddressOfReturnAddress(void) |
_BitScanForward | unsigned char _BitScanForward(unsigned long * _Index, unsigned long _Mask) |
_BitScanReverse | unsigned char _BitScanReverse(unsigned long * _Index, unsigned long _Mask) |
_bittest | unsigned char _bittest(long const *, long) |
_bittestandcomplement | unsigned char _bittestandcomplement(long *, long) |
_bittestandreset | unsigned char _bittestandreset(long *, long) |
_bittestandset | unsigned char _bittestandset(long *, long) |
_byteswap_uint64 | unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64) |
_byteswap_ulong | unsigned long __cdecl _byteswap_ulong(unsigned long) |
_byteswap_ushort | unsigned short __cdecl _byteswap_ushort(unsigned short) |
_disable | void __cdecl _disable(void) 注意:在 ARM 平台上,此函数生成 CPSID 指令;它只能用作内部函数。 |
_enable | void __cdecl _enable(void) 注意:在 ARM 平台上,此函数生成 CPSIE 指令;它只能用作内部函数。 |
_lrotl | unsigned long __cdecl _lrotl(unsigned long, int) |
_lrotr | unsigned long __cdecl _lrotr(unsigned long, int) |
_ReadBarrier | void _ReadBarrier(void) |
_ReadWriteBarrier | void _ReadWriteBarrier(void) |
_ReturnAddress | void * _ReturnAddress(void) |
_rotl | unsigned int __cdecl _rotl(unsigned int _Value, int _Shift) |
_rotl16 | unsigned short _rotl16(unsigned short _Value, unsigned char _Shift) |
_rotl64 | unsigned __int64 __cdecl _rotl64(unsigned __int64 _Value, int _Shift) |
_rotl8 | unsigned char _rotl8(unsigned char _Value, unsigned char _Shift) |
_rotr | unsigned int __cdecl _rotr(unsigned int _Value, int _Shift) |
_rotr16 | unsigned short _rotr16(unsigned short _Value, unsigned char _Shift) |
_rotr64 | unsigned __int64 __cdecl _rotr64(unsigned __int64 _Value, int _Shift) |
_rotr8 | unsigned char _rotr8(unsigned char _Value, unsigned char _Shift) |
_setjmpex | int __cdecl _setjmpex(jmp_buf) |
_WriteBarrier | void _WriteBarrier(void) |
[返回顶部]
互锁内部函数
互锁内部函数是用于执行原子读取-修改-写入操作的一组内部函数。 其中一些互锁内部函数通用于所有平台。 此处单独将其列出不是因为它们数量庞大,而是因为它们的定义通常是多余的,一般情况下较容易就想到它们。 它们的名称可用于派生确切行为。
下表总结了非 bittest 互锁内部函数的 ARM 支持。 表中的每个单元格都对应一个名称,这些名称的派生方式是将该行的最左侧单元格中的操作名和该列的最上面单元格中的类型名附加到 _Interlocked
。 例如,第 Xor
行和第 8
列交叉处的单元格对应于 _InterlockedXor8
并且完全受支持。 大部分受支持的函数提供以下可选后缀:_acq
、_rel
和 _nf
。 _acq
后缀表示“获取”语义,而 _rel
后缀表示“发布”语义。 _nf
或“no fence”后缀对于 ARM 来说是唯一的,我们将在下一节进行讨论。
Operation | 8 | 16 | 32 | 64 | P |
---|---|---|---|---|---|
添加 | 无 | 无 | 完全 | 完全 | 无 |
且 | 完全 | 完全 | 完全 | 完全 | 无 |
CompareExchange | 完整 | 完全 | 完全 | 完全 | 完全 |
递减 | 无 | 完全 | 完全 | 完全 | 无 |
Exchange | 部分 | 部分 | 部分 | 部分 | 部分 |
ExchangeAdd | 完整 | 完全 | 完全 | 完全 | 无 |
增量 | 无 | 完全 | 完全 | 完全 | 无 |
或 | 完全 | 完全 | 完全 | 完全 | 无 |
Xor | 完全 | 完全 | 完全 | 完全 | 无 |
密钥:
完全:支持普通、
_acq
、_rel
和_nf
窗体。部分:支持普通、
_acq
和_nf
窗体。无:不支持
_nf (no fence) 后缀
_nf
或“no fence”后缀表示操作不表现为任何类型的内存屏障,与表现为某种类型屏障的其他三种形式(无格式、_acq
和 _rel
)相反。 _nf
形式的一种可能用途是维护统计信息计数器,该计数器由多个线程同时更新,但在执行多个线程时不会使用该计数器的值。
互锁内部函数列表
函数名称 | 函数原型 |
---|---|
_InterlockedAdd | long _InterlockedAdd(long _volatile *, long) |
_InterlockedAdd64 | __int64 _InterlockedAdd64(__int64 volatile *, __int64) |
_InterlockedAdd64_acq | __int64 _InterlockedAdd64_acq(__int64 volatile *, __int64) |
_InterlockedAdd64_nf | __int64 _InterlockedAdd64_nf(__int64 volatile *, __int64) |
_InterlockedAdd64_rel | __int64 _InterlockedAdd64_rel(__int64 volatile *, __int64) |
_InterlockedAdd_acq | long _InterlockedAdd_acq(long volatile *, long) |
_InterlockedAdd_nf | long _InterlockedAdd_nf(long volatile *, long) |
_InterlockedAdd_rel | long _InterlockedAdd_rel(long volatile *, long) |
_InterlockedAnd | long _InterlockedAnd(long volatile *, long) |
_InterlockedAnd16 | short _InterlockedAnd16(short volatile *, short) |
_InterlockedAnd16_acq | short _InterlockedAnd16_acq(short volatile *, short) |
_InterlockedAnd16_nf | short _InterlockedAnd16_nf(short volatile *, short) |
_InterlockedAnd16_rel | short _InterlockedAnd16_rel(short volatile *, short) |
_InterlockedAnd64 | __int64 _InterlockedAnd64(__int64 volatile *, __int64) |
_InterlockedAnd64_acq | __int64 _InterlockedAnd64_acq(__int64 volatile *, __int64) |
_InterlockedAnd64_nf | __int64 _InterlockedAnd64_nf(__int64 volatile *, __int64) |
_InterlockedAnd64_rel | __int64 _InterlockedAnd64_rel(__int64 volatile *, __int64) |
_InterlockedAnd8 | char _InterlockedAnd8(char volatile *, char) |
_InterlockedAnd8_acq | char _InterlockedAnd8_acq(char volatile *, char) |
_InterlockedAnd8_nf | char _InterlockedAnd8_nf(char volatile *, char) |
_InterlockedAnd8_rel | char _InterlockedAnd8_rel(char volatile *, char) |
_InterlockedAnd_acq | long _InterlockedAnd_acq(long volatile *, long) |
_InterlockedAnd_nf | long _InterlockedAnd_nf(long volatile *, long) |
_InterlockedAnd_rel | long _InterlockedAnd_rel(long volatile *, long) |
_InterlockedCompareExchange | long __cdecl _InterlockedCompareExchange(long volatile *, long, long) |
_InterlockedCompareExchange16 | short _InterlockedCompareExchange16(short volatile *, short, short) |
_InterlockedCompareExchange16_acq | short _InterlockedCompareExchange16_acq(short volatile *, short, short) |
_InterlockedCompareExchange16_nf | short _InterlockedCompareExchange16_nf(short volatile *, short, short) |
_InterlockedCompareExchange16_rel | short _InterlockedCompareExchange16_rel(short volatile *, short, short) |
_InterlockedCompareExchange64 | __int64 _InterlockedCompareExchange64(__int64 volatile *, __int64, __int64) |
_InterlockedCompareExchange64_acq | __int64 _InterlockedCompareExchange64_acq(__int64 volatile *, __int64, __int64) |
_InterlockedCompareExchange64_nf | __int64 _InterlockedCompareExchange64_nf(__int64 volatile *, __int64, __int64) |
_InterlockedCompareExchange64_rel | __int64 _InterlockedCompareExchange64_rel(__int64 volatile *, __int64, __int64) |
_InterlockedCompareExchange8 | char _InterlockedCompareExchange8(char volatile *, char, char) |
_InterlockedCompareExchange8_acq | char _InterlockedCompareExchange8_acq(char volatile *, char, char) |
_InterlockedCompareExchange8_nf | char _InterlockedCompareExchange8_nf(char volatile *, char, char) |
_InterlockedCompareExchange8_rel | char _InterlockedCompareExchange8_rel(char volatile *, char, char) |
_InterlockedCompareExchangePointer | void * _InterlockedCompareExchangePointer(void * volatile *, void *, void *) |
_InterlockedCompareExchangePointer_acq | void * _InterlockedCompareExchangePointer_acq(void * volatile *, void *, void *) |
_InterlockedCompareExchangePointer_nf | void * _InterlockedCompareExchangePointer_nf(void * volatile *, void *, void *) |
_InterlockedCompareExchangePointer_rel | void * _InterlockedCompareExchangePointer_rel(void * volatile *, void *, void *) |
_InterlockedCompareExchange_acq | long _InterlockedCompareExchange_acq(long volatile *, long, long) |
_InterlockedCompareExchange_nf | long _InterlockedCompareExchange_nf(long volatile *, long, long) |
_InterlockedCompareExchange_rel | long _InterlockedCompareExchange_rel(long volatile *, long, long) |
_InterlockedDecrement | long __cdecl _InterlockedDecrement(long volatile *) |
_InterlockedDecrement16 | short _InterlockedDecrement16(short volatile *) |
_InterlockedDecrement16_acq | short _InterlockedDecrement16_acq(short volatile *) |
_InterlockedDecrement16_nf | short _InterlockedDecrement16_nf(short volatile *) |
_InterlockedDecrement16_rel | short _InterlockedDecrement16_rel(short volatile *) |
_InterlockedDecrement64 | __int64 _InterlockedDecrement64(__int64 volatile *) |
_InterlockedDecrement64_acq | __int64 _InterlockedDecrement64_acq(__int64 volatile *) |
_InterlockedDecrement64_nf | __int64 _InterlockedDecrement64_nf(__int64 volatile *) |
_InterlockedDecrement64_rel | __int64 _InterlockedDecrement64_rel(__int64 volatile *) |
_InterlockedDecrement_acq | long _InterlockedDecrement_acq(long volatile *) |
_InterlockedDecrement_nf | long _InterlockedDecrement_nf(long volatile *) |
_InterlockedDecrement_rel | long _InterlockedDecrement_rel(long volatile *) |
_InterlockedExchange | long __cdecl _InterlockedExchange(long volatile * _Target, long) |
_InterlockedExchange16 | short _InterlockedExchange16(short volatile * _Target, short) |
_InterlockedExchange16_acq | short _InterlockedExchange16_acq(short volatile * _Target, short) |
_InterlockedExchange16_nf | short _InterlockedExchange16_nf(short volatile * _Target, short) |
_InterlockedExchange64 | __int64 _InterlockedExchange64(__int64 volatile * _Target, __int64) |
_InterlockedExchange64_acq | __int64 _InterlockedExchange64_acq(__int64 volatile * _Target, __int64) |
_InterlockedExchange64_nf | __int64 _InterlockedExchange64_nf(__int64 volatile * _Target, __int64) |
_InterlockedExchange8 | char _InterlockedExchange8(char volatile * _Target, char) |
_InterlockedExchange8_acq | char _InterlockedExchange8_acq(char volatile * _Target, char) |
_InterlockedExchange8_nf | char _InterlockedExchange8_nf(char volatile * _Target, char) |
_InterlockedExchangeAdd | long __cdecl _InterlockedExchangeAdd(long volatile *, long) |
_InterlockedExchangeAdd16 | short _InterlockedExchangeAdd16(short volatile *, short) |
_InterlockedExchangeAdd16_acq | short _InterlockedExchangeAdd16_acq(short volatile *, short) |
_InterlockedExchangeAdd16_nf | short _InterlockedExchangeAdd16_nf(short volatile *, short) |
_InterlockedExchangeAdd16_rel | short _InterlockedExchangeAdd16_rel(short volatile *, short) |
_InterlockedExchangeAdd64 | __int64 _InterlockedExchangeAdd64(__int64 volatile *, __int64) |
_InterlockedExchangeAdd64_acq | __int64 _InterlockedExchangeAdd64_acq(__int64 volatile *, __int64) |
_InterlockedExchangeAdd64_nf | __int64 _InterlockedExchangeAdd64_nf(__int64 volatile *, __int64) |
_InterlockedExchangeAdd64_rel | __int64 _InterlockedExchangeAdd64_rel(__int64 volatile *, __int64) |
_InterlockedExchangeAdd8 | char _InterlockedExchangeAdd8(char volatile *, char) |
_InterlockedExchangeAdd8_acq | char _InterlockedExchangeAdd8_acq(char volatile *, char) |
_InterlockedExchangeAdd8_nf | char _InterlockedExchangeAdd8_nf(char volatile *, char) |
_InterlockedExchangeAdd8_rel | char _InterlockedExchangeAdd8_rel(char volatile *, char) |
_InterlockedExchangeAdd_acq | long _InterlockedExchangeAdd_acq(long volatile *, long) |
_InterlockedExchangeAdd_nf | long _InterlockedExchangeAdd_nf(long volatile *, long) |
_InterlockedExchangeAdd_rel | long _InterlockedExchangeAdd_rel(long volatile *, long) |
_InterlockedExchangePointer | void * _InterlockedExchangePointer(void * volatile * _Target, void *) |
_InterlockedExchangePointer_acq | void * _InterlockedExchangePointer_acq(void * volatile * _Target, void *) |
_InterlockedExchangePointer_nf | void * _InterlockedExchangePointer_nf(void * volatile * _Target, void *) |
_InterlockedExchange_acq | long _InterlockedExchange_acq(long volatile * _Target, long) |
_InterlockedExchange_nf | long _InterlockedExchange_nf(long volatile * _Target, long) |
_InterlockedIncrement | long __cdecl _InterlockedIncrement(long volatile *) |
_InterlockedIncrement16 | short _InterlockedIncrement16(short volatile *) |
_InterlockedIncrement16_acq | short _InterlockedIncrement16_acq(short volatile *) |
_InterlockedIncrement16_nf | short _InterlockedIncrement16_nf(short volatile *) |
_InterlockedIncrement16_rel | short _InterlockedIncrement16_rel(short volatile *) |
_InterlockedIncrement64 | __int64 _InterlockedIncrement64(__int64 volatile *) |
_InterlockedIncrement64_acq | __int64 _InterlockedIncrement64_acq(__int64 volatile *) |
_InterlockedIncrement64_nf | __int64 _InterlockedIncrement64_nf(__int64 volatile *) |
_InterlockedIncrement64_rel | __int64 _InterlockedIncrement64_rel(__int64 volatile *) |
_InterlockedIncrement_acq | long _InterlockedIncrement_acq(long volatile *) |
_InterlockedIncrement_nf | long _InterlockedIncrement_nf(long volatile *) |
_InterlockedIncrement_rel | long _InterlockedIncrement_rel(long volatile *) |
_InterlockedOr | long _InterlockedOr(long volatile *, long) |
_InterlockedOr16 | short _InterlockedOr16(short volatile *, short) |
_InterlockedOr16_acq | short _InterlockedOr16_acq(short volatile *, short) |
_InterlockedOr16_nf | short _InterlockedOr16_nf(short volatile *, short) |
_InterlockedOr16_rel | short _InterlockedOr16_rel(short volatile *, short) |
_InterlockedOr64 | __int64 _InterlockedOr64(__int64 volatile *, __int64) |
_InterlockedOr64_acq | __int64 _InterlockedOr64_acq(__int64 volatile *, __int64) |
_InterlockedOr64_nf | __int64 _InterlockedOr64_nf(__int64 volatile *, __int64) |
_InterlockedOr64_rel | __int64 _InterlockedOr64_rel(__int64 volatile *, __int64) |
_InterlockedOr8 | char _InterlockedOr8(char volatile *, char) |
_InterlockedOr8_acq | char _InterlockedOr8_acq(char volatile *, char) |
_InterlockedOr8_nf | char _InterlockedOr8_nf(char volatile *, char) |
_InterlockedOr8_rel | char _InterlockedOr8_rel(char volatile *, char) |
_InterlockedOr_acq | long _InterlockedOr_acq(long volatile *, long) |
_InterlockedOr_nf | long _InterlockedOr_nf(long volatile *, long) |
_InterlockedOr_rel | long _InterlockedOr_rel(long volatile *, long) |
_InterlockedXor | long _InterlockedXor(long volatile *, long) |
_InterlockedXor16 | short _InterlockedXor16(short volatile *, short) |
_InterlockedXor16_acq | short _InterlockedXor16_acq(short volatile *, short) |
_InterlockedXor16_nf | short _InterlockedXor16_nf(short volatile *, short) |
_InterlockedXor16_rel | short _InterlockedXor16_rel(short volatile *, short) |
_InterlockedXor64 | __int64 _InterlockedXor64(__int64 volatile *, __int64) |
_InterlockedXor64_acq | __int64 _InterlockedXor64_acq(__int64 volatile *, __int64) |
_InterlockedXor64_nf | __int64 _InterlockedXor64_nf(__int64 volatile *, __int64) |
_InterlockedXor64_rel | __int64 _InterlockedXor64_rel(__int64 volatile *, __int64) |
_InterlockedXor8 | char _InterlockedXor8(char volatile *, char) |
_InterlockedXor8_acq | char _InterlockedXor8_acq(char volatile *, char) |
_InterlockedXor8_nf | char _InterlockedXor8_nf(char volatile *, char) |
_InterlockedXor8_rel | char _InterlockedXor8_rel(char volatile *, char) |
_InterlockedXor_acq | long _InterlockedXor_acq(long volatile *, long) |
_InterlockedXor_nf | long _InterlockedXor_nf(long volatile *, long) |
_InterlockedXor_rel | long _InterlockedXor_rel(long volatile *, long) |
[返回顶部]
_interlockedbittest 内部函数
纯互锁的 bit 测试内部函数通用于所有平台。 ARM 添加 _acq
、_rel
和 _nf
变量,它们只修改操作的屏障语义,如本文前面的 _nf (no fence) 后缀所述。
函数名称 | 函数原型 |
---|---|
_interlockedbittestandreset | unsigned char _interlockedbittestandreset(long volatile *, long) |
_interlockedbittestandreset_acq | unsigned char _interlockedbittestandreset_acq(long volatile *, long) |
_interlockedbittestandreset_nf | unsigned char _interlockedbittestandreset_nf(long volatile *, long) |
_interlockedbittestandreset_rel | unsigned char _interlockedbittestandreset_rel(long volatile *, long) |
_interlockedbittestandset | unsigned char _interlockedbittestandset(long volatile *, long) |
_interlockedbittestandset_acq | unsigned char _interlockedbittestandset_acq(long volatile *, long) |
_interlockedbittestandset_nf | unsigned char _interlockedbittestandset_nf(long volatile *, long) |
_interlockedbittestandset_rel | unsigned char _interlockedbittestandset_rel(long volatile *, long) |
[返回顶部]