コード例 #1
0
ファイル: IRGenerator.cpp プロジェクト: TwinkleStars/x0
void IRGenerator::accept(Variable& variable)
{
    FNTRACE();

    Value* initializer = codegen(variable.initializer());
    if (!initializer)
        return;

    AllocaInstr* var = createAlloca(initializer->type(), get(1), variable.name());
    scope().update(&variable, var);

    createStore(var, initializer);
    result_ = var;
}
コード例 #2
0
ファイル: vardef.cpp プロジェクト: linlifengx/step2
void VarDef::codeGen(AstContext &astContext) {
	ClassInfo *classInfo = typeDecl->getClassInfo();
	for (unsigned i = 0; i < varInitList.size(); i++) {
		VarInit *varInit = varInitList[i];
		Value *value = NULL;
		if (varInit->expr != NULL) {
			varInit->expr->expectedType = classInfo;
			AValue v = varInit->expr->codeGen(astContext);
			value = v.llvmValue;
		} else {
			value = classInfo->getInitial();
		}
		Value *var = createAlloca(classInfo->llvmType, astContext.allocBB);
		if (!astContext.addVar(varInit->varName, AValue(var, classInfo))) {
			throwError(varInit);
		}
		builder.CreateStore(value, var);
	}
}
コード例 #3
0
void IRGenerator::accept(ArrayExpr& arrayExpr)
{
    FNTRACE();

    // loads a new array of given elements from regs[1] to regs[N], where regs[0] equals N;

    Value* array = createAlloca(arrayExpr.getType(), get(1 + arrayExpr.values().size()));

    // store array size at array[0]
    createArraySet(array, get(0), get(arrayExpr.values().size()));

    // store array values at array[1] to array[N]
    for (size_t i = 1, e = 1 + arrayExpr.values().size(); i != e; ++i) {
        Value* element = codegen(arrayExpr.values()[i].get());
        createArraySet(array, get(i), element);
    }

    result_ = array;
}
コード例 #4
0
ファイル: IRGenerator.cpp プロジェクト: TwinkleStars/x0
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;
    }
}