Browse Source

Added missing atomic test-and-set

git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@8685 8c9fc860-2736-0410-a75d-ab315db34111
negelef 6 years ago
parent
commit
a392f3b8af
1 changed files with 20 additions and 1 deletions
  1. 20 1
      source/ARM.Machine.Mod

+ 20 - 1
source/ARM.Machine.Mod

@@ -2574,10 +2574,29 @@ VAR
 		ADD SP, SP, #8
 	END AtomicAdd;
 
+	(* Atomic test-and-set. Set x = TRUE and return old value of x. *)
+	PROCEDURE -AtomicTestSet * (VAR x: BOOLEAN): BOOLEAN;
+	CODE
+		LDR	R3, [SP, #x]			; R3 := ADDRESSOF(x)
+		MOV	R1, #0				; R1 := FALSE
+		MOV	R2, #1				; R2 := TRUE
+		ADD	SP, SP, #4				; pop variable from stack
+
+	loop:
+		LDREXB	R0, R3					; load excl x
+		CMP	R0, R1
+		BNE	exit						; x # old -> exit
+		STREXB	R4, R2, R3				; x = old -> store excl new -> x
+		CMP	R4, #0
+		BNE	loop					; store exclusive failed: retry
+
+	exit:
+	END AtomicTestSet;
+
 	(* Atomic compare-and-swap. Set x = new if x = old and return old value of x *)
 	PROCEDURE -AtomicCAS * (VAR x: LONGINT; old, new: LONGINT): LONGINT;
 	CODE
-		LDR	R3, [SP, #x]			; R0 := ADDRESSOF(x)
+		LDR	R3, [SP, #x]			; R3 := ADDRESSOF(x)
 		LDR	R1, [SP, #old]			; R1 := old
 		LDR	R2, [SP, #new]			; R2 := new
 		ADD	SP, SP, #12				; pop variable from stack