示例#1
0
void IRGenerator::accept(BinaryExpr& expr)
{
    FNTRACE();

    static const std::unordered_map<
        int /*FlowVM::Opcode*/,
        Value* (IRGenerator::*)(Value*, Value*, const std::string&)
    > ops = {
        // numerical
        { FlowVM::Opcode::NADD, &IRGenerator::createAdd },
        { FlowVM::Opcode::NSUB, &IRGenerator::createSub },
        { FlowVM::Opcode::NMUL, &IRGenerator::createMul },
        { FlowVM::Opcode::NDIV, &IRGenerator::createDiv },
        { FlowVM::Opcode::NREM, &IRGenerator::createRem },
        { FlowVM::Opcode::NSHL, &IRGenerator::createShl },
        { FlowVM::Opcode::NSHR, &IRGenerator::createShr },
        { FlowVM::Opcode::NPOW, &IRGenerator::createPow },
        { FlowVM::Opcode::NAND, &IRGenerator::createAnd },
        { FlowVM::Opcode::NOR,  &IRGenerator::createOr },
        { FlowVM::Opcode::NXOR, &IRGenerator::createXor },
        { FlowVM::Opcode::NCMPEQ, &IRGenerator::createNCmpEQ },
        { FlowVM::Opcode::NCMPNE, &IRGenerator::createNCmpNE },
        { FlowVM::Opcode::NCMPLE, &IRGenerator::createNCmpLE },
        { FlowVM::Opcode::NCMPGE, &IRGenerator::createNCmpGE },
        { FlowVM::Opcode::NCMPLT, &IRGenerator::createNCmpLT },
        { FlowVM::Opcode::NCMPGT, &IRGenerator::createNCmpGT },

        // string
        { FlowVM::Opcode::SADD, &IRGenerator::createSAdd },
        { FlowVM::Opcode::SCMPEQ, &IRGenerator::createSCmpEQ },
        { FlowVM::Opcode::SCMPNE, &IRGenerator::createSCmpNE },
        { FlowVM::Opcode::SCMPLE, &IRGenerator::createSCmpLE },
        { FlowVM::Opcode::SCMPGE, &IRGenerator::createSCmpGE },
        { FlowVM::Opcode::SCMPLT, &IRGenerator::createSCmpLT },
        { FlowVM::Opcode::SCMPGT, &IRGenerator::createSCmpGT },
        { FlowVM::Opcode::SCMPBEG, &IRGenerator::createSCmpEB },
        { FlowVM::Opcode::SCMPEND, &IRGenerator::createSCmpEE },
        //{ FlowVM::Opcode::SCONTAINS, &IRGenerator::createSContains },

        // regex
        { FlowVM::Opcode::SREGMATCH, &IRGenerator::createSCmpRE },
    };

    Value* lhs = codegen(expr.leftExpr());
    Value* rhs = codegen(expr.rightExpr());

    auto i = ops.find(expr.op());
    if (i != ops.end()) {
        result_ = (this->*i->second)(lhs, rhs, "");
    } else {
        // fall back to generic VmInstr
        result_ = insert(new VmInstr(expr.op(), {lhs, rhs}));
    }
}
示例#2
0
      std::string process_impl(BinaryExpr const & e, bool use_parenthesis, rt_latex_translator<InterfaceType> const & translator) const
      {
        std::stringstream ss;
        viennamath::rt_expr<InterfaceType> lhs(e.lhs()->clone());
        viennamath::rt_expr<InterfaceType> rhs(e.rhs()->clone());

        if (dynamic_cast< const op_binary<op_div<NumericType>, InterfaceType> * >(e.op()) != NULL)  //division -> \frac{}{}
        {
          if (use_parenthesis)
            ss << " \\left( ";
          ss << " \\frac{" << translator(lhs) << "}{" << translator(rhs) << "} ";
          if (use_parenthesis)
            ss << " \\right) ";
        }
        else
        {
          bool is_op_mult = false;
          if (dynamic_cast< const op_binary<op_mult<NumericType>, InterfaceType> * >(e.op()) != NULL)
            is_op_mult = true;

          bool is_op_minus = false;
          if (dynamic_cast< const op_binary<op_minus<NumericType>, InterfaceType> * >(e.op()) != NULL)
            is_op_minus = true;

          if (use_parenthesis)
            ss << "(";
          ss << translator(lhs, is_op_mult);
          if (is_op_mult)
            ss << " \\cdot ";
          else
            ss << " " << e.op()->str() << " ";
          ss << translator(rhs, is_op_mult || is_op_minus);
          if (use_parenthesis)
            ss << ")";
        }

        return ss.str();
      }
