github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/math/big/arith_amd64.s (about)

     1  // Copyright 2009 The Go 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  // This file provides fast assembly versions for the elementary
     6  // arithmetic operations on vectors implemented in arith.go.
     7  
     8  // Literal instruction for MOVQ $0, CX.
     9  // (MOVQ $0, reg is translated to XORQ reg, reg and clears CF.)
    10  #define ZERO_CX BYTE $0x48; \
    11  		BYTE $0xc7; \
    12  		BYTE $0xc1; \
    13  		BYTE $0x00; \
    14  		BYTE $0x00; \
    15  		BYTE $0x00; \
    16  		BYTE $0x00
    17  
    18  // func mulWW(x, y Word) (z1, z0 Word)
    19  TEXT ·mulWW(SB),7,$0
    20  	MOVQ x+0(FP), AX
    21  	MULQ y+8(FP)
    22  	MOVQ DX, z1+16(FP)
    23  	MOVQ AX, z0+24(FP)
    24  	RET
    25  
    26  
    27  // func divWW(x1, x0, y Word) (q, r Word)
    28  TEXT ·divWW(SB),7,$0
    29  	MOVQ x1+0(FP), DX
    30  	MOVQ x0+8(FP), AX
    31  	DIVQ y+16(FP)
    32  	MOVQ AX, q+24(FP)
    33  	MOVQ DX, r+32(FP)
    34  	RET
    35  
    36  
    37  // func addVV(z, x, y []Word) (c Word)
    38  TEXT ·addVV(SB),7,$0
    39  	MOVQ z_len+8(FP), DI
    40  	MOVQ x+24(FP), R8
    41  	MOVQ y+48(FP), R9
    42  	MOVQ z+0(FP), R10
    43  
    44  	MOVQ $0, CX		// c = 0
    45  	MOVQ $0, SI		// i = 0
    46  
    47  	// s/JL/JMP/ below to disable the unrolled loop
    48  	SUBQ $4, DI		// n -= 4
    49  	JL V1			// if n < 0 goto V1
    50  
    51  U1:	// n >= 0
    52  	// regular loop body unrolled 4x
    53  	RCRQ $1, CX		// CF = c
    54  	MOVQ 0(R8)(SI*8), R11
    55  	MOVQ 8(R8)(SI*8), R12
    56  	MOVQ 16(R8)(SI*8), R13
    57  	MOVQ 24(R8)(SI*8), R14
    58  	ADCQ 0(R9)(SI*8), R11
    59  	ADCQ 8(R9)(SI*8), R12
    60  	ADCQ 16(R9)(SI*8), R13
    61  	ADCQ 24(R9)(SI*8), R14
    62  	MOVQ R11, 0(R10)(SI*8)
    63  	MOVQ R12, 8(R10)(SI*8)
    64  	MOVQ R13, 16(R10)(SI*8)
    65  	MOVQ R14, 24(R10)(SI*8)
    66  	RCLQ $1, CX		// c = CF
    67  
    68  	ADDQ $4, SI		// i += 4
    69  	SUBQ $4, DI		// n -= 4
    70  	JGE U1			// if n >= 0 goto U1
    71  
    72  V1:	ADDQ $4, DI		// n += 4
    73  	JLE E1			// if n <= 0 goto E1
    74  
    75  L1:	// n > 0
    76  	RCRQ $1, CX		// CF = c
    77  	MOVQ 0(R8)(SI*8), R11
    78  	ADCQ 0(R9)(SI*8), R11
    79  	MOVQ R11, 0(R10)(SI*8)
    80  	RCLQ $1, CX		// c = CF
    81  
    82  	ADDQ $1, SI		// i++
    83  	SUBQ $1, DI		// n--
    84  	JG L1			// if n > 0 goto L1
    85  
    86  E1:	MOVQ CX, c+72(FP)	// return c
    87  	RET
    88  
    89  
    90  // func subVV(z, x, y []Word) (c Word)
    91  // (same as addVV except for SBBQ instead of ADCQ and label names)
    92  TEXT ·subVV(SB),7,$0
    93  	MOVQ z_len+8(FP), DI
    94  	MOVQ x+24(FP), R8
    95  	MOVQ y+48(FP), R9
    96  	MOVQ z+0(FP), R10
    97  
    98  	MOVQ $0, CX		// c = 0
    99  	MOVQ $0, SI		// i = 0
   100  
   101  	// s/JL/JMP/ below to disable the unrolled loop
   102  	SUBQ $4, DI		// n -= 4
   103  	JL V2			// if n < 0 goto V2
   104  
   105  U2:	// n >= 0
   106  	// regular loop body unrolled 4x
   107  	RCRQ $1, CX		// CF = c
   108  	MOVQ 0(R8)(SI*8), R11
   109  	MOVQ 8(R8)(SI*8), R12
   110  	MOVQ 16(R8)(SI*8), R13
   111  	MOVQ 24(R8)(SI*8), R14
   112  	SBBQ 0(R9)(SI*8), R11
   113  	SBBQ 8(R9)(SI*8), R12
   114  	SBBQ 16(R9)(SI*8), R13
   115  	SBBQ 24(R9)(SI*8), R14
   116  	MOVQ R11, 0(R10)(SI*8)
   117  	MOVQ R12, 8(R10)(SI*8)
   118  	MOVQ R13, 16(R10)(SI*8)
   119  	MOVQ R14, 24(R10)(SI*8)
   120  	RCLQ $1, CX		// c = CF
   121  
   122  	ADDQ $4, SI		// i += 4
   123  	SUBQ $4, DI		// n -= 4
   124  	JGE U2			// if n >= 0 goto U2
   125  
   126  V2:	ADDQ $4, DI		// n += 4
   127  	JLE E2			// if n <= 0 goto E2
   128  
   129  L2:	// n > 0
   130  	RCRQ $1, CX		// CF = c
   131  	MOVQ 0(R8)(SI*8), R11
   132  	SBBQ 0(R9)(SI*8), R11
   133  	MOVQ R11, 0(R10)(SI*8)
   134  	RCLQ $1, CX		// c = CF
   135  
   136  	ADDQ $1, SI		// i++
   137  	SUBQ $1, DI		// n--
   138  	JG L2			// if n > 0 goto L2
   139  
   140  E2:	MOVQ CX, c+72(FP)	// return c
   141  	RET
   142  
   143  
   144  // func addVW(z, x []Word, y Word) (c Word)
   145  TEXT ·addVW(SB),7,$0
   146  	MOVQ z_len+8(FP), DI
   147  	MOVQ x+24(FP), R8
   148  	MOVQ y+48(FP), CX	// c = y
   149  	MOVQ z+0(FP), R10
   150  
   151  	MOVQ $0, SI		// i = 0
   152  
   153  	// s/JL/JMP/ below to disable the unrolled loop
   154  	SUBQ $4, DI		// n -= 4
   155  	JL V3			// if n < 4 goto V3
   156  
   157  U3:	// n >= 0
   158  	// regular loop body unrolled 4x
   159  	MOVQ 0(R8)(SI*8), R11
   160  	MOVQ 8(R8)(SI*8), R12
   161  	MOVQ 16(R8)(SI*8), R13
   162  	MOVQ 24(R8)(SI*8), R14
   163  	ADDQ CX, R11
   164  	ZERO_CX
   165  	ADCQ $0, R12
   166  	ADCQ $0, R13
   167  	ADCQ $0, R14
   168  	SETCS CX		// c = CF
   169  	MOVQ R11, 0(R10)(SI*8)
   170  	MOVQ R12, 8(R10)(SI*8)
   171  	MOVQ R13, 16(R10)(SI*8)
   172  	MOVQ R14, 24(R10)(SI*8)
   173  
   174  	ADDQ $4, SI		// i += 4
   175  	SUBQ $4, DI		// n -= 4
   176  	JGE U3			// if n >= 0 goto U3
   177  
   178  V3:	ADDQ $4, DI		// n += 4
   179  	JLE E3			// if n <= 0 goto E3
   180  
   181  L3:	// n > 0
   182  	ADDQ 0(R8)(SI*8), CX
   183  	MOVQ CX, 0(R10)(SI*8)
   184  	ZERO_CX
   185  	RCLQ $1, CX		// c = CF
   186  
   187  	ADDQ $1, SI		// i++
   188  	SUBQ $1, DI		// n--
   189  	JG L3			// if n > 0 goto L3
   190  
   191  E3:	MOVQ CX, c+56(FP)	// return c
   192  	RET
   193  
   194  
   195  // func subVW(z, x []Word, y Word) (c Word)
   196  // (same as addVW except for SUBQ/SBBQ instead of ADDQ/ADCQ and label names)
   197  TEXT ·subVW(SB),7,$0
   198  	MOVQ z_len+8(FP), DI
   199  	MOVQ x+24(FP), R8
   200  	MOVQ y+48(FP), CX	// c = y
   201  	MOVQ z+0(FP), R10
   202  	
   203  	MOVQ $0, SI		// i = 0
   204  
   205  	// s/JL/JMP/ below to disable the unrolled loop
   206  	SUBQ $4, DI		// n -= 4
   207  	JL V4			// if n < 4 goto V4
   208  
   209  U4:	// n >= 0
   210  	// regular loop body unrolled 4x
   211  	MOVQ 0(R8)(SI*8), R11
   212  	MOVQ 8(R8)(SI*8), R12
   213  	MOVQ 16(R8)(SI*8), R13
   214  	MOVQ 24(R8)(SI*8), R14
   215  	SUBQ CX, R11
   216  	ZERO_CX
   217  	SBBQ $0, R12
   218  	SBBQ $0, R13
   219  	SBBQ $0, R14
   220  	SETCS CX		// c = CF
   221  	MOVQ R11, 0(R10)(SI*8)
   222  	MOVQ R12, 8(R10)(SI*8)
   223  	MOVQ R13, 16(R10)(SI*8)
   224  	MOVQ R14, 24(R10)(SI*8)
   225  
   226  	ADDQ $4, SI		// i += 4
   227  	SUBQ $4, DI		// n -= 4
   228  	JGE U4			// if n >= 0 goto U4
   229  
   230  V4:	ADDQ $4, DI		// n += 4
   231  	JLE E4			// if n <= 0 goto E4
   232  
   233  L4:	// n > 0
   234  	MOVQ 0(R8)(SI*8), R11
   235  	SUBQ CX, R11
   236  	MOVQ R11, 0(R10)(SI*8)
   237  	ZERO_CX
   238  	RCLQ $1, CX		// c = CF
   239  
   240  	ADDQ $1, SI		// i++
   241  	SUBQ $1, DI		// n--
   242  	JG L4			// if n > 0 goto L4
   243  
   244  E4:	MOVQ CX, c+56(FP)	// return c
   245  	RET
   246  
   247  
   248  // func shlVU(z, x []Word, s uint) (c Word)
   249  TEXT ·shlVU(SB),7,$0
   250  	MOVQ z_len+8(FP), BX	// i = z
   251  	SUBQ $1, BX		// i--
   252  	JL X8b			// i < 0	(n <= 0)
   253  
   254  	// n > 0
   255  	MOVQ z+0(FP), R10
   256  	MOVQ x+24(FP), R8
   257  	MOVQ s+48(FP), CX
   258  	MOVQ (R8)(BX*8), AX	// w1 = x[n-1]
   259  	MOVQ $0, DX
   260  	SHLQ CX, DX:AX		// w1>>ŝ
   261  	MOVQ DX, c+56(FP)
   262  
   263  	CMPQ BX, $0
   264  	JLE X8a			// i <= 0
   265  
   266  	// i > 0
   267  L8:	MOVQ AX, DX		// w = w1
   268  	MOVQ -8(R8)(BX*8), AX	// w1 = x[i-1]
   269  	SHLQ CX, DX:AX		// w<<s | w1>>ŝ
   270  	MOVQ DX, (R10)(BX*8)	// z[i] = w<<s | w1>>ŝ
   271  	SUBQ $1, BX		// i--
   272  	JG L8			// i > 0
   273  
   274  	// i <= 0
   275  X8a:	SHLQ CX, AX		// w1<<s
   276  	MOVQ AX, (R10)		// z[0] = w1<<s
   277  	RET
   278  
   279  X8b:	MOVQ $0, c+56(FP)
   280  	RET
   281  
   282  
   283  // func shrVU(z, x []Word, s uint) (c Word)
   284  TEXT ·shrVU(SB),7,$0
   285  	MOVQ z_len+8(FP), R11
   286  	SUBQ $1, R11		// n--
   287  	JL X9b			// n < 0	(n <= 0)
   288  
   289  	// n > 0
   290  	MOVQ z+0(FP), R10
   291  	MOVQ x+24(FP), R8
   292  	MOVQ s+48(FP), CX
   293  	MOVQ (R8), AX		// w1 = x[0]
   294  	MOVQ $0, DX
   295  	SHRQ CX, DX:AX		// w1<<ŝ
   296  	MOVQ DX, c+56(FP)
   297  
   298  	MOVQ $0, BX		// i = 0
   299  	JMP E9
   300  
   301  	// i < n-1
   302  L9:	MOVQ AX, DX		// w = w1
   303  	MOVQ 8(R8)(BX*8), AX	// w1 = x[i+1]
   304  	SHRQ CX, DX:AX		// w>>s | w1<<ŝ
   305  	MOVQ DX, (R10)(BX*8)	// z[i] = w>>s | w1<<ŝ
   306  	ADDQ $1, BX		// i++
   307  	
   308  E9:	CMPQ BX, R11
   309  	JL L9			// i < n-1
   310  
   311  	// i >= n-1
   312  X9a:	SHRQ CX, AX		// w1>>s
   313  	MOVQ AX, (R10)(R11*8)	// z[n-1] = w1>>s
   314  	RET
   315  
   316  X9b:	MOVQ $0, c+56(FP)
   317  	RET
   318  
   319  
   320  // func mulAddVWW(z, x []Word, y, r Word) (c Word)
   321  TEXT ·mulAddVWW(SB),7,$0
   322  	MOVQ z+0(FP), R10
   323  	MOVQ x+24(FP), R8
   324  	MOVQ y+48(FP), R9
   325  	MOVQ r+56(FP), CX	// c = r
   326  	MOVQ z_len+8(FP), R11
   327  	MOVQ $0, BX		// i = 0
   328  	JMP E5
   329  
   330  L5:	MOVQ (R8)(BX*8), AX
   331  	MULQ R9
   332  	ADDQ CX, AX
   333  	ADCQ $0, DX
   334  	MOVQ AX, (R10)(BX*8)
   335  	MOVQ DX, CX
   336  	ADDQ $1, BX		// i++
   337  
   338  E5:	CMPQ BX, R11		// i < n
   339  	JL L5
   340  
   341  	MOVQ CX, c+64(FP)
   342  	RET
   343  
   344  
   345  // func addMulVVW(z, x []Word, y Word) (c Word)
   346  TEXT ·addMulVVW(SB),7,$0
   347  	MOVQ z+0(FP), R10
   348  	MOVQ x+24(FP), R8
   349  	MOVQ y+48(FP), R9
   350  	MOVQ z_len+8(FP), R11
   351  	MOVQ $0, BX		// i = 0
   352  	MOVQ $0, CX		// c = 0
   353  	JMP E6
   354  
   355  L6:	MOVQ (R8)(BX*8), AX
   356  	MULQ R9
   357  	ADDQ CX, AX
   358  	ADCQ $0, DX
   359  	ADDQ AX, (R10)(BX*8)
   360  	ADCQ $0, DX
   361  	MOVQ DX, CX
   362  	ADDQ $1, BX		// i++
   363  
   364  E6:	CMPQ BX, R11		// i < n
   365  	JL L6
   366  
   367  	MOVQ CX, c+56(FP)
   368  	RET
   369  
   370  
   371  // func divWVW(z []Word, xn Word, x []Word, y Word) (r Word)
   372  TEXT ·divWVW(SB),7,$0
   373  	MOVQ z+0(FP), R10
   374  	MOVQ xn+24(FP), DX	// r = xn
   375  	MOVQ x+32(FP), R8
   376  	MOVQ y+56(FP), R9
   377  	MOVQ z_len+8(FP), BX	// i = z
   378  	JMP E7
   379  
   380  L7:	MOVQ (R8)(BX*8), AX
   381  	DIVQ R9
   382  	MOVQ AX, (R10)(BX*8)
   383  
   384  E7:	SUBQ $1, BX		// i--
   385  	JGE L7			// i >= 0
   386  
   387  	MOVQ DX, r+64(FP)
   388  	RET
   389  
   390  // func bitLen(x Word) (n int)
   391  TEXT ·bitLen(SB),7,$0
   392  	BSRQ x+0(FP), AX
   393  	JZ Z1
   394  	ADDQ $1, AX
   395  	MOVQ AX, n+8(FP)
   396  	RET
   397  
   398  Z1:	MOVQ $0, n+8(FP)
   399  	RET