
Interlocked Memory Instructions (Alpha Only)
A.4 Coding Requirements
• STx_C instructions that do not have a preceding LDx_L instruction
This typically indicates that a backward branch is taken from an LDx_L to
the STx_C Note that hardware device drivers that do device mailbox writes
are an exception. These drivers use the STx_C to write the mailbox. This
condition is found only on early Alpha systems and not on PCI-based systems.
• Excessive instructions between an LDx_L and an STxC
The AARM recommends that no more than 40 instructions appear between
an LDx_l and an STx_C. In theory, more than 40 instructions can cause
hardware interrupts to keep the sequence from completing. However, there
are no known occurrences of this.
To illustrate, the following are examples of code flagged by SRM_CHECK.
** Found an unexpected ldq at 0008291C
00082914 AC300000 ldq_l R1, (R16)
00082918 2284FFEC lda R20, 0xFFEC(R4)
0008291C A6A20038 ldq R21, 0x38(R2)
In the above example, an LDQ instruction was found after an LDQ_L before
the matching STQ_C. The LDQ must be moved out of the sequence, either by
recompiling or by source code changes. (See Section A.3.)
** Backward branch from 000405B0 to a STx_C sequence at 0004059C
00040598 C3E00003 br R31, 000405A8
0004059C 47F20400 bis R31, R18, R0
000405A0 B8100000 stl_c R0, (R16)
000405A4 F4000003 bne R0, 000405B4
000405A8 A8300000 ldl_l R1, (R16)
000405AC 40310DA0 cmple R1, R17, R0
000405B0 F41FFFFA bne R0, 0004059C
In the above example, a branch was discovered between the LDL_L and STQ_C.
In this case, there is no "fall through" path between the LDx_L and STx_C, which
the architecture requires.
Note
This branch backward from the LDx_L to the STx_C is characteristic of
the noncompliant code introduced by the "loop rotation" optimization.
The following MACRO–32 source code demonstrates code where there is a "fall
through" path, but this case is still noncompliant because of the potential branch
and a memory reference in the lock sequence:
getlck: evax_ldql r0, lockdata(r8) ; Get the lock data
movl index, r2 ; and the current index.
tstl r0 ; If the lock is zero,
beql is_clear ; skip ahead to store.
movl r3, r2 ; Else, set special index.
is_clear:
incl r0 ; Increment lock count
evax_stqc r0, lockdata(r8) ; and store it.
tstl r0 ; Did store succeed?
beql getlck ; Retry if not.
A–4 Interlocked Memory Instructions (Alpha Only)