Beispiel #1
0
/*
 *      generate shift equals operators.
 */
AMODE *GenerateAssignShift(ENODE *node,int flags,int size,int op)
{
	struct amode    *ap1, *ap2, *ap3;

	ap1 = GetTempRegister();
	//size = GetNaturalSize(node->p[0]);
    ap3 = GenerateExpression(node->p[0],F_ALL,size);
    ap2 = GenerateExpression(node->p[1],F_REG | F_IMMED,size);
	if (ap3->mode==am_reg)
		GenerateDiadic(op_mov,0,ap1,ap3);
	else if (ap3->mode == am_immed) {
		error(ERR_LVALUE);
		if (isFISA64)
		    FISA64_GenLdi(ap1,ap2);
        else
		    GenerateDiadic(op_ldi,0,ap1,ap3);
	}
	else
        GenLoad(ap1,ap3,size);
	MaskShift(op, ap1, size);
	if (ap2->mode==am_immed)
		GenerateTriadic(op,0,ap1,ap1,make_immed(ap2->offset->i));
	else
		GenerateTriadic(op,0,ap1,ap1,ap2);
	if (ap3->mode != am_reg)
        GenStore(ap1,ap3,size);
    ReleaseTempRegister(ap2);
    ReleaseTempRegister(ap3);
    MakeLegalAmode(ap1,flags,size);
    return ap1;
}
Beispiel #2
0
void GenerateSpinUnlock(Statement *stmt)
{
	AMODE *ap;

    if( stmt != NULL && stmt->exp != NULL )
	{
		initstack();
		ap = GenerateExpression(stmt->exp,F_REG|F_IMMED,8);
		// Force return value into register 1
		if( ap->preg != 1 ) {
			if (ap->mode == am_immed) {
                if (isFISA64)
                    FISA64_GenLdi(makereg(1),ap,8);
                else
				    GenerateTriadic(op_ori, 0, makereg(1),makereg(0),ap);
            }
			else
				GenerateDiadic(op_mov, 0, makereg(1),ap);
			if (isRaptor64)
				GenerateDiadic(op_outb, 0, makereg(0),make_indexed((int64_t)stmt->incrExpr,1));
    		else if (isFISA64) {
                GenerateMonadic(op_bsr, 0, make_string("_UnlockSema"));
            }
			else
				GenerateDiadic(op_sb, 0, makereg(0),make_indexed((int64_t)stmt->incrExpr,1));
		}
		ReleaseTempRegister(ap);
	}
}
Beispiel #3
0
void GenerateFirstcall(Statement *stmt)
{
	int     lab1, lab2;
	char buf[20];
	AMODE *ap1,*ap2;

    lab1 = contlab;         /* save old continue label */
    lab2 = breaklab;        /* save old break label */
    contlab = nextlabel++;  /* new continue label */
    if( stmt->s1 != NULL )      /* has block */
    {
        breaklab = nextlabel++;
		ap1 = GetTempRegister();
		GenerateDiadic(op_lb,0,ap1,make_string(stmt->fcname));
		if (isThor) {
            GenerateDiadic(op_tst,0,make_string("p0"), ap1);
          	GeneratePredicatedMonadic(0,PredOp(op_eq),op_br,0,make_clabel(breaklab));
        }
        else
        	GenerateDiadic(op_beq,0,ap1,make_clabel(breaklab));
		ReleaseTempRegister(ap1);
		GenerateDiadic(op_sb,0,makereg(0),make_string(stmt->fcname));
		GenerateStatement(stmt->s1);
        GenerateLabel(breaklab);
        breaklab = lab2;        /* restore old break label */
    }
    contlab = lab1;         /* restore old continue label */
}
Beispiel #4
0
// push the operand expression onto the stack.
//
static void GeneratePushParameter(ENODE *ep, int i, int n)
{    
	AMODE *ap;

	if (ep==NULL)
		return;
	ap = GenerateExpression(ep,F_REG|F_IMM8,8);
	if (ap==NULL)
		return;
	if (ap->mode==am_immed)
		GenerateDiadic(op_ss|op_sti,0,ap,make_indexed((n-i)*8-8,SP));
	else
		GenerateDiadic(op_ss|op_sw,0,ap,make_indexed((n-i)*8-8,SP));
	ReleaseTempRegister(ap);
}
Beispiel #5
0
// push the operand expression onto the stack.
//
static void GeneratePushParameter(ENODE *ep, int i, int n)
{    
	AMODE *ap;
	ap = GenerateExpression(ep,F_REG,8);
	GenerateDiadic(op_sw,0,ap,make_indexed((n-i)*8-8,30));
	ReleaseTempRegister(ap);
}
Beispiel #6
0
/*
 *      generate code to evaluate an if statement.
 */
