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