Coverage Report

Created: 2026-03-26 07:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/gimli-0.32.3/src/read/value.rs
Line
Count
Source
1
//! Definitions for values used in DWARF expressions.
2
3
use crate::constants;
4
#[cfg(feature = "read")]
5
use crate::read::{AttributeValue, DebuggingInformationEntry};
6
use 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]
13
0
fn sign_extend(value: u64, mask: u64) -> i64 {
14
0
    let value = (value & mask) as i64;
15
0
    let sign = ((mask >> 1) + 1) as i64;
16
0
    (value ^ sign).wrapping_sub(sign)
17
0
}
18
19
#[inline]
20
0
fn mask_bit_size(addr_mask: u64) -> u32 {
21
0
    64 - addr_mask.leading_zeros()
22
0
}
23
24
/// The type of an entry on the DWARF stack.
25
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
26
pub enum ValueType {
27
    /// The generic type, which is address-sized and of unspecified sign,
28
    /// as specified in the DWARF 5 standard, section 2.5.1.
29
    /// This type is also used to represent address base types.
30
    Generic,
31
    /// Signed 8-bit integer type.
32
    I8,
33
    /// Unsigned 8-bit integer type.
34
    U8,
35
    /// Signed 16-bit integer type.
36
    I16,
37
    /// Unsigned 16-bit integer type.
38
    U16,
39
    /// Signed 32-bit integer type.
40
    I32,
41
    /// Unsigned 32-bit integer type.
42
    U32,
43
    /// Signed 64-bit integer type.
44
    I64,
45
    /// Unsigned 64-bit integer type.
46
    U64,
47
    /// 32-bit floating point type.
48
    F32,
49
    /// 64-bit floating point type.
50
    F64,
51
}
52
53
/// The value of an entry on the DWARF stack.
54
#[derive(Debug, Clone, Copy, PartialEq)]
55
pub enum Value {
56
    /// A generic value, which is address-sized and of unspecified sign.
57
    Generic(u64),
58
    /// A signed 8-bit integer value.
59
    I8(i8),
60
    /// An unsigned 8-bit integer value.
61
    U8(u8),
62
    /// A signed 16-bit integer value.
63
    I16(i16),
64
    /// An unsigned 16-bit integer value.
65
    U16(u16),
66
    /// A signed 32-bit integer value.
67
    I32(i32),
68
    /// An unsigned 32-bit integer value.
69
    U32(u32),
70
    /// A signed 64-bit integer value.
71
    I64(i64),
72
    /// An unsigned 64-bit integer value.
73
    U64(u64),
74
    /// A 32-bit floating point value.
75
    F32(f32),
76
    /// A 64-bit floating point value.
77
    F64(f64),
78
}
79
80
impl ValueType {
81
    /// The size in bits of a value for this type.
82
0
    pub fn bit_size(self, addr_mask: u64) -> u32 {
83
0
        match self {
84
0
            ValueType::Generic => mask_bit_size(addr_mask),
85
0
            ValueType::I8 | ValueType::U8 => 8,
86
0
            ValueType::I16 | ValueType::U16 => 16,
87
0
            ValueType::I32 | ValueType::U32 | ValueType::F32 => 32,
88
0
            ValueType::I64 | ValueType::U64 | ValueType::F64 => 64,
89
        }
90
0
    }
91
92
    /// Construct a `ValueType` from the attributes of a base type DIE.
93
0
    pub fn from_encoding(encoding: constants::DwAte, byte_size: u64) -> Option<ValueType> {
94
0
        Some(match (encoding, byte_size) {
95
0
            (constants::DW_ATE_signed, 1) => ValueType::I8,
96
0
            (constants::DW_ATE_signed, 2) => ValueType::I16,
97
0
            (constants::DW_ATE_signed, 4) => ValueType::I32,
98
0
            (constants::DW_ATE_signed, 8) => ValueType::I64,
99
0
            (constants::DW_ATE_unsigned, 1) => ValueType::U8,
100
0
            (constants::DW_ATE_unsigned, 2) => ValueType::U16,
101
0
            (constants::DW_ATE_unsigned, 4) => ValueType::U32,
102
0
            (constants::DW_ATE_unsigned, 8) => ValueType::U64,
103
0
            (constants::DW_ATE_float, 4) => ValueType::F32,
104
0
            (constants::DW_ATE_float, 8) => ValueType::F64,
105
0
            _ => return None,
106
        })
107
0
    }
108
109
    /// Construct a `ValueType` from a base type DIE.
110
    #[cfg(feature = "read")]
111
0
    pub fn from_entry<R: Reader>(
112
0
        entry: &DebuggingInformationEntry<'_, '_, R>,
113
0
    ) -> Result<Option<ValueType>> {
114
0
        if entry.tag() != constants::DW_TAG_base_type {
115
0
            return Ok(None);
116
0
        }
117
0
        let mut encoding = None;
118
0
        let mut byte_size = None;
119
0
        let mut endianity = constants::DW_END_default;
120
0
        let mut attrs = entry.attrs();
121
0
        while let Some(attr) = attrs.next()? {
122
0
            match attr.name() {
123
0
                constants::DW_AT_byte_size => byte_size = attr.udata_value(),
124
                constants::DW_AT_encoding => {
125
0
                    if let AttributeValue::Encoding(x) = attr.value() {
126
0
                        encoding = Some(x);
127
0
                    }
128
                }
129
                constants::DW_AT_endianity => {
130
0
                    if let AttributeValue::Endianity(x) = attr.value() {
131
0
                        endianity = x;
132
0
                    }
133
                }
134
0
                _ => {}
135
            }
136
        }
137
138
0
        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
0
            return Ok(None);
142
0
        }
143
144
0
        if let (Some(encoding), Some(byte_size)) = (encoding, byte_size) {
145
0
            Ok(ValueType::from_encoding(encoding, byte_size))
146
        } else {
147
0
            Ok(None)
148
        }
149
0
    }
