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