dotgnu-pnet-commits
[Top][All Lists]
Advanced

[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 = &regs->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, &regs->descs[1], &regs->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(&regs, insn, 0, 
-1, -1);\n");
+                               printf("\t\t_jit_regs_init_dest(&regs, insn, 
0);\n");
                        }
                }
 
@@ -1114,61 +1178,71 @@
 
                        case GENSEL_PATT_REG:
                        case GENSEL_PATT_FREG:
+                               printf("\t\t_jit_regs_init_%s(&regs, 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(&regs, 
insn, %s, %s, -1);\n",
-                                              args[index],
-                                              gensel_reg_flags[pattern->flags],
-                                              gensel_reg_names[regs]);
-                               }
-                               else
-                               {
-                                       printf("\t\t_jit_regs_set_%s(&regs, 
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(&regs, _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(&regs, regset);\n",
+                                                      args[index]);
+                                       }
                                }
                                ++regs;
                                ++index;
                                break;
 
                        case GENSEL_PATT_LREG:
+                               printf("\t\t_jit_regs_init_%s(&regs, 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(&regs, 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(&regs, _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(&regs, _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(&regs, 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(&regs, regset);\n",
+                                                      args[index]);
                                        }
                                }
-                               else
-                               {
-                                       printf("\t\t_jit_regs_set_%s(&regs, 
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(&regs, %s);\n",
-                                                      gensel_reg_names[regs]);
+                                               if(values->type == 
GENSEL_VALUE_STRING)
+                                               {
+                                                       
printf("\t\t_jit_regs_add_scratch(&regs, _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(&regs, regset);\n");
+                                               }
                                        }
                                        else
                                        {
-                                               
printf("\t\t_jit_regs_set_scratch(&regs, -1);\n");
+                                               
printf("\t\t_jit_regs_add_scratch(&regs, -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(&regs, _jit_regs_lookup(\"%s\"));\n",
                                                       values->value);
-                                               
printf("\t\t_jit_regs_set_clobber(&regs, clobber);\n");
                                        }
                                        values = values->next;
                                }
@@ -1289,7 +1379,7 @@
                                values = pattern->values;
                                while(values)
                                {
-                                       printf("\t\t%s = 
_jit_regs_scratch(&regs, %d);\n",
+                                       printf("\t\t%s = 
_jit_reg_info[_jit_regs_scratch(&regs, %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);
                }
        ;
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]