github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/crypto/secp256k1/libsecp256k1/src/field_5x52_asm_impl.h (about)

     1  /**********************************************************************
     2   * Copyright (c) 2013-2014 Diederik Huys, Pieter Wuille               *
     3   * Distributed under the MIT software license, see the accompanying   *
     4   * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
     5   **********************************************************************/
     6  
     7  /**
     8   * Changelog:
     9   * - March 2013, Diederik Huys:    original version
    10   * - November 2014, Pieter Wuille: updated to use Peter Dettman's parallel multiplication algorithm
    11   * - December 2014, Pieter Wuille: converted from YASM to GCC inline assembly
    12   */
    13  
    14  #ifndef _SECP256K1_FIELD_INNER5X52_IMPL_H_
    15  #define _SECP256K1_FIELD_INNER5X52_IMPL_H_
    16  
    17  SECP256K1_INLINE static void secp256k1_fe_mul_inner(uint64_t *r, const uint64_t *a, const uint64_t * SECP256K1_RESTRICT b) {
    18  /**
    19   * Registers: rdx:rax = multiplication accumulator
    20   *            r9:r8   = c
    21   *            r15:rcx = d
    22   *            r10-r14 = a0-a4
    23   *            rbx     = b
    24   *            rdi     = r
    25   *            rsi     = a / t?
    26   */
    27    uint64_t tmp1, tmp2, tmp3;
    28  __asm__ __volatile__(
    29      "movq 0(%%rsi),%%r10\n"
    30      "movq 8(%%rsi),%%r11\n"
    31      "movq 16(%%rsi),%%r12\n"
    32      "movq 24(%%rsi),%%r13\n"
    33      "movq 32(%%rsi),%%r14\n"
    34  
    35      /* d += a3 * b0 */
    36      "movq 0(%%rbx),%%rax\n"
    37      "mulq %%r13\n"
    38      "movq %%rax,%%rcx\n"
    39      "movq %%rdx,%%r15\n"
    40      /* d += a2 * b1 */
    41      "movq 8(%%rbx),%%rax\n"
    42      "mulq %%r12\n"
    43      "addq %%rax,%%rcx\n"
    44      "adcq %%rdx,%%r15\n"
    45      /* d += a1 * b2 */
    46      "movq 16(%%rbx),%%rax\n"
    47      "mulq %%r11\n"
    48      "addq %%rax,%%rcx\n"
    49      "adcq %%rdx,%%r15\n"
    50      /* d = a0 * b3 */
    51      "movq 24(%%rbx),%%rax\n"
    52      "mulq %%r10\n"
    53      "addq %%rax,%%rcx\n"
    54      "adcq %%rdx,%%r15\n"
    55      /* c = a4 * b4 */
    56      "movq 32(%%rbx),%%rax\n"
    57      "mulq %%r14\n"
    58      "movq %%rax,%%r8\n"
    59      "movq %%rdx,%%r9\n"
    60      /* d += (c & M) * R */
    61      "movq $0xfffffffffffff,%%rdx\n"
    62      "andq %%rdx,%%rax\n"
    63      "movq $0x1000003d10,%%rdx\n"
    64      "mulq %%rdx\n"
    65      "addq %%rax,%%rcx\n"
    66      "adcq %%rdx,%%r15\n"
    67      /* c >>= 52 (%%r8 only) */
    68      "shrdq $52,%%r9,%%r8\n"
    69      /* t3 (tmp1) = d & M */
    70      "movq %%rcx,%%rsi\n"
    71      "movq $0xfffffffffffff,%%rdx\n"
    72      "andq %%rdx,%%rsi\n"
    73      "movq %%rsi,%q1\n"
    74      /* d >>= 52 */
    75      "shrdq $52,%%r15,%%rcx\n"
    76      "xorq %%r15,%%r15\n"
    77      /* d += a4 * b0 */
    78      "movq 0(%%rbx),%%rax\n"
    79      "mulq %%r14\n"
    80      "addq %%rax,%%rcx\n"
    81      "adcq %%rdx,%%r15\n"
    82      /* d += a3 * b1 */
    83      "movq 8(%%rbx),%%rax\n"
    84      "mulq %%r13\n"
    85      "addq %%rax,%%rcx\n"
    86      "adcq %%rdx,%%r15\n"
    87      /* d += a2 * b2 */
    88      "movq 16(%%rbx),%%rax\n"
    89      "mulq %%r12\n"
    90      "addq %%rax,%%rcx\n"
    91      "adcq %%rdx,%%r15\n"
    92      /* d += a1 * b3 */
    93      "movq 24(%%rbx),%%rax\n"
    94      "mulq %%r11\n"
    95      "addq %%rax,%%rcx\n"
    96      "adcq %%rdx,%%r15\n"
    97      /* d += a0 * b4 */
    98      "movq 32(%%rbx),%%rax\n"
    99      "mulq %%r10\n"
   100      "addq %%rax,%%rcx\n"
   101      "adcq %%rdx,%%r15\n"
   102      /* d += c * R */
   103      "movq %%r8,%%rax\n"
   104      "movq $0x1000003d10,%%rdx\n"
   105      "mulq %%rdx\n"
   106      "addq %%rax,%%rcx\n"
   107      "adcq %%rdx,%%r15\n"
   108      /* t4 = d & M (%%rsi) */
   109      "movq %%rcx,%%rsi\n"
   110      "movq $0xfffffffffffff,%%rdx\n"
   111      "andq %%rdx,%%rsi\n"
   112      /* d >>= 52 */
   113      "shrdq $52,%%r15,%%rcx\n"
   114      "xorq %%r15,%%r15\n"
   115      /* tx = t4 >> 48 (tmp3) */
   116      "movq %%rsi,%%rax\n"
   117      "shrq $48,%%rax\n"
   118      "movq %%rax,%q3\n"
   119      /* t4 &= (M >> 4) (tmp2) */
   120      "movq $0xffffffffffff,%%rax\n"
   121      "andq %%rax,%%rsi\n"
   122      "movq %%rsi,%q2\n"
   123      /* c = a0 * b0 */
   124      "movq 0(%%rbx),%%rax\n"
   125      "mulq %%r10\n"
   126      "movq %%rax,%%r8\n"
   127      "movq %%rdx,%%r9\n"
   128      /* d += a4 * b1 */
   129      "movq 8(%%rbx),%%rax\n"
   130      "mulq %%r14\n"
   131      "addq %%rax,%%rcx\n"
   132      "adcq %%rdx,%%r15\n"
   133      /* d += a3 * b2 */
   134      "movq 16(%%rbx),%%rax\n"
   135      "mulq %%r13\n"
   136      "addq %%rax,%%rcx\n"
   137      "adcq %%rdx,%%r15\n"
   138      /* d += a2 * b3 */
   139      "movq 24(%%rbx),%%rax\n"
   140      "mulq %%r12\n"
   141      "addq %%rax,%%rcx\n"
   142      "adcq %%rdx,%%r15\n"
   143      /* d += a1 * b4 */
   144      "movq 32(%%rbx),%%rax\n"
   145      "mulq %%r11\n"
   146      "addq %%rax,%%rcx\n"
   147      "adcq %%rdx,%%r15\n"
   148      /* u0 = d & M (%%rsi) */
   149      "movq %%rcx,%%rsi\n"
   150      "movq $0xfffffffffffff,%%rdx\n"
   151      "andq %%rdx,%%rsi\n"
   152      /* d >>= 52 */
   153      "shrdq $52,%%r15,%%rcx\n"
   154      "xorq %%r15,%%r15\n"
   155      /* u0 = (u0 << 4) | tx (%%rsi) */
   156      "shlq $4,%%rsi\n"
   157      "movq %q3,%%rax\n"
   158      "orq %%rax,%%rsi\n"
   159      /* c += u0 * (R >> 4) */
   160      "movq $0x1000003d1,%%rax\n"
   161      "mulq %%rsi\n"
   162      "addq %%rax,%%r8\n"
   163      "adcq %%rdx,%%r9\n"
   164      /* r[0] = c & M */
   165      "movq %%r8,%%rax\n"
   166      "movq $0xfffffffffffff,%%rdx\n"
   167      "andq %%rdx,%%rax\n"
   168      "movq %%rax,0(%%rdi)\n"
   169      /* c >>= 52 */
   170      "shrdq $52,%%r9,%%r8\n"
   171      "xorq %%r9,%%r9\n"
   172      /* c += a1 * b0 */
   173      "movq 0(%%rbx),%%rax\n"
   174      "mulq %%r11\n"
   175      "addq %%rax,%%r8\n"
   176      "adcq %%rdx,%%r9\n"
   177      /* c += a0 * b1 */
   178      "movq 8(%%rbx),%%rax\n"
   179      "mulq %%r10\n"
   180      "addq %%rax,%%r8\n"
   181      "adcq %%rdx,%%r9\n"
   182      /* d += a4 * b2 */
   183      "movq 16(%%rbx),%%rax\n"
   184      "mulq %%r14\n"
   185      "addq %%rax,%%rcx\n"
   186      "adcq %%rdx,%%r15\n"
   187      /* d += a3 * b3 */
   188      "movq 24(%%rbx),%%rax\n"
   189      "mulq %%r13\n"
   190      "addq %%rax,%%rcx\n"
   191      "adcq %%rdx,%%r15\n"
   192      /* d += a2 * b4 */
   193      "movq 32(%%rbx),%%rax\n"
   194      "mulq %%r12\n"
   195      "addq %%rax,%%rcx\n"
   196      "adcq %%rdx,%%r15\n"
   197      /* c += (d & M) * R */
   198      "movq %%rcx,%%rax\n"
   199      "movq $0xfffffffffffff,%%rdx\n"
   200      "andq %%rdx,%%rax\n"
   201      "movq $0x1000003d10,%%rdx\n"
   202      "mulq %%rdx\n"
   203      "addq %%rax,%%r8\n"
   204      "adcq %%rdx,%%r9\n"
   205      /* d >>= 52 */
   206      "shrdq $52,%%r15,%%rcx\n"
   207      "xorq %%r15,%%r15\n"
   208      /* r[1] = c & M */
   209      "movq %%r8,%%rax\n"
   210      "movq $0xfffffffffffff,%%rdx\n"
   211      "andq %%rdx,%%rax\n"
   212      "movq %%rax,8(%%rdi)\n"
   213      /* c >>= 52 */
   214      "shrdq $52,%%r9,%%r8\n"
   215      "xorq %%r9,%%r9\n"
   216      /* c += a2 * b0 */
   217      "movq 0(%%rbx),%%rax\n"
   218      "mulq %%r12\n"
   219      "addq %%rax,%%r8\n"
   220      "adcq %%rdx,%%r9\n"
   221      /* c += a1 * b1 */
   222      "movq 8(%%rbx),%%rax\n"
   223      "mulq %%r11\n"
   224      "addq %%rax,%%r8\n"
   225      "adcq %%rdx,%%r9\n"
   226      /* c += a0 * b2 (last use of %%r10 = a0) */
   227      "movq 16(%%rbx),%%rax\n"
   228      "mulq %%r10\n"
   229      "addq %%rax,%%r8\n"
   230      "adcq %%rdx,%%r9\n"
   231      /* fetch t3 (%%r10, overwrites a0), t4 (%%rsi) */
   232      "movq %q2,%%rsi\n"
   233      "movq %q1,%%r10\n"
   234      /* d += a4 * b3 */
   235      "movq 24(%%rbx),%%rax\n"
   236      "mulq %%r14\n"
   237      "addq %%rax,%%rcx\n"
   238      "adcq %%rdx,%%r15\n"
   239      /* d += a3 * b4 */
   240      "movq 32(%%rbx),%%rax\n"
   241      "mulq %%r13\n"
   242      "addq %%rax,%%rcx\n"
   243      "adcq %%rdx,%%r15\n"
   244      /* c += (d & M) * R */
   245      "movq %%rcx,%%rax\n"
   246      "movq $0xfffffffffffff,%%rdx\n"
   247      "andq %%rdx,%%rax\n"
   248      "movq $0x1000003d10,%%rdx\n"
   249      "mulq %%rdx\n"
   250      "addq %%rax,%%r8\n"
   251      "adcq %%rdx,%%r9\n"
   252      /* d >>= 52 (%%rcx only) */
   253      "shrdq $52,%%r15,%%rcx\n"
   254      /* r[2] = c & M */
   255      "movq %%r8,%%rax\n"
   256      "movq $0xfffffffffffff,%%rdx\n"
   257      "andq %%rdx,%%rax\n"
   258      "movq %%rax,16(%%rdi)\n"
   259      /* c >>= 52 */
   260      "shrdq $52,%%r9,%%r8\n"
   261      "xorq %%r9,%%r9\n"
   262      /* c += t3 */
   263      "addq %%r10,%%r8\n"
   264      /* c += d * R */
   265      "movq %%rcx,%%rax\n"
   266      "movq $0x1000003d10,%%rdx\n"
   267      "mulq %%rdx\n"
   268      "addq %%rax,%%r8\n"
   269      "adcq %%rdx,%%r9\n"
   270      /* r[3] = c & M */
   271      "movq %%r8,%%rax\n"
   272      "movq $0xfffffffffffff,%%rdx\n"
   273      "andq %%rdx,%%rax\n"
   274      "movq %%rax,24(%%rdi)\n"
   275      /* c >>= 52 (%%r8 only) */
   276      "shrdq $52,%%r9,%%r8\n"
   277      /* c += t4 (%%r8 only) */
   278      "addq %%rsi,%%r8\n"
   279      /* r[4] = c */
   280      "movq %%r8,32(%%rdi)\n"
   281  : "+S"(a), "=m"(tmp1), "=m"(tmp2), "=m"(tmp3)
   282  : "b"(b), "D"(r)
   283  : "%rax", "%rcx", "%rdx", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory"
   284  );
   285  }
   286  
   287  SECP256K1_INLINE static void secp256k1_fe_sqr_inner(uint64_t *r, const uint64_t *a) {
   288  /**
   289   * Registers: rdx:rax = multiplication accumulator
   290   *            r9:r8   = c
   291   *            rcx:rbx = d
   292   *            r10-r14 = a0-a4
   293   *            r15     = M (0xfffffffffffff)
   294   *            rdi     = r
   295   *            rsi     = a / t?
   296   */
   297    uint64_t tmp1, tmp2, tmp3;
   298  __asm__ __volatile__(
   299      "movq 0(%%rsi),%%r10\n"
   300      "movq 8(%%rsi),%%r11\n"
   301      "movq 16(%%rsi),%%r12\n"
   302      "movq 24(%%rsi),%%r13\n"
   303      "movq 32(%%rsi),%%r14\n"
   304      "movq $0xfffffffffffff,%%r15\n"
   305  
   306      /* d = (a0*2) * a3 */
   307      "leaq (%%r10,%%r10,1),%%rax\n"
   308      "mulq %%r13\n"
   309      "movq %%rax,%%rbx\n"
   310      "movq %%rdx,%%rcx\n"
   311      /* d += (a1*2) * a2 */
   312      "leaq (%%r11,%%r11,1),%%rax\n"
   313      "mulq %%r12\n"
   314      "addq %%rax,%%rbx\n"
   315      "adcq %%rdx,%%rcx\n"
   316      /* c = a4 * a4 */
   317      "movq %%r14,%%rax\n"
   318      "mulq %%r14\n"
   319      "movq %%rax,%%r8\n"
   320      "movq %%rdx,%%r9\n"
   321      /* d += (c & M) * R */
   322      "andq %%r15,%%rax\n"
   323      "movq $0x1000003d10,%%rdx\n"
   324      "mulq %%rdx\n"
   325      "addq %%rax,%%rbx\n"
   326      "adcq %%rdx,%%rcx\n"
   327      /* c >>= 52 (%%r8 only) */
   328      "shrdq $52,%%r9,%%r8\n"
   329      /* t3 (tmp1) = d & M */
   330      "movq %%rbx,%%rsi\n"
   331      "andq %%r15,%%rsi\n"
   332      "movq %%rsi,%q1\n"
   333      /* d >>= 52 */
   334      "shrdq $52,%%rcx,%%rbx\n"
   335      "xorq %%rcx,%%rcx\n"
   336      /* a4 *= 2 */
   337      "addq %%r14,%%r14\n"
   338      /* d += a0 * a4 */
   339      "movq %%r10,%%rax\n"
   340      "mulq %%r14\n"
   341      "addq %%rax,%%rbx\n"
   342      "adcq %%rdx,%%rcx\n"
   343      /* d+= (a1*2) * a3 */
   344      "leaq (%%r11,%%r11,1),%%rax\n"
   345      "mulq %%r13\n"
   346      "addq %%rax,%%rbx\n"
   347      "adcq %%rdx,%%rcx\n"
   348      /* d += a2 * a2 */
   349      "movq %%r12,%%rax\n"
   350      "mulq %%r12\n"
   351      "addq %%rax,%%rbx\n"
   352      "adcq %%rdx,%%rcx\n"
   353      /* d += c * R */
   354      "movq %%r8,%%rax\n"
   355      "movq $0x1000003d10,%%rdx\n"
   356      "mulq %%rdx\n"
   357      "addq %%rax,%%rbx\n"
   358      "adcq %%rdx,%%rcx\n"
   359      /* t4 = d & M (%%rsi) */
   360      "movq %%rbx,%%rsi\n"
   361      "andq %%r15,%%rsi\n"
   362      /* d >>= 52 */
   363      "shrdq $52,%%rcx,%%rbx\n"
   364      "xorq %%rcx,%%rcx\n"
   365      /* tx = t4 >> 48 (tmp3) */
   366      "movq %%rsi,%%rax\n"
   367      "shrq $48,%%rax\n"
   368      "movq %%rax,%q3\n"
   369      /* t4 &= (M >> 4) (tmp2) */
   370      "movq $0xffffffffffff,%%rax\n"
   371      "andq %%rax,%%rsi\n"
   372      "movq %%rsi,%q2\n"
   373      /* c = a0 * a0 */
   374      "movq %%r10,%%rax\n"
   375      "mulq %%r10\n"
   376      "movq %%rax,%%r8\n"
   377      "movq %%rdx,%%r9\n"
   378      /* d += a1 * a4 */
   379      "movq %%r11,%%rax\n"
   380      "mulq %%r14\n"
   381      "addq %%rax,%%rbx\n"
   382      "adcq %%rdx,%%rcx\n"
   383      /* d += (a2*2) * a3 */
   384      "leaq (%%r12,%%r12,1),%%rax\n"
   385      "mulq %%r13\n"
   386      "addq %%rax,%%rbx\n"
   387      "adcq %%rdx,%%rcx\n"
   388      /* u0 = d & M (%%rsi) */
   389      "movq %%rbx,%%rsi\n"
   390      "andq %%r15,%%rsi\n"
   391      /* d >>= 52 */
   392      "shrdq $52,%%rcx,%%rbx\n"
   393      "xorq %%rcx,%%rcx\n"
   394      /* u0 = (u0 << 4) | tx (%%rsi) */
   395      "shlq $4,%%rsi\n"
   396      "movq %q3,%%rax\n"
   397      "orq %%rax,%%rsi\n"
   398      /* c += u0 * (R >> 4) */
   399      "movq $0x1000003d1,%%rax\n"
   400      "mulq %%rsi\n"
   401      "addq %%rax,%%r8\n"
   402      "adcq %%rdx,%%r9\n"
   403      /* r[0] = c & M */
   404      "movq %%r8,%%rax\n"
   405      "andq %%r15,%%rax\n"
   406      "movq %%rax,0(%%rdi)\n"
   407      /* c >>= 52 */
   408      "shrdq $52,%%r9,%%r8\n"
   409      "xorq %%r9,%%r9\n"
   410      /* a0 *= 2 */
   411      "addq %%r10,%%r10\n"
   412      /* c += a0 * a1 */
   413      "movq %%r10,%%rax\n"
   414      "mulq %%r11\n"
   415      "addq %%rax,%%r8\n"
   416      "adcq %%rdx,%%r9\n"
   417      /* d += a2 * a4 */
   418      "movq %%r12,%%rax\n"
   419      "mulq %%r14\n"
   420      "addq %%rax,%%rbx\n"
   421      "adcq %%rdx,%%rcx\n"
   422      /* d += a3 * a3 */
   423      "movq %%r13,%%rax\n"
   424      "mulq %%r13\n"
   425      "addq %%rax,%%rbx\n"
   426      "adcq %%rdx,%%rcx\n"
   427      /* c += (d & M) * R */
   428      "movq %%rbx,%%rax\n"
   429      "andq %%r15,%%rax\n"
   430      "movq $0x1000003d10,%%rdx\n"
   431      "mulq %%rdx\n"
   432      "addq %%rax,%%r8\n"
   433      "adcq %%rdx,%%r9\n"
   434      /* d >>= 52 */
   435      "shrdq $52,%%rcx,%%rbx\n"
   436      "xorq %%rcx,%%rcx\n"
   437      /* r[1] = c & M */
   438      "movq %%r8,%%rax\n"
   439      "andq %%r15,%%rax\n"
   440      "movq %%rax,8(%%rdi)\n"
   441      /* c >>= 52 */
   442      "shrdq $52,%%r9,%%r8\n"
   443      "xorq %%r9,%%r9\n"
   444      /* c += a0 * a2 (last use of %%r10) */
   445      "movq %%r10,%%rax\n"
   446      "mulq %%r12\n"
   447      "addq %%rax,%%r8\n"
   448      "adcq %%rdx,%%r9\n"
   449      /* fetch t3 (%%r10, overwrites a0),t4 (%%rsi) */
   450      "movq %q2,%%rsi\n"
   451      "movq %q1,%%r10\n"
   452      /* c += a1 * a1 */
   453      "movq %%r11,%%rax\n"
   454      "mulq %%r11\n"
   455      "addq %%rax,%%r8\n"
   456      "adcq %%rdx,%%r9\n"
   457      /* d += a3 * a4 */
   458      "movq %%r13,%%rax\n"
   459      "mulq %%r14\n"
   460      "addq %%rax,%%rbx\n"
   461      "adcq %%rdx,%%rcx\n"
   462      /* c += (d & M) * R */
   463      "movq %%rbx,%%rax\n"
   464      "andq %%r15,%%rax\n"
   465      "movq $0x1000003d10,%%rdx\n"
   466      "mulq %%rdx\n"
   467      "addq %%rax,%%r8\n"
   468      "adcq %%rdx,%%r9\n"
   469      /* d >>= 52 (%%rbx only) */
   470      "shrdq $52,%%rcx,%%rbx\n"
   471      /* r[2] = c & M */
   472      "movq %%r8,%%rax\n"
   473      "andq %%r15,%%rax\n"
   474      "movq %%rax,16(%%rdi)\n"
   475      /* c >>= 52 */
   476      "shrdq $52,%%r9,%%r8\n"
   477      "xorq %%r9,%%r9\n"
   478      /* c += t3 */
   479      "addq %%r10,%%r8\n"
   480      /* c += d * R */
   481      "movq %%rbx,%%rax\n"
   482      "movq $0x1000003d10,%%rdx\n"
   483      "mulq %%rdx\n"
   484      "addq %%rax,%%r8\n"
   485      "adcq %%rdx,%%r9\n"
   486      /* r[3] = c & M */
   487      "movq %%r8,%%rax\n"
   488      "andq %%r15,%%rax\n"
   489      "movq %%rax,24(%%rdi)\n"
   490      /* c >>= 52 (%%r8 only) */
   491      "shrdq $52,%%r9,%%r8\n"
   492      /* c += t4 (%%r8 only) */
   493      "addq %%rsi,%%r8\n"
   494      /* r[4] = c */
   495      "movq %%r8,32(%%rdi)\n"
   496  : "+S"(a), "=m"(tmp1), "=m"(tmp2), "=m"(tmp3)
   497  : "D"(r)
   498  : "%rax", "%rbx", "%rcx", "%rdx", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", "cc", "memory"
   499  );
   500  }
   501  
   502  #endif