C3.2  Loads and stores

  C3.2.1 加载存储-寄存器

  C3.2.2 加载存储-非扩展模式

  C3.2.3 加载存储-成对寄存器

  C3.2.4 加载存储-非时序成对

  C3.2.5 加载存储-非特权

  C3.2.6 加载存储-独享内存

  C3.2.7 加载-aquire/存储-release 

  C3.2.8 加载-aquire/存储-release--带有limit order属性

  C3.2.9 加载存储-可拓展SIMD和floating point

  C3.2.10 加载存储-矢量

  C3.2.11 预期内存

ARM64处理器提供了预加载提示指令(PRFM,它是Prefetch from Memory的缩写) .

PLD表示加载预取(prefetch for load),PST表示存储预取(prefetch for store)。

L1表示1级缓存,L2表示2级缓存,L3表示3级缓存。

KEEP表示把预取的数据保存在缓存中(因为预取的数据会被使用多次),称为保存预取(retain prefetch)或暂存预取(temporal prefetch);

STRM(stream)表示直接把预取的数据传给处理器的核(因为预取的数据只会使用一次,不需要保存在缓存中),称为流动预取(streaming prefetch)或非暂存预取(non-temporal prefetch)。

例如:PRFM PLDL1KEEP, [Xm, #imm]表示为一个从虚拟地址(Xm + 偏移)加载数据的操作预取数据到1级缓存中,并且暂存在缓存中。

支持的其他参数:

PLDL1KEEP, PLDL1STRM, PLDL2KEEP, PLDL2STRM, PLDL3KEEP, PLDL3STRM
PSTL1KEEP, PSTL1STRM, PSTL2KEEP, PSTL2STRM, PSTL3KEEP, PSTL3STRM
PLIL1KEEP, PLIL1STRM, PLIL2KEEP, PLIL2STRM, PLIL3KEEP, PLIL3STRM

(1)使用场景

在linux源码中有部分使用:--arch/arm64/include/asm/spinlock.h

#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)

static inline void arch_spin_lock(arch_spinlock_t *lock)
{
        unsigned int tmp;
        arch_spinlock_t lockval, newval;

        asm volatile(
        /* Atomically increment the next ticket. */
        ARM64_LSE_ATOMIC_INSN(
        /* LL/SC */
"       prfm    pstl1strm, %3\n"
"1:     ldaxr   %w0, %3\n"
"       add     %w1, %w0, %w5\n"
"       stxr    %w2, %w1, %3\n"
"       cbnz    %w2, 1b\n",
        /* LSE atomics */
"       mov     %w2, %w5\n"
"       ldadda  %w2, %w0, %3\n"
"       nop\n"
"       nop\n"
"       nop\n"
        )

        /* Did we get the lock? */
"       eor     %w1, %w0, %w0, ror #16\n"
"       cbz     %w1, 3f\n"
        /*
         * No: spin on the owner. Send a local event to avoid missing an
         * unlock before the exclusive load.
         */
"       sevl\n"
"2:     wfe\n"
"       ldaxrh  %w2, %4\n"
"       eor     %w1, %w2, %w0, lsr #16\n"
"       cbnz    %w1, 2b\n"
        /* We got the lock. Critical section starts here. */
"3:"
        : "=&r" (lockval), "=&r" (newval), "=&r" (tmp), "+Q" (*lock)
        : "Q" (lock->owner), "I" (1 << TICKET_SHIFT)
        : "memory");
}

 

 

 

  C3.2.12 比较并交换

  C3.2.12 原子内存操作

  C3.2.12 交换-swap指令

  C3.2.12 内存标记指令