[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[dotgnu-pnet-commits] libjit ChangeLog tools/gen-rules-scanner.l tool...
From: |
Aleksey Demakov |
Subject: |
[dotgnu-pnet-commits] libjit ChangeLog tools/gen-rules-scanner.l tool... |
Date: |
Fri, 29 Dec 2006 23:16:15 +0000 |
CVSROOT: /sources/dotgnu-pnet
Module name: libjit
Changes by: Aleksey Demakov <avd> 06/12/29 23:16:15
Modified files:
. : ChangeLog
tools : gen-rules-scanner.l gen-rules-parser.y
jit : jit-reg-alloc.h jit-reg-alloc.c
jit-rules-alpha.ins jit-rules-x86.ins
Log message:
add support for register classes, clean up rule syntax and reg alloc
interface
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/libjit/ChangeLog?cvsroot=dotgnu-pnet&r1=1.288&r2=1.289
http://cvs.savannah.gnu.org/viewcvs/libjit/tools/gen-rules-scanner.l?cvsroot=dotgnu-pnet&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/libjit/tools/gen-rules-parser.y?cvsroot=dotgnu-pnet&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/libjit/jit/jit-reg-alloc.h?cvsroot=dotgnu-pnet&r1=1.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/libjit/jit/jit-reg-alloc.c?cvsroot=dotgnu-pnet&r1=1.47&r2=1.48
http://cvs.savannah.gnu.org/viewcvs/libjit/jit/jit-rules-alpha.ins?cvsroot=dotgnu-pnet&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/libjit/jit/jit-rules-x86.ins?cvsroot=dotgnu-pnet&r1=1.25&r2=1.26
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/ChangeLog,v
retrieving revision 1.288
retrieving revision 1.289
diff -u -b -r1.288 -r1.289
--- ChangeLog 29 Dec 2006 19:08:14 -0000 1.288
+++ ChangeLog 29 Dec 2006 23:16:15 -0000 1.289
@@ -6,6 +6,20 @@
* jit/jit-rules-x86.c (_jit_init_backend): initialize x86 register
classes.
+ * jit/jit-reg-alloc.h, jit/jit-reg-alloc.c: specify register class
+ for each value and scratch register. Clean up interface.
+
+ * tools/gen-rules-scanner.l, tools/gen-rules-parser.y: add register
+ class declaration; "reg", "lreg", "freg" are not keywords anymore.
+ "scratch" requires register class specification. "clobber" accepts
+ register class which means all registers in the class are clobbered.
+ Remove "only", "spill_before", "unary", and "binary" keywords.
+ Replace "unary_note" and "binary_note" with "note". Also replace
+ "unary_branch" and "binary_branch" with "branch".
+
+ * jit/jit-rules-alpha.ins, jit/jit-rules-x86.ins: update according
+ to the new rule syntax.
+
2006-12-20 Aleksey Demakov <address@hidden>
* jit/jit-thread.h, jit/jit-thread.c: add _jit_global_lock mutex.
Index: tools/gen-rules-scanner.l
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/tools/gen-rules-scanner.l,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- tools/gen-rules-scanner.l 30 Aug 2006 18:35:10 -0000 1.4
+++ tools/gen-rules-scanner.l 29 Dec 2006 23:16:15 -0000 1.5
@@ -84,9 +84,7 @@
"->" { RETURNTOK(K_PTR); }
"any" { RETURNTOK(K_ANY); }
-"reg" { RETURNTOK(K_REG); }
-"lreg" { RETURNTOK(K_LREG); }
-"freg" { RETURNTOK(K_FREG); }
+"all" { RETURNTOK(K_ALL); }
"imm" { RETURNTOK(K_IMM); }
"immzero" { RETURNTOK(K_IMMZERO); }
"imms8" { RETURNTOK(K_IMMS8); }
@@ -95,27 +93,24 @@
"immu16" { RETURNTOK(K_IMMU16); }
"local" { RETURNTOK(K_LOCAL); }
"frame" { RETURNTOK(K_FRAME); }
-"binary" { RETURNTOK(K_BINARY); }
-"unary" { RETURNTOK(K_UNARY); }
-"unary_branch" { RETURNTOK(K_UNARY_BRANCH); }
-"binary_branch" { RETURNTOK(K_BINARY_BRANCH); }
-"unary_note" { RETURNTOK(K_UNARY_NOTE); }
-"binary_note" { RETURNTOK(K_BINARY_NOTE); }
"ternary" { RETURNTOK(K_TERNARY); }
-"stack" { RETURNTOK(K_STACK); }
-"only" { RETURNTOK(K_ONLY); }
+"branch" { RETURNTOK(K_BRANCH); }
+"note" { RETURNTOK(K_NOTE); }
"copy" { RETURNTOK(K_COPY); }
-"x87arith" { RETURNTOK(K_X87ARITH); }
"commutative" { RETURNTOK(K_COMMUTATIVE); }
-"reversible" { RETURNTOK(K_REVERSIBLE); }
"if" { RETURNTOK(K_IF); }
"clobber" { RETURNTOK(K_CLOBBER); }
"scratch" { RETURNTOK(K_SCRATCH); }
"space" { RETURNTOK(K_SPACE); }
+"stack" { RETURNTOK(K_STACK); }
+"x87_arith" { RETURNTOK(K_X87_ARITH); }
+"x87_arith_reversible" { RETURNTOK(K_X87_ARITH_REVERSIBLE); }
+"%inst_type" { RETURNTOK(K_INST_TYPE); }
+"%regclass" { RETURNTOK(K_REG_CLASS); }
+"%lregclass" { RETURNTOK(K_LREG_CLASS); }
+
"manual" { RETURNTOK(K_MANUAL); }
"more_space" { RETURNTOK(K_MORE_SPACE); }
-"spill_before" { RETURNTOK(K_SPILL_BEFORE); }
-"%inst_type" { RETURNTOK(K_INST_TYPE); }
"!"?{IDALPHA}({DIGIT}|{IDALPHA})* {
yylval.name = gensel_strdup(yytext);
Index: tools/gen-rules-parser.y
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/tools/gen-rules-parser.y,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- tools/gen-rules-parser.y 9 Sep 2006 05:21:03 -0000 1.12
+++ tools/gen-rules-parser.y 29 Dec 2006 23:16:15 -0000 1.13
@@ -103,32 +103,26 @@
#define MAX_PATTERN (MAX_INPUT + MAX_SCRATCH)
/*
- * Options.
+ * Rule Options.
*/
-#define GENSEL_OPT_BINARY 1
-#define GENSEL_OPT_UNARY 2
-#define GENSEL_OPT_UNARY_BRANCH 3
-#define GENSEL_OPT_BINARY_BRANCH 4
-#define GENSEL_OPT_UNARY_NOTE 5
-#define GENSEL_OPT_BINARY_NOTE 6
-#define GENSEL_OPT_TERNARY 7
-#define GENSEL_OPT_STACK 8
-#define GENSEL_OPT_ONLY 9
-#define GENSEL_OPT_COPY 10
-#define GENSEL_OPT_X87ARITH 11
-#define GENSEL_OPT_COMMUTATIVE 12
-#define GENSEL_OPT_REVERSIBLE 13
-
-#define GENSEL_OPT_MANUAL 14
-#define GENSEL_OPT_MORE_SPACE 15
-#define GENSEL_OPT_SPILL_BEFORE 16
+#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_REG 1
-#define GENSEL_PATT_LREG 2
-#define GENSEL_PATT_FREG 3
+#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
@@ -141,20 +135,27 @@
#define GENSEL_PATT_CLOBBER 13
#define GENSEL_PATT_IF 14
#define GENSEL_PATT_SPACE 15
-#define GENSEL_PATT_ANY 16
/*
- * Register flags.
+ * Value types.
*/
-#define GENSEL_FLAG_DEST 1
-#define GENSEL_FLAG_CLOBBER 2
-#define GENSEL_FLAG_EARLY_CLOBBER 3
+#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
/*
- * Value Type.
+ * Register class.
*/
-#define GENSEL_VALUE_STRING 1
-#define GENSEL_VALUE_CHOICE 2
+typedef struct gensel_regclass *gensel_regclass_t;
+struct gensel_regclass
+{
+ char *id;
+ char *def;
+ int is_long;
+ gensel_regclass_t next;
+};
/*
* Option value.
@@ -163,11 +164,7 @@
struct gensel_value
{
int type;
- union
- {
- char *value;
- gensel_value_t children;
- };
+ void *value;
gensel_value_t next;
};
@@ -178,7 +175,6 @@
struct gensel_option
{
int option;
- int flags;
gensel_value_t values;
gensel_option_t next;
};
@@ -189,6 +185,7 @@
typedef struct gensel_clause *gensel_clause_t;
struct gensel_clause
{
+ int dest;
gensel_option_t pattern;
char *filename;
long linenum;
@@ -214,9 +211,55 @@
static char *gensel_local_names[] = {
"local_offset", "local_offset2", "local_offset3"
};
-static char *gensel_reg_flags[] = {
- "0", "0", "_JIT_REGS_CLOBBER", "_JIT_REGS_EARLY_CLOBBER"
-};
+
+/*
+ * Register classes.
+ */
+static gensel_regclass_t gensel_regclass_list;
+
+/*
+ * Create a register class.
+ */
+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;
+ }
+}
/*
* Create a value.
@@ -233,7 +276,9 @@
}
vp->type = type;
+ vp->value = 0;
vp->next = 0;
+
return vp;
}
@@ -241,25 +286,27 @@
* Create string value.
*/
static gensel_value_t
-gensel_create_string(char *value)
+gensel_create_string_value(char *value)
{
gensel_value_t vp;
vp = gensel_create_value(GENSEL_VALUE_STRING);
vp->value = value;
+
return vp;
}
/*
- * Create choice value.
+ * Create string value.
*/
static gensel_value_t
-gensel_create_choice(gensel_value_t children)
+gensel_create_regclass_value(char *value)
{
gensel_value_t vp;
- vp = gensel_create_value(GENSEL_VALUE_CHOICE);
- vp->children = children;
+ vp = gensel_create_value(GENSEL_VALUE_REGCLASS);
+ vp->value = gensel_lookup_regclass(value);
+
return vp;
}
@@ -267,7 +314,7 @@
* Create an option.
*/
static gensel_option_t
-gensel_create_option_2(int option, int flags, gensel_value_t values)
+gensel_create_option(int option, gensel_value_t values)
{
gensel_option_t op;
@@ -278,19 +325,48 @@
}
op->option = option;
- op->flags = flags;
op->values = values;
op->next = 0;
return op;
}
/*
- * Create an option with no flags.
+ * Create a register pattern element.
*/
static gensel_option_t
-gensel_create_option(int option, gensel_value_t values)
+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);
+}
+
+/*
+ * Create a scratch register pattern element.
+ */
+static gensel_option_t
+gensel_create_scratch(
+ gensel_value_t regclass,
+ gensel_value_t values)
{
- return gensel_create_option_2(option, 0, values);
+ regclass->next = values;
+ return gensel_create_option(GENSEL_PATT_SCRATCH, regclass);
}
/*
@@ -307,10 +383,6 @@
{
free(values->value);
}
- else
- {
- gensel_free_values(values->children);
- }
free(values);
values = next;
}
@@ -365,22 +437,20 @@
/*
* Declare the register variables that are needed for a set of clauses.
*/
-static void gensel_declare_regs(gensel_clause_t clauses, gensel_option_t
options)
+static void
+gensel_declare_regs(gensel_clause_t clauses, gensel_option_t options)
{
gensel_option_t pattern;
- gensel_value_t values;
int regs, max_regs;
int other_regs_mask;
int imms, max_imms;
int locals, max_locals;
int scratch, others;
- int have_regset;
max_regs = 0;
other_regs_mask = 0;
max_imms = 0;
max_locals = 0;
- have_regset = 0;
while(clauses != 0)
{
regs = 0;
@@ -398,23 +468,12 @@
break;
case GENSEL_PATT_REG:
- case GENSEL_PATT_FREG:
++regs;
- if(pattern->values
- && pattern->values->type !=
GENSEL_VALUE_STRING)
- {
- have_regset = 1;
- }
break;
case GENSEL_PATT_LREG:
other_regs_mask |= (1 << regs);
++regs;
- if(pattern->values
- && pattern->values->type !=
GENSEL_VALUE_STRING)
- {
- have_regset = 1;
- }
break;
case GENSEL_PATT_IMMZERO:
@@ -435,16 +494,7 @@
break;
case GENSEL_PATT_SCRATCH:
- values = pattern->values;
- while(values)
- {
++scratch;
- if(values->type != GENSEL_VALUE_STRING)
- {
- have_regset = 1;
- }
- values = values->next;
- }
}
pattern = pattern->next;
}
@@ -536,10 +586,6 @@
printf("\tjit_nint local_offset, local_offset2,
local_offset3;\n");
break;
}
- if(have_regset)
- {
- printf("\tjit_regused_t regset;\n");
- }
}
/*
@@ -553,7 +599,6 @@
switch(pattern->option)
{
case GENSEL_PATT_REG:
- case GENSEL_PATT_FREG:
case GENSEL_PATT_LREG:
case GENSEL_PATT_SCRATCH:
case GENSEL_PATT_CLOBBER:
@@ -565,52 +610,22 @@
}
/*
- * Check if the pattern contains the dest register and if it is
- * defined correctly.
+ * Returns first register in the pattern if any.
*/
-static int
-gensel_contains_free_dest(gensel_clause_t clauses, gensel_option_t pattern)
+static gensel_option_t
+gensel_get_first_register(gensel_option_t pattern)
{
- int found, index;
-
- found = 0;
- index = 0;
while(pattern)
{
switch(pattern->option)
{
case GENSEL_PATT_REG:
- case GENSEL_PATT_FREG:
case GENSEL_PATT_LREG:
- case GENSEL_PATT_LOCAL:
- case GENSEL_PATT_FRAME:
- if(pattern->flags == GENSEL_FLAG_DEST)
- {
- if(index != 0)
- {
- gensel_error(
- clauses->filename,
- clauses->linenum,
- "The destination must be the
first pattern element.");
- }
- found = 1;
- }
- ++index;
- break;
-
- case GENSEL_PATT_ANY:
- case GENSEL_PATT_IMMZERO:
- case GENSEL_PATT_IMM:
- case GENSEL_PATT_IMMS8:
- case GENSEL_PATT_IMMU8:
- case GENSEL_PATT_IMMS16:
- case GENSEL_PATT_IMMU16:
- ++index;
- break;
+ return pattern;
}
pattern = pattern->next;
}
- return found;
+ return 0;
}
static void
@@ -654,7 +669,6 @@
break;
case GENSEL_PATT_REG:
- case GENSEL_PATT_FREG:
case GENSEL_PATT_LREG:
case GENSEL_PATT_LOCAL:
case GENSEL_PATT_FRAME:
@@ -705,7 +719,6 @@
{
case GENSEL_PATT_ANY:
case GENSEL_PATT_REG:
- case GENSEL_PATT_FREG:
case GENSEL_PATT_LREG:
case GENSEL_PATT_LOCAL:
case GENSEL_PATT_FRAME:
@@ -748,7 +761,6 @@
char *names[MAX_PATTERN],
char *other_names[MAX_PATTERN])
{
- gensel_value_t values;
int regs, imms, locals, index;
gensel_init_names(MAX_PATTERN, names, other_names);
@@ -766,7 +778,6 @@
break;
case GENSEL_PATT_REG:
- case GENSEL_PATT_FREG:
names[index] = gensel_reg_names[regs];
++regs;
++index;
@@ -801,14 +812,9 @@
break;
case GENSEL_PATT_SCRATCH:
- values = pattern->values;
- while(values)
- {
names[index] = gensel_reg_names[regs];
++regs;
++index;
- values = values->next;
- }
}
pattern = pattern->next;
}
@@ -836,11 +842,7 @@
}
while(*code != '\0')
{
-#if 0
- first = free_dest ? '0' : '1';
-#else
first = '1';
-#endif
if(*code == '$' && code[1] >= first && code[1] < (first +
MAX_PATTERN))
{
index = code[1] - first;
@@ -889,30 +891,75 @@
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);
+ }
+ }
+}
+
+/*
+ * 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);
+}
+
/*
* 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, child;
- int first, seen_option;
+ gensel_value_t values;
int regs, imms, locals, scratch, index;
- int clobber_all, ternary, free_dest;
+ int first, seen_option;
+ int ternary, free_dest;
int contains_registers;
+ gensel_regclass_t regclass;
/* If the clause is manual, then output it as-is */
if(gensel_search_option(options, GENSEL_OPT_MANUAL))
{
- if(gensel_search_option(options, GENSEL_OPT_SPILL_BEFORE))
- {
- printf("\t_jit_regs_spill_all(gen);\n");
- }
gensel_init_names(MAX_PATTERN, names, other_names);
gensel_output_clause_code(clauses, names, other_names, 0);
return;
@@ -936,10 +983,6 @@
printf("\t_jit_regs_t regs;\n");
}
gensel_declare_regs(clauses, options);
- if(gensel_search_option(options, GENSEL_OPT_SPILL_BEFORE))
- {
- printf("\t_jit_regs_spill_all(gen);\n");
- }
ternary = (0 != gensel_search_option(options, GENSEL_OPT_TERNARY));
@@ -949,23 +992,7 @@
while(clause)
{
contains_registers = gensel_contains_registers(clause->pattern);
- free_dest = gensel_contains_free_dest(clauses, clause->pattern);
-
- clobber_all = 0;
- pattern = gensel_search_option(clause->pattern,
GENSEL_PATT_CLOBBER);
- if(pattern)
- {
- values = pattern->values;
- while(values)
- {
- if(values->value && strcmp(values->value, "*")
== 0)
- {
- clobber_all = 1;
- break;
- }
- values = values->next;
- }
- }
+ free_dest = clause->dest;
gensel_build_arg_index(clause->pattern, 3, args, 0, ternary,
free_dest);
@@ -989,7 +1016,6 @@
case GENSEL_PATT_REG:
case GENSEL_PATT_LREG:
- case GENSEL_PATT_FREG:
/* Do not check if the value is in
a register as the allocator will
load them anyway as long as other
@@ -1128,55 +1154,21 @@
printf("\telse\n\t{\n");
}
- if(gensel_search_option(options, GENSEL_OPT_BINARY_BRANCH)
- || gensel_search_option(options, GENSEL_OPT_UNARY_BRANCH))
- {
- /* Spill all other registers back to their original
positions */
- if(contains_registers)
- {
- clobber_all = 1;
- }
- else
- {
- printf("\t\t_jit_regs_spill_all(gen);\n");
- }
- }
-
if(contains_registers)
{
seen_option = 0;
printf("\t\t_jit_regs_init(gen, ®s, ");
- if(clobber_all)
- {
- seen_option = 1;
- printf("_JIT_REGS_CLOBBER_ALL");
- }
if(ternary)
{
- if(seen_option)
- {
- printf(" | ");
- }
- else
- {
seen_option = 1;
- }
printf("_JIT_REGS_TERNARY");
}
- if(free_dest)
- {
- if(seen_option)
- {
- printf(" | ");
- }
- else
+ else if(free_dest)
{
seen_option = 1;
- }
printf("_JIT_REGS_FREE_DEST");
}
- if(gensel_search_option(options,
GENSEL_OPT_BINARY_BRANCH)
- || gensel_search_option(options,
GENSEL_OPT_UNARY_BRANCH))
+ if(gensel_search_option(options, GENSEL_OPT_BRANCH))
{
if(seen_option)
{
@@ -1212,7 +1204,7 @@
}
printf("_JIT_REGS_STACK");
}
- if(gensel_search_option(options, GENSEL_OPT_ONLY))
+ if(gensel_search_option(options,
GENSEL_OPT_COMMUTATIVE))
{
if(seen_option)
{
@@ -1222,9 +1214,10 @@
{
seen_option = 1;
}
- printf("_JIT_REGS_CLOBBER_STACK");
+ printf("_JIT_REGS_COMMUTATIVE");
}
- if(gensel_search_option(options, GENSEL_OPT_X87ARITH))
+ /* x87 options */
+ if(gensel_search_option(options, GENSEL_OPT_X87_ARITH))
{
if(seen_option)
{
@@ -1236,19 +1229,7 @@
}
printf("_JIT_REGS_X87_ARITH");
}
- 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_REVERSIBLE))
+ else if(gensel_search_option(options,
GENSEL_OPT_X87_ARITH_REVERSIBLE))
{
if(seen_option)
{
@@ -1258,7 +1239,7 @@
{
seen_option = 1;
}
- printf("_JIT_REGS_REVERSIBLE");
+ printf("_JIT_REGS_X87_ARITH_REVERSIBLE");
}
if(!seen_option)
{
@@ -1267,17 +1248,17 @@
printf(");\n");
if(!(ternary || free_dest
- || gensel_search_option(options,
GENSEL_OPT_BINARY_NOTE)
- || gensel_search_option(options,
GENSEL_OPT_BINARY_BRANCH)
- || gensel_search_option(options,
GENSEL_OPT_UNARY_NOTE)
- || gensel_search_option(options,
GENSEL_OPT_UNARY_BRANCH)))
+ || gensel_search_option(options, GENSEL_OPT_NOTE)
+ || gensel_search_option(options,
GENSEL_OPT_BRANCH)))
{
- printf("\t\t_jit_regs_init_dest(®s, insn,
0);\n");
+ 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)
{
@@ -1288,72 +1269,8 @@
break;
case GENSEL_PATT_REG:
- case GENSEL_PATT_FREG:
- printf("\t\t_jit_regs_init_%s(®s, insn,
%s);\n",
- args[index],
gensel_reg_flags[pattern->flags]);
- if(pattern->values && pattern->values->value)
- {
- if(pattern->values->type ==
GENSEL_VALUE_STRING)
- {
-
printf("\t\t_jit_regs_set_%s(gen, ®s, _jit_regs_lookup(\"%s\"), -1);\n",
- args[index],
pattern->values->value);
- }
- else
- {
- printf("\t\tregset =
jit_regused_init;\n");
- child =
pattern->values->children;
- while(child)
- {
- printf("\t\t%s =
_jit_regs_lookup(\"%s\");\n",
-
gensel_reg_names[regs], child->value);
- printf("\t\tif(%s >=
0)\n", gensel_reg_names[regs]);
-
printf("\t\t\tjit_reg_set_used(regset, %s);\n",
-
gensel_reg_names[regs]);
- child = child->next;
- }
-
printf("\t\t_jit_regs_set_%s_from(®s, regset);\n",
- args[index]);
- }
- }
- ++regs;
- ++index;
- break;
-
case GENSEL_PATT_LREG:
- printf("\t\t_jit_regs_init_%s(®s, insn,
%s);\n",
- args[index],
gensel_reg_flags[pattern->flags]);
- if(pattern->values && pattern->values->value)
- {
- if(pattern->values->type ==
GENSEL_VALUE_STRING)
- {
- if(pattern->values->next &&
pattern->values->next->value)
- {
-
printf("\t\t_jit_regs_set_%s(gen, ®s, _jit_regs_lookup(\"%s\"),
_jit_regs_lookup(\"%s\"));\n",
- args[index],
pattern->values->value, pattern->values->next->value);
- }
- else
- {
-
printf("\t\t_jit_regs_set_%s(gen, ®s, _jit_regs_lookup(\"%s\"), -1);\n",
- args[index],
pattern->values->value);
- }
- }
- else
- {
- printf("\t\tregset =
jit_regused_init;\n");
- child =
pattern->values->children;
- while(child)
- {
- printf("\t\t%s =
_jit_regs_lookup(\"%s\");\n",
-
gensel_reg_names[regs], child->value);
- printf("\t\tif(%s >=
0)\n", gensel_reg_names[regs]);
-
printf("\t\t\tjit_reg_set_used(regset, %s);\n",
-
gensel_reg_names[regs]);
- child = child->next;
- }
-
printf("\t\t_jit_regs_set_%s_from(®s, regset);\n",
- args[index]);
- }
- }
+ gensel_output_register_pattern(args[index],
pattern);
++regs;
++index;
break;
@@ -1370,59 +1287,52 @@
case GENSEL_PATT_FRAME:
printf("\t\t_jit_regs_force_out(gen, insn->%s,
%d);\n",
- args[index], (pattern->flags ==
GENSEL_FLAG_DEST));
+ args[index], (free_dest && index == 0));
printf("\t\t_jit_gen_fix_value(insn->%s);\n",
args[index]);
++index;
break;
case GENSEL_PATT_SCRATCH:
- values = pattern->values;
- while(values)
- {
- if(values->value
- && (values->type !=
GENSEL_VALUE_STRING
- || strcmp(values->value, "?") !=
0))
- {
- if(values->type ==
GENSEL_VALUE_STRING)
- {
-
printf("\t\t_jit_regs_add_scratch(gen, ®s, _jit_regs_lookup(\"%s\"));\n",
- values->value);
- }
- else
- {
- printf("\t\tregset =
jit_regused_init;\n");
- child =
values->children;
- while(child)
- {
- printf("\t\t%s
= _jit_regs_lookup(\"%s\");\n",
-
gensel_reg_names[regs], child->value);
-
printf("\t\tif(%s >= 0)\n", gensel_reg_names[regs]);
-
printf("\t\t\tjit_reg_set_used(regset, %s);\n",
-
gensel_reg_names[regs]);
- child =
child->next;
- }
-
printf("\t\t_jit_regs_add_scratch_from(®s, regset);\n");
- }
- }
- else
+ regclass = pattern->values->value;
+ printf("\t\t_jit_regs_add_scratch(®s,
%s);\n",
+ regclass->def);
+ if(pattern->values->next &&
pattern->values->next->value)
{
-
printf("\t\t_jit_regs_add_scratch(gen, ®s, -1);\n");
+ 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;
- values = values->next;
- }
break;
case GENSEL_PATT_CLOBBER:
values = pattern->values;
while(values)
{
- if(values->value &&
strcmp(values->value, "*") != 0)
+ if(!values->value)
{
-
printf("\t\t_jit_regs_set_clobber(gen, ®s, _jit_regs_lookup(\"%s\"));\n",
- 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;
}
@@ -1431,6 +1341,19 @@
pattern = pattern->next;
}
+ if(gensel_search_option(options, GENSEL_OPT_BRANCH))
+ {
+ /* Spill all other registers back to their original
positions */
+ 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)
@@ -1510,17 +1433,16 @@
break;
case GENSEL_PATT_REG:
- case GENSEL_PATT_FREG:
- printf("\t\t%s =
_jit_reg_info[_jit_regs_%s(®s)].cpu_reg;\n",
+ 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_%s(®s)].cpu_reg;\n",
+ 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_%s_other(®s)].cpu_reg;\n",
+ 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;
@@ -1550,15 +1472,11 @@
break;
case GENSEL_PATT_SCRATCH:
- values = pattern->values;
- while(values)
- {
- printf("\t\t%s =
_jit_reg_info[_jit_regs_scratch(®s, %d)].cpu_reg;\n",
+ printf("\t\t%s =
_jit_reg_info[_jit_regs_get_scratch(®s, %d)].cpu_reg;\n",
gensel_reg_names[regs], scratch);
++regs;
++scratch;
- values = values->next;
- }
+ ++index;
break;
}
@@ -1693,10 +1611,8 @@
%token CODE_BLOCK "a code block"
%token LITERAL "literal string"
%token K_PTR "`->'"
-%token K_ANY "any variable"
-%token K_REG "word register"
-%token K_LREG "long register"
-%token K_FREG "float register"
+%token K_ANY "any value"
+%token K_ALL "all registers"
%token K_IMM "immediate value"
%token K_IMMZERO "immediate zero value"
%token K_IMMS8 "immediate signed 8-bit value"
@@ -1705,30 +1621,26 @@
%token K_IMMU16 "immediate unsigned 16-bit value"
%token K_LOCAL "local variable"
%token K_FRAME "local variable forced out into the stack frame"
-%token K_BINARY "`binary'"
-%token K_UNARY "`unary'"
-%token K_UNARY_BRANCH "`unary_branch'"
-%token K_BINARY_BRANCH "`binary_branch'"
-%token K_UNARY_NOTE "`unary_note'"
-%token K_BINARY_NOTE "`binary_note'"
+%token K_NOTE "`note'"
%token K_TERNARY "`ternary'"
-%token K_STACK "`stack'"
-%token K_ONLY "`only'"
+%token K_BRANCH "`branch'"
%token K_COPY "`copy'"
-%token K_X87ARITH "`x87arith'"
%token K_COMMUTATIVE "`commutative'"
-%token K_REVERSIBLE "`reversible'"
%token K_IF "`if'"
%token K_CLOBBER "`clobber'"
%token K_SCRATCH "`scratch'"
%token K_SPACE "`space'"
+%token K_STACK "`stack'"
+%token K_X87_ARITH "`x87_arith'"
+%token K_X87_ARITH_REVERSIBLE "`x87_arith_reversible'"
%token K_INST_TYPE "`%inst_type'"
+%token K_REG_CLASS "`%reg_class'"
+%token K_LREG_CLASS "`%lreg_class'"
/* deperecated keywords */
%token K_MANUAL "`manual'"
%token K_MORE_SPACE "`more_space'"
-%token K_SPILL_BEFORE "`spill_before'"
/*
* Define the yylval types of the various non-terminals.
@@ -1736,12 +1648,12 @@
%type <code> CODE_BLOCK
%type <name> IDENTIFIER LITERAL
%type <name> IfClause IdentifierList Literal
-%type <tag> OptionTag InputTag RegTag LRegTag RegFlag
LocalTag LocalFlag
+%type <tag> OptionTag InputTag DestFlag RegFlag
%type <clauses> Clauses Clause
-%type <options> Options OptionList Pattern Pattern2
-%type <option> Option PatternElement Scratch Clobber If Space
-%type <values> ValuePair ValueList ValueChoice ValueChoiceList
-%type <value> Value
+%type <options> Options Pattern
+%type <option> Option PatternElement
+%type <values> ValuePair ClobberList ClobberSpec
+%type <value> Value ClobberEntry RegClass
%expect 0
@@ -1787,6 +1699,12 @@
gensel_inst_type = $2;
gensel_new_inst_type = 1;
}
+ | K_REG_CLASS IDENTIFIER IDENTIFIER {
+ gensel_create_regclass($2, $3, 0);
+ }
+ | K_LREG_CLASS IDENTIFIER IDENTIFIER {
+ gensel_create_regclass($2, $3, 1);
+ }
;
IdentifierList
@@ -1812,16 +1730,15 @@
;
Options
- : /* empty */ { $$.head = $$.tail = 0; }
- | OptionList { $$ = $1; }
- ;
-
-OptionList
- : Option {
+ : /* empty */ {
+ $$.head = 0;
+ $$.tail = 0;
+ }
+ | Option {
$$.head = $1;
$$.tail = $1;
}
- | OptionList ',' Option {
+ | Options ',' Option {
$1.tail->next = $3;
$$.head = $1.head;
$$.tail = $3;
@@ -1829,7 +1746,9 @@
;
Option
- : OptionTag { $$ = gensel_create_option($1, 0); }
+ : OptionTag {
+ $$ = gensel_create_option($1, 0);
+ }
;
Clauses
@@ -1842,17 +1761,18 @@
;
Clause
- : '[' Pattern ']' K_PTR CODE_BLOCK {
+ : '[' DestFlag Pattern ']' K_PTR CODE_BLOCK {
gensel_clause_t clause;
clause = (gensel_clause_t)malloc(sizeof(struct
gensel_clause));
if(!clause)
{
exit(1);
}
- clause->pattern = $2.head;
- clause->filename = $5.filename;
- clause->linenum = $5.linenum;
- clause->code = $5.block;
+ clause->dest = $2;
+ clause->pattern = $3.head;
+ clause->filename = $6.filename;
+ clause->linenum = $6.linenum;
+ clause->code = $6.block;
clause->next = 0;
$$.head = clause;
$$.tail = clause;
@@ -1860,19 +1780,15 @@
;
Pattern
- : /* empty */ { $$.head = $$.tail = 0; }
- | Pattern2 {
- $$.head = $1.head;
- $$.tail = $1.tail;
+ : /* empty */ {
+ $$.head = 0;
+ $$.tail = 0;
}
- ;
-
-Pattern2
- : PatternElement {
+ | PatternElement {
$$.head = $1;
$$.tail = $1;
}
- | Pattern2 ',' PatternElement {
+ | Pattern ',' PatternElement {
$1.tail->next = $3;
$$.head = $1.head;
$$.tail = $3;
@@ -1883,147 +1799,115 @@
: InputTag {
$$ = gensel_create_option($1, 0);
}
- | LocalFlag LocalTag {
- $$ = gensel_create_option_2($2, $1, 0);
- }
- | RegFlag RegTag {
- $$ = gensel_create_option_2($2, $1, 0);
+ | RegFlag RegClass {
+ $$ = gensel_create_register($1, $2, 0);
}
- | RegFlag RegTag '(' Value ')' {
- $$ = gensel_create_option_2($2, $1, $4);
+ | RegFlag RegClass '(' Value ')' {
+ $$ = gensel_create_register($1, $2, $4);
}
- | RegFlag RegTag '(' ValueChoice ')' {
- gensel_value_t cp;
- cp = gensel_create_choice($4.head);
- $$ = gensel_create_option_2($2, $1, cp);
+ | RegFlag RegClass '(' ValuePair ')' {
+ gensel_regclass_t regclass;
+ regclass = $2->value;
+ if(!regclass->is_long)
+ {
+ gensel_error(
+ gensel_filename, gensel_linenum,
+ "not a long pair register");
}
- | RegFlag LRegTag {
- $$ = gensel_create_option_2($2, $1, 0);
+ $$ = gensel_create_register($1, $2, $4.head);
}
- | RegFlag LRegTag '(' Value ')' {
- $$ = gensel_create_option_2($2, $1, $4);
+ | K_SCRATCH RegClass {
+ gensel_regclass_t regclass;
+ regclass = $2->value;
+ if(regclass->is_long)
+ {
+ gensel_error(
+ gensel_filename, gensel_linenum,
+ "scratch register cannot be a long
pair");
}
- | RegFlag LRegTag '(' ValuePair ')' {
- $$ = gensel_create_option_2($2, $1, $4.head);
+ $$ = gensel_create_scratch($2, 0);
}
- | RegFlag LRegTag '(' ValueChoice ')' {
- gensel_value_t cp;
- cp = gensel_create_choice($4.head);
- $$ = gensel_create_option_2($2, $1, cp);
+ | K_SCRATCH RegClass '(' Value ')' {
+ gensel_regclass_t regclass;
+ regclass = $2->value;
+ if(regclass->is_long)
+ {
+ gensel_error(
+ gensel_filename, gensel_linenum,
+ "scratch register cannot be a long
pair");
}
- | Scratch
- | Clobber
- | If
- | Space
- ;
-
-Scratch
- : K_SCRATCH '(' ValueChoiceList ')' {
- $$ = gensel_create_option(GENSEL_PATT_SCRATCH, $3.head);
+ $$ = gensel_create_scratch($2, $4);
}
- ;
-
-Clobber
- : K_CLOBBER '(' ValueList ')' {
+ | K_CLOBBER '(' ClobberSpec ')' {
$$ = gensel_create_option(GENSEL_PATT_CLOBBER, $3.head);
}
- ;
-
-If
- : K_IF '(' Value ')' {
+ | K_IF '(' Value ')' {
$$ = gensel_create_option(GENSEL_PATT_IF, $3);
}
- ;
-
-Space
- : K_SPACE '(' Value ')' {
+ | K_SPACE '(' Value ')' {
$$ = gensel_create_option(GENSEL_PATT_SPACE, $3);
}
;
-ValueChoiceList
- : Value {
- $$.head = $1;
- $$.tail = $1;
+ClobberSpec
+ : K_ALL {
+ $$.head = $$.tail =
gensel_create_value(GENSEL_VALUE_ALL);
}
- | ValueChoice {
- gensel_value_t cp;
- cp = gensel_create_choice($1.head);
- $$.head = cp;
- $$.tail = cp;
- }
- | ValueChoiceList ',' Value {
- $1.tail->next = $3;
- $$.head = $1.head;
- $$.tail = $3;
- }
- | ValueChoiceList ',' ValueChoice {
- gensel_value_t cp;
- cp = gensel_create_choice($3.head);
- $1.tail->next = cp;
- $$.head = $1.head;
- $$.tail = cp;
+ | ClobberList {
+ $$ = $1;
}
;
-ValueChoice
- : Value '|' Value {
- $1->next = $3;
+ClobberList
+ : ClobberEntry {
$$.head = $1;
- $$.tail = $3;
+ $$.tail = $1;
}
- | ValueChoice '|' Value {
+ | ClobberList ',' ClobberEntry {
$1.tail->next = $3;
$$.head = $1.head;
$$.tail = $3;
}
;
-ValuePair
- : Value ':' Value {
- $1->next = $3;
- $$.head = $1;
- $$.tail = $3;
- }
+ClobberEntry
+ : RegClass { $$ = $1; }
+ | Value { $$ = $1; }
;
-ValueList
- : Value {
- $$.head = $1;
- $$.tail = $1;
- }
- | ValueList ',' Value {
- $1.tail->next = $3;
- $$.head = $1.head;
- $$.tail = $3;
+RegClass
+ : IDENTIFIER {
+ $$ = gensel_create_regclass_value($1);
}
;
Value
: Literal {
- $$ = gensel_create_string($1);
+ $$ = gensel_create_string_value($1);
+ }
+ ;
+
+ValuePair
+ : Value ':' Value {
+ $1->next = $3;
+ $$.head = $1;
+ $$.tail = $3;
}
;
OptionTag
- : K_BINARY { $$ = GENSEL_OPT_BINARY; }
- | K_UNARY { $$ = GENSEL_OPT_UNARY; }
- | K_UNARY_BRANCH { $$ = GENSEL_OPT_UNARY_BRANCH; }
- | K_BINARY_BRANCH { $$ = GENSEL_OPT_BINARY_BRANCH; }
- | K_UNARY_NOTE { $$ = GENSEL_OPT_UNARY_NOTE; }
- | K_BINARY_NOTE { $$ = GENSEL_OPT_BINARY_NOTE; }
- | K_TERNARY { $$ = GENSEL_OPT_TERNARY; }
- | K_STACK { $$ = GENSEL_OPT_STACK; }
- | K_ONLY { $$ = GENSEL_OPT_ONLY; }
+ : K_TERNARY { $$ = GENSEL_OPT_TERNARY; }
+ | K_BRANCH { $$ = GENSEL_OPT_BRANCH; }
+ | K_NOTE { $$ = GENSEL_OPT_NOTE; }
| K_COPY { $$ = GENSEL_OPT_COPY; }
- | K_X87ARITH { $$ = GENSEL_OPT_X87ARITH; }
| K_COMMUTATIVE { $$ = GENSEL_OPT_COMMUTATIVE; }
- | K_REVERSIBLE { $$ = GENSEL_OPT_REVERSIBLE; }
+ | K_STACK { $$ = GENSEL_OPT_STACK; }
+ | K_X87_ARITH { $$ = GENSEL_OPT_X87_ARITH; }
+ | K_X87_ARITH_REVERSIBLE { $$ = GENSEL_OPT_X87_ARITH_REVERSIBLE;
}
/* deprecated: */
| K_MANUAL { $$ = GENSEL_OPT_MANUAL; }
| K_MORE_SPACE { $$ = GENSEL_OPT_MORE_SPACE; }
- | K_SPILL_BEFORE { $$ = GENSEL_OPT_SPILL_BEFORE; }
;
InputTag
@@ -2033,33 +1917,20 @@
| K_IMMU8 { $$ = GENSEL_PATT_IMMU8; }
| K_IMMS16 { $$ = GENSEL_PATT_IMMS16; }
| K_IMMU16 { $$ = GENSEL_PATT_IMMU16; }
- | K_ANY { $$ = GENSEL_PATT_ANY; }
- ;
-
-LocalTag
- : K_LOCAL { $$ = GENSEL_PATT_LOCAL; }
+ | K_LOCAL { $$ = GENSEL_PATT_LOCAL; }
| K_FRAME { $$ = GENSEL_PATT_FRAME; }
+ | K_ANY { $$ = GENSEL_PATT_ANY; }
;
-RegTag
- : K_REG { $$ = GENSEL_PATT_REG; }
- | K_FREG { $$ = GENSEL_PATT_FREG; }
- ;
-
-LRegTag
- : K_LREG { $$ = GENSEL_PATT_LREG; }
- ;
-
-LocalFlag
+DestFlag
: /* empty */ { $$ = 0; }
- | '=' { $$ = GENSEL_FLAG_DEST; }
+ | '=' { $$ = 1; }
;
RegFlag
: /* empty */ { $$ = 0; }
- | '=' { $$ = GENSEL_FLAG_DEST; }
- | '*' { $$ = GENSEL_FLAG_CLOBBER; }
- | '+' { $$ = GENSEL_FLAG_EARLY_CLOBBER; }
+ | '*' { $$ = GENSEL_VALUE_CLOBBER; }
+ | '+' { $$ = GENSEL_VALUE_EARLY_CLOBBER; }
;
Literal
Index: jit/jit-reg-alloc.h
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-reg-alloc.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- jit/jit-reg-alloc.h 14 Sep 2006 06:27:08 -0000 1.19
+++ jit/jit-reg-alloc.h 29 Dec 2006 23:16:15 -0000 1.20
@@ -22,6 +22,7 @@
#define _JIT_REG_ALLOC_H
#include "jit-rules.h"
+#include "jit-reg-class.h"
#ifdef __cplusplus
extern "C" {
@@ -40,16 +41,14 @@
/*
* Flags for _jit_regs_init().
*/
-#define _JIT_REGS_CLOBBER_ALL 0x0001
-#define _JIT_REGS_TERNARY 0x0002
-#define _JIT_REGS_BRANCH 0x0004
-#define _JIT_REGS_COPY 0x0008
-#define _JIT_REGS_STACK 0x0010
-#define _JIT_REGS_X87_ARITH 0x0020
-#define _JIT_REGS_COMMUTATIVE 0x0040
-#define _JIT_REGS_REVERSIBLE 0x0080
-#define _JIT_REGS_FREE_DEST 0x0100
-#define _JIT_REGS_CLOBBER_STACK 0x0200
+#define _JIT_REGS_TERNARY 0x0001
+#define _JIT_REGS_BRANCH 0x0002
+#define _JIT_REGS_COPY 0x0004
+#define _JIT_REGS_FREE_DEST 0x0008
+#define _JIT_REGS_COMMUTATIVE 0x0010
+#define _JIT_REGS_STACK 0x0020
+#define _JIT_REGS_X87_ARITH 0x0040
+#define _JIT_REGS_REVERSIBLE 0X0080
/*
* Flags for _jit_regs_init_dest(), _jit_regs_init_value1(), and
@@ -74,14 +73,14 @@
int reg;
int other_reg;
int stack_reg;
- jit_regused_t regset;
+ _jit_regclass_t *regclass;
unsigned live : 1;
unsigned used : 1;
unsigned clobber : 1;
unsigned early_clobber : 1;
unsigned duplicate : 1;
unsigned thrash : 1;
- unsigned save : 1;
+ unsigned store : 1;
unsigned load : 1;
unsigned copy : 1;
unsigned kill : 1;
@@ -94,7 +93,7 @@
typedef struct
{
int reg;
- jit_regused_t regset;
+ _jit_regclass_t *regclass;
} _jit_scratch_t;
@@ -108,19 +107,23 @@
int num_scratch;
unsigned clobber_all : 1;
- unsigned clobber_stack : 1;
+
unsigned ternary : 1;
unsigned branch : 1;
unsigned copy : 1;
unsigned commutative : 1;
+ unsigned free_dest : 1;
+
+#ifdef JIT_REG_STACK
unsigned on_stack : 1;
unsigned x87_arith : 1;
unsigned reversible : 1;
- unsigned free_dest : 1;
+ unsigned clobber_stack : 1;
unsigned no_pop : 1;
unsigned reverse_dest : 1;
unsigned reverse_args : 1;
+#endif
/* The input value index that is going to be overwritten
by the destination value. For ordinary binary and unary
@@ -132,8 +135,10 @@
jit_regused_t assigned;
jit_regused_t clobber;
+#ifdef JIT_REG_STACK
int wanted_stack_count;
int loaded_stack_count;
+#endif
} _jit_regs_t;
@@ -150,39 +155,44 @@
int _jit_regs_load_value(jit_gencode_t gen, jit_value_t value, int destroy,
int used_again);
void _jit_regs_init(jit_gencode_t gen, _jit_regs_t *regs, int flags);
-void _jit_regs_init_dest(_jit_regs_t *regs, jit_insn_t insn, int flags);
-void _jit_regs_init_value1(_jit_regs_t *regs, jit_insn_t insn, int flags);
-void _jit_regs_init_value2(_jit_regs_t *regs, jit_insn_t insn, int flags);
+
+void _jit_regs_init_dest(_jit_regs_t *regs, jit_insn_t insn,
+ int flags, _jit_regclass_t *regclass);
+void _jit_regs_init_value1(_jit_regs_t *regs, jit_insn_t insn,
+ int flags, _jit_regclass_t *regclass);
+void _jit_regs_init_value2(_jit_regs_t *regs, jit_insn_t insn,
+ int flags, _jit_regclass_t *regclass);
+void _jit_regs_add_scratch(_jit_regs_t *regs, _jit_regclass_t *regclass);
void _jit_regs_set_dest(jit_gencode_t gen, _jit_regs_t *regs, int reg, int
other_reg);
void _jit_regs_set_value1(jit_gencode_t gen, _jit_regs_t *regs, int reg, int
other_reg);
void _jit_regs_set_value2(jit_gencode_t gen, _jit_regs_t *regs, int reg, int
other_reg);
-void _jit_regs_add_scratch(jit_gencode_t gen, _jit_regs_t *regs, int reg);
-void _jit_regs_set_clobber(jit_gencode_t gen, _jit_regs_t *regs, int reg);
+void _jit_regs_set_scratch(jit_gencode_t gen, _jit_regs_t *regs, int index,
int reg);
-void _jit_regs_set_dest_from(_jit_regs_t *regs, jit_regused_t regset);
-void _jit_regs_set_value1_from(_jit_regs_t *regs, jit_regused_t regset);
-void _jit_regs_set_value2_from(_jit_regs_t *regs, jit_regused_t regset);
-void _jit_regs_add_scratch_from(_jit_regs_t *regs, jit_regused_t regset);
+void _jit_regs_clobber(_jit_regs_t *regs, int reg);
+void _jit_regs_clobber_class(jit_gencode_t gen, _jit_regs_t *regs,
_jit_regclass_t *regclass);
+void _jit_regs_clobber_all(jit_gencode_t gen, _jit_regs_t *regs);
int _jit_regs_assign(jit_gencode_t gen, _jit_regs_t *regs);
int _jit_regs_gen(jit_gencode_t gen, _jit_regs_t *regs);
+#ifdef JIT_REG_STACK
int _jit_regs_select(_jit_regs_t *regs);
+#endif
void _jit_regs_commit(jit_gencode_t gen, _jit_regs_t *regs);
void _jit_regs_abort(jit_gencode_t gen, _jit_regs_t *regs);
+int _jit_regs_get_dest(_jit_regs_t *regs);
+int _jit_regs_get_value1(_jit_regs_t *regs);
+int _jit_regs_get_value2(_jit_regs_t *regs);
+int _jit_regs_get_dest_other(_jit_regs_t *regs);
+int _jit_regs_get_value1_other(_jit_regs_t *regs);
+int _jit_regs_get_value2_other(_jit_regs_t *regs);
+int _jit_regs_get_scratch(_jit_regs_t *regs, int index);
+
unsigned char *_jit_regs_inst_ptr(jit_gencode_t gen, int space);
unsigned char *_jit_regs_begin(jit_gencode_t gen, _jit_regs_t *regs, int
space);
void _jit_regs_end(jit_gencode_t gen, _jit_regs_t *regs, unsigned char *inst);
-int _jit_regs_dest(_jit_regs_t *regs);
-int _jit_regs_value1(_jit_regs_t *regs);
-int _jit_regs_value2(_jit_regs_t *regs);
-int _jit_regs_dest_other(_jit_regs_t *regs);
-int _jit_regs_value1_other(_jit_regs_t *regs);
-int _jit_regs_value2_other(_jit_regs_t *regs);
-int _jit_regs_scratch(_jit_regs_t *regs, int index);
-
#ifdef __cplusplus
};
#endif
Index: jit/jit-reg-alloc.c
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-reg-alloc.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -b -r1.47 -r1.48
--- jit/jit-reg-alloc.c 28 Nov 2006 20:26:42 -0000 1.47
+++ jit/jit-reg-alloc.c 29 Dec 2006 23:16:15 -0000 1.48
@@ -62,11 +62,11 @@
#define COST_COPY 4
#define COST_SPILL_DIRTY 16
-#define COST_SPILL_DIRTY_GLOBAL 2
+#define COST_SPILL_DIRTY_GLOBAL 4
#define COST_SPILL_CLEAN 1
#define COST_SPILL_CLEAN_GLOBAL 1
-#define COST_GLOBAL_BIAS 1
-#define COST_THRASH 32
+#define COST_GLOBAL_BIAS 2
+#define COST_THRASH 100
#define COST_CLOBBER_GLOBAL 1000
#ifdef JIT_BACKEND_X86
@@ -398,10 +398,16 @@
if(regs->ternary || !regs->descs[0].value)
{
/* this is either a ternary or binary or unary note */
- if(IS_STACK_REG(reg) || regs->descs[index].clobber)
+ if(regs->descs[index].clobber)
{
flags = CLOBBER_INPUT_VALUE;
}
+#ifdef JIT_REG_STACK
+ else if(IS_STACK_REG(reg) && !regs->no_pop)
+ {
+ flags = CLOBBER_INPUT_VALUE;
+ }
+#endif
else
{
flags = CLOBBER_NONE;
@@ -439,12 +445,14 @@
{
flags = CLOBBER_NONE;
}
- else if(regs->on_stack && !regs->no_pop)
+#ifdef JIT_REG_STACK
+ else if(IS_STACK_REG(reg) && !regs->no_pop)
{
/* this is a binary or unary stack op -- the input value
is either popped or overwritten by the output */
flags = CLOBBER_INPUT_VALUE;
}
+#endif
else if(reg == regs->descs[0].reg
|| reg == regs->descs[0].other_reg
|| other_reg == regs->descs[0].reg)
@@ -504,36 +512,17 @@
}
/*
- * Initialize value descriptor.
- */
-static void
-init_regdesc(_jit_regs_t *regs, int index)
-{
- _jit_regdesc_t *desc;
-
- desc = ®s->descs[index];
- desc->value = 0;
- desc->reg = -1;
- desc->other_reg = -1;
- desc->stack_reg = -1;
- desc->regset = jit_regused_init_used;
- desc->live = 0;
- desc->used = 0;
- desc->clobber = 0;
- desc->early_clobber = 0;
- desc->duplicate = 0;
- desc->thrash = 0;
- desc->save = 0;
- desc->load = 0;
- desc->copy = 0;
- desc->kill = 0;
-}
-
-/*
* Set value information.
*/
static void
-set_regdesc_value(_jit_regs_t *regs, int index, jit_value_t value, int flags,
int live, int used)
+set_regdesc_value(
+ _jit_regs_t *regs,
+ int index,
+ jit_value_t value,
+ int flags,
+ _jit_regclass_t *regclass,
+ int live,
+ int used)
{
_jit_regdesc_t *desc;
@@ -551,6 +540,7 @@
desc->clobber = 1;
}
}
+ desc->regclass = regclass;
desc->live = live;
desc->used = used;
}
@@ -595,6 +585,7 @@
_jit_regdesc_t *desc;
int reg, other_reg;
int clobber, clobber_input;
+ int is_input, is_live_input, is_used_input;
#ifdef JIT_REG_DEBUG
printf("set_regdesc_flags(index = %d)\n", index);
@@ -606,61 +597,64 @@
return 1;
}
- /* Find the register the value is already in (if any). */
- if(desc->value->in_register)
+ /* See if the value clobbers the register it is assigned to. */
+ clobber = clobbers_register(gen, regs, index, desc->reg,
desc->other_reg);
+
+ /* See if this is an input value and whether it is alive. */
+ if(regs->ternary)
{
- reg = desc->value->reg;
- if(gen->contents[reg].is_long_start)
+ is_input = 1;
+ is_live_input = desc->live;
+ is_used_input = desc->used;
+ }
+ else if(index > 0)
{
- other_reg = OTHER_REG(reg);
+ is_input = 1;
+ if(regs->descs[0].value == desc->value)
+ {
+ is_live_input = is_used_input = 0;
}
else
{
- other_reg = -1;
+ is_live_input = desc->live;
+ is_used_input = desc->used;
}
}
else
{
- reg = -1;
- other_reg = -1;
+ is_input = is_live_input = is_used_input = 0;
}
- /* See if the value clobbers the register it is assigned to. */
- clobber = clobbers_register(gen, regs, index, desc->reg,
desc->other_reg);
- if((clobber & CLOBBER_INPUT_VALUE) != 0)
+ if(is_input)
{
- clobber_input = 1;
- }
- else if(jit_reg_is_used(regs->clobber, desc->reg))
+ /* Find the register the value is already in (if any). */
+ if(desc->value->in_register)
{
- clobber_input = 1;
- }
- else if(desc->other_reg >= 0 && jit_reg_is_used(regs->clobber,
desc->other_reg))
+ reg = desc->value->reg;
+ if(gen->contents[reg].is_long_start)
{
- clobber_input = 1;
+ other_reg = OTHER_REG(reg);
}
else
{
- clobber_input = 0;
+ other_reg = -1;
}
- if((clobber & CLOBBER_REG) != 0)
- {
- jit_reg_set_used(regs->clobber, desc->reg);
}
- if((clobber & CLOBBER_OTHER_REG) != 0)
+ else
{
- jit_reg_set_used(regs->clobber, desc->other_reg);
+ reg = -1;
+ other_reg = -1;
}
- /* See if the input value is thrashed by other inputs or clobbered
- by the output. The allocator tries to avoid thrashing so it may
- only take place if the register is assigned explicitly. For x87
- registers the problem of thrashing may be best solved with fxch
- but as the stack registers are never assigned explicitely there
- is no such problem for them at all. */
- if(reg >= 0 && (index > 0 || regs->ternary))
+ /* See if the input value is thrashed by other inputs. The
allocator
+ tries to avoid thrashing so it may only take place if the
register
+ is assigned explicitly. For x87 registers the problem of
thrashing
+ may be best solved with fxch but as the stack registers are
never
+ assigned explicitely there is no such problem for them at
all. */
+ if(reg >= 0)
{
- if(index != 0 && regs->ternary && !are_values_equal(desc,
®s->descs[0]))
+ if(index != 0 && regs->ternary
+ && !are_values_equal(desc, ®s->descs[0]))
{
if(reg == regs->descs[0].reg
|| reg == regs->descs[0].other_reg
@@ -698,31 +692,41 @@
{
reg = -1;
other_reg = -1;
- desc->save = 1;
+ desc->store = 1;
}
}
- if(index > 0 || regs->ternary)
- {
/* See if the value needs to be loaded or copied or none. */
- if(desc->value->has_global_register)
+ if(reg != desc->reg)
{
- if(desc->value->global_reg != desc->reg
- && !(reg >= 0 && reg == desc->reg))
+ if(desc->value->has_global_register)
{
- desc->copy = 1;
+ desc->copy = (desc->value->global_reg !=
desc->reg);
}
+ else if(reg < 0)
+ {
+ desc->load = 1;
}
else
{
- if(reg < 0)
+ desc->copy = 1;
+ }
+ }
+
+ /* See if the input value is destroyed by the instruction. */
+ if(desc->copy)
{
- desc->load = 1;
+ clobber_input = 0;
}
- else if(reg != desc->reg)
+ else if(jit_reg_is_used(regs->clobber, desc->reg)
+ || (desc->other_reg >= 0
+ && jit_reg_is_used(regs->clobber, desc->other_reg)))
{
- desc->copy = 1;
+ clobber_input = 1;
}
+ else
+ {
+ clobber_input = ((clobber & CLOBBER_INPUT_VALUE) != 0);
}
/* See if the input value needs to be saved before the
@@ -732,32 +736,28 @@
{
desc->kill = 1;
}
- else if(reg >= 0)
+ else if(clobber_input)
{
- if(desc->used)
- {
- if(!desc->copy && clobber_input)
- {
- desc->save = 1;
+ desc->store = (is_live_input || is_used_input);
desc->kill = 1;
}
- }
- else
+ else if(!is_used_input)
{
- if(desc->live)
- {
- desc->save = 1;
- }
+ desc->store = is_live_input;
desc->kill = 1;
}
- }
- else if(desc->load)
+
+#ifdef JIT_REG_STACK
+ /* Count stack registers. */
+ if(IS_STACK_REG(desc->reg))
{
- if(!desc->used || clobber_input)
+ ++(regs->wanted_stack_count);
+ if(!desc->load && !desc->copy)
{
- desc->kill = 1;
+ ++(regs->loaded_stack_count);
}
}
+#endif
}
/* See if the value clobbers a global register. In this case the global
@@ -771,16 +771,14 @@
desc->kill = 1;
}
- if(IS_STACK_REG(desc->reg))
- {
- if(index > 0 || regs->ternary)
- {
- ++(regs->wanted_stack_count);
- if(!(desc->load || desc->copy))
+ /* Set clobber flags (this indicates registers to be spilled). */
+ if((clobber & CLOBBER_REG) != 0)
{
- ++(regs->loaded_stack_count);
- }
+ jit_reg_set_used(regs->clobber, desc->reg);
}
+ if((clobber & CLOBBER_OTHER_REG) != 0)
+ {
+ jit_reg_set_used(regs->clobber, desc->other_reg);
}
#ifdef JIT_REG_DEBUG
@@ -801,7 +799,7 @@
printf("early_clobber = %d\n", desc->early_clobber);
printf("duplicate = %d\n", desc->duplicate);
printf("thrash = %d\n", desc->thrash);
- printf("save = %d\n", desc->save);
+ printf("store = %d\n", desc->store);
printf("load = %d\n", desc->load);
printf("copy = %d\n", desc->copy);
printf("kill = %d\n", desc->kill);
@@ -983,31 +981,25 @@
static int
choose_scratch_register(jit_gencode_t gen, _jit_regs_t *regs, int index)
{
- int reg, type;
+ _jit_regclass_t *regclass;
+ int reg_index, reg;
int use_cost;
int suitable_reg;
int suitable_cost;
int suitable_age;
- type = JIT_REG_WORD;
+ regclass = regs->scratch[index].regclass;
suitable_reg = -1;
suitable_cost = COST_TOO_MUCH;
suitable_age = -1;
- for(reg = 0; reg < JIT_NUM_REGS; reg++)
- {
- if((_jit_reg_info[reg].flags & type) == 0)
+ for(reg_index = 0; reg_index < regclass->num_regs; reg_index++)
{
- continue;
- }
+ reg = regclass->regs[reg_index];
if(jit_reg_is_used(regs->assigned, reg))
{
continue;
}
- if(!jit_reg_is_used(regs->scratch[index].regset, reg))
- {
- continue;
- }
#if ALLOW_CLOBBER_GLOBAL
if(jit_reg_is_used(gen->permanent, reg))
@@ -1067,38 +1059,28 @@
static int
choose_output_register(jit_gencode_t gen, _jit_regs_t *regs)
{
- int type, need_pair;
- int reg, other_reg;
+ _jit_regclass_t *regclass;
+ int need_pair;
+ int reg_index, reg, other_reg;
int use_cost;
int suitable_reg, suitable_other_reg;
int suitable_cost;
int suitable_age;
+ regclass = regs->descs[0].regclass;
need_pair = _jit_regs_needs_long_pair(regs->descs[0].value->type);
- type = get_register_type(regs->descs[0].value, need_pair);
- if(!type)
- {
- return 0;
- }
suitable_reg = -1;
suitable_other_reg = -1;
suitable_cost = COST_TOO_MUCH;
suitable_age = -1;
- for(reg = 0; reg < JIT_NUM_REGS; reg++)
- {
- if((_jit_reg_info[reg].flags & type) == 0)
+ for(reg_index = 0; reg_index < regclass->num_regs; reg_index++)
{
- continue;
- }
+ reg = regclass->regs[reg_index];
if(jit_reg_is_used(gen->inhibit, reg))
{
continue;
}
- if(!jit_reg_is_used(regs->descs[0].regset, reg))
- {
- continue;
- }
if(need_pair)
{
@@ -1174,10 +1156,16 @@
&& regs->descs[2].value->in_register
&& regs->descs[2].value->reg == reg)
{
- if(regs->commutative || regs->x87_arith)
+ if(regs->commutative)
+ {
+ use_cost = 0;
+ }
+#ifdef JIT_REG_STACK
+ else if(regs->x87_arith)
{
use_cost = 0;
}
+#endif
else
{
use_cost = COST_THRASH;
@@ -1227,26 +1215,21 @@
choose_input_order(jit_gencode_t gen, _jit_regs_t *regs)
{
_jit_regdesc_t temp_desc;
- int keep1, keep2;
-
- if(regs->ternary || regs->free_dest || !regs->descs[0].value)
- {
- regs->dest_input_index = 0;
- return;
- }
if(regs->descs[2].value
&& regs->descs[2].value->in_register
&& regs->descs[2].value->reg == regs->descs[0].reg
&& regs->descs[2].value != regs->descs[1].value)
{
- if(regs->on_stack && regs->x87_arith)
+#ifdef JIT_REG_STACK
+ if(regs->x87_arith)
{
regs->no_pop = 1;
regs->reverse_dest = 1;
regs->dest_input_index = 2;
}
else
+#endif
{
if(regs->commutative)
{
@@ -1266,11 +1249,14 @@
regs->dest_input_index = 0;
}
+#ifdef JIT_REG_STACK
/* Choose between pop and no-pop instructions. */
- if(regs->on_stack && regs->x87_arith && !regs->no_pop
+ if(!regs->no_pop && regs->x87_arith
&& !regs->clobber_all && !regs->clobber_stack
&& regs->descs[1].value && regs->descs[2].value)
{
+ int keep1, keep2;
+
/* Determine if we might want to keep either of input values
in registers after the instruction completion. */
if(regs->descs[1].value->in_register)
@@ -1296,15 +1282,17 @@
regs->no_pop = (keep1 || keep2);
}
+#endif
}
static int
choose_input_register(jit_gencode_t gen, _jit_regs_t *regs, int index)
{
+ _jit_regclass_t *regclass;
_jit_regdesc_t *desc;
_jit_regdesc_t *desc2;
- int type, need_pair;
- int reg, other_reg;
+ int need_pair;
+ int reg_index, reg, other_reg;
int use_cost;
int suitable_reg, suitable_other_reg;
int suitable_cost;
@@ -1317,12 +1305,8 @@
return 0;
}
+ regclass = regs->descs[index].regclass;
need_pair = _jit_regs_needs_long_pair(desc->value->type);
- type = get_register_type(desc->value, need_pair);
- if(!type)
- {
- return 0;
- }
if(index == regs->dest_input_index)
{
@@ -1337,20 +1321,13 @@
suitable_other_reg = -1;
suitable_cost = COST_TOO_MUCH;
suitable_age = -1;
- for(reg = 0; reg < JIT_NUM_REGS; reg++)
- {
- if((_jit_reg_info[reg].flags & type) == 0)
+ for(reg_index = 0; reg_index < regclass->num_regs; reg_index++)
{
- continue;
- }
+ reg = regclass->regs[reg_index];
if(jit_reg_is_used(regs->assigned, reg))
{
continue;
}
- if(!jit_reg_is_used(desc->regset, reg))
- {
- continue;
- }
if(need_pair)
{
@@ -1463,9 +1440,10 @@
static void
check_duplicate_value(_jit_regs_t *regs, _jit_regdesc_t *desc1, _jit_regdesc_t
*desc2)
{
- if((!regs->on_stack || regs->x87_arith)
- && are_values_equal(desc1, desc2)
- && desc1->reg >= 0 && desc2->reg < 0
+ if(desc2->reg < 0 && desc1->reg >= 0 && are_values_equal(desc1, desc2)
+#ifdef JIT_REG_STACK
+ && (!IS_STACK_REG(desc1->reg) || regs->x87_arith)
+#endif
&& !desc1->early_clobber && !desc2->early_clobber)
{
desc2->reg = desc1->reg;
@@ -1501,7 +1479,7 @@
index = regs->dest_input_index;
}
- if(regs->x87_arith && desc->value->in_register && !desc->copy)
+ if(desc->value->in_register && !desc->copy && regs->x87_arith)
{
desc->reg = desc->value->reg;
}
@@ -1523,7 +1501,8 @@
int top_index;
/* Choose instruction that results into fewer exchanges. */
- if(regs->on_stack && regs->no_pop && (regs->commutative ||
regs->reversible))
+ if(regs->wanted_stack_count > 1 && regs->no_pop
+ && (regs->commutative || regs->reversible))
{
desc1 = ®s->descs[1];
desc2 = ®s->descs[2];
@@ -1806,7 +1785,7 @@
#ifdef JIT_REG_DEBUG
printf("free_value(value = ");
jit_dump_value(stdout, jit_value_get_function(value), value, 0);
- printf(", reg = %d, other_reg = %d)\n", reg, other_reg);
+ printf(", reg = %d, other_reg = %d, temp = %d)\n", reg, other_reg,
temp);
#endif
/* Never free global registers. */
@@ -1847,7 +1826,7 @@
#ifdef JIT_REG_DEBUG
printf("save_value(value = ");
jit_dump_value(stdout, jit_value_get_function(value), value, 0);
- printf(", reg = %d, other_reg = %d)\n", reg, other_reg);
+ printf(", reg = %d, other_reg = %d, free=%d)\n", reg, other_reg, free);
#endif
/* First take care of values that reside in global registers. */
if(value->has_global_register)
@@ -2066,7 +2045,7 @@
#endif
desc = ®s->descs[index];
- if(!(desc->value && desc->value->in_register && desc->save))
+ if(!desc->value || !desc->value->in_register || !desc->store)
{
return;
}
@@ -2291,13 +2270,16 @@
}
static void
-commit_input_value(jit_gencode_t gen, _jit_regs_t *regs, int index)
+commit_input_value(jit_gencode_t gen, _jit_regs_t *regs, int index, int
go_down_stack)
{
_jit_regdesc_t *desc;
int reg, other_reg;
+#ifdef JIT_REG_STACK
+ int is_down_stack = 0;
+#endif
#ifdef JIT_REG_DEBUG
- printf("commit_input_value(%d)\n", index);
+ printf("commit_input_value(%d, %d)\n", index, go_down_stack);
#endif
desc = ®s->descs[index];
@@ -2309,19 +2291,34 @@
if(desc->copy)
{
#ifdef JIT_REG_STACK
- if(IS_STACK_REG(desc->reg) && !regs->copy)
+ if(IS_STACK_REG(desc->reg))
+ {
+ if(!go_down_stack)
+ {
+ if(1/*!regs->copy*/)
{
--(gen->reg_stack_top);
}
+ gen->contents[desc->reg].used_for_temp = 0;
+ }
+ is_down_stack = 1;
+ }
+ else
#endif
+ {
gen->contents[desc->reg].used_for_temp = 0;
if(desc->other_reg >= 0)
{
gen->contents[desc->other_reg].used_for_temp = 0;
}
}
+ }
+#ifdef JIT_REG_STACK
+ if(desc->kill && desc->value->in_register && is_down_stack ==
go_down_stack)
+#else
if(desc->kill && desc->value->in_register)
+#endif
{
reg = desc->value->reg;
if(gen->contents[reg].is_long_start)
@@ -2332,12 +2329,21 @@
{
other_reg = -1;
}
- unbind_value(gen, desc->value, reg, other_reg);
#ifdef JIT_REG_STACK
- if(IS_STACK_REG(reg) && !regs->copy)
+ if(is_down_stack)
+ {
+ free_value(gen, desc->value, reg, other_reg, 0);
+ }
+ else
+ {
+ unbind_value(gen, desc->value, reg, other_reg);
+ if(IS_STACK_REG(reg) /*&& !regs->copy*/)
{
--(gen->reg_stack_top);
}
+ }
+#else
+ unbind_value(gen, desc->value, reg, other_reg);
#endif
}
@@ -2369,7 +2375,7 @@
}
#ifdef JIT_REG_STACK
- if(IS_STACK_REG(desc->reg) && !regs->copy)
+ if(IS_STACK_REG(desc->reg) /*&& !regs->copy*/)
{
++(gen->reg_stack_top);
}
@@ -2951,91 +2957,80 @@
{
int index;
- regs->clobber_all = (flags & _JIT_REGS_CLOBBER_ALL) != 0;
- regs->clobber_stack = (flags & _JIT_REGS_CLOBBER_STACK) != 0;
+ jit_memset(regs, 0, sizeof(_jit_regs_t));
+
regs->ternary = (flags & _JIT_REGS_TERNARY) != 0;
regs->branch = (flags & _JIT_REGS_BRANCH) != 0;
regs->copy = (flags & _JIT_REGS_COPY) != 0;
regs->commutative = (flags & _JIT_REGS_COMMUTATIVE) != 0;
+ regs->free_dest = (flags & _JIT_REGS_FREE_DEST) != 0;
+#ifdef JIT_REG_STACK
regs->on_stack = (flags & _JIT_REGS_STACK) != 0;
regs->x87_arith = (flags & _JIT_REGS_X87_ARITH) != 0;
regs->reversible = (flags & _JIT_REGS_REVERSIBLE) != 0;
- regs->free_dest = (flags & _JIT_REGS_FREE_DEST) != 0;
-
- regs->no_pop = 0;
- regs->reverse_dest = 0;
- regs->reverse_args = 0;
+ regs->no_pop = (regs->on_stack & regs->copy) != 0;
+#endif
for(index = 0; index < _JIT_REGS_VALUE_MAX; index++)
{
- init_regdesc(regs, index);
+ regs->descs[index].reg = -1;
+ regs->descs[index].other_reg = -1;
+ regs->descs[index].stack_reg = -1;
}
for(index = 0; index < _JIT_REGS_SCRATCH_MAX; index++)
{
regs->scratch[index].reg = -1;
- regs->scratch[index].regset = jit_regused_init_used;
}
- regs->num_scratch = 0;
- regs->dest_input_index = 0;
- /* Set clobber flags. */
regs->clobber = jit_regused_init;
- if(regs->clobber_all || regs->clobber_stack)
- {
- for(index = 0; index < JIT_NUM_REGS; index++)
- {
- if((_jit_reg_info[index].flags & JIT_REG_FIXED)
- || jit_reg_is_used(gen->permanent, index))
- {
- continue;
- }
- if(regs->clobber_all || IS_STACK_REG(index))
- {
- jit_reg_set_used(regs->clobber, index);
- }
- }
- }
-
regs->assigned = gen->inhibit;
-
- regs->wanted_stack_count = 0;
- regs->loaded_stack_count = 0;
}
void
-_jit_regs_init_dest(_jit_regs_t *regs, jit_insn_t insn, int flags)
+_jit_regs_init_dest(_jit_regs_t *regs, jit_insn_t insn, int flags,
_jit_regclass_t *regclass)
{
if((insn->flags & JIT_INSN_DEST_OTHER_FLAGS) == 0)
{
- set_regdesc_value(regs, 0, insn->dest, flags,
+ set_regdesc_value(regs, 0, insn->dest, flags, regclass,
(insn->flags & JIT_INSN_DEST_LIVE) != 0,
(insn->flags & JIT_INSN_DEST_NEXT_USE) != 0);
}
}
void
-_jit_regs_init_value1(_jit_regs_t *regs, jit_insn_t insn, int flags)
+_jit_regs_init_value1(_jit_regs_t *regs, jit_insn_t insn, int flags,
_jit_regclass_t *regclass)
{
if((insn->flags & JIT_INSN_VALUE1_OTHER_FLAGS) == 0)
{
- set_regdesc_value(regs, 1, insn->value1, flags,
+ set_regdesc_value(regs, 1, insn->value1, flags, regclass,
(insn->flags & JIT_INSN_VALUE1_LIVE) != 0,
(insn->flags & JIT_INSN_VALUE1_NEXT_USE) !=
0);
}
}
void
-_jit_regs_init_value2(_jit_regs_t *regs, jit_insn_t insn, int flags)
+_jit_regs_init_value2(_jit_regs_t *regs, jit_insn_t insn, int flags,
_jit_regclass_t *regclass)
{
if((insn->flags & JIT_INSN_VALUE2_OTHER_FLAGS) == 0)
{
- set_regdesc_value(regs, 2, insn->value2, flags,
+ set_regdesc_value(regs, 2, insn->value2, flags, regclass,
(insn->flags & JIT_INSN_VALUE2_LIVE) != 0,
(insn->flags & JIT_INSN_VALUE2_NEXT_USE) !=
0);
}
}
void
+_jit_regs_add_scratch(_jit_regs_t *regs, _jit_regclass_t *regclass)
+{
+ if(regs->num_scratch < _JIT_REGS_SCRATCH_MAX)
+ {
+ regs->scratch[regs->num_scratch].reg = -1;
+ regs->scratch[regs->num_scratch].regclass = regclass;
+ ++regs->num_scratch;
+ }
+}
+
+void
_jit_regs_set_dest(jit_gencode_t gen, _jit_regs_t *regs, int reg, int
other_reg)
{
if(reg >= 0 && !IS_STACK_REG(reg))
@@ -3063,95 +3058,52 @@
}
void
-_jit_regs_add_scratch(jit_gencode_t gen, _jit_regs_t *regs, int reg)
+_jit_regs_set_scratch(jit_gencode_t gen, _jit_regs_t *regs, int index, int reg)
{
- if(regs->num_scratch < _JIT_REGS_SCRATCH_MAX)
+ if(index < regs->num_scratch && index >= 0 && reg >= 0 &&
!IS_STACK_REG(reg))
{
- if(reg < 0)
- {
- ++regs->num_scratch;
- }
- else if(!IS_STACK_REG(reg))
- {
- set_scratch_register(gen, regs, regs->num_scratch++,
reg);
- }
- }
-}
-
-void
-_jit_regs_set_clobber(jit_gencode_t gen, _jit_regs_t *regs, int reg)
-{
- if(reg >= 0)
- {
- jit_reg_set_used(regs->clobber, reg);
- }
-}
-
-void
-_jit_regs_set_dest_from(_jit_regs_t *regs, jit_regused_t regset)
-{
- regs->descs[0].regset = regset;
-}
-
-void
-_jit_regs_set_value1_from(_jit_regs_t *regs, jit_regused_t regset)
-{
- regs->descs[1].regset = regset;
-}
-
-void
-_jit_regs_set_value2_from(_jit_regs_t *regs, jit_regused_t regset)
-{
- regs->descs[2].regset = regset;
-}
-
-void
-_jit_regs_add_scratch_from(_jit_regs_t *regs, jit_regused_t regset)
-{
- if(regs->num_scratch < _JIT_REGS_SCRATCH_MAX)
- {
- regs->scratch[regs->num_scratch++].regset = regset;
+ set_scratch_register(gen, regs, index, reg);
}
}
int
-_jit_regs_dest(_jit_regs_t *regs)
+_jit_regs_get_dest(_jit_regs_t *regs)
{
return regs->descs[0].reg;
}
int
-_jit_regs_value1(_jit_regs_t *regs)
+_jit_regs_get_value1(_jit_regs_t *regs)
{
return regs->descs[1].reg;
}
int
-_jit_regs_value2(_jit_regs_t *regs)
+_jit_regs_get_value2(_jit_regs_t *regs)
{
return regs->descs[2].reg;
}
int
-_jit_regs_dest_other(_jit_regs_t *regs)
+_jit_regs_get_dest_other(_jit_regs_t *regs)
{
return regs->descs[0].other_reg;
}
int
-_jit_regs_value1_other(_jit_regs_t *regs)
+_jit_regs_get_value1_other(_jit_regs_t *regs)
{
return regs->descs[1].other_reg;
}
int
-_jit_regs_value2_other(_jit_regs_t *regs)
+_jit_regs_get_value2_other(_jit_regs_t *regs)
{
return regs->descs[2].other_reg;
}
int
-_jit_regs_scratch(_jit_regs_t *regs, int index)
+_jit_regs_get_scratch(_jit_regs_t *regs, int index)
{
if(index < regs->num_scratch && index >= 0)
{
@@ -3160,6 +3112,58 @@
return -1;
}
+void
+_jit_regs_clobber(_jit_regs_t *regs, int reg)
+{
+ if(reg >= 0)
+ {
+ jit_reg_set_used(regs->clobber, reg);
+ }
+}
+
+void
+_jit_regs_clobber_class(jit_gencode_t gen, _jit_regs_t *regs, _jit_regclass_t
*regclass)
+{
+ int index;
+
+#ifdef JIT_REG_STACK
+ if((regclass->flags & JIT_REG_IN_STACK) != 0)
+ {
+ regs->clobber_stack = 1;
+ }
+#endif
+
+ for(index = 0; index < regclass->num_regs; index++)
+ {
+ if(jit_reg_is_used(gen->permanent, index))
+ {
+ continue;
+ }
+ jit_reg_set_used(regs->clobber, regclass->regs[index]);
+ }
+}
+
+void
+_jit_regs_clobber_all(jit_gencode_t gen, _jit_regs_t *regs)
+{
+ int index;
+
+ regs->clobber_all = 1;
+
+ for(index = 0; index < JIT_NUM_REGS; index++)
+ {
+ if((_jit_reg_info[index].flags & JIT_REG_FIXED) != 0)
+ {
+ continue;
+ }
+ if(jit_reg_is_used(gen->permanent, index))
+ {
+ continue;
+ }
+ jit_reg_set_used(regs->clobber, index);
+ }
+}
+
int
_jit_regs_assign(jit_gencode_t gen, _jit_regs_t *regs)
{
@@ -3172,8 +3176,9 @@
/* For binary or unary ops with explicitely assigned registers
the output always goes to the same register as the first input
value unless this is a three-address instruction. */
- if(!(regs->ternary || regs->free_dest)
- && regs->descs[0].value && regs->descs[1].value)
+ if(!regs->ternary && !regs->free_dest
+ && regs->descs[0].value
+ && regs->descs[1].value)
{
if(regs->descs[0].reg >= 0)
{
@@ -3412,6 +3417,7 @@
return 1;
}
+#ifdef JIT_REG_STACK
int
_jit_regs_select(_jit_regs_t *regs)
{
@@ -3433,6 +3439,7 @@
return flags;
}
+#endif
void
_jit_regs_commit(jit_gencode_t gen, _jit_regs_t *regs)
@@ -3444,26 +3451,74 @@
#endif
#ifdef JIT_REG_STACK
+ if(regs->wanted_stack_count > 0)
+ {
+ int reg1, reg2;
+
+ /* The stack registers has to be freed from the top down. It is
+ assumed that only binary instructions may have more than one
+ stack register. The unary instruction may not do that for
+ obvious reasons. The practical observation is that no ternary
+ instruction in libjit does that as well. */
if(regs->reverse_args)
{
- commit_input_value(gen, regs, 1);
- commit_input_value(gen, regs, 2);
+ commit_input_value(gen, regs, 1, 0);
+ commit_input_value(gen, regs, 2, 0);
}
else
-#endif
{
- commit_input_value(gen, regs, 2);
- commit_input_value(gen, regs, 1);
+ commit_input_value(gen, regs, 2, 0);
+ commit_input_value(gen, regs, 1, 0);
}
if(regs->ternary)
{
- commit_input_value(gen, regs, 0);
+ commit_input_value(gen, regs, 0, 0);
}
else
{
commit_output_value(gen, regs);
}
+ /* If the allocator makes a copy of a value that was already on
+ the stack we might need to free the original register as
well.
+ In general, the allocator makes a copy if the value is going
+ to be destroyed by the instruction while it is still used
+ (according to the liveness analysis). But the original value
+ needs to be freed only if it is no longer used. So this extra
+ code seems useless. But there were cases when the allocator
+ miscalculated the cost of spilling and made a copy when it
+ was not needed. So this code serves as a precaution against
+ such problematic cases. */
+ reg1 = ((regs->descs[1].value &&
regs->descs[1].value->in_register)
+ ? regs->descs[1].value->reg : -1);
+ reg2 = ((regs->descs[2].value &&
regs->descs[2].value->in_register)
+ ? regs->descs[2].value->reg : -1);
+ if(reg1 > reg2)
+ {
+ commit_input_value(gen, regs, 1, 1);
+ commit_input_value(gen, regs, 2, 1);
+ }
+ else
+ {
+ commit_input_value(gen, regs, 2, 1);
+ commit_input_value(gen, regs, 1, 1);
+ }
+ }
+ else
+#endif
+ {
+ commit_input_value(gen, regs, 2, 0);
+ commit_input_value(gen, regs, 1, 0);
+ if(regs->ternary)
+ {
+ commit_input_value(gen, regs, 0, 0);
+ }
+ else
+ {
+ commit_output_value(gen, regs);
+ }
+ }
+
/* Load clobbered global registers. */
for(reg = JIT_NUM_REGS - 1; reg >= 0; reg--)
{
Index: jit/jit-rules-alpha.ins
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-rules-alpha.ins,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- jit/jit-rules-alpha.ins 20 Aug 2006 15:47:54 -0000 1.5
+++ jit/jit-rules-alpha.ins 29 Dec 2006 23:16:15 -0000 1.6
@@ -20,29 +20,32 @@
%inst_type alpha_inst
+%regclass reg alpha_reg
+%regclass lreg alpha_reg
+
/*
* Conversion opcodes.
*/
-JIT_OP_TRUNC_SBYTE: unary
+JIT_OP_TRUNC_SBYTE:
[reg] -> {
alpha_slli(inst,$1,56,$1);
alpha_srai(inst,$1,56,$1);
}
-JIT_OP_TRUNC_UBYTE: unary
+JIT_OP_TRUNC_UBYTE:
[reg] -> {
_alpha_li8(inst,ALPHA_AT,0xff);
alpha_and(inst,$1,ALPHA_AT,$1);
}
-JIT_OP_TRUNC_SHORT: unary
+JIT_OP_TRUNC_SHORT:
[reg] -> {
alpha_slli(inst,$1,56,$1);
alpha_srai(inst,$1,56,$1);
}
-JIT_OP_TRUNC_USHORT: unary
+JIT_OP_TRUNC_USHORT:
[reg] -> {
alpha_slli(inst,$1,56,$1);
alpha_srli(inst,$1,56,$1);
@@ -69,7 +72,7 @@
*/
/* return value1 + value2; */
-JIT_OP_IADD: binary
+JIT_OP_IADD:
[=reg, reg, imm, if("$3 == 0")] -> {
alpha_mov(inst,$2,$1);
}
@@ -78,7 +81,7 @@
}
/* return value1 - value2; */
-JIT_OP_ISUB: binary
+JIT_OP_ISUB:
[=reg, reg, imm, if("$3 == 0")] -> {
alpha_mov(inst,$2,$1);
}
@@ -88,7 +91,7 @@
/* return value1 * value2; */
/* TODO add more trivial IMUL imm rules */
-JIT_OP_IMUL: binary
+JIT_OP_IMUL:
[=reg, reg, imm, if("$3 == 1")] -> {
alpha_mov(inst,$2,$1);
}
@@ -113,27 +116,27 @@
*/
/* return -value1; */
-JIT_OP_INEG: unary
+JIT_OP_INEG:
[reg] -> {
/* Alpha has no neg operation, do $1 = 0 - $1; instead */
alpha_subl(inst,ALPHA_ZERO,$1,$1);
}
/* return value1 + value2 */
-JIT_OP_LADD: binary
+JIT_OP_LADD:
[=lreg, lreg, lreg] -> {
alpha_addq(inst,$3,$2,$1);
}
/* return value1 - value2 */
-JIT_OP_LSUB: binary
+JIT_OP_LSUB:
[=lreg, lreg, lreg] -> {
alpha_subq(inst,$3,$2,$1);
}
/* return value1 * value2 */
/* TODO add more trivial LMUL imm rules */
-JIT_OP_LMUL: binary
+JIT_OP_LMUL:
[=lreg, lreg, imm, if("$3 == 1")] -> {
alpha_mov(inst,$2,$1);
}
@@ -147,7 +150,7 @@
alpha_mulq(inst,$3,$2,$1);
}
-JIT_OP_LNEG: unary
+JIT_OP_LNEG:
[lreg] -> {
/* Alpha has no neg operation, do $1 = 0 - $1; instead */
alpha_subq(inst,ALPHA_ZERO,$1,$1);
@@ -167,22 +170,22 @@
/*
* Bitwise opcodes.
*/
-JIT_OP_IAND: binary
+JIT_OP_IAND:
[=reg, reg, reg] -> {
alpha_and(inst,$3,$2,$1);
}
-JIT_OP_IOR: binary
+JIT_OP_IOR:
[=reg, reg, reg] -> {
alpha_or(inst,$3,$2,$1);
}
-JIT_OP_IXOR: binary
+JIT_OP_IXOR:
[=reg, reg, reg] -> {
alpha_xor(inst,$3,$2,$1);
}
-JIT_OP_INOT: unary
+JIT_OP_INOT:
[reg] -> {
_alpha_li32(inst,ALPHA_AT,0xffffffff);
alpha_xor(inst,ALPHA_AT,$1,$1);
@@ -196,38 +199,38 @@
* these to work properly.
*/
-JIT_OP_LAND: binary
+JIT_OP_LAND:
[=reg, reg, reg] -> {
alpha_and(inst,$3,$2,$1);
}
-JIT_OP_LOR: binary
+JIT_OP_LOR:
[=reg, reg, reg] -> {
alpha_or(inst,$3,$2,$1);
}
-JIT_OP_LXOR: binary
+JIT_OP_LXOR:
[=reg, reg, reg] -> {
alpha_xor(inst,$3,$2,$1);
}
-JIT_OP_LNOT: unary
+JIT_OP_LNOT:
[reg] -> {
_alpha_li64(inst,ALPHA_AT,0xffffffff);
alpha_xor(inst,ALPHA_AT,$1,$1);
}
-JIT_OP_LSHL: binary
+JIT_OP_LSHL:
[=reg, reg, reg] -> {
alpha_sll(inst,$3,$2,$1);
}
-JIT_OP_LSHR: binary
+JIT_OP_LSHR:
[=reg, reg, reg] -> {
alpha_srl(inst,$3,$2,$1);
}
-JIT_OP_LSHR_UN: binary
+JIT_OP_LSHR_UN:
[=reg, reg, reg] -> {
alpha_sra(inst,$3,$2,$1);
}
@@ -236,25 +239,25 @@
* Branch opcodes
*/
-JIT_OP_BR: spill_before
+JIT_OP_BR: branch
[] -> {
/* branch if ALPHA_ZERO is zero (this is always true) */
alpha_output_branch(func, inst, ALPHA_OP_BEQ, insn, ALPHA_ZERO);
}
-JIT_OP_BR_IFALSE: unary_branch
+JIT_OP_BR_IFALSE: branch
[reg] -> {
/* banch if $1 == 0 */
alpha_output_branch(func, inst, ALPHA_OP_BEQ, insn, $1);
}
-JIT_OP_BR_ITRUE: unary_branch
+JIT_OP_BR_ITRUE: branch
[reg] -> {
/* branch if $1 != 0 */
alpha_output_branch(func, inst, ALPHA_OP_BNE, insn, $1);
}
-JIT_OP_BR_IEQ: binary_branch
+JIT_OP_BR_IEQ: branch
[reg, reg] -> {
/* $1 == $2 -> $at */
alpha_cmpeq(inst, $1, $2, ALPHA_AT);
@@ -263,7 +266,7 @@
alpha_output_branch(func, inst, ALPHA_OP_BEQ, insn, ALPHA_AT);
}
-JIT_OP_BR_INE: binary_branch
+JIT_OP_BR_INE: branch
[reg, reg] -> {
/* $1 == $2 -> $at */
alpha_cmpeq(inst, $1, $2, ALPHA_AT);
@@ -271,7 +274,8 @@
/* branch if $at == 0 */
alpha_output_branch(func, inst, ALPHA_OP_BNE, insn, ALPHA_AT);
}
-JIT_OP_BR_ILT: binary_branch
+
+JIT_OP_BR_ILT: branch
[reg, reg] -> {
/* $1 < $2 -> $at */
alpha_cmplt(inst, $1, $2, ALPHA_AT);
@@ -280,7 +284,7 @@
alpha_output_branch(func, inst, ALPHA_OP_BEQ, insn, ALPHA_AT);
}
-JIT_OP_BR_ILT_UN: binary_branch
+JIT_OP_BR_ILT_UN: branch
[reg, reg] -> {
/* $1 < $2 -> $at */
alpha_cmpult(inst, $1, $2, ALPHA_AT);
@@ -289,7 +293,7 @@
alpha_output_branch(func, inst, ALPHA_OP_BEQ, insn, ALPHA_AT);
}
-JIT_OP_BR_ILE: binary_branch
+JIT_OP_BR_ILE: branch
[reg, reg] -> {
/* $1 <= $2 -> $at */
alpha_cmple(inst, $1, $2, ALPHA_AT);
@@ -298,7 +302,7 @@
alpha_output_branch(func, inst, ALPHA_OP_BEQ, insn, ALPHA_AT);
}
-JIT_OP_BR_ILE_UN: binary_branch
+JIT_OP_BR_ILE_UN: branch
[reg, reg] -> {
/* $1 <= $2 -> $at */
alpha_cmpule(inst, $1, $2, ALPHA_AT);
@@ -307,7 +311,7 @@
alpha_output_branch(func, inst, ALPHA_OP_BEQ, insn, ALPHA_AT);
}
-JIT_OP_BR_IGT:
+JIT_OP_BR_IGT: branch
[reg, reg] -> {
/* $1 <= $2 -> $at */
alpha_cmpgt(inst, $1, $2, ALPHA_AT);
@@ -316,7 +320,7 @@
alpha_output_branch(func, inst, ALPHA_OP_BEQ, insn, ALPHA_AT);
}
-JIT_OP_BR_IGT_UN:
+JIT_OP_BR_IGT_UN: branch
[reg, reg] -> {
/* $1 > $2 -> $at */
alpha_cmpugt(inst, $1, $2, ALPHA_AT);
@@ -325,7 +329,7 @@
alpha_output_branch(func, inst, ALPHA_OP_BEQ, insn, ALPHA_AT);
}
-JIT_OP_BR_IGE:
+JIT_OP_BR_IGE: branch
[reg, reg] -> {
/* $1 >= $2 -> $at */
alpha_cmpge(inst, $1, $2, ALPHA_AT);
@@ -334,7 +338,7 @@
alpha_output_branch(func, inst, ALPHA_OP_BEQ, insn, ALPHA_AT);
}
-JIT_OP_BR_IGE_UN:
+JIT_OP_BR_IGE_UN: branch
[reg, reg] -> {
/* $1 >= $2 -> $at */
alpha_cmpuge(inst, $1, $2, ALPHA_AT);
@@ -348,34 +352,34 @@
* Comparison opcodes.
*/
-JIT_OP_IEQ: binary
+JIT_OP_IEQ:
[=reg, reg, reg] -> {
alpha_cmpeq(inst,$3,$2,$1);
}
-JIT_OP_INE: binary
+JIT_OP_INE:
[=reg, reg, reg] -> {
alpha_cmpeq(inst,$3,$2,$1);
alpha_cmpeq(inst,$1,ALPHA_ZERO,$1);
}
-JIT_OP_ILT: binary
+JIT_OP_ILT:
[=reg, reg, reg] -> {
alpha_cmplt(inst,$3,$2,$1);
}
-JIT_OP_ILT_UN: binary
+JIT_OP_ILT_UN:
[=reg, reg, reg] -> {
alpha_cmpult(inst,$3,$2,$1);
}
-JIT_OP_ILE: binary
+JIT_OP_ILE:
[=reg, reg, reg] -> {
alpha_cmple(inst,$3,$2,$1);
}
-JIT_OP_ILE_UN: binary
+JIT_OP_ILE_UN:
[=reg, reg, reg] -> {
alpha_cmpule(inst,$3,$2,$1);
}
@@ -396,7 +400,7 @@
* Pointer check opcodes.
*/
-/* TODO: JIT_OP_CHECK_NULL: unary_note */
+/* TODO: JIT_OP_CHECK_NULL: note */
/*
* Function calls.
@@ -415,13 +419,13 @@
jump_to_epilog(gen, inst, block);
}
-JIT_OP_RETURN_INT: unary_branch
+JIT_OP_RETURN_INT: branch
[reg] -> {
alpha_mov(inst,$1,ALPHA_V0);
jump_to_epilog(gen, inst, block);
}
-JIT_OP_RETURN_LONG: unary_branch
+JIT_OP_RETURN_LONG: branch
[reg] -> {
alpha_mov(inst,$1,ALPHA_V0);
jump_to_epilog(gen, inst, block);
@@ -443,7 +447,7 @@
/* Nothing to do here */;
}
-JIT_OP_PUSH_INT: unary_note
+JIT_OP_PUSH_INT: note
[imm] -> {
alpha_li(inst,ALPHA_AT,$1);
alpha_stq(inst,ALPHA_AT,ALPHA_SP,0);
@@ -454,7 +458,7 @@
alpha_lda(inst,ALPHA_SP,ALPHA_SP,-8);
}
-JIT_OP_PUSH_LONG: unary_note
+JIT_OP_PUSH_LONG: note
[imm] -> {
alpha_li(inst,ALPHA_AT,$1);
alpha_stq(inst,ALPHA_AT,ALPHA_SP,0);
Index: jit/jit-rules-x86.ins
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-rules-x86.ins,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -b -r1.25 -r1.26
--- jit/jit-rules-x86.ins 28 Nov 2006 16:10:07 -0000 1.25
+++ jit/jit-rules-x86.ins 29 Dec 2006 23:16:15 -0000 1.26
@@ -18,17 +18,22 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+%regclass reg x86_reg
+%regclass breg x86_breg
+%regclass freg x86_freg
+%lregclass lreg x86_lreg
+
/*
* Conversion opcodes.
*/
JIT_OP_TRUNC_SBYTE:
- [=reg, reg("eax"|"ecx"|"edx"|"ebx")] -> {
+ [=reg, breg] -> {
x86_widen_reg(inst, $1, $2, 1, 0);
}
JIT_OP_TRUNC_UBYTE:
- [=reg, reg("eax"|"ecx"|"edx"|"ebx")] -> {
+ [=reg, breg] -> {
x86_widen_reg(inst, $1, $2, 0, 0);
}
@@ -147,7 +152,7 @@
}
JIT_OP_UINT_TO_NFLOAT:
- [=freg, reg, scratch("?")] -> {
+ [=freg, reg, scratch reg] -> {
x86_clear_reg(inst, $3);
x86_push_reg(inst, $3);
x86_push_reg(inst, $2);
@@ -189,7 +194,7 @@
}
JIT_OP_NFLOAT_TO_FLOAT32: stack
- [=freg, freg] -> {
+ [freg] -> {
x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(void *));
x86_fst_membase(inst, X86_ESP, 0, 0, 1);
x86_fld_membase(inst, X86_ESP, 0, 0);
@@ -197,7 +202,7 @@
}
JIT_OP_NFLOAT_TO_FLOAT64: stack
- [=freg, freg] -> {
+ [freg] -> {
x86_alu_reg_imm(inst, X86_SUB, X86_ESP, sizeof(jit_float64));
x86_fst_membase(inst, X86_ESP, 0, 1, 1);
x86_fld_membase(inst, X86_ESP, 0, 1);
@@ -224,7 +229,7 @@
x86_alu_reg_reg(inst, X86_ADD, $1, $2);
}
-JIT_OP_ISUB: binary
+JIT_OP_ISUB:
[reg, imm] -> {
x86_alu_reg_imm(inst, X86_SUB, $1, $2);
}
@@ -543,12 +548,12 @@
}
x86_shift_reg_imm(inst, X86_SAR, $1, shift);
}
- [reg("eax"), imm, scratch("?", "edx")] -> {
+ [reg("eax"), imm, scratch reg, scratch reg("edx")] -> {
x86_mov_reg_imm(inst, $3, $2);
x86_cdq(inst);
x86_div_reg(inst, $3, 1);
}
- [reg("eax"), reg, scratch("edx")] -> {
+ [reg("eax"), reg, scratch reg("edx")] -> {
unsigned char *patch, *patch2;
#ifndef JIT_USE_SIGNALS
x86_alu_reg_reg(inst, X86_OR, $2, $2);
@@ -585,12 +590,12 @@
}
x86_shift_reg_imm(inst, X86_SHR, $1, shift);
}
- [reg("eax"), imm, scratch("?", "edx")] -> {
+ [reg("eax"), imm, scratch reg, scratch reg("edx")] -> {
x86_mov_reg_imm(inst, $3, $2);
x86_clear_reg(inst, X86_EDX);
x86_div_reg(inst, $3, 0);
}
- [reg("eax"), reg, scratch("edx")] -> {
+ [reg("eax"), reg, scratch reg("edx")] -> {
#ifndef JIT_USE_SIGNALS
unsigned char *patch;
x86_alu_reg_reg(inst, X86_OR, $2, $2);
@@ -621,12 +626,12 @@
x86_patch(patch, inst);
x86_clear_reg(inst, $1);
}
- [=reg("edx"), *reg("eax"), imm, scratch("?", "edx")] -> {
+ [=reg("edx"), *reg("eax"), imm, scratch reg, scratch reg("edx")] -> {
x86_mov_reg_imm(inst, $4, $3);
x86_cdq(inst);
x86_div_reg(inst, $4, 1);
}
- [=reg("edx"), *reg("eax"), reg, scratch("edx")] -> {
+ [=reg("edx"), *reg("eax"), reg, scratch reg("edx")] -> {
unsigned char *patch, *patch2;
#ifndef JIT_USE_SIGNALS
x86_alu_reg_reg(inst, X86_OR, $3, $3);
@@ -659,12 +664,12 @@
/* x & (x - 1) is equal to zero if x is a power of 2 */
x86_alu_reg_imm(inst, X86_AND, $1, $2 - 1);
}
- [=reg("edx"), *reg("eax"), imm, scratch("?", "edx")] -> {
+ [=reg("edx"), *reg("eax"), imm, scratch reg, scratch reg("edx")] -> {
x86_mov_reg_imm(inst, $4, $3);
x86_clear_reg(inst, X86_EDX);
x86_div_reg(inst, $4, 0);
}
- [=reg("edx"), *reg("eax"), reg, scratch("edx")] -> {
+ [=reg("edx"), *reg("eax"), reg, scratch reg("edx")] -> {
#ifndef JIT_USE_SIGNALS
unsigned char *patch;
x86_alu_reg_reg(inst, X86_OR, $3, $3);
@@ -677,7 +682,7 @@
x86_div_reg(inst, $3, 0);
}
-JIT_OP_INEG: unary
+JIT_OP_INEG:
[reg] -> {
x86_neg_reg(inst, $1);
}
@@ -705,7 +710,7 @@
x86_alu_reg_reg(inst, X86_ADC, %1, %2);
}
-JIT_OP_LSUB: binary
+JIT_OP_LSUB:
[lreg, imm] -> {
jit_int value1 = ((jit_int *)($2))[0];
jit_int value2 = ((jit_int *)($2))[1];
@@ -728,7 +733,7 @@
x86_alu_reg_reg(inst, X86_SBB, %1, %2);
}
-JIT_OP_LNEG: unary
+JIT_OP_LNEG:
[lreg] -> {
/* TODO: gcc generates the first variant while
AoA suggests the second. Figure out if one
@@ -744,36 +749,29 @@
#endif
}
-JIT_OP_FADD, JIT_OP_DADD, JIT_OP_NFADD: binary, stack
+JIT_OP_FADD, JIT_OP_DADD, JIT_OP_NFADD: stack
[freg, freg] -> {
x86_fp_op_reg(inst, X86_FADD, 1, 1);
}
-JIT_OP_FSUB, JIT_OP_DSUB, JIT_OP_NFSUB: binary, stack
+JIT_OP_FSUB, JIT_OP_DSUB, JIT_OP_NFSUB: stack
[freg, freg] -> {
x86_fp_op_reg(inst, X86_FSUB, 1, 1);
}
-JIT_OP_FMUL, JIT_OP_DMUL, JIT_OP_NFMUL: binary, stack
+JIT_OP_FMUL, JIT_OP_DMUL, JIT_OP_NFMUL: stack
[freg, freg] -> {
x86_fp_op_reg(inst, X86_FMUL, 1, 1);
}
-JIT_OP_FDIV, JIT_OP_DDIV, JIT_OP_NFDIV: binary, stack
+JIT_OP_FDIV, JIT_OP_DDIV, JIT_OP_NFDIV: stack
[freg, freg] -> {
x86_fp_op_reg(inst, X86_FDIV, 1, 1);
}
-JIT_OP_FREM, JIT_OP_DREM, JIT_OP_NFREM: binary, stack
- [freg, freg] -> {
+JIT_OP_FREM, JIT_OP_DREM, JIT_OP_NFREM: stack
+ [freg, freg, scratch reg("eax")] -> {
unsigned char *label;
- int save_eax = 0;
- if(gen->contents[X86_REG_EAX].num_values > 0 ||
- gen->contents[X86_REG_EAX].used_for_temp)
- {
- save_eax = 1;
- x86_push_reg(inst, X86_EAX);
- }
x86_fxch(inst, 1);
label = inst;
x86_fprem(inst);
@@ -781,13 +779,9 @@
x86_alu_reg_imm(inst, X86_AND, X86_EAX, 0x0400);
x86_branch(inst, X86_CC_NZ, label, 0);
x86_fstp(inst, 1);
- if(save_eax)
- {
- x86_pop_reg(inst, X86_EAX);
- }
}
-JIT_OP_FNEG, JIT_OP_DNEG, JIT_OP_NFNEG: unary, stack
+JIT_OP_FNEG, JIT_OP_DNEG, JIT_OP_NFNEG: stack
[freg] -> {
x86_fchs(inst);
}
@@ -829,12 +823,12 @@
x86_alu_reg_reg(inst, X86_XOR, $1, $2);
}
-JIT_OP_INOT: unary
+JIT_OP_INOT:
[reg] -> {
x86_not_reg(inst, $1);
}
-JIT_OP_ISHL: binary
+JIT_OP_ISHL:
[reg, imm] -> {
x86_shift_reg_imm(inst, X86_SHL, $1, ($2 & 0x1F));
}
@@ -842,7 +836,7 @@
inst = shift_reg(inst, X86_SHL, $1, $2);
}
-JIT_OP_ISHR: binary
+JIT_OP_ISHR:
[reg, imm] -> {
x86_shift_reg_imm(inst, X86_SAR, $1, ($2 & 0x1F));
}
@@ -850,7 +844,7 @@
inst = shift_reg(inst, X86_SAR, $1, $2);
}
-JIT_OP_ISHR_UN: binary
+JIT_OP_ISHR_UN:
[reg, imm] -> {
x86_shift_reg_imm(inst, X86_SHR, $1, ($2 & 0x1F));
}
@@ -906,7 +900,7 @@
x86_alu_reg_reg(inst, X86_XOR, %1, %2);
}
-JIT_OP_LNOT: binary
+JIT_OP_LNOT:
[lreg] -> {
x86_not_reg(inst, $1);
x86_not_reg(inst, %1);
@@ -916,24 +910,24 @@
* Branch opcodes.
*/
-JIT_OP_BR: spill_before
+JIT_OP_BR: branch
[] -> {
inst = output_branch(func, inst, 0xEB /* jmp */, insn);
}
-JIT_OP_BR_IFALSE: unary_branch
+JIT_OP_BR_IFALSE: branch
[reg] -> {
x86_alu_reg_reg(inst, X86_OR, $1, $1);
inst = output_branch(func, inst, 0x74 /* eq */, insn);
}
-JIT_OP_BR_ITRUE: unary_branch
+JIT_OP_BR_ITRUE: branch
[reg] -> {
x86_alu_reg_reg(inst, X86_OR, $1, $1);
inst = output_branch(func, inst, 0x75 /* ne */, insn);
}
-JIT_OP_BR_IEQ: binary_branch
+JIT_OP_BR_IEQ: branch
[reg, immzero] -> {
x86_alu_reg_reg(inst, X86_OR, $1, $1);
inst = output_branch(func, inst, 0x74 /* eq */, insn);
@@ -951,7 +945,7 @@
inst = output_branch(func, inst, 0x74 /* eq */, insn);
}
-JIT_OP_BR_INE: binary_branch
+JIT_OP_BR_INE: branch
[reg, immzero] -> {
x86_alu_reg_reg(inst, X86_OR, $1, $1);
inst = output_branch(func, inst, 0x75 /* ne */, insn);
@@ -969,7 +963,7 @@
inst = output_branch(func, inst, 0x75 /* ne */, insn);
}
-JIT_OP_BR_ILT: binary_branch
+JIT_OP_BR_ILT: branch
[reg, imm] -> {
x86_alu_reg_imm(inst, X86_CMP, $1, $2);
inst = output_branch(func, inst, 0x7C /* lt */, insn);
@@ -983,7 +977,7 @@
inst = output_branch(func, inst, 0x7C /* lt */, insn);
}
-JIT_OP_BR_ILT_UN: binary_branch
+JIT_OP_BR_ILT_UN: branch
[reg, imm] -> {
x86_alu_reg_imm(inst, X86_CMP, $1, $2);
inst = output_branch(func, inst, 0x72 /* lt_un */, insn);
@@ -997,7 +991,7 @@
inst = output_branch(func, inst, 0x72 /* lt_un */, insn);
}
-JIT_OP_BR_ILE: binary_branch
+JIT_OP_BR_ILE: branch
[reg, imm] -> {
x86_alu_reg_imm(inst, X86_CMP, $1, $2);
inst = output_branch(func, inst, 0x7E /* le */, insn);
@@ -1011,7 +1005,7 @@
inst = output_branch(func, inst, 0x7E /* le */, insn);
}
-JIT_OP_BR_ILE_UN: binary_branch
+JIT_OP_BR_ILE_UN: branch
[reg, imm] -> {
x86_alu_reg_imm(inst, X86_CMP, $1, $2);
inst = output_branch(func, inst, 0x76 /* le_un */, insn);
@@ -1025,7 +1019,7 @@
inst = output_branch(func, inst, 0x76 /* le_un */, insn);
}
-JIT_OP_BR_IGT: binary_branch
+JIT_OP_BR_IGT: branch
[reg, imm] -> {
x86_alu_reg_imm(inst, X86_CMP, $1, $2);
inst = output_branch(func, inst, 0x7F /* gt */, insn);
@@ -1039,7 +1033,7 @@
inst = output_branch(func, inst, 0x7F /* gt */, insn);
}
-JIT_OP_BR_IGT_UN: binary_branch
+JIT_OP_BR_IGT_UN: branch
[reg, imm] -> {
x86_alu_reg_imm(inst, X86_CMP, $1, $2);
inst = output_branch(func, inst, 0x77 /* gt_un */, insn);
@@ -1053,7 +1047,7 @@
inst = output_branch(func, inst, 0x77 /* gt_un */, insn);
}
-JIT_OP_BR_IGE: binary_branch
+JIT_OP_BR_IGE: branch
[reg, imm] -> {
x86_alu_reg_imm(inst, X86_CMP, $1, $2);
inst = output_branch(func, inst, 0x7D /* ge */, insn);
@@ -1067,7 +1061,7 @@
inst = output_branch(func, inst, 0x7D /* ge */, insn);
}
-JIT_OP_BR_IGE_UN: binary_branch
+JIT_OP_BR_IGE_UN: branch
[reg, imm] -> {
x86_alu_reg_imm(inst, X86_CMP, $1, $2);
inst = output_branch(func, inst, 0x73 /* ge_un */, insn);
@@ -1237,29 +1231,29 @@
* Mathematical opcodes.
*/
-JIT_OP_FATAN, JIT_OP_DATAN, JIT_OP_NFATAN: unary, stack, only
- [freg] -> {
+JIT_OP_FATAN, JIT_OP_DATAN, JIT_OP_NFATAN: stack
+ [freg, clobber(freg)] -> {
x86_fld1(inst);
x86_fpatan(inst);
x86_fldz(inst);
x86_fp_op_reg(inst, X86_FADD, 1, 1);
}
-JIT_OP_FCOS, JIT_OP_DCOS, JIT_OP_NFCOS: unary, stack, only
- [freg] -> {
+JIT_OP_FCOS, JIT_OP_DCOS, JIT_OP_NFCOS: stack
+ [freg, clobber(freg)] -> {
x86_fcos(inst);
x86_fldz(inst);
x86_fp_op_reg(inst, X86_FADD, 1, 1);
}
-JIT_OP_FSIN, JIT_OP_DSIN, JIT_OP_NFSIN: unary, stack, only
- [freg] -> {
+JIT_OP_FSIN, JIT_OP_DSIN, JIT_OP_NFSIN: stack
+ [freg, clobber(freg)] -> {
x86_fsin(inst);
x86_fldz(inst);
x86_fp_op_reg(inst, X86_FADD, 1, 1);
}
-JIT_OP_FSQRT, JIT_OP_DSQRT, JIT_OP_NFSQRT: unary, stack
+JIT_OP_FSQRT, JIT_OP_DSQRT, JIT_OP_NFSQRT: stack
[freg] -> {
x86_fsqrt(inst);
}
@@ -1269,14 +1263,14 @@
*/
JIT_OP_IABS:
- [reg("eax"), scratch("edx")] -> {
+ [reg("eax"), scratch reg("edx")] -> {
x86_cdq(inst);
x86_alu_reg_reg(inst, X86_XOR, $1, $2);
x86_alu_reg_reg(inst, X86_SUB, $1, $2);
}
JIT_OP_LABS:
- [lreg, scratch("?")] -> {
+ [lreg, scratch reg] -> {
x86_mov_reg_reg(inst, $2, %1, 4);
x86_shift_reg_imm(inst, X86_SAR, $2, 31);
x86_alu_reg_reg(inst, X86_XOR, $1, $2);
@@ -1285,7 +1279,7 @@
x86_alu_reg_reg(inst, X86_SBB, %1, $2);
}
-JIT_OP_FABS, JIT_OP_DABS, JIT_OP_NFABS: unary, stack
+JIT_OP_FABS, JIT_OP_DABS, JIT_OP_NFABS: stack
[freg] -> {
x86_fabs(inst);
}
@@ -1329,7 +1323,7 @@
* Pointer check opcodes.
*/
-JIT_OP_CHECK_NULL: unary_note
+JIT_OP_CHECK_NULL: note
[reg] -> {
unsigned char *patch;
x86_alu_reg_reg(inst, X86_OR, $1, $1);
@@ -1398,32 +1392,35 @@
inst = jump_to_epilog(gen, inst, block);
}
-JIT_OP_RETURN_INT: unary_note
+JIT_OP_RETURN_INT: note
[reg("eax")] -> {
inst = jump_to_epilog(gen, inst, block);
}
-JIT_OP_RETURN_LONG: unary_note
+JIT_OP_RETURN_LONG: note
[lreg("eax":"edx")] -> {
inst = jump_to_epilog(gen, inst, block);
}
-JIT_OP_RETURN_FLOAT32: unary_note, stack, only
- [freg] -> {
+JIT_OP_RETURN_FLOAT32: note, stack
+ [freg, clobber(freg)] -> {
+ /* clobber(freg) frees all registers on the fp stack */
inst = jump_to_epilog(gen, inst, block);
}
-JIT_OP_RETURN_FLOAT64: unary_note, stack, only
- [freg] -> {
+JIT_OP_RETURN_FLOAT64: note, stack
+ [freg, clobber(freg)] -> {
+ /* clobber(freg) frees all registers on the fp stack */
inst = jump_to_epilog(gen, inst, block);
}
-JIT_OP_RETURN_NFLOAT: unary_note, stack, only
- [freg] -> {
+JIT_OP_RETURN_NFLOAT: note, stack
+ [freg, clobber(freg)] -> {
+ /* clobber(freg) frees all registers on the fp stack */
inst = jump_to_epilog(gen, inst, block);
}
-JIT_OP_RETURN_SMALL_STRUCT: binary_note
+JIT_OP_RETURN_SMALL_STRUCT: note
[reg, imm] -> {
switch($2)
{
@@ -1520,7 +1517,7 @@
inst = jump_to_epilog(gen, inst, block);
}
-JIT_OP_SETUP_FOR_NESTED: spill_before
+JIT_OP_SETUP_FOR_NESTED: branch
[] -> {
jit_nint nest_reg = jit_value_get_nint_constant(insn->value1);
if(nest_reg == -1)
@@ -1534,7 +1531,7 @@
}
}
-JIT_OP_SETUP_FOR_SIBLING: spill_before
+JIT_OP_SETUP_FOR_SIBLING: branch
[] -> {
jit_value_t parent;
jit_nint level = jit_value_get_nint_constant(insn->value1);
@@ -1615,7 +1612,7 @@
* Exception handling.
*/
-JIT_OP_THROW: unary_branch
+JIT_OP_THROW: branch
[reg] -> {
x86_push_reg(inst, $1);
if(func->builder->setjmp_value != 0)
@@ -1664,13 +1661,13 @@
JIT_OP_ENTER_FINALLY: manual
[] -> { /* Nothing to do here: return address on the stack */ }
-JIT_OP_LEAVE_FINALLY: spill_before
+JIT_OP_LEAVE_FINALLY: branch
[] -> {
/* The "finally" return address is on the stack */
x86_ret(inst);
}
-JIT_OP_CALL_FINALLY: spill_before
+JIT_OP_CALL_FINALLY: branch
[] -> {
jit_block_t block;
@@ -1769,28 +1766,17 @@
JIT_OP_COPY_NFLOAT: copy, stack
[freg] -> {}
-JIT_OP_COPY_STRUCT: manual, spill_before
- [] -> {
- unsigned char *inst;
- _jit_gen_fix_value(insn->dest);
- _jit_gen_fix_value(insn->value1);
- inst = gen->posn.ptr;
- if(!jit_cache_check_for_n(&(gen->posn), 128))
- {
- jit_cache_mark_full(&(gen->posn));
- return;
- }
- inst = memory_copy(gen, inst, X86_EBP, insn->dest->frame_offset,
- X86_EBP,
insn->value1->frame_offset,
+JIT_OP_COPY_STRUCT:
+ [=frame, frame, clobber(reg)] -> {
+ inst = memory_copy(gen, inst, X86_EBP, $1, X86_EBP, $2,
jit_type_get_size(jit_value_get_type(insn->dest)));
- gen->posn.ptr = inst;
}
JIT_OP_COPY_STORE_BYTE:
[=frame, imm] -> {
x86_mov_membase_imm(inst, X86_EBP, $1, $2, 1);
}
- [=frame, reg("eax"|"ecx"|"edx"|"ebx")] -> {
+ [=frame, breg] -> {
x86_mov_membase_reg(inst, X86_EBP, $1, $2, 1);
}
@@ -1812,9 +1798,11 @@
*/
JIT_OP_RETURN_REG: manual
- [] -> { /* Nothing to do here */ }
+ [] -> {
+ /* Nothing to do here */;
+ }
-JIT_OP_PUSH_INT: unary_note
+JIT_OP_PUSH_INT: note
[imm] -> {
x86_push_imm(inst, $1);
gen->stack_changed = 1;
@@ -1828,7 +1816,7 @@
gen->stack_changed = 1;
}
-JIT_OP_PUSH_LONG: unary_note
+JIT_OP_PUSH_LONG: note
[imm] -> {
x86_push_imm(inst, ((jit_int *)($1))[1]);
x86_push_imm(inst, ((jit_int *)($1))[0]);
@@ -1845,7 +1833,7 @@
gen->stack_changed = 1;
}
-JIT_OP_PUSH_FLOAT32: unary_note, stack
+JIT_OP_PUSH_FLOAT32: note, stack
[imm] -> {
jit_int *ptr = (jit_int *)($1);
x86_push_imm(inst, ptr[0]);
@@ -1861,7 +1849,7 @@
gen->stack_changed = 1;
}
-JIT_OP_PUSH_FLOAT64: unary_note, stack
+JIT_OP_PUSH_FLOAT64: note, stack
[imm] -> {
jit_int *ptr = (jit_int *)($1);
x86_push_imm(inst, ptr[1]);
@@ -1879,7 +1867,7 @@
gen->stack_changed = 1;
}
-JIT_OP_PUSH_NFLOAT: unary_note, stack
+JIT_OP_PUSH_NFLOAT: note, stack
[imm] -> {
jit_int *ptr = (jit_int *)($1);
if(sizeof(jit_nfloat) != sizeof(jit_float64))
@@ -1913,8 +1901,8 @@
gen->stack_changed = 1;
}
-JIT_OP_PUSH_STRUCT: unary_branch, more_space
- [reg] -> {
+JIT_OP_PUSH_STRUCT: note, more_space
+ [reg, clobber(reg)] -> {
jit_nuint size;
size = (jit_nuint)jit_value_get_nint_constant(insn->value2);
if((size % sizeof(void *)) == 0 && size <= 4 * sizeof(void *))
@@ -2013,11 +2001,9 @@
x86_fld_membase(inst, $2, $3, 1);
}
-JIT_OP_LOAD_RELATIVE_STRUCT: unary_branch, more_space
- [reg] -> {
- _jit_gen_fix_value(insn->dest);
- inst = memory_copy(gen, inst, X86_EBP, insn->dest->frame_offset,
- $1,
jit_value_get_nint_constant(insn->value2),
+JIT_OP_LOAD_RELATIVE_STRUCT: more_space
+ [=frame, reg, imm, clobber(reg)] -> {
+ inst = memory_copy(gen, inst, X86_EBP, $1, $2, $3,
jit_type_get_size(jit_value_get_type(insn->dest)));
}
@@ -2025,13 +2011,13 @@
[imm, imm, imm] -> {
x86_mov_mem_imm(inst, $1 + $3, $2, 1);
}
- [imm, reg("eax"|"ecx"|"edx"|"ebx"), imm] -> {
+ [imm, breg, imm] -> {
x86_mov_mem_reg(inst, $1 + $3, $2, 1);
}
[reg, imm, imm] -> {
x86_mov_membase_imm(inst, $1, $3, $2, 1);
}
- [reg, reg("eax"|"ecx"|"edx"|"ebx"), imm] -> {
+ [reg, breg, imm] -> {
x86_mov_membase_reg(inst, $1, $3, $2, 1);
}
@@ -2068,7 +2054,7 @@
x86_mov_membase_imm(inst, $1, $3, *(int *)($2), 4);
x86_mov_membase_imm(inst, $1, $3 + 4, *(int *)($2 + 4), 4);
}
- [reg, local, imm, scratch("?")] -> {
+ [reg, local, imm, scratch reg] -> {
x86_mov_reg_membase(inst, $4, X86_EBP, $2, 4);
x86_mov_membase_reg(inst, $1, $3, $4, 4);
x86_mov_reg_membase(inst, $4, X86_EBP, $2 + 4, 4);
@@ -2138,11 +2124,11 @@
gen->posn.ptr = inst;
}
-JIT_OP_ADD_RELATIVE: unary
- [reg] -> {
+JIT_OP_ADD_RELATIVE:
+ [reg, imm] -> {
if(insn->value2->address != 0)
{
- x86_alu_reg_imm(inst, X86_ADD, $1,
insn->value2->address);
+ x86_alu_reg_imm(inst, X86_ADD, $1, $2);
}
}
@@ -2211,7 +2197,7 @@
}
JIT_OP_STORE_ELEMENT_BYTE: ternary
- [reg, reg, reg("eax"|"ecx"|"edx"|"ebx")] -> {
+ [reg, reg, breg] -> {
x86_mov_memindex_reg(inst, $1, 0, $2, 0, $3, 1);
}
@@ -2230,7 +2216,7 @@
x86_mov_memindex_imm(inst, $1, 0, $2, 3, *(int *)($3), 4);
x86_mov_memindex_imm(inst, $1, 4, $2, 3, *(int *)($3 + 4), 4);
}
- [reg, reg, local, scratch("?")] -> {
+ [reg, reg, local, scratch reg] -> {
x86_mov_reg_membase(inst, $4, X86_EBP, $3, 4);
x86_mov_memindex_reg(inst, $1, 0, $2, 3, $4, 4);
x86_mov_reg_membase(inst, $4, X86_EBP, $3 + 4, 4);
@@ -2268,8 +2254,7 @@
JIT_OP_MEMCPY: ternary
[any, any, imm, if("$3 <= 0")] -> { }
- [reg, reg, imm, if("$3 <= 32"),
- scratch("eax" | "ecx" | "edx" | "ebx"), space("32 + $3 * 4")] -> {
+ [reg, reg, imm, scratch breg, if("$3 <= 32"), space("32 + $3 * 4")] -> {
int disp;
disp = 0;
while($3 >= (disp + 4))
@@ -2328,7 +2313,7 @@
x86_mov_membase_imm(inst, $1, disp, $2, 1);
}
}
- [reg, reg("eax"|"ecx"|"edx"|"ebx"), imm, if("$3 < 4")] -> {
+ [reg, breg, imm, if("$3 < 4")] -> {
x86_mov_membase_reg(inst, $1, 0, $2, 1);
if($3 > 1)
{
@@ -2339,7 +2324,7 @@
}
}
}
- [reg, +reg, imm, scratch("?"),
+ [reg, +reg, imm, scratch reg,
if("$3 <= 32 && ($3 % 2) == 0"), space("32 + $3 * 4")] -> {
int disp;
x86_mov_reg_reg(inst, $4, $2, 4);
@@ -2359,7 +2344,7 @@
x86_mov_membase_reg(inst, $1, disp, $2, 2);
}
}
- [reg, +reg("eax"|"ecx"|"edx"|"ebx"), imm, scratch("?"),
+ [reg, +breg, imm, scratch reg,
if("$3 <= 32 && ($3 % 2) != 0"), space("32 + $3 * 4")] -> {
int disp;
x86_mov_reg_reg(inst, $4, $2, 4);
@@ -2396,7 +2381,7 @@
* Allocate memory from the stack.
*/
-JIT_OP_ALLOCA: unary
+JIT_OP_ALLOCA:
[reg] -> {
x86_alu_reg_imm(inst, X86_ADD, $1, 15);
x86_alu_reg_imm(inst, X86_AND, $1, ~15);
@@ -2405,8 +2390,8 @@
gen->stack_changed = 1;
}
-JIT_OP_JUMP_TABLE: ternary
- [reg, imm, imm, clobber("*"), space("32 + sizeof(void) * $3")] -> {
+JIT_OP_JUMP_TABLE: ternary, branch
+ [reg, imm, imm, space("32 + sizeof(void) * $3")] -> {
unsigned char *patch_jump_table;
unsigned char *patch_fall_through;
int index;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [dotgnu-pnet-commits] libjit ChangeLog tools/gen-rules-scanner.l tool...,
Aleksey Demakov <=