OpenCores
URL https://opencores.org/ocsvn/raptor64/raptor64/trunk

Subversion Repositories raptor64

[/] [raptor64/] [trunk/] [software/] [c64/] [source/] [GenerateStatement.c] - Rev 51

Compare with Previous | Blame | View Log

#include <stdio.h>
#include "c.h"
#include "expr.h"
#include "Statement.h"
#include "gen.h"
#include "cglbdec.h"
 
/*
 *	68000 C compiler
 *
 *	Copyright 1984, 1985, 1986 Matthew Brandt.
 *  all commercial rights reserved.
 *
 *	This compiler is intended as an instructive tool for personal use. Any
 *	use for profit without the written consent of the author is prohibited.
 *
 *	This compiler may be distributed freely for non-commercial use as long
 *	as this notice stays intact. Please forward any enhancements or questions
 *	to:
 *
 *		Matthew Brandt
 *		Box 920337
 *		Norcross, Ga 30092
 */
/*******************************************************
	Modified to support Raptor64 'C64' language
	by Robert Finch
	robfinch@opencores.org
*******************************************************/
 
int     breaklab;
int     contlab;
int     retlab;
int		throwlab;
 
int lastsph;
char *semaphores[20];
 
extern TYP              stdfunc;
 
 
int bitsset(int mask)
{
	int nn,bs=0;
	for (nn =0; nn < 32; nn++)
		if (mask & (1 << nn)) bs++;
	return bs;
}
 
AMODE *makereg(int r)
{
	AMODE *ap;
    ap = allocAmode();
    ap->mode = am_reg;
    ap->preg = r;
    return ap;
}
 
/*
 *      generate the mask address structure.
 */
AMODE *make_mask(int mask)
{
	AMODE *ap;
    ap = allocAmode();
    ap->mode = am_mask;
    ap->offset = mask;
    return ap;
}
 
/*
 *      make a direct reference to an immediate value.
 */
AMODE *make_direct(__int64 i)
{
	return make_offset(makeinode(en_icon,i,0));
}
 
/*
 *      generate a direct reference to a string label.
 */
AMODE *make_strlab(char *s)
{
	AMODE *ap;
    ap = allocAmode();
    ap->mode = am_direct;
    ap->offset = makesnode(en_nacon,s);
    return ap;
}
 
/*
 *      generate code to evaluate a while statement.
 */
void GenerateWhile(struct snode *stmt)
{
	int lab1, lab2;
 
    initstack();            /* initialize temp registers */
    lab1 = contlab;         /* save old continue label */
    lab2 = breaklab;        /* save old break label */
    contlab = nextlabel++;  /* new continue label */
    GenerateLabel(contlab);
    if( stmt->s1 != NULL )      /* has block */
    {
		breaklab = nextlabel++;
		initstack();
		GenerateFalseJump(stmt->exp,breaklab);
		GenerateStatement(stmt->s1);
		GenerateDiadic(op_bra,0,make_label(contlab),NULL);
		GenerateLabel(breaklab);
		breaklab = lab2;        /* restore old break label */
    }
    else					        /* no loop code */
    {
		initstack();
		GenerateTrueJump(stmt->exp,contlab);
    }
    contlab = lab1;         /* restore old continue label */
}
 
/*
 *      generate code to evaluate an until statement.
 */
