Package org.jakstab.solver.yices

Source Code of org.jakstab.solver.yices.YicesConversionVisitor

/*
* YicesConversionVisitor.java - This file is part of the Jakstab project.
* Copyright 2007-2012 Johannes Kinder <jk@jakstab.org>
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, see <http://www.gnu.org/licenses/>.
*/
package org.jakstab.solver.yices;

import java.util.Set;

import org.jakstab.rtl.expressions.*;
import org.jakstab.solver.UnrepresentableElementException;
import org.jakstab.util.*;

/**
* @author Johannes Kinder
*/
public class YicesConversionVisitor implements ExpressionVisitor<String> {

  @SuppressWarnings("unused")
  private static final Logger logger = Logger.getLogger(YicesConversionVisitor.class);
 
  private SetOfVariables variables = new SetOfVariables();
  private Set<Pair<String, Integer>> nondets = new FastSet<Pair<String, Integer>>();
  private int usedMemoryStates = -1;
 
  public SetOfVariables getVariables() {
    return variables;
  }

  public Set<Pair<String, Integer>> getNondets() {
    return nondets;
  }
 
  public int usedMemoryStates() {
    return usedMemoryStates;
  }

  @Override
  public String visit(RTLBitRange e) {
    return YicesWrapper.makeBVExtract(e.getOperand().accept(this),
        ((RTLNumber)e.getFirstBitIndex()).intValue(),
        ((RTLNumber)e.getLastBitIndex()).intValue());
  }

  @Override
  public String visit(RTLConditionalExpression e) {
    return YicesWrapper.makeITE(
        YicesWrapper.makeEquality(e.getCondition().accept(this), YicesSolver.yTrue),
        e.getTrueExpression().accept(this), e.getFalseExpression().accept(this));
  }
 
  private String addOffset(String address, int offset) {
    return YicesWrapper.makeBVAdd(address, YicesWrapper.makeBVConstant(32, offset));
  }

  @Override
  public String visit(RTLMemoryLocation e) {
    usedMemoryStates = Math.max(usedMemoryStates, e.getMemoryState());
    String mem = "m" + e.getMemoryState();
    if (e.getSegmentRegister() == null) {
      String address = e.getAddress().accept(this);
      String result = null;
      String curCase;
      switch (e.getBitWidth()) {
      case 32:
        curCase = YicesWrapper.makeOperation(mem, addOffset(address, 3));
        result = result != null ? YicesWrapper.makeBVConcat(result, curCase) : curCase;
      case 24:
        curCase = YicesWrapper.makeOperation(mem, addOffset(address, 2));
        result = result != null ? YicesWrapper.makeBVConcat(result, curCase) : curCase;
      case 16:
        curCase = YicesWrapper.makeOperation(mem, addOffset(address, 1));
        result = result != null ? YicesWrapper.makeBVConcat(result, curCase) : curCase;
      case 8:
        curCase = YicesWrapper.makeOperation(mem, address);
        result = result != null ? YicesWrapper.makeBVConcat(result, curCase) : curCase;
        return result;

        /*
      case 8:
        return YicesWrapper.makeOperation(mem, address);
      case 16:
        return YicesWrapper.makeBVConcat(YicesWrapper.makeOperation(mem, addOffset(address, 1)),
            YicesWrapper.makeOperation(mem, address)
            );
      case 32:
        return YicesWrapper.makeBVConcat(YicesWrapper.makeOperation(mem, addOffset(address, 3)),
            YicesWrapper.makeBVConcat(YicesWrapper.makeOperation(mem, addOffset(address, 2)),
             YicesWrapper.makeBVConcat(YicesWrapper.makeOperation(mem, addOffset(address, 1)),
              YicesWrapper.makeOperation(mem, address)
                )));
      case 64:
        return YicesWrapper.makeBVConcat(YicesWrapper.makeOperation(mem, addOffset(address, 7)),
            YicesWrapper.makeBVConcat(YicesWrapper.makeOperation(mem, addOffset(address, 6)),
             YicesWrapper.makeBVConcat(YicesWrapper.makeOperation(mem, addOffset(address, 5)),
              YicesWrapper.makeBVConcat(YicesWrapper.makeOperation(mem, addOffset(address, 4)),
               YicesWrapper.makeBVConcat(YicesWrapper.makeOperation(mem, addOffset(address, 3)),
                  YicesWrapper.makeBVConcat(YicesWrapper.makeOperation(mem, addOffset(address, 2)),
                 YicesWrapper.makeBVConcat(YicesWrapper.makeOperation(mem, addOffset(address, 1)),
                  YicesWrapper.makeOperation(mem, address)
                )))))));
                */
      default:
        throw new UnrepresentableElementException("Unsupported memory access width: " + e.getBitWidth());
      }
     
    } else {
      throw new UnrepresentableElementException("Segments not yet supported");
    }
  }

