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