diff options
| author | Keith Randall <keithr@alum.mit.edu> | 2017-06-14 11:36:36 -0700 |
|---|---|---|
| committer | Keith Randall <khr@golang.org> | 2017-06-15 03:51:03 +0000 |
| commit | 79d05e75ca38f0e4b9986bbba4cd56398428f9fb (patch) | |
| tree | b3e363ce26fb39aed4cbcde6c144a71286ae0e10 /src/runtime | |
| parent | 90b7058ec4b73fe1da0e94ccd80d78835b6e32cb (diff) | |
| download | go-79d05e75ca38f0e4b9986bbba4cd56398428f9fb.tar.xz | |
runtime: restore arm assembly stubs for div/mod
These are used by DIV[U] and MOD[U] assembly instructions.
Add a test in the stdlib so we actually exercise linking
to these routines.
Update #19507
Change-Id: I0d8e19a53e3744abc0c661ea95486f94ec67585e
Reviewed-on: https://go-review.googlesource.com/45703
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/runtime')
| -rw-r--r-- | src/runtime/softfloat_arm.go | 6 | ||||
| -rw-r--r-- | src/runtime/vlop_arm.s | 112 |
2 files changed, 117 insertions, 1 deletions
diff --git a/src/runtime/softfloat_arm.go b/src/runtime/softfloat_arm.go index 8519f4cbd5..726699d720 100644 --- a/src/runtime/softfloat_arm.go +++ b/src/runtime/softfloat_arm.go @@ -655,6 +655,10 @@ func sfloat2(pc uint32, regs *[15]uint32) uint32 { } // Stubs to pacify vet. Not safe to call from Go. -// Calls to these functions are inserted by the compiler. +// Calls to these functions are inserted by the compiler or assembler. func _sfloat() func udiv() +func _div() +func _divu() +func _mod() +func _modu() diff --git a/src/runtime/vlop_arm.s b/src/runtime/vlop_arm.s index 7489a65071..6a602ffbb8 100644 --- a/src/runtime/vlop_arm.s +++ b/src/runtime/vlop_arm.s @@ -199,6 +199,118 @@ DATA fast_udiv_tab<>+0x38(SB)/4, $0x85868788 DATA fast_udiv_tab<>+0x3c(SB)/4, $0x81828384 GLOBL fast_udiv_tab<>(SB), RODATA, $64 +// The linker will pass numerator in R8 +#define Rn R8 +// The linker expects the result in RTMP +#define RTMP R11 + +TEXT runtime·_divu(SB), NOSPLIT, $16-0 + // It's not strictly true that there are no local pointers. + // It could be that the saved registers Rq, Rr, Rs, and Rm + // contain pointers. However, the only way this can matter + // is if the stack grows (which it can't, udiv is nosplit) + // or if a fault happens and more frames are added to + // the stack due to deferred functions. + // In the latter case, the stack can grow arbitrarily, + // and garbage collection can happen, and those + // operations care about pointers, but in that case + // the calling frame is dead, and so are the saved + // registers. So we can claim there are no pointers here. + NO_LOCAL_POINTERS + MOVW Rq, 4(R13) + MOVW Rr, 8(R13) + MOVW Rs, 12(R13) + MOVW RM, 16(R13) + + MOVW Rn, Rr /* numerator */ + MOVW g_m(g), Rq + MOVW m_divmod(Rq), Rq /* denominator */ + BL runtime·udiv(SB) + MOVW Rq, RTMP + MOVW 4(R13), Rq + MOVW 8(R13), Rr + MOVW 12(R13), Rs + MOVW 16(R13), RM + RET + +TEXT runtime·_modu(SB), NOSPLIT, $16-0 + NO_LOCAL_POINTERS + MOVW Rq, 4(R13) + MOVW Rr, 8(R13) + MOVW Rs, 12(R13) + MOVW RM, 16(R13) + + MOVW Rn, Rr /* numerator */ + MOVW g_m(g), Rq + MOVW m_divmod(Rq), Rq /* denominator */ + BL runtime·udiv(SB) + MOVW Rr, RTMP + MOVW 4(R13), Rq + MOVW 8(R13), Rr + MOVW 12(R13), Rs + MOVW 16(R13), RM + RET + +TEXT runtime·_div(SB),NOSPLIT,$16-0 + NO_LOCAL_POINTERS + MOVW Rq, 4(R13) + MOVW Rr, 8(R13) + MOVW Rs, 12(R13) + MOVW RM, 16(R13) + MOVW Rn, Rr /* numerator */ + MOVW g_m(g), Rq + MOVW m_divmod(Rq), Rq /* denominator */ + CMP $0, Rr + BGE d1 + RSB $0, Rr, Rr + CMP $0, Rq + BGE d2 + RSB $0, Rq, Rq +d0: + BL runtime·udiv(SB) /* none/both neg */ + MOVW Rq, RTMP + B out1 +d1: + CMP $0, Rq + BGE d0 + RSB $0, Rq, Rq +d2: + BL runtime·udiv(SB) /* one neg */ + RSB $0, Rq, RTMP +out1: + MOVW 4(R13), Rq + MOVW 8(R13), Rr + MOVW 12(R13), Rs + MOVW 16(R13), RM + RET + +TEXT runtime·_mod(SB),NOSPLIT,$16-0 + NO_LOCAL_POINTERS + MOVW Rq, 4(R13) + MOVW Rr, 8(R13) + MOVW Rs, 12(R13) + MOVW RM, 16(R13) + MOVW Rn, Rr /* numerator */ + MOVW g_m(g), Rq + MOVW m_divmod(Rq), Rq /* denominator */ + CMP $0, Rq + RSB.LT $0, Rq, Rq + CMP $0, Rr + BGE m1 + RSB $0, Rr, Rr + BL runtime·udiv(SB) /* neg numerator */ + RSB $0, Rr, RTMP + B out +m1: + BL runtime·udiv(SB) /* pos numerator */ + MOVW Rr, RTMP +out: + MOVW 4(R13), Rq + MOVW 8(R13), Rr + MOVW 12(R13), Rs + MOVW 16(R13), RM + RET + // _mul64by32 and _div64by32 not implemented on arm TEXT runtime·_mul64by32(SB), NOSPLIT, $0 MOVW $0, R0 |
