arnaucube
arnaucube/circomPublic Self-hosted repository
circom/c/buildasm/fr.asm
c/buildasm/fr.asmRaw
   1
   2
   3        global Fr_copy
   4        global Fr_copyn
   5        global Fr_add
   6        global Fr_sub
   7        global Fr_neg
   8        global Fr_mul
   9        global Fr_square
  10        global Fr_band
  11        global Fr_bor
  12        global Fr_bxor
  13        global Fr_bnot
  14        global Fr_eq
  15        global Fr_neq
  16        global Fr_lt
  17        global Fr_gt
  18        global Fr_leq
  19        global Fr_geq
  20        global Fr_land
  21        global Fr_lor
  22        global Fr_lnot
  23        global Fr_toNormal
  24        global Fr_toLongNormal
  25        global Fr_toMontgomery
  26        global Fr_q
  27        DEFAULT REL
  28
  29        section .text
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47;;;;;;;;;;;;;;;;;;;;;;
  48; copy
  49;;;;;;;;;;;;;;;;;;;;;;
  50; Copies
  51; Params:
  52;   rsi <= the src
  53;   rdi <= the dest
  54;
  55; Nidified registers:
  56;   rax
  57;;;;;;;;;;;;;;;;;;;;;;;
  58Fr_copy:
  59
  60        mov     rax, [rsi + 0]
  61        mov     [rdi + 0], rax
  62
  63        mov     rax, [rsi + 8]
  64        mov     [rdi + 8], rax
  65
  66        mov     rax, [rsi + 16]
  67        mov     [rdi + 16], rax
  68
  69        mov     rax, [rsi + 24]
  70        mov     [rdi + 24], rax
  71
  72        mov     rax, [rsi + 32]
  73        mov     [rdi + 32], rax
  74
  75        ret
  76
  77;;;;;;;;;;;;;;;;;;;;;;
  78; copy an array of integers
  79;;;;;;;;;;;;;;;;;;;;;;
  80; Copies
  81; Params:
  82;   rsi <= the src
  83;   rdi <= the dest
  84;   rdx <= number of integers to copy
  85;
  86; Nidified registers:
  87;   rax
  88;;;;;;;;;;;;;;;;;;;;;;;
  89Fr_copyn:
  90Fr_copyn_loop:
  91        mov     r8, rsi
  92        mov     r9, rdi
  93        mov     rax, 5
  94        mul     rdx
  95        mov     rcx, rax
  96        cld
  97   rep  movsq
  98        mov     rsi, r8
  99        mov     rdi, r9
 100        ret
 101
 102;;;;;;;;;;;;;;;;;;;;;;
 103; rawCopyS2L
 104;;;;;;;;;;;;;;;;;;;;;;
 105; Convert a 64 bit integer to a long format field element
 106; Params:
 107;   rsi <= the integer
 108;   rdi <= Pointer to the overwritted element
 109;
 110; Nidified registers:
 111;   rax
 112;;;;;;;;;;;;;;;;;;;;;;;
 113
 114rawCopyS2L:
 115        mov     al, 0x80
 116        shl     rax, 56
 117        mov     [rdi], rax    ; set the result to LONG normal
 118
 119        cmp     rsi, 0
 120        js      u64toLong_adjust_neg
 121
 122        mov     [rdi + 8], rsi
 123        xor     rax, rax
 124
 125        mov     [rdi + 16], rax
 126
 127        mov     [rdi + 24], rax
 128
 129        mov     [rdi + 32], rax
 130
 131        ret
 132
 133u64toLong_adjust_neg:
 134        add    rsi, [q]         ; Set the first digit
 135        mov    [rdi + 8], rsi   ;
 136
 137        mov    rsi, -1          ; all ones
 138
 139        mov    rax, rsi                       ; Add to q
 140        adc    rax, [q + 8 ]
 141        mov    [rdi + 16], rax
 142
 143        mov    rax, rsi                       ; Add to q
 144        adc    rax, [q + 16 ]
 145        mov    [rdi + 24], rax
 146
 147        mov    rax, rsi                       ; Add to q
 148        adc    rax, [q + 24 ]
 149        mov    [rdi + 32], rax
 150
 151        ret
 152
 153
 154
 155
 156
 157
 158;;;;;;;;;;;;;;;;;;;;;;
 159; rawMontgomeryMul
 160;;;;;;;;;;;;;;;;;;;;;;
 161; Multiply two elements in montgomery form
 162; Params:
 163;   rsi <= Pointer to the long data of element 1
 164;   rdx <= Pointer to the long data of element 2
 165;   rdi <= Pointer to the long data of result
 166; Modified registers:
 167;    r8, r9, 10, r11, rax, rcx
 168;;;;;;;;;;;;;;;;;;;;;;
 169
 170rawMontgomeryMul:
 171        sub     rsp, 32  ; Reserve space for ms
 172        mov     rcx, rdx            ; rdx is needed for multiplications so keep it in cx
 173        mov     r11, 0xc2e1f593efffffff ; np
 174        xor     r8,r8
 175        xor     r9,r9
 176        xor     r10,r10
 177
 178        mov     rax, [rsi + 0]
 179        mul     qword [rcx + 0]
 180        add     r8, rax
 181        adc     r9, rdx
 182        adc     r10, 0x0
 183
 184
 185
 186
 187
 188        mov     rax, r8
 189        mul     r11
 190        mov     [rsp + 0], rax
 191        mul     qword [q]
 192        add     r8, rax
 193        adc     r9, rdx
 194        adc     r10, 0x0
 195
 196
 197
 198        mov     rax, [rsi + 0]
 199        mul     qword [rcx + 8]
 200        add     r9, rax
 201        adc     r10, rdx
 202        adc     r8, 0x0
 203
 204        mov     rax, [rsi + 8]
 205        mul     qword [rcx + 0]
 206        add     r9, rax
 207        adc     r10, rdx
 208        adc     r8, 0x0
 209
 210
 211
 212        mov     rax, [rsp + 0]
 213        mul     qword [q + 8]
 214        add     r9, rax
 215        adc     r10, rdx
 216        adc     r8, 0x0
 217
 218
 219
 220        mov     rax, r9
 221        mul     r11
 222        mov     [rsp + 8], rax
 223        mul     qword [q]
 224        add     r9, rax
 225        adc     r10, rdx
 226        adc     r8, 0x0
 227
 228
 229
 230        mov     rax, [rsi + 0]
 231        mul     qword [rcx + 16]
 232        add     r10, rax
 233        adc     r8, rdx
 234        adc     r9, 0x0
 235
 236        mov     rax, [rsi + 8]
 237        mul     qword [rcx + 8]
 238        add     r10, rax
 239        adc     r8, rdx
 240        adc     r9, 0x0
 241
 242        mov     rax, [rsi + 16]
 243        mul     qword [rcx + 0]
 244        add     r10, rax
 245        adc     r8, rdx
 246        adc     r9, 0x0
 247
 248
 249
 250        mov     rax, [rsp + 8]
 251        mul     qword [q + 8]
 252        add     r10, rax
 253        adc     r8, rdx
 254        adc     r9, 0x0
 255
 256        mov     rax, [rsp + 0]
 257        mul     qword [q + 16]
 258        add     r10, rax
 259        adc     r8, rdx
 260        adc     r9, 0x0
 261
 262
 263
 264        mov     rax, r10
 265        mul     r11
 266        mov     [rsp + 16], rax
 267        mul     qword [q]
 268        add     r10, rax
 269        adc     r8, rdx
 270        adc     r9, 0x0
 271
 272
 273
 274        mov     rax, [rsi + 0]
 275        mul     qword [rcx + 24]
 276        add     r8, rax
 277        adc     r9, rdx
 278        adc     r10, 0x0
 279
 280        mov     rax, [rsi + 8]
 281        mul     qword [rcx + 16]
 282        add     r8, rax
 283        adc     r9, rdx
 284        adc     r10, 0x0
 285
 286        mov     rax, [rsi + 16]
 287        mul     qword [rcx + 8]
 288        add     r8, rax
 289        adc     r9, rdx
 290        adc     r10, 0x0
 291
 292        mov     rax, [rsi + 24]
 293        mul     qword [rcx + 0]
 294        add     r8, rax
 295        adc     r9, rdx
 296        adc     r10, 0x0
 297
 298
 299
 300        mov     rax, [rsp + 16]
 301        mul     qword [q + 8]
 302        add     r8, rax
 303        adc     r9, rdx
 304        adc     r10, 0x0
 305
 306        mov     rax, [rsp + 8]
 307        mul     qword [q + 16]
 308        add     r8, rax
 309        adc     r9, rdx
 310        adc     r10, 0x0
 311
 312        mov     rax, [rsp + 0]
 313        mul     qword [q + 24]
 314        add     r8, rax
 315        adc     r9, rdx
 316        adc     r10, 0x0
 317
 318
 319
 320        mov     rax, r8
 321        mul     r11
 322        mov     [rsp + 24], rax
 323        mul     qword [q]
 324        add     r8, rax
 325        adc     r9, rdx
 326        adc     r10, 0x0
 327
 328
 329
 330        mov     rax, [rsi + 8]
 331        mul     qword [rcx + 24]
 332        add     r9, rax
 333        adc     r10, rdx
 334        adc     r8, 0x0
 335
 336        mov     rax, [rsi + 16]
 337        mul     qword [rcx + 16]
 338        add     r9, rax
 339        adc     r10, rdx
 340        adc     r8, 0x0
 341
 342        mov     rax, [rsi + 24]
 343        mul     qword [rcx + 8]
 344        add     r9, rax
 345        adc     r10, rdx
 346        adc     r8, 0x0
 347
 348
 349
 350        mov     rax, [rsp + 24]
 351        mul     qword [q + 8]
 352        add     r9, rax
 353        adc     r10, rdx
 354        adc     r8, 0x0
 355
 356        mov     rax, [rsp + 16]
 357        mul     qword [q + 16]
 358        add     r9, rax
 359        adc     r10, rdx
 360        adc     r8, 0x0
 361
 362        mov     rax, [rsp + 8]
 363        mul     qword [q + 24]
 364        add     r9, rax
 365        adc     r10, rdx
 366        adc     r8, 0x0
 367
 368
 369
 370        mov     [rdi + 0 ], r9
 371        xor     r9,r9
 372
 373
 374
 375        mov     rax, [rsi + 16]
 376        mul     qword [rcx + 24]
 377        add     r10, rax
 378        adc     r8, rdx
 379        adc     r9, 0x0
 380
 381        mov     rax, [rsi + 24]
 382        mul     qword [rcx + 16]
 383        add     r10, rax
 384        adc     r8, rdx
 385        adc     r9, 0x0
 386
 387
 388
 389        mov     rax, [rsp + 24]
 390        mul     qword [q + 16]
 391        add     r10, rax
 392        adc     r8, rdx
 393        adc     r9, 0x0
 394
 395        mov     rax, [rsp + 16]
 396        mul     qword [q + 24]
 397        add     r10, rax
 398        adc     r8, rdx
 399        adc     r9, 0x0
 400
 401
 402
 403        mov     [rdi + 8 ], r10
 404        xor     r10,r10
 405
 406
 407
 408        mov     rax, [rsi + 24]
 409        mul     qword [rcx + 24]
 410        add     r8, rax
 411        adc     r9, rdx
 412        adc     r10, 0x0
 413
 414
 415
 416        mov     rax, [rsp + 24]
 417        mul     qword [q + 24]
 418        add     r8, rax
 419        adc     r9, rdx
 420        adc     r10, 0x0
 421
 422
 423
 424        mov     [rdi + 16 ], r8
 425        xor     r8,r8
 426
 427
 428
 429
 430
 431
 432
 433        mov     [rdi + 24 ], r9
 434        xor     r9,r9
 435
 436
 437
 438        test    r10, r10
 439        jnz     rawMontgomeryMul_mulM_sq
 440        ; Compare with q
 441
 442        mov rax, [rdi + 24]
 443        cmp rax, [q + 24]
 444        jc rawMontgomeryMul_mulM_done        ; q is bigget so done.
 445        jnz rawMontgomeryMul_mulM_sq         ; q is lower
 446
 447        mov rax, [rdi + 16]
 448        cmp rax, [q + 16]
 449        jc rawMontgomeryMul_mulM_done        ; q is bigget so done.
 450        jnz rawMontgomeryMul_mulM_sq         ; q is lower
 451
 452        mov rax, [rdi + 8]
 453        cmp rax, [q + 8]
 454        jc rawMontgomeryMul_mulM_done        ; q is bigget so done.
 455        jnz rawMontgomeryMul_mulM_sq         ; q is lower
 456
 457        mov rax, [rdi + 0]
 458        cmp rax, [q + 0]
 459        jc rawMontgomeryMul_mulM_done        ; q is bigget so done.
 460        jnz rawMontgomeryMul_mulM_sq         ; q is lower
 461
 462        ; If equal substract q
 463
 464rawMontgomeryMul_mulM_sq:
 465
 466        mov rax, [q + 0]
 467        sub [rdi + 0], rax
 468
 469        mov rax, [q + 8]
 470        sbb [rdi + 8], rax
 471
 472        mov rax, [q + 16]
 473        sbb [rdi + 16], rax
 474
 475        mov rax, [q + 24]
 476        sbb [rdi + 24], rax
 477
 478
 479rawMontgomeryMul_mulM_done:
 480        mov rdx, rcx            ; recover rdx to its original place.
 481        add rsp, 32   ; recover rsp
 482        ret
 483
 484
 485
 486;;;;;;;;;;;;;;;;;;;;;;
 487; rawMontgomerySquare
 488;;;;;;;;;;;;;;;;;;;;;;
 489; Square an element
 490; Params:
 491;   rsi <= Pointer to the long data of element 1
 492;   rdi <= Pointer to the long data of result
 493; Modified registers:
 494;    r8, r9, 10, r11, rax, rcx
 495;;;;;;;;;;;;;;;;;;;;;;
 496
 497rawMontgomerySquare:
 498        sub     rsp, 32  ; Reserve space for ms
 499        mov     rcx, rdx            ; rdx is needed for multiplications so keep it in cx
 500        mov     r11, 0xc2e1f593efffffff ; np
 501        xor     r8,r8
 502        xor     r9,r9
 503        xor     r10,r10
 504
 505
 506
 507        mov     rax, [rsi + 0]
 508        mul     rax
 509        add     r8, rax
 510        adc     r9, rdx
 511        adc     r10, 0x0
 512
 513
 514
 515
 516
 517
 518
 519        mov     rax, r8
 520        mul     r11
 521        mov     [rsp + 0], rax
 522        mul     qword [q]
 523        add     r8, rax
 524        adc     r9, rdx
 525        adc     r10, 0x0
 526
 527
 528
 529        mov     rax, [rsi + 0]
 530        mul     qword [rsi + 8]
 531        add     r9, rax
 532        adc     r10, rdx
 533        adc     r8, 0x0
 534        add     r9, rax
 535        adc     r10, rdx
 536        adc     r8, 0x0
 537
 538
 539
 540
 541
 542
 543
 544        mov     rax, [rsp + 0]
 545        mul     qword [q + 8]
 546        add     r9, rax
 547        adc     r10, rdx
 548        adc     r8, 0x0
 549
 550
 551
 552        mov     rax, r9
 553        mul     r11
 554        mov     [rsp + 8], rax
 555        mul     qword [q]
 556        add     r9, rax
 557        adc     r10, rdx
 558        adc     r8, 0x0
 559
 560
 561
 562        mov     rax, [rsi + 0]
 563        mul     qword [rsi + 16]
 564        add     r10, rax
 565        adc     r8, rdx
 566        adc     r9, 0x0
 567        add     r10, rax
 568        adc     r8, rdx
 569        adc     r9, 0x0
 570
 571
 572
 573        mov     rax, [rsi + 8]
 574        mul     rax
 575        add     r10, rax
 576        adc     r8, rdx
 577        adc     r9, 0x0
 578
 579
 580
 581
 582
 583        mov     rax, [rsp + 8]
 584        mul     qword [q + 8]
 585        add     r10, rax
 586        adc     r8, rdx
 587        adc     r9, 0x0
 588
 589        mov     rax, [rsp + 0]
 590        mul     qword [q + 16]
 591        add     r10, rax
 592        adc     r8, rdx
 593        adc     r9, 0x0
 594
 595
 596
 597        mov     rax, r10
 598        mul     r11
 599        mov     [rsp + 16], rax
 600        mul     qword [q]
 601        add     r10, rax
 602        adc     r8, rdx
 603        adc     r9, 0x0
 604
 605
 606
 607        mov     rax, [rsi + 0]
 608        mul     qword [rsi + 24]
 609        add     r8, rax
 610        adc     r9, rdx
 611        adc     r10, 0x0
 612        add     r8, rax
 613        adc     r9, rdx
 614        adc     r10, 0x0
 615
 616        mov     rax, [rsi + 8]
 617        mul     qword [rsi + 16]
 618        add     r8, rax
 619        adc     r9, rdx
 620        adc     r10, 0x0
 621        add     r8, rax
 622        adc     r9, rdx
 623        adc     r10, 0x0
 624
 625
 626
 627
 628
 629
 630
 631        mov     rax, [rsp + 16]
 632        mul     qword [q + 8]
 633        add     r8, rax
 634        adc     r9, rdx
 635        adc     r10, 0x0
 636
 637        mov     rax, [rsp + 8]
 638        mul     qword [q + 16]
 639        add     r8, rax
 640        adc     r9, rdx
 641        adc     r10, 0x0
 642
 643        mov     rax, [rsp + 0]
 644        mul     qword [q + 24]
 645        add     r8, rax
 646        adc     r9, rdx
 647        adc     r10, 0x0
 648
 649
 650
 651        mov     rax, r8
 652        mul     r11
 653        mov     [rsp + 24], rax
 654        mul     qword [q]
 655        add     r8, rax
 656        adc     r9, rdx
 657        adc     r10, 0x0
 658
 659
 660
 661        mov     rax, [rsi + 8]
 662        mul     qword [rsi + 24]
 663        add     r9, rax
 664        adc     r10, rdx
 665        adc     r8, 0x0
 666        add     r9, rax
 667        adc     r10, rdx
 668        adc     r8, 0x0
 669
 670
 671
 672        mov     rax, [rsi + 16]
 673        mul     rax
 674        add     r9, rax
 675        adc     r10, rdx
 676        adc     r8, 0x0
 677
 678
 679
 680
 681
 682        mov     rax, [rsp + 24]
 683        mul     qword [q + 8]
 684        add     r9, rax
 685        adc     r10, rdx
 686        adc     r8, 0x0
 687
 688        mov     rax, [rsp + 16]
 689        mul     qword [q + 16]
 690        add     r9, rax
 691        adc     r10, rdx
 692        adc     r8, 0x0
 693
 694        mov     rax, [rsp + 8]
 695        mul     qword [q + 24]
 696        add     r9, rax
 697        adc     r10, rdx
 698        adc     r8, 0x0
 699
 700
 701
 702        mov     [rdi + 0 ], r9
 703        xor     r9,r9
 704
 705
 706
 707        mov     rax, [rsi + 16]
 708        mul     qword [rsi + 24]
 709        add     r10, rax
 710        adc     r8, rdx
 711        adc     r9, 0x0
 712        add     r10, rax
 713        adc     r8, rdx
 714        adc     r9, 0x0
 715
 716
 717
 718
 719
 720
 721
 722        mov     rax, [rsp + 24]
 723        mul     qword [q + 16]
 724        add     r10, rax
 725        adc     r8, rdx
 726        adc     r9, 0x0
 727
 728        mov     rax, [rsp + 16]
 729        mul     qword [q + 24]
 730        add     r10, rax
 731        adc     r8, rdx
 732        adc     r9, 0x0
 733
 734
 735
 736        mov     [rdi + 8 ], r10
 737        xor     r10,r10
 738
 739
 740
 741
 742
 743        mov     rax, [rsi + 24]
 744        mul     rax
 745        add     r8, rax
 746        adc     r9, rdx
 747        adc     r10, 0x0
 748
 749
 750
 751
 752
 753        mov     rax, [rsp + 24]
 754        mul     qword [q + 24]
 755        add     r8, rax
 756        adc     r9, rdx
 757        adc     r10, 0x0
 758
 759
 760
 761        mov     [rdi + 16 ], r8
 762        xor     r8,r8
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774        mov     [rdi + 24 ], r9
 775        xor     r9,r9
 776
 777
 778
 779        test    r10, r10
 780        jnz     rawMontgomerySquare_mulM_sq
 781        ; Compare with q
 782
 783        mov rax, [rdi + 24]
 784        cmp rax, [q + 24]
 785        jc rawMontgomerySquare_mulM_done        ; q is bigget so done.
 786        jnz rawMontgomerySquare_mulM_sq         ; q is lower
 787
 788        mov rax, [rdi + 16]
 789        cmp rax, [q + 16]
 790        jc rawMontgomerySquare_mulM_done        ; q is bigget so done.
 791        jnz rawMontgomerySquare_mulM_sq         ; q is lower
 792
 793        mov rax, [rdi + 8]
 794        cmp rax, [q + 8]
 795        jc rawMontgomerySquare_mulM_done        ; q is bigget so done.
 796        jnz rawMontgomerySquare_mulM_sq         ; q is lower
 797
 798        mov rax, [rdi + 0]
 799        cmp rax, [q + 0]
 800        jc rawMontgomerySquare_mulM_done        ; q is bigget so done.
 801        jnz rawMontgomerySquare_mulM_sq         ; q is lower
 802
 803        ; If equal substract q
 804
 805rawMontgomerySquare_mulM_sq:
 806
 807        mov rax, [q + 0]
 808        sub [rdi + 0], rax
 809
 810        mov rax, [q + 8]
 811        sbb [rdi + 8], rax
 812
 813        mov rax, [q + 16]
 814        sbb [rdi + 16], rax
 815
 816        mov rax, [q + 24]
 817        sbb [rdi + 24], rax
 818
 819
 820rawMontgomerySquare_mulM_done:
 821        mov rdx, rcx            ; recover rdx to its original place.
 822        add rsp, 32   ; recover rsp
 823        ret
 824
 825
 826
 827
 828;;;;;;;;;;;;;;;;;;;;;;
 829; rawMontgomeryMul1
 830;;;;;;;;;;;;;;;;;;;;;;
 831; Multiply two elements in montgomery form
 832; Params:
 833;   rsi <= Pointer to the long data of element 1
 834;   rdx <= second operand
 835;   rdi <= Pointer to the long data of result
 836; Modified registers:
 837;    r8, r9, 10, r11, rax, rcx
 838;;;;;;;;;;;;;;;;;;;;;;
 839
 840rawMontgomeryMul1:
 841        sub     rsp, 32  ; Reserve space for ms
 842        mov     rcx, rdx            ; rdx is needed for multiplications so keep it in cx
 843        mov     r11, 0xc2e1f593efffffff ; np
 844        xor     r8,r8
 845        xor     r9,r9
 846        xor     r10,r10
 847
 848        mov     rax, [rsi + 0]
 849        mul     rcx
 850        add     r8, rax
 851        adc     r9, rdx
 852        adc     r10, 0x0
 853
 854
 855
 856
 857
 858        mov     rax, r8
 859        mul     r11
 860        mov     [rsp + 0], rax
 861        mul     qword [q]
 862        add     r8, rax
 863        adc     r9, rdx
 864        adc     r10, 0x0
 865
 866
 867
 868        mov     rax, [rsi + 8]
 869        mul     rcx
 870        add     r9, rax
 871        adc     r10, rdx
 872        adc     r8, 0x0
 873
 874
 875
 876        mov     rax, [rsp + 0]
 877        mul     qword [q + 8]
 878        add     r9, rax
 879        adc     r10, rdx
 880        adc     r8, 0x0
 881
 882
 883
 884        mov     rax, r9
 885        mul     r11
 886        mov     [rsp + 8], rax
 887        mul     qword [q]
 888        add     r9, rax
 889        adc     r10, rdx
 890        adc     r8, 0x0
 891
 892
 893
 894        mov     rax, [rsi + 16]
 895        mul     rcx
 896        add     r10, rax
 897        adc     r8, rdx
 898        adc     r9, 0x0
 899
 900
 901
 902        mov     rax, [rsp + 8]
 903        mul     qword [q + 8]
 904        add     r10, rax
 905        adc     r8, rdx
 906        adc     r9, 0x0
 907
 908        mov     rax, [rsp + 0]
 909        mul     qword [q + 16]
 910        add     r10, rax
 911        adc     r8, rdx
 912        adc     r9, 0x0
 913
 914
 915
 916        mov     rax, r10
 917        mul     r11
 918        mov     [rsp + 16], rax
 919        mul     qword [q]
 920        add     r10, rax
 921        adc     r8, rdx
 922        adc     r9, 0x0
 923
 924
 925
 926        mov     rax, [rsi + 24]
 927        mul     rcx
 928        add     r8, rax
 929        adc     r9, rdx
 930        adc     r10, 0x0
 931
 932
 933
 934        mov     rax, [rsp + 16]
 935        mul     qword [q + 8]
 936        add     r8, rax
 937        adc     r9, rdx
 938        adc     r10, 0x0
 939
 940        mov     rax, [rsp + 8]
 941        mul     qword [q + 16]
 942        add     r8, rax
 943        adc     r9, rdx
 944        adc     r10, 0x0
 945
 946        mov     rax, [rsp + 0]
 947        mul     qword [q + 24]
 948        add     r8, rax
 949        adc     r9, rdx
 950        adc     r10, 0x0
 951
 952
 953
 954        mov     rax, r8
 955        mul     r11
 956        mov     [rsp + 24], rax
 957        mul     qword [q]
 958        add     r8, rax
 959        adc     r9, rdx
 960        adc     r10, 0x0
 961
 962
 963
 964
 965
 966        mov     rax, [rsp + 24]
 967        mul     qword [q + 8]
 968        add     r9, rax
 969        adc     r10, rdx
 970        adc     r8, 0x0
 971
 972        mov     rax, [rsp + 16]
 973        mul     qword [q + 16]
 974        add     r9, rax
 975        adc     r10, rdx
 976        adc     r8, 0x0
 977
 978        mov     rax, [rsp + 8]
 979        mul     qword [q + 24]
 980        add     r9, rax
 981        adc     r10, rdx
 982        adc     r8, 0x0
 983
 984
 985
 986        mov     [rdi + 0 ], r9
 987        xor     r9,r9
 988
 989
 990
 991
 992
 993        mov     rax, [rsp + 24]
 994        mul     qword [q + 16]
 995        add     r10, rax
 996        adc     r8, rdx
 997        adc     r9, 0x0
 998
 999        mov     rax, [rsp + 16]
