This breaks all machines because the declared return type void disagrees with the implicit return type int (when I compile mach.c with clang). Unbreak i386, i80, i86, m68020, powerpc, vc4 by adding the return types to mach.c. We don't build any other machines; they are broken since commita46ee91(May 19, 2013) declared void prolog() and commitfd91851(Nov 10, 2016) declared void mes(), with both declarations in mach/proto/ncg/fillem.c. Also fix mach/vc4/ncg/mach.c where type full is long, so fprintf() must use "%ld" not "%d" to print full nlocals.
		
			
				
	
	
		
			1135 lines
		
	
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1135 lines
		
	
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#ifndef NORCSID
 | 
						|
static char rcsid[] = "$Id$";
 | 
						|
#endif
 | 
						|
 | 
						|
#include <assert.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include "param.h"
 | 
						|
#include "tables.h"
 | 
						|
#include "types.h"
 | 
						|
#include <cgg_cg.h>
 | 
						|
#include "data.h"
 | 
						|
#include "result.h"
 | 
						|
#include "state.h"
 | 
						|
#include "equiv.h"
 | 
						|
#include "extern.h"
 | 
						|
#ifdef REGVARS
 | 
						|
#include "regvar.h" /* regreturn */
 | 
						|
#endif
 | 
						|
 | 
						|
/*
 | 
						|
 * (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
 | 
						|
 */
 | 
						|
 | 
						|
#define ALLOW_NEXTEM /* code generator is allowed new try of NEXTEM \
 | 
						|
            in exceptional cases */
 | 
						|
 | 
						|
byte startupcode[] = { DO_NEXTEM };
 | 
						|
 | 
						|
#ifdef NDEBUG
 | 
						|
#define DEBUG(string)
 | 
						|
#else
 | 
						|
#include <stdio.h>
 | 
						|
#define DEBUG(string)                                              \
 | 
						|
	{                                                              \
 | 
						|
		if (Debug)                                                 \
 | 
						|
			fprintf(stderr, "%-*d%s\n", 4 * level, level, string); \
 | 
						|
	}
 | 
						|
#endif
 | 
						|
 | 
						|
#define BROKE()                                    \
 | 
						|
	{                                              \
 | 
						|
		assert(origcp != startupcode || !paniced); \
 | 
						|
		DEBUG("BROKE");                            \
 | 
						|
		totalcost = INFINITY;                      \
 | 
						|
		goto doreturn;                             \
 | 
						|
	}
 | 
						|
#define CHKCOST()                   \
 | 
						|
	{                               \
 | 
						|
		if (totalcost >= costlimit) \
 | 
						|
			BROKE();                \
 | 
						|
	}
 | 
						|
 | 
						|
#ifdef TABLEDEBUG
 | 
						|
int tablelines[MAXTDBUG];
 | 
						|
int ntableline;
 | 
						|
int set_fd, set_size;
 | 
						|
short* set_val;
 | 
						|
char* set_flag;
 | 
						|
#endif
 | 
						|
 | 
						|
