cas2

Compare and swap with two operands 68020

Compares two data registers with two operands in memory, and writes two other registers there only if both are equal.

Sizes .w .l, .w by default68020 only: select opt p=68020 before any code or data

XNZVC –●●●●
  • ● set from the result
  • – not changed

Forms

  • cas2 , ,

Operands

Dc1:Dc2
The compare registers for the first and second memory operands, for example d0:d1. If either comparison fails, both registers receive the corresponding memory values. More
Du1:Du2
The update registers for the first and second memory operands, for example d2:d3. Both values are written only if both comparisons succeed. More
(Rn1):(Rn2)
Two memory addresses, each held in a data or address register, for example (a0):(a1). The first uses Dc1 and Du1, and the second uses Dc2 and Du2. More

The operands are a pair of compare registers Dc1:Dc2, a pair of update registers Du1:Du2, and two addresses (Rn1):(Rn2). Each address may be held in a data or address register.

For example, cas2.l d0:d1, d2:d3, (a0):(a1) compares d0 with the long at a0, then d1 with the long at a1. On success, it writes d2 at a0 and d3 at a1. If either comparison fails, it writes neither update and copies the two memory values into d0 and d1.

N, Z, V and C describe memory minus its compare register for the first comparison, or for the second if the first was equal. X is unchanged. Z is set only if both comparisons succeed, so beq branches when both updates were written. The entire operation is indivisible, as with cas. This lets a program update two related values together.

opt p=68020
* --- Move both ends of a queue, but only if neither has changed ---
lea head, a0
lea tail, a1
move.l (a0), d0 ; the head read: 1
move.l (a1), d1 ; the tail read: 4
moveq #2, d2 ; the new head
moveq #5, d3 ; the new tail
cas2.l d0:d1, d2:d3, (a0):(a1) ; both still hold what was read: both are written
move.l head, d4 ; d4 = 2
move.l tail, d5 ; d5 = 5
bra END

head:
    dc.l 1
tail:
    dc.l 4

END: