bvt boolbvt::convert_union(const union_exprt &expr) { std::size_t width=boolbv_width(expr.type()); if(width==0) return conversion_failed(expr); const bvt &op_bv=convert_bv(expr.op()); if(width<op_bv.size()) throw "union: unexpected operand op width"; bvt bv; bv.resize(width); if(config.ansi_c.endianness==configt::ansi_ct::endiannesst::IS_LITTLE_ENDIAN) { for(std::size_t i=0; i<op_bv.size(); i++) bv[i]=op_bv[i]; // pad with nondets for(std::size_t i=op_bv.size(); i<bv.size(); i++) bv[i]=prop.new_variable(); } else { assert( config.ansi_c.endianness==configt::ansi_ct::endiannesst::IS_BIG_ENDIAN); endianness_mapt map_u(expr.type(), false, ns); endianness_mapt map_op(expr.op0().type(), false, ns); for(std::size_t i=0; i<op_bv.size(); i++) bv[map_u.map_bit(i)]=op_bv[map_op.map_bit(i)]; // pad with nondets for(std::size_t i=op_bv.size(); i<bv.size(); i++) bv[map_u.map_bit(i)]=prop.new_variable(); } return bv; }
int input_mapper_add(struct list_head *mappers, struct imapper *entry, int (*map_op)(void *, struct imapper *), void *data) { struct list_head *pos, *pre, *head; struct imapper *pre_ent, *pos_ent; head = mappers; if (list_empty(head)) { entry->next = entry->addr; map_op(data, entry); list_add(&entry->list, head); return 0; } list_for_each(pos, head) { pos_ent = list_entry(pos, struct imapper, list); if (pos_ent->slot > entry->slot) { /* found a position in list */ break; } }
bvt boolbvt::convert_byte_update(const byte_update_exprt &expr) { if(expr.operands().size()!=3) throw "byte_update takes three operands"; const exprt &op=expr.op0(); const exprt &offset_expr=expr.offset(); const exprt &value=expr.value(); bool little_endian; if(expr.id()==ID_byte_update_little_endian) little_endian=true; else if(expr.id()==ID_byte_update_big_endian) little_endian=false; else assert(false); bvt bv=convert_bv(op); const bvt &value_bv=convert_bv(value); std::size_t update_width=value_bv.size(); std::size_t byte_width=8; if(update_width>bv.size()) update_width=bv.size(); // see if the byte number is constant mp_integer index; if(!to_integer(offset_expr, index)) { // yes! mp_integer offset=index*8; if(offset+update_width>mp_integer(bv.size()) || offset<0) { // out of bounds } else { if(little_endian) { for(std::size_t i=0; i<update_width; i++) bv[integer2size_t(offset+i)]=value_bv[i]; } else { endianness_mapt map_op(op.type(), false, ns); endianness_mapt map_value(value.type(), false, ns); std::size_t offset_i=integer2unsigned(offset); for(std::size_t i=0; i<update_width; i++) { size_t index_op=map_op.map_bit(offset_i+i); size_t index_value=map_value.map_bit(i); assert(index_op<bv.size()); assert(index_value<value_bv.size()); bv[index_op]=value_bv[index_value]; } } } return bv; } // byte_update with variable index for(std::size_t offset=0; offset<bv.size(); offset+=byte_width) { // index condition equal_exprt equality; equality.lhs()=offset_expr; equality.rhs()=from_integer(offset/byte_width, offset_expr.type()); literalt equal=convert(equality); endianness_mapt map_op(op.type(), little_endian, ns); endianness_mapt map_value(value.type(), little_endian, ns); for(std::size_t bit=0; bit<update_width; bit++) if(offset+bit<bv.size()) { std::size_t bv_o=map_op.map_bit(offset+bit); std::size_t value_bv_o=map_value.map_bit(bit); bv[bv_o]=prop.lselect(equal, value_bv[value_bv_o], bv[bv_o]); } } return bv; }