Package org.renjin.gcc.translate

Source Code of org.renjin.gcc.translate.Comparison

package org.renjin.gcc.translate;

import org.renjin.gcc.gimple.GimpleOp;
import org.renjin.gcc.jimple.JimpleExpr;
import org.renjin.gcc.jimple.JimpleType;
import org.renjin.gcc.translate.expr.ArrayRef;
import org.renjin.gcc.translate.expr.ImExpr;
import org.renjin.gcc.translate.expr.ImIndirectExpr;
import org.renjin.gcc.translate.expr.ImLiteralPrimitiveExpr;
import org.renjin.gcc.translate.type.ImPrimitiveType;

public class Comparison {
  private GimpleOp op;
  private ImExpr a, ap;
  private ImExpr b, bp;
  private ImPrimitiveType type;


  public Comparison(GimpleOp op, ImExpr a, ImExpr b) {
    super();
    this.op = op;
    this.a = a;
    this.b = b;
  }

  /**
   * If pointers are being used in the comparison, than we
   * need to interpret them as integers.
   */
  private ImExpr pointerToInteger(FunctionContext context, ImExpr a) {
    if(a instanceof ImIndirectExpr) {
      ArrayRef arrayRef = ((ImIndirectExpr) a).translateToArrayRef(context);
      return new ImLiteralPrimitiveExpr(arrayRef.getIndexExpr(), ImPrimitiveType.INT);
    } else {
      return a;
    }
  }


  public JimpleExpr toCondition(FunctionContext context) {

    ap = pointerToInteger(context, this.a);
    bp = pointerToInteger(context, this.b);
    TypeChecker.assertSamePrimitiveType(ap, bp);
    type = (ImPrimitiveType) ap.type();


    switch(type) {
    case FLOAT:
    case DOUBLE:
      switch (op) {
      case NE_EXPR:
        return floatComparison(context, "cmpl", "!=", 0);
      case EQ_EXPR:
        return floatComparison(context, "cmpl", "==", 0);
      case LE_EXPR:
        return floatComparison(context, "cmpg", "<=", 0);
      case LT_EXPR:
        return floatComparison(context, "cmpg", "<", 0);
      case GT_EXPR:
        return floatComparison(context, "cmpl", ">", 0);
      case GE_EXPR:
        return floatComparison(context, "cmpl", ">=", 0);
      }
      break;
    case INT:
    case CHAR:
    case LONG:
    case BOOLEAN:

      switch (op) {
      case NE_EXPR:
        return intComparison(context, "!=");
      case EQ_EXPR:
        return intComparison(context, "==");
      case LE_EXPR:
        return intComparison(context, "<=");
      case LT_EXPR:
        return intComparison(context, "<");
      case GT_EXPR:
        return intComparison(context, ">");
      case GE_EXPR:
        return intComparison(context, ">=");
      }
    }
    throw new UnsupportedOperationException(" don't know how to compare expressions of type " + a.type());
  }

  private JimpleExpr floatComparison(FunctionContext context, String operator, String condition, int operand) {
    String cmp = context.declareTemp(JimpleType.INT);
    context.getBuilder().addStatement(String.format("%s = %s %s %s",
        cmp,
        ap.translateToPrimitive(context, type),
        operator,
        bp.translateToPrimitive(context, type)));

    return new JimpleExpr(cmp + " " + condition + " " + operand);
  }
 
  private JimpleExpr intComparison(FunctionContext context, String operator) {
    return JimpleExpr.binaryInfix(operator,
        ap.translateToPrimitive(context, type),
        bp.translateToPrimitive(context, type));
   
  }
}
TOP

Related Classes of org.renjin.gcc.translate.Comparison

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.