150
}
151
152
impl Value {
153
    /// Return the `ValueType` corresponding to this `Value`.
154
0
    pub fn value_type(&self) -> ValueType {
155
0
        match *self {
156
0
            Value::Generic(_) => ValueType::Generic,
157
0
            Value::I8(_) => ValueType::I8,
158
0
            Value::U8(_) => ValueType::U8,
159
0
            Value::I16(_) => ValueType::I16,
160
0
            Value::U16(_) => ValueType::U16,
161
0
            Value::I32(_) => ValueType::I32,
162
0
            Value::U32(_) => ValueType::U32,
163
0
            Value::I64(_) => ValueType::I64,
164
0
            Value::U64(_) => ValueType::U64,
165
0
            Value::F32(_) => ValueType::F32,
166
0
            Value::F64(_) => ValueType::F64,
167
        }
168
0
    }
169
170
    /// Read a `Value` with the given `value_type` from a `Reader`.
171
0
    pub fn parse<R: Reader>(value_type: ValueType, mut bytes: R) -> Result<Value> {
172
0
        let value = match value_type {
173
0
            ValueType::I8 => Value::I8(bytes.read_i8()?),
174
0
            ValueType::U8 => Value::U8(bytes.read_u8()?),
175
0
            ValueType::I16 => Value::I16(bytes.read_i16()?),
176
0
            ValueType::U16 => Value::U16(bytes.read_u16()?),
177
0
            ValueType::I32 => Value::I32(bytes.read_i32()?),
178
0
            ValueType::U32 => Value::U32(bytes.read_u32()?),
179
0
            ValueType::I64 => Value::I64(bytes.read_i64()?),
180
0
            ValueType::U64 => Value::U64(bytes.read_u64()?),
181
0
            ValueType::F32 => Value::F32(bytes.read_f32()?),
182
0
            ValueType::F64 => Value::F64(bytes.read_f64()?),
183
0
            _ => return Err(Error::UnsupportedTypeOperation),
184
        };
185
0
        Ok(value)
186
0
    }
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
0
    pub fn to_u64(self, addr_mask: u64) -> Result<u64> {
193
0
        let value = match self {
194
0
            Value::Generic(value) => value & addr_mask,
195
0
            Value::I8(value) => value as u64,
196
0
            Value::U8(value) => u64::from(value),
197
0
            Value::I16(value) => value as u64,
198
0
            Value::U16(value) => u64::from(value),
199
0
            Value::I32(value) => value as u64,
200
0
            Value::U32(value) => u64::from(value),
201
0
            Value::I64(value) => value as u64,
202
0
            Value::U64(value) => value,
203
0
            _ => return Err(Error::IntegralTypeRequired),
204
        };
205
0
        Ok(value)
206
0
    }
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
0
    pub fn from_u64(value_type: ValueType, value: u64) -> Result<Value> {
214
0
        let value = match value_type {
215
0
            ValueType::Generic => Value::Generic(value),
216
0
            ValueType::I8 => Value::I8(value as i8),
217
0
            ValueType::U8 => Value::U8(value as u8),
218
0
            ValueType::I16 => Value::I16(value as i16),
219
0
            ValueType::U16 => Value::U16(value as u16),
220
0
            ValueType::I32 => Value::I32(value as i32),
221
0
            ValueType::U32 => Value::U32(value as u32),
222
0
            ValueType::I64 => Value::I64(value as i64),
223
0
            ValueType::U64 => Value::U64(value),
224
0
            ValueType::F32 => Value::F32(value as f32),
225
0
            ValueType::F64 => Value::F64(value as f64),
226
        };
227
0
        Ok(value)
228
0
    }
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
0
    fn from_f32(value_type: ValueType, value: f32) -> Result<Value> {
236
0
        let value = match value_type {
237
0
            ValueType::Generic => Value::Generic(value as u64),
238
0
            ValueType::I8 => Value::I8(value as i8),
239
0
            ValueType::U8 => Value::U8(value as u8),
240
0
            ValueType::I16 => Value::I16(value as i16),
241
0
            ValueType::U16 => Value::U16(value as u16),
242
0
            ValueType::I32 => Value::I32(value as i32),
243
0
            ValueType::U32 => Value::U32(value as u32),
244
0
            ValueType::I64 => Value::I64(value as i64),
245
0
            ValueType::U64 => Value::U64(value as u64),
246
0
            ValueType::F32 => Value::F32(value),
247
0
            ValueType::F64 => Value::F64(f64::from(value)),
248
        };
249
0
        Ok(value)
250
0
    }
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
0
    fn from_f64(value_type: ValueType, value: f64) -> Result<Value> {
258
0
        let value = match value_type {
259
0
            ValueType::Generic => Value::Generic(value as u64),
260
0
            ValueType::I8 => Value::I8(value as i8),
261
0
            ValueType::U8 => Value::U8(value as u8),
262
0
            ValueType::I16 => Value::I16(value as i16),
263
0
            ValueType::U16 => Value::U16(value as u16),
264
0
            ValueType::I32 => Value::I32(value as i32),
265
0
            ValueType::U32 => Value::U32(value as u32),
266
0
            ValueType::I64 => Value::I64(value as i64),
267
0
            ValueType::U64 => Value::U64(value as u64),
268
0
            ValueType::F32 => Value::F32(value as f32),
269
0
            ValueType::F64 => Value::F64(value),
270
        };
271
0
        Ok(value)
272
0
    }
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
0
    pub fn convert(self, value_type: ValueType, addr_mask: u64) -> Result<Value> {
283
0
        match self {
284
0
            Value::F32(value) => Value::from_f32(value_type, value),
285
0
            Value::F64(value) => Value::from_f64(value_type, value),
286
0
            _ => Value::from_u64(value_type, self.to_u64(addr_mask)?),
287
        }
288
0
    }
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
0
    pub fn reinterpret(self, value_type: ValueType, addr_mask: u64) -> Result<Value> {
296
0
        if self.value_type().bit_size(addr_mask) != value_type.bit_size(addr_mask) {
297
0
            return Err(Error::TypeMismatch);
298
0
        }
299
0
        let bits = match self {
300
0
            Value::Generic(value) => value,
301
0
            Value::I8(value) => value as u64,
302
0
            Value::U8(value) => u64::from(value),
303
0
            Value::I16(value) => value as u64,
304
0
            Value::U16(value) => u64::from(value),
305
0
            Value::I32(value) => value as u64,
306
0
            Value::U32(value) => u64::from(value),
307
0
            Value::I64(value) => value as u64,
308
0
            Value::U64(value) => value,
309
0
            Value::F32(value) => u64::from(f32::to_bits(value)),
310
0
            Value::F64(value) => f64::to_bits(value),
311
        };
312
0
        let value = match value_type {
313
0
            ValueType::Generic => Value::Generic(bits),
314
0
            ValueType::I8 => Value::I8(bits as i8),
315
0
            ValueType::U8 => Value::U8(bits as u8),
316
0
            ValueType::I16 => Value::I16(bits as i16),
317
0
            ValueType::U16 => Value::U16(bits as u16),
318
0
            ValueType::I32 => Value::I32(bits as i32),
319
0
            ValueType::U32 => Value::U32(bits as u32),
320
0
            ValueType::I64 => Value::I64(bits as i64),
321
0
            ValueType::U64 => Value::U64(bits),
322
0
            ValueType::F32 => Value::F32(f32::from_bits(bits as u32)),
323
0
            ValueType::F64 => Value::F64(f64::from_bits(bits)),
324
        };
325
0
        Ok(value)
326
0
    }
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
0
    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
0
        let value = match self {
337
0
            Value::Generic(value) => {
338
0
                Value::Generic(sign_extend(value, addr_mask).wrapping_abs() as u64)
339
            }
340
0
            Value::I8(value) => Value::I8(value.wrapping_abs()),
341
0
            Value::I16(value) => Value::I16(value.wrapping_abs()),
342
0
            Value::I32(value) => Value::I32(value.wrapping_abs()),
343
0
            Value::I64(value) => Value::I64(value.wrapping_abs()),
344
            // f32/f64::abs() is not available in libcore
345
0
            Value::F32(value) => Value::F32(if value < 0. { -value } else { value }),
346
0
            Value::F64(value) => Value::F64(if value < 0. { -value } else { value }),
347
0
            Value::U8(_) | Value::U16(_) | Value::U32(_) | Value::U64(_) => self,
348
        };
349
0
        Ok(value)
350
0
    }
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
0
    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
