// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
// It saves all GP registers if necessary,
- // but clobbers R14 (LR) because it's a call.
- {name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R2"), buildReg("R3")}, clobbers: (callerSave &^ gpg) | buildReg("R14")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
+ // but clobbers R14 (LR) because it's a call,
+ // and also clobbers R1 as the PLT stub does.
+ {name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R2"), buildReg("R3")}, clobbers: (callerSave &^ gpg) | buildReg("R14") | r1}, clobberFlags: true, aux: "Sym", symEffect: "None"},
// There are three of these functions so that they can have three different register inputs.
// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
// gcWriteBarrier does NOT follow the Go ABI. It takes two arguments:
// - R2 is the destination of the write
// - R3 is the value being written at R2.
-// It clobbers R10 (the temp register).
+// It clobbers R10 (the temp register) and R1 (used by PLT stub).
// It does not clobber any other general-purpose registers,
// but may clobber others (e.g., floating point registers).
-TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$104
+TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$96
// Save the registers clobbered by the fast path.
- MOVD R1, 96(R15)
- MOVD R4, 104(R15)
+ MOVD R4, 96(R15)
MOVD g_m(g), R1
MOVD m_p(R1), R1
// Increment wbBuf.next position.
// Is the buffer full?
CMPBEQ R4, R1, flush
ret:
- MOVD 96(R15), R1
- MOVD 104(R15), R4
+ MOVD 96(R15), R4
// Do the write.
MOVD R3, (R2)
RET