예제 #1
0
파일: handlers.c 프로젝트: Gwaltrip/CLP
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");
	}			
}
예제 #2
0
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);
    }
}
예제 #3
0
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);
}
예제 #4
0
파일: istmt.c 프로젝트: doniexun/OrangeC
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;
}
예제 #5
0
파일: istmt.c 프로젝트: doniexun/OrangeC
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;
}
예제 #6
0
파일: istmt.c 프로젝트: doniexun/OrangeC
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;
    }
}
예제 #7
0
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");
	}*/
}
예제 #8
0
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;
	}