Alien-LibJIT
view release on metacpan or search on metacpan
libjit/tools/gen-rules-parser.y view on Meta::CPAN
/*
* Imports from the lexical analyser.
*/
extern int yylex(void);
extern void yyrestart(FILE *file);
#ifdef YYTEXT_POINTER
extern char *yytext;
#else
extern char yytext[];
#endif
/*
* Current file and line number.
*/
extern char *gensel_filename;
extern long gensel_linenum;
/*
* Report error message.
*/
static void
gensel_error_message(char *filename, long linenum, char *msg)
{
fprintf(stderr, "%s(%ld): %s\n", filename, linenum, msg);
}
/*
* Report error message and exit.
*/
static void
gensel_error(char *filename, long linenum, char *msg)
{
gensel_error_message(filename, linenum, msg);
exit(1);
}
/*
* Report error messages from the parser.
*/
static void
yyerror(char *msg)
{
gensel_error_message(gensel_filename, gensel_linenum, msg);
}
/*
* Instruction type for the "inst" variable.
*/
static char *gensel_inst_type = "unsigned char *";
static int gensel_new_inst_type = 0;
/*
* Amount of space to reserve for the primary instruction output.
*/
static int gensel_reserve_space = 32;
static int gensel_reserve_more_space = 128;
/*
* Maximal number of input values in a pattern.
*/
#define MAX_INPUT 3
/*
* Maximal number of scratch registers in a pattern.
*/
#define MAX_SCRATCH 6
/*
* Maximal number of pattern elements.
*/
#define MAX_PATTERN (MAX_INPUT + MAX_SCRATCH)
/*
* Rule Options.
*/
#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
/*
* Pattern values.
*/
#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
/*
* Value types.
*/
#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
/*
* Register class.
*/
typedef struct gensel_regclass *gensel_regclass_t;
struct gensel_regclass
{
char *id;
char *def;
int is_long;
gensel_regclass_t next;
};
/*
* Option value.
libjit/tools/gen-rules-parser.y view on Meta::CPAN
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");
libjit/tools/gen-rules-parser.y view on Meta::CPAN
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);
}
}
}
/*
* Output value initialization code.
*/
static void
gensel_output_register_pattern(char *name, gensel_option_t pattern)
{
gensel_output_register(name, pattern->values->value, pattern->values->next);
}
/*
* Create an upper-case copy of a string.
*/
static char *
gensel_string_upper(char *string)
{
char *cp;
if(string)
{
string = strdup(string);
for(cp = string; *cp; cp++)
{
*cp = toupper(*cp);
}
}
return string;
}
/*
* Output the clauses for a rule.
*/
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 the clause is manual, then output it as-is */
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));
/* Output the clause checking and dispatching code */
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;
( run in 0.311 second using v1.01-cache-2.11-cpan-efa8479b9fe )