summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/arm/asm.s
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/arm/asm.s')
-rw-r--r--src/pkg/runtime/arm/asm.s41
1 files changed, 36 insertions, 5 deletions
diff --git a/src/pkg/runtime/arm/asm.s b/src/pkg/runtime/arm/asm.s
index a4e4b3283..f9fe7e628 100644
--- a/src/pkg/runtime/arm/asm.s
+++ b/src/pkg/runtime/arm/asm.s
@@ -12,10 +12,10 @@ TEXT _rt0_arm(SB),7,$-4
// use R13 instead of SP to avoid linker rewriting the offsets
MOVW 0(R13), R0 // argc
MOVW $4(R13), R1 // argv
- SUB $128, R13 // plenty of scratch
+ SUB $64, R13 // plenty of scratch
AND $~7, R13
- MOVW R0, 120(R13) // save argc, argv away
- MOVW R1, 124(R13)
+ MOVW R0, 60(R13) // save argc, argv away
+ MOVW R1, 64(R13)
// set up m and g registers
// g is R10, m is R9
@@ -34,9 +34,9 @@ TEXT _rt0_arm(SB),7,$-4
BL runtime·check(SB)
// saved argc, argv
- MOVW 120(R13), R0
+ MOVW 60(R13), R0
MOVW R0, 4(R13)
- MOVW 124(R13), R1
+ MOVW 64(R13), R1
MOVW R1, 8(R13)
BL runtime·args(SB)
BL runtime·osinit(SB)
@@ -274,3 +274,34 @@ TEXT runtime·abort(SB),7,$-4
TEXT runtime·runcgocallback(SB),7,$0
MOVW $0, R0
MOVW (R0), R1
+
+// bool armcas(int32 *val, int32 old, int32 new)
+// Atomically:
+// if(*val == old){
+// *val = new;
+// return 1;
+// }else
+// return 0;
+//
+// To implement runtime·cas in ../$GOOS/arm/sys.s
+// using the native instructions, use:
+//
+// TEXT runtime·cas(SB),7,$0
+// B runtime·armcas(SB)
+//
+TEXT runtime·armcas(SB),7,$0
+ MOVW valptr+0(FP), R1
+ MOVW old+4(FP), R2
+ MOVW new+8(FP), R3
+casl:
+ LDREX (R1), R0
+ CMP R0, R2
+ BNE casfail
+ STREX R3, (R1), R0
+ CMP $0, R0
+ BNE casl
+ MOVW $1, R0
+ RET
+casfail:
+ MOVW $0, R0
+ RET