aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/libgcc/config/rl78/divmodhi.S
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/libgcc/config/rl78/divmodhi.S')
-rw-r--r--gcc-4.9/libgcc/config/rl78/divmodhi.S337
1 files changed, 337 insertions, 0 deletions
diff --git a/gcc-4.9/libgcc/config/rl78/divmodhi.S b/gcc-4.9/libgcc/config/rl78/divmodhi.S
new file mode 100644
index 000000000..e08345a32
--- /dev/null
+++ b/gcc-4.9/libgcc/config/rl78/divmodhi.S
@@ -0,0 +1,337 @@
+/* HImode div/mod functions for the GCC support library for the Renesas RL78 processors.
+ Copyright (C) 2012-2014 Free Software Foundation, Inc.
+ Contributed by Red Hat.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef __RL78_G10__
+
+#include "vregs.h"
+
+ .macro make_generic which,need_result
+
+ .if \need_result
+ quot = r8
+ num = r10
+ den = r12
+ bit = r14
+ .else
+ num = r8
+ quot = r10
+ den = r12
+ bit = r14
+ .endif
+
+ quotB0 = quot
+ quotB1 = quot+1
+
+ numB0 = num
+ numB1 = num+1
+
+ denB0 = den
+ denB1 = den+1
+
+ bitB0 = bit
+ bitB1 = bit+1
+
+#if 1
+#define bit bc
+#define bitB0 c
+#define bitB1 b
+#endif
+
+num_lt_den\which:
+ .if \need_result
+ movw r8, #0
+ .else
+ movw ax, [sp+8]
+ movw r8, ax
+ .endif
+ ret
+
+ ;; These routines leave DE alone - the signed functions use DE
+ ;; to store sign information that must remain intact
+
+ .if \need_result
+
+generic_div:
+
+ .else
+
+generic_mod:
+
+ .endif
+
+ ;; (quot,rem) = 8[sp] /% 10[sp]
+
+ movw hl, sp
+ movw ax, [hl+10] ; denH
+ cmpw ax, [hl+8] ; numH
+ bh $num_lt_den\which
+
+ ;; (quot,rem) = 16[sp] /% 20[sp]
+
+ ;; copy numerator
+ movw ax, [hl+8]
+ movw num, ax
+
+ ;; copy denomonator
+ movw ax, [hl+10]
+ movw den, ax
+
+ movw ax, den
+ cmpw ax, #0
+ bnz $den_not_zero\which
+ movw num, #0
+ ret
+
+den_not_zero\which:
+ .if \need_result
+ ;; zero out quot
+ movw quot, #0
+ .endif
+
+ ;; initialize bit to 1
+ movw bit, #1
+
+; while (den < num && !(den & (1L << BITS_MINUS_1)))
+
+shift_den_bit\which:
+ movw ax, den
+ mov1 cy,a.7
+ bc $enter_main_loop\which
+ cmpw ax, num
+ bh $enter_main_loop\which
+
+ ;; den <<= 1
+; movw ax, den ; already has it from the cmpw above
+ shlw ax, 1
+ movw den, ax
+
+ ;; bit <<= 1
+ .if \need_result
+#ifdef bit
+ shlw bit, 1
+#else
+ movw ax, bit
+ shlw ax, 1
+ movw bit, ax
+#endif
+ .else
+ ;; if we don't need to compute the quotent, we don't need an
+ ;; actual bit *mask*, we just need to keep track of which bit
+ inc bitB0
+ .endif
+
+ br $shift_den_bit\which
+
+main_loop\which:
+
+ ;; if (num >= den) (cmp den > num)
+ movw ax, den
+ cmpw ax, num
+ bh $next_loop\which
+
+ ;; num -= den
+ movw ax, num
+ subw ax, den
+ movw num, ax
+
+ .if \need_result
+ ;; res |= bit
+ mov a, quotB0
+ or a, bitB0
+ mov quotB0, a
+ mov a, quotB1
+ or a, bitB1
+ mov quotB1, a
+ .endif
+
+next_loop\which:
+
+ ;; den >>= 1
+ movw ax, den
+ shrw ax, 1
+ movw den, ax
+
+ .if \need_result
+ ;; bit >>= 1
+ movw ax, bit
+ shrw ax, 1
+ movw bit, ax
+ .else
+ dec bitB0
+ .endif
+
+enter_main_loop\which:
+ .if \need_result
+ movw ax, bit
+ cmpw ax, #0
+ .else
+ cmp0 bitB0
+ .endif
+ bnz $main_loop\which
+
+main_loop_done\which:
+ ret
+ .endm
+
+ make_generic _d 1
+ make_generic _m 0
+
+;----------------------------------------------------------------------
+
+ .global ___udivhi3
+ .type ___udivhi3,@function
+___udivhi3:
+ ;; r8 = 4[sp] / 6[sp]
+ call $!generic_div
+ ret
+ .size ___udivhi3, . - ___udivhi3
+
+
+ .global ___umodhi3
+ .type ___umodhi3,@function
+___umodhi3:
+ ;; r8 = 4[sp] % 6[sp]
+ call $!generic_mod
+ ret
+ .size ___umodhi3, . - ___umodhi3
+
+;----------------------------------------------------------------------
+
+ .macro neg_ax
+ movw hl, ax
+ movw ax, #0
+ subw ax, [hl]
+ movw [hl], ax
+ .endm
+
+ .global ___divhi3
+ .type ___divhi3,@function
+___divhi3:
+ ;; r8 = 4[sp] / 6[sp]
+ movw de, #0
+ mov a, [sp+5]
+ mov1 cy, a.7
+ bc $div_signed_num
+ mov a, [sp+7]
+ mov1 cy, a.7
+ bc $div_signed_den
+ call $!generic_div
+ ret
+
+div_signed_num:
+ ;; neg [sp+4]
+ movw ax, sp
+ addw ax, #4
+ neg_ax
+ mov d, #1
+ mov a, [sp+7]
+ mov1 cy, a.7
+ bnc $div_unsigned_den
+div_signed_den:
+ ;; neg [sp+6]
+ movw ax, sp
+ addw ax, #6
+ neg_ax
+ mov e, #1
+div_unsigned_den:
+ call $!generic_div
+
+ mov a, d
+ cmp0 a
+ bz $div_skip_restore_num
+ ;; We have to restore the numerator [sp+4]
+ movw ax, sp
+ addw ax, #4
+ neg_ax
+ mov a, d
+div_skip_restore_num:
+ xor a, e
+ bz $div_no_neg
+ movw ax, #r8
+ neg_ax
+div_no_neg:
+ mov a, e
+ cmp0 a
+ bz $div_skip_restore_den
+ movw ax, sp
+ addw ax, #6
+ neg_ax
+div_skip_restore_den:
+ ret
+ .size ___divhi3, . - ___divhi3
+
+
+ .global ___modhi3
+ .type ___modhi3,@function
+___modhi3:
+ ;; r8 = 4[sp] % 6[sp]
+ movw de, #0
+ mov a, [sp+5]
+ mov1 cy, a.7
+ bc $mod_signed_num
+ mov a, [sp+7]
+ mov1 cy, a.7
+ bc $mod_signed_den
+ call $!generic_mod
+ ret
+
+mod_signed_num:
+ ;; neg [sp+4]
+ movw ax, sp
+ addw ax, #4
+ neg_ax
+ mov d, #1
+ mov a, [sp+7]
+ mov1 cy, a.7
+ bnc $mod_unsigned_den
+mod_signed_den:
+ ;; neg [sp+6]
+ movw ax, sp
+ addw ax, #6
+ neg_ax
+mod_unsigned_den:
+ call $!generic_mod
+
+ mov a, d
+ cmp0 a
+ bz $mod_no_neg
+ movw ax, #r8
+ neg_ax
+ ;; Also restore numerator
+ movw ax, sp
+ addw ax, #4
+ neg_ax
+mod_no_neg:
+ mov a, e
+ cmp0 a
+ bz $mod_skip_restore_den
+ movw ax, sp
+ addw ax, #6
+ neg_ax
+mod_skip_restore_den:
+ ret
+ .size ___modhi3, . - ___modhi3
+
+#endif