Initial revision
This commit is contained in:
237
lang/cem/cemcom.ansi/util.c
Normal file
237
lang/cem/cemcom.ansi/util.c
Normal file
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
/* M I S C E L L A N E O U S U T I L I T I E S */
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
/* Code for the allocation and de-allocation of temporary variables,
|
||||
allowing re-use.
|
||||
*/
|
||||
|
||||
#include <em.h>
|
||||
#include <em_reg.h>
|
||||
#include <alloc.h>
|
||||
#include <em_mes.h>
|
||||
|
||||
#include "lint.h"
|
||||
#include "util.h"
|
||||
#include "use_tmp.h"
|
||||
#include "regcount.h"
|
||||
#include "sizes.h"
|
||||
#include "align.h"
|
||||
#include "stack.h"
|
||||
#include "Lpars.h"
|
||||
#include "def.h"
|
||||
|
||||
static struct localvar *FreeTmps;
|
||||
#ifdef USE_TMP
|
||||
static int loc_id;
|
||||
#endif USE_TMP
|
||||
|
||||
#ifdef PEEPHOLE
|
||||
#undef REGCOUNT
|
||||
#define REGCOUNT 1
|
||||
#endif
|
||||
|
||||
extern char options[];
|
||||
|
||||
LocalInit()
|
||||
{
|
||||
#ifdef USE_TMP
|
||||
C_insertpart(loc_id = C_getid());
|
||||
#endif USE_TMP
|
||||
}
|
||||
|
||||
arith
|
||||
LocalSpace(sz, al)
|
||||
arith sz;
|
||||
{
|
||||
register struct stack_level *stl = local_level;
|
||||
|
||||
stl->sl_max_block = - align(sz - stl->sl_max_block, al);
|
||||
return stl->sl_max_block;
|
||||
}
|
||||
|
||||
#define TABSIZ 32
|
||||
static struct localvar *regs[TABSIZ];
|
||||
|
||||
arith
|
||||
NewLocal(sz, al, regtype, sc)
|
||||
arith sz;
|
||||
{
|
||||
register struct localvar *tmp = FreeTmps;
|
||||
struct localvar *prev = 0;
|
||||
register int index;
|
||||
|
||||
while (tmp) {
|
||||
if (tmp->t_align >= al &&
|
||||
tmp->t_size >= sz &&
|
||||
tmp->t_sc == sc &&
|
||||
tmp->t_regtype == regtype) {
|
||||
if (prev) {
|
||||
prev->next = tmp->next;
|
||||
}
|
||||
else FreeTmps = tmp->next;
|
||||
break;
|
||||
}
|
||||
prev = tmp;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
if (! tmp) {
|
||||
tmp = new_localvar();
|
||||
tmp->t_offset = LocalSpace(sz, al);
|
||||
tmp->t_align = al;
|
||||
tmp->t_size = sz;
|
||||
tmp->t_sc = sc;
|
||||
tmp->t_regtype = regtype;
|
||||
tmp->t_count = REG_DEFAULT;
|
||||
}
|
||||
index = (int) (tmp->t_offset >> 2) & (TABSIZ - 1);
|
||||
tmp->next = regs[index];
|
||||
regs[index] = tmp;
|
||||
return tmp->t_offset;
|
||||
}
|
||||
|
||||
FreeLocal(off)
|
||||
arith off;
|
||||
{
|
||||
int index = (int) (off >> 2) & (TABSIZ - 1);
|
||||
register struct localvar *tmp = regs[index];
|
||||
struct localvar *prev = 0;
|
||||
|
||||
while (tmp && tmp->t_offset != off) {
|
||||
prev = tmp;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
if (tmp) {
|
||||
if (prev) prev->next = tmp->next;
|
||||
else regs[index] = tmp->next;
|
||||
tmp->next = FreeTmps;
|
||||
FreeTmps = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
LocalFinish()
|
||||
{
|
||||
register struct localvar *tmp, *tmp1;
|
||||
register int i;
|
||||
|
||||
#ifdef USE_TMP
|
||||
C_beginpart(loc_id);
|
||||
#endif
|
||||
tmp = FreeTmps;
|
||||
while (tmp) {
|
||||
tmp1 = tmp;
|
||||
if (tmp->t_sc == REGISTER) tmp->t_count += REG_BONUS;
|
||||
if (! options['n'] && tmp->t_regtype >= 0) {
|
||||
C_ms_reg(tmp->t_offset, tmp->t_size, tmp->t_regtype, tmp->t_count);
|
||||
}
|
||||
tmp = tmp->next;
|
||||
free_localvar(tmp1);
|
||||
}
|
||||
FreeTmps = 0;
|
||||
for (i = 0; i < TABSIZ; i++) {
|
||||
tmp = regs[i];
|
||||
while (tmp) {
|
||||
if (tmp->t_sc == REGISTER) tmp->t_count += REG_BONUS;
|
||||
tmp1 = tmp;
|
||||
if (! options['n'] && tmp->t_regtype >= 0) {
|
||||
C_ms_reg(tmp->t_offset,
|
||||
tmp->t_size,
|
||||
tmp->t_regtype,
|
||||
tmp->t_count);
|
||||
}
|
||||
tmp = tmp->next;
|
||||
free_localvar(tmp1);
|
||||
}
|
||||
regs[i] = 0;
|
||||
}
|
||||
if (! options['n']) {
|
||||
C_mes_begin(ms_reg);
|
||||
C_mes_end();
|
||||
}
|
||||
#ifdef USE_TMP
|
||||
C_endpart(loc_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
RegisterAccount(offset, size, regtype, sc)
|
||||
arith offset, size;
|
||||
{
|
||||
register struct localvar *p;
|
||||
int index;
|
||||
|
||||
if (regtype < 0) return;
|
||||
|
||||
p = new_localvar();
|
||||
index = (int) (offset >> 2) & (TABSIZ - 1);
|
||||
p->t_offset = offset;
|
||||
p->t_regtype = regtype;
|
||||
p->t_count = REG_DEFAULT;
|
||||
p->t_sc = sc;
|
||||
p->t_size = size;
|
||||
p->next = regs[index];
|
||||
regs[index] = p;
|
||||
}
|
||||
|
||||
static struct localvar *
|
||||
find_reg(off)
|
||||
arith off;
|
||||
{
|
||||
register struct localvar *p = regs[(int)(off >> 2) & (TABSIZ - 1)];
|
||||
|
||||
while (p && p->t_offset != off) p = p->next;
|
||||
return p;
|
||||
}
|
||||
|
||||
LoadLocal(off, sz)
|
||||
arith off, sz;
|
||||
{
|
||||
register struct localvar *p = find_reg(off);
|
||||
|
||||
#ifdef USE_TMP
|
||||
#ifdef REGCOUNT
|
||||
if (p) p->t_count++;
|
||||
#endif
|
||||
#endif
|
||||
if (sz == word_size) C_lol(off);
|
||||
else if (sz == dword_size) C_ldl(off);
|
||||
else {
|
||||
if (p) p->t_regtype = -1;
|
||||
C_lal(off);
|
||||
C_loi(sz);
|
||||
}
|
||||
}
|
||||
|
||||
StoreLocal(off, sz)
|
||||
arith off, sz;
|
||||
{
|
||||
register struct localvar *p = find_reg(off);
|
||||
|
||||
#ifdef USE_TMP
|
||||
#ifdef REGCOUNT
|
||||
if (p) p->t_count++;
|
||||
#endif
|
||||
#endif
|
||||
if (sz == word_size) C_stl(off);
|
||||
else if (sz == dword_size) C_sdl(off);
|
||||
else {
|
||||
if (p) p->t_regtype = -1;
|
||||
C_lal(off);
|
||||
C_sti(sz);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef LINT
|
||||
AddrLocal(off)
|
||||
arith off;
|
||||
{
|
||||
register struct localvar *p = find_reg(off);
|
||||
|
||||
if (p) p->t_regtype = -1;
|
||||
C_lal(off);
|
||||
}
|
||||
#endif LINT
|
||||
Reference in New Issue
Block a user