Esempio n. 1
0
File: gen.c Progetto: irori/8cc
static void emit_func_call(Node *node) {
    SAVE;
    int opos = stackpos;
    bool isptr = (node->type == AST_FUNCPTR_CALL);
    Ctype *ftype = isptr ? node->fptr->ctype->ptr : node->ftype;

    List *ints = make_list();
    List *floats = make_list();
    List *rest = make_list();
    classify_args(ints, floats, rest, node->args);
    save_arg_regs(list_len(ints), list_len(floats));

    bool padding = stackpos % 16;
    if (padding) {
        emit("sub $8, %%rsp");
        stackpos += 8;
    }

    emit_args(list_reverse(rest));
    if (isptr) {
        emit_expr(node->fptr);
        push("rax");
    }
    emit_args(ints);
    emit_args(floats);
    pop_float_args(list_len(floats));
    pop_int_args(list_len(ints));

    if (isptr) pop("r11");
    if (ftype->hasva)
        emit("mov $%d, %%eax", list_len(floats));

    if (isptr)
        emit("call *%%r11");
    else
        emit("call %s", node->fname);
    maybe_booleanize_retval(node->ctype);
    if (list_len(rest) > 0) {
        emit("add $%d, %%rsp", list_len(rest) * 8);
        stackpos -= list_len(rest) * 8;
    }
    if (padding) {
        emit("add $8, %%rsp");
        stackpos -= 8;
    }
    restore_arg_regs(list_len(ints), list_len(floats));
    assert(opos == stackpos);
}
Esempio n. 2
0
File: gen.c Progetto: 4ker/8cc
static void emit_func_call(Node *node) {
    SAVE;
    int opos = stackpos;
    bool isptr = (node->kind == AST_FUNCPTR_CALL);
    Type *ftype = isptr ? node->fptr->ty->ptr : node->ftype;

    Vector *ints = make_vector();
    Vector *floats = make_vector();
    Vector *rest = make_vector();
    classify_args(ints, floats, rest, node->args);
    save_arg_regs(vec_len(ints), vec_len(floats));

    bool padding = stackpos % 16;
    if (padding) {
        emit("sub $8, #rsp");
        stackpos += 8;
    }

    int restsize = emit_args(vec_reverse(rest));
    if (isptr) {
        emit_expr(node->fptr);
        push("rax");
    }
    emit_args(ints);
    emit_args(floats);
    pop_float_args(vec_len(floats));
    pop_int_args(vec_len(ints));

    if (isptr) pop("r11");
    if (ftype->hasva)
        emit("mov $%u, #eax", vec_len(floats));

    if (isptr)
        emit("call *#r11");
    else
        emit("call %s", node->fname);
    maybe_booleanize_retval(node->ty);
    if (restsize > 0) {
        emit("add $%d, #rsp", restsize);
        stackpos -= restsize;
    }
    if (padding) {
        emit("add $8, #rsp");
        stackpos -= 8;
    }
    restore_arg_regs(vec_len(ints), vec_len(floats));
    assert(opos == stackpos);
}