unsigned codegen(byte* codep, int ply, int toplevel, unsigned costlimit, int forced)
 | 
						|
{
 | 
						|
#ifndef NDEBUG
 | 
						|
	byte* origcp = codep;
 | 
						|
	static int level = 0;
 | 
						|
#endif
 | 
						|
	unsigned totalcost = 0;
 | 
						|
	int inscoerc = 0;
 | 
						|
	int procarg[MAXPROCARG + 1] = {};
 | 
						|
#ifdef ALLOW_NEXTEM
 | 
						|
	static int paniced;
 | 
						|
	char* savebp = 0;
 | 
						|
#endif
 | 
						|
	state_t state;
 | 
						|
#define SAVEST savestatus(&state)
 | 
						|
#define RESTST restorestatus(&state)
 | 
						|
#define FREEST /* nothing */
 | 
						|
#ifdef TABLEDEBUG
 | 
						|
	extern char* tablename;
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef NDEBUG
 | 
						|
	assert(costlimit <= INFINITY);
 | 
						|
	level++;
 | 
						|
	DEBUG("Entering codegen");
 | 
						|
	if (Debug > 1)
 | 
						|
		fprintf(stderr, "toplevel = %d\n", toplevel);
 | 
						|
#endif
 | 
						|
	for (;;)
 | 
						|
	{
 | 
						|
		switch ((*codep++) & 037)
 | 
						|
		{
 | 
						|
			default:
 | 
						|
				assert(FALSE);
 | 
						|
/* NOTREACHED */
 | 
						|
#ifdef TABLEDEBUG
 | 
						|
			case DO_DLINE:
 | 
						|
			{
 | 
						|
				int n;
 | 
						|
 | 
						|
				getint(n, codep);
 | 
						|
				tablelines[ntableline++] = n;
 | 
						|
				if (ntableline >= MAXTDBUG)
 | 
						|
					ntableline -= MAXTDBUG;
 | 
						|
				if (set_fd)
 | 
						|
					set_val[n >> 4] &= ~(1 << (n & 017));
 | 
						|
#ifndef NDEBUG
 | 
						|
				if (Debug)
 | 
						|
					fprintf(stderr, "code from \"%s\", line %d\n", tablename, n);
 | 
						|
#endif
 | 
						|
				break;
 | 
						|
			}
 | 
						|
#endif
 | 
						|
			case DO_NEXTEM:
 | 
						|
			{
 | 
						|
				byte* bp;
 | 
						|
				int n;
 | 
						|
				unsigned mindistance, dist;
 | 
						|
				int i;
 | 
						|
				int cindex;
 | 
						|
				int npos, pos[MAXRULE];
 | 
						|
				unsigned mincost, t;
 | 
						|
 | 
						|
				DEBUG("NEXTEM");
 | 
						|
				tokpatlen = 0;
 | 
						|
				nallreg = 0;
 | 
						|
				if (toplevel)
 | 
						|
				{
 | 
						|
					garbage_collect();
 | 
						|
					totalcost = 0;
 | 
						|
				}
 | 
						|
				else
 | 
						|
				{
 | 
						|
					if (--ply <= 0)
 | 
						|
						goto doreturn;
 | 
						|
				}
 | 
						|
				if (stackheight > MAXFSTACK - 7)
 | 
						|
				{
 | 
						|
#ifndef NDEBUG
 | 
						|
					if (Debug)
 | 
						|
						fprintf(stderr, "Fakestack overflow threatens(%d), action ...\n", stackheight);
 | 
						|
#endif
 | 
						|
					totalcost += stackupto(&fakestack[6], ply, toplevel);
 | 
						|
				}
 | 
						|
#ifndef ALLOW_NEXTEM
 | 
						|
				bp = nextem(toplevel);
 | 
						|
#else
 | 
						|
				if (toplevel)
 | 
						|
					paniced = 0;
 | 
						|
				savebp = nextem(toplevel);
 | 
						|
			panic:
 | 
						|
				if (toplevel)
 | 
						|
					totalcost = 0;
 | 
						|
				bp = savebp;
 | 
						|
#endif
 | 
						|
				if (bp == 0)
 | 
						|
				{
 | 
						|
					/*
 | 
						|
		 * No pattern found, can be pseudo or error
 | 
						|
		 * in table.
 | 
						|
		 */
 | 
						|
					if (toplevel)
 | 
						|
					{
 | 
						|
						codep--;
 | 
						|
						DEBUG("pseudo");
 | 
						|
						dopseudo();
 | 
						|
					}
 | 
						|
					else
 | 
						|
						goto doreturn;
 | 
						|
				}
 | 
						|
				else
 | 
						|
				{
 | 
						|
#ifndef NDEBUG
 | 
						|
					chkregs();
 | 
						|
#endif
 | 
						|
					if (!toplevel)
 | 
						|
					{
 | 
						|
						ply -= emp - saveemp + 1;
 | 
						|
						if (ply <= 0)
 | 
						|
							ply = 1;
 | 
						|
					}
 | 
						|
					n = *bp++;
 | 
						|
					if (n == 0)
 | 
						|
					{ /* "procedure" */
 | 
						|
						int j, nargs;
 | 
						|
						getint(i, bp);
 | 
						|
						getint(nargs, bp);
 | 
						|
						assert(nargs <= MAXPROCARG);
 | 
						|
						for (j = 0; j < nargs; j++)
 | 
						|
						{
 | 
						|
							getint(procarg[j], bp);
 | 
						|
						}
 | 
						|
						bp = &pattern[i];
 | 
						|
						n = *bp++;
 | 
						|
						DEBUG("PROC_CALL");
 | 
						|
					}
 | 
						|
					assert(n > 0 && n <= MAXRULE);
 | 
						|
					if (n > 1)
 | 
						|
					{
 | 
						|
						mindistance = MAXINT;
 | 
						|
						npos = 0;
 | 
						|
						for (i = 0; i < n; i++)
 | 
						|
						{
 | 
						|
							getint(cindex, bp);
 | 
						|
							dist = distance(cindex);
 | 
						|
#ifndef NDEBUG
 | 
						|
							if (Debug)
 | 
						|
								fprintf(stderr, "distance of pos %d is %u\n", i, dist);
 | 
						|
#endif
 | 
						|
							if (dist <= mindistance
 | 
						|
#ifdef ALLOW_NEXTEM
 | 
						|
							    || paniced
 | 
						|
#endif
 | 
						|
							    )
 | 
						|
							{
 | 
						|
								if (dist < mindistance)
 | 
						|
								{
 | 
						|
									if (dist == 0)
 | 
						|
										goto gotit;
 | 
						|
									npos = 0;
 | 
						|
									mindistance = dist;
 | 
						|
								}
 | 
						|
#ifdef ALLOW_NEXTEM
 | 
						|
								if (dist < MAXINT)
 | 
						|
#endif
 | 
						|
									pos[npos++] = cindex;
 | 
						|
							}
 | 
						|
						}
 | 
						|
						assert(mindistance < MAXINT);
 | 
						|
						if (npos > 1)
 | 
						|
						{
 | 
						|
							/*
 | 
						|
				 * More than 1 tokenpattern is a candidate.
 | 
						|
				 * Decision has to be made by lookahead.
 | 
						|
				 */
 | 
						|
							SAVEST;
 | 
						|
							mincost = costlimit - totalcost + 1;
 | 
						|
							assert(mincost <= INFINITY);
 | 
						|
							for (i = 0; i < npos; i++)
 | 
						|
							{
 | 
						|
								t = codegen(&coderules[pos[i]], ply, FALSE,
 | 
						|
								    costlimit < MAXINT ? mincost : MAXINT, 0);
 | 
						|
#ifndef NDEBUG
 | 
						|
								if (Debug)
 | 
						|
									fprintf(stderr, "mincost %u,cost %u,pos %d\n", mincost, t, i);
 | 
						|
#endif
 | 
						|
								if (t < mincost)
 | 
						|
								{
 | 
						|
									mincost = t;
 | 
						|
									cindex = pos[i];
 | 
						|
								}
 | 
						|
								RESTST;
 | 
						|
							}
 | 
						|
							FREEST;
 | 
						|
							if (totalcost + mincost > costlimit)
 | 
						|
							{
 | 
						|
								BROKE();
 | 
						|
							}
 | 
						|
						}
 | 
						|
						else
 | 
						|
						{
 | 
						|
							cindex = pos[0];
 | 
						|
						}
 | 
						|
					}
 | 
						|
					else
 | 
						|
					{
 | 
						|
						getint(cindex, bp);
 | 
						|
					}
 | 
						|
 | 
						|
				gotit:
 | 
						|
					/*
 | 
						|
		 * Now cindex contains the code-index of the best candidate
 | 
						|
		 * so proceed to use it.
 | 
						|
		 */
 | 
						|
					codep = &coderules[cindex];
 | 
						|
				}
 | 
						|
				break;
 | 
						|
			}
 | 
						|
			case DO_COERC:
 | 
						|
			{
 | 
						|
				DEBUG("COERC");
 | 
						|
				tokpatlen = 1;
 | 
						|
				inscoerc = 1;
 | 
						|
				break;
 | 
						|
			}
 | 
						|
			case DO_XXMATCH:
 | 
						|
				DEBUG("XXMATCH");
 | 
						|
			case DO_XMATCH:
 | 
						|
			{
 | 
						|
				int i, temp;
 | 
						|
 | 
						|
				DEBUG("XMATCH");
 | 
						|
				tokpatlen = (codep[-1] >> 5) & 07;
 | 
						|
				for (i = 0; i < tokpatlen; i++)
 | 
						|
					getint(temp, codep);
 | 
						|
				break; /* match already checked by distance() */
 | 
						|
			}
 | 
						|
			case DO_MATCH:
 | 
						|
			{
 | 
						|
				int i, j;
 | 
						|
				unsigned mincost, t;
 | 
						|
				token_p tp;
 | 
						|
				int size, lsize;
 | 
						|
				int tokexp[MAXPATLEN];
 | 
						|
				int nregneeded;
 | 
						|
				token_p regtp[MAXCREG];
 | 
						|
				c3_p regcp[MAXCREG];
 | 
						|
				rl_p regls[MAXCREG];
 | 
						|
				c3_p cp, findcoerc();
 | 
						|
#ifdef MAXSPLIT
 | 
						|
				int sret;
 | 
						|
#endif
 | 
						|
				int stackpad = 0;
 | 
						|
				struct perm *tup, *ntup, *besttup, *tuples();
 | 
						|
 | 
						|
				DEBUG("MATCH");
 | 
						|
				tokpatlen = (codep[-1] >> 5) & 07;
 | 
						|
				for (i = 0; i < tokpatlen; i++)
 | 
						|
					getint(tokexp[i], codep);
 | 
						|
				tp = &fakestack[stackheight - 1];
 | 
						|
				i = 0;
 | 
						|
				while (i < tokpatlen && tp >= fakestack)
 | 
						|
				{
 | 
						|
					size = tsize(tp);
 | 
						|
					while (i < tokpatlen && (lsize = ssize(tokexp[i])) <= size)
 | 
						|
					{
 | 
						|
						size -= lsize;
 | 
						|
						i++;
 | 
						|
					}
 | 
						|
					if (i < tokpatlen && size != 0)
 | 
						|
					{
 | 
						|
						totalcost += stackupto(tp, ply, toplevel);
 | 
						|
						CHKCOST();
 | 
						|
						break;
 | 
						|
					}
 | 
						|
					tp--;
 | 
						|
				}
 | 
						|
				tp = &fakestack[stackheight - 1];
 | 
						|
				i = 0;
 | 
						|
				while (i < tokpatlen && tp >= fakestack)
 | 
						|
				{
 | 
						|
					size = tsize(tp);
 | 
						|
					lsize = ssize(tokexp[i]);
 | 
						|
					if (size != lsize)
 | 
						|
					{ /* find coercion */
 | 
						|
#ifdef MAXSPLIT
 | 
						|
						sret = split(tp, &tokexp[i], ply, toplevel);
 | 
						|
						if (sret == 0)
 | 
						|
						{
 | 
						|
#endif /* MAXSPLIT */
 | 
						|
							totalcost += stackupto(tp, ply, toplevel);
 | 
						|
							CHKCOST();
 | 
						|
							break;
 | 
						|
#ifdef MAXSPLIT
 | 
						|
						}
 | 
						|
						i += sret;
 | 
						|
#endif /* MAXSPLIT */
 | 
						|
					}
 | 
						|
					else
 | 
						|
						i += 1;
 | 
						|
					tp--;
 | 
						|
				}
 | 
						|
			nextmatch:
 | 
						|
				tp = &fakestack[stackheight - 1];
 | 
						|
				i = 0;
 | 
						|
				nregneeded = 0;
 | 
						|
				while (i < tokpatlen && tp >= fakestack)
 | 
						|
				{
 | 
						|
					if (!match(tp, &machsets[tokexp[i]], 0))
 | 
						|
					{
 | 
						|
						cp = findcoerc(tp, &machsets[tokexp[i]]);
 | 
						|
#ifndef NDEBUG
 | 
						|
						if (Debug > 1)
 | 
						|
							fprintf(stderr, "findcoerc returns 0x%x at position %d\n", (unsigned)cp, i);
 | 
						|
#endif
 | 
						|
						if (cp == 0)
 | 
						|
						{
 | 
						|
							for (j = 0; j < nregneeded; j++)
 | 
						|
								regtp[j] -= (tp - fakestack + 1);
 | 
						|
							totalcost += stackupto(tp, ply, toplevel);
 | 
						|
							CHKCOST();
 | 
						|
							break;
 | 
						|
						}
 | 
						|
						else
 | 
						|
						{
 | 
						|
							if (cp->c3_prop < 0)
 | 
						|
							{
 | 
						|
								totalcost += docoerc(tp, cp, ply, toplevel, 0);
 | 
						|
								CHKCOST();
 | 
						|
							}
 | 
						|
							else
 | 
						|
							{
 | 
						|
#ifndef NDEBUG
 | 
						|
								if (Debug > 1)
 | 
						|
									fprintf(stderr, "Register of type %d needed, remembering...\n", cp->c3_prop);
 | 
						|
#endif
 | 
						|
								assert(nregneeded < MAXCREG);
 | 
						|
								regtp[nregneeded] = tp;
 | 
						|
								regcp[nregneeded] = cp;
 | 
						|
								regls[nregneeded] = curreglist;
 | 
						|
								nregneeded++;
 | 
						|
							}
 | 
						|
						}
 | 
						|
					}
 | 
						|
					i++;
 | 
						|
					tp--;
 | 
						|
				}
 | 
						|
				if (tokpatlen > stackheight)
 | 
						|
				{
 | 
						|
#ifndef NDEBUG
 | 
						|
					if (Debug > 1)
 | 
						|
						fprintf(stderr, "Pattern too long, %d with only %d items on stack\n",
 | 
						|
						    tokpatlen, stackheight);
 | 
						|
#endif
 | 
						|
					stackpad = tokpatlen - stackheight;
 | 
						|
					for (j = stackheight - 1; j >= 0; j--)
 | 
						|
						fakestack[j + stackpad] = fakestack[j];
 | 
						|
					for (j = 0; j < stackpad; j++)
 | 
						|
						fakestack[j].t_token = 0;
 | 
						|
					stackheight += stackpad;
 | 
						|
					for (j = 0; j < nregneeded; j++)
 | 
						|
						regtp[j] += stackpad;
 | 
						|
					for (tp = &fakestack[stackpad - 1]; i < tokpatlen && tp >= fakestack; i++, tp--)
 | 
						|
					{
 | 
						|
						cp = findcoerc((token_p)0, &machsets[tokexp[i]]);
 | 
						|
						if (cp == 0)
 | 
						|
						{
 | 
						|
							for (j = 0; j < nregneeded; j++)
 | 
						|
								myfree((string)(regls[j]));
 | 
						|
#ifndef ALLOW_NEXTEM
 | 
						|
							assert(!toplevel);
 | 
						|
							BROKE();
 | 
						|
#else
 | 
						|
							assert(!(toplevel && paniced));
 | 
						|
							if (paniced)
 | 
						|
								goto normalfailed;
 | 
						|
							totalcost = INFINITY;
 | 
						|
							for (i = 0; i < stackheight - stackpad; i++)
 | 
						|
								fakestack[i] = fakestack[i + stackpad];
 | 
						|
							stackheight -= stackpad;
 | 
						|
							goto doreturn;
 | 
						|
#endif
 | 
						|
						}
 | 
						|
						if (cp->c3_prop < 0)
 | 
						|
						{
 | 
						|
							totalcost += docoerc(tp, cp, ply, toplevel, 0);
 | 
						|
							CHKCOST();
 | 
						|
						}
 | 
						|
						else
 | 
						|
						{
 | 
						|
							assert(nregneeded < MAXCREG);
 | 
						|
							regtp[nregneeded] = tp;
 | 
						|
							regcp[nregneeded] = cp;
 | 
						|
							regls[nregneeded] = curreglist;
 | 
						|
							nregneeded++;
 | 
						|
						}
 | 
						|
					}
 | 
						|
				}
 | 
						|
				else
 | 
						|
					stackpad = 0;
 | 
						|
				assert(i == tokpatlen);
 | 
						|
				if (nregneeded == 0)
 | 
						|
					break;
 | 
						|
				SAVEST;
 | 
						|
				mincost = costlimit - totalcost + 1;
 | 
						|
				tup = tuples(regls, nregneeded);
 | 
						|
				besttup = 0;
 | 
						|
				for (; tup != 0; tup = ntup)
 | 
						|
				{
 | 
						|
#ifndef NDEBUG
 | 
						|
					if (Debug > 1)
 | 
						|
					{
 | 
						|
						fprintf(stderr, "Next tuple %d,%d,%d,%d\n",
 | 
						|
						    tup->p_rar[0],
 | 
						|
						    tup->p_rar[1],
 | 
						|
						    tup->p_rar[2],
 | 
						|
						    tup->p_rar[3]);
 | 
						|
						fprintf(stderr, "totalcost = %u, costlimit = %u, mincost = %u\n",
 | 
						|
						    totalcost, costlimit, mincost);
 | 
						|
					}
 | 
						|
#endif
 | 
						|
					ntup = tup->p_next;
 | 
						|
					for (i = 0, t = 0; i < nregneeded && t < mincost; i++)
 | 
						|
						t += docoerc(regtp[i], regcp[i], ply, FALSE, tup->p_rar[i]);
 | 
						|
#ifndef NDEBUG
 | 
						|
					if (Debug > 1)
 | 
						|
						fprintf(stderr, "cost after coercions: %u\n", t);
 | 
						|
#endif
 | 
						|
					if (t < mincost && tokpatlen <= stackheight)
 | 
						|
					{
 | 
						|
#ifndef NDEBUG
 | 
						|
						if (Debug > 2)
 | 
						|
							fprintf(stderr, "Continuing match after coercions\n");
 | 
						|
#endif
 | 
						|
						t += codegen(codep, ply, FALSE, mincost < MAXINT ? mincost - t : MAXINT, 0);
 | 
						|
					}
 | 
						|
					if (t < mincost && tokpatlen <= stackheight)
 | 
						|
					{
 | 
						|
						mincost = t;
 | 
						|
						besttup = tup;
 | 
						|
					}
 | 
						|
					else
 | 
						|
						myfree((string)tup);
 | 
						|
					RESTST;
 | 
						|
				}
 | 
						|
				FREEST;
 | 
						|
				for (i = 0; i < nregneeded; i++)
 | 
						|
					myfree((string)(regls[i]));
 | 
						|
				if (totalcost + mincost > costlimit)
 | 
						|
				{
 | 
						|
					if (besttup)
 | 
						|
						myfree((string)besttup);
 | 
						|
				normalfailed:
 | 
						|
					if (stackpad != tokpatlen)
 | 
						|
					{
 | 
						|
						if (stackpad)
 | 
						|
						{
 | 
						|
							for (i = 0; i < stackheight - stackpad; i++)
 | 
						|
								fakestack[i] = fakestack[i + stackpad];
 | 
						|
							stackheight -= stackpad;
 | 
						|
							if (costlimit < MAXINT)
 | 
						|
								BROKE();
 | 
						|
							totalcost += stackupto(&fakestack[stackheight - 1], ply, toplevel);
 | 
						|
						}
 | 
						|
						else
 | 
						|
							totalcost += stackupto(fakestack, ply, toplevel);
 | 
						|
						CHKCOST();
 | 
						|
						goto nextmatch;
 | 
						|
					}
 | 
						|
					totalcost += mincost;
 | 
						|
					for (i = 0; i < stackheight - stackpad; i++)
 | 
						|
						fakestack[i] = fakestack[i + stackpad];
 | 
						|
					stackheight -= stackpad;
 | 
						|
					BROKE();
 | 
						|
				}
 | 
						|
				for (i = 0; i < nregneeded; i++)
 | 
						|
					totalcost += docoerc(regtp[i], regcp[i], ply, toplevel, besttup->p_rar[i]);
 | 
						|
				assert(totalcost <= costlimit);
 | 
						|
				myfree((string)besttup);
 | 
						|
				break;
 | 
						|
			}
 | 
						|
			case DO_TOSTACK:
 | 
						|
			case DO_REMOVE:
 | 
						|
			{
 | 
						|
				int texpno, nodeno;
 | 
						|
				token_p tp;
 | 
						|
				struct reginfo* rp;
 | 
						|
				int doremove = (codep[-1] & 037) == DO_REMOVE;
 | 
						|
				extern int allsetno;
 | 
						|
 | 
						|
				DEBUG(doremove ? "REMOVE" : "TOSTACK");
 | 
						|
				if (codep[-1] & 32)
 | 
						|
				{
 | 
						|
					getint(texpno, codep);
 | 
						|
					getint(nodeno, codep);
 | 
						|
				}
 | 
						|
				else
 | 
						|
				{
 | 
						|
					getint(texpno, codep);
 | 
						|
					nodeno = 0;
 | 
						|
				}
 | 
						|
				if (texpno == allsetno)
 | 
						|
				{
 | 
						|
					totalcost += stackupto(&fakestack[stackheight - tokpatlen - 1], ply, toplevel);
 | 
						|
					CHKCOST();
 | 
						|
					if (doremove)
 | 
						|
						for (rp = machregs; rp < machregs + NREGS; rp++)
 | 
						|
							rp->r_contents.t_token = 0;
 | 
						|
					break;
 | 
						|
				}
 | 
						|
				for (tp = &fakestack[stackheight - tokpatlen - 1]; tp >= &fakestack[0]; tp--)
 | 
						|
					if (match(tp, &machsets[texpno], nodeno))
 | 
						|
					{
 | 
						|
						/* investigate possible coercion to register */
 | 
						|
						totalcost += stackupto(tp, ply, toplevel);
 | 
						|
						CHKCOST();
 | 
						|
						break;
 | 
						|
					}
 | 
						|
				if (doremove)
 | 
						|
					for (rp = machregs; rp < machregs + NREGS; rp++)
 | 
						|
					{
 | 
						|
						if (rp->r_contents.t_token != 0 && match(&rp->r_contents, &machsets[texpno], nodeno))
 | 
						|
						{
 | 
						|
#ifndef NDEBUG
 | 
						|
							if (Debug > 1)
 | 
						|
								fprintf(stderr, "killing reg %ld (%s)\n", (long)(rp - machregs), rp->r_repr ? codestrings[rp->r_repr] : "cc");
 | 
						|
#endif
 | 
						|
							rp->r_contents.t_token = 0;
 | 
						|
						}
 | 
						|
					}
 | 
						|
				break;
 | 
						|
			}
 | 
						|
			case DO_KILLREG:
 | 
						|
			case DO_RREMOVE:
 | 
						|
			{ /* register remove */
 | 
						|
				int i, nodeno;
 | 
						|
				token_p tp;
 | 
						|
				tkdef_p tdp;
 | 
						|
				result_t result;
 | 
						|
				int dokill = (codep[-1] & 037) == DO_KILLREG;
 | 
						|
 | 
						|
				DEBUG(dokill ? "KILLREG" : "RREMOVE");
 | 
						|
				getint(nodeno, codep);
 | 
						|
				compute(&enodes[nodeno], &result);
 | 
						|
				if (result.e_typ != EV_REG)
 | 
						|
					break;
 | 
						|
				if (in_stack(result.e_v.e_reg))
 | 
						|
					BROKE(); /* Check aside-stack */
 | 
						|
				if (dokill)
 | 
						|
				{
 | 
						|
					/* kill register, and kill condition codes if they are set to
 | 
						|
		   this register
 | 
						|
		*/
 | 
						|
					machregs[result.e_v.e_reg].r_contents.t_token = 0;
 | 
						|
					if (machregs[0].r_contents.t_token == -1 && machregs[0].r_contents.t_att[0].ar == result.e_v.e_reg)
 | 
						|
					{
 | 
						|
						machregs[0].r_contents.t_token = 0;
 | 
						|
					}
 | 
						|
				}
 | 
						|
				for (tp = &fakestack[stackheight - tokpatlen - 1]; tp >= &fakestack[0]; tp--)
 | 
						|
					if (tp->t_token == -1)
 | 
						|
					{
 | 
						|
						if (tp->t_att[0].ar == result.e_v.e_reg)
 | 
						|
							goto gotone;
 | 
						|
					}
 | 
						|
					else
 | 
						|
					{
 | 
						|
						tdp = &tokens[tp->t_token];
 | 
						|
						for (i = 0; i < TOKENSIZE; i++)
 | 
						|
							if (tdp->t_type[i] == EV_REG && tp->t_att[i].ar == result.e_v.e_reg)
 | 
						|
								goto gotone;
 | 
						|
					}
 | 
						|
				break;
 | 
						|
			gotone:
 | 
						|
				/* investigate possible coercion to register */
 | 
						|
				totalcost += stackupto(tp, ply, toplevel);
 | 
						|
				CHKCOST();
 | 
						|
				break;
 | 
						|
			}
 | 
						|
			case DO_DEALLOCATE:
 | 
						|
			{
 | 
						|
				int i;
 | 
						|
				tkdef_p tdp;
 | 
						|
				int tinstno;
 | 
						|
				token_t token;
 | 
						|
 | 
						|
				DEBUG("DEALLOCATE");
 | 
						|
				getint(tinstno, codep);
 | 
						|
				instance(tinstno, &token);
 | 
						|
				if (token.t_token == -1)
 | 
						|
					chrefcount(token.t_att[0].ar, -1, TRUE);
 | 
						|
				else
 | 
						|
				{
 | 
						|
					tdp = &tokens[token.t_token];
 | 
						|
					for (i = 0; i < TOKENSIZE; i++)
 | 
						|
						if (tdp->t_type[i] == EV_REG)
 | 
						|
							chrefcount(token.t_att[i].ar, -1, TRUE);
 | 
						|
				}
 | 
						|
				break;
 | 
						|
			}
 | 
						|
			case DO_REALLOCATE:
 | 
						|
			{
 | 
						|
				struct reginfo* rp;
 | 
						|
 | 
						|
				DEBUG("REALLOCATE");
 | 
						|
				for (rp = machregs + 1; rp < machregs + NREGS; rp++)
 | 
						|
					if (rp->r_tcount)
 | 
						|
					{
 | 
						|
						rp->r_refcount -= rp->r_tcount;
 | 
						|
						rp->r_tcount = 0;
 | 
						|
					}
 | 
						|
				break;
 | 
						|
			}
 | 
						|
			case DO_ALLOCATE:
 | 
						|
			{
 | 
						|
				int i, j;
 | 
						|
				int tinstno;
 | 
						|
				int npos, npos2, pos[NREGS], pos2[NREGS];
 | 
						|
				unsigned mincost, t;
 | 
						|
				struct reginfo *rp, **rpp;
 | 
						|
				token_t token, token2;
 | 
						|
				int propno;
 | 
						|
				int exactmatch;
 | 
						|
				int decision;
 | 
						|
 | 
						|
				if (codep[-1] & 32)
 | 
						|
				{
 | 
						|
					getint(propno, codep);
 | 
						|
					getint(tinstno, codep);
 | 
						|
					DEBUG("ALLOCATE,INIT");
 | 
						|
				}
 | 
						|
				else
 | 
						|
				{
 | 
						|
					getint(propno, codep);
 | 
						|
					tinstno = 0;
 | 
						|
					DEBUG("ALLOCATE,EMPTY");
 | 
						|
				}
 | 
						|
				instance(tinstno, &token);
 | 
						|
				if (!forced)
 | 
						|
				{
 | 
						|
					do
 | 
						|
					{
 | 
						|
						npos = exactmatch = 0;
 | 
						|
						for (rpp = reglist[propno]; rp = *rpp; rpp++)
 | 
						|
							if (getrefcount((int)(rp - machregs), FALSE) == 0)
 | 
						|
							{
 | 
						|
								pos[npos++] = rp - machregs;
 | 
						|
								if (eqtoken(&rp->r_contents, &token))
 | 
						|
									pos2[exactmatch++] = rp - machregs;
 | 
						|
							}
 | 
						|
						/*
 | 
						|
			 * Now pos[] contains all free registers with desired
 | 
						|
			 * property. If none then some stacking has to take place.
 | 
						|
			 */
 | 
						|
						if (npos == 0)
 | 
						|
						{
 | 
						|
							if (stackheight <= tokpatlen)
 | 
						|
							{
 | 
						|
								if (!toplevel)
 | 
						|
								{
 | 
						|
									BROKE();
 | 
						|
								}
 | 
						|
								else
 | 
						|
								{
 | 
						|
									if (paniced)
 | 
						|
										fatal("No regs available");
 | 
						|
									totalcost += stackupto(&fakestack[0], ply, toplevel);
 | 
						|
									goto panic;
 | 
						|
								}
 | 
						|
							}
 | 
						|
							totalcost += stackupto(&fakestack[0], ply, toplevel);
 | 
						|
							CHKCOST();
 | 
						|
						}
 | 
						|
					} while (npos == 0);
 | 
						|
 | 
						|
					if (!exactmatch && tinstno != 0)
 | 
						|
					{
 | 
						|
						/*
 | 
						|
			 * No exact match, but we were looking for a particular
 | 
						|
			 * token. Now try to find registers of which no
 | 
						|
			 * known contents is available (the others might still
 | 
						|
			 * be useful).
 | 
						|
			 */
 | 
						|
						for (i = 0; i < npos; i++)
 | 
						|
							if (machregs[pos[i]].r_contents.t_token == 0)
 | 
						|
							{
 | 
						|
								pos2[exactmatch++] = pos[i];
 | 
						|
							}
 | 
						|
					}
 | 
						|
 | 
						|
					if (!exactmatch)
 | 
						|
					{
 | 
						|
						npos2 = npos;
 | 
						|
						for (i = 0; i < npos; i++)
 | 
						|
							pos2[i] = pos[i];
 | 
						|
					}
 | 
						|
					else
 | 
						|
					{
 | 
						|
						/*
 | 
						|
			 * Now we are reducing the number of possible registers.
 | 
						|
			 * We take only one equally likely register out of every
 | 
						|
			 * equivalence class as given by set of properties.
 | 
						|
			 */
 | 
						|
						npos2 = 0;
 | 
						|
						for (i = 0; i < exactmatch; i++)
 | 
						|
						{
 | 
						|
							pos2[npos2++] = pos2[i];
 | 
						|
							for (j = 0; j < npos2 - 1; j++)
 | 
						|
								if (eqregclass(pos2[j], pos2[i]))
 | 
						|
								{
 | 
						|
									npos2--;
 | 
						|
									break;
 | 
						|
								}
 | 
						|
						}
 | 
						|
					}
 | 
						|
					/*
 | 
						|
		 * Now pos2[] contains all possibilities to try, if more than
 | 
						|
		 * one, lookahead is necessary.
 | 
						|
		 */
 | 
						|
					token2.t_token = -1;
 | 
						|
					for (i = 1; i < TOKENSIZE; i++)
 | 
						|
						token2.t_att[i].aw = 0;
 | 
						|
					decision = pos2[0];
 | 
						|
					if (npos2 != 1)
 | 
						|
					{
 | 
						|
						SAVEST;
 | 
						|
						mincost = costlimit - totalcost + 1;
 | 
						|
						for (j = 0; j < npos2; j++)
 | 
						|
						{
 | 
						|
							chrefcount(pos2[j], 1, FALSE);
 | 
						|
							token2.t_att[0].ar = pos2[j];
 | 
						|
							allreg[nallreg++] = pos2[j];
 | 
						|
							if (token.t_token != 0)
 | 
						|
								t = move(&token, &token2, ply, FALSE, mincost);
 | 
						|
							else
 | 
						|
							{
 | 
						|
								t = 0;
 | 
						|
								erasereg(pos2[j]);
 | 
						|
							}
 | 
						|
							if (t < mincost)
 | 
						|
								t += codegen(codep, ply, FALSE, mincost < MAXINT ? mincost - t : MAXINT, 0);
 | 
						|
							if (t < mincost)
 | 
						|
							{
 | 
						|
								mincost = t;
 | 
						|
								decision = pos2[j];
 | 
						|
							}
 | 
						|
							RESTST;
 | 
						|
						}
 | 
						|
						FREEST;
 | 
						|
						if (totalcost + mincost > costlimit)
 | 
						|
							BROKE();
 | 
						|
					}
 | 
						|
				}
 | 
						|
				else
 | 
						|
				{
 | 
						|
					decision = forced;
 | 
						|
					if (getrefcount(decision, FALSE) != 0)
 | 
						|
						BROKE();
 | 
						|
					token2.t_token = -1;
 | 
						|
				}
 | 
						|
				chrefcount(decision, 1, FALSE);
 | 
						|
				token2.t_att[0].ar = decision;
 | 
						|
				if (token.t_token != 0)
 | 
						|
				{
 | 
						|
					totalcost += move(&token, &token2, ply, toplevel, MAXINT);
 | 
						|
					CHKCOST();
 | 
						|
				}
 | 
						|
				else
 | 
						|
					erasereg(decision);
 | 
						|
				allreg[nallreg++] = decision;
 | 
						|
				break;
 | 
						|
			}
 | 
						|
			case DO_INSTR:
 | 
						|
			{
 | 
						|
				int i, n;
 | 
						|
				int tinstno;
 | 
						|
				token_t token;
 | 
						|
				int stringno;
 | 
						|
 | 
						|
				DEBUG("INSTR");
 | 
						|
				n = ((codep[-1] >> 5) & 07);
 | 
						|
				getint(stringno, codep);
 | 
						|
				if (toplevel)
 | 
						|
				{
 | 
						|
					swtxt();
 | 
						|
					if (stringno > 10000)
 | 
						|
					{
 | 
						|
						assert(stringno < 10001 + MAXPROCARG);
 | 
						|
						genstr(procarg[stringno - 10001]);
 | 
						|
					}
 | 
						|
					else
 | 
						|
						genstr(stringno);
 | 
						|
				}
 | 
						|
				for (i = 0; i < n; i++)
 | 
						|
				{
 | 
						|
					getint(tinstno, codep);
 | 
						|
					instance(tinstno, &token);
 | 
						|
					if (toplevel)
 | 
						|
						prtoken(&token, i == 0 ? ' ' : ',');
 | 
						|
					if (token.t_token > 0)
 | 
						|
						totalcost += tokens[token.t_token].t_cost.ct_space;
 | 
						|
				}
 | 
						|
				if (toplevel)
 | 
						|
					gennl();
 | 
						|
				CHKCOST();
 | 
						|
				break;
 | 
						|
			}
 | 
						|
			case DO_MOVE:
 | 
						|
			{
 | 
						|
				int tinstno;
 | 
						|
				token_t token, token2;
 | 
						|
 | 
						|
				DEBUG("MOVE");
 | 
						|
				getint(tinstno, codep);
 | 
						|
				instance(tinstno, &token);
 | 
						|
				getint(tinstno, codep);
 | 
						|
				instance(tinstno, &token2);
 | 
						|
				totalcost += move(&token, &token2, ply, toplevel, costlimit - totalcost + 1);
 | 
						|
				CHKCOST();
 | 
						|
				break;
 | 
						|
			}
 | 
						|
			case DO_TEST:
 | 
						|
			{
 | 
						|
				int tinstno;
 | 
						|
				token_t token;
 | 
						|
 | 
						|
				DEBUG("TEST");
 | 
						|
				getint(tinstno, codep);
 | 
						|
				instance(tinstno, &token);
 | 
						|
				totalcost += test(&token, ply, toplevel, costlimit - totalcost + 1);
 | 
						|
				CHKCOST();
 | 
						|
				break;
 | 
						|
			}
 | 
						|
			case DO_SETCC:
 | 
						|
			{
 | 
						|
				int tinstno;
 | 
						|
				token_t token;
 | 
						|
 | 
						|
				DEBUG("SETCC");
 | 
						|
				getint(tinstno, codep);
 | 
						|
				instance(tinstno, &token);
 | 
						|
				setcc(&token);
 | 
						|
				break;
 | 
						|
			}
 | 
						|
			case DO_ERASE:
 | 
						|
			{
 | 
						|
				int nodeno;
 | 
						|
				result_t result;
 | 
						|
 | 
						|
				DEBUG("ERASE");
 | 
						|
				getint(nodeno, codep);
 | 
						|
				compute(&enodes[nodeno], &result);
 | 
						|
				assert(result.e_typ != EV_INT && result.e_typ != EV_ADDR);
 | 
						|
				if (result.e_typ == EV_REG)
 | 
						|
				{
 | 
						|
					int regno = result.e_v.e_reg;
 | 
						|
					erasereg(regno);
 | 
						|
				}
 | 
						|
				break;
 | 
						|
			}
 | 
						|
			case DO_TOKREPLACE:
 | 
						|
			{
 | 
						|
				int i;
 | 
						|
				int tinstno;
 | 
						|
				int repllen;
 | 
						|
				token_t reptoken[MAXREPLLEN];
 | 
						|
 | 
						|
				DEBUG("TOKREPLACE");
 | 
						|
				assert(stackheight >= tokpatlen);
 | 
						|
				repllen = (codep[-1] >> 5) & 07;
 | 
						|
#ifndef NDEBUG
 | 
						|
				if (Debug > 2)
 | 
						|
					fprintf(stderr, "Stackheight=%d, tokpatlen=%d, repllen=%d %s\n",
 | 
						|
					    stackheight, tokpatlen, repllen, inscoerc ? "(inscoerc)" : "");
 | 
						|
#endif
 | 
						|
				for (i = 0; i < repllen; i++)
 | 
						|
				{
 | 
						|
					getint(tinstno, codep);
 | 
						|
					instance(tinstno, &reptoken[i]);
 | 
						|
					tref(&reptoken[i], 1);
 | 
						|
				}
 | 
						|
				for (i = 0; i < tokpatlen; i++)
 | 
						|
				{
 | 
						|
					if (!inscoerc)
 | 
						|
						tref(&fakestack[stackheight - 1], -1);
 | 
						|
					stackheight--;
 | 
						|
				}
 | 
						|
				for (i = 0; i < repllen; i++)
 | 
						|
				{
 | 
						|
					assert(stackheight < MAXFSTACK);
 | 
						|
					fakestack[stackheight++] = reptoken[i];
 | 
						|
				}
 | 
						|
				for (i = 0; i < nallreg; i++)
 | 
						|
					chrefcount(allreg[i], -1, FALSE);
 | 
						|
				break;
 | 
						|
			}
 | 
						|
			case DO_EMREPLACE:
 | 
						|
			{
 | 
						|
				int i, j;
 | 
						|
				int nodeno;
 | 
						|
				result_t result[MAXEMREPLLEN];
 | 
						|
				int emrepllen, eminstr;
 | 
						|
 | 
						|
				DEBUG("EMREPLACE");
 | 
						|
				emrepllen = (codep[-1] >> 5) & 07;
 | 
						|
				j = emp - emlines;
 | 
						|
				if (emrepllen > j)
 | 
						|
				{
 | 
						|
					assert(nemlines + emrepllen - j < MAXEMLINES);
 | 
						|
					for (i = nemlines; i >= 0; i--)
 | 
						|
						emlines[i + emrepllen - j] = emlines[i];
 | 
						|
					nemlines += emrepllen - j;
 | 
						|
					emp += emrepllen - j;
 | 
						|
				}
 | 
						|
				emp -= emrepllen;
 | 
						|
				for (i = 0; i < emrepllen; i++)
 | 
						|
				{
 | 
						|
					getint(eminstr, codep);
 | 
						|
					getint(nodeno, codep);
 | 
						|
					emp[i].em_instr = eminstr;
 | 
						|
					compute(&enodes[nodeno], &result[i]);
 | 
						|
				}
 | 
						|
				for (i = 0; i < emrepllen; i++)
 | 
						|
				{
 | 
						|
					switch (result[i].e_typ)
 | 
						|
					{
 | 
						|
						default:
 | 
						|
							assert(FALSE);
 | 
						|
						case 0:
 | 
						|
							emp[i].em_optyp = OPNO;
 | 
						|
							emp[i].em_soper = 0;
 | 
						|
							break;
 | 
						|
						case EV_INT:
 | 
						|
							emp[i].em_optyp = OPINT;
 | 
						|
							emp[i].em_soper = tostring(result[i].e_v.e_con);
 | 
						|
							emp[i].em_u.em_ioper = result[i].e_v.e_con;
 | 
						|
							break;
 | 
						|
						case EV_ADDR:
 | 
						|
							emp[i].em_optyp = OPSYMBOL;
 | 
						|
							emp[i].em_soper = ad2str(result[i].e_v.e_addr);
 | 
						|
							break;
 | 
						|
					}
 | 
						|
				}
 | 
						|
				if (!toplevel)
 | 
						|
				{
 | 
						|
					ply += emrepllen;
 | 
						|
#ifndef NDEBUG
 | 
						|
					if (Debug > 4)
 | 
						|
						fprintf(stderr, "ply becomes %d\n", ply);
 | 
						|
#endif
 | 
						|
				}
 | 
						|
				break;
 | 
						|
			}
 | 
						|
			case DO_COST:
 | 
						|
			{
 | 
						|
				cost_t cost;
 | 
						|
 | 
						|
				DEBUG("COST");
 | 
						|
				getint(cost.ct_space, codep);
 | 
						|
				getint(cost.ct_time, codep);
 | 
						|
				totalcost += costcalc(cost);
 | 
						|
				CHKCOST();
 | 
						|
				break;
 | 
						|
			}
 | 
						|
#ifdef REGVARS
 | 
						|
			case DO_PRETURN:
 | 
						|
			{
 | 
						|
				if (toplevel)
 | 
						|
				{
 | 
						|
					swtxt();
 | 
						|
					regreturn(); /* in mach.c */
 | 
						|
				}
 | 
						|
				break;
 | 
						|
			}
 | 
						|
#endif
 | 
						|
			case DO_RETURN:
 | 
						|
				DEBUG("RETURN");
 | 
						|
				assert(origcp != startupcode);
 | 
						|
#ifndef NDEBUG
 | 
						|
				level--;
 | 
						|
#endif
 | 
						|
				return (totalcost);
 | 
						|
#ifdef USE_TES
 | 
						|
			case DO_LABDEF:
 | 
						|
			{
 | 
						|
				int index;
 | 
						|
 | 
						|
				DEBUG("LABDEF");
 | 
						|
				getint(index, codep);
 | 
						|
				if (toplevel)
 | 
						|
				{
 | 
						|
					swtxt();
 | 
						|
					printlabel(index);
 | 
						|
				}
 | 
						|
 | 
						|
				break;
 | 
						|
			}
 | 
						|
#endif
 | 
						|
		}
 | 
						|
	}
 | 
						|
doreturn:
 | 
						|
#ifdef ALLOW_NEXTEM
 | 
						|
	if (toplevel && totalcost == INFINITY && !paniced)
 | 
						|
	{
 | 
						|
		DEBUG("PANIC!");
 | 
						|
		totalcost += stackupto(&fakestack[stackheight - 1], ply, toplevel);
 | 
						|
#ifndef NDEBUG
 | 
						|
		if (Debug > 2)
 | 
						|
			fprintf(stderr, "Stackheight = %d\n", stackheight);
 | 
						|
#endif
 | 
						|
		paniced = 1;
 | 
						|
		tokpatlen = 0;
 | 
						|
		goto panic;
 | 
						|
	}
 | 
						|
#endif
 | 
						|
#ifndef NDEBUG
 | 
						|
	level--;
 | 
						|
#endif
 | 
						|
	return (totalcost);
 | 
						|
}
 | 
						|
 | 
						|