void GenerateIf(Statement *stmt)
{
	int lab1, lab2, oldbreak;
    lab1 = nextlabel++;     /* else label */
    lab2 = nextlabel++;     /* exit label */
    oldbreak = breaklab;    /* save break label */
    initstack();            /* clear temps */
	if (gCpu!=888)
		if (stmt->predreg==70)
			GenerateFalseJump(stmt->exp,lab1,stmt->predreg);
    GenerateFalseJump(stmt->exp,lab1,stmt->predreg);
    //if( stmt->s1 != 0 && stmt->s1->next != 0 )
    //    if( stmt->s2 != 0 )
    //        breaklab = lab2;
    //    else
    //        breaklab = lab1;
    GenerateStatement(stmt->s1);
    if( stmt->s2 != 0 )             /* else part exists */
    {
        GenerateDiadic(isThor ? op_br:op_bra,0,make_clabel(lab2),0);
        if (mixedSource)
          	GenerateMonadic(op_rem,0,make_string("; else"));
        GenerateLabel(lab1);
        //if( stmt->s2 == 0 || stmt->s2->next == 0 )
        //    breaklab = oldbreak;
        //else
        //    breaklab = lab2;
        GenerateStatement(stmt->s2);
        GenerateLabel(lab2);
    }
    else                            /* no else code */
        GenerateLabel(lab1);
    breaklab = oldbreak;
}
Beispiel #7
0
void GenerateThrow(Statement *stmt)
{
	AMODE *ap;

    if( stmt != NULL && stmt->exp != NULL )
	{
		initstack();
		ap = GenerateExpression(stmt->exp,F_ALL,8);
		if (ap->mode==am_immed) {
            if (isFISA64)
                FISA64_GenLdi(makereg(1),ap,8);
            else
			    GenerateTriadic(op_ori,0,makereg(1),makereg(0),ap);
        }
		else if( ap->mode != am_reg)
			GenerateDiadic(op_lw,0,makereg(1),ap);
		else if (ap->preg != 1 )
			GenerateTriadic(op_or,0,makereg(1),ap,makereg(0));
		ReleaseTempRegister(ap);
		if (isFISA64)
		    FISA64_GenLdi(makereg(2),make_immed((int64_t)stmt->label),8);
        else
		    GenerateTriadic(op_ori,0,makereg(2),makereg(0),make_immed((int64_t)stmt->label));
	}
	GenerateMonadic(isThor?op_br:op_bra,0,make_clabel(throwlab));
}
Beispiel #8
0
void LoadFPRegister(int regno, int number)
{
	if (fpreg_in_use[regno] >= 0)
		fatal("LoadRegister():register still in use");
	fpreg_in_use[regno] = number;
	GenerateDiadic(op_lf,'d',makefpreg(regno),make_indexed(currentFn->GetTempBot()-number*sizeOfWord,regFP));
    fpreg_alloc[number].f.isPushed = 'F';
}
Beispiel #9
0
void SpillFPRegister(Operand *ap, int number)
{
	GenerateDiadic(op_sf,'d',ap,make_indexed(currentFn->GetTempBot()-ap->deep*sizeOfWord,regFP));
    fpreg_stack[fpreg_stack_ptr].Operand = ap;
    fpreg_stack[fpreg_stack_ptr].f.allocnum = number;
    if (fpreg_alloc[number].f.isPushed=='T')
		fatal("SpillRegister(): register already spilled");
    reg_alloc[number].f.isPushed = 'T';
}
Beispiel #10
0
AMODE *GenerateFunctionCall(ENODE *node, int flags)
{ 
	AMODE *ap, *result;
	SYM *sym;
    int             i;
	int msk;

 	msk = SaveTempRegs();
	sym = NULL;
    i = GeneratePushParameterList(node->p[1]);
	// Call the function
	if( node->p[0]->nodetype == en_nacon ) {
        GenerateDiadic(op_call,0,make_offset(node->p[0]),NULL);
		sym = gsearch(node->p[0]->sp);
	}
    else
    {
		ap = GenerateExpression(node->p[0],F_REG,8);
		ap->mode = am_ind;
		GenerateDiadic(op_jal,0,makereg(31),ap);
		ReleaseTempRegister(ap);
    }
	// Pop parameters off the stack
	if (i!=0) {
		if (sym) {
			if (!sym->IsPascal)
				GenerateTriadic(op_addui,0,makereg(30),makereg(30),make_immed(i * 8));
		}
		else
			GenerateTriadic(op_addui,0,makereg(30),makereg(30),make_immed(i * 8));
	}
	RestoreTempRegs(msk);
    result = GetTempRegister();
    if( result->preg != 1 || (flags & F_REG) == 0 )
		if (sym) {
			if (sym->tp->btp->type==bt_void)
				;
			else
				GenerateDiadic(op_mov,0,result,makereg(1));
		}
		else
			GenerateDiadic(op_mov,0,result,makereg(1));
    return result;
}
Beispiel #11
0
AMODE *GenerateFunctionCall(ENODE *node, int flags)
{ 
	AMODE *ap, *result;
	SYM *sym;
    int             i;
	int msk;
	int sp;

 	//msk = SaveTempRegs();
	sp = TempInvalidate();
	sym = (SYM*)NULL;
    i = GeneratePushParameterList(node->p[1]);
	// Call the function
	if( node->p[0]->nodetype == en_cnacon ) {
        GenerateMonadic(op_jsr,0,make_offset(node->p[0]));
		sym = gsearch(node->p[0]->sp);
	}
    else
    {
		ap = GenerateExpression(node->p[0],F_BREG,8);
		ap->mode = am_brind;
		GenerateDiadic(op_jsr,0,makebreg(LR),ap);
		ReleaseTempRegister(ap);
    }
	// Pop parameters off the stack
	if (i!=0) {
		if (sym) {
			if (!sym->IsPascal)
				GenerateTriadic(op_addui,0,makereg(regSP),makereg(regSP),make_immed(i * 8));
		}
		else
			GenerateTriadic(op_addui,0,makereg(regSP),makereg(regSP),make_immed(i * 8));
	}
	//RestoreTempRegs(msk);
	TempRevalidate(sp);
	ap = GetTempRegister();
	GenerateDiadic(op_mov,0,ap,makereg(1));
    return ap;
}
Beispiel #12
0
// Generate a return statement.
//
void GenerateReturn(Statement *stmt)
{
	AMODE *ap;
	int nn;
	int lab1;
	int cnt;

	// Generate code to evaluate the return expression.
    if( stmt != NULL && stmt->exp != NULL )
	{
		initstack();
		ap = GenerateExpression(stmt->exp,F_ALL & ~F_BREG,8);
		// Force return value into register 1
		if( ap->preg != 1 ) {
			if (ap->mode == am_immed)
				GenerateDiadic(op_ldi, 0, makereg(1),ap);
			else if (ap->mode == am_reg)
				GenerateDiadic(op_mov, 0, makereg(1),ap);
			else
				GenerateDiadic(op_lw,0,makereg(1),ap);
		}
	}
	GenerateMonadic(op_br,0,make_clabel(retlab));
}
Beispiel #13
0
static void MaskShift(int op, AMODE *ap1, int size)
{
	switch(op) {
	case op_shru:
j1:
		switch (size) {
			case 1:	GenerateTriadic(op_andi,0,ap1,ap1,make_immed(0xff)); break;
			case 2:	GenerateTriadic(op_andi,0,ap1,ap1,make_immed(0xffff)); break;
			case 4:	GenerateTriadic(op_andi,0,ap1,ap1,make_immed(0xffffffff)); break;
			default:	;
		}
		break;
    case op_srl:
    case op_sra:
	case op_asr:
	case op_shr:
		if (isTable888|isFISA64|isThor) {
			if (ap1->isUnsigned)
				goto j1;
			switch (size) {
				case 1:	GenerateDiadic(op_sxb,0,ap1,ap1); break;
				case 2:	GenerateDiadic(op_sxc,0,ap1,ap1); break;
				case 4:	GenerateDiadic(op_sxh,0,ap1,ap1); break;
				default:	;
			}
		}
		else {
			switch (size) {
				case 1:	GenerateDiadic(op_sext8,0,ap1,ap1); break;
				case 2:	GenerateDiadic(op_sext16,0,ap1,ap1); break;
				case 4:	GenerateDiadic(op_sext32,0,ap1,ap1); break;
				default:	;
			}
		}
		break;
	}
}
Beispiel #14
0
/*
 *      generate a linear search switch statement.
 */
