1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use apint::{APInt, APIntData};
use bitwidth::{BitWidth};
use storage::{Storage};
use digit::{Digit};
use digit;
impl Drop for APInt {
fn drop(&mut self) {
use std::mem;
if self.len.storage() == Storage::Ext {
let len = self.len_blocks();
unsafe{
mem::drop(Vec::from_raw_parts(self.data.ext, len, len))
}
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
enum RawData {
Inl(Digit),
Ext(Vec<Digit>)
}
impl APInt {
#[inline]
pub fn from_i8(val: i8) -> APInt {
APInt{len: BitWidth::w8(), data: APIntData{inl: Digit(val as u64)}}
}
#[inline]
pub fn from_u8(val: u8) -> APInt {
APInt{len: BitWidth::w8(), data: APIntData{inl: Digit(val as u64)}}
}
#[inline]
pub fn from_i16(val: i16) -> APInt {
APInt{len: BitWidth::w16(), data: APIntData{inl: Digit(val as u64)}}
}
#[inline]
pub fn from_u16(val: u16) -> APInt {
APInt{len: BitWidth::w16(), data: APIntData{inl: Digit(val as u64)}}
}
#[inline]
pub fn from_i32(val: i32) -> APInt {
APInt{len: BitWidth::w32(), data: APIntData{inl: Digit(val as u64)}}
}
#[inline]
pub fn from_u32(val: u32) -> APInt {
APInt{len: BitWidth::w32(), data: APIntData{inl: Digit(val as u64)}}
}
#[inline]
pub fn from_i64(val: i64) -> APInt {
APInt{len: BitWidth::w64(), data: APIntData{inl: Digit(val as u64)}}
}
#[inline]
pub fn from_u64(val: u64) -> APInt {
APInt{len: BitWidth::w64(), data: APIntData{inl: Digit(val)}}
}
fn repeat_digit<D>(bitwidth: BitWidth, digit: D) -> APInt
where D: Into<Digit>
{
let digit = digit.into();
match bitwidth.storage() {
Storage::Inl => {
APInt{len: bitwidth, data: APIntData{inl: digit.truncated(bitwidth).unwrap()}}
}
Storage::Ext => {
use std::mem;
let req_blocks = bitwidth.required_blocks();
let mut buffer = vec![digit; req_blocks];
let last_width = bitwidth.to_usize() % digit::BITS;
buffer.last_mut().unwrap().truncate(last_width).unwrap();
assert_eq!(buffer.capacity(), req_blocks);
let ptr_buffer = buffer.as_ptr() as *mut Digit;
mem::forget(buffer);
APInt{len: bitwidth, data: APIntData{ext: ptr_buffer}}
}
}
}
pub fn zero(width: BitWidth) -> APInt {
APInt::repeat_digit(width, digit::ZERO)
}
pub fn one(width: BitWidth) -> APInt {
APInt::from_u64(1).zero_extend(width).unwrap()
}
pub fn zeros(width: BitWidth) -> APInt {
APInt::zero(width)
}
pub fn ones(width: BitWidth) -> APInt
{
APInt::repeat_digit(width, Digit::ones())
}
}