Esempio n. 1
0
/**
 * asm - fetch the address of the specified symbol into the primary register
 * @param sym the symbol name
 * @return which register pair contains result
 */
int gen_get_locale(SYMBOL *sym) {
    if (sym->storage == LSTATIC) {
        gen_immediate();
        print_label(sym->offset);
        newline();
        return HL_REG;
    } else {
        gen_immediate();
        output_number(sym->offset);
        output_string("+fp");
        newline();
        return HL_REG;
    }
}
Esempio n. 2
0
int constant(int val[]) {
    if (number (val))
        gen_immediate ();
    else if (quoted_char (val))
        gen_immediate ();
    else if (quoted_string (val)) {
        gen_immediate ();
        print_label (litlab);
        output_byte ('+');
    } else
        return (0);
    output_number (val[0]);
    newline ();
    return (1);
}
Esempio n. 3
0
/**
 * "switch" statement
 */
void doswitch(void) {
        WHILE ws;
        WHILE *ptr;

        ws.symbol_idx = local_table_index;
        ws.stack_pointer = stkp;
        ws.type = WSSWITCH;
        ws.case_test = swstp;
        ws.body_tab = getlabel ();
        ws.incr_def = ws.while_exit = getlabel ();
        addwhile (&ws);
        gen_immediate ();
        print_label (ws.body_tab);
        newline ();
        gen_push (HL_REG);
        needbrack ("(");
        expression (YES);
        needbrack (")");
        stkp = stkp + INTSIZE;  // '?case' will adjust the stack
        gen_jump_case ();
        statement (NO);
        ptr = readswitch ();
        gen_jump (ptr->while_exit);
        dumpsw (ptr);
        generate_label (ptr->while_exit);
        local_table_index = ptr->symbol_idx;
        stkp = gen_modify_stack (ptr->stack_pointer);
        swstp = ptr->case_test;
        delwhile ();
}
Esempio n. 4
0
/**
 * divide the primary register by INTSIZE, never used
 */
void gen_divide_by_two(void) {
    gen_push(HL_REG);        /* push primary in prep for gasr */
    gen_immediate ();
    output_number (1);
    newline ();
    gen_arithm_shift_right ();  /* divide by two */
}
Esempio n. 5
0
/**
 * perform subroutine call to value on top of stack
 */
void callstk(void) {
    gen_immediate ();
    output_string ("#.+5");
    newline ();
    gen_swap_stack ();
    output_line ("pchl");
    stkp = stkp + INTSIZE;
}
Esempio n. 6
0
/**
 * asm - fetch the address of the specified symbol into the primary register
 * @param sym the symbol name
 * @return which register pair contains result
 */
int gen_get_locale(SYMBOL *sym) {
    if (sym->storage == LSTATIC) {
        gen_immediate();
        print_label(sym->offset);
        newline();
        return HL_REG;
    } else {
        if (uflag && !(sym->identity == ARRAY)) {// ||
                //(sym->identity == VARIABLE && sym->type == STRUCT))) {
            output_with_tab("ldsi\t");
            output_number(sym->offset - stkp);
            newline ();
            return DE_REG;
        } else {
            gen_immediate();
            output_number(sym->offset - stkp);
            newline ();
            output_line ("dad \tsp");
            return HL_REG;
        }
    }
}
Esempio n. 7
0
/**
 * modify the stack pointer to the new value indicated
 * @param newstkp new value
 */