void GenerateSwitch(Statement *stmt)
{    
     AMODE *ap2;
	int             curlab;
	int *bf;
	int nn;
	int predreg;
        struct snode    *defcase;
        struct amode    *ap;
		predreg = stmt->predreg;
        curlab = nextlabel++;
        defcase = 0;
        initstack();
		if (stmt->exp==NULL) {
			error(ERR_BAD_SWITCH_EXPR);
			return;
		}
        ap = GenerateExpression(stmt->exp,F_REG,GetNaturalSize(stmt->exp));
//        if( ap->preg != 0 )
//                GenerateDiadic(op_mov,0,makereg(1),ap);
//		ReleaseTempRegister(ap);
        stmt = stmt->s1;
        while( stmt != NULL )
        {
            if( stmt->s2 )          /* default case ? */
            {
				stmt->label = (int64_t *)curlab;
				defcase = stmt;
            }
            else
            {
				bf = (int *)stmt->label;
				for (nn = bf[0]; nn >= 1; nn--) {
                    if (isFISA64) {
                        ap2 = GetTempRegister();
                        GenerateTriadic(op_cmpi,0,ap2,ap,make_immed(bf[nn]));
						GenerateDiadic(op_beq,0,ap2,make_clabel(curlab));
						ReleaseTempRegister(ap2);
                    }
					else if (isTable888) {
						GenerateTriadic(op_cmp,0,makereg(244),makereg(1),make_immed(bf[nn]));
						GenerateDiadic(op_beq,0,makereg(244),make_clabel(curlab));
					}
					else if (isRaptor64) {
						GenerateTriadic(op_beq,0,ap,make_immed(bf[nn]),make_label(curlab));
					}
					else {
						GenerateTriadic(op_cmp,0,makepred(predreg),ap,make_immed(bf[nn]));
						GeneratePredicatedMonadic(predreg,PredOp(op_eq),op_br,0,make_clabel(curlab));
					}
				}
		        //GenerateDiadic(op_dw,0,make_label(curlab), make_direct(stmt->label));
	            stmt->label = (int64_t *)curlab;
            }
            if( stmt->s1 != NULL && stmt->next != NULL )
                curlab = nextlabel++;
            stmt = stmt->next;
        }
        if( defcase == NULL )
            GenerateMonadic(isThor ? op_br : op_bra,0,make_clabel(breaklab));
        else
			GenerateMonadic(isThor ? op_br : op_bra,0,make_clabel((int64_t)defcase->label));
    ReleaseTempRegister(ap);
}
Beispiel #15
0
// Generate a function body.
//
void GenerateFunction(SYM *sym, Statement *stmt)
{
	char buf[20];
	char *bl;
	int cnt, nn;
	AMODE *ap;
	ENODE *ep;
	SYM *sp;

	throwlab = retlab = contlab = breaklab = -1;
	lastsph = 0;
	memset(semaphores,0,sizeof(semaphores));
	throwlab = nextlabel++;
	while( lc_auto & 7 )	/* round frame size to word */
		++lc_auto;
	if (sym->IsInterrupt) {
		//GenerateTriadic(op_subui,0,makereg(30),makereg(30),make_immed(30*8));
		//GenerateDiadic(op_sm,0,make_indirect(30), make_mask(0x9FFFFFFE));
	}
	if (!sym->IsNocall) {
		GenerateTriadic(op_subui,0,makereg(SP),makereg(SP),make_immed(32));
		if (lc_auto || sym->NumParms > 0) {
			GenerateDiadic(op_ss|op_sw,0,makereg(regBP),make_indirect(SP));
		}
//		if (sym->UsesPredicate)
			GenerateDiadic(op_ss|op_sws, 0, make_string("pregs"), make_indexed(24,SP));
		// For a leaf routine don't bother to store the link register or exception link register.
		if (!sym->IsLeaf) {
			if (exceptions) {
				GenerateDiadic(op_ss|op_sws, 0, makebreg(CLR), make_indexed(8,SP));
			}
			GenerateDiadic(op_ss|op_sws, 0, makebreg(LR), make_indexed(16,SP));
			if (exceptions) {
				ep = allocEnode();
				ep->nodetype = en_clabcon;
				ep->i = throwlab;
				ap = allocAmode();
				ap->mode = am_immed;
				ap->offset = ep;
				GenerateDiadic(op_ldis,0, makebreg(CLR), ap);
			}
		}
		if (lc_auto || sym->NumParms > 0) {
			GenerateDiadic(op_mov,0,makereg(regBP),makereg(regSP));
			if (lc_auto)
				GenerateTriadic(op_subui,0,makereg(regSP),makereg(regSP),make_immed(lc_auto));
		}

		// Save registers used as register variables.
		// **** Done in Analyze.c ****
		//if( save_mask != 0 ) {
		//	GenerateTriadic(op_subui,0,makereg(SP),makereg(SP),make_immed(popcnt(save_mask)*8));
		//	cnt = (bitsset(save_mask)-1)*8;
		//	for (nn = 31; nn >=1 ; nn--) {
		//		if (save_mask & (1 << nn)) {
		//			GenerateTriadic(op_sw,0,makereg(nn),make_indexed(cnt,SP),NULL);
		//			cnt -= 8;
		//		}
		//	}
		//}
	}
	if (optimize)
		sym->NumRegisterVars = opt1(stmt);
    GenerateStatement(stmt);
    GenerateReturn(sym,0);
	// Generate code for the hidden default catch
	if (exceptions) {
		if (sym->IsLeaf){
			if (sym->DoesThrow) {
				GenerateLabel(throwlab);
				ap = GetTempRegister();
				GenerateDiadic(op_mfspr,0,ap,makebreg(CLR));
				GenerateDiadic(op_mtspr,0,makebreg(LR),ap);
				ReleaseTempRegister(ap);
				GenerateMonadic(op_bra,0,make_clabel(retlab));				// goto regular return cleanup code
			}
		}
		else {
			GenerateLabel(throwlab);
			GenerateDiadic(op_lws,0,makebreg(regLR),make_indexed(8,regBP));		// load throw return address from stack into LR
			GenerateDiadic(op_sws,0,makebreg(regLR),make_indexed(16,regBP));		// and store it back (so it can be loaded with the lm)
			GenerateMonadic(op_bra,0,make_clabel(retlab));				// goto regular return cleanup code
		}
	}
}
Beispiel #16
0
void GenerateTry(Statement *stmt)
{
    int lab1,curlab;
	int oldthrow;
	char buf[20];
	AMODE *ap, *a, *ap2;
	ENODE *node;
	SYM *sym;

    lab1 = nextlabel++;
	oldthrow = throwlab;
	throwlab = nextlabel++;

	if (isTable888|isRaptor64)
		GenerateDiadic(op_lea,0,makereg(regXLR),make_clabel(throwlab));
	else if (isFISA64) {
        a = make_clabel(throwlab);
        a->mode = am_immed;
        FISA64_GenLdi(makereg(regXLR),a,8);
    }
    else
		GenerateDiadic(op_ldi,0,makebreg(CLR),make_clabel(throwlab));
	GenerateStatement(stmt->s1);
    GenerateMonadic(isThor?op_br:op_bra,0,make_clabel(lab1));
	GenerateLabel(throwlab);
	stmt = stmt->s2;
	// Generate catch statements
	// r1 holds the value to be assigned to the catch variable
	// r2 holds the type number
	while (stmt) {
        GenMixedSource(stmt);
		throwlab = oldthrow;
		curlab = nextlabel++;
		GenerateLabel(curlab);
		if (stmt->s2==(Statement *)99999)
			;
		else {
			if (isRaptor64)
				GenerateTriadic(op_bnei,0,makereg(2),make_immed((int64_t)stmt->s2),make_clabel(nextlabel));
			else if (isFISA64) {
                ap = GetTempRegister();
				GenerateTriadic(op_cmp, 0, ap, makereg(2), make_immed((int64_t)stmt->s2));
				GenerateDiadic(op_bne, 0, ap, make_clabel(nextlabel));
				ReleaseTempRegister(ap);
            }
			else if (isTable888) {
				GenerateTriadic(op_cmp, 0, makereg(244), makereg(2), make_immed((int64_t)stmt->s2));
				GenerateDiadic(op_bne, 0, makereg(244), make_clabel(nextlabel));
			}
			else {
				// ToDo: fix Thor
				GenerateTriadic(op_cmpi, 0, make_string("p0"), makereg(2), make_immed((int64_t)stmt->s2));
            	GeneratePredicatedMonadic(0,PredOp(op_ne),op_br,0,make_clabel(nextlabel));
			}
		}
		// move the throw expression result in 'r1' into the catch variable.
		node = (ENODE *)stmt->label;
        {
            ap2 = GenerateExpression(node,F_REG|F_MEM,GetNaturalSize(node));
            if (ap2->mode==am_reg)
               GenerateDiadic(op_mov,0,ap2,makereg(1));
            else
               GenStore(makereg(1),ap2,GetNaturalSize(node));
            ReleaseTempRegister(ap2);
        }
//            GenStore(makereg(1),make_indexed(sym->value.i,regBP),sym->tp->size);
		GenerateStatement(stmt->s1);
		stmt=stmt->next;
	}
    GenerateLabel(lab1);
	if (isTable888|isRaptor64)
		GenerateDiadic(op_lea,0,makereg(regXLR),make_clabel(oldthrow));
	else if (isFISA64) {
        a = make_clabel(oldthrow);
        a->mode = am_immed;
        FISA64_GenLdi(makereg(regXLR),a,8);
    }
	else
		GenerateDiadic(op_ldi,0,makebreg(CLR),make_clabel(oldthrow));
}
Beispiel #17
0
// Generate a return statement.
//
void GenerateReturn(SYM *sym, Statement *stmt)
{
	AMODE *ap;
	int nn;
	int lab1;
	int cnt;

	// Generate code to evaluate the return expression.
    if( stmt != NULL && stmt->exp != NULL )
	{
		initstack();
		ap = GenerateExpression(stmt->exp,F_ALL & ~F_BREG,8);
		// Force return value into register 1
		if( ap->preg != 1 ) {
			if (ap->mode == am_immed)
				GenerateDiadic(op_ldi, 0, makereg(1),ap);
			else if (ap->mode == am_reg)
				GenerateDiadic(op_mov, 0, makereg(1),ap);
			else
				GenerateDiadic(op_lw,0,makereg(1),ap);
		}
	}

	// Generate the return code only once. Branch to the return code for all returns.
	if( retlab == -1 )
    {
		retlab = nextlabel++;
		GenerateLabel(retlab);
		// Unlock any semaphores that may have been set
		for (nn = lastsph - 1; nn >= 0; nn--)
			GenerateDiadic(op_sb,0,makereg(0),make_string(semaphores[nn]));
		if (sym->IsNocall)	// nothing to do for nocall convention
			return;
		// Restore registers used as register variables.
		if( bsave_mask != 0 ) {
			cnt = (bitsset(bsave_mask)-1)*8;
			for (nn = 15; nn >=1 ; nn--) {
				if (bsave_mask & (1 << nn)) {
					GenerateDiadic(op_ss|op_lws,0,makebreg(nn),make_indexed(cnt,SP));
					cnt -= 8;
				}
			}
			GenerateTriadic(op_addui,0,makereg(SP),makereg(SP),make_immed(popcnt(bsave_mask)*8));
		}
		if( save_mask != 0 ) {
			cnt = (bitsset(save_mask)-1)*8;
			for (nn = 31; nn >=1 ; nn--) {
				if (save_mask & (1 << nn)) {
					GenerateDiadic(op_ss|op_lw,0,makereg(nn),make_indexed(cnt,SP));
					cnt -= 8;
				}
			}
			GenerateTriadic(op_addui,0,makereg(SP),makereg(SP),make_immed(popcnt(save_mask)*8));
		}
		// Unlink the stack
		// For a leaf routine the link register and exception link register doesn't need to be saved/restored.
		if (lc_auto || sym->NumParms > 0) {
			GenerateDiadic(op_mov,0,makereg(SP),makereg(regBP));
			GenerateDiadic(op_ss|op_lw,0,makereg(regBP),make_indirect(regSP));
		}
		if (!sym->IsLeaf) {
			if (exceptions)
				GenerateDiadic(op_ss|op_lws,0,makebreg(CLR),make_indexed(8,regSP));
			GenerateDiadic(op_ss|op_lws,0,makebreg(LR),make_indexed(16,regSP));
//			if (sym->UsesPredicate)
		}
		GenerateDiadic(op_ss|op_lws,0,make_string("pregs"),make_indexed(24,regSP));
		//if (isOscall) {
		//	GenerateDiadic(op_move,0,makereg(0),make_string("_TCBregsave"));
		//	gen_regrestore();
		//}
		// Generate the return instruction. For the Pascal calling convention pop the parameters
		// from the stack.
		if (sym->IsInterrupt) {
			//GenerateTriadic(op_addui,0,makereg(30),makereg(30),make_immed(24));
			//GenerateDiadic(op_lm,0,make_indirect(30),make_mask(0x9FFFFFFE));
			//GenerateTriadic(op_addui,0,makereg(30),makereg(30),make_immed(popcnt(0x9FFFFFFE)*8));
			GenerateMonadic(op_rti,0,(AMODE *)NULL);
			return;
		}
		if (sym->IsPascal) {
			GenerateTriadic(op_addui,0,makereg(regSP),makereg(regSP),make_immed(32+sym->NumParms * 8));
			GenerateMonadic(op_rts,0,(AMODE *)NULL);
		}
		else {
			GenerateTriadic(op_addui,0,makereg(regSP),makereg(regSP),make_immed(32));
			GenerateMonadic(op_rts,0,(AMODE*)NULL);
		}
    }
	// Just branch to the already generated stack cleanup code.
	else {
		GenerateMonadic(op_bra,0,make_clabel(retlab));
	}
}
Beispiel #18
0
// Generate a function body.
//
void GenerateFunction(SYM *sym, Statement *stmt)
{
	char buf[20];
	char *bl;
	int cnt, nn;
	AMODE *ap;
	ENODE *ep;
	SYM *sp;
  std::string vep;

	throwlab = retlab = contlab = breaklab = -1;
	lastsph = 0;
	memset(semaphores,0,sizeof(semaphores));
	throwlab = nextlabel++;
	retlab = nextlabel++;
	while( lc_auto & 7 )	/* round frame size to word */
		++lc_auto;
	if (sym->IsInterrupt) {
		//GenerateTriadic(op_subui,0,makereg(30),makereg(30),make_immed(30*8));
		//GenerateDiadic(op_sm,0,make_indirect(30), make_mask(0x9FFFFFFE));
	}
	if (sym->prolog) {
       if (optimize)
           opt1(sym->prolog);
	   GenerateStatement(sym->prolog);
  }
	if (!sym->IsNocall) {
		GenerateTriadic(op_addui,0,makereg(regSP),makereg(regSP),make_immed(-GetReturnBlockSize()));
		if (lc_auto || sym->NumParms > 0) {
			GenerateDiadic(op_sw,0,makereg(regBP),make_indirect(regSP));
		}
//		if (sym->UsesPredicate)
			GenerateDiadic(op_sws, 0, make_string("pregs"), make_indexed(24,regSP));
			GenerateDiadic(op_sw, 0, makereg(regCLP),make_indexed(32,regSP));
		// For a leaf routine don't bother to store the link register or exception link register.
		// Since virtual functions call other functions, they can't be leaf
    // routines.
		if (!sym->IsLeaf || sym->IsVirtual) {
			if (exceptions) {
				GenerateDiadic(op_sws, 0, makebreg(regXLR), make_indexed(8,regSP));
			}
			GenerateDiadic(op_sws, 0, makebreg(regLR), make_indexed(16,regSP));
			if (exceptions) {
				ep = allocEnode();
				ep->nodetype = en_clabcon;
				ep->i = throwlab;
				ap = allocAmode();
				ap->mode = am_immed;
				ap->offset = ep;
				GenerateDiadic(op_ldis,0, makebreg(regXLR), ap);
			}
		}

		GenerateDiadic(op_lw,0,makereg(regCLP),make_indexed(GetReturnBlockSize(),regSP));

    vep = *sym->mangledName;
    vep += "_VEP";
	  GenerateMonadic(op_fnname,0,make_string((char *)vep.c_str()));
	
  	// Generate switch to call derived methods
  	if (sym->IsVirtual || sym->derivitives) {
  	  char buf[20];
  	  char *buf2;
  	  DerivedMethod *mthd;
  	  
  	  dfs.printf("VirtualFunction Switch");
  	  GenerateDiadic(op_lcu,0,makereg(24),make_indirect(regCLP));
  	  mthd = sym->derivitives;
  	  while (mthd) {
     	  sprintf(buf, "p%d", 7);
  	    buf2 = my_strdup(buf);
        GenerateTriadic(op_cmpi,0,make_string(buf2),makereg(24),make_immed(mthd->typeno));
        vep = *(mthd->name);
        vep += "_VEP";      // Virtual Entry Point
     	  GeneratePredicatedMonadic(7,PredOp(op_eq),op_jmp,0,
          make_string((char *)vep.c_str()));   // jump to the method
     	  mthd = mthd->next;
  	  }
    }
		if (lc_auto || sym->NumParms > 0) {
			GenerateDiadic(op_mov,0,makereg(regBP),makereg(regSP));
			if (lc_auto)
				GenerateTriadic(op_addui,0,makereg(regSP),makereg(regSP),make_immed(-lc_auto));
		}

		// Save registers used as register variables.
		// **** Done in Analyze.c ****
		//if( save_mask != 0 ) {
		//	GenerateTriadic(op_subui,0,makereg(SP),makereg(SP),make_immed(popcnt(save_mask)*8));
		//	cnt = (bitsset(save_mask)-1)*8;
		//	for (nn = 31; nn >=1 ; nn--) {
		//		if (save_mask & (1 << nn)) {
		//			GenerateTriadic(op_sw,0,makereg(nn),make_indexed(cnt,SP),NULL);
		//			cnt -= 8;
		//		}
		//	}
		//}
	}
	if (optimize)
		sym->NumRegisterVars = opt1(stmt);
  GenerateStatement(stmt);
  GenerateEpilog(sym);
	// Generate code for the hidden default catch
	if (exceptions) {
		if (sym->IsLeaf){
			if (sym->DoesThrow) {
				GenerateLabel(throwlab);
				ap = GetTempRegister();
				GenerateDiadic(op_mfspr,0,ap,makebreg(regXLR));
				GenerateDiadic(op_mtspr,0,makebreg(regLR),ap);
				ReleaseTempRegister(ap);
				GenerateMonadic(op_br,0,make_clabel(retlab));				// goto regular return cleanup code
			}
		}
		else {
			GenerateLabel(throwlab);
			GenerateDiadic(op_lws,0,makebreg(regLR),make_indexed(8,regBP));		// load throw return address from stack into LR
			GenerateDiadic(op_sws,0,makebreg(regLR),make_indexed(16,regBP));		// and store it back (so it can be loaded with the lm)
			GenerateMonadic(op_br,0,make_clabel(retlab));				// goto regular return cleanup code
		}
	}
}
Beispiel #19
0
AMODE *GenerateFunctionCall(ENODE *node, int flags)
{ 
	AMODE *ap, *result;
	SYM *sym;
  int             i;
	int msk;
	int sp;
	int isPascal = FALSE;
 
  dfs.puts("<GenerateFunctionCall>");
 	//msk = SaveTempRegs();
 	if (node->p[0] < (ENODE *)0x0FLL) {
 	  error(ERR_NULLPOINTER);
 	  goto xit1;
 	}
	sp = TempInvalidate();
	sym = (SYM*)NULL;
  i = GeneratePushParameterList(node->p[1]);
	// Call the function
	if( node->p[0]->nodetype == en_cnacon ) {
	  dfs.printf("cnacon node:%s|\n",(char *)node->p[0]->sp->c_str());
//		if (node->p[0]->i==25)
//			GenerateDiadic(op_sw,0,makereg(regCLP),make_indexed(0,regSP));
    if (node->p[0]->sp < (std::string *)0x0FLL)
      node->p[0]->sp = new std::string("<null>");
    GenerateMonadic(op_jsr,0,make_offset(node->p[0]));
    sym = gsearch(*node->p[0]->sp);
    dfs.puts((char*)(node->p[0]->sp->c_str()));
    if (sym) {
       dfs.puts("<found></found>");
       }
    else {
       dfs.printf("<notfound>%s</notfound>",(char*)(node->p[0]->sp->c_str()));
    }
	}
  else
  {

		ap = GenerateExpression(node->p[0],F_BREG,8);
		ap->mode = am_brind;
		isPascal = node->p[0]->isPascal;
		GenerateDiadic(op_jsr,0,makebreg(1),ap);
		ReleaseTempRegister(ap);

    }
	// Pop parameters off the stack
	if (i!=0) {
		if (sym) {
			if (!sym->IsPascal)
				GenerateTriadic(op_addui,0,makereg(regSP),makereg(regSP),make_immed(i * 8));
		}
		else if (!isPascal)
			GenerateTriadic(op_addui,0,makereg(regSP),makereg(regSP),make_immed(i * 8));
	}
	//RestoreTempRegs(msk);
	TempRevalidate(sp);
xit1:
	ap = GetTempRegister();
	if (flags & F_NOVALUE)
		;
	else
		GenerateDiadic(op_mov,0,ap,makereg(1));
  dfs.puts("</GenerateFunctionCall>");
    return ap;
}
Beispiel #20
0
// Generate function epilog code.
//
void GenerateEpilog(SYM *sym)
{
	AMODE *ap;
	int nn;
	int lab1;
	int cnt;

	// Generate the return code only once. Branch to the return code for all returns.
	GenerateLabel(retlab);
	// Unlock any semaphores that may have been set
	for (nn = lastsph - 1; nn >= 0; nn--)
		GenerateDiadic(op_sb,0,makereg(0),make_string(semaphores[nn]));
	if (sym->IsNocall)	// nothing to do for nocall convention
		return;
	// Restore registers used as register variables.
	if( bsave_mask != 0 ) {
		cnt = (bitsset(bsave_mask)-1)*8;
		for (nn = 15; nn >=1 ; nn--) {
			if (bsave_mask & (1 << nn)) {
				GenerateDiadic(op_lws,0,makebreg(nn),make_indexed(cnt,regSP));
				cnt -= 8;
			}
		}
		GenerateTriadic(op_addui,0,makereg(SP),makereg(regSP),make_immed(popcnt(bsave_mask)*8));
	}
	if( save_mask != 0 ) {
		cnt = (bitsset(save_mask)-1)*8;
		for (nn = 31; nn >=1 ; nn--) {
			if (save_mask & (1 << nn)) {
				GenerateDiadic(op_lw,0,makereg(nn),make_indexed(cnt,regSP));
				cnt -= 8;
			}
		}
		GenerateTriadic(op_addui,0,makereg(regSP),makereg(regSP),make_immed(popcnt(save_mask)*8));
	}
	// Unlink the stack
	// For a leaf routine the link register and exception link register doesn't need to be saved/restored.
	if (lc_auto || sym->NumParms > 0) {
		GenerateDiadic(op_mov,0,makereg(regSP),makereg(regBP));
		GenerateDiadic(op_lw,0,makereg(regBP),make_indirect(regSP));
	}
	if (!sym->IsLeaf) {
		if (exceptions)
			GenerateDiadic(op_lws,0,makebreg(regXLR),make_indexed(8,regSP));        // 11=CLR
		GenerateDiadic(op_lws,0,makebreg(regLR),make_indexed(16,regSP));            // 1 = LR
//			if (sym->UsesPredicate)
	}
	GenerateDiadic(op_lws,0,make_string("pregs"),make_indexed(24,regSP));
	GenerateDiadic(op_lw,0,makereg(regCLP),make_indexed(32,regSP));
	    if (sym->epilog) {
           if (optimize)
              opt1(sym->epilog);
	       GenerateStatement(sym->epilog);
	       return;
       }
	//if (isOscall) {
	//	GenerateDiadic(op_move,0,makereg(0),make_string("_TCBregsave"));
	//	gen_regrestore();
	//}
	// Generate the return instruction. For the Pascal calling convention pop the parameters
	// from the stack.
	if (sym->IsInterrupt) {
		//GenerateTriadic(op_addui,0,makereg(30),makereg(30),make_immed(24));
		//GenerateDiadic(op_lm,0,make_indirect(30),make_mask(0x9FFFFFFE));
		//GenerateTriadic(op_addui,0,makereg(30),makereg(30),make_immed(popcnt(0x9FFFFFFE)*8));
		GenerateMonadic(op_rti,0,(AMODE *)NULL);
		return;
	}
	if (sym->IsPascal) {
		GenerateTriadic(op_addui,0,makereg(regSP),makereg(regSP),make_immed(GetReturnBlockSize()+sym->NumParms * 8));
		GenerateMonadic(op_rts,0,(AMODE *)NULL);
	}
	else {
		GenerateTriadic(op_addui,0,makereg(regSP),makereg(regSP),make_immed(GetReturnBlockSize()));
		GenerateMonadic(op_rts,0,(AMODE*)NULL);
	}
}
Beispiel #21
0
// Generate a function body.
//
void GenerateFunction(SYM *sym, Statement *stmt)
{
	char buf[20];
	char *bl;

	throwlab = retlab = contlab = breaklab = -1;
	lastsph = 0;
	memset(semaphores,0,sizeof(semaphores));
	throwlab = nextlabel++;
	while( lc_auto & 7 )	/* round frame size to word */
		++lc_auto;
	if (sym->IsInterrupt) {
		//GenerateTriadic(op_subui,0,makereg(30),makereg(30),make_immed(30*8));
		//GenerateDiadic(op_sm,0,make_indirect(30), make_mask(0x9FFFFFFE));
	}
	if (!sym->IsNocall) {
		GenerateTriadic(op_subui,0,makereg(30),makereg(30),make_immed(24));
		// For a leaf routine don't bother to store the link register or exception link register.
		if (sym->IsLeaf)
			GenerateDiadic(op_sw,0,makereg(27),make_indirect(30));
		else {
			GenerateDiadic(op_sw, 0, makereg(27), make_indexed(0,30));
			GenerateDiadic(op_sw, 0, makereg(28), make_indexed(8,30));
			GenerateDiadic(op_sw, 0, makereg(31), make_indexed(16,30));
			GenerateDiadic(op_lea,0,makereg(28),make_label(throwlab));
		}
		GenerateDiadic(op_mov,0,makereg(27),makereg(30));
		if (lc_auto)
			GenerateTriadic(op_subui,0,makereg(30),makereg(30),make_immed(lc_auto));
	}
	if (optimize)
		opt1(stmt);
    GenerateStatement(stmt);
    GenerateReturn(sym,0);
	// Generate code for the hidden default catch
	GenerateLabel(throwlab);
	if (sym->IsLeaf){
		if (sym->DoesThrow) {
			GenerateDiadic(op_mov,0,makereg(31),makereg(28));
			GenerateDiadic(op_bra,0,make_label(retlab),NULL);				// goto regular return cleanup code
		}
	}
	else {
		GenerateDiadic(op_lw,0,makereg(31),make_indexed(8,27));		// load throw return address from stack into LR
		GenerateDiadic(op_sw,0,makereg(31),make_indexed(16,27));		// and store it back (so it can be loaded with the lm)
		GenerateDiadic(op_bra,0,make_label(retlab),NULL);				// goto regular return cleanup code
	}
}
Beispiel #22
0
void GenerateSpinlock(Statement *stmt)
{
	int lab1, lab2, lab3, lab4;
	AMODE *ap1, *ap2;
	AMODE *ap;
	int sp = 0;

	lab1 = nextlabel++;
	lab2 = nextlabel++;
	lab3 = nextlabel++;

    if( stmt != (Statement *)NULL && stmt->exp != (ENODE *)NULL )
	{
		initstack();
		ap1 = GetTempRegister();
		ap2 = GetTempRegister();
		ap = GenerateExpression(stmt->exp,F_REG,8);
		GenerateDiadic(op_mov,0,makereg(1),ap);
		if (stmt->initExpr) {
            if (isFISA64)
                FISA64_GenLdi(makereg(2),make_immed((int64_t)stmt->initExpr));
            else
			    GenerateTriadic(op_ori, 0, makereg(2),makereg(0),make_immed((int64_t)stmt->initExpr));
        }
        else {
            GenerateDiadic(op_ldi,0,makereg(2),make_immed(-1));
        }
        GenerateMonadic(op_bsr,0,make_string("_LockSema"));
        if (stmt->initExpr)
            GenerateDiadic(op_beq,0,makereg(1),make_clabel(lab2));
		ReleaseTempRegister(ap);
		ReleaseTempRegister(ap2);
		ReleaseTempRegister(ap1);
        // We treat this statement generation like a function call and save
        // the used temporary beforehand.  The statement might reinitialize
        // the expression vars. There aren't any other cases where temporaries
        // are needed after statements are generated.
       	GenerateMonadic(op_push,0,ap);
		GenerateStatement(stmt->s1);
    	GenerateMonadic(op_pop,0,ap);
		// unlock
		if (isRaptor64)
			GenerateDiadic(op_outb, 0, makereg(0), make_indexed((int64_t)stmt->incrExpr,ap->preg));
		else if (isFISA64) {
            GenerateDiadic(op_mov, 0, makereg(1), makereg(ap->preg));
            GenerateMonadic(op_bsr, 0, make_string("_UnlockSema"));
        }
		else
			GenerateDiadic(op_sw, 0, makereg(0), make_indexed((int64_t)stmt->incrExpr,ap->preg));
		if (stmt->initExpr) {
			GenerateMonadic(isThor?op_br:op_bra,0,make_clabel(lab3));
			GenerateLabel(lab2);
			GenerateStatement(stmt->s2);
			GenerateLabel(lab3);
		}
		else {
			printf("Warning: The lockfail code is unreachable because spinlock tries are infinite.\r\n");
		}
	}

	//ap1 = GetTempRegister();
	//ap2 = GetTempRegister();
	//if (stmt->exp) {
	//	lab2 = nextlabel++;
	//	GenerateTriadic(op_ori,0,ap2,makereg(0),make_immed(stmt->exp));
	//    GenerateLabel(lab1);
	//	GenerateTriadic(op_beq,0,ap2,makereg(0),make_label(lab2));
	//	GenerateTriadic(op_subui,0,ap2,ap2,make_immed(1));
	//	GenerateTriadic(op_lwr,0,ap1,make_string(stmt->label),NULL);
	//	GenerateTriadic(op_bne,0,ap1,makereg(0),make_label(lab1),NULL);
	//	GenerateTriadic(op_not,0,ap1,ap1,NULL);
	//	GenerateTriadic(op_swc,0,ap1,make_string(stmt->label),NULL);
	//	GenerateTriadic(op_bnr,0,make_label(lab1),NULL,NULL);
	//}
	//else {
	//	GenerateLabel(lab1);
	//	GenerateTriadic(op_lwr,0,ap1,make_string(stmt->label),NULL);
	//	GenerateTriadic(op_bne,0,ap1,makereg(0),make_label(lab1),NULL);
	//	GenerateTriadic(op_not,0,ap1,ap1,NULL);
	//	GenerateTriadic(op_swc,0,ap1,make_string(stmt->label),NULL);
	//	GenerateTriadic(op_bnr,0,make_label(lab1),NULL,NULL);
	//}
	//ReleaseTempRegister(ap1);
	//ReleaseTempRegister(ap2);
	//GenerateStatement(stmt->s1);
	//GenerateDiadic(op_sb,0,makereg(0),make_string(stmt->label));
	//if (stmt->exp) {
	//	lab3 = nextlabel++;
	//	GenerateTriadic(op_bra,0,make_label(lab3),NULL,NULL);
	//	GenerateLabel(lab2);
	//	GenerateStatement(stmt->s2);
	//	GenerateLabel(lab3);
	//}
	//else {
	//	printf("Warning: The lockfail code is unreachable because spinlock tries are infinite.\r\n");
	//}
}
Beispiel #23
0
/*
 *      genstmt will generate a statement and follow the next pointer
 *      until the block is generated.
 */