void readcodebytes(void)
 | 
						|
{
 | 
						|
#ifndef CODEINC
 | 
						|
	int fd;
 | 
						|
	extern int ncodebytes;
 | 
						|
 | 
						|
	if ((fd = open("code", 0)) < 0)
 | 
						|
	{
 | 
						|
		error("Can't open code");
 | 
						|
	}
 | 
						|
	if (read(fd, coderules, ncodebytes) != ncodebytes)
 | 
						|
	{
 | 
						|
		error("Short read from code");
 | 
						|
	}
 | 
						|
	close(fd);
 | 
						|
#endif /* CODEINC */
 | 
						|
}
 | 
						|
 | 
						|
#ifdef TABLEDEBUG
 | 
						|
void initlset(char *f)
 | 
						|
{
 | 
						|
 | 
						|
	set_flag = f;
 | 
						|
	if ((set_fd = open(f + 1, 2)) < 0)
 | 
						|
		error("Can't open %s rw", f + 1);
 | 
						|
	read(set_fd, &set_size, sizeof(int));
 | 
						|
	set_val = (short*)myalloc(set_size);
 | 
						|
	read(set_fd, set_val, set_size);
 | 
						|
}
 | 
						|
 | 
						|
void termlset(void)
 | 
						|
{
 | 
						|
 | 
						|
	if (set_fd)
 | 
						|
	{
 | 
						|
		lseek(set_fd, (long)sizeof(int), 0);
 | 
						|
		write(set_fd, set_val, set_size);
 | 
						|
		close(set_fd);
 | 
						|
		if (set_flag[0] == 'u')
 | 
						|
		{
 | 
						|
			int i;
 | 
						|
 | 
						|
			fprintf(stderr, "Unused code rules:\n\n");
 | 
						|
			for (i = 0; i < 8 * set_size; i++)
 | 
						|
				if (set_val[i >> 4] & (1 << (i & 017)))
 | 
						|
					fprintf(stderr, "\"%s\", line %d\n", tablename, i);
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
#endif /* TABLEDEBUG */
 |