Commit c9d2c7f0 authored by Russ Cox's avatar Russ Cox

runtime: replace divide with multiply in runtime.usleep on arm

We want to adjust the DIV calling convention to use m,
and usleep can be called without an m, so switch to a
multiplication by the reciprocal (and test).

Step toward a fix for #6699 and #10486.

Change-Id: Iccf76a18432d835e48ec64a2fa34a0e4d6d4b955
Reviewed-on: https://go-review.googlesource.com/12898Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
parent a1e42207
......@@ -1029,3 +1029,24 @@ TEXT runtime·prefetcht2(SB),NOSPLIT,$0-4
TEXT runtime·prefetchnta(SB),NOSPLIT,$0-4
RET
// x -> x/1000000, x%1000000, called from Go with args, results on stack.
TEXT runtime·usplit(SB),NOSPLIT,$0-12
MOVW x+0(FP), R0
CALL runtime·usplitR0(SB)
MOVW R0, q+4(FP)
MOVW R1, r+8(FP)
RET
// R0, R1 = R0/1000000, R0%1000000
TEXT runtime·usplitR0(SB),NOSPLIT,$0
// magic multiply to avoid software divide without available m.
// see output of go tool compile -S for x/1000000.
MOVW R0, R3
MOVW $1125899907, R1
MULLU R1, R0, (R0, R1)
MOVW R0>>18, R0
MOVW $1000000, R1
MULU R0, R1
SUB R1, R3, R1
RET
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Export guts for testing.
package runtime
var Usplit = usplit
......@@ -33,3 +33,6 @@ func rewindmorestack(buf *gobuf) {
print("runtime: pc=", hex(buf.pc), " ", hex(inst), "\n")
throw("runtime: misuse of rewindmorestack")
}
// for testing
func usplit(x uint32) (q, r uint32)
......@@ -283,10 +283,7 @@ TEXT runtime·sigaction(SB),NOSPLIT,$0
TEXT runtime·usleep(SB),NOSPLIT,$12
MOVW usec+0(FP), R0
MOVW R0, R1
MOVW $1000000, R2
DIV R2, R0
MOD R2, R1
CALL runtime·usplitR0(SB)
MOVW R0, a-12(SP)
MOVW R1, b-8(SP)
......
......@@ -302,15 +302,12 @@ TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
TEXT runtime·usleep(SB),NOSPLIT,$16
MOVW usec+0(FP), R0
MOVW R0, R2
MOVW $1000000, R1
DIV R1, R0
CALL runtime·usplitR0(SB)
// 0(R13) is the saved LR, don't use it
MOVW R0, 4(R13) // tv_sec.low
MOVW $0, R0
MOVW R0, 8(R13) // tv_sec.high
MOD R1, R2
MOVW $1000, R1
MOVW $1000, R2
MUL R1, R2
MOVW R2, 12(R13) // tv_nsec
......
......@@ -378,10 +378,7 @@ TEXT runtime·rt_sigaction(SB),NOSPLIT,$0
TEXT runtime·usleep(SB),NOSPLIT,$12
MOVW usec+0(FP), R0
MOVW R0, R1
MOVW $1000000, R2
DIV R2, R0
MOD R2, R1
CALL runtime·usplitR0(SB)
MOVW R0, 4(R13)
MOVW R1, 8(R13)
MOVW $0, R0
......
......@@ -104,15 +104,12 @@ TEXT runtime·lwp_tramp(SB),NOSPLIT,$0
TEXT runtime·usleep(SB),NOSPLIT,$16
MOVW usec+0(FP), R0
MOVW R0, R2
MOVW $1000000, R1
DIV R1, R0
CALL runtime·usplitR0(SB)
// 0(R13) is the saved LR, don't use it
MOVW R0, 4(R13) // tv_sec.low
MOVW $0, R0
MOVW R0, 8(R13) // tv_sec.high
MOD R1, R2
MOVW $1000, R1
MOVW $1000, R2
MUL R1, R2
MOVW R2, 12(R13) // tv_nsec
......
......@@ -70,14 +70,11 @@ TEXT runtime·write(SB),NOSPLIT,$-4
TEXT runtime·usleep(SB),NOSPLIT,$16
MOVW usec+0(FP), R0
MOVW R0, R2
MOVW $1000000, R1
DIV R1, R0
CALL runtime·usplitR0(SB)
MOVW R0, 4(R13) // tv_sec - l32
MOVW $0, R0
MOVW R0, 8(R13) // tv_sec - h32
MOD R1, R2
MOVW $1000, R1
MOVW $1000, R2
MUL R1, R2
MOVW R2, 12(R13) // tv_nsec
......
......@@ -4,7 +4,10 @@
package runtime_test
import "testing"
import (
"runtime"
"testing"
)
// arm soft division benchmarks adapted from
// http://ridiculousfish.com/files/division_benchmarks.tar.gz
......@@ -68,3 +71,14 @@ func BenchmarkUint32Mod13307(b *testing.B) { bmUint32Mod(13307, b) }
func BenchmarkUint32Mod52513(b *testing.B) { bmUint32Mod(52513, b) }
func BenchmarkUint32Mod60978747(b *testing.B) { bmUint32Mod(60978747, b) }
func BenchmarkUint32Mod106956295(b *testing.B) { bmUint32Mod(106956295, b) }
func TestUsplit(t *testing.T) {
var den uint32 = 1000000
for _, x := range []uint32{0, 1, 999999, 1000000, 1010101, 0xFFFFFFFF} {
q1, r1 := runtime.Usplit(x)
q2, r2 := x/den, x%den
if q1 != q2 || r1 != r2 {
t.Errorf("%d/1e6, %d%%1e6 = %d, %d, want %d, %d", x, x, q1, r1, q2, r2)
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment