CBV bv = CONSTANTBV::BitVector_Create(width, true);
- unsigned long c_val = (0x00000000ffffffffLL) & bvconst;
+ unsigned long c_val = (~((unsigned long)0)) & bvconst;
unsigned int copied = 0;
// sizeof(unsigned long) returns the number of bytes in unsigned
while(copied + (sizeof(unsigned long)<<3) < width){
CONSTANTBV::BitVector_Chunk_Store(bv, sizeof(unsigned long)<<3,copied,c_val);
bvconst = bvconst >> (sizeof(unsigned long) << 3);
- c_val = (0x00000000ffffffffLL) & bvconst;
+ c_val = (~((unsigned long)0)) & bvconst;
copied += sizeof(unsigned long) << 3;
}
CONSTANTBV::BitVector_Chunk_Store(bv,width - copied,copied,c_val);
return CreateBVConst(bv,width);
}
+ ASTNode BeevMgr::CreateBVConst(string*& strval, unsigned int base, size_t bit_width) {
+
+ if(!(2 == base || 10 == base || 16 == base))
+ {
+ FatalError("CreateBVConst: unsupported base: ",ASTUndefined,base);
+ }
+
+ //checking if the input is in the correct format
+ CBV bv = CONSTANTBV::BitVector_Create(bit_width,true);
+ CONSTANTBV::ErrCode e;
+ if(2 == base){
+ e = CONSTANTBV::BitVector_from_Bin(bv, (unsigned char*) strval->c_str());
+ }else if(10 == base){
+ e = CONSTANTBV::BitVector_from_Dec(bv, (unsigned char*) strval->c_str());
+ }else if(16 == base){
+ e = CONSTANTBV::BitVector_from_Hex(bv, (unsigned char*) strval->c_str());
+ }else{
+ e = CONSTANTBV::ErrCode_Pars;
+ }
+
+ if(0 != e) {
+ cerr << "CreateBVConst: " << BitVector_Error(e);
+ FatalError("",ASTUndefined);
+ }
+
+ return CreateBVConst(bv, bit_width);
+ }
+
+
+
//Create a ASTBVConst node from std::string
ASTNode BeevMgr::CreateBVConst(const char* const strval, int base) {
size_t width = strlen((const char *)strval);
CBV GetBVConst() const {return _bvconst;}
}; //End of ASTBVConst
- //FIXME This function is DEPRICATED
+
+ //FIXME This function is DEPRECATED
//Do not use in the future
- inline unsigned int GetUnsignedConst(const ASTNode n) {
- if(32 < n.GetValueWidth())
- FatalError("GetUnsignedConst: cannot convert bvconst of length greater than 32 to unsigned int:");
-
+ inline unsigned int GetUnsignedConst(const ASTNode n)
+ {
+ if(sizeof(unsigned int) * 8 <= n.GetValueWidth())
+ {
+ // It may only contain a small value in a bit type, which fits nicely into an unsigned int.
+ // This is common for functions like: bvshl(bv1[128], bv1[128])
+ // where both operands have the same type.
+ unsigned long maxBit = (unsigned) CONSTANTBV::Set_Max(n.GetBVConst());
+ if (maxBit >= sizeof(unsigned int) * 8 )
+ {
+ n.LispPrint(cerr); //print the node so they can find it.
+ FatalError("GetUnsignedConst: cannot convert bvconst of length greater than 32 to unsigned int");
+ }
+ }
return (unsigned int) *((unsigned int *)n.GetBVConst());
}
#else
void BBLShift(ASTVec& x);
void BBRShift(ASTVec& x);
+ void BBLShift(ASTVec& x, unsigned int shift);
+ void BBRShift(ASTVec& x, unsigned int shift);
+
public:
// Simplifying create functions
ASTNode CreateSimpForm(Kind kind, ASTVec &children);
// Create and return an ASTNode for a symbol
// Width is number of bits.
+ ASTNode CreateBVConst(string*& strval, unsigned int base, size_t bit_width);
ASTNode CreateBVConst(unsigned int width, unsigned long long int bvconst);
ASTNode CreateZeroConst(unsigned int width);
ASTNode CreateOneConst(unsigned int width);
ASTNode CreateTwoConst(unsigned int width);
ASTNode CreateMaxConst(unsigned int width);
+
// Create and return an ASTNode for a symbol
// Optional base was a problem because 0 could be an int or char *,
// so CreateBVConst was ambiguous.
result = CreateNode(BOOLVEC, BBNeg(bbkids.GetChildren()));
break;
}
+
+ case BVLEFTSHIFT:
+ {
+ if (BVCONST == term[1].GetKind())
+ {
+ // Constant shifts should be removed during simplification.
+ unsigned int shift = GetUnsignedConst(term[1]);
+
+ ASTNode term0 = BBTerm(term[0]);
+ ASTVec children(term0.GetChildren()); // mutable copy of the children.
+ BBLShift(children, shift);
+
+ result = CreateNode(BOOLVEC, children);
+ }
+ else
+ {
+ // Barrel shifter
+ const ASTVec& bbarg1 = BBTerm(term[0]).GetChildren();
+ const ASTVec& bbarg2 = BBTerm(term[1]).GetChildren();
+
+ ASTVec temp_result(bbarg1);
+
+ for (unsigned int i =0; i < bbarg2.size(); i++)
+ {
+ if (bbarg2[i] == ASTFalse)
+ continue; // Not shifting by anything.
+
+ unsigned int shift_amount = 1 << i;
+
+ bool done = false;
+
+ for (unsigned int j=temp_result.size()-1; !done; j--)
+ {
+ if (j < shift_amount)
+ temp_result[j] = CreateSimpForm(ITE, bbarg2[i],ASTFalse,temp_result[j]);
+ else
+ temp_result[j] = CreateSimpForm(ITE, bbarg2[i],temp_result[j-shift_amount],temp_result[j]);
+
+ // want it to stop after doing 0, but subtracting 1 from j makes it very big.
+ if (j ==0)
+ done = true;
+ }
+ }
+
+ result = CreateNode(BOOLVEC, temp_result);
+ }
+ break;
+ }
+
+ case BVRIGHTSHIFT:
+ {
+ if (BVCONST == term[1].GetKind())
+ {
+ // Constant shifts should be removed during simplification.
+
+ unsigned int shift = GetUnsignedConst(term[1]);
+
+ ASTNode term0 = BBTerm(term[0]);
+ ASTVec children(term0.GetChildren()); // mutable copy of the children.
+ BBRShift(children, shift);
+
+ result = CreateNode(BOOLVEC, children);
+ }
+ else
+ {
+ FatalError("Not implemented shift right by unk. value.");
+ }
+ }
+ break;
+
+
+
case BVSRSHIFT:
case BVVARSHIFT:
FatalError("BBTerm: These kinds have not been implemented in the BitBlaster: ", term);
CreateNode(BOOLVEC, BBITE(cond, thn.GetChildren(), els.GetChildren()));
break;
}
+
+
case BVSX: {
// Replicate high-order bit as many times as necessary.
// Arg 0 is expression to be sign extended.
*res_it = *bb_it;
}
// repeat MSB to fill up rest of result.
- for( ; res_it < res_end; (res_it++, bb_it++)) {
+ for( ; res_it < res_end; (res_it++)) {
*res_it = msb;
}
// lpvec(x);
}
+// Left shift within fixed field inserting zeros at LSB.
+// Writes result into first argument.
+ void BeevMgr::BBLShift(ASTVec& x, unsigned int shift)
+{
+ // left shift x (destructively) within width.
+ // loop backwards so that copy to self works correctly. (DON'T use STL insert!)
+ ASTVec::iterator xbeg = x.begin();
+ ASTVec::iterator xit = x.end()-1;
+ for(; xit >= xbeg; xit--) {
+ if (xit-shift >= xbeg)
+ *xit = *(xit-shift);
+ else
+ *xit= ASTFalse; // new LSB is zero.
+ }
+}
+
+// Right shift within fixed field inserting zeros at MSB.
+// Writes result into first argument.
+ void BeevMgr::BBRShift(ASTVec& x, unsigned int shift)
+{
+ // right shift x (destructively) within width.
+ ASTVec::iterator xend = x.end();
+ ASTVec::iterator xit = x.begin();
+ for(; xit < xend; xit++) {
+ if (xit+shift < xend)
+ *xit = *(xit+shift);
+ else
+ *xit= ASTFalse; // new MSB is zero.
+ }
+}
+
+
+
+
// Right shift by 1 within fixed field, inserting new zeros at MSB.
// Writes result into first argument.
// Fixme: generalize to n bits.
*xit = ASTFalse; // new MSB is zero.
}
-
// Return bit-blasted form for BVLE, BVGE, BVGT, SBLE, etc.
ASTNode BeevMgr::BBcompare(const ASTNode& form) {
const ASTNode lnode = BBTerm(form[0]);
}
+ case BVLEFTSHIFT:
+ {
+ output = CONSTANTBV::BitVector_Create(inputwidth,true);
+
+ // the shift is destructive, get a copy.
+ CONSTANTBV::BitVector_Interval_Copy(output, tmp0, 0, 0, inputwidth);
+
+ // get the number of bits to shift it.
+ unsigned int shift = GetUnsignedConst(BVConstEvaluator(t[1]));
+
+ CONSTANTBV::BitVector_Move_Left(output,shift);
+ OutputNode = CreateBVConst(output,outputwidth);
+ break;
+ }
+ case BVRIGHTSHIFT:
+ {
+ output = CONSTANTBV::BitVector_Create(inputwidth,true);
+
+ // the shift is destructive, get a copy.
+ CONSTANTBV::BitVector_Interval_Copy(output, tmp0, 0, 0, inputwidth);
+
+ // get the number of bits to shift it.
+ unsigned int shift = GetUnsignedConst(BVConstEvaluator(t[1]));
+
+ CONSTANTBV::BitVector_Move_Right(output,shift);
+ OutputNode = CreateBVConst(output,outputwidth);
+ break;
+ }
+
+
case BVAND: {
output = CONSTANTBV::BitVector_Create(inputwidth,true);
CONSTANTBV::Set_Intersection(output,tmp0,tmp1);
{DIGIT}+ { yylval.uintval = strtoul(yytext, NULL, 10); return NUMERAL_TOK; }
-bv{DIGIT}+ { yylval.ullval = strtoull(yytext+2, NULL, 10); return BVCONST_TOK; }
+ bv{DIGIT}+ { yylval.str = new std::string(yytext+2); return BVCONST_TOK; }
bit{DIGIT}+ {
char c = yytext[3];
%type <str> user_value
%token <uintval> NUMERAL_TOK
-%token <ullval> BVCONST_TOK
+%token <str> BVCONST_TOK
%token <node> BITCONST_TOK
%token <node> FORMID_TOK TERMID_TOK
%token <str> STRING_TOK
an_term:
BVCONST_TOK
{
- $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst(64, $1));
+ $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst($1, 10, 32));
}
| BVCONST_TOK LBRACKET_TOK NUMERAL_TOK RBRACKET_TOK
{
- $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst($3, $1));
+ $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst($1,10,$3));
+ delete $1;
}
| an_nonbvconst_term
;
delete $2;
}
| BVLEFTSHIFT_1_TOK an_term an_term
+{
+ // shifting left by who know how much?
+ unsigned int w = $2->GetValueWidth();
+ BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVLEFTSHIFT,w,*$2,*$3));
+ BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+ $$ = n;
+ delete $2;
+ }
+ | BVRIGHTSHIFT_1_TOK an_term an_term
{
+ // shifting right by who know how much?
unsigned int w = $2->GetValueWidth();
- unsigned int shift_amt = GetUnsignedConst(*$3);
- if((unsigned)shift_amt < w) {
- BEEV::ASTNode trailing_zeros = BEEV::globalBeevMgr_for_parser->CreateBVConst(shift_amt, 0);
- BEEV::ASTNode hi = BEEV::globalBeevMgr_for_parser->CreateBVConst(32, w-shift_amt-1);
- BEEV::ASTNode low = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,0);
- BEEV::ASTNode m = BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVEXTRACT,w-shift_amt,*$2,hi,low);
- BEEV::ASTNode * n =
- new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVCONCAT,w,m,trailing_zeros));
- BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
- $$ = n;
- }
- else {
- $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst(w,0));
- }
+ BEEV::ASTNode * n = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVRIGHTSHIFT,w,*$2,*$3));
+ BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
+ $$ = n;
delete $2;
- //delete $3;
}
| BVRIGHTSHIFT_TOK an_term NUMERAL_TOK
{
}
delete $2;
}
- | BVRIGHTSHIFT_1_TOK an_term an_term
- {
- unsigned int shift_amt = GetUnsignedConst(*$3);
- BEEV::ASTNode leading_zeros = BEEV::globalBeevMgr_for_parser->CreateBVConst(shift_amt, 0);
- unsigned int w = $2->GetValueWidth();
-
- //the amount by which you are rightshifting
- //is less-than/equal-to the length of input
- //bitvector
- if((unsigned)shift_amt < w) {
- BEEV::ASTNode hi = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,w-1);
- BEEV::ASTNode low = BEEV::globalBeevMgr_for_parser->CreateBVConst(32,shift_amt);
- BEEV::ASTNode extract = BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVEXTRACT,w-shift_amt,*$2,hi,low);
- BEEV::ASTNode * n =
- new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateTerm(BEEV::BVCONCAT, w,leading_zeros, extract));
- BEEV::globalBeevMgr_for_parser->BVTypeCheck(*n);
- $$ = n;
- }
- else {
- $$ = new BEEV::ASTNode(BEEV::globalBeevMgr_for_parser->CreateBVConst(w,0));
- }
- delete $2;
- }
| BVARITHRIGHTSHIFT_TOK an_term an_term
{
unsigned int shift_amt = GetUnsignedConst(*$3);
}
break;
}
+ case BVZX:
+ {
+ //a0 is the expr which is being zero extended
+ ASTNode a0 = SimplifyTerm(inputterm[0]);
+ //a1 represents the length of the term BVZX(a0)
+ ASTNode a1 = inputterm[1];
+ //output length of the BVSX term
+ unsigned len = inputValueWidth;
+
+ output = CreateTerm(BVZX,len,a0,a1);
+ break;
+ }
+ break;
+
case BVSX:{
//a0 is the expr which is being sign extended
ASTNode a0 = SimplifyTerm(inputterm[0]);
output = CreateSimplifiedTermITE(t0,t1,t2);
break;
}
+ case SBVREM:
case SBVMOD:
case SBVDIV: {
ASTVec c = inputterm.GetChildren();
}
case WRITE:
default:
- FatalError("SimplifyTerm: Control should never reach here:", inputterm, k);
+ FatalError("SimplifyTermAux: Control should never reach here:", inputterm, k);
return inputterm;
break;
}