OSDN Git Service

new repo
[bytom/vapor.git] / vendor / gonum.org / v1 / gonum / internal / asm / f64 / dot_amd64.s
1 // Copyright ©2015 The Gonum Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 //
5 // Some of the loop unrolling code is copied from:
6 // http://golang.org/src/math/big/arith_amd64.s
7 // which is distributed under these terms:
8 //
9 // Copyright (c) 2012 The Go Authors. All rights reserved.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 //    * Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //    * Redistributions in binary form must reproduce the above
18 // copyright notice, this list of conditions and the following disclaimer
19 // in the documentation and/or other materials provided with the
20 // distribution.
21 //    * Neither the name of Google Inc. nor the names of its
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36
37 //+build !noasm,!appengine
38
39 #include "textflag.h"
40
41 // func DdotUnitary(x, y []float64) (sum float64)
42 // This function assumes len(y) >= len(x).
43 TEXT ·DotUnitary(SB), NOSPLIT, $0
44         MOVQ x+0(FP), R8
45         MOVQ x_len+8(FP), DI // n = len(x)
46         MOVQ y+24(FP), R9
47
48         MOVSD $(0.0), X7 // sum = 0
49         MOVSD $(0.0), X8 // sum = 0
50
51         MOVQ $0, SI   // i = 0
52         SUBQ $4, DI   // n -= 4
53         JL   tail_uni // if n < 0 goto tail_uni
54
55 loop_uni:
56         // sum += x[i] * y[i] unrolled 4x.
57         MOVUPD 0(R8)(SI*8), X0
58         MOVUPD 0(R9)(SI*8), X1
59         MOVUPD 16(R8)(SI*8), X2
60         MOVUPD 16(R9)(SI*8), X3
61         MULPD  X1, X0
62         MULPD  X3, X2
63         ADDPD  X0, X7
64         ADDPD  X2, X8
65
66         ADDQ $4, SI   // i += 4
67         SUBQ $4, DI   // n -= 4
68         JGE  loop_uni // if n >= 0 goto loop_uni
69
70 tail_uni:
71         ADDQ $4, DI  // n += 4
72         JLE  end_uni // if n <= 0 goto end_uni
73
74 onemore_uni:
75         // sum += x[i] * y[i] for the remaining 1-3 elements.
76         MOVSD 0(R8)(SI*8), X0
77         MOVSD 0(R9)(SI*8), X1
78         MULSD X1, X0
79         ADDSD X0, X7
80
81         ADDQ $1, SI      // i++
82         SUBQ $1, DI      // n--
83         JNZ  onemore_uni // if n != 0 goto onemore_uni
84
85 end_uni:
86         // Add the four sums together.
87         ADDPD    X8, X7
88         MOVSD    X7, X0
89         UNPCKHPD X7, X7
90         ADDSD    X0, X7
91         MOVSD    X7, sum+48(FP) // Return final sum.
92         RET
93
94 // func DdotInc(x, y []float64, n, incX, incY, ix, iy uintptr) (sum float64)
95 TEXT ·DotInc(SB), NOSPLIT, $0
96         MOVQ x+0(FP), R8
97         MOVQ y+24(FP), R9
98         MOVQ n+48(FP), CX
99         MOVQ incX+56(FP), R11
100         MOVQ incY+64(FP), R12
101         MOVQ ix+72(FP), R13
102         MOVQ iy+80(FP), R14
103
104         MOVSD $(0.0), X7      // sum = 0
105         LEAQ  (R8)(R13*8), SI // p = &x[ix]
106         LEAQ  (R9)(R14*8), DI // q = &y[ix]
107         SHLQ  $3, R11         // incX *= sizeof(float64)
108         SHLQ  $3, R12         // indY *= sizeof(float64)
109
110         SUBQ $2, CX   // n -= 2
111         JL   tail_inc // if n < 0 goto tail_inc
112
113 loop_inc:
114         // sum += *p * *q unrolled 2x.
115         MOVHPD (SI), X0
116         MOVHPD (DI), X1
117         ADDQ   R11, SI  // p += incX
118         ADDQ   R12, DI  // q += incY
119         MOVLPD (SI), X0
120         MOVLPD (DI), X1
121         ADDQ   R11, SI  // p += incX
122         ADDQ   R12, DI  // q += incY
123
124         MULPD X1, X0
125         ADDPD X0, X7
126
127         SUBQ $2, CX   // n -= 2
128         JGE  loop_inc // if n >= 0 goto loop_inc
129
130 tail_inc:
131         ADDQ $2, CX  // n += 2
132         JLE  end_inc // if n <= 0 goto end_inc
133
134         // sum += *p * *q for the last iteration if n is odd.
135         MOVSD (SI), X0
136         MULSD (DI), X0
137         ADDSD X0, X7
138
139 end_inc:
140         // Add the two sums together.
141         MOVSD    X7, X0
142         UNPCKHPD X7, X7
143         ADDSD    X0, X7
144         MOVSD    X7, sum+88(FP) // Return final sum.
145         RET