Yoshinori Sato | a71a29d | 2015-01-28 02:48:15 +0900 | [diff] [blame] | 1 | #include "libgcc.h" |
| 2 | |
| 3 | ;; This function also computes the remainder and stores it in er3. |
| 4 | .global __udivsi3 |
| 5 | __udivsi3: |
| 6 | mov.w A1E,A1E ; denominator top word 0? |
| 7 | bne DenHighNonZero |
| 8 | |
| 9 | ; do it the easy way, see page 107 in manual |
| 10 | mov.w A0E,A2 |
| 11 | extu.l A2P |
| 12 | divxu.w A1,A2P |
| 13 | mov.w A2E,A0E |
| 14 | divxu.w A1,A0P |
| 15 | mov.w A0E,A3 |
| 16 | mov.w A2,A0E |
| 17 | extu.l A3P |
| 18 | rts |
| 19 | |
| 20 | ; er0 = er0 / er1 |
| 21 | ; er3 = er0 % er1 |
| 22 | ; trashes er1 er2 |
| 23 | ; expects er1 >= 2^16 |
| 24 | DenHighNonZero: |
| 25 | mov.l er0,er3 |
| 26 | mov.l er1,er2 |
| 27 | #ifdef CONFIG_CPU_H8300H |
| 28 | divmod_L21: |
| 29 | shlr.l er0 |
| 30 | shlr.l er2 ; make divisor < 2^16 |
| 31 | mov.w e2,e2 |
| 32 | bne divmod_L21 |
| 33 | #else |
| 34 | shlr.l #2,er2 ; make divisor < 2^16 |
| 35 | mov.w e2,e2 |
| 36 | beq divmod_L22A |
| 37 | divmod_L21: |
| 38 | shlr.l #2,er0 |
| 39 | divmod_L22: |
| 40 | shlr.l #2,er2 ; make divisor < 2^16 |
| 41 | mov.w e2,e2 |
| 42 | bne divmod_L21 |
| 43 | divmod_L22A: |
| 44 | rotxl.w r2 |
| 45 | bcs divmod_L23 |
| 46 | shlr.l er0 |
| 47 | bra divmod_L24 |
| 48 | divmod_L23: |
| 49 | rotxr.w r2 |
| 50 | shlr.l #2,er0 |
| 51 | divmod_L24: |
| 52 | #endif |
| 53 | ;; At this point, |
| 54 | ;; er0 contains shifted dividend |
| 55 | ;; er1 contains divisor |
| 56 | ;; er2 contains shifted divisor |
| 57 | ;; er3 contains dividend, later remainder |
| 58 | divxu.w r2,er0 ; r0 now contains the approximate quotient (AQ) |
| 59 | extu.l er0 |
| 60 | beq divmod_L25 |
| 61 | subs #1,er0 ; er0 = AQ - 1 |
| 62 | mov.w e1,r2 |
| 63 | mulxu.w r0,er2 ; er2 = upper (AQ - 1) * divisor |
| 64 | sub.w r2,e3 ; dividend - 65536 * er2 |
| 65 | mov.w r1,r2 |
| 66 | mulxu.w r0,er2 ; compute er3 = remainder (tentative) |
| 67 | sub.l er2,er3 ; er3 = dividend - (AQ - 1) * divisor |
| 68 | divmod_L25: |
| 69 | cmp.l er1,er3 ; is divisor < remainder? |
| 70 | blo divmod_L26 |
| 71 | adds #1,er0 |
| 72 | sub.l er1,er3 ; correct the remainder |
| 73 | divmod_L26: |
| 74 | rts |
| 75 | |
| 76 | .end |