• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
3  *
4  * UniProton is licensed under Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *          http://license.coscl.org.cn/MulanPSL2
8  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11  * See the Mulan PSL v2 for more details.
12  * Create: 2009-07-25
13  * Description: 64位除法文件。
14  */
15 #include "prt_typedef.h"
16 #include "prt_lib_external.h"
17 #include "prt_attr_external.h"
18 
19 #define OS_32_BITS_COUNT 32
20 
21 /*
22  * 描述:前导0个数获取
23  */
OsleadingZeroCount(U64 data)24 OS_SEC_TEXT U32 OsleadingZeroCount(U64 data)
25 {
26     U32 high = (U32)OS_GET_64BIT_HIGH_32BIT(data);
27     U32 low = (U32)OS_GET_64BIT_LOW_32BIT(data);
28     U32 count = 0;
29 
30     if (high == 0) {
31         OS_EMBED_ASM("CLZ %0, %1" : "=r"(count) : "r"(low));
32         count += OS_32_BITS_COUNT;
33     } else {
34         OS_EMBED_ASM("CLZ %0, %1" : "=r"(count) : "r"(high));
35     }
36 
37     return count;
38 }
39 
OsU64Div(U64 dividend,U64 divisor,U64 * quotient,U64 * remainder)40 OS_SEC_TEXT void OsU64Div(U64 dividend, U64 divisor, U64 *quotient, U64 *remainder)
41 {
42     U32 alignShift;
43     U32 i;
44     U64 tmpDivisor;
45     U64 tmpRemainder;
46     U64 tmpQuotient = 0;
47 
48     if (divisor == 0) {
49         return;                  // 除数为0返回1
50     }
51 
52     if (dividend < divisor) {
53         /* 被除数小于除数,商为0,余数即被除数 */
54         *remainder = dividend;
55         *quotient = 0;
56         return;
57     }
58 
59     alignShift = OsleadingZeroCount(divisor) - OsleadingZeroCount(dividend);
60     tmpDivisor = divisor << alignShift;
61     tmpRemainder = dividend;
62 
63     /* 竖式除法, 类大数相除 */
64     for (i = 0; i <= alignShift; i++) {
65         tmpQuotient <<= 1;
66         if (tmpRemainder >= tmpDivisor) {
67             tmpRemainder -= tmpDivisor;
68             tmpQuotient += 1;
69         }
70         tmpDivisor >>= 1;
71     }
72 
73     *quotient = tmpQuotient;
74     *remainder = tmpRemainder;
75 
76     return;
77 }
78 
OsU64DivGetQuotient(U64 dividend,U64 divisor)79 OS_SEC_TEXT U64 OsU64DivGetQuotient(U64 dividend, U64 divisor)
80 {
81     U64 quotient = 0;
82     U64 remainder;
83 
84     OsU64Div(dividend, divisor, &quotient, &remainder);
85 
86     return quotient;
87 }
88 
OsU64DivGetRemainder(U64 dividend,U64 divisor)89 OS_SEC_TEXT U64 OsU64DivGetRemainder(U64 dividend, U64 divisor)
90 {
91     U64 quotient;
92     U64 remainder = 0;
93 
94     OsU64Div(dividend, divisor, &quotient, &remainder);
95 
96     return remainder;
97 }