Example #1
0
File: gen.c Project: irori/8cc
static void emit_binop_int_arith(Node *node) {
    SAVE;
    char *op = NULL;
    switch (node->type) {
    case '+': op = "add"; break;
    case '-': op = "sub"; break;
    case '*': op = "imul"; break;
    case '^': op = "xor"; break;
    case OP_SAL: op = "sal"; break;
    case OP_SAR: op = "sar"; break;
    case OP_SHR: op = "shr"; break;
    case '/': case '%': break;
    default: error("invalid operator '%d'", node->type);
    }
    emit_expr(node->left);
    push("rax");
    emit_expr(node->right);
    emit("mov %%rax, %%rcx");
    pop("rax");
    if (node->type == '/' || node->type == '%') {
        emit("cqto");
        emit("idiv %%rcx");
        if (node->type == '%')
            emit("mov %%edx, %%eax");
    } else if (node->type == OP_SAL || node->type == OP_SAR || node->type == OP_SHR) {
        emit("%s %%cl, %%%s", op, get_int_reg(node->left->ctype, 'a'));
    } else {
        emit("%s %%rcx, %rax", op);
    }
}
Example #2
0
File: gen.c Project: irori/8cc
static void emit_gsave(char *varname, Ctype *ctype, int off) {
    SAVE;
    assert(ctype->type != CTYPE_ARRAY);
    maybe_convert_bool(ctype);
    char *reg = get_int_reg(ctype, 'a');
    char *addr = format("%s+%d(%%rip)", varname, off);
    maybe_emit_bitshift_save(ctype, addr);
    emit("mov %%%s, %s", reg, addr);
}
Example #3
0
File: gen.c Project: 4ker/8cc
static void emit_gsave(char *varname, Type *ty, int off) {
    SAVE;
    assert(ty->kind != KIND_ARRAY);
    maybe_convert_bool(ty);
    char *reg = get_int_reg(ty, 'a');
    char *addr = format("%s+%d(%%rip)", varname, off);
    maybe_emit_bitshift_save(ty, addr);
    emit("mov #%s, %s", reg, addr);
}
Example #4
0
File: gen.c Project: irori/8cc
static void emit_assign_deref_int(Ctype *ctype, int off) {
    SAVE;
    emit("mov (%%rsp), %%rcx");
    char *reg = get_int_reg(ctype, 'c');
    if (off)
        emit("mov %%%s, %d(%%rax)", reg, off);
    else
        emit("mov %%%s, (%%rax)", reg);
    pop("rax");
}
Example #5
0
File: gen.c Project: 4ker/8cc
static void do_emit_assign_deref(Type *ty, int off) {
    SAVE;
    emit("mov (#rsp), #rcx");
    char *reg = get_int_reg(ty, 'c');
    if (off)
        emit("mov #%s, %d(#rax)", reg, off);
    else
        emit("mov #%s, (#rax)", reg);
    pop("rax");
}
Example #6
0
File: gen.c Project: irori/8cc
static void emit_lsave(Ctype *ctype, int off) {
    SAVE;
    if (ctype->type == CTYPE_FLOAT) {
        emit("movss %%xmm0, %d(%%rbp)", off);
    } else if (ctype->type == CTYPE_DOUBLE) {
        emit("movsd %%xmm0, %d(%%rbp)", off);
    } else {
        maybe_convert_bool(ctype);
        char *reg = get_int_reg(ctype, 'a');
        char *addr = format("%d(%%rbp)", off);
        maybe_emit_bitshift_save(ctype, addr);
        emit("mov %%%s, %s", reg, addr);
    }
}
Example #7
0
File: gen.c Project: 4ker/8cc
static void emit_lsave(Type *ty, int off) {
    SAVE;
    if (ty->kind == KIND_FLOAT) {
        emit("movss #xmm0, %d(#rbp)", off);
    } else if (ty->kind == KIND_DOUBLE) {
        emit("movsd #xmm0, %d(#rbp)", off);
    } else {
        maybe_convert_bool(ty);
        char *reg = get_int_reg(ty, 'a');
        char *addr = format("%d(%%rbp)", off);
        maybe_emit_bitshift_save(ty, addr);
        emit("mov #%s, %s", reg, addr);
    }
}
Example #8
0
File: gen.c Project: irori/8cc
static void maybe_emit_bitshift_save(Ctype *ctype, char *addr) {
    SAVE;
    if (ctype->bitsize <= 0)
        return;
    push("rcx");
    push("rdi");
    emit("mov $0x%lx, %%rdi", (1 << (long)ctype->bitsize) - 1);
    emit("and %%rdi, %%rax");
    emit("shl $%d, %%rax", ctype->bitoff);
    emit("mov %s, %%%s", addr, get_int_reg(ctype, 'c'));
    emit("mov $0x%lx, %%rdi", ~(((1 << (long)ctype->bitsize) - 1) << ctype->bitoff));
    emit("and %%rdi, %%rcx");
    emit("or %%rcx, %%rax");
    pop("rdi");
    pop("rcx");
}
Example #9
0
File: gen.c Project: 4ker/8cc
static void maybe_emit_bitshift_save(Type *ty, char *addr) {
    SAVE;
    if (ty->bitsize <= 0)
        return;
    push("rcx");
    push("rdi");
    emit("mov $0x%lx, #rdi", (1 << (long)ty->bitsize) - 1);
    emit("and #rdi, #rax");
    emit("shl $%d, #rax", ty->bitoff);
    emit("mov %s, #%s", addr, get_int_reg(ty, 'c'));
    emit("mov $0x%lx, #rdi", ~(((1 << (long)ty->bitsize) - 1) << ty->bitoff));
    emit("and #rdi, #rcx");
    emit("or #rcx, #rax");
    pop("rdi");
    pop("rcx");
}