$$ = n;
delete $1;
}
-| Expr BVRIGHTSHIFT_TOK NUMERAL_TOK
+| Expr BVRIGHTSHIFT_TOK NUMERAL_TOK
{
ASTNode len = ParserBM->CreateZeroConst($3);
unsigned int w = $1->GetValueWidth();
ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVCONCAT, w,len, extract));
BVTypeCheck(*n);
$$ = n;
- }
+ }
else
- $$ = new ASTNode(ParserBM->CreateZeroConst(w));
+ $$ = new ASTNode(ParserBM->CreateZeroConst(w));
delete $1;
}
-/* | Expr BVRIGHTSHIFT_TOK Expr */
-/* { */
-/* //$1 is being shifted by variable shift amount $3 */
-/* // */
+| Expr BVRIGHTSHIFT_TOK Expr
+{
+ // VARIABLE RIGHT SHIFT
+ //
+ // $1 (THEEXPR) is being shifted
+ //
+ // $3 is the variable shift amount
+ ASTNode inputExpr = *$1;
+ ASTNode varShiftAmt = *$3;
-/* delete $1; */
-/* delete $3; */
-/* } */
+ unsigned int exprWidth = $1->GetValueWidth();
+ unsigned int shiftAmtWidth = $3->GetValueWidth();
+ ASTNode exprWidthNode = ParserBM->CreateBVConst(shiftAmtWidth, exprWidth);
+
+ ASTNode cond, thenExpr, elseExpr;
+ unsigned int count = 0;
+ ASTNode hi = ParserBM->CreateBVConst(32,exprWidth-1);
+ while(count < exprWidth)
+ {
+ if(0 == count)
+ {
+ // if count is zero then the appropriate rightshift expression is
+ // THEEXPR itself
+ elseExpr = inputExpr;
+ }
+ else
+ {
+ // 1 <= count < exprWidth
+ //
+ // Construct appropriate conditional
+ ASTNode countNode = ParserBM->CreateBVConst(shiftAmtWidth, count);
+ cond = ParserBM->CreateNode(EQ, countNode, varShiftAmt);
+
+ //Construct the rightshift expression padding @ Expr[hi:low]
+ ASTNode low =
+ ParserBM->CreateBVConst(32,count);
+ ASTNode extract =
+ ParserBM->CreateTerm(BVEXTRACT,exprWidth-count,inputExpr,hi,low);
+ ASTNode padding =
+ ParserBM->CreateZeroConst(count);
+ thenExpr =
+ ParserBM->CreateTerm(BVCONCAT, exprWidth, padding, extract);
+ ASTNode ite =
+ ParserBM->CreateTerm(ITE, exprWidth, cond, thenExpr, elseExpr);
+ BVTypeCheck(ite);
+ elseExpr = ite;
+ }
+ count++;
+ } //End of while loop
+
+ // if shiftamount is greater than or equal to exprwidth, then
+ // output is zero.
+ cond = ParserBM->CreateNode(BVGE, varShiftAmt, exprWidthNode);
+ thenExpr = ParserBM->CreateZeroConst(exprWidth);
+ ASTNode * ret =
+ new ASTNode(ParserBM->CreateTerm(ITE,
+ exprWidth,
+ cond, thenExpr, elseExpr));
+ BVTypeCheck(*ret);
+ //cout << *ret;
+
+ $$ = ret;
+ delete $1;
+ delete $3;
+}
| BVPLUS_TOK '(' NUMERAL_TOK ',' Exprs ')'
{
ASTNode * n = new ASTNode(ParserBM->CreateTerm(BVPLUS, $3, *$5));