working on instruction models
[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) << 32;
128 let divisor = u64::from(inputs.divisor);
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 } else {
139 result = resultu64 as u32 as u64;
140 }
141 overflow = false;
142 }
143 TestDivResult {
144 result,
145 overflow: Some(OverflowFlags {
146 overflow,
147 overflow32: overflow,
148 }),
149 }
150 }
151
152 pub fn divwo(inputs: TestDivInput) -> TestDivResult {
153 let dividend = inputs.dividend as i32;
154 let divisor = inputs.divisor as i32;
155 let overflow;
156 let result;
157 if divisor == 0 || (divisor == -1 && dividend == i32::min_value()) {
158 result = 0;
159 overflow = true;
160 } else {
161 result = (dividend / divisor) as u32 as u64;
162 overflow = false;
163 }
164 TestDivResult {
165 result,
166 overflow: Some(OverflowFlags {
167 overflow,
168 overflow32: overflow,
169 }),
170 }
171 }
172
173 pub fn divwuo(inputs: TestDivInput) -> TestDivResult {
174 let dividend = inputs.dividend as u32;
175 let divisor = inputs.divisor as u32;
176 let overflow;
177 let result;
178 if divisor == 0 {
179 result = 0;
180 overflow = true;
181 } else {
182 result = (dividend / divisor) as u64;
183 overflow = false;
184 }
185 TestDivResult {
186 result,
187 overflow: Some(OverflowFlags {
188 overflow,
189 overflow32: overflow,
190 }),
191 }
192 }
193
194 pub fn modsd(inputs: TestDivInput) -> TestDivResult {
195 let dividend = inputs.dividend as i64;
196 let divisor = inputs.divisor as i64;
197 let result;
198 if divisor == 0 || (divisor == -1 && dividend == i64::min_value()) {
199 result = 0;
200 } else {
201 result = (dividend % divisor) as u64;
202 }
203 TestDivResult {
204 result,
205 overflow: None,
206 }
207 }
208
209 pub fn modud(inputs: TestDivInput) -> TestDivResult {
210 let dividend: u64 = inputs.dividend;
211 let divisor: u64 = inputs.divisor;
212 let result;
213 if divisor == 0 {
214 result = 0;
215 } else {
216 result = dividend % divisor;
217 }
218 TestDivResult {
219 result,
220 overflow: None,
221 }
222 }
223
224 pub fn modsw(inputs: TestDivInput) -> TestDivResult {
225 let dividend = inputs.dividend as i32;
226 let divisor = inputs.divisor as i32;
227 let result;
228 if divisor == 0 || (divisor == -1 && dividend == i32::min_value()) {
229 result = 0;
230 } else {
231 result = (dividend % divisor) as u32 as u64;
232 }
233 TestDivResult {
234 result,
235 overflow: None,
236 }
237 }
238
239 pub fn moduw(inputs: TestDivInput) -> TestDivResult {
240 let dividend = inputs.dividend as u32;
241 let divisor = inputs.divisor as u32;
242 let result;
243 if divisor == 0 {
244 result = 0;
245 } else {
246 result = (dividend % divisor) as u64;
247 }
248 TestDivResult {
249 result,
250 overflow: None,
251 }
252 }