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