github.com/snowblossomcoin/go-ethereum@v1.9.25/crypto/bls12381/arithmetic_x86.s (about)

     1  // +build amd64,blsasm amd64,blsadx
     2  
     3  #include "textflag.h"
     4  
     5  // addition w/ modular reduction
     6  // a = (a + b) % p
     7  TEXT ·addAssign(SB), NOSPLIT, $0-16
     8  	// |
     9  	MOVQ a+0(FP), DI
    10  	MOVQ b+8(FP), SI
    11  
    12  	// |
    13  	MOVQ (DI), R8
    14  	MOVQ 8(DI), R9
    15  	MOVQ 16(DI), R10
    16  	MOVQ 24(DI), R11
    17  	MOVQ 32(DI), R12
    18  	MOVQ 40(DI), R13
    19  
    20  	// |
    21  	ADDQ (SI), R8
    22  	ADCQ 8(SI), R9
    23  	ADCQ 16(SI), R10
    24  	ADCQ 24(SI), R11
    25  	ADCQ 32(SI), R12
    26  	ADCQ 40(SI), R13
    27  
    28  	// |
    29  	MOVQ R8, R14
    30  	MOVQ R9, R15
    31  	MOVQ R10, CX
    32  	MOVQ R11, DX
    33  	MOVQ R12, SI
    34  	MOVQ R13, BX
    35  	MOVQ $0xb9feffffffffaaab, AX
    36  	SUBQ AX, R14
    37  	MOVQ $0x1eabfffeb153ffff, AX
    38  	SBBQ AX, R15
    39  	MOVQ $0x6730d2a0f6b0f624, AX
    40  	SBBQ AX, CX
    41  	MOVQ $0x64774b84f38512bf, AX
    42  	SBBQ AX, DX
    43  	MOVQ $0x4b1ba7b6434bacd7, AX
    44  	SBBQ AX, SI
    45  	MOVQ $0x1a0111ea397fe69a, AX
    46  	SBBQ AX, BX
    47  	CMOVQCC R14, R8
    48  	CMOVQCC R15, R9
    49  	CMOVQCC CX, R10
    50  	CMOVQCC DX, R11
    51  	CMOVQCC SI, R12
    52  	CMOVQCC BX, R13
    53  
    54  	// |
    55  	MOVQ R8, (DI)
    56  	MOVQ R9, 8(DI)
    57  	MOVQ R10, 16(DI)
    58  	MOVQ R11, 24(DI)
    59  	MOVQ R12, 32(DI)
    60  	MOVQ R13, 40(DI)
    61  	RET
    62  
    63  /*	 | end											*/
    64  
    65  
    66  // addition w/ modular reduction
    67  // c = (a + b) % p
    68  TEXT ·add(SB), NOSPLIT, $0-24
    69  	// |
    70  	MOVQ a+8(FP), DI
    71  	MOVQ b+16(FP), SI
    72  
    73  	// |
    74  	MOVQ (DI), R8
    75  	MOVQ 8(DI), R9
    76  	MOVQ 16(DI), R10
    77  	MOVQ 24(DI), R11
    78  	MOVQ 32(DI), R12
    79  	MOVQ 40(DI), R13
    80  
    81  	// |
    82  	ADDQ (SI), R8
    83  	ADCQ 8(SI), R9
    84  	ADCQ 16(SI), R10
    85  	ADCQ 24(SI), R11
    86  	ADCQ 32(SI), R12
    87  	ADCQ 40(SI), R13
    88  
    89  	// |
    90  	MOVQ R8, R14
    91  	MOVQ R9, R15
    92  	MOVQ R10, CX
    93  	MOVQ R11, DX
    94  	MOVQ R12, SI
    95  	MOVQ R13, BX
    96  	MOVQ $0xb9feffffffffaaab, DI
    97  	SUBQ DI, R14
    98  	MOVQ $0x1eabfffeb153ffff, DI
    99  	SBBQ DI, R15
   100  	MOVQ $0x6730d2a0f6b0f624, DI
   101  	SBBQ DI, CX
   102  	MOVQ $0x64774b84f38512bf, DI
   103  	SBBQ DI, DX
   104  	MOVQ $0x4b1ba7b6434bacd7, DI
   105  	SBBQ DI, SI
   106  	MOVQ $0x1a0111ea397fe69a, DI
   107  	SBBQ DI, BX
   108  	CMOVQCC R14, R8
   109  	CMOVQCC R15, R9
   110  	CMOVQCC CX, R10
   111  	CMOVQCC DX, R11
   112  	CMOVQCC SI, R12
   113  	CMOVQCC BX, R13
   114  
   115  	// |
   116  	MOVQ c+0(FP), DI
   117  	MOVQ R8, (DI)
   118  	MOVQ R9, 8(DI)
   119  	MOVQ R10, 16(DI)
   120  	MOVQ R11, 24(DI)
   121  	MOVQ R12, 32(DI)
   122  	MOVQ R13, 40(DI)
   123  	RET
   124  /*	 | end													*/
   125  
   126  
   127  // addition w/o reduction check
   128  // c = (a + b)
   129  TEXT ·ladd(SB), NOSPLIT, $0-24
   130  	// |
   131  	MOVQ a+8(FP), DI
   132  	MOVQ b+16(FP), SI
   133  
   134  	// |
   135  	MOVQ (DI), R8
   136  	MOVQ 8(DI), R9
   137  	MOVQ 16(DI), R10
   138  	MOVQ 24(DI), R11
   139  	MOVQ 32(DI), R12
   140  	MOVQ 40(DI), R13
   141  
   142  	// |
   143  	ADDQ (SI), R8
   144  	ADCQ 8(SI), R9
   145  	ADCQ 16(SI), R10
   146  	ADCQ 24(SI), R11
   147  	ADCQ 32(SI), R12
   148  	ADCQ 40(SI), R13
   149  
   150  	// |
   151  	MOVQ c+0(FP), DI
   152  	MOVQ R8, (DI)
   153  	MOVQ R9, 8(DI)
   154  	MOVQ R10, 16(DI)
   155  	MOVQ R11, 24(DI)
   156  	MOVQ R12, 32(DI)
   157  	MOVQ R13, 40(DI)
   158  	RET
   159  /*	 | end													*/
   160  
   161  
   162  // addition w/o reduction check
   163  // a = a + b
   164  TEXT ·laddAssign(SB), NOSPLIT, $0-16
   165  	// |
   166  	MOVQ a+0(FP), DI
   167  	MOVQ b+8(FP), SI
   168  
   169  	// |
   170  	MOVQ (DI), R8
   171  	MOVQ 8(DI), R9
   172  	MOVQ 16(DI), R10
   173  	MOVQ 24(DI), R11
   174  	MOVQ 32(DI), R12
   175  	MOVQ 40(DI), R13
   176  
   177  	// |
   178  	ADDQ (SI), R8
   179  	ADCQ 8(SI), R9
   180  	ADCQ 16(SI), R10
   181  	ADCQ 24(SI), R11
   182  	ADCQ 32(SI), R12
   183  	ADCQ 40(SI), R13
   184  
   185  	// |
   186  	MOVQ a+0(FP), DI
   187  	MOVQ R8, (DI)
   188  	MOVQ R9, 8(DI)
   189  	MOVQ R10, 16(DI)
   190  	MOVQ R11, 24(DI)
   191  	MOVQ R12, 32(DI)
   192  	MOVQ R13, 40(DI)
   193  	RET
   194  /*	 | end													*/
   195  
   196  
   197  // subtraction w/ modular reduction
   198  // c = (a - b) % p
   199  TEXT ·sub(SB), NOSPLIT, $0-24
   200  	// |
   201  	MOVQ a+8(FP), DI
   202  	MOVQ b+16(FP), SI
   203  	XORQ AX, AX
   204  
   205  	// |
   206  	MOVQ (DI), R8
   207  	MOVQ 8(DI), R9
   208  	MOVQ 16(DI), R10
   209  	MOVQ 24(DI), R11
   210  	MOVQ 32(DI), R12
   211  	MOVQ 40(DI), R13
   212  	SUBQ (SI), R8
   213  	SBBQ 8(SI), R9
   214  	SBBQ 16(SI), R10
   215  	SBBQ 24(SI), R11
   216  	SBBQ 32(SI), R12
   217  	SBBQ 40(SI), R13
   218  
   219  	// |
   220  	MOVQ $0xb9feffffffffaaab, R14
   221  	MOVQ $0x1eabfffeb153ffff, R15
   222  	MOVQ $0x6730d2a0f6b0f624, CX
   223  	MOVQ $0x64774b84f38512bf, DX
   224  	MOVQ $0x4b1ba7b6434bacd7, SI
   225  	MOVQ $0x1a0111ea397fe69a, BX
   226  	CMOVQCC AX, R14
   227  	CMOVQCC AX, R15
   228  	CMOVQCC AX, CX
   229  	CMOVQCC AX, DX
   230  	CMOVQCC AX, SI
   231  	CMOVQCC AX, BX
   232  	ADDQ R14, R8
   233  	ADCQ R15, R9
   234  	ADCQ CX, R10
   235  	ADCQ DX, R11
   236  	ADCQ SI, R12
   237  	ADCQ BX, R13
   238  
   239  	// |
   240  	MOVQ c+0(FP), DI
   241  	MOVQ R8, (DI)
   242  	MOVQ R9, 8(DI)
   243  	MOVQ R10, 16(DI)
   244  	MOVQ R11, 24(DI)
   245  	MOVQ R12, 32(DI)
   246  	MOVQ R13, 40(DI)
   247  	RET
   248  /*	 | end													*/
   249  
   250  
   251  // subtraction w/ modular reduction
   252  // a = (a - b) % p
   253  TEXT ·subAssign(SB), NOSPLIT, $0-16
   254  	// |
   255  	MOVQ a+0(FP), DI
   256  	MOVQ b+8(FP), SI
   257  	XORQ AX, AX
   258  
   259  	// |
   260  	MOVQ (DI), R8
   261  	MOVQ 8(DI), R9
   262  	MOVQ 16(DI), R10
   263  	MOVQ 24(DI), R11
   264  	MOVQ 32(DI), R12
   265  	MOVQ 40(DI), R13
   266  	SUBQ (SI), R8
   267  	SBBQ 8(SI), R9
   268  	SBBQ 16(SI), R10
   269  	SBBQ 24(SI), R11
   270  	SBBQ 32(SI), R12
   271  	SBBQ 40(SI), R13
   272  
   273  	// |
   274  	MOVQ $0xb9feffffffffaaab, R14
   275  	MOVQ $0x1eabfffeb153ffff, R15
   276  	MOVQ $0x6730d2a0f6b0f624, CX
   277  	MOVQ $0x64774b84f38512bf, DX
   278  	MOVQ $0x4b1ba7b6434bacd7, SI
   279  	MOVQ $0x1a0111ea397fe69a, BX
   280  	CMOVQCC AX, R14
   281  	CMOVQCC AX, R15
   282  	CMOVQCC AX, CX
   283  	CMOVQCC AX, DX
   284  	CMOVQCC AX, SI
   285  	CMOVQCC AX, BX
   286  	ADDQ R14, R8
   287  	ADCQ R15, R9
   288  	ADCQ CX, R10
   289  	ADCQ DX, R11
   290  	ADCQ SI, R12
   291  	ADCQ BX, R13
   292  
   293  	// |
   294  	MOVQ a+0(FP), DI
   295  	MOVQ R8, (DI)
   296  	MOVQ R9, 8(DI)
   297  	MOVQ R10, 16(DI)
   298  	MOVQ R11, 24(DI)
   299  	MOVQ R12, 32(DI)
   300  	MOVQ R13, 40(DI)
   301  	RET
   302  /*	 | end													*/
   303  
   304  
   305  // subtraction w/o reduction check
   306  // a = (a - b)
   307  TEXT ·lsubAssign(SB), NOSPLIT, $0-16
   308  	// |
   309  	MOVQ a+0(FP), DI
   310  	MOVQ b+8(FP), SI
   311  
   312  	// |
   313  	MOVQ (DI), R8
   314  	MOVQ 8(DI), R9
   315  	MOVQ 16(DI), R10
   316  	MOVQ 24(DI), R11
   317  	MOVQ 32(DI), R12
   318  	MOVQ 40(DI), R13
   319  	SUBQ (SI), R8
   320  	SBBQ 8(SI), R9
   321  	SBBQ 16(SI), R10
   322  	SBBQ 24(SI), R11
   323  	SBBQ 32(SI), R12
   324  	SBBQ 40(SI), R13
   325  	
   326  	// |
   327  	MOVQ a+0(FP), DI
   328  	MOVQ R8, (DI)
   329  	MOVQ R9, 8(DI)
   330  	MOVQ R10, 16(DI)
   331  	MOVQ R11, 24(DI)
   332  	MOVQ R12, 32(DI)
   333  	MOVQ R13, 40(DI)
   334  	RET
   335  /*	 | end													*/
   336  
   337  // doubling w/ reduction
   338  // c = (2 * a) % p
   339  TEXT ·double(SB), NOSPLIT, $0-16
   340  	// |
   341  	MOVQ a+8(FP), DI
   342  
   343  	MOVQ (DI), R8
   344  	MOVQ 8(DI), R9
   345  	MOVQ 16(DI), R10
   346  	MOVQ 24(DI), R11
   347  	MOVQ 32(DI), R12
   348  	MOVQ 40(DI), R13
   349  	ADDQ R8, R8
   350  	ADCQ R9, R9
   351  	ADCQ R10, R10
   352  	ADCQ R11, R11
   353  	ADCQ R12, R12
   354  	ADCQ R13, R13
   355  
   356  	// |
   357  	MOVQ R8, R14
   358  	MOVQ R9, R15
   359  	MOVQ R10, CX
   360  	MOVQ R11, DX
   361  	MOVQ R12, SI
   362  	MOVQ R13, BX
   363  	MOVQ $0xb9feffffffffaaab, DI
   364  	SUBQ DI, R14
   365  	MOVQ $0x1eabfffeb153ffff, DI
   366  	SBBQ DI, R15
   367  	MOVQ $0x6730d2a0f6b0f624, DI
   368  	SBBQ DI, CX
   369  	MOVQ $0x64774b84f38512bf, DI
   370  	SBBQ DI, DX
   371  	MOVQ $0x4b1ba7b6434bacd7, DI
   372  	SBBQ DI, SI
   373  	MOVQ $0x1a0111ea397fe69a, DI
   374  	SBBQ DI, BX
   375  	CMOVQCC R14, R8
   376  	CMOVQCC R15, R9
   377  	CMOVQCC CX, R10
   378  	CMOVQCC DX, R11
   379  	CMOVQCC SI, R12
   380  	CMOVQCC BX, R13
   381  
   382  	// |
   383  	MOVQ c+0(FP), DI
   384  	MOVQ R8, (DI)
   385  	MOVQ R9, 8(DI)
   386  	MOVQ R10, 16(DI)
   387  	MOVQ R11, 24(DI)
   388  	MOVQ R12, 32(DI)
   389  	MOVQ R13, 40(DI)
   390  	RET
   391  /*	 | end													*/
   392  
   393  
   394  // doubling w/ reduction
   395  // a = (2 * a) % p
   396  TEXT ·doubleAssign(SB), NOSPLIT, $0-8
   397  	// |
   398  	MOVQ a+0(FP), DI
   399  
   400  	MOVQ (DI), R8
   401  	MOVQ 8(DI), R9
   402  	MOVQ 16(DI), R10
   403  	MOVQ 24(DI), R11
   404  	MOVQ 32(DI), R12
   405  	MOVQ 40(DI), R13
   406  	ADDQ R8, R8
   407  	ADCQ R9, R9
   408  	ADCQ R10, R10
   409  	ADCQ R11, R11
   410  	ADCQ R12, R12
   411  	ADCQ R13, R13
   412  
   413  	// |
   414  	MOVQ R8, R14
   415  	MOVQ R9, R15
   416  	MOVQ R10, CX
   417  	MOVQ R11, DX
   418  	MOVQ R12, SI
   419  	MOVQ R13, BX
   420  	MOVQ $0xb9feffffffffaaab, AX
   421  	SUBQ AX, R14
   422  	MOVQ $0x1eabfffeb153ffff, AX
   423  	SBBQ AX, R15
   424  	MOVQ $0x6730d2a0f6b0f624, AX
   425  	SBBQ AX, CX
   426  	MOVQ $0x64774b84f38512bf, AX
   427  	SBBQ AX, DX
   428  	MOVQ $0x4b1ba7b6434bacd7, AX
   429  	SBBQ AX, SI
   430  	MOVQ $0x1a0111ea397fe69a, AX
   431  	SBBQ AX, BX
   432  	CMOVQCC R14, R8
   433  	CMOVQCC R15, R9
   434  	CMOVQCC CX, R10
   435  	CMOVQCC DX, R11
   436  	CMOVQCC SI, R12
   437  	CMOVQCC BX, R13
   438  
   439  	MOVQ R8, (DI)
   440  	MOVQ R9, 8(DI)
   441  	MOVQ R10, 16(DI)
   442  	MOVQ R11, 24(DI)
   443  	MOVQ R12, 32(DI)
   444  	MOVQ R13, 40(DI)
   445  	RET
   446  /*	 | end													*/
   447  
   448  
   449  // doubling w/o reduction
   450  // c = 2 * a
   451  TEXT ·ldouble(SB), NOSPLIT, $0-16
   452  	// |
   453  	MOVQ a+8(FP), DI
   454  
   455  	MOVQ (DI), R8
   456  	MOVQ 8(DI), R9
   457  	MOVQ 16(DI), R10
   458  	MOVQ 24(DI), R11
   459  	MOVQ 32(DI), R12
   460  	MOVQ 40(DI), R13
   461  
   462  	// |
   463  	ADDQ R8, R8
   464  	ADCQ R9, R9
   465  	ADCQ R10, R10
   466  	ADCQ R11, R11
   467  	ADCQ R12, R12
   468  	ADCQ R13, R13
   469  
   470  	// |
   471  	MOVQ c+0(FP), DI
   472  	MOVQ R8, (DI)
   473  	MOVQ R9, 8(DI)
   474  	MOVQ R10, 16(DI)
   475  	MOVQ R11, 24(DI)
   476  	MOVQ R12, 32(DI)
   477  	MOVQ R13, 40(DI)
   478  
   479  	RET
   480  /*	 | end													*/
   481  
   482  
   483  TEXT ·_neg(SB), NOSPLIT, $0-16
   484  	// |
   485  	MOVQ a+8(FP), DI
   486  
   487  	// |
   488  	MOVQ $0xb9feffffffffaaab, R8
   489  	MOVQ $0x1eabfffeb153ffff, R9
   490  	MOVQ $0x6730d2a0f6b0f624, R10
   491  	MOVQ $0x64774b84f38512bf, R11
   492  	MOVQ $0x4b1ba7b6434bacd7, R12
   493  	MOVQ $0x1a0111ea397fe69a, R13
   494  	SUBQ (DI), R8
   495  	SBBQ 8(DI), R9
   496  	SBBQ 16(DI), R10
   497  	SBBQ 24(DI), R11
   498  	SBBQ 32(DI), R12
   499  	SBBQ 40(DI), R13
   500  
   501  	// |
   502  	MOVQ c+0(FP), DI
   503  	MOVQ R8, (DI)
   504  	MOVQ R9, 8(DI)
   505  	MOVQ R10, 16(DI)
   506  	MOVQ R11, 24(DI)
   507  	MOVQ R12, 32(DI)
   508  	MOVQ R13, 40(DI)
   509  	RET
   510  /*	 | end													*/
   511  
   512  
   513  // multiplication without using MULX/ADX
   514  // c = a * b % p
   515  TEXT ·mulNoADX(SB), NOSPLIT, $24-24
   516  	// |
   517  
   518  /* inputs                                  */
   519  
   520  	MOVQ a+8(FP), DI
   521  	MOVQ b+16(FP), SI
   522  	MOVQ $0x00, R9
   523  	MOVQ $0x00, R10
   524  	MOVQ $0x00, R11
   525  	MOVQ $0x00, R12
   526  	MOVQ $0x00, R13
   527  	MOVQ $0x00, R14
   528  	MOVQ $0x00, R15
   529  
   530  	// |
   531  
   532  /* i0                                   */
   533  
   534  	// | a0 @ CX
   535  	MOVQ (DI), CX
   536  
   537  	// | a0 * b0
   538  	MOVQ (SI), AX
   539  	MULQ CX
   540  	MOVQ AX, (SP)
   541  	MOVQ DX, R8
   542  
   543  	// | a0 * b1
   544  	MOVQ 8(SI), AX
   545  	MULQ CX
   546  	ADDQ AX, R8
   547  	ADCQ DX, R9
   548  
   549  	// | a0 * b2
   550  	MOVQ 16(SI), AX
   551  	MULQ CX
   552  	ADDQ AX, R9
   553  	ADCQ DX, R10
   554  
   555  	// | a0 * b3
   556  	MOVQ 24(SI), AX
   557  	MULQ CX
   558  	ADDQ AX, R10
   559  	ADCQ DX, R11
   560  
   561  	// | a0 * b4
   562  	MOVQ 32(SI), AX
   563  	MULQ CX
   564  	ADDQ AX, R11
   565  	ADCQ DX, R12
   566  
   567  	// | a0 * b5
   568  	MOVQ 40(SI), AX
   569  	MULQ CX
   570  	ADDQ AX, R12
   571  	ADCQ DX, R13
   572  
   573  	// |
   574  
   575  /* i1                                   */
   576  
   577  	// | a1 @ CX
   578  	MOVQ 8(DI), CX
   579  	MOVQ $0x00, BX
   580  
   581  	// | a1 * b0
   582  	MOVQ (SI), AX
   583  	MULQ CX
   584  	ADDQ AX, R8
   585  	ADCQ DX, R9
   586  	ADCQ $0x00, R10
   587  	ADCQ $0x00, BX
   588  	MOVQ R8, 8(SP)
   589  	MOVQ $0x00, R8
   590  
   591  	// | a1 * b1
   592  	MOVQ 8(SI), AX
   593  	MULQ CX
   594  	ADDQ AX, R9
   595  	ADCQ DX, R10
   596  	ADCQ BX, R11
   597  	MOVQ $0x00, BX
   598  	ADCQ $0x00, BX
   599  
   600  	// | a1 * b2
   601  	MOVQ 16(SI), AX
   602  	MULQ CX
   603  	ADDQ AX, R10
   604  	ADCQ DX, R11
   605  	ADCQ BX, R12
   606  	MOVQ $0x00, BX
   607  	ADCQ $0x00, BX
   608  
   609  	// | a1 * b3
   610  	MOVQ 24(SI), AX
   611  	MULQ CX
   612  	ADDQ AX, R11
   613  	ADCQ DX, R12
   614  	ADCQ BX, R13
   615  	MOVQ $0x00, BX
   616  	ADCQ $0x00, BX
   617  
   618  	// | a1 * b4
   619  	MOVQ 32(SI), AX
   620  	MULQ CX
   621  	ADDQ AX, R12
   622  	ADCQ DX, R13
   623  	ADCQ BX, R14
   624  
   625  	// | a1 * b5
   626  	MOVQ 40(SI), AX
   627  	MULQ CX
   628  	ADDQ AX, R13
   629  	ADCQ DX, R14
   630  
   631  	// |
   632  
   633  /* i2                                   */
   634  
   635  	// | a2 @ CX
   636  	MOVQ 16(DI), CX
   637  	MOVQ $0x00, BX
   638  
   639  	// | a2 * b0
   640  	MOVQ (SI), AX
   641  	MULQ CX
   642  	ADDQ AX, R9
   643  	ADCQ DX, R10
   644  	ADCQ $0x00, R11
   645  	ADCQ $0x00, BX
   646  	MOVQ R9, 16(SP)
   647  	MOVQ $0x00, R9
   648  
   649  	// | a2 * b1
   650  	MOVQ 8(SI), AX
   651  	MULQ CX
   652  	ADDQ AX, R10
   653  	ADCQ DX, R11
   654  	ADCQ BX, R12
   655  	MOVQ $0x00, BX
   656  	ADCQ $0x00, BX
   657  
   658  	// | a2 * b2
   659  	MOVQ 16(SI), AX
   660  	MULQ CX
   661  	ADDQ AX, R11
   662  	ADCQ DX, R12
   663  	ADCQ BX, R13
   664  	MOVQ $0x00, BX
   665  	ADCQ $0x00, BX
   666  
   667  	// | a2 * b3
   668  	MOVQ 24(SI), AX
   669  	MULQ CX
   670  	ADDQ AX, R12
   671  	ADCQ DX, R13
   672  	ADCQ BX, R14
   673  	MOVQ $0x00, BX
   674  	ADCQ $0x00, BX
   675  
   676  	// | a2 * b4
   677  	MOVQ 32(SI), AX
   678  	MULQ CX
   679  	ADDQ AX, R13
   680  	ADCQ DX, R14
   681  	ADCQ BX, R15
   682  
   683  	// | a2 * b5
   684  	MOVQ 40(SI), AX
   685  	MULQ CX
   686  	ADDQ AX, R14
   687  	ADCQ DX, R15
   688  
   689  	// |
   690  
   691  /* i3                                   */
   692  
   693  	// | a3 @ CX
   694  	MOVQ 24(DI), CX
   695  	MOVQ $0x00, BX
   696  
   697  	// | a3 * b0
   698  	MOVQ (SI), AX
   699  	MULQ CX
   700  	ADDQ AX, R10
   701  	ADCQ DX, R11
   702  	ADCQ $0x00, R12
   703  	ADCQ $0x00, BX
   704  
   705  	// | a3 * b1
   706  	MOVQ 8(SI), AX
   707  	MULQ CX
   708  	ADDQ AX, R11
   709  	ADCQ DX, R12
   710  	ADCQ BX, R13
   711  	MOVQ $0x00, BX
   712  	ADCQ $0x00, BX
   713  
   714  	// | a3 * b2
   715  	MOVQ 16(SI), AX
   716  	MULQ CX
   717  	ADDQ AX, R12
   718  	ADCQ DX, R13
   719  	ADCQ BX, R14
   720  	MOVQ $0x00, BX
   721  	ADCQ $0x00, BX
   722  
   723  	// | a3 * b3
   724  	MOVQ 24(SI), AX
   725  	MULQ CX
   726  	ADDQ AX, R13
   727  	ADCQ DX, R14
   728  	ADCQ BX, R15
   729  	MOVQ $0x00, BX
   730  	ADCQ $0x00, BX
   731  
   732  	// | a3 * b4
   733  	MOVQ 32(SI), AX
   734  	MULQ CX
   735  	ADDQ AX, R14
   736  	ADCQ DX, R15
   737  	ADCQ BX, R8
   738  
   739  	// | a3 * b5
   740  	MOVQ 40(SI), AX
   741  	MULQ CX
   742  	ADDQ AX, R15
   743  	ADCQ DX, R8
   744  
   745  	// |
   746  
   747  /* i4                                   */
   748  
   749  	// | a4 @ CX
   750  	MOVQ 32(DI), CX
   751  	MOVQ $0x00, BX
   752  
   753  	// | a4 * b0
   754  	MOVQ (SI), AX
   755  	MULQ CX
   756  	ADDQ AX, R11
   757  	ADCQ DX, R12
   758  	ADCQ $0x00, R13
   759  	ADCQ $0x00, BX
   760  
   761  	// | a4 * b1
   762  	MOVQ 8(SI), AX
   763  	MULQ CX
   764  	ADDQ AX, R12
   765  	ADCQ DX, R13
   766  	ADCQ BX, R14
   767  	MOVQ $0x00, BX
   768  	ADCQ $0x00, BX
   769  
   770  	// | a4 * b2
   771  	MOVQ 16(SI), AX
   772  	MULQ CX
   773  	ADDQ AX, R13
   774  	ADCQ DX, R14
   775  	ADCQ BX, R15
   776  	MOVQ $0x00, BX
   777  	ADCQ $0x00, BX
   778  
   779  	// | a4 * b3
   780  	MOVQ 24(SI), AX
   781  	MULQ CX
   782  	ADDQ AX, R14
   783  	ADCQ DX, R15
   784  	ADCQ BX, R8
   785  	MOVQ $0x00, BX
   786  	ADCQ $0x00, BX
   787  
   788  	// | a4 * b4
   789  	MOVQ 32(SI), AX
   790  	MULQ CX
   791  	ADDQ AX, R15
   792  	ADCQ DX, R8
   793  	ADCQ BX, R9
   794  
   795  	// | a4 * b5
   796  	MOVQ 40(SI), AX
   797  	MULQ CX
   798  	ADDQ AX, R8
   799  	ADCQ DX, R9
   800  
   801  	// |
   802  
   803  /* i5                                   */
   804  
   805  	// | a5 @ CX
   806  	MOVQ 40(DI), CX
   807  	MOVQ $0x00, BX
   808  
   809  	// | a5 * b0
   810  	MOVQ (SI), AX
   811  	MULQ CX
   812  	ADDQ AX, R12
   813  	ADCQ DX, R13
   814  	ADCQ $0x00, R14
   815  	ADCQ $0x00, BX
   816  
   817  	// | a5 * b1
   818  	MOVQ 8(SI), AX
   819  	MULQ CX
   820  	ADDQ AX, R13
   821  	ADCQ DX, R14
   822  	ADCQ BX, R15
   823  	MOVQ $0x00, BX
   824  	ADCQ $0x00, BX
   825  
   826  	// | a5 * b2
   827  	MOVQ 16(SI), AX
   828  	MULQ CX
   829  	ADDQ AX, R14
   830  	ADCQ DX, R15
   831  	ADCQ BX, R8
   832  	MOVQ $0x00, BX
   833  	ADCQ $0x00, BX
   834  
   835  	// | a5 * b3
   836  	MOVQ 24(SI), AX
   837  	MULQ CX
   838  	ADDQ AX, R15
   839  	ADCQ DX, R8
   840  	ADCQ BX, R9
   841  	MOVQ $0x00, BX
   842  	ADCQ $0x00, BX
   843  
   844  	// | a5 * b4
   845  	MOVQ 32(SI), AX
   846  	MULQ CX
   847  	ADDQ AX, R8
   848  	ADCQ DX, R9
   849  	ADCQ $0x00, BX
   850  
   851  	// | a5 * b5
   852  	MOVQ 40(SI), AX
   853  	MULQ CX
   854  	ADDQ AX, R9
   855  	ADCQ DX, BX
   856  
   857  	// |
   858  
   859  /* 			                                     */
   860  
   861  	// |
   862  	// | W
   863  	// | 0   (SP)      | 1   8(SP)     | 2   16(SP)    | 3   R10       | 4   R11       | 5   R12
   864  	// | 6   R13       | 7   R14       | 8   R15       | 9   R8        | 10  R9        | 11  BX
   865  
   866  
   867  	MOVQ (SP), CX
   868  	MOVQ 8(SP), DI
   869  	MOVQ 16(SP), SI
   870  	MOVQ BX, (SP)
   871  	MOVQ R9, 8(SP)
   872  
   873  	// |
   874  
   875  /* montgomery reduction                    */
   876  
   877  	// |
   878  
   879  /* i0                                   */
   880  
   881  	// |
   882  	// | W
   883  	// | 0   CX        | 1   DI        | 2   SI        | 3   R10       | 4   R11       | 5   R12
   884  	// | 6   R13       | 7   R14       | 8   R15       | 9   R8        | 10  8(SP)     | 11  (SP)
   885  
   886  
   887  	// | | u0 = w0 * inp
   888  	MOVQ CX, AX
   889  	MULQ ·inp+0(SB)
   890  	MOVQ AX, R9
   891  	MOVQ $0x00, BX
   892  
   893  	// |
   894  
   895  /*                                         */
   896  
   897  	// | j0
   898  
   899  	// | w0 @ CX
   900  	MOVQ ·modulus+0(SB), AX
   901  	MULQ R9
   902  	ADDQ AX, CX
   903  	ADCQ DX, BX
   904  
   905  	// | j1
   906  
   907  	// | w1 @ DI
   908  	MOVQ ·modulus+8(SB), AX
   909  	MULQ R9
   910  	ADDQ AX, DI
   911  	ADCQ $0x00, DX
   912  	ADDQ BX, DI
   913  	MOVQ $0x00, BX
   914  	ADCQ DX, BX
   915  
   916  	// | j2
   917  
   918  	// | w2 @ SI
   919  	MOVQ ·modulus+16(SB), AX
   920  	MULQ R9
   921  	ADDQ AX, SI
   922  	ADCQ $0x00, DX
   923  	ADDQ BX, SI
   924  	MOVQ $0x00, BX
   925  	ADCQ DX, BX
   926  
   927  	// | j3
   928  
   929  	// | w3 @ R10
   930  	MOVQ ·modulus+24(SB), AX
   931  	MULQ R9
   932  	ADDQ AX, R10
   933  	ADCQ $0x00, DX
   934  	ADDQ BX, R10
   935  	MOVQ $0x00, BX
   936  	ADCQ DX, BX
   937  
   938  	// | j4
   939  
   940  	// | w4 @ R11
   941  	MOVQ ·modulus+32(SB), AX
   942  	MULQ R9
   943  	ADDQ AX, R11
   944  	ADCQ $0x00, DX
   945  	ADDQ BX, R11
   946  	MOVQ $0x00, BX
   947  	ADCQ DX, BX
   948  
   949  	// | j5
   950  
   951  	// | w5 @ R12
   952  	MOVQ ·modulus+40(SB), AX
   953  	MULQ R9
   954  	ADDQ AX, R12
   955  	ADCQ $0x00, DX
   956  	ADDQ BX, R12
   957  
   958  	// | w6 @ R13
   959  	ADCQ DX, R13
   960  	ADCQ $0x00, CX
   961  
   962  	// |
   963  
   964  /* i1                                   */
   965  
   966  	// |
   967  	// | W
   968  	// | 0   -         | 1   DI        | 2   SI        | 3   R10       | 4   R11       | 5   R12
   969  	// | 6   R13       | 7   R14       | 8   R15       | 9   R8        | 10  8(SP)     | 11  (SP)
   970  
   971  
   972  	// | | u1 = w1 * inp
   973  	MOVQ DI, AX
   974  	MULQ ·inp+0(SB)
   975  	MOVQ AX, R9
   976  	MOVQ $0x00, BX
   977  
   978  	// |
   979  
   980  /*                                         */
   981  
   982  	// | j0
   983  
   984  	// | w1 @ DI
   985  	MOVQ ·modulus+0(SB), AX
   986  	MULQ R9
   987  	ADDQ AX, DI
   988  	ADCQ DX, BX
   989  
   990  	// | j1
   991  
   992  	// | w2 @ SI
   993  	MOVQ ·modulus+8(SB), AX
   994  	MULQ R9
   995  	ADDQ AX, SI
   996  	ADCQ $0x00, DX
   997  	ADDQ BX, SI
   998  	MOVQ $0x00, BX
   999  	ADCQ DX, BX
  1000  
  1001  	// | j2
  1002  
  1003  	// | w3 @ R10
  1004  	MOVQ ·modulus+16(SB), AX
  1005  	MULQ R9
  1006  	ADDQ AX, R10
  1007  	ADCQ $0x00, DX
  1008  	ADDQ BX, R10
  1009  	MOVQ $0x00, BX
  1010  	ADCQ DX, BX
  1011  
  1012  	// | j3
  1013  
  1014  	// | w4 @ R11
  1015  	MOVQ ·modulus+24(SB), AX
  1016  	MULQ R9
  1017  	ADDQ AX, R11
  1018  	ADCQ $0x00, DX
  1019  	ADDQ BX, R11
  1020  	MOVQ $0x00, BX
  1021  	ADCQ DX, BX
  1022  
  1023  	// | j4
  1024  
  1025  	// | w5 @ R12
  1026  	MOVQ ·modulus+32(SB), AX
  1027  	MULQ R9
  1028  	ADDQ AX, R12
  1029  	ADCQ $0x00, DX
  1030  	ADDQ BX, R12
  1031  	MOVQ $0x00, BX
  1032  	ADCQ DX, BX
  1033  
  1034  	// | j5
  1035  
  1036  	// | w6 @ R13
  1037  	MOVQ ·modulus+40(SB), AX
  1038  	MULQ R9
  1039  	ADDQ AX, R13
  1040  	ADCQ DX, CX
  1041  	ADDQ BX, R13
  1042  
  1043  	// | w7 @ R14
  1044  	ADCQ CX, R14
  1045  	MOVQ $0x00, CX
  1046  	ADCQ $0x00, CX
  1047  
  1048  	// |
  1049  
  1050  /* i2                                   */
  1051  
  1052  	// |
  1053  	// | W
  1054  	// | 0   -         | 1   -         | 2   SI        | 3   R10       | 4   R11       | 5   R12
  1055  	// | 6   R13       | 7   R14       | 8   R15       | 9   R8        | 10  8(SP)     | 11  (SP)
  1056  
  1057  
  1058  	// | | u2 = w2 * inp
  1059  	MOVQ SI, AX
  1060  	MULQ ·inp+0(SB)
  1061  	MOVQ AX, R9
  1062  	MOVQ $0x00, BX
  1063  
  1064  	// |
  1065  
  1066  /*                                         */
  1067  
  1068  	// | j0
  1069  
  1070  	// | w2 @ SI
  1071  	MOVQ ·modulus+0(SB), AX
  1072  	MULQ R9
  1073  	ADDQ AX, SI
  1074  	ADCQ DX, BX
  1075  
  1076  	// | j1
  1077  
  1078  	// | w3 @ R10
  1079  	MOVQ ·modulus+8(SB), AX
  1080  	MULQ R9
  1081  	ADDQ AX, R10
  1082  	ADCQ $0x00, DX
  1083  	ADDQ BX, R10
  1084  	MOVQ $0x00, BX
  1085  	ADCQ DX, BX
  1086  
  1087  	// | j2
  1088  
  1089  	// | w4 @ R11
  1090  	MOVQ ·modulus+16(SB), AX
  1091  	MULQ R9
  1092  	ADDQ AX, R11
  1093  	ADCQ $0x00, DX
  1094  	ADDQ BX, R11
  1095  	MOVQ $0x00, BX
  1096  	ADCQ DX, BX
  1097  
  1098  	// | j3
  1099  
  1100  	// | w5 @ R12
  1101  	MOVQ ·modulus+24(SB), AX
  1102  	MULQ R9
  1103  	ADDQ AX, R12
  1104  	ADCQ $0x00, DX
  1105  	ADDQ BX, R12
  1106  	MOVQ $0x00, BX
  1107  	ADCQ DX, BX
  1108  
  1109  	// | j4
  1110  
  1111  	// | w6 @ R13
  1112  	MOVQ ·modulus+32(SB), AX
  1113  	MULQ R9
  1114  	ADDQ AX, R13
  1115  	ADCQ $0x00, DX
  1116  	ADDQ BX, R13
  1117  	MOVQ $0x00, BX
  1118  	ADCQ DX, BX
  1119  
  1120  	// | j5
  1121  
  1122  	// | w7 @ R14
  1123  	MOVQ ·modulus+40(SB), AX
  1124  	MULQ R9
  1125  	ADDQ AX, R14
  1126  	ADCQ DX, CX
  1127  	ADDQ BX, R14
  1128  
  1129  	// | w8 @ R15
  1130  	ADCQ CX, R15
  1131  	MOVQ $0x00, CX
  1132  	ADCQ $0x00, CX
  1133  
  1134  	// |
  1135  
  1136  /* i3                                   */
  1137  
  1138  	// |
  1139  	// | W
  1140  	// | 0   -         | 1   -         | 2   -         | 3   R10       | 4   R11       | 5   R12
  1141  	// | 6   R13       | 7   R14       | 8   R15       | 9   R8        | 10  8(SP)     | 11  (SP)
  1142  
  1143  
  1144  	// | | u3 = w3 * inp
  1145  	MOVQ R10, AX
  1146  	MULQ ·inp+0(SB)
  1147  	MOVQ AX, R9
  1148  	MOVQ $0x00, BX
  1149  
  1150  	// |
  1151  
  1152  /*                                         */
  1153  
  1154  	// | j0
  1155  
  1156  	// | w3 @ R10
  1157  	MOVQ ·modulus+0(SB), AX
  1158  	MULQ R9
  1159  	ADDQ AX, R10
  1160  	ADCQ DX, BX
  1161  
  1162  	// | j1
  1163  
  1164  	// | w4 @ R11
  1165  	MOVQ ·modulus+8(SB), AX
  1166  	MULQ R9
  1167  	ADDQ AX, R11
  1168  	ADCQ $0x00, DX
  1169  	ADDQ BX, R11
  1170  	MOVQ $0x00, BX
  1171  	ADCQ DX, BX
  1172  
  1173  	// | j2
  1174  
  1175  	// | w5 @ R12
  1176  	MOVQ ·modulus+16(SB), AX
  1177  	MULQ R9
  1178  	ADDQ AX, R12
  1179  	ADCQ $0x00, DX
  1180  	ADDQ BX, R12
  1181  	MOVQ $0x00, BX
  1182  	ADCQ DX, BX
  1183  
  1184  	// | j3
  1185  
  1186  	// | w6 @ R13
  1187  	MOVQ ·modulus+24(SB), AX
  1188  	MULQ R9
  1189  	ADDQ AX, R13
  1190  	ADCQ $0x00, DX
  1191  	ADDQ BX, R13
  1192  	MOVQ $0x00, BX
  1193  	ADCQ DX, BX
  1194  
  1195  	// | j4
  1196  
  1197  	// | w7 @ R14
  1198  	MOVQ ·modulus+32(SB), AX
  1199  	MULQ R9
  1200  	ADDQ AX, R14
  1201  	ADCQ $0x00, DX
  1202  	ADDQ BX, R14
  1203  	MOVQ $0x00, BX
  1204  	ADCQ DX, BX
  1205  
  1206  	// | j5
  1207  
  1208  	// | w8 @ R15
  1209  	MOVQ ·modulus+40(SB), AX
  1210  	MULQ R9
  1211  	ADDQ AX, R15
  1212  	ADCQ DX, CX
  1213  	ADDQ BX, R15
  1214  
  1215  	// | w9 @ R8
  1216  	ADCQ CX, R8
  1217  	MOVQ $0x00, CX
  1218  	ADCQ $0x00, CX
  1219  
  1220  	// |
  1221  
  1222  /* i4                                   */
  1223  
  1224  	// |
  1225  	// | W
  1226  	// | 0   -         | 1   -         | 2   -         | 3   -         | 4   R11       | 5   R12
  1227  	// | 6   R13       | 7   R14       | 8   R15       | 9   R8        | 10  8(SP)     | 11  (SP)
  1228  
  1229  
  1230  	// | | u4 = w4 * inp
  1231  	MOVQ R11, AX
  1232  	MULQ ·inp+0(SB)
  1233  	MOVQ AX, R9
  1234  	MOVQ $0x00, BX
  1235  
  1236  	// |
  1237  
  1238  /*                                         */
  1239  
  1240  	// | j0
  1241  
  1242  	// | w4 @ R11
  1243  	MOVQ ·modulus+0(SB), AX
  1244  	MULQ R9
  1245  	ADDQ AX, R11
  1246  	ADCQ DX, BX
  1247  
  1248  	// | j1
  1249  
  1250  	// | w5 @ R12
  1251  	MOVQ ·modulus+8(SB), AX
  1252  	MULQ R9
  1253  	ADDQ AX, R12
  1254  	ADCQ $0x00, DX
  1255  	ADDQ BX, R12
  1256  	MOVQ $0x00, BX
  1257  	ADCQ DX, BX
  1258  
  1259  	// | j2
  1260  
  1261  	// | w6 @ R13
  1262  	MOVQ ·modulus+16(SB), AX
  1263  	MULQ R9
  1264  	ADDQ AX, R13
  1265  	ADCQ $0x00, DX
  1266  	ADDQ BX, R13
  1267  	MOVQ $0x00, BX
  1268  	ADCQ DX, BX
  1269  
  1270  	// | j3
  1271  
  1272  	// | w7 @ R14
  1273  	MOVQ ·modulus+24(SB), AX
  1274  	MULQ R9
  1275  	ADDQ AX, R14
  1276  	ADCQ $0x00, DX
  1277  	ADDQ BX, R14
  1278  	MOVQ $0x00, BX
  1279  	ADCQ DX, BX
  1280  
  1281  	// | j4
  1282  
  1283  	// | w8 @ R15
  1284  	MOVQ ·modulus+32(SB), AX
  1285  	MULQ R9
  1286  	ADDQ AX, R15
  1287  	ADCQ $0x00, DX
  1288  	ADDQ BX, R15
  1289  	MOVQ $0x00, BX
  1290  	ADCQ DX, BX
  1291  
  1292  	// | j5
  1293  
  1294  	// | w9 @ R8
  1295  	MOVQ ·modulus+40(SB), AX
  1296  	MULQ R9
  1297  	ADDQ AX, R8
  1298  	ADCQ DX, CX
  1299  	ADDQ BX, R8
  1300  
  1301  	// | move to idle register
  1302  	MOVQ 8(SP), DI
  1303  
  1304  	// | w10 @ DI
  1305  	ADCQ CX, DI
  1306  	MOVQ $0x00, CX
  1307  	ADCQ $0x00, CX
  1308  
  1309  	// |
  1310  
  1311  /* i5                                   */
  1312  
  1313  	// |
  1314  	// | W
  1315  	// | 0   -         | 1   -         | 2   -         | 3   -         | 4   -         | 5   R12
  1316  	// | 6   R13       | 7   R14       | 8   R15       | 9   R8        | 10  DI        | 11  (SP)
  1317  
  1318  
  1319  	// | | u5 = w5 * inp
  1320  	MOVQ R12, AX
  1321  	MULQ ·inp+0(SB)
  1322  	MOVQ AX, R9
  1323  	MOVQ $0x00, BX
  1324  
  1325  	// |
  1326  
  1327  /*                                         */
  1328  
  1329  	// | j0
  1330  
  1331  	// | w5 @ R12
  1332  	MOVQ ·modulus+0(SB), AX
  1333  	MULQ R9
  1334  	ADDQ AX, R12
  1335  	ADCQ DX, BX
  1336  
  1337  	// | j1
  1338  
  1339  	// | w6 @ R13
  1340  	MOVQ ·modulus+8(SB), AX
  1341  	MULQ R9
  1342  	ADDQ AX, R13
  1343  	ADCQ $0x00, DX
  1344  	ADDQ BX, R13
  1345  	MOVQ $0x00, BX
  1346  	ADCQ DX, BX
  1347  
  1348  	// | j2
  1349  
  1350  	// | w7 @ R14
  1351  	MOVQ ·modulus+16(SB), AX
  1352  	MULQ R9
  1353  	ADDQ AX, R14
  1354  	ADCQ $0x00, DX
  1355  	ADDQ BX, R14
  1356  	MOVQ $0x00, BX
  1357  	ADCQ DX, BX
  1358  
  1359  	// | j3
  1360  
  1361  	// | w8 @ R15
  1362  	MOVQ ·modulus+24(SB), AX
  1363  	MULQ R9
  1364  	ADDQ AX, R15
  1365  	ADCQ $0x00, DX
  1366  	ADDQ BX, R15
  1367  	MOVQ $0x00, BX
  1368  	ADCQ DX, BX
  1369  
  1370  	// | j4
  1371  
  1372  	// | w9 @ R8
  1373  	MOVQ ·modulus+32(SB), AX
  1374  	MULQ R9
  1375  	ADDQ AX, R8
  1376  	ADCQ $0x00, DX
  1377  	ADDQ BX, R8
  1378  	MOVQ $0x00, BX
  1379  	ADCQ DX, BX
  1380  
  1381  	// | j5
  1382  
  1383  	// | w10 @ DI
  1384  	MOVQ ·modulus+40(SB), AX
  1385  	MULQ R9
  1386  	ADDQ AX, DI
  1387  	ADCQ DX, CX
  1388  	ADDQ BX, DI
  1389  
  1390  	// | w11 @ CX
  1391  	ADCQ (SP), CX
  1392  
  1393  	// |
  1394  	// | W montgomerry reduction ends
  1395  	// | 0   -         | 1   -         | 2   -         | 3   -         | 4   -         | 5   -
  1396  	// | 6   R13       | 7   R14       | 8   R15       | 9   R8        | 10  DI        | 11  CX
  1397  
  1398  
  1399  	// |
  1400  
  1401  
  1402  /* modular reduction                       */
  1403  
  1404  	MOVQ R13, R10
  1405  	SUBQ ·modulus+0(SB), R10
  1406  	MOVQ R14, R11
  1407  	SBBQ ·modulus+8(SB), R11
  1408  	MOVQ R15, R12
  1409  	SBBQ ·modulus+16(SB), R12
  1410  	MOVQ R8, AX
  1411  	SBBQ ·modulus+24(SB), AX
  1412  	MOVQ DI, BX
  1413  	SBBQ ·modulus+32(SB), BX
  1414  	MOVQ CX, R9
  1415  	SBBQ ·modulus+40(SB), R9
  1416  	// |
  1417  
  1418  /* out                                     */
  1419  
  1420  	MOVQ    c+0(FP), SI
  1421  	CMOVQCC R10, R13
  1422  	MOVQ    R13, (SI)
  1423  	CMOVQCC R11, R14
  1424  	MOVQ    R14, 8(SI)
  1425  	CMOVQCC R12, R15
  1426  	MOVQ    R15, 16(SI)
  1427  	CMOVQCC AX, R8
  1428  	MOVQ    R8, 24(SI)
  1429  	CMOVQCC BX, DI
  1430  	MOVQ    DI, 32(SI)
  1431  	CMOVQCC R9, CX
  1432  	MOVQ    CX, 40(SI)
  1433  	RET
  1434  
  1435  	// |
  1436  
  1437  /* end                                     */
  1438  
  1439  
  1440  // multiplication
  1441  // c = a * b % p
  1442  TEXT ·mulADX(SB), NOSPLIT, $16-24
  1443  	// |
  1444  
  1445  /* inputs                                  */
  1446  
  1447  	MOVQ a+8(FP), DI
  1448  	MOVQ b+16(FP), SI
  1449  	XORQ AX, AX
  1450  
  1451  	// |
  1452  
  1453  /* i0                                   */
  1454  
  1455  	// | a0 @ DX
  1456  	MOVQ (DI), DX
  1457  
  1458  	// | a0 * b0
  1459  	MULXQ (SI), AX, CX
  1460  	MOVQ  AX, (SP)
  1461  
  1462  	// | a0 * b1
  1463  	MULXQ 8(SI), AX, R8
  1464  	ADCXQ AX, CX
  1465  
  1466  	// | a0 * b2
  1467  	MULXQ 16(SI), AX, R9
  1468  	ADCXQ AX, R8
  1469  
  1470  	// | a0 * b3
  1471  	MULXQ 24(SI), AX, R10
  1472  	ADCXQ AX, R9
  1473  
  1474  	// | a0 * b4
  1475  	MULXQ 32(SI), AX, R11
  1476  	ADCXQ AX, R10
  1477  
  1478  	// | a0 * b5
  1479  	MULXQ 40(SI), AX, R12
  1480  	ADCXQ AX, R11
  1481  	ADCQ  $0x00, R12
  1482  
  1483  	// |
  1484  
  1485  /* i1                                   */
  1486  
  1487  	// | a1 @ DX
  1488  	MOVQ 8(DI), DX
  1489  	XORQ R13, R13
  1490  
  1491  	// | a1 * b0
  1492  	MULXQ (SI), AX, BX
  1493  	ADOXQ AX, CX
  1494  	ADCXQ BX, R8
  1495  	MOVQ  CX, 8(SP)
  1496  
  1497  	// | a1 * b1
  1498  	MULXQ 8(SI), AX, BX
  1499  	ADOXQ AX, R8
  1500  	ADCXQ BX, R9
  1501  
  1502  	// | a1 * b2
  1503  	MULXQ 16(SI), AX, BX
  1504  	ADOXQ AX, R9
  1505  	ADCXQ BX, R10
  1506  
  1507  	// | a1 * b3
  1508  	MULXQ 24(SI), AX, BX
  1509  	ADOXQ AX, R10
  1510  	ADCXQ BX, R11
  1511  
  1512  	// | a1 * b4
  1513  	MULXQ 32(SI), AX, BX
  1514  	ADOXQ AX, R11
  1515  	ADCXQ BX, R12
  1516  
  1517  	// | a1 * b5
  1518  	MULXQ 40(SI), AX, BX
  1519  	ADOXQ AX, R12
  1520  	ADOXQ R13, R13
  1521  	ADCXQ BX, R13
  1522  
  1523  	// |
  1524  
  1525  /* i2                                   */
  1526  
  1527  	// | a2 @ DX
  1528  	MOVQ 16(DI), DX
  1529  	XORQ R14, R14
  1530  
  1531  	// | a2 * b0
  1532  	MULXQ (SI), AX, BX
  1533  	ADOXQ AX, R8
  1534  	ADCXQ BX, R9
  1535  
  1536  	// | a2 * b1
  1537  	MULXQ 8(SI), AX, BX
  1538  	ADOXQ AX, R9
  1539  	ADCXQ BX, R10
  1540  
  1541  	// | a2 * b2
  1542  	MULXQ 16(SI), AX, BX
  1543  	ADOXQ AX, R10
  1544  	ADCXQ BX, R11
  1545  
  1546  	// | a2 * b3
  1547  	MULXQ 24(SI), AX, BX
  1548  	ADOXQ AX, R11
  1549  	ADCXQ BX, R12
  1550  
  1551  	// | a2 * b4
  1552  	MULXQ 32(SI), AX, BX
  1553  	ADOXQ AX, R12
  1554  	ADCXQ BX, R13
  1555  
  1556  	// | a2 * b5
  1557  	MULXQ 40(SI), AX, BX
  1558  	ADOXQ AX, R13
  1559  	ADOXQ R14, R14
  1560  	ADCXQ BX, R14
  1561  
  1562  	// |
  1563  
  1564  /* i3                                   */
  1565  
  1566  	// | a3 @ DX
  1567  	MOVQ 24(DI), DX
  1568  	XORQ R15, R15
  1569  
  1570  	// | a3 * b0
  1571  	MULXQ (SI), AX, BX
  1572  	ADOXQ AX, R9
  1573  	ADCXQ BX, R10
  1574  
  1575  	// | a3 * b1
  1576  	MULXQ 8(SI), AX, BX
  1577  	ADOXQ AX, R10
  1578  	ADCXQ BX, R11
  1579  
  1580  	// | a3 * b2
  1581  	MULXQ 16(SI), AX, BX
  1582  	ADOXQ AX, R11
  1583  	ADCXQ BX, R12
  1584  
  1585  	// | a3 * b3
  1586  	MULXQ 24(SI), AX, BX
  1587  	ADOXQ AX, R12
  1588  	ADCXQ BX, R13
  1589  
  1590  	// | a3 * b4
  1591  	MULXQ 32(SI), AX, BX
  1592  	ADOXQ AX, R13
  1593  	ADCXQ BX, R14
  1594  
  1595  	// | a3 * b5
  1596  	MULXQ 40(SI), AX, BX
  1597  	ADOXQ AX, R14
  1598  	ADOXQ R15, R15
  1599  	ADCXQ BX, R15
  1600  
  1601  	// |
  1602  
  1603  /* i4                                   */
  1604  
  1605  	// | a4 @ DX
  1606  	MOVQ 32(DI), DX
  1607  	XORQ CX, CX
  1608  
  1609  	// | a4 * b0
  1610  	MULXQ (SI), AX, BX
  1611  	ADOXQ AX, R10
  1612  	ADCXQ BX, R11
  1613  
  1614  	// | a4 * b1
  1615  	MULXQ 8(SI), AX, BX
  1616  	ADOXQ AX, R11
  1617  	ADCXQ BX, R12
  1618  
  1619  	// | a4 * b2
  1620  	MULXQ 16(SI), AX, BX
  1621  	ADOXQ AX, R12
  1622  	ADCXQ BX, R13
  1623  
  1624  	// | a4 * b3
  1625  	MULXQ 24(SI), AX, BX
  1626  	ADOXQ AX, R13
  1627  	ADCXQ BX, R14
  1628  
  1629  	// | a4 * b4
  1630  	MULXQ 32(SI), AX, BX
  1631  	ADOXQ AX, R14
  1632  	ADCXQ BX, R15
  1633  
  1634  	// | a4 * b5
  1635  	MULXQ 40(SI), AX, BX
  1636  	ADOXQ AX, R15
  1637  	ADOXQ CX, CX
  1638  	ADCXQ BX, CX
  1639  
  1640  	// |
  1641  
  1642  /* i5                                   */
  1643  
  1644  	// | a5 @ DX
  1645  	MOVQ 40(DI), DX
  1646  	XORQ DI, DI
  1647  
  1648  	// | a5 * b0
  1649  	MULXQ (SI), AX, BX
  1650  	ADOXQ AX, R11
  1651  	ADCXQ BX, R12
  1652  
  1653  	// | a5 * b1
  1654  	MULXQ 8(SI), AX, BX
  1655  	ADOXQ AX, R12
  1656  	ADCXQ BX, R13
  1657  
  1658  	// | a5 * b2
  1659  	MULXQ 16(SI), AX, BX
  1660  	ADOXQ AX, R13
  1661  	ADCXQ BX, R14
  1662  
  1663  	// | a5 * b3
  1664  	MULXQ 24(SI), AX, BX
  1665  	ADOXQ AX, R14
  1666  	ADCXQ BX, R15
  1667  
  1668  	// | a5 * b4
  1669  	MULXQ 32(SI), AX, BX
  1670  	ADOXQ AX, R15
  1671  	ADCXQ BX, CX
  1672  
  1673  	// | a5 * b5
  1674  	MULXQ 40(SI), AX, BX
  1675  	ADOXQ AX, CX
  1676  	ADOXQ BX, DI
  1677  	ADCQ  $0x00, DI
  1678  
  1679  	// |
  1680  
  1681  /* 			                                     */
  1682  
  1683  	// |
  1684  	// | W
  1685  	// | 0   (SP)      | 1   8(SP)     | 2   R8        | 3   R9        | 4   R10       | 5   R11
  1686  	// | 6   R12       | 7   R13       | 8   R14       | 9   R15       | 10  CX        | 11  DI
  1687  
  1688  
  1689  	MOVQ (SP), BX
  1690  	MOVQ 8(SP), SI
  1691  	MOVQ DI, (SP)
  1692  
  1693  	// |
  1694  	// | W ready to mont
  1695  	// | 0   BX        | 1   SI        | 2   R8        | 3   R9        | 4   R10       | 5   R11
  1696  	// | 6   R12       | 7   R13       | 8   R14       | 9   R15       | 10  CX        | 11  (SP)
  1697  
  1698  
  1699  	// |
  1700  
  1701  /* montgomery reduction                    */
  1702  
  1703  	// | clear flags
  1704  	XORQ AX, AX
  1705  
  1706  	// |
  1707  
  1708  /* i0                                   */
  1709  
  1710  	// |
  1711  	// | W
  1712  	// | 0   BX        | 1   SI        | 2   R8        | 3   R9        | 4   R10       | 5   R11
  1713  	// | 6   R12       | 7   R13       | 8   R14       | 9   R15       | 10  CX        | 11  (SP)
  1714  
  1715  
  1716  	// | | u0 = w0 * inp
  1717  	MOVQ  BX, DX
  1718  	MULXQ ·inp+0(SB), DX, DI
  1719  
  1720  	// |
  1721  
  1722  /*                                         */
  1723  
  1724  	// | j0
  1725  
  1726  	// | w0 @ BX
  1727  	MULXQ ·modulus+0(SB), AX, DI
  1728  	ADOXQ AX, BX
  1729  	ADCXQ DI, SI
  1730  
  1731  	// | j1
  1732  
  1733  	// | w1 @ SI
  1734  	MULXQ ·modulus+8(SB), AX, DI
  1735  	ADOXQ AX, SI
  1736  	ADCXQ DI, R8
  1737  
  1738  	// | j2
  1739  
  1740  	// | w2 @ R8
  1741  	MULXQ ·modulus+16(SB), AX, DI
  1742  	ADOXQ AX, R8
  1743  	ADCXQ DI, R9
  1744  
  1745  	// | j3
  1746  
  1747  	// | w3 @ R9
  1748  	MULXQ ·modulus+24(SB), AX, DI
  1749  	ADOXQ AX, R9
  1750  	ADCXQ DI, R10
  1751  
  1752  	// | j4
  1753  
  1754  	// | w4 @ R10
  1755  	MULXQ ·modulus+32(SB), AX, DI
  1756  	ADOXQ AX, R10
  1757  	ADCXQ DI, R11
  1758  
  1759  	// | j5
  1760  
  1761  	// | w5 @ R11
  1762  	MULXQ ·modulus+40(SB), AX, DI
  1763  	ADOXQ AX, R11
  1764  	ADCXQ DI, R12
  1765  	ADOXQ BX, R12
  1766  	ADCXQ BX, BX
  1767  	MOVQ  $0x00, AX
  1768  	ADOXQ AX, BX
  1769  
  1770  	// | clear flags
  1771  	XORQ AX, AX
  1772  
  1773  	// |
  1774  
  1775  /* i1                                   */
  1776  
  1777  	// |
  1778  	// | W
  1779  	// | 0   -         | 1   SI        | 2   R8        | 3   R9        | 4   R10       | 5   R11
  1780  	// | 6   R12       | 7   R13       | 8   R14       | 9   R15       | 10  CX        | 11  (SP)
  1781  
  1782  
  1783  	// | | u1 = w1 * inp
  1784  	MOVQ  SI, DX
  1785  	MULXQ ·inp+0(SB), DX, DI
  1786  
  1787  	// |
  1788  
  1789  /*                                         */
  1790  
  1791  	// | j0
  1792  
  1793  	// | w1 @ SI
  1794  	MULXQ ·modulus+0(SB), AX, DI
  1795  	ADOXQ AX, SI
  1796  	ADCXQ DI, R8
  1797  
  1798  	// | j1
  1799  
  1800  	// | w2 @ R8
  1801  	MULXQ ·modulus+8(SB), AX, DI
  1802  	ADOXQ AX, R8
  1803  	ADCXQ DI, R9
  1804  
  1805  	// | j2
  1806  
  1807  	// | w3 @ R9
  1808  	MULXQ ·modulus+16(SB), AX, DI
  1809  	ADOXQ AX, R9
  1810  	ADCXQ DI, R10
  1811  
  1812  	// | j3
  1813  
  1814  	// | w4 @ R10
  1815  	MULXQ ·modulus+24(SB), AX, DI
  1816  	ADOXQ AX, R10
  1817  	ADCXQ DI, R11
  1818  
  1819  	// | j4
  1820  
  1821  	// | w5 @ R11
  1822  	MULXQ ·modulus+32(SB), AX, DI
  1823  	ADOXQ AX, R11
  1824  	ADCXQ DI, R12
  1825  
  1826  	// | j5
  1827  
  1828  	// | w6 @ R12
  1829  	MULXQ ·modulus+40(SB), AX, DI
  1830  	ADOXQ AX, R12
  1831  	ADCXQ DI, R13
  1832  	ADOXQ BX, R13
  1833  	ADCXQ SI, SI
  1834  	MOVQ  $0x00, AX
  1835  	ADOXQ AX, SI
  1836  
  1837  	// | clear flags
  1838  	XORQ AX, AX
  1839  
  1840  	// |
  1841  
  1842  /* i2                                   */
  1843  
  1844  	// |
  1845  	// | W
  1846  	// | 0   -         | 1   -         | 2   R8        | 3   R9        | 4   R10       | 5   R11
  1847  	// | 6   R12       | 7   R13       | 8   R14       | 9   R15       | 10  CX        | 11  (SP)
  1848  
  1849  
  1850  	// | | u2 = w2 * inp
  1851  	MOVQ  R8, DX
  1852  	MULXQ ·inp+0(SB), DX, DI
  1853  
  1854  	// |
  1855  
  1856  /*                                         */
  1857  
  1858  	// | j0
  1859  
  1860  	// | w2 @ R8
  1861  	MULXQ ·modulus+0(SB), AX, DI
  1862  	ADOXQ AX, R8
  1863  	ADCXQ DI, R9
  1864  
  1865  	// | j1
  1866  
  1867  	// | w3 @ R9
  1868  	MULXQ ·modulus+8(SB), AX, DI
  1869  	ADOXQ AX, R9
  1870  	ADCXQ DI, R10
  1871  
  1872  	// | j2
  1873  
  1874  	// | w4 @ R10
  1875  	MULXQ ·modulus+16(SB), AX, DI
  1876  	ADOXQ AX, R10
  1877  	ADCXQ DI, R11
  1878  
  1879  	// | j3
  1880  
  1881  	// | w5 @ R11
  1882  	MULXQ ·modulus+24(SB), AX, DI
  1883  	ADOXQ AX, R11
  1884  	ADCXQ DI, R12
  1885  
  1886  	// | j4
  1887  
  1888  	// | w6 @ R12
  1889  	MULXQ ·modulus+32(SB), AX, DI
  1890  	ADOXQ AX, R12
  1891  	ADCXQ DI, R13
  1892  
  1893  	// | j5
  1894  
  1895  	// | w7 @ R13
  1896  	MULXQ ·modulus+40(SB), AX, DI
  1897  	ADOXQ AX, R13
  1898  	ADCXQ DI, R14
  1899  	ADOXQ SI, R14
  1900  	ADCXQ R8, R8
  1901  	MOVQ  $0x00, AX
  1902  	ADOXQ AX, R8
  1903  
  1904  	// | clear flags
  1905  	XORQ AX, AX
  1906  
  1907  	// |
  1908  
  1909  /* i3                                   */
  1910  
  1911  	// |
  1912  	// | W
  1913  	// | 0   -         | 1   -         | 2   -         | 3   R9        | 4   R10       | 5   R11
  1914  	// | 6   R12       | 7   R13       | 8   R14       | 9   R15       | 10  CX        | 11  (SP)
  1915  
  1916  
  1917  	// | | u3 = w3 * inp
  1918  	MOVQ  R9, DX
  1919  	MULXQ ·inp+0(SB), DX, DI
  1920  
  1921  	// |
  1922  
  1923  /*                                         */
  1924  
  1925  	// | j0
  1926  
  1927  	// | w3 @ R9
  1928  	MULXQ ·modulus+0(SB), AX, DI
  1929  	ADOXQ AX, R9
  1930  	ADCXQ DI, R10
  1931  
  1932  	// | j1
  1933  
  1934  	// | w4 @ R10
  1935  	MULXQ ·modulus+8(SB), AX, DI
  1936  	ADOXQ AX, R10
  1937  	ADCXQ DI, R11
  1938  
  1939  	// | j2
  1940  
  1941  	// | w5 @ R11
  1942  	MULXQ ·modulus+16(SB), AX, DI
  1943  	ADOXQ AX, R11
  1944  	ADCXQ DI, R12
  1945  
  1946  	// | j3
  1947  
  1948  	// | w6 @ R12
  1949  	MULXQ ·modulus+24(SB), AX, DI
  1950  	ADOXQ AX, R12
  1951  	ADCXQ DI, R13
  1952  
  1953  	// | j4
  1954  
  1955  	// | w7 @ R13
  1956  	MULXQ ·modulus+32(SB), AX, DI
  1957  	ADOXQ AX, R13
  1958  	ADCXQ DI, R14
  1959  
  1960  	// | j5
  1961  
  1962  	// | w8 @ R14
  1963  	MULXQ ·modulus+40(SB), AX, DI
  1964  	ADOXQ AX, R14
  1965  	ADCXQ DI, R15
  1966  	ADOXQ R8, R15
  1967  	ADCXQ R9, R9
  1968  	MOVQ  $0x00, AX
  1969  	ADOXQ AX, R9
  1970  
  1971  	// | clear flags
  1972  	XORQ AX, AX
  1973  
  1974  	// |
  1975  
  1976  /* i4                                   */
  1977  
  1978  	// |
  1979  	// | W
  1980  	// | 0   -         | 1   -         | 2   -         | 3   -         | 4   R10       | 5   R11
  1981  	// | 6   R12       | 7   R13       | 8   R14       | 9   R15       | 10  CX        | 11  (SP)
  1982  
  1983  
  1984  	// | | u4 = w4 * inp
  1985  	MOVQ  R10, DX
  1986  	MULXQ ·inp+0(SB), DX, DI
  1987  
  1988  	// |
  1989  
  1990  /*                                         */
  1991  
  1992  	// | j0
  1993  
  1994  	// | w4 @ R10
  1995  	MULXQ ·modulus+0(SB), AX, DI
  1996  	ADOXQ AX, R10
  1997  	ADCXQ DI, R11
  1998  
  1999  	// | j1
  2000  
  2001  	// | w5 @ R11
  2002  	MULXQ ·modulus+8(SB), AX, DI
  2003  	ADOXQ AX, R11
  2004  	ADCXQ DI, R12
  2005  
  2006  	// | j2
  2007  
  2008  	// | w6 @ R12
  2009  	MULXQ ·modulus+16(SB), AX, DI
  2010  	ADOXQ AX, R12
  2011  	ADCXQ DI, R13
  2012  
  2013  	// | j3
  2014  
  2015  	// | w7 @ R13
  2016  	MULXQ ·modulus+24(SB), AX, DI
  2017  	ADOXQ AX, R13
  2018  	ADCXQ DI, R14
  2019  
  2020  	// | j4
  2021  
  2022  	// | w8 @ R14
  2023  	MULXQ ·modulus+32(SB), AX, DI
  2024  	ADOXQ AX, R14
  2025  	ADCXQ DI, R15
  2026  
  2027  	// | j5
  2028  
  2029  	// | w9 @ R15
  2030  	MULXQ ·modulus+40(SB), AX, DI
  2031  	ADOXQ AX, R15
  2032  	ADCXQ DI, CX
  2033  	ADOXQ R9, CX
  2034  	ADCXQ R10, R10
  2035  	MOVQ  $0x00, AX
  2036  	ADOXQ AX, R10
  2037  
  2038  	// | clear flags
  2039  	XORQ AX, AX
  2040  
  2041  	// |
  2042  
  2043  /* i5                                   */
  2044  
  2045  	// |
  2046  	// | W
  2047  	// | 0   -         | 1   -         | 2   -         | 3   -         | 4   -         | 5   R11
  2048  	// | 6   R12       | 7   R13       | 8   R14       | 9   R15       | 10  CX        | 11  (SP)
  2049  
  2050  
  2051  	// | | u5 = w5 * inp
  2052  	MOVQ  R11, DX
  2053  	MULXQ ·inp+0(SB), DX, DI
  2054  
  2055  	// |
  2056  
  2057  /*                                         */
  2058  
  2059  	// | j0
  2060  
  2061  	// | w5 @ R11
  2062  	MULXQ ·modulus+0(SB), AX, DI
  2063  	ADOXQ AX, R11
  2064  	ADCXQ DI, R12
  2065  
  2066  	// | j1
  2067  
  2068  	// | w6 @ R12
  2069  	MULXQ ·modulus+8(SB), AX, DI
  2070  	ADOXQ AX, R12
  2071  	ADCXQ DI, R13
  2072  
  2073  	// | j2
  2074  
  2075  	// | w7 @ R13
  2076  	MULXQ ·modulus+16(SB), AX, DI
  2077  	ADOXQ AX, R13
  2078  	ADCXQ DI, R14
  2079  
  2080  	// | j3
  2081  
  2082  	// | w8 @ R14
  2083  	MULXQ ·modulus+24(SB), AX, DI
  2084  	ADOXQ AX, R14
  2085  	ADCXQ DI, R15
  2086  
  2087  	// | j4
  2088  
  2089  	// | w9 @ R15
  2090  	MULXQ ·modulus+32(SB), AX, DI
  2091  	ADOXQ AX, R15
  2092  	ADCXQ DI, CX
  2093  
  2094  	// | j5
  2095  
  2096  	// | w10 @ CX
  2097  	MULXQ ·modulus+40(SB), AX, DI
  2098  	ADOXQ AX, CX
  2099  
  2100  	// | w11 @ (SP)
  2101  	// | move to an idle register
  2102  	MOVQ  (SP), BX
  2103  	ADCXQ DI, BX
  2104  	ADOXQ R10, BX
  2105  
  2106  	// |
  2107  	// | W montgomery reduction ends
  2108  	// | 0   -         | 1   -         | 2   -         | 3   -         | 4   -         | 5   -
  2109  	// | 6   R12       | 7   R13       | 8   R14       | 9   R15       | 10  CX        | 11  BX
  2110  
  2111  
  2112  	// |
  2113  
  2114  /* modular reduction                       */
  2115  
  2116  	MOVQ R12, AX
  2117  	SUBQ ·modulus+0(SB), AX
  2118  	MOVQ R13, DI
  2119  	SBBQ ·modulus+8(SB), DI
  2120  	MOVQ R14, SI
  2121  	SBBQ ·modulus+16(SB), SI
  2122  	MOVQ R15, R8
  2123  	SBBQ ·modulus+24(SB), R8
  2124  	MOVQ CX, R9
  2125  	SBBQ ·modulus+32(SB), R9
  2126  	MOVQ BX, R10
  2127  	SBBQ ·modulus+40(SB), R10
  2128  
  2129  	// |
  2130  
  2131  /* out                                     */
  2132  
  2133  	MOVQ    c+0(FP), R11
  2134  	CMOVQCC AX, R12
  2135  	MOVQ    R12, (R11)
  2136  	CMOVQCC DI, R13
  2137  	MOVQ    R13, 8(R11)
  2138  	CMOVQCC SI, R14
  2139  	MOVQ    R14, 16(R11)
  2140  	CMOVQCC R8, R15
  2141  	MOVQ    R15, 24(R11)
  2142  	CMOVQCC R9, CX
  2143  	MOVQ    CX, 32(R11)
  2144  	CMOVQCC R10, BX
  2145  	MOVQ    BX, 40(R11)
  2146  	RET
  2147  
  2148  	// |
  2149  
  2150  /* end 																			*/