[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[dotgnu-pnet-commits] libjit ./ChangeLog jit/jit-reg-alloc.h jit/jit-...
From: |
Aleksey Demakov |
Subject: |
[dotgnu-pnet-commits] libjit ./ChangeLog jit/jit-reg-alloc.h jit/jit-... |
Date: |
Sun, 23 Apr 2006 07:56:59 +0000 |
CVSROOT: /sources/dotgnu-pnet
Module name: libjit
Branch:
Changes by: Aleksey Demakov <address@hidden> 06/04/23 07:56:59
Modified files:
. : ChangeLog
jit : jit-reg-alloc.h jit-reg-alloc.c
tools : gen-rules-parser.y
Log message:
register allocator now supports register set constraints
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/libjit/ChangeLog.diff?tr1=1.220&tr2=1.221&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/libjit/jit/jit-reg-alloc.h.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/libjit/jit/jit-reg-alloc.c.diff?tr1=1.23&tr2=1.24&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/libjit/tools/gen-rules-parser.y.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
Patches:
Index: libjit/ChangeLog
diff -u libjit/ChangeLog:1.220 libjit/ChangeLog:1.221
--- libjit/ChangeLog:1.220 Thu Apr 20 12:22:33 2006
+++ libjit/ChangeLog Sun Apr 23 07:56:59 2006
@@ -1,3 +1,11 @@
+2006-04-23 Aleksey Demakov <address@hidden>
+
+ * jit/jit-reg-alloc.h, jit/jit-reg-alloc.c: register allocator now
+ supports register sets that constrain the register assignment.
+
+ * tools/gen-rules-parser.y: extend grammar to support register sets.
+ Fix bugs.
+
2006-04-20 Aleksey Demakov <address@hidden>
* tools/gen-rules-parser.y: fix generation of `if' pattern code.
Index: libjit/jit/jit-reg-alloc.c
diff -u libjit/jit/jit-reg-alloc.c:1.23 libjit/jit/jit-reg-alloc.c:1.24
--- libjit/jit/jit-reg-alloc.c:1.23 Fri Apr 14 14:44:29 2006
+++ libjit/jit/jit-reg-alloc.c Sun Apr 23 07:56:59 2006
@@ -1843,6 +1843,37 @@
}
/*
+ * Initialize register descriptor.
+ */
+static void
+init_desc(_jit_regs_t *regs, int index, jit_value_t value, int flags, int
live, int used)
+{
+ _jit_regdesc_t *desc;
+
+ desc = ®s->descs[index];
+
+ desc->value = value;
+ if(index > 0 || regs->ternary)
+ {
+ if((flags & _JIT_REGS_EARLY_CLOBBER) != 0)
+ {
+ desc->clobber = 1;
+ desc->early_clobber = 1;
+ }
+ else if((flags & _JIT_REGS_CLOBBER) != 0)
+ {
+ desc->clobber = 1;
+ }
+ }
+ desc->live = live;
+ desc->used = used;
+ if(regs->on_stack)
+ {
+ desc->on_stack = 1;
+ }
+}
+
+/*
* Set assigned and clobbered flags for register.
*/
static void
@@ -2067,7 +2098,7 @@
*
*/
static int
-use_cheapest_register(jit_gencode_t gen, _jit_regs_t *regs, int index)
+use_cheapest_register(jit_gencode_t gen, _jit_regs_t *regs, int index,
jit_regused_t regset)
{
_jit_regdesc_t *desc;
int output;
@@ -2121,7 +2152,8 @@
other_reg = -1;
}
- if(jit_reg_is_used(gen->inhibit, reg)
+ if(!jit_reg_is_used(regset, reg)
+ || jit_reg_is_used(gen->inhibit, reg)
|| jit_reg_is_used(regs->assigned, reg))
{
continue;
@@ -2975,6 +3007,7 @@
regs->descs[index].value = 0;
regs->descs[index].reg = -1;
regs->descs[index].other_reg = -1;
+ regs->descs[index].regset = jit_regused_init_used;
regs->descs[index].clobber = 0;
regs->descs[index].early_clobber = 0;
regs->descs[index].live = 0;
@@ -2982,11 +3015,11 @@
regs->descs[index].on_stack = 0;
regs->descs[index].duplicate = 0;
}
- regs->num_descs = 0;
for(index = 0; index < _JIT_REGS_SCRATCH_MAX; index++)
{
- regs->scratch[index] = -1;
+ regs->scratch[index].reg = -1;
+ regs->scratch[index].regset = jit_regused_init_used;
}
regs->num_scratch = 0;
@@ -3001,140 +3034,65 @@
}
void
-_jit_regs_set_dest(_jit_regs_t *regs, jit_insn_t insn, int flags, int reg, int
other_reg)
+_jit_regs_init_dest(_jit_regs_t *regs, jit_insn_t insn, int flags)
{
- if((insn->flags & JIT_INSN_DEST_OTHER_FLAGS) != 0)
- {
- return;
- }
-
- if(regs->num_descs < 1)
- {
- regs->num_descs = 1;
- }
-
- regs->descs[0].value = insn->dest;
- if(reg >= 0)
+ if((insn->flags & JIT_INSN_DEST_OTHER_FLAGS) == 0)
{
- regs->descs[0].reg = reg;
- regs->descs[0].other_reg = other_reg;
- }
- if(regs->ternary)
- {
- if((flags & _JIT_REGS_EARLY_CLOBBER) != 0)
- {
- regs->descs[0].clobber = 1;
- regs->descs[0].early_clobber = 1;
- }
- else if((flags & _JIT_REGS_CLOBBER) != 0)
- {
- regs->descs[0].clobber = 1;
- }
- }
- if((insn->flags & JIT_INSN_DEST_LIVE) != 0)
- {
- regs->descs[0].live = 1;
- }
- if((insn->flags & JIT_INSN_DEST_NEXT_USE) != 0)
- {
- regs->descs[0].used = 1;
- }
- if(regs->on_stack)
- {
- regs->descs[0].on_stack = 1;
+ init_desc(regs, 0, insn->dest, flags,
+ (insn->flags & JIT_INSN_DEST_LIVE) != 0,
+ (insn->flags & JIT_INSN_DEST_NEXT_USE) != 0);
}
}
void
-_jit_regs_set_value1(_jit_regs_t *regs, jit_insn_t insn, int flags, int reg,
int other_reg)
+_jit_regs_init_value1(_jit_regs_t *regs, jit_insn_t insn, int flags)
{
- if((insn->flags & JIT_INSN_VALUE1_OTHER_FLAGS) != 0)
+ if((insn->flags & JIT_INSN_VALUE1_OTHER_FLAGS) == 0)
{
- return;
- }
-
- if(regs->num_descs < 2)
- {
- regs->num_descs = 2;
+ init_desc(regs, 1, insn->value1, flags,
+ (insn->flags & JIT_INSN_VALUE1_LIVE) != 0,
+ (insn->flags & JIT_INSN_VALUE1_NEXT_USE) != 0);
}
+}
- regs->descs[1].value = insn->value1;
- if(reg >= 0)
- {
- regs->descs[1].reg = reg;
- regs->descs[1].other_reg = other_reg;
- }
- if((flags & _JIT_REGS_EARLY_CLOBBER) != 0)
- {
- regs->descs[1].clobber = 1;
- regs->descs[1].early_clobber = 1;
- }
- else if((flags & _JIT_REGS_CLOBBER) != 0)
- {
- regs->descs[1].clobber = 1;
- }
- if((insn->flags & JIT_INSN_VALUE1_LIVE) != 0)
- {
- regs->descs[1].live = 1;
- }
- if((insn->flags & JIT_INSN_VALUE1_NEXT_USE) != 0)
- {
- regs->descs[1].used = 1;
- }
- if(regs->on_stack)
+void
+_jit_regs_init_value2(_jit_regs_t *regs, jit_insn_t insn, int flags)
+{
+ if((insn->flags & JIT_INSN_VALUE2_OTHER_FLAGS) == 0)
{
- regs->descs[1].on_stack = 1;
+ init_desc(regs, 2, insn->value2, flags,
+ (insn->flags & JIT_INSN_VALUE2_LIVE) != 0,
+ (insn->flags & JIT_INSN_VALUE2_NEXT_USE) != 0);
}
}
void
-_jit_regs_set_value2(_jit_regs_t *regs, jit_insn_t insn, int flags, int reg,
int other_reg)
+_jit_regs_set_dest(_jit_regs_t *regs, int reg, int other_reg)
{
- if((insn->flags & JIT_INSN_VALUE2_OTHER_FLAGS) != 0)
- {
- return;
- }
+ regs->descs[0].reg = reg;
+ regs->descs[0].other_reg = other_reg;
+}
- if(regs->num_descs < 3)
- {
- regs->num_descs = 3;
- }
+void
+_jit_regs_set_value1(_jit_regs_t *regs, int reg, int other_reg)
+{
+ regs->descs[1].reg = reg;
+ regs->descs[1].other_reg = other_reg;
+}
- regs->descs[2].value = insn->value2;
- if(reg >= 0)
- {
- regs->descs[2].reg = reg;
- regs->descs[2].other_reg = other_reg;
- }
- if((flags & _JIT_REGS_EARLY_CLOBBER) != 0)
- {
- regs->descs[2].clobber = 1;
- regs->descs[2].early_clobber = 1;
- }
- else if((flags & _JIT_REGS_CLOBBER) != 0)
- {
- regs->descs[2].clobber = 1;
- }
- if((insn->flags & JIT_INSN_VALUE2_LIVE) != 0)
- {
- regs->descs[2].live = 1;
- }
- if((insn->flags & JIT_INSN_VALUE2_NEXT_USE) != 0)
- {
- regs->descs[2].used = 1;
- }
- if(regs->on_stack)
- {
- regs->descs[2].on_stack = 1;
- }
+void
+_jit_regs_set_value2(_jit_regs_t *regs, int reg, int other_reg)
+{
+ regs->descs[2].reg = reg;
+ regs->descs[2].other_reg = other_reg;
}
void
-_jit_regs_set_scratch(_jit_regs_t *regs, int reg)
+_jit_regs_add_scratch(_jit_regs_t *regs, int reg)
{
if(regs->num_scratch < _JIT_REGS_SCRATCH_MAX)
{
- regs->scratch[regs->num_scratch++] = reg;
+ regs->scratch[regs->num_scratch++].reg = reg;
}
}
@@ -3144,6 +3102,33 @@
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;
+ }
+}
+
int
_jit_regs_dest(_jit_regs_t *regs)
{
@@ -3185,7 +3170,7 @@
{
if(index < regs->num_scratch && index >= 0)
{
- return regs->scratch[index];
+ return regs->scratch[index].reg;
}
return -1;
}
@@ -3224,14 +3209,25 @@
for(index = 0; index < regs->num_scratch; index++)
{
- if(regs->scratch[index] >= 0)
+ if(regs->scratch[index].reg >= 0)
+ {
+ if(IS_STACK_REG(regs->scratch[index].reg))
+ {
+ return 0;
+ }
+ jit_reg_set_used(regs->assigned,
regs->scratch[index].reg);
+ jit_reg_set_used(regs->clobber,
regs->scratch[index].reg);
+ }
+ else if(regs->scratch[index].regset != jit_regused_init_used)
{
- if(IS_STACK_REG(regs->scratch[index]))
+ regs->scratch[index].reg = use_cheapest_register(
+ gen, regs, -1, regs->scratch[index].regset);
+ if(regs->scratch[index].reg < 0)
{
return 0;
}
- jit_reg_set_used(regs->assigned, regs->scratch[index]);
- jit_reg_set_used(regs->clobber, regs->scratch[index]);
+ jit_reg_set_used(regs->assigned,
regs->scratch[index].reg);
+ jit_reg_set_used(regs->clobber,
regs->scratch[index].reg);
}
}
@@ -3257,7 +3253,7 @@
{
if(regs->descs[0].value && regs->descs[0].reg < 0)
{
- use_cheapest_register(gen, regs, 0);
+ use_cheapest_register(gen, regs, 0,
regs->descs[0].regset);
if(regs->descs[0].reg < 0)
{
return 0;
@@ -3274,7 +3270,8 @@
&&
gen->contents[regs->descs[out_index].value->reg].num_values == 1
&& !(regs->descs[out_index].live ||
regs->descs[out_index].used))
{
- use_cheapest_register(gen, regs, out_index);
+ use_cheapest_register(
+ gen, regs, out_index,
regs->descs[out_index].regset);
if(regs->descs[out_index].reg < 0)
{
return 0;
@@ -3284,7 +3281,7 @@
|| (regs->descs[0].value->in_register
&&
gen->contents[regs->descs[0].value->reg].num_values == 1))
{
- use_cheapest_register(gen, regs, 0);
+ use_cheapest_register(gen, regs, 0,
regs->descs[0].regset);
if(regs->descs[0].reg < 0)
{
return 0;
@@ -3300,7 +3297,7 @@
}
if(regs->descs[1].value && regs->descs[1].reg < 0)
{
- use_cheapest_register(gen, regs, 1);
+ use_cheapest_register(gen, regs, 1, regs->descs[1].regset);
if(regs->descs[1].reg < 0)
{
return 0;
@@ -3309,7 +3306,7 @@
check_duplicate_value(regs, ®s->descs[1], ®s->descs[2]);
if(regs->descs[2].value && regs->descs[2].reg < 0)
{
- use_cheapest_register(gen, regs, 2);
+ use_cheapest_register(gen, regs, 2, regs->descs[2].regset);
if(regs->descs[2].reg < 0)
{
return 0;
@@ -3319,7 +3316,7 @@
{
if(regs->descs[out_index].reg < 0)
{
- use_cheapest_register(gen, regs, 0);
+ use_cheapest_register(gen, regs, 0,
regs->descs[0].regset);
if(regs->descs[0].reg < 0)
{
return 0;
@@ -3335,15 +3332,16 @@
for(index = 0; index < regs->num_scratch; index++)
{
- if(regs->scratch[index] < 0)
+ if(regs->scratch[index].reg < 0)
{
- regs->scratch[index] = use_cheapest_register(gen, regs,
-1);
- if(regs->scratch[index] < 0)
+ regs->scratch[index].reg = use_cheapest_register(
+ gen, regs, -1, jit_regused_init_used);
+ if(regs->scratch[index].reg < 0)
{
return 0;
}
- jit_reg_set_used(regs->assigned, regs->scratch[index]);
- jit_reg_set_used(regs->clobber, regs->scratch[index]);
+ jit_reg_set_used(regs->assigned,
regs->scratch[index].reg);
+ jit_reg_set_used(regs->clobber,
regs->scratch[index].reg);
}
}
@@ -3596,6 +3594,11 @@
}
}
+/*@
+ * @deftypefun void _jit_regs_lookup (char *name)
+ * Get register by name.
+ * @end deftypefun
address@hidden/
int
_jit_regs_lookup(char *name)
{
Index: libjit/jit/jit-reg-alloc.h
diff -u libjit/jit/jit-reg-alloc.h:1.8 libjit/jit/jit-reg-alloc.h:1.9
--- libjit/jit/jit-reg-alloc.h:1.8 Fri Apr 14 11:46:05 2006
+++ libjit/jit/jit-reg-alloc.h Sun Apr 23 07:56:59 2006
@@ -92,7 +92,8 @@
#define _JIT_REGS_REVERSIBLE 0x0080
/*
- * Flags for _jit_regs_set_dest(), _jit_regs_set_value1(),
_jit_regs_set_value2().
+ * Flags for _jit_regs_init_dest(), _jit_regs_init_value1(), and
+ * _jit_regs_init_value2().
*/
#define _JIT_REGS_CLOBBER 0x0001
#define _JIT_REGS_EARLY_CLOBBER 0x0002
@@ -105,13 +106,6 @@
#define _JIT_REGS_REVERSE_ARGS 0x0004
/*
- * This value is used internally to assign a stack register.
- * It indicates that we are going to use the next free stack
- * regsiter but we do not yet know which one it is.
-#define _JIT_REGS_NEXT_STACK_REG 0x7fff
- */
-
-/*
* Contains register assignment data for single operand.
*/
typedef struct
@@ -119,6 +113,7 @@
jit_value_t value;
int reg;
int other_reg;
+ jit_regused_t regset;
unsigned live : 1;
unsigned used : 1;
unsigned clobber : 1;
@@ -129,6 +124,16 @@
} _jit_regdesc_t;
/*
+ * Contains scratch register assignment data.
+ */
+typedef struct
+{
+ int reg;
+ jit_regused_t regset;
+
+} _jit_scratch_t;
+
+/*
* Contains register assignment data for instruction.
*/
typedef struct
@@ -147,9 +152,7 @@
unsigned reverse_args : 1;
_jit_regdesc_t descs[_JIT_REGS_VALUE_MAX];
- int num_descs;
-
- int scratch[_JIT_REGS_SCRATCH_MAX];
+ _jit_scratch_t scratch[_JIT_REGS_SCRATCH_MAX];
int num_scratch;
jit_regused_t assigned;
@@ -164,15 +167,26 @@
} _jit_regs_t;
void _jit_regs_init(_jit_regs_t *regs, int flags);
-void _jit_regs_set_dest(_jit_regs_t *regs, jit_insn_t insn, int flags, int
reg, int other_reg);
-void _jit_regs_set_value1(_jit_regs_t *regs, jit_insn_t insn, int flags, int
reg, int other_reg);
-void _jit_regs_set_value2(_jit_regs_t *regs, jit_insn_t insn, int flags, int
reg, int other_reg);
-void _jit_regs_set_scratch(_jit_regs_t *regs, int reg);
+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_set_dest(_jit_regs_t *regs, int reg, int other_reg);
+void _jit_regs_set_value1(_jit_regs_t *regs, int reg, int other_reg);
+void _jit_regs_set_value2(_jit_regs_t *regs, int reg, int other_reg);
+void _jit_regs_add_scratch(_jit_regs_t *regs, int reg);
void _jit_regs_set_clobber(_jit_regs_t *regs, 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);
+
int _jit_regs_assign(jit_gencode_t gen, _jit_regs_t *regs);
int _jit_regs_gen(jit_gencode_t gen, _jit_regs_t *regs);
int _jit_regs_select(_jit_regs_t *regs);
void _jit_regs_commit(jit_gencode_t gen, _jit_regs_t *regs);
+
int _jit_regs_dest(_jit_regs_t *regs);
int _jit_regs_value1(_jit_regs_t *regs);
int _jit_regs_value2(_jit_regs_t *regs);
@@ -180,6 +194,7 @@
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);
+
int _jit_regs_lookup(char *name);
#ifdef __cplusplus
Index: libjit/tools/gen-rules-parser.y
diff -u libjit/tools/gen-rules-parser.y:1.5 libjit/tools/gen-rules-parser.y:1.6
--- libjit/tools/gen-rules-parser.y:1.5 Thu Apr 20 12:22:34 2006
+++ libjit/tools/gen-rules-parser.y Sun Apr 23 07:56:59 2006
@@ -149,12 +149,23 @@
#define GENSEL_FLAG_EARLY_CLOBBER 2
/*
+ * Value Type.
+ */
+#define GENSEL_VALUE_STRING 1
+#define GENSEL_VALUE_CHOICE 2
+
+/*
* Option value.
*/
typedef struct gensel_value *gensel_value_t;
struct gensel_value
{
- char *value;
+ int type;
+ union
+ {
+ char *value;
+ gensel_value_t children;
+ };
gensel_value_t next;
};
@@ -200,6 +211,51 @@
};
/*
+ * Create a value.
+ */
+static gensel_value_t
+gensel_create_value(int type)
+{
+ gensel_value_t vp;
+
+ vp = (gensel_value_t) malloc(sizeof(struct gensel_value));
+ if(!vp)
+ {
+ exit(1);
+ }
+
+ vp->type = type;
+ vp->next = 0;
+ return vp;
+}
+
+/*
+ * Create string value.
+ */
+static gensel_value_t
+gensel_create_string(char *value)
+{
+ gensel_value_t vp;
+
+ vp = gensel_create_value(GENSEL_VALUE_STRING);
+ vp->value = value;
+ return vp;
+}
+
+/*
+ * Create choice value.
+ */
+static gensel_value_t
+gensel_create_choice(gensel_value_t children)
+{
+ gensel_value_t vp;
+
+ vp = gensel_create_value(GENSEL_VALUE_CHOICE);
+ vp->children = children;
+ return vp;
+}
+
+/*
* Create an option.
*/
static gensel_option_t
@@ -221,7 +277,7 @@
}
/*
- * Create an option.
+ * Create an option with no flags.
*/
static gensel_option_t
gensel_create_option(int option, gensel_value_t values)
@@ -239,7 +295,14 @@
while(values)
{
next = values->next;
- free(values->value);
+ if(values->type == GENSEL_VALUE_STRING)
+ {
+ free(values->value);
+ }
+ else
+ {
+ gensel_free_values(values->children);
+ }
free(values);
values = next;
}
@@ -303,13 +366,13 @@
int imms, max_imms;
int have_local;
int scratch, others;
- int have_clobber;
+ int have_regset;
max_regs = 0;
other_regs_mask = 0;
max_imms = 0;
have_local = 0;
- have_clobber = 0;
+ have_regset = 0;
while(clauses != 0)
{
regs = 0;
@@ -328,11 +391,21 @@
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:
@@ -357,17 +430,9 @@
while(values)
{
++scratch;
- values = values->next;
- }
-
- case GENSEL_PATT_CLOBBER:
- values = pattern->values;
- while(values)
- {
- if(values->value &&
strcmp(values->value, "*") != 0)
+ if(values->type != GENSEL_VALUE_STRING)
{
- have_clobber = 1;
- break;
+ have_regset = 1;
}
values = values->next;
}
@@ -450,9 +515,9 @@
{
printf("\tjit_nint local_offset;\n");
}
- if(have_clobber)
+ if(have_regset)
{
- printf("\tint clobber;\n");
+ printf("\tjit_regused_t regset;\n");
}
}
@@ -736,12 +801,11 @@
char *other_names[9];
gensel_clause_t clause;
gensel_option_t pattern;
- gensel_value_t values;
+ gensel_value_t values, child;
int first, seen_option;
- int regs, imms, index;
- int scratch, clobber_all;
+ int regs, imms, scratch, index;
+ int clobber_all, ternary;
int contains_registers;
- int ternary;
/* If the clause is manual, then output it as-is */
if(gensel_search_option(options, GENSEL_OPT_MANUAL))
@@ -1097,7 +1161,7 @@
|| gensel_search_option(options,
GENSEL_OPT_UNARY_NOTE)
|| gensel_search_option(options,
GENSEL_OPT_UNARY_BRANCH)))
{
- printf("\t\t_jit_regs_set_dest(®s, insn, 0,
-1, -1);\n");
+ printf("\t\t_jit_regs_init_dest(®s, insn,
0);\n");
}
}
@@ -1114,61 +1178,71 @@
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)
{
- printf("\t\t%s =
_jit_regs_lookup(\"%s\");\n",
- gensel_reg_names[regs],
- pattern->values->value);
- printf("\t\t_jit_regs_set_%s(®s,
insn, %s, %s, -1);\n",
- args[index],
- gensel_reg_flags[pattern->flags],
- gensel_reg_names[regs]);
- }
- else
- {
- printf("\t\t_jit_regs_set_%s(®s,
insn, %s, -1, -1);\n",
- args[index],
-
gensel_reg_flags[pattern->flags]);
+ if(pattern->values->type ==
GENSEL_VALUE_STRING)
+ {
+
printf("\t\t_jit_regs_set_%s(®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->next
- && pattern->values->next->value)
+ if(pattern->values->type ==
GENSEL_VALUE_STRING)
{
- printf("\t\t%s =
_jit_regs_lookup(\"%s\")];\n",
- gensel_reg_names[regs],
- pattern->values->value);
- printf("\t\t%s =
_jit_regs_lookup(\"%s\")];\n",
-
gensel_other_reg_names[regs],
-
pattern->values->next->value);
-
printf("\t\t_jit_regs_set_%s(®s, insn, %s, %s, %s);\n",
- args[index],
-
gensel_reg_flags[pattern->flags],
- gensel_reg_names[regs],
-
gensel_other_reg_names[regs]);
+ if(pattern->values->next &&
pattern->values->next->value)
+ {
+
printf("\t\t_jit_regs_set_%s(®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(®s, _jit_regs_lookup(\"%s\"), -1);\n",
+ args[index],
pattern->values->value);
+ }
}
else
{
- printf("\t\t%s =
_jit_regs_lookup(\"%s\")];\n",
- gensel_reg_names[regs],
- pattern->values->value);
-
printf("\t\t_jit_regs_set_%s(®s, insn, %s, %s, -1);\n",
- args[index],
-
gensel_reg_flags[pattern->flags],
- gensel_reg_names[regs]);
+ 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]);
}
}
- else
- {
- printf("\t\t_jit_regs_set_%s(®s,
insn, %s, -1, -1);\n",
- args[index],
-
gensel_reg_flags[pattern->flags]);
- }
++regs;
++index;
break;
@@ -1187,17 +1261,34 @@
values = pattern->values;
while(values)
{
- if(values->value &&
strcmp(values->value, "?") != 0)
+ if(values->value
+ && (values->type !=
GENSEL_VALUE_STRING
+ || strcmp(values->value, "?") !=
0))
{
- printf("\t\t%s =
_jit_regs_lookup(\"%s\")];\n",
- gensel_reg_names[regs],
- values->value);
-
printf("\t\t_jit_regs_set_scratch(®s, %s);\n",
- gensel_reg_names[regs]);
+ if(values->type ==
GENSEL_VALUE_STRING)
+ {
+
printf("\t\t_jit_regs_add_scratch(®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
{
-
printf("\t\t_jit_regs_set_scratch(®s, -1);\n");
+
printf("\t\t_jit_regs_add_scratch(®s, -1);\n");
}
++regs;
++index;
@@ -1211,9 +1302,8 @@
{
if(values->value &&
strcmp(values->value, "*") != 0)
{
- printf("\t\tclobber =
_jit_regs_lookup(\"%s\");\n",
+
printf("\t\t_jit_regs_set_clobber(®s, _jit_regs_lookup(\"%s\"));\n",
values->value);
-
printf("\t\t_jit_regs_set_clobber(®s, clobber);\n");
}
values = values->next;
}
@@ -1289,7 +1379,7 @@
values = pattern->values;
while(values)
{
- printf("\t\t%s =
_jit_regs_scratch(®s, %d);\n",
+ printf("\t\t%s =
_jit_reg_info[_jit_regs_scratch(®s, %d)].cpu_reg;\n",
gensel_reg_names[regs], scratch);
++regs;
++scratch;
@@ -1462,7 +1552,7 @@
%type <clauses> Clauses Clause
%type <options> Options OptionList Pattern Pattern2
%type <option> Option PatternElement Scratch Clobber If Space
-%type <values> ValuePair ValueList
+%type <values> ValuePair ValueList ValueChoice ValueChoiceList
%type <value> Value
%expect 0
@@ -1608,25 +1698,36 @@
| RegFlag RegTag {
$$ = gensel_create_option_2($2, $1, 0);
}
- | RegFlag LRegTag {
- $$ = gensel_create_option_2($2, $1, 0);
- }
| RegFlag RegTag '(' Value ')' {
$$ = gensel_create_option_2($2, $1, $4);
}
+ | RegFlag RegTag '(' ValueChoice ')' {
+ gensel_value_t cp;
+ cp = gensel_create_choice($4.head);
+ $$ = gensel_create_option_2($2, $1, cp);
+ }
+ | RegFlag LRegTag {
+ $$ = gensel_create_option_2($2, $1, 0);
+ }
| RegFlag LRegTag '(' Value ')' {
$$ = gensel_create_option_2($2, $1, $4);
}
| RegFlag LRegTag '(' ValuePair ')' {
$$ = gensel_create_option_2($2, $1, $4.head);
}
+ | RegFlag LRegTag '(' ValueChoice ')' {
+ gensel_value_t cp;
+ cp = gensel_create_choice($4.head);
+ $$ = gensel_create_option_2($2, $1, cp);
+ }
| Scratch
| Clobber
| If
| Space
;
+
Scratch
- : K_SCRATCH '(' ValueList ')' {
+ : K_SCRATCH '(' ValueChoiceList ')' {
$$ = gensel_create_option(GENSEL_PATT_SCRATCH, $3.head);
}
;
@@ -1649,6 +1750,44 @@
}
;
+ValueChoiceList
+ : Value {
+ $$.head = $1;
+ $$.tail = $1;
+ }
+ | 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;
+ }
+ ;
+
+ValueChoice
+ : Value '|' Value {
+ $1->next = $3;
+ $$.head = $1;
+ $$.tail = $3;
+ }
+ | ValueChoice '|' Value {
+ $1.tail->next = $3;
+ $$.head = $1.head;
+ $$.tail = $3;
+ }
+ ;
+
ValuePair
: Value ':' Value {
$1->next = $3;
@@ -1671,15 +1810,7 @@
Value
: Literal {
- gensel_value_t vp;
- vp = (gensel_value_t) malloc(sizeof(struct
gensel_value));
- if(!vp)
- {
- exit(1);
- }
- vp->value = $1;
- vp->next = 0;
- $$ = vp;
+ $$ = gensel_create_string($1);
}
;