Lib/Source/Translate.cpp
/**
 * Creates the instructions for this comparison.
 *
 * The comparison is internally implemented as a subtract-operation.
 */
Creates the instructions for this comparison.
The comparison is internally implemented as a subtract-operation.
Creates the instructions for this comparison . The comparison is internally implemented as a subtract - operation .
void cmpExp(Instr::List *seq, BExpr::Ptr bexpr, Var v) {
  BExpr b = *bexpr;
  assert(b.tag() == CMP);
  auto cmp_swap_leftright = [] (BExpr &b) {
    auto tmp   = b.cmp_lhs();
    b.cmp_lhs(b.cmp_rhs());
    b.cmp_rhs(tmp);
  };
  if (b.cmp.op() == CmpOp::GT) {                       
    cmp_swap_leftright(b);
    b.cmp.op(CmpOp::LT);
  }
  if (b.cmp.op() == CmpOp::LE) {                       
    cmp_swap_leftright(b);
    b.cmp.op(CmpOp::GE);
  }
  if (!b.cmp_lhs()->isSimple()) {                      
    b.cmp_lhs(simplify(seq, b.cmp_lhs()));
  }
  if (!b.cmp_rhs()->isSimple()) {                      
    b.cmp_rhs(simplify(seq, b.cmp_rhs()));
  }
  if (b.cmp_rhs()->isLit() && b.cmp_rhs()->isLit()) {  
    Var tmpVar = VarGen::fresh();
    *seq << varAssign(tmpVar, b.cmp_lhs());
    b.cmp_lhs(mkVar(tmpVar));
  }
   At this point x and y are simple
  using namespace V3DLib::Target::instr;
  Var dummy  = VarGen::fresh();
  Var dummy2 = VarGen::fresh();
  AssignCond assign_cond(b.cmp);
   Implement comparison using subtraction instruction
  Op op(SUB, b.cmp.type());
  Instr instr(ALU);
  instr.setCondOp(b.cmp);
  instr.ALU.op       = ALUOp(op);
  instr.ALU.srcA     = operand(b.cmp_lhs());
  instr.ALU.srcB     = operand(b.cmp_rhs());
  instr.dest(dummy);
  *seq << li(v, 0).comment("Store condition as Bool var")
       << instr
       << mov(v, 1).cond(assign_cond)             TODO: would be better if this used acc-reg
       << mov(dummy2, v).setCondFlag(Flag::ZC);   Reset flags so that Z-flag is used
  seq->back().comment("End store condition as Bool var");
}
void cmpExp ( Instr :: List * seq , BExpr :: Ptr bexpr , Var v ) { BExpr b = * bexpr ; assert ( b . tag ( ) == CMP ) ; auto cmp_swap_leftright = [ ] ( BExpr & b ) { auto tmp = b . cmp_lhs ( ) ; b . cmp_lhs ( b . cmp_rhs ( ) ) ; b . cmp_rhs ( tmp ) ; } ; if ( b . cmp . op ( ) == CmpOp :: GT ) { cmp_swap_leftright ( b ) ; b . cmp . op ( CmpOp :: LT ) ; } if ( b . cmp . op ( ) == CmpOp :: LE ) { cmp_swap_leftright ( b ) ; b . cmp . op ( CmpOp :: GE ) ; } if ( ! b . cmp_lhs ( ) -> isSimple ( ) ) { b . cmp_lhs ( simplify ( seq , b . cmp_lhs ( ) ) ) ; } if ( ! b . cmp_rhs ( ) -> isSimple ( ) ) { b . cmp_rhs ( simplify ( seq , b . cmp_rhs ( ) ) ) ; } if ( b . cmp_rhs ( ) -> isLit ( ) && b . cmp_rhs ( ) -> isLit ( ) ) { Var tmpVar = VarGen :: fresh ( ) ; * seq << varAssign ( tmpVar , b . cmp_lhs ( ) ) ; b . cmp_lhs ( mkVar ( tmpVar ) ) ; } using namespace V3DLib :: Target :: instr ; Var dummy = VarGen :: fresh ( ) ; Var dummy2 = VarGen :: fresh ( ) ; AssignCond assign_cond ( b . cmp ) ; Op op ( SUB , b . cmp . type ( ) ) ; Instr instr ( ALU ) ; instr . setCondOp ( b . cmp ) ; instr . ALU . op = ALUOp ( op ) ; instr . ALU . srcA = operand ( b . cmp_lhs ( ) ) ; instr . ALU . srcB = operand ( b . cmp_rhs ( ) ) ; instr . dest ( dummy ) ; * seq << li ( v , 0 ) . comment ( " " ) << instr << mov ( v , 1 ) . cond ( assign_cond ) << mov ( dummy2 , v ) . setCondFlag ( Flag :: ZC ) ; seq -> back ( ) . comment ( " " ) ; }
Creates the instructions for this comparison.
Creates the instructions for this comparison .
// 'x > y', replace with y < x // 'x <= y', replace with y >= x // 'x op y', where x is not simple // 'x op y', where y is not simple // 'x op y', where x and y are both literals // // At this point x and y are simple // // Implement comparison using subtraction instruction // TODO: would be better if this used acc-reg // Reset flags so that Z-flag is used