1000        mul     qword [q + 24]
1001        add     r10, rax
1002        adc     r8, rdx
1003        adc     r9, 0x0
1004
1005
1006
1007        mov     [rdi + 8 ], r10
1008        xor     r10,r10
1009
1010
1011
1012
1013
1014        mov     rax, [rsp + 24]
1015        mul     qword [q + 24]
1016        add     r8, rax
1017        adc     r9, rdx
1018        adc     r10, 0x0
1019
1020
1021
1022        mov     [rdi + 16 ], r8
1023        xor     r8,r8
1024
1025
1026
1027
1028
1029
1030
1031        mov     [rdi + 24 ], r9
1032        xor     r9,r9
1033
1034
1035
1036        test    r10, r10
1037        jnz     rawMontgomeryMul1_mulM_sq
1038        ; Compare with q
1039
1040        mov rax, [rdi + 24]
1041        cmp rax, [q + 24]
1042        jc rawMontgomeryMul1_mulM_done        ; q is bigget so done.
1043        jnz rawMontgomeryMul1_mulM_sq         ; q is lower
1044
1045        mov rax, [rdi + 16]
1046        cmp rax, [q + 16]
1047        jc rawMontgomeryMul1_mulM_done        ; q is bigget so done.
1048        jnz rawMontgomeryMul1_mulM_sq         ; q is lower
1049
1050        mov rax, [rdi + 8]
1051        cmp rax, [q + 8]
1052        jc rawMontgomeryMul1_mulM_done        ; q is bigget so done.
1053        jnz rawMontgomeryMul1_mulM_sq         ; q is lower
1054
1055        mov rax, [rdi + 0]
1056        cmp rax, [q + 0]
1057        jc rawMontgomeryMul1_mulM_done        ; q is bigget so done.
1058        jnz rawMontgomeryMul1_mulM_sq         ; q is lower
1059
1060        ; If equal substract q
1061
1062rawMontgomeryMul1_mulM_sq:
1063
1064        mov rax, [q + 0]
1065        sub [rdi + 0], rax
1066
1067        mov rax, [q + 8]
1068        sbb [rdi + 8], rax
1069
1070        mov rax, [q + 16]
1071        sbb [rdi + 16], rax
1072
1073        mov rax, [q + 24]
1074        sbb [rdi + 24], rax
1075
1076
1077rawMontgomeryMul1_mulM_done:
1078        mov rdx, rcx            ; recover rdx to its original place.
1079        add rsp, 32   ; recover rsp
1080        ret
1081
1082
1083
1084
1085;;;;;;;;;;;;;;;;;;;;;;
1086; rawFromMontgomery
1087;;;;;;;;;;;;;;;;;;;;;;
1088; Multiply two elements in montgomery form
1089; Params:
1090;   rsi <= Pointer to the long data of element 1
1091;   rdi <= Pointer to the long data of result
1092; Modified registers:
1093;    r8, r9, 10, r11, rax, rcx
1094;;;;;;;;;;;;;;;;;;;;;;
1095
1096rawFromMontgomery:
1097        sub     rsp, 32  ; Reserve space for ms
1098        mov     rcx, rdx            ; rdx is needed for multiplications so keep it in cx
1099        mov     r11, 0xc2e1f593efffffff ; np
1100        xor     r8,r8
1101        xor     r9,r9
1102        xor     r10,r10
1103
1104        add     r8, [rdi + 0]
1105        adc     r9, 0x0
1106        adc     r10, 0x0
1107
1108
1109
1110
1111
1112        mov     rax, r8
1113        mul     r11
1114        mov     [rsp + 0], rax
1115        mul     qword [q]
1116        add     r8, rax
1117        adc     r9, rdx
1118        adc     r10, 0x0
1119
1120
1121
1122        add     r9, [rdi + 8]
1123        adc     r10, 0x0
1124        adc     r8, 0x0
1125
1126
1127
1128        mov     rax, [rsp + 0]
1129        mul     qword [q + 8]
1130        add     r9, rax
1131        adc     r10, rdx
1132        adc     r8, 0x0
1133
1134
1135
1136        mov     rax, r9
1137        mul     r11
1138        mov     [rsp + 8], rax
1139        mul     qword [q]
1140        add     r9, rax
1141        adc     r10, rdx
1142        adc     r8, 0x0
1143
1144
1145
1146        add     r10, [rdi + 16]
1147        adc     r8, 0x0
1148        adc     r9, 0x0
1149
1150
1151
1152        mov     rax, [rsp + 8]
1153        mul     qword [q + 8]
1154        add     r10, rax
1155        adc     r8, rdx
1156        adc     r9, 0x0
1157
1158        mov     rax, [rsp + 0]
1159        mul     qword [q + 16]
1160        add     r10, rax
1161        adc     r8, rdx
1162        adc     r9, 0x0
1163
1164
1165
1166        mov     rax, r10
1167        mul     r11
1168        mov     [rsp + 16], rax
1169        mul     qword [q]
1170        add     r10, rax
1171        adc     r8, rdx
1172        adc     r9, 0x0
1173
1174
1175
1176        add     r8, [rdi + 24]
1177        adc     r9, 0x0
1178        adc     r10, 0x0
1179
1180
1181
1182        mov     rax, [rsp + 16]
1183        mul     qword [q + 8]
1184        add     r8, rax
1185        adc     r9, rdx
1186        adc     r10, 0x0
1187
1188        mov     rax, [rsp + 8]
1189        mul     qword [q + 16]
1190        add     r8, rax
1191        adc     r9, rdx
1192        adc     r10, 0x0
1193
1194        mov     rax, [rsp + 0]
1195        mul     qword [q + 24]
1196        add     r8, rax
1197        adc     r9, rdx
1198        adc     r10, 0x0
1199
1200
1201
1202        mov     rax, r8
1203        mul     r11
1204        mov     [rsp + 24], rax
1205        mul     qword [q]
1206        add     r8, rax
1207        adc     r9, rdx
1208        adc     r10, 0x0
1209
1210
1211
1212
1213
1214        mov     rax, [rsp + 24]
1215        mul     qword [q + 8]
1216        add     r9, rax
1217        adc     r10, rdx
1218        adc     r8, 0x0
1219
1220        mov     rax, [rsp + 16]
1221        mul     qword [q + 16]
1222        add     r9, rax
1223        adc     r10, rdx
1224        adc     r8, 0x0
1225
1226        mov     rax, [rsp + 8]
1227        mul     qword [q + 24]
1228        add     r9, rax
1229        adc     r10, rdx
1230        adc     r8, 0x0
1231
1232
1233
1234        mov     [rdi + 0 ], r9
1235        xor     r9,r9
1236
1237
1238
1239
1240
1241        mov     rax, [rsp + 24]
1242        mul     qword [q + 16]
1243        add     r10, rax
1244        adc     r8, rdx
1245        adc     r9, 0x0
1246
1247        mov     rax, [rsp + 16]
1248        mul     qword [q + 24]
1249        add     r10, rax
1250        adc     r8, rdx
1251        adc     r9, 0x0
1252
1253
1254
1255        mov     [rdi + 8 ], r10
1256        xor     r10,r10
1257
1258
1259
1260
1261
1262        mov     rax, [rsp + 24]
1263        mul     qword [q + 24]
1264        add     r8, rax
1265        adc     r9, rdx
1266        adc     r10, 0x0
1267
1268
1269
1270        mov     [rdi + 16 ], r8
1271        xor     r8,r8
1272
1273
1274
1275
1276
1277
1278
1279        mov     [rdi + 24 ], r9
1280        xor     r9,r9
1281
1282
1283
1284        test    r10, r10
1285        jnz     rawFromMontgomery_mulM_sq
1286        ; Compare with q
1287
1288        mov rax, [rdi + 24]
1289        cmp rax, [q + 24]
1290        jc rawFromMontgomery_mulM_done        ; q is bigget so done.
1291        jnz rawFromMontgomery_mulM_sq         ; q is lower
1292
1293        mov rax, [rdi + 16]
1294        cmp rax, [q + 16]
1295        jc rawFromMontgomery_mulM_done        ; q is bigget so done.
1296        jnz rawFromMontgomery_mulM_sq         ; q is lower
1297
1298        mov rax, [rdi + 8]
1299        cmp rax, [q + 8]
1300        jc rawFromMontgomery_mulM_done        ; q is bigget so done.
1301        jnz rawFromMontgomery_mulM_sq         ; q is lower
1302
1303        mov rax, [rdi + 0]
1304        cmp rax, [q + 0]
1305        jc rawFromMontgomery_mulM_done        ; q is bigget so done.
1306        jnz rawFromMontgomery_mulM_sq         ; q is lower
1307
1308        ; If equal substract q
1309
1310rawFromMontgomery_mulM_sq:
1311
1312        mov rax, [q + 0]
1313        sub [rdi + 0], rax
1314
1315        mov rax, [q + 8]
1316        sbb [rdi + 8], rax
1317
1318        mov rax, [q + 16]
1319        sbb [rdi + 16], rax
1320
1321        mov rax, [q + 24]
1322        sbb [rdi + 24], rax
1323
1324
1325rawFromMontgomery_mulM_done:
1326        mov rdx, rcx            ; recover rdx to its original place.
1327        add rsp, 32   ; recover rsp
1328        ret
1329
1330
1331
1332;;;;;;;;;;;;;;;;;;;;;;
1333; toMontgomery
1334;;;;;;;;;;;;;;;;;;;;;;
1335; Convert a number to Montgomery
1336;   rdi <= Pointer element to convert
1337; Modified registers:
1338;    r8, r9, 10, r11, rax, rcx
1339;;;;;;;;;;;;;;;;;;;;
1340Fr_toMontgomery:
1341    mov     rax, [rdi]
1342    bts     rax, 62                     ; check if montgomery
1343    jc      toMontgomery_doNothing
1344    bts     rax, 63
1345    jc      toMontgomeryLong
1346
1347toMontgomeryShort:
1348    mov     [rdi], rax
1349    add     rdi, 8
1350    push    rsi
1351    lea     rsi, [R2]
1352    movsx   rdx, eax
1353    cmp     rdx, 0
1354    js      negMontgomeryShort
1355posMontgomeryShort:
1356    call    rawMontgomeryMul1
1357    pop     rsi
1358    sub     rdi, 8
1359    ret
1360
1361negMontgomeryShort:
1362    neg     rdx              ; Do the multiplication positive and then negate the result.
1363    call    rawMontgomeryMul1
1364    mov     rsi, rdi
1365    call    rawNegL
1366    pop     rsi
1367    sub     rdi, 8
1368    ret
1369
1370
1371toMontgomeryLong:
1372    mov     [rdi], rax
1373    add     rdi, 8
1374    push    rsi
1375    mov     rdx, rdi
1376    lea     rsi, [R2]
1377    call    rawMontgomeryMul
1378    pop     rsi
1379    sub     rdi, 8
1380
1381toMontgomery_doNothing:
1382    ret
1383
1384;;;;;;;;;;;;;;;;;;;;;;
1385; toNormal
1386;;;;;;;;;;;;;;;;;;;;;;
1387; Convert a number from Montgomery
1388;   rdi <= Pointer element to convert
1389; Modified registers:
1390;    r8, r9, 10, r11, rax, rcx
1391;;;;;;;;;;;;;;;;;;;;
1392Fr_toNormal:
1393    mov     rax, [rdi]
1394    btc     rax, 62                     ; check if montgomery
1395    jnc     toNormal_doNothing
1396    bt      rax, 63                     ; if short, it means it's converted
1397    jnc     toNormal_doNothing
1398
1399toNormalLong:
1400    mov     [rdi], rax
1401    add     rdi, 8
1402    call    rawFromMontgomery
1403    sub     rdi, 8
1404
1405toNormal_doNothing:
1406    ret
1407
1408;;;;;;;;;;;;;;;;;;;;;;
1409; toLongNormal
1410;;;;;;;;;;;;;;;;;;;;;;
1411; Convert a number to long normal
1412;   rdi <= Pointer element to convert
1413; Modified registers:
1414;    r8, r9, 10, r11, rax, rcx
1415;;;;;;;;;;;;;;;;;;;;
1416Fr_toLongNormal:
1417    mov     rax, [rdi]
1418    bt      rax, 62                     ; check if montgomery
1419    jc      toLongNormal_fromMontgomery
1420    bt      rax, 63                     ; check if long
1421    jnc     toLongNormal_fromShort
1422    ret                                 ; It is already long
1423
1424toLongNormal_fromMontgomery:
1425    add     rdi, 8
1426    call    rawFromMontgomery
1427    sub     rdi, 8
1428    ret
1429
1430toLongNormal_fromShort:
1431    mov     r8, rsi                     ; save rsi
1432    movsx   rsi, eax
1433    call    rawCopyS2L
1434    mov     rsi, r8                     ; recover rsi
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447;;;;;;;;;;;;;;;;;;;;;;
1448; add
1449;;;;;;;;;;;;;;;;;;;;;;
1450; Adds two elements of any kind
1451; Params:
1452;   rsi <= Pointer to element 1
1453;   rdx <= Pointer to element 2
1454;   rdi <= Pointer to result
1455; Modified Registers:
1456;    r8, r9, 10, r11, rax, rcx
1457;;;;;;;;;;;;;;;;;;;;;;
1458Fr_add:
1459        mov    rax, [rsi]
1460        mov    rcx, [rdx]
1461        bt     rax, 63          ; Check if is short first operand
1462        jc     add_l1
1463        bt     rcx, 63          ; Check if is short second operand
1464        jc     add_s1l2
1465
1466add_s1s2:                       ; Both operands are short
1467
1468        xor    rdx, rdx
1469        mov    edx, eax
1470        add    edx, ecx
1471        jo     add_manageOverflow   ; rsi already is the 64bits result
1472
1473        mov    [rdi], rdx       ; not necessary to adjust so just save and return
1474        ret
1475
1476add_manageOverflow:                 ; Do the operation in 64 bits
1477        push   rsi
1478        movsx  rsi, eax
1479        movsx  rdx, ecx
1480        add    rsi, rdx
1481        call   rawCopyS2L
1482        pop    rsi
1483        ret
1484
1485add_l1:
1486        bt     rcx, 63          ; Check if is short second operand
1487        jc     add_l1l2
1488
1489;;;;;;;;
1490add_l1s2:
1491        bt     rax, 62          ; check if montgomery first
1492        jc     add_l1ms2
1493add_l1ns2:
1494        mov r11b, 0x80
1495        shl r11, 56
1496        mov [rdi], r11
1497
1498        add rsi, 8
1499        movsx rdx, ecx
1500        add rdi, 8
1501        cmp rdx, 0
1502        
1503        jns tmp_1
1504        neg rdx
1505        call rawSubLS
1506        sub rdi, 8
1507        sub rsi, 8
1508        ret
1509tmp_1:
1510        call rawAddLS
1511        sub rdi, 8
1512        sub rsi, 8
1513        ret
1514
1515
1516
1517add_l1ms2:
1518        bt     rcx, 62          ; check if montgomery second
1519        jc     add_l1ms2m
1520add_l1ms2n:
1521        mov r11b, 0xC0
1522        shl r11, 56
1523        mov [rdi], r11
1524        push rdi
1525        mov  rdi, rdx
1526        call Fr_toMontgomery
1527        mov  rdx, rdi
1528        pop  rdi
1529
1530        add rdi, 8
1531        add rsi, 8
1532        add rdx, 8
1533        call rawAddLL
1534        sub rdi, 8
1535        sub rsi, 8
1536        ret
1537
1538
1539add_l1ms2m:
1540        mov r11b, 0xC0
1541        shl r11, 56
1542        mov [rdi], r11
1543
1544        add rdi, 8
1545        add rsi, 8
1546        add rdx, 8
1547        call rawAddLL
1548        sub rdi, 8
1549        sub rsi, 8
1550        ret
1551
1552
1553
1554;;;;;;;;
1555add_s1l2:
1556        bt     rcx, 62          ; check if montgomery first
1557        jc     add_s1l2m
1558add_s1l2n:
1559        mov r11b, 0x80
1560        shl r11, 56
1561        mov [rdi], r11
1562
1563        lea rsi, [rdx + 8]
1564        movsx rdx, eax
1565        add rdi, 8
1566        cmp rdx, 0
1567        
1568        jns tmp_2
1569        neg rdx
1570        call rawSubLS
1571        sub rdi, 8
1572        sub rsi, 8
1573        ret
1574tmp_2:
1575        call rawAddLS
1576        sub rdi, 8
1577        sub rsi, 8
1578        ret
1579
1580
1581add_s1l2m:
1582        bt     rax, 62          ; check if montgomery second
1583        jc     add_s1ml2m
1584add_s1nl2m:
1585        mov r11b, 0xC0
1586        shl r11, 56
1587        mov [rdi], r11
1588        push rdi
1589        mov  rdi, rsi
1590        mov  rsi, rdx
1591        call Fr_toMontgomery
1592        mov  rdx, rsi
1593        mov  rsi, rdi
1594        pop  rdi
1595
1596        add rdi, 8
1597        add rsi, 8
1598        add rdx, 8
1599        call rawAddLL
1600        sub rdi, 8
1601        sub rsi, 8
1602        ret
1603
1604
1605add_s1ml2m:
1606        mov r11b, 0xC0
1607        shl r11, 56
1608        mov [rdi], r11
1609
1610        add rdi, 8
1611        add rsi, 8
1612        add rdx, 8
1613        call rawAddLL
1614        sub rdi, 8
1615        sub rsi, 8
1616        ret
1617
1618
1619;;;;
1620add_l1l2:
1621        bt     rax, 62          ; check if montgomery first
1622        jc     add_l1ml2
1623add_l1nl2:
1624        bt     rcx, 62          ; check if montgomery second
1625        jc     add_l1nl2m
1626add_l1nl2n:
1627        mov r11b, 0x80
1628        shl r11, 56
1629        mov [rdi], r11
1630
1631        add rdi, 8
1632        add rsi, 8
1633        add rdx, 8
1634        call rawAddLL
1635        sub rdi, 8
1636        sub rsi, 8
1637        ret
1638
1639
1640add_l1nl2m:
1641        mov r11b, 0xC0
1642        shl r11, 56
1643        mov [rdi], r11
1644        push rdi
1645        mov  rdi, rsi
1646        mov  rsi, rdx
1647        call Fr_toMontgomery
1648        mov  rdx, rsi
1649        mov  rsi, rdi
1650        pop  rdi
1651
1652        add rdi, 8
1653        add rsi, 8
1654        add rdx, 8
1655        call rawAddLL
1656        sub rdi, 8
1657        sub rsi, 8
1658        ret
1659
1660
1661add_l1ml2:
1662        bt     rcx, 62          ; check if montgomery seconf
1663        jc     add_l1ml2m
1664add_l1ml2n:
1665        mov r11b, 0xC0
1666        shl r11, 56
1667        mov [rdi], r11
1668        push rdi
1669        mov  rdi, rdx
1670        call Fr_toMontgomery
1671        mov  rdx, rdi
1672        pop  rdi
1673
1674        add rdi, 8
1675        add rsi, 8
1676        add rdx, 8
1677        call rawAddLL
1678        sub rdi, 8
1679        sub rsi, 8
1680        ret
1681
1682
1683add_l1ml2m:
1684        mov r11b, 0xC0
1685        shl r11, 56
1686        mov [rdi], r11
1687
1688        add rdi, 8
1689        add rsi, 8
1690        add rdx, 8
1691        call rawAddLL
1692        sub rdi, 8
1693        sub rsi, 8
1694        ret
1695
1696
1697
1698
1699;;;;;;;;;;;;;;;;;;;;;;
1700; rawAddLL
1701;;;;;;;;;;;;;;;;;;;;;;
1702; Adds two elements of type long
1703; Params:
1704;   rsi <= Pointer to the long data of element 1
1705;   rdx <= Pointer to the long data of element 2
1706;   rdi <= Pointer to the long data of result
1707; Modified Registers:
1708;    rax
1709;;;;;;;;;;;;;;;;;;;;;;
1710rawAddLL:
1711        ; Add component by component with carry
1712
1713        mov rax, [rsi + 0]
1714        add rax, [rdx + 0]
1715        mov [rdi + 0], rax
1716
1717        mov rax, [rsi + 8]
1718        adc rax, [rdx + 8]
1719        mov [rdi + 8], rax
1720
1721        mov rax, [rsi + 16]
1722        adc rax, [rdx + 16]
1723        mov [rdi + 16], rax
1724
1725        mov rax, [rsi + 24]
1726        adc rax, [rdx + 24]
1727        mov [rdi + 24], rax
1728
1729        jc rawAddLL_sq   ; if overflow, substract q
1730
1731        ; Compare with q
1732
1733
1734        cmp rax, [q + 24]
1735        jc rawAddLL_done        ; q is bigget so done.
1736        jnz rawAddLL_sq         ; q is lower
1737
1738
1739        mov rax, [rdi + 16]
1740
1741        cmp rax, [q + 16]
1742        jc rawAddLL_done        ; q is bigget so done.
1743        jnz rawAddLL_sq         ; q is lower
1744
1745
1746        mov rax, [rdi + 8]
1747
1748        cmp rax, [q + 8]
1749        jc rawAddLL_done        ; q is bigget so done.
1750        jnz rawAddLL_sq         ; q is lower
1751
1752
1753        mov rax, [rdi + 0]
1754
1755        cmp rax, [q + 0]
1756        jc rawAddLL_done        ; q is bigget so done.
1757        jnz rawAddLL_sq         ; q is lower
1758
1759        ; If equal substract q
1760rawAddLL_sq:
1761
1762        mov rax, [q + 0]
1763        sub [rdi + 0], rax
1764
1765        mov rax, [q + 8]
1766        sbb [rdi + 8], rax
1767
1768        mov rax, [q + 16]
1769        sbb [rdi + 16], rax
1770
1771        mov rax, [q + 24]
1772        sbb [rdi + 24], rax
1773
1774rawAddLL_done:
1775        ret
1776
1777
1778;;;;;;;;;;;;;;;;;;;;;;
1779; rawAddLS
1780;;;;;;;;;;;;;;;;;;;;;;
1781; Adds two elements of type long
1782; Params:
1783;   rdi <= Pointer to the long data of result
1784;   rsi <= Pointer to the long data of element 1
1785;   rdx <= Value to be added
1786;;;;;;;;;;;;;;;;;;;;;;
1787rawAddLS:
1788        ; Add component by component with carry
1789
1790        add rdx, [rsi]
1791        mov [rdi] ,rdx
1792
1793        mov rdx, 0
1794        adc rdx, [rsi + 8]
1795        mov [rdi + 8], rdx
1796
1797        mov rdx, 0
1798        adc rdx, [rsi + 16]
1799        mov [rdi + 16], rdx
1800
1801        mov rdx, 0
1802        adc rdx, [rsi + 24]
1803        mov [rdi + 24], rdx
1804
1805        jc rawAddLS_sq   ; if overflow, substract q
1806
1807        ; Compare with q
1808
1809        mov rax, [rdi + 24]
1810        cmp rax, [q + 24]
1811        jc rawAddLS_done        ; q is bigget so done.
1812        jnz rawAddLS_sq         ; q is lower
1813
1814        mov rax, [rdi + 16]
1815        cmp rax, [q + 16]
1816        jc rawAddLS_done        ; q is bigget so done.
1817        jnz rawAddLS_sq         ; q is lower
1818
1819        mov rax, [rdi + 8]
1820        cmp rax, [q + 8]
1821        jc rawAddLS_done        ; q is bigget so done.
1822        jnz rawAddLS_sq         ; q is lower
1823
1824        mov rax, [rdi + 0]
1825        cmp rax, [q + 0]
1826        jc rawAddLS_done        ; q is bigget so done.
1827        jnz rawAddLS_sq         ; q is lower
1828
1829        ; If equal substract q
1830rawAddLS_sq:
1831
1832        mov rax, [q + 0]
1833        sub [rdi + 0], rax
1834
1835        mov rax, [q + 8]
1836        sbb [rdi + 8], rax
1837
1838        mov rax, [q + 16]
1839        sbb [rdi + 16], rax
1840
1841        mov rax, [q + 24]
1842        sbb [rdi + 24], rax
1843
1844rawAddLS_done:
1845        ret
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861;;;;;;;;;;;;;;;;;;;;;;
1862; sub
1863;;;;;;;;;;;;;;;;;;;;;;
1864; Substracts two elements of any kind
1865; Params:
1866;   rsi <= Pointer to element 1
1867;   rdx <= Pointer to element 2
1868;   rdi <= Pointer to result
1869; Modified Registers:
1870;    r8, r9, 10, r11, rax, rcx
1871;;;;;;;;;;;;;;;;;;;;;;
1872Fr_sub:
1873        mov    rax, [rsi]
1874        mov    rcx, [rdx]
1875        bt     rax, 63          ; Check if is long first operand
1876        jc     sub_l1
1877        bt     rcx, 63          ; Check if is long second operand
1878        jc     sub_s1l2
1879
1880sub_s1s2:                       ; Both operands are short
1881
1882        xor    rdx, rdx
1883        mov    edx, eax
1884        sub    edx, ecx
1885        jo     sub_manageOverflow   ; rsi already is the 64bits result
1886
1887        mov    [rdi], rdx       ; not necessary to adjust so just save and return
1888        ret
1889
1890sub_manageOverflow:                 ; Do the operation in 64 bits
1891        push   rsi
1892        movsx  rsi, eax
1893        movsx  rdx, ecx
1894        sub    rsi, rdx
1895        call   rawCopyS2L
1896        pop    rsi
1897        ret
1898
1899sub_l1:
1900        bt     rcx, 63          ; Check if is short second operand
1901        jc     sub_l1l2
1902
1903;;;;;;;;
1904sub_l1s2:
1905        bt     rax, 62          ; check if montgomery first
1906        jc     sub_l1ms2
1907sub_l1ns2:
1908        mov r11b, 0x80
1909        shl r11, 56
1910        mov [rdi], r11
1911
1912        add rsi, 8
1913        movsx rdx, ecx
1914        add rdi, 8
1915        cmp rdx, 0
1916        
1917        jns tmp_3
1918        neg rdx
1919        call rawAddLS
1920        sub rdi, 8
1921        sub rsi, 8
1922        ret
1923tmp_3:
1924        call rawSubLS
1925        sub rdi, 8
1926        sub rsi, 8
1927        ret
1928
1929
1930sub_l1ms2:
1931        bt     rcx, 62          ; check if montgomery second
1932        jc     sub_l1ms2m
1933sub_l1ms2n:
1934        mov r11b, 0xC0
1935        shl r11, 56
1936        mov [rdi], r11
1937        push rdi
1938        mov  rdi, rdx
1939        call Fr_toMontgomery
1940        mov  rdx, rdi
1941        pop  rdi
1942
1943        add rdi, 8
1944        add rsi, 8
1945        add rdx, 8
1946        call rawSubLL
1947        sub rdi, 8
1948        sub rsi, 8
1949        ret
1950
1951
1952sub_l1ms2m:
1953        mov r11b, 0xC0
1954        shl r11, 56
1955        mov [rdi], r11
1956
1957        add rdi, 8
1958        add rsi, 8
1959        add rdx, 8
1960        call rawSubLL
1961        sub rdi, 8
1962        sub rsi, 8
1963        ret
1964
1965
1966
1967;;;;;;;;
1968sub_s1l2:
1969        bt     rcx, 62          ; check if montgomery first
1970        jc     sub_s1l2m
1971sub_s1l2n:
1972        mov r11b, 0x80
1973        shl r11, 56
1974        mov [rdi], r11
1975
1976        cmp eax, 0
1977        
1978        js tmp_4
1979
1980        ; First Operand is positive
1981        push rsi
1982        add rdi, 8
1983        movsx rsi, eax
1984        add rdx, 8
1985        call rawSubSL
1986        sub rdi, 8
1987        pop rsi
1988        ret
1989
1990tmp_4:   ; First operand is negative
1991        push rsi
1992        lea rsi, [rdx + 8]
1993        movsx rdx, eax
1994        add rdi, 8
1995        neg rdx
1996        call rawNegLS
1997        sub rdi, 8
1998        pop rsi
1999        ret
2000
2001
2002sub_s1l2m:
2003        bt     rax, 62          ; check if montgomery second
2004        jc     sub_s1ml2m
2005sub_s1nl2m:
2006        mov r11b, 0xC0
2007        shl r11, 56
2008        mov [rdi], r11
2009        push rdi
2010        mov  rdi, rsi
2011        mov  rsi, rdx
2012        call Fr_toMontgomery
2013        mov  rdx, rsi
2014        mov  rsi, rdi
2015        pop  rdi
2016
2017        add rdi, 8
2018        add rsi, 8
2019        add rdx, 8
2020        call rawSubLL
2021        sub rdi, 8
2022        sub rsi, 8
2023        ret
2024
2025
2026sub_s1ml2m:
2027        mov r11b, 0xC0
2028        shl r11, 56
2029        mov [rdi], r11
2030
2031        add rdi, 8
2032        add rsi, 8
2033        add rdx, 8
2034        call rawSubLL
2035        sub rdi, 8
2036        sub rsi, 8
2037        ret
2038
2039
2040;;;;
2041sub_l1l2:
2042        bt     rax, 62          ; check if montgomery first
2043        jc     sub_l1ml2
2044sub_l1nl2:
2045        bt     rcx, 62          ; check if montgomery second
2046        jc     sub_l1nl2m
2047sub_l1nl2n:
2048        mov r11b, 0x80
2049        shl r11, 56
2050        mov [rdi], r11
2051
2052        add rdi, 8
2053        add rsi, 8
2054        add rdx, 8
2055        call rawSubLL
2056        sub rdi, 8
2057        sub rsi, 8
2058        ret
2059
2060
2061sub_l1nl2m:
2062        mov r11b, 0xC0
2063        shl r11, 56
2064        mov [rdi], r11
2065        push rdi
2066        mov  rdi, rsi
2067        mov  rsi, rdx
2068        call Fr_toMontgomery
2069        mov  rdx, rsi
2070        mov  rsi, rdi
2071        pop  rdi
2072
2073        add rdi, 8
2074        add rsi, 8
2075        add rdx, 8
2076        call rawSubLL
2077        sub rdi, 8
2078        sub rsi, 8
2079        ret
2080
2081
2082sub_l1ml2:
2083        bt     rcx, 62          ; check if montgomery seconf
2084        jc     sub_l1ml2m
2085sub_l1ml2n:
2086        mov r11b, 0xC0
2087        shl r11, 56
2088        mov [rdi], r11
2089        push rdi
2090        mov  rdi, rdx
2091        call Fr_toMontgomery
2092        mov  rdx, rdi
2093        pop  rdi
2094
2095        add rdi, 8
2096        add rsi, 8
2097        add rdx, 8
2098        call rawSubLL
2099        sub rdi, 8
2100        sub rsi, 8
2101        ret
2102
2103
2104sub_l1ml2m:
2105        mov r11b, 0xC0
2106        shl r11, 56
2107        mov [rdi], r11
2108
2109        add rdi, 8
2110        add rsi, 8
2111        add rdx, 8
2112        call rawSubLL
2113        sub rdi, 8
2114        sub rsi, 8
2115        ret
2116
2117
2118
2119;;;;;;;;;;;;;;;;;;;;;;
2120; rawSubLS
2121;;;;;;;;;;;;;;;;;;;;;;
2122; Substracts a short element from the long element
2123; Params:
2124;   rdi <= Pointer to the long data of result
2125;   rsi <= Pointer to the long data of element 1 where will be substracted
2126;   rdx <= Value to be substracted
2127;   [rdi] = [rsi] - rdx
2128; Modified Registers:
2129;    rax
2130;;;;;;;;;;;;;;;;;;;;;;
2131rawSubLS:
2132        ; Substract first digit
2133
2134        mov rax, [rsi]
2135        sub rax, rdx
2136        mov [rdi] ,rax
2137        mov rdx, 0
2138
2139        mov rax, [rsi + 8]
2140        sbb rax, rdx
2141        mov [rdi + 8], rax
2142
2143        mov rax, [rsi + 16]
2144        sbb rax, rdx
2145        mov [rdi + 16], rax
2146
2147        mov rax, [rsi + 24]
2148        sbb rax, rdx
2149        mov [rdi + 24], rax
2150
2151        jnc rawSubLS_done   ; if overflow, add q
2152
2153        ; Add q
2154rawSubLS_aq:
2155
2156        mov rax, [q + 0]
2157        add [rdi + 0], rax
2158
2159        mov rax, [q + 8]
2160        adc [rdi + 8], rax
2161
2162        mov rax, [q + 16]
2163        adc [rdi + 16], rax
2164
2165        mov rax, [q + 24]
2166        adc [rdi + 24], rax
2167
2168rawSubLS_done:
2169        ret
2170
2171
2172;;;;;;;;;;;;;;;;;;;;;;
2173; rawSubSL
2174;;;;;;;;;;;;;;;;;;;;;;
2175; Substracts a long element from a short element
2176; Params:
2177;   rdi <= Pointer to the long data of result
2178;   rsi <= Value from where will bo substracted
2179;   rdx <= Pointer to long of the value to be substracted
2180;
2181;   [rdi] = rsi - [rdx]
2182; Modified Registers:
2183;    rax
2184;;;;;;;;;;;;;;;;;;;;;;
2185rawSubSL:
2186        ; Substract first digit
2187        sub rsi, [rdx]
2188        mov [rdi] ,rsi
2189
2190
2191        mov rax, 0
2192        sbb rax, [rdx + 8]
2193        mov [rdi + 8], rax
2194
2195        mov rax, 0
2196        sbb rax, [rdx + 16]
2197        mov [rdi + 16], rax
2198
2199        mov rax, 0
2200        sbb rax, [rdx + 24]
2201        mov [rdi + 24], rax
2202
2203        jnc rawSubSL_done   ; if overflow, add q
2204
2205        ; Add q
2206rawSubSL_aq:
2207
2208        mov rax, [q + 0]
2209        add [rdi + 0], rax
2210
2211        mov rax, [q + 8]
2212        adc [rdi + 8], rax
2213
2214        mov rax, [q + 16]
2215        adc [rdi + 16], rax
2216
2217        mov rax, [q + 24]
2218        adc [rdi + 24], rax
2219
2220rawSubSL_done:
2221        ret
2222
2223;;;;;;;;;;;;;;;;;;;;;;
2224; rawSubLL
2225;;;;;;;;;;;;;;;;;;;;;;
2226; Substracts a long element from a short element
2227; Params:
2228;   rdi <= Pointer to the long data of result
2229;   rsi <= Pointer to long from where substracted
2230;   rdx <= Pointer to long of the value to be substracted
2231;
2232;   [rdi] = [rsi] - [rdx]
2233; Modified Registers:
2234;    rax
2235;;;;;;;;;;;;;;;;;;;;;;
2236rawSubLL:
2237        ; Substract first digit
2238
2239        mov rax, [rsi + 0]
2240        sub rax, [rdx + 0]
2241        mov [rdi + 0], rax
2242
2243        mov rax, [rsi + 8]
2244        sbb rax, [rdx + 8]
2245        mov [rdi + 8], rax
2246
2247        mov rax, [rsi + 16]
2248        sbb rax, [rdx + 16]
2249        mov [rdi + 16], rax
2250
2251        mov rax, [rsi + 24]
2252        sbb rax, [rdx + 24]
2253        mov [rdi + 24], rax
2254
2255        jnc rawSubLL_done   ; if overflow, add q
2256
2257        ; Add q
2258rawSubLL_aq:
2259
2260        mov rax, [q + 0]
2261        add [rdi + 0], rax
2262
2263        mov rax, [q + 8]
2264        adc [rdi + 8], rax
2265
2266        mov rax, [q + 16]
2267        adc [rdi + 16], rax
2268
2269        mov rax, [q + 24]
2270        adc [rdi + 24], rax
2271
2272rawSubLL_done:
2273        ret
2274
2275;;;;;;;;;;;;;;;;;;;;;;
2276; rawNegLS
2277;;;;;;;;;;;;;;;;;;;;;;
2278; Substracts a long element and a short element form 0
2279; Params:
2280;   rdi <= Pointer to the long data of result
2281;   rsi <= Pointer to long from where substracted
2282;   rdx <= short value to be substracted too
2283;
2284;   [rdi] = -[rsi] - rdx
2285; Modified Registers:
2286;    rax
2287;;;;;;;;;;;;;;;;;;;;;;
2288rawNegLS:
2289        mov rax, [q]
2290        sub rax, rdx
2291        mov [rdi], rax
2292
2293        mov rax, [q + 8 ]
2294        sbb rax, 0
2295        mov [rdi + 8], rax
2296
2297        mov rax, [q + 16 ]
2298        sbb rax, 0
2299        mov [rdi + 16], rax
2300
2301        mov rax, [q + 24 ]
2302        sbb rax, 0
2303        mov [rdi + 24], rax
2304
2305        setc dl
2306
2307
2308        mov rax, [rdi + 0 ]
2309        sub rax, [rsi + 0]
2310        mov [rdi + 0], rax
2311
2312        mov rax, [rdi + 8 ]
2313        sbb rax, [rsi + 8]
2314        mov [rdi + 8], rax
2315
2316        mov rax, [rdi + 16 ]
2317        sbb rax, [rsi + 16]
2318        mov [rdi + 16], rax
2319
2320        mov rax, [rdi + 24 ]
2321        sbb rax, [rsi + 24]
2322        mov [rdi + 24], rax
2323
2324
2325        setc dh
2326        or dl, dh
2327        jz rawNegSL_done
2328
2329        ; it is a negative value, so add q
2330
2331        mov rax, [q + 0]
2332        add [rdi + 0], rax
2333
2334        mov rax, [q + 8]
2335        adc [rdi + 8], rax
2336
2337        mov rax, [q + 16]
2338        adc [rdi + 16], rax
2339
2340        mov rax, [q + 24]
2341        adc [rdi + 24], rax
2342
2343
2344rawNegSL_done:
2345        ret
2346
2347
2348
2349
2350
2351
2352
2353;;;;;;;;;;;;;;;;;;;;;;
2354; neg
2355;;;;;;;;;;;;;;;;;;;;;;
2356; Adds two elements of any kind
2357; Params:
2358;   rsi <= Pointer to element to be negated
2359;   rdi <= Pointer to result
2360;   [rdi] = -[rsi]
2361;;;;;;;;;;;;;;;;;;;;;;
2362Fr_neg:
2363        mov    rax, [rsi]
2364        bt     rax, 63          ; Check if is short first operand
2365        jc     neg_l
2366
2367neg_s:                          ; Operand is short
2368
2369        neg    eax
2370        jo     neg_manageOverflow   ; Check if overflow. (0x80000000 is the only case)
2371
2372        mov    [rdi], rax           ; not necessary to adjust so just save and return
2373        ret
2374
2375neg_manageOverflow:                 ; Do the operation in 64 bits
2376        push   rsi
2377        movsx  rsi, eax
2378        neg    rsi
2379        call   rawCopyS2L
2380        pop    rsi
2381        ret
2382
2383
2384
2385neg_l:
2386        mov [rdi], rax          ; Copy the type
2387
2388        add rdi, 8
2389        add rsi, 8
2390        call rawNegL
2391        sub rdi, 8
2392        sub rsi, 8
2393        ret
2394
2395
2396
2397;;;;;;;;;;;;;;;;;;;;;;
2398; rawNeg
2399;;;;;;;;;;;;;;;;;;;;;;
2400; Negates a value
2401; Params:
2402;   rdi <= Pointer to the long data of result
2403;   rsi <= Pointer to the long data of element 1
2404;
2405;   [rdi] = - [rsi]
2406;;;;;;;;;;;;;;;;;;;;;;
2407rawNegL:
2408        ; Compare is zero
2409
2410        xor rax, rax
2411
2412        cmp [rsi + 0], rax
2413        jnz doNegate
2414
2415        cmp [rsi + 8], rax
2416        jnz doNegate
2417
2418        cmp [rsi + 16], rax
2419        jnz doNegate
2420
2421        cmp [rsi + 24], rax
2422        jnz doNegate
2423
2424        ; it's zero so just set to zero
2425
2426        mov [rdi + 0], rax
2427
2428        mov [rdi + 8], rax
2429
2430        mov [rdi + 16], rax
2431
2432        mov [rdi + 24], rax
2433
2434        ret
2435doNegate:
2436
2437        mov rax, [q + 0]
2438        sub rax, [rsi + 0]
2439        mov [rdi + 0], rax
2440
2441        mov rax, [q + 8]
2442        sbb rax, [rsi + 8]
2443        mov [rdi + 8], rax
2444
2445        mov rax, [q + 16]
2446        sbb rax, [rsi + 16]
2447        mov [rdi + 16], rax
2448
2449        mov rax, [q + 24]
2450        sbb rax, [rsi + 24]
2451        mov [rdi + 24], rax
2452
2453        ret
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473;;;;;;;;;;;;;;;;;;;;;;
2474; square
2475;;;;;;;;;;;;;;;;;;;;;;
2476; Squares a field element
2477; Params:
2478;   rsi <= Pointer to element 1
2479;   rdi <= Pointer to result
2480;   [rdi] = [rsi] * [rsi]
2481; Modified Registers:
2482;    r8, r9, 10, r11, rax, rcx
2483;;;;;;;;;;;;;;;;;;;;;;
2484Fr_square:
2485        mov    r8, [rsi]
2486        bt     r8, 63          ; Check if is short first operand
2487        jc     square_l1
2488
2489square_s1:                       ; Both operands are short
2490
2491        xor    rax, rax
2492        mov    eax, r8d
2493        imul   eax
2494        jo     square_manageOverflow   ; rsi already is the 64bits result
2495
2496        mov    [rdi], rax       ; not necessary to adjust so just save and return
2497
2498square_manageOverflow:                 ; Do the operation in 64 bits
2499        push   rsi
2500        movsx  rax, r8d
2501        imul   rax
2502        mov    rsi, rax
2503        call   rawCopyS2L
2504        pop    rsi
2505
2506        ret
2507
2508square_l1:
2509        bt     r8, 62          ; check if montgomery first
2510        jc     square_l1m
2511square_l1n:
2512        mov r11b, 0xC0
2513        shl r11, 56
2514        mov [rdi], r11
2515
2516        add rdi, 8
2517        add rsi, 8
2518        call rawMontgomerySquare
2519        sub rdi, 8
2520        sub rsi, 8
2521
2522
2523        push rsi
2524        add rdi, 8
2525        mov rsi, rdi
2526        lea rdx, [R3]
2527        call rawMontgomeryMul
2528        sub rdi, 8
2529        pop rsi
2530
2531        ret
2532
2533square_l1m:
2534        mov r11b, 0xC0
2535        shl r11, 56
2536        mov [rdi], r11
2537
2538        add rdi, 8
2539        add rsi, 8
2540        call rawMontgomerySquare
2541        sub rdi, 8
2542        sub rsi, 8
2543
2544        ret
2545
2546
2547
2548;;;;;;;;;;;;;;;;;;;;;;
2549; mul
2550;;;;;;;;;;;;;;;;;;;;;;
2551; Multiplies two elements of any kind
2552; Params:
2553;   rsi <= Pointer to element 1
2554;   rdx <= Pointer to element 2
2555;   rdi <= Pointer to result
2556;   [rdi] = [rsi] * [rdi]
2557; Modified Registers:
2558;    r8, r9, 10, r11, rax, rcx
2559;;;;;;;;;;;;;;;;;;;;;;
2560Fr_mul:
2561        mov    r8, [rsi]
2562        mov    r9, [rdx]
2563        bt     r8, 63          ; Check if is short first operand
2564        jc     mul_l1
2565        bt     r9, 63          ; Check if is short second operand
2566        jc     mul_s1l2
2567
2568mul_s1s2:                       ; Both operands are short
2569
2570        xor    rax, rax
2571        mov    eax, r8d
2572        imul   r9d
2573        jo     mul_manageOverflow   ; rsi already is the 64bits result
2574
2575        mov    [rdi], rax       ; not necessary to adjust so just save and return
2576
2577mul_manageOverflow:                 ; Do the operation in 64 bits
2578        push   rsi
2579        movsx  rax, r8d
2580        movsx  rcx, r9d
2581        imul   rcx
2582        mov    rsi, rax
2583        call   rawCopyS2L
2584        pop    rsi
2585
2586        ret
2587
2588mul_l1:
2589        bt     r9, 63          ; Check if is short second operand
2590        jc     mul_l1l2
2591
2592;;;;;;;;
2593mul_l1s2:
2594        bt     r8, 62          ; check if montgomery first
2595        jc     mul_l1ms2
2596mul_l1ns2:
2597        bt     r9, 62          ; check if montgomery first
2598        jc     mul_l1ns2m
2599mul_l1ns2n:
2600        mov r11b, 0xC0
2601        shl r11, 56
2602        mov [rdi], r11
2603
2604        push rsi
2605        add rsi, 8
2606        movsx rdx, r9d
2607        add rdi, 8
2608        cmp rdx, 0
2609        
2610        jns tmp_5
2611        neg rdx
2612        call rawMontgomeryMul1
2613        mov rsi, rdi
2614        call rawNegL
2615        sub rdi, 8
2616        pop rsi
2617        
2618        jmp tmp_6
2619tmp_5:
2620        call rawMontgomeryMul1
2621        sub rdi, 8
2622        pop rsi
2623tmp_6:
2624
2625
2626
2627        push rsi
2628        add rdi, 8
2629        mov rsi, rdi
2630        lea rdx, [R3]
2631        call rawMontgomeryMul
2632        sub rdi, 8
2633        pop rsi
2634
2635        ret
2636
2637
2638mul_l1ns2m:
2639        mov r11b, 0x80
2640        shl r11, 56
2641        mov [rdi], r11
2642
2643        add rdi, 8
2644        add rsi, 8
2645        add rdx, 8
2646        call rawMontgomeryMul
2647        sub rdi, 8
2648        sub rsi, 8
2649
2650        ret
2651
2652
2653mul_l1ms2:
2654        bt     r9, 62          ; check if montgomery second
2655        jc     mul_l1ms2m
2656mul_l1ms2n:
2657        mov r11b, 0x80
2658        shl r11, 56
2659        mov [rdi], r11
2660
2661        push rsi
2662        add rsi, 8
2663        movsx rdx, r9d
2664        add rdi, 8
2665        cmp rdx, 0
2666        
2667        jns tmp_7
2668        neg rdx
2669        call rawMontgomeryMul1
2670        mov rsi, rdi
2671        call rawNegL
2672        sub rdi, 8
2673        pop rsi
2674        
2675        jmp tmp_8
2676tmp_7:
2677        call rawMontgomeryMul1
2678        sub rdi, 8
2679        pop rsi
2680tmp_8:
2681
2682
2683        ret
2684
2685mul_l1ms2m:
2686        mov r11b, 0xC0
2687        shl r11, 56
2688        mov [rdi], r11
2689
2690        add rdi, 8
2691        add rsi, 8
2692        add rdx, 8
2693        call rawMontgomeryMul
2694        sub rdi, 8
2695        sub rsi, 8
2696
2697        ret
2698
2699
2700;;;;;;;;
2701mul_s1l2:
2702        bt     r8, 62          ; check if montgomery first
2703        jc     mul_s1ml2
2704mul_s1nl2:
2705        bt     r9, 62          ; check if montgomery first
2706        jc     mul_s1nl2m
2707mul_s1nl2n:
2708        mov r11b, 0xC0
2709        shl r11, 56
2710        mov [rdi], r11
2711
2712        push rsi
2713        lea rsi, [rdx + 8]
2714        movsx rdx, r8d
2715        add rdi, 8
2716        cmp rdx, 0
2717        
2718        jns tmp_9
2719        neg rdx
2720        call rawMontgomeryMul1
2721        mov rsi, rdi
2722        call rawNegL
2723        sub rdi, 8
2724        pop rsi
2725        
2726        jmp tmp_10
2727tmp_9:
2728        call rawMontgomeryMul1
2729        sub rdi, 8
2730        pop rsi
2731tmp_10:
2732
2733
2734
2735        push rsi
2736        add rdi, 8
2737        mov rsi, rdi
2738        lea rdx, [R3]
2739        call rawMontgomeryMul
2740        sub rdi, 8
2741        pop rsi
2742
2743        ret
2744
2745mul_s1nl2m:
2746        mov r11b, 0x80
2747        shl r11, 56
2748        mov [rdi], r11
2749
2750        push rsi
2751        lea rsi, [rdx + 8]
2752        movsx rdx, r8d
2753        add rdi, 8
2754        cmp rdx, 0
2755        
2756        jns tmp_11
2757        neg rdx
2758        call rawMontgomeryMul1
2759        mov rsi, rdi
2760        call rawNegL
2761        sub rdi, 8
2762        pop rsi
2763        
2764        jmp tmp_12
2765tmp_11:
2766        call rawMontgomeryMul1
2767        sub rdi, 8
2768        pop rsi
2769tmp_12:
2770
2771
2772        ret
2773
2774mul_s1ml2:
2775        bt     r9, 62          ; check if montgomery first
2776        jc     mul_s1ml2m
2777mul_s1ml2n:
2778        mov r11b, 0x80
2779        shl r11, 56
2780        mov [rdi], r11
2781
2782        add rdi, 8
2783        add rsi, 8
2784        add rdx, 8
2785        call rawMontgomeryMul
2786        sub rdi, 8
2787        sub rsi, 8
2788
2789        ret
2790
2791mul_s1ml2m:
2792        mov r11b, 0xC0
2793        shl r11, 56
2794        mov [rdi], r11
2795
2796        add rdi, 8
2797        add rsi, 8
2798        add rdx, 8
2799        call rawMontgomeryMul
2800        sub rdi, 8
2801        sub rsi, 8
2802
2803        ret
2804
2805;;;;
2806mul_l1l2:
2807        bt     r8, 62          ; check if montgomery first
2808        jc     mul_l1ml2
2809mul_l1nl2:
2810        bt     r9, 62          ; check if montgomery second
2811        jc     mul_l1nl2m
2812mul_l1nl2n:
2813        mov r11b, 0xC0
2814        shl r11, 56
2815        mov [rdi], r11
2816
2817        add rdi, 8
2818        add rsi, 8
2819        add rdx, 8
2820        call rawMontgomeryMul
2821        sub rdi, 8
2822        sub rsi, 8
2823
2824
2825        push rsi
2826        add rdi, 8
2827        mov rsi, rdi
2828        lea rdx, [R3]
2829        call rawMontgomeryMul
2830        sub rdi, 8
2831        pop rsi
2832
2833        ret
2834
2835mul_l1nl2m:
2836        mov r11b, 0x80
2837        shl r11, 56
2838        mov [rdi], r11
2839
2840        add rdi, 8
2841        add rsi, 8
2842        add rdx, 8
2843        call rawMontgomeryMul
2844        sub rdi, 8
2845        sub rsi, 8
2846
2847        ret
2848
2849mul_l1ml2:
2850        bt     r9, 62          ; check if montgomery seconf
2851        jc     mul_l1ml2m
2852mul_l1ml2n:
2853        mov r11b, 0x80
2854        shl r11, 56
2855        mov [rdi], r11
2856
2857        add rdi, 8
2858        add rsi, 8
2859        add rdx, 8
2860        call rawMontgomeryMul
2861        sub rdi, 8
2862        sub rsi, 8
2863
2864        ret
2865
2866mul_l1ml2m:
2867        mov r11b, 0xC0
2868        shl r11, 56
2869        mov [rdi], r11
2870
2871        add rdi, 8
2872        add rsi, 8
2873        add rdx, 8
2874        call rawMontgomeryMul
2875        sub rdi, 8
2876        sub rsi, 8
2877
2878        ret
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896;;;;;;;;;;;;;;;;;;;;;;
2897; band
2898;;;;;;;;;;;;;;;;;;;;;;
2899; Adds two elements of any kind
2900; Params:
2901;   rsi <= Pointer to element 1
2902;   rdx <= Pointer to element 2
2903;   rdi <= Pointer to result
2904; Modified Registers:
2905;    r8, r9, 10, r11, rax, rcx
2906;;;;;;;;;;;;;;;;;;;;;;
2907Fr_band:
2908        mov    r8, [rsi]
2909        mov    r9, [rdx]
2910        bt     r8, 63          ; Check if is short first operand
2911        jc     and_l1
2912        bt     r9, 63          ; Check if is short second operand
2913        jc     and_s1l2
2914
2915and_s1s2:
2916
2917        cmp    r8d, 0
2918        
2919        js     tmp_13
2920
2921        cmp    r9d, 0
2922        js     tmp_13
2923        xor    rdx, rdx         ; both ops are positive so do the op and return
2924        mov    edx, r8d
2925        and    edx, r9d
2926        mov    [rdi], rdx       ; not necessary to adjust so just save and return
2927        ret
2928
2929tmp_13:
2930        mov r11b, 0x80
2931        shl r11, 56
2932        mov [rdi], r11
2933        push  rdi
2934        push   rsi
2935        mov   rdi, rdx
2936        movsx rsi, r9d
2937        call  rawCopyS2L
2938        mov   rdx, rdi
2939        pop   rsi
2940        pop   rdi
2941        push  rdi
2942        push  rdx
2943        mov   rdi, rsi
2944        movsx rsi, r8d
2945        call  rawCopyS2L
2946        mov   rsi, rdi
2947        pop   rdx
2948        pop   rdi
2949
2950
2951        mov rax, [rsi + 8]
2952        and rax, [rdx + 8]
2953
2954        mov    [rdi + 8 ], rax
2955
2956        mov rax, [rsi + 16]
2957        and rax, [rdx + 16]
2958
2959        mov    [rdi + 16 ], rax
2960
2961        mov rax, [rsi + 24]
2962        and rax, [rdx + 24]
2963
2964        mov    [rdi + 24 ], rax
2965
2966        mov rax, [rsi + 32]
2967        and rax, [rdx + 32]
2968
2969        and    rax, [lboMask]
2970
2971        mov    [rdi + 32 ], rax
2972
2973        ret
2974
2975
2976
2977
2978
2979
2980and_l1:
2981        bt     r9, 63          ; Check if is short second operand
2982        jc     and_l1l2
2983
2984
2985and_l1s2:
2986        bt     r8, 62          ; check if montgomery first
2987        jc     and_l1ms2
2988and_l1ns2:
2989        mov r11b, 0x80
2990        shl r11, 56
2991        mov [rdi], r11
2992
2993        cmp    r9d, 0
2994        
2995        js     tmp_14
2996        movsx  rax, r9d
2997        and rax, [rsi +8]
2998        mov    [rdi+8], rax
2999
3000        xor    rax, rax
3001        and rax, [rsi + 16];
3002
3003        mov    [rdi + 16 ], rax;
3004
3005        xor    rax, rax
3006        and rax, [rsi + 24];
3007
3008        mov    [rdi + 24 ], rax;
3009
3010        xor    rax, rax
3011        and rax, [rsi + 32];
3012
3013        and    rax, [lboMask] ;
3014
3015        mov    [rdi + 32 ], rax;
3016
3017        ret
3018
3019tmp_14:
3020        push  rdi
3021        push   rsi
3022        mov   rdi, rdx
3023        movsx rsi, r9d
3024        call  rawCopyS2L
3025        mov   rdx, rdi
3026        pop   rsi
3027        pop   rdi
3028        mov r11b, 0x80
3029        shl r11, 56
3030        mov [rdi], r11
3031
3032
3033        mov rax, [rsi + 8]
3034        and rax, [rdx + 8]
3035
3036        mov    [rdi + 8 ], rax
3037
3038        mov rax, [rsi + 16]
3039        and rax, [rdx + 16]
3040
3041        mov    [rdi + 16 ], rax
3042
3043        mov rax, [rsi + 24]
3044        and rax, [rdx + 24]
3045
3046        mov    [rdi + 24 ], rax
3047
3048        mov rax, [rsi + 32]
3049        and rax, [rdx + 32]
3050
3051        and    rax, [lboMask]
3052
3053        mov    [rdi + 32 ], rax
3054
3055        ret
3056
3057
3058
3059
3060and_l1ms2:
3061        mov r11b, 0x80
3062        shl r11, 56
3063        mov [rdi], r11
3064        push   r9              ; r9 is used in montgomery so we need to save it
3065        push rdi
3066        mov  rdi, rsi
3067        mov  rsi, rdx
3068        call Fr_toNormal
3069        mov  rdx, rsi
3070        mov  rsi, rdi
3071        pop  rdi
3072        pop    r9
3073
3074        cmp    r9d, 0
3075        
3076        js     tmp_15
3077        movsx  rax, r9d
3078        and rax, [rsi +8]
3079        mov    [rdi+8], rax
3080
3081        xor    rax, rax
3082        and rax, [rsi + 16];
3083
3084        mov    [rdi + 16 ], rax;
3085
3086        xor    rax, rax
3087        and rax, [rsi + 24];
3088
3089        mov    [rdi + 24 ], rax;
3090
3091        xor    rax, rax
3092        and rax, [rsi + 32];
3093
3094        and    rax, [lboMask] ;
3095
3096        mov    [rdi + 32 ], rax;
3097
3098        ret
3099
3100tmp_15:
3101        push  rdi
3102        push   rsi
3103        mov   rdi, rdx
3104        movsx rsi, r9d
3105        call  rawCopyS2L
3106        mov   rdx, rdi
3107        pop   rsi
3108        pop   rdi
3109        mov r11b, 0x80
3110        shl r11, 56
3111        mov [rdi], r11
3112
3113
3114        mov rax, [rsi + 8]
3115        and rax, [rdx + 8]
3116
3117        mov    [rdi + 8 ], rax
3118
3119        mov rax, [rsi + 16]
3120        and rax, [rdx + 16]
3121
3122        mov    [rdi + 16 ], rax
3123
3124        mov rax, [rsi + 24]
3125        and rax, [rdx + 24]
3126
3127        mov    [rdi + 24 ], rax
3128
3129        mov rax, [rsi + 32]
3130        and rax, [rdx + 32]
3131
3132        and    rax, [lboMask]
3133
3134        mov    [rdi + 32 ], rax
3135
3136        ret
3137
3138
3139
3140
3141
3142and_s1l2:
3143        bt     r9, 62          ; check if montgomery first
3144        jc     and_s1l2m
3145and_s1l2n:
3146        mov r11b, 0x80
3147        shl r11, 56
3148        mov [rdi], r11
3149
3150        cmp    r8d, 0
3151        
3152        js     tmp_16
3153        movsx  rax, r8d
3154        and rax, [rdx +8]
3155        mov    [rdi+8], rax
3156
3157        xor    rax, rax
3158        and rax, [rdx + 16]
3159
3160        mov    [rdi + 16 ], rax
3161
3162        xor    rax, rax
3163        and rax, [rdx + 24]
3164
3165        mov    [rdi + 24 ], rax
3166
3167        xor    rax, rax
3168        and rax, [rdx + 32]
3169
3170        and    rax, [lboMask]
3171
3172        mov    [rdi + 32 ], rax
3173
3174        ret
3175
3176tmp_16:
3177        push  rdi
3178        push  rdx
3179        mov   rdi, rsi
3180        movsx rsi, r8d
3181        call  rawCopyS2L
3182        mov   rsi, rdi
3183        pop   rdx
3184        pop   rdi
3185        mov r11b, 0x80
3186        shl r11, 56
3187        mov [rdi], r11
3188
3189
3190        mov rax, [rsi + 8]
3191        and rax, [rdx + 8]
3192
3193        mov    [rdi + 8 ], rax
3194
3195        mov rax, [rsi + 16]
3196        and rax, [rdx + 16]
3197
3198        mov    [rdi + 16 ], rax
3199
3200        mov rax, [rsi + 24]
3201        and rax, [rdx + 24]
3202
3203        mov    [rdi + 24 ], rax
3204
3205        mov rax, [rsi + 32]
3206        and rax, [rdx + 32]
3207
3208        and    rax, [lboMask]
3209
3210        mov    [rdi + 32 ], rax
3211
3212        ret
3213
3214
3215
3216
3217and_s1l2m:
3218        mov r11b, 0x80
3219        shl r11, 56
3220        mov [rdi], r11
3221        push   r8             ; r8 is used in montgomery so we need to save it
3222        push rdi
3223        mov  rdi, rdx
3224        call Fr_toNormal
3225        mov  rdx, rdi
3226        pop  rdi
3227        pop    r8
3228
3229        cmp    r8d, 0
3230        
3231        js     tmp_17
3232        movsx  rax, r8d
3233        and rax, [rdx +8]
3234        mov    [rdi+8], rax
3235
3236        xor    rax, rax
3237        and rax, [rdx + 16]
3238
3239        mov    [rdi + 16 ], rax
3240
3241        xor    rax, rax
3242        and rax, [rdx + 24]
3243
3244        mov    [rdi + 24 ], rax
3245
3246        xor    rax, rax
3247        and rax, [rdx + 32]
3248
3249        and    rax, [lboMask]
3250
3251        mov    [rdi + 32 ], rax
3252
3253        ret
3254
3255tmp_17:
3256        push  rdi
3257        push  rdx
3258        mov   rdi, rsi
3259        movsx rsi, r8d
3260        call  rawCopyS2L
3261        mov   rsi, rdi
3262        pop   rdx
3263        pop   rdi
3264        mov r11b, 0x80
3265        shl r11, 56
3266        mov [rdi], r11
3267
3268
3269        mov rax, [rsi + 8]
3270        and rax, [rdx + 8]
3271
3272        mov    [rdi + 8 ], rax
3273
3274        mov rax, [rsi + 16]
3275        and rax, [rdx + 16]
3276
3277        mov    [rdi + 16 ], rax
3278
3279        mov rax, [rsi + 24]
3280        and rax, [rdx + 24]
3281
3282        mov    [rdi + 24 ], rax
3283
3284        mov rax, [rsi + 32]
3285        and rax, [rdx + 32]
3286
3287        and    rax, [lboMask]
3288
3289        mov    [rdi + 32 ], rax
3290
3291        ret
3292
3293
3294
3295
3296
3297and_l1l2:
3298        bt     r8, 62          ; check if montgomery first
3299        jc     and_l1ml2
3300        bt     r9, 62          ; check if montgomery first
3301        jc     and_l1nl2m
3302and_l1nl2n:
3303        mov r11b, 0x80
3304        shl r11, 56
3305        mov [rdi], r11
3306
3307
3308        mov rax, [rsi + 8]
3309        and rax, [rdx + 8]
3310
3311        mov    [rdi + 8 ], rax
3312
3313        mov rax, [rsi + 16]
3314        and rax, [rdx + 16]
3315
3316        mov    [rdi + 16 ], rax
3317
3318        mov rax, [rsi + 24]
3319        and rax, [rdx + 24]
3320
3321        mov    [rdi + 24 ], rax
3322
3323        mov rax, [rsi + 32]
3324        and rax, [rdx + 32]
3325
3326        and    rax, [lboMask]
3327
3328        mov    [rdi + 32 ], rax
3329
3330        ret
3331
3332
3333and_l1nl2m:
3334        mov r11b, 0x80
3335        shl r11, 56
3336        mov [rdi], r11
3337        push rdi
3338        mov  rdi, rdx
3339        call Fr_toNormal
3340        mov  rdx, rdi
3341        pop  rdi
3342
3343
3344        mov rax, [rsi + 8]
3345        and rax, [rdx + 8]
3346
3347        mov    [rdi + 8 ], rax
3348
3349        mov rax, [rsi + 16]
3350        and rax, [rdx + 16]
3351
3352        mov    [rdi + 16 ], rax
3353
3354        mov rax, [rsi + 24]
3355        and rax, [rdx + 24]
3356
3357        mov    [rdi + 24 ], rax
3358
3359        mov rax, [rsi + 32]
3360        and rax, [rdx + 32]
3361
3362        and    rax, [lboMask]
3363
3364        mov    [rdi + 32 ], rax
3365
3366        ret
3367
3368
3369and_l1ml2:
3370        bt     r9, 62          ; check if montgomery first
3371        jc     and_l1ml2m
3372and_l1ml2n:
3373        mov r11b, 0x80
3374        shl r11, 56
3375        mov [rdi], r11
3376        push rdi
3377        mov  rdi, rsi
3378        mov  rsi, rdx
3379        call Fr_toNormal
3380        mov  rdx, rsi
3381        mov  rsi, rdi
3382        pop  rdi
3383
3384
3385        mov rax, [rsi + 8]
3386        and rax, [rdx + 8]
3387
3388        mov    [rdi + 8 ], rax
3389
3390        mov rax, [rsi + 16]
3391        and rax, [rdx + 16]
3392
3393        mov    [rdi + 16 ], rax
3394
3395        mov rax, [rsi + 24]
3396        and rax, [rdx + 24]
3397
3398        mov    [rdi + 24 ], rax
3399
3400        mov rax, [rsi + 32]
3401        and rax, [rdx + 32]
3402
3403        and    rax, [lboMask]
3404
3405        mov    [rdi + 32 ], rax
3406
3407        ret
3408
3409
3410and_l1ml2m:
3411        mov r11b, 0x80
3412        shl r11, 56
3413        mov [rdi], r11
3414        push rdi
3415        mov  rdi, rsi
3416        mov  rsi, rdx
3417        call Fr_toNormal
3418        mov  rdx, rsi
3419        mov  rsi, rdi
3420        pop  rdi
3421        push rdi
3422        mov  rdi, rdx
3423        call Fr_toNormal
3424        mov  rdx, rdi
3425        pop  rdi
3426
3427
3428        mov rax, [rsi + 8]
3429        and rax, [rdx + 8]
3430
3431        mov    [rdi + 8 ], rax
3432
3433        mov rax, [rsi + 16]
3434        and rax, [rdx + 16]
3435
3436        mov    [rdi + 16 ], rax
3437
3438        mov rax, [rsi + 24]
3439        and rax, [rdx + 24]
3440
3441        mov    [rdi + 24 ], rax
3442
3443        mov rax, [rsi + 32]
3444        and rax, [rdx + 32]
3445
3446        and    rax, [lboMask]
3447
3448        mov    [rdi + 32 ], rax
3449
3450        ret
3451
3452
3453
3454;;;;;;;;;;;;;;;;;;;;;;
3455; bor
3456;;;;;;;;;;;;;;;;;;;;;;
3457; Adds two elements of any kind
3458; Params:
3459;   rsi <= Pointer to element 1
3460;   rdx <= Pointer to element 2
3461;   rdi <= Pointer to result
3462; Modified Registers:
3463;    r8, r9, 10, r11, rax, rcx
3464;;;;;;;;;;;;;;;;;;;;;;
3465Fr_bor:
3466        mov    r8, [rsi]
3467        mov    r9, [rdx]
3468        bt     r8, 63          ; Check if is short first operand
3469        jc     or_l1
3470        bt     r9, 63          ; Check if is short second operand
3471        jc     or_s1l2
3472
3473or_s1s2:
3474
3475        cmp    r8d, 0
3476        
3477        js     tmp_18
3478
3479        cmp    r9d, 0
3480        js     tmp_18
3481        xor    rdx, rdx         ; both ops are positive so do the op and return
3482        mov    edx, r8d
3483        or    edx, r9d
3484        mov    [rdi], rdx       ; not necessary to adjust so just save and return
3485        ret
3486
3487tmp_18:
3488        mov r11b, 0x80
3489        shl r11, 56
3490        mov [rdi], r11
3491        push  rdi
3492        push   rsi
3493        mov   rdi, rdx
3494        movsx rsi, r9d
3495        call  rawCopyS2L
3496        mov   rdx, rdi
3497        pop   rsi
3498        pop   rdi
3499        push  rdi
3500        push  rdx
3501        mov   rdi, rsi
3502        movsx rsi, r8d
3503        call  rawCopyS2L
3504        mov   rsi, rdi
3505        pop   rdx
3506        pop   rdi
3507
3508
3509        mov rax, [rsi + 8]
3510        or rax, [rdx + 8]
3511
3512        mov    [rdi + 8 ], rax
3513
3514        mov rax, [rsi + 16]
3515        or rax, [rdx + 16]
3516
3517        mov    [rdi + 16 ], rax
3518
3519        mov rax, [rsi + 24]
3520        or rax, [rdx + 24]
3521
3522        mov    [rdi + 24 ], rax
3523
3524        mov rax, [rsi + 32]
3525        or rax, [rdx + 32]
3526
3527        and    rax, [lboMask]
3528
3529        mov    [rdi + 32 ], rax
3530
3531        ret
3532
3533
3534
3535
3536
3537
3538or_l1:
3539        bt     r9, 63          ; Check if is short second operand
3540        jc     or_l1l2
3541
3542
3543or_l1s2:
3544        bt     r8, 62          ; check if montgomery first
3545        jc     or_l1ms2
3546or_l1ns2:
3547        mov r11b, 0x80
3548        shl r11, 56
3549        mov [rdi], r11
3550
3551        cmp    r9d, 0
3552        
3553        js     tmp_19
3554        movsx  rax, r9d
3555        or rax, [rsi +8]
3556        mov    [rdi+8], rax
3557
3558        xor    rax, rax
3559        or rax, [rsi + 16];
3560
3561        mov    [rdi + 16 ], rax;
3562
3563        xor    rax, rax
3564        or rax, [rsi + 24];
3565
3566        mov    [rdi + 24 ], rax;
3567
3568        xor    rax, rax
3569        or rax, [rsi + 32];
3570
3571        and    rax, [lboMask] ;
3572
3573        mov    [rdi + 32 ], rax;
3574
3575        ret
3576
3577tmp_19:
3578        push  rdi
3579        push   rsi
3580        mov   rdi, rdx
3581        movsx rsi, r9d
3582        call  rawCopyS2L
3583        mov   rdx, rdi
3584        pop   rsi
3585        pop   rdi
3586        mov r11b, 0x80
3587        shl r11, 56
3588        mov [rdi], r11
3589
3590
3591        mov rax, [rsi + 8]
3592        or rax, [rdx + 8]
3593
3594        mov    [rdi + 8 ], rax
3595
3596        mov rax, [rsi + 16]
3597        or rax, [rdx + 16]
3598
3599        mov    [rdi + 16 ], rax
3600
3601        mov rax, [rsi + 24]
3602        or rax, [rdx + 24]
3603
3604        mov    [rdi + 24 ], rax
3605
3606        mov rax, [rsi + 32]
3607        or rax, [rdx + 32]
3608
3609        and    rax, [lboMask]
3610
3611        mov    [rdi + 32 ], rax
3612
3613        ret
3614
3615
3616
3617
3618or_l1ms2:
3619        mov r11b, 0x80
3620        shl r11, 56
3621        mov [rdi], r11
3622        push   r9              ; r9 is used in montgomery so we need to save it
3623        push rdi
3624        mov  rdi, rsi
3625        mov  rsi, rdx
3626        call Fr_toNormal
3627        mov  rdx, rsi
3628        mov  rsi, rdi
3629        pop  rdi
3630        pop    r9
3631
3632        cmp    r9d, 0
3633        
3634        js     tmp_20
3635        movsx  rax, r9d
3636        or rax, [rsi +8]
3637        mov    [rdi+8], rax
3638
3639        xor    rax, rax
3640        or rax, [rsi + 16];
3641
3642        mov    [rdi + 16 ], rax;
3643
3644        xor    rax, rax
3645        or rax, [rsi + 24];
3646
3647        mov    [rdi + 24 ], rax;
3648
3649        xor    rax, rax
3650        or rax, [rsi + 32];
3651
3652        and    rax, [lboMask] ;
3653
3654        mov    [rdi + 32 ], rax;
3655
3656        ret
3657
3658tmp_20:
3659        push  rdi
3660        push   rsi
3661        mov   rdi, rdx
3662        movsx rsi, r9d
3663        call  rawCopyS2L
3664        mov   rdx, rdi
3665        pop   rsi
3666        pop   rdi
3667        mov r11b, 0x80
3668        shl r11, 56
3669        mov [rdi], r11
3670
3671
3672        mov rax, [rsi + 8]
3673        or rax, [rdx + 8]
3674
3675        mov    [rdi + 8 ], rax
3676
3677        mov rax, [rsi + 16]
3678        or rax, [rdx + 16]
3679
3680        mov    [rdi + 16 ], rax
3681
3682        mov rax, [rsi + 24]
3683        or rax, [rdx + 24]
3684
3685        mov    [rdi + 24 ], rax
3686
3687        mov rax, [rsi + 32]
3688        or rax, [rdx + 32]
3689
3690        and    rax, [lboMask]
3691
3692        mov    [rdi + 32 ], rax
3693
3694        ret
3695
3696
3697
3698
3699
3700or_s1l2:
3701        bt     r9, 62          ; check if montgomery first
3702        jc     or_s1l2m
3703or_s1l2n:
3704        mov r11b, 0x80
3705        shl r11, 56
3706        mov [rdi], r11
3707
3708        cmp    r8d, 0
3709        
3710        js     tmp_21
3711        movsx  rax, r8d
3712        or rax, [rdx +8]
3713        mov    [rdi+8], rax
3714
3715        xor    rax, rax
3716        or rax, [rdx + 16]
3717
3718        mov    [rdi + 16 ], rax
3719
3720        xor    rax, rax
3721        or rax, [rdx + 24]
3722
3723        mov    [rdi + 24 ], rax
3724
3725        xor    rax, rax
3726        or rax, [rdx + 32]
3727
3728        and    rax, [lboMask]
3729
3730        mov    [rdi + 32 ], rax
3731
3732        ret
3733
3734tmp_21:
3735        push  rdi
3736        push  rdx
3737        mov   rdi, rsi
3738        movsx rsi, r8d
3739        call  rawCopyS2L
3740        mov   rsi, rdi
3741        pop   rdx
3742        pop   rdi
3743        mov r11b, 0x80
3744        shl r11, 56
3745        mov [rdi], r11
3746
3747
3748        mov rax, [rsi + 8]
3749        or rax, [rdx + 8]
3750
3751        mov    [rdi + 8 ], rax
3752
3753        mov rax, [rsi + 16]
3754        or rax, [rdx + 16]
3755
3756        mov    [rdi + 16 ], rax
3757
3758        mov rax, [rsi + 24]
3759        or rax, [rdx + 24]
3760
3761        mov    [rdi + 24 ], rax
3762
3763        mov rax, [rsi + 32]
3764        or rax, [rdx + 32]
3765
3766        and    rax, [lboMask]
3767
3768        mov    [rdi + 32 ], rax
3769
3770        ret
3771
3772
3773
3774
3775or_s1l2m:
3776        mov r11b, 0x80
3777        shl r11, 56
3778        mov [rdi], r11
3779        push   r8             ; r8 is used in montgomery so we need to save it
3780        push rdi
3781        mov  rdi, rdx
3782        call Fr_toNormal
3783        mov  rdx, rdi
3784        pop  rdi
3785        pop    r8
3786
3787        cmp    r8d, 0
3788        
3789        js     tmp_22
3790        movsx  rax, r8d
3791        or rax, [rdx +8]
3792        mov    [rdi+8], rax
3793
3794        xor    rax, rax
3795        or rax, [rdx + 16]
3796
3797        mov    [rdi + 16 ], rax
3798
3799        xor    rax, rax
3800        or rax, [rdx + 24]
3801
3802        mov    [rdi + 24 ], rax
3803
3804        xor    rax, rax
3805        or rax, [rdx + 32]
3806
3807        and    rax, [lboMask]
3808
3809        mov    [rdi + 32 ], rax
3810
3811        ret
3812
3813tmp_22:
3814        push  rdi
3815        push  rdx
3816        mov   rdi, rsi
3817        movsx rsi, r8d
3818        call  rawCopyS2L
3819        mov   rsi, rdi
3820        pop   rdx
3821        pop   rdi
3822        mov r11b, 0x80
3823        shl r11, 56
3824        mov [rdi], r11
3825
3826
3827        mov rax, [rsi + 8]
3828        or rax, [rdx + 8]
3829
3830        mov    [rdi + 8 ], rax
3831
3832        mov rax, [rsi + 16]
3833        or rax, [rdx + 16]
3834
3835        mov    [rdi + 16 ], rax
3836
3837        mov rax, [rsi + 24]
3838        or rax, [rdx + 24]
3839
3840        mov    [rdi + 24 ], rax
3841
3842        mov rax, [rsi + 32]
3843        or rax, [rdx + 32]
3844
3845        and    rax, [lboMask]
3846
3847        mov    [rdi + 32 ], rax
3848
3849        ret
3850
3851
3852
3853
3854
3855or_l1l2:
3856        bt     r8, 62          ; check if montgomery first
3857        jc     or_l1ml2
3858        bt     r9, 62          ; check if montgomery first
3859        jc     or_l1nl2m
3860or_l1nl2n:
3861        mov r11b, 0x80
3862        shl r11, 56
3863        mov [rdi], r11
3864
3865
3866        mov rax, [rsi + 8]
3867        or rax, [rdx + 8]
3868
3869        mov    [rdi + 8 ], rax
3870
3871        mov rax, [rsi + 16]
3872        or rax, [rdx + 16]
3873
3874        mov    [rdi + 16 ], rax
3875
3876        mov rax, [rsi + 24]
3877        or rax, [rdx + 24]
3878
3879        mov    [rdi + 24 ], rax
3880
3881        mov rax, [rsi + 32]
3882        or rax, [rdx + 32]
3883
3884        and    rax, [lboMask]
3885
3886        mov    [rdi + 32 ], rax
3887
3888        ret
3889
3890
3891or_l1nl2m:
3892        mov r11b, 0x80
3893        shl r11, 56
3894        mov [rdi], r11
3895        push rdi
3896        mov  rdi, rdx
3897        call Fr_toNormal
3898        mov  rdx, rdi
3899        pop  rdi
3900
3901
3902        mov rax, [rsi + 8]
3903        or rax, [rdx + 8]
3904
3905        mov    [rdi + 8 ], rax
3906
3907        mov rax, [rsi + 16]
3908        or rax, [rdx + 16]
3909
3910        mov    [rdi + 16 ], rax
3911
3912        mov rax, [rsi + 24]
3913        or rax, [rdx + 24]
3914
3915        mov    [rdi + 24 ], rax
3916
3917        mov rax, [rsi + 32]
3918        or rax, [rdx + 32]
3919
3920        and    rax, [lboMask]
3921
3922        mov    [rdi + 32 ], rax
3923
3924        ret
3925
3926
3927or_l1ml2:
3928        bt     r9, 62          ; check if montgomery first
3929        jc     or_l1ml2m
3930or_l1ml2n:
3931        mov r11b, 0x80
3932        shl r11, 56
3933        mov [rdi], r11
3934        push rdi
3935        mov  rdi, rsi
3936        mov  rsi, rdx
3937        call Fr_toNormal
3938        mov  rdx, rsi
3939        mov  rsi, rdi
3940        pop  rdi
3941
3942
3943        mov rax, [rsi + 8]
3944        or rax, [rdx + 8]
3945
3946        mov    [rdi + 8 ], rax
3947
3948        mov rax, [rsi + 16]
3949        or rax, [rdx + 16]
3950
3951        mov    [rdi + 16 ], rax
3952
3953        mov rax, [rsi + 24]
3954        or rax, [rdx + 24]
3955
3956        mov    [rdi + 24 ], rax
3957
3958        mov rax, [rsi + 32]
3959        or rax, [rdx + 32]
3960
3961        and    rax, [lboMask]
3962
3963        mov    [rdi + 32 ], rax
3964
3965        ret
3966
3967
3968or_l1ml2m:
3969        mov r11b, 0x80
3970        shl r11, 56
3971        mov [rdi], r11
3972        push rdi
3973        mov  rdi, rsi
3974        mov  rsi, rdx
3975        call Fr_toNormal
3976        mov  rdx, rsi
3977        mov  rsi, rdi
3978        pop  rdi
3979        push rdi
3980        mov  rdi, rdx
3981        call Fr_toNormal
3982        mov  rdx, rdi
3983        pop  rdi
3984
3985
3986        mov rax, [rsi + 8]
3987        or rax, [rdx + 8]
3988
3989        mov    [rdi + 8 ], rax
3990
3991        mov rax, [rsi + 16]
3992        or rax, [rdx + 16]
3993
3994        mov    [rdi + 16 ], rax
3995
3996        mov rax, [rsi + 24]
3997        or rax, [rdx + 24]
3998
3999        mov    [rdi + 24 ], rax
4000
4001        mov rax, [rsi + 32]
4002        or rax, [rdx + 32]
4003
4004        and    rax, [lboMask]
4005
4006        mov    [rdi + 32 ], rax
4007
4008        ret
4009
4010
4011
4012;;;;;;;;;;;;;;;;;;;;;;
4013; bxor
4014;;;;;;;;;;;;;;;;;;;;;;
4015; Adds two elements of any kind
4016; Params:
4017;   rsi <= Pointer to element 1
4018;   rdx <= Pointer to element 2
4019;   rdi <= Pointer to result
4020; Modified Registers:
4021;    r8, r9, 10, r11, rax, rcx
4022;;;;;;;;;;;;;;;;;;;;;;
4023Fr_bxor:
4024        mov    r8, [rsi]
4025        mov    r9, [rdx]
4026        bt     r8, 63          ; Check if is short first operand
4027        jc     xor_l1
4028        bt     r9, 63          ; Check if is short second operand
4029        jc     xor_s1l2
4030
4031xor_s1s2:
4032
4033        cmp    r8d, 0
4034        
4035        js     tmp_23
4036
4037        cmp    r9d, 0
4038        js     tmp_23
4039        xor    rdx, rdx         ; both ops are positive so do the op and return
4040        mov    edx, r8d
4041        xor    edx, r9d
4042        mov    [rdi], rdx       ; not necessary to adjust so just save and return
4043        ret
4044
4045tmp_23:
4046        mov r11b, 0x80
4047        shl r11, 56
4048        mov [rdi], r11
4049        push  rdi
4050        push   rsi
4051        mov   rdi, rdx
4052        movsx rsi, r9d
4053        call  rawCopyS2L
4054        mov   rdx, rdi
4055        pop   rsi
4056        pop   rdi
4057        push  rdi
4058        push  rdx
4059        mov   rdi, rsi
4060        movsx rsi, r8d
4061        call  rawCopyS2L
4062        mov   rsi, rdi
4063        pop   rdx
4064        pop   rdi
4065
4066
4067        mov rax, [rsi + 8]
4068        xor rax, [rdx + 8]
4069
4070        mov    [rdi + 8 ], rax
4071
4072        mov rax, [rsi + 16]
4073        xor rax, [rdx + 16]
4074
4075        mov    [rdi + 16 ], rax
4076
4077        mov rax, [rsi + 24]
4078        xor rax, [rdx + 24]
4079
4080        mov    [rdi + 24 ], rax
4081
4082        mov rax, [rsi + 32]
4083        xor rax, [rdx + 32]
4084
4085        and    rax, [lboMask]
4086
4087        mov    [rdi + 32 ], rax
4088
4089        ret
4090
4091
4092
4093
4094
4095
4096xor_l1:
4097        bt     r9, 63          ; Check if is short second operand
4098        jc     xor_l1l2
4099
4100
4101xor_l1s2:
4102        bt     r8, 62          ; check if montgomery first
4103        jc     xor_l1ms2
4104xor_l1ns2:
4105        mov r11b, 0x80
4106        shl r11, 56
4107        mov [rdi], r11
4108
4109        cmp    r9d, 0
4110        
4111        js     tmp_24
4112        movsx  rax, r9d
4113        xor rax, [rsi +8]
4114        mov    [rdi+8], rax
4115
4116        xor    rax, rax
4117        xor rax, [rsi + 16];
4118
4119        mov    [rdi + 16 ], rax;
4120
4121        xor    rax, rax
4122        xor rax, [rsi + 24];
4123
4124        mov    [rdi + 24 ], rax;
4125
4126        xor    rax, rax
4127        xor rax, [rsi + 32];
4128
4129        and    rax, [lboMask] ;
4130
4131        mov    [rdi + 32 ], rax;
4132
4133        ret
4134
4135tmp_24:
4136        push  rdi
4137        push   rsi
4138        mov   rdi, rdx
4139        movsx rsi, r9d
4140        call  rawCopyS2L
4141        mov   rdx, rdi
4142        pop   rsi
4143        pop   rdi
4144        mov r11b, 0x80
4145        shl r11, 56
4146        mov [rdi], r11
4147
4148
4149        mov rax, [rsi + 8]
4150        xor rax, [rdx + 8]
4151
4152        mov    [rdi + 8 ], rax
4153
4154        mov rax, [rsi + 16]
4155        xor rax, [rdx + 16]
4156
4157        mov    [rdi + 16 ], rax
4158
4159        mov rax, [rsi + 24]
4160        xor rax, [rdx + 24]
4161
4162        mov    [rdi + 24 ], rax
4163
4164        mov rax, [rsi + 32]
4165        xor rax, [rdx + 32]
4166
4167        and    rax, [lboMask]
4168
4169        mov    [rdi + 32 ], rax
4170
4171        ret
4172
4173
4174
4175
4176xor_l1ms2:
4177        mov r11b, 0x80
4178        shl r11, 56
4179        mov [rdi], r11
4180        push   r9              ; r9 is used in montgomery so we need to save it
4181        push rdi
4182        mov  rdi, rsi
4183        mov  rsi, rdx
4184        call Fr_toNormal
4185        mov  rdx, rsi
4186        mov  rsi, rdi
4187        pop  rdi
4188        pop    r9
4189
4190        cmp    r9d, 0
4191        
4192        js     tmp_25
4193        movsx  rax, r9d
4194        xor rax, [rsi +8]
4195        mov    [rdi+8], rax
4196
4197        xor    rax, rax
4198        xor rax, [rsi + 16];
4199
4200        mov    [rdi + 16 ], rax;
4201
4202        xor    rax, rax
4203        xor rax, [rsi + 24];
4204
4205        mov    [rdi + 24 ], rax;
4206
4207        xor    rax, rax
4208        xor rax, [rsi + 32];
4209
4210        and    rax, [lboMask] ;
4211
4212        mov    [rdi + 32 ], rax;
4213
4214        ret
4215
4216tmp_25:
4217        push  rdi
4218        push   rsi
4219        mov   rdi, rdx
4220        movsx rsi, r9d
4221        call  rawCopyS2L
4222        mov   rdx, rdi
4223        pop   rsi
4224        pop   rdi
4225        mov r11b, 0x80
4226        shl r11, 56
4227        mov [rdi], r11
4228
4229
4230        mov rax, [rsi + 8]
4231        xor rax, [rdx + 8]
4232
4233        mov    [rdi + 8 ], rax
4234
4235        mov rax, [rsi + 16]
4236        xor rax, [rdx + 16]
4237
4238        mov    [rdi + 16 ], rax
4239
4240        mov rax, [rsi + 24]
4241        xor rax, [rdx + 24]
4242
4243        mov    [rdi + 24 ], rax
4244
4245        mov rax, [rsi + 32]
4246        xor rax, [rdx + 32]
4247
4248        and    rax, [lboMask]
4249
4250        mov    [rdi + 32 ], rax
4251
4252        ret
4253
4254
4255
4256
4257
4258xor_s1l2:
4259        bt     r9, 62          ; check if montgomery first
4260        jc     xor_s1l2m
4261xor_s1l2n:
4262        mov r11b, 0x80
4263        shl r11, 56
4264        mov [rdi], r11
4265
4266        cmp    r8d, 0
4267        
4268        js     tmp_26
4269        movsx  rax, r8d
4270        xor rax, [rdx +8]
4271        mov    [rdi+8], rax
4272
4273        xor    rax, rax
4274        xor rax, [rdx + 16]
4275
4276        mov    [rdi + 16 ], rax
4277
4278        xor    rax, rax
4279        xor rax, [rdx + 24]
4280
4281        mov    [rdi + 24 ], rax
4282
4283        xor    rax, rax
4284        xor rax, [rdx + 32]
4285
4286        and    rax, [lboMask]
4287
4288        mov    [rdi + 32 ], rax
4289
4290        ret
4291
4292tmp_26:
4293        push  rdi
4294        push  rdx
4295        mov   rdi, rsi
4296        movsx rsi, r8d
4297        call  rawCopyS2L
4298        mov   rsi, rdi
4299        pop   rdx
4300        pop   rdi
4301        mov r11b, 0x80
4302        shl r11, 56
4303        mov [rdi], r11
4304
4305
4306        mov rax, [rsi + 8]
4307        xor rax, [rdx + 8]
4308
4309        mov    [rdi + 8 ], rax
4310
4311        mov rax, [rsi + 16]
4312        xor rax, [rdx + 16]
4313
4314        mov    [rdi + 16 ], rax
4315
4316        mov rax, [rsi + 24]
4317        xor rax, [rdx + 24]
4318
4319        mov    [rdi + 24 ], rax
4320
4321        mov rax, [rsi + 32]
4322        xor rax, [rdx + 32]
4323
4324        and    rax, [lboMask]
4325
4326        mov    [rdi + 32 ], rax
4327
4328        ret
4329
4330
4331
4332
4333xor_s1l2m:
4334        mov r11b, 0x80
4335        shl r11, 56
4336        mov [rdi], r11
4337        push   r8             ; r8 is used in montgomery so we need to save it
4338        push rdi
4339        mov  rdi, rdx
4340        call Fr_toNormal
4341        mov  rdx, rdi
4342        pop  rdi
4343        pop    r8
4344
4345        cmp    r8d, 0
4346        
4347        js     tmp_27
4348        movsx  rax, r8d
4349        xor rax, [rdx +8]
4350        mov    [rdi+8], rax
4351
4352        xor    rax, rax
4353        xor rax, [rdx + 16]
4354
4355        mov    [rdi + 16 ], rax
4356
4357        xor    rax, rax
4358        xor rax, [rdx + 24]
4359
4360        mov    [rdi + 24 ], rax
4361
4362        xor    rax, rax
4363        xor rax, [rdx + 32]
4364
4365        and    rax, [lboMask]
4366
4367        mov    [rdi + 32 ], rax
4368
4369        ret
4370
4371tmp_27:
4372        push  rdi
4373        push  rdx
4374        mov   rdi, rsi
4375        movsx rsi, r8d
4376        call  rawCopyS2L
4377        mov   rsi, rdi
4378        pop   rdx
4379        pop   rdi
4380        mov r11b, 0x80
4381        shl r11, 56
4382        mov [rdi], r11
4383
4384
4385        mov rax, [rsi + 8]
4386        xor rax, [rdx + 8]
4387
4388        mov    [rdi + 8 ], rax
4389
4390        mov rax, [rsi + 16]
4391        xor rax, [rdx + 16]
4392
4393        mov    [rdi + 16 ], rax
4394
4395        mov rax, [rsi + 24]
4396        xor rax, [rdx + 24]
4397
4398        mov    [rdi + 24 ], rax
4399
4400        mov rax, [rsi + 32]
4401        xor rax, [rdx + 32]
4402
4403        and    rax, [lboMask]
4404
4405        mov    [rdi + 32 ], rax
4406
4407        ret
4408
4409
4410
4411
4412
4413xor_l1l2:
4414        bt     r8, 62          ; check if montgomery first
4415        jc     xor_l1ml2
4416        bt     r9, 62          ; check if montgomery first
4417        jc     xor_l1nl2m
4418xor_l1nl2n:
4419        mov r11b, 0x80
4420        shl r11, 56
4421        mov [rdi], r11
4422
4423
4424        mov rax, [rsi + 8]
4425        xor rax, [rdx + 8]
4426
4427        mov    [rdi + 8 ], rax
4428
4429        mov rax, [rsi + 16]
4430        xor rax, [rdx + 16]
4431
4432        mov    [rdi + 16 ], rax
4433
4434        mov rax, [rsi + 24]
4435        xor rax, [rdx + 24]
4436
4437        mov    [rdi + 24 ], rax
4438
4439        mov rax, [rsi + 32]
4440        xor rax, [rdx + 32]
4441
4442        and    rax, [lboMask]
4443
4444        mov    [rdi + 32 ], rax
4445
4446        ret
4447
4448
4449xor_l1nl2m:
4450        mov r11b, 0x80
4451        shl r11, 56
4452        mov [rdi], r11
4453        push rdi
4454        mov  rdi, rdx
4455        call Fr_toNormal
4456        mov  rdx, rdi
4457        pop  rdi
4458
4459
4460        mov rax, [rsi + 8]
4461        xor rax, [rdx + 8]
4462
4463        mov    [rdi + 8 ], rax
4464
4465        mov rax, [rsi + 16]
4466        xor rax, [rdx + 16]
4467
4468        mov    [rdi + 16 ], rax
4469
4470        mov rax, [rsi + 24]
4471        xor rax, [rdx + 24]
4472
4473        mov    [rdi + 24 ], rax
4474
4475        mov rax, [rsi + 32]
4476        xor rax, [rdx + 32]
4477
4478        and    rax, [lboMask]
4479
4480        mov    [rdi + 32 ], rax
4481
4482        ret
4483
4484
4485xor_l1ml2:
4486        bt     r9, 62          ; check if montgomery first
4487        jc     xor_l1ml2m
4488xor_l1ml2n:
4489        mov r11b, 0x80
4490        shl r11, 56
4491        mov [rdi], r11
4492        push rdi
4493        mov  rdi, rsi
4494        mov  rsi, rdx
4495        call Fr_toNormal
4496        mov  rdx, rsi
4497        mov  rsi, rdi
4498        pop  rdi
4499
4500
4501        mov rax, [rsi + 8]
4502        xor rax, [rdx + 8]
4503
4504        mov    [rdi + 8 ], rax
4505
4506        mov rax, [rsi + 16]
4507        xor rax, [rdx + 16]
4508
4509        mov    [rdi + 16 ], rax
4510
4511        mov rax, [rsi + 24]
4512        xor rax, [rdx + 24]
4513
4514        mov    [rdi + 24 ], rax
4515
4516        mov rax, [rsi + 32]
4517        xor rax, [rdx + 32]
4518
4519        and    rax, [lboMask]
4520
4521        mov    [rdi + 32 ], rax
4522
4523        ret
4524
4525
4526xor_l1ml2m:
4527        mov r11b, 0x80
4528        shl r11, 56
4529        mov [rdi], r11
4530        push rdi
4531        mov  rdi, rsi
4532        mov  rsi, rdx
4533        call Fr_toNormal
4534        mov  rdx, rsi
4535        mov  rsi, rdi
4536        pop  rdi
4537        push rdi
4538        mov  rdi, rdx
4539        call Fr_toNormal
4540        mov  rdx, rdi
4541        pop  rdi
4542
4543
4544        mov rax, [rsi + 8]
4545        xor rax, [rdx + 8]
4546
4547        mov    [rdi + 8 ], rax
4548
4549        mov rax, [rsi + 16]
4550        xor rax, [rdx + 16]
4551
4552        mov    [rdi + 16 ], rax
4553
4554        mov rax, [rsi + 24]
4555        xor rax, [rdx + 24]
4556
4557        mov    [rdi + 24 ], rax
4558
4559        mov rax, [rsi + 32]
4560        xor rax, [rdx + 32]
4561
4562        and    rax, [lboMask]
4563
4564        mov    [rdi + 32 ], rax
4565
4566        ret
4567
4568
4569
4570
4571;;;;;;;;;;;;;;;;;;;;;;
4572; bnot
4573;;;;;;;;;;;;;;;;;;;;;;
4574; Adds two elements of any kind
4575; Params:
4576;   rsi <= Pointer to element 1
4577;   rdi <= Pointer to result
4578; Modified Registers:
4579;    r8, r9, 10, r11, rax, rcx
4580;;;;;;;;;;;;;;;;;;;;;;
4581Fr_bnot:
4582                mov r11b, 0x80
4583        shl r11, 56
4584        mov [rdi], r11
4585
4586        mov     r8, [rsi]
4587        bt      r8, 63          ; Check if is long operand
4588        jc      bnot_l1
4589bnot_s:
4590                push  rdi
4591        push  rdx
4592        mov   rdi, rsi
4593        movsx rsi, r8d
4594        call  rawCopyS2L
4595        mov   rsi, rdi
4596        pop   rdx
4597        pop   rdi
4598        jmp     bnot_l1n
4599
4600bnot_l1:
4601        bt     r8, 62          ; check if montgomery first
4602        jnc    bnot_l1n
4603
4604bnot_l1m:
4605        push rdi
4606        mov  rdi, rsi
4607        mov  rsi, rdx
4608        call Fr_toNormal
4609        mov  rdx, rsi
4610        mov  rsi, rdi
4611        pop  rdi
4612
4613bnot_l1n:
4614
4615        mov    rax, [rsi + 8]
4616        not    rax
4617
4618        mov    [rdi + 8], rax
4619
4620        mov    rax, [rsi + 16]
4621        not    rax
4622
4623        mov    [rdi + 16], rax
4624
4625        mov    rax, [rsi + 24]
4626        not    rax
4627
4628        mov    [rdi + 24], rax
4629
4630        mov    rax, [rsi + 32]
4631        not    rax
4632
4633        and    rax, [lboMask]
4634
4635        mov    [rdi + 32], rax
4636
4637        ret
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651;;;;;;;;;;;;;;;;;;;;;;
4652; eq
4653;;;;;;;;;;;;;;;;;;;;;;
4654; Adds two elements of any kind
4655; Params:
4656;   rsi <= Pointer to element 1
4657;   rdx <= Pointer to element 2
4658;   rdi <= Pointer to result can be zero or one.
4659; Modified Registers:
4660;    r8, r9, 10, r11, rax, rcx
4661;;;;;;;;;;;;;;;;;;;;;;
4662Fr_eq:
4663    sub     rsp, 40  ; Save space for the result of the substraction
4664    push    rdi                    ; Save rdi
4665    lea     rdi, [rsp+8]           ; We pushed rdi so we need to add 8
4666    call    Fr_sub          ; Do a substraction
4667    call    Fr_toNormal     ; Convert it to normal
4668    pop     rdi
4669
4670    mov     rax, [rsp]             ; We already poped do no need to add 8
4671    bt      rax, 63                ; check is result is long
4672    jc      eq_longCmp
4673
4674eq_shortCmp:
4675    cmp     eax, 0
4676    je      eq_s_eq
4677    js      eq_s_lt
4678eq_s_gt:
4679
4680        mov qword [rdi], 0
4681        add rsp, 40
4682        ret
4683
4684eq_s_lt:
4685
4686        mov qword [rdi], 0
4687        add rsp, 40
4688        ret
4689
4690eq_s_eq:
4691
4692        mov qword [rdi], 1
4693        add rsp, 40
4694        ret
4695
4696
4697eq_longCmp:
4698
4699
4700    cmp     qword [rsp + 32], 0
4701    jnz eq_neq
4702
4703    cmp     qword [rsp + 24], 0
4704    jnz eq_neq
4705
4706    cmp     qword [rsp + 16], 0
4707    jnz eq_neq
4708
4709    cmp     qword [rsp + 8], 0
4710    jnz eq_neq
4711
4712eq_eq:
4713
4714        mov qword [rdi], 1
4715        add rsp, 40
4716        ret
4717
4718eq_neq:
4719
4720        mov qword [rdi], 0
4721        add rsp, 40
4722        ret
4723
4724
4725
4726
4727
4728;;;;;;;;;;;;;;;;;;;;;;
4729; neq
4730;;;;;;;;;;;;;;;;;;;;;;
4731; Adds two elements of any kind
4732; Params:
4733;   rsi <= Pointer to element 1
4734;   rdx <= Pointer to element 2
4735;   rdi <= Pointer to result can be zero or one.
4736; Modified Registers:
4737;    r8, r9, 10, r11, rax, rcx
4738;;;;;;;;;;;;;;;;;;;;;;
4739Fr_neq:
4740    sub     rsp, 40  ; Save space for the result of the substraction
4741    push    rdi                    ; Save rdi
4742    lea     rdi, [rsp+8]           ; We pushed rdi so we need to add 8
4743    call    Fr_sub          ; Do a substraction
4744    call    Fr_toNormal     ; Convert it to normal
4745    pop     rdi
4746
4747    mov     rax, [rsp]             ; We already poped do no need to add 8
4748    bt      rax, 63                ; check is result is long
4749    jc      neq_longCmp
4750
4751neq_shortCmp:
4752    cmp     eax, 0
4753    je      neq_s_eq
4754    js      neq_s_lt
4755neq_s_gt:
4756
4757        mov qword [rdi], 1
4758        add rsp, 40
4759        ret
4760
4761neq_s_lt:
4762
4763        mov qword [rdi], 1
4764        add rsp, 40
4765        ret
4766
4767neq_s_eq:
4768
4769        mov qword [rdi], 0
4770        add rsp, 40
4771        ret
4772
4773
4774neq_longCmp:
4775
4776
4777    cmp     qword [rsp + 32], 0
4778    jnz neq_neq
4779
4780    cmp     qword [rsp + 24], 0
4781    jnz neq_neq
4782
4783    cmp     qword [rsp + 16], 0
4784    jnz neq_neq
4785
4786    cmp     qword [rsp + 8], 0
4787    jnz neq_neq
4788
4789neq_eq:
4790
4791        mov qword [rdi], 0
4792        add rsp, 40
4793        ret
4794
4795neq_neq:
4796
4797        mov qword [rdi], 1
4798        add rsp, 40
4799        ret
4800
4801
4802
4803
4804
4805;;;;;;;;;;;;;;;;;;;;;;
4806; lt
4807;;;;;;;;;;;;;;;;;;;;;;
4808; Adds two elements of any kind
4809; Params:
4810;   rsi <= Pointer to element 1
4811;   rdx <= Pointer to element 2
4812;   rdi <= Pointer to result can be zero or one.
4813; Modified Registers:
4814;    r8, r9, 10, r11, rax, rcx
4815;;;;;;;;;;;;;;;;;;;;;;
4816Fr_lt:
4817    sub     rsp, 40  ; Save space for the result of the substraction
4818    push    rdi                    ; Save rdi
4819    lea     rdi, [rsp+8]           ; We pushed rdi so we need to add 8
4820    call    Fr_sub          ; Do a substraction
4821    call    Fr_toNormal     ; Convert it to normal
4822    pop     rdi
4823
4824    mov     rax, [rsp]             ; We already poped do no need to add 8
4825    bt      rax, 63                ; check is result is long
4826    jc      lt_longCmp
4827
4828lt_shortCmp:
4829    cmp     eax, 0
4830    je      lt_s_eq
4831    js      lt_s_lt
4832lt_s_gt:
4833
4834        mov qword [rdi], 0
4835        add rsp, 40
4836        ret
4837
4838lt_s_lt:
4839
4840        mov qword [rdi], 1
4841        add rsp, 40
4842        ret
4843
4844lt_s_eq:
4845
4846        mov qword [rdi], 0
4847        add rsp, 40
4848        ret
4849
4850
4851lt_longCmp:
4852
4853
4854    cmp     qword [rsp + 32], 0
4855    jnz lt_neq
4856
4857    cmp     qword [rsp + 24], 0
4858    jnz lt_neq
4859
4860    cmp     qword [rsp + 16], 0
4861    jnz lt_neq
4862
4863    cmp     qword [rsp + 8], 0
4864    jnz lt_neq
4865
4866lt_eq:
4867
4868
4869
4870        mov qword [rdi], 0
4871        add rsp, 40
4872        ret
4873
4874
4875
4876
4877
4878
4879        mov     rax, [rsp + 32]
4880        cmp     [half + 24], rax     ; comare with (q-1)/2
4881        jc tmp_29                           ; half<rax => e1-e2 is neg => e1 < e2
4882        jnz tmp_28                       ; half>rax => e1 -e2 is pos => e1 > e2
4883
4884        mov     rax, [rsp + 24]
4885        cmp     [half + 16], rax     ; comare with (q-1)/2
4886        jc tmp_29                           ; half<rax => e1-e2 is neg => e1 < e2
4887        jnz tmp_28                       ; half>rax => e1 -e2 is pos => e1 > e2
4888
4889        mov     rax, [rsp + 16]
4890        cmp     [half + 8], rax     ; comare with (q-1)/2
4891        jc tmp_29                           ; half<rax => e1-e2 is neg => e1 < e2
4892        jnz tmp_28                       ; half>rax => e1 -e2 is pos => e1 > e2
4893
4894        mov     rax, [rsp + 8]
4895        cmp     [half + 0], rax     ; comare with (q-1)/2
4896        jc tmp_29                           ; half<rax => e1-e2 is neg => e1 < e2
4897        jnz tmp_28                       ; half>rax => e1 -e2 is pos => e1 > e2
4898
4899                                                ; half == rax => e1-e2 is pos => e1 > e2
4900tmp_28:
4901
4902        mov qword [rdi], 0
4903        add rsp, 40
4904        ret
4905
4906tmp_29:
4907
4908        mov qword [rdi], 1
4909        add rsp, 40
4910        ret
4911
4912
4913lt_neq:
4914
4915
4916
4917
4918
4919
4920
4921
4922        mov     rax, [rsp + 32]
4923        cmp     [half + 24], rax     ; comare with (q-1)/2
4924        jc tmp_31                           ; half<rax => e1-e2 is neg => e1 < e2
4925        jnz tmp_30                       ; half>rax => e1 -e2 is pos => e1 > e2
4926
4927        mov     rax, [rsp + 24]
4928        cmp     [half + 16], rax     ; comare with (q-1)/2
4929        jc tmp_31                           ; half<rax => e1-e2 is neg => e1 < e2
4930        jnz tmp_30                       ; half>rax => e1 -e2 is pos => e1 > e2
4931
4932        mov     rax, [rsp + 16]
4933        cmp     [half + 8], rax     ; comare with (q-1)/2
4934        jc tmp_31                           ; half<rax => e1-e2 is neg => e1 < e2
4935        jnz tmp_30                       ; half>rax => e1 -e2 is pos => e1 > e2
4936
4937        mov     rax, [rsp + 8]
4938        cmp     [half + 0], rax     ; comare with (q-1)/2
4939        jc tmp_31                           ; half<rax => e1-e2 is neg => e1 < e2
4940        jnz tmp_30                       ; half>rax => e1 -e2 is pos => e1 > e2
4941
4942                                                ; half == rax => e1-e2 is pos => e1 > e2
4943tmp_30:
4944
4945        mov qword [rdi], 0
4946        add rsp, 40
4947        ret
4948
4949tmp_31:
4950
4951        mov qword [rdi], 1
4952        add rsp, 40
4953        ret
4954
4955
4956
4957
4958
4959
4960;;;;;;;;;;;;;;;;;;;;;;
4961; gt
4962;;;;;;;;;;;;;;;;;;;;;;
4963; Adds two elements of any kind
4964; Params:
4965;   rsi <= Pointer to element 1
4966;   rdx <= Pointer to element 2
4967;   rdi <= Pointer to result can be zero or one.
4968; Modified Registers:
4969;    r8, r9, 10, r11, rax, rcx
4970;;;;;;;;;;;;;;;;;;;;;;
4971Fr_gt:
4972    sub     rsp, 40  ; Save space for the result of the substraction
4973    push    rdi                    ; Save rdi
4974    lea     rdi, [rsp+8]           ; We pushed rdi so we need to add 8
4975    call    Fr_sub          ; Do a substraction
4976    call    Fr_toNormal     ; Convert it to normal
4977    pop     rdi
4978
4979    mov     rax, [rsp]             ; We already poped do no need to add 8
4980    bt      rax, 63                ; check is result is long
4981    jc      gt_longCmp
4982
4983gt_shortCmp:
4984    cmp     eax, 0
4985    je      gt_s_eq
4986    js      gt_s_lt
4987gt_s_gt:
4988
4989        mov qword [rdi], 1
4990        add rsp, 40
4991        ret
4992
4993gt_s_lt:
4994
4995        mov qword [rdi], 0
4996        add rsp, 40
4997        ret
4998
4999gt_s_eq:
5000
5001        mov qword [rdi], 0
5002        add rsp, 40
5003        ret
5004
5005
5006gt_longCmp:
5007
5008
5009    cmp     qword [rsp + 32], 0
5010    jnz gt_neq
5011
5012    cmp     qword [rsp + 24], 0
5013    jnz gt_neq
5014
5015    cmp     qword [rsp + 16], 0
5016    jnz gt_neq
5017
5018    cmp     qword [rsp + 8], 0
5019    jnz gt_neq
5020
5021gt_eq:
5022
5023
5024
5025        mov qword [rdi], 0
5026        add rsp, 40
5027        ret
5028
5029
5030
5031
5032
5033
5034        mov     rax, [rsp + 32]
5035        cmp     [half + 24], rax     ; comare with (q-1)/2
5036        jc tmp_33                           ; half<rax => e1-e2 is neg => e1 < e2
5037        jnz tmp_32                       ; half>rax => e1 -e2 is pos => e1 > e2
5038
5039        mov     rax, [rsp + 24]
5040        cmp     [half + 16], rax     ; comare with (q-1)/2
5041        jc tmp_33                           ; half<rax => e1-e2 is neg => e1 < e2
5042        jnz tmp_32                       ; half>rax => e1 -e2 is pos => e1 > e2
5043
5044        mov     rax, [rsp + 16]
5045        cmp     [half + 8], rax     ; comare with (q-1)/2
5046        jc tmp_33                           ; half<rax => e1-e2 is neg => e1 < e2
5047        jnz tmp_32                       ; half>rax => e1 -e2 is pos => e1 > e2
5048
5049        mov     rax, [rsp + 8]
5050        cmp     [half + 0], rax     ; comare with (q-1)/2
5051        jc tmp_33                           ; half<rax => e1-e2 is neg => e1 < e2
5052        jnz tmp_32                       ; half>rax => e1 -e2 is pos => e1 > e2
5053
5054                                                ; half == rax => e1-e2 is pos => e1 > e2
5055tmp_32:
5056
5057        mov qword [rdi], 1
5058        add rsp, 40
5059        ret
5060
5061tmp_33:
5062
5063        mov qword [rdi], 0
5064        add rsp, 40
5065        ret
5066
5067
5068gt_neq:
5069
5070
5071
5072
5073
5074
5075
5076
5077        mov     rax, [rsp + 32]
5078        cmp     [half + 24], rax     ; comare with (q-1)/2
5079        jc tmp_35                           ; half<rax => e1-e2 is neg => e1 < e2
5080        jnz tmp_34                       ; half>rax => e1 -e2 is pos => e1 > e2
5081
5082        mov     rax, [rsp + 24]
5083        cmp     [half + 16], rax     ; comare with (q-1)/2
5084        jc tmp_35                           ; half<rax => e1-e2 is neg => e1 < e2
5085        jnz tmp_34                       ; half>rax => e1 -e2 is pos => e1 > e2
5086
5087        mov     rax, [rsp + 16]
5088        cmp     [half + 8], rax     ; comare with (q-1)/2
5089        jc tmp_35                           ; half<rax => e1-e2 is neg => e1 < e2
5090        jnz tmp_34                       ; half>rax => e1 -e2 is pos => e1 > e2
5091
5092        mov     rax, [rsp + 8]
5093        cmp     [half + 0], rax     ; comare with (q-1)/2
5094        jc tmp_35                           ; half<rax => e1-e2 is neg => e1 < e2
5095        jnz tmp_34                       ; half>rax => e1 -e2 is pos => e1 > e2
5096
5097                                                ; half == rax => e1-e2 is pos => e1 > e2
5098tmp_34:
5099
5100        mov qword [rdi], 1
5101        add rsp, 40
5102        ret
5103
5104tmp_35:
5105
5106        mov qword [rdi], 0
5107        add rsp, 40
5108        ret
5109
5110
5111
5112
5113
5114
5115;;;;;;;;;;;;;;;;;;;;;;
5116; leq
5117;;;;;;;;;;;;;;;;;;;;;;
5118; Adds two elements of any kind
5119; Params:
5120;   rsi <= Pointer to element 1
5121;   rdx <= Pointer to element 2
5122;   rdi <= Pointer to result can be zero or one.
5123; Modified Registers:
5124;    r8, r9, 10, r11, rax, rcx
5125;;;;;;;;;;;;;;;;;;;;;;
5126Fr_leq:
5127    sub     rsp, 40  ; Save space for the result of the substraction
5128    push    rdi                    ; Save rdi
5129    lea     rdi, [rsp+8]           ; We pushed rdi so we need to add 8
5130    call    Fr_sub          ; Do a substraction
5131    call    Fr_toNormal     ; Convert it to normal
5132    pop     rdi
5133
5134    mov     rax, [rsp]             ; We already poped do no need to add 8
5135    bt      rax, 63                ; check is result is long
5136    jc      leq_longCmp
5137
5138leq_shortCmp:
5139    cmp     eax, 0
5140    je      leq_s_eq
5141    js      leq_s_lt
5142leq_s_gt:
5143
5144        mov qword [rdi], 0
5145        add rsp, 40
5146        ret
5147
5148leq_s_lt:
5149
5150        mov qword [rdi], 1
5151        add rsp, 40
5152        ret
5153
5154leq_s_eq:
5155
5156        mov qword [rdi], 1
5157        add rsp, 40
5158        ret
5159
5160
5161leq_longCmp:
5162
5163
5164    cmp     qword [rsp + 32], 0
5165    jnz leq_neq
5166
5167    cmp     qword [rsp + 24], 0
5168    jnz leq_neq
5169
5170    cmp     qword [rsp + 16], 0
5171    jnz leq_neq
5172
5173    cmp     qword [rsp + 8], 0
5174    jnz leq_neq
5175
5176leq_eq:
5177
5178
5179
5180        mov qword [rdi], 1
5181        add rsp, 40
5182        ret
5183
5184
5185
5186
5187
5188
5189        mov     rax, [rsp + 32]
5190        cmp     [half + 24], rax     ; comare with (q-1)/2
5191        jc tmp_37                           ; half<rax => e1-e2 is neg => e1 < e2
5192        jnz tmp_36                       ; half>rax => e1 -e2 is pos => e1 > e2
5193
5194        mov     rax, [rsp + 24]
5195        cmp     [half + 16], rax     ; comare with (q-1)/2
5196        jc tmp_37                           ; half<rax => e1-e2 is neg => e1 < e2
5197        jnz tmp_36                       ; half>rax => e1 -e2 is pos => e1 > e2
5198
5199        mov     rax, [rsp + 16]
5200        cmp     [half + 8], rax     ; comare with (q-1)/2
5201        jc tmp_37                           ; half<rax => e1-e2 is neg => e1 < e2
5202        jnz tmp_36                       ; half>rax => e1 -e2 is pos => e1 > e2
5203
5204        mov     rax, [rsp + 8]
5205        cmp     [half + 0], rax     ; comare with (q-1)/2
5206        jc tmp_37                           ; half<rax => e1-e2 is neg => e1 < e2
5207        jnz tmp_36                       ; half>rax => e1 -e2 is pos => e1 > e2
5208
5209                                                ; half == rax => e1-e2 is pos => e1 > e2
5210tmp_36:
5211
5212        mov qword [rdi], 0
5213        add rsp, 40
5214        ret
5215
5216tmp_37:
5217
5218        mov qword [rdi], 1
5219        add rsp, 40
5220        ret
5221
5222
5223leq_neq:
5224
5225
5226
5227
5228
5229
5230
5231
5232        mov     rax, [rsp + 32]
5233        cmp     [half + 24], rax     ; comare with (q-1)/2
5234        jc tmp_39                           ; half<rax => e1-e2 is neg => e1 < e2
5235        jnz tmp_38                       ; half>rax => e1 -e2 is pos => e1 > e2
5236
5237        mov     rax, [rsp + 24]
5238        cmp     [half + 16], rax     ; comare with (q-1)/2
5239        jc tmp_39                           ; half<rax => e1-e2 is neg => e1 < e2
5240        jnz tmp_38                       ; half>rax => e1 -e2 is pos => e1 > e2
5241
5242        mov     rax, [rsp + 16]
5243        cmp     [half + 8], rax     ; comare with (q-1)/2
5244        jc tmp_39                           ; half<rax => e1-e2 is neg => e1 < e2
5245        jnz tmp_38                       ; half>rax => e1 -e2 is pos => e1 > e2
5246
5247        mov     rax, [rsp + 8]
5248        cmp     [half + 0], rax     ; comare with (q-1)/2
5249        jc tmp_39                           ; half<rax => e1-e2 is neg => e1 < e2
5250        jnz tmp_38                       ; half>rax => e1 -e2 is pos => e1 > e2
5251
5252                                                ; half == rax => e1-e2 is pos => e1 > e2
5253tmp_38:
5254
5255        mov qword [rdi], 0
5256        add rsp, 40
5257        ret
5258
5259tmp_39:
5260
5261        mov qword [rdi], 1
5262        add rsp, 40
5263        ret
5264
5265
5266
5267
5268
5269
5270;;;;;;;;;;;;;;;;;;;;;;
5271; geq
5272;;;;;;;;;;;;;;;;;;;;;;
5273; Adds two elements of any kind
5274; Params:
5275;   rsi <= Pointer to element 1
5276;   rdx <= Pointer to element 2
5277;   rdi <= Pointer to result can be zero or one.
5278; Modified Registers:
5279;    r8, r9, 10, r11, rax, rcx
5280;;;;;;;;;;;;;;;;;;;;;;
5281Fr_geq:
5282    sub     rsp, 40  ; Save space for the result of the substraction
5283    push    rdi                    ; Save rdi
5284    lea     rdi, [rsp+8]           ; We pushed rdi so we need to add 8
5285    call    Fr_sub          ; Do a substraction
5286    call    Fr_toNormal     ; Convert it to normal
5287    pop     rdi
5288
5289    mov     rax, [rsp]             ; We already poped do no need to add 8
5290    bt      rax, 63                ; check is result is long
5291    jc      geq_longCmp
5292
5293geq_shortCmp:
5294    cmp     eax, 0
5295    je      geq_s_eq
5296    js      geq_s_lt
5297geq_s_gt:
5298
5299        mov qword [rdi], 1
5300        add rsp, 40
5301        ret
5302
5303geq_s_lt:
5304
5305        mov qword [rdi], 0
5306        add rsp, 40
5307        ret
5308
5309geq_s_eq:
5310
5311        mov qword [rdi], 1
5312        add rsp, 40
5313        ret
5314
5315
5316geq_longCmp:
5317
5318
5319    cmp     qword [rsp + 32], 0
5320    jnz geq_neq
5321
5322    cmp     qword [rsp + 24], 0
5323    jnz geq_neq
5324
5325    cmp     qword [rsp + 16], 0
5326    jnz geq_neq
5327
5328    cmp     qword [rsp + 8], 0
5329    jnz geq_neq
5330
5331geq_eq:
5332
5333
5334
5335        mov qword [rdi], 1
5336        add rsp, 40
5337        ret
5338
5339
5340
5341
5342
5343
5344        mov     rax, [rsp + 32]
5345        cmp     [half + 24], rax     ; comare with (q-1)/2
5346        jc tmp_41                           ; half<rax => e1-e2 is neg => e1 < e2
5347        jnz tmp_40                       ; half>rax => e1 -e2 is pos => e1 > e2
5348
5349        mov     rax, [rsp + 24]
5350        cmp     [half + 16], rax     ; comare with (q-1)/2
5351        jc tmp_41                           ; half<rax => e1-e2 is neg => e1 < e2
5352        jnz tmp_40                       ; half>rax => e1 -e2 is pos => e1 > e2
5353
5354        mov     rax, [rsp + 16]
5355        cmp     [half + 8], rax     ; comare with (q-1)/2
5356        jc tmp_41                           ; half<rax => e1-e2 is neg => e1 < e2
5357        jnz tmp_40                       ; half>rax => e1 -e2 is pos => e1 > e2
5358
5359        mov     rax, [rsp + 8]
5360        cmp     [half + 0], rax     ; comare with (q-1)/2
5361        jc tmp_41                           ; half<rax => e1-e2 is neg => e1 < e2
5362        jnz tmp_40                       ; half>rax => e1 -e2 is pos => e1 > e2
5363
5364                                                ; half == rax => e1-e2 is pos => e1 > e2
5365tmp_40:
5366
5367        mov qword [rdi], 1
5368        add rsp, 40
5369        ret
5370
5371tmp_41:
5372
5373        mov qword [rdi], 0
5374        add rsp, 40
5375        ret
5376
5377
5378geq_neq:
5379
5380
5381
5382
5383
5384
5385
5386
5387        mov     rax, [rsp + 32]
5388        cmp     [half + 24], rax     ; comare with (q-1)/2
5389        jc tmp_43                           ; half<rax => e1-e2 is neg => e1 < e2
5390        jnz tmp_42                       ; half>rax => e1 -e2 is pos => e1 > e2
5391
5392        mov     rax, [rsp + 24]
5393        cmp     [half + 16], rax     ; comare with (q-1)/2
5394        jc tmp_43                           ; half<rax => e1-e2 is neg => e1 < e2
5395        jnz tmp_42                       ; half>rax => e1 -e2 is pos => e1 > e2
5396
5397        mov     rax, [rsp + 16]
5398        cmp     [half + 8], rax     ; comare with (q-1)/2
5399        jc tmp_43                           ; half<rax => e1-e2 is neg => e1 < e2
5400        jnz tmp_42                       ; half>rax => e1 -e2 is pos => e1 > e2
5401
5402        mov     rax, [rsp + 8]
5403        cmp     [half + 0], rax     ; comare with (q-1)/2
5404        jc tmp_43                           ; half<rax => e1-e2 is neg => e1 < e2
5405        jnz tmp_42                       ; half>rax => e1 -e2 is pos => e1 > e2
5406
5407                                                ; half == rax => e1-e2 is pos => e1 > e2
5408tmp_42:
5409
5410        mov qword [rdi], 1
5411        add rsp, 40
5412        ret
5413
5414tmp_43:
5415
5416        mov qword [rdi], 0
5417        add rsp, 40
5418        ret
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436;;;;;;;;;;;;;;;;;;;;;;
5437; land
5438;;;;;;;;;;;;;;;;;;;;;;
5439; Logical and between two elements
5440; Params:
5441;   rsi <= Pointer to element 1
5442;   rdx <= Pointer to element 2
5443;   rdi <= Pointer to result zero or one
5444; Modified Registers:
5445;    rax, rcx, r8
5446;;;;;;;;;;;;;;;;;;;;;;
5447Fr_land:
5448
5449
5450
5451
5452
5453
5454    mov     rax, [rsi]
5455    bt      rax, 63
5456    jc      tmp_44
5457
5458    test    eax, eax
5459    jz      retZero_46
5460    jmp     retOne_45
5461
5462tmp_44:
5463
5464    mov     rax, [rsi + 8]
5465    test    rax, rax
5466    jnz     retOne_45
5467
5468    mov     rax, [rsi + 16]
5469    test    rax, rax
5470    jnz     retOne_45
5471
5472    mov     rax, [rsi + 24]
5473    test    rax, rax
5474    jnz     retOne_45
5475
5476    mov     rax, [rsi + 32]
5477    test    rax, rax
5478    jnz     retOne_45
5479
5480
5481retZero_46:
5482    mov     qword r8, 0
5483    jmp     done_47
5484
5485retOne_45:
5486    mov     qword r8, 1
5487
5488done_47:
5489
5490
5491
5492
5493
5494
5495
5496    mov     rax, [rdx]
5497    bt      rax, 63
5498    jc      tmp_48
5499
5500    test    eax, eax
5501    jz      retZero_50
5502    jmp     retOne_49
5503
5504tmp_48:
5505
5506    mov     rax, [rdx + 8]
5507    test    rax, rax
5508    jnz     retOne_49
5509
5510    mov     rax, [rdx + 16]
5511    test    rax, rax
5512    jnz     retOne_49
5513
5514    mov     rax, [rdx + 24]
5515    test    rax, rax
5516    jnz     retOne_49
5517
5518    mov     rax, [rdx + 32]
5519    test    rax, rax
5520    jnz     retOne_49
5521
5522
5523retZero_50:
5524    mov     qword rcx, 0
5525    jmp     done_51
5526
5527retOne_49:
5528    mov     qword rcx, 1
5529
5530done_51:
5531
5532        and rcx, r8
5533        mov [rdi], rcx
5534        ret
5535
5536
5537;;;;;;;;;;;;;;;;;;;;;;
5538; lor
5539;;;;;;;;;;;;;;;;;;;;;;
5540; Logical or between two elements
5541; Params:
5542;   rsi <= Pointer to element 1
5543;   rdx <= Pointer to element 2
5544;   rdi <= Pointer to result zero or one
5545; Modified Registers:
5546;    rax, rcx, r8
5547;;;;;;;;;;;;;;;;;;;;;;
5548Fr_lor:
5549
5550
5551
5552
5553
5554
5555    mov     rax, [rsi]
5556    bt      rax, 63
5557    jc      tmp_52
5558
5559    test    eax, eax
5560    jz      retZero_54
5561    jmp     retOne_53
5562
5563tmp_52:
5564
5565    mov     rax, [rsi + 8]
5566    test    rax, rax
5567    jnz     retOne_53
5568
5569    mov     rax, [rsi + 16]
5570    test    rax, rax
5571    jnz     retOne_53
5572
5573    mov     rax, [rsi + 24]
5574    test    rax, rax
5575    jnz     retOne_53
5576
5577    mov     rax, [rsi + 32]
5578    test    rax, rax
5579    jnz     retOne_53
5580
5581
5582retZero_54:
5583    mov     qword r8, 0
5584    jmp     done_55
5585
5586retOne_53:
5587    mov     qword r8, 1
5588
5589done_55:
5590
5591
5592
5593
5594
5595
5596
5597    mov     rax, [rdx]
5598    bt      rax, 63
5599    jc      tmp_56
5600
5601    test    eax, eax
5602    jz      retZero_58
5603    jmp     retOne_57
5604
5605tmp_56:
5606
5607    mov     rax, [rdx + 8]
5608    test    rax, rax
5609    jnz     retOne_57
5610
5611    mov     rax, [rdx + 16]
5612    test    rax, rax
5613    jnz     retOne_57
5614
5615    mov     rax, [rdx + 24]
5616    test    rax, rax
5617    jnz     retOne_57
5618
5619    mov     rax, [rdx + 32]
5620    test    rax, rax
5621    jnz     retOne_57
5622
5623
5624retZero_58:
5625    mov     qword rcx, 0
5626    jmp     done_59
5627
5628retOne_57:
5629    mov     qword rcx, 1
5630
5631done_59:
5632
5633        or rcx, r8
5634        mov [rdi], rcx
5635        ret
5636
5637
5638;;;;;;;;;;;;;;;;;;;;;;
5639; lnot
5640;;;;;;;;;;;;;;;;;;;;;;
5641; Do the logical not of an element
5642; Params:
5643;   rsi <= Pointer to element to be tested
5644;   rdi <= Pointer to result one if element1 is zero and zero otherwise
5645; Modified Registers:
5646;    rax, rax, r8
5647;;;;;;;;;;;;;;;;;;;;;;
5648Fr_lnot:
5649
5650
5651
5652
5653
5654
5655    mov     rax, [rsi]
5656    bt      rax, 63
5657    jc      tmp_60
5658
5659    test    eax, eax
5660    jz      retZero_62
5661    jmp     retOne_61
5662
5663tmp_60:
5664
5665    mov     rax, [rsi + 8]
5666    test    rax, rax
5667    jnz     retOne_61
5668
5669    mov     rax, [rsi + 16]
5670    test    rax, rax
5671    jnz     retOne_61
5672
5673    mov     rax, [rsi + 24]
5674    test    rax, rax
5675    jnz     retOne_61
5676
5677    mov     rax, [rsi + 32]
5678    test    rax, rax
5679    jnz     retOne_61
5680
5681
5682retZero_62:
5683    mov     qword rcx, 0
5684    jmp     done_63
5685
5686retOne_61:
5687    mov     qword rcx, 1
5688
5689done_63:
5690
5691        test rcx, rcx
5692
5693        jz lnot_retOne
5694lnot_retZero:
5695        mov qword [rdi], 0
5696        ret
5697lnot_retOne:
5698        mov qword [rdi], 1
5699        ret
5700
5701
5702
5703
5704        section .data
5705Fr_q:
5706        dd      0
5707        dd      0x80000000
5708q       dq      0x43e1f593f0000001,0x2833e84879b97091,0xb85045b68181585d,0x30644e72e131a029
5709half    dq      0xa1f0fac9f8000000,0x9419f4243cdcb848,0xdc2822db40c0ac2e,0x183227397098d014
5710R2      dq      0x1bb8e645ae216da7,0x53fe3ab1e35c59e3,0x8c49833d53bb8085,0x0216d0b17f4e44a5
5711R3      dq      0x5e94d8e1b4bf0040,0x2a489cbe1cfbb6b8,0x893cc664a19fcfed,0x0cf8594b7fcc657c
5712lboMask dq      0x1fffffffffffffff
5713