@@ -74,6 +74,17 @@ macro_rules! isle_common_prelude_methods {
7474 Some ( Imm64 :: new( result) . mask_to_width( type_width) )
7575 }
7676
77+ #[ inline]
78+ fn imm64_udiv( & mut self , ty: Type , x: Imm64 , y: Imm64 ) -> Option <Imm64 > {
79+ let type_width = ty. bits( ) ;
80+ assert!( type_width <= 64 ) ;
81+ let mask = self . ty_mask( ty) ;
82+ let x = ( x. bits( ) as u64 ) & mask;
83+ let y = ( y. bits( ) as u64 ) & mask;
84+ let result = x. checked_div( y) ?;
85+ Some ( Imm64 :: new( result as i64 ) . mask_to_width( type_width) )
86+ }
87+
7788 #[ inline]
7889 fn imm64_srem( & mut self , ty: Type , x: Imm64 , y: Imm64 ) -> Option <Imm64 > {
7990 // Sign extend `x` and `y`.
@@ -89,6 +100,125 @@ macro_rules! isle_common_prelude_methods {
89100 Some ( Imm64 :: new( result) . mask_to_width( type_width) )
90101 }
91102
103+ #[ inline]
104+ fn imm64_urem( & mut self , ty: Type , x: Imm64 , y: Imm64 ) -> Option <Imm64 > {
105+ let type_width = ty. bits( ) ;
106+ assert!( type_width <= 64 ) ;
107+ let mask = self . ty_mask( ty) ;
108+ let x = ( x. bits( ) as u64 ) & mask;
109+ let y = ( y. bits( ) as u64 ) & mask;
110+ let result = x. checked_rem( y) ?;
111+ Some ( Imm64 :: new( result as i64 ) . mask_to_width( type_width) )
112+ }
113+
114+ #[ inline]
115+ fn imm64_add( & mut self , ty: Type , x: Imm64 , y: Imm64 ) -> Imm64 {
116+ let ty_mask = self . ty_mask( ty) as i64 ;
117+ Imm64 :: new( x. bits( ) . wrapping_add( y. bits( ) ) & ty_mask)
118+ }
119+
120+ #[ inline]
121+ fn imm64_sub( & mut self , ty: Type , x: Imm64 , y: Imm64 ) -> Imm64 {
122+ let ty_mask = self . ty_mask( ty) as i64 ;
123+ Imm64 :: new( x. bits( ) . wrapping_sub( y. bits( ) ) & ty_mask)
124+ }
125+
126+ #[ inline]
127+ fn imm64_mul( & mut self , ty: Type , x: Imm64 , y: Imm64 ) -> Imm64 {
128+ let ty_mask = self . ty_mask( ty) as i64 ;
129+ Imm64 :: new( x. bits( ) . wrapping_mul( y. bits( ) ) & ty_mask)
130+ }
131+
132+ #[ inline]
133+ fn imm64_and( & mut self , ty: Type , x: Imm64 , y: Imm64 ) -> Imm64 {
134+ let ty_mask = self . ty_mask( ty) as i64 ;
135+ Imm64 :: new( ( x. bits( ) & y. bits( ) ) & ty_mask)
136+ }
137+
138+ #[ inline]
139+ fn imm64_or( & mut self , ty: Type , x: Imm64 , y: Imm64 ) -> Imm64 {
140+ let ty_mask = self . ty_mask( ty) as i64 ;
141+ Imm64 :: new( ( x. bits( ) | y. bits( ) ) & ty_mask)
142+ }
143+
144+ #[ inline]
145+ fn imm64_xor( & mut self , ty: Type , x: Imm64 , y: Imm64 ) -> Imm64 {
146+ let ty_mask = self . ty_mask( ty) as i64 ;
147+ Imm64 :: new( ( x. bits( ) ^ y. bits( ) ) & ty_mask)
148+ }
149+
150+ #[ inline]
151+ fn imm64_not( & mut self , ty: Type , x: Imm64 ) -> Imm64 {
152+ let ty_mask = self . ty_mask( ty) as i64 ;
153+ Imm64 :: new( ( !x. bits( ) ) & ty_mask)
154+ }
155+
156+ #[ inline]
157+ fn imm64_neg( & mut self , ty: Type , x: Imm64 ) -> Imm64 {
158+ let ty_mask = self . ty_mask( ty) as i64 ;
159+ Imm64 :: new( x. bits( ) . wrapping_neg( ) & ty_mask)
160+ }
161+
162+ #[ inline]
163+ fn imm64_abs( & mut self , ty: Type , x: Imm64 ) -> Option <Imm64 > {
164+ let type_width = ty. bits( ) ;
165+ assert!( type_width <= 64 ) ;
166+
167+ let x = x. sign_extend_from_width( type_width) . bits( ) ;
168+ let shift = 64 - type_width;
169+ let min = ( ( self . ty_smin( ty) as i64 ) << shift) >> shift;
170+ if x == min {
171+ return None ;
172+ }
173+
174+ Some ( Imm64 :: new( x. abs( ) ) . mask_to_width( type_width) )
175+ }
176+
177+ #[ inline]
178+ fn imm64_ilog2( & mut self , ty: Type , x: Imm64 ) -> Option <Imm64 > {
179+ let type_width = ty. bits( ) ;
180+ assert!( type_width <= 64 ) ;
181+ let masked = ( x. bits( ) as u64 ) & self . ty_mask( ty) ;
182+ let result = masked. checked_ilog2( ) ?;
183+ Some ( Imm64 :: new( result. into( ) ) )
184+ }
185+
186+ #[ inline]
187+ fn imm64_umin( & mut self , ty: Type , x: Imm64 , y: Imm64 ) -> Imm64 {
188+ let ty_mask = self . ty_mask( ty) ;
189+ let x_u = ( x. bits( ) as u64 ) & ty_mask;
190+ let y_u = ( y. bits( ) as u64 ) & ty_mask;
191+ Imm64 :: new( ( if x_u <= y_u { x_u } else { y_u } ) as i64 )
192+ }
193+
194+ #[ inline]
195+ fn imm64_umax( & mut self , ty: Type , x: Imm64 , y: Imm64 ) -> Imm64 {
196+ let ty_mask = self . ty_mask( ty) ;
197+ let x_u = ( x. bits( ) as u64 ) & ty_mask;
198+ let y_u = ( y. bits( ) as u64 ) & ty_mask;
199+ Imm64 :: new( ( if x_u >= y_u { x_u } else { y_u } ) as i64 )
200+ }
201+
202+ #[ inline]
203+ fn imm64_smin( & mut self , ty: Type , x: Imm64 , y: Imm64 ) -> Imm64 {
204+ let type_width = ty. bits( ) ;
205+ assert!( type_width <= 64 ) ;
206+ let x_s = x. sign_extend_from_width( type_width) . bits( ) ;
207+ let y_s = y. sign_extend_from_width( type_width) . bits( ) ;
208+ let selected = if x_s <= y_s { x_s } else { y_s } ;
209+ Imm64 :: new( selected) . mask_to_width( type_width)
210+ }
211+
212+ #[ inline]
213+ fn imm64_smax( & mut self , ty: Type , x: Imm64 , y: Imm64 ) -> Imm64 {
214+ let type_width = ty. bits( ) ;
215+ assert!( type_width <= 64 ) ;
216+ let x_s = x. sign_extend_from_width( type_width) . bits( ) ;
217+ let y_s = y. sign_extend_from_width( type_width) . bits( ) ;
218+ let selected = if x_s >= y_s { x_s } else { y_s } ;
219+ Imm64 :: new( selected) . mask_to_width( type_width)
220+ }
221+
92222 #[ inline]
93223 fn imm64_shl( & mut self , ty: Type , x: Imm64 , y: Imm64 ) -> Imm64 {
94224 // Mask off any excess shift bits.
0 commit comments