void GenerateUntil(Statement *stmt)
{
	int lab1, lab2;
 
        initstack();            /* initialize temp registers */
        lab1 = contlab;         /* save old continue label */
        lab2 = breaklab;        /* save old break label */
        contlab = nextlabel++;  /* new continue label */
        GenerateLabel(contlab);
        if( stmt->s1 != NULL )      /* has block */
                {
                breaklab = nextlabel++;
                initstack();
                GenerateTrueJump(stmt->exp,breaklab);
                GenerateStatement(stmt->s1);
                GenerateDiadic(op_bra,0,make_label(contlab),NULL);
                GenerateLabel(breaklab);
                breaklab = lab2;        /* restore old break label */
                }
        else					        /* no loop code */
                {
                initstack();
                GenerateFalseJump(stmt->exp,contlab);
                }
        contlab = lab1;         /* restore old continue label */
}
 
 
//      generate code to evaluate a for loop
//
void GenerateFor(struct snode *stmt)
{
	int     old_break, old_cont, exit_label, loop_label;
    old_break = breaklab;
    old_cont = contlab;
    loop_label = nextlabel++;
    exit_label = nextlabel++;
    contlab = loop_label;
    initstack();
    if( stmt->initExpr != NULL )
            GenerateExpression(stmt->initExpr,F_ALL | F_NOVALUE
                    ,GetNaturalSize(stmt->initExpr));
    GenerateLabel(loop_label);
    initstack();
    if( stmt->exp != NULL )
            GenerateFalseJump(stmt->exp,exit_label);
    if( stmt->s1 != NULL )
	{
            breaklab = exit_label;
            GenerateStatement(stmt->s1);
	}
    initstack();
    if( stmt->incrExpr != NULL )
            GenerateExpression(stmt->incrExpr,F_ALL | F_NOVALUE,GetNaturalSize(stmt->incrExpr));
    GenerateTriadic(op_bra,0,make_label(loop_label),NULL,NULL);
    breaklab = old_break;
    contlab = old_cont;
    GenerateLabel(exit_label);
}
 
 
//     generate code to evaluate a forever loop
//
void GenerateForever(Statement *stmt)
{
	int old_break, old_cont, exit_label, loop_label;
    old_break = breaklab;
    old_cont = contlab;
    loop_label = nextlabel++;
    exit_label = nextlabel++;
    contlab = loop_label;
    GenerateLabel(loop_label);
    if( stmt->s1 != NULL )
	{
        breaklab = exit_label;
        GenerateStatement(stmt->s1);
	}
    GenerateDiadic(op_bra,0,make_label(loop_label),NULL);
    breaklab = old_break;
    contlab = old_cont;
    GenerateLabel(exit_label);
}
 
/*
 *      generate code to evaluate an if statement.
 */
void GenerateIf(struct snode *stmt)
{       int     lab1, lab2, oldbreak;
        lab1 = nextlabel++;     /* else label */
        lab2 = nextlabel++;     /* exit label */
        oldbreak = breaklab;    /* save break label */
        initstack();            /* clear temps */
        GenerateFalseJump(stmt->exp,lab1);
        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(op_bra,0,make_label(lab2),0);
                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;
}
 
/*
 *      generate code for a do - while loop.
 */
void GenerateDo(struct snode *stmt)
{
	int     oldcont, oldbreak;
    oldcont = contlab;
    oldbreak = breaklab;
    contlab = nextlabel++;
    GenerateLabel(contlab);
    if( stmt->s1 != 0 && stmt->s1->next != 0 )
            {
            breaklab = nextlabel++;
            GenerateStatement(stmt->s1);      /* generate body */
            initstack();
            GenerateTrueJump(stmt->exp,contlab);
            GenerateLabel(breaklab);
            }
    else
            {
            GenerateStatement(stmt->s1);
            initstack();
            GenerateTrueJump(stmt->exp,contlab);
            }
    breaklab = oldbreak;
    contlab = oldcont;
}
 
/*
 *      generate code for a do - while loop.
 */
void GenerateDoUntil(struct snode *stmt)
{
	int     oldcont, oldbreak;
    oldcont = contlab;
    oldbreak = breaklab;
    contlab = nextlabel++;
    GenerateLabel(contlab);
    if( stmt->s1 != 0 && stmt->s1->next != 0 )
    {
        breaklab = nextlabel++;
        GenerateStatement(stmt->s1);      /* generate body */
        initstack();
        GenerateFalseJump(stmt->exp,contlab);
        GenerateLabel(breaklab);
    }
    else
    {
        GenerateStatement(stmt->s1);
        initstack();
        GenerateFalseJump(stmt->exp,contlab);
    }
    breaklab = oldbreak;
    contlab = oldcont;
}
 
/*
 *      generate a call to a library routine.
 */
void call_library(char *lib_name)
{    
	SYM     *sp;
    sp = gsearch(lib_name);
    if( sp == NULL )
    {
		++global_flag;
		sp = allocSYM();
		sp->tp = &stdfunc;
		sp->name = lib_name;
		sp->storage_class = sc_external;
		insert(sp,&gsyms);
		--global_flag;
    }
    GenerateDiadic(op_call,0,make_strlab(lib_name),NULL);
}
 
/*
 *      generate a linear search switch statement.
 */
