Example #1
0
llvm_value CompileExpression::DoPrefix(Prefix *what)
// ----------------------------------------------------------------------------
//   Compile prefix expressions
// ----------------------------------------------------------------------------
{
    if (Name *name = what->left->AsName())
    {
        if (name->value == "data" || name->value == "extern")
            return NULL;

        if (name->value == "opcode")
        {
            // This is a builtin, find if we write to code or data
            llvm_builder bld = unit->code;
            Tree *builtin = what->right;
            if (Prefix *prefix = builtin->AsPrefix())
            {
                if (Name *name = prefix->left->AsName())
                {
                    if (name->value == "data")
                    {
                        bld = unit->data;
                        builtin = prefix->right;
                    }
                }
            }

            // Take args list for current function as input
            llvm_values args;
            Function *function = unit->function;
            uint i, max = function->arg_size();
            Function::arg_iterator arg = function->arg_begin();
            for (i = 0; i < max; i++)
            {
                llvm_value inputArg = arg++;
                args.push_back(inputArg);
            }

            // Call the primitive (effectively creating a wrapper for it)
            Name *name = builtin->AsName();
            assert(name || !"Malformed primitive");
            Compiler *compiler = unit->compiler;
            text op = name->value;
            uint sz = args.size();
            llvm_value *a = &args[0];
            return compiler->Primitive(bld, op, sz, a);
        }
    }
    return DoCall(what);
}
Example #2
0
llvm_value CompileExpression::DoRewrite(RewriteCandidate &cand)
// ----------------------------------------------------------------------------
//   Generate code for a particular rewwrite candidate
// ----------------------------------------------------------------------------
{
    Infix *rw = cand.rewrite;
    llvm_value result = NULL;

    IFTRACE(calltypes)
        std::cerr << "Rewrite: " << rw << "\n";

    // Evaluate parameters
    llvm_values args;
    RewriteBindings &bnds = cand.bindings;
    RewriteBindings::iterator b;
    for (b = bnds.begin(); b != bnds.end(); b++)
    {
        Tree *tree = (*b).value;
        IFTRACE(calltypes)
            std::cerr << "  Arg: " << tree << ": ";
        if (llvm_value closure = (*b).Closure(unit))
        {
            args.push_back(closure);
            IFTRACE(calltypes)
                llvm::errs() << "  closure " << *closure << "\n";
        }
        else if (llvm_value value = Value(tree))
        {
            args.push_back(value);
            llvm_type mtype = value->getType();
            if (unit->compiler->IsClosureType(mtype))
                (*b).closure = value;
            IFTRACE(calltypes)
                llvm::errs() << "  value " << *value
                             << " mtype " << *mtype << "\n";
        }
    }

    // Check if this is an LLVM builtin
    Tree *builtin = NULL;
    if (Tree *value = rw->right)
        if (Prefix *prefix = value->AsPrefix())
            if (Name *name = prefix->left->AsName())
                if (name->value == "opcode")
                    builtin = prefix->right;

    if (builtin)
    {
        llvm_builder bld = unit->code;
        if (Prefix *prefix = builtin->AsPrefix())
        {
            if (Name *name = prefix->left->AsName())
            {
                if (name->value == "data")
                {
                    bld = unit->data;
                    builtin = prefix->right;
                }
            }
        }

        Name *name = builtin->AsName();
        if (!name)
        {
            Ooops("Malformed primitive $1", builtin);
            result = unit->CallFormError(builtin);
        }
        else
        {
            Compiler *compiler = unit->compiler;
            text op = name->value;
            uint sz = args.size();
            llvm_value *a = &args[0];
            result = compiler->Primitive(*unit, bld, op, sz, a);
            if (!result)
                Ooops("Invalid primitive $1", builtin);
            IFTRACE(calltypes)
                llvm::errs() << "  = Primitive: " << *result << "\n";
        }
    }
    else
    {
        llvm_value function = unit->Compile(cand, args);
        IFTRACE(calltypes)
            llvm::errs() << "  < Function: " << *function << "\n";
        if (function)
            result = unit->code->CreateCall(function, LLVMS_ARGS(args));
        IFTRACE(calltypes)
            llvm::errs() << "  =Call: " << *result << "\n";
    }

    return result;
}
Example #3
0
File: unit.cpp Project: c3d/elfe
Function *CompiledUnit::RewriteFunction(RewriteCandidate &rc)
// ----------------------------------------------------------------------------
//   Create a function for a tree rewrite
// ----------------------------------------------------------------------------
{
    Types *types = rc.types;
    Infix *rewrite = rc.rewrite;

    // We must have verified the types before
    assert((types && !this->types) || !"RewriteFunction: bogus type check");
    this->types = types;

    Tree *source = RewriteDefined(rewrite->left);
    Tree *def = rewrite->right;
    IFTRACE(llvm)
        std::cerr << "CompiledUnit::RewriteFunction T" << (void *) source;

    // Extract parameters from source form
    ParameterList parameters(this);
    if (!source->Do(parameters))
        return NULL;

    // Create the function signature, one entry per parameter
    llvm_types signature;
    Signature(parameters.parameters, rc, signature);

    // Compute return type:
    // - If explicitly specified, use that (TODO: Check compatibility)
    // - For definitions, infer from definition
    // - For data forms, this is the type of the data form
    llvm_type retTy;
    if (llvm_type specifiedRetTy = parameters.returned)
        retTy = specifiedRetTy;
    else if (def)
        retTy = ReturnType(def);
    else
        retTy = StructureType(signature, source);

    text label = "_ELFE_" + parameters.name;
    IFTRACE(labels)
        label += "[" + text(*source) + "]";

    // Check if we are actually declaring a C function
    bool isC = false;
    bool isVararg = false;
    if (Tree *defined = parameters.defined)
    {
        if (Name *name = def->AsName())
            if (name->value == "C")
                if (ValidCName(defined, label))
                    isC = true;

        if (Prefix *prefix = def->AsPrefix())
            if (Name *name = prefix->left->AsName())
                if (name->value == "C")
                    if (ValidCName(prefix->right, label))
                        isC = true;
    }

    FunctionType *fnTy = FunctionType::get(retTy, signature, isVararg);
    Function *f = InitializeFunction(fnTy, &parameters.parameters,
                                     label.c_str(), isC, isC);
    if (isC)
    {
        void *address = sys::DynamicLibrary::SearchForAddressOfSymbol(label);
        if (!address)
        {
            Ooops("No library function matching $1", rewrite->left);
            return NULL;
        }
        sys::DynamicLibrary::AddSymbol(label, address);
    }
    return f;
}
Example #4
0
llvm_value CompileExpression::DoRewrite(RewriteCandidate &cand)
// ----------------------------------------------------------------------------
//   Generate code for a particular rewwrite candidate
// ----------------------------------------------------------------------------
{
    Rewrite *rw = cand.rewrite;
    llvm_value result = NULL;

    // Evaluate parameters
    llvm_values args;
    RewriteBindings &bnds = cand.bindings;
    RewriteBindings::iterator b;
    for (b = bnds.begin(); b != bnds.end(); b++)
    {
        Tree *tree = (*b).value;
        if (llvm_value closure = (*b).Closure(unit))
        {
            args.push_back(closure);
        }
        else if (llvm_value value = Value(tree))
        {
            args.push_back(value);
            llvm_type mtype = value->getType();
            if (unit->compiler->IsClosureType(mtype))
                (*b).closure = value;
        }
    }

    // Check if this is an LLVM builtin
    Tree *builtin = NULL;
    if (rw->to)
        if (Prefix *prefix = rw->to->AsPrefix())
            if (Name *name = prefix->left->AsName())
                if (name->value == "opcode")
                    builtin = prefix->right;

    if (builtin)
    {
        llvm_builder bld = unit->code;
        if (Prefix *prefix = builtin->AsPrefix())
        {
            if (Name *name = prefix->left->AsName())
            {
                if (name->value == "data")
                {
                    bld = unit->data;
                    builtin = prefix->right;
                }
            }
        }

        Name *name = builtin->AsName();
        assert(name || !"Malformed primitive");
        Compiler *compiler = unit->compiler;
        text op = name->value;
        uint sz = args.size();
        llvm_value *a = &args[0];
        result = compiler->Primitive(bld, op, sz, a);
    }
    else
    {
        llvm_value function = unit->Compile(cand, args);
        if (function)
            result = unit->code->CreateCall(function, LLVMS_ARGS(args));
    }

    return result;
}