OpenCores
URL https://opencores.org/ocsvn/forwardcom/forwardcom/trunk

Subversion Repositories forwardcom

[/] [forwardcom/] [libraries/] [divide_int_light.as] - Blame information for rev 106

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 74 Agner
/****************************  divide_int_light.as **************************
2
* Author:        Agner Fog
3
* date created:  2021-05-26
4
* Last modified: 2021-05-26
5
* Version:       1.11
6
* Project:       ForwardCom library libc_light.li
7
* Description:   divide_int: divide two 32-bit signed integers
8
* This function is for small CPUs with limited capabilities and no division
9
* instruction. It returns the quotient and the remainder.
10
* Returns INT_MIN if dividing by zero.
11
*
12
* Copyright 2021 GNU General Public License http://www.gnu.org/licenses
13
*****************************************************************************/
14
 
15
 
16
code section execute
17
 
18
_divide_int function public reguse=3,0
19
  // divide two 32 bit signed integers. return quotient and remainder
20
  // input r0: dividend
21
  // input r1: divisor
22
  // output r0: r0 / r1
23
  // output r1: r0 % r1
24
 
25
  if (int32 r1 == 0) {jump divide_error} // check for division by 0
26
 
27
  // save r2 - r5
28
  int64 sp -= 4*8
29
  int64 [sp+0x00] = r2
30
  int64 [sp+0x08] = r3
31
  int64 [sp+0x10] = r4
32
  int64 [sp+0x18] = r5
33
 
34
  // get signs
35
  int32 r2 = r0 < 0                    // sign of r0
36
  int32 r0 = -r0, mask = r2            // abs(r0)
37
  int32 r3 = r1 < 0                    // sign of r1
38
  int32 r1 = -r1, mask = r3            // abs(r1)
39
  int r3 ^= r2                         // sign of result
40
  int r2 = 0                           // quotient calcuated in r2
41
  int r4 = bitscan(r0, 1)              // number of significant bits in dividend
42
  int r5 = bitscan(r1, 1)              // number of significant bits in divisor
43
  if (int r4 >= r5) {
44
    // division loop
45
    int r4 -= r5                       // approximate number of significant bits in quotient
46
    int r1 <<= r4                      // shift left divisor
47
    do {                               // loop r4 + 1 times
48
      uint32 r5 = r0 >= r1             // one bit of quotient
49
      int32 r0 -= r1, mask = r5        // subtract if bigger
50
      int32 r2 <<= 1                   // shift left quotient
51
      int32 r2 |= r5                   // add new bit
52
      uint32 r1 >>= 1                  // shift right divisor
53
      int r4--                         // loop counter
54
    } while (int r4 >= 0)
55
  }
56
  // quotient = r2, remainder = r0
57
  int32 r1 = r3 ? -r0 : r0             // apply sign to remainder
58
  int32 r0 = r3 ? -r2 : r2             // apply sign to quotient
59
 
60
  // restore r2 - r5
61
  int64 r2 = [sp+0x00]
62
  int64 r3 = [sp+0x08]
63
  int64 r4 = [sp+0x10]
64
  int64 r5 = [sp+0x18]
65
  int64 sp += 4*8
66
  return
67
 
68
  divide_error:                        // division by zero
69
  int32 r0 = 0x80000000                // return INT_MIN
70
  int32 r1 = 0
71
  return
72
 
73
code end

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.