Alien-LibJIT
view release on metacpan or search on metacpan
libjit/tools/gen-ops-parser.y view on Meta::CPAN
{
struct genops_opcode *next;
const char *name;
int type;
int oper;
int dest_flags;
int input1_flags;
int input2_flags;
const char *expression;
struct intrinsic_info intrinsic_info;
};
/*
* Opcode declaration list header
*/
struct genops_opcode_list
{
const char *declaration;
const char *define_start;
const char *counter_prefix_expr;
struct genops_opcode *first_opcode;
struct genops_opcode *last_opcode;
};
/*
* The task to execute.
*/
static int genops_task = TASK_GEN_NONE;
/*
* The file to execute
*/
static FILE *genops_file = 0;
static int genops_file_needs_close = 0;
/*
* options
*/
static int genops_gen_intrinsic_table = 0;
static const char *genops_intrinsic_decl = 0;
/*
* Blocks coppied to the resulting file.
*/
static const char *start_code_block = 0;
static const char *start_header_block = 0;
static const char *end_code_block = 0;
static const char *end_header_block = 0;
/*
* Current opcode declaration header
*/
static struct genops_opcode_list *opcode_header = 0;
/*
* Report error message.
*/
static void
genops_error_message(char *filename, long linenum, char *msg)
{
fprintf(stderr, "%s(%ld): %s\n", filename, linenum, msg);
}
/*
* Report error messages from the parser.
*/
static void
yyerror(char *msg)
{
genops_error_message(genops_filename, genops_linenum, msg);
}
/*
* Create an opcode declaration header.
*/
static void
genops_create_opcode_header(const char *define_start, const char *declaration,
const char *counter_prefix_expr)
{
struct genops_opcode_list *header;
header = (struct genops_opcode_list *)malloc(sizeof(struct genops_opcode_list));
if(!header)
{
exit(1);
}
if(counter_prefix_expr && (strlen(counter_prefix_expr) == 0))
{
counter_prefix_expr = 0;
}
header->declaration = declaration;
header->define_start = define_start;
header->counter_prefix_expr = counter_prefix_expr;
header->first_opcode = 0;
header->last_opcode = 0;
opcode_header = header;
}
/*
* Create an opcode entry
*/
static struct genops_opcode *
genops_add_opcode(const char *name, int type, int oper, int dest_flags,
int input1_flags, int input2_flags, const char *expression,
const char *intrinsic_flags, int signature,
const char *intrinsic)
{
struct genops_opcode *opcode;
opcode = (struct genops_opcode *) malloc(sizeof(struct genops_opcode));
if(!opcode)
{
exit(1);
}
if(opcode_header->first_opcode == 0)
{
opcode_header->first_opcode = opcode;
}
if(opcode_header->last_opcode != 0)
{
libjit/tools/gen-ops-parser.y view on Meta::CPAN
if(!cp)
{
exit(1);
}
strcpy(cp, $1);
strcat(cp, $2);
free($1);
free($2);
$$ = cp;
}
;
OptOptions
: /* None */ { }
| Options
;
Options
: Option
| Options Option
;
Option
: K_POPTION IDENTIFIER '=' IDENTIFIER {
genops_set_option($2, $4);
}
| K_POPTION IDENTIFIER '=' Literal {
genops_set_option($2, $4);
}
;
%%
/*
* Parse the commandline arguments
*/
static int
genops_parseargs(int argc, char *argv[])
{
int current;
current = 1;
while(current < argc - 1)
{
if(!strcmp(argv[current], "-H") ||
!strcmp(argv[current], "--header"))
{
genops_task = TASK_GEN_HEADER;
}
else if(!strcmp(argv[current], "-T") ||
!strcmp(argv[current], "--table"))
{
genops_task = TASK_GEN_TABLE;
}
else if(!strcmp(argv[current], "--help"))
{
return 1;
}
else
{
fprintf(stderr, "Invalid commandline option %s\n",
argv[current]);
return 1;
}
++current;
}
if(genops_task == TASK_GEN_NONE)
{
return 1;
}
if(argc > 1)
{
if(strcmp(argv[argc - 1], "-"))
{
genops_file = fopen(argv[argc - 1], "r");
if(!genops_file)
{
perror(argv[argc - 1]);
return 1;
}
genops_file_needs_close = 1;
}
else
{
genops_file = stdin;
}
}
else
{
return 1;
}
return 0;
}
/*
* Output the opcode declaration header
*/
static void
genops_output_defines(const char *define_start, const char *counter_prefix_expr)
{
struct genops_opcode *current;
int start_len;
int opcode_no;
int name_len;
int num_tabs;
start_len = strlen(define_start);
opcode_no = 0;
current = opcode_header->first_opcode;
while(current)
{
char *upper_name;
upper_name = genops_string_upper(current->name);
if(upper_name == 0)
{
/* Out of memory */
perror(genops_filename);
exit(1);
}
printf("#define\t%s%s", define_start, upper_name);
libjit/tools/gen-ops-parser.y view on Meta::CPAN
genops_output_signature(current->intrinsic_info.signature);
printf(", ");
if(current->intrinsic_info.intrinsic)
{
printf("%s", current->intrinsic_info.intrinsic);
}
else
{
printf("0");
}
printf("}");
current = current->next;
if(current)
{
printf(",\n");
}
else
{
printf("\n");
}
}
printf("};\n");
}
static void
genops_output_opcode_table(const char *filename)
{
printf("/%c Automatically generated from %s - DO NOT EDIT %c/\n",
'*', filename, '*');
if(start_code_block)
{
printf("%s", start_code_block);
}
genops_output_ops();
if(genops_gen_intrinsic_table)
{
printf("\n");
genops_output_intrinsic_table(opcode_header->define_start);
}
if(end_code_block)
{
printf("%s", end_code_block);
}
}
#define USAGE \
"Usage: %s option file\n" \
"Generates an opcode header or table from opcode definitions\n" \
"and writes the result to standard output\n\n" \
"Options:\n" \
" -H, --header\tgenerate a header file\n" \
" -T, --table\tgenerate a file with the opcode table\n" \
" --help\tdisplay this information\n" \
"\nExactly one of header or table option must be supplied.\n" \
"If file is - standard input is used.\n"
int main(int argc, char *argv[])
{
if(genops_parseargs(argc, argv))
{
fprintf(stderr, USAGE, argv[0]);
return 1;
}
genops_filename = argv[argc - 1];
genops_linenum = 1;
yyrestart(genops_file);
if(yyparse())
{
if(genops_file_needs_close)
{
fclose(genops_file);
}
return 1;
}
if(genops_file_needs_close)
{
fclose(genops_file);
}
switch(genops_task)
{
case TASK_GEN_HEADER:
{
genops_output_defs(genops_filename);
}
break;
case TASK_GEN_TABLE:
{
genops_output_opcode_table(genops_filename);
}
break;
}
return 0;
}
( run in 0.800 second using v1.01-cache-2.11-cpan-f5b5a18a01a )