Changeset 98508 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Feb 8, 2023 3:31:06 PM (2 years ago)
- Location:
- trunk/src/VBox/Runtime/common/compiler/vcc
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/compiler/vcc/RTVccUInt64Div.cpp
r98493 r98508 42 42 43 43 44 DECLASM(void) RTVccUInt64Div(RTUINT64U const *paDividendDivisor, RTUINT64U *paQuotientRem inder)44 DECLASM(void) RTVccUInt64Div(RTUINT64U const *paDividendDivisor, RTUINT64U *paQuotientRemainder) 45 45 { 46 RTUInt64DivRem(&paQuotientRem inder[0], &paQuotientReminder[1], &paDividendDivisor[0], &paDividendDivisor[1]);46 RTUInt64DivRem(&paQuotientRemainder[0], &paQuotientRemainder[1], &paDividendDivisor[0], &paDividendDivisor[1]); 47 47 } 48 48 -
trunk/src/VBox/Runtime/common/compiler/vcc/x86-alldiv.asm
r98495 r98508 49 49 50 50 ;; 51 ; Division of signed 64-bit values, returning both the quotient and rem inder.51 ; Division of signed 64-bit values, returning both the quotient and remainder. 52 52 ; 53 53 ; @returns EDX:EAX Quotient. -
trunk/src/VBox/Runtime/common/compiler/vcc/x86-alldvrm.asm
r98495 r98508 49 49 50 50 ;; 51 ; Division of signed 64-bit values, returning both the quotient and rem inder.51 ; Division of signed 64-bit values, returning both the quotient and remainder. 52 52 ; 53 53 ; @returns EDX:EAX Quotient, EBX:ECX Remainder. -
trunk/src/VBox/Runtime/common/compiler/vcc/x86-allrem.asm
r98495 r98508 49 49 50 50 ;; 51 ; Division of signed 64-bit values, returning the rem inder.51 ; Division of signed 64-bit values, returning the remainder. 52 52 ; 53 53 ; @returns EDX:EAX Remainder. -
trunk/src/VBox/Runtime/common/compiler/vcc/x86-aulldiv.asm
r98493 r98508 58 58 push ebp 59 59 mov ebp, esp 60 sub esp, 10h ; space for quotient and rem inder.60 sub esp, 10h ; space for quotient and remainder. 61 61 62 ; Call RTVccUInt64Div(RTUINT64U const *paDividendDivisor, RTUINT64U *paQuotientRem inder)62 ; Call RTVccUInt64Div(RTUINT64U const *paDividendDivisor, RTUINT64U *paQuotientRemainder) 63 63 mov edx, esp 64 64 push edx -
trunk/src/VBox/Runtime/common/compiler/vcc/x86-aulldvrm.asm
r98493 r98508 49 49 50 50 ;; 51 ; Division of unsigned 64-bit values, returning both quotient and rem inder.51 ; Division of unsigned 64-bit values, returning both quotient and remainder. 52 52 ; 53 53 ; @returns Quotient in edx:eax, remainder in ebx:ecx. … … 60 60 push ebp 61 61 mov ebp, esp 62 sub esp, 10h ; space for quotient and reminder.63 62 64 ; Call RTVccUInt64Div(RTUINT64U const *paDividendDivisor, RTUINT64U *paQuotientReminder) 63 %define DIVIDEND_LO ebp + 08h 64 %define DIVIDEND_HI ebp + 0ch 65 %define DIVISOR_LO ebp + 10h 66 %define DIVISOR_HI ebp + 14h 67 68 ; 69 ; If the divisor is only 32-bit wide as we can do a two-step division on 32-bit units. 70 ; 71 mov ebx, [DIVISOR_HI] 72 or ebx, ebx 73 jnz .full_64_bit_divisor 74 75 ; step 1: dividend_hi / divisor 76 mov ebx, [DIVISOR_LO] 77 mov eax, [DIVIDEND_HI] 78 xor edx, edx 79 div ebx 80 mov ecx, eax ; high quotient bits. 81 82 ; step 2: (dividend_lo + step_1_remainder) / divisor 83 mov eax, [DIVIDEND_LO] ; edx contains the remainder from the first step. 84 div ebx ; -> eax = low quotient, edx = remainder. 85 86 xchg edx, ecx ; ecx = (low) remainder, edx = saved high quotient from step 1 87 xor ebx, ebx ; ebx = high remainder is zero, since divisor is 32-bit. 88 89 leave 90 ret 10h 91 92 %if 1 93 ; 94 ; The divisor is larger than 32 bits. 95 ; 96 ; We can approximate the quotient by reducing the divisor to 32 bits 97 ; (reducing the dividend accordingly) and perform a 32-bit division. 98 ; The result will be at most one off. 99 ; 100 ; The remainder has to be calculated using multiplication and 101 ; subtraction. 102 ; 103 .full_64_bit_divisor: 104 push edi 105 106 ; Find the shift count needed to reduce the divisor to 32-bit. 107 bsr ecx, ebx 108 inc cl 109 test cl, ~31 110 jnz .shift_32 111 112 ; Shift the divisor into edi. 113 mov edi, [DIVISOR_LO] 114 shrd edi, ebx, cl ; edi = reduced divisor 115 116 ; Shift the dividend into edx:eax. 117 mov eax, [DIVIDEND_LO] 118 mov edx, [DIVIDEND_HI] 119 shrd eax, edx, cl 120 shr edx, cl 121 jmp .shifted 122 123 .shift_32: ; simplified version. 124 mov edi, ebx 125 mov eax, [DIVIDEND_HI] 126 xor edx, edx 127 .shifted: 128 129 ; Divide and save the approximate quotient (Qapprox) in edi. 130 div edi 131 mov edi, eax ; edi = Qapprox 132 133 ; Now multiply Qapprox with the divisor. 134 mul dword [DIVISOR_HI] 135 mov ecx, eax ; temporary storage 136 mov eax, [DIVISOR_LO] 137 mul edi 138 add edx, ecx ; edx:eax = QapproxDividend = Qapprox * divisor 139 140 ; Preload the dividend into ebx:ecx for remainder calculation and for adjusting Qapprox. 141 mov ecx, [DIVIDEND_LO] 142 mov ebx, [DIVIDEND_HI] 143 144 ; If carry is set, the result overflowed 64 bits, so the quotient must be too large. 145 jc .quotient_is_one_above_and_calc_remainder 146 147 ; Calculate the remainder, if this overflows (CF) it means Qapprox is 148 ; one above and we need to reduce it and the adjust the remainder. 149 sub ecx, eax 150 sbb ebx, edx 151 jc .quotient_is_one_above 152 .done: 153 mov eax, edi 154 xor edx, edx 155 156 pop edi 157 leave 158 ret 10h 159 160 .quotient_is_one_above_and_calc_remainder: 161 sub ecx, eax 162 sbb ebx, edx 163 .quotient_is_one_above: 164 add ecx, [DIVISOR_LO] 165 adc ebx, [DIVISOR_HI] 166 dec edi 167 jmp .done 168 169 %else 170 ; 171 ; Fall back on a rather slow C implementation. 172 ; 173 .full_64_bit_divisor: 174 ; Call RTVccUInt64Div(RTUINT64U const *paDividendDivisor, RTUINT64U *paQuotientRemainder) 175 sub esp, 10h ; space for quotient and remainder. 65 176 mov edx, esp 66 177 push edx … … 75 186 mov ecx, [ebp - 08h] 76 187 mov ebx, [ebp - 08h + 4] 77 78 188 leave 79 189 ret 10h 190 191 %endif 80 192 ENDPROC_RAW __aulldvrm 81 193 -
trunk/src/VBox/Runtime/common/compiler/vcc/x86-aullrem.asm
r98494 r98508 49 49 50 50 ;; 51 ; Division of unsigned 64-bit values, returning the rem inder.51 ; Division of unsigned 64-bit values, returning the remainder. 52 52 ; 53 53 ; @returns Remainder in edx:eax. … … 58 58 push ebp 59 59 mov ebp, esp 60 sub esp, 10h ; space for quotient and rem inder.60 sub esp, 10h ; space for quotient and remainder. 61 61 62 ; Call RTVccUInt64Div(RTUINT64U const *paDividendDivisor, RTUINT64U *paQuotientRem inder)62 ; Call RTVccUInt64Div(RTUINT64U const *paDividendDivisor, RTUINT64U *paQuotientRemainder) 63 63 mov edx, esp 64 64 push edx
Note:
See TracChangeset
for help on using the changeset viewer.