#define YYBISON 1
#define YYBISON_VERSION "3.0.4"
#define YYSKELETON_NAME "yacc.c"
#define YYPURE 0
#define YYPUSH 0
#define YYPULL 1
#line 1 "gen-rules-parser.y"
#include <config.h>
#include <ctype.h>
#include <stdio.h>
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#elif defined(HAVE_STRINGS_H)
# include <strings.h>
#endif
extern int yylex(void);
extern void yyrestart(FILE *file);
#ifdef YYTEXT_POINTER
extern char *yytext;
#else
extern char yytext[];
#endif
extern char *gensel_filename;
extern long gensel_linenum;
static void
gensel_error_message(char *filename, long linenum, char *msg)
{
fprintf(stderr, "%s(%ld): %s\n", filename, linenum, msg);
}
static void
gensel_error(char *filename, long linenum, char *msg)
{
gensel_error_message(filename, linenum, msg);
exit(1);
}
static void
yyerror(char *msg)
{
gensel_error_message(gensel_filename, gensel_linenum, msg);
}
static char *gensel_inst_type = "unsigned char *";
static int gensel_new_inst_type = 0;
static int gensel_reserve_space = 32;
static int gensel_reserve_more_space = 128;
#define MAX_INPUT 3
#define MAX_SCRATCH 6
#define MAX_PATTERN (MAX_INPUT + MAX_SCRATCH)
#define GENSEL_OPT_TERNARY 1
#define GENSEL_OPT_BRANCH 2
#define GENSEL_OPT_NOTE 3
#define GENSEL_OPT_COPY 4
#define GENSEL_OPT_COMMUTATIVE 5
#define GENSEL_OPT_STACK 6
#define GENSEL_OPT_X87_ARITH 7
#define GENSEL_OPT_X87_ARITH_REVERSIBLE 8
#define GENSEL_OPT_MANUAL 9
#define GENSEL_OPT_MORE_SPACE 10
#define GENSEL_PATT_ANY 1
#define GENSEL_PATT_REG 2
#define GENSEL_PATT_LREG 3
#define GENSEL_PATT_IMM 4
#define GENSEL_PATT_IMMZERO 5
#define GENSEL_PATT_IMMS8 6
#define GENSEL_PATT_IMMU8 7
#define GENSEL_PATT_IMMS16 8
#define GENSEL_PATT_IMMU16 9
#define GENSEL_PATT_IMMS32 10
#define GENSEL_PATT_IMMU32 11
#define GENSEL_PATT_LOCAL 12
#define GENSEL_PATT_FRAME 13
#define GENSEL_PATT_SCRATCH 14
#define GENSEL_PATT_CLOBBER 15
#define GENSEL_PATT_IF 16
#define GENSEL_PATT_SPACE 17
#define GENSEL_VALUE_STRING 1
#define GENSEL_VALUE_REGCLASS 2
#define GENSEL_VALUE_ALL 3
#define GENSEL_VALUE_CLOBBER 4
#define GENSEL_VALUE_EARLY_CLOBBER 5
typedef struct gensel_regclass *gensel_regclass_t;
struct gensel_regclass
{
char *id;
char *def;
int is_long;
gensel_regclass_t next;
};
typedef struct gensel_value *gensel_value_t;
struct gensel_value
{
int type;
void *value;
gensel_value_t next;
};
typedef struct gensel_option *gensel_option_t;
struct gensel_option
{
int option;
gensel_value_t values;
gensel_option_t next;
};
typedef struct gensel_clause *gensel_clause_t;
struct gensel_clause
{
int dest;
gensel_option_t pattern;
char *filename;
long linenum;
char *code;
gensel_clause_t next;
};
static char *gensel_args[] = {
"dest", "value1", "value2"
};
static char *gensel_imm_args[] = {
"insn->dest->address", "insn->value1->address", "insn->value2->address"
};
static char *gensel_reg_names[] = {
"reg", "reg2", "reg3", "reg4", "reg5", "reg6", "reg7", "reg8", "reg9"
};
static char *gensel_other_reg_names[] = {
"other_reg", "other_reg2", "other_reg3"
};
static char *gensel_imm_names[] = {
"imm_value", "imm_value2", "imm_value3"
};
static char *gensel_local_names[] = {
"local_offset", "local_offset2", "local_offset3"
};
static gensel_regclass_t gensel_regclass_list;
static void
gensel_create_regclass(char *id, char *def, int is_long)
{
gensel_regclass_t rp;
rp = (gensel_regclass_t) malloc(sizeof(struct gensel_regclass));
if(!rp)
{
exit(1);
}
rp->id = id;
rp->def = def;
rp->is_long = is_long;
rp->next = gensel_regclass_list;
gensel_regclass_list = rp;
}
gensel_regclass_t
gensel_lookup_regclass(char *id)
{
gensel_regclass_t rp;
rp = gensel_regclass_list;
for(;;)
{
if(!rp)
{
gensel_error(
gensel_filename, gensel_linenum,
"invalid register class");
}
if(strcmp(id, rp->id) == 0)
{
return rp;
}
rp = rp->next;
}
}
static gensel_value_t
gensel_create_value(int type)
{
gensel_value_t vp;
vp = (gensel_value_t) malloc(sizeof(struct gensel_value));
if(!vp)
{
exit(1);
}
vp->type = type;
vp->value = 0;
vp->next = 0;
return vp;
}
static gensel_value_t
gensel_create_string_value(char *value)
{
gensel_value_t vp;
vp = gensel_create_value(GENSEL_VALUE_STRING);
vp->value = value;
return vp;
}
static gensel_value_t
gensel_create_regclass_value(char *value)
{
gensel_value_t vp;
vp = gensel_create_value(GENSEL_VALUE_REGCLASS);
vp->value = gensel_lookup_regclass(value);
return vp;
}
static gensel_option_t
gensel_create_option(int option, gensel_value_t values)
{
gensel_option_t op;
op = (gensel_option_t) malloc(sizeof(struct gensel_option));
if(!op)
{
exit(1);
}
op->option = option;
op->values = values;
op->next = 0;
return op;
}
static gensel_option_t
gensel_create_register(
int flags,
gensel_value_t value,
gensel_value_t values)
{
gensel_regclass_t regclass;
if(flags)
{
value->next = gensel_create_value(flags);
value->next->next = values;
}
else
{
value->next = values;
}
regclass = value->value;
return gensel_create_option(
regclass->is_long ? GENSEL_PATT_LREG : GENSEL_PATT_REG,
value);
}
static gensel_option_t
gensel_create_scratch(
gensel_value_t regclass,
gensel_value_t values)
{
regclass->next = values;
return gensel_create_option(GENSEL_PATT_SCRATCH, regclass);
}
static void
gensel_free_values(gensel_value_t values)
{
gensel_value_t next;
while(values)
{
next = values->next;
if(values->type == GENSEL_VALUE_STRING)
{
free(values->value);
}
free(values);
values = next;
}
}
static void
gensel_free_options(gensel_option_t options)
{
gensel_option_t next;
while(options)
{
next = options->next;
gensel_free_values(options->values);
free(options);
options = next;
}
}
static void
gensel_free_clauses(gensel_clause_t clauses)
{
gensel_clause_t next;
while(clauses != 0)
{
next = clauses->next;
gensel_free_options(clauses->pattern);
free(clauses->code);
free(clauses);
clauses = next;
}
}
static gensel_option_t
gensel_search_option(gensel_option_t options, int tag)
{
while(options && options->option != tag)
{
options = options->next;
}
return options;
}
static void
gensel_declare_regs(gensel_clause_t clauses, gensel_option_t options)
{
gensel_option_t pattern;
int regs, max_regs;
int other_regs_mask;
int imms, max_imms;
int locals, max_locals;
int scratch, others;
max_regs = 0;
other_regs_mask = 0;
max_imms = 0;
max_locals = 0;
while(clauses != 0)
{
regs = 0;
imms = 0;
locals = 0;
others = 0;
scratch = 0;
pattern = clauses->pattern;
while(pattern)
{
switch(pattern->option)
{
case GENSEL_PATT_ANY:
++others;
break;
case GENSEL_PATT_REG:
++regs;
break;
case GENSEL_PATT_LREG:
other_regs_mask |= (1 << regs);
++regs;
break;
case GENSEL_PATT_IMMZERO:
++others;
break;
case GENSEL_PATT_IMM:
case GENSEL_PATT_IMMS8:
case GENSEL_PATT_IMMU8:
case GENSEL_PATT_IMMS16:
case GENSEL_PATT_IMMU16:
case GENSEL_PATT_IMMS32:
case GENSEL_PATT_IMMU32:
++imms;
break;
case GENSEL_PATT_LOCAL:
case GENSEL_PATT_FRAME:
++locals;
break;
case GENSEL_PATT_SCRATCH:
++scratch;
}
pattern = pattern->next;
}
if((regs + imms + locals + others) > MAX_INPUT)
{
gensel_error(
clauses->filename,
clauses->linenum,
"too many input args in the pattern");
}
if(scratch > MAX_SCRATCH)
{
gensel_error(
clauses->filename,
clauses->linenum,
"too many scratch args in the pattern");
}
if(max_regs < (regs + scratch))
{
max_regs = regs + scratch;
}
if(max_imms < imms)
{
max_imms = imms;
}
if(max_locals < locals)
{
max_locals = locals;
}
clauses = clauses->next;
}
if(max_regs > 0)
{
printf("\tint reg");
for(scratch = 1; scratch < max_regs; scratch++)
{
printf(", reg%d", scratch + 1);
}
printf(";\n");
}
if(other_regs_mask)
{
switch(other_regs_mask)
{
case 1:
printf("\tint other_reg;\n");
break;
case 2:
printf("\tint other_reg2;\n");
break;
case 3:
printf("\tint other_reg, other_reg2;\n");
break;
case 4:
printf("\tint other_reg3;\n");
break;
case 5:
printf("\tint other_reg, other_reg3;\n");
break;
case 6:
printf("\tint other_reg2, other_reg3;\n");
break;
case 7:
printf("\tint other_reg, other_reg2, other_reg3;\n");
break;
}
}
switch(max_imms)
{
case 1:
printf("\tjit_nint imm_value;\n");
break;
case 2:
printf("\tjit_nint imm_value, imm_value2;\n");
break;
case 3:
printf("\tjit_nint imm_value, imm_value2, imm_value3;\n");
break;
}
switch(max_locals)
{
case 1:
printf("\tjit_nint local_offset;\n");
break;
case 2:
printf("\tjit_nint local_offset, local_offset2;\n");
break;
case 3:
printf("\tjit_nint local_offset, local_offset2, local_offset3;\n");
break;
}
}
static int
gensel_contains_registers(gensel_option_t pattern)
{
while(pattern)
{
switch(pattern->option)
{
case GENSEL_PATT_REG:
case GENSEL_PATT_LREG:
case GENSEL_PATT_SCRATCH:
case GENSEL_PATT_CLOBBER:
return 1;
}
pattern = pattern->next;
}
return 0;
}
static gensel_option_t
gensel_get_first_register(gensel_option_t pattern)
{
while(pattern)
{
switch(pattern->option)
{
case GENSEL_PATT_REG:
case GENSEL_PATT_LREG:
return pattern;
}
pattern = pattern->next;
}
return 0;
}
static void
gensel_init_names(int count, char *names[], char *other_names[])
{
int index;
for(index = 0; index < count; index++)
{
if(names)
{
names[index] = "undefined";
}
if(other_names)
{
other_names[index] = "undefined";
}
}
}
static void
gensel_build_arg_index(
gensel_option_t pattern,
int count,
char *names[],
char *other_names[],
int ternary,
int free_dest)
{
int index;
gensel_init_names(count, names, other_names);
index = 0;
while(pattern)
{
switch(pattern->option)
{
case GENSEL_PATT_ANY:
++index;
break;
case GENSEL_PATT_REG:
case GENSEL_PATT_LREG:
case GENSEL_PATT_LOCAL:
case GENSEL_PATT_FRAME:
case GENSEL_PATT_IMMZERO:
case GENSEL_PATT_IMM:
case GENSEL_PATT_IMMS8:
case GENSEL_PATT_IMMU8:
case GENSEL_PATT_IMMS16:
case GENSEL_PATT_IMMU16:
case GENSEL_PATT_IMMS32:
case GENSEL_PATT_IMMU32:
if(ternary || free_dest)
{
if(index < 3)
{
names[index] = gensel_args[index];
}
}
else
{
if(index < 2)
{
names[index] = gensel_args[index + 1];
}
}
++index;
break;
}
pattern = pattern->next;
}
}
static void
gensel_build_imm_arg_index(
gensel_option_t pattern,
int count,
char *names[],
char *other_names[],
int ternary,
int free_dest)
{
int index;
gensel_init_names(count, names, other_names);
index = 0;
while(pattern)
{
switch(pattern->option)
{
case GENSEL_PATT_ANY:
case GENSEL_PATT_REG:
case GENSEL_PATT_LREG:
case GENSEL_PATT_LOCAL:
case GENSEL_PATT_FRAME:
case GENSEL_PATT_IMMZERO:
++index;
break;
case GENSEL_PATT_IMM:
case GENSEL_PATT_IMMS8:
case GENSEL_PATT_IMMU8:
case GENSEL_PATT_IMMS16:
case GENSEL_PATT_IMMU16:
case GENSEL_PATT_IMMS32:
case GENSEL_PATT_IMMU32:
if(ternary || free_dest)
{
if(index < 3)
{
names[index] = gensel_imm_args[index];
}
}
else
{
if(index < 2)
{
names[index] = gensel_imm_args[index + 1];
}
}
++index;
break;
}
pattern = pattern->next;
}
}
static void
gensel_build_var_index(
gensel_option_t pattern,
char *names[MAX_PATTERN],
char *other_names[MAX_PATTERN])
{
int regs, imms, locals, index;
gensel_init_names(MAX_PATTERN, names, other_names);
regs = 0;
imms = 0;
locals = 0;
index = 0;
while(pattern)
{
switch(pattern->option)
{
case GENSEL_PATT_ANY:
++index;
break;
case GENSEL_PATT_REG:
names[index] = gensel_reg_names[regs];
++regs;
++index;
break;
case GENSEL_PATT_LREG:
names[index] = gensel_reg_names[regs];
other_names[index] = gensel_other_reg_names[regs];
++regs;
++index;
break;
case GENSEL_PATT_IMMZERO:
++index;
break;
case GENSEL_PATT_IMM:
case GENSEL_PATT_IMMS8:
case GENSEL_PATT_IMMU8:
case GENSEL_PATT_IMMS16:
case GENSEL_PATT_IMMU16:
case GENSEL_PATT_IMMS32:
case GENSEL_PATT_IMMU32:
names[index] = gensel_imm_names[imms];
++imms;
++index;
break;
case GENSEL_PATT_LOCAL:
case GENSEL_PATT_FRAME:
names[index] = gensel_local_names[locals];
++locals;
++index;
break;
case GENSEL_PATT_SCRATCH:
names[index] = gensel_reg_names[regs];
++regs;
++index;
}
pattern = pattern->next;
}
}
static void
gensel_output_code(
gensel_option_t pattern,
char *code,
char *names[MAX_PATTERN],
char *other_names[MAX_PATTERN],
int free_dest,
int in_line)
{
char first;
int index;
if(!in_line)
{
printf("\t\t");
}
while(*code != '\0')
{
first = '1';
if(*code == '$' && code[1] >= first && code[1] < (first + MAX_PATTERN))
{
index = code[1] - first;
printf(names[index]);
code += 2;
}
else if(*code == '%' && code[1] >= first && code[1] < (first + MAX_PATTERN))
{
index = code[1] - first;
printf(other_names[index]);
code += 2;
}
else if(*code == '\n')
{
putc(*code, stdout);
putc('\t', stdout);
++code;
}
else
{
putc(*code, stdout);
++code;
}
}
if(!in_line)
{
printf("\n");
}
}
static void
gensel_output_clause_code(
gensel_clause_t clause,
char *names[MAX_PATTERN],
char *other_names[MAX_PATTERN],
int free_dest)
{
#if 0#endif
gensel_output_code(clause->pattern, clause->code, names, other_names, free_dest, 0);
}
static void
gensel_output_register(char *name, gensel_regclass_t regclass, gensel_value_t values)
{
printf("\t\t_jit_regs_init_%s(®s, insn, ", name);
switch(values ? values->type : 0)
{
case GENSEL_VALUE_CLOBBER:
printf("_JIT_REGS_CLOBBER");
values = values->next;
break;
case GENSEL_VALUE_EARLY_CLOBBER:
printf("_JIT_REGS_EARLY_CLOBBER");
values = values->next;
break;
default:
printf("0");
break;
}
printf(", %s);\n", regclass->def);
if(values && values->value)
{
char *reg;
reg = values->value;
if(values->next && values->next->value)
{
char *other_reg;
other_reg = values->next->value;
printf("\t\t_jit_regs_set_%s(gen, ®s, _jit_regs_lookup(\"%s\"), _jit_regs_lookup(\"%s\"));\n",
name, reg, other_reg);
}
else
{
printf("\t\t_jit_regs_set_%s(gen, ®s, _jit_regs_lookup(\"%s\"), -1);\n",
name, reg);
}
}
}
static void
gensel_output_register_pattern(char *name, gensel_option_t pattern)
{
gensel_output_register(name, pattern->values->value, pattern->values->next);
}
static char *
gensel_string_upper(char *string)
{
char *cp;
if(string)
{
string = strdup(string);
for(cp = string; *cp; cp++)
{
*cp = toupper(*cp);
}
}
return string;
}
static void gensel_output_clauses(gensel_clause_t clauses, gensel_option_t options)
{
char *name;
char *args[MAX_INPUT];
char *names[MAX_PATTERN];
char *other_names[MAX_PATTERN];
gensel_clause_t clause;
gensel_option_t pattern;
gensel_option_t space, more_space;
gensel_value_t values;
int regs, imms, locals, scratch, index;
int first, seen_option;
int ternary, free_dest;
int contains_registers;
gensel_regclass_t regclass;
char *uc_arg;
if(gensel_search_option(options, GENSEL_OPT_MANUAL))
{
gensel_init_names(MAX_PATTERN, names, other_names);
gensel_output_clause_code(clauses, names, other_names, 0);
return;
}
clause = clauses;
contains_registers = 0;
while(clause)
{
contains_registers = gensel_contains_registers(clause->pattern);
if(contains_registers)
{
break;
}
clause = clause->next;
}
printf("\t%s inst;\n", gensel_inst_type);
if(contains_registers)
{
printf("\t_jit_regs_t regs;\n");
}
gensel_declare_regs(clauses, options);
ternary = (0 != gensel_search_option(options, GENSEL_OPT_TERNARY));
clause = clauses;
first = 1;
while(clause)
{
contains_registers = gensel_contains_registers(clause->pattern);
free_dest = clause->dest;
gensel_build_arg_index(clause->pattern, 3, args, 0, ternary, free_dest);
if(clause->next)
{
if(first)
printf("\tif(");
else
printf("\telse if(");
index = 0;
seen_option = 0;
pattern = clause->pattern;
while(pattern)
{
switch(pattern->option)
{
case GENSEL_PATT_ANY:
++index;
break;
case GENSEL_PATT_REG:
case GENSEL_PATT_LREG:
#if 0#endif
++index;
break;
case GENSEL_PATT_IMM:
if(seen_option)
{
printf(" && ");
}
printf("insn->%s->is_constant", args[index]);
seen_option = 1;
++index;
break;
case GENSEL_PATT_IMMZERO:
if(seen_option)
{
printf(" && ");
}
printf("insn->%s->is_nint_constant && ", args[index]);
printf("insn->%s->address == 0", args[index]);
seen_option = 1;
++index;
break;
case GENSEL_PATT_IMMS8:
if(seen_option)
{
printf(" && ");
}
printf("insn->%s->is_nint_constant && ", args[index]);
printf("insn->%s->address >= -128 && ", args[index]);
printf("insn->%s->address <= 127", args[index]);
seen_option = 1;
++index;
break;
case GENSEL_PATT_IMMU8:
if(seen_option)
{
printf(" && ");
}
printf("insn->%s->is_nint_constant && ", args[index]);
printf("insn->%s->address >= 0 && ", args[index]);
printf("insn->%s->address <= 255", args[index]);
seen_option = 1;
++index;
break;
case GENSEL_PATT_IMMS16:
if(seen_option)
{
printf(" && ");
}
printf("insn->%s->is_nint_constant && ", args[index]);
printf("insn->%s->address >= -32768 && ", args[index]);
printf("insn->%s->address <= 32767", args[index]);
seen_option = 1;
++index;
break;
case GENSEL_PATT_IMMU16:
if(seen_option)
{
printf(" && ");
}
printf("insn->%s->is_nint_constant && ", args[index]);
printf("insn->%s->address >= 0 && ", args[index]);
printf("insn->%s->address <= 65535", args[index]);
seen_option = 1;
++index;
break;
case GENSEL_PATT_IMMS32:
if(seen_option)
{
printf(" && ");
}
printf("insn->%s->is_nint_constant && ", args[index]);
printf("insn->%s->address >= -2147483648 && ", args[index]);
printf("insn->%s->address <= 2147483647", args[index]);
seen_option = 1;
++index;
break;
case GENSEL_PATT_IMMU32:
if(seen_option)
{
printf(" && ");
}
printf("insn->%s->is_nint_constant && ", args[index]);
printf("insn->%s->address >= 0 && ", args[index]);
printf("insn->%s->address <= 4294967295", args[index]);
seen_option = 1;
++index;
break;
case GENSEL_PATT_LOCAL:
if(seen_option)
{
printf(" && ");
}
printf("!insn->%s->is_constant && ", args[index]);
printf("!insn->%s->in_register && ", args[index]);
printf("!insn->%s->has_global_register", args[index]);
uc_arg = gensel_string_upper(args[index]);
printf("&& (insn->flags & JIT_INSN_%s_NEXT_USE) == 0", uc_arg);
free(uc_arg);
seen_option = 1;
++index;
break;
case GENSEL_PATT_FRAME:
if(seen_option)
{
printf(" && ");
}
printf("!insn->%s->is_constant && ", args[index]);
printf("!insn->%s->has_global_register", args[index]);
seen_option = 1;
++index;
break;
case GENSEL_PATT_IF:
if(seen_option)
{
printf(" && ");
}
printf("(");
gensel_build_imm_arg_index(
clause->pattern, MAX_PATTERN,
names, other_names, ternary, free_dest);
gensel_output_code(
clause->pattern,
pattern->values->value,
names, other_names, free_dest, 1);
printf(")");
seen_option = 1;
break;
}
pattern = pattern->next;
}
if(!seen_option)
{
printf("1");
}
printf(")\n\t{\n");
}
else if(first)
{
printf("\t{\n");
}
else
{
printf("\telse\n\t{\n");
}
if(contains_registers)
{
seen_option = 0;
printf("\t\t_jit_regs_init(gen, ®s, ");
if(ternary)
{
seen_option = 1;
printf("_JIT_REGS_TERNARY");
}
else if(free_dest)
{
seen_option = 1;
printf("_JIT_REGS_FREE_DEST");
}
if(gensel_search_option(options, GENSEL_OPT_BRANCH))
{
if(seen_option)
{
printf(" | ");
}
else
{
seen_option = 1;
}
printf("_JIT_REGS_BRANCH");
}
if(gensel_search_option(options, GENSEL_OPT_COPY))
{
if(seen_option)
{
printf(" | ");
}
else
{
seen_option = 1;
}
printf("_JIT_REGS_COPY");
}
if(gensel_search_option(options, GENSEL_OPT_STACK))
{
if(seen_option)
{
printf(" | ");
}
else
{
seen_option = 1;
}
printf("_JIT_REGS_STACK");
}
if(gensel_search_option(options, GENSEL_OPT_COMMUTATIVE))
{
if(seen_option)
{
printf(" | ");
}
else
{
seen_option = 1;
}
printf("_JIT_REGS_COMMUTATIVE");
}
if(gensel_search_option(options, GENSEL_OPT_X87_ARITH))
{
if(seen_option)
{
printf(" | ");
}
else
{
seen_option = 1;
}
printf("_JIT_REGS_X87_ARITH");
}
else if(gensel_search_option(options, GENSEL_OPT_X87_ARITH_REVERSIBLE))
{
if(seen_option)
{
printf(" | ");
}
else
{
seen_option = 1;
}
printf("_JIT_REGS_X87_ARITH | _JIT_REGS_REVERSIBLE");
}
if(!seen_option)
{
printf("0");
}
printf(");\n");
if(!(ternary || free_dest
|| gensel_search_option(options, GENSEL_OPT_NOTE)
|| gensel_search_option(options, GENSEL_OPT_BRANCH)))
{
pattern = gensel_get_first_register(clause->pattern);
gensel_output_register("dest", pattern ? pattern->values->value : 0, 0);
}
}
regs = 0;
index = 0;
scratch = 0;
pattern = clause->pattern;
while(pattern)
{
switch(pattern->option)
{
case GENSEL_PATT_ANY:
++index;
break;
case GENSEL_PATT_REG:
case GENSEL_PATT_LREG:
gensel_output_register_pattern(args[index], pattern);
++regs;
++index;
break;
case GENSEL_PATT_IMMZERO:
case GENSEL_PATT_IMM:
case GENSEL_PATT_IMMS8:
case GENSEL_PATT_IMMU8:
case GENSEL_PATT_IMMS16:
case GENSEL_PATT_IMMU16:
case GENSEL_PATT_IMMS32:
case GENSEL_PATT_IMMU32:
++index;
break;
case GENSEL_PATT_LOCAL:
printf("\t\t_jit_gen_fix_value(insn->%s);\n", args[index]);
++index;
break;
case GENSEL_PATT_FRAME:
printf("\t\t_jit_regs_force_out(gen, insn->%s, %d);\n",
args[index], (free_dest && index == 0));
printf("\t\t_jit_gen_fix_value(insn->%s);\n", args[index]);
++index;
break;
case GENSEL_PATT_SCRATCH:
regclass = pattern->values->value;
printf("\t\t_jit_regs_add_scratch(®s, %s);\n",
regclass->def);
if(pattern->values->next && pattern->values->next->value)
{
name = pattern->values->next->value;
printf("\t\t_jit_regs_set_scratch(gen, ®s, %d, _jit_regs_lookup(\"%s\"));\n",
scratch, name);
}
++regs;
++scratch;
++index;
break;
case GENSEL_PATT_CLOBBER:
values = pattern->values;
while(values)
{
if(!values->value)
{
continue;
}
switch(values->type)
{
case GENSEL_VALUE_STRING:
name = values->value;
printf("\t\t_jit_regs_clobber(®s, _jit_regs_lookup(\"%s\"));\n",
name);
break;
case GENSEL_VALUE_REGCLASS:
regclass = values->value;
printf("\t\t_jit_regs_clobber_class(gen, ®s, %s);\n",
regclass->def);
break;
case GENSEL_VALUE_ALL:
printf("\t\t_jit_regs_clobber_all(gen, ®s);\n");
break;
}
values = values->next;
}
break;
}
pattern = pattern->next;
}
if(gensel_search_option(options, GENSEL_OPT_BRANCH))
{
if(contains_registers)
{
printf("\t\t_jit_regs_clobber_all(gen, ®s);\n");
}
else
{
printf("\t\t_jit_regs_spill_all(gen);\n");
}
}
if(gensel_new_inst_type)
{
if(contains_registers)
{
printf("\t\t_jit_regs_assign(gen, ®s);\n");
printf("\t\t_jit_regs_gen(gen, ®s);\n");
}
printf("\t\tjit_gen_load_inst_ptr(gen, inst);\n");
}
else
{
space = gensel_search_option(clause->pattern, GENSEL_PATT_SPACE);
more_space = gensel_search_option(options, GENSEL_OPT_MORE_SPACE);
if(contains_registers)
{
printf("\t\t_jit_regs_begin(gen, ®s, ");
}
else
{
printf("\t\t_jit_gen_check_space(gen, ");
}
if(space && space->values && space->values->value)
{
printf("(");
gensel_build_imm_arg_index(
clause->pattern, MAX_PATTERN,
names, other_names, ternary, free_dest);
gensel_output_code(
clause->pattern,
space->values->value,
names, other_names, free_dest, 1);
printf(")");
}
else
{
printf("%d", ((more_space == 0)
? gensel_reserve_space
: gensel_reserve_more_space));
}
printf(");\n");
}
printf("\t\tinst = (%s)(gen->ptr);\n", gensel_inst_type);
regs = 0;
imms = 0;
locals = 0;
index = 0;
scratch = 0;
pattern = clause->pattern;
while(pattern)
{
switch(pattern->option)
{
case GENSEL_PATT_ANY:
++index;
break;
case GENSEL_PATT_REG:
printf("\t\t%s = _jit_reg_info[_jit_regs_get_%s(®s)].cpu_reg;\n",
gensel_reg_names[regs], args[index]);
++regs;
++index;
break;
case GENSEL_PATT_LREG:
printf("\t\t%s = _jit_reg_info[_jit_regs_get_%s(®s)].cpu_reg;\n",
gensel_reg_names[regs], args[index]);
printf("\t\t%s = _jit_reg_info[_jit_regs_get_%s_other(®s)].cpu_reg;\n",
gensel_other_reg_names[regs], args[index]);
++regs;
++index;
break;
case GENSEL_PATT_IMMZERO:
++index;
break;
case GENSEL_PATT_IMM:
case GENSEL_PATT_IMMS8:
case GENSEL_PATT_IMMU8:
case GENSEL_PATT_IMMS16:
case GENSEL_PATT_IMMU16:
case GENSEL_PATT_IMMS32:
case GENSEL_PATT_IMMU32:
printf("\t\t%s = insn->%s->address;\n",
gensel_imm_names[imms], args[index]);
++imms;
++index;
break;
case GENSEL_PATT_LOCAL:
case GENSEL_PATT_FRAME:
printf("\t\t%s = insn->%s->frame_offset;\n",
gensel_local_names[locals], args[index]);
++locals;
++index;
break;
case GENSEL_PATT_SCRATCH:
printf("\t\t%s = _jit_reg_info[_jit_regs_get_scratch(®s, %d)].cpu_reg;\n",
gensel_reg_names[regs], scratch);
++regs;
++scratch;
++index;
break;
}
pattern = pattern->next;
}
gensel_build_var_index(clause->pattern, names, other_names);
gensel_output_clause_code(clause, names, other_names, free_dest);
if(gensel_new_inst_type)
{
printf("\t\tjit_gen_save_inst_ptr(gen, inst);\n");
}
else
{
printf("\t\tgen->ptr = (unsigned char *)inst;\n");
}
if(contains_registers)
{
printf("\t\t_jit_regs_commit(gen, ®s);\n");
}
printf("\t}\n");
first = 0;
clause = clause->next;
}
}
static char **supported = 0;
static char **supported_options = 0;
static int num_supported = 0;
static void gensel_add_supported(char *name, char *option)
{
supported = (char **)realloc
(supported, (num_supported + 1) * sizeof(char *));
if(!supported)
{
exit(1);
}
supported[num_supported] = name;
supported_options = (char **)realloc
(supported_options, (num_supported + 1) * sizeof(char *));
if(!supported_options)
{
exit(1);
}
supported_options[num_supported++] = option;
}
static void gensel_output_supported(void)
{
int index;
for(index = 0; index < num_supported; ++index)
{
if(supported_options[index])
{
if(supported_options[index][0] == '!')
{
printf("#ifndef %s\n", supported_options[index] + 1);
}
else
{
printf("#ifdef %s\n", supported_options[index]);
}
printf("case %s:\n", supported[index]);
printf("#endif\n");
}
else
{
printf("case %s:\n", supported[index]);
}
}
printf("\treturn 1;\n\n");
}
#line 1687 "gen-rules-parser.c"
# ifndef YY_NULLPTR
# if defined __cplusplus && 201103L <= __cplusplus
# define YY_NULLPTR nullptr
# else
# define YY_NULLPTR 0
# endif
# endif
#ifdef YYERROR_VERBOSE
# undef YYERROR_VERBOSE
# define YYERROR_VERBOSE 1
#else
# define YYERROR_VERBOSE 1
#endif
#ifndef YY_YY_GEN_RULES_PARSER_H_INCLUDED
# define YY_YY_GEN_RULES_PARSER_H_INCLUDED
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
#if YYDEBUG
extern int yydebug;
#endif
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
enum yytokentype
{
IDENTIFIER = 258,
CODE_BLOCK = 259,
LITERAL = 260,
K_PTR = 261,
K_ANY = 262,
K_ALL = 263,
K_IMM = 264,
K_IMMZERO = 265,
K_IMMS8 = 266,
K_IMMU8 = 267,
K_IMMS16 = 268,
K_IMMU16 = 269,
K_IMMS32 = 270,
K_IMMU32 = 271,
K_LOCAL = 272,
K_FRAME = 273,
K_NOTE = 274,
K_TERNARY = 275,
K_BRANCH = 276,
K_COPY = 277,
K_COMMUTATIVE = 278,
K_IF = 279,
K_CLOBBER = 280,
K_SCRATCH = 281,
K_SPACE = 282,
K_STACK = 283,
K_X87_ARITH = 284,
K_X87_ARITH_REVERSIBLE = 285,
K_INST_TYPE = 286,
K_REG_CLASS = 287,
K_LREG_CLASS = 288,
K_MANUAL = 289,
K_MORE_SPACE = 290
};
#endif
#define IDENTIFIER 258
#define CODE_BLOCK 259
#define LITERAL 260
#define K_PTR 261
#define K_ANY 262
#define K_ALL 263
#define K_IMM 264
#define K_IMMZERO 265
#define K_IMMS8 266
#define K_IMMU8 267
#define K_IMMS16 268
#define K_IMMU16 269
#define K_IMMS32 270
#define K_IMMU32 271
#define K_LOCAL 272
#define K_FRAME 273
#define K_NOTE 274
#define K_TERNARY 275
#define K_BRANCH 276
#define K_COPY 277
#define K_COMMUTATIVE 278
#define K_IF 279
#define K_CLOBBER 280
#define K_SCRATCH 281
#define K_SPACE 282
#define K_STACK 283
#define K_X87_ARITH 284
#define K_X87_ARITH_REVERSIBLE 285
#define K_INST_TYPE 286
#define K_REG_CLASS 287
#define K_LREG_CLASS 288
#define K_MANUAL 289
#define K_MORE_SPACE 290
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
union YYSTYPE
{
#line 1625 "gen-rules-parser.y"
int tag;
char *name;
struct gensel_value *value;
struct gensel_option *option;
struct
{
char *filename;
long linenum;
char *block;
} code;
struct
{
struct gensel_value *head;
struct gensel_value *tail;
} values;
struct
{
struct gensel_option *head;
struct gensel_option *tail;
} options;
struct
{
struct gensel_clause *head;
struct gensel_clause *tail;
} clauses;
#line 1829 "gen-rules-parser.c"
};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
#endif
extern YYSTYPE yylval;
int yyparse (void);
#endif
#line 1846 "gen-rules-parser.c"
#ifdef short
# undef short
#endif
#ifdef YYTYPE_UINT8
typedef YYTYPE_UINT8 yytype_uint8;
#else
typedef unsigned char yytype_uint8;
#endif
#ifdef YYTYPE_INT8
typedef YYTYPE_INT8 yytype_int8;
#else
typedef signed char yytype_int8;
#endif
#ifdef YYTYPE_UINT16
typedef YYTYPE_UINT16 yytype_uint16;
#else
typedef unsigned short int yytype_uint16;
#endif
#ifdef YYTYPE_INT16
typedef YYTYPE_INT16 yytype_int16;
#else
typedef short int yytype_int16;
#endif
#ifndef YYSIZE_T
# ifdef __SIZE_TYPE__
# define YYSIZE_T __SIZE_TYPE__
# elif defined size_t
# define YYSIZE_T size_t
# elif ! defined YYSIZE_T
# include <stddef.h>
# define YYSIZE_T size_t
# else
# define YYSIZE_T unsigned int
# endif
#endif
#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
#ifndef YY_
# if defined YYENABLE_NLS && YYENABLE_NLS
# if ENABLE_NLS
# include <libintl.h>
# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
# endif
# endif
# ifndef YY_
# define YY_(Msgid) Msgid
# endif
#endif
#ifndef YY_ATTRIBUTE
# if (defined __GNUC__ \
&& (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
|| defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
# define YY_ATTRIBUTE(Spec) __attribute__(Spec)
# else
# define YY_ATTRIBUTE(Spec)
# endif
#endif
#ifndef YY_ATTRIBUTE_PURE
# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
#endif
#ifndef YY_ATTRIBUTE_UNUSED
# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
#endif
#if !defined _Noreturn \
&& (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
# if defined _MSC_VER && 1200 <= _MSC_VER
# define _Noreturn __declspec (noreturn)
# else
# define _Noreturn YY_ATTRIBUTE ((__noreturn__))
# endif
#endif
#if ! defined lint || defined __GNUC__
# define YYUSE(E) ((void) (E))
#else
# define YYUSE(E)
#endif
#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
_Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
_Pragma ("GCC diagnostic pop")
#else
# define YY_INITIAL_VALUE(Value) Value
#endif
#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
# define YY_IGNORE_MAYBE_UNINITIALIZED_END
#endif
#ifndef YY_INITIAL_VALUE
# define YY_INITIAL_VALUE(Value)
#endif
#if ! defined yyoverflow || YYERROR_VERBOSE
# ifdef YYSTACK_USE_ALLOCA
# if YYSTACK_USE_ALLOCA
# ifdef __GNUC__
# define YYSTACK_ALLOC __builtin_alloca
# elif defined __BUILTIN_VA_ARG_INCR
# include <alloca.h>
# elif defined _AIX
# define YYSTACK_ALLOC __alloca
# elif defined _MSC_VER
# include <malloc.h>
# define alloca _alloca
# else
# define YYSTACK_ALLOC alloca
# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
# include <stdlib.h>
# ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
# endif
# endif
# endif
# endif
# endif
# ifdef YYSTACK_ALLOC
# define YYSTACK_FREE(Ptr) do { ; } while (0)
# ifndef YYSTACK_ALLOC_MAXIMUM
# define YYSTACK_ALLOC_MAXIMUM 4032
# endif
# else
# define YYSTACK_ALLOC YYMALLOC
# define YYSTACK_FREE YYFREE
# ifndef YYSTACK_ALLOC_MAXIMUM
# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
# endif
# if (defined __cplusplus && ! defined EXIT_SUCCESS \
&& ! ((defined YYMALLOC || defined malloc) \
&& (defined YYFREE || defined free)))
# include <stdlib.h>
# ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
# endif
# endif
# ifndef YYMALLOC
# define YYMALLOC malloc
# if ! defined malloc && ! defined EXIT_SUCCESS
void *malloc (YYSIZE_T);
# endif
# endif
# ifndef YYFREE
# define YYFREE free
# if ! defined free && ! defined EXIT_SUCCESS
void free (void *);
# endif
# endif
# endif
#endif
#if (! defined yyoverflow \
&& (! defined __cplusplus \
|| (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
union yyalloc
{
yytype_int16 yyss_alloc;
YYSTYPE yyvs_alloc;
};
# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
# define YYSTACK_BYTES(N) \
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ YYSTACK_GAP_MAXIMUM)
# define YYCOPY_NEEDED 1
# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
do \
{ \
YYSIZE_T yynewbytes; \
YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
Stack = &yyptr->Stack_alloc; \
yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
yyptr += yynewbytes / sizeof (*yyptr); \
} \
while (0)
#endif
#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
# ifndef YYCOPY
# if defined __GNUC__ && 1 < __GNUC__
# define YYCOPY(Dst, Src, Count) \
__builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
# else
# define YYCOPY(Dst, Src, Count) \
do \
{ \
YYSIZE_T yyi; \
for (yyi = 0; yyi < (Count); yyi++) \
(Dst)[yyi] = (Src)[yyi]; \
} \
while (0)
# endif
# endif
#endif
#define YYFINAL 12
#define YYLAST 101
#define YYNTOKENS 45
#define YYNNTS 23
#define YYNRULES 69
#define YYNSTATES 102
#define YYUNDEFTOK 2
#define YYMAXUTOK 290
#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
static const yytype_uint8 yytranslate[] =
{
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
38, 39, 43, 44, 37, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 36, 2,
2, 42, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 40, 2, 41, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
35
};
#if YYDEBUG
static const yytype_uint16 yyrline[] =
{
0, 1717, 1717, 1719, 1723, 1724, 1728, 1750, 1754, 1757,
1763, 1764, 1780, 1781, 1785, 1789, 1793, 1801, 1807, 1808,
1816, 1835, 1839, 1843, 1851, 1854, 1857, 1860, 1871, 1882,
1893, 1896, 1899, 1905, 1908, 1914, 1918, 1926, 1927, 1931,
1937, 1943, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958,
1961, 1962, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973,
1974, 1975, 1976, 1980, 1981, 1985, 1986, 1987, 1991, 1992
};
#endif
#if YYDEBUG || YYERROR_VERBOSE || 1
static const char *const yytname[] =
{
"$end", "error", "$undefined", "\"an identifier\"", "\"a code block\"",
"\"literal string\"", "\"`->'\"", "\"any value\"", "\"all registers\"",
"\"immediate value\"", "\"immediate zero value\"",
"\"immediate signed 8-bit value\"", "\"immediate unsigned 8-bit value\"",
"\"immediate signed 16-bit value\"",
"\"immediate unsigned 16-bit value\"",
"\"immediate signed 32-bit value\"",
"\"immediate unsigned 32-bit value\"", "\"local variable\"",
"\"local variable forced out into the stack frame\"", "\"`note'\"",
"\"`ternary'\"", "\"`branch'\"", "\"`copy'\"", "\"`commutative'\"",
"\"`if'\"", "\"`clobber'\"", "\"`scratch'\"", "\"`space'\"",
"\"`stack'\"", "\"`x87_arith'\"", "\"`x87_arith_reversible'\"",
"\"`%inst_type'\"", "\"`%reg_class'\"", "\"`%lreg_class'\"",
"\"`manual'\"", "\"`more_space'\"", "':'", "','", "'('", "')'", "'['",
"']'", "'='", "'*'", "'+'", "$accept", "Start", "Rules", "Rule",
"IdentifierList", "IfClause", "Options", "Option", "Clauses", "Clause",
"Pattern", "PatternElement", "ClobberSpec", "ClobberList",
"ClobberEntry", "RegClass", "Value", "ValuePair", "OptionTag",
"InputTag", "DestFlag", "RegFlag", "Literal", YY_NULLPTR
};
#endif
# ifdef YYPRINT
static const yytype_uint16 yytoknum[] =
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
285, 286, 287, 288, 289, 290, 58, 44, 40, 41,
91, 93, 61, 42, 43
};
# endif
#define YYPACT_NINF -37
#define yypact_value_is_default(Yystate) \
(!!((Yystate) == (-37)))
#define YYTABLE_NINF -66
#define yytable_value_is_error(Yytable_value) \
0
static const yytype_int8 yypact[] =
{
16, -37, 23, 34, 35, 39, 16, -37, -35, -37,
49, 65, -37, -37, 66, 70, 40, -37, -37, -37,
41, 36, -37, -37, -37, -37, -37, -37, -37, -37,
-37, -37, -37, -20, -37, -37, 36, 33, 38, -37,
-37, -37, -3, -37, -37, -37, -37, -37, -37, -37,
-37, -37, -37, -37, -37, 43, 44, 80, 46, -37,
-37, -36, -37, -37, 80, 81, 69, -37, 47, 81,
18, 82, 51, -37, 48, 85, -37, 52, 55, -37,
-37, -37, 81, 54, -37, 90, 81, -37, -37, -37,
13, 56, -37, -37, 15, 57, -37, -37, 81, -37,
-37, -37
};
static const yytype_uint8 yydefact[] =
{
2, 10, 0, 0, 0, 0, 3, 4, 12, 7,
0, 0, 1, 5, 0, 0, 0, 8, 9, 11,
0, 14, 13, 44, 42, 43, 45, 46, 47, 48,
49, 50, 51, 0, 15, 17, 0, 63, 6, 18,
16, 64, 21, 19, 62, 52, 53, 54, 55, 56,
57, 58, 59, 60, 61, 0, 0, 0, 0, 66,
67, 0, 22, 24, 0, 0, 0, 39, 28, 0,
65, 0, 25, 68, 0, 40, 33, 0, 34, 35,
37, 38, 0, 0, 23, 0, 0, 31, 69, 30,
0, 0, 32, 20, 0, 0, 36, 29, 0, 26,
27, 41
};
static const yytype_int8 yypgoto[] =
{
-37, -37, -37, 91, -37, -37, -37, 62, -37, 61,
-37, 30, -37, -37, 11, -4, -19, -37, -37, -37,
-37, -37, -37
};
static const yytype_int8 yydefgoto[] =
{
-1, 5, 6, 7, 8, 16, 33, 34, 38, 39,
61, 62, 77, 78, 79, 80, 81, 95, 35, 63,
42, 64, 75
};
static const yytype_int8 yytable[] =
{
-65, 70, 14, 15, 44, 71, 45, 46, 47, 48,
49, 50, 51, 52, 53, 54, 67, 36, 73, 1,
37, 55, 56, 57, 58, 44, 9, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 10, 11, 12,
59, 60, 55, 56, 57, 58, 74, 2, 3, 4,
83, 98, 17, 68, 99, 23, 24, 25, 26, 27,
72, 59, 60, 91, 28, 29, 30, 94, 18, 19,
31, 32, 67, 20, 73, 41, 21, 76, 37, 101,
22, 65, 66, 67, 69, 82, 73, 87, 85, 86,
88, 89, 90, 92, 93, 97, 100, 13, 40, 43,
84, 96
};
static const yytype_uint8 yycheck[] =
{
3, 37, 37, 38, 7, 41, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 3, 37, 5, 3,
40, 24, 25, 26, 27, 7, 3, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18, 3, 3, 0,
43, 44, 24, 25, 26, 27, 65, 31, 32, 33,
69, 36, 3, 57, 39, 19, 20, 21, 22, 23,
64, 43, 44, 82, 28, 29, 30, 86, 3, 3,
34, 35, 3, 3, 5, 42, 36, 8, 40, 98,
39, 38, 38, 3, 38, 38, 5, 39, 6, 38,
5, 39, 37, 39, 4, 39, 39, 6, 36, 38,
70, 90
};
static const yytype_uint8 yystos[] =
{
0, 3, 31, 32, 33, 46, 47, 48, 49, 3,
3, 3, 0, 48, 37, 38, 50, 3, 3, 3,
3, 36, 39, 19, 20, 21, 22, 23, 28, 29,
30, 34, 35, 51, 52, 63, 37, 40, 53, 54,
52, 42, 65, 54, 7, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 24, 25, 26, 27, 43,
44, 55, 56, 64, 66, 38, 38, 3, 60, 38,
37, 41, 60, 5, 61, 67, 8, 57, 58, 59,
60, 61, 38, 61, 56, 6, 38, 39, 5, 39,
37, 61, 39, 4, 61, 62, 59, 39, 36, 39,
39, 61
};
static const yytype_uint8 yyr1[] =
{
0, 45, 46, 46, 47, 47, 48, 48, 48, 48,
49, 49, 50, 50, 51, 51, 51, 52, 53, 53,
54, 55, 55, 55, 56, 56, 56, 56, 56, 56,
56, 56, 56, 57, 57, 58, 58, 59, 59, 60,
61, 62, 63, 63, 63, 63, 63, 63, 63, 63,
63, 63, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 65, 65, 66, 66, 66, 67, 67
};
static const yytype_uint8 yyr2[] =
{
0, 2, 0, 1, 1, 2, 5, 2, 3, 3,
1, 3, 0, 3, 0, 1, 3, 1, 1, 2,
6, 0, 1, 3, 1, 2, 5, 5, 2, 5,
4, 4, 4, 1, 1, 1, 3, 1, 1, 1,
1, 3, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 1, 0, 1, 1, 1, 2
};
#define yyerrok (yyerrstatus = 0)
#define yyclearin (yychar = YYEMPTY)
#define YYEMPTY (-2)
#define YYEOF 0
#define YYACCEPT goto yyacceptlab
#define YYABORT goto yyabortlab
#define YYERROR goto yyerrorlab
#define YYRECOVERING() (!!yyerrstatus)
#define YYBACKUP(Token, Value) \
do \
if (yychar == YYEMPTY) \
{ \
yychar = (Token); \
yylval = (Value); \
YYPOPSTACK (yylen); \
yystate = *yyssp; \
goto yybackup; \
} \
else \
{ \
yyerror (YY_("syntax error: cannot back up")); \
YYERROR; \
} \
while (0)
#define YYTERROR 1
#define YYERRCODE 256
#if YYDEBUG
# ifndef YYFPRINTF
# include <stdio.h>
# define YYFPRINTF fprintf
# endif
# define YYDPRINTF(Args) \
do { \
if (yydebug) \
YYFPRINTF Args; \
} while (0)
#ifndef YY_LOCATION_PRINT
# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
#endif
# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
do { \
if (yydebug) \
{ \
YYFPRINTF (stderr, "%s ", Title); \
yy_symbol_print (stderr, \
Type, Value); \
YYFPRINTF (stderr, "\n"); \
} \
} while (0)
static void
yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
{
FILE *yyo = yyoutput;
YYUSE (yyo);
if (!yyvaluep)
return;
# ifdef YYPRINT
if (yytype < YYNTOKENS)
YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
# endif
YYUSE (yytype);
}
static void
yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
{
YYFPRINTF (yyoutput, "%s %s (",
yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
yy_symbol_value_print (yyoutput, yytype, yyvaluep);
YYFPRINTF (yyoutput, ")");
}
static void
yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
{
YYFPRINTF (stderr, "Stack now");
for (; yybottom <= yytop; yybottom++)
{
int yybot = *yybottom;
YYFPRINTF (stderr, " %d", yybot);
}
YYFPRINTF (stderr, "\n");
}
# define YY_STACK_PRINT(Bottom, Top) \
do { \
if (yydebug) \
yy_stack_print ((Bottom), (Top)); \
} while (0)
static void
yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule)
{
unsigned long int yylno = yyrline[yyrule];
int yynrhs = yyr2[yyrule];
int yyi;
YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
yyrule - 1, yylno);
for (yyi = 0; yyi < yynrhs; yyi++)
{
YYFPRINTF (stderr, " $%d = ", yyi + 1);
yy_symbol_print (stderr,
yystos[yyssp[yyi + 1 - yynrhs]],
&(yyvsp[(yyi + 1) - (yynrhs)])
);
YYFPRINTF (stderr, "\n");
}
}
# define YY_REDUCE_PRINT(Rule) \
do { \
if (yydebug) \
yy_reduce_print (yyssp, yyvsp, Rule); \
} while (0)
int yydebug;
#else
# define YYDPRINTF(Args)
# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
# define YY_STACK_PRINT(Bottom, Top)
# define YY_REDUCE_PRINT(Rule)
#endif
#ifndef YYINITDEPTH
# define YYINITDEPTH 200
#endif
#ifndef YYMAXDEPTH
# define YYMAXDEPTH 10000
#endif
#if YYERROR_VERBOSE
# ifndef yystrlen
# if defined __GLIBC__ && defined _STRING_H
# define yystrlen strlen
# else
static YYSIZE_T
yystrlen (const char *yystr)
{
YYSIZE_T yylen;
for (yylen = 0; yystr[yylen]; yylen++)
continue;
return yylen;
}
# endif
# endif
# ifndef yystpcpy
# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
# define yystpcpy stpcpy
# else
static char *
yystpcpy (char *yydest, const char *yysrc)
{
char *yyd = yydest;
const char *yys = yysrc;
while ((*yyd++ = *yys++) != '\0')
continue;
return yyd - 1;
}
# endif
# endif
# ifndef yytnamerr
static YYSIZE_T
yytnamerr (char *yyres, const char *yystr)
{
if (*yystr == '"')
{
YYSIZE_T yyn = 0;
char const *yyp = yystr;
for (;;)
switch (*++yyp)
{
case '\'':
case ',':
goto do_not_strip_quotes;
case '\\':
if (*++yyp != '\\')
goto do_not_strip_quotes;
default:
if (yyres)
yyres[yyn] = *yyp;
yyn++;
break;
case '"':
if (yyres)
yyres[yyn] = '\0';
return yyn;
}
do_not_strip_quotes: ;
}
if (! yyres)
return yystrlen (yystr);
return yystpcpy (yyres, yystr) - yyres;
}
# endif
static int
yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
yytype_int16 *yyssp, int yytoken)
{
YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
YYSIZE_T yysize = yysize0;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
const char *yyformat = YY_NULLPTR;
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
int yycount = 0;
if (yytoken != YYEMPTY)
{
int yyn = yypact[*yyssp];
yyarg[yycount++] = yytname[yytoken];
if (!yypact_value_is_default (yyn))
{
int yyxbegin = yyn < 0 ? -yyn : 0;
int yychecklim = YYLAST - yyn + 1;
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
int yyx;
for (yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
&& !yytable_value_is_error (yytable[yyx + yyn]))
{
if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
{
yycount = 1;
yysize = yysize0;
break;
}
yyarg[yycount++] = yytname[yyx];
{
YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
if (! (yysize <= yysize1
&& yysize1 <= YYSTACK_ALLOC_MAXIMUM))
return 2;
yysize = yysize1;
}
}
}
}
switch (yycount)
{
# define YYCASE_(N, S) \
case N: \
yyformat = S; \
break
YYCASE_(0, YY_("syntax error"));
YYCASE_(1, YY_("syntax error, unexpected %s"));
YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
# undef YYCASE_
}
{
YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
return 2;
yysize = yysize1;
}
if (*yymsg_alloc < yysize)
{
*yymsg_alloc = 2 * yysize;
if (! (yysize <= *yymsg_alloc
&& *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
*yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
return 1;
}
{
char *yyp = *yymsg;
int yyi = 0;
while ((*yyp = *yyformat) != '\0')
if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
{
yyp += yytnamerr (yyp, yyarg[yyi++]);
yyformat += 2;
}
else
{
yyp++;
yyformat++;
}
}
return 0;
}
#endif
static void
yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
{
YYUSE (yyvaluep);
if (!yymsg)
yymsg = "Deleting";
YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
YYUSE (yytype);
YY_IGNORE_MAYBE_UNINITIALIZED_END
}
int yychar;
YYSTYPE yylval;
int yynerrs;
int
yyparse (void)
{
int yystate;
int yyerrstatus;
yytype_int16 yyssa[YYINITDEPTH];
yytype_int16 *yyss;
yytype_int16 *yyssp;
YYSTYPE yyvsa[YYINITDEPTH];
YYSTYPE *yyvs;
YYSTYPE *yyvsp;
YYSIZE_T yystacksize;
int yyn;
int yyresult;
int yytoken = 0;
YYSTYPE yyval;
#if YYERROR_VERBOSE
char yymsgbuf[128];
char *yymsg = yymsgbuf;
YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
#endif
#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
int yylen = 0;
yyssp = yyss = yyssa;
yyvsp = yyvs = yyvsa;
yystacksize = YYINITDEPTH;
YYDPRINTF ((stderr, "Starting parse\n"));
yystate = 0;
yyerrstatus = 0;
yynerrs = 0;
yychar = YYEMPTY;
goto yysetstate;
yynewstate:
yyssp++;
yysetstate:
*yyssp = yystate;
if (yyss + yystacksize - 1 <= yyssp)
{
YYSIZE_T yysize = yyssp - yyss + 1;
#ifdef yyoverflow
{
YYSTYPE *yyvs1 = yyvs;
yytype_int16 *yyss1 = yyss;
yyoverflow (YY_("memory exhausted"),
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),
&yystacksize);
yyss = yyss1;
yyvs = yyvs1;
}
#else
# ifndef YYSTACK_RELOCATE
goto yyexhaustedlab;
# else
if (YYMAXDEPTH <= yystacksize)
goto yyexhaustedlab;
yystacksize *= 2;
if (YYMAXDEPTH < yystacksize)
yystacksize = YYMAXDEPTH;
{
yytype_int16 *yyss1 = yyss;
union yyalloc *yyptr =
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
if (! yyptr)
goto yyexhaustedlab;
YYSTACK_RELOCATE (yyss_alloc, yyss);
YYSTACK_RELOCATE (yyvs_alloc, yyvs);
# undef YYSTACK_RELOCATE
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
}
# endif
#endif
yyssp = yyss + yysize - 1;
yyvsp = yyvs + yysize - 1;
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
(unsigned long int) yystacksize));
if (yyss + yystacksize - 1 <= yyssp)
YYABORT;
}
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
if (yystate == YYFINAL)
YYACCEPT;
goto yybackup;
yybackup:
yyn = yypact[yystate];
if (yypact_value_is_default (yyn))
goto yydefault;
if (yychar == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token: "));
yychar = yylex ();
}
if (yychar <= YYEOF)
{
yychar = yytoken = YYEOF;
YYDPRINTF ((stderr, "Now at end of input.\n"));
}
else
{
yytoken = YYTRANSLATE (yychar);
YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
}
yyn += yytoken;
if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
goto yydefault;
yyn = yytable[yyn];
if (yyn <= 0)
{
if (yytable_value_is_error (yyn))
goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
if (yyerrstatus)
yyerrstatus--;
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
yychar = YYEMPTY;
yystate = yyn;
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
YY_IGNORE_MAYBE_UNINITIALIZED_END
goto yynewstate;
yydefault:
yyn = yydefact[yystate];
if (yyn == 0)
goto yyerrlab;
goto yyreduce;
yyreduce:
yylen = yyr2[yyn];
yyval = yyvsp[1-yylen];
YY_REDUCE_PRINT (yyn);
switch (yyn)
{
case 6:
#line 1728 "gen-rules-parser.y"
{
if((yyvsp[-3].name))
{
if(((yyvsp[-3].name))[0] == '!')
{
printf("#ifndef %s\n\n", (yyvsp[-3].name) + 1);
}
else
{
printf("#ifdef %s\n\n", (yyvsp[-3].name));
}
}
printf("case %s:\n{\n", (yyvsp[-4].name));
gensel_output_clauses((yyvsp[0].clauses).head, (yyvsp[-1].options).head);
printf("}\nbreak;\n\n");
if((yyvsp[-3].name))
{
printf("#endif /* %s */\n\n", (yyvsp[-3].name));
}
gensel_free_clauses((yyvsp[0].clauses).head);
gensel_add_supported((yyvsp[-4].name), (yyvsp[-3].name));
}
#line 3029 "gen-rules-parser.c"
break;
case 7:
#line 1750 "gen-rules-parser.y"
{
gensel_inst_type = (yyvsp[0].name);
gensel_new_inst_type = 1;
}
#line 3038 "gen-rules-parser.c"
break;
case 8:
#line 1754 "gen-rules-parser.y"
{
gensel_create_regclass((yyvsp[-1].name), (yyvsp[0].name), 0);
}
#line 3046 "gen-rules-parser.c"
break;
case 9:
#line 1757 "gen-rules-parser.y"
{
gensel_create_regclass((yyvsp[-1].name), (yyvsp[0].name), 1);
}
#line 3054 "gen-rules-parser.c"
break;
case 10:
#line 1763 "gen-rules-parser.y"
{ (yyval.name) = (yyvsp[0].name); }
#line 3060 "gen-rules-parser.c"
break;
case 11:
#line 1764 "gen-rules-parser.y"
{
char *result = (char *)malloc(strlen((yyvsp[-2].name)) + strlen((yyvsp[0].name)) + 16);
if(!result)
{
exit(1);
}
strcpy(result, (yyvsp[-2].name));
strcat(result, ":\ncase ");
strcat(result, (yyvsp[0].name));
free((yyvsp[-2].name));
free((yyvsp[0].name));
(yyval.name) = result;
}
#line 3078 "gen-rules-parser.c"
break;
case 12:
#line 1780 "gen-rules-parser.y"
{ (yyval.name) = 0; }
#line 3084 "gen-rules-parser.c"
break;
case 13:
#line 1781 "gen-rules-parser.y"
{ (yyval.name) = (yyvsp[-1].name); }
#line 3090 "gen-rules-parser.c"
break;
case 14:
#line 1785 "gen-rules-parser.y"
{
(yyval.options).head = 0;
(yyval.options).tail = 0;
}
#line 3099 "gen-rules-parser.c"
break;
case 15:
#line 1789 "gen-rules-parser.y"
{
(yyval.options).head = (yyvsp[0].option);
(yyval.options).tail = (yyvsp[0].option);
}
#line 3108 "gen-rules-parser.c"
break;
case 16:
#line 1793 "gen-rules-parser.y"
{
(yyvsp[-2].options).tail->next = (yyvsp[0].option);
(yyval.options).head = (yyvsp[-2].options).head;
(yyval.options).tail = (yyvsp[0].option);
}
#line 3118 "gen-rules-parser.c"
break;
case 17:
#line 1801 "gen-rules-parser.y"
{
(yyval.option) = gensel_create_option((yyvsp[0].tag), 0);
}
#line 3126 "gen-rules-parser.c"
break;
case 18:
#line 1807 "gen-rules-parser.y"
{ (yyval.clauses) = (yyvsp[0].clauses); }
#line 3132 "gen-rules-parser.c"
break;
case 19:
#line 1808 "gen-rules-parser.y"
{
(yyvsp[-1].clauses).tail->next = (yyvsp[0].clauses).head;
(yyval.clauses).head = (yyvsp[-1].clauses).head;
(yyval.clauses).tail = (yyvsp[0].clauses).tail;
}
#line 3142 "gen-rules-parser.c"
break;
case 20:
#line 1816 "gen-rules-parser.y"
{
gensel_clause_t clause;
clause = (gensel_clause_t)malloc(sizeof(struct gensel_clause));
if(!clause)
{
exit(1);
}
clause->dest = (yyvsp[-4].tag);
clause->pattern = (yyvsp[-3].options).head;
clause->filename = (yyvsp[0].code).filename;
clause->linenum = (yyvsp[0].code).linenum;
clause->code = (yyvsp[0].code).block;
clause->next = 0;
(yyval.clauses).head = clause;
(yyval.clauses).tail = clause;
}
#line 3163 "gen-rules-parser.c"
break;
case 21:
#line 1835 "gen-rules-parser.y"
{
(yyval.options).head = 0;
(yyval.options).tail = 0;
}
#line 3172 "gen-rules-parser.c"
break;
case 22:
#line 1839 "gen-rules-parser.y"
{
(yyval.options).head = (yyvsp[0].option);
(yyval.options).tail = (yyvsp[0].option);
}
#line 3181 "gen-rules-parser.c"
break;
case 23:
#line 1843 "gen-rules-parser.y"
{
(yyvsp[-2].options).tail->next = (yyvsp[0].option);
(yyval.options).head = (yyvsp[-2].options).head;
(yyval.options).tail = (yyvsp[0].option);
}
#line 3191 "gen-rules-parser.c"
break;
case 24:
#line 1851 "gen-rules-parser.y"
{
(yyval.option) = gensel_create_option((yyvsp[0].tag), 0);
}
#line 3199 "gen-rules-parser.c"
break;
case 25:
#line 1854 "gen-rules-parser.y"
{
(yyval.option) = gensel_create_register((yyvsp[-1].tag), (yyvsp[0].value), 0);
}
#line 3207 "gen-rules-parser.c"
break;
case 26:
#line 1857 "gen-rules-parser.y"
{
(yyval.option) = gensel_create_register((yyvsp[-4].tag), (yyvsp[-3].value), (yyvsp[-1].value));
}
#line 3215 "gen-rules-parser.c"
break;
case 27:
#line 1860 "gen-rules-parser.y"
{
gensel_regclass_t regclass;
regclass = (yyvsp[-3].value)->value;
if(!regclass->is_long)
{
gensel_error(
gensel_filename, gensel_linenum,
"not a long pair register");
}
(yyval.option) = gensel_create_register((yyvsp[-4].tag), (yyvsp[-3].value), (yyvsp[-1].values).head);
}
#line 3231 "gen-rules-parser.c"
break;
case 28:
#line 1871 "gen-rules-parser.y"
{
gensel_regclass_t regclass;
regclass = (yyvsp[0].value)->value;
if(regclass->is_long)
{
gensel_error(
gensel_filename, gensel_linenum,
"scratch register cannot be a long pair");
}
(yyval.option) = gensel_create_scratch((yyvsp[0].value), 0);
}
#line 3247 "gen-rules-parser.c"
break;
case 29:
#line 1882 "gen-rules-parser.y"
{
gensel_regclass_t regclass;
regclass = (yyvsp[-3].value)->value;
if(regclass->is_long)
{
gensel_error(
gensel_filename, gensel_linenum,
"scratch register cannot be a long pair");
}
(yyval.option) = gensel_create_scratch((yyvsp[-3].value), (yyvsp[-1].value));
}
#line 3263 "gen-rules-parser.c"
break;
case 30:
#line 1893 "gen-rules-parser.y"
{
(yyval.option) = gensel_create_option(GENSEL_PATT_CLOBBER, (yyvsp[-1].values).head);
}
#line 3271 "gen-rules-parser.c"
break;
case 31:
#line 1896 "gen-rules-parser.y"
{
(yyval.option) = gensel_create_option(GENSEL_PATT_IF, (yyvsp[-1].value));
}
#line 3279 "gen-rules-parser.c"
break;
case 32:
#line 1899 "gen-rules-parser.y"
{
(yyval.option) = gensel_create_option(GENSEL_PATT_SPACE, (yyvsp[-1].value));
}
#line 3287 "gen-rules-parser.c"
break;
case 33:
#line 1905 "gen-rules-parser.y"
{
(yyval.values).head = (yyval.values).tail = gensel_create_value(GENSEL_VALUE_ALL);
}
#line 3295 "gen-rules-parser.c"
break;
case 34:
#line 1908 "gen-rules-parser.y"
{
(yyval.values) = (yyvsp[0].values);
}
#line 3303 "gen-rules-parser.c"
break;
case 35:
#line 1914 "gen-rules-parser.y"
{
(yyval.values).head = (yyvsp[0].value);
(yyval.values).tail = (yyvsp[0].value);
}
#line 3312 "gen-rules-parser.c"
break;
case 36:
#line 1918 "gen-rules-parser.y"
{
(yyvsp[-2].values).tail->next = (yyvsp[0].value);
(yyval.values).head = (yyvsp[-2].values).head;
(yyval.values).tail = (yyvsp[0].value);
}
#line 3322 "gen-rules-parser.c"
break;
case 37:
#line 1926 "gen-rules-parser.y"
{ (yyval.value) = (yyvsp[0].value); }
#line 3328 "gen-rules-parser.c"
break;
case 38:
#line 1927 "gen-rules-parser.y"
{ (yyval.value) = (yyvsp[0].value); }
#line 3334 "gen-rules-parser.c"
break;
case 39:
#line 1931 "gen-rules-parser.y"
{
(yyval.value) = gensel_create_regclass_value((yyvsp[0].name));
}
#line 3342 "gen-rules-parser.c"
break;
case 40:
#line 1937 "gen-rules-parser.y"
{
(yyval.value) = gensel_create_string_value((yyvsp[0].name));
}
#line 3350 "gen-rules-parser.c"
break;
case 41:
#line 1943 "gen-rules-parser.y"
{
(yyvsp[-2].value)->next = (yyvsp[0].value);
(yyval.values).head = (yyvsp[-2].value);
(yyval.values).tail = (yyvsp[0].value);
}
#line 3360 "gen-rules-parser.c"
break;
case 42:
#line 1951 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_OPT_TERNARY; }
#line 3366 "gen-rules-parser.c"
break;
case 43:
#line 1952 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_OPT_BRANCH; }
#line 3372 "gen-rules-parser.c"
break;
case 44:
#line 1953 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_OPT_NOTE; }
#line 3378 "gen-rules-parser.c"
break;
case 45:
#line 1954 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_OPT_COPY; }
#line 3384 "gen-rules-parser.c"
break;
case 46:
#line 1955 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_OPT_COMMUTATIVE; }
#line 3390 "gen-rules-parser.c"
break;
case 47:
#line 1956 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_OPT_STACK; }
#line 3396 "gen-rules-parser.c"
break;
case 48:
#line 1957 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_OPT_X87_ARITH; }
#line 3402 "gen-rules-parser.c"
break;
case 49:
#line 1958 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_OPT_X87_ARITH_REVERSIBLE; }
#line 3408 "gen-rules-parser.c"
break;
case 50:
#line 1961 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_OPT_MANUAL; }
#line 3414 "gen-rules-parser.c"
break;
case 51:
#line 1962 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_OPT_MORE_SPACE; }
#line 3420 "gen-rules-parser.c"
break;
case 52:
#line 1966 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_PATT_IMM; }
#line 3426 "gen-rules-parser.c"
break;
case 53:
#line 1967 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_PATT_IMMZERO; }
#line 3432 "gen-rules-parser.c"
break;
case 54:
#line 1968 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_PATT_IMMS8; }
#line 3438 "gen-rules-parser.c"
break;
case 55:
#line 1969 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_PATT_IMMU8; }
#line 3444 "gen-rules-parser.c"
break;
case 56:
#line 1970 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_PATT_IMMS16; }
#line 3450 "gen-rules-parser.c"
break;
case 57:
#line 1971 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_PATT_IMMU16; }
#line 3456 "gen-rules-parser.c"
break;
case 58:
#line 1972 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_PATT_IMMS32; }
#line 3462 "gen-rules-parser.c"
break;
case 59:
#line 1973 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_PATT_IMMU32; }
#line 3468 "gen-rules-parser.c"
break;
case 60:
#line 1974 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_PATT_LOCAL; }
#line 3474 "gen-rules-parser.c"
break;
case 61:
#line 1975 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_PATT_FRAME; }
#line 3480 "gen-rules-parser.c"
break;
case 62:
#line 1976 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_PATT_ANY; }
#line 3486 "gen-rules-parser.c"
break;
case 63:
#line 1980 "gen-rules-parser.y"
{ (yyval.tag) = 0; }
#line 3492 "gen-rules-parser.c"
break;
case 64:
#line 1981 "gen-rules-parser.y"
{ (yyval.tag) = 1; }
#line 3498 "gen-rules-parser.c"
break;
case 65:
#line 1985 "gen-rules-parser.y"
{ (yyval.tag) = 0; }
#line 3504 "gen-rules-parser.c"
break;
case 66:
#line 1986 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_VALUE_CLOBBER; }
#line 3510 "gen-rules-parser.c"
break;
case 67:
#line 1987 "gen-rules-parser.y"
{ (yyval.tag) = GENSEL_VALUE_EARLY_CLOBBER; }
#line 3516 "gen-rules-parser.c"
break;
case 68:
#line 1991 "gen-rules-parser.y"
{ (yyval.name) = (yyvsp[0].name); }
#line 3522 "gen-rules-parser.c"
break;
case 69:
#line 1992 "gen-rules-parser.y"
{
char *cp = malloc(strlen((yyvsp[-1].name)) + strlen((yyvsp[0].name)) + 1);
if(!cp)
{
exit(1);
}
strcpy(cp, (yyvsp[-1].name));
strcat(cp, (yyvsp[0].name));
free((yyvsp[-1].name));
free((yyvsp[0].name));
(yyval.name) = cp;
}
#line 3539 "gen-rules-parser.c"
break;
#line 3543 "gen-rules-parser.c"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
YYPOPSTACK (yylen);
yylen = 0;
YY_STACK_PRINT (yyss, yyssp);
*++yyvsp = yyval;
yyn = yyr1[yyn];
yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
yystate = yytable[yystate];
else
yystate = yydefgoto[yyn - YYNTOKENS];
goto yynewstate;
yyerrlab:
yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
if (!yyerrstatus)
{
++yynerrs;
#if ! YYERROR_VERBOSE
yyerror (YY_("syntax error"));
#else
# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
yyssp, yytoken)
{
char const *yymsgp = YY_("syntax error");
int yysyntax_error_status;
yysyntax_error_status = YYSYNTAX_ERROR;
if (yysyntax_error_status == 0)
yymsgp = yymsg;
else if (yysyntax_error_status == 1)
{
if (yymsg != yymsgbuf)
YYSTACK_FREE (yymsg);
yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
if (!yymsg)
{
yymsg = yymsgbuf;
yymsg_alloc = sizeof yymsgbuf;
yysyntax_error_status = 2;
}
else
{
yysyntax_error_status = YYSYNTAX_ERROR;
yymsgp = yymsg;
}
}
yyerror (yymsgp);
if (yysyntax_error_status == 2)
goto yyexhaustedlab;
}
# undef YYSYNTAX_ERROR
#endif
}
if (yyerrstatus == 3)
{
if (yychar <= YYEOF)
{
if (yychar == YYEOF)
YYABORT;
}
else
{
yydestruct ("Error: discarding",
yytoken, &yylval);
yychar = YYEMPTY;
}
}
goto yyerrlab1;
yyerrorlab:
if ( 0)
goto yyerrorlab;
YYPOPSTACK (yylen);
yylen = 0;
YY_STACK_PRINT (yyss, yyssp);
yystate = *yyssp;
goto yyerrlab1;
yyerrlab1:
yyerrstatus = 3;
for (;;)
{
yyn = yypact[yystate];
if (!yypact_value_is_default (yyn))
{
yyn += YYTERROR;
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
{
yyn = yytable[yyn];
if (0 < yyn)
break;
}
}
if (yyssp == yyss)
YYABORT;
yydestruct ("Error: popping",
yystos[yystate], yyvsp);
YYPOPSTACK (1);
yystate = *yyssp;
YY_STACK_PRINT (yyss, yyssp);
}
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
YY_IGNORE_MAYBE_UNINITIALIZED_END
YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
yystate = yyn;
goto yynewstate;
yyacceptlab:
yyresult = 0;
goto yyreturn;
yyabortlab:
yyresult = 1;
goto yyreturn;
#if !defined yyoverflow || YYERROR_VERBOSE
yyexhaustedlab:
yyerror (YY_("memory exhausted"));
yyresult = 2;
#endif
yyreturn:
if (yychar != YYEMPTY)
{
yytoken = YYTRANSLATE (yychar);
yydestruct ("Cleanup: discarding lookahead",
yytoken, &yylval);
}
YYPOPSTACK (yylen);
YY_STACK_PRINT (yyss, yyssp);
while (yyssp != yyss)
{
yydestruct ("Cleanup: popping",
yystos[*yyssp], yyvsp);
YYPOPSTACK (1);
}
#ifndef yyoverflow
if (yyss != yyssa)
YYSTACK_FREE (yyss);
#endif
#if YYERROR_VERBOSE
if (yymsg != yymsgbuf)
YYSTACK_FREE (yymsg);
#endif
return yyresult;
}
#line 2006 "gen-rules-parser.y"
#define COPYRIGHT_MSG \
" * Copyright (C) 2004, 2006-2007 Southern Storm Software, Pty Ltd.\n" \
" *\n" \
" * This file is part of the libjit library.\n" \
" *\n" \
" * The libjit library is free software: you can redistribute it and/or\n" \
" * modify it under the terms of the GNU Lesser General Public License\n" \
" * as published by the Free Software Foundation, either version 2.1 of\n" \
" * the License, or (at your option) any later version.\n" \
" *\n" \
" * The libjit library is distributed in the hope that it will be useful,\n" \
" * but WITHOUT ANY WARRANTY; without even the implied warranty of\n" \
" * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" \
" * Lesser General Public License for more details.\n" \
" *\n" \
" * You should have received a copy of the GNU Lesser General Public\n" \
" * License along with the libjit library. If not, see\n" \
" * <http://www.gnu.org/licenses/>.\n"
int main(int argc, char *argv[])
{
FILE *file;
if(argc != 2)
{
fprintf(stderr, "Usage: %s input.sel >output.slc\n", argv[0]);
return 1;
}
file = fopen(argv[1], "r");
if(!file)
{
perror(argv[1]);
return 1;
}
printf("/%c Automatically generated from %s - DO NOT EDIT %c/\n",
'*', argv[1], '*');
printf("/%c\n%s%c/\n\n", '*', COPYRIGHT_MSG, '*');
printf("#if defined(JIT_INCLUDE_RULES)\n\n");
gensel_filename = argv[1];
gensel_linenum = 1;
yyrestart(file);
if(yyparse())
{
fclose(file);
return 1;
}
fclose(file);
printf("#elif defined(JIT_INCLUDE_SUPPORTED)\n\n");
gensel_output_supported();
printf("#endif\n");
return 0;
}