use crate::{
abstr::BitvectorDomain,
backward::RExt,
bitvector::{
abstr::three_valued::RThreeValuedBitvector, refin::three_valued::RMarkBitvector, RBound,
},
concr::ConcreteBitvector,
misc::BitvectorBound,
refin::RefinementDomain,
traits::forward,
};
impl RExt for RThreeValuedBitvector {
type Mark = RMarkBitvector;
fn uext(normal_input: (Self,), mark_later: RMarkBitvector) -> (RMarkBitvector,) {
let earlier_bound = normal_input.0.bound();
let earlier_width = earlier_bound.width();
let Some(mark_later) = mark_later.inner else {
return (RMarkBitvector::new_unmarked(earlier_width),);
};
let mark_earlier = forward::BExt::uext(mark_later.mark, earlier_bound);
let extended = RMarkBitvector::new(mark_earlier, mark_later.importance, earlier_width);
(extended.limit(&normal_input.0),)
}
fn sext(normal_input: (Self,), mark_later: RMarkBitvector) -> (RMarkBitvector,) {
let earlier_bound = normal_input.0.bound();
let earlier_width = earlier_bound.width();
let later_width = mark_later.width;
let later_bound = RBound::new(later_width);
let Some(mark_later) = mark_later.inner else {
return (RMarkBitvector::new_unmarked(earlier_width),);
};
let mut extended = forward::BExt::uext(mark_later.mark, earlier_bound);
let unextended = forward::BExt::uext(extended, later_bound);
if later_width > earlier_width && mark_later.mark != unextended {
extended = crate::forward::Bitwise::bit_or(
extended,
ConcreteBitvector::bit_mask(earlier_bound),
);
}
let extended = RMarkBitvector::new(extended, mark_later.importance, earlier_width);
(extended.limit(&normal_input.0),)
}
}