void GenerateStatement(Statement *stmt)
{
	AMODE *ap;
 
	while( stmt != NULL )
    {
        GenMixedSource(stmt);
        switch( stmt->stype )
                {
				//case st_vortex:
				//		gen_vortex(stmt);
				//		break;
	            case st_funcbody:
                        GenerateFuncbody(stmt);
                        break;
				case st_compound:
						GenerateCompound(stmt);
						break;
				case st_try:
						GenerateTry(stmt);
						break;
				case st_throw:
						GenerateThrow(stmt);
						break;
				case st_intoff:
						GenerateIntoff(stmt);
						break;
				case st_stop:
						GenerateStop(stmt);
						break;
				case st_inton:
						GenerateInton(stmt);
						break;
				case st_asm:
						GenerateAsm(stmt);
						break;
                case st_label:
                        GenerateLabel((int64_t)stmt->label);
                        break;
                case st_goto:
                        GenerateMonadic(isThor?op_br:op_bra,0,make_clabel((int64_t)stmt->label));
                        break;
				//case st_critical:
    //                    GenerateCritical(stmt);
    //                    break;
				case st_spinlock:
						GenerateSpinlock(stmt);
						break;
				case st_spinunlock:
						GenerateSpinUnlock(stmt);
						break;
				case st_check:
                        GenerateCheck(stmt);
                        break;
                case st_expr:
                        initstack();
                        ap = GenerateExpression(stmt->exp,F_ALL | F_NOVALUE,
                                GetNaturalSize(stmt->exp));
						ReleaseTempRegister(ap);
						tmpFreeAll();
                        break;
                case st_return:
                        if (isFISA64)
							GenerateFISA64Return(currentFn,stmt);
                        else if (is816)
							Generate816Return(currentFn,stmt);
						else if (isTable888)
							GenerateTable888Return(currentFn,stmt);
						else if (isRaptor64)
							GenerateRaptor64Return(currentFn,stmt);
						else
							GenerateReturn(currentFn,stmt);
                        break;
                case st_if:
                        GenerateIf(stmt);
                        break;
                case st_do:
                        GenerateDo(stmt);
                        break;
                case st_dountil:
                        GenerateDoUntil(stmt);
                        break;
                case st_doloop:
                        GenerateForever(stmt);
                        break;
                case st_while:
                        GenerateWhile(stmt);
                        break;
                case st_until:
                        GenerateUntil(stmt);
                        break;
                case st_for:
                        GenerateFor(stmt);
                        break;
                case st_forever:
                        GenerateForever(stmt);
                        break;
                case st_firstcall:
                        GenerateFirstcall(stmt);
                        break;
                case st_continue:
						if (contlab==-1)
							error(ERR_NOT_IN_LOOP);
                        GenerateDiadic(isThor?op_br:op_bra,0,make_clabel(contlab),0);
                        break;
                case st_break:
						if (breaklab==-1)
							error(ERR_NOT_IN_LOOP);
                        GenerateDiadic(isThor?op_br:op_bra,0,make_clabel(breaklab),0);
                        break;
                case st_switch:
                        genxswitch(stmt);
                        break;
				case st_empty:
						break;
                default:
                        printf("DIAG - unknown statement.\n");
                        break;
                }
        stmt = stmt->next;
    }
}