示例#3
0
void IRGenerator::accept(BinaryExpr& expr)
{
    FNTRACE();

    static const std::unordered_map<
        int /*FlowVM::Opcode*/,
        Value* (IRGenerator::*)(Value*, Value*, const std::string&)
    > ops = {
        // numerical
        { FlowVM::Opcode::NADD, &IRGenerator::createAdd },
        { FlowVM::Opcode::NSUB, &IRGenerator::createSub },
        { FlowVM::Opcode::NMUL, &IRGenerator::createMul },
        { FlowVM::Opcode::NDIV, &IRGenerator::createDiv },
        { FlowVM::Opcode::NREM, &IRGenerator::createRem },
        { FlowVM::Opcode::NSHL, &IRGenerator::createShl },
        { FlowVM::Opcode::NSHR, &IRGenerator::createShr },
        { FlowVM::Opcode::NPOW, &IRGenerator::createPow },
        { FlowVM::Opcode::NAND, &IRGenerator::createAnd },
        { FlowVM::Opcode::NOR,  &IRGenerator::createOr },
        { FlowVM::Opcode::NXOR, &IRGenerator::createXor },
        { FlowVM::Opcode::NCMPEQ, &IRGenerator::createNCmpEQ },
        { FlowVM::Opcode::NCMPNE, &IRGenerator::createNCmpNE },
        { FlowVM::Opcode::NCMPLE, &IRGenerator::createNCmpLE },
        { FlowVM::Opcode::NCMPGE, &IRGenerator::createNCmpGE },
        { FlowVM::Opcode::NCMPLT, &IRGenerator::createNCmpLT },
        { FlowVM::Opcode::NCMPGT, &IRGenerator::createNCmpGT },

        // string
        { FlowVM::Opcode::SADD, &IRGenerator::createSAdd },
        { FlowVM::Opcode::SCMPEQ, &IRGenerator::createSCmpEQ },
        { FlowVM::Opcode::SCMPNE, &IRGenerator::createSCmpNE },
        { FlowVM::Opcode::SCMPLE, &IRGenerator::createSCmpLE },
        { FlowVM::Opcode::SCMPGE, &IRGenerator::createSCmpGE },
        { FlowVM::Opcode::SCMPLT, &IRGenerator::createSCmpLT },
        { FlowVM::Opcode::SCMPGT, &IRGenerator::createSCmpGT },
        { FlowVM::Opcode::SCMPBEG, &IRGenerator::createSCmpEB },
        { FlowVM::Opcode::SCMPEND, &IRGenerator::createSCmpEE },
        { FlowVM::Opcode::SCONTAINS, &IRGenerator::createSIn },

        // regex
        { FlowVM::Opcode::SREGMATCH, &IRGenerator::createSCmpRE },

        // ip
        { FlowVM::Opcode::PCMPEQ, &IRGenerator::createPCmpEQ },
        { FlowVM::Opcode::PCMPNE, &IRGenerator::createPCmpNE },
        { FlowVM::Opcode::PINCIDR, &IRGenerator::createPInCidr },
    };

    if (expr.op() == FlowVM::Opcode::BOR) {
        // (lhs || rhs)
        //
        //   L = lhs();
        //   if (L) goto end;
        //   R = rhs();
        //   L = R;
        // end:
        //   result = L;

        BasicBlock* borLeft = createBlock("bor.left");
        BasicBlock* borRight = createBlock("bor.right");
        BasicBlock* borCont = createBlock("bor.cont");

        AllocaInstr* result = createAlloca(FlowType::Boolean, get(1), "bor");
        Value* lhs = codegen(expr.leftExpr());
        createCondBr(lhs, borLeft, borRight);

        setInsertPoint(borLeft);
        createStore(result, lhs, "bor.left");
        createBr(borCont);

        setInsertPoint(borRight);
        Value* rhs = codegen(expr.rightExpr());
        createStore(result, rhs, "bor.right");
        createBr(borCont);

        setInsertPoint(borCont);

        result_ = result;

        return;
    }

    Value* lhs = codegen(expr.leftExpr());
    Value* rhs = codegen(expr.rightExpr());

    auto i = ops.find(expr.op());
    if (i != ops.end()) {
        result_ = (this->*i->second)(lhs, rhs, "");
    } else {
        fprintf(stderr, "BUG: Binary operation `%s` not implemented.\n", mnemonic(expr.op()));
        assert(!"Unimplemented");
        result_ = nullptr;
    }
}
void InstantiationVisitor::visit(BinaryExpr& b)
{
	_expr.reset(new BinaryExpr(b.sloc(), clone(b.left()), b.op(), clone(b.right())));
}