@@ -46,6 +46,18 @@ pub fn codegen_in_range_expr(
4646 mm : & MachineModel ,
4747) -> Expr {
4848 match float_ty {
49+ FloatTy :: F16 => {
50+ let ( lower, upper) = get_bounds_f16 ( integral_ty, mm) ;
51+ let mut in_range = Expr :: bool_true ( ) ;
52+ // Avoid unnecessary comparison against -∞ or ∞
53+ if lower != f16:: NEG_INFINITY {
54+ in_range = in_range. and ( float_expr. clone ( ) . gt ( Expr :: float16_constant ( lower) ) ) ;
55+ }
56+ if upper != f16:: INFINITY {
57+ in_range = in_range. and ( float_expr. clone ( ) . lt ( Expr :: float16_constant ( upper) ) ) ;
58+ }
59+ in_range
60+ }
4961 FloatTy :: F32 => {
5062 let ( lower, upper) = get_bounds_f32 ( integral_ty, mm) ;
5163 let mut in_range = Expr :: bool_true ( ) ;
@@ -69,10 +81,31 @@ pub fn codegen_in_range_expr(
6981 }
7082 in_range
7183 }
72- _ => unimplemented ! ( ) ,
84+ FloatTy :: F128 => {
85+ let ( lower, upper) = get_bounds_f128 ( integral_ty, mm) ;
86+ let mut in_range = Expr :: bool_true ( ) ;
87+ if lower != f128:: NEG_INFINITY {
88+ in_range = in_range. and ( float_expr. clone ( ) . gt ( Expr :: float128_constant ( lower) ) ) ;
89+ }
90+ if upper != f128:: INFINITY {
91+ in_range = in_range. and ( float_expr. clone ( ) . lt ( Expr :: float128_constant ( upper) ) ) ;
92+ }
93+ in_range
94+ }
7395 }
7496}
7597
98+ const F16_I8_LOWER : [ u8 ; 2 ] = [ 0x08 , 0xD8 ] ;
99+ const F16_I8_UPPER : [ u8 ; 2 ] = [ 0x00 , 0x58 ] ;
100+ const F16_I16_LOWER : [ u8 ; 2 ] = [ 0x01 , 0xF8 ] ;
101+ const F16_I16_UPPER : [ u8 ; 2 ] = [ 0x00 , 0x78 ] ;
102+ const F16_I32_LOWER : [ u8 ; 2 ] = [ 0x00 , 0xFC ] ; // -inf
103+ const F16_I32_UPPER : [ u8 ; 2 ] = [ 0x00 , 0x7C ] ; // inf
104+ const F16_I64_LOWER : [ u8 ; 2 ] = [ 0x00 , 0xFC ] ; // -inf
105+ const F16_I64_UPPER : [ u8 ; 2 ] = [ 0x00 , 0x7C ] ; // inf
106+ const F16_I128_LOWER : [ u8 ; 2 ] = [ 0x00 , 0xFC ] ; // -inf
107+ const F16_I128_UPPER : [ u8 ; 2 ] = [ 0x00 , 0x7C ] ; // inf
108+
76109const F32_I8_LOWER : [ u8 ; 4 ] = [ 0x00 , 0x00 , 0x01 , 0xC3 ] ; // -129.0
77110const F32_I8_UPPER : [ u8 ; 4 ] = [ 0x00 , 0x00 , 0x00 , 0x43 ] ; // 128.0
78111const F32_I16_LOWER : [ u8 ; 4 ] = [ 0x00 , 0x01 , 0x00 , 0xC7 ] ; // -32769.0
@@ -97,6 +130,44 @@ const F64_I64_UPPER: [u8; 8] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x43];
97130const F64_I128_LOWER : [ u8 ; 8 ] = [ 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xE0 , 0xC7 ] ; // -170141183460469269510619166673045815296.0
98131const F64_I128_UPPER : [ u8 ; 8 ] = [ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xE0 , 0x47 ] ; // 170141183460469231731687303715884105728.0
99132
133+ const F128_I8_LOWER : [ u8 ; 16 ] = [
134+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 , 0x06 , 0xC0 ,
135+ ] ;
136+ const F128_I8_UPPER : [ u8 ; 16 ] = [
137+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x06 , 0x40 ,
138+ ] ;
139+ const F128_I16_LOWER : [ u8 ; 16 ] = [
140+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 , 0x00 , 0x0E , 0xC0 ,
141+ ] ;
142+ const F128_I16_UPPER : [ u8 ; 16 ] = [
143+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x0E , 0x40 ,
144+ ] ;
145+ const F128_I32_LOWER : [ u8 ; 16 ] = [
146+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 , 0x00 , 0x00 , 0x00 , 0x1E , 0xC0 ,
147+ ] ;
148+ const F128_I32_UPPER : [ u8 ; 16 ] = [
149+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x1E , 0x40 ,
150+ ] ;
151+ const F128_I64_LOWER : [ u8 ; 16 ] = [
152+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x02 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x3E , 0xC0 ,
153+ ] ;
154+ const F128_I64_UPPER : [ u8 ; 16 ] = [
155+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x3E , 0x40 ,
156+ ] ;
157+ const F128_I128_LOWER : [ u8 ; 16 ] = [
158+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x7F , 0xC0 ,
159+ ] ;
160+ const F128_I128_UPPER : [ u8 ; 16 ] = [
161+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x7E , 0x40 ,
162+ ] ;
163+
164+ const F16_U_LOWER : [ u8 ; 2 ] = [ 0x00 , 0xBC ] ;
165+ const F16_U8_UPPER : [ u8 ; 2 ] = [ 0x00 , 0x5C ] ;
166+ const F16_U16_UPPER : [ u8 ; 2 ] = [ 0x00 , 0x7C ] ; // inf
167+ const F16_U32_UPPER : [ u8 ; 2 ] = [ 0x00 , 0x7C ] ; // inf
168+ const F16_U64_UPPER : [ u8 ; 2 ] = [ 0x00 , 0x7C ] ; // inf
169+ const F16_U128_UPPER : [ u8 ; 2 ] = [ 0x00 , 0x7C ] ; // inf
170+
100171const F32_U_LOWER : [ u8 ; 4 ] = [ 0x00 , 0x00 , 0x80 , 0xBF ] ; // -1.0
101172const F32_U8_UPPER : [ u8 ; 4 ] = [ 0x00 , 0x00 , 0x80 , 0x43 ] ; // 256.0
102173const F32_U16_UPPER : [ u8 ; 4 ] = [ 0x00 , 0x00 , 0x80 , 0x47 ] ; // 65536.0
@@ -112,6 +183,25 @@ const F64_U32_UPPER: [u8; 8] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x41];
112183const F64_U64_UPPER : [ u8 ; 8 ] = [ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xF0 , 0x43 ] ; // 18446744073709551616.0
113184const F64_U128_UPPER : [ u8 ; 8 ] = [ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xF0 , 0x47 ] ; // 340282366920938463463374607431768211456.0
114185
186+ const F128_U_LOWER : [ u8 ; 16 ] = [
187+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xFF , 0xBF ,
188+ ] ;
189+ const F128_U8_UPPER : [ u8 ; 16 ] = [
190+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x07 , 0x40 ,
191+ ] ;
192+ const F128_U16_UPPER : [ u8 ; 16 ] = [
193+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x0F , 0x40 ,
194+ ] ;
195+ const F128_U32_UPPER : [ u8 ; 16 ] = [
196+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x1F , 0x40 ,
197+ ] ;
198+ const F128_U64_UPPER : [ u8 ; 16 ] = [
199+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x3F , 0x40 ,
200+ ] ;
201+ const F128_U128_UPPER : [ u8 ; 16 ] = [
202+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x7F , 0x40 ,
203+ ] ;
204+
115205/// upper is the smallest `f32` that after truncation is strictly larger than i<N>::MAX or u<N>::MAX
116206/// lower is the largest `f32` that after truncation is strictly smaller than i<N>::MIN or u<N>::MIN
117207///
@@ -135,6 +225,14 @@ const F64_U128_UPPER: [u8; 8] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x47]
135225///
136226/// For all unsigned types, lower is -1.0 because the next higher number, when
137227/// truncated is -0.0 (or 0.0) which is not strictly smaller than `u<N>::MIN`
228+ fn get_bounds_f16 ( integral_ty : RigidTy , mm : & MachineModel ) -> ( f16 , f16 ) {
229+ match integral_ty {
230+ RigidTy :: Int ( int_ty) => get_bounds_f16_int ( int_ty, mm) ,
231+ RigidTy :: Uint ( uint_ty) => get_bounds_f16_uint ( uint_ty, mm) ,
232+ _ => unreachable ! ( ) ,
233+ }
234+ }
235+
138236fn get_bounds_f32 ( integral_ty : RigidTy , mm : & MachineModel ) -> ( f32 , f32 ) {
139237 match integral_ty {
140238 RigidTy :: Int ( int_ty) => get_bounds_f32_int ( int_ty, mm) ,
@@ -151,6 +249,31 @@ fn get_bounds_f64(integral_ty: RigidTy, mm: &MachineModel) -> (f64, f64) {
151249 }
152250}
153251
252+ fn get_bounds_f128 ( integral_ty : RigidTy , mm : & MachineModel ) -> ( f128 , f128 ) {
253+ match integral_ty {
254+ RigidTy :: Int ( int_ty) => get_bounds_f128_int ( int_ty, mm) ,
255+ RigidTy :: Uint ( uint_ty) => get_bounds_f128_uint ( uint_ty, mm) ,
256+ _ => unreachable ! ( ) ,
257+ }
258+ }
259+
260+ fn get_bounds_f16_uint ( uint_ty : UintTy , mm : & MachineModel ) -> ( f16 , f16 ) {
261+ let lower: f16 = f16:: from_le_bytes ( F16_U_LOWER ) ;
262+ let upper: f16 = match uint_ty {
263+ UintTy :: U8 => f16:: from_le_bytes ( F16_U8_UPPER ) ,
264+ UintTy :: U16 => f16:: from_le_bytes ( F16_U16_UPPER ) ,
265+ UintTy :: U32 => f16:: from_le_bytes ( F16_U32_UPPER ) ,
266+ UintTy :: U64 => f16:: from_le_bytes ( F16_U64_UPPER ) ,
267+ UintTy :: U128 => f16:: from_le_bytes ( F16_U128_UPPER ) ,
268+ UintTy :: Usize => match mm. pointer_width {
269+ 32 => f16:: from_le_bytes ( F16_U32_UPPER ) ,
270+ 64 => f16:: from_le_bytes ( F16_U64_UPPER ) ,
271+ _ => unreachable ! ( ) ,
272+ } ,
273+ } ;
274+ ( lower, upper)
275+ }
276+
154277fn get_bounds_f32_uint ( uint_ty : UintTy , mm : & MachineModel ) -> ( f32 , f32 ) {
155278 let lower: f32 = f32:: from_le_bytes ( F32_U_LOWER ) ;
156279 let upper: f32 = match uint_ty {
@@ -185,6 +308,52 @@ fn get_bounds_f64_uint(uint_ty: UintTy, mm: &MachineModel) -> (f64, f64) {
185308 ( lower, upper)
186309}
187310
311+ fn get_bounds_f128_uint ( uint_ty : UintTy , mm : & MachineModel ) -> ( f128 , f128 ) {
312+ let lower = f128:: from_le_bytes ( F128_U_LOWER ) ;
313+ let upper = match uint_ty {
314+ UintTy :: U8 => f128:: from_le_bytes ( F128_U8_UPPER ) ,
315+ UintTy :: U16 => f128:: from_le_bytes ( F128_U16_UPPER ) ,
316+ UintTy :: U32 => f128:: from_le_bytes ( F128_U32_UPPER ) ,
317+ UintTy :: U64 => f128:: from_le_bytes ( F128_U64_UPPER ) ,
318+ UintTy :: U128 => f128:: from_le_bytes ( F128_U128_UPPER ) ,
319+ UintTy :: Usize => match mm. pointer_width {
320+ 32 => f128:: from_le_bytes ( F128_U32_UPPER ) ,
321+ 64 => f128:: from_le_bytes ( F128_U64_UPPER ) ,
322+ _ => unreachable ! ( ) ,
323+ } ,
324+ } ;
325+ ( lower, upper)
326+ }
327+
328+ fn get_bounds_f16_int ( int_ty : IntTy , mm : & MachineModel ) -> ( f16 , f16 ) {
329+ let lower = match int_ty {
330+ IntTy :: I8 => f16:: from_le_bytes ( F16_I8_LOWER ) ,
331+ IntTy :: I16 => f16:: from_le_bytes ( F16_I16_LOWER ) ,
332+ IntTy :: I32 => f16:: from_le_bytes ( F16_I32_LOWER ) ,
333+ IntTy :: I64 => f16:: from_le_bytes ( F16_I64_LOWER ) ,
334+ IntTy :: I128 => f16:: from_le_bytes ( F16_I128_LOWER ) ,
335+ IntTy :: Isize => match mm. pointer_width {
336+ 32 => f16:: from_le_bytes ( F16_I32_LOWER ) ,
337+ 64 => f16:: from_le_bytes ( F16_I64_LOWER ) ,
338+ _ => unreachable ! ( ) ,
339+ } ,
340+ } ;
341+
342+ let upper = match int_ty {
343+ IntTy :: I8 => f16:: from_le_bytes ( F16_I8_UPPER ) ,
344+ IntTy :: I16 => f16:: from_le_bytes ( F16_I16_UPPER ) ,
345+ IntTy :: I32 => f16:: from_le_bytes ( F16_I32_UPPER ) ,
346+ IntTy :: I64 => f16:: from_le_bytes ( F16_I64_UPPER ) ,
347+ IntTy :: I128 => f16:: from_le_bytes ( F16_I128_UPPER ) ,
348+ IntTy :: Isize => match mm. pointer_width {
349+ 32 => f16:: from_le_bytes ( F16_I32_UPPER ) ,
350+ 64 => f16:: from_le_bytes ( F16_I64_UPPER ) ,
351+ _ => unreachable ! ( ) ,
352+ } ,
353+ } ;
354+ ( lower, upper)
355+ }
356+
188357fn get_bounds_f32_int ( int_ty : IntTy , mm : & MachineModel ) -> ( f32 , f32 ) {
189358 let lower = match int_ty {
190359 IntTy :: I8 => f32:: from_le_bytes ( F32_I8_LOWER ) ,
@@ -242,6 +411,34 @@ fn get_bounds_f64_int(int_ty: IntTy, mm: &MachineModel) -> (f64, f64) {
242411 ( lower, upper)
243412}
244413
414+ fn get_bounds_f128_int ( int_ty : IntTy , mm : & MachineModel ) -> ( f128 , f128 ) {
415+ let lower = match int_ty {
416+ IntTy :: I8 => f128:: from_le_bytes ( F128_I8_LOWER ) ,
417+ IntTy :: I16 => f128:: from_le_bytes ( F128_I16_LOWER ) ,
418+ IntTy :: I32 => f128:: from_le_bytes ( F128_I32_LOWER ) ,
419+ IntTy :: I64 => f128:: from_le_bytes ( F128_I64_LOWER ) ,
420+ IntTy :: I128 => f128:: from_le_bytes ( F128_I128_LOWER ) ,
421+ IntTy :: Isize => match mm. pointer_width {
422+ 32 => f128:: from_le_bytes ( F128_I32_LOWER ) ,
423+ 64 => f128:: from_le_bytes ( F128_I64_LOWER ) ,
424+ _ => unreachable ! ( ) ,
425+ } ,
426+ } ;
427+ let upper = match int_ty {
428+ IntTy :: I8 => f128:: from_le_bytes ( F128_I8_UPPER ) ,
429+ IntTy :: I16 => f128:: from_le_bytes ( F128_I16_UPPER ) ,
430+ IntTy :: I32 => f128:: from_le_bytes ( F128_I32_UPPER ) ,
431+ IntTy :: I64 => f128:: from_le_bytes ( F128_I64_UPPER ) ,
432+ IntTy :: I128 => f128:: from_le_bytes ( F128_I128_UPPER ) ,
433+ IntTy :: Isize => match mm. pointer_width {
434+ 32 => f128:: from_le_bytes ( F128_I32_UPPER ) ,
435+ 64 => f128:: from_le_bytes ( F128_I64_UPPER ) ,
436+ _ => unreachable ! ( ) ,
437+ } ,
438+ } ;
439+ ( lower, upper)
440+ }
441+
245442#[ cfg( test) ]
246443mod tests {
247444 use super :: * ;
0 commit comments