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 )