aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/asm_mipsx.s
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2017-11-15 14:54:24 -0800
committerAustin Clements <austin@google.com>2018-02-13 16:34:21 +0000
commit313a4b2b7f6479f13c4d460aebe514aa86543e21 (patch)
treea608750561400f7e13c59c187ae17b2803fab81f /src/runtime/asm_mipsx.s
parenta39de964385fb32d13d8fac3991a669de962f0bd (diff)
downloadgo-313a4b2b7f6479f13c4d460aebe514aa86543e21.tar.gz
go-313a4b2b7f6479f13c4d460aebe514aa86543e21.zip
runtime: buffered write barrier for mips
Updates #22460. Change-Id: Ieaca94385c3bb88dcc8351c3866b4b0e2a1412b5 Reviewed-on: https://go-review.googlesource.com/92701 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/runtime/asm_mipsx.s')
-rw-r--r--src/runtime/asm_mipsx.s101
1 files changed, 101 insertions, 0 deletions
diff --git a/src/runtime/asm_mipsx.s b/src/runtime/asm_mipsx.s
index 6a4eb0af25..47367f1703 100644
--- a/src/runtime/asm_mipsx.s
+++ b/src/runtime/asm_mipsx.s
@@ -856,3 +856,104 @@ TEXT ·checkASM(SB),NOSPLIT,$0-1
MOVW $1, R1
MOVB R1, ret+0(FP)
RET
+
+// gcWriteBarrier performs a heap pointer write and informs the GC.
+//
+// gcWriteBarrier does NOT follow the Go ABI. It takes two arguments:
+// - R20 is the destination of the write
+// - R21 is the value being written at R20.
+// It clobbers R23 (the linker temp register).
+// The act of CALLing gcWriteBarrier will clobber R31 (LR).
+// It does not clobber any other general-purpose registers,
+// but may clobber others (e.g., floating point registers).
+TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$104
+ // Save the registers clobbered by the fast path.
+ MOVW R1, 100(R29)
+ MOVW R2, 104(R29)
+ MOVW g_m(g), R1
+ MOVW m_p(R1), R1
+ MOVW (p_wbBuf+wbBuf_next)(R1), R2
+ // Increment wbBuf.next position.
+ ADD $8, R2
+ MOVW R2, (p_wbBuf+wbBuf_next)(R1)
+ MOVW (p_wbBuf+wbBuf_end)(R1), R1
+ MOVW R1, R23 // R23 is linker temp register
+ // Record the write.
+ MOVW R21, -8(R2) // Record value
+ MOVW (R20), R1 // TODO: This turns bad writes into bad reads.
+ MOVW R1, -4(R2) // Record *slot
+ // Is the buffer full?
+ BEQ R2, R23, flush
+ret:
+ MOVW 100(R29), R1
+ MOVW 104(R29), R2
+ // Do the write.
+ MOVW R21, (R20)
+ RET
+
+flush:
+ // Save all general purpose registers since these could be
+ // clobbered by wbBufFlush and were not saved by the caller.
+ MOVW R20, 4(R29) // Also first argument to wbBufFlush
+ MOVW R21, 8(R29) // Also second argument to wbBufFlush
+ // R1 already saved
+ // R2 already saved
+ MOVW R3, 12(R29)
+ MOVW R4, 16(R29)
+ MOVW R5, 20(R29)
+ MOVW R6, 24(R29)
+ MOVW R7, 28(R29)
+ MOVW R8, 32(R29)
+ MOVW R9, 36(R29)
+ MOVW R10, 40(R29)
+ MOVW R11, 44(R29)
+ MOVW R12, 48(R29)
+ MOVW R13, 52(R29)
+ MOVW R14, 56(R29)
+ MOVW R15, 60(R29)
+ MOVW R16, 64(R29)
+ MOVW R17, 68(R29)
+ MOVW R18, 72(R29)
+ MOVW R19, 76(R29)
+ MOVW R20, 80(R29)
+ // R21 already saved
+ // R22 already saved.
+ MOVW R22, 84(R29)
+ // R23 is tmp register.
+ MOVW R24, 88(R29)
+ MOVW R25, 92(R29)
+ // R26 is reserved by kernel.
+ // R27 is reserved by kernel.
+ MOVW R28, 96(R29)
+ // R29 is SP.
+ // R30 is g.
+ // R31 is LR, which was saved by the prologue.
+
+ // This takes arguments R20 and R21.
+ CALL runtime·wbBufFlush(SB)
+
+ MOVW 4(R29), R20
+ MOVW 8(R29), R21
+ MOVW 12(R29), R3
+ MOVW 16(R29), R4
+ MOVW 20(R29), R5
+ MOVW 24(R29), R6
+ MOVW 28(R29), R7
+ MOVW 32(R29), R8
+ MOVW 36(R29), R9
+ MOVW 40(R29), R10
+ MOVW 44(R29), R11
+ MOVW 48(R29), R12
+ MOVW 52(R29), R13
+ MOVW 56(R29), R14
+ MOVW 60(R29), R15
+ MOVW 64(R29), R16
+ MOVW 68(R29), R17
+ MOVW 72(R29), R18
+ MOVW 76(R29), R19
+ MOVW 80(R29), R20
+ MOVW 84(R29), R22
+ MOVW 88(R29), R24
+ MOVW 92(R29), R25
+ MOVW 96(R29), R28
+ JMP ret