0
        let value = match self {
361
0
            Value::Generic(value) => {
362
0
                Value::Generic(sign_extend(value, addr_mask).wrapping_neg() as u64)
363
            }
364
0
            Value::I8(value) => Value::I8(value.wrapping_neg()),
365
0
            Value::I16(value) => Value::I16(value.wrapping_neg()),
366
0
            Value::I32(value) => Value::I32(value.wrapping_neg()),
367
0
            Value::I64(value) => Value::I64(value.wrapping_neg()),
368
0
            Value::F32(value) => Value::F32(-value),
369
0
            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
0
                return Err(Error::UnsupportedTypeOperation);
374
            }
375
        };
376
0
        Ok(value)
377
0
    }
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
0
    pub fn add(self, rhs: Value, addr_mask: u64) -> Result<Value> {
385
0
        let value = match (self, rhs) {
386
0
            (Value::Generic(v1), Value::Generic(v2)) => {
387
0
                Value::Generic(v1.wrapping_add(v2) & addr_mask)
388
            }
389
0
            (Value::I8(v1), Value::I8(v2)) => Value::I8(v1.wrapping_add(v2)),
390
0
            (Value::U8(v1), Value::U8(v2)) => Value::U8(v1.wrapping_add(v2)),
391
0
            (Value::I16(v1), Value::I16(v2)) => Value::I16(v1.wrapping_add(v2)),
392
0
            (Value::U16(v1), Value::U16(v2)) => Value::U16(v1.wrapping_add(v2)),
393
0
            (Value::I32(v1), Value::I32(v2)) => Value::I32(v1.wrapping_add(v2)),
394
0
            (Value::U32(v1), Value::U32(v2)) => Value::U32(v1.wrapping_add(v2)),
395
0
            (Value::I64(v1), Value::I64(v2)) => Value::I64(v1.wrapping_add(v2)),
396
0
            (Value::U64(v1), Value::U64(v2)) => Value::U64(v1.wrapping_add(v2)),
397
0
            (Value::F32(v1), Value::F32(v2)) => Value::F32(v1 + v2),
398
0
            (Value::F64(v1), Value::F64(v2)) => Value::F64(v1 + v2),
399
0
            _ => return Err(Error::TypeMismatch),
400
        };
401
0
        Ok(value)
402
0
    }
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
0
    pub fn sub(self, rhs: Value, addr_mask: u64) -> Result<Value> {
410
0
        let value = match (self, rhs) {
411
0
            (Value::Generic(v1), Value::Generic(v2)) => {
412
0
                Value::Generic(v1.wrapping_sub(v2) & addr_mask)
413
            }
414
0
            (Value::I8(v1), Value::I8(v2)) => Value::I8(v1.wrapping_sub(v2)),
415
0
            (Value::U8(v1), Value::U8(v2)) => Value::U8(v1.wrapping_sub(v2)),
416
0
            (Value::I16(v1), Value::I16(v2)) => Value::I16(v1.wrapping_sub(v2)),
417
0
            (Value::U16(v1), Value::U16(v2)) => Value::U16(v1.wrapping_sub(v2)),
418
0
            (Value::I32(v1), Value::I32(v2)) => Value::I32(v1.wrapping_sub(v2)),
419
0
            (Value::U32(v1), Value::U32(v2)) => Value::U32(v1.wrapping_sub(v2)),
420
0
            (Value::I64(v1), Value::I64(v2)) => Value::I64(v1.wrapping_sub(v2)),
421
0
            (Value::U64(v1), Value::U64(v2)) => Value::U64(v1.wrapping_sub(v2)),
422
0
            (Value::F32(v1), Value::F32(v2)) => Value::F32(v1 - v2),
423
0
            (Value::F64(v1), Value::F64(v2)) => Value::F64(v1 - v2),
424
0
            _ => return Err(Error::TypeMismatch),
425
        };
426
0
        Ok(value)
427
0
    }
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
0
    pub fn mul(self, rhs: Value, addr_mask: u64) -> Result<Value> {
435
0
        let value = match (self, rhs) {
436
0
            (Value::Generic(v1), Value::Generic(v2)) => {
437
0
                Value::Generic(v1.wrapping_mul(v2) & addr_mask)
438
            }
439
0
            (Value::I8(v1), Value::I8(v2)) => Value::I8(v1.wrapping_mul(v2)),
440
0
            (Value::U8(v1), Value::U8(v2)) => Value::U8(v1.wrapping_mul(v2)),
441
0
            (Value::I16(v1), Value::I16(v2)) => Value::I16(v1.wrapping_mul(v2)),
442
0
            (Value::U16(v1), Value::U16(v2)) => Value::U16(v1.wrapping_mul(v2)),
443
0
            (Value::I32(v1), Value::I32(v2)) => Value::I32(v1.wrapping_mul(v2)),
444
0
            (Value::U32(v1), Value::U32(v2)) => Value::U32(v1.wrapping_mul(v2)),
445
0
            (Value::I64(v1), Value::I64(v2)) => Value::I64(v1.wrapping_mul(v2)),
446
0
            (Value::U64(v1), Value::U64(v2)) => Value::U64(v1.wrapping_mul(v2)),
447
0
            (Value::F32(v1), Value::F32(v2)) => Value::F32(v1 * v2),
448
0
            (Value::F64(v1), Value::F64(v2)) => Value::F64(v1 * v2),
449
0
            _ => return Err(Error::TypeMismatch),
450
        };
451
0
        Ok(value)
452
0
    }
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
0
    pub fn div(self, rhs: Value, addr_mask: u64) -> Result<Value> {
461
0
        match rhs {
462
0
            Value::Generic(v2) if sign_extend(v2, addr_mask) == 0 => {
463
0
                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
0
                return Err(Error::DivisionByZero);
474
            }
475
0
            _ => {}
476
        }
477
0
        let value = match (self, rhs) {
478
0
            (Value::Generic(v1), Value::Generic(v2)) => {
479
                // Signed division
480
0
                Value::Generic(
481
0
                    sign_extend(v1, addr_mask).wrapping_div(sign_extend(v2, addr_mask)) as u64,
482
0
                )
483
            }
484
0
            (Value::I8(v1), Value::I8(v2)) => Value::I8(v1.wrapping_div(v2)),
485
0
            (Value::U8(v1), Value::U8(v2)) => Value::U8(v1.wrapping_div(v2)),
486
0
            (Value::I16(v1), Value::I16(v2)) => Value::I16(v1.wrapping_div(v2)),
487
0
            (Value::U16(v1), Value::U16(v2)) => Value::U16(v1.wrapping_div(v2)),
488
0
            (Value::I32(v1), Value::I32(v2)) => Value::I32(v1.wrapping_div(v2)),
489
0
            (Value::U32(v1), Value::U32(v2)) => Value::U32(v1.wrapping_div(v2)),
490
0
            (Value::I64(v1), Value::I64(v2)) => Value::I64(v1.wrapping_div(v2)),
491
0
            (Value::U64(v1), Value::U64(v2)) => Value::U64(v1.wrapping_div(v2)),
492
0
            (Value::F32(v1), Value::F32(v2)) => Value::F32(v1 / v2),
493
0
            (Value::F64(v1), Value::F64(v2)) => Value::F64(v1 / v2),
494
0
            _ => return Err(Error::TypeMismatch),
495
        };
496
0
        Ok(value)
497
0
    }
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
0
    pub fn rem(self, rhs: Value, addr_mask: u64) -> Result<Value> {
506
0
        match rhs {
507
0
            Value::Generic(rhs) if (rhs & addr_mask) == 0 => {
508
0
                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
0
                return Err(Error::DivisionByZero);
519
            }
520
0
            _ => {}
521
        }
522
0
        let value = match (self, rhs) {
523
0
            (Value::Generic(v1), Value::Generic(v2)) => {
524
                // Unsigned modulus
525
0
                Value::Generic((v1 & addr_mask).wrapping_rem(v2 & addr_mask))
526
            }
527
0
            (Value::I8(v1), Value::I8(v2)) => Value::I8(v1.wrapping_rem(v2)),
528
0
            (Value::U8(v1), Value::U8(v2)) => Value::U8(v1.wrapping_rem(v2)),
529
0
            (Value::I16(v1), Value::I16(v2)) => Value::I16(v1.wrapping_rem(v2)),
530
0
            (Value::U16(v1), Value::U16(v2)) => Value::U16(v1.wrapping_rem(v2)),
531
0
            (Value::I32(v1), Value::I32(v2)) => Value::I32(v1.wrapping_rem(v2)),
532
0
            (Value::U32(v1), Value::U32(v2)) => Value::U32(v1.wrapping_rem(v2)),
533
0
            (Value::I64(v1), Value::I64(v2)) => Value::I64(v1.wrapping_rem(v2)),
534
0
            (Value::U64(v1), Value::U64(v2)) => Value::U64(v1.wrapping_rem(v2)),
535
0
            (Value::F32(_), Value::F32(_)) => return Err(Error::IntegralTypeRequired),
536
0
            (Value::F64(_), Value::F64(_)) => return Err(Error::IntegralTypeRequired),
537
0
            _ => return Err(Error::TypeMismatch),
538
        };
539
0
        Ok(value)
540
0
    }
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
0
    pub fn not(self, addr_mask: u64) -> Result<Value> {
548
0
        let value_type = self.value_type();
549
0
        let v = self.to_u64(addr_mask)?;
550
0
        Value::from_u64(value_type, !v)
551
0
    }
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
0
    pub fn and(self, rhs: Value, addr_mask: u64) -> Result<Value> {
559
0
        let value_type = self.value_type();
560
0
        if value_type != rhs.value_type() {
561
0
            return Err(Error::TypeMismatch);
562
0
        }
563
0
        let v1 = self.to_u64(addr_mask)?;
564
0
        let v2 = rhs.to_u64(addr_mask)?;
565
0
        Value::from_u64(value_type, v1 & v2)
566
0
    }
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
0
    pub fn or(self, rhs: Value, addr_mask: u64) -> Result<Value> {
574
0
        let value_type = self.value_type();
575
0
        if value_type != rhs.value_type() {
576
0
            return Err(Error::TypeMismatch);
577
0
        }
578
0
        let v1 = self.to_u64(addr_mask)?;
579
0
        let v2 = rhs.to_u64(addr_mask)?;
580
0
        Value::from_u64(value_type, v1 | v2)
581
0
    }
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
0
    pub fn xor(self, rhs: Value, addr_mask: u64) -> Result<Value> {
589
0
        let value_type = self.value_type();
590
0
        if value_type != rhs.value_type() {
591
0
            return Err(Error::TypeMismatch);
592
0
        }
593
0
        let v1 = self.to_u64(addr_mask)?;
594
0
        let v2 = rhs.to_u64(addr_mask)?;
595
0
        Value::from_u64(value_type, v1 ^ v2)
596
0
    }
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
0
    fn shift_length(self) -> Result<u64> {
602
0
        let value = match self {
603
0
            Value::Generic(value) => value,
604
0
            Value::I8(value) if value >= 0 => value as u64,
605
0
            Value::U8(value) => u64::from(value),
606
0
            Value::I16(value) if value >= 0 => value as u64,
607
0
            Value::U16(value) => u64::from(value),
608
0
            Value::I32(value) if value >= 0 => value as u64,
609
0
            Value::U32(value) => u64::from(value),
610
0
            Value::I64(value) if value >= 0 => value as u64,
611
0
            Value::U64(value) => value,
612
0
            _ => return Err(Error::InvalidShiftExpression),
613
        };
614
0
        Ok(value)
615
0
    }
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
0
    pub fn shl(self, rhs: Value, addr_mask: u64) -> Result<Value> {
625
0
        let v2 = rhs.shift_length()?;
626
0
        let value = match self {
627
0
            Value::Generic(v1) => Value::Generic(if v2 >= u64::from(mask_bit_size(addr_mask)) {
628
0
                0
629
            } else {
630
0
                (v1 & addr_mask) << v2
631
            }),
632
0
            Value::I8(v1) => Value::I8(if v2 >= 8 { 0 } else { v1 << v2 }),
633
0
            Value::U8(v1) => Value::U8(if v2 >= 8 { 0 } else { v1 << v2 }),
634
0
            Value::I16(v1) => Value::I16(if v2 >= 16 { 0 } else { v1 << v2 }),
635
0
            Value::U16(v1) => Value::U16(if v2 >= 16 { 0 } else { v1 << v2 }),
636
0
            Value::I32(v1) => Value::I32(if v2 >= 32 { 0 } else { v1 << v2 }),
637
0
            Value::U32(v1) => Value::U32(if v2 >= 32 { 0 } else { v1 << v2 }),
638
0
            Value::I64(v1) => Value::I64(if v2 >= 64 { 0 } else { v1 << v2 }),
639
0
            Value::U64(v1) => Value::U64(if v2 >= 64 { 0 } else { v1 << v2 }),
640
0
            _ => return Err(Error::IntegralTypeRequired),
641
        };
642
0
        Ok(value)
643
0
    }
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
0
    pub fn shr(self, rhs: Value, addr_mask: u64) -> Result<Value> {
656
0
        let v2 = rhs.shift_length()?;
657
0
        let value = match self {
658
0
            Value::Generic(v1) => Value::Generic(if v2 >= u64::from(mask_bit_size(addr_mask)) {
659
0
                0
660
            } else {
661
0
                (v1 & addr_mask) >> v2
662
            }),
663
0
            Value::U8(v1) => Value::U8(if v2 >= 8 { 0 } else { v1 >> v2 }),
664
0
            Value::U16(v1) => Value::U16(if v2 >= 16 { 0 } else { v1 >> v2 }),
665
0
            Value::U32(v1) => Value::U32(if v2 >= 32 { 0 } else { v1 >> v2 }),
666
0
            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
0
                return Err(Error::UnsupportedTypeOperation);
671
            }
672
0
            _ => return Err(Error::IntegralTypeRequired),
673
        };
