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})); } }
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(); }
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()))); }