void GenerateSwitch(Statement *stmt)
{    
	int             curlab;
	int *bf;
	int nn;
        struct snode    *defcase;
        struct amode    *ap;
        curlab = nextlabel++;
        defcase = 0;
        initstack();
        ap = GenerateExpression(stmt->exp,F_REG,4);
        if( ap->preg != 0 )
                GenerateTriadic(op_or,0,makereg(1),ap,makereg(0));
        stmt = stmt->s1;
        while( stmt != NULL )
        {
            if( stmt->s2 )          /* default case ? */
            {
				stmt->label = curlab;
				defcase = stmt;
            }
            else
            {
				bf = stmt->label;
				for (nn = bf[0]; nn >= 1; nn--)
					GenerateTriadic(op_beq,0,makereg(1),make_immed(bf[nn]),make_label(curlab));
		        //GenerateDiadic(op_dw,0,make_label(curlab), make_direct(stmt->label));
	            stmt->label = curlab;
            }
            if( stmt->s1 != NULL && stmt->next != NULL )
                curlab = nextlabel++;
            stmt = stmt->next;
        }
        if( defcase == NULL )
            GenerateTriadic(op_bra,0,make_label(breaklab),NULL,NULL);
        else
			GenerateTriadic(op_bra,0,make_label(defcase->label),NULL,NULL);
}
 
 
//      generate all cases for a switch statement.
//
void GenerateCase(Statement *stmt)
{
	while( stmt != NULL )
    {
		if( stmt->s1 != NULL )
		{
			GenerateLabel(stmt->label);
			GenerateStatement(stmt->s1);
		}
		else if( stmt->next == NULL )
			GenerateLabel(stmt->label);
		stmt = stmt->next;
    }
}
 
/*
 *      analyze and generate best switch statement.
 */
genxswitch(Statement *stmt)
{ 
	int     oldbreak;
    oldbreak = breaklab;
    breaklab = nextlabel++;
    GenerateSwitch(stmt);
    GenerateCase(stmt->s1);
    GenerateLabel(breaklab);
    breaklab = oldbreak;
}
 
int popcnt(int m)
{
	int n;
	int cnt;
 
	cnt =0;
	for (n = 0; n < 32; n = n + 1)
		if (m & (1 << n)) cnt = cnt + 1;
	return cnt;
}
/*
void gen_regsave()
{
	int lab1;
 
	lab1 = nextlabel++;
	GenerateLabel(lab1);
	GenerateDiadic(op_tas,1,make_strlab("sfRunningTCB"),NULL);
	GenerateDiadic(op_bmi,0,make_label(lab1),NULL);
	GenerateDiadic(op_move,0,makereg(1),make_strlab("a0save"));
	GenerateDiadic(op_move,0,make_strlab("RunningTCB"),makereg(1));
	GenerateDiadic(op_movem,0,make_strlab("d0-d7/a0-a7"),make_strlab("(a0)"));
	GenerateDiadic(op_move,0,make_strlab("a0save"),make_strlab("32(a0)"));
	GenerateDiadic(op_move,0,make_strlab("usp"),makereg(1));
	GenerateDiadic(op_move,0,makereg(1),make_strlab("64(a0)"));
	GenerateDiadic(op_move,0,make_strlab("4(a7)"),make_strlab("68(a0)"));
 
	//GenerateDiadic(op_move,4,make_string("sr"),make_string("_TCBsrsave"));
	//GenerateDiadic(op_movem,4,make_mask(0xFFFF),make_string("_TCBregsave"));
	//GenerateDiadic(op_move,4,make_string("usp"),make_string("a0"));
	//GenerateDiadic(op_move,4,make_string("a0"),make_string("_TCBuspsave"));
}
 
void gen_regrestore()
{
	GenerateDiadic(op_move,0,make_strlab("_TCBuspsave"),make_string("a0"));
	GenerateDiadic(op_move,0,make_string("a0"),make_string("usp"));
	GenerateDiadic(op_movem,0,make_string("_TCBregsave"),make_mask(0xFFFF));
	GenerateDiadic(op_move,0,make_string("_TCBsrsave"),make_string("sr"));
}
*/
/*
void gen_vortex(struct snode *stmt)
{
    int lab1;
 
    lab1 = nextlabel++;
    GenerateDiadic(op_bra,0,make_label(lab1),0);
    //gen_ilabel(stmt->label);
	gen_regsave();
	GenerateStatement(stmt->s1);
	gen_regrestore();
	GenerateDiadic(op_rte,0,0,0);
    GenerateLabel(lab1);
}
*/
 
