1 //! Definitions for values used in DWARF expressions.
2 
3 use core::mem;
4 
5 use crate::constants;
6 #[cfg(feature = "read")]
7 use crate::read::{AttributeValue, DebuggingInformationEntry};
8 use crate::read::{Error, Reader, Result};
9 
10 /// Convert a u64 to an i64, with sign extension if required.
11 ///
12 /// This is primarily used when needing to treat `Value::Generic`
13 /// as a signed value.
14 #[inline]
sign_extend(value: u64, mask: u64) -> i6415 fn sign_extend(value: u64, mask: u64) -> i64 {
16     let value = (value & mask) as i64;
17     let sign = ((mask >> 1) + 1) as i64;
18     (value ^ sign).wrapping_sub(sign)
19 }
20 
21 #[inline]
mask_bit_size(addr_mask: u64) -> u3222 fn mask_bit_size(addr_mask: u64) -> u32 {
23     64 - addr_mask.leading_zeros()
24 }
25 
26 /// The type of an entry on the DWARF stack.
27 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
28 pub enum ValueType {
29     /// The generic type, which is address-sized and of unspecified sign,
30     /// as specified in the DWARF 5 standard, section 2.5.1.
31     /// This type is also used to represent address base types.
32     Generic,
33     /// Signed 8-bit integer type.
34     I8,
35     /// Unsigned 8-bit integer type.
36     U8,
37     /// Signed 16-bit integer type.
38     I16,
39     /// Unsigned 16-bit integer type.
40     U16,
41     /// Signed 32-bit integer type.
42     I32,
43     /// Unsigned 32-bit integer type.
44     U32,
45     /// Signed 64-bit integer type.
46     I64,
47     /// Unsigned 64-bit integer type.
48     U64,
49     /// 32-bit floating point type.
50     F32,
51     /// 64-bit floating point type.
52     F64,
53 }
54 
55 /// The value of an entry on the DWARF stack.
56 #[derive(Debug, Clone, Copy, PartialEq)]
57 pub enum Value {
58     /// A generic value, which is address-sized and of unspecified sign.
59     Generic(u64),
60     /// A signed 8-bit integer value.
61     I8(i8),
62     /// An unsigned 8-bit integer value.
63     U8(u8),
64     /// A signed 16-bit integer value.
65     I16(i16),
66     /// An unsigned 16-bit integer value.
67     U16(u16),
68     /// A signed 32-bit integer value.
69     I32(i32),
70     /// An unsigned 32-bit integer value.
71     U32(u32),
72     /// A signed 64-bit integer value.
73     I64(i64),
74     /// An unsigned 64-bit integer value.
75     U64(u64),
76     /// A 32-bit floating point value.
77     F32(f32),
78     /// A 64-bit floating point value.
79     F64(f64),
80 }
81 
82 impl ValueType {
83     /// The size in bits of a value for this type.
bit_size(self, addr_mask: u64) -> u3284     pub fn bit_size(self, addr_mask: u64) -> u32 {
85         match self {
86             ValueType::Generic => mask_bit_size(addr_mask),
87             ValueType::I8 | ValueType::U8 => 8,
88             ValueType::I16 | ValueType::U16 => 16,
89             ValueType::I32 | ValueType::U32 | ValueType::F32 => 32,
90             ValueType::I64 | ValueType::U64 | ValueType::F64 => 64,
91         }
92     }
93 
94     /// Construct a `ValueType` from the attributes of a base type DIE.
from_encoding(encoding: constants::DwAte, byte_size: u64) -> Option<ValueType>95     pub fn from_encoding(encoding: constants::DwAte, byte_size: u64) -> Option<ValueType> {
96         Some(match (encoding, byte_size) {
97             (constants::DW_ATE_signed, 1) => ValueType::I8,
98             (constants::DW_ATE_signed, 2) => ValueType::I16,
99             (constants::DW_ATE_signed, 4) => ValueType::I32,
100             (constants::DW_ATE_signed, 8) => ValueType::I64,
101             (constants::DW_ATE_unsigned, 1) => ValueType::U8,
102             (constants::DW_ATE_unsigned, 2) => ValueType::U16,
103             (constants::DW_ATE_unsigned, 4) => ValueType::U32,
104             (constants::DW_ATE_unsigned, 8) => ValueType::U64,
105             (constants::DW_ATE_float, 4) => ValueType::F32,
106             (constants::DW_ATE_float, 8) => ValueType::F64,
107             _ => return None,
108         })
109     }
110 
111     /// Construct a `ValueType` from a base type DIE.
112     #[cfg(feature = "read")]
from_entry<R: Reader>( entry: &DebuggingInformationEntry<R>, ) -> Result<Option<ValueType>>113     pub fn from_entry<R: Reader>(
114         entry: &DebuggingInformationEntry<R>,
115     ) -> Result<Option<ValueType>> {
116         if entry.tag() != constants::DW_TAG_base_type {
117             return Ok(None);
118         }
119         let mut encoding = None;
120         let mut byte_size = None;
121         let mut endianity = constants::DW_END_default;
122         let mut attrs = entry.attrs();
123         while let Some(attr) = attrs.next()? {
124             match attr.name() {
125                 constants::DW_AT_byte_size => byte_size = attr.udata_value(),
126                 constants::DW_AT_encoding => {
127                     if let AttributeValue::Encoding(x) = attr.value() {
128                         encoding = Some(x);
129                     }
130                 }
131                 constants::DW_AT_endianity => {
132                     if let AttributeValue::Endianity(x) = attr.value() {
133                         endianity = x;
134                     }
135                 }
136                 _ => {}
137             }
138         }
139 
140         if endianity != constants::DW_END_default {
141             // TODO: we could check if it matches the reader endianity,
142             // but normally it would use DW_END_default in that case.
143             return Ok(None);
144         }
145 
146         if let (Some(encoding), Some(byte_size)) = (encoding, byte_size) {
147             Ok(ValueType::from_encoding(encoding, byte_size))
148         } else {
149             Ok(None)
150         }
151     }
152 }
153 
154 impl Value {
155     /// Return the `ValueType` corresponding to this `Value`.
value_type(&self) -> ValueType156     pub fn value_type(&self) -> ValueType {
157         match *self {
158             Value::Generic(_) => ValueType::Generic,
159             Value::I8(_) => ValueType::I8,
160             Value::U8(_) => ValueType::U8,
161             Value::I16(_) => ValueType::I16,
162             Value::U16(_) => ValueType::U16,
163             Value::I32(_) => ValueType::I32,
164             Value::U32(_) => ValueType::U32,
165             Value::I64(_) => ValueType::I64,
166             Value::U64(_) => ValueType::U64,
167             Value::F32(_) => ValueType::F32,
168             Value::F64(_) => ValueType::F64,
169         }
170     }
171 
172     /// Read a `Value` with the given `value_type` from a `Reader`.
parse<R: Reader>(value_type: ValueType, mut bytes: R) -> Result<Value>173     pub fn parse<R: Reader>(value_type: ValueType, mut bytes: R) -> Result<Value> {
174         let value = match value_type {
175             ValueType::I8 => Value::I8(bytes.read_i8()?),
176             ValueType::U8 => Value::U8(bytes.read_u8()?),
177             ValueType::I16 => Value::I16(bytes.read_i16()?),
178             ValueType::U16 => Value::U16(bytes.read_u16()?),
179             ValueType::I32 => Value::I32(bytes.read_i32()?),
180             ValueType::U32 => Value::U32(bytes.read_u32()?),
181             ValueType::I64 => Value::I64(bytes.read_i64()?),
182             ValueType::U64 => Value::U64(bytes.read_u64()?),
183             ValueType::F32 => Value::F32(bytes.read_f32()?),
184             ValueType::F64 => Value::F64(bytes.read_f64()?),
185             _ => return Err(Error::UnsupportedTypeOperation),
186         };
187         Ok(value)
188     }
189 
190     /// Convert a `Value` to a `u64`.
191     ///
192     /// The `ValueType` of `self` must be integral.
193     /// Values are sign extended if the source value is signed.
to_u64(self, addr_mask: u64) -> Result<u64>194     pub fn to_u64(self, addr_mask: u64) -> Result<u64> {
195         let value = match self {
196             Value::Generic(value) => value & addr_mask,
197             Value::I8(value) => value as u64,
198             Value::U8(value) => u64::from(value),
199             Value::I16(value) => value as u64,
200             Value::U16(value) => u64::from(value),
201             Value::I32(value) => value as u64,
202             Value::U32(value) => u64::from(value),
203             Value::I64(value) => value as u64,
204             Value::U64(value) => value as u64,
205             _ => return Err(Error::IntegralTypeRequired),
206         };
207         Ok(value)
208     }
209 
210     /// Create a `Value` with the given `value_type` from a `u64` value.
211     ///
212     /// The `value_type` may be integral or floating point.
213     /// The result is truncated if the `u64` value does
214     /// not fit the bounds of the `value_type`.
from_u64(value_type: ValueType, value: u64) -> Result<Value>215     pub fn from_u64(value_type: ValueType, value: u64) -> Result<Value> {
216         let value = match value_type {
217             ValueType::Generic => Value::Generic(value),
218             ValueType::I8 => Value::I8(value as i8),
219             ValueType::U8 => Value::U8(value as u8),
220             ValueType::I16 => Value::I16(value as i16),
221             ValueType::U16 => Value::U16(value as u16),
222             ValueType::I32 => Value::I32(value as i32),
223             ValueType::U32 => Value::U32(value as u32),
224             ValueType::I64 => Value::I64(value as i64),
225             ValueType::U64 => Value::U64(value),
226             ValueType::F32 => Value::F32(value as f32),
227             ValueType::F64 => Value::F64(value as f64),
228         };
229         Ok(value)
230     }
231 
232     /// Create a `Value` with the given `value_type` from a `f32` value.
233     ///
234     /// The `value_type` may be integral or floating point.
235     /// The result is not defined if the `f32` value does
236     /// not fit the bounds of the `value_type`.
from_f32(value_type: ValueType, value: f32) -> Result<Value>237     fn from_f32(value_type: ValueType, value: f32) -> Result<Value> {
238         let value = match value_type {
239             ValueType::Generic => Value::Generic(value as u64),
240             ValueType::I8 => Value::I8(value as i8),
241             ValueType::U8 => Value::U8(value as u8),
242             ValueType::I16 => Value::I16(value as i16),
243             ValueType::U16 => Value::U16(value as u16),
244             ValueType::I32 => Value::I32(value as i32),
245             ValueType::U32 => Value::U32(value as u32),
246             ValueType::I64 => Value::I64(value as i64),
247             ValueType::U64 => Value::U64(value as u64),
248             ValueType::F32 => Value::F32(value),
249             ValueType::F64 => Value::F64(f64::from(value)),
250         };
251         Ok(value)
252     }
253 
254     /// Create a `Value` with the given `value_type` from a `f64` value.
255     ///
256     /// The `value_type` may be integral or floating point.
257     /// The result is not defined if the `f64` value does
258     /// not fit the bounds of the `value_type`.
from_f64(value_type: ValueType, value: f64) -> Result<Value>259     fn from_f64(value_type: ValueType, value: f64) -> Result<Value> {
260         let value = match value_type {
261             ValueType::Generic => Value::Generic(value as u64),
262             ValueType::I8 => Value::I8(value as i8),
263             ValueType::U8 => Value::U8(value as u8),
264             ValueType::I16 => Value::I16(value as i16),
265             ValueType::U16 => Value::U16(value as u16),
266             ValueType::I32 => Value::I32(value as i32),
267             ValueType::U32 => Value::U32(value as u32),
268             ValueType::I64 => Value::I64(value as i64),
269             ValueType::U64 => Value::U64(value as u64),
270             ValueType::F32 => Value::F32(value as f32),
271             ValueType::F64 => Value::F64(value),
272         };
273         Ok(value)
274     }
275 
276     /// Convert a `Value` to the given `value_type`.
277     ///
278     /// When converting between integral types, the result is truncated
279     /// if the source value does not fit the bounds of the `value_type`.
280     /// When converting from floating point types, the result is not defined
281     /// if the source value does not fit the bounds of the `value_type`.
282     ///
283     /// This corresponds to the DWARF `DW_OP_convert` operation.
convert(self, value_type: ValueType, addr_mask: u64) -> Result<Value>284     pub fn convert(self, value_type: ValueType, addr_mask: u64) -> Result<Value> {
285         match self {
286             Value::F32(value) => Value::from_f32(value_type, value),
287             Value::F64(value) => Value::from_f64(value_type, value),
288             _ => Value::from_u64(value_type, self.to_u64(addr_mask)?),
289         }
290     }
291 
292     /// Reinterpret the bits in a `Value` as the given `value_type`.
293     ///
294     /// The source and result value types must have equal sizes.
295     ///
296     /// This corresponds to the DWARF `DW_OP_reinterpret` operation.
reinterpret(self, value_type: ValueType, addr_mask: u64) -> Result<Value>297     pub fn reinterpret(self, value_type: ValueType, addr_mask: u64) -> Result<Value> {
298         if self.value_type().bit_size(addr_mask) != value_type.bit_size(addr_mask) {
299             return Err(Error::TypeMismatch);
300         }
301         let bits = match self {
302             Value::Generic(value) => value,
303             Value::I8(value) => value as u64,
304             Value::U8(value) => u64::from(value),
305             Value::I16(value) => value as u64,
306             Value::U16(value) => u64::from(value),
307             Value::I32(value) => value as u64,
308             Value::U32(value) => u64::from(value),
309             Value::I64(value) => value as u64,
310             Value::U64(value) => value,
311             Value::F32(value) => u64::from(f32::to_bits(value)),
312             Value::F64(value) => f64::to_bits(value),
313         };
314         let value = match value_type {
315             ValueType::Generic => Value::Generic(bits),
316             ValueType::I8 => Value::I8(bits as i8),
317             ValueType::U8 => Value::U8(bits as u8),
318             ValueType::I16 => Value::I16(bits as i16),
319             ValueType::U16 => Value::U16(bits as u16),
320             ValueType::I32 => Value::I32(bits as i32),
321             ValueType::U32 => Value::U32(bits as u32),
322             ValueType::I64 => Value::I64(bits as i64),
323             ValueType::U64 => Value::U64(bits),
324             ValueType::F32 => Value::F32(f32::from_bits(bits as u32)),
325             ValueType::F64 => Value::F64(f64::from_bits(bits)),
326         };
327         Ok(value)
328     }
329 
330     /// Perform an absolute value operation.
331     ///
332     /// If the value type is `Generic`, then it is interpreted as a signed value.
333     ///
334     /// This corresponds to the DWARF `DW_OP_abs` operation.
abs(self, addr_mask: u64) -> Result<Value>335     pub fn abs(self, addr_mask: u64) -> Result<Value> {
336         // wrapping_abs() can be used because DWARF specifies that the result is undefined
337         // for negative minimal values.
338         let value = match self {
339             Value::Generic(value) => {
340                 Value::Generic(sign_extend(value, addr_mask).wrapping_abs() as u64)
341             }
342             Value::I8(value) => Value::I8(value.wrapping_abs()),
343             Value::I16(value) => Value::I16(value.wrapping_abs()),
344             Value::I32(value) => Value::I32(value.wrapping_abs()),
345             Value::I64(value) => Value::I64(value.wrapping_abs()),
346             // f32/f64::abs() is not available in libcore
347             Value::F32(value) => Value::F32(if value < 0. { -value } else { value }),
348             Value::F64(value) => Value::F64(if value < 0. { -value } else { value }),
349             Value::U8(_) | Value::U16(_) | Value::U32(_) | Value::U64(_) => self,
350         };
351         Ok(value)
352     }
353 
354     /// Perform a negation operation.
355     ///
356     /// If the value type is `Generic`, then it is interpreted as a signed value.
357     ///
358     /// This corresponds to the DWARF `DW_OP_neg` operation.
neg(self, addr_mask: u64) -> Result<Value>359     pub fn neg(self, addr_mask: u64) -> Result<Value> {
360         // wrapping_neg() can be used because DWARF specifies that the result is undefined
361         // for negative minimal values.
362         let value = match self {
363             Value::Generic(value) => {
364                 Value::Generic(sign_extend(value, addr_mask).wrapping_neg() as u64)
365             }
366             Value::I8(value) => Value::I8(value.wrapping_neg()),
367             Value::I16(value) => Value::I16(value.wrapping_neg()),
368             Value::I32(value) => Value::I32(value.wrapping_neg()),
369             Value::I64(value) => Value::I64(value.wrapping_neg()),
370             Value::F32(value) => Value::F32(-value),
371             Value::F64(value) => Value::F64(-value),
372             // It's unclear if these should implicity convert to a signed value.
373             // For now, we don't support them.
374             Value::U8(_) | Value::U16(_) | Value::U32(_) | Value::U64(_) => {
375                 return Err(Error::UnsupportedTypeOperation);
376             }
377         };
378         Ok(value)
379     }
380 
381     /// Perform an addition operation.
382     ///
383     /// This operation requires matching types.
384     ///
385     /// This corresponds to the DWARF `DW_OP_plus` operation.
add(self, rhs: Value, addr_mask: u64) -> Result<Value>386     pub fn add(self, rhs: Value, addr_mask: u64) -> Result<Value> {
387         let value = match (self, rhs) {
388             (Value::Generic(v1), Value::Generic(v2)) => {
389                 Value::Generic(v1.wrapping_add(v2) & addr_mask)
390             }
391             (Value::I8(v1), Value::I8(v2)) => Value::I8(v1.wrapping_add(v2)),
392             (Value::U8(v1), Value::U8(v2)) => Value::U8(v1.wrapping_add(v2)),
393             (Value::I16(v1), Value::I16(v2)) => Value::I16(v1.wrapping_add(v2)),
394             (Value::U16(v1), Value::U16(v2)) => Value::U16(v1.wrapping_add(v2)),
395             (Value::I32(v1), Value::I32(v2)) => Value::I32(v1.wrapping_add(v2)),
396             (Value::U32(v1), Value::U32(v2)) => Value::U32(v1.wrapping_add(v2)),
397             (Value::I64(v1), Value::I64(v2)) => Value::I64(v1.wrapping_add(v2)),
398             (Value::U64(v1), Value::U64(v2)) => Value::U64(v1.wrapping_add(v2)),
399             (Value::F32(v1), Value::F32(v2)) => Value::F32(v1 + v2),
400             (Value::F64(v1), Value::F64(v2)) => Value::F64(v1 + v2),
401             _ => return Err(Error::TypeMismatch),
402         };
403         Ok(value)
404     }
405 
406     /// Perform a subtraction operation.
407     ///
408     /// This operation requires matching types.
409     ///
410     /// This corresponds to the DWARF `DW_OP_minus` operation.
sub(self, rhs: Value, addr_mask: u64) -> Result<Value>411     pub fn sub(self, rhs: Value, addr_mask: u64) -> Result<Value> {
412         let value = match (self, rhs) {
413             (Value::Generic(v1), Value::Generic(v2)) => {
414                 Value::Generic(v1.wrapping_sub(v2) & addr_mask)
415             }
416             (Value::I8(v1), Value::I8(v2)) => Value::I8(v1.wrapping_sub(v2)),
417             (Value::U8(v1), Value::U8(v2)) => Value::U8(v1.wrapping_sub(v2)),
418             (Value::I16(v1), Value::I16(v2)) => Value::I16(v1.wrapping_sub(v2)),
419             (Value::U16(v1), Value::U16(v2)) => Value::U16(v1.wrapping_sub(v2)),
420             (Value::I32(v1), Value::I32(v2)) => Value::I32(v1.wrapping_sub(v2)),
421             (Value::U32(v1), Value::U32(v2)) => Value::U32(v1.wrapping_sub(v2)),
422             (Value::I64(v1), Value::I64(v2)) => Value::I64(v1.wrapping_sub(v2)),
423             (Value::U64(v1), Value::U64(v2)) => Value::U64(v1.wrapping_sub(v2)),
424             (Value::F32(v1), Value::F32(v2)) => Value::F32(v1 - v2),
425             (Value::F64(v1), Value::F64(v2)) => Value::F64(v1 - v2),
426             _ => return Err(Error::TypeMismatch),
427         };
428         Ok(value)
429     }
430 
431     /// Perform a multiplication operation.
432     ///
433     /// This operation requires matching types.
434     ///
435     /// This corresponds to the DWARF `DW_OP_mul` operation.
mul(self, rhs: Value, addr_mask: u64) -> Result<Value>436     pub fn mul(self, rhs: Value, addr_mask: u64) -> Result<Value> {
437         let value = match (self, rhs) {
438             (Value::Generic(v1), Value::Generic(v2)) => {
439                 Value::Generic(v1.wrapping_mul(v2) & addr_mask)
440             }
441             (Value::I8(v1), Value::I8(v2)) => Value::I8(v1.wrapping_mul(v2)),
442             (Value::U8(v1), Value::U8(v2)) => Value::U8(v1.wrapping_mul(v2)),
443             (Value::I16(v1), Value::I16(v2)) => Value::I16(v1.wrapping_mul(v2)),
444             (Value::U16(v1), Value::U16(v2)) => Value::U16(v1.wrapping_mul(v2)),
445             (Value::I32(v1), Value::I32(v2)) => Value::I32(v1.wrapping_mul(v2)),
446             (Value::U32(v1), Value::U32(v2)) => Value::U32(v1.wrapping_mul(v2)),
447             (Value::I64(v1), Value::I64(v2)) => Value::I64(v1.wrapping_mul(v2)),
448             (Value::U64(v1), Value::U64(v2)) => Value::U64(v1.wrapping_mul(v2)),
449             (Value::F32(v1), Value::F32(v2)) => Value::F32(v1 * v2),
450             (Value::F64(v1), Value::F64(v2)) => Value::F64(v1 * v2),
451             _ => return Err(Error::TypeMismatch),
452         };
453         Ok(value)
454     }
455 
456     /// Perform a division operation.
457     ///
458     /// This operation requires matching types.
459     /// If the value type is `Generic`, then it is interpreted as a signed value.
460     ///
461     /// This corresponds to the DWARF `DW_OP_div` operation.
div(self, rhs: Value, addr_mask: u64) -> Result<Value>462     pub fn div(self, rhs: Value, addr_mask: u64) -> Result<Value> {
463         match rhs {
464             Value::Generic(v2) if sign_extend(v2, addr_mask) == 0 => {
465                 return Err(Error::DivisionByZero);
466             }
467             Value::I8(0)
468             | Value::U8(0)
469             | Value::I16(0)
470             | Value::U16(0)
471             | Value::I32(0)
472             | Value::U32(0)
473             | Value::I64(0)
474             | Value::U64(0) => {
475                 return Err(Error::DivisionByZero);
476             }
477             _ => {}
478         }
479         let value = match (self, rhs) {
480             (Value::Generic(v1), Value::Generic(v2)) => {
481                 // Signed division
482                 Value::Generic(
483                     sign_extend(v1, addr_mask).wrapping_div(sign_extend(v2, addr_mask)) as u64,
484                 )
485             }
486             (Value::I8(v1), Value::I8(v2)) => Value::I8(v1.wrapping_div(v2)),
487             (Value::U8(v1), Value::U8(v2)) => Value::U8(v1.wrapping_div(v2)),
488             (Value::I16(v1), Value::I16(v2)) => Value::I16(v1.wrapping_div(v2)),
489             (Value::U16(v1), Value::U16(v2)) => Value::U16(v1.wrapping_div(v2)),
490             (Value::I32(v1), Value::I32(v2)) => Value::I32(v1.wrapping_div(v2)),
491             (Value::U32(v1), Value::U32(v2)) => Value::U32(v1.wrapping_div(v2)),
492             (Value::I64(v1), Value::I64(v2)) => Value::I64(v1.wrapping_div(v2)),
493             (Value::U64(v1), Value::U64(v2)) => Value::U64(v1.wrapping_div(v2)),
494             (Value::F32(v1), Value::F32(v2)) => Value::F32(v1 / v2),
495             (Value::F64(v1), Value::F64(v2)) => Value::F64(v1 / v2),
496             _ => return Err(Error::TypeMismatch),
497         };
498         Ok(value)
499     }
500 
501     /// Perform a remainder operation.
502     ///
503     /// This operation requires matching integral types.
504     /// If the value type is `Generic`, then it is interpreted as an unsigned value.
505     ///
506     /// This corresponds to the DWARF `DW_OP_mod` operation.
rem(self, rhs: Value, addr_mask: u64) -> Result<Value>507     pub fn rem(self, rhs: Value, addr_mask: u64) -> Result<Value> {
508         match rhs {
509             Value::Generic(rhs) if (rhs & addr_mask) == 0 => {
510                 return Err(Error::DivisionByZero);
511             }
512             Value::I8(0)
513             | Value::U8(0)
514             | Value::I16(0)
515             | Value::U16(0)
516             | Value::I32(0)
517             | Value::U32(0)
518             | Value::I64(0)
519             | Value::U64(0) => {
520                 return Err(Error::DivisionByZero);
521             }
522             _ => {}
523         }
524         let value = match (self, rhs) {
525             (Value::Generic(v1), Value::Generic(v2)) => {
526                 // Unsigned modulus
527                 Value::Generic((v1 & addr_mask).wrapping_rem(v2 & addr_mask))
528             }
529             (Value::I8(v1), Value::I8(v2)) => Value::I8(v1.wrapping_rem(v2)),
530             (Value::U8(v1), Value::U8(v2)) => Value::U8(v1.wrapping_rem(v2)),
531             (Value::I16(v1), Value::I16(v2)) => Value::I16(v1.wrapping_rem(v2)),
532             (Value::U16(v1), Value::U16(v2)) => Value::U16(v1.wrapping_rem(v2)),
533             (Value::I32(v1), Value::I32(v2)) => Value::I32(v1.wrapping_rem(v2)),
534             (Value::U32(v1), Value::U32(v2)) => Value::U32(v1.wrapping_rem(v2)),
535             (Value::I64(v1), Value::I64(v2)) => Value::I64(v1.wrapping_rem(v2)),
536             (Value::U64(v1), Value::U64(v2)) => Value::U64(v1.wrapping_rem(v2)),
537             (Value::F32(_), Value::F32(_)) => return Err(Error::IntegralTypeRequired),
538             (Value::F64(_), Value::F64(_)) => return Err(Error::IntegralTypeRequired),
539             _ => return Err(Error::TypeMismatch),
540         };
541         Ok(value)
542     }
543 
544     /// Perform a bitwise not operation.
545     ///
546     /// This operation requires matching integral types.
547     ///
548     /// This corresponds to the DWARF `DW_OP_not` operation.
not(self, addr_mask: u64) -> Result<Value>549     pub fn not(self, addr_mask: u64) -> Result<Value> {
550         let value_type = self.value_type();
551         let v = self.to_u64(addr_mask)?;
552         Value::from_u64(value_type, !v)
553     }
554 
555     /// Perform a bitwise and operation.
556     ///
557     /// This operation requires matching integral types.
558     ///
559     /// This corresponds to the DWARF `DW_OP_and` operation.
and(self, rhs: Value, addr_mask: u64) -> Result<Value>560     pub fn and(self, rhs: Value, addr_mask: u64) -> Result<Value> {
561         let value_type = self.value_type();
562         if value_type != rhs.value_type() {
563             return Err(Error::TypeMismatch);
564         }
565         let v1 = self.to_u64(addr_mask)?;
566         let v2 = rhs.to_u64(addr_mask)?;
567         Value::from_u64(value_type, v1 & v2)
568     }
569 
570     /// Perform a bitwise or operation.
571     ///
572     /// This operation requires matching integral types.
573     ///
574     /// This corresponds to the DWARF `DW_OP_or` operation.
or(self, rhs: Value, addr_mask: u64) -> Result<Value>575     pub fn or(self, rhs: Value, addr_mask: u64) -> Result<Value> {
576         let value_type = self.value_type();
577         if value_type != rhs.value_type() {
578             return Err(Error::TypeMismatch);
579         }
580         let v1 = self.to_u64(addr_mask)?;
581         let v2 = rhs.to_u64(addr_mask)?;
582         Value::from_u64(value_type, v1 | v2)
583     }
584 
585     /// Perform a bitwise exclusive-or operation.
586     ///
587     /// This operation requires matching integral types.
588     ///
589     /// This corresponds to the DWARF `DW_OP_xor` operation.
xor(self, rhs: Value, addr_mask: u64) -> Result<Value>590     pub fn xor(self, rhs: Value, addr_mask: u64) -> Result<Value> {
591         let value_type = self.value_type();
592         if value_type != rhs.value_type() {
593             return Err(Error::TypeMismatch);
594         }
595         let v1 = self.to_u64(addr_mask)?;
596         let v2 = rhs.to_u64(addr_mask)?;
597         Value::from_u64(value_type, v1 ^ v2)
598     }
599 
600     /// Convert value to bit length suitable for a shift operation.
601     ///
602     /// If the value is negative then an error is returned.
shift_length(self) -> Result<u64>603     fn shift_length(self) -> Result<u64> {
604         let value = match self {
605             Value::Generic(value) => value,
606             Value::I8(value) if value >= 0 => value as u64,
607             Value::U8(value) => u64::from(value),
608             Value::I16(value) if value >= 0 => value as u64,
609             Value::U16(value) => u64::from(value),
610             Value::I32(value) if value >= 0 => value as u64,
611             Value::U32(value) => u64::from(value),
612             Value::I64(value) if value >= 0 => value as u64,
613             Value::U64(value) => value,
614             _ => return Err(Error::InvalidShiftExpression),
615         };
616         Ok(value)
617     }
618 
619     /// Perform a shift left operation.
620     ///
621     /// This operation requires integral types.
622     /// If the shift length exceeds the type size, then 0 is returned.
623     /// If the shift length is negative then an error is returned.
624     ///
625     /// This corresponds to the DWARF `DW_OP_shl` operation.
shl(self, rhs: Value, addr_mask: u64) -> Result<Value>626     pub fn shl(self, rhs: Value, addr_mask: u64) -> Result<Value> {
627         let v2 = rhs.shift_length()?;
628         let value = match self {
629             Value::Generic(v1) => Value::Generic(if v2 >= u64::from(mask_bit_size(addr_mask)) {
630                 0
631             } else {
632                 (v1 & addr_mask) << v2
633             }),
634             Value::I8(v1) => Value::I8(if v2 >= 8 { 0 } else { v1 << v2 }),
635             Value::U8(v1) => Value::U8(if v2 >= 8 { 0 } else { v1 << v2 }),
636             Value::I16(v1) => Value::I16(if v2 >= 16 { 0 } else { v1 << v2 }),
637             Value::U16(v1) => Value::U16(if v2 >= 16 { 0 } else { v1 << v2 }),
638             Value::I32(v1) => Value::I32(if v2 >= 32 { 0 } else { v1 << v2 }),
639             Value::U32(v1) => Value::U32(if v2 >= 32 { 0 } else { v1 << v2 }),
640             Value::I64(v1) => Value::I64(if v2 >= 64 { 0 } else { v1 << v2 }),
641             Value::U64(v1) => Value::U64(if v2 >= 64 { 0 } else { v1 << v2 }),
642             _ => return Err(Error::IntegralTypeRequired),
643         };
644         Ok(value)
645     }
646 
647     /// Perform a logical shift right operation.
648     ///
649     /// This operation requires an unsigned integral type for the value.
650     /// If the value type is `Generic`, then it is interpreted as an unsigned value.
651     ///
652     /// This operation requires an integral type for the shift length.
653     /// If the shift length exceeds the type size, then 0 is returned.
654     /// If the shift length is negative then an error is returned.
655     ///
656     /// This corresponds to the DWARF `DW_OP_shr` operation.
shr(self, rhs: Value, addr_mask: u64) -> Result<Value>657     pub fn shr(self, rhs: Value, addr_mask: u64) -> Result<Value> {
658         let v2 = rhs.shift_length()?;
659         let value = match self {
660             Value::Generic(v1) => Value::Generic(if v2 >= u64::from(mask_bit_size(addr_mask)) {
661                 0
662             } else {
663                 (v1 & addr_mask) >> v2
664             }),
665             Value::U8(v1) => Value::U8(if v2 >= 8 { 0 } else { v1 >> v2 }),
666             Value::U16(v1) => Value::U16(if v2 >= 16 { 0 } else { v1 >> v2 }),
667             Value::U32(v1) => Value::U32(if v2 >= 32 { 0 } else { v1 >> v2 }),
668             Value::U64(v1) => Value::U64(if v2 >= 64 { 0 } else { v1 >> v2 }),
669             // It's unclear if signed values should implicity convert to an unsigned value.
670             // For now, we don't support them.
671             Value::I8(_) | Value::I16(_) | Value::I32(_) | Value::I64(_) => {
672                 return Err(Error::UnsupportedTypeOperation);
673             }
674             _ => return Err(Error::IntegralTypeRequired),
675         };
676         Ok(value)
677     }
678 
679     /// Perform an arithmetic shift right operation.
680     ///
681     /// This operation requires a signed integral type for the value.
682     /// If the value type is `Generic`, then it is interpreted as a signed value.
683     ///
684     /// This operation requires an integral type for the shift length.
685     /// If the shift length exceeds the type size, then 0 is returned for positive values,
686     /// and -1 is returned for negative values.
687     /// If the shift length is negative then an error is returned.
688     ///
689     /// This corresponds to the DWARF `DW_OP_shra` operation.
shra(self, rhs: Value, addr_mask: u64) -> Result<Value>690     pub fn shra(self, rhs: Value, addr_mask: u64) -> Result<Value> {
691         let v2 = rhs.shift_length()?;
692         let value = match self {
693             Value::Generic(v1) => {
694                 let v1 = sign_extend(v1, addr_mask);
695                 let value = if v2 >= u64::from(mask_bit_size(addr_mask)) {
696                     if v1 < 0 {
697                         !0
698                     } else {
699                         0
700                     }
701                 } else {
702                     (v1 >> v2) as u64
703                 };
704                 Value::Generic(value)
705             }
706             Value::I8(v1) => Value::I8(if v2 >= 8 {
707                 if v1 < 0 {
708                     !0
709                 } else {
710                     0
711                 }
712             } else {
713                 v1 >> v2
714             }),
715             Value::I16(v1) => Value::I16(if v2 >= 16 {
716                 if v1 < 0 {
717                     !0
718                 } else {
719                     0
720                 }
721             } else {
722                 v1 >> v2
723             }),
724             Value::I32(v1) => Value::I32(if v2 >= 32 {
725                 if v1 < 0 {
726                     !0
727                 } else {
728                     0
729                 }
730             } else {
731                 v1 >> v2
732             }),
733             Value::I64(v1) => Value::I64(if v2 >= 64 {
734                 if v1 < 0 {
735                     !0
736                 } else {
737                     0
738                 }
739             } else {
740                 v1 >> v2
741             }),
742             // It's unclear if unsigned values should implicity convert to a signed value.
743             // For now, we don't support them.
744             Value::U8(_) | Value::U16(_) | Value::U32(_) | Value::U64(_) => {
745                 return Err(Error::UnsupportedTypeOperation);
746             }
747             _ => return Err(Error::IntegralTypeRequired),
748         };
749         Ok(value)
750     }
751 
752     /// Perform the `==` relational operation.
753     ///
754     /// This operation requires matching integral types.
755     /// If the value type is `Generic`, then it is interpreted as a signed value.
756     ///
757     /// This corresponds to the DWARF `DW_OP_eq` operation.
eq(self, rhs: Value, addr_mask: u64) -> Result<Value>758     pub fn eq(self, rhs: Value, addr_mask: u64) -> Result<Value> {
759         let value = match (self, rhs) {
760             (Value::Generic(v1), Value::Generic(v2)) => {
761                 sign_extend(v1, addr_mask) == sign_extend(v2, addr_mask)
762             }
763             (Value::I8(v1), Value::I8(v2)) => v1 == v2,
764             (Value::U8(v1), Value::U8(v2)) => v1 == v2,
765             (Value::I16(v1), Value::I16(v2)) => v1 == v2,
766             (Value::U16(v1), Value::U16(v2)) => v1 == v2,
767             (Value::I32(v1), Value::I32(v2)) => v1 == v2,
768             (Value::U32(v1), Value::U32(v2)) => v1 == v2,
769             (Value::I64(v1), Value::I64(v2)) => v1 == v2,
770             (Value::U64(v1), Value::U64(v2)) => v1 == v2,
771             (Value::F32(v1), Value::F32(v2)) => v1 == v2,
772             (Value::F64(v1), Value::F64(v2)) => v1 == v2,
773             _ => return Err(Error::TypeMismatch),
774         };
775         Ok(Value::Generic(value as u64))
776     }
777 
778     /// Perform the `>=` relational operation.
779     ///
780     /// This operation requires matching integral types.
781     /// If the value type is `Generic`, then it is interpreted as a signed value.
782     ///
783     /// This corresponds to the DWARF `DW_OP_ge` operation.
ge(self, rhs: Value, addr_mask: u64) -> Result<Value>784     pub fn ge(self, rhs: Value, addr_mask: u64) -> Result<Value> {
785         let value = match (self, rhs) {
786             (Value::Generic(v1), Value::Generic(v2)) => {
787                 sign_extend(v1, addr_mask) >= sign_extend(v2, addr_mask)
788             }
789             (Value::I8(v1), Value::I8(v2)) => v1 >= v2,
790             (Value::U8(v1), Value::U8(v2)) => v1 >= v2,
791             (Value::I16(v1), Value::I16(v2)) => v1 >= v2,
792             (Value::U16(v1), Value::U16(v2)) => v1 >= v2,
793             (Value::I32(v1), Value::I32(v2)) => v1 >= v2,
794             (Value::U32(v1), Value::U32(v2)) => v1 >= v2,
795             (Value::I64(v1), Value::I64(v2)) => v1 >= v2,
796             (Value::U64(v1), Value::U64(v2)) => v1 >= v2,
797             (Value::F32(v1), Value::F32(v2)) => v1 >= v2,
798             (Value::F64(v1), Value::F64(v2)) => v1 >= v2,
799             _ => return Err(Error::TypeMismatch),
800         };
801         Ok(Value::Generic(value as u64))
802     }
803 
804     /// Perform the `>` relational operation.
805     ///
806     /// This operation requires matching integral types.
807     /// If the value type is `Generic`, then it is interpreted as a signed value.
808     ///
809     /// This corresponds to the DWARF `DW_OP_gt` operation.
gt(self, rhs: Value, addr_mask: u64) -> Result<Value>810     pub fn gt(self, rhs: Value, addr_mask: u64) -> Result<Value> {
811         let value = match (self, rhs) {
812             (Value::Generic(v1), Value::Generic(v2)) => {
813                 sign_extend(v1, addr_mask) > sign_extend(v2, addr_mask)
814             }
815             (Value::I8(v1), Value::I8(v2)) => v1 > v2,
816             (Value::U8(v1), Value::U8(v2)) => v1 > v2,
817             (Value::I16(v1), Value::I16(v2)) => v1 > v2,
818             (Value::U16(v1), Value::U16(v2)) => v1 > v2,
819             (Value::I32(v1), Value::I32(v2)) => v1 > v2,
820             (Value::U32(v1), Value::U32(v2)) => v1 > v2,
821             (Value::I64(v1), Value::I64(v2)) => v1 > v2,
822             (Value::U64(v1), Value::U64(v2)) => v1 > v2,
823             (Value::F32(v1), Value::F32(v2)) => v1 > v2,
824             (Value::F64(v1), Value::F64(v2)) => v1 > v2,
825             _ => return Err(Error::TypeMismatch),
826         };
827         Ok(Value::Generic(value as u64))
828     }
829 
830     /// Perform the `<= relational operation.
831     ///
832     /// This operation requires matching integral types.
833     /// If the value type is `Generic`, then it is interpreted as a signed value.
834     ///
835     /// This corresponds to the DWARF `DW_OP_le` operation.
le(self, rhs: Value, addr_mask: u64) -> Result<Value>836     pub fn le(self, rhs: Value, addr_mask: u64) -> Result<Value> {
837         let value = match (self, rhs) {
838             (Value::Generic(v1), Value::Generic(v2)) => {
839                 sign_extend(v1, addr_mask) <= sign_extend(v2, addr_mask)
840             }
841             (Value::I8(v1), Value::I8(v2)) => v1 <= v2,
842             (Value::U8(v1), Value::U8(v2)) => v1 <= v2,
843             (Value::I16(v1), Value::I16(v2)) => v1 <= v2,
844             (Value::U16(v1), Value::U16(v2)) => v1 <= v2,
845             (Value::I32(v1), Value::I32(v2)) => v1 <= v2,
846             (Value::U32(v1), Value::U32(v2)) => v1 <= v2,
847             (Value::I64(v1), Value::I64(v2)) => v1 <= v2,
848             (Value::U64(v1), Value::U64(v2)) => v1 <= v2,
849             (Value::F32(v1), Value::F32(v2)) => v1 <= v2,
850             (Value::F64(v1), Value::F64(v2)) => v1 <= v2,
851             _ => return Err(Error::TypeMismatch),
852         };
853         Ok(Value::Generic(value as u64))
854     }
855 
856     /// Perform the `< relational operation.
857     ///
858     /// This operation requires matching integral types.
859     /// If the value type is `Generic`, then it is interpreted as a signed value.
860     ///
861     /// This corresponds to the DWARF `DW_OP_lt` operation.
lt(self, rhs: Value, addr_mask: u64) -> Result<Value>862     pub fn lt(self, rhs: Value, addr_mask: u64) -> Result<Value> {
863         let value = match (self, rhs) {
864             (Value::Generic(v1), Value::Generic(v2)) => {
865                 sign_extend(v1, addr_mask) < sign_extend(v2, addr_mask)
866             }
867             (Value::I8(v1), Value::I8(v2)) => v1 < v2,
868             (Value::U8(v1), Value::U8(v2)) => v1 < v2,
869             (Value::I16(v1), Value::I16(v2)) => v1 < v2,
870             (Value::U16(v1), Value::U16(v2)) => v1 < v2,
871             (Value::I32(v1), Value::I32(v2)) => v1 < v2,
872             (Value::U32(v1), Value::U32(v2)) => v1 < v2,
873             (Value::I64(v1), Value::I64(v2)) => v1 < v2,
874             (Value::U64(v1), Value::U64(v2)) => v1 < v2,
875             (Value::F32(v1), Value::F32(v2)) => v1 < v2,
876             (Value::F64(v1), Value::F64(v2)) => v1 < v2,
877             _ => return Err(Error::TypeMismatch),
878         };
879         Ok(Value::Generic(value as u64))
880     }
881 
882     /// Perform the `!= relational operation.
883     ///
884     /// This operation requires matching integral types.
885     /// If the value type is `Generic`, then it is interpreted as a signed value.
886     ///
887     /// This corresponds to the DWARF `DW_OP_ne` operation.
ne(self, rhs: Value, addr_mask: u64) -> Result<Value>888     pub fn ne(self, rhs: Value, addr_mask: u64) -> Result<Value> {
889         let value = match (self, rhs) {
890             (Value::Generic(v1), Value::Generic(v2)) => {
891                 sign_extend(v1, addr_mask) != sign_extend(v2, addr_mask)
892             }
893             (Value::I8(v1), Value::I8(v2)) => v1 != v2,
894             (Value::U8(v1), Value::U8(v2)) => v1 != v2,
895             (Value::I16(v1), Value::I16(v2)) => v1 != v2,
896             (Value::U16(v1), Value::U16(v2)) => v1 != v2,
897             (Value::I32(v1), Value::I32(v2)) => v1 != v2,
898             (Value::U32(v1), Value::U32(v2)) => v1 != v2,
899             (Value::I64(v1), Value::I64(v2)) => v1 != v2,
900             (Value::U64(v1), Value::U64(v2)) => v1 != v2,
901             (Value::F32(v1), Value::F32(v2)) => v1 != v2,
902             (Value::F64(v1), Value::F64(v2)) => v1 != v2,
903             _ => return Err(Error::TypeMismatch),
904         };
905         Ok(Value::Generic(value as u64))
906     }
907 }
908 
909 #[cfg(test)]
910 mod tests {
911     use super::*;
912     use crate::common::{DebugAbbrevOffset, DebugInfoOffset, Encoding, Format};
913     use crate::endianity::LittleEndian;
914     use crate::read::{
915         Abbreviation, AttributeSpecification, DebuggingInformationEntry, EndianSlice, UnitHeader,
916         UnitOffset, UnitType,
917     };
918 
919     #[test]
920     #[rustfmt::skip]
valuetype_from_encoding()921     fn valuetype_from_encoding() {
922         let encoding = Encoding {
923             format: Format::Dwarf32,
924             version: 4,
925             address_size: 4,
926         };
927         let unit = UnitHeader::new(
928             encoding,
929             7,
930             UnitType::Compilation,
931             DebugAbbrevOffset(0),
932             DebugInfoOffset(0).into(),
933             EndianSlice::new(&[], LittleEndian),
934         );
935 
936         let abbrev = Abbreviation::new(
937             42,
938             constants::DW_TAG_base_type,
939             constants::DW_CHILDREN_no,
940             vec![
941                 AttributeSpecification::new(
942                     constants::DW_AT_byte_size,
943                     constants::DW_FORM_udata,
944                     None,
945                 ),
946                 AttributeSpecification::new(
947                     constants::DW_AT_encoding,
948                     constants::DW_FORM_udata,
949                     None,
950                 ),
951                 AttributeSpecification::new(
952                     constants::DW_AT_endianity,
953                     constants::DW_FORM_udata,
954                     None,
955                 ),
956             ].into(),
957         );
958 
959         for &(attrs, result) in &[
960             ([0x01, constants::DW_ATE_signed.0, constants::DW_END_default.0], ValueType::I8),
961             ([0x02, constants::DW_ATE_signed.0, constants::DW_END_default.0], ValueType::I16),
962             ([0x04, constants::DW_ATE_signed.0, constants::DW_END_default.0], ValueType::I32),
963             ([0x08, constants::DW_ATE_signed.0, constants::DW_END_default.0], ValueType::I64),
964             ([0x01, constants::DW_ATE_unsigned.0, constants::DW_END_default.0], ValueType::U8),
965             ([0x02, constants::DW_ATE_unsigned.0, constants::DW_END_default.0], ValueType::U16),
966             ([0x04, constants::DW_ATE_unsigned.0, constants::DW_END_default.0], ValueType::U32),
967             ([0x08, constants::DW_ATE_unsigned.0, constants::DW_END_default.0], ValueType::U64),
968             ([0x04, constants::DW_ATE_float.0, constants::DW_END_default.0], ValueType::F32),
969             ([0x08, constants::DW_ATE_float.0, constants::DW_END_default.0], ValueType::F64),
970         ] {
971             let entry = DebuggingInformationEntry::new(
972                 UnitOffset(0),
973                 EndianSlice::new(&attrs, LittleEndian),
974                 &abbrev,
975                 &unit,
976             );
977             assert_eq!(ValueType::from_entry(&entry), Ok(Some(result)));
978         }
979 
980         for attrs in &[
981             [0x03, constants::DW_ATE_signed.0, constants::DW_END_default.0],
982             [0x02, constants::DW_ATE_signed.0, constants::DW_END_big.0],
983         ] {
984             let entry = DebuggingInformationEntry::new(
985                 UnitOffset(0),
986                 EndianSlice::new(attrs, LittleEndian),
987                 &abbrev,
988                 &unit,
989             );
990             assert_eq!(ValueType::from_entry(&entry), Ok(None));
991         }
992     }
993 
994     #[test]
value_convert()995     fn value_convert() {
996         let addr_mask = !0 >> 32;
997         for &(v, t, result) in &[
998             (Value::Generic(1), ValueType::I8, Ok(Value::I8(1))),
999             (Value::I8(1), ValueType::U8, Ok(Value::U8(1))),
1000             (Value::U8(1), ValueType::I16, Ok(Value::I16(1))),
1001             (Value::I16(1), ValueType::U16, Ok(Value::U16(1))),
1002             (Value::U16(1), ValueType::I32, Ok(Value::I32(1))),
1003             (Value::I32(1), ValueType::U32, Ok(Value::U32(1))),
1004             (Value::U32(1), ValueType::F32, Ok(Value::F32(1.))),
1005             (Value::F32(1.), ValueType::I64, Ok(Value::I64(1))),
1006             (Value::I64(1), ValueType::U64, Ok(Value::U64(1))),
1007             (Value::U64(1), ValueType::F64, Ok(Value::F64(1.))),
1008             (Value::F64(1.), ValueType::Generic, Ok(Value::Generic(1))),
1009         ] {
1010             assert_eq!(v.convert(t, addr_mask), result);
1011         }
1012     }
1013 
1014     #[test]
1015     #[rustfmt::skip]
value_reinterpret()1016     fn value_reinterpret() {
1017         let addr_mask = !0 >> 32;
1018         for &(v, t, result) in &[
1019             // 8-bit
1020             (Value::I8(-1), ValueType::U8, Ok(Value::U8(0xff))),
1021             (Value::U8(0xff), ValueType::I8, Ok(Value::I8(-1))),
1022             // 16-bit
1023             (Value::I16(1), ValueType::U16, Ok(Value::U16(1))),
1024             (Value::U16(1), ValueType::I16, Ok(Value::I16(1))),
1025             // 32-bit
1026             (Value::Generic(1), ValueType::I32, Ok(Value::I32(1))),
1027             (Value::I32(1), ValueType::U32, Ok(Value::U32(1))),
1028             (Value::U32(0x3f80_0000), ValueType::F32, Ok(Value::F32(1.0))),
1029             (Value::F32(1.0), ValueType::Generic, Ok(Value::Generic(0x3f80_0000))),
1030             // Type mismatches
1031             (Value::Generic(1), ValueType::U8, Err(Error::TypeMismatch)),
1032             (Value::U8(1), ValueType::U16, Err(Error::TypeMismatch)),
1033             (Value::U16(1), ValueType::U32, Err(Error::TypeMismatch)),
1034             (Value::U32(1), ValueType::U64, Err(Error::TypeMismatch)),
1035             (Value::U64(1), ValueType::Generic, Err(Error::TypeMismatch)),
1036         ] {
1037             assert_eq!(v.reinterpret(t, addr_mask), result);
1038         }
1039 
1040         let addr_mask = !0;
1041         for &(v, t, result) in &[
1042             // 64-bit
1043             (Value::Generic(1), ValueType::I64, Ok(Value::I64(1))),
1044             (Value::I64(1), ValueType::U64, Ok(Value::U64(1))),
1045             (Value::U64(0x3ff0_0000_0000_0000), ValueType::F64, Ok(Value::F64(1.0))),
1046             (Value::F64(1.0), ValueType::Generic, Ok(Value::Generic(0x3ff0_0000_0000_0000))),
1047         ] {
1048             assert_eq!(v.reinterpret(t, addr_mask), result);
1049         }
1050     }
1051 
1052     #[test]
1053     #[rustfmt::skip]
value_abs()1054     fn value_abs() {
1055         let addr_mask = 0xffff_ffff;
1056         for &(v, result) in &[
1057             (Value::Generic(0xffff_ffff), Ok(Value::Generic(1))),
1058             (Value::I8(-1), Ok(Value::I8(1))),
1059             (Value::U8(1), Ok(Value::U8(1))),
1060             (Value::I16(-1), Ok(Value::I16(1))),
1061             (Value::U16(1), Ok(Value::U16(1))),
1062             (Value::I32(-1), Ok(Value::I32(1))),
1063             (Value::U32(1), Ok(Value::U32(1))),
1064             (Value::I64(-1), Ok(Value::I64(1))),
1065             (Value::U64(1), Ok(Value::U64(1))),
1066             (Value::F32(-1.), Ok(Value::F32(1.))),
1067             (Value::F64(-1.), Ok(Value::F64(1.))),
1068         ] {
1069             assert_eq!(v.abs(addr_mask), result);
1070         }
1071     }
1072 
1073     #[test]
1074     #[rustfmt::skip]
value_neg()1075     fn value_neg() {
1076         let addr_mask = 0xffff_ffff;
1077         for &(v, result) in &[
1078             (Value::Generic(0xffff_ffff), Ok(Value::Generic(1))),
1079             (Value::I8(1), Ok(Value::I8(-1))),
1080             (Value::U8(1), Err(Error::UnsupportedTypeOperation)),
1081             (Value::I16(1), Ok(Value::I16(-1))),
1082             (Value::U16(1), Err(Error::UnsupportedTypeOperation)),
1083             (Value::I32(1), Ok(Value::I32(-1))),
1084             (Value::U32(1), Err(Error::UnsupportedTypeOperation)),
1085             (Value::I64(1), Ok(Value::I64(-1))),
1086             (Value::U64(1), Err(Error::UnsupportedTypeOperation)),
1087             (Value::F32(1.), Ok(Value::F32(-1.))),
1088             (Value::F64(1.), Ok(Value::F64(-1.))),
1089         ] {
1090             assert_eq!(v.neg(addr_mask), result);
1091         }
1092     }
1093 
1094     #[test]
1095     #[rustfmt::skip]
value_add()1096     fn value_add() {
1097         let addr_mask = 0xffff_ffff;
1098         for &(v1, v2, result) in &[
1099             (Value::Generic(1), Value::Generic(2), Ok(Value::Generic(3))),
1100             (Value::I8(-1), Value::I8(2), Ok(Value::I8(1))),
1101             (Value::U8(1), Value::U8(2), Ok(Value::U8(3))),
1102             (Value::I16(-1), Value::I16(2), Ok(Value::I16(1))),
1103             (Value::U16(1), Value::U16(2), Ok(Value::U16(3))),
1104             (Value::I32(-1), Value::I32(2), Ok(Value::I32(1))),
1105             (Value::U32(1), Value::U32(2), Ok(Value::U32(3))),
1106             (Value::I64(-1), Value::I64(2), Ok(Value::I64(1))),
1107             (Value::U64(1), Value::U64(2), Ok(Value::U64(3))),
1108             (Value::F32(-1.), Value::F32(2.), Ok(Value::F32(1.))),
1109             (Value::F64(-1.), Value::F64(2.), Ok(Value::F64(1.))),
1110             (Value::Generic(1), Value::U32(2), Err(Error::TypeMismatch)),
1111         ] {
1112             assert_eq!(v1.add(v2, addr_mask), result);
1113         }
1114     }
1115 
1116     #[test]
1117     #[rustfmt::skip]
value_sub()1118     fn value_sub() {
1119         let addr_mask = 0xffff_ffff;
1120         for &(v1, v2, result) in &[
1121             (Value::Generic(3), Value::Generic(2), Ok(Value::Generic(1))),
1122             (Value::I8(-1), Value::I8(2), Ok(Value::I8(-3))),
1123             (Value::U8(3), Value::U8(2), Ok(Value::U8(1))),
1124             (Value::I16(-1), Value::I16(2), Ok(Value::I16(-3))),
1125             (Value::U16(3), Value::U16(2), Ok(Value::U16(1))),
1126             (Value::I32(-1), Value::I32(2), Ok(Value::I32(-3))),
1127             (Value::U32(3), Value::U32(2), Ok(Value::U32(1))),
1128             (Value::I64(-1), Value::I64(2), Ok(Value::I64(-3))),
1129             (Value::U64(3), Value::U64(2), Ok(Value::U64(1))),
1130             (Value::F32(-1.), Value::F32(2.), Ok(Value::F32(-3.))),
1131             (Value::F64(-1.), Value::F64(2.), Ok(Value::F64(-3.))),
1132             (Value::Generic(3), Value::U32(2), Err(Error::TypeMismatch)),
1133         ] {
1134             assert_eq!(v1.sub(v2, addr_mask), result);
1135         }
1136     }
1137 
1138     #[test]
1139     #[rustfmt::skip]
value_mul()1140     fn value_mul() {
1141         let addr_mask = 0xffff_ffff;
1142         for &(v1, v2, result) in &[
1143             (Value::Generic(2), Value::Generic(3), Ok(Value::Generic(6))),
1144             (Value::I8(-2), Value::I8(3), Ok(Value::I8(-6))),
1145             (Value::U8(2), Value::U8(3), Ok(Value::U8(6))),
1146             (Value::I16(-2), Value::I16(3), Ok(Value::I16(-6))),
1147             (Value::U16(2), Value::U16(3), Ok(Value::U16(6))),
1148             (Value::I32(-2), Value::I32(3), Ok(Value::I32(-6))),
1149             (Value::U32(2), Value::U32(3), Ok(Value::U32(6))),
1150             (Value::I64(-2), Value::I64(3), Ok(Value::I64(-6))),
1151             (Value::U64(2), Value::U64(3), Ok(Value::U64(6))),
1152             (Value::F32(-2.), Value::F32(3.), Ok(Value::F32(-6.))),
1153             (Value::F64(-2.), Value::F64(3.), Ok(Value::F64(-6.))),
1154             (Value::Generic(2), Value::U32(3), Err(Error::TypeMismatch)),
1155         ] {
1156             assert_eq!(v1.mul(v2, addr_mask), result);
1157         }
1158     }
1159 
1160     #[test]
1161     #[rustfmt::skip]
value_div()1162     fn value_div() {
1163         let addr_mask = 0xffff_ffff;
1164         for &(v1, v2, result) in &[
1165             (Value::Generic(6), Value::Generic(3), Ok(Value::Generic(2))),
1166             (Value::I8(-6), Value::I8(3), Ok(Value::I8(-2))),
1167             (Value::U8(6), Value::U8(3), Ok(Value::U8(2))),
1168             (Value::I16(-6), Value::I16(3), Ok(Value::I16(-2))),
1169             (Value::U16(6), Value::U16(3), Ok(Value::U16(2))),
1170             (Value::I32(-6), Value::I32(3), Ok(Value::I32(-2))),
1171             (Value::U32(6), Value::U32(3), Ok(Value::U32(2))),
1172             (Value::I64(-6), Value::I64(3), Ok(Value::I64(-2))),
1173             (Value::U64(6), Value::U64(3), Ok(Value::U64(2))),
1174             (Value::F32(-6.), Value::F32(3.), Ok(Value::F32(-2.))),
1175             (Value::F64(-6.), Value::F64(3.), Ok(Value::F64(-2.))),
1176             (Value::Generic(6), Value::U32(3), Err(Error::TypeMismatch)),
1177         ] {
1178             assert_eq!(v1.div(v2, addr_mask), result);
1179         }
1180         for &(v1, v2, result) in &[
1181             (Value::Generic(6), Value::Generic(0), Err(Error::DivisionByZero)),
1182             (Value::I8(-6), Value::I8(0), Err(Error::DivisionByZero)),
1183             (Value::U8(6), Value::U8(0), Err(Error::DivisionByZero)),
1184             (Value::I16(-6), Value::I16(0), Err(Error::DivisionByZero)),
1185             (Value::U16(6), Value::U16(0), Err(Error::DivisionByZero)),
1186             (Value::I32(-6), Value::I32(0), Err(Error::DivisionByZero)),
1187             (Value::U32(6), Value::U32(0), Err(Error::DivisionByZero)),
1188             (Value::I64(-6), Value::I64(0), Err(Error::DivisionByZero)),
1189             (Value::U64(6), Value::U64(0), Err(Error::DivisionByZero)),
1190             (Value::F32(-6.), Value::F32(0.), Ok(Value::F32(-6. / 0.))),
1191             (Value::F64(-6.), Value::F64(0.), Ok(Value::F64(-6. / 0.))),
1192         ] {
1193             assert_eq!(v1.div(v2, addr_mask), result);
1194         }
1195     }
1196 
1197     #[test]
1198     #[rustfmt::skip]
value_rem()1199     fn value_rem() {
1200         let addr_mask = 0xffff_ffff;
1201         for &(v1, v2, result) in &[
1202             (Value::Generic(3), Value::Generic(2), Ok(Value::Generic(1))),
1203             (Value::I8(-3), Value::I8(2), Ok(Value::I8(-1))),
1204             (Value::U8(3), Value::U8(2), Ok(Value::U8(1))),
1205             (Value::I16(-3), Value::I16(2), Ok(Value::I16(-1))),
1206             (Value::U16(3), Value::U16(2), Ok(Value::U16(1))),
1207             (Value::I32(-3), Value::I32(2), Ok(Value::I32(-1))),
1208             (Value::U32(3), Value::U32(2), Ok(Value::U32(1))),
1209             (Value::I64(-3), Value::I64(2), Ok(Value::I64(-1))),
1210             (Value::U64(3), Value::U64(2), Ok(Value::U64(1))),
1211             (Value::F32(-3.), Value::F32(2.), Err(Error::IntegralTypeRequired)),
1212             (Value::F64(-3.), Value::F64(2.), Err(Error::IntegralTypeRequired)),
1213             (Value::Generic(3), Value::U32(2), Err(Error::TypeMismatch)),
1214         ] {
1215             assert_eq!(v1.rem(v2, addr_mask), result);
1216         }
1217         for &(v1, v2, result) in &[
1218             (Value::Generic(3), Value::Generic(0), Err(Error::DivisionByZero)),
1219             (Value::I8(-3), Value::I8(0), Err(Error::DivisionByZero)),
1220             (Value::U8(3), Value::U8(0), Err(Error::DivisionByZero)),
1221             (Value::I16(-3), Value::I16(0), Err(Error::DivisionByZero)),
1222             (Value::U16(3), Value::U16(0), Err(Error::DivisionByZero)),
1223             (Value::I32(-3), Value::I32(0), Err(Error::DivisionByZero)),
1224             (Value::U32(3), Value::U32(0), Err(Error::DivisionByZero)),
1225             (Value::I64(-3), Value::I64(0), Err(Error::DivisionByZero)),
1226             (Value::U64(3), Value::U64(0), Err(Error::DivisionByZero)),
1227         ] {
1228             assert_eq!(v1.rem(v2, addr_mask), result);
1229         }
1230     }
1231 
1232     #[test]
1233     #[rustfmt::skip]
value_not()1234     fn value_not() {
1235         let addr_mask = 0xffff_ffff;
1236         for &(v, result) in &[
1237             (Value::Generic(1), Ok(Value::Generic(!1))),
1238             (Value::I8(1), Ok(Value::I8(!1))),
1239             (Value::U8(1), Ok(Value::U8(!1))),
1240             (Value::I16(1), Ok(Value::I16(!1))),
1241             (Value::U16(1), Ok(Value::U16(!1))),
1242             (Value::I32(1), Ok(Value::I32(!1))),
1243             (Value::U32(1), Ok(Value::U32(!1))),
1244             (Value::I64(1), Ok(Value::I64(!1))),
1245             (Value::U64(1), Ok(Value::U64(!1))),
1246             (Value::F32(1.), Err(Error::IntegralTypeRequired)),
1247             (Value::F64(1.), Err(Error::IntegralTypeRequired)),
1248         ] {
1249             assert_eq!(v.not(addr_mask), result);
1250         }
1251     }
1252 
1253     #[test]
1254     #[rustfmt::skip]
value_and()1255     fn value_and() {
1256         let addr_mask = 0xffff_ffff;
1257         for &(v1, v2, result) in &[
1258             (Value::Generic(3), Value::Generic(5), Ok(Value::Generic(1))),
1259             (Value::I8(3), Value::I8(5), Ok(Value::I8(1))),
1260             (Value::U8(3), Value::U8(5), Ok(Value::U8(1))),
1261             (Value::I16(3), Value::I16(5), Ok(Value::I16(1))),
1262             (Value::U16(3), Value::U16(5), Ok(Value::U16(1))),
1263             (Value::I32(3), Value::I32(5), Ok(Value::I32(1))),
1264             (Value::U32(3), Value::U32(5), Ok(Value::U32(1))),
1265             (Value::I64(3), Value::I64(5), Ok(Value::I64(1))),
1266             (Value::U64(3), Value::U64(5), Ok(Value::U64(1))),
1267             (Value::F32(3.), Value::F32(5.), Err(Error::IntegralTypeRequired)),
1268             (Value::F64(3.), Value::F64(5.), Err(Error::IntegralTypeRequired)),
1269             (Value::Generic(3), Value::U32(5), Err(Error::TypeMismatch)),
1270         ] {
1271             assert_eq!(v1.and(v2, addr_mask), result);
1272         }
1273     }
1274 
1275     #[test]
1276     #[rustfmt::skip]
value_or()1277     fn value_or() {
1278         let addr_mask = 0xffff_ffff;
1279         for &(v1, v2, result) in &[
1280             (Value::Generic(3), Value::Generic(5), Ok(Value::Generic(7))),
1281             (Value::I8(3), Value::I8(5), Ok(Value::I8(7))),
1282             (Value::U8(3), Value::U8(5), Ok(Value::U8(7))),
1283             (Value::I16(3), Value::I16(5), Ok(Value::I16(7))),
1284             (Value::U16(3), Value::U16(5), Ok(Value::U16(7))),
1285             (Value::I32(3), Value::I32(5), Ok(Value::I32(7))),
1286             (Value::U32(3), Value::U32(5), Ok(Value::U32(7))),
1287             (Value::I64(3), Value::I64(5), Ok(Value::I64(7))),
1288             (Value::U64(3), Value::U64(5), Ok(Value::U64(7))),
1289             (Value::F32(3.), Value::F32(5.), Err(Error::IntegralTypeRequired)),
1290             (Value::F64(3.), Value::F64(5.), Err(Error::IntegralTypeRequired)),
1291             (Value::Generic(3), Value::U32(5), Err(Error::TypeMismatch)),
1292         ] {
1293             assert_eq!(v1.or(v2, addr_mask), result);
1294         }
1295     }
1296 
1297     #[test]
1298     #[rustfmt::skip]
value_xor()1299     fn value_xor() {
1300         let addr_mask = 0xffff_ffff;
1301         for &(v1, v2, result) in &[
1302             (Value::Generic(3), Value::Generic(5), Ok(Value::Generic(6))),
1303             (Value::I8(3), Value::I8(5), Ok(Value::I8(6))),
1304             (Value::U8(3), Value::U8(5), Ok(Value::U8(6))),
1305             (Value::I16(3), Value::I16(5), Ok(Value::I16(6))),
1306             (Value::U16(3), Value::U16(5), Ok(Value::U16(6))),
1307             (Value::I32(3), Value::I32(5), Ok(Value::I32(6))),
1308             (Value::U32(3), Value::U32(5), Ok(Value::U32(6))),
1309             (Value::I64(3), Value::I64(5), Ok(Value::I64(6))),
1310             (Value::U64(3), Value::U64(5), Ok(Value::U64(6))),
1311             (Value::F32(3.), Value::F32(5.), Err(Error::IntegralTypeRequired)),
1312             (Value::F64(3.), Value::F64(5.), Err(Error::IntegralTypeRequired)),
1313             (Value::Generic(3), Value::U32(5), Err(Error::TypeMismatch)),
1314         ] {
1315             assert_eq!(v1.xor(v2, addr_mask), result);
1316         }
1317     }
1318 
1319     #[test]
1320     #[rustfmt::skip]
value_shl()1321     fn value_shl() {
1322         let addr_mask = 0xffff_ffff;
1323         for &(v1, v2, result) in &[
1324             // One of each type
1325             (Value::Generic(3), Value::Generic(5), Ok(Value::Generic(96))),
1326             (Value::I8(3), Value::U8(5), Ok(Value::I8(96))),
1327             (Value::U8(3), Value::I8(5), Ok(Value::U8(96))),
1328             (Value::I16(3), Value::U16(5), Ok(Value::I16(96))),
1329             (Value::U16(3), Value::I16(5), Ok(Value::U16(96))),
1330             (Value::I32(3), Value::U32(5), Ok(Value::I32(96))),
1331             (Value::U32(3), Value::I32(5), Ok(Value::U32(96))),
1332             (Value::I64(3), Value::U64(5), Ok(Value::I64(96))),
1333             (Value::U64(3), Value::I64(5), Ok(Value::U64(96))),
1334             (Value::F32(3.), Value::U8(5), Err(Error::IntegralTypeRequired)),
1335             (Value::F64(3.), Value::U8(5), Err(Error::IntegralTypeRequired)),
1336             // Invalid shifts
1337             (Value::U8(3), Value::I8(-5), Err(Error::InvalidShiftExpression)),
1338             (Value::U8(3), Value::I16(-5), Err(Error::InvalidShiftExpression)),
1339             (Value::U8(3), Value::I32(-5), Err(Error::InvalidShiftExpression)),
1340             (Value::U8(3), Value::I64(-5), Err(Error::InvalidShiftExpression)),
1341             (Value::U8(3), Value::F32(5.), Err(Error::InvalidShiftExpression)),
1342             (Value::U8(3), Value::F64(5.), Err(Error::InvalidShiftExpression)),
1343             // Large shifts
1344             (Value::Generic(3), Value::Generic(32), Ok(Value::Generic(0))),
1345             (Value::I8(3), Value::U8(8), Ok(Value::I8(0))),
1346             (Value::U8(3), Value::I8(9), Ok(Value::U8(0))),
1347             (Value::I16(3), Value::U16(17), Ok(Value::I16(0))),
1348             (Value::U16(3), Value::I16(16), Ok(Value::U16(0))),
1349             (Value::I32(3), Value::U32(32), Ok(Value::I32(0))),
1350             (Value::U32(3), Value::I32(33), Ok(Value::U32(0))),
1351             (Value::I64(3), Value::U64(65), Ok(Value::I64(0))),
1352             (Value::U64(3), Value::I64(64), Ok(Value::U64(0))),
1353         ] {
1354             assert_eq!(v1.shl(v2, addr_mask), result);
1355         }
1356     }
1357 
1358     #[test]
1359     #[rustfmt::skip]
value_shr()1360     fn value_shr() {
1361         let addr_mask = 0xffff_ffff;
1362         for &(v1, v2, result) in &[
1363             // One of each type
1364             (Value::Generic(96), Value::Generic(5), Ok(Value::Generic(3))),
1365             (Value::I8(96), Value::U8(5), Err(Error::UnsupportedTypeOperation)),
1366             (Value::U8(96), Value::I8(5), Ok(Value::U8(3))),
1367             (Value::I16(96), Value::U16(5), Err(Error::UnsupportedTypeOperation)),
1368             (Value::U16(96), Value::I16(5), Ok(Value::U16(3))),
1369             (Value::I32(96), Value::U32(5), Err(Error::UnsupportedTypeOperation)),
1370             (Value::U32(96), Value::I32(5), Ok(Value::U32(3))),
1371             (Value::I64(96), Value::U64(5), Err(Error::UnsupportedTypeOperation)),
1372             (Value::U64(96), Value::I64(5), Ok(Value::U64(3))),
1373             (Value::F32(96.), Value::U8(5), Err(Error::IntegralTypeRequired)),
1374             (Value::F64(96.), Value::U8(5), Err(Error::IntegralTypeRequired)),
1375             // Invalid shifts
1376             (Value::U8(96), Value::I8(-5), Err(Error::InvalidShiftExpression)),
1377             (Value::U8(96), Value::I16(-5), Err(Error::InvalidShiftExpression)),
1378             (Value::U8(96), Value::I32(-5), Err(Error::InvalidShiftExpression)),
1379             (Value::U8(96), Value::I64(-5), Err(Error::InvalidShiftExpression)),
1380             (Value::U8(96), Value::F32(5.), Err(Error::InvalidShiftExpression)),
1381             (Value::U8(96), Value::F64(5.), Err(Error::InvalidShiftExpression)),
1382             // Large shifts
1383             (Value::Generic(96), Value::Generic(32), Ok(Value::Generic(0))),
1384             (Value::U8(96), Value::I8(9), Ok(Value::U8(0))),
1385             (Value::U16(96), Value::I16(16), Ok(Value::U16(0))),
1386             (Value::U32(96), Value::I32(33), Ok(Value::U32(0))),
1387             (Value::U64(96), Value::I64(64), Ok(Value::U64(0))),
1388         ] {
1389             assert_eq!(v1.shr(v2, addr_mask), result);
1390         }
1391     }
1392 
1393     #[test]
1394     #[rustfmt::skip]
value_shra()1395     fn value_shra() {
1396         let addr_mask = 0xffff_ffff;
1397         for &(v1, v2, result) in &[
1398             // One of each type
1399             (Value::Generic(u64::from(-96i32 as u32)), Value::Generic(5), Ok(Value::Generic(-3i64 as u64))),
1400             (Value::I8(-96), Value::U8(5), Ok(Value::I8(-3))),
1401             (Value::U8(96), Value::I8(5), Err(Error::UnsupportedTypeOperation)),
1402             (Value::I16(-96), Value::U16(5), Ok(Value::I16(-3))),
1403             (Value::U16(96), Value::I16(5), Err(Error::UnsupportedTypeOperation)),
1404             (Value::I32(-96), Value::U32(5), Ok(Value::I32(-3))),
1405             (Value::U32(96), Value::I32(5), Err(Error::UnsupportedTypeOperation)),
1406             (Value::I64(-96), Value::U64(5), Ok(Value::I64(-3))),
1407             (Value::U64(96), Value::I64(5), Err(Error::UnsupportedTypeOperation)),
1408             (Value::F32(96.), Value::U8(5), Err(Error::IntegralTypeRequired)),
1409             (Value::F64(96.), Value::U8(5), Err(Error::IntegralTypeRequired)),
1410             // Invalid shifts
1411             (Value::U8(96), Value::I8(-5), Err(Error::InvalidShiftExpression)),
1412             (Value::U8(96), Value::I16(-5), Err(Error::InvalidShiftExpression)),
1413             (Value::U8(96), Value::I32(-5), Err(Error::InvalidShiftExpression)),
1414             (Value::U8(96), Value::I64(-5), Err(Error::InvalidShiftExpression)),
1415             (Value::U8(96), Value::F32(5.), Err(Error::InvalidShiftExpression)),
1416             (Value::U8(96), Value::F64(5.), Err(Error::InvalidShiftExpression)),
1417             // Large shifts
1418             (Value::Generic(96), Value::Generic(32), Ok(Value::Generic(0))),
1419             (Value::I8(96), Value::U8(8), Ok(Value::I8(0))),
1420             (Value::I8(-96), Value::U8(8), Ok(Value::I8(-1))),
1421             (Value::I16(96), Value::U16(17), Ok(Value::I16(0))),
1422             (Value::I16(-96), Value::U16(17), Ok(Value::I16(-1))),
1423             (Value::I32(96), Value::U32(32), Ok(Value::I32(0))),
1424             (Value::I32(-96), Value::U32(32), Ok(Value::I32(-1))),
1425             (Value::I64(96), Value::U64(65), Ok(Value::I64(0))),
1426             (Value::I64(-96), Value::U64(65), Ok(Value::I64(-1))),
1427         ] {
1428             assert_eq!(v1.shra(v2, addr_mask), result);
1429         }
1430     }
1431 
1432     #[test]
value_eq()1433     fn value_eq() {
1434         let addr_mask = 0xffff_ffff;
1435         for &(v1, v2, result) in &[
1436             (Value::Generic(3), Value::Generic(3), Ok(Value::Generic(1))),
1437             (Value::Generic(!3), Value::Generic(3), Ok(Value::Generic(0))),
1438             (Value::I8(3), Value::I8(3), Ok(Value::Generic(1))),
1439             (Value::I8(!3), Value::I8(3), Ok(Value::Generic(0))),
1440             (Value::U8(3), Value::U8(3), Ok(Value::Generic(1))),
1441             (Value::U8(!3), Value::U8(3), Ok(Value::Generic(0))),
1442             (Value::I16(3), Value::I16(3), Ok(Value::Generic(1))),
1443             (Value::I16(!3), Value::I16(3), Ok(Value::Generic(0))),
1444             (Value::U16(3), Value::U16(3), Ok(Value::Generic(1))),
1445             (Value::U16(!3), Value::U16(3), Ok(Value::Generic(0))),
1446             (Value::I32(3), Value::I32(3), Ok(Value::Generic(1))),
1447             (Value::I32(!3), Value::I32(3), Ok(Value::Generic(0))),
1448             (Value::U32(3), Value::U32(3), Ok(Value::Generic(1))),
1449             (Value::U32(!3), Value::U32(3), Ok(Value::Generic(0))),
1450             (Value::I64(3), Value::I64(3), Ok(Value::Generic(1))),
1451             (Value::I64(!3), Value::I64(3), Ok(Value::Generic(0))),
1452             (Value::U64(3), Value::U64(3), Ok(Value::Generic(1))),
1453             (Value::U64(!3), Value::U64(3), Ok(Value::Generic(0))),
1454             (Value::F32(3.), Value::F32(3.), Ok(Value::Generic(1))),
1455             (Value::F32(-3.), Value::F32(3.), Ok(Value::Generic(0))),
1456             (Value::F64(3.), Value::F64(3.), Ok(Value::Generic(1))),
1457             (Value::F64(-3.), Value::F64(3.), Ok(Value::Generic(0))),
1458             (Value::Generic(3), Value::U32(3), Err(Error::TypeMismatch)),
1459         ] {
1460             assert_eq!(v1.eq(v2, addr_mask), result);
1461         }
1462     }
1463 
1464     #[test]
value_ne()1465     fn value_ne() {
1466         let addr_mask = 0xffff_ffff;
1467         for &(v1, v2, result) in &[
1468             (Value::Generic(3), Value::Generic(3), Ok(Value::Generic(0))),
1469             (Value::Generic(!3), Value::Generic(3), Ok(Value::Generic(1))),
1470             (Value::I8(3), Value::I8(3), Ok(Value::Generic(0))),
1471             (Value::I8(!3), Value::I8(3), Ok(Value::Generic(1))),
1472             (Value::U8(3), Value::U8(3), Ok(Value::Generic(0))),
1473             (Value::U8(!3), Value::U8(3), Ok(Value::Generic(1))),
1474             (Value::I16(3), Value::I16(3), Ok(Value::Generic(0))),
1475             (Value::I16(!3), Value::I16(3), Ok(Value::Generic(1))),
1476             (Value::U16(3), Value::U16(3), Ok(Value::Generic(0))),
1477             (Value::U16(!3), Value::U16(3), Ok(Value::Generic(1))),
1478             (Value::I32(3), Value::I32(3), Ok(Value::Generic(0))),
1479             (Value::I32(!3), Value::I32(3), Ok(Value::Generic(1))),
1480             (Value::U32(3), Value::U32(3), Ok(Value::Generic(0))),
1481             (Value::U32(!3), Value::U32(3), Ok(Value::Generic(1))),
1482             (Value::I64(3), Value::I64(3), Ok(Value::Generic(0))),
1483             (Value::I64(!3), Value::I64(3), Ok(Value::Generic(1))),
1484             (Value::U64(3), Value::U64(3), Ok(Value::Generic(0))),
1485             (Value::U64(!3), Value::U64(3), Ok(Value::Generic(1))),
1486             (Value::F32(3.), Value::F32(3.), Ok(Value::Generic(0))),
1487             (Value::F32(-3.), Value::F32(3.), Ok(Value::Generic(1))),
1488             (Value::F64(3.), Value::F64(3.), Ok(Value::Generic(0))),
1489             (Value::F64(-3.), Value::F64(3.), Ok(Value::Generic(1))),
1490             (Value::Generic(3), Value::U32(3), Err(Error::TypeMismatch)),
1491         ] {
1492             assert_eq!(v1.ne(v2, addr_mask), result);
1493         }
1494     }
1495 
1496     #[test]
value_ge()1497     fn value_ge() {
1498         let addr_mask = 0xffff_ffff;
1499         for &(v1, v2, result) in &[
1500             (Value::Generic(3), Value::Generic(!3), Ok(Value::Generic(1))),
1501             (Value::Generic(!3), Value::Generic(3), Ok(Value::Generic(0))),
1502             (Value::I8(3), Value::I8(!3), Ok(Value::Generic(1))),
1503             (Value::I8(!3), Value::I8(3), Ok(Value::Generic(0))),
1504             (Value::U8(3), Value::U8(!3), Ok(Value::Generic(0))),
1505             (Value::U8(!3), Value::U8(3), Ok(Value::Generic(1))),
1506             (Value::I16(3), Value::I16(!3), Ok(Value::Generic(1))),
1507             (Value::I16(!3), Value::I16(3), Ok(Value::Generic(0))),
1508             (Value::U16(3), Value::U16(!3), Ok(Value::Generic(0))),
1509             (Value::U16(!3), Value::U16(3), Ok(Value::Generic(1))),
1510             (Value::I32(3), Value::I32(!3), Ok(Value::Generic(1))),
1511             (Value::I32(!3), Value::I32(3), Ok(Value::Generic(0))),
1512             (Value::U32(3), Value::U32(!3), Ok(Value::Generic(0))),
1513             (Value::U32(!3), Value::U32(3), Ok(Value::Generic(1))),
1514             (Value::I64(3), Value::I64(!3), Ok(Value::Generic(1))),
1515             (Value::I64(!3), Value::I64(3), Ok(Value::Generic(0))),
1516             (Value::U64(3), Value::U64(!3), Ok(Value::Generic(0))),
1517             (Value::U64(!3), Value::U64(3), Ok(Value::Generic(1))),
1518             (Value::F32(3.), Value::F32(-3.), Ok(Value::Generic(1))),
1519             (Value::F32(-3.), Value::F32(3.), Ok(Value::Generic(0))),
1520             (Value::F64(3.), Value::F64(-3.), Ok(Value::Generic(1))),
1521             (Value::F64(-3.), Value::F64(3.), Ok(Value::Generic(0))),
1522             (Value::Generic(3), Value::U32(3), Err(Error::TypeMismatch)),
1523         ] {
1524             assert_eq!(v1.ge(v2, addr_mask), result);
1525         }
1526     }
1527 
1528     #[test]
value_gt()1529     fn value_gt() {
1530         let addr_mask = 0xffff_ffff;
1531         for &(v1, v2, result) in &[
1532             (Value::Generic(3), Value::Generic(!3), Ok(Value::Generic(1))),
1533             (Value::Generic(!3), Value::Generic(3), Ok(Value::Generic(0))),
1534             (Value::I8(3), Value::I8(!3), Ok(Value::Generic(1))),
1535             (Value::I8(!3), Value::I8(3), Ok(Value::Generic(0))),
1536             (Value::U8(3), Value::U8(!3), Ok(Value::Generic(0))),
1537             (Value::U8(!3), Value::U8(3), Ok(Value::Generic(1))),
1538             (Value::I16(3), Value::I16(!3), Ok(Value::Generic(1))),
1539             (Value::I16(!3), Value::I16(3), Ok(Value::Generic(0))),
1540             (Value::U16(3), Value::U16(!3), Ok(Value::Generic(0))),
1541             (Value::U16(!3), Value::U16(3), Ok(Value::Generic(1))),
1542             (Value::I32(3), Value::I32(!3), Ok(Value::Generic(1))),
1543             (Value::I32(!3), Value::I32(3), Ok(Value::Generic(0))),
1544             (Value::U32(3), Value::U32(!3), Ok(Value::Generic(0))),
1545             (Value::U32(!3), Value::U32(3), Ok(Value::Generic(1))),
1546             (Value::I64(3), Value::I64(!3), Ok(Value::Generic(1))),
1547             (Value::I64(!3), Value::I64(3), Ok(Value::Generic(0))),
1548             (Value::U64(3), Value::U64(!3), Ok(Value::Generic(0))),
1549             (Value::U64(!3), Value::U64(3), Ok(Value::Generic(1))),
1550             (Value::F32(3.), Value::F32(-3.), Ok(Value::Generic(1))),
1551             (Value::F32(-3.), Value::F32(3.), Ok(Value::Generic(0))),
1552             (Value::F64(3.), Value::F64(-3.), Ok(Value::Generic(1))),
1553             (Value::F64(-3.), Value::F64(3.), Ok(Value::Generic(0))),
1554             (Value::Generic(3), Value::U32(3), Err(Error::TypeMismatch)),
1555         ] {
1556             assert_eq!(v1.gt(v2, addr_mask), result);
1557         }
1558     }
1559 
1560     #[test]
value_le()1561     fn value_le() {
1562         let addr_mask = 0xffff_ffff;
1563         for &(v1, v2, result) in &[
1564             (Value::Generic(3), Value::Generic(!3), Ok(Value::Generic(0))),
1565             (Value::Generic(!3), Value::Generic(3), Ok(Value::Generic(1))),
1566             (Value::I8(3), Value::I8(!3), Ok(Value::Generic(0))),
1567             (Value::I8(!3), Value::I8(3), Ok(Value::Generic(1))),
1568             (Value::U8(3), Value::U8(!3), Ok(Value::Generic(1))),
1569             (Value::U8(!3), Value::U8(3), Ok(Value::Generic(0))),
1570             (Value::I16(3), Value::I16(!3), Ok(Value::Generic(0))),
1571             (Value::I16(!3), Value::I16(3), Ok(Value::Generic(1))),
1572             (Value::U16(3), Value::U16(!3), Ok(Value::Generic(1))),
1573             (Value::U16(!3), Value::U16(3), Ok(Value::Generic(0))),
1574             (Value::I32(3), Value::I32(!3), Ok(Value::Generic(0))),
1575             (Value::I32(!3), Value::I32(3), Ok(Value::Generic(1))),
1576             (Value::U32(3), Value::U32(!3), Ok(Value::Generic(1))),
1577             (Value::U32(!3), Value::U32(3), Ok(Value::Generic(0))),
1578             (Value::I64(3), Value::I64(!3), Ok(Value::Generic(0))),
1579             (Value::I64(!3), Value::I64(3), Ok(Value::Generic(1))),
1580             (Value::U64(3), Value::U64(!3), Ok(Value::Generic(1))),
1581             (Value::U64(!3), Value::U64(3), Ok(Value::Generic(0))),
1582             (Value::F32(3.), Value::F32(-3.), Ok(Value::Generic(0))),
1583             (Value::F32(-3.), Value::F32(3.), Ok(Value::Generic(1))),
1584             (Value::F64(3.), Value::F64(-3.), Ok(Value::Generic(0))),
1585             (Value::F64(-3.), Value::F64(3.), Ok(Value::Generic(1))),
1586             (Value::Generic(3), Value::U32(3), Err(Error::TypeMismatch)),
1587         ] {
1588             assert_eq!(v1.le(v2, addr_mask), result);
1589         }
1590     }
1591 
1592     #[test]
value_lt()1593     fn value_lt() {
1594         let addr_mask = 0xffff_ffff;
1595         for &(v1, v2, result) in &[
1596             (Value::Generic(3), Value::Generic(!3), Ok(Value::Generic(0))),
1597             (Value::Generic(!3), Value::Generic(3), Ok(Value::Generic(1))),
1598             (Value::I8(3), Value::I8(!3), Ok(Value::Generic(0))),
1599             (Value::I8(!3), Value::I8(3), Ok(Value::Generic(1))),
1600             (Value::U8(3), Value::U8(!3), Ok(Value::Generic(1))),
1601             (Value::U8(!3), Value::U8(3), Ok(Value::Generic(0))),
1602             (Value::I16(3), Value::I16(!3), Ok(Value::Generic(0))),
1603             (Value::I16(!3), Value::I16(3), Ok(Value::Generic(1))),
1604             (Value::U16(3), Value::U16(!3), Ok(Value::Generic(1))),
1605             (Value::U16(!3), Value::U16(3), Ok(Value::Generic(0))),
1606             (Value::I32(3), Value::I32(!3), Ok(Value::Generic(0))),
1607             (Value::I32(!3), Value::I32(3), Ok(Value::Generic(1))),
1608             (Value::U32(3), Value::U32(!3), Ok(Value::Generic(1))),
1609             (Value::U32(!3), Value::U32(3), Ok(Value::Generic(0))),
1610             (Value::I64(3), Value::I64(!3), Ok(Value::Generic(0))),
1611             (Value::I64(!3), Value::I64(3), Ok(Value::Generic(1))),
1612             (Value::U64(3), Value::U64(!3), Ok(Value::Generic(1))),
1613             (Value::U64(!3), Value::U64(3), Ok(Value::Generic(0))),
1614             (Value::F32(3.), Value::F32(-3.), Ok(Value::Generic(0))),
1615             (Value::F32(-3.), Value::F32(3.), Ok(Value::Generic(1))),
1616             (Value::F64(3.), Value::F64(-3.), Ok(Value::Generic(0))),
1617             (Value::F64(-3.), Value::F64(3.), Ok(Value::Generic(1))),
1618             (Value::Generic(3), Value::U32(3), Err(Error::TypeMismatch)),
1619         ] {
1620             assert_eq!(v1.lt(v2, addr_mask), result);
1621         }
1622     }
1623 }
1624