2019-05-10 17:11:54 +00:00
|
|
|
/*
|
|
|
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
|
|
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
|
|
|
*
|
|
|
|
* Author: Hans van Staveren
|
|
|
|
*/
|
1984-05-18 21:27:39 +00:00
|
|
|
#include "assert.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "param.h"
|
|
|
|
#include "tables.h"
|
|
|
|
#include "types.h"
|
|
|
|
#include <cg_pattern.h>
|
|
|
|
#include "data.h"
|
|
|
|
#include "result.h"
|
|
|
|
#include "extern.h"
|
2019-05-10 17:11:54 +00:00
|
|
|
#include "subr.h"
|
|
|
|
#include "gencode.h"
|
|
|
|
#include "fillem.h"
|
1984-05-18 21:27:39 +00:00
|
|
|
|
|
|
|
FILE *codefile;
|
|
|
|
|
2019-05-10 17:11:54 +00:00
|
|
|
|
|
|
|
void out_init(char *filename)
|
|
|
|
{
|
1984-05-18 21:27:39 +00:00
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
|
2019-05-10 17:11:54 +00:00
|
|
|
if (Debug)
|
|
|
|
{
|
|
|
|
codefile = stderr;
|
|
|
|
}
|
1984-05-18 21:27:39 +00:00
|
|
|
else
|
2019-05-10 17:11:54 +00:00
|
|
|
{
|
|
|
|
#endif
|
|
|
|
if (filename == (char *) 0)
|
|
|
|
codefile = stdout;
|
2022-07-17 10:58:48 +00:00
|
|
|
else if ((codefile = freopen(filename, "wb", stdout)) == NULL)
|
2019-05-10 17:11:54 +00:00
|
|
|
error("Can't create %s", filename);
|
1984-05-18 21:27:39 +00:00
|
|
|
#ifndef NDEBUG
|
2019-05-10 17:11:54 +00:00
|
|
|
}
|
1984-05-18 21:27:39 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2019-05-10 17:11:54 +00:00
|
|
|
void out_finish(void) {
|
1984-05-18 21:27:39 +00:00
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
if (Debug)
|
|
|
|
fflush(stderr);
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
fclose(codefile);
|
|
|
|
}
|
|
|
|
|
2019-05-10 17:11:54 +00:00
|
|
|
void tstoutput(void) {
|
1984-05-19 11:40:08 +00:00
|
|
|
|
|
|
|
if (ferror(codefile))
|
|
|
|
error("Write error on output");
|
|
|
|
}
|
|
|
|
|
2019-05-10 17:11:54 +00:00
|
|
|
void gencode(register char *code)
|
|
|
|
{
|
|
|
|
register int c;
|
1984-05-18 21:27:39 +00:00
|
|
|
int tokno,fldno,insno,regno,subno;
|
|
|
|
register token_p tp;
|
|
|
|
|
|
|
|
swtxt();
|
|
|
|
while ((c= *code++)!=0) switch(c) {
|
|
|
|
default:
|
|
|
|
fputc(c,codefile);
|
|
|
|
break;
|
|
|
|
case PR_TOK:
|
|
|
|
tokno = *code++;
|
|
|
|
tp = &fakestack[stackheight-tokno];
|
|
|
|
if (tp->t_token==-1)
|
|
|
|
fprintf(codefile,"%s",codestrings[machregs[tp->t_att[0].ar].r_repr]);
|
|
|
|
else
|
|
|
|
prtoken(tp);
|
|
|
|
break;
|
|
|
|
case PR_TOKFLD:
|
|
|
|
tokno = *code++;
|
|
|
|
fldno = *code++;
|
|
|
|
tp = &fakestack[stackheight-tokno];
|
|
|
|
assert(tp->t_token != -1);
|
|
|
|
switch(tokens[tp->t_token].t_type[fldno-1]) {
|
|
|
|
default:
|
|
|
|
assert(FALSE);
|
|
|
|
case EV_INT:
|
|
|
|
fprintf(codefile,WRD_FMT,tp->t_att[fldno-1].aw);
|
|
|
|
break;
|
|
|
|
case EV_STR:
|
|
|
|
fprintf(codefile,"%s",tp->t_att[fldno-1].as);
|
|
|
|
break;
|
|
|
|
case EV_REG:
|
|
|
|
assert(tp->t_att[fldno-1].ar>0 && tp->t_att[fldno-1].ar<NREGS);
|
|
|
|
fprintf(codefile,"%s",codestrings[machregs[tp->t_att[fldno-1].ar].r_repr]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PR_EMINT:
|
|
|
|
insno = *code++;
|
|
|
|
fprintf(codefile,WRD_FMT,dollar[insno-1].e_v.e_con);
|
|
|
|
break;
|
|
|
|
case PR_EMSTR:
|
|
|
|
insno = *code++;
|
|
|
|
fprintf(codefile,"%s",dollar[insno-1].e_v.e_str);
|
|
|
|
break;
|
|
|
|
case PR_ALLREG:
|
|
|
|
regno = *code++;
|
|
|
|
subno = (*code++)&0377;
|
|
|
|
assert(regno>=1 && regno<=nallreg);
|
|
|
|
regno = allreg[regno-1];
|
|
|
|
#if MAXMEMBERS!=0
|
|
|
|
if (subno!=255) {
|
|
|
|
assert(subno>=1 && subno<=MAXMEMBERS);
|
|
|
|
regno = machregs[regno].r_members[subno-1];
|
|
|
|
assert(regno!=0);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
fprintf(codefile,"%s",codestrings[machregs[regno].r_repr]);
|
|
|
|
break;
|
|
|
|
#if MAXMEMBERS!=0
|
|
|
|
case PR_SUBREG:
|
|
|
|
tokno = *code++;
|
|
|
|
subno = *code++;
|
|
|
|
tp = &fakestack[stackheight-tokno];
|
|
|
|
assert(tp->t_token == -1);
|
|
|
|
fprintf(codefile,"%s",codestrings[machregs[machregs[tp->t_att[0].ar].r_members[subno-1]].r_repr]);
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-10 17:11:54 +00:00
|
|
|
void genexpr(int nodeno)
|
|
|
|
{
|
1984-05-18 21:27:39 +00:00
|
|
|
result_t result;
|
|
|
|
|
|
|
|
result= compute(&enodes[nodeno]);
|
|
|
|
switch(result.e_typ) {
|
|
|
|
default: assert(FALSE);
|
|
|
|
case EV_INT:
|
|
|
|
fprintf(codefile,WRD_FMT,result.e_v.e_con);
|
|
|
|
break;
|
|
|
|
case EV_REG:
|
|
|
|
fprintf(codefile,"%s", codestrings[machregs[result.e_v.e_reg].r_repr]);
|
|
|
|
break;
|
|
|
|
case EV_STR:
|
|
|
|
fprintf(codefile,"%s",result.e_v.e_str);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-10 17:11:54 +00:00
|
|
|
void gennl(void)
|
|
|
|
{
|
1984-05-18 21:27:39 +00:00
|
|
|
fputc('\n',codefile);
|
|
|
|
}
|
|
|
|
|
2019-05-10 17:11:54 +00:00
|
|
|
void prtoken(token_p tp)
|
|
|
|
{
|
|
|
|
register int c;
|
1984-05-18 21:27:39 +00:00
|
|
|
register char *code;
|
|
|
|
register tkdef_p tdp;
|
|
|
|
|
|
|
|
tdp = &tokens[tp->t_token];
|
|
|
|
assert(tdp->t_format != -1);
|
|
|
|
code = codestrings[tdp->t_format];
|
|
|
|
while ((c = *code++) != 0) {
|
|
|
|
if (c>=' ' && c<='~')
|
|
|
|
fputc(c,codefile);
|
|
|
|
else {
|
|
|
|
assert(c>0 && c<=TOKENSIZE);
|
|
|
|
switch(tdp->t_type[c-1]) {
|
|
|
|
default:
|
|
|
|
assert(FALSE);
|
|
|
|
case EV_INT:
|
|
|
|
fprintf(codefile,WRD_FMT,tp->t_att[c-1].aw);
|
|
|
|
break;
|
|
|
|
case EV_STR:
|
|
|
|
fprintf(codefile,"%s",tp->t_att[c-1].as);
|
|
|
|
break;
|
|
|
|
case EV_REG:
|
|
|
|
fprintf(codefile,"%s",codestrings[machregs[tp->t_att[c-1].ar].r_repr]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|