1;; Licensed to the .NET Foundation under one or more agreements. 2;; The .NET Foundation licenses this file to you under the MIT license. 3;; See the LICENSE file in the project root for more information. 4 5 6 .586 7 .model flat 8 option casemap:none 9 .code 10 11 12include AsmMacros.inc 13 14EXTERN RhExceptionHandling_ThrowClasslibOverflowException : PROC 15EXTERN RhExceptionHandling_ThrowClasslibDivideByZeroException : PROC 16EXTERN __alldiv : PROC 17EXTERN __allrem : PROC 18EXTERN __aulldiv : PROC 19EXTERN __aullrem : PROC 20EXTERN __aulldvrm : PROC 21EXTERN __alldvrm : PROC 22 23esp_offsetof_dividend_low equ 4 24esp_offsetof_dividend_high equ 8 25esp_offsetof_divisor_low equ 12 26esp_offsetof_divisor_high equ 16 27 28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 29;; 30;; RhpLDiv 31;; 32;; INPUT: [ESP+4]: dividend low 33;; [ESP+8]: dividend high 34;; [ESP+12]: divisor low 35;; [ESP+16]: divisor high 36;; 37;; OUTPUT: EAX: result low 38;; EDX: result high 39;; 40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 41FASTCALL_FUNC RhpLDiv, 16 42 43 ;; pretest for the problematic cases of overflow and divide by zero 44 ;; overflow: dividend = 0x80000000`00000000 and divisor = -1l = 0xffffffff`ffffffff 45 ;; divide by zero: divisor = 0x00000000`00000000 46 ;; 47 ;; quick pretest - if the two halves of the divisor are unequal, we cannot 48 ;; have one of the problematic cases 49 mov eax,[esp+esp_offsetof_divisor_low] 50 cmp eax,[esp+esp_offsetof_divisor_high] 51 je LDivDoMoreTests 52LDivOkToDivide: 53 ;; tailcall to the actual divide routine 54 jmp __alldiv 55LDivDoMoreTests: 56 ;; we know the high and low halves of the divisor are equal 57 ;; 58 ;; check for the divide by zero case 59 test eax,eax 60 je ThrowClasslibDivideByZeroException 61 ;; 62 ;; is the divisor == -1l? I.e., can we have the overflow case? 63 cmp eax,-1 64 jne LDivOkToDivide 65 ;; 66 ;; is the dividend == 0x80000000`00000000? 67 cmp dword ptr [esp+esp_offsetof_dividend_low],0 68 jne LDivOkToDivide 69 cmp dword ptr [esp+esp_offsetof_dividend_high],80000000h 70 jne LDivOkToDivide 71FASTCALL_ENDFUNC 72 73 ;; make it look like the managed code called this directly 74 ;; by popping the parameters and putting the return address in the proper place 75ThrowClasslibOverflowException proc 76 pop ecx 77 add esp,16 78 push ecx 79 ;; passing return address in ecx 80 jmp RhExceptionHandling_ThrowClasslibOverflowException 81ThrowClasslibOverflowException endp 82 83ThrowClasslibDivideByZeroException proc 84 pop ecx 85 add esp,16 86 push ecx 87 ;; passing return address in ecx 88 jmp RhExceptionHandling_ThrowClasslibDivideByZeroException 89ThrowClasslibDivideByZeroException endp 90 91;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 92;; 93;; RhpLMod 94;; 95;; INPUT: [ESP+4]: dividend low 96;; [ESP+8]: dividend high 97;; [ESP+12]: divisor low 98;; [ESP+16]: divisor high 99;; 100;; OUTPUT: EAX: result low 101;; EDX: result high 102;; 103;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 104FASTCALL_FUNC RhpLMod, 16 105 106 ;; pretest for the problematic cases of overflow and divide by zero 107 ;; overflow: dividend = 0x80000000`00000000 and divisor = -1l = 0xffffffff`ffffffff 108 ;; divide by zero: divisor = 0x00000000`00000000 109 ;; 110 ;; quick pretest - if the two halves of the divisor are unequal, we cannot 111 ;; have one of the problematic cases 112 mov eax,[esp+esp_offsetof_divisor_low] 113 cmp eax,[esp+esp_offsetof_divisor_high] 114 je LModDoMoreTests 115LModOkToDivide: 116 jmp __allrem 117LModDoMoreTests: 118 ;; we know the high and low halves of the divisor are equal 119 ;; 120 ;; check for the divide by zero case 121 test eax,eax 122 je ThrowClasslibDivideByZeroException 123 ;; 124 ;; is the divisor == -1l? I.e., can we have the overflow case? 125 cmp eax,-1 126 jne LModOkToDivide 127 ;; 128 ;; is the dividend == 0x80000000`00000000? 129 cmp dword ptr [esp+esp_offsetof_dividend_low],0 130 jne LModOkToDivide 131 cmp dword ptr [esp+esp_offsetof_dividend_high],80000000h 132 jne LModOkToDivide 133 jmp ThrowClasslibOverflowException 134 135FASTCALL_ENDFUNC 136 137;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 138;; 139;; RhpLDivMod 140;; 141;; INPUT: [ESP+4]: dividend low 142;; [ESP+8]: dividend high 143;; [ESP+12]: divisor low 144;; [ESP+16]: divisor high 145;; 146;; OUTPUT: EAX: quotient low 147;; EDX: quotient high 148;; ECX: remainder high 149;; EBX: remainder high 150;; 151;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 152FASTCALL_FUNC RhpLDivMod, 16 153 154 ;; pretest for the problematic cases of overflow and divide by zero 155 ;; overflow: dividend = 0x80000000`00000000 and divisor = -1l = 0xffffffff`ffffffff 156 ;; divide by zero: divisor = 0x00000000`00000000 157 ;; 158 ;; quick pretest - if the two halves of the divisor are unequal, we cannot 159 ;; have one of the problematic cases 160 mov eax,[esp+esp_offsetof_divisor_low] 161 cmp eax,[esp+esp_offsetof_divisor_high] 162 je LDivModDoMoreTests 163LDivModOkToDivide: 164 jmp __alldvrm 165LDivModDoMoreTests: 166 ;; we know the high and low halves of the divisor are equal 167 ;; 168 ;; check for the divide by zero case 169 test eax,eax 170 je ThrowClasslibDivideByZeroException 171 ;; 172 ;; is the divisor == -1l? I.e., can we have the overflow case? 173 cmp eax,-1 174 jne LDivModOkToDivide 175 ;; 176 ;; is the dividend == 0x80000000`00000000? 177 cmp dword ptr [esp+esp_offsetof_dividend_low],0 178 jne LDivModOkToDivide 179 cmp dword ptr [esp+esp_offsetof_dividend_high],80000000h 180 jne LDivModOkToDivide 181 jmp ThrowClasslibOverflowException 182 183FASTCALL_ENDFUNC 184 185;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 186;; 187;; RhpULDiv 188;; 189;; INPUT: [ESP+4]: dividend low 190;; [ESP+8]: dividend high 191;; [ESP+12]: divisor low 192;; [ESP+16]: divisor high 193;; 194;; OUTPUT: EAX: result low 195;; EDX: result high 196;; 197;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 198FASTCALL_FUNC RhpULDiv, 16 199 200 ;; pretest for divide by zero 201 mov eax,[esp+esp_offsetof_divisor_low] 202 or eax,[esp+esp_offsetof_divisor_high] 203 jne __aulldiv 204 jmp ThrowClasslibDivideByZeroException 205 206FASTCALL_ENDFUNC 207 208;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 209;; 210;; RhpULMod 211;; 212;; INPUT: [ESP+4]: dividend low 213;; [ESP+8]: dividend high 214;; [ESP+12]: divisor low 215;; [ESP+16]: divisor high 216;; 217;; OUTPUT: EAX: result low 218;; EDX: result high 219;; 220;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 221FASTCALL_FUNC RhpULMod, 16 222 223 ;; pretest for divide by zero 224 mov eax,[esp+esp_offsetof_divisor_low] 225 or eax,[esp+esp_offsetof_divisor_high] 226 jne __aullrem 227 jmp ThrowClasslibDivideByZeroException 228 229FASTCALL_ENDFUNC 230 231;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 232;; 233;; RhpULDivMod 234;; 235;; INPUT: [ESP+4]: dividend low 236;; [ESP+8]: dividend high 237;; [ESP+12]: divisor low 238;; [ESP+16]: divisor high 239;; 240;; OUTPUT: EAX: quotient low 241;; EDX: quotient high 242;; ECX: remainder high 243;; EBX: remainder high 244;; 245;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 246FASTCALL_FUNC RhpULDivMod, 16 247 248 ;; pretest for divide by zero 249 mov eax,[esp+esp_offsetof_divisor_low] 250 or eax,[esp+esp_offsetof_divisor_high] 251 jne __aulldvrm 252 jmp ThrowClasslibDivideByZeroException 253 254FASTCALL_ENDFUNC 255 256 257 end 258