Line 172... |
Line 172... |
static void
|
static void
|
gen_eval_operands (FILE *fo, int insn_index, int level)
|
gen_eval_operands (FILE *fo, int insn_index, int level)
|
{
|
{
|
struct insn_op_struct *opd = op_start[insn_index];
|
struct insn_op_struct *opd = op_start[insn_index];
|
int dis = 0;
|
int dis = 0;
|
int no = 0, num_op;
|
int no = 0;
|
int firstd = 1;
|
int firstd = 1;
|
|
|
while (1)
|
while (1)
|
{
|
{
|
int nbits = 0, first = 1;
|
int nbits = 0, first = 1;
|
Line 221... |
Line 221... |
opd++;
|
opd++;
|
}
|
}
|
|
|
last:
|
last:
|
num_op = no;
|
num_op = no;
|
SHIFT; fprintf (fo, "if (do_stats) {\n");
|
|
level++;
|
|
SHIFT; fprintf (fo, "num_op = %i;\n", no);
|
|
SHIFT; fprintf (fo, "insn_index = %i; /* \"%s\" */\n", insn_index, insn_name (insn_index));
|
|
for (no = 0; no < num_op; no++) {
|
|
SHIFT; fprintf (fo, "op[%i] = %c;\n", no, 'a' + no);
|
|
SHIFT; fprintf (fo, "op[%i + MAX_OPERANDS] = 0x%08x;\n", no, op[no]);
|
|
}
|
|
level--;
|
|
SHIFT; fprintf (fo, "}\n");
|
|
}
|
}
|
|
|
/* Generates decode and execute for one instruction instance */
|
/* Generates decode and execute for one instruction instance */
|
int output_call (FILE *fo, int index, int level)
|
int output_call (FILE *fo, int index, int level)
|
{
|
{
|
Line 245... |
Line 235... |
if (index >= 0) {
|
if (index >= 0) {
|
SHIFT; fprintf (fo, "unsigned long data, tmp;\n");
|
SHIFT; fprintf (fo, "unsigned long data, tmp;\n");
|
SHIFT; fprintf (fo, "unsigned long a, b, c; /* operands */\n");
|
SHIFT; fprintf (fo, "unsigned long a, b, c; /* operands */\n");
|
}
|
}
|
write_to_reg = 0;
|
write_to_reg = 0;
|
if (index >= 0) {
|
if (index >= 0)
|
gen_eval_operands (fo, index, level);
|
gen_eval_operands (fo, index, level);
|
} else {
|
else
|
SHIFT; fprintf (fo, "if (do_stats) {\n");
|
num_op = 0;
|
level++;
|
|
SHIFT; fprintf (fo, "num_op = 0;\n");
|
|
SHIFT; fprintf (fo, "insn_index = -1;\n");
|
|
level--;
|
|
SHIFT; fprintf (fo, "}\n");
|
|
}
|
|
SHIFT;
|
SHIFT;
|
if (index < 0) output_function (fo, "l_invalid", level);
|
if (index < 0) output_function (fo, "l_invalid", level);
|
else output_function (fo, or32_opcodes[index].function_name, level);
|
else output_function (fo, or32_opcodes[index].function_name, level);
|
fprintf (fo, "\n");
|
fprintf (fo, "\n");
|
for (i = 0; i < num_op; i++)
|
|
if (op[i] & OPTYPE_DST) {
|
SHIFT; fprintf (fo, "if (do_stats) {\n");
|
SHIFT; fprintf (fo, "IFF (config.cpu.dependstats) op[%i + MAX_OPERANDS] |= OPTYPE_DST;\n", i);
|
level++;
|
|
SHIFT; fprintf (fo, "num_op = %i;\n", num_op);
|
|
if (num_op) {SHIFT; fprintf (fo, " op = ¤t->op[0];\n");}
|
|
SHIFT; fprintf (fo, "current->insn_index = %i; /* \"%s\" */\n", index, insn_name (index));
|
|
for (i = 0; i < num_op; i++) {
|
|
SHIFT; fprintf (fo, "op[%i] = %c;\n", i, 'a' + i);
|
|
SHIFT; fprintf (fo, "op[%i + MAX_OPERANDS] = 0x%08x;\n", i, op[i]);
|
}
|
}
|
|
SHIFT; fprintf (fo, "analysis(current);\n");
|
|
level--;
|
|
SHIFT; fprintf (fo, "}\n");
|
if (write_to_reg) {
|
if (write_to_reg) {
|
SHIFT; fprintf (fo, "reg[0] = 0; /* Repair in case we changed it */\n", i);
|
SHIFT; fprintf (fo, "reg[0] = 0; /* Repair in case we changed it */\n", i);
|
}
|
}
|
level--;
|
level--;
|
SHIFT; fprintf (fo, "}");
|
SHIFT; fprintf (fo, "}");
|
return 0;
|
return 0;
|
}
|
}
|
|
|
/* Generates .c file header */
|
/* Generates .c file header */
|
static int generate_header (FILE *fo)
|
int generate_header (FILE *fo)
|
{
|
{
|
fprintf (fo, "/* This file was automatically generated by generate (see cpu/or32/generate.c) */\n\n");
|
fprintf (fo, "/* This file was automatically generated by generate (see cpu/or32/generate.c) */\n\n");
|
fprintf (fo, "static inline void decode_execute (struct iqueue_entry *current)\n{\n");
|
fprintf (fo, "static inline void decode_execute (struct iqueue_entry *current)\n{\n");
|
fprintf (fo, " unsigned long insn = current->insn;\n");
|
fprintf (fo, " unsigned long insn = current->insn;\n");
|
fprintf (fo, " int insn_index;\n");
|
|
fprintf (fo, " op = ¤t->op[0];\n");
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
/* Generates .c file footer */
|
/* Generates .c file footer */
|
int generate_footer (FILE *fo)
|
int generate_footer (FILE *fo)
|
{
|
{
|
fprintf (fo, " current->insn_index = insn_index;\n");
|
|
fprintf (fo, "}\n");
|
fprintf (fo, "}\n");
|
return 0;
|
return 0;
|
}
|
}
|
|
|
/* Decodes all instructions and generates code for that. This function
|
/* Decodes all instructions and generates code for that. This function
|
is similar to insn_decode, except it decodes all instructions. */
|
is similar to insn_decode, except it decodes all instructions. */
|
static int generate_body (FILE *fo, unsigned long *a, unsigned long cur_mask, int level)
|
static int generate_body (FILE *fo, unsigned long *a, unsigned long cur_mask, int level)
|
{
|
{
|
|
|
int i;
|
int i;
|
if (!(*a & LEAF_FLAG)) {
|
if (!(*a & LEAF_FLAG)) {
|
unsigned int shift = *a++;
|
unsigned int shift = *a++;
|
unsigned int mask = *a++;
|
unsigned int mask = *a++;
|
int prev_invalid = 0;
|
int prev_invalid = 0;
|