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