]> git.proxmox.com Git - mirror_edk2.git/blobdiff - CryptoPkg/Library/IntrinsicLib/Ia32/MathLlmul.asm
CryptoPkg: Add instrinsics to support building ECC on IA32 windows
[mirror_edk2.git] / CryptoPkg / Library / IntrinsicLib / Ia32 / MathLlmul.asm
diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathLlmul.asm b/CryptoPkg/Library/IntrinsicLib/Ia32/MathLlmul.asm
new file mode 100644 (file)
index 0000000..341ea8a
--- /dev/null
@@ -0,0 +1,98 @@
+;***\r
+;llmul.asm - long multiply routine\r
+;\r
+;       Copyright (c) Microsoft Corporation. All rights reserved.\r
+;       SPDX-License-Identifier: BSD-2-Clause-Patent\r
+;\r
+;Purpose:\r
+;       Defines long multiply routine\r
+;       Both signed and unsigned routines are the same, since multiply's\r
+;       work out the same in 2's complement\r
+;       creates the following routine:\r
+;           __allmul\r
+;\r
+;Original Implemenation: MSVC 14.12.25827\r
+;\r
+;*******************************************************************************\r
+    .686\r
+    .model  flat,C\r
+    .code\r
+\r
+\r
+;***\r
+;llmul - long multiply routine\r
+;\r
+;Purpose:\r
+;       Does a long multiply (same for signed/unsigned)\r
+;       Parameters are not changed.\r
+;\r
+;Entry:\r
+;       Parameters are passed on the stack:\r
+;               1st pushed: multiplier (QWORD)\r
+;               2nd pushed: multiplicand (QWORD)\r
+;\r
+;Exit:\r
+;       EDX:EAX - product of multiplier and multiplicand\r
+;       NOTE: parameters are removed from the stack\r
+;\r
+;Uses:\r
+;       ECX\r
+;\r
+;Exceptions:\r
+;\r
+;*******************************************************************************\r
+_allmul PROC NEAR\r
+\r
+A       EQU     [esp + 4]       ; stack address of a\r
+B       EQU     [esp + 12]      ; stack address of b\r
+\r
+HIGH_PART  EQU     [4]             ;\r
+LOW_PART   EQU     [0]\r
+\r
+;\r
+;       AHI, BHI : upper 32 bits of A and B\r
+;       ALO, BLO : lower 32 bits of A and B\r
+;\r
+;             ALO * BLO\r
+;       ALO * BHI\r
+; +     BLO * AHI\r
+; ---------------------\r
+;\r
+\r
+        mov     eax,HIGH_PART(A)\r
+        mov     ecx,HIGH_PART(B)\r
+        or      ecx,eax         ;test for both high dwords zero.\r
+        mov     ecx,LOW_PART(B)\r
+        jnz     short hard      ;both are zero, just mult ALO and BLO\r
+\r
+        mov     eax,LOW_PART(A)\r
+        mul     ecx\r
+\r
+        ret     16              ; callee restores the stack\r
+\r
+hard:\r
+        push    ebx\r
+\r
+; must redefine A and B since esp has been altered\r
+\r
+A2      EQU     [esp + 8]       ; stack address of a\r
+B2      EQU     [esp + 16]      ; stack address of b\r
+\r
+        mul     ecx             ;eax has AHI, ecx has BLO, so AHI * BLO\r
+        mov     ebx,eax         ;save result\r
+\r
+        mov     eax,LOW_PART(A2)\r
+        mul     dword ptr HIGH_PART(B2) ;ALO * BHI\r
+        add     ebx,eax         ;ebx = ((ALO * BHI) + (AHI * BLO))\r
+\r
+        mov     eax,LOW_PART(A2);ecx = BLO\r
+        mul     ecx             ;so edx:eax = ALO*BLO\r
+        add     edx,ebx         ;now edx has all the LO*HI stuff\r
+\r
+        pop     ebx\r
+\r
+        ret     16              ; callee restores the stack\r
+\r
+_allmul ENDP\r
+\r
+        end\r