]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/builtins/hexagon/udivdi3.S
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / builtins / hexagon / udivdi3.S
1 //===----------------------Hexagon builtin routine ------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10
11         .macro FUNCTION_BEGIN name
12         .text
13         .p2align 5
14         .globl \name
15         .type  \name, @function
16 \name:
17         .endm
18
19         .macro FUNCTION_END name
20         .size  \name, . - \name
21         .endm
22
23
24 FUNCTION_BEGIN __hexagon_udivdi3
25         {
26                 r6 = cl0(r1:0)              // count leading 0's of dividend (numerator)
27                 r7 = cl0(r3:2)              // count leading 0's of divisor (denominator)
28                 r5:4 = r3:2                 // divisor moved into working registers
29                 r3:2 = r1:0                 // dividend is the initial remainder, r3:2 contains remainder
30         }
31         {
32                 r10 = sub(r7,r6)            // left shift count for bit & divisor
33                 r1:0 = #0                   // initialize quotient to 0
34                 r15:14 = #1                 // initialize bit to 1
35         }
36         {
37                 r11 = add(r10,#1)           // loop count is 1 more than shift count
38                 r13:12 = lsl(r5:4,r10)      // shift divisor msb into same bit position as dividend msb
39                 r15:14 = lsl(r15:14,r10)    // shift the bit left by same amount as divisor
40         }
41         {
42                 p0 = cmp.gtu(r5:4,r3:2)     // check if divisor > dividend
43                 loop0(1f,r11)               // register loop
44         }
45         {
46                 if (p0) jumpr r31           // if divisor > dividend, we're done, so return
47         }
48         .falign
49 1:
50         {
51                 p0 = cmp.gtu(r13:12,r3:2)   // set predicate reg if shifted divisor > current remainder
52         }
53         {
54                 r7:6 = sub(r3:2, r13:12)    // subtract shifted divisor from current remainder
55                 r9:8 = add(r1:0, r15:14)    // save current quotient to temp (r9:8)
56         }
57         {
58                 r1:0 = vmux(p0, r1:0, r9:8) // choose either current quotient or new quotient (r9:8)
59                 r3:2 = vmux(p0, r3:2, r7:6) // choose either current remainder or new remainder (r7:6)
60         }
61         {
62                 r15:14 = lsr(r15:14, #1)    // shift bit right by 1 for next iteration
63                 r13:12 = lsr(r13:12, #1)    // shift "shifted divisor" right by 1 for next iteration
64         }:endloop0
65         {
66                 jumpr r31                   // return
67         }
68 FUNCTION_END __hexagon_udivdi3
69
70   .globl __qdsp_udivdi3
71   .set   __qdsp_udivdi3, __hexagon_udivdi3