1+ use  std:: hint:: unreachable_unchecked; 
2+ use  std:: intrinsics:: { unchecked_div,  unchecked_rem} ; 
3+ 
14pub  struct  DivSqrt  { 
25    pub  sqrt_cnt :  u16 , 
3-     pub   sqrt_result :  u32 , 
6+     sqrt_result :  u32 , 
47    sqrt_param :  u64 , 
8+     sqrt_dirty :  bool , 
59    pub  div_cnt :  u16 , 
610    div_numer :  i64 , 
711    div_denom :  i64 , 
812    div_result :  i64 , 
913    divrem_result :  i64 , 
14+     div_dirty :  bool , 
1015} 
1116
1217impl  DivSqrt  { 
@@ -15,11 +20,13 @@ impl DivSqrt {
1520            sqrt_cnt :  0 , 
1621            sqrt_result :  0 , 
1722            sqrt_param :  0 , 
23+             sqrt_dirty :  true , 
1824            div_cnt :  0 , 
1925            div_numer :  0 , 
2026            div_denom :  0 , 
2127            div_result :  0 , 
2228            divrem_result :  0 , 
29+             div_dirty :  true , 
2330        } 
2431    } 
2532
@@ -31,7 +38,16 @@ impl DivSqrt {
3138        ( self . sqrt_param  >> 32 )  as  u32 
3239    } 
3340
41+     pub  fn  get_sqrt_result ( & mut  self )  -> u32  { 
42+         self . sqrt ( ) ; 
43+         self . sqrt_result 
44+     } 
45+ 
3446    fn  sqrt ( & mut  self )  { 
47+         if  !self . sqrt_dirty  { 
48+             return ; 
49+         } 
50+         self . sqrt_dirty  = false ; 
3551        if  self . sqrt_cnt  &  1  == 0  { 
3652            self . sqrt_result  = ( self . sqrt_param  as  u32 ) . isqrt ( ) ; 
3753        }  else  { 
@@ -42,17 +58,17 @@ impl DivSqrt {
4258    pub  fn  set_sqrt_cnt ( & mut  self ,  mut  mask :  u16 ,  value :  u16 )  { 
4359        mask &= 0x1 ; 
4460        self . sqrt_cnt  = ( self . sqrt_cnt  &  !mask)  | ( value &  mask) ; 
45-         self . sqrt ( ) ; 
61+         self . sqrt_dirty  =  true ; 
4662    } 
4763
4864    pub  fn  set_sqrt_param_l ( & mut  self ,  mask :  u32 ,  value :  u32 )  { 
4965        self . sqrt_param  = ( self . sqrt_param  &  !( mask as  u64 ) )  | ( value &  mask)  as  u64 ; 
50-         self . sqrt ( ) ; 
66+         self . sqrt_dirty  =  true ; 
5167    } 
5268
5369    pub  fn  set_sqrt_param_h ( & mut  self ,  mask :  u32 ,  value :  u32 )  { 
5470        self . sqrt_param  = ( self . sqrt_param  &  !( ( mask as  u64 )  << 32 ) )  | ( ( ( value &  mask)  as  u64 )  << 32 ) ; 
55-         self . sqrt ( ) ; 
71+         self . sqrt_dirty  =  true ; 
5672    } 
5773
5874    pub  fn  get_div_numer_l ( & self )  -> u32  { 
@@ -71,23 +87,31 @@ impl DivSqrt {
7187        ( self . div_denom  as  u64  >> 32 )  as  u32 
7288    } 
7389
74-     pub  fn  get_div_result_l ( & self )  -> u32  { 
90+     pub  fn  get_div_result_l ( & mut  self )  -> u32  { 
91+         self . div ( ) ; 
7592        self . div_result  as  u32 
7693    } 
7794
78-     pub  fn  get_div_result_h ( & self )  -> u32  { 
95+     pub  fn  get_div_result_h ( & mut  self )  -> u32  { 
96+         self . div ( ) ; 
7997        ( self . div_result  as  u64  >> 32 )  as  u32 
8098    } 
8199
82-     pub  fn  get_divrem_result_l ( & self )  -> u32  { 
100+     pub  fn  get_divrem_result_l ( & mut  self )  -> u32  { 
101+         self . div ( ) ; 
83102        self . divrem_result  as  u32 
84103    } 
85104
86-     pub  fn  get_divrem_result_h ( & self )  -> u32  { 
105+     pub  fn  get_divrem_result_h ( & mut  self )  -> u32  { 
106+         self . div ( ) ; 
87107        ( self . divrem_result  as  u64  >> 32 )  as  u32 
88108    } 
89109
90110    fn  div ( & mut  self )  { 
111+         if  !self . div_dirty  { 
112+             return ; 
113+         } 
114+         self . div_dirty  = false ; 
91115        if  self . div_denom  == 0  { 
92116            self . div_cnt  |= 1  << 14 ; 
93117        }  else  { 
@@ -98,74 +122,48 @@ impl DivSqrt {
98122            0  => { 
99123                let  num = self . div_numer  as  i32 ; 
100124                let  denom = self . div_denom  as  i32 ; 
101-                 if  num == i32:: MIN  && denom == -1  { 
102-                     self . div_result  = ( num as  u64  ^ ( ( !0u32  as  u64 )  << 32 ) )  as  i64 ; 
103-                     self . divrem_result  = 0 ; 
104-                 }  else  if  denom != 0  { 
105-                     self . div_result  = ( num / denom)  as  i64 ; 
106-                     self . divrem_result  = ( num % denom)  as  i64 ; 
107-                 }  else  { 
108-                     self . div_result  = ( if  num < 0  {  1  }  else  {  -1i32  }  as  u64  ^ ( ( !0u32  as  u64 )  << 32 ) )  as  i64 ; 
109-                     self . divrem_result  = num as  i64 ; 
110-                 } 
125+                 self . div_result  = unsafe  {  unchecked_div ( num,  denom)  }  as  i64 ; 
126+                 self . divrem_result  = unsafe  {  unchecked_rem ( num,  denom)  }  as  i64 ; 
111127            } 
112128            1  => { 
113129                let  num = self . div_numer ; 
114130                let  denom = self . div_denom  as  i32 ; 
115-                 if  num == i64:: MIN  && denom == -1  { 
116-                     self . div_result  = num; 
117-                     self . divrem_result  = 0 ; 
118-                 }  else  if  denom != 0  { 
119-                     self . div_result  = num / denom as  i64 ; 
120-                     self . divrem_result  = num % denom as  i64 ; 
121-                 }  else  { 
122-                     self . div_result  = if  num < 0  {  1  }  else  {  -1  } ; 
123-                     self . divrem_result  = num; 
124-                 } 
131+                 self . div_result  = unsafe  {  unchecked_div ( num,  denom as  i64 )  } ; 
132+                 self . divrem_result  = unsafe  {  unchecked_rem ( num,  denom as  i64 )  } ; 
125133            } 
126134            2  => { 
127135                let  num = self . div_numer ; 
128136                let  denom = self . div_denom ; 
129-                 if  num == i64:: MIN  && denom == -1  { 
130-                     self . div_result  = num; 
131-                     self . divrem_result  = 0 ; 
132-                 }  else  if  denom != 0  { 
133-                     self . div_result  = num / denom; 
134-                     self . divrem_result  = num % denom; 
135-                 }  else  { 
136-                     self . div_result  = if  num < 0  {  1  }  else  {  -1  } ; 
137-                     self . divrem_result  = num; 
138-                 } 
139-             } 
140-             _ => { 
141-                 unreachable ! ( ) 
137+                 self . div_result  = unsafe  {  unchecked_div ( num,  denom)  } ; 
138+                 self . divrem_result  = unsafe  {  unchecked_rem ( num,  denom)  } ; 
142139            } 
140+             _ => unsafe  {  unreachable_unchecked ( )  } , 
143141        } 
144142    } 
145143
146144    pub  fn  set_div_cnt ( & mut  self ,  mut  mask :  u16 ,  value :  u16 )  { 
147145        mask &= 0x3 ; 
148146        self . div_cnt  = ( self . div_cnt  &  !mask)  | ( value &  mask) ; 
149-         self . div ( ) ; 
147+         self . div_dirty  =  true ; 
150148    } 
151149
152150    pub  fn  set_div_numer_l ( & mut  self ,  mask :  u32 ,  value :  u32 )  { 
153151        self . div_numer  = ( ( self . div_numer  as  u64  &  !( mask as  u64 ) )  | ( value &  mask)  as  u64 )  as  i64 ; 
154-         self . div ( ) ; 
152+         self . div_dirty  =  true ; 
155153    } 
156154
157155    pub  fn  set_div_numer_h ( & mut  self ,  mask :  u32 ,  value :  u32 )  { 
158156        self . div_numer  = ( ( self . div_numer  as  u64  &  !( ( mask as  u64 )  << 32 ) )  | ( ( ( value &  mask)  as  u64 )  << 32 ) )  as  i64 ; 
159-         self . div ( ) ; 
157+         self . div_dirty  =  true ; 
160158    } 
161159
162160    pub  fn  set_div_denom_l ( & mut  self ,  mask :  u32 ,  value :  u32 )  { 
163161        self . div_denom  = ( ( self . div_denom  as  u64  &  !( mask as  u64 ) )  | ( value &  mask)  as  u64 )  as  i64 ; 
164-         self . div ( ) ; 
162+         self . div_dirty  =  true ; 
165163    } 
166164
167165    pub  fn  set_div_denom_h ( & mut  self ,  mask :  u32 ,  value :  u32 )  { 
168166        self . div_denom  = ( ( self . div_denom  as  u64  &  !( ( mask as  u64 )  << 32 ) )  | ( ( ( value &  mask)  as  u64 )  << 32 ) )  as  i64 ; 
169-         self . div ( ) ; 
167+         self . div_dirty  =  true ; 
170168    } 
171169} 
0 commit comments