Lib/Source/Translate.cpp
/**
 * Variable assignments
 *
 * Translate the conditional assignment of a variable to an expression.
 *
 * @param cond  Condition on assignment
 * @param v     Variable on LHS
 * @param expr  Expression on RHS
 *
 * @return  A sequence of instructions
 */
Variable assignments
Translate the conditional assignment of a variable to an expression.

@param cond  Condition on assignment
@param v     Variable on LHS
@param expr  Expression on RHS

@return  A sequence of instructions
Variable assignments Translate the conditional assignment of a variable to an expression . @param cond Condition on assignment @param v Variable on LHS @param expr Expression on RHS @return A sequence of instructions
Instr::List varAssign(AssignCond cond, Var v, Expr::Ptr expr) {
  using namespace V3DLib::Target::instr;
  Instr::List ret;
  Expr e = *expr;
  switch (e.tag()) {
    case Expr::VAR:                                                   
      ret << mov(v, e.var()).cond(cond);
      break;
    case Expr::INT_LIT:                                               
      ret << li(v, e.intLit).cond(cond);
      break;
    case Expr::FLOAT_LIT:                                             
      ret << li(v, e.floatLit).cond(cond);
      break;
    case Expr::APPLY: {                                               
      if (!e.lhs()->isSimple() || !e.rhs()->isSimple()) { 
        e.lhs(simplify(&ret, e.lhs()));
        e.rhs(simplify(&ret, e.rhs()));
      }
      if (e.lhs()->isLit() && e.rhs()->isLit()) {         
        Var tmpVar = VarGen::fresh();
        ret << varAssign(cond, tmpVar, e.lhs());
        e.lhs(mkVar(tmpVar));
      }
      switch (e.apply_op().op) {                          
      case RECIP:     ret << recip(v, e.lhs()->var());     break;
      case RECIPSQRT: ret << recipsqrt(v, e.lhs()->var()); break;
      case EXP:       ret << bexp(v, e.lhs()->var());      break;
      case LOG:       ret << blog(v, e.lhs()->var());      break;
      default:
        Instr instr(ALU);
        instr.ALU.op    = ALUOp(e.apply_op());
        instr.ALU.srcA  = operand(e.lhs());
        instr.ALU.srcB  = operand(e.rhs());
        instr.assign_cond(cond);
        instr.dest(v);
        ret << instr;
        break;
      }
    }
    break;
    case Expr::DEREF:                                                
      if (e.deref_ptr()->tag() != Expr::VAR) {                       
        assert(!e.deref_ptr()->isLit());
        e.deref_ptr(simplify(&ret, e.deref_ptr()));
      }
       Restriction:
       dereferencing is disallowed in conditional ('where') assignments for simplicity.
       In most (all?) cases it should be trivial to lift these outside the 'where'.
      assertq(cond.is_always(), "V3DLib: dereferencing not yet supported inside 'where'");
      ret << getSourceTranslate().load_var(v, e);
      break;
    default:
      assertq(false, "This case should not be reachable");
      break;
  }
  return ret;
}
Instr :: List varAssign ( AssignCond cond , Var v , Expr :: Ptr expr ) { using namespace V3DLib :: Target :: instr ; Instr :: List ret ; Expr e = * expr ; switch ( e . tag ( ) ) { case Expr :: VAR : ret << mov ( v , e . var ( ) ) . cond ( cond ) ; break ; case Expr :: INT_LIT : ret << li ( v , e . intLit ) . cond ( cond ) ; break ; case Expr :: FLOAT_LIT : ret << li ( v , e . floatLit ) . cond ( cond ) ; break ; case Expr :: APPLY : { if ( ! e . lhs ( ) -> isSimple ( ) || ! e . rhs ( ) -> isSimple ( ) ) { e . lhs ( simplify ( & ret , e . lhs ( ) ) ) ; e . rhs ( simplify ( & ret , e . rhs ( ) ) ) ; } if ( e . lhs ( ) -> isLit ( ) && e . rhs ( ) -> isLit ( ) ) { Var tmpVar = VarGen :: fresh ( ) ; ret << varAssign ( cond , tmpVar , e . lhs ( ) ) ; e . lhs ( mkVar ( tmpVar ) ) ; } switch ( e . apply_op ( ) . op ) { case RECIP : ret << recip ( v , e . lhs ( ) -> var ( ) ) ; break ; case RECIPSQRT : ret << recipsqrt ( v , e . lhs ( ) -> var ( ) ) ; break ; case EXP : ret << bexp ( v , e . lhs ( ) -> var ( ) ) ; break ; case LOG : ret << blog ( v , e . lhs ( ) -> var ( ) ) ; break ; default : Instr instr ( ALU ) ; instr . ALU . op = ALUOp ( e . apply_op ( ) ) ; instr . ALU . srcA = operand ( e . lhs ( ) ) ; instr . ALU . srcB = operand ( e . rhs ( ) ) ; instr . assign_cond ( cond ) ; instr . dest ( v ) ; ret << instr ; break ; } } break ; case Expr :: DEREF : if ( e . deref_ptr ( ) -> tag ( ) != Expr :: VAR ) { assert ( ! e . deref_ptr ( ) -> isLit ( ) ) ; e . deref_ptr ( simplify ( & ret , e . deref_ptr ( ) ) ) ; } assertq ( cond . is_always ( ) , " " ) ; ret << getSourceTranslate ( ) . load_var ( v , e ) ; break ; default : assertq ( false , " " ) ; break ; } return ret ; }
Variable assignments
 Translate the conditional assignment of a variable to an expression.
Variable assignments Translate the conditional assignment of a variable to an expression .
// 'v := w', where v and w are variables // 'v := i', where i is an integer literal // 'v := f', where f is a float literal // 'v := x op y' // x or y are not simple // x and y are both literals // x and y are simple // Everything else is considered to be a single binary operation // 'v := *w' // w is not a variable // w is a variable // // Restriction: // dereferencing is disallowed in conditional ('where') assignments for simplicity. // In most (all?) cases it should be trivial to lift these outside the 'where'. //