void handle_unary_expr(node *n) { if (strcmp(n->children[0]->id, "inc") == 0) { if (LVALUE) { lerr(n->line, "[code_gen] invalid lvalue\n"); } else { /* preincrement the value and return it in t0 */ LVALUE = 1; handle(n->children[1]); LVALUE = 0; e("lw $t1, 0($t0)\n"); e("addiu $t1, $t1, 1\n"); e("sw $t1, 0($t0)\n"); e("move $t0, $t1\n"); } } else if (strcmp(n->children[0]->id, "dec") == 0) { if (LVALUE) { lerr(n->line, "[code_gen] invalid lvalue\n"); } else { /* predecrement the value and return it in t0 */ LVALUE = 1; handle(n->children[1]); LVALUE = 0; e("lw $t1, 0($t0)\n"); e("addiu $t1, $t1, -1\n"); e("sw $t1, 0($t0)\n"); e("move $t0, $t1\n"); } } else if (strcmp(n->children[0]->id, "&") == 0) { int prev_lvalue = LVALUE; LVALUE = 1; handle(n->children[1]); LVALUE = prev_lvalue; } else if (strcmp(n->children[0]->id, "*") == 0) { int prev_lvalue = LVALUE; LVALUE = 0; handle(n->children[1]); LVALUE = prev_lvalue; if (!LVALUE) { /* dereference it */ e("lw $t0, 0($t0)\n"); } } else if (strcmp(n->children[0]->id, "+") == 0) { lerr(n->line, "[code_gen] unary + is just silly\n"); } else if (strcmp(n->children[0]->id, "-") == 0) { lerr(n->line, "[code_gen] unary - is just silly\n"); } else if (strcmp(n->children[0]->id, "~") == 0) { /* bitwise invert */ if (LVALUE) { lerr(n->line, "[code_gen] invalid lvalue\n"); } else { handle(n->children[1]); e("nor $t0, $t0, $t0\n"); } } else if (strcmp(n->children[0]->id, "!") == 0) { /* boolean true/false */ if (LVALUE) { lerr(n->line, "[code_gen] invalid lvalue\n"); } else { char *done = gen_label(); handle(n->children[1]); e("move $t1, $t0\n"); e("move $t0, $zero\n"); e("bne $t1, $t0, %s\n", done); e("nop\n"); e("ori $t0, $zero, 1\n"); e("%s:\n", done); } } else { lerr(n->line, "[code_gen] unary expressions not fully implemented\n"); } }
void allocate(int datareg, int addreg, int floatreg, SNODE *block) /* * allocate will allocate registers for the expressions that have * a high enough desirability. It also puts the function * header, consisting of saved registers and stack decrments for local * variables */ { CSE *csp; ENODE *exptr; unsigned mask, rmask, i, fmask, frmask, size; AMODE *ap, *ap2; mask = asmMask; rmask = asmRMask; fmask = frmask = 0; for (i = cf_freedata; i < datareg; i++) { rmask = rmask | (1 << (15-i)); mask = mask | (1 << i); } for (i = cf_freeaddress + 16; i < addreg; i++) { rmask = rmask | (1 << (23-i)); mask = mask | (1 << (i - 8)); } while (bsort(&olist)) ; /* sort the expression list */ csp = olist; while (csp != 0) { if (csp->reg == - 1 && !(csp->exp->cflags &DF_VOL) && !csp->voidf) { if (desire(csp) < 3) csp->reg = - 1; else { if (csp->exp->nodetype == en_rcon || csp->exp->nodetype == en_fcon || csp->exp->nodetype == en_lrcon || csp->exp ->nodetype == en_floatref || csp->exp->nodetype == en_doubleref || csp->exp->nodetype == en_longdoubleref || csp->exp->nodetype == en_fimaginarycon || csp->exp->nodetype == en_rimaginarycon || csp->exp->nodetype == en_lrimaginarycon || csp->exp->nodetype == en_fimaginaryref || csp->exp->nodetype == en_rimaginaryref || csp->exp->nodetype == en_lrimaginaryref) {} else if ((csp->duses <= csp->uses / 4) && (datareg < cf_maxdata) && dataregs) csp->reg = (datareg)++; else if (!(csp->size == 1 || csp->size == - 1 || csp->size == 5) && (addreg < cf_maxaddress) && addrregs) csp->reg = (addreg)++; else if ((datareg < cf_maxdata) && dataregs) csp->reg = (datareg)++; if (csp->reg != - 1) // if (lvalue(csp->exp)) // csp->seg = defseg(csp->exp->v.p[0]) ; // else if (!csp->seg) { csp->seg = defseg(csp->exp); if (csp->seg) csp->reg = -1; } } } if (csp->reg != - 1) { if (lvalue(csp->exp) && !((SYM*)csp->exp->v.p[0]->v.p[0])->funcparm) { ((SYM*)csp->exp->v.p[0]->v.p[0])->mainsym->inreg = TRUE; ((SYM*)csp->exp->v.p[0]->v.p[0])->mainsym->value.i = - csp ->reg - (csp->size < 0 ? - csp->size: csp->size) *256; } if (csp->reg < 16) { rmask = rmask | (1 << (15-csp->reg)); mask = mask | (1 << csp->reg); } if (csp->reg < 32) { rmask = rmask | (1 << (23-csp->reg)); mask = mask | (1 << (csp->reg - 8)); } else { frmask = frmask | (1 << (39-csp->reg)); fmask = fmask | (1 << (csp->reg - 32)); } } csp = csp->next; } allocstack(); /* Allocate stack space for the local vars */ floatstack_mode = 0; /* no space for floating point temps */ if (currentfunc->intflag || currentfunc->faultflag) { mask = 0; rmask = 0; if (currentfunc->loadds) loadds(); if (prm_farkeyword) { GenPush(ES + 24, am_dreg, 0); GenPush(FS + 24, am_dreg, 0); GenPush(GS + 24, am_dreg, 0); } gen_code(op_pushad, 0, 0); } if ((conscount || try_block_list || currentfunc->value.classdata.throwlist && currentfunc->value.classdata.throwlist->data) && prm_xcept) { xceptoffs = lc_maxauto += sizeof(XCEPTDATA); } if (prm_debug) { rmask = rmask | (1 << (15-EBX)); mask = mask | (1 << EBX); rmask = rmask | (1 << (15-ESI-4)); mask = mask | (1 << (ESI+4)); rmask = rmask | (1 << (15-EDI-4)); mask = mask | (1 << (EDI+4)); } if (prm_cplusplus && prm_xcept || (funcfloat || lc_maxauto || currentfunc ->tp->lst.head && currentfunc->tp->lst.head != (SYM*) - 1) || (currentfunc->value.classdata.cppflags &PF_MEMBER) && !(currentfunc ->value.classdata.cppflags &PF_STATIC) || !prm_smartframes || !stackframeoff) { /* enter is *really* inefficient so we will not use it */ if (!currentfunc->intflag) gen_codes(op_push, 4, makedreg(EBP), 0); gen_codes(op_mov, 4, makedreg(EBP), makedreg(ESP)); if (lc_maxauto) gen_code(op_sub, makedreg(ESP), make_immed(lc_maxauto)); // FIXME ... could auto-alloc an FP value when no frame! frame_ins = peep_tail; } else frame_ins = 0; if (mask != 0) PushRegs(rmask); save_mask = mask; if (fmask != 0) fsave_mask = fmask; if (currentfunc->loadds && !currentfunc->intflag) { loadds(); } if (prm_stackcheck && lc_maxauto) { AMODE *ap1; ap = set_symbol("__stackerror", 1); ap1 = set_symbol("__stackbottom", 0); ap1->mode = am_direct; gen_codes(op_cmp, 4, makedreg(ESP), ap1); gen_codes(op_jb, 0, ap, 0); } AddProfilerData(); if ((conscount || try_block_list || currentfunc->value.classdata.throwlist && currentfunc->value.classdata.throwlist->data) && prm_xcept) { currentfunc->value.classdata.conslabel = nextlabel++; currentfunc->value.classdata.destlabel = nextlabel++; gen_codes(op_mov, 4, makedreg(EAX), make_label(nextlabel - 2)); call_library("__InitExceptBlock"); gen_label(nextlabel - 1); } }
void loadregs(void) /* * initialize allocated registers */ { CSE *csp; ENODE *exptr; unsigned mask, rmask, i, fmask, frmask, size; AMODE *ap, *ap2; csp = olist; while (csp != 0) { int sz; if (csp->reg != - 1) { /* see if preload needed */ exptr = csp->exp; if (!lvalue(exptr) || ((SYM*)exptr->v.p[0]->v.p[0])->funcparm) { exptr = csp->exp; InitRegs(); sz = csp->size; ap = gen_expr_external(exptr, FALSE, F_MEM | F_DREG | F_IMMED, sz); if (csp->reg < 16) { if (ap->mode == am_dreg) peep_tail->oper1->preg = csp->reg; else { if (csp->reg > 3 && chksize(BESZ_WORD, sz)) DIAG("byte sized non-register in analyze"); ap2 = makedreg(csp->reg); ap2->length = BESZ_DWORD; if (ap->mode == am_immed || ap->length == BESZ_DWORD || ap ->length == - BESZ_DWORD) gen_codes(op_mov, BESZ_DWORD, ap2, ap); else if (sz < 0) gen_code(op_movsx, ap2, ap); else gen_code(op_movzx, ap2, ap); } } else if (csp->reg < 32) { if (ap->mode == am_dreg) peep_tail->oper1->preg = csp->reg - 12; else { if (csp->reg - 12 > 3 && chksize(BESZ_WORD, sz)) DIAG("byte sized non-register in analyze"); ap2 = makedreg(csp->reg - 12); ap2->length = BESZ_DWORD; if (ap->mode == am_immed || ap->length == BESZ_DWORD || ap ->length == - BESZ_DWORD) gen_codes(op_mov, BESZ_DWORD, ap2, ap); else if (sz < 0) gen_code(op_movsx, ap2, ap); else gen_code(op_movzx, ap2, ap); } } else { /* Should never get here */ DIAG("float reg assigned in analyze"); } if (lvalue(exptr) && ((SYM*)exptr->v.p[0]->v.p[0])->funcparm) { ((SYM*)exptr->v.p[0]->v.p[0])->mainsym->inreg = TRUE; ((SYM*)exptr->v.p[0]->v.p[0])->mainsym->value.i = - csp ->reg - (csp->size < 0 ? - csp->size: csp->size) *256; } } } csp = csp->next; } gen_label(startlab); }
void genfunc(SYMBOL *funcsp) /* * generate a function body and dump the icode */ { IMODE *allocaAP = NULL; SYMBOL *oldCurrentFunc; EXPRESSION *funcexp = varNode(en_global, funcsp); SYMBOL *tmpl = funcsp; if (total_errors) return; while (tmpl) if (tmpl->templateLevel) break; else tmpl = tmpl->parentClass; // //printf("%s\n", funcsp->name); temporarySymbols = NULL; contlab = breaklab = - 1; structret_imode = 0 ; tempCount = 0; blockCount = 0; blockMax = 0; exitBlock = 0; consIndex = 0; oldCurrentFunc = theCurrentFunc; theCurrentFunc = funcsp; iexpr_func_init(); if (funcsp->xc && funcsp->xc->xctab) { EXPRESSION *exp; xcexp = varNode(en_auto, funcsp->xc->xctab); xcexp = exprNode(en_add, xcexp, intNode(en_c_i, (LLONG_TYPE)&(((struct _xctab *)0)->funcIndex))); deref(&stdpointer, &xcexp); exp = intNode(en_c_i, 0); xcexp = exprNode(en_assign, xcexp, exp); } else { xcexp = NULL; } /* firstlabel = nextLabel;*/ cseg(); gen_line(funcsp->linedata); gen_func(funcexp, 1); /* in C99 inlines can clash if declared 'extern' in multiple modules */ /* in C++ we introduce virtual functions that get coalesced at link time */ if (cparams.prm_cplusplus && (funcsp->linkage == lk_inline || tmpl)) gen_virtual(funcsp, FALSE); else { if (funcsp->storage_class == sc_global || (funcsp->storage_class == sc_member || funcsp->storage_class == sc_virtual) && funcsp->inlineFunc.stmt) globaldef(funcsp); else localdef(funcsp); gen_strlab(funcsp); /* name of function */ } addblock( - 1); if (funcsp->linkage == lk_interrupt || funcsp->linkage == lk_fault) { gen_icode(i_pushcontext, 0,0,0); /* if (funcsp->loadds) */ /* gen_icode(i_loadcontext, 0,0,0); */ } gen_icode(i_prologue,0,0,0); gen_label(startlab); if (cparams.prm_xcept && funcsp->xc && funcsp->xc->xcInitializeFunc) { gen_expr(funcsp, funcsp->xc->xcInitializeFunc, F_NOVALUE, ISZ_UINT); gen_label(funcsp->xc->xcInitLab); } /* if (funcsp->loadds && funcsp->farproc) */ /* gen_icode(i_loadcontext, 0,0,0); */ AllocateLocalContext(NULL, funcsp); if (funcsp->allocaUsed) { EXPRESSION *allocaExp = anonymousVar(sc_auto, &stdpointer); allocaAP = gen_expr(funcsp, allocaExp, 0, ISZ_ADDR); gen_icode(i_savestack, 0, allocaAP, 0); } /* Generate the icode */ /* LCSE is done while code is generated */ genstmt(funcsp->inlineFunc.stmt->lower, funcsp); if (funcsp->inlineFunc.stmt->blockTail) { gen_icode(i_functailstart, 0, 0, 0); genstmt(funcsp->inlineFunc.stmt->blockTail, funcsp); gen_icode(i_functailend, 0, 0, 0); } genreturn(0, funcsp, 1, 0, allocaAP); gen_func(funcexp, 0); tFree(); InsertParameterThunks(funcsp, blockArray[1]); optimize(funcsp); FreeLocalContext(NULL, funcsp); AllocateStackSpace(funcsp); FillInPrologue(intermed_head, funcsp); /* Code gen from icode */ rewrite_icode(); /* Translate to machine code & dump */ if (chosenAssembler->gen->post_function_gen) chosenAssembler->gen->post_function_gen(funcsp, intermed_head); if (cparams.prm_cplusplus && (funcsp->linkage == lk_inline || tmpl)) gen_endvirtual(funcsp); XTDumpTab(funcsp); intermed_head = NULL; dag_rundown(); oFree(); theCurrentFunc = oldCurrentFunc; if (blockCount > maxBlocks) maxBlocks = blockCount; if (tempCount > maxTemps) maxTemps = tempCount; }
IMODE *genstmt(STATEMENT *stmt, SYMBOL *funcsp) /* * genstmt will generate a statement and follow the next pointer * until the block is generated. */ { IMODE *rv = NULL; while (stmt != 0) { STATEMENT *last = stmt; switch (stmt->type) { case st_varstart: gen_varstart(stmt->select); break; case st_dbgblock: gen_dbgblock(stmt->label); break; break; case st_block: rv = genstmt(stmt->lower, funcsp); genstmt(stmt->blockTail, funcsp); break; case st_label: gen_label((int)stmt->label); break; case st_goto: gen_igoto(i_goto, (int)stmt->label); break; case st_asmgoto: gen_igoto(i_asmgoto, (int)stmt->label); break; case st_asmcond: gen_igoto(i_asmcond, (int)stmt->label); break; case st_try: gen_try(funcsp, stmt, stmt->label, stmt->endlabel, stmt->breaklabel, stmt->lower); break; case st_catch: { STATEMENT *last; while (stmt && stmt->type == st_catch) { gen_catch(funcsp, stmt, stmt->altlabel, stmt->breaklabel, stmt->lower); last = stmt; stmt = stmt->next; } stmt = last; gen_label(stmt->breaklabel); } break; case st_expr: case st_declare: if (stmt->select) rv = gen_expr(funcsp, stmt->select, F_NOVALUE, natural_size(stmt->select)); break; case st_return: genreturn(stmt, funcsp, 0, 0, NULL); break; case st_line: gen_line(stmt->lineData); break; case st_select: genselect(stmt, funcsp, TRUE); break; case st_notselect: genselect(stmt, funcsp, FALSE); break; case st_switch: genxswitch(stmt, funcsp); break; case st__genword: gen_genword(stmt, funcsp); break; case st_passthrough: gen_asm(stmt); break; case st_datapassthrough: gen_asmdata(stmt); break; default: diag("unknown statement."); break; } if (last->type != st_return && last->destexp) { gen_expr(funcsp, last->destexp, F_NOVALUE, ISZ_ADDR); } stmt = stmt->next; } return rv; }
void genreturn(STATEMENT *stmt, SYMBOL *funcsp, int flag, int noepilogue, IMODE *allocaAP) /* * generate a return statement. */ { IMODE *ap = NULL, *ap1, *ap3; EXPRESSION ep; int size; /* returns a value? */ if (stmt != 0 && stmt->select != 0) { if (basetype(funcsp->tp)->btp && (isstructured(basetype(funcsp->tp)->btp) || basetype(basetype(funcsp->tp)->btp)->type == bt_memberptr)) { EXPRESSION *en = anonymousVar(sc_parameter, &stdpointer); SYMBOL *sp = en->v.sp; gen_expr(funcsp, stmt->select, 0, ISZ_ADDR); DumpIncDec(funcsp); sp->offset = chosenAssembler->arch->retblocksize; sp->allocate = FALSE; if ((funcsp->linkage == lk_pascal) && basetype(funcsp->tp)->syms->table[0] && ((SYMBOL *)basetype(funcsp->tp)->syms->table[0])->tp->type != bt_void) sp->offset = funcsp->paramsize; deref(&stdpointer, &en); ap = gen_expr(funcsp, en, 0, ISZ_ADDR); size = ISZ_ADDR; } else { size = natural_size(stmt->select); ap3 = gen_expr(funcsp, stmt->select, 0, size); DumpIncDec(funcsp); ap = LookupLoadTemp(NULL, ap3); if (ap != ap3) { IMODE *barrier; if (stmt->select->isatomic) { barrier = doatomicFence(funcsp, stmt->select, NULL); } gen_icode(i_assn, ap, ap3, NULL); if (stmt->select->isatomic) { doatomicFence(funcsp, stmt->select, barrier); } } if (abs(size) < ISZ_UINT) size = -ISZ_UINT; } } else { DumpIncDec(funcsp); } if (ap) { ap1 = tempreg(size, 0); ap1->retval = TRUE; gen_icode(i_assn, ap1, ap, 0); } if (stmt && stmt->destexp) { gen_expr(funcsp, stmt->destexp, F_NOVALUE, ISZ_ADDR); } /* create the return or a branch to the return * return is put at end of function... */ if (flag) { int retsize = 0; if (funcsp->linkage == lk_pascal || funcsp->linkage == lk_stdcall) { retsize = funcsp->paramsize ; } gen_label(retlab); if (!noepilogue) { if (allocaAP) { gen_icode(i_loadstack, 0, allocaAP, 0); } /* if (funcsp->loadds && funcsp->farproc) gen_icode(i_unloadcontext,0,0,0); */ if (cparams.prm_xcept && funcsp->xc && funcsp->xc->xcRundownFunc) gen_expr(funcsp, funcsp->xc->xcRundownFunc, F_NOVALUE, ISZ_UINT); gen_icode(i_epilogue,0,0,0); if (funcsp->linkage == lk_interrupt || funcsp->linkage == lk_fault) { /* if (funcsp->loadds) gen_icode(i_unloadcontext,0,0,0); */ gen_icode(i_popcontext, 0,0,0); gen_icode(i_rett, 0, make_immed(ISZ_UINT,funcsp->linkage == lk_interrupt), 0); } else { gen_icode(i_ret, 0, make_immed(ISZ_UINT,retsize), 0); } } } else { /* not using gen_igoto because it will make a new block */ gen_icode(i_goto, NULL, NULL, NULL); intermed_tail->dc.v.label = retlab; } }
void write_syntax(FILE *out, Syntax *syntax){ printf("write_syntax\n"); if(syntax->type == IMMEDIATE){ printf("case gen immediate\n"); emit_instr_format(out, "mov", "$%d, %%eax", syntax->immediate->value); } else if (syntax->type == VARIABLE) { printf("case gen var\n"); emit_instr_format(out, "mov", "-%d(%%ebp), %%eax", 4*(syntax->variable->var_index+1)); } else if (syntax->type == BINARY_OPERATOR){ printf("case gen binary\n"); BinaryExpression *binary_syntax = syntax->binary_expression; //reserve space for temporary write_syntax(out, binary_syntax->left); emit_instr(out, "sub", "$4, %esp"); emit_instr(out, "mov", "%eax, 0(%esp)"); write_syntax(out, binary_syntax->right); if(binary_syntax->binary_type == MULTIPLICATION){ emit_instr(out, "mull", "0(%esp)"); //emit_instr(out, "mull", "%ebx"); emit_instr(out, "add", "$4, %esp"); } else if (binary_syntax->binary_type == DIVISION) { //edx:eax / 0(%esp) emit_instr(out, "mov", "$0, %edx"); emit_instr(out, "xchg", "0(%esp), %eax"); emit_instr(out, "divl", "0(%esp)"); emit_instr(out, "add", "$4, %esp"); } else if (binary_syntax->binary_type == MOD) { emit_instr(out, "mov", "$0, %edx"); emit_instr(out, "xchg", "0(%esp), %eax"); emit_instr(out, "divl", "0(%esp)"); emit_instr(out, "mov", "%edx, %eax"); emit_instr(out, "add", "$4, %esp"); } else if (binary_syntax->binary_type == ADDITION){ emit_instr(out, "add", "0(%esp), %eax"); //emit_instr(out, "add", "%ebx, %eax"); //TODO: check if this instruction redundant emit_instr(out, "add", "$4, %esp"); } else if (binary_syntax->binary_type == SUBTRACTION) { emit_instr(out, "sub", "%eax, 0(%esp)"); emit_instr(out, "mov", "0(%esp), %eax"); emit_instr(out, "add", "$4, %esp"); } else if (binary_syntax->binary_type == COMPARISION) { emit_instr(out, "xor", "0(%esp), %eax"); emit_instr(out, "add", "$4, %esp"); } } else if (syntax->type == ASSIGNMENT) { printf("case gen assignment\n"); write_syntax(out, syntax->assignment->expression); emit_instr_format(out, "mov", "%%eax, -%d(%%ebp)", 4*(syntax->assignment->var_index+1)); } else if (syntax->type == SHOW_STATEMENT){ printf("case get SHOW statement"); if(syntax->show_statement->decOrHex == 'd'){ emit_instr_format(out, "pushl", "-%d(%%ebp)", 4*(syntax->show_statement->var->variable->var_index+1)); emit_instr(out, "pushl", "$.LC0"); emit_instr(out, "call", "_printf"); } else if (syntax->show_statement->decOrHex == 'h') { emit_instr_format(out, "pushl", "-%d(%%ebp)", 4*(syntax->show_statement->var->variable->var_index+1)); emit_instr(out, "pushl", "$.LC1"); emit_instr(out, "call", "_printf"); } } else if (syntax->type == IF_STATEMENT){ char *label; printf("case if statement kaa"); write_syntax(out, syntax->if_statement->condition); emit_instr(out, "test", "%eax, %eax"); label = gen_label("LC"); emit_instr_format(out, "jne", "%s", label); write_syntax(out, syntax->if_statement->then); emit_label(out, label); //emit_instr(out, "call", "_printf"); } else if (syntax->type == FOR_STATEMENT) { char *start_label; char *end_label; if(syntax->for_statement->startNum->type == IMMEDIATE){ emit_instr_format(out, "mov", "$%d, %%edi", syntax->for_statement->startNum->immediate->value); } else if (syntax->for_statement->startNum->type == VARIABLE) { emit_instr_format(out, "mov", "-%d(%%ebp), %%edi", 4*(syntax->for_statement->startNum->variable->var_index+1)); } if(syntax->for_statement->stopNum->type == IMMEDIATE){ emit_instr_format(out, "mov", "$%d, %%esi", syntax->for_statement->stopNum->immediate->value); } else if (syntax->for_statement->stopNum->type == VARIABLE) { emit_instr_format(out, "mov", "-%d(%%ebp), %%esi", 4*(syntax->for_statement->stopNum->variable->var_index+1)); } start_label = gen_label("LC"); end_label = gen_label("LC"); emit_label(out, start_label); emit_instr(out, "cmp", "%edi, %esi"); //confuse which jump condition to use. emit_instr_format(out, "jg", "%s", end_label); write_syntax(out, syntax->for_statement->expression); emit_instr(out, "inc", "%esi"); emit_instr_format(out, "jmp", "%s", start_label); emit_label(out, end_label); } else if (syntax->type == INPUT) { //printf("gen INPUT\n"); List *lines = syntax->input->lines; int i; for (i = list_length(lines)-1; i >= 0; i--) { //printf("*"); write_syntax(out, list_get(lines, i)); } } else if(syntax->type = MINUS){ printf("gen minus\n"); write_syntax(out,syntax->minus->expression); emit_instr(out, "xor", "%ebx, %ebx"); emit_instr(out, "sub", "%eax, %ebx"); emit_instr(out, "mov", "%ebx, %eax"); } else { printf("last case\n"); } /*else if(syntax->type = MINUS){ write_syntax(out,syntax->expression); emit_instr(out, "sub", "0(%esp), %eax"); }*/ }
void doinit(SYM *sp) { static bool first = true; char lbl[200]; int algn; enum e_sg oseg; char buf[500]; std::streampos endpoint; TYP *tp; hasPointer = false; if (first) { firstPrim = true; first = false; } oseg = noseg; lbl[0] = 0; // Initialize constants into read-only data segment. Constants may be placed // in ROM along with code. if (sp->isConst) { oseg = rodataseg; } if (sp->storage_class == sc_thread) { if (sp->tp->type==bt_struct || sp->tp->type==bt_union) algn = imax(sp->tp->alignment,8); else if (sp->tp->type==bt_pointer)// && sp->tp->val_flag) algn = imax(sp->tp->GetBtp()->alignment,8); else algn = 2; seg(oseg==noseg ? tlsseg : oseg,algn); nl(); } else if (sp->storage_class == sc_static || lastst==assign) { if (sp->tp->type==bt_struct || sp->tp->type==bt_union) algn = imax(sp->tp->alignment,8); else if (sp->tp->type==bt_pointer)// && sp->tp->val_flag) algn = imax(sp->tp->GetBtp()->alignment,8); else algn = 2; seg(oseg==noseg ? dataseg : oseg,algn); /* initialize into data segment */ nl(); /* start a new line in object */ } else { if (sp->tp->type==bt_struct || sp->tp->type==bt_union) algn = imax(sp->tp->alignment,8); else if (sp->tp->type==bt_pointer)// && sp->tp->val_flag) algn = imax(sp->tp->GetBtp()->alignment,8); else algn = 2; seg(oseg==noseg ? (lastst==assign ? dataseg : bssseg) : oseg,algn); /* initialize into data segment */ nl(); /* start a new line in object */ } if (sp->storage_class == sc_static || sp->storage_class == sc_thread) { //strcpy_s(glbl, sizeof(glbl), gen_label((int)sp->value.i, (char *)sp->name->c_str(), GetNamespace(), 'D')); if (sp->tp->IsSkippable()) { patchpoint = ofs.tellp(); sprintf_s(buf, sizeof(buf), "\talign\t8\n\tdw\t$FFF0200000000001\n"); ofs.printf(buf); } sp->realname = my_strdup(put_label((int)sp->value.i, (char *)sp->name->c_str(), GetNamespace(), 'D')); strcpy_s(glbl2, sizeof(glbl2), gen_label((int)sp->value.i, (char *)sp->name->c_str(), GetNamespace(), 'D')); } else { if (sp->storage_class == sc_global) { strcpy_s(lbl, sizeof(lbl), "public "); if (curseg==dataseg) strcat_s(lbl, sizeof(lbl), "data "); else if (curseg==bssseg) strcat_s(lbl, sizeof(lbl), "bss "); else if (curseg==tlsseg) strcat_s(lbl, sizeof(lbl), "tls "); } strcat_s(lbl, sizeof(lbl), sp->name->c_str()); if (sp->tp->IsSkippable()) { patchpoint = ofs.tellp(); sprintf_s(buf, sizeof(buf), "\talign\t8\n\tdw\t$FFF0200000000001\n"); ofs.printf(buf); } strcpy_s(glbl2, sizeof(glbl2), sp->name->c_str()); gen_strlab(lbl); } if (lastst == kw_firstcall) { GenerateByte(1); return; } else if( lastst != assign) { hasPointer = sp->tp->FindPointer(); genstorage(sp->tp->size); } else { NextToken(); hasPointer = sp->tp->FindPointer(); typ_sp = 0; tp = sp->tp; push_typ(tp); while (tp = tp->GetBtp()) { push_typ(tp); } brace_level = 0; sp->tp->Initialize(nullptr); if (sp->tp->numele == 0) { if (sp->tp->GetBtp()) { if (sp->tp->GetBtp()->type == bt_char || sp->tp->GetBtp()->type == bt_uchar || sp->tp->GetBtp()->type == bt_ichar || sp->tp->GetBtp()->type == bt_iuchar ) { sp->tp->numele = laststrlen; sp->tp->size = laststrlen; } } } } if (!hasPointer && sp->tp->IsSkippable()) { endpoint = ofs.tellp(); ofs.seekp(patchpoint); sprintf_s(buf, sizeof(buf), "\talign\t8\n\tdw\t$%I64X\n", ((genst_cumulative + 7LL) >> 3LL) | 0xFFF0200000000000LL); ofs.printf(buf); ofs.seekp(endpoint); genst_cumulative = 0; }