home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d1xx
/
d110
/
pdc.lha
/
Pdc
/
src
/
Register.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-10-28
|
5KB
|
162 lines
#include <stdio.h>
#include "c.h"
#include "expr.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
*/
/*
* this module handles the allocation and de-allocation of
* temporary registers. when a temporary register is allocated
* the stack depth is saved in the field deep of the address
* mode structure. when validate is called on an address mode
* structure the stack is popped until the register is restored
* to it's pre-push value.
*/
struct amode push[] = { {am_adec,(enum e_am)7} },
pop[] = { {am_ainc, (enum e_am)7} };
int next_data,
next_addr;
int max_data,
max_addr;
gen_push(reg,rmode)
/*
* this routine generates code to push a register onto the stack
*/
enum e_am reg, rmode;
{ struct amode *ap1;
ap1 = xalloc(sizeof(struct amode));
ap1->preg = reg;
ap1->mode = rmode;
gen_code(op_move,4,ap1,push);
}
gen_pop(reg,rmode)
/*
* generate code to pop the primary register in ap from the
* stack.
*/
enum e_am reg, rmode;
{ struct amode *ap1;
ap1 = xalloc(sizeof(struct amode));
ap1->preg = reg;
ap1->mode = rmode;
gen_code(op_move,4,pop,ap1);
}
initstack()
/*
* this routine should be called before each expression is
* evaluated to make sure the stack is balanced and all of
* the registers are marked free.
*/
{ next_data = 0;
next_addr = 0;
max_data = 2;
max_addr = 1;
}
validate(ap)
/*
* validate will make sure that if a register within an address
* mode has been pushed onto the stack that it is popped back
* at this time.
*/
struct amode *ap;
{ switch( ap->mode )
{
case am_direct:
case am_immed:
return; /* no registers used */
case am_dreg:
if( (int)ap->preg > 2 )
return; /* not a temporary */
if( max_data - ap->deep >= 3 )
{
gen_pop(ap->preg,am_dreg);
--max_data;
}
break;
default:
if( (int)ap->preg > 1 )
return; /* not a temp register */
if( max_addr - ap->deep >= 2 )
{
gen_pop(ap->preg,am_areg);
--max_addr;
}
break;
}
}
struct amode *temp_data()
/*
* allocate a temporary data register and return it's
* addressing mode.
*/
{ struct amode *ap;
ap = xalloc(sizeof(struct amode));
ap->mode = am_dreg;
ap->preg = (enum e_am)(next_data % 3);
ap->deep = next_data;
if( next_data > max_data )
{
gen_push((enum e_am)(next_data % 3),am_dreg);
max_data = next_data;
}
++next_data;
return ap;
}
struct amode *temp_addr()
/*
* allocate a temporary address register and return it's
* addressing mode.
*/
{ struct amode *ap;
ap = xalloc(sizeof(struct amode));
ap->mode = am_areg;
ap->preg = (enum e_am)(next_addr % 2);
ap->deep = next_addr;
if( next_addr > max_addr )
{
gen_push((enum e_am)(next_addr % 2),am_areg);
max_addr = next_addr;
}
++next_addr;
return ap;
}
freeop(ap)
/*
* release any temporary registers used in an addressing mode.
*/
struct amode *ap;
{ if( ap->mode == am_immed || ap->mode == am_direct )
return; /* no registers used */
if( ap->mode == am_dreg && (int)ap->preg < 3 )
--next_data;
else if( (int)ap->preg < 2 )
--next_addr;
}