void GenerateTry(Statement *stmt)
{
    int lab1,curlab;
	int oldthrow;
	char buf[20];
	AMODE *ap;
	SYM *sym;
 
    lab1 = nextlabel++;
	oldthrow = throwlab;
	throwlab = nextlabel++;
 
	GenerateDiadic(op_lea,0,makereg(28),make_label(throwlab));
	GenerateStatement(stmt->s1);
    GenerateDiadic(op_bra,0,make_label(lab1),NULL);
	GenerateLabel(throwlab);
	stmt = stmt->s2;
	while (stmt) {
		throwlab = oldthrow;
		curlab = nextlabel++;
		GenerateLabel(curlab);
		if (stmt->s2==99999)
			;
		else
			GenerateTriadic(op_bnei,0,makereg(2),make_immed((int)stmt->s2),make_label(nextlabel));
		// move the throw expression result in 'r1' into the catch variable.
		sym = (SYM *)stmt->label;
		if (sym) {
			switch(sym->tp->size) {
			case 1:	GenerateDiadic(op_sb,0,makereg(1),make_indexed(sym->value.i,27));
			case 2: GenerateDiadic(op_sc,0,makereg(1),make_indexed(sym->value.i,27));
			case 4: GenerateDiadic(op_sh,0,makereg(1),make_indexed(sym->value.i,27));
			case 8: GenerateDiadic(op_sw,0,makereg(1),make_indexed(sym->value.i,27));
			}
		}
		GenerateStatement(stmt->s1);
		stmt=stmt->next;
	}
    GenerateLabel(lab1);
	GenerateDiadic(op_lea,0,makereg(28),make_label(oldthrow));
}
 
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)
			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);
		GenerateTriadic(op_ori,0,makereg(2),makereg(0),make_immed((int)stmt->label));
	}
	GenerateDiadic(op_bra,0,make_label(throwlab),NULL);
}
/*
void GenerateCritical(struct snode *stmt)
{
	int lab1;
 
	lab1 = nextlabel++;
	semaphores[lastsph] = stmt->label;
	lastsph++;
    GenerateLabel(lab1);
	GenerateDiadic(op_tas,0,make_string(stmt->label),NULL);
	GenerateDiadic(op_bmi,0,make_label(lab1),NULL);
	GenerateStatement(stmt->s1);
	--lastsph;
	semaphores[lastsph] = NULL;
	GenerateDiadic(op_move,0,make_immed(0),make_string(stmt->label));
}
*/
 
void GenerateSpinlock(Statement *stmt)
{
	int lab1, lab2, lab3, lab4;
	AMODE *ap1, *ap2;
	AMODE *ap;
 
	lab1 = nextlabel++;
	lab2 = nextlabel++;
	lab3 = nextlabel++;
 
    if( stmt != NULL && stmt->exp != NULL )
	{
		initstack();
		ap1 = GetTempRegister();
		ap2 = GetTempRegister();
		ap = GenerateExpression(stmt->exp,F_REG,8);
		if (stmt->initExpr)
			GenerateTriadic(op_ori, 0, ap1,makereg(0),make_immed(stmt->initExpr));
		GenerateLabel(lab1);
		if (stmt->initExpr) {
			GenerateTriadic(op_sub, 0, ap1, ap1, make_immed(1));
			GenerateTriadic(op_beq, 0, ap1, makereg(0), make_label(lab2));
		}
		GenerateDiadic(op_inbu, 0, ap2, make_indexed(stmt->incrExpr,ap->preg));
		GenerateTriadic(op_beq, 0, ap2, makereg(0), make_label(lab1));
		ReleaseTempRegister(ap2);
		GenerateStatement(stmt->s1);
		// unlock
		GenerateDiadic(op_outb, 0, makereg(0), make_indexed(stmt->incrExpr,ap->preg));
		if (stmt->initExpr) {
			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");
		}
	}
 
	//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");
	//}
}
 
void GenerateSpinUnlock(struct snode *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)
				GenerateTriadic(op_ori, 0, makereg(1),makereg(0),ap);
			else
				GenerateDiadic(op_mov, 0, makereg(1),ap);
			GenerateDiadic(op_outb, 0, makereg(0),make_indexed(stmt->incrExpr,1));
		}
	}
 
//	GenerateDiadic(op_sb,0,makereg(0),make_string(stmt->label));
}
/*
 *      genstmt will generate a statement and follow the next pointer
 *      until the block is generated.
 */
void GenerateStatement(struct snode *stmt)
{
	while( stmt != NULL )
    {
        switch( stmt->stype )
                {
				//case st_vortex:
				//		gen_vortex(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(stmt->label);
                        break;
                case st_goto:
                        GenerateDiadic(op_bra,0,make_label(stmt->label),0);
                        break;
				//case st_critical:
    //                    GenerateCritical(stmt);
    //                    break;
				case st_spinlock:
						GenerateSpinlock(stmt);
						break;
				case st_spinunlock:
						GenerateSpinUnlock(stmt);
						break;
                case st_expr:
                        initstack();
                        GenerateExpression(stmt->exp,F_ALL | F_NOVALUE,
                                GetNaturalSize(stmt->exp));
                        break;
                case st_return:
                        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:
                        GenerateDiadic(op_bra,0,make_label(contlab),0);
                        break;
                case st_break:
                        GenerateDiadic(op_bra,0,make_label(breaklab),0);
                        break;
                case st_switch:
                        genxswitch(stmt);
                        break;
                default:
                        printf("DIAG - unknown statement.\n");
                        break;
                }
        stmt = stmt->next;
    }
}
 
