1#![allow(clippy::comparison_chain)]
42#![allow(clippy::cognitive_complexity)]
43
44use std::collections::HashMap;
45use std::convert::{TryFrom, TryInto};
46use std::ops::{BitAnd, BitOr, Not, Shl, Shr};
47use std::str::FromStr;
48
49use crate::bitvector::b64::B64;
50use crate::bitvector::BV;
51use crate::error::ExecError;
52use crate::executor::LocalFrame;
53use crate::ir::{UVal, Val, ELF_ENTRY};
54use crate::smt::smtlib::*;
55use crate::smt::*;
56
57pub type Unary<B> = fn(Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError>;
58pub type Binary<B> = fn(Val<B>, Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError>;
59pub type Variadic<B> = fn(Vec<Val<B>>, solver: &mut Solver<B>, frame: &mut LocalFrame<B>) -> Result<Val<B>, ExecError>;
60
61#[allow(clippy::needless_range_loop)]
62pub fn smt_i128(i: i128) -> Exp {
63 let mut bitvec = [false; 128];
64 for n in 0..128 {
65 if (i >> n & 1) == 1 {
66 bitvec[n] = true
67 }
68 }
69 Exp::Bits(bitvec.to_vec())
70}
71
72pub fn smt_i64(i: i64) -> Exp {
73 Exp::Bits64(B64::new(i as u64, 64))
74}
75
76pub fn smt_u8(i: u8) -> Exp {
77 Exp::Bits64(B64::new(i as u64, 8))
78}
79
80#[allow(clippy::needless_range_loop)]
81fn smt_mask_lower(len: usize, mask_width: usize) -> Exp {
82 if len <= 64 {
83 Exp::Bits64(B64::new(u64::MAX >> (64 - mask_width), len as u32))
84 } else {
85 let mut bitvec = vec![false; len];
86 for i in 0..mask_width {
87 bitvec[i] = true
88 }
89 Exp::Bits(bitvec)
90 }
91}
92
93fn smt_zeros(i: i128) -> Exp {
94 if i <= 64 {
95 Exp::Bits64(B64::zeros(i as u32))
96 } else {
97 Exp::Bits(vec![false; i as usize])
98 }
99}
100
101fn smt_ones(i: i128) -> Exp {
102 if i <= 64 {
103 Exp::Bits64(B64::ones(i as u32))
104 } else {
105 Exp::Bits(vec![true; i as usize])
106 }
107}
108
109pub fn smt_sbits<B: BV>(bv: B) -> Exp {
110 if let Ok(u) = bv.try_into() {
111 bits64(u, bv.len())
112 } else {
113 let mut bitvec = Vec::with_capacity(bv.len().try_into().unwrap());
114 for n in 0..bv.len() {
115 bitvec.push((bv.shiftr(n as i128).lower_u64() & 1) == 1)
116 }
117 Exp::Bits(bitvec)
118 }
119}
120
121macro_rules! unary_primop_copy {
122 ($f:ident, $name:expr, $unwrap:path, $wrap:path, $concrete_op:path, $smt_op:path) => {
123 pub(crate) fn $f<B: BV>(x: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
124 match x {
125 Val::Symbolic(x) => solver.define_const($smt_op(Box::new(Exp::Var(x)))).into(),
126 $unwrap(x) => Ok($wrap($concrete_op(x))),
127 _ => Err(ExecError::Type($name)),
128 }
129 }
130 };
131}
132
133macro_rules! binary_primop_copy {
134 ($f:ident, $name:expr, $unwrap:path, $wrap:path, $concrete_op:path, $smt_op:path, $to_symbolic:path) => {
135 pub(crate) fn $f<B: BV>(x: Val<B>, y: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
136 match (x, y) {
137 (Val::Symbolic(x), Val::Symbolic(y)) => {
138 solver.define_const($smt_op(Box::new(Exp::Var(x)), Box::new(Exp::Var(y)))).into()
139 }
140 (Val::Symbolic(x), $unwrap(y)) => {
141 solver.define_const($smt_op(Box::new(Exp::Var(x)), Box::new($to_symbolic(y)))).into()
142 }
143 ($unwrap(x), Val::Symbolic(y)) => {
144 solver.define_const($smt_op(Box::new($to_symbolic(x)), Box::new(Exp::Var(y)))).into()
145 }
146 ($unwrap(x), $unwrap(y)) => Ok($wrap($concrete_op(x, y))),
147 (_, _) => Err(ExecError::Type($name)),
148 }
149 }
150 };
151}
152
153macro_rules! binary_primop {
154 ($f:ident, $name:expr, $unwrap:path, $wrap:path, $concrete_op:path, $smt_op:path, $to_symbolic:path) => {
155 pub(crate) fn $f<B: BV>(x: Val<B>, y: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
156 match (x, y) {
157 (Val::Symbolic(x), Val::Symbolic(y)) => {
158 solver.define_const($smt_op(Box::new(Exp::Var(x)), Box::new(Exp::Var(y)))).into()
159 }
160 (Val::Symbolic(x), $unwrap(y)) => {
161 solver.define_const($smt_op(Box::new(Exp::Var(x)), Box::new($to_symbolic(y)))).into()
162 }
163 ($unwrap(x), Val::Symbolic(y)) => {
164 solver.define_const($smt_op(Box::new($to_symbolic(x)), Box::new(Exp::Var(y)))).into()
165 }
166 ($unwrap(x), $unwrap(y)) => Ok($wrap($concrete_op(&x, &y))),
167 (_, _) => Err(ExecError::Type($name)),
168 }
169 }
170 };
171}
172
173fn assume<B: BV>(x: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
174 match x {
175 Val::Symbolic(v) => {
176 solver.add(Def::Assert(Exp::Var(v)));
177 Ok(Val::Unit)
178 }
179 Val::Bool(b) => {
180 if b {
181 Ok(Val::Unit)
182 } else {
183 solver.add(Def::Assert(Exp::Bool(false)));
184 Ok(Val::Unit)
185 }
186 }
187 _ => Err(ExecError::Type(format!("assert {:?}", &x))),
188 }
189}
190
191fn optimistic_assert<B: BV>(x: Val<B>, message: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
193 let message = match message {
194 Val::String(message) => message,
195 _ => return Err(ExecError::Type(format!("optimistic_assert {:?}", &message))),
196 };
197 match x {
198 Val::Symbolic(v) => {
199 let test_true = Box::new(Exp::Var(v));
200 let can_be_true = solver.check_sat_with(&test_true).is_sat()?;
201 if can_be_true {
202 solver.add(Def::Assert(Exp::Var(v)));
203 Ok(Val::Unit)
204 } else {
205 Err(ExecError::AssertionFailed(message))
206 }
207 }
208 Val::Bool(b) => {
209 if b {
210 Ok(Val::Unit)
211 } else {
212 Err(ExecError::AssertionFailed(message))
213 }
214 }
215 _ => Err(ExecError::Type(format!("optimistic_assert {:?}", &x))),
216 }
217}
218
219fn pessimistic_assert<B: BV>(x: Val<B>, message: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
221 let message = match message {
222 Val::String(message) => message,
223 _ => return Err(ExecError::Type(format!("pessimistic_assert {:?}", &message))),
224 };
225 match x {
226 Val::Symbolic(v) => {
227 let test_false = Exp::Not(Box::new(Exp::Var(v)));
228 let can_be_false = solver.check_sat_with(&test_false).is_sat()?;
229 if can_be_false {
230 Err(ExecError::AssertionFailed(message))
231 } else {
232 Ok(Val::Unit)
233 }
234 }
235 Val::Bool(b) => {
236 if b {
237 Ok(Val::Unit)
238 } else {
239 Err(ExecError::AssertionFailed(message))
240 }
241 }
242 _ => Err(ExecError::Type(format!("pessimistic_assert {:?}", &x))),
243 }
244}
245
246fn i64_to_i128<B: BV>(x: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
249 match x {
250 Val::I64(x) => Ok(Val::I128(i128::from(x))),
251 Val::Symbolic(x) => solver.define_const(Exp::SignExtend(64, Box::new(Exp::Var(x)))).into(),
252 _ => Err(ExecError::Type(format!("%i64->%i {:?}", &x))),
253 }
254}
255
256fn i128_to_i64<B: BV>(x: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
257 match x {
258 Val::I128(x) => match i64::try_from(x) {
259 Ok(y) => Ok(Val::I64(y)),
260 Err(_) => Err(ExecError::Overflow),
261 },
262 Val::Symbolic(x) => solver.define_const(Exp::Extract(63, 0, Box::new(Exp::Var(x)))).into(),
263 _ => Err(ExecError::Type(format!("%i->%i64 {:?}", &x))),
264 }
265}
266
267pub(crate) fn op_eq<B: BV>(x: Val<B>, y: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
271 match (x, y) {
272 (Val::List(xs), Val::List(ys)) => {
273 if xs.len() != ys.len() {
274 Ok(Val::Bool(false))
275 } else if xs.is_empty() && ys.is_empty() {
276 Ok(Val::Bool(true))
277 } else {
278 Err(ExecError::Type(format!("op_eq {:?} {:?}", &xs, &ys)))
279 }
280 }
281 (x, y) => eq_anything(x, y, solver),
282 }
283}
284
285pub(crate) fn op_neq<B: BV>(x: Val<B>, y: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
286 match (x, y) {
287 (Val::List(xs), Val::List(ys)) => {
288 if xs.len() != ys.len() {
289 Ok(Val::Bool(true))
290 } else if xs.is_empty() && ys.is_empty() {
291 Ok(Val::Bool(false))
292 } else {
293 Err(ExecError::Type(format!("op_neq {:?} {:?}", &xs, &ys)))
294 }
295 }
296 (x, y) => neq_anything(x, y, solver),
297 }
298}
299
300pub(crate) fn op_head<B: BV>(xs: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
301 match xs {
302 Val::List(mut xs) => match xs.pop() {
303 Some(x) => Ok(x),
304 None => Err(ExecError::Type(format!("op_head (list empty) {:?}", &xs))),
305 },
306 _ => Err(ExecError::Type(format!("op_head {:?}", &xs))),
307 }
308}
309
310pub(crate) fn op_tail<B: BV>(xs: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
311 match xs {
312 Val::List(mut xs) => {
313 xs.pop();
314 Ok(Val::List(xs))
315 }
316 _ => Err(ExecError::Type(format!("op_tail {:?}", &xs))),
317 }
318}
319
320binary_primop!(op_lt, "op_lt".to_string(), Val::I64, Val::Bool, i64::lt, Exp::Bvslt, smt_i64);
321binary_primop!(op_gt, "op_gt".to_string(), Val::I64, Val::Bool, i64::gt, Exp::Bvsgt, smt_i64);
322binary_primop!(op_lteq, "op_lteq".to_string(), Val::I64, Val::Bool, i64::le, Exp::Bvsle, smt_i64);
323binary_primop!(op_gteq, "op_gteq".to_string(), Val::I64, Val::Bool, i64::ge, Exp::Bvsge, smt_i64);
324binary_primop_copy!(op_add, "op_add".to_string(), Val::I64, Val::I64, i64::wrapping_add, Exp::Bvadd, smt_i64);
325binary_primop_copy!(op_sub, "op_sub".to_string(), Val::I64, Val::I64, i64::wrapping_sub, Exp::Bvsub, smt_i64);
326
327pub(crate) fn bit_to_bool<B: BV>(bit: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
328 match bit {
329 Val::Bits(bit) => Ok(Val::Bool(bit == B::BIT_ONE)),
330 Val::Symbolic(bit) => {
331 solver.define_const(Exp::Eq(Box::new(Exp::Bits([true].to_vec())), Box::new(Exp::Var(bit)))).into()
332 }
333 _ => Err(ExecError::Type(format!("bit_to_bool {:?}", &bit))),
334 }
335}
336
337pub(crate) fn op_unsigned<B: BV>(bits: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
338 match bits {
339 Val::Bits(bits) => Ok(Val::I64(bits.unsigned() as i64)),
340 Val::Symbolic(bits) => match solver.length(bits) {
341 Some(length) => solver.define_const(Exp::ZeroExtend(64 - length, Box::new(Exp::Var(bits)))).into(),
342 None => Err(ExecError::Type(format!("op_unsigned {:?}", &bits))),
343 },
344 _ => Err(ExecError::Type(format!("op_unsigned {:?}", &bits))),
345 }
346}
347
348pub(crate) fn op_signed<B: BV>(bits: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
349 match bits {
350 Val::Bits(bits) => Ok(Val::I64(bits.signed() as i64)),
351 Val::Symbolic(bits) => match solver.length(bits) {
352 Some(length) => solver.define_const(Exp::SignExtend(64 - length, Box::new(Exp::Var(bits)))).into(),
353 None => Err(ExecError::Type(format!("op_unsigned (solver cannot determine length) {:?}", &bits))),
354 },
355 _ => Err(ExecError::Type(format!("op_unsigned {:?}", &bits))),
356 }
357}
358
359unary_primop_copy!(not_bool, "not".to_string(), Val::Bool, Val::Bool, bool::not, Exp::Not);
362binary_primop_copy!(and_bool, "and_bool".to_string(), Val::Bool, Val::Bool, bool::bitand, Exp::And, Exp::Bool);
363binary_primop_copy!(or_bool, "or_bool".to_string(), Val::Bool, Val::Bool, bool::bitor, Exp::Or, Exp::Bool);
364binary_primop!(eq_int, "eq_int".to_string(), Val::I128, Val::Bool, i128::eq, Exp::Eq, smt_i128);
365binary_primop!(eq_bool, "eq_bool".to_string(), Val::Bool, Val::Bool, bool::eq, Exp::Eq, Exp::Bool);
366binary_primop!(lteq_int, "lteq".to_string(), Val::I128, Val::Bool, i128::le, Exp::Bvsle, smt_i128);
367binary_primop!(gteq_int, "gteq".to_string(), Val::I128, Val::Bool, i128::ge, Exp::Bvsge, smt_i128);
368binary_primop!(lt_int, "lt".to_string(), Val::I128, Val::Bool, i128::lt, Exp::Bvslt, smt_i128);
369binary_primop!(gt_int, "gt".to_string(), Val::I128, Val::Bool, i128::gt, Exp::Bvsgt, smt_i128);
370
371fn abs_int<B: BV>(x: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
372 match x {
373 Val::I128(x) => Ok(Val::I128(x.abs())),
374 Val::Symbolic(x) => {
375 let y = solver.fresh();
376 solver.add(Def::DefineConst(
377 y,
378 Exp::Ite(
379 Box::new(Exp::Bvslt(Box::new(Exp::Var(x)), Box::new(smt_i128(0)))),
380 Box::new(Exp::Bvneg(Box::new(Exp::Var(x)))),
381 Box::new(Exp::Var(x)),
382 ),
383 ));
384 Ok(Val::Symbolic(y))
385 }
386 _ => Err(ExecError::Type(format!("abs_int {:?}", &x))),
387 }
388}
389
390binary_primop_copy!(sub_int, "sub_int".to_string(), Val::I128, Val::I128, i128::wrapping_sub, Exp::Bvsub, smt_i128);
393binary_primop_copy!(mult_int, "mult_int".to_string(), Val::I128, Val::I128, i128::wrapping_mul, Exp::Bvmul, smt_i128);
394unary_primop_copy!(neg_int, "neg_int".to_string(), Val::I128, Val::I128, i128::wrapping_neg, Exp::Bvneg);
395binary_primop_copy!(tdiv_int, "tdiv_int".to_string(), Val::I128, Val::I128, i128::wrapping_div, Exp::Bvsdiv, smt_i128);
396binary_primop_copy!(tmod_int, "tmod_int".to_string(), Val::I128, Val::I128, i128::wrapping_rem, Exp::Bvsmod, smt_i128);
397binary_primop_copy!(shl_int, "shl_int".to_string(), Val::I128, Val::I128, i128::shl, Exp::Bvshl, smt_i128);
398binary_primop_copy!(shr_int, "shr_int".to_string(), Val::I128, Val::I128, i128::shr, Exp::Bvashr, smt_i128);
399binary_primop_copy!(shl_mach_int, "shl_mach_int".to_string(), Val::I64, Val::I64, i64::shl, Exp::Bvshl, smt_i64);
400binary_primop_copy!(shr_mach_int, "shr_mach_int".to_string(), Val::I64, Val::I64, i64::shr, Exp::Bvashr, smt_i64);
401binary_primop_copy!(udiv_int, "udiv_int".to_string(), Val::I128, Val::I128, i128::wrapping_div, Exp::Bvudiv, smt_i128);
402
403pub(crate) fn add_int<B: BV>(x: Val<B>, y: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
404 match (x, y) {
405 (Val::Symbolic(x), Val::Symbolic(y)) => {
406 solver.define_const(Exp::Bvadd(Box::new(Exp::Var(x)), Box::new(Exp::Var(y)))).into()
407 }
408 (Val::Symbolic(x), Val::I128(y)) => {
409 if y != 0 {
410 solver.define_const(Exp::Bvadd(Box::new(Exp::Var(x)), Box::new(smt_i128(y)))).into()
411 } else {
412 Ok(Val::Symbolic(x))
413 }
414 }
415 (Val::I128(x), Val::Symbolic(y)) => {
416 if x != 0 {
417 solver.define_const(Exp::Bvadd(Box::new(smt_i128(x)), Box::new(Exp::Var(y)))).into()
418 } else {
419 Ok(Val::Symbolic(y))
420 }
421 }
422 (Val::I128(x), Val::I128(y)) => Ok(Val::I128(i128::wrapping_add(x, y))),
423 (x, y) => Err(ExecError::Type(format!("add_int {:?} {:?}", &x, &y))),
424 }
425}
426
427macro_rules! symbolic_compare {
428 ($op: path, $x: expr, $y: expr, $solver: ident) => {{
429 let z = $solver.fresh();
430 $solver
431 .add(Def::DefineConst(z, Exp::Ite(Box::new($op(Box::new($x), Box::new($y))), Box::new($x), Box::new($y))));
432 Ok(Val::Symbolic(z))
433 }};
434}
435
436fn max_int<B: BV>(x: Val<B>, y: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
437 match (x, y) {
438 (Val::I128(x), Val::I128(y)) => Ok(Val::I128(i128::max(x, y))),
439 (Val::I128(x), Val::Symbolic(y)) => symbolic_compare!(Exp::Bvsgt, smt_i128(x), Exp::Var(y), solver),
440 (Val::Symbolic(x), Val::I128(y)) => symbolic_compare!(Exp::Bvsgt, Exp::Var(x), smt_i128(y), solver),
441 (Val::Symbolic(x), Val::Symbolic(y)) => symbolic_compare!(Exp::Bvsgt, Exp::Var(x), Exp::Var(y), solver),
442 (x, y) => Err(ExecError::Type(format!("max_int {:?} {:?}", &x, &y))),
443 }
444}
445
446fn min_int<B: BV>(x: Val<B>, y: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
447 match (x, y) {
448 (Val::I128(x), Val::I128(y)) => Ok(Val::I128(i128::min(x, y))),
449 (Val::I128(x), Val::Symbolic(y)) => symbolic_compare!(Exp::Bvslt, smt_i128(x), Exp::Var(y), solver),
450 (Val::Symbolic(x), Val::I128(y)) => symbolic_compare!(Exp::Bvslt, Exp::Var(x), smt_i128(y), solver),
451 (Val::Symbolic(x), Val::Symbolic(y)) => symbolic_compare!(Exp::Bvslt, Exp::Var(x), Exp::Var(y), solver),
452 (x, y) => Err(ExecError::Type(format!("max_int {:?} {:?}", &x, &y))),
453 }
454}
455
456fn pow2<B: BV>(x: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
457 match x {
458 Val::I128(x) => Ok(Val::I128(1 << x)),
459 Val::Symbolic(x) => solver.define_const(Exp::Bvshl(Box::new(smt_i128(1)), Box::new(Exp::Var(x)))).into(),
460 _ => Err(ExecError::Type(format!("pow2 {:?}", &x))),
461 }
462}
463
464fn pow_int<B: BV>(x: Val<B>, y: Val<B>, _solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
465 match (x, y) {
466 (Val::I128(x), Val::I128(y)) => Ok(Val::I128(x.pow(y.try_into().map_err(|_| ExecError::Overflow)?))),
467 (x, y) => Err(ExecError::Type(format!("pow_int {:?} {:?}", &x, &y))),
468 }
469}
470
471fn sub_nat<B: BV>(x: Val<B>, y: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
472 match (x, y) {
473 (Val::I128(x), Val::I128(y)) => Ok(Val::I128(i128::max(x - y, 0))),
474 (Val::I128(x), Val::Symbolic(y)) => {
475 symbolic_compare!(Exp::Bvsgt, Exp::Bvsub(Box::new(smt_i128(x)), Box::new(Exp::Var(y))), smt_i128(0), solver)
476 }
477 (Val::Symbolic(x), Val::I128(y)) => {
478 symbolic_compare!(Exp::Bvsgt, Exp::Bvsub(Box::new(Exp::Var(x)), Box::new(smt_i128(y))), smt_i128(0), solver)
479 }
480 (Val::Symbolic(x), Val::Symbolic(y)) => {
481 symbolic_compare!(Exp::Bvsgt, Exp::Bvsub(Box::new(Exp::Var(x)), Box::new(Exp::Var(y))), smt_i128(0), solver)
482 }
483 (x, y) => Err(ExecError::Type(format!("sub_nat {:?} {:?}", &x, &y))),
484 }
485}
486
487fn length<B: BV>(x: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
490 match x {
491 Val::Symbolic(v) => match solver.length(v) {
492 Some(len) => Ok(Val::I128(i128::from(len))),
493 None => Err(ExecError::Type(format!("length (solver cannot determine length) {:?}", &v))),
494 },
495 Val::Bits(bv) => Ok(Val::I128(bv.len_i128())),
496 _ => Err(ExecError::Type(format!("length {:?}", &x))),
497 }
498}
499
500binary_primop!(eq_bits, "eq_bits".to_string(), Val::Bits, Val::Bool, B::eq, Exp::Eq, smt_sbits);
501binary_primop!(neq_bits, "neq_bits".to_string(), Val::Bits, Val::Bool, B::ne, Exp::Neq, smt_sbits);
502unary_primop_copy!(not_bits, "not_bits".to_string(), Val::Bits, Val::Bits, B::not, Exp::Bvnot);
503binary_primop_copy!(xor_bits, "xor_bits".to_string(), Val::Bits, Val::Bits, B::bitxor, Exp::Bvxor, smt_sbits);
504binary_primop_copy!(or_bits, "or_bits".to_string(), Val::Bits, Val::Bits, B::bitor, Exp::Bvor, smt_sbits);
505binary_primop_copy!(and_bits, "and_bits".to_string(), Val::Bits, Val::Bits, B::bitand, Exp::Bvand, smt_sbits);
506binary_primop_copy!(add_bits, "add_bits".to_string(), Val::Bits, Val::Bits, B::add, Exp::Bvadd, smt_sbits);
507binary_primop_copy!(sub_bits, "sub_bits".to_string(), Val::Bits, Val::Bits, B::sub, Exp::Bvsub, smt_sbits);
508
509fn add_bits_int<B: BV>(bits: Val<B>, n: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
510 match (bits, n) {
511 (Val::Bits(bits), Val::I128(n)) => Ok(Val::Bits(bits.add_i128(n))),
512 (Val::Symbolic(bits), Val::I128(n)) => {
513 let result = solver.fresh();
514 let len = match solver.length(bits) {
515 Some(len) => len,
516 None => {
517 return Err(ExecError::Type(format!(
518 "add_bits_int (solver cannot determine length) {:?} {:?}",
519 &bits, &n
520 )))
521 }
522 };
523 assert!(len <= 128);
524 solver.add(Def::DefineConst(
525 result,
526 Exp::Bvadd(Box::new(Exp::Var(bits)), Box::new(Exp::Extract(len - 1, 0, Box::new(smt_i128(n))))),
527 ));
528 Ok(Val::Symbolic(result))
529 }
530 (Val::Symbolic(bits), Val::Symbolic(n)) => {
531 let result = solver.fresh();
532 let len = match solver.length(bits) {
533 Some(len) => len,
534 None => {
535 return Err(ExecError::Type(format!(
536 "add_bits_int (solver cannot determine length) {:?} {:?}",
537 &bits, &n
538 )))
539 }
540 };
541 assert!(len <= 128);
542 solver.add(Def::DefineConst(
543 result,
544 Exp::Bvadd(Box::new(Exp::Var(bits)), Box::new(Exp::Extract(len - 1, 0, Box::new(Exp::Var(n))))),
545 ));
546 Ok(Val::Symbolic(result))
547 }
548 (bits, n) => Err(ExecError::Type(format!("add_bits_int {:?} {:?}", &bits, &n))),
549 }
550}
551
552fn sub_bits_int<B: BV>(bits: Val<B>, n: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
553 match (bits, n) {
554 (Val::Bits(bits), Val::I128(n)) => Ok(Val::Bits(bits.sub_i128(n))),
555 (Val::Symbolic(bits), Val::I128(n)) => {
556 let result = solver.fresh();
557 let len = match solver.length(bits) {
558 Some(len) => len,
559 None => {
560 return Err(ExecError::Type(format!(
561 "sub_bits_int (solver cannot determine length) {:?} {:?}",
562 &bits, &n
563 )))
564 }
565 };
566 assert!(len <= 128);
567 solver.add(Def::DefineConst(
568 result,
569 Exp::Bvsub(Box::new(Exp::Var(bits)), Box::new(Exp::Extract(len - 1, 0, Box::new(smt_i128(n))))),
570 ));
571 Ok(Val::Symbolic(result))
572 }
573 (Val::Symbolic(bits), Val::Symbolic(n)) => {
574 let result = solver.fresh();
575 let len = match solver.length(bits) {
576 Some(len) => len,
577 None => {
578 return Err(ExecError::Type(format!(
579 "sub_bits_int (solver cannot determine length) {:?} {:?}",
580 &bits, &n
581 )))
582 }
583 };
584 assert!(len <= 128);
585 solver.add(Def::DefineConst(
586 result,
587 Exp::Bvsub(Box::new(Exp::Var(bits)), Box::new(Exp::Extract(len - 1, 0, Box::new(Exp::Var(n))))),
588 ));
589 Ok(Val::Symbolic(result))
590 }
591 (bits, n) => Err(ExecError::Type(format!("sub_bits_int {:?} {:?}", &bits, &n))),
592 }
593}
594
595fn zeros<B: BV>(len: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
596 match len {
597 Val::I128(len) => {
598 if len <= B::MAX_WIDTH as i128 {
599 Ok(Val::Bits(B::zeros(len as u32)))
600 } else {
601 solver.define_const(smt_zeros(len)).into()
602 }
603 }
604 Val::Symbolic(_) => Err(ExecError::SymbolicLength("zeros")),
605 _ => Err(ExecError::Type(format!("zeros {:?}", &len))),
606 }
607}
608
609fn ones<B: BV>(len: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
610 match len {
611 Val::I128(len) => {
612 if len <= B::MAX_WIDTH as i128 {
613 Ok(Val::Bits(B::ones(len as u32)))
614 } else {
615 solver.define_const(smt_ones(len)).into()
616 }
617 }
618 Val::Symbolic(_) => Err(ExecError::SymbolicLength("ones")),
619 _ => Err(ExecError::Type(format!("ones {:?}", &len))),
620 }
621}
622
623macro_rules! extension {
626 ($id: ident, $name: expr, $smt_extension: path, $concrete_extension: path) => {
627 pub fn $id<B: BV>(bits: Val<B>, len: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
628 match (bits, len) {
629 (Val::Bits(bits), Val::I128(len)) => {
630 let len = len as u32;
631 if len > B::MAX_WIDTH {
632 let ext = len - bits.len();
633 solver.define_const($smt_extension(ext, Box::new(smt_sbits(bits)))).into()
634 } else {
635 Ok(Val::Bits($concrete_extension(bits, len)))
636 }
637 }
638 (Val::Symbolic(bits), Val::I128(len)) => {
639 let ext = match solver.length(bits) {
640 Some(orig_len) => len as u32 - orig_len,
641 None => return Err(ExecError::Type($name)),
642 };
643 solver.define_const($smt_extension(ext, Box::new(Exp::Var(bits)))).into()
644 }
645 (_, Val::Symbolic(_)) => Err(ExecError::SymbolicLength("extension")),
646 (_, _) => Err(ExecError::Type($name)),
647 }
648 }
649 };
650}
651
652extension!(zero_extend, "zero_extend".to_string(), Exp::ZeroExtend, B::zero_extend);
653extension!(sign_extend, "sign_extend".to_string(), Exp::SignExtend, B::sign_extend);
654
655pub(crate) fn op_zero_extend<B: BV>(bits: Val<B>, len: u32, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
656 match bits {
657 Val::Bits(bits) => {
658 if len > 64 {
659 let ext = len - bits.len();
660 solver.define_const(Exp::ZeroExtend(ext, Box::new(smt_sbits(bits)))).into()
661 } else {
662 Ok(Val::Bits(B::zero_extend(bits, len)))
663 }
664 }
665 Val::Symbolic(bits) => {
666 let ext = match solver.length(bits) {
667 Some(orig_len) => len - orig_len,
668 None => {
669 return Err(ExecError::Type(format!("op_zero_extend (solver cannot determine length) {:?}", &bits)))
670 }
671 };
672 solver.define_const(Exp::ZeroExtend(ext, Box::new(Exp::Var(bits)))).into()
673 }
674 _ => Err(ExecError::Type(format!("op_zero_extend {:?}", &bits))),
675 }
676}
677
678fn replicate_exp(bits: Exp, times: i128) -> Exp {
679 if times == 0 {
680 bits64(0, 0)
681 } else if times == 1 {
682 bits
683 } else {
684 Exp::Concat(Box::new(bits.clone()), Box::new(replicate_exp(bits, times - 1)))
685 }
686}
687
688fn replicate_bits<B: BV>(bits: Val<B>, times: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
689 match (bits, times) {
690 (Val::Bits(bits), Val::I128(times)) => match bits.replicate(times) {
691 Some(replicated) => Ok(Val::Bits(replicated)),
692 None => solver.define_const(replicate_exp(smt_sbits(bits), times)).into(),
693 },
694 (Val::Symbolic(bits), Val::I128(times)) => {
695 if times == 0 {
696 Ok(Val::Bits(B::zeros(0)))
697 } else {
698 solver.define_const(replicate_exp(Exp::Var(bits), times)).into()
699 }
700 }
701 (bits, times) => Err(ExecError::Type(format!("replicate_bits {:?} {:?}", &bits, ×))),
702 }
703}
704
705pub fn length_bits<B: BV>(bits: &Val<B>, solver: &mut Solver<B>) -> Result<u32, ExecError> {
709 match bits {
710 Val::Bits(bits) => Ok(bits.len()),
711 Val::Symbolic(bits) => match solver.length(*bits) {
712 Some(len) => Ok(len),
713 None => Err(ExecError::Type(format!("length_bits (solver cannot determine length) {:?}", &bits))),
714 },
715 _ => Err(ExecError::Type(format!("length_bits {:?}", &bits))),
716 }
717}
718
719macro_rules! slice {
723 ($bits_length: expr, $bits: expr, $from: expr, $slice_length: expr, $solver: ident) => {{
724 assert!(($slice_length as u32) <= $bits_length);
725 match $from {
726 _ if $slice_length == 0 => Ok(Val::Bits(B::zeros(0))),
727
728 Val::Symbolic(from) => {
729 let sliced = $solver.fresh();
730 let shift = if $bits_length > 128 {
735 Exp::ZeroExtend($bits_length - 128, Box::new(Exp::Var(from)))
736 } else if $bits_length < 128 {
737 Exp::Extract($bits_length - 1, 0, Box::new(Exp::Var(from)))
738 } else {
739 Exp::Var(from)
740 };
741 $solver.add(Def::DefineConst(
742 sliced,
743 Exp::Extract($slice_length as u32 - 1, 0, Box::new(Exp::Bvlshr(Box::new($bits), Box::new(shift)))),
744 ));
745 Ok(Val::Symbolic(sliced))
746 }
747
748 Val::I128(from) => {
749 let sliced = $solver.fresh();
750 if from == 0 && ($slice_length as u32) == $bits_length {
751 $solver.add(Def::DefineConst(sliced, $bits))
752 } else {
753 $solver.add(Def::DefineConst(
754 sliced,
755 Exp::Extract((from + $slice_length - 1) as u32, from as u32, Box::new($bits)),
756 ))
757 }
758 Ok(Val::Symbolic(sliced))
759 }
760
761 Val::I64(from) => {
762 let sliced = $solver.fresh();
763 if from == 0 && ($slice_length as u32) == $bits_length {
764 $solver.add(Def::DefineConst(sliced, $bits))
765 } else {
766 $solver.add(Def::DefineConst(
767 sliced,
768 Exp::Extract((from as i128 + $slice_length - 1) as u32, from as u32, Box::new($bits)),
769 ))
770 }
771 Ok(Val::Symbolic(sliced))
772 }
773
774 _ => Err(ExecError::Type(format!("slice! {:?}", &$from))),
775 }
776 }};
777}
778
779pub(crate) fn op_slice<B: BV>(
780 bits: Val<B>,
781 from: Val<B>,
782 length: u32,
783 solver: &mut Solver<B>,
784) -> Result<Val<B>, ExecError> {
785 let bits_length = length_bits(&bits, solver)?;
786 match bits {
787 Val::Symbolic(bits) => slice!(bits_length, Exp::Var(bits), from, length as i128, solver),
788 Val::Bits(bits) => match from {
789 Val::I64(from) => match bits.slice(from as u32, length) {
790 Some(bits) => Ok(Val::Bits(bits)),
791 None => Err(ExecError::Type("op_slice (can't slice)".to_string())),
792 },
793 _ if bits.is_zero() => Ok(Val::Bits(B::zeros(bits_length))),
794 _ => slice!(bits_length, smt_sbits(bits), from, length as i128, solver),
795 },
796 _ => Err(ExecError::Type(format!("op_slice {:?}", &bits))),
797 }
798}
799
800fn slice_internal<B: BV>(
801 bits: Val<B>,
802 from: Val<B>,
803 length: Val<B>,
804 solver: &mut Solver<B>,
805) -> Result<Val<B>, ExecError> {
806 let bits_length = length_bits(&bits, solver)?;
807 match length {
808 Val::I128(length) => match bits {
809 Val::Symbolic(bits) => slice!(bits_length, Exp::Var(bits), from, length, solver),
810 Val::Bits(bits) => match from {
811 Val::I128(from) => match bits.slice(from as u32, length as u32) {
812 Some(bits) => Ok(Val::Bits(bits)),
813 None => {
814 match bits.shiftr(from).slice(0, length as u32) {
818 Some(bits) => Ok(Val::Bits(bits)),
819 None => {
820 Err(ExecError::Type(format!("slice_internal (cannot slice) {:?} {:?}", &from, &length)))
821 }
822 }
823 }
824 },
825 _ if bits.is_zero() => Ok(Val::Bits(B::zeros(bits_length))),
826 _ => slice!(bits_length, smt_sbits(bits), from, length, solver),
827 },
828 _ => Err(ExecError::Type(format!("slice_internal {:?}", &bits))),
829 },
830 Val::Symbolic(_) => Err(ExecError::SymbolicLength("slice_internal")),
831 _ => Err(ExecError::Type(format!("slice_internal {:?}", &length))),
832 }
833}
834
835fn slice<B: BV>(args: Vec<Val<B>>, solver: &mut Solver<B>, _: &mut LocalFrame<B>) -> Result<Val<B>, ExecError> {
836 slice_internal(args[0].clone(), args[1].clone(), args[2].clone(), solver)
837}
838
839pub fn subrange_internal<B: BV>(
840 bits: Val<B>,
841 high: Val<B>,
842 low: Val<B>,
843 solver: &mut Solver<B>,
844) -> Result<Val<B>, ExecError> {
845 match (bits, high, low) {
846 (Val::Symbolic(bits), Val::I128(high), Val::I128(low)) => {
847 solver.define_const(Exp::Extract(high as u32, low as u32, Box::new(Exp::Var(bits)))).into()
848 }
849 (Val::Bits(bits), Val::I128(high), Val::I128(low)) => match bits.extract(high as u32, low as u32) {
850 Some(bits) => Ok(Val::Bits(bits)),
851 None => {
852 Err(ExecError::Type(format!("subrange_internal (cannot extract) {:?} {:?} {:?}", &bits, &high, &low)))
853 }
854 },
855 (_, _, Val::Symbolic(_)) => Err(ExecError::SymbolicLength("subrange_internal")),
856 (_, Val::Symbolic(_), _) => Err(ExecError::SymbolicLength("subrange_internal")),
857 (bits, high, low) => Err(ExecError::Type(format!("subrange_internal {:?} {:?} {:?}", &bits, &high, &low))),
858 }
859}
860
861fn subrange<B: BV>(args: Vec<Val<B>>, solver: &mut Solver<B>, _: &mut LocalFrame<B>) -> Result<Val<B>, ExecError> {
862 subrange_internal(args[0].clone(), args[1].clone(), args[2].clone(), solver)
863}
864
865fn sail_truncate<B: BV>(bits: Val<B>, len: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
866 slice_internal(bits, Val::I128(0), len, solver)
867}
868
869fn sail_truncate_lsb<B: BV>(bits: Val<B>, len: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
870 match (bits, len) {
871 (Val::Bits(bits), Val::I128(len)) => match bits.truncate_lsb(len) {
872 Some(truncated) => Ok(Val::Bits(truncated)),
873 None => Err(ExecError::Type(format!("sail_truncateLSB (cannot truncate) {:?} {:?}", &bits, &len))),
874 },
875 (Val::Symbolic(bits), Val::I128(len)) => {
876 if len == 0 {
877 Ok(Val::Bits(B::new(0, 0)))
878 } else if let Some(orig_len) = solver.length(bits) {
879 let low = orig_len - (len as u32);
880 solver.define_const(Exp::Extract(orig_len - 1, low, Box::new(Exp::Var(bits)))).into()
881 } else {
882 Err(ExecError::Type(format!("sail_truncateLSB (invalid length) {:?} {:?}", &bits, &len)))
883 }
884 }
885 (_, Val::Symbolic(_)) => Err(ExecError::SymbolicLength("sail_truncateLSB")),
886 (bits, len) => Err(ExecError::Type(format!("sail_truncateLSB {:?} {:?}", &bits, &len))),
887 }
888}
889
890fn sail_unsigned<B: BV>(bits: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
891 match bits {
892 Val::Bits(bits) => Ok(Val::I128(bits.unsigned())),
893 Val::Symbolic(bits) => match solver.length(bits) {
894 Some(length) => {
895 assert!(length < 128);
896 solver.define_const(Exp::ZeroExtend(128 - length, Box::new(Exp::Var(bits)))).into()
897 }
898 None => Err(ExecError::Type(format!("sail_unsigned (solver cannot determine length) {:?}", &bits))),
899 },
900 _ => Err(ExecError::Type(format!("sail_unsigned {:?}", &bits))),
901 }
902}
903
904fn sail_signed<B: BV>(bits: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
905 match bits {
906 Val::Bits(bits) => Ok(Val::I128(bits.signed())),
907 Val::Symbolic(bits) => match solver.length(bits) {
908 Some(length) => {
909 assert!(length < 128);
910 solver.define_const(Exp::SignExtend(128 - length, Box::new(Exp::Var(bits)))).into()
911 }
912 None => Err(ExecError::Type(format!("sail_signed (solver cannot determine length) {:?}", &bits))),
913 },
914 _ => Err(ExecError::Type(format!("sail_signed {:?}", &bits))),
915 }
916}
917
918fn shiftr<B: BV>(bits: Val<B>, shift: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
919 match (bits, shift) {
920 (Val::Symbolic(x), Val::Symbolic(y)) => match solver.length(x) {
921 Some(length) => {
922 let shift = if length < 128 {
923 Exp::Extract(length - 1, 0, Box::new(Exp::Var(y)))
924 } else if length > 128 {
925 Exp::ZeroExtend(length - 128, Box::new(Exp::Var(y)))
926 } else {
927 Exp::Var(y)
928 };
929 solver.define_const(Exp::Bvlshr(Box::new(Exp::Var(x)), Box::new(shift))).into()
930 }
931 None => Err(ExecError::Type(format!("shiftr {:?} {:?}", &x, &y))),
932 },
933 (Val::Symbolic(x), Val::I128(0)) => Ok(Val::Symbolic(x)),
934 (Val::Symbolic(x), Val::I128(y)) => match solver.length(x) {
935 Some(length) => {
936 let shift = if length < 128 {
937 Exp::Extract(length - 1, 0, Box::new(smt_i128(y)))
938 } else if length > 128 {
939 Exp::ZeroExtend(length - 128, Box::new(smt_i128(y)))
940 } else {
941 smt_i128(y)
942 };
943 solver.define_const(Exp::Bvlshr(Box::new(Exp::Var(x)), Box::new(shift))).into()
944 }
945 None => Err(ExecError::Type(format!("shiftr {:?} {:?}", &x, &y))),
946 },
947 (Val::Bits(x), Val::Symbolic(y)) => solver
948 .define_const(Exp::Bvlshr(
949 Box::new(smt_sbits(x)),
950 Box::new(Exp::Extract(x.len() - 1, 0, Box::new(Exp::Var(y)))),
951 ))
952 .into(),
953 (Val::Bits(x), Val::I128(y)) => Ok(Val::Bits(x.shiftr(y))),
954 (bits, shift) => Err(ExecError::Type(format!("shiftr {:?} {:?}", &bits, &shift))),
955 }
956}
957
958fn arith_shiftr<B: BV>(bits: Val<B>, shift: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
959 match (bits, shift) {
960 (Val::Symbolic(x), Val::Symbolic(y)) => match solver.length(x) {
961 Some(length) => {
962 let shift = if length < 128 {
963 Exp::Extract(length - 1, 0, Box::new(Exp::Var(y)))
964 } else if length > 128 {
965 Exp::ZeroExtend(length - 128, Box::new(Exp::Var(y)))
966 } else {
967 Exp::Var(y)
968 };
969 solver.define_const(Exp::Bvashr(Box::new(Exp::Var(x)), Box::new(shift))).into()
970 }
971 None => Err(ExecError::Type(format!("arith_shiftr {:?} {:?}", &x, &y))),
972 },
973 (Val::Symbolic(x), Val::I128(0)) => Ok(Val::Symbolic(x)),
974 (Val::Symbolic(x), Val::I128(y)) => match solver.length(x) {
975 Some(length) => {
976 let shift = if length < 128 {
977 Exp::Extract(length - 1, 0, Box::new(smt_i128(y)))
978 } else if length > 128 {
979 Exp::ZeroExtend(length - 128, Box::new(smt_i128(y)))
980 } else {
981 smt_i128(y)
982 };
983 solver.define_const(Exp::Bvashr(Box::new(Exp::Var(x)), Box::new(shift))).into()
984 }
985 None => Err(ExecError::Type(format!("arith_shiftr {:?} {:?}", &x, &y))),
986 },
987 (Val::Bits(x), Val::Symbolic(y)) => solver
988 .define_const(Exp::Bvashr(
989 Box::new(smt_sbits(x)),
990 Box::new(Exp::Extract(x.len() - 1, 0, Box::new(Exp::Var(y)))),
991 ))
992 .into(),
993 (Val::Bits(x), Val::I128(y)) => Ok(Val::Bits(x.arith_shiftr(y))),
994 (bits, shift) => Err(ExecError::Type(format!("arith_shiftr {:?} {:?}", &bits, &shift))),
995 }
996}
997
998fn shiftl<B: BV>(bits: Val<B>, len: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
999 match (bits, len) {
1000 (Val::Symbolic(x), Val::Symbolic(y)) => match solver.length(x) {
1001 Some(length) => {
1002 let shift = if length < 128 {
1003 Exp::Extract(length - 1, 0, Box::new(Exp::Var(y)))
1004 } else if length > 128 {
1005 Exp::ZeroExtend(length - 128, Box::new(Exp::Var(y)))
1006 } else {
1007 Exp::Var(y)
1008 };
1009 solver.define_const(Exp::Bvshl(Box::new(Exp::Var(x)), Box::new(shift))).into()
1010 }
1011 None => Err(ExecError::Type(format!("shiftl {:?} {:?}", &x, &y))),
1012 },
1013 (Val::Symbolic(x), Val::I128(0)) => Ok(Val::Symbolic(x)),
1014 (Val::Symbolic(x), Val::I128(y)) => match solver.length(x) {
1015 Some(length) => {
1016 let shift = if length < 128 {
1017 Exp::Extract(length - 1, 0, Box::new(smt_i128(y)))
1018 } else if length > 128 {
1019 Exp::ZeroExtend(length - 128, Box::new(smt_i128(y)))
1020 } else {
1021 smt_i128(y)
1022 };
1023 solver.define_const(Exp::Bvshl(Box::new(Exp::Var(x)), Box::new(shift))).into()
1024 }
1025 None => Err(ExecError::Type(format!("shiftl {:?} {:?}", &x, &y))),
1026 },
1027 (Val::Bits(x), Val::Symbolic(y)) => solver
1028 .define_const(Exp::Bvshl(
1029 Box::new(smt_sbits(x)),
1030 Box::new(Exp::Extract(x.len() - 1, 0, Box::new(Exp::Var(y)))),
1031 ))
1032 .into(),
1033 (Val::Bits(x), Val::I128(y)) => Ok(Val::Bits(x.shiftl(y))),
1034 (bits, len) => Err(ExecError::Type(format!("shiftl {:?} {:?}", &bits, &len))),
1035 }
1036}
1037
1038fn shift_bits_right<B: BV>(bits: Val<B>, shift: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1039 let bits_len = length_bits(&bits, solver)?;
1040 let shift_len = length_bits(&bits, solver)?;
1041 match (&bits, &shift) {
1042 (Val::Symbolic(_), Val::Symbolic(_)) | (Val::Bits(_), Val::Symbolic(_)) | (Val::Symbolic(_), Val::Bits(_)) => {
1043 let shift = if bits_len < shift_len {
1044 Exp::Extract(bits_len - 1, 0, Box::new(smt_value(&shift)?))
1045 } else if bits_len > shift_len {
1046 Exp::ZeroExtend(bits_len - shift_len, Box::new(smt_value(&shift)?))
1047 } else {
1048 smt_value(&shift)?
1049 };
1050 solver.define_const(Exp::Bvlshr(Box::new(smt_value(&bits)?), Box::new(shift))).into()
1051 }
1052 (Val::Bits(x), Val::Bits(y)) => {
1053 let shift: u64 = (*y).try_into()?;
1054 Ok(Val::Bits(x.shiftr(shift as i128)))
1055 }
1056 (_, _) => Err(ExecError::Type(format!("shift_bits_right {:?} {:?}", &bits, &shift))),
1057 }
1058}
1059
1060fn shift_bits_left<B: BV>(bits: Val<B>, shift: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1061 let bits_len = length_bits(&bits, solver)?;
1062 let shift_len = length_bits(&bits, solver)?;
1063 match (&bits, &shift) {
1064 (Val::Symbolic(_), Val::Symbolic(_)) | (Val::Bits(_), Val::Symbolic(_)) | (Val::Symbolic(_), Val::Bits(_)) => {
1065 let shift = if bits_len < shift_len {
1066 Exp::Extract(bits_len - 1, 0, Box::new(smt_value(&shift)?))
1067 } else if bits_len > shift_len {
1068 Exp::ZeroExtend(bits_len - shift_len, Box::new(smt_value(&shift)?))
1069 } else {
1070 smt_value(&shift)?
1071 };
1072 solver.define_const(Exp::Bvshl(Box::new(smt_value(&bits)?), Box::new(shift))).into()
1073 }
1074 (Val::Bits(x), Val::Bits(y)) => {
1075 let shift: u64 = (*y).try_into()?;
1076 Ok(Val::Bits(x.shiftl(shift as i128)))
1077 }
1078 (_, _) => Err(ExecError::Type(format!("shift_bits_left {:?} {:?}", &bits, &shift))),
1079 }
1080}
1081
1082pub(crate) fn append<B: BV>(lhs: Val<B>, rhs: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1083 match (lhs, rhs) {
1084 (Val::Symbolic(x), Val::Symbolic(y)) => {
1085 solver.define_const(Exp::Concat(Box::new(Exp::Var(x)), Box::new(Exp::Var(y)))).into()
1086 }
1087 (Val::Symbolic(x), Val::Bits(y)) => {
1088 if y.len() == 0 {
1089 solver.define_const(Exp::Var(x)).into()
1090 } else {
1091 solver.define_const(Exp::Concat(Box::new(Exp::Var(x)), Box::new(smt_sbits(y)))).into()
1092 }
1093 }
1094 (Val::Bits(x), Val::Symbolic(y)) => {
1095 if x.len() == 0 {
1096 solver.define_const(Exp::Var(y)).into()
1097 } else {
1098 solver.define_const(Exp::Concat(Box::new(smt_sbits(x)), Box::new(Exp::Var(y)))).into()
1099 }
1100 }
1101 (Val::Bits(x), Val::Bits(y)) => match x.append(y) {
1102 Some(z) => Ok(Val::Bits(z)),
1103 None => solver.define_const(Exp::Concat(Box::new(smt_sbits(x)), Box::new(smt_sbits(y)))).into(),
1104 },
1105 (lhs, rhs) => Err(ExecError::Type(format!("append {:?} {:?}", &lhs, &rhs))),
1106 }
1107}
1108
1109pub(crate) fn vector_access<B: BV>(vec: Val<B>, n: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1110 match (vec, n) {
1111 (Val::Symbolic(bits), Val::Symbolic(n)) => match solver.length(bits) {
1112 Some(length) => {
1113 let shift = if length < 128 {
1114 Exp::Extract(length - 1, 0, Box::new(Exp::Var(n)))
1115 } else if length > 128 {
1116 Exp::ZeroExtend(length - 128, Box::new(Exp::Var(n)))
1117 } else {
1118 Exp::Var(n)
1119 };
1120 solver
1121 .define_const(Exp::Extract(0, 0, Box::new(Exp::Bvlshr(Box::new(Exp::Var(bits)), Box::new(shift)))))
1122 .into()
1123 }
1124 None => Err(ExecError::Type(format!("vector_access {:?} {:?}", &bits, &n))),
1125 },
1126 (Val::Symbolic(bits), Val::I128(n)) => match solver.length(bits) {
1127 Some(length) => {
1128 let shift = if length < 128 {
1129 Exp::Extract(length - 1, 0, Box::new(smt_i128(n)))
1130 } else if length > 128 {
1131 Exp::ZeroExtend(length - 128, Box::new(smt_i128(n)))
1132 } else {
1133 smt_i128(n)
1134 };
1135 solver
1136 .define_const(Exp::Extract(0, 0, Box::new(Exp::Bvlshr(Box::new(Exp::Var(bits)), Box::new(shift)))))
1137 .into()
1138 }
1139 None => Err(ExecError::Type(format!("vector_access {:?} {:?}", &bits, &n))),
1140 },
1141 (Val::Bits(bits), Val::Symbolic(n)) => {
1142 let shift = Exp::Extract(bits.len() - 1, 0, Box::new(Exp::Var(n)));
1143 solver
1144 .define_const(Exp::Extract(0, 0, Box::new(Exp::Bvlshr(Box::new(smt_sbits(bits)), Box::new(shift)))))
1145 .into()
1146 }
1147 (Val::Bits(bits), Val::I128(n)) => match bits.slice(n as u32, 1) {
1148 Some(bit) => Ok(Val::Bits(bit)),
1149 None => Err(ExecError::Type(format!("vector_access {:?} {:?}", &bits, &n))),
1150 },
1151 (Val::Vector(vec), Val::I128(n)) => match vec.get(n as usize) {
1152 Some(elem) => Ok(elem.clone()),
1153 None => Err(ExecError::OutOfBounds("vector_access")),
1154 },
1155 (vec, n) => Err(ExecError::Type(format!("vector_access {:?} {:?}", &vec, &n))),
1156 }
1157}
1158
1159macro_rules! set_slice {
1164 ($bits_length: expr, $update_length: ident, $bits: expr, $n: expr, $update: expr, $solver: ident) => {
1165 if $bits_length == 0 {
1166 Ok(Val::Bits(B::zeros(0)))
1167 } else if $update_length == 0 {
1168 $solver.define_const($bits).into()
1169 } else {
1170 let mask_lower = smt_mask_lower($bits_length as usize, $update_length as usize);
1171 let update = if $bits_length == $update_length {
1172 $update
1173 } else {
1174 Exp::ZeroExtend($bits_length - $update_length, Box::new($update))
1175 };
1176 let shift = if $bits_length < 128 {
1177 Exp::Extract($bits_length - 1, 0, Box::new($n))
1178 } else if $bits_length > 128 {
1179 Exp::ZeroExtend($bits_length - 128, Box::new($n))
1180 } else {
1181 $n
1182 };
1183 let sliced = $solver.fresh();
1184 $solver.add(Def::DefineConst(
1185 sliced,
1186 Exp::Bvor(
1187 Box::new(Exp::Bvand(
1188 Box::new($bits),
1189 Box::new(Exp::Bvnot(Box::new(Exp::Bvshl(Box::new(mask_lower), Box::new(shift.clone()))))),
1190 )),
1191 Box::new(Exp::Bvshl(Box::new(update), Box::new(shift))),
1192 ),
1193 ));
1194 Ok(Val::Symbolic(sliced))
1195 }
1196 };
1197}
1198
1199macro_rules! set_slice_n0 {
1201 ($bits_length: expr, $update_length: ident, $bits: expr, $update: expr, $solver: ident) => {
1202 if $bits_length == 0 {
1203 Ok(Val::Bits(B::zeros(0)))
1204 } else if $update_length == 0 {
1205 $solver.define_const($bits).into()
1206 } else {
1207 let mask_lower = smt_mask_lower($bits_length as usize, $update_length as usize);
1208 let update = if $bits_length == $update_length {
1209 $update
1210 } else {
1211 Exp::ZeroExtend($bits_length - $update_length, Box::new($update))
1212 };
1213 let sliced = $solver.fresh();
1214 $solver.add(Def::DefineConst(
1215 sliced,
1216 Exp::Bvor(
1217 Box::new(Exp::Bvand(Box::new($bits), Box::new(Exp::Bvnot(Box::new(mask_lower))))),
1218 Box::new(update),
1219 ),
1220 ));
1221 Ok(Val::Symbolic(sliced))
1222 }
1223 };
1224}
1225
1226fn set_slice_internal<B: BV>(
1227 bits: Val<B>,
1228 n: Val<B>,
1229 update: Val<B>,
1230 solver: &mut Solver<B>,
1231) -> Result<Val<B>, ExecError> {
1232 let bits_length = length_bits(&bits, solver)?;
1233 let update_length = length_bits(&update, solver)?;
1234 match (bits, n, update) {
1235 (Val::Symbolic(bits), Val::Symbolic(n), Val::Symbolic(update)) => {
1236 set_slice!(bits_length, update_length, Exp::Var(bits), Exp::Var(n), Exp::Var(update), solver)
1237 }
1238 (Val::Symbolic(bits), Val::Symbolic(n), Val::Bits(update)) => {
1239 set_slice!(bits_length, update_length, Exp::Var(bits), Exp::Var(n), smt_sbits(update), solver)
1240 }
1241 (Val::Symbolic(bits), Val::I128(n), Val::Symbolic(update)) => {
1242 if n == 0 {
1243 set_slice_n0!(bits_length, update_length, Exp::Var(bits), Exp::Var(update), solver)
1244 } else {
1245 set_slice!(bits_length, update_length, Exp::Var(bits), smt_i128(n), Exp::Var(update), solver)
1246 }
1247 }
1248 (Val::Symbolic(bits), Val::I128(n), Val::Bits(update)) => {
1249 if n == 0 {
1250 if bits_length == update_length {
1251 Ok(Val::Bits(update))
1252 } else {
1253 set_slice_n0!(bits_length, update_length, Exp::Var(bits), smt_sbits(update), solver)
1254 }
1255 } else {
1256 set_slice!(bits_length, update_length, Exp::Var(bits), smt_i128(n), smt_sbits(update), solver)
1257 }
1258 }
1259 (Val::Bits(bits), Val::Symbolic(n), Val::Symbolic(update)) => {
1260 set_slice!(bits_length, update_length, smt_sbits(bits), Exp::Var(n), Exp::Var(update), solver)
1261 }
1262 (Val::Bits(bits), Val::Symbolic(n), Val::Bits(update)) => {
1263 set_slice!(bits_length, update_length, smt_sbits(bits), Exp::Var(n), smt_sbits(update), solver)
1264 }
1265 (Val::Bits(bits), Val::I128(n), Val::Symbolic(update)) => {
1266 if n == 0 {
1267 set_slice_n0!(bits_length, update_length, smt_sbits(bits), Exp::Var(update), solver)
1268 } else {
1269 set_slice!(bits_length, update_length, smt_sbits(bits), smt_i128(n), Exp::Var(update), solver)
1270 }
1271 }
1272 (Val::Bits(bits), Val::I128(n), Val::Bits(update)) => Ok(Val::Bits(bits.set_slice(n as u32, update))),
1273 (bits, n, update) => Err(ExecError::Type(format!("set_slice {:?} {:?} {:?}", &bits, &n, &update))),
1274 }
1275}
1276
1277fn set_slice<B: BV>(args: Vec<Val<B>>, solver: &mut Solver<B>, _: &mut LocalFrame<B>) -> Result<Val<B>, ExecError> {
1278 set_slice_internal(args[2].clone(), args[3].clone(), args[4].clone(), solver)
1281}
1282
1283fn set_slice_int_internal<B: BV>(
1284 int: Val<B>,
1285 n: Val<B>,
1286 update: Val<B>,
1287 solver: &mut Solver<B>,
1288) -> Result<Val<B>, ExecError> {
1289 let update_length = length_bits(&update, solver)?;
1290 match (int, n, update) {
1291 (Val::Symbolic(int), Val::Symbolic(n), Val::Symbolic(update)) => {
1292 set_slice!(128, update_length, Exp::Var(int), Exp::Var(n), Exp::Var(update), solver)
1293 }
1294 (Val::Symbolic(int), Val::Symbolic(n), Val::Bits(update)) => {
1295 set_slice!(128, update_length, Exp::Var(int), Exp::Var(n), smt_sbits(update), solver)
1296 }
1297 (Val::Symbolic(int), Val::I128(n), Val::Symbolic(update)) => {
1298 if n == 0 {
1299 set_slice_n0!(128, update_length, Exp::Var(int), Exp::Var(update), solver)
1300 } else {
1301 set_slice!(128, update_length, Exp::Var(int), smt_i128(n), Exp::Var(update), solver)
1302 }
1303 }
1304 (Val::Symbolic(int), Val::I128(n), Val::Bits(update)) => {
1305 if n == 0 {
1306 set_slice_n0!(128, update_length, Exp::Var(int), smt_sbits(update), solver)
1307 } else {
1308 set_slice!(128, update_length, Exp::Var(int), smt_i128(n), smt_sbits(update), solver)
1309 }
1310 }
1311 (Val::I128(int), Val::Symbolic(n), Val::Symbolic(update)) => {
1312 set_slice!(128, update_length, smt_i128(int), Exp::Var(n), Exp::Var(update), solver)
1313 }
1314 (Val::I128(int), Val::Symbolic(n), Val::Bits(update)) => {
1315 set_slice!(128, update_length, smt_i128(int), Exp::Var(n), smt_sbits(update), solver)
1316 }
1317 (Val::I128(int), Val::I128(n), Val::Symbolic(update)) => {
1318 if n == 0 {
1319 set_slice_n0!(128, update_length, smt_i128(int), Exp::Var(update), solver)
1320 } else {
1321 set_slice!(128, update_length, smt_i128(int), smt_i128(n), Exp::Var(update), solver)
1322 }
1323 }
1324 (Val::I128(int), Val::I128(n), Val::Bits(update)) => Ok(Val::I128(B::set_slice_int(int, n as u32, update))),
1325 (int, n, update) => Err(ExecError::Type(format!("set_slice_int {:?} {:?} {:?}", &int, &n, &update))),
1326 }
1327}
1328
1329fn set_slice_int<B: BV>(args: Vec<Val<B>>, solver: &mut Solver<B>, _: &mut LocalFrame<B>) -> Result<Val<B>, ExecError> {
1330 set_slice_int_internal(args[1].clone(), args[2].clone(), args[3].clone(), solver)
1333}
1334
1335pub(crate) fn op_set_slice<B: BV>(
1337 bits: Val<B>,
1338 n: Val<B>,
1339 update: Val<B>,
1340 solver: &mut Solver<B>,
1341) -> Result<Val<B>, ExecError> {
1342 let bits_length = length_bits(&bits, solver)?;
1343 let update_length = length_bits(&update, solver)?;
1344 match (bits, n, update) {
1345 (Val::Symbolic(bits), Val::Symbolic(n), Val::Symbolic(update)) => {
1346 set_slice!(bits_length, update_length, Exp::Var(bits), Exp::Var(n), Exp::Var(update), solver)
1347 }
1348 (Val::Symbolic(bits), Val::Symbolic(n), Val::Bits(update)) => {
1349 set_slice!(bits_length, update_length, Exp::Var(bits), Exp::Var(n), smt_sbits(update), solver)
1350 }
1351 (Val::Symbolic(bits), Val::I64(n), Val::Symbolic(update)) => {
1352 if n == 0 {
1353 set_slice_n0!(bits_length, update_length, Exp::Var(bits), Exp::Var(update), solver)
1354 } else {
1355 set_slice!(bits_length, update_length, Exp::Var(bits), smt_i64(n), Exp::Var(update), solver)
1356 }
1357 }
1358 (Val::Symbolic(bits), Val::I64(n), Val::Bits(update)) => {
1359 if n == 0 {
1360 set_slice_n0!(bits_length, update_length, Exp::Var(bits), smt_sbits(update), solver)
1361 } else {
1362 set_slice!(bits_length, update_length, Exp::Var(bits), smt_i64(n), smt_sbits(update), solver)
1363 }
1364 }
1365 (Val::Bits(bits), Val::Symbolic(n), Val::Symbolic(update)) => {
1366 set_slice!(bits_length, update_length, smt_sbits(bits), Exp::Var(n), Exp::Var(update), solver)
1367 }
1368 (Val::Bits(bits), Val::Symbolic(n), Val::Bits(update)) => {
1369 set_slice!(bits_length, update_length, smt_sbits(bits), Exp::Var(n), smt_sbits(update), solver)
1370 }
1371 (Val::Bits(bits), Val::I64(n), Val::Symbolic(update)) => {
1372 if n == 0 {
1373 set_slice_n0!(bits_length, update_length, smt_sbits(bits), Exp::Var(update), solver)
1374 } else {
1375 set_slice!(bits_length, update_length, smt_sbits(bits), smt_i64(n), Exp::Var(update), solver)
1376 }
1377 }
1378 (Val::Bits(bits), Val::I64(n), Val::Bits(update)) => Ok(Val::Bits(bits.set_slice(n as u32, update))),
1379 (bits, n, update) => Err(ExecError::Type(format!("set_slice {:?} {:?} {:?}", &bits, &n, &update))),
1380 }
1381}
1382
1383pub fn vector_update<B: BV>(
1387 args: Vec<Val<B>>,
1388 solver: &mut Solver<B>,
1389 _: &mut LocalFrame<B>,
1390) -> Result<Val<B>, ExecError> {
1391 let arg0 = args[0].clone();
1392 match arg0 {
1393 Val::Vector(mut vec) => match args[1] {
1394 Val::I128(n) => {
1395 vec[n as usize] = args[2].clone();
1396 Ok(Val::Vector(vec))
1397 }
1398 Val::I64(n) => {
1399 vec[n as usize] = args[2].clone();
1400 Ok(Val::Vector(vec))
1401 }
1402 Val::Symbolic(n) => {
1403 for (i, item) in vec.iter_mut().enumerate() {
1404 let var = solver.fresh();
1405 solver.add(Def::DefineConst(
1406 var,
1407 Exp::Ite(
1408 Box::new(Exp::Eq(Box::new(Exp::Var(n)), Box::new(bits64(i as u64, 128)))),
1409 Box::new(smt_value(&args[2])?),
1410 Box::new(smt_value(&item)?),
1411 ),
1412 ));
1413 *item = Val::Symbolic(var);
1414 }
1415 Ok(Val::Vector(vec))
1416 }
1417 _ => {
1418 eprintln!("{:?}", args);
1419 Err(ExecError::Type(format!("vector_update (index) {:?}", &args[1])))
1420 }
1421 },
1422 Val::Bits(_) => {
1423 set_slice_internal(arg0, args[1].clone(), args[2].clone(), solver)
1426 }
1427 Val::Symbolic(v) if solver.is_bitvector(v) => {
1428 set_slice_internal(arg0, args[1].clone(), args[2].clone(), solver)
1429 }
1430 _ => Err(ExecError::Type(format!("vector_update {:?}", &arg0))),
1431 }
1432}
1433
1434fn vector_update_subrange<B: BV>(
1435 args: Vec<Val<B>>,
1436 solver: &mut Solver<B>,
1437 _: &mut LocalFrame<B>,
1438) -> Result<Val<B>, ExecError> {
1439 set_slice_internal(args[0].clone(), args[2].clone(), args[3].clone(), solver)
1440}
1441
1442fn undefined_vector<B: BV>(len: Val<B>, elem: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1443 if let Val::I128(len) = len {
1444 if let Ok(len) = usize::try_from(len) {
1445 Ok(Val::Vector(vec![elem; len]))
1446 } else {
1447 Err(ExecError::Overflow)
1448 }
1449 } else {
1450 Err(ExecError::SymbolicLength("undefined_vector"))
1451 }
1452}
1453
1454fn bitvector_update<B: BV>(
1455 args: Vec<Val<B>>,
1456 solver: &mut Solver<B>,
1457 _: &mut LocalFrame<B>,
1458) -> Result<Val<B>, ExecError> {
1459 op_set_slice(args[0].clone(), args[1].clone(), args[2].clone(), solver)
1460}
1461
1462fn get_slice_int_internal<B: BV>(
1463 length: Val<B>,
1464 n: Val<B>,
1465 from: Val<B>,
1466 solver: &mut Solver<B>,
1467) -> Result<Val<B>, ExecError> {
1468 match length {
1469 Val::I128(length) => match n {
1470 Val::Symbolic(n) => slice!(128, Exp::Var(n), from, length, solver),
1471 Val::I128(n) => match from {
1472 Val::I128(from) if length <= B::MAX_WIDTH as i128 => {
1473 Ok(Val::Bits(B::get_slice_int(length as u32, n, from as u32)))
1474 }
1475 _ => slice!(128, smt_i128(n), from, length, solver),
1476 },
1477 _ => Err(ExecError::Type(format!("get_slice_int {:?}", &length))),
1478 },
1479 Val::Symbolic(_) => Err(ExecError::SymbolicLength("get_slice_int")),
1480 _ => Err(ExecError::Type(format!("get_slice_int length is {:?}", &length))),
1481 }
1482}
1483
1484fn get_slice_int<B: BV>(args: Vec<Val<B>>, solver: &mut Solver<B>, _: &mut LocalFrame<B>) -> Result<Val<B>, ExecError> {
1485 get_slice_int_internal(args[0].clone(), args[1].clone(), args[2].clone(), solver)
1486}
1487
1488fn unimplemented<B: BV>(_: Vec<Val<B>>, _: &mut Solver<B>, _: &mut LocalFrame<B>) -> Result<Val<B>, ExecError> {
1489 Err(ExecError::Unimplemented)
1490}
1491
1492fn eq_string<B: BV>(lhs: Val<B>, rhs: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1493 match (lhs, rhs) {
1494 (Val::String(lhs), Val::String(rhs)) => Ok(Val::Bool(lhs == rhs)),
1495 (lhs, rhs) => Err(ExecError::Type(format!("eq_string {:?} {:?}", &lhs, &rhs))),
1496 }
1497}
1498
1499fn concat_str<B: BV>(lhs: Val<B>, rhs: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1500 match (lhs, rhs) {
1501 (Val::String(lhs), Val::String(rhs)) => Ok(Val::String(format!("{}{}", lhs, rhs))),
1502 (lhs, rhs) => Err(ExecError::Type(format!("concat_str {:?} {:?}", &lhs, &rhs))),
1503 }
1504}
1505
1506fn hex_str<B: BV>(n: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1507 match n {
1508 Val::I128(n) => Ok(Val::String(format!("0x{:x}", n))),
1509 Val::Symbolic(v) => Ok(Val::String(format!("0x[{}]", v))),
1510 _ => Err(ExecError::Type(format!("hex_str {:?}", &n))),
1511 }
1512}
1513
1514fn dec_str<B: BV>(n: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1515 match n {
1516 Val::I128(n) => Ok(Val::String(format!("{}", n))),
1517 Val::Symbolic(v) => Ok(Val::String(format!("[{}]", v))),
1518 _ => Err(ExecError::Type(format!("dec_str {:?}", &n))),
1519 }
1520}
1521
1522fn undefined_string<B: BV>(_: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1524 Ok(Val::Poison)
1525}
1526
1527fn string_to_i128<B: BV>(s: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1528 if let Val::String(s) = s {
1529 if let Ok(n) = i128::from_str(&s) {
1530 Ok(Val::I128(n))
1531 } else {
1532 Err(ExecError::Overflow)
1533 }
1534 } else {
1535 Err(ExecError::Type(format!("%string->%int {:?}", &s)))
1536 }
1537}
1538
1539fn eq_anything<B: BV>(lhs: Val<B>, rhs: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1540 match (lhs, rhs) {
1541 (Val::Symbolic(lhs), Val::Symbolic(rhs)) => {
1542 solver.define_const(Exp::Eq(Box::new(Exp::Var(lhs)), Box::new(Exp::Var(rhs)))).into()
1543 }
1544 (lhs, Val::Symbolic(rhs)) => {
1545 solver.define_const(Exp::Eq(Box::new(smt_value(&lhs)?), Box::new(Exp::Var(rhs)))).into()
1546 }
1547 (Val::Symbolic(lhs), rhs) => {
1548 solver.define_const(Exp::Eq(Box::new(Exp::Var(lhs)), Box::new(smt_value(&rhs)?))).into()
1549 }
1550
1551 (Val::Bits(lhs), Val::Bits(rhs)) => Ok(Val::Bool(lhs == rhs)),
1552 (Val::Enum(lhs), Val::Enum(rhs)) => Ok(Val::Bool(lhs == rhs)),
1553 (Val::Bool(lhs), Val::Bool(rhs)) => Ok(Val::Bool(lhs == rhs)),
1554 (Val::I128(lhs), Val::I128(rhs)) => Ok(Val::Bool(lhs == rhs)),
1555 (Val::I64(lhs), Val::I64(rhs)) => Ok(Val::Bool(lhs == rhs)),
1556 (Val::Struct(lhs), Val::Struct(rhs)) => {
1557 let mut vars = vec![];
1558 for (k, lhs_v) in lhs {
1559 let rhs_v = match rhs.get(&k) {
1560 Some(v) => v,
1561 None => return Err(ExecError::Type("eq_anything None".to_string())),
1562 };
1563 let result = eq_anything(lhs_v, rhs_v.clone(), solver)?;
1564 match result {
1565 Val::Bool(true) => (),
1566 Val::Bool(false) => return Ok(Val::Bool(false)),
1567 Val::Symbolic(r) => vars.push(r),
1568 _ => return Err(ExecError::Type(format!("eq_anything {:?}", &result))),
1569 }
1570 }
1571 match vars.pop() {
1572 None => Ok(Val::Bool(true)),
1573 Some(init) => {
1574 let exp = vars
1575 .iter()
1576 .map(|v| Exp::Var(*v))
1577 .fold(Exp::Var(init), |e1, e2| Exp::And(Box::new(e1), Box::new(e2)));
1578 solver.define_const(exp).into()
1579 }
1580 }
1581 }
1582
1583 (lhs, rhs) => Err(ExecError::Type(format!("eq_anything {:?} {:?}", &lhs, &rhs))),
1584 }
1585}
1586
1587fn neq_anything<B: BV>(lhs: Val<B>, rhs: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1588 match (lhs, rhs) {
1589 (Val::Symbolic(lhs), Val::Symbolic(rhs)) => {
1590 solver.define_const(Exp::Neq(Box::new(Exp::Var(lhs)), Box::new(Exp::Var(rhs)))).into()
1591 }
1592 (Val::Bits(lhs), Val::Symbolic(rhs)) => {
1593 solver.define_const(Exp::Neq(Box::new(smt_sbits(lhs)), Box::new(Exp::Var(rhs)))).into()
1594 }
1595 (Val::Symbolic(lhs), Val::Bits(rhs)) => {
1596 solver.define_const(Exp::Neq(Box::new(Exp::Var(lhs)), Box::new(smt_sbits(rhs)))).into()
1597 }
1598 (Val::Bits(lhs), Val::Bits(rhs)) => Ok(Val::Bool(lhs != rhs)),
1599
1600 (Val::Symbolic(lhs), Val::Enum(rhs)) => {
1601 solver.define_const(Exp::Neq(Box::new(Exp::Var(lhs)), Box::new(Exp::Enum(rhs)))).into()
1602 }
1603 (Val::Enum(lhs), Val::Symbolic(rhs)) => {
1604 solver.define_const(Exp::Neq(Box::new(Exp::Enum(lhs)), Box::new(Exp::Var(rhs)))).into()
1605 }
1606 (Val::Enum(lhs), Val::Enum(rhs)) => Ok(Val::Bool(lhs != rhs)),
1607
1608 (lhs, rhs) => Err(ExecError::Type(format!("neq_anything {:?} {:?}", &lhs, &rhs))),
1609 }
1610}
1611
1612fn string_startswith<B: BV>(s: Val<B>, prefix: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1613 match (s, prefix) {
1614 (Val::String(s), Val::String(prefix)) => Ok(Val::Bool(s.starts_with(&prefix))),
1615 other => Err(ExecError::Type(format!("string_startswith {:?}", &other))),
1616 }
1617}
1618
1619fn string_length<B: BV>(s: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1620 if let Val::String(s) = s {
1621 Ok(Val::I128(s.len() as i128))
1622 } else {
1623 Err(ExecError::Type(format!("string_length {:?}", &s)))
1624 }
1625}
1626
1627fn string_drop<B: BV>(s: Val<B>, n: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1628 match (s, n) {
1629 (Val::String(s), Val::I128(n)) => Ok(Val::String(s.get((n as usize)..).unwrap_or("").to_string())),
1630 other => Err(ExecError::Type(format!("string_drop {:?}", &other))),
1631 }
1632}
1633
1634fn string_take<B: BV>(s: Val<B>, n: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1635 match (s, n) {
1636 (Val::String(s), Val::I128(n)) => Ok(Val::String(s.get(..(n as usize)).unwrap_or(&s).to_string())),
1637 other => Err(ExecError::Type(format!("string_take {:?}", &other))),
1638 }
1639}
1640
1641fn string_of_bits<B: BV>(bv: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1642 match bv {
1643 Val::Bits(bv) => Ok(Val::String(format!("{}", bv))),
1644 Val::Symbolic(v) => Ok(Val::String(format!("v{}", v))),
1645 other => Err(ExecError::Type(format!("string_of_bits {:?}", &other))),
1646 }
1647}
1648
1649fn decimal_string_of_bits<B: BV>(bv: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1650 match bv {
1651 Val::Bits(bv) => Ok(Val::String(format!("{}", bv.signed()))),
1652 Val::Symbolic(v) => Ok(Val::String(format!("v{}", v))),
1653 other => Err(ExecError::Type(format!("decimal_string_of_bits {:?}", &other))),
1654 }
1655}
1656
1657fn string_of_int<B: BV>(n: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1658 match n {
1659 Val::I128(n) => Ok(Val::String(format!("{}", n))),
1660 Val::Symbolic(v) => Ok(Val::String(format!("v{}", v))),
1661 other => Err(ExecError::Type(format!("string_of_int {:?}", &other))),
1662 }
1663}
1664
1665fn putchar<B: BV>(_c: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1666 Ok(Val::Unit)
1670}
1671
1672fn print<B: BV>(_message: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1673 Ok(Val::Unit)
1677}
1678
1679fn prerr<B: BV>(_message: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1680 Ok(Val::Unit)
1684}
1685
1686fn print_string<B: BV>(_prefix: Val<B>, _message: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1687 Ok(Val::Unit)
1688}
1689
1690fn prerr_string<B: BV>(_prefix: Val<B>, _message: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1691 Ok(Val::Unit)
1692}
1693
1694fn print_int<B: BV>(_prefix: Val<B>, _n: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1695 Ok(Val::Unit)
1696}
1697
1698fn prerr_int<B: BV>(_prefix: Val<B>, _n: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1699 Ok(Val::Unit)
1700}
1701
1702fn print_endline<B: BV>(_message: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1703 Ok(Val::Unit)
1704}
1705
1706fn prerr_endline<B: BV>(_message: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1707 Ok(Val::Unit)
1708}
1709
1710fn print_bits<B: BV>(_message: Val<B>, _bits: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1711 Ok(Val::Unit)
1715}
1716
1717fn prerr_bits<B: BV>(_message: Val<B>, _bits: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1718 Ok(Val::Unit)
1722}
1723
1724fn undefined_bitvector<B: BV>(sz: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1725 if let Val::I128(sz) = sz {
1726 solver.declare_const(Ty::BitVec(sz as u32)).into()
1727 } else {
1728 Err(ExecError::Type(format!("undefined_bitvector {:?}", &sz)))
1729 }
1730}
1731
1732fn undefined_bool<B: BV>(_: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1733 solver.declare_const(Ty::Bool).into()
1734}
1735
1736fn undefined_int<B: BV>(_: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1737 solver.declare_const(Ty::BitVec(128)).into()
1738}
1739
1740fn undefined_nat<B: BV>(_: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1741 let sym = solver.fresh();
1742 solver.add(Def::DeclareConst(sym, Ty::BitVec(128)));
1743 solver.add(Def::Assert(Exp::Bvsge(Box::new(Exp::Var(sym)), Box::new(smt_i128(0)))));
1744 Ok(Val::Symbolic(sym))
1745}
1746
1747fn undefined_range<B: BV>(lo: Val<B>, hi: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1748 let sym = solver.fresh();
1749 solver.add(Def::DeclareConst(sym, Ty::BitVec(128)));
1750 solver.add(Def::Assert(Exp::Bvsle(Box::new(smt_value(&lo)?), Box::new(Exp::Var(sym)))));
1751 solver.add(Def::Assert(Exp::Bvsle(Box::new(Exp::Var(sym)), Box::new(smt_value(&hi)?))));
1752 Ok(Val::Symbolic(sym))
1753}
1754
1755fn undefined_unit<B: BV>(_: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1756 Ok(Val::Unit)
1757}
1758
1759fn one_if<B: BV>(condition: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1760 match condition {
1761 Val::Bool(true) => Ok(Val::Bits(B::BIT_ONE)),
1762 Val::Bool(false) => Ok(Val::Bits(B::BIT_ZERO)),
1763 Val::Symbolic(v) => solver
1764 .define_const(Exp::Ite(
1765 Box::new(Exp::Var(v)),
1766 Box::new(smt_sbits(B::BIT_ONE)),
1767 Box::new(smt_sbits(B::BIT_ZERO)),
1768 ))
1769 .into(),
1770 _ => Err(ExecError::Type(format!("one_if {:?}", &condition))),
1771 }
1772}
1773
1774fn zero_if<B: BV>(condition: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1775 match condition {
1776 Val::Bool(true) => Ok(Val::Bits(B::BIT_ZERO)),
1777 Val::Bool(false) => Ok(Val::Bits(B::BIT_ONE)),
1778 Val::Symbolic(v) => solver
1779 .define_const(Exp::Ite(
1780 Box::new(Exp::Var(v)),
1781 Box::new(smt_sbits(B::BIT_ZERO)),
1782 Box::new(smt_sbits(B::BIT_ONE)),
1783 ))
1784 .into(),
1785 other => Err(ExecError::Type(format!("one_if {:?}", &other))),
1786 }
1787}
1788
1789fn cons<B: BV>(x: Val<B>, xs: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1790 match xs {
1791 Val::Poison => Ok(Val::List(vec![x])),
1793 Val::List(mut xs) => {
1794 xs.push(x);
1795 Ok(Val::List(xs))
1796 }
1797 _ => Err(ExecError::Type(format!("cons {:?}", &xs))),
1798 }
1799}
1800
1801pub fn smt_value<B: BV>(v: &Val<B>) -> Result<Exp, ExecError> {
1803 Ok(match v {
1804 Val::I128(n) => smt_i128(*n),
1805 Val::I64(n) => smt_i64(*n),
1806 Val::Bits(bv) => smt_sbits(*bv),
1807 Val::Bool(b) => Exp::Bool(*b),
1808 Val::Enum(e) => Exp::Enum(*e),
1809 Val::Symbolic(v) => Exp::Var(*v),
1810 _ => return Err(ExecError::Type(format!("smt_value {:?}", &v))),
1811 })
1812}
1813
1814fn choice_chain<B: BV>(sym: Sym, n: u64, sz: u32, mut xs: Vec<Val<B>>) -> Result<Exp, ExecError> {
1815 if xs.len() == 1 {
1816 smt_value(&xs[0])
1817 } else {
1818 let x = xs.pop().unwrap();
1819 Ok(Exp::Ite(
1820 Box::new(Exp::Eq(Box::new(Exp::Var(sym)), Box::new(bits64(n, sz)))),
1821 Box::new(smt_value(&x)?),
1822 Box::new(choice_chain(sym, n + 1, sz, xs)?),
1823 ))
1824 }
1825}
1826
1827fn choice<B: BV>(xs: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1828 match xs {
1829 Val::List(xs) => {
1830 let sz = ((xs.len() + 1) as f64).log2().ceil() as u32;
1835 let sym = solver.fresh();
1836 let choice = solver.fresh();
1837 solver.add(Def::DeclareConst(sym, Ty::BitVec(sz)));
1838 solver.add(Def::DefineConst(choice, choice_chain(sym, 0, sz, xs)?));
1839 Ok(Val::Symbolic(choice))
1840 }
1841 _ => Err(ExecError::Type(format!("choice {:?}", &xs))),
1842 }
1843}
1844
1845fn read_mem<B: BV>(args: Vec<Val<B>>, solver: &mut Solver<B>, frame: &mut LocalFrame<B>) -> Result<Val<B>, ExecError> {
1846 frame.memory().read(args[0].clone(), args[2].clone(), args[3].clone(), solver, false)
1847}
1848
1849fn read_memt<B: BV>(args: Vec<Val<B>>, solver: &mut Solver<B>, frame: &mut LocalFrame<B>) -> Result<Val<B>, ExecError> {
1850 frame.memory().read(args[0].clone(), args[1].clone(), args[2].clone(), solver, true)
1851}
1852
1853fn bad_read<B: BV>(_: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1854 Err(ExecError::BadRead("spec-defined bad read"))
1855}
1856
1857fn write_mem<B: BV>(args: Vec<Val<B>>, solver: &mut Solver<B>, frame: &mut LocalFrame<B>) -> Result<Val<B>, ExecError> {
1858 frame.memory_mut().write(args[0].clone(), args[2].clone(), args[4].clone(), solver, None)
1859}
1860
1861fn write_memt<B: BV>(
1862 args: Vec<Val<B>>,
1863 solver: &mut Solver<B>,
1864 frame: &mut LocalFrame<B>,
1865) -> Result<Val<B>, ExecError> {
1866 frame.memory_mut().write(args[0].clone(), args[1].clone(), args[3].clone(), solver, Some(args[4].clone()))
1867}
1868
1869fn bad_write<B: BV>(_: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1870 Err(ExecError::BadWrite("spec-defined bad write"))
1871}
1872
1873fn write_mem_ea<B: BV>(
1874 _: Vec<Val<B>>,
1875 _solver: &mut Solver<B>,
1876 _frame: &mut LocalFrame<B>,
1877) -> Result<Val<B>, ExecError> {
1878 Ok(Val::Unit)
1879}
1880
1881fn cycle_count<B: BV>(_: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1882 solver.cycle_count();
1883 Ok(Val::Unit)
1884}
1885
1886fn get_cycle_count<B: BV>(_: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1887 Ok(Val::I128(solver.get_cycle_count()))
1888}
1889
1890fn get_verbosity<B: BV>(_: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1891 Ok(Val::Bits(B::zeros(64)))
1892}
1893
1894fn sleeping<B: BV>(_: Val<B>, _solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1895 Ok(Val::Bool(false))
1900}
1901
1902fn wakeup_request<B: BV>(_: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1903 solver.add_event(Event::WakeupRequest);
1904 Ok(Val::Unit)
1905}
1906
1907fn sleep_request<B: BV>(_: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1908 solver.add_event(Event::WakeupRequest);
1909 Ok(Val::Unit)
1910}
1911
1912fn instr_announce<B: BV>(opcode: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1913 solver.add_event(Event::Instr(opcode));
1914 Ok(Val::Unit)
1915}
1916
1917fn branch_announce<B: BV>(_: Val<B>, target: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1918 solver.add_event(Event::Branch { address: target });
1919 Ok(Val::Unit)
1920}
1921
1922fn barrier<B: BV>(barrier_kind: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1923 solver.add_event(Event::Barrier { barrier_kind });
1924 Ok(Val::Unit)
1925}
1926
1927fn cache_maintenance<B: BV>(
1928 args: Vec<Val<B>>,
1929 solver: &mut Solver<B>,
1930 _: &mut LocalFrame<B>,
1931) -> Result<Val<B>, ExecError> {
1932 solver.add_event(Event::CacheOp { cache_op_kind: args[0].clone(), address: args[2].clone() });
1933 Ok(Val::Unit)
1934}
1935
1936fn elf_entry<B: BV>(_: Vec<Val<B>>, _: &mut Solver<B>, frame: &mut LocalFrame<B>) -> Result<Val<B>, ExecError> {
1937 match frame.lets().get(&ELF_ENTRY) {
1938 Some(UVal::Init(value)) => Ok(value.clone()),
1939 _ => Err(ExecError::NoElfEntry),
1940 }
1941}
1942
1943fn monomorphize<B: BV>(val: Val<B>, _: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1944 Ok(val)
1945}
1946
1947fn mark_register<B: BV>(r: Val<B>, mark: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1948 match (r, mark) {
1949 (Val::Ref(r), Val::String(mark)) => {
1950 solver.add_event(Event::MarkReg { regs: vec![r], mark });
1951 Ok(Val::Unit)
1952 }
1953 (r, mark) => Err(ExecError::Type(format!("mark_register {:?} {:?}", &r, &mark))),
1954 }
1955}
1956
1957fn mark_register_pair_internal<B: BV>(
1958 r1: Val<B>,
1959 r2: Val<B>,
1960 mark: Val<B>,
1961 solver: &mut Solver<B>,
1962) -> Result<Val<B>, ExecError> {
1963 match (r1, r2, mark) {
1964 (Val::Ref(r1), Val::Ref(r2), Val::String(mark)) => {
1965 solver.add_event(Event::MarkReg { regs: vec![r1, r2], mark });
1966 Ok(Val::Unit)
1967 }
1968 (r1, r2, mark) => Err(ExecError::Type(format!("mark_register_pair {:?} {:?} {:?}", &r1, &r2, &mark))),
1969 }
1970}
1971
1972fn mark_register_pair<B: BV>(
1973 mut args: Vec<Val<B>>,
1974 solver: &mut Solver<B>,
1975 _: &mut LocalFrame<B>,
1976) -> Result<Val<B>, ExecError> {
1977 if args.len() == 3 {
1978 let mark = args.pop().unwrap();
1979 let r2 = args.pop().unwrap();
1980 let r1 = args.pop().unwrap();
1981 mark_register_pair_internal(r1, r2, mark, solver)
1982 } else {
1983 Err(ExecError::Type("Incorrect number of arguments for mark_register_pair".to_string()))
1984 }
1985}
1986
1987fn align_bits<B: BV>(bv: Val<B>, alignment: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
1988 let bv_len = length_bits(&bv, solver)?;
1989 match (bv, alignment) {
1990 (Val::Symbolic(bv), Val::I128(alignment)) if (bv_len <= 64) & ((alignment & (alignment - 1)) == 0) => {
1992 let mask = !B::new((alignment as u64) - 1, bv_len);
1993 solver.define_const(Exp::Bvand(Box::new(Exp::Var(bv)), Box::new(smt_sbits(mask)))).into()
1994 }
1995 (bv, alignment) => {
1996 let x = sail_unsigned(bv, solver)?;
1997 let aligned_x = mult_int(alignment.clone(), udiv_int(x, alignment, solver)?, solver)?;
1998 get_slice_int_internal(Val::I128(bv_len as i128), aligned_x, Val::I128(0), solver)
1999 }
2000 }
2001}
2002
2003fn smt_clz<B: BV>(bv: Sym, len: u32, solver: &mut Solver<B>) -> Sym {
2006 if len == 1 {
2007 solver.define_const(Exp::Ite(
2008 Box::new(Exp::Eq(Box::new(Exp::Var(bv)), Box::new(smt_zeros(1)))),
2009 Box::new(smt_i128(1)),
2010 Box::new(smt_i128(0)),
2011 ))
2012 } else {
2013 let low_len = len / 2;
2014 let top_len = len - low_len;
2015
2016 let top = solver.define_const(Exp::Extract(len - 1, low_len, Box::new(Exp::Var(bv))));
2017 let low = solver.define_const(Exp::Extract(low_len - 1, 0, Box::new(Exp::Var(bv))));
2018
2019 let top_bits_are_zero = Exp::Eq(Box::new(Exp::Var(top)), Box::new(smt_zeros(top_len as i128)));
2020
2021 let top_clz = smt_clz(top, top_len, solver);
2022 let low_clz = smt_clz(low, low_len, solver);
2023
2024 solver.define_const(Exp::Ite(
2025 Box::new(top_bits_are_zero),
2026 Box::new(Exp::Bvadd(Box::new(smt_i128(top_len as i128)), Box::new(Exp::Var(low_clz)))),
2027 Box::new(Exp::Var(top_clz)),
2028 ))
2029 }
2030}
2031
2032fn count_leading_zeros<B: BV>(bv: Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
2033 match bv {
2034 Val::Bits(bv) => Ok(Val::I128(bv.leading_zeros() as i128)),
2035 Val::Symbolic(bv) => {
2036 if let Some(len) = solver.length(bv) {
2037 smt_clz(bv, len, solver).into()
2038 } else {
2039 Err(ExecError::Type("count_leading_zeros (solver could not determine length)".to_string()))
2040 }
2041 }
2042 _ => Err(ExecError::Type(format!("count_leading_zeros {:?}", &bv))),
2043 }
2044}
2045
2046fn build_ite<B: BV>(b: Sym, lhs: &Val<B>, rhs: &Val<B>, solver: &mut Solver<B>) -> Result<Val<B>, ExecError> {
2047 match (lhs, rhs) {
2048 (Val::Struct(l_fields), Val::Struct(r_fields)) => {
2049 let fields: Result<_, _> = l_fields
2050 .iter()
2051 .map(|(k, l_val)| match r_fields.get(k) {
2052 None => Err(ExecError::Type(format!("build_ite {:?}", &k))),
2053 Some(r_val) => Ok((*k, build_ite(b, l_val, r_val, solver)?)),
2054 })
2055 .collect();
2056 Ok(Val::Struct(fields?))
2057 }
2058 _ => solver
2059 .define_const(Exp::Ite(Box::new(Exp::Var(b)), Box::new(smt_value(lhs)?), Box::new(smt_value(rhs)?)))
2060 .into(),
2061 }
2062}
2063
2064fn ite<B: BV>(args: Vec<Val<B>>, solver: &mut Solver<B>, _: &mut LocalFrame<B>) -> Result<Val<B>, ExecError> {
2065 match args[0] {
2066 Val::Symbolic(b) => build_ite(b, &args[1], &args[2], solver),
2067 Val::Bool(true) => Ok(args[1].clone()),
2068 Val::Bool(false) => Ok(args[2].clone()),
2069 _ => Err(ExecError::Type(format!("ite {:?}", &args[0]))),
2070 }
2071}
2072
2073pub fn unary_primops<B: BV>() -> HashMap<String, Unary<B>> {
2074 let mut primops = HashMap::new();
2075 primops.insert("%i64->%i".to_string(), i64_to_i128 as Unary<B>);
2076 primops.insert("%i->%i64".to_string(), i128_to_i64 as Unary<B>);
2077 primops.insert("%string->%i".to_string(), string_to_i128 as Unary<B>);
2078 primops.insert("bit_to_bool".to_string(), bit_to_bool as Unary<B>);
2079 primops.insert("assume".to_string(), assume as Unary<B>);
2080 primops.insert("not".to_string(), not_bool as Unary<B>);
2081 primops.insert("neg_int".to_string(), neg_int as Unary<B>);
2082 primops.insert("abs_int".to_string(), abs_int as Unary<B>);
2083 primops.insert("pow2".to_string(), pow2 as Unary<B>);
2084 primops.insert("not_bits".to_string(), not_bits as Unary<B>);
2085 primops.insert("length".to_string(), length as Unary<B>);
2086 primops.insert("zeros".to_string(), zeros as Unary<B>);
2087 primops.insert("ones".to_string(), ones as Unary<B>);
2088 primops.insert("sail_unsigned".to_string(), sail_unsigned as Unary<B>);
2089 primops.insert("sail_signed".to_string(), sail_signed as Unary<B>);
2090 primops.insert("sail_putchar".to_string(), putchar as Unary<B>);
2091 primops.insert("print".to_string(), print as Unary<B>);
2092 primops.insert("prerr".to_string(), prerr as Unary<B>);
2093 primops.insert("print_endline".to_string(), print_endline as Unary<B>);
2094 primops.insert("prerr_endline".to_string(), prerr_endline as Unary<B>);
2095 primops.insert("count_leading_zeros".to_string(), count_leading_zeros as Unary<B>);
2096 primops.insert("undefined_bitvector".to_string(), undefined_bitvector as Unary<B>);
2097 primops.insert("undefined_bool".to_string(), undefined_bool as Unary<B>);
2098 primops.insert("undefined_int".to_string(), undefined_int as Unary<B>);
2099 primops.insert("undefined_nat".to_string(), undefined_nat as Unary<B>);
2100 primops.insert("undefined_unit".to_string(), undefined_unit as Unary<B>);
2101 primops.insert("undefined_string".to_string(), undefined_string as Unary<B>);
2102 primops.insert("one_if".to_string(), one_if as Unary<B>);
2103 primops.insert("zero_if".to_string(), zero_if as Unary<B>);
2104 primops.insert("internal_pick".to_string(), choice as Unary<B>);
2105 primops.insert("bad_read".to_string(), bad_read as Unary<B>);
2106 primops.insert("bad_write".to_string(), bad_write as Unary<B>);
2107 primops.insert("hex_str".to_string(), hex_str as Unary<B>);
2108 primops.insert("dec_str".to_string(), dec_str as Unary<B>);
2109 primops.insert("string_length".to_string(), string_length as Unary<B>);
2110 primops.insert("string_of_bits".to_string(), string_of_bits as Unary<B>);
2111 primops.insert("decimal_string_of_bits".to_string(), decimal_string_of_bits as Unary<B>);
2112 primops.insert("string_of_int".to_string(), string_of_int as Unary<B>);
2113 primops.insert("cycle_count".to_string(), cycle_count as Unary<B>);
2114 primops.insert("get_cycle_count".to_string(), get_cycle_count as Unary<B>);
2115 primops.insert("sail_get_verbosity".to_string(), get_verbosity as Unary<B>);
2116 primops.insert("sleeping".to_string(), sleeping as Unary<B>);
2117 primops.insert("sleep_request".to_string(), sleep_request as Unary<B>);
2118 primops.insert("wakeup_request".to_string(), wakeup_request as Unary<B>);
2119 primops.insert("platform_instr_announce".to_string(), instr_announce as Unary<B>);
2120 primops.insert("platform_barrier".to_string(), barrier as Unary<B>);
2121 primops.insert("monomorphize".to_string(), monomorphize as Unary<B>);
2122 primops
2123}
2124
2125pub fn binary_primops<B: BV>() -> HashMap<String, Binary<B>> {
2126 let mut primops = HashMap::new();
2127 primops.insert("optimistic_assert".to_string(), optimistic_assert as Binary<B>);
2128 primops.insert("pessimistic_assert".to_string(), pessimistic_assert as Binary<B>);
2129 primops.insert("and_bool".to_string(), and_bool as Binary<B>);
2130 primops.insert("strict_and_bool".to_string(), and_bool as Binary<B>);
2131 primops.insert("or_bool".to_string(), or_bool as Binary<B>);
2132 primops.insert("strict_or_bool".to_string(), or_bool as Binary<B>);
2133 primops.insert("eq_int".to_string(), eq_int as Binary<B>);
2134 primops.insert("eq_bool".to_string(), eq_bool as Binary<B>);
2135 primops.insert("lteq".to_string(), lteq_int as Binary<B>);
2136 primops.insert("gteq".to_string(), gteq_int as Binary<B>);
2137 primops.insert("lt".to_string(), lt_int as Binary<B>);
2138 primops.insert("gt".to_string(), gt_int as Binary<B>);
2139 primops.insert("add_int".to_string(), add_int as Binary<B>);
2140 primops.insert("sub_int".to_string(), sub_int as Binary<B>);
2141 primops.insert("sub_nat".to_string(), sub_nat as Binary<B>);
2142 primops.insert("mult_int".to_string(), mult_int as Binary<B>);
2143 primops.insert("tdiv_int".to_string(), tdiv_int as Binary<B>);
2144 primops.insert("tmod_int".to_string(), tmod_int as Binary<B>);
2145 primops.insert("ediv_int".to_string(), tdiv_int as Binary<B>);
2147 primops.insert("emod_int".to_string(), tmod_int as Binary<B>);
2148 primops.insert("pow_int".to_string(), pow_int as Binary<B>);
2149 primops.insert("shl_int".to_string(), shl_int as Binary<B>);
2150 primops.insert("shr_int".to_string(), shr_int as Binary<B>);
2151 primops.insert("shl_mach_int".to_string(), shl_mach_int as Binary<B>);
2152 primops.insert("shr_mach_int".to_string(), shr_mach_int as Binary<B>);
2153 primops.insert("max_int".to_string(), max_int as Binary<B>);
2154 primops.insert("min_int".to_string(), min_int as Binary<B>);
2155 primops.insert("eq_bit".to_string(), eq_bits as Binary<B>);
2156 primops.insert("eq_bits".to_string(), eq_bits as Binary<B>);
2157 primops.insert("neq_bits".to_string(), neq_bits as Binary<B>);
2158 primops.insert("xor_bits".to_string(), xor_bits as Binary<B>);
2159 primops.insert("or_bits".to_string(), or_bits as Binary<B>);
2160 primops.insert("and_bits".to_string(), and_bits as Binary<B>);
2161 primops.insert("add_bits".to_string(), add_bits as Binary<B>);
2162 primops.insert("sub_bits".to_string(), sub_bits as Binary<B>);
2163 primops.insert("add_bits_int".to_string(), add_bits_int as Binary<B>);
2164 primops.insert("sub_bits_int".to_string(), sub_bits_int as Binary<B>);
2165 primops.insert("align_bits".to_string(), align_bits as Binary<B>);
2166 primops.insert("undefined_range".to_string(), undefined_range as Binary<B>);
2167 primops.insert("zero_extend".to_string(), zero_extend as Binary<B>);
2168 primops.insert("sign_extend".to_string(), sign_extend as Binary<B>);
2169 primops.insert("sail_truncate".to_string(), sail_truncate as Binary<B>);
2170 primops.insert("sail_truncateLSB".to_string(), sail_truncate_lsb as Binary<B>);
2171 primops.insert("replicate_bits".to_string(), replicate_bits as Binary<B>);
2172 primops.insert("shiftr".to_string(), shiftr as Binary<B>);
2173 primops.insert("shiftl".to_string(), shiftl as Binary<B>);
2174 primops.insert("arith_shiftr".to_string(), arith_shiftr as Binary<B>);
2175 primops.insert("shift_bits_right".to_string(), shift_bits_right as Binary<B>);
2176 primops.insert("shift_bits_left".to_string(), shift_bits_left as Binary<B>);
2177 primops.insert("append".to_string(), append as Binary<B>);
2178 primops.insert("append_64".to_string(), append as Binary<B>);
2179 primops.insert("vector_access".to_string(), vector_access as Binary<B>);
2180 primops.insert("eq_anything".to_string(), eq_anything as Binary<B>);
2181 primops.insert("eq_string".to_string(), eq_string as Binary<B>);
2182 primops.insert("concat_str".to_string(), concat_str as Binary<B>);
2183 primops.insert("string_startswith".to_string(), string_startswith as Binary<B>);
2184 primops.insert("string_drop".to_string(), string_drop as Binary<B>);
2185 primops.insert("string_take".to_string(), string_take as Binary<B>);
2186 primops.insert("cons".to_string(), cons as Binary<B>);
2187 primops.insert("undefined_vector".to_string(), undefined_vector as Binary<B>);
2188 primops.insert("print_string".to_string(), print_string as Binary<B>);
2189 primops.insert("prerr_string".to_string(), prerr_string as Binary<B>);
2190 primops.insert("print_int".to_string(), print_int as Binary<B>);
2191 primops.insert("prerr_int".to_string(), prerr_int as Binary<B>);
2192 primops.insert("print_bits".to_string(), print_bits as Binary<B>);
2193 primops.insert("prerr_bits".to_string(), prerr_bits as Binary<B>);
2194 primops.insert("platform_branch_announce".to_string(), branch_announce as Binary<B>);
2195 primops.insert("mark_register".to_string(), mark_register as Binary<B>);
2196 primops
2197}
2198
2199pub fn variadic_primops<B: BV>() -> HashMap<String, Variadic<B>> {
2200 let mut primops = HashMap::new();
2201 primops.insert("slice".to_string(), slice as Variadic<B>);
2202 primops.insert("vector_subrange".to_string(), subrange as Variadic<B>);
2203 primops.insert("vector_update".to_string(), vector_update as Variadic<B>);
2204 primops.insert("vector_update_subrange".to_string(), vector_update_subrange as Variadic<B>);
2205 primops.insert("bitvector_update".to_string(), bitvector_update as Variadic<B>);
2206 primops.insert("set_slice".to_string(), set_slice as Variadic<B>);
2207 primops.insert("get_slice_int".to_string(), get_slice_int as Variadic<B>);
2208 primops.insert("set_slice_int".to_string(), set_slice_int as Variadic<B>);
2209 primops.insert("platform_read_mem".to_string(), read_mem as Variadic<B>);
2210 primops.insert("platform_read_memt".to_string(), read_memt as Variadic<B>);
2211 primops.insert("platform_write_mem".to_string(), write_mem as Variadic<B>);
2212 primops.insert("platform_write_memt".to_string(), write_memt as Variadic<B>);
2213 primops.insert("platform_write_mem_ea".to_string(), write_mem_ea as Variadic<B>);
2214 primops.insert("platform_cache_maintenance".to_string(), cache_maintenance as Variadic<B>);
2215 primops.insert("elf_entry".to_string(), elf_entry as Variadic<B>);
2216 primops.insert("ite".to_string(), ite as Variadic<B>);
2217 primops.insert("mark_register_pair".to_string(), mark_register_pair as Variadic<B>);
2218 primops.insert("%string->%real".to_string(), unimplemented as Variadic<B>);
2220 primops.insert("neg_real".to_string(), unimplemented as Variadic<B>);
2221 primops.insert("mult_real".to_string(), unimplemented as Variadic<B>);
2222 primops.insert("sub_real".to_string(), unimplemented as Variadic<B>);
2223 primops.insert("add_real".to_string(), unimplemented as Variadic<B>);
2224 primops.insert("div_real".to_string(), unimplemented as Variadic<B>);
2225 primops.insert("sqrt_real".to_string(), unimplemented as Variadic<B>);
2226 primops.insert("abs_real".to_string(), unimplemented as Variadic<B>);
2227 primops.insert("round_down".to_string(), unimplemented as Variadic<B>);
2228 primops.insert("round_up".to_string(), unimplemented as Variadic<B>);
2229 primops.insert("to_real".to_string(), unimplemented as Variadic<B>);
2230 primops.insert("eq_real".to_string(), unimplemented as Variadic<B>);
2231 primops.insert("lt_real".to_string(), unimplemented as Variadic<B>);
2232 primops.insert("gt_real".to_string(), unimplemented as Variadic<B>);
2233 primops.insert("lteq_real".to_string(), unimplemented as Variadic<B>);
2234 primops.insert("gteq_real".to_string(), unimplemented as Variadic<B>);
2235 primops.insert("real_power".to_string(), unimplemented as Variadic<B>);
2236 primops.insert("print_real".to_string(), unimplemented as Variadic<B>);
2237 primops.insert("prerr_real".to_string(), unimplemented as Variadic<B>);
2238 primops.insert("undefined_real".to_string(), unimplemented as Variadic<B>);
2239 primops
2240}
2241
2242pub struct Primops<B> {
2243 pub unary: HashMap<String, Unary<B>>,
2244 pub binary: HashMap<String, Binary<B>>,
2245 pub variadic: HashMap<String, Variadic<B>>,
2246}
2247
2248impl<B: BV> Default for Primops<B> {
2249 fn default() -> Self {
2250 Primops { unary: unary_primops(), binary: binary_primops(), variadic: variadic_primops() }
2251 }
2252}