/** * 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; } }
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); }
/** * "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 (); }
/** * 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 */ }
/** * 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; }
/** * 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; } } }
/** * 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); }
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; } }
// 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)); }