/*-------------------------------------------------------------------------*/
/* Prolog To Wam Compiler INRIA Rocquencourt - CLoE Project */
/* C Run-time Daniel Diaz - 1994 */
/* */
/* GCC and WAM Configuration */
/* */
/* configure.c */
/*-------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#define CONFIGURE
#include "bool.h"
#include "machine.h"
/*---------------------------------*/
/* Constants */
/*---------------------------------*/
#define ARITY_SIZE 8 /* also in atom_prd.h */
#define WORD_SIZE (sizeof(long)*8)
/*---------------------------------*/
/* Type Definitions */
/*---------------------------------*/
typedef struct
{
char type[32];
char name[32];
}RegInf;
typedef enum
{
INTEGER,
UNSIGNED,
STACK,
MALLOC
}TypTag;
typedef struct
{
char name[32];
TypTag type;
char cast[32];
}TagInf;
typedef struct
{
char name[32];
int def_size;
char top_macro[128];
}StackInf;
/*---------------------------------*/
/* Global Variables */
/*---------------------------------*/
char save_str[256];
/*---------------------------------*/
/* Function Prototypes */
/*---------------------------------*/
void Generate_Gcc (int nb_of_used_regs);
int Generate_Archi (void);
char *Read_Identifier (char *s,Bool fail_if_error,char **end);
int Read_Integer (char *s,char **end);
int Generate_Regs (FILE *f,FILE *g);
void Generate_Tags (FILE *f,FILE *g);
void Generate_Stacks (FILE *f,FILE *g);
void Fatal_Error (char *format,...);
/*-------------------------------------------------------------------------*/
/* MAIN */
/* */
/*-------------------------------------------------------------------------*/
main()
{
#ifndef M_MACHINE
printf("Error: unsupported machine\n");
exit(-1);
#else
char *used_regs[]=M_USED_REGS;
int nb_of_used_regs;
int i;
printf("\t-------------------------------\n");
printf("Configuring %s for %s\n",COMPILER,M_MACHINE);
nb_of_used_regs=Generate_Archi();
Generate_Gcc(nb_of_used_regs);
printf("size of machine words : %d bits\n",WORD_SIZE);
printf("register used : ");
for(i=0;i<nb_of_used_regs;i++)
printf("%s ",used_regs[i]);
printf("\n");
printf("Prolog to C compiler : %s\n",COMPILER);
printf("C compiler script name : %s\n",WCC);
printf("C compiler name : %s\n",CC);
printf("directory for includes : %s\n",INCPATH);
printf("directory for libraries: %s\n",LIBPATH);
printf("\t-------------------------------\n");
exit(0);
#endif
}
#ifdef M_MACHINE
/*-------------------------------------------------------------------------*/
/* GENERATE_GCC */
/* */
/*-------------------------------------------------------------------------*/
void Generate_Gcc(int nb_of_used_regs)
{
FILE *f;
char str[4096];
char *used_regs[]=M_USED_REGS;
int i;
#ifdef NO_REGS
char *no_regs="-DNO_REGS ";
#else
char *no_regs="";
#endif
if ((f=fopen(WCC,"w"))==NULL)
Fatal_Error("cannot open %s",WCC);
fprintf(f,"#!/bin/sh\n");
sprintf(str,"%s -DM_%s -DWORD_SIZE=%d %s-DCOMPILER='\"'%s'\"' %s -I. -I%s -L. -L%s ",CC,M_MACHINE,WORD_SIZE,no_regs,COMPILER,EXTRA_CFLAGS,INCPATH,LIBPATH);
for(i=0;i<nb_of_used_regs;i++)
sprintf(str+strlen(str),"'-ffixed-%s' ",used_regs[i]);
strcat(str,"$*");
fprintf(f,"%s\n",str);
fclose(f);
}
/*-------------------------------------------------------------------------*/
/* GENERATE_ARCHI */
/* */
/*-------------------------------------------------------------------------*/
int Generate_Archi(void)
{
FILE *f,*g;
char str[256];
char *p1,*p2;
int nb_of_used_regs;
if ((f=fopen("archi.def","r"))==NULL)
Fatal_Error("cannot open archi.def",WCC);
if ((g=fopen("archi.h","w"))==NULL)
Fatal_Error("cannot open archi.h",WCC);
while(!feof(f) && fgets(str,sizeof(str),f))
{
if (*str!='@')
{
fputs(str,g);
continue;
}
strcpy(save_str,str);
p1=Read_Identifier(str+1,TRUE,&p2);
if (strcmp(p1,"begin")!=0)
Fatal_Error("Syntax error: incorrect @ declaration in: %s",save_str);
p1=Read_Identifier(p2+1,TRUE,&p2);
if (strcmp(p1,"regs")==0)
{
nb_of_used_regs=Generate_Regs(f,g);
continue;
}
if (strcmp(p1,"tags")==0)
{
Generate_Tags(f,g);
continue;
}
if (strcmp(p1,"stacks")==0)
{
Generate_Stacks(f,g);
continue;
}
Fatal_Error("Syntax error: unknown division in: %s",save_str);
}
fclose(f);
fclose(g);
return nb_of_used_regs;
}
/*-------------------------------------------------------------------------*/
/* READ_IDENTIFIER */
/* */
/*-------------------------------------------------------------------------*/
char *Read_Identifier(char *s,Bool fail_if_error,char **end)
{
while(isspace(*s))
s++;
*end=s;
if (!isalpha(**end))
if (fail_if_error)
Fatal_Error("Syntax error: identifier expected in: %s",save_str);
else
return NULL;
do
(*end)++;
while(isalnum(**end) || **end=='_');
if (!isspace(**end))
Fatal_Error("Syntax error: space expected after identifier in: %s",
save_str);
**end='\0';
return s;
}
/*-------------------------------------------------------------------------*/
/* READ_INTEGER */
/* */
/*-------------------------------------------------------------------------*/
int Read_Integer(char *s,char **end)
{
int x=0;
while(isspace(*s))
s++;
*end=s;
if (!isdigit(**end))
Fatal_Error("Syntax error: integer expected in: %s",save_str);
do
{
x=x*10+**end-'0';
(*end)++;
}
while(isdigit(**end) || **end=='_');
if (!isspace(**end))
Fatal_Error("Syntax error: space expected after identifier in: %s",
save_str);
**end='\0';
return x;
}
/*-------------------------------------------------------------------------*/
/* GENERATE_REGS */
/* */
/* initial filler description */
/* @filler size */
/* */
/* register description: */
/* @reg priority type name */
/* priority: 1-9 (1:high, 9:low) */
/* type must be machine word castable (ex int unsigned pointer...) */
/* */
/*-------------------------------------------------------------------------*/
int Generate_Regs(FILE *f,FILE *g)
{
char *p1,*p2;
char str[256];
char offset[32]="";
char *used_regs[]=M_USED_REGS;
int nb_of_used_regs=0;
RegInf reg[10][50];
int nb_reg[10]={0,0,0,0,0,0,0,0,0,0};
RegInf *dp;
char **p;
int total_nb_reg=0;
int nb_not_alloc=0;
int i,j,k;
for(;;)
{
if (feof(f) || !fgets(str,sizeof(str),f))
Fatal_Error("Syntax error: end expected for @begin reg");
if (*str!='@')
{
if (*str!='\n')
fputs(str,g);
continue;
}
strcpy(save_str,str);
p1=Read_Identifier(str+1,TRUE,&p2);
if (strcmp(p1,"end")==0)
break;
if (strcmp(p1,"filler")==0)
{
p1=Read_Identifier(p2+1,FALSE,&p2);
if (!p1)
{
i=Read_Integer(p2,&p2);
p1=str;
sprintf(p1,"%d",i);
}
sprintf(offset+strlen(offset),"%s+",p1);
continue;
}
if (strcmp(p1,"reg")==0)
{
i=Read_Integer(p2+1,&p2);
strcpy(reg[i][nb_reg[i]].type,Read_Identifier(p2+1,TRUE,&p2));
strcpy(reg[i][nb_reg[i]].name,Read_Identifier(p2+1,TRUE,&p2));
nb_reg[i]++;
continue;
}
Fatal_Error("Syntax error: incorrect @ declaration in: %s",save_str);
}
fprintf(g,"\n\n /*--- Begin Register Generation ---*/\n\n");
p=used_regs;
if (*p)
{
nb_of_used_regs++;
fprintf(g,"register WamWord \t\t*reg_bank asm (\"%s\");\n\n",*p++);
}
else
{
fprintf(g,"#ifdef WAM_ENGINE\n\n");
fprintf(g," WamWord \t\t\t*reg_bank;\n");
fprintf(g,"\n#else\n\n");
fprintf(g,"extern WamWord \t\t\t*reg_bank;\n");
fprintf(g,"\n#endif\n\n");
}
for(i=0;i<10;i++)
for(j=0,total_nb_reg+=nb_reg[i];j<nb_reg[i];j++)
{
dp= ®[i][j];
if (*p)
{
nb_of_used_regs++;
fprintf(g,"register %s\t\t%-3s asm (\"%s\");\n",
dp->type,dp->name,*p++);
if (!*p)
fprintf(g,"\n\n");
}
else
fprintf(g,"#define %s\t\t\t((%s)\t (reg_bank[%s%d]))\n",
dp->name,dp->type,offset,nb_not_alloc++);
}
fprintf(g,"\n\n");
fprintf(g,"#define NB_OF_REGS \t%d\n",total_nb_reg);
fprintf(g,"#define NB_OF_ALLOC_REGS \t%d\n",total_nb_reg-nb_not_alloc);
fprintf(g,"#define NB_OF_NOT_ALLOC_REGS\t%d\n",nb_not_alloc);
fprintf(g,"#define REG_BANK_SIZE \t(%sNB_OF_NOT_ALLOC_REGS)\n",offset);
fprintf(g,"\n\n");
fprintf(g,"#define Reg(i)\t\t\t(");
k=0;
for(i=0;i<10;i++)
for(j=0;j<nb_reg[i];j++)
{
dp= ®[i][j];
if (k<total_nb_reg-1)
fprintf(g,"((i)==%d) ? (WamWord) %-3s\t: \\\n\t\t\t\t ",
k++,dp->name);
else
fprintf(g," (WamWord) %s)\n",dp->name);
}
fprintf(g,"\n");
fprintf(g,"#ifdef WAM_ENGINE\n\n");
fprintf(g," char *reg_tbl[]=\t{");
k=0;
for(i=0;i<10;i++)
for(j=0;j<nb_reg[i];j++)
{
dp= ®[i][j];
fprintf(g,"\"%s\"%s",dp->name,k<total_nb_reg-1 ? "," : "};\n");
k++;
}
fprintf(g,"\n#else\n\n");
fprintf(g,"extern char *reg_tbl[];\n");
fprintf(g,"\n#endif\n");
fprintf(g,"\n\n\n\n#define NB_OF_USED_MACHINE_REGS %d\n",nb_of_used_regs);
fprintf(g,"\n\n\n\n#define Save_Machine_Regs(buff_save)\t\t\\\n");
fprintf(g," { \t\t\t\t\\\n");
for(i=0;i<nb_of_used_regs;i++)
fprintf(g," register long reg%d asm (\"%s\");\t\t\\\n",i,used_regs[i]);
for(i=0;i<nb_of_used_regs;i++)
fprintf(g," buff_save[%d]=reg%d;\t\t\t\t\\\n",i,i);
fprintf(g," }\n");
fprintf(g,"\n\n\n\n#define Restore_Machine_Regs(buff_save)\t\\\n");
fprintf(g," { \t\t\t\t\\\n");
for(i=0;i<nb_of_used_regs;i++)
fprintf(g," register long reg%d asm (\"%s\");\t\t\\\n",i,used_regs[i]);
for(i=0;i<nb_of_used_regs;i++)
fprintf(g," reg%d=buff_save[%d];\t\t\t\t\\\n",i,i);
fprintf(g," }\n");
fprintf(g,"\n\n /*--- End Register Generation ---*/\n\n");
return nb_of_used_regs;
}
/*-------------------------------------------------------------------------*/
/* GENERATE_TAGS */
/* */
/* tag description: */
/* @tag name type [cast_type] */
/* type of the value: int/unsigned/stack/malloc */
/*-------------------------------------------------------------------------*/
void Generate_Tags(FILE *f,FILE *g)
{
char str[256];
char *p1,*p2;
TagInf tag[128];
int nb_tag=0;
int tag_size,value_size;
unsigned long malloc_start;
unsigned long malloc_high_adr;
unsigned long tag_mask;
unsigned long arity_mask;
int i;
for(;;)
{
if (feof(f) || !fgets(str,sizeof(str),f))
Fatal_Error("Syntax error: end expected for @begin tag");
if (*str!='@')
{
if (*str!='\n')
fputs(str,g);
continue;
}
strcpy(save_str,str);
p1=Read_Identifier(str+1,TRUE,&p2);
if (strcmp(p1,"end")==0)
break;
if (strcmp(p1,"tag")==0)
{
strcpy(tag[nb_tag].name,Read_Identifier(p2+1,TRUE,&p2));
p1=Read_Identifier(p2+1,TRUE,&p2);
if (strcmp(p1,"int")==0)
tag[nb_tag].type=INTEGER;
else
if (strcmp(p1,"unsigned")==0)
tag[nb_tag].type=UNSIGNED;
else
if (strcmp(p1,"stack")==0)
tag[nb_tag].type=STACK;
else
if (strcmp(p1,"malloc")==0)
tag[nb_tag].type=MALLOC;
else
Fatal_Error("Syntax error: wrong tag type in: %s",
save_str);
if (p1=Read_Identifier(p2+1,FALSE,&p2))
strcpy(tag[nb_tag].cast,p1);
else
tag[nb_tag].cast[0]='\0';
nb_tag++;
continue;
}
Fatal_Error("Syntax error: incorrect @ declaration in: %s",save_str);
}
fprintf(g,"\n\n /*--- Begin Tag Generation ---*/\n\n");
for(tag_size=0;(1<<tag_size) < nb_tag;tag_size++)
;
value_size=WORD_SIZE-tag_size;
tag_mask=(unsigned long) (((unsigned long) -1) << value_size);
malloc_start=(unsigned long) malloc(256);
malloc_high_adr=malloc_start+15*1024*1024;
fprintf(g,"#define TAG_SIZE \t\t%d\n",tag_size);
fprintf(g,"#define VALUE_SIZE \t\t%d\n",value_size);
fprintf(g,"\n");
for(i=0;i<nb_tag;i++)
fprintf(g,"#define %-10s \t\t%-2d\n",tag[i].name,i);
fprintf(g,"\n");
fprintf(g,"#define MALLOC_MASK \t\t%#lx\n",(long) (malloc_high_adr & tag_mask));
#if defined(M_USE_MMAP)
fprintf(g,"#define STACK_MASK \t\t%#lx\n",(long) (M_MMAP_HIGH_ADR & tag_mask));
#elif defined(M_USE_SHM)
fprintf(g,"#define STACK_MASK \t\t%#lx\n",(long) (M_SHM_HIGH_ADR & tag_mask));
#else
fprintf(g,"#define STACK_MASK \t\tMALLOC_MASK\n");
#endif
arity_mask=(unsigned long) (((unsigned long) -1) << (WORD_SIZE-ARITY_SIZE));
if ((malloc_start & arity_mask) != (malloc_high_adr & arity_mask))
Fatal_Error("Cannot compute MALLOC_START");
fprintf(g,"#define MALLOC_START \t\t%#lx\n",(long) (malloc_start & arity_mask));
fprintf(g,"\n");
fprintf(g,"#define Tag_Value(t,v)\t\t(((unsigned long) (v) << %d) | (t))\n",tag_size);
fprintf(g,"#define Tag_Of(w) \t\t((unsigned long) (w) & %#x)\n",(1<<tag_size)-1);
fprintf(g,"\n");
fprintf(g,"#define UnTag_Integer(w) \t((int) (((long) (w) >> %d)))\n",
tag_size);
fprintf(g,"#define UnTag_Unsigned(w)\t((unsigned) (((unsigned long) (w) >> %d)))\n",
tag_size);
fprintf(g,"#define UnTag_Stack(w) \t((WamWord *) (((unsigned long) (w) >> %d) | STACK_MASK))\n",
tag_size);
fprintf(g,"#define UnTag_Malloc(w) \t((unsigned long) (((unsigned long) (w) >> %d) | MALLOC_MASK))\n",
tag_size);
fprintf(g,"\n");
fprintf(g,"#define NB_OF_TAGS \t%d\n\n",nb_tag);
for(i=0;i<nb_tag;i++)
{
fprintf(g,"#define Tag_%s(v) \t\tTag_Value(%s,v)\n",
tag[i].name,tag[i].name);
fprintf(g,"#define UnTag_%s(w) \t\t",tag[i].name);
if (tag[i].cast[0])
fprintf(g,"((%s) ",tag[i].cast);
fprintf(g,"UnTag_%s(w)%s\n\n",
(tag[i].type==INTEGER) ? "Integer" :
(tag[i].type==UNSIGNED) ? "Unsigned" :
(tag[i].type==STACK) ? "Stack" : "Malloc",
(tag[i].cast[0]) ? ")" : "");
}
fprintf(g,"\ntypedef enum\n");
fprintf(g," {\n");
fprintf(g," INTEGER,\n");
fprintf(g," UNSIGNED,\n");
fprintf(g," STACK,\n");
fprintf(g," MALLOC\n");
fprintf(g," }TypTag;\n");
fprintf(g,"\ntypedef struct\n");
fprintf(g," {\n");
fprintf(g," char *name;\n");
fprintf(g," TypTag type;\n");
fprintf(g," }InfTag;\n\n\n");
fprintf(g,"#ifdef WAM_ENGINE\n\n");
fprintf(g," InfTag tag_tbl[]=\t{");
for(i=0;i<nb_tag;i++)
{
fprintf(g,"{\"%s\",%s}%s",tag[i].name,
(tag[i].type==INTEGER) ? "INTEGER" :
(tag[i].type==UNSIGNED) ? "UNSIGNED" :
(tag[i].type==STACK) ? "STACK" : "MALLOC",
(i<nb_tag-1) ? ",\n\t\t\t\t " : "};\n");
}
fprintf(g,"\n#else\n\n");
fprintf(g,"extern InfTag tag_tbl[];\n");
fprintf(g,"\n#endif\n");
fprintf(g,"\n\n /*--- End Tag Generation ---*/\n\n");
}
/*-------------------------------------------------------------------------*/
/* GENERATE_STACKS */
/* */
/* stack description: */
/* @stack name default_size stack_top_macro */
/*-------------------------------------------------------------------------*/
void Generate_Stacks(FILE *f,FILE *g)
{
char str[256];
char *p1,*p2;
int i;
StackInf stack[128];
int nb_stack=0;
for(;;)
{
if (feof(f) || !fgets(str,sizeof(str),f))
Fatal_Error("Syntax error: end expected for @begin stack");
if (*str!='@')
{
if (*str!='\n')
fputs(str,g);
continue;
}
strcpy(save_str,str);
p1=Read_Identifier(str+1,TRUE,&p2);
if (strcmp(p1,"end")==0)
break;
if (strcmp(p1,"stack")==0)
{
strcpy(stack[nb_stack].name,Read_Identifier(p2+1,TRUE,&p2));
i=Read_Integer(p2+1,&p2);
stack[nb_stack].def_size=i*1024/sizeof(long);
strcpy(stack[nb_stack].top_macro,Read_Identifier(p2+1,TRUE,&p2));
nb_stack++;
continue;
}
Fatal_Error("Syntax error: incorrect @ declaration in: %s",save_str);
}
fprintf(g,"\n\n /*--- Begin Stack Generation ---*/\n\n");
fprintf(g,"#define NB_OF_STACKS \t\t%d\n\n",nb_stack);
for(i=0;i<nb_stack;i++)
{
strcpy(str,stack[i].name);
*str=toupper(*str);
fprintf(g,"#define %s_Stack \t(stk_tbl[%d].stack)\n",str,i);
fprintf(g,"#define %s_Size \t(stk_tbl[%d].size)\n", str,i);
fprintf(g,"#define %s_Offset(adr) \t((WamWord *)(adr)-%s_Stack)\n",
str,str);
fprintf(g,"#define %s_Used_Size \t%s_Offset(%s)\n\n",str,str,
stack[i].top_macro);
}
fprintf(g,"\n#define Stack_Top(s) \t(");
for(i=0;i<nb_stack-1;i++)
fprintf(g,"((s)==%d) ? %s : ",i,stack[i].top_macro);
fprintf(g,"%s)\n",stack[nb_stack-1].top_macro);
fprintf(g,"\ntypedef struct\n");
fprintf(g," {\n");
fprintf(g," char *name;\n");
fprintf(g," char *env_var_name;\n");
fprintf(g," int default_size; \t/* in WamWords */\n");
fprintf(g," int size; \t/* in WamWords */\n");
fprintf(g," WamWord *stack;\n");
fprintf(g," }InfStack;\n\n\n");
fprintf(g,"#ifdef WAM_ENGINE\n\n");
fprintf(g," InfStack stk_tbl[]=\t{");
for(i=0;i<nb_stack;i++)
{
strcpy(str,stack[i].name);
for(p1=str;*p1;p1++)
*p1=toupper(*p1);
fprintf(g,"{\"%s\",\"%sSZ\",%d,0,NULL}%s",
stack[i].name,str,stack[i].def_size,
(i<nb_stack-1) ? ",\n\t\t\t\t " : "};\n");
}
fprintf(g,"\n#else\n\n");
fprintf(g,"extern InfStack stk_tbl[];\n");
fprintf(g,"\n#endif\n");
fprintf(g,"\n\n /*--- End Stack Generation ---*/\n\n");
}
/*-------------------------------------------------------------------------*/
/* FATAL_ERROR */
/* */
/*-------------------------------------------------------------------------*/
void Fatal_Error(char *format,...)
{
va_list arg_ptr;
va_start(arg_ptr,format);
vprintf(format,arg_ptr);
va_end(arg_ptr);
printf("\n");
exit(1);
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1