int gen_modify_stack(int newstkp) {
    int k;

    k = newstkp - stkp;
    if (k == 0)
        return (newstkp);
    if (k > 0) {
        if (k < 7) {
            if (k & 1) {
                output_line ("inx \tsp");
                k--;
            }
            while (k) {
                output_line ("pop \tb");
                k = k - INTSIZE;
            }
            return (newstkp);
        }
    } else {
        if (k > -7) {
            if (k & 1) {
                output_line ("dcx \tsp");
                k++;
            }
            while (k) {
                output_line ("push\tb");
                k = k + INTSIZE;
            }
            return (newstkp);
        }
    }
    gen_swap ();
    gen_immediate ();
    output_number (k);
    newline ();
    output_line ("dad \tsp");
    output_line ("sphl");
    gen_swap ();
    return (newstkp);
}
Esempio n. 8
0
int primary(LVALUE *lval) {
    char    sname[NAMESIZE];
    int     num[1], k, symbol_table_idx, offset, reg;
    SYMBOL *symbol;

    lval->ptr_type = 0;  // clear pointer/array type
    lval->tagsym = 0;
    if (match ("(")) {
        k = hier1 (lval);
        needbrack (")");
        return (k);
    }
    if (amatch("sizeof", 6)) {
        needbrack("(");
        gen_immediate();
        if (amatch("int", 3)) output_number(INTSIZE);
        else if (amatch("char", 4)) output_number(1);
        else if (symname(sname)) {
            if (((symbol_table_idx = find_locale(sname)) > -1) ||
                ((symbol_table_idx = find_global(sname)) > -1)) {
                symbol = &symbol_table[symbol_table_idx];
                if (symbol->storage == LSTATIC)
                    error("sizeof local static");
                offset = symbol->offset;
                if ((symbol->type & CINT) ||
                    (symbol->identity == POINTER))
                    offset *= INTSIZE;
                else if (symbol->type == STRUCT)
                    offset *= tag_table[symbol->tagidx].size;
                output_number(offset);
            } else {
                error("sizeof undeclared variable");
                output_number(0);
            }
        } else {
            error("sizeof only on type or variable");
        }
        needbrack(")");
        newline();
        lval->symbol = 0;
        lval->indirect = 0;
        return(0);
    }
    if (symname (sname)) {
        if ((symbol_table_idx = find_locale(sname)) > -1) {
            symbol = &symbol_table[symbol_table_idx];
            reg = gen_get_locale(symbol);
            lval->symbol = symbol;
            lval->indirect = symbol->type;
            if (symbol->type == STRUCT) {
                lval->tagsym = &tag_table[symbol->tagidx];
            }
            if (symbol->identity == ARRAY ||
                (symbol->identity == VARIABLE && symbol->type == STRUCT)) {
                lval->ptr_type = symbol->type;
                return reg;
            }
            if (symbol->identity == POINTER) {
                lval->indirect = CINT;
                lval->ptr_type = symbol->type;
            }
            return FETCH | reg;
        }
        if ((symbol_table_idx = find_global(sname)) > -1) {
            symbol = &symbol_table[symbol_table_idx];
            if (symbol->identity != FUNCTION) {
                lval->symbol = symbol;
                lval->indirect = 0;
                if (symbol->type == STRUCT) {
                    lval->tagsym = &tag_table[symbol->tagidx];
                }
                if (symbol->identity != ARRAY &&
                    (symbol->identity != VARIABLE || symbol->type != STRUCT)) {
                    if (symbol->identity == POINTER) {
                        lval->ptr_type = symbol->type;
                    }
                    return FETCH | HL_REG;
                }
                gen_immediate();
                output_string(symbol->name);
                newline();
                lval->indirect = symbol->type;
                lval->ptr_type = symbol->type;
                return 0;
            }
        }
        blanks();
        if (ch() != '(')
            error("undeclared variable");
        symbol_table_idx = add_global(sname, FUNCTION, CINT, 0, PUBLIC);
        symbol = &symbol_table[symbol_table_idx];
        lval->symbol = symbol;
        lval->indirect = 0;
        return 0;
    }
    lval->symbol = 0;
    lval->indirect = 0;
    if (constant(num))
        return 0;
    else {
        error("invalid expression");
        gen_immediate();
        output_number(0);
        newline();
        junk();
        return 0;
    }
}
Esempio n. 9
0
 // Register generators.  Immediates are indexed and unified by
 // their values; inputs and outputs are indexed arrays passed to
 // the generated function.  Temporary scratch registers can be
 // created as needed, or will be created via the expression
 // generators.
 vr imm_i(int val) { return vr(this, gen_immediate(val)); }