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