BDD bits_range_bdd(uint32_t low_bits,uint32_t high_bits) { BDD rval,tail,newbdd; int i; uint32_t b; if (low_bits>0) { tail=bddtrue; for (i=31,b=1;i>=0;i--,b<<=1) { if (low_bits&b) newbdd=bdd_addref(bdd_and(bdd_ithvar(i),tail)); else newbdd=bdd_addref(bdd_or(bdd_ithvar(i),tail)); bdd_delref(tail); tail=newbdd; } rval=tail; } else rval=bddtrue; if (high_bits<UINT32_MAX) { tail=bddtrue; for (i=31,b=1;i>=0;i--,b<<=1) { if (high_bits&b) newbdd=bdd_addref(bdd_or(bdd_nithvar(i),tail)); else newbdd=bdd_addref(bdd_and(bdd_nithvar(i),tail)); bdd_delref(tail); tail=newbdd; } rval=bdd_addref(bdd_and(rval,tail)); bdd_delref(tail); } return rval; }
void set_range_width(uint32_t low_code,uint32_t high_code,int width) { BDD x,y; /* sanity check */ if (low_code>high_code) return; /* make a BDD for the range */ x=code_range_bdd(low_code,high_code); /* if (in range) /\ (already defined) === true, we've been pre-empted */ y=bdd_and(x,defined_codes); /* note no addref, we don't need it */ if (y==x) { bdd_delref(x); return; } /* if (in range) /\ (already defined) !== false, must split */ if (y!=bddfalse) { bdd_delref(x); set_range_width(low_code,(low_code+high_code)/2,width); set_range_width((low_code+high_code)/2+1,high_code,width); return; } y=bdd_addref(bdd_or(x,defined_codes)); bdd_delref(defined_codes); defined_codes=y; if (width==0) { y=bdd_addref(bdd_or(x,zero_codes)); bdd_delref(zero_codes); zero_codes=y; } else if (width==2) { y=bdd_addref(bdd_or(x,wide_codes)); bdd_delref(wide_codes); wide_codes=y; } bdd_delref(x); }
BDD pre_all(TransitionSystem *model, BDD p) { //pre_all = S - pre_exists(S - p) where S is the set of all states BDD S = bdd_addref(bdd_or(model->all_states, model->pseudo_end)); BDD s_diff_p = bdd_addref(bdd_apply(S, p, bddop_diff)); BDD pres = bdd_addref(pre_exists(model, s_diff_p)); BDD res = bdd_apply(model->all_states, pres, bddop_diff); bdd_delref(s_diff_p); bdd_delref(pres); bdd_delref(S); return res; }
BDD code_range_bdd(uint32_t low_code,uint32_t high_code) { BDD rval,subrange,srx; if (low_code<0x80) rval=bits_range_bdd((low_code<<24), (high_code>=0x80? 0x7FFFFFFF: high_code<<24)); else rval=bddfalse; if ((low_code<0x800) && (high_code>=0x80)) { subrange=bits_range_bdd((low_code<0x80? 0xC2800000: ((low_code& 0x3F)<<16)+ ((low_code&0x7C0)<<18)+ 0xC0800000), (high_code>=0x800? 0xDFBFFFFF: ((high_code& 0x3F)<<16)+ ((high_code&0x7C0)<<18)+ 0xC080FFFF)); srx=bdd_addref(bdd_and(subrange,bdd_nithvar(9))); bdd_delref(subrange); subrange=bdd_addref(bdd_and(srx,bdd_ithvar(8))); bdd_delref(srx); srx=bdd_addref(bdd_or(rval,subrange)); bdd_delref(rval); bdd_delref(subrange); rval=srx; } if ((low_code<0x10000) && (high_code>=0x800)) { subrange=bits_range_bdd((low_code<0x800? 0xE0A00000: ((low_code& 0x3F)<<8)+ ((low_code& 0xFC0)<<10)+ ((low_code&0xF000)<<12)+ 0xE0808000), (high_code>=0x10000? 0xEFBFBFFF: ((high_code& 0x3F)<<8)+ ((high_code& 0xFC0)<<10)+ ((high_code&0xF000)<<12)+ 0xE08080FF)); srx=bdd_addref(bdd_and(subrange,bdd_nithvar(17))); bdd_delref(subrange); subrange=bdd_addref(bdd_and(srx,bdd_ithvar(16))); bdd_delref(srx); srx=bdd_addref(bdd_and(subrange,bdd_nithvar(9))); bdd_delref(subrange); subrange=bdd_addref(bdd_and(srx,bdd_ithvar(8))); bdd_delref(srx); srx=bdd_addref(bdd_or(rval,subrange)); bdd_delref(rval); bdd_delref(subrange); rval=srx; } if (high_code>=0x10000) { subrange=bits_range_bdd((low_code<0x10000? 0xF0900000: (low_code& 0x3F)+ ((low_code& 0xFC0)<<2)+ ((low_code& 0x3F000)<<4)+ ((low_code&0x1C0000)<<6)+ 0xF0808080), (high_code& 0x3F)+ ((high_code& 0xFC0)<<2)+ ((high_code& 0x3F000)<<4)+ ((high_code&0x1C0000)<<6)+ 0xF0808080); srx=bdd_addref(bdd_and(subrange,bdd_nithvar(25))); bdd_delref(subrange); subrange=bdd_addref(bdd_and(srx,bdd_ithvar(24))); bdd_delref(srx); srx=bdd_addref(bdd_and(subrange,bdd_nithvar(17))); bdd_delref(subrange); subrange=bdd_addref(bdd_and(srx,bdd_ithvar(16))); bdd_delref(srx); srx=bdd_addref(bdd_and(subrange,bdd_nithvar(9))); bdd_delref(subrange); subrange=bdd_addref(bdd_and(srx,bdd_ithvar(8))); bdd_delref(srx); srx=bdd_addref(bdd_or(rval,subrange)); bdd_delref(rval); bdd_delref(subrange); rval=srx; } return rval; }