674
0
        Ok(value)
675
0
    }
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
0
    pub fn shra(self, rhs: Value, addr_mask: u64) -> Result<Value> {
689
0
        let v2 = rhs.shift_length()?;
690
0
        let value = match self {
691
0
            Value::Generic(v1) => {
692
0
                let v1 = sign_extend(v1, addr_mask);
693
0
                let value = if v2 >= u64::from(mask_bit_size(addr_mask)) {
694
0
                    if v1 < 0 {
695
0
                        !0
696
                    } else {
697
0
                        0
698
                    }
699
                } else {
700
0
                    (v1 >> v2) as u64
701
                };
702
0
                Value::Generic(value)
703
            }
704
0
            Value::I8(v1) => Value::I8(if v2 >= 8 {
705
0
                if v1 < 0 {
706
0
                    !0
707
                } else {
708
0
                    0
709
                }
710
            } else {
711
0
                v1 >> v2
712
            }),
713
0
            Value::I16(v1) => Value::I16(if v2 >= 16 {
714
0
                if v1 < 0 {
715
0
                    !0
716
                } else {
717
0
                    0
718
                }
719
            } else {
720
0
                v1 >> v2
721
            }),
722
0
            Value::I32(v1) => Value::I32(if v2 >= 32 {
723
0
                if v1 < 0 {
724
0
                    !0
725
                } else {
726
0
                    0
727
                }
728
            } else {
729
0
                v1 >> v2
730
            }),
731
0
            Value::I64(v1) => Value::I64(if v2 >= 64 {
732
0
                if v1 < 0 {
733
0
                    !0
734
                } else {
735
0
                    0
736
                }
737
            } else {
738
0
                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
0
                return Err(Error::UnsupportedTypeOperation);
744
            }
745
0
            _ => return Err(Error::IntegralTypeRequired),
746
        };
747
0
        Ok(value)
748
0
    }
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
0
    pub fn eq(self, rhs: Value, addr_mask: u64) -> Result<Value> {
757
0
        let value = match (self, rhs) {
758
0
            (Value::Generic(v1), Value::Generic(v2)) => {
759
0
                sign_extend(v1, addr_mask) == sign_extend(v2, addr_mask)
760
            }
761
0
            (Value::I8(v1), Value::I8(v2)) => v1 == v2,
762
0
            (Value::U8(v1), Value::U8(v2)) => v1 == v2,
763
0
            (Value::I16(v1), Value::I16(v2)) => v1 == v2,
764
0
            (Value::U16(v1), Value::U16(v2)) => v1 == v2,
765
0
            (Value::I32(v1), Value::I32(v2)) => v1 == v2,
766
0
            (Value::U32(v1), Value::U32(v2)) => v1 == v2,
767
0
            (Value::I64(v1), Value::I64(v2)) => v1 == v2,
768
0
            (Value::U64(v1), Value::U64(v2)) => v1 == v2,
769
0
            (Value::F32(v1), Value::F32(v2)) => v1 == v2,
770
0
            (Value::F64(v1), Value::F64(v2)) => v1 == v2,
771
0
            _ => return Err(Error::TypeMismatch),
772
        };
773
0
        Ok(Value::Generic(value as u64))
774
0
    }
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
0
    pub fn ge(self, rhs: Value, addr_mask: u64) -> Result<Value> {
783
0
        let value = match (self, rhs) {
784
0
            (Value::Generic(v1), Value::Generic(v2)) => {
785
0
                sign_extend(v1, addr_mask) >= sign_extend(v2, addr_mask)
786
            }
787
0
            (Value::I8(v1), Value::I8(v2)) => v1 >= v2,
788
0
            (Value::U8(v1), Value::U8(v2)) => v1 >= v2,
789
0
            (Value::I16(v1), Value::I16(v2)) => v1 >= v2,
790
0
            (Value::U16(v1), Value::U16(v2)) => v1 >= v2,
791
0
            (Value::I32(v1), Value::I32(v2)) => v1 >= v2,
792
0
            (Value::U32(v1), Value::U32(v2)) => v1 >= v2,
793
0
            (Value::I64(v1), Value::I64(v2)) => v1 >= v2,
794
0
            (Value::U64(v1), Value::U64(v2)) => v1 >= v2,
795
0
            (Value::F32(v1), Value::F32(v2)) => v1 >= v2,
796
0
            (Value::F64(v1), Value::F64(v2)) => v1 >= v2,
797
0
            _ => return Err(Error::TypeMismatch),
798
        };
799
0
        Ok(Value::Generic(value as u64))
800
0
    }
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
0
    pub fn gt(self, rhs: Value, addr_mask: u64) -> Result<Value> {
809
0
        let value = match (self, rhs) {
810
0
            (Value::Generic(v1), Value::Generic(v2)) => {
811
0
                sign_extend(v1, addr_mask) > sign_extend(v2, addr_mask)
812
            }
813
0
            (Value::I8(v1), Value::I8(v2)) => v1 > v2,
814
0
            (Value::U8(v1), Value::U8(v2)) => v1 > v2,
815
0
            (Value::I16(v1), Value::I16(v2)) => v1 > v2,
816
0
            (Value::U16(v1), Value::U16(v2)) => v1 > v2,
817
0
            (Value::I32(v1), Value::I32(v2)) => v1 > v2,
818
0
            (Value::U32(v1), Value::U32(v2)) => v1 > v2,
819
0
            (Value::I64(v1), Value::I64(v2)) => v1 > v2,
820
0
            (Value::U64(v1), Value::U64(v2)) => v1 > v2,
821
0
            (Value::F32(v1), Value::F32(v2)) => v1 > v2,
822
0
            (Value::F64(v1), Value::F64(v2)) => v1 > v2,
823
0
            _ => return Err(Error::TypeMismatch),
824
        };
825
0
        Ok(Value::Generic(value as u64))
826
0
    }
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
0
    pub fn le(self, rhs: Value, addr_mask: u64) -> Result<Value> {
835
0
        let value = match (self, rhs) {
836
0
            (Value::Generic(v1), Value::Generic(v2)) => {
837
0
                sign_extend(v1, addr_mask) <= sign_extend(v2, addr_mask)
838
            }
839
0
            (Value::I8(v1), Value::I8(v2)) => v1 <= v2,
840
0
            (Value::U8(v1), Value::U8(v2)) => v1 <= v2,
841
0
            (Value::I16(v1), Value::I16(v2)) => v1 <= v2,
842
0
            (Value::U16(v1), Value::U16(v2)) => v1 <= v2,
843
0
            (Value::I32(v1), Value::I32(v2)) => v1 <= v2,
844
0
            (Value::U32(v1), Value::U32(v2)) => v1 <= v2,
845
0
            (Value::I64(v1), Value::I64(v2)) => v1 <= v2,
846
0
            (Value::U64(v1), Value::U64(v2)) => v1 <= v2,
847
0
            (Value::F32(v1), Value::F32(v2)) => v1 <= v2,
848
0
            (Value::F64(v1), Value::F64(v2)) => v1 <= v2,
849
0
            _ => return Err(Error::TypeMismatch),
850
        };
851
0
        Ok(Value::Generic(value as u64))
852
0
    }
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
0
    pub fn lt(self, rhs: Value, addr_mask: u64) -> Result<Value> {
861
0
        let value = match (self, rhs) {
862
0
            (Value::Generic(v1), Value::Generic(v2)) => {
863
0
                sign_extend(v1, addr_mask) < sign_extend(v2, addr_mask)
864
            }
865
0
            (Value::I8(v1), Value::I8(v2)) => v1 < v2,
866
0
            (Value::U8(v1), Value::U8(v2)) => v1 < v2,
867
0
            (Value::I16(v1), Value::I16(v2)) => v1 < v2,
868
0
            (Value::U16(v1), Value::U16(v2)) => v1 < v2,
869
0
            (Value::I32(v1), Value::I32(v2)) => v1 < v2,
870
0
            (Value::U32(v1), Value::U32(v2)) => v1 < v2,
871
0
            (Value::I64(v1), Value::I64(v2)) => v1 < v2,
872
0
            (Value::U64(v1), Value::U64(v2)) => v1 < v2,
873
0
            (Value::F32(v1), Value::F32(v2)) => v1 < v2,
874
0
            (Value::F64(v1), Value::F64(v2)) => v1 < v2,
875
0
            _ => return Err(Error::TypeMismatch),
876
        };
877
0
        Ok(Value::Generic(value as u64))
878
0
    }
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
0
    pub fn ne(self, rhs: Value, addr_mask: u64) -> Result<Value> {
887
0
        let value = match (self, rhs) {
888
0
            (Value::Generic(v1), Value::Generic(v2)) => {
889
0
                sign_extend(v1, addr_mask) != sign_extend(v2, addr_mask)
890
            }
891
0
            (Value::I8(v1), Value::I8(v2)) => v1 != v2,
892
0
            (Value::U8(v1), Value::U8(v2)) => v1 != v2,
893
0
            (Value::I16(v1), Value::I16(v2)) => v1 != v2,
894
0
            (Value::U16(v1), Value::U16(v2)) => v1 != v2,
895
0
            (Value::I32(v1), Value::I32(v2)) => v1 != v2,
896
0
            (Value::U32(v1), Value::U32(v2)) => v1 != v2,
897
0
            (Value::I64(v1), Value::I64(v2)) => v1 != v2,
898
0
            (Value::U64(v1), Value::U64(v2)) => v1 != v2,
899
0
            (Value::F32(v1), Value::F32(v2)) => v1 != v2,
900
0
            (Value::F64(v1), Value::F64(v2)) => v1 != v2,
901
0
            _ => return Err(Error::TypeMismatch),
902
        };
903
0
        Ok(Value::Generic(value as u64))
904
0
    }
905
}
906
907
#[cfg(test)]
908
mod 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
}