ack/util/ncgg/instruct.c
George Koehler 307a8b996e Add regvar_w() and regvar_d() for use with reglap.
If the ncg table uses reglap, then regvar($1, reg_float) would have
two sizes of registers.  An error from ncgg would happen if regvar()
was in a token that allows only one size.  Now one can pick a size
with regvar_w() for word size or regvar_d() for double-word size.

Add regvar_d and regvar_w as keywords in ncgg.  Modify EX_REGVAR to
include the register size.  In ncg, add some checks for the register
size.  In tables without reglap, regvar() works as before, and ncg
ignores the register size in EX_REGVAR.
2017-10-17 12:05:41 -04:00

205 lines
4.3 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".
*/
#ifndef NORCSID
static char rcsid[]= "$Id$";
#endif
#include "param.h"
#include "instruct.h"
#include "pseudo.h"
#include "varinfo.h"
#include "set.h"
#include "expr.h"
#include "iocc.h"
#include <cgg_cg.h>
#include "extern.h"
extern int niops;
extern iocc_t iops[];
extern inproc;
extern set_t l_sets[];
extern inst_t l_instances[];
extern expr_t subreg_expr(),regno_expr();
struct varinfo * setcoco(n) {
struct varinfo *vi;
NEW(vi,struct varinfo);
vi->vi_next = VI_NULL;
vi->vi_int[0] = INSSETCC;
vi->vi_int[1] = n;
return(vi);
}
struct varinfo * generase(n) {
struct varinfo *vi;
NEW(vi,struct varinfo);
vi->vi_next = VI_NULL;
vi->vi_int[0] = INSERASE;
vi->vi_int[1] = n;
return(vi);
}
struct varinfo * genremove(n) {
struct varinfo *vi;
NEW(vi,struct varinfo);
vi->vi_next = VI_NULL;
vi->vi_int[0] = INSREMOVE;
vi->vi_int[1] = n;
return(vi);
}
onlyreg(argno) {
register bitno;
register short *sp;
if (! argno) argno++;
sp = l_sets[tokpatset[argno-1]].set_val;
for(bitno=nregs;bitno<nregs+ntokens;bitno++)
if (BIT(sp,bitno))
return(0);
return(1);
}
makescratch(argno) {
set_t s;
if (! argno) argno++;
if (tokpatro[argno-1])
error("Instruction destroys %%%d, not allowed here",argno);
s = l_sets[tokpatset[argno-1]];
BIC(s.set_val,0);
tokpatset[argno-1] = setlookup(s);
}
struct varinfo *gen_inst(ident,star) char *ident; {
register struct varinfo *vi,*retval,*eravi;
register instr_p ip;
register struct operand *op;
register i;
register inst_p insta;
if (star && !inproc)
error("Variable instruction only allowed inside proc");
for (ip=l_instr;ip<l_instr+ninstr;ip++) {
if(strcmp(ident,ip->i_name))
continue;
if (ip->i_nops!=niops)
continue;
for(i=0,op=ip->i_oplist;i<niops;i++,op=op->o_next) {
if (!subset(iops[i].in_set,l_sets[op->o_setno].set_val,SETSIZE))
goto cont;
}
goto found; /* oh well, one more won't hurt */
cont:;
}
error("Such an \"%s\" does not exist",ident);
return(0);
found:
NEW(vi,struct varinfo);
vi->vi_int[0] = ip-l_instr;
vi->vi_int[1] = star;
vi->vi_next=0;
retval = vi;
for(i=0;i<niops;i++) {
NEW(vi->vi_vi,struct varinfo);
vi=vi->vi_vi;
vi->vi_int[0] = iops[i].in_index;
}
vi->vi_vi = 0;
vi = retval;
for(i=0,op=ip->i_oplist;i<niops;i++,op=op->o_next) {
if(op->o_adorn&AD_CC) {
vi->vi_next = setcoco(iops[i].in_index);
vi=vi->vi_next;
}
switch(op->o_adorn&AD_RWMASK) {
default:
/* Nothing possible to do */
break;
case AD_RO:
/* It might be possible to do something
* here but not now.
*/
break;
case AD_RW:
case AD_WO:
/* Treated the same for now */
insta = &l_instances[iops[i].in_index];
switch(insta->in_which) {
case IN_COPY:
if(insta->in_info[1]==0 && !onlyreg(insta->in_info[0]))
break;
makescratch(insta->in_info[0]);
vi->vi_next = generase(
ex_lookup(
EX_SUBREG,insta->in_info[0],
insta->in_info[1]
)
);
vi = vi->vi_next;
break;
case IN_MEMB:
vi->vi_next = generase(
ex_lookup(
EX_TOKFIELD,insta->in_info[0],
insta->in_info[1]
)
);
vi=vi->vi_next;
break;
case IN_RIDENT:
vi->vi_next = generase(
ex_lookup(
EX_REG,insta->in_info[0],0
)
);
vi = vi->vi_next;
break;
case IN_ALLOC:
vi->vi_next = generase(
ex_lookup(
EX_ALLREG,insta->in_info[0]+1,
insta->in_info[1]
)
);
vi = vi->vi_next;
break;
case IN_S_DESCR:
case IN_D_DESCR:
{ int temp;
if (insta->in_which == IN_S_DESCR)
temp = wordsize;
else
temp = 2 * wordsize;
temp=ex_lookup(EX_REGVAR,insta->in_info[1],temp);
vi->vi_next = generase(temp);
vi = vi->vi_next;
vi->vi_next = genremove(temp);
vi = vi->vi_next;
break;
}
}
break;
}
}
for (eravi=ip->i_erases;eravi != VI_NULL;eravi=eravi->vi_next) {
if (eravi->vi_int[0] < 0)
vi->vi_next = setcoco(0);
else {
vi->vi_next = generase(eravi->vi_int[0]);
vi=vi->vi_next;
vi->vi_next = genremove(eravi->vi_int[0]);
}
vi=vi->vi_next;
}
return(retval);
}