?login_element?

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*-------------------------------------------------------------------------
  2.    _divsint.c :- routine for signed int (16 bit) division. just calls
  3.                  routine for unsigned division after sign adjustment
  4.  
  5.    Copyright (C) 1999, Sandeep Dutta . sandeep.dutta@usa.net
  6.  
  7.    This library is free software; you can redistribute it and/or modify it
  8.    under the terms of the GNU General Public License as published by the
  9.    Free Software Foundation; either version 2, or (at your option) any
  10.    later version.
  11.  
  12.    This library is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.  
  17.    You should have received a copy of the GNU General Public License
  18.    along with this library; see the file COPYING. If not, write to the
  19.    Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
  20.    MA 02110-1301, USA.
  21.  
  22.    As a special exception, if you link this library with other files,
  23.    some of which are compiled with SDCC, to produce an executable,
  24.    this library does not by itself cause the resulting executable to
  25.    be covered by the GNU General Public License. This exception does
  26.    not however invalidate any other reasons why the executable file
  27.    might be covered by the GNU General Public License.
  28. -------------------------------------------------------------------------*/
  29.  
  30.  
  31. #include <sdcc-lib.h>
  32.  
  33. #if _SDCC_MANGLES_SUPPORT_FUNS
  34. unsigned unsigned _divuint (unsigned x, unsigned y);
  35. #endif
  36.  
  37. /*   Assembler-functions are provided for:
  38.      mcs51 small
  39.      mcs51 small stack-auto
  40. */
  41.  
  42. #if !defined(__SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
  43. #  if defined(__SDCC_mcs51)
  44. #    if defined(__SDCC_MODEL_SMALL)
  45. #      if defined(__SDCC_STACK_AUTO) && !defined(__SDCC_PARMS_IN_BANK1)
  46. #        define _DIVSINT_ASM_SMALL_AUTO
  47. #      else
  48. #        define _DIVSINT_ASM_SMALL
  49. #      endif
  50. #    endif
  51. #  endif
  52. #endif
  53.  
  54. #if defined _DIVSINT_ASM_SMALL
  55.  
  56. static void
  57. _divsint_dummy (void) __naked
  58. {
  59.         __asm
  60.  
  61.         #define xl      dpl
  62.         #define xh      dph
  63.  
  64.         .globl __divsint
  65.  
  66.         // _divsint_PARM_2 shares the same memory with _divuint_PARM_2
  67.         // and is defined in _divuint.c
  68. #if defined(__SDCC_PARMS_IN_BANK1)
  69.         #define yl      (b1_0)
  70.         #define yh      (b1_1)
  71. #else
  72.         #define yl      (__divsint_PARM_2)
  73.         #define yh      (__divsint_PARM_2 + 1)
  74. #endif
  75. __divsint:
  76.                                 ; xh in dph
  77.                                 ; yh in (__divsint_PARM_2 + 1)
  78.  
  79.         clr     F0              ; Flag 0 in PSW
  80.                                 ; available to user for general purpose
  81.         mov     a,xh
  82.         jnb     acc.7,a_not_negative
  83.  
  84.         setb    F0
  85.  
  86.         clr     a
  87.         clr     c
  88.         subb    a,xl
  89.         mov     xl,a
  90.         clr     a
  91.         subb    a,xh
  92.         mov     xh,a
  93.  
  94. a_not_negative:
  95.  
  96.         mov     a,yh
  97.         jnb     acc.7,b_not_negative
  98.  
  99.         cpl     F0
  100.  
  101.         clr     a
  102.         clr     c
  103.         subb    a,yl
  104.         mov     yl,a
  105.         clr     a
  106.         subb    a,yh
  107.         mov     yh,a
  108.  
  109. b_not_negative:
  110.  
  111.         lcall   __divuint
  112.  
  113.         jnb     F0,not_negative
  114.  
  115.         clr     a
  116.         clr     c
  117.         subb    a,xl
  118.         mov     xl,a
  119.         clr     a
  120.         subb    a,xh
  121.         mov     xh,a
  122.  
  123. not_negative:
  124.         ret
  125.  
  126.         __endasm;
  127. }
  128.  
  129. #elif defined _DIVSINT_ASM_SMALL_AUTO
  130.  
  131. static void
  132. _divsint_dummy (void) __naked
  133. {
  134.         __asm
  135.  
  136.         #define xl      dpl
  137.         #define xh      dph
  138.  
  139.         .globl __divsint
  140.  
  141. __divsint:
  142.  
  143.         clr     F0              ; Flag 0 in PSW
  144.                                 ; available to user for general purpose
  145.         mov     a,xh
  146.         jnb     acc.7,a_not_negative
  147.  
  148.         setb    F0
  149.  
  150.         clr     a
  151.         clr     c
  152.         subb    a,xl
  153.         mov     xl,a
  154.         clr     a
  155.         subb    a,xh
  156.         mov     xh,a
  157.  
  158. a_not_negative:
  159.  
  160.         mov     a,sp
  161.         add     a,#-2           ; 2 bytes return address
  162.         mov     r0,a            ; r0 points to yh
  163.         mov     a,@r0           ; a = yh
  164.  
  165.         jnb     acc.7,b_not_negative
  166.  
  167.         cpl     F0
  168.  
  169.         dec     r0
  170.  
  171.         clr     a
  172.         clr     c
  173.         subb    a,@r0           ; yl
  174.         mov     @r0,a
  175.         clr     a
  176.         inc     r0
  177.         subb    a,@r0           ; a = yh
  178.  
  179. b_not_negative:
  180.  
  181.         mov     r1,a            ; yh
  182.         dec     r0
  183.         mov     a,@r0           ; yl
  184.         mov     r0,a
  185.  
  186.         lcall   __divint
  187.  
  188.         jnb     F0,not_negative
  189.  
  190.         clr     a
  191.         clr     c
  192.         subb    a,xl
  193.         mov     xl,a
  194.         clr     a
  195.         subb    a,xh
  196.         mov     xh,a
  197.  
  198. not_negative:
  199.         ret
  200.  
  201.         __endasm;
  202. }
  203.  
  204. #else  // _DIVSINT_ASM_
  205.  
  206. int
  207. _divsint (int x, int y)
  208. {
  209.   register int r;
  210.  
  211.   r = (unsigned int)(x < 0 ? -x : x) / (unsigned int)(y < 0 ? -y : y);
  212.   if ((x < 0) ^ (y < 0))
  213.     return -r;
  214.   else
  215.     return r;
  216. }
  217.  
  218. #endif  // _DIVSINT_ASM_
  219.