ack/lang/m2/comp/tmpvar.c
2022-07-16 19:34:25 +02:00

133 lines
2.5 KiB
C

/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Ceriel J.H. Jacobs
*/
/* T E M P O R A R Y V A R I A B L E S */
/* $Id$ */
/* Code for the allocation and de-allocation of temporary variables,
allowing re-use.
The routines use "ProcScope" instead of "CurrentScope", because
"CurrentScope" also reflects WITH statements, and these scopes do not
have local variabes.
*/
#include "parameters.h"
#include "debug.h"
#include <em_arith.h>
#include <em_label.h>
#include <em_code.h>
#include <em_reg.h>
#include <alloc.h>
#include <assert.h>
#include <stdlib.h>
#include "LLlex.h"
#include "def.h"
#include "type.h"
#include "scope.h"
#include "tmpvar.h"
#include "main.h"
#include "tmpvar.h"
struct tmpvar {
struct tmpvar *t_next;
arith t_offset; /* offset from LocalBase */
};
#define new_tmpvar() ((struct tmpvar*) calloc(1, sizeof(struct tmpvar)))
#define free_tmpvar(p) free(p)
static struct tmpvar *TmpInts, /* for integer temporaries */
*TmpPtrs; /* for pointer temporaries */
static struct scope *ProcScope; /* scope of procedure in which the
temporaries are allocated
*/
void TmpOpen(struct scope *sc)
{
/* Initialize for temporaries in scope "sc".
*/
ProcScope = sc;
}
arith TmpSpace(arith sz, int al)
{
register struct scope *sc = ProcScope;
sc->sc_off = - WA(align(sz - sc->sc_off, al));
return sc->sc_off;
}
static arith NewTmp(struct tmpvar **plist, arith sz, int al, int regtype)
{
register arith offset;
register struct tmpvar *tmp;
if (!*plist) {
offset = TmpSpace(sz, al);
if (! options['n']) C_ms_reg(offset, sz, regtype, 0);
}
else {
tmp = *plist;
offset = tmp->t_offset;
*plist = tmp->t_next;
free_tmpvar(tmp);
}
return offset;
}
arith NewInt(void)
{
return NewTmp(&TmpInts, int_size, int_align, reg_any);
}
arith NewPtr(void)
{
return NewTmp(&TmpPtrs, pointer_size, pointer_align, reg_pointer);
}
static void FreeTmp(struct tmpvar **plist, arith off)
{
register struct tmpvar *tmp = new_tmpvar();
tmp->t_next = *plist;
tmp->t_offset = off;
*plist = tmp;
}
void FreeInt(arith off)
{
FreeTmp(&TmpInts, off);
}
void FreePtr(arith off)
{
FreeTmp(&TmpPtrs, off);
}
void TmpClose(void)
{
register struct tmpvar *tmp, *tmp1;
tmp = TmpInts;
while (tmp) {
tmp1 = tmp;
tmp = tmp->t_next;
free_tmpvar(tmp1);
}
tmp = TmpPtrs;
while (tmp) {
tmp1 = tmp;
tmp = tmp->t_next;
free_tmpvar(tmp1);
}
TmpInts = TmpPtrs = 0;
}