diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-25 13:07:24 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-25 13:07:24 -0700 |
commit | 55a7d4b85ca1f723d26b8956e8faeff730d0d240 (patch) | |
tree | 4f8e9460bbd2096971215b67321c14a14c3c1d3f /arch/h8300/lib/udivsi3.S | |
parent | aefbef10e3ae6e2c6e3c54f906f10b34c73a2c66 (diff) | |
parent | 07834743f42b4f27a21010cf5bab483b3ae3d13d (diff) |
Merge tag 'for-4.2' of git://git.sourceforge.jp/gitroot/uclinux-h8/linux
Pull Renesas H8/300 architecture re-introduction from Yoshinori Sato.
We dropped arch/h8300 two years ago as stale and old, this is a new and
more modern rewritten arch support for the same architecture.
* tag 'for-4.2' of git://git.sourceforge.jp/gitroot/uclinux-h8/linux: (27 commits)
h8300: fix typo.
h8300: Always build dtb
h8300: Remove ARCH_WANT_IPC_PARSE_VERSION
sh-sci: Get register size from platform device
clk: h8300: fix error handling in h8s2678_pll_clk_setup()
h8300: Symbol name fix
h8300: devicetree source
h8300: configs
h8300: IRQ chip driver
h8300: clocksource
h8300: clock driver
h8300: Build scripts
h8300: library functions
h8300: Memory management
h8300: miscellaneous functions
h8300: process helpers
h8300: compressed image support
h8300: Low level entry
h8300: kernel startup
h8300: Interrupt and exceptions
...
Diffstat (limited to 'arch/h8300/lib/udivsi3.S')
-rw-r--r-- | arch/h8300/lib/udivsi3.S | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/arch/h8300/lib/udivsi3.S b/arch/h8300/lib/udivsi3.S new file mode 100644 index 000000000000..bbe65610f316 --- /dev/null +++ b/arch/h8300/lib/udivsi3.S @@ -0,0 +1,76 @@ +#include "libgcc.h" + + ;; This function also computes the remainder and stores it in er3. + .global __udivsi3 +__udivsi3: + mov.w A1E,A1E ; denominator top word 0? + bne DenHighNonZero + + ; do it the easy way, see page 107 in manual + mov.w A0E,A2 + extu.l A2P + divxu.w A1,A2P + mov.w A2E,A0E + divxu.w A1,A0P + mov.w A0E,A3 + mov.w A2,A0E + extu.l A3P + rts + + ; er0 = er0 / er1 + ; er3 = er0 % er1 + ; trashes er1 er2 + ; expects er1 >= 2^16 +DenHighNonZero: + mov.l er0,er3 + mov.l er1,er2 +#ifdef CONFIG_CPU_H8300H +divmod_L21: + shlr.l er0 + shlr.l er2 ; make divisor < 2^16 + mov.w e2,e2 + bne divmod_L21 +#else + shlr.l #2,er2 ; make divisor < 2^16 + mov.w e2,e2 + beq divmod_L22A +divmod_L21: + shlr.l #2,er0 +divmod_L22: + shlr.l #2,er2 ; make divisor < 2^16 + mov.w e2,e2 + bne divmod_L21 +divmod_L22A: + rotxl.w r2 + bcs divmod_L23 + shlr.l er0 + bra divmod_L24 +divmod_L23: + rotxr.w r2 + shlr.l #2,er0 +divmod_L24: +#endif + ;; At this point, + ;; er0 contains shifted dividend + ;; er1 contains divisor + ;; er2 contains shifted divisor + ;; er3 contains dividend, later remainder + divxu.w r2,er0 ; r0 now contains the approximate quotient (AQ) + extu.l er0 + beq divmod_L25 + subs #1,er0 ; er0 = AQ - 1 + mov.w e1,r2 + mulxu.w r0,er2 ; er2 = upper (AQ - 1) * divisor + sub.w r2,e3 ; dividend - 65536 * er2 + mov.w r1,r2 + mulxu.w r0,er2 ; compute er3 = remainder (tentative) + sub.l er2,er3 ; er3 = dividend - (AQ - 1) * divisor +divmod_L25: + cmp.l er1,er3 ; is divisor < remainder? + blo divmod_L26 + adds #1,er0 + sub.l er1,er3 ; correct the remainder +divmod_L26: + rts + + .end |