void GenerateIntoff(Statement *stmt)
{
//	GenerateDiadic(op_move,0,make_string("sr"),make_string("_TCBsrsave"));
	GenerateDiadic(op_sei,0,NULL,NULL);
}
 
void GenerateInton(Statement *stmt)
{
//	GenerateDiadic(op_move,0,make_string("_TCBsrsave"),make_string("sr"));
}
 
void GenerateStop(Statement *stmt)
{
	GenerateDiadic(op_stop,0,make_immed(0),NULL);
}
 
void GenerateAsm(Statement *stmt)
{
	GenerateTriadic(op_asm,0,make_string(stmt->label),NULL,NULL);
}
 
void GenerateFirstcall(Statement *stmt)
{
	int     lab1, lab2, lab3,lab4,lab5,lab6,lab7;
	char buf[20];
	AMODE *ap1,*ap2;
 
    lab1 = contlab;         /* save old continue label */
    lab2 = breaklab;        /* save old break label */
    contlab = nextlabel++;  /* new continue label */
	lab3 = nextlabel++;
	lab4 = nextlabel++;
	lab5 = nextlabel++;
	lab6 = nextlabel++;
	lab7 = nextlabel++;
    if( stmt->s1 != NULL )      /* has block */
    {
        breaklab = nextlabel++;
        GenerateLabel(lab3);	// marks address of brf
        GenerateDiadic(op_bra,0,make_label(lab7),NULL);	// branch to the firstcall statement
        GenerateLabel(lab6);	// prevent optimizer from optimizing move away
		GenerateDiadic(op_bra,0,make_label(breaklab),NULL);	// then branch around it
        GenerateLabel(lab7);	// prevent optimizer from optimizing move away
		ap1 = GetTempRegister();
		ap2 = GetTempRegister();
		GenerateDiadic(op_lea,0,ap2,make_label(lab3));
		GenerateTriadic(op_andi,0,ap2,ap2,make_immed(0x0c));
		GenerateTriadic(op_beqi,0,ap2,make_immed(0x08L),make_label(lab4));
		GenerateTriadic(op_beqi,0,ap2,make_immed(0x04L),make_label(lab5));
		GenerateDiadic(op_lea,0,ap2,make_label(lab3));
		GenerateDiadic(op_lw,0,ap1,make_indirect(ap2->preg));
		GenerateTriadic(op_andi,0,ap1,ap1,make_immed(0xFFFFFC0000000000L));
		GenerateTriadic(op_ori,0,ap1,ap1,make_immed(0x000037800000000L));	// nop instruction
		GenerateDiadic(op_sw,0,ap1,make_indirect(ap2->preg));
		GenerateDiadic(op_cache,0,make_string("invil"),make_indirect(ap2->preg));
		GenerateDiadic(op_bra,0,make_label(lab6),NULL);
		GenerateLabel(lab4);
		GenerateDiadic(op_lea,0,ap2,make_label(lab3));
		GenerateDiadic(op_lw,0,ap1,make_indirect(ap2->preg));
		GenerateTriadic(op_andi,0,ap1,ap1,make_immed(0x00000000000FFFFFL));
		GenerateTriadic(op_ori,0,ap1,ap1,make_immed(0x3780000000000000L));	// nop instruction
		GenerateDiadic(op_sw,0,ap1,make_indirect(ap2->preg));
		GenerateDiadic(op_cache,0,make_string("invil"),make_indirect(ap2->preg));
		GenerateDiadic(op_bra,0,make_label(lab6),NULL);
		GenerateLabel(lab5);
		GenerateDiadic(op_lea,0,ap2,make_label(lab3));
		GenerateDiadic(op_lw,0,ap1,make_indexed(4,ap2->preg));
		GenerateTriadic(op_andi,0,ap1,ap1,make_immed(0xFFFFFFFFFFF00000L));
		GenerateTriadic(op_ori,0,ap1,ap1,make_immed(0x00000000000DE000L));	// nop instruction
		GenerateDiadic(op_sw,0,ap1,make_indexed(4,ap2->preg));
		GenerateDiadic(op_cache,0,make_string("invil"),make_indexed(4,ap2->preg));
		GenerateLabel(lab6);
		GenerateStatement(stmt->s1);
        GenerateLabel(breaklab);
        breaklab = lab2;        /* restore old break label */
    }
    contlab = lab1;         /* restore old continue label */
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.