/** * asm - store the primary register into the specified static memory cell * @param sym */ void gen_put_memory(SYMBOL *sym) { if ((sym->identity != POINTER) && (sym->type & CCHAR)) output_with_tab ("storeb r1 "); else output_with_tab("store r1 "); describe_access(sym); }
/** * fetch a static memory cell into the primary register * @param sym */ void gen_get_memory(SYMBOL *sym) { if ((sym->identity != POINTER) && (sym->type == CCHAR)) output_with_tab ("loadsb r1 "); else if ((sym->identity != POINTER) && (sym->type == UCHAR)) output_with_tab("loadub r1 "); else output_with_tab ("load r1 "); describe_access(sym); }
/** * asm - store the primary register into the specified static memory cell * @param sym */ void gen_put_memory(SYMBOL *sym) { if ((sym->identity != POINTER) && (sym->type & CCHAR)) { output_line ("mov \ta,l"); output_with_tab ("sta \t"); } else { output_with_tab ("shld\t"); } output_string (sym->name); newline (); }
/** * test the primary register and jump if false to label * @param label the label * @param ft if true jnz is generated, jz otherwise */ void gen_test_jump(int label, int ft) { output_line ("test r1"); if (ft) output_with_tab ("jumpnz "); else output_with_tab ("jumpz "); print_label (label); newline (); }
/** * test the primary register and jump if false to label * @param label the label * @param ft if true jnz is generated, jz otherwise */ void gen_test_jump(int label, int ft) { output_line ("mov \ta,h"); output_line ("ora \tl"); if (ft) output_with_tab ("jnz \t"); else output_with_tab ("jz \t"); print_label (label); newline (); }
/** * call the specified subroutine name * @param sname subroutine name */ void gen_call(char *sname) { output_with_tab ("call "); output_string (sname); output_byte(','); output_number(args); newline (); }
/** * fetch a static memory cell into the primary register * @param sym */ void gen_get_memory(SYMBOL *sym) { if ((sym->identity != POINTER) && (sym->type == CCHAR)) { output_with_tab ("lda\t"); output_string (sym->name); newline (); gen_call ("ccsxt"); } else if ((sym->identity != POINTER) && (sym->type == UCHAR)) { output_with_tab("lda\t"); output_string(sym->name); newline(); output_line("mov \tl,a"); output_line("mvi \th,#0"); } else { output_with_tab ("lhld\t"); output_string (sym->name); newline (); } }
void gen_epilogue(void) { int i; /* FIXME: usual case we can pop these in this order need to spot the sp position and optimize accordingly */ for (i = nextreg - 1; i >= 3; i--) { if (stkp == regv[i]) { stkp += 2; output_with_tab("pop r"); output_number(i); } else { output_with_tab("load r"); output_number(i); output_string(" ("); output_number(regv[i]); output_string("+fp)"); } newline(); } }
/** * 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); output_with_tab("add sp "); output_decimal(k); newline(); return (newstkp); }
int gen_register(int vp, int size, int typ) { if (size != 2) return -1; if (nextreg > 6) return -1; stkp = stkp - 2; regv[nextreg] = stkp; output_with_tab("push r"); output_number(nextreg); newline(); return nextreg++; }
/** * multiply the primary register by the length of some variable * @param type * @param size */ void gen_multiply(int type, int size) { switch (type) { case CINT: case UINT: output_line("mul r1 2"); break; case STRUCT: output_with_tab("mul r1 "); output_number(size); newline(); break; default: break; } }
/** * report errors */ void errorsummary(void) { if (ncmp) error("missing closing bracket"); newline(); gen_comment(); output_decimal(errcnt); if (errcnt) errfile = YES; output_string(" error(s) in compilation"); newline(); gen_comment(); output_with_tab("literal pool:"); output_decimal(litptr); newline(); gen_comment(); output_with_tab("global pool:"); output_decimal(global_table_index - rglobal_table_index); newline(); gen_comment(); output_with_tab("Macro pool:"); output_decimal(macptr); newline(); if (errcnt > 0) pl("Error(s)"); }
/** * decrement the primary register by one if char, INTSIZE if int */ void gen_decrement_primary_reg(LVALUE *lval) { switch (lval->ptr_type) { case CINT: case UINT: output_line("sub r1 2"); break; case STRUCT: output_with_tab("sub r1 "); output_number(lval->tagsym->size - 1); newline(); break ; default: output_line("sub r1 1"); break; } }
/** * 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; } } }
/** * Output the variable symbol at scptr as an extrn or a public * @param scptr */ void ppubext(SYMBOL *scptr) { if (symbol_table[current_symbol_table_idx].storage == STATIC) return; output_with_tab (scptr->storage == EXTERN ? ";extrn\t" : ".globl\t"); output_string (scptr->name); newline(); }
/** * print partial instruction to get an immediate value into * the secondary register */ void gen_immediate2(void) { output_with_tab ("lxi \td,"); }
/** * Squirrel away argument count in a register that modstk doesn't touch. * @param d */ void gnargs(int d) { output_with_tab ("mvi \ta,"); output_number(d); newline (); }
/** * Case jump instruction */ void gen_jump_case(void) { output_with_tab ("jmp \tcccase"); newline (); }
/** * print pseudo-op to define a word */ void gen_def_word(void) { output_with_tab (".dw\t"); }
/** * print pseudo-op to define storage */ void gen_def_storage(void) { output_with_tab (".ds\t"); }
/** * print pseudo-op to define a byte */ void gen_def_byte(void) { output_with_tab (".db\t"); }
/** * print partial instruction to get an immediate value into * the primary register */ void gen_immediate(void) { output_with_tab ("load r1 "); }
/** * jump to specified internal label number * @param label the label */ void gen_jump(int label) { output_with_tab ("jmp \t"); print_label (label); newline (); }
/** * call the specified subroutine name * @param sname subroutine name */ void gen_call(char *sname) { output_with_tab ("call\t"); output_string (sname); newline (); }
/** * print partial instruction to get an immediate value into * the primary register */ void gen_immediate(void) { output_with_tab ("lxi \th,"); }
/** * add offset to primary register * @param val the value */ void add_offset(int val) { output_with_tab("add r1 "); output_number(val); newline(); }
/** * Output the function symbol at scptr as an extrn or a public * @param scptr */ void fpubext(SYMBOL *scptr) { if (scptr->storage == STATIC) return; output_with_tab (scptr->offset == FUNCTION ? ".globl\t" : ";extrn\t"); output_string (scptr->name); newline (); }