Skip to main content

gimli/read/
value.rs

1//! Definitions for values used in DWARF expressions.
2
3use crate::constants;
4#[cfg(feature = "read")]
5use crate::read::{AttributeValue, DebuggingInformationEntry};
6use crate::read::{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]
13fn 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]
20fn 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)]
26pub 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)]
55pub 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
80impl ValueType {
81    /// The size in bits of a value for this type.
82    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.
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.
110    #[cfg(feature = "read")]
111    pub fn from_entry<R: Reader>(
112        entry: &DebuggingInformationEntry<R>,
113    ) -> Result<Option<ValueType>> {
114        if entry.tag() != constants::DW_TAG_base_type {
115            return Ok(None);
116        }
117        let mut encoding = None;
118        let mut byte_size = None;
119        let mut endianity = constants::DW_END_default;
120        for attr in entry.attrs() {
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
151impl Value {
152    /// Return the `ValueType` corresponding to this `Value`.
153    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`.
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.
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,
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`.
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`.
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`.
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.
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.
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(f32::to_bits(value)),
309            Value::F64(value) => f64::to_bits(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.
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.
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 implicitly 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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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 implicitly 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.
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 { !0 } else { 0 }
694                } else {
695                    (v1 >> v2) as u64
696                };
697                Value::Generic(value)
698            }
699            Value::I8(v1) => Value::I8(if v2 >= 8 {
700                if v1 < 0 { !0 } else { 0 }
701            } else {
702                v1 >> v2
703            }),
704            Value::I16(v1) => Value::I16(if v2 >= 16 {
705                if v1 < 0 { !0 } else { 0 }
706            } else {
707                v1 >> v2
708            }),
709            Value::I32(v1) => Value::I32(if v2 >= 32 {
710                if v1 < 0 { !0 } else { 0 }
711            } else {
712                v1 >> v2
713            }),
714            Value::I64(v1) => Value::I64(if v2 >= 64 {
715                if v1 < 0 { !0 } else { 0 }
716            } else {
717                v1 >> v2
718            }),
719            // It's unclear if unsigned values should implicitly convert to a signed value.
720            // For now, we don't support them.
721            Value::U8(_) | Value::U16(_) | Value::U32(_) | Value::U64(_) => {
722                return Err(Error::UnsupportedTypeOperation);
723            }
724            _ => return Err(Error::IntegralTypeRequired),
725        };
726        Ok(value)
727    }
728
729    /// Perform the `==` relational operation.
730    ///
731    /// This operation requires matching integral types.
732    /// If the value type is `Generic`, then it is interpreted as a signed value.
733    ///
734    /// This corresponds to the DWARF `DW_OP_eq` operation.
735    pub fn eq(self, rhs: Value, addr_mask: u64) -> Result<Value> {
736        let value = match (self, rhs) {
737            (Value::Generic(v1), Value::Generic(v2)) => {
738                sign_extend(v1, addr_mask) == sign_extend(v2, addr_mask)
739            }
740            (Value::I8(v1), Value::I8(v2)) => v1 == v2,
741            (Value::U8(v1), Value::U8(v2)) => v1 == v2,
742            (Value::I16(v1), Value::I16(v2)) => v1 == v2,
743            (Value::U16(v1), Value::U16(v2)) => v1 == v2,
744            (Value::I32(v1), Value::I32(v2)) => v1 == v2,
745            (Value::U32(v1), Value::U32(v2)) => v1 == v2,
746            (Value::I64(v1), Value::I64(v2)) => v1 == v2,
747            (Value::U64(v1), Value::U64(v2)) => v1 == v2,
748            (Value::F32(v1), Value::F32(v2)) => v1 == v2,
749            (Value::F64(v1), Value::F64(v2)) => v1 == v2,
750            _ => return Err(Error::TypeMismatch),
751        };
752        Ok(Value::Generic(value as u64))
753    }
754
755    /// Perform the `>=` relational operation.
756    ///
757    /// This operation requires matching integral types.
758    /// If the value type is `Generic`, then it is interpreted as a signed value.
759    ///
760    /// This corresponds to the DWARF `DW_OP_ge` operation.
761    pub fn ge(self, rhs: Value, addr_mask: u64) -> Result<Value> {
762        let value = match (self, rhs) {
763            (Value::Generic(v1), Value::Generic(v2)) => {
764                sign_extend(v1, addr_mask) >= sign_extend(v2, addr_mask)
765            }
766            (Value::I8(v1), Value::I8(v2)) => v1 >= v2,
767            (Value::U8(v1), Value::U8(v2)) => v1 >= v2,
768            (Value::I16(v1), Value::I16(v2)) => v1 >= v2,
769            (Value::U16(v1), Value::U16(v2)) => v1 >= v2,
770            (Value::I32(v1), Value::I32(v2)) => v1 >= v2,
771            (Value::U32(v1), Value::U32(v2)) => v1 >= v2,
772            (Value::I64(v1), Value::I64(v2)) => v1 >= v2,
773            (Value::U64(v1), Value::U64(v2)) => v1 >= v2,
774            (Value::F32(v1), Value::F32(v2)) => v1 >= v2,
775            (Value::F64(v1), Value::F64(v2)) => v1 >= v2,
776            _ => return Err(Error::TypeMismatch),
777        };
778        Ok(Value::Generic(value as u64))
779    }
780
781    /// Perform the `>` relational operation.
782    ///
783    /// This operation requires matching integral types.
784    /// If the value type is `Generic`, then it is interpreted as a signed value.
785    ///
786    /// This corresponds to the DWARF `DW_OP_gt` operation.
787    pub fn gt(self, rhs: Value, addr_mask: u64) -> Result<Value> {
788        let value = match (self, rhs) {
789            (Value::Generic(v1), Value::Generic(v2)) => {
790                sign_extend(v1, addr_mask) > sign_extend(v2, addr_mask)
791            }
792            (Value::I8(v1), Value::I8(v2)) => v1 > v2,
793            (Value::U8(v1), Value::U8(v2)) => v1 > v2,
794            (Value::I16(v1), Value::I16(v2)) => v1 > v2,
795            (Value::U16(v1), Value::U16(v2)) => v1 > v2,
796            (Value::I32(v1), Value::I32(v2)) => v1 > v2,
797            (Value::U32(v1), Value::U32(v2)) => v1 > v2,
798            (Value::I64(v1), Value::I64(v2)) => v1 > v2,
799            (Value::U64(v1), Value::U64(v2)) => v1 > v2,
800            (Value::F32(v1), Value::F32(v2)) => v1 > v2,
801            (Value::F64(v1), Value::F64(v2)) => v1 > v2,
802            _ => return Err(Error::TypeMismatch),
803        };
804        Ok(Value::Generic(value as u64))
805    }
806
807    /// Perform the `<= relational operation.
808    ///
809    /// This operation requires matching integral types.
810    /// If the value type is `Generic`, then it is interpreted as a signed value.
811    ///
812    /// This corresponds to the DWARF `DW_OP_le` operation.
813    pub fn le(self, rhs: Value, addr_mask: u64) -> Result<Value> {
814        let value = match (self, rhs) {
815            (Value::Generic(v1), Value::Generic(v2)) => {
816                sign_extend(v1, addr_mask) <= sign_extend(v2, addr_mask)
817            }
818            (Value::I8(v1), Value::I8(v2)) => v1 <= v2,
819            (Value::U8(v1), Value::U8(v2)) => v1 <= v2,
820            (Value::I16(v1), Value::I16(v2)) => v1 <= v2,
821            (Value::U16(v1), Value::U16(v2)) => v1 <= v2,
822            (Value::I32(v1), Value::I32(v2)) => v1 <= v2,
823            (Value::U32(v1), Value::U32(v2)) => v1 <= v2,
824            (Value::I64(v1), Value::I64(v2)) => v1 <= v2,
825            (Value::U64(v1), Value::U64(v2)) => v1 <= v2,
826            (Value::F32(v1), Value::F32(v2)) => v1 <= v2,
827            (Value::F64(v1), Value::F64(v2)) => v1 <= v2,
828            _ => return Err(Error::TypeMismatch),
829        };
830        Ok(Value::Generic(value as u64))
831    }
832
833    /// Perform the `< relational operation.
834    ///
835    /// This operation requires matching integral types.
836    /// If the value type is `Generic`, then it is interpreted as a signed value.
837    ///
838    /// This corresponds to the DWARF `DW_OP_lt` operation.
839    pub fn lt(self, rhs: Value, addr_mask: u64) -> Result<Value> {
840        let value = match (self, rhs) {
841            (Value::Generic(v1), Value::Generic(v2)) => {
842                sign_extend(v1, addr_mask) < sign_extend(v2, addr_mask)
843            }
844            (Value::I8(v1), Value::I8(v2)) => v1 < v2,
845            (Value::U8(v1), Value::U8(v2)) => v1 < v2,
846            (Value::I16(v1), Value::I16(v2)) => v1 < v2,
847            (Value::U16(v1), Value::U16(v2)) => v1 < v2,
848            (Value::I32(v1), Value::I32(v2)) => v1 < v2,
849            (Value::U32(v1), Value::U32(v2)) => v1 < v2,
850            (Value::I64(v1), Value::I64(v2)) => v1 < v2,
851            (Value::U64(v1), Value::U64(v2)) => v1 < v2,
852            (Value::F32(v1), Value::F32(v2)) => v1 < v2,
853            (Value::F64(v1), Value::F64(v2)) => v1 < v2,
854            _ => return Err(Error::TypeMismatch),
855        };
856        Ok(Value::Generic(value as u64))
857    }
858
859    /// Perform the `!= relational operation.
860    ///
861    /// This operation requires matching integral types.
862    /// If the value type is `Generic`, then it is interpreted as a signed value.
863    ///
864    /// This corresponds to the DWARF `DW_OP_ne` operation.
865    pub fn ne(self, rhs: Value, addr_mask: u64) -> Result<Value> {
866        let value = match (self, rhs) {
867            (Value::Generic(v1), Value::Generic(v2)) => {
868                sign_extend(v1, addr_mask) != sign_extend(v2, addr_mask)
869            }
870            (Value::I8(v1), Value::I8(v2)) => v1 != v2,
871            (Value::U8(v1), Value::U8(v2)) => v1 != v2,
872            (Value::I16(v1), Value::I16(v2)) => v1 != v2,
873            (Value::U16(v1), Value::U16(v2)) => v1 != v2,
874            (Value::I32(v1), Value::I32(v2)) => v1 != v2,
875            (Value::U32(v1), Value::U32(v2)) => v1 != v2,
876            (Value::I64(v1), Value::I64(v2)) => v1 != v2,
877            (Value::U64(v1), Value::U64(v2)) => v1 != v2,
878            (Value::F32(v1), Value::F32(v2)) => v1 != v2,
879            (Value::F64(v1), Value::F64(v2)) => v1 != v2,
880            _ => return Err(Error::TypeMismatch),
881        };
882        Ok(Value::Generic(value as u64))
883    }
884}
885
886#[cfg(test)]
887mod tests {
888    use super::*;
889    use crate::common::{Encoding, Format};
890    use crate::endianity::LittleEndian;
891    use crate::read::{
892        Abbreviation, Abbreviations, AttributeSpecification, DebuggingInformationEntry,
893        EndianSlice, EntriesRaw, UnitOffset,
894    };
895    use alloc::vec::Vec;
896
897    #[test]
898    fn valuetype_from_encoding() {
899        let encoding = Encoding {
900            format: Format::Dwarf32,
901            version: 4,
902            address_size: 4,
903        };
904
905        let abbrevs = Abbreviations::default();
906        let abbrev = Abbreviation::new(
907            42,
908            constants::DW_TAG_base_type,
909            constants::DW_CHILDREN_no,
910            vec![
911                AttributeSpecification::new(
912                    constants::DW_AT_byte_size,
913                    constants::DW_FORM_udata,
914                    None,
915                ),
916                AttributeSpecification::new(
917                    constants::DW_AT_encoding,
918                    constants::DW_FORM_udata,
919                    None,
920                ),
921                AttributeSpecification::new(
922                    constants::DW_AT_endianity,
923                    constants::DW_FORM_udata,
924                    None,
925                ),
926            ]
927            .into(),
928        );
929
930        #[rustfmt::skip]
931        let tests = [
932            ([0x01, constants::DW_ATE_signed.0, constants::DW_END_default.0], Some(ValueType::I8)),
933            ([0x02, constants::DW_ATE_signed.0, constants::DW_END_default.0], Some(ValueType::I16)),
934            ([0x04, constants::DW_ATE_signed.0, constants::DW_END_default.0], Some(ValueType::I32)),
935            ([0x08, constants::DW_ATE_signed.0, constants::DW_END_default.0], Some(ValueType::I64)),
936            ([0x01, constants::DW_ATE_unsigned.0, constants::DW_END_default.0], Some(ValueType::U8)),
937            ([0x02, constants::DW_ATE_unsigned.0, constants::DW_END_default.0], Some(ValueType::U16)),
938            ([0x04, constants::DW_ATE_unsigned.0, constants::DW_END_default.0], Some(ValueType::U32)),
939            ([0x08, constants::DW_ATE_unsigned.0, constants::DW_END_default.0], Some(ValueType::U64)),
940            ([0x04, constants::DW_ATE_float.0, constants::DW_END_default.0], Some(ValueType::F32)),
941            ([0x08, constants::DW_ATE_float.0, constants::DW_END_default.0], Some(ValueType::F64)),
942            ([0x03, constants::DW_ATE_signed.0, constants::DW_END_default.0], None),
943            ([0x02, constants::DW_ATE_signed.0, constants::DW_END_big.0], None),
944        ];
945
946        for (attrs, result) in &tests {
947            let mut input = EntriesRaw::new(
948                EndianSlice::new(attrs, LittleEndian),
949                encoding,
950                &abbrevs,
951                UnitOffset(0),
952            );
953            let attrs = abbrev
954                .attributes()
955                .iter()
956                .map(|spec| input.read_attribute(*spec))
957                .collect::<Result<Vec<_>>>()
958                .unwrap();
959            let entry = DebuggingInformationEntry::new(
960                abbrev.tag(),
961                abbrev.has_children(),
962                attrs,
963                UnitOffset(0),
964            );
965            assert_eq!(ValueType::from_entry(&entry), Ok(*result));
966        }
967    }
968
969    #[test]
970    fn value_convert() {
971        let addr_mask = !0 >> 32;
972        for &(v, t, result) in &[
973            (Value::Generic(1), ValueType::I8, Ok(Value::I8(1))),
974            (Value::I8(1), ValueType::U8, Ok(Value::U8(1))),
975            (Value::U8(1), ValueType::I16, Ok(Value::I16(1))),
976            (Value::I16(1), ValueType::U16, Ok(Value::U16(1))),
977            (Value::U16(1), ValueType::I32, Ok(Value::I32(1))),
978            (Value::I32(1), ValueType::U32, Ok(Value::U32(1))),
979            (Value::U32(1), ValueType::F32, Ok(Value::F32(1.))),
980            (Value::F32(1.), ValueType::I64, Ok(Value::I64(1))),
981            (Value::I64(1), ValueType::U64, Ok(Value::U64(1))),
982            (Value::U64(1), ValueType::F64, Ok(Value::F64(1.))),
983            (Value::F64(1.), ValueType::Generic, Ok(Value::Generic(1))),
984        ] {
985            assert_eq!(v.convert(t, addr_mask), result);
986        }
987    }
988
989    #[test]
990    #[rustfmt::skip]
991    fn value_reinterpret() {
992        let addr_mask = !0 >> 32;
993        for &(v, t, result) in &[
994            // 8-bit
995            (Value::I8(-1), ValueType::U8, Ok(Value::U8(0xff))),
996            (Value::U8(0xff), ValueType::I8, Ok(Value::I8(-1))),
997            // 16-bit
998            (Value::I16(1), ValueType::U16, Ok(Value::U16(1))),
999            (Value::U16(1), ValueType::I16, Ok(Value::I16(1))),
1000            // 32-bit
1001            (Value::Generic(1), ValueType::I32, Ok(Value::I32(1))),
1002            (Value::I32(1), ValueType::U32, Ok(Value::U32(1))),
1003            (Value::U32(0x3f80_0000), ValueType::F32, Ok(Value::F32(1.0))),
1004            (Value::F32(1.0), ValueType::Generic, Ok(Value::Generic(0x3f80_0000))),
1005            // Type mismatches
1006            (Value::Generic(1), ValueType::U8, Err(Error::TypeMismatch)),
1007            (Value::U8(1), ValueType::U16, Err(Error::TypeMismatch)),
1008            (Value::U16(1), ValueType::U32, Err(Error::TypeMismatch)),
1009            (Value::U32(1), ValueType::U64, Err(Error::TypeMismatch)),
1010            (Value::U64(1), ValueType::Generic, Err(Error::TypeMismatch)),
1011        ] {
1012            assert_eq!(v.reinterpret(t, addr_mask), result);
1013        }
1014
1015        let addr_mask = !0;
1016        for &(v, t, result) in &[
1017            // 64-bit
1018            (Value::Generic(1), ValueType::I64, Ok(Value::I64(1))),
1019            (Value::I64(1), ValueType::U64, Ok(Value::U64(1))),
1020            (Value::U64(0x3ff0_0000_0000_0000), ValueType::F64, Ok(Value::F64(1.0))),
1021            (Value::F64(1.0), ValueType::Generic, Ok(Value::Generic(0x3ff0_0000_0000_0000))),
1022        ] {
1023            assert_eq!(v.reinterpret(t, addr_mask), result);
1024        }
1025    }
1026
1027    #[test]
1028    #[rustfmt::skip]
1029    fn value_abs() {
1030        let addr_mask = 0xffff_ffff;
1031        for &(v, result) in &[
1032            (Value::Generic(0xffff_ffff), Ok(Value::Generic(1))),
1033            (Value::I8(-1), Ok(Value::I8(1))),
1034            (Value::U8(1), Ok(Value::U8(1))),
1035            (Value::I16(-1), Ok(Value::I16(1))),
1036            (Value::U16(1), Ok(Value::U16(1))),
1037            (Value::I32(-1), Ok(Value::I32(1))),
1038            (Value::U32(1), Ok(Value::U32(1))),
1039            (Value::I64(-1), Ok(Value::I64(1))),
1040            (Value::U64(1), Ok(Value::U64(1))),
1041            (Value::F32(-1.), Ok(Value::F32(1.))),
1042            (Value::F64(-1.), Ok(Value::F64(1.))),
1043        ] {
1044            assert_eq!(v.abs(addr_mask), result);
1045        }
1046    }
1047
1048    #[test]
1049    #[rustfmt::skip]
1050    fn value_neg() {
1051        let addr_mask = 0xffff_ffff;
1052        for &(v, result) in &[
1053            (Value::Generic(0xffff_ffff), Ok(Value::Generic(1))),
1054            (Value::I8(1), Ok(Value::I8(-1))),
1055            (Value::U8(1), Err(Error::UnsupportedTypeOperation)),
1056            (Value::I16(1), Ok(Value::I16(-1))),
1057            (Value::U16(1), Err(Error::UnsupportedTypeOperation)),
1058            (Value::I32(1), Ok(Value::I32(-1))),
1059            (Value::U32(1), Err(Error::UnsupportedTypeOperation)),
1060            (Value::I64(1), Ok(Value::I64(-1))),
1061            (Value::U64(1), Err(Error::UnsupportedTypeOperation)),
1062            (Value::F32(1.), Ok(Value::F32(-1.))),
1063            (Value::F64(1.), Ok(Value::F64(-1.))),
1064        ] {
1065            assert_eq!(v.neg(addr_mask), result);
1066        }
1067    }
1068
1069    #[test]
1070    #[rustfmt::skip]
1071    fn value_add() {
1072        let addr_mask = 0xffff_ffff;
1073        for &(v1, v2, result) in &[
1074            (Value::Generic(1), Value::Generic(2), Ok(Value::Generic(3))),
1075            (Value::I8(-1), Value::I8(2), Ok(Value::I8(1))),
1076            (Value::U8(1), Value::U8(2), Ok(Value::U8(3))),
1077            (Value::I16(-1), Value::I16(2), Ok(Value::I16(1))),
1078            (Value::U16(1), Value::U16(2), Ok(Value::U16(3))),
1079            (Value::I32(-1), Value::I32(2), Ok(Value::I32(1))),
1080            (Value::U32(1), Value::U32(2), Ok(Value::U32(3))),
1081            (Value::I64(-1), Value::I64(2), Ok(Value::I64(1))),
1082            (Value::U64(1), Value::U64(2), Ok(Value::U64(3))),
1083            (Value::F32(-1.), Value::F32(2.), Ok(Value::F32(1.))),
1084            (Value::F64(-1.), Value::F64(2.), Ok(Value::F64(1.))),
1085            (Value::Generic(1), Value::U32(2), Err(Error::TypeMismatch)),
1086        ] {
1087            assert_eq!(v1.add(v2, addr_mask), result);
1088        }
1089    }
1090
1091    #[test]
1092    #[rustfmt::skip]
1093    fn value_sub() {
1094        let addr_mask = 0xffff_ffff;
1095        for &(v1, v2, result) in &[
1096            (Value::Generic(3), Value::Generic(2), Ok(Value::Generic(1))),
1097            (Value::I8(-1), Value::I8(2), Ok(Value::I8(-3))),
1098            (Value::U8(3), Value::U8(2), Ok(Value::U8(1))),
1099            (Value::I16(-1), Value::I16(2), Ok(Value::I16(-3))),
1100            (Value::U16(3), Value::U16(2), Ok(Value::U16(1))),
1101            (Value::I32(-1), Value::I32(2), Ok(Value::I32(-3))),
1102            (Value::U32(3), Value::U32(2), Ok(Value::U32(1))),
1103            (Value::I64(-1), Value::I64(2), Ok(Value::I64(-3))),
1104            (Value::U64(3), Value::U64(2), Ok(Value::U64(1))),
1105            (Value::F32(-1.), Value::F32(2.), Ok(Value::F32(-3.))),
1106            (Value::F64(-1.), Value::F64(2.), Ok(Value::F64(-3.))),
1107            (Value::Generic(3), Value::U32(2), Err(Error::TypeMismatch)),
1108        ] {
1109            assert_eq!(v1.sub(v2, addr_mask), result);
1110        }
1111    }
1112
1113    #[test]
1114    #[rustfmt::skip]
1115    fn value_mul() {
1116        let addr_mask = 0xffff_ffff;
1117        for &(v1, v2, result) in &[
1118            (Value::Generic(2), Value::Generic(3), Ok(Value::Generic(6))),
1119            (Value::I8(-2), Value::I8(3), Ok(Value::I8(-6))),
1120            (Value::U8(2), Value::U8(3), Ok(Value::U8(6))),
1121            (Value::I16(-2), Value::I16(3), Ok(Value::I16(-6))),
1122            (Value::U16(2), Value::U16(3), Ok(Value::U16(6))),
1123            (Value::I32(-2), Value::I32(3), Ok(Value::I32(-6))),
1124            (Value::U32(2), Value::U32(3), Ok(Value::U32(6))),
1125            (Value::I64(-2), Value::I64(3), Ok(Value::I64(-6))),
1126            (Value::U64(2), Value::U64(3), Ok(Value::U64(6))),
1127            (Value::F32(-2.), Value::F32(3.), Ok(Value::F32(-6.))),
1128            (Value::F64(-2.), Value::F64(3.), Ok(Value::F64(-6.))),
1129            (Value::Generic(2), Value::U32(3), Err(Error::TypeMismatch)),
1130        ] {
1131            assert_eq!(v1.mul(v2, addr_mask), result);
1132        }
1133    }
1134
1135    #[test]
1136    #[rustfmt::skip]
1137    fn value_div() {
1138        let addr_mask = 0xffff_ffff;
1139        for &(v1, v2, result) in &[
1140            (Value::Generic(6), Value::Generic(3), Ok(Value::Generic(2))),
1141            (Value::I8(-6), Value::I8(3), Ok(Value::I8(-2))),
1142            (Value::U8(6), Value::U8(3), Ok(Value::U8(2))),
1143            (Value::I16(-6), Value::I16(3), Ok(Value::I16(-2))),
1144            (Value::U16(6), Value::U16(3), Ok(Value::U16(2))),
1145            (Value::I32(-6), Value::I32(3), Ok(Value::I32(-2))),
1146            (Value::U32(6), Value::U32(3), Ok(Value::U32(2))),
1147            (Value::I64(-6), Value::I64(3), Ok(Value::I64(-2))),
1148            (Value::U64(6), Value::U64(3), Ok(Value::U64(2))),
1149            (Value::F32(-6.), Value::F32(3.), Ok(Value::F32(-2.))),
1150            (Value::F64(-6.), Value::F64(3.), Ok(Value::F64(-2.))),
1151            (Value::Generic(6), Value::U32(3), Err(Error::TypeMismatch)),
1152        ] {
1153            assert_eq!(v1.div(v2, addr_mask), result);
1154        }
1155        for &(v1, v2, result) in &[
1156            (Value::Generic(6), Value::Generic(0), Err(Error::DivisionByZero)),
1157            (Value::I8(-6), Value::I8(0), Err(Error::DivisionByZero)),
1158            (Value::U8(6), Value::U8(0), Err(Error::DivisionByZero)),
1159            (Value::I16(-6), Value::I16(0), Err(Error::DivisionByZero)),
1160            (Value::U16(6), Value::U16(0), Err(Error::DivisionByZero)),
1161            (Value::I32(-6), Value::I32(0), Err(Error::DivisionByZero)),
1162            (Value::U32(6), Value::U32(0), Err(Error::DivisionByZero)),
1163            (Value::I64(-6), Value::I64(0), Err(Error::DivisionByZero)),
1164            (Value::U64(6), Value::U64(0), Err(Error::DivisionByZero)),
1165            (Value::F32(-6.), Value::F32(0.), Ok(Value::F32(-6. / 0.))),
1166            (Value::F64(-6.), Value::F64(0.), Ok(Value::F64(-6. / 0.))),
1167        ] {
1168            assert_eq!(v1.div(v2, addr_mask), result);
1169        }
1170    }
1171
1172    #[test]
1173    #[rustfmt::skip]
1174    fn value_rem() {
1175        let addr_mask = 0xffff_ffff;
1176        for &(v1, v2, result) in &[
1177            (Value::Generic(3), Value::Generic(2), Ok(Value::Generic(1))),
1178            (Value::I8(-3), Value::I8(2), Ok(Value::I8(-1))),
1179            (Value::U8(3), Value::U8(2), Ok(Value::U8(1))),
1180            (Value::I16(-3), Value::I16(2), Ok(Value::I16(-1))),
1181            (Value::U16(3), Value::U16(2), Ok(Value::U16(1))),
1182            (Value::I32(-3), Value::I32(2), Ok(Value::I32(-1))),
1183            (Value::U32(3), Value::U32(2), Ok(Value::U32(1))),
1184            (Value::I64(-3), Value::I64(2), Ok(Value::I64(-1))),
1185            (Value::U64(3), Value::U64(2), Ok(Value::U64(1))),
1186            (Value::F32(-3.), Value::F32(2.), Err(Error::IntegralTypeRequired)),
1187            (Value::F64(-3.), Value::F64(2.), Err(Error::IntegralTypeRequired)),
1188            (Value::Generic(3), Value::U32(2), Err(Error::TypeMismatch)),
1189        ] {
1190            assert_eq!(v1.rem(v2, addr_mask), result);
1191        }
1192        for &(v1, v2, result) in &[
1193            (Value::Generic(3), Value::Generic(0), Err(Error::DivisionByZero)),
1194            (Value::I8(-3), Value::I8(0), Err(Error::DivisionByZero)),
1195            (Value::U8(3), Value::U8(0), Err(Error::DivisionByZero)),
1196            (Value::I16(-3), Value::I16(0), Err(Error::DivisionByZero)),
1197            (Value::U16(3), Value::U16(0), Err(Error::DivisionByZero)),
1198            (Value::I32(-3), Value::I32(0), Err(Error::DivisionByZero)),
1199            (Value::U32(3), Value::U32(0), Err(Error::DivisionByZero)),
1200            (Value::I64(-3), Value::I64(0), Err(Error::DivisionByZero)),
1201            (Value::U64(3), Value::U64(0), Err(Error::DivisionByZero)),
1202        ] {
1203            assert_eq!(v1.rem(v2, addr_mask), result);
1204        }
1205    }
1206
1207    #[test]
1208    #[rustfmt::skip]
1209    fn value_not() {
1210        let addr_mask = 0xffff_ffff;
1211        for &(v, result) in &[
1212            (Value::Generic(1), Ok(Value::Generic(!1))),
1213            (Value::I8(1), Ok(Value::I8(!1))),
1214            (Value::U8(1), Ok(Value::U8(!1))),
1215            (Value::I16(1), Ok(Value::I16(!1))),
1216            (Value::U16(1), Ok(Value::U16(!1))),
1217            (Value::I32(1), Ok(Value::I32(!1))),
1218            (Value::U32(1), Ok(Value::U32(!1))),
1219            (Value::I64(1), Ok(Value::I64(!1))),
1220            (Value::U64(1), Ok(Value::U64(!1))),
1221            (Value::F32(1.), Err(Error::IntegralTypeRequired)),
1222            (Value::F64(1.), Err(Error::IntegralTypeRequired)),
1223        ] {
1224            assert_eq!(v.not(addr_mask), result);
1225        }
1226    }
1227
1228    #[test]
1229    #[rustfmt::skip]
1230    fn value_and() {
1231        let addr_mask = 0xffff_ffff;
1232        for &(v1, v2, result) in &[
1233            (Value::Generic(3), Value::Generic(5), Ok(Value::Generic(1))),
1234            (Value::I8(3), Value::I8(5), Ok(Value::I8(1))),
1235            (Value::U8(3), Value::U8(5), Ok(Value::U8(1))),
1236            (Value::I16(3), Value::I16(5), Ok(Value::I16(1))),
1237            (Value::U16(3), Value::U16(5), Ok(Value::U16(1))),
1238            (Value::I32(3), Value::I32(5), Ok(Value::I32(1))),
1239            (Value::U32(3), Value::U32(5), Ok(Value::U32(1))),
1240            (Value::I64(3), Value::I64(5), Ok(Value::I64(1))),
1241            (Value::U64(3), Value::U64(5), Ok(Value::U64(1))),
1242            (Value::F32(3.), Value::F32(5.), Err(Error::IntegralTypeRequired)),
1243            (Value::F64(3.), Value::F64(5.), Err(Error::IntegralTypeRequired)),
1244            (Value::Generic(3), Value::U32(5), Err(Error::TypeMismatch)),
1245        ] {
1246            assert_eq!(v1.and(v2, addr_mask), result);
1247        }
1248    }
1249
1250    #[test]
1251    #[rustfmt::skip]
1252    fn value_or() {
1253        let addr_mask = 0xffff_ffff;
1254        for &(v1, v2, result) in &[
1255            (Value::Generic(3), Value::Generic(5), Ok(Value::Generic(7))),
1256            (Value::I8(3), Value::I8(5), Ok(Value::I8(7))),
1257            (Value::U8(3), Value::U8(5), Ok(Value::U8(7))),
1258            (Value::I16(3), Value::I16(5), Ok(Value::I16(7))),
1259            (Value::U16(3), Value::U16(5), Ok(Value::U16(7))),
1260            (Value::I32(3), Value::I32(5), Ok(Value::I32(7))),
1261            (Value::U32(3), Value::U32(5), Ok(Value::U32(7))),
1262            (Value::I64(3), Value::I64(5), Ok(Value::I64(7))),
1263            (Value::U64(3), Value::U64(5), Ok(Value::U64(7))),
1264            (Value::F32(3.), Value::F32(5.), Err(Error::IntegralTypeRequired)),
1265            (Value::F64(3.), Value::F64(5.), Err(Error::IntegralTypeRequired)),
1266            (Value::Generic(3), Value::U32(5), Err(Error::TypeMismatch)),
1267        ] {
1268            assert_eq!(v1.or(v2, addr_mask), result);
1269        }
1270    }
1271
1272    #[test]
1273    #[rustfmt::skip]
1274    fn value_xor() {
1275        let addr_mask = 0xffff_ffff;
1276        for &(v1, v2, result) in &[
1277            (Value::Generic(3), Value::Generic(5), Ok(Value::Generic(6))),
1278            (Value::I8(3), Value::I8(5), Ok(Value::I8(6))),
1279            (Value::U8(3), Value::U8(5), Ok(Value::U8(6))),
1280            (Value::I16(3), Value::I16(5), Ok(Value::I16(6))),
1281            (Value::U16(3), Value::U16(5), Ok(Value::U16(6))),
1282            (Value::I32(3), Value::I32(5), Ok(Value::I32(6))),
1283            (Value::U32(3), Value::U32(5), Ok(Value::U32(6))),
1284            (Value::I64(3), Value::I64(5), Ok(Value::I64(6))),
1285            (Value::U64(3), Value::U64(5), Ok(Value::U64(6))),
1286            (Value::F32(3.), Value::F32(5.), Err(Error::IntegralTypeRequired)),
1287            (Value::F64(3.), Value::F64(5.), Err(Error::IntegralTypeRequired)),
1288            (Value::Generic(3), Value::U32(5), Err(Error::TypeMismatch)),
1289        ] {
1290            assert_eq!(v1.xor(v2, addr_mask), result);
1291        }
1292    }
1293
1294    #[test]
1295    #[rustfmt::skip]
1296    fn value_shl() {
1297        let addr_mask = 0xffff_ffff;
1298        for &(v1, v2, result) in &[
1299            // One of each type
1300            (Value::Generic(3), Value::Generic(5), Ok(Value::Generic(96))),
1301            (Value::I8(3), Value::U8(5), Ok(Value::I8(96))),
1302            (Value::U8(3), Value::I8(5), Ok(Value::U8(96))),
1303            (Value::I16(3), Value::U16(5), Ok(Value::I16(96))),
1304            (Value::U16(3), Value::I16(5), Ok(Value::U16(96))),
1305            (Value::I32(3), Value::U32(5), Ok(Value::I32(96))),
1306            (Value::U32(3), Value::I32(5), Ok(Value::U32(96))),
1307            (Value::I64(3), Value::U64(5), Ok(Value::I64(96))),
1308            (Value::U64(3), Value::I64(5), Ok(Value::U64(96))),
1309            (Value::F32(3.), Value::U8(5), Err(Error::IntegralTypeRequired)),
1310            (Value::F64(3.), Value::U8(5), Err(Error::IntegralTypeRequired)),
1311            // Invalid shifts
1312            (Value::U8(3), Value::I8(-5), Err(Error::InvalidShiftExpression)),
1313            (Value::U8(3), Value::I16(-5), Err(Error::InvalidShiftExpression)),
1314            (Value::U8(3), Value::I32(-5), Err(Error::InvalidShiftExpression)),
1315            (Value::U8(3), Value::I64(-5), Err(Error::InvalidShiftExpression)),
1316            (Value::U8(3), Value::F32(5.), Err(Error::InvalidShiftExpression)),
1317            (Value::U8(3), Value::F64(5.), Err(Error::InvalidShiftExpression)),
1318            // Large shifts
1319            (Value::Generic(3), Value::Generic(32), Ok(Value::Generic(0))),
1320            (Value::I8(3), Value::U8(8), Ok(Value::I8(0))),
1321            (Value::U8(3), Value::I8(9), Ok(Value::U8(0))),
1322            (Value::I16(3), Value::U16(17), Ok(Value::I16(0))),
1323            (Value::U16(3), Value::I16(16), Ok(Value::U16(0))),
1324            (Value::I32(3), Value::U32(32), Ok(Value::I32(0))),
1325            (Value::U32(3), Value::I32(33), Ok(Value::U32(0))),
1326            (Value::I64(3), Value::U64(65), Ok(Value::I64(0))),
1327            (Value::U64(3), Value::I64(64), Ok(Value::U64(0))),
1328        ] {
1329            assert_eq!(v1.shl(v2, addr_mask), result);
1330        }
1331    }
1332
1333    #[test]
1334    #[rustfmt::skip]
1335    fn value_shr() {
1336        let addr_mask = 0xffff_ffff;
1337        for &(v1, v2, result) in &[
1338            // One of each type
1339            (Value::Generic(96), Value::Generic(5), Ok(Value::Generic(3))),
1340            (Value::I8(96), Value::U8(5), Err(Error::UnsupportedTypeOperation)),
1341            (Value::U8(96), Value::I8(5), Ok(Value::U8(3))),
1342            (Value::I16(96), Value::U16(5), Err(Error::UnsupportedTypeOperation)),
1343            (Value::U16(96), Value::I16(5), Ok(Value::U16(3))),
1344            (Value::I32(96), Value::U32(5), Err(Error::UnsupportedTypeOperation)),
1345            (Value::U32(96), Value::I32(5), Ok(Value::U32(3))),
1346            (Value::I64(96), Value::U64(5), Err(Error::UnsupportedTypeOperation)),
1347            (Value::U64(96), Value::I64(5), Ok(Value::U64(3))),
1348            (Value::F32(96.), Value::U8(5), Err(Error::IntegralTypeRequired)),
1349            (Value::F64(96.), Value::U8(5), Err(Error::IntegralTypeRequired)),
1350            // Invalid shifts
1351            (Value::U8(96), Value::I8(-5), Err(Error::InvalidShiftExpression)),
1352            (Value::U8(96), Value::I16(-5), Err(Error::InvalidShiftExpression)),
1353            (Value::U8(96), Value::I32(-5), Err(Error::InvalidShiftExpression)),
1354            (Value::U8(96), Value::I64(-5), Err(Error::InvalidShiftExpression)),
1355            (Value::U8(96), Value::F32(5.), Err(Error::InvalidShiftExpression)),
1356            (Value::U8(96), Value::F64(5.), Err(Error::InvalidShiftExpression)),
1357            // Large shifts
1358            (Value::Generic(96), Value::Generic(32), Ok(Value::Generic(0))),
1359            (Value::U8(96), Value::I8(9), Ok(Value::U8(0))),
1360            (Value::U16(96), Value::I16(16), Ok(Value::U16(0))),
1361            (Value::U32(96), Value::I32(33), Ok(Value::U32(0))),
1362            (Value::U64(96), Value::I64(64), Ok(Value::U64(0))),
1363        ] {
1364            assert_eq!(v1.shr(v2, addr_mask), result);
1365        }
1366    }
1367
1368    #[test]
1369    #[rustfmt::skip]
1370    fn value_shra() {
1371        let addr_mask = 0xffff_ffff;
1372        for &(v1, v2, result) in &[
1373            // One of each type
1374            (Value::Generic(u64::from(-96i32 as u32)), Value::Generic(5), Ok(Value::Generic(-3i64 as u64))),
1375            (Value::I8(-96), Value::U8(5), Ok(Value::I8(-3))),
1376            (Value::U8(96), Value::I8(5), Err(Error::UnsupportedTypeOperation)),
1377            (Value::I16(-96), Value::U16(5), Ok(Value::I16(-3))),
1378            (Value::U16(96), Value::I16(5), Err(Error::UnsupportedTypeOperation)),
1379            (Value::I32(-96), Value::U32(5), Ok(Value::I32(-3))),
1380            (Value::U32(96), Value::I32(5), Err(Error::UnsupportedTypeOperation)),
1381            (Value::I64(-96), Value::U64(5), Ok(Value::I64(-3))),
1382            (Value::U64(96), Value::I64(5), Err(Error::UnsupportedTypeOperation)),
1383            (Value::F32(96.), Value::U8(5), Err(Error::IntegralTypeRequired)),
1384            (Value::F64(96.), Value::U8(5), Err(Error::IntegralTypeRequired)),
1385            // Invalid shifts
1386            (Value::U8(96), Value::I8(-5), Err(Error::InvalidShiftExpression)),
1387            (Value::U8(96), Value::I16(-5), Err(Error::InvalidShiftExpression)),
1388            (Value::U8(96), Value::I32(-5), Err(Error::InvalidShiftExpression)),
1389            (Value::U8(96), Value::I64(-5), Err(Error::InvalidShiftExpression)),
1390            (Value::U8(96), Value::F32(5.), Err(Error::InvalidShiftExpression)),
1391            (Value::U8(96), Value::F64(5.), Err(Error::InvalidShiftExpression)),
1392            // Large shifts
1393            (Value::Generic(96), Value::Generic(32), Ok(Value::Generic(0))),
1394            (Value::I8(96), Value::U8(8), Ok(Value::I8(0))),
1395            (Value::I8(-96), Value::U8(8), Ok(Value::I8(-1))),
1396            (Value::I16(96), Value::U16(17), Ok(Value::I16(0))),
1397            (Value::I16(-96), Value::U16(17), Ok(Value::I16(-1))),
1398            (Value::I32(96), Value::U32(32), Ok(Value::I32(0))),
1399            (Value::I32(-96), Value::U32(32), Ok(Value::I32(-1))),
1400            (Value::I64(96), Value::U64(65), Ok(Value::I64(0))),
1401            (Value::I64(-96), Value::U64(65), Ok(Value::I64(-1))),
1402        ] {
1403            assert_eq!(v1.shra(v2, addr_mask), result);
1404        }
1405    }
1406
1407    #[test]
1408    fn value_eq() {
1409        let addr_mask = 0xffff_ffff;
1410        for &(v1, v2, result) in &[
1411            (Value::Generic(3), Value::Generic(3), Ok(Value::Generic(1))),
1412            (Value::Generic(!3), Value::Generic(3), Ok(Value::Generic(0))),
1413            (Value::I8(3), Value::I8(3), Ok(Value::Generic(1))),
1414            (Value::I8(!3), Value::I8(3), Ok(Value::Generic(0))),
1415            (Value::U8(3), Value::U8(3), Ok(Value::Generic(1))),
1416            (Value::U8(!3), Value::U8(3), Ok(Value::Generic(0))),
1417            (Value::I16(3), Value::I16(3), Ok(Value::Generic(1))),
1418            (Value::I16(!3), Value::I16(3), Ok(Value::Generic(0))),
1419            (Value::U16(3), Value::U16(3), Ok(Value::Generic(1))),
1420            (Value::U16(!3), Value::U16(3), Ok(Value::Generic(0))),
1421            (Value::I32(3), Value::I32(3), Ok(Value::Generic(1))),
1422            (Value::I32(!3), Value::I32(3), Ok(Value::Generic(0))),
1423            (Value::U32(3), Value::U32(3), Ok(Value::Generic(1))),
1424            (Value::U32(!3), Value::U32(3), Ok(Value::Generic(0))),
1425            (Value::I64(3), Value::I64(3), Ok(Value::Generic(1))),
1426            (Value::I64(!3), Value::I64(3), Ok(Value::Generic(0))),
1427            (Value::U64(3), Value::U64(3), Ok(Value::Generic(1))),
1428            (Value::U64(!3), Value::U64(3), Ok(Value::Generic(0))),
1429            (Value::F32(3.), Value::F32(3.), Ok(Value::Generic(1))),
1430            (Value::F32(-3.), Value::F32(3.), Ok(Value::Generic(0))),
1431            (Value::F64(3.), Value::F64(3.), Ok(Value::Generic(1))),
1432            (Value::F64(-3.), Value::F64(3.), Ok(Value::Generic(0))),
1433            (Value::Generic(3), Value::U32(3), Err(Error::TypeMismatch)),
1434        ] {
1435            assert_eq!(v1.eq(v2, addr_mask), result);
1436        }
1437    }
1438
1439    #[test]
1440    fn value_ne() {
1441        let addr_mask = 0xffff_ffff;
1442        for &(v1, v2, result) in &[
1443            (Value::Generic(3), Value::Generic(3), Ok(Value::Generic(0))),
1444            (Value::Generic(!3), Value::Generic(3), Ok(Value::Generic(1))),
1445            (Value::I8(3), Value::I8(3), Ok(Value::Generic(0))),
1446            (Value::I8(!3), Value::I8(3), Ok(Value::Generic(1))),
1447            (Value::U8(3), Value::U8(3), Ok(Value::Generic(0))),
1448            (Value::U8(!3), Value::U8(3), Ok(Value::Generic(1))),
1449            (Value::I16(3), Value::I16(3), Ok(Value::Generic(0))),
1450            (Value::I16(!3), Value::I16(3), Ok(Value::Generic(1))),
1451            (Value::U16(3), Value::U16(3), Ok(Value::Generic(0))),
1452            (Value::U16(!3), Value::U16(3), Ok(Value::Generic(1))),
1453            (Value::I32(3), Value::I32(3), Ok(Value::Generic(0))),
1454            (Value::I32(!3), Value::I32(3), Ok(Value::Generic(1))),
1455            (Value::U32(3), Value::U32(3), Ok(Value::Generic(0))),
1456            (Value::U32(!3), Value::U32(3), Ok(Value::Generic(1))),
1457            (Value::I64(3), Value::I64(3), Ok(Value::Generic(0))),
1458            (Value::I64(!3), Value::I64(3), Ok(Value::Generic(1))),
1459            (Value::U64(3), Value::U64(3), Ok(Value::Generic(0))),
1460            (Value::U64(!3), Value::U64(3), Ok(Value::Generic(1))),
1461            (Value::F32(3.), Value::F32(3.), Ok(Value::Generic(0))),
1462            (Value::F32(-3.), Value::F32(3.), Ok(Value::Generic(1))),
1463            (Value::F64(3.), Value::F64(3.), Ok(Value::Generic(0))),
1464            (Value::F64(-3.), Value::F64(3.), Ok(Value::Generic(1))),
1465            (Value::Generic(3), Value::U32(3), Err(Error::TypeMismatch)),
1466        ] {
1467            assert_eq!(v1.ne(v2, addr_mask), result);
1468        }
1469    }
1470
1471    #[test]
1472    fn value_ge() {
1473        let addr_mask = 0xffff_ffff;
1474        for &(v1, v2, result) in &[
1475            (Value::Generic(3), Value::Generic(!3), Ok(Value::Generic(1))),
1476            (Value::Generic(!3), Value::Generic(3), Ok(Value::Generic(0))),
1477            (Value::I8(3), Value::I8(!3), Ok(Value::Generic(1))),
1478            (Value::I8(!3), Value::I8(3), Ok(Value::Generic(0))),
1479            (Value::U8(3), Value::U8(!3), Ok(Value::Generic(0))),
1480            (Value::U8(!3), Value::U8(3), Ok(Value::Generic(1))),
1481            (Value::I16(3), Value::I16(!3), Ok(Value::Generic(1))),
1482            (Value::I16(!3), Value::I16(3), Ok(Value::Generic(0))),
1483            (Value::U16(3), Value::U16(!3), Ok(Value::Generic(0))),
1484            (Value::U16(!3), Value::U16(3), Ok(Value::Generic(1))),
1485            (Value::I32(3), Value::I32(!3), Ok(Value::Generic(1))),
1486            (Value::I32(!3), Value::I32(3), Ok(Value::Generic(0))),
1487            (Value::U32(3), Value::U32(!3), Ok(Value::Generic(0))),
1488            (Value::U32(!3), Value::U32(3), Ok(Value::Generic(1))),
1489            (Value::I64(3), Value::I64(!3), Ok(Value::Generic(1))),
1490            (Value::I64(!3), Value::I64(3), Ok(Value::Generic(0))),
1491            (Value::U64(3), Value::U64(!3), Ok(Value::Generic(0))),
1492            (Value::U64(!3), Value::U64(3), Ok(Value::Generic(1))),
1493            (Value::F32(3.), Value::F32(-3.), Ok(Value::Generic(1))),
1494            (Value::F32(-3.), Value::F32(3.), Ok(Value::Generic(0))),
1495            (Value::F64(3.), Value::F64(-3.), Ok(Value::Generic(1))),
1496            (Value::F64(-3.), Value::F64(3.), Ok(Value::Generic(0))),
1497            (Value::Generic(3), Value::U32(3), Err(Error::TypeMismatch)),
1498        ] {
1499            assert_eq!(v1.ge(v2, addr_mask), result);
1500        }
1501    }
1502
1503    #[test]
1504    fn value_gt() {
1505        let addr_mask = 0xffff_ffff;
1506        for &(v1, v2, result) in &[
1507            (Value::Generic(3), Value::Generic(!3), Ok(Value::Generic(1))),
1508            (Value::Generic(!3), Value::Generic(3), Ok(Value::Generic(0))),
1509            (Value::I8(3), Value::I8(!3), Ok(Value::Generic(1))),
1510            (Value::I8(!3), Value::I8(3), Ok(Value::Generic(0))),
1511            (Value::U8(3), Value::U8(!3), Ok(Value::Generic(0))),
1512            (Value::U8(!3), Value::U8(3), Ok(Value::Generic(1))),
1513            (Value::I16(3), Value::I16(!3), Ok(Value::Generic(1))),
1514            (Value::I16(!3), Value::I16(3), Ok(Value::Generic(0))),
1515            (Value::U16(3), Value::U16(!3), Ok(Value::Generic(0))),
1516            (Value::U16(!3), Value::U16(3), Ok(Value::Generic(1))),
1517            (Value::I32(3), Value::I32(!3), Ok(Value::Generic(1))),
1518            (Value::I32(!3), Value::I32(3), Ok(Value::Generic(0))),
1519            (Value::U32(3), Value::U32(!3), Ok(Value::Generic(0))),
1520            (Value::U32(!3), Value::U32(3), Ok(Value::Generic(1))),
1521            (Value::I64(3), Value::I64(!3), Ok(Value::Generic(1))),
1522            (Value::I64(!3), Value::I64(3), Ok(Value::Generic(0))),
1523            (Value::U64(3), Value::U64(!3), Ok(Value::Generic(0))),
1524            (Value::U64(!3), Value::U64(3), Ok(Value::Generic(1))),
1525            (Value::F32(3.), Value::F32(-3.), Ok(Value::Generic(1))),
1526            (Value::F32(-3.), Value::F32(3.), Ok(Value::Generic(0))),
1527            (Value::F64(3.), Value::F64(-3.), Ok(Value::Generic(1))),
1528            (Value::F64(-3.), Value::F64(3.), Ok(Value::Generic(0))),
1529            (Value::Generic(3), Value::U32(3), Err(Error::TypeMismatch)),
1530        ] {
1531            assert_eq!(v1.gt(v2, addr_mask), result);
1532        }
1533    }
1534
1535    #[test]
1536    fn value_le() {
1537        let addr_mask = 0xffff_ffff;
1538        for &(v1, v2, result) in &[
1539            (Value::Generic(3), Value::Generic(!3), Ok(Value::Generic(0))),
1540            (Value::Generic(!3), Value::Generic(3), Ok(Value::Generic(1))),
1541            (Value::I8(3), Value::I8(!3), Ok(Value::Generic(0))),
1542            (Value::I8(!3), Value::I8(3), Ok(Value::Generic(1))),
1543            (Value::U8(3), Value::U8(!3), Ok(Value::Generic(1))),
1544            (Value::U8(!3), Value::U8(3), Ok(Value::Generic(0))),
1545            (Value::I16(3), Value::I16(!3), Ok(Value::Generic(0))),
1546            (Value::I16(!3), Value::I16(3), Ok(Value::Generic(1))),
1547            (Value::U16(3), Value::U16(!3), Ok(Value::Generic(1))),
1548            (Value::U16(!3), Value::U16(3), Ok(Value::Generic(0))),
1549            (Value::I32(3), Value::I32(!3), Ok(Value::Generic(0))),
1550            (Value::I32(!3), Value::I32(3), Ok(Value::Generic(1))),
1551            (Value::U32(3), Value::U32(!3), Ok(Value::Generic(1))),
1552            (Value::U32(!3), Value::U32(3), Ok(Value::Generic(0))),
1553            (Value::I64(3), Value::I64(!3), Ok(Value::Generic(0))),
1554            (Value::I64(!3), Value::I64(3), Ok(Value::Generic(1))),
1555            (Value::U64(3), Value::U64(!3), Ok(Value::Generic(1))),
1556            (Value::U64(!3), Value::U64(3), Ok(Value::Generic(0))),
1557            (Value::F32(3.), Value::F32(-3.), Ok(Value::Generic(0))),
1558            (Value::F32(-3.), Value::F32(3.), Ok(Value::Generic(1))),
1559            (Value::F64(3.), Value::F64(-3.), Ok(Value::Generic(0))),
1560            (Value::F64(-3.), Value::F64(3.), Ok(Value::Generic(1))),
1561            (Value::Generic(3), Value::U32(3), Err(Error::TypeMismatch)),
1562        ] {
1563            assert_eq!(v1.le(v2, addr_mask), result);
1564        }
1565    }
1566
1567    #[test]
1568    fn value_lt() {
1569        let addr_mask = 0xffff_ffff;
1570        for &(v1, v2, result) in &[
1571            (Value::Generic(3), Value::Generic(!3), Ok(Value::Generic(0))),
1572            (Value::Generic(!3), Value::Generic(3), Ok(Value::Generic(1))),
1573            (Value::I8(3), Value::I8(!3), Ok(Value::Generic(0))),
1574            (Value::I8(!3), Value::I8(3), Ok(Value::Generic(1))),
1575            (Value::U8(3), Value::U8(!3), Ok(Value::Generic(1))),
1576            (Value::U8(!3), Value::U8(3), Ok(Value::Generic(0))),
1577            (Value::I16(3), Value::I16(!3), Ok(Value::Generic(0))),
1578            (Value::I16(!3), Value::I16(3), Ok(Value::Generic(1))),
1579            (Value::U16(3), Value::U16(!3), Ok(Value::Generic(1))),
1580            (Value::U16(!3), Value::U16(3), Ok(Value::Generic(0))),
1581            (Value::I32(3), Value::I32(!3), Ok(Value::Generic(0))),
1582            (Value::I32(!3), Value::I32(3), Ok(Value::Generic(1))),
1583            (Value::U32(3), Value::U32(!3), Ok(Value::Generic(1))),
1584            (Value::U32(!3), Value::U32(3), Ok(Value::Generic(0))),
1585            (Value::I64(3), Value::I64(!3), Ok(Value::Generic(0))),
1586            (Value::I64(!3), Value::I64(3), Ok(Value::Generic(1))),
1587            (Value::U64(3), Value::U64(!3), Ok(Value::Generic(1))),
1588            (Value::U64(!3), Value::U64(3), Ok(Value::Generic(0))),
1589            (Value::F32(3.), Value::F32(-3.), Ok(Value::Generic(0))),
1590            (Value::F32(-3.), Value::F32(3.), Ok(Value::Generic(1))),
1591            (Value::F64(3.), Value::F64(-3.), Ok(Value::Generic(0))),
1592            (Value::F64(-3.), Value::F64(3.), Ok(Value::Generic(1))),
1593            (Value::Generic(3), Value::U32(3), Err(Error::TypeMismatch)),
1594        ] {
1595            assert_eq!(v1.lt(v2, addr_mask), result);
1596        }
1597    }
1598}