コード例 #1
0
ファイル: gen.c プロジェクト: 4ker/8cc
static void emit_comp(char *inst, char *usiginst, Node *node) {
    SAVE;
    if (is_flotype(node->left->ty)) {
        emit_expr(node->left);
        push_xmm(0);
        emit_expr(node->right);
        pop_xmm(1);
        if (node->left->ty->kind == KIND_FLOAT)
            emit("ucomiss #xmm0, #xmm1");
        else
            emit("ucomisd #xmm0, #xmm1");
    } else {
        emit_expr(node->left);
        push("rax");
        emit_expr(node->right);
        pop("rcx");
        int kind = node->left->ty->kind;
        if (kind == KIND_LONG || kind == KIND_LLONG)
          emit("cmp #rax, #rcx");
        else
          emit("cmp #eax, #ecx");
    }
    if (is_flotype(node->left->ty) || node->left->ty->usig)
        emit("%s #al", usiginst);
    else
        emit("%s #al", inst);
    emit("movzb #al, #eax");
}
コード例 #2
0
ファイル: gen.c プロジェクト: irori/8cc
static void emit_va_arg(Node *node) {
    SAVE;
    emit_expr(node->ap);
    emit("nop");
    push("rcx");
    push("rbx");
    emit("mov 16(%%rax), %%rcx");
    if (is_flotype(node->ctype)) {
        emit("mov 4(%%rax), %%ebx");
        emit("add %%rbx, %%rcx");
        emit("add $16, %%ebx");
        emit("mov %%ebx, 4(%%rax)");
        emit("movsd (%%rcx), %%xmm0");
        if (node->ctype->type == CTYPE_FLOAT)
            emit("cvtpd2ps %%xmm0, %%xmm0");
    } else {
        emit("mov (%%rax), %%ebx");
        emit("add %%rbx, %%rcx");
        emit("add $8, %%ebx");
        emit("mov %%rbx, (%%rax)");
        emit("mov (%%rcx), %%rax");
    }
    pop("rbx");
    pop("rcx");
}
コード例 #3
0
ファイル: gen.c プロジェクト: irori/8cc
static void emit_comp(char *inst, Node *node) {
    SAVE;
    if (is_flotype(node->left->ctype)) {
        emit_expr(node->left);
        push_xmm(0);
        emit_expr(node->right);
        pop_xmm(1);
        if (node->left->ctype->type == CTYPE_FLOAT)
            emit("ucomiss %%xmm0, %%xmm1");
        else
            emit("ucomisd %%xmm0, %%xmm1");
    } else {
        emit_expr(node->left);
        push("rax");
        emit_expr(node->right);
        pop("rcx");
        int type = node->left->ctype->type;
        if (type == CTYPE_LONG || type == CTYPE_LLONG)
          emit("cmp %%rax, %%rcx");
        else
          emit("cmp %%eax, %%ecx");
    }
    emit("%s %%al", inst);
    emit("movzb %%al, %%eax");
}
コード例 #4
0
ファイル: gen.c プロジェクト: irori/8cc
static void set_reg_nums(List *args) {
    numgp = numfp = 0;
    for (Iter *i = list_iter(args); !iter_end(i);) {
        Node *arg = iter_next(i);
        if (is_flotype(arg->ctype))
            numfp++;
        else
            numgp++;
    }
}
コード例 #5
0
ファイル: gen.c プロジェクト: 4ker/8cc
static void set_reg_nums(Vector *args) {
    numgp = numfp = 0;
    for (int i = 0; i < vec_len(args); i++) {
        Node *arg = vec_get(args, i);
        if (is_flotype(arg->ty))
            numfp++;
        else
            numgp++;
    }
}
コード例 #6
0
ファイル: gen.c プロジェクト: irori/8cc
static void emit_uminus(Node *node) {
    emit_expr(node->operand);
    if (is_flotype(node->ctype)) {
        push_xmm(1);
        emit("xorpd %%xmm1, %%xmm1");
        emit("%s %%xmm1, %%xmm0", (node->ctype->type == CTYPE_DOUBLE ? "subsd" : "subss"));
        pop_xmm(1);
    } else {
        emit("neg %%rax");
    }
}
コード例 #7
0
ファイル: gen.c プロジェクト: 4ker/8cc
// Set the register class for parameter passing to RAX.
// 0 is INTEGER, 1 is SSE, 2 is MEMORY.
static void emit_builtin_reg_class(Node *node) {
    Node *arg = vec_get(node->args, 0);
    assert(arg->ty->kind == KIND_PTR);
    Type *ty = arg->ty->ptr;
    if (ty->kind == KIND_STRUCT)
        emit("mov $2, #eax");
    else if (is_flotype(ty))
        emit("mov $1, #eax");
    else
        emit("mov $0, #eax");
}
コード例 #8
0
ファイル: gen.c プロジェクト: irori/8cc
static void emit_args(List *vals) {
    SAVE;
    Iter *iter = list_iter(vals);
    while (!iter_end(iter)) {
        Node *v = iter_next(iter);
        emit_expr(v);
        if (is_flotype(v->ctype))
            push_xmm(0);
        else
            push("rax");
    }
}
コード例 #9
0
ファイル: gen.c プロジェクト: irori/8cc
static void classify_args(List *ints, List *floats, List *rest, List *args) {
    SAVE;
    int ireg = 0, xreg = 0;
    int imax = 6, xmax = 8;
    Iter *iter = list_iter(args);
    while (!iter_end(iter)) {
        Node *v = iter_next(iter);
        if (is_flotype(v->ctype))
            list_push((xreg++ < xmax) ? floats : rest, v);
        else
            list_push((ireg++ < imax) ? ints : rest, v);
    }
}
コード例 #10
0
ファイル: gen.c プロジェクト: irori/8cc
static void emit_to_bool(Ctype *ctype) {
    SAVE;
    if (is_flotype(ctype)) {
        push_xmm(1);
        emit("xorpd %%xmm1, %%xmm1");
        emit("%s %%xmm1, %%xmm0", (ctype->type == CTYPE_FLOAT) ? "ucomiss" : "ucomisd");
        emit("setne %%al");
        pop_xmm(1);
    } else {
        emit("cmp $0, %%rax");
        emit("setne %%al");
    }
    emit("movzb %%al, %%eax");
}
コード例 #11
0
ファイル: gen.c プロジェクト: 4ker/8cc
static void classify_args(Vector *ints, Vector *floats, Vector *rest, Vector *args) {
    SAVE;
    int ireg = 0, xreg = 0;
    int imax = 6, xmax = 8;
    for (int i = 0; i < vec_len(args); i++) {
        Node *v = vec_get(args, i);
        if (v->ty->kind == KIND_STRUCT)
            vec_push(rest, v);
        else if (is_flotype(v->ty))
            vec_push((xreg++ < xmax) ? floats : rest, v);
        else
            vec_push((ireg++ < imax) ? ints : rest, v);
    }
}
コード例 #12
0
ファイル: gen.c プロジェクト: 4ker/8cc
static void emit_to_bool(Type *ty) {
    SAVE;
    if (is_flotype(ty)) {
        push_xmm(1);
        emit("xorpd #xmm1, #xmm1");
        emit("%s #xmm1, #xmm0", (ty->kind == KIND_FLOAT) ? "ucomiss" : "ucomisd");
        emit("setne #al");
        pop_xmm(1);
    } else {
        emit("cmp $0, #rax");
        emit("setne #al");
    }
    emit("movzb #al, #eax");
}
コード例 #13
0
ファイル: gen.c プロジェクト: 4ker/8cc
static void emit_binop(Node *node) {
    SAVE;
    if (node->ty->kind == KIND_PTR) {
        emit_pointer_arith(node->kind, node->left, node->right);
        return;
    }
    switch (node->kind) {
    case '<': emit_comp("setl", "setb", node); return;
    case OP_EQ: emit_comp("sete", "sete", node); return;
    case OP_LE: emit_comp("setle", "setna", node); return;
    case OP_NE: emit_comp("setne", "setne", node); return;
    }
    if (is_inttype(node->ty))
        emit_binop_int_arith(node);
    else if (is_flotype(node->ty))
        emit_binop_float_arith(node);
    else
        error("internal error: %s", node2s(node));
}
コード例 #14
0
ファイル: gen.c プロジェクト: 4ker/8cc
static int emit_args(Vector *vals) {
    SAVE;
    int r = 0;
    for (int i = 0; i < vec_len(vals); i++) {
        Node *v = vec_get(vals, i);
        if (v->ty->kind == KIND_STRUCT) {
            emit_addr(v);
            r += push_struct(v->ty->size);
        } else if (is_flotype(v->ty)) {
            emit_expr(v);
            push_xmm(0);
            r += 8;
        } else {
            emit_expr(v);
            push("rax");
            r += 8;
        }
    }
    return r;
}
コード例 #15
0
ファイル: gen.c プロジェクト: irori/8cc
static void emit_binop(Node *node) {
    SAVE;
    if (node->ctype->type == CTYPE_PTR) {
        emit_pointer_arith(node->type, node->left, node->right);
        return;
    }
    switch (node->type) {
    case '<': emit_comp("setl", node); return;
    case '>': emit_comp("setg", node); return;
    case OP_EQ: emit_comp("sete", node); return;
    case OP_GE: emit_comp("setge", node); return;
    case OP_LE: emit_comp("setle", node); return;
    case OP_NE: emit_comp("setne", node); return;
    }
    if (is_inttype(node->ctype))
        emit_binop_int_arith(node);
    else if (is_flotype(node->ctype))
        emit_binop_float_arith(node);
    else
        error("internal error");
}