working on instruction model
[power-instruction-analyzer.git] / src / instr_models.rs
1 use crate::{OverflowFlags, TestDivInput, TestDivResult};
2
3 pub fn divdeo(inputs: TestDivInput) -> TestDivResult {
4 let dividend = i128::from(inputs.dividend as i64) << 64;
5 let divisor = i128::from(inputs.divisor as i64);
6 let overflow;
7 let result;
8 if divisor == 0 || (divisor == -1 && dividend == i128::min_value()) {
9 result = 0;
10 overflow = true;
11 } else {
12 let result128 = dividend / divisor;
13 if result128 as i64 as i128 != result128 {
14 result = 0;
15 overflow = true;
16 } else {
17 result = result128 as u64;
18 overflow = false;
19 }
20 }
21 TestDivResult {
22 result,
23 overflow: Some(OverflowFlags {
24 overflow,
25 overflow32: overflow,
26 }),
27 }
28 }
29
30 pub fn divdeuo(inputs: TestDivInput) -> TestDivResult {
31 let dividend = u128::from(inputs.dividend) << 64;
32 let divisor = u128::from(inputs.divisor);
33 let overflow;
34 let result;
35 if divisor == 0 {
36 result = 0;
37 overflow = true;
38 } else {
39 let resultu128 = dividend / divisor;
40 if resultu128 > u128::from(u64::max_value()) {
41 result = 0;
42 overflow = true;
43 } else {
44 result = resultu128 as u64;
45 overflow = false;
46 }
47 }
48 TestDivResult {
49 result,
50 overflow: Some(OverflowFlags {
51 overflow,
52 overflow32: overflow,
53 }),
54 }
55 }
56
57 pub fn divdo(inputs: TestDivInput) -> TestDivResult {
58 let dividend = inputs.dividend as i64;
59 let divisor = inputs.divisor as i64;
60 let overflow;
61 let result;
62 if divisor == 0 || (divisor == -1 && dividend == i64::min_value()) {
63 result = 0;
64 overflow = true;
65 } else {
66 result = (dividend / divisor) as u64;
67 overflow = false;
68 }
69 TestDivResult {
70 result,
71 overflow: Some(OverflowFlags {
72 overflow,
73 overflow32: overflow,
74 }),
75 }
76 }
77
78 pub fn divduo(inputs: TestDivInput) -> TestDivResult {
79 let dividend: u64 = inputs.dividend;
80 let divisor: u64 = inputs.divisor;
81 let overflow;
82 let result;
83 if divisor == 0 {
84 result = 0;
85 overflow = true;
86 } else {
87 result = dividend / divisor;
88 overflow = false;
89 }
90 TestDivResult {
91 result,
92 overflow: Some(OverflowFlags {
93 overflow,
94 overflow32: overflow,
95 }),
96 }
97 }
98
99 pub fn divweo(inputs: TestDivInput) -> TestDivResult {
100 let dividend = i64::from(inputs.dividend as i32) << 32;
101 let divisor = i64::from(inputs.divisor as i32);
102 let overflow;
103 let result;
104 if divisor == 0 || (divisor == -1 && dividend == i64::min_value()) {
105 result = 0;
106 overflow = true;
107 } else {
108 let result64 = dividend / divisor;
109 if result64 as i32 as i64 != result64 {
110 result = 0;
111 overflow = true;
112 } else {
113 result = result64 as u32 as u64;
114 overflow = false;
115 }
116 }
117 TestDivResult {
118 result,
119 overflow: Some(OverflowFlags {
120 overflow,
121 overflow32: overflow,
122 }),
123 }
124 }
125
126 pub fn divweuo(inputs: TestDivInput) -> TestDivResult {
127 let dividend = u64::from(inputs.dividend as u32) << 32;
128 let divisor = u64::from(inputs.divisor as u32);
129 let overflow;
130 let result;
131 if divisor == 0 {
132 result = 0;
133 overflow = true;
134 } else {
135 let resultu64 = dividend / divisor;
136 if resultu64 > u64::from(u32::max_value()) {
137 result = 0;
138 overflow = true;
139 } else {
140 result = resultu64 as u32 as u64;
141 overflow = false;
142 }
143 }
144 TestDivResult {
145 result,
146 overflow: Some(OverflowFlags {
147 overflow,
148 overflow32: overflow,
149 }),
150 }
151 }
152
153 pub fn divwo(inputs: TestDivInput) -> TestDivResult {
154 let dividend = inputs.dividend as i32;
155 let divisor = inputs.divisor as i32;
156 let overflow;
157 let result;
158 if divisor == 0 || (divisor == -1 && dividend == i32::min_value()) {
159 result = 0;
160 overflow = true;
161 } else {
162 result = (dividend / divisor) as u32 as u64;
163 overflow = false;
164 }
165 TestDivResult {
166 result,
167 overflow: Some(OverflowFlags {
168 overflow,
169 overflow32: overflow,
170 }),
171 }
172 }
173
174 pub fn divwuo(inputs: TestDivInput) -> TestDivResult {
175 let dividend = inputs.dividend as u32;
176 let divisor = inputs.divisor as u32;
177 let overflow;
178 let result;
179 if divisor == 0 {
180 result = 0;
181 overflow = true;
182 } else {
183 result = (dividend / divisor) as u64;
184 overflow = false;
185 }
186 TestDivResult {
187 result,
188 overflow: Some(OverflowFlags {
189 overflow,
190 overflow32: overflow,
191 }),
192 }
193 }
194
195 pub fn modsd(inputs: TestDivInput) -> TestDivResult {
196 let dividend = inputs.dividend as i64;
197 let divisor = inputs.divisor as i64;
198 let result;
199 if divisor == 0 || (divisor == -1 && dividend == i64::min_value()) {
200 result = 0;
201 } else {
202 result = (dividend % divisor) as u64;
203 }
204 TestDivResult {
205 result,
206 overflow: None,
207 }
208 }
209
210 pub fn modud(inputs: TestDivInput) -> TestDivResult {
211 let dividend: u64 = inputs.dividend;
212 let divisor: u64 = inputs.divisor;
213 let result;
214 if divisor == 0 {
215 result = 0;
216 } else {
217 result = dividend % divisor;
218 }
219 TestDivResult {
220 result,
221 overflow: None,
222 }
223 }
224
225 pub fn modsw(inputs: TestDivInput) -> TestDivResult {
226 let dividend = inputs.dividend as i32;
227 let divisor = inputs.divisor as i32;
228 let result;
229 if divisor == 0 || (divisor == -1 && dividend == i32::min_value()) {
230 result = 0;
231 } else {
232 result = (dividend % divisor) as u64;
233 }
234 TestDivResult {
235 result,
236 overflow: None,
237 }
238 }
239
240 pub fn moduw(inputs: TestDivInput) -> TestDivResult {
241 let dividend = inputs.dividend as u32;
242 let divisor = inputs.divisor as u32;
243 let result;
244 if divisor == 0 {
245 result = 0;
246 } else {
247 result = (dividend % divisor) as u64;
248 }
249 TestDivResult {
250 result,
251 overflow: None,
252 }
253 }