  @Override
  public String visit(RTLNondet e) {
    String n = e.toString() + "_" + nondets.size();
    nondets.add(Pair.create(n, e.getBitWidth()));
    return n;
  }

  @Override
  public String visit(RTLNumber e) {
    if (e.longValue() < 0) {
      return YicesWrapper.makeBVNeg(YicesWrapper.makeBVConstant(e.getBitWidth(), -e.longValue()));
    } else {
      return YicesWrapper.makeBVConstant(e.getBitWidth(), e.longValue());
    }
  }
 
  private String yicesOperator(Operator op) {
    switch(op) {
   
    case EQUAL:          return "=";
    case LESS:          return "bv-slt";
    case LESS_OR_EQUAL:      return "bv-sle";
    case UNSIGNED_LESS:      return "bv-lt";
    case UNSIGNED_LESS_OR_EQUAL:return "bv-le";
    case NOT:          return "bv-not";
    case NEG:          return "bv-neg";
    case AND:          return "bv-and";
    case OR:          return "bv-or";
    case XOR:          return "bv-xor";
    case PLUS:          return "bv-add";
    case MUL:          return "bv-mul";
    case SIGN_EXTEND: case ZERO_FILL: case SHR: case SHL:
      return "requires_special_handling";
     
    default: throw new UnrepresentableElementException(op.toString());
    }

  }

  @Override
  public String visit(RTLOperation e) {
   
    String[] yicesOperands = new String[e.getOperandCount()];
    for (int i=0; i<e.getOperandCount(); i++) {
      yicesOperands[i] = e.getOperands()[i].accept(this);
    }
   
    String yicesOp = yicesOperator(e.getOperator());

    switch (e.getOperator()) {
   
    // Operations with non-bitvector operands
    case SIGN_EXTEND:
      int signBits = ((RTLNumber)e.getOperands()[1]).intValue() - ((RTLNumber)e.getOperands()[0]).intValue() + 1;
      return YicesWrapper.makeBVSignExtend(yicesOperands[2], signBits);

    case ZERO_FILL:
      int zeroes = ((RTLNumber)e.getOperands()[1]).intValue() - ((RTLNumber)e.getOperands()[0]).intValue() + 1;
      return YicesWrapper.makeBVZeroExtend(yicesOperands[2], zeroes);

    case SHR:
      return YicesWrapper.makeBVShiftRight(e.getOperands()[0].accept(this),
          ((RTLNumber)e.getOperands()[1]).intValue());
    case SHL:
      return YicesWrapper.makeBVShiftLeft(e.getOperands()[0].accept(this),
          ((RTLNumber)e.getOperands()[1]).intValue());     

    // In Jakstab, booleans are represented as 1-bit bitvectors, so here we convert
    // Yices booleans into bitvectors
    case LESS:
    case LESS_OR_EQUAL:
    case UNSIGNED_LESS:
    case UNSIGNED_LESS_OR_EQUAL:
    case EQUAL:
      return YicesWrapper.makeITE(YicesWrapper.makeOperation(yicesOp, yicesOperands),
          YicesSolver.yTrue,
          YicesSolver.yFalse);
     
    case AND: case OR: case PLUS: case MUL:
      String result = YicesWrapper.makeOperation(yicesOp,
          yicesOperands[e.getOperandCount() - 2],
          yicesOperands[e.getOperandCount() - 1]);
       
      for (int i=e.getOperandCount() - 3; i >= 0; i--) {
        result = YicesWrapper.makeOperation(yicesOp,
            yicesOperands[i], result);
      }
      return result;     
     
    default:
      return YicesWrapper.makeOperation(yicesOp, yicesOperands);
    }
  }

  @Override
  public String visit(RTLSpecialExpression e) {
    throw new UnrepresentableElementException(e.toString());
  }

  @Override
  public String visit(RTLVariable e) {
    variables.add(e);
    return e.toString();
  }
 


}
TOP

Related Classes of org.jakstab.solver.yices.YicesConversionVisitor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.