?login_element?

Subversion Repositories NedoOS

Rev

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

  1. /*-------------------------------------------------------------------------
  2.    _modslong.c - routine for modulus of 32 bit signed long
  3.  
  4.    Copyright (C) 1999, Sandeep Dutta . sandeep.dutta@usa.net
  5.  
  6.    This library is free software; you can redistribute it and/or modify it
  7.    under the terms of the GNU General Public License as published by the
  8.    Free Software Foundation; either version 2, or (at your option) any
  9.    later version.
  10.  
  11.    This library is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with this library; see the file COPYING. If not, write to the
  18.    Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
  19.    MA 02110-1301, USA.
  20.  
  21.    As a special exception, if you link this library with other files,
  22.    some of which are compiled with SDCC, to produce an executable,
  23.    this library does not by itself cause the resulting executable to
  24.    be covered by the GNU General Public License. This exception does
  25.    not however invalidate any other reasons why the executable file
  26.    might be covered by the GNU General Public License.
  27. -------------------------------------------------------------------------*/
  28.  
  29. #include <sdcc-lib.h>
  30.  
  31. #if _SDCC_MANGLES_SUPPORT_FUNS
  32. unsigned long _modulong (unsigned long a, unsigned long b);
  33. #endif
  34.  
  35. /*   Assembler-functions are provided for:
  36.      mcs51 small
  37.      mcs51 small stack-auto
  38. */
  39.  
  40. #if !defined(__SDCC_USE_XSTACK) && !defined(_SDCC_NO_ASM_LIB_FUNCS)
  41. #  if defined(__SDCC_mcs51)
  42. #    if defined(__SDCC_MODEL_SMALL)
  43. #      if defined(__SDCC_STACK_AUTO) && !defined(__SDCC_PARMS_IN_BANK1)
  44. #        define _MODSLONG_ASM_SMALL_AUTO
  45. #      else
  46. #        define _MODSLONG_ASM_SMALL
  47. #      endif
  48. #    endif
  49. #  endif
  50. #endif
  51.  
  52. #if defined _MODSLONG_ASM_SMALL
  53.  
  54. static void
  55. _modslong_dummy (void) __naked
  56. {
  57.         __asm
  58.  
  59.         #define a0      dpl
  60.         #define a1      dph
  61.         #define a2      b
  62.         #define a3      r1
  63.  
  64.         .globl __modslong
  65. #if defined(__SDCC_PARMS_IN_BANK1)
  66.         #define b0      (b1_0)
  67.         #define b1      (b1_1)
  68.         #define b2      (b1_2)
  69.         #define b3      (b1_3)
  70. #else
  71.         // _modslong_PARM_2 shares the same memory with _modulong_PARM_2
  72.         // and is defined in _modulong.c
  73.         #define b0      (__modslong_PARM_2)
  74.         #define b1      (__modslong_PARM_2 + 1)
  75.         #define b2      (__modslong_PARM_2 + 2)
  76.         #define b3      (__modslong_PARM_2 + 3)
  77. #endif
  78. __modslong:
  79.                                 ; a3 in acc
  80.                                 ; b3 in (__modslong_PARM_2 + 3)
  81.         mov     a3,a            ; save a3
  82.  
  83.         clr     F0              ; Flag 0 in PSW
  84.                                 ; available to user for general purpose
  85.         jnb     acc.7,a_not_negative
  86.  
  87.         setb    F0
  88.  
  89.         clr     a               ; a = -a;
  90.         clr     c
  91.         subb    a,a0
  92.         mov     a0,a
  93.         clr     a
  94.         subb    a,a1
  95.         mov     a1,a
  96.         clr     a
  97.         subb    a,a2
  98.         mov     a2,a
  99.         clr     a
  100.         subb    a,a3
  101.         mov     a3,a
  102.  
  103. a_not_negative:
  104.  
  105.         mov     a,b3
  106.         jnb     acc.7,b_not_negative
  107.  
  108.         clr     a               ; b = -b;
  109.         clr     c
  110.         subb    a,b0
  111.         mov     b0,a
  112.         clr     a
  113.         subb    a,b1
  114.         mov     b1,a
  115.         clr     a
  116.         subb    a,b2
  117.         mov     b2,a
  118.         clr     a
  119.         subb    a,b3
  120.         mov     b3,a
  121.  
  122. b_not_negative:
  123.  
  124.         mov     a,a3            ; restore a3 in acc
  125.  
  126.         lcall   __modulong
  127.  
  128.         jnb     F0,not_negative
  129.  
  130.                                 ; result in (a == r1), b, dph, dpl
  131.         clr     a
  132.         clr     c
  133.         subb    a,a0
  134.         mov     a0,a
  135.         clr     a
  136.         subb    a,a1
  137.         mov     a1,a
  138.         clr     a
  139.         subb    a,a2
  140.         mov     a2,a
  141.         clr     a
  142.         subb    a,a3
  143.                                 ; result in a, b, dph, dpl
  144. not_negative:
  145.         ret
  146.  
  147.         __endasm;
  148. }
  149.  
  150. #elif defined _MODSLONG_ASM_SMALL_AUTO
  151.  
  152. static void
  153. _modslong_dummy (void) __naked
  154. {
  155.         __asm
  156.  
  157.         #define a0      dpl
  158.         #define a1      dph
  159.         #define a2      b
  160.         #define a3      r1
  161.  
  162.         #define b0      r2
  163.         #define b1      r3
  164.         #define b2      r4
  165.         #define b3      r5
  166.  
  167.         ar2 = 2                 ; BUG register set is not considered
  168.         ar3 = 3
  169.         ar4 = 4
  170.         ar5 = 5
  171.  
  172.         .globl __modslong
  173.  
  174. __modslong:
  175.  
  176.                                 ; a3 in acc
  177.         mov     a3,a            ; save a3
  178.  
  179.         clr     F0              ; F0 (Flag 0)
  180.                                 ; available to user for general purpose
  181.         jnb     acc.7,a_not_negative
  182.  
  183.         setb    F0
  184.  
  185.         clr     a               ; a = -a;
  186.         clr     c
  187.         subb    a,a0
  188.         mov     a0,a
  189.         clr     a
  190.         subb    a,a1
  191.         mov     a1,a
  192.         clr     a
  193.         subb    a,a2
  194.         mov     a2,a
  195.         clr     a
  196.         subb    a,a3
  197.         mov     a3,a
  198.  
  199. a_not_negative:
  200.  
  201.         mov     a,sp
  202.         add     a,#-2-3         ; 2 bytes return address, 3 bytes param b
  203.         mov     r0,a            ; r1 points to b0
  204.  
  205.         mov     ar2,@r0         ; load b0
  206.         inc     r0              ; r0 points to b1
  207.         mov     ar3,@r0         ; b1
  208.         inc     r0
  209.         mov     ar4,@r0         ; b2
  210.         inc     r0
  211.         mov     a,@r0           ; b3
  212.         mov     b3,a
  213.  
  214.         jnb     acc.7,b_not_negative
  215.  
  216.         clr     a               ; b = -b;
  217.         clr     c
  218.         subb    a,b0
  219.         mov     b0,a
  220.         clr     a
  221.         subb    a,b1
  222.         mov     b1,a
  223.         clr     a
  224.         subb    a,b2
  225.         mov     b2,a
  226.         clr     a
  227.         subb    a,b3
  228.         mov     b3,a
  229.  
  230. b_not_negative:
  231.  
  232.         lcall   __modlong
  233.  
  234.         jnb     F0,not_negative
  235.  
  236.                                 ; result in (a == r1), b, dph, dpl
  237.         clr     a
  238.         clr     c
  239.         subb    a,a0
  240.         mov     a0,a
  241.         clr     a
  242.         subb    a,a1
  243.         mov     a1,a
  244.         clr     a
  245.         subb    a,a2
  246.         mov     a2,a
  247.         clr     a
  248.         subb    a,a3            ; result in a, b, dph, dpl
  249.  
  250. not_negative:
  251.         ret
  252.  
  253.         __endasm;
  254. }
  255.  
  256. #else // _MODSLONG_ASM
  257.  
  258. long
  259. _modslong (long a, long b)
  260. {
  261.   long r;
  262.  
  263.   r = (unsigned long)(a < 0 ? -a : a) % (unsigned long)(b < 0 ? -b : b);
  264.  
  265.   if (a < 0)
  266.     return -r;
  267.   else
  268.     return r;
  269. }
  270.  
  271. #endif // _MODSLONG_ASM
  272.