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-re...


From: Aleksey Demakov
Subject: [dotgnu-pnet-commits] libjit ChangeLog jit/jit-reg-alloc.h jit/jit-re...
Date: Fri, 16 Jun 2006 17:53:52 +0000

CVSROOT:        /sources/dotgnu-pnet
Module name:    libjit
Changes by:     Aleksey Demakov <avd>   06/06/16 17:53:52

Modified files:
        .              : ChangeLog 
        jit            : jit-reg-alloc.h jit-reg-alloc.c 
                         jit-rules-x86.ins 
        tools          : gen-rules-parser.y 

Log message:
        Extend register allocator to allow separate specification of the 
destination
        register. Take advantage of this for some x86 rules. Tweak the 
allocator's
        API.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/libjit/ChangeLog?cvsroot=dotgnu-pnet&r1=1.236&r2=1.237
http://cvs.savannah.gnu.org/viewcvs/libjit/jit/jit-reg-alloc.h?cvsroot=dotgnu-pnet&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/libjit/jit/jit-reg-alloc.c?cvsroot=dotgnu-pnet&r1=1.33&r2=1.34
http://cvs.savannah.gnu.org/viewcvs/libjit/jit/jit-rules-x86.ins?cvsroot=dotgnu-pnet&r1=1.7&r2=1.8
http://cvs.savannah.gnu.org/viewcvs/libjit/tools/gen-rules-parser.y?cvsroot=dotgnu-pnet&r1=1.8&r2=1.9

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/ChangeLog,v
retrieving revision 1.236
retrieving revision 1.237
diff -u -b -r1.236 -r1.237
--- ChangeLog   16 Jun 2006 02:35:16 -0000      1.236
+++ ChangeLog   16 Jun 2006 17:53:51 -0000      1.237
@@ -1,3 +1,19 @@
+2006-06-17  Aleksey Demakov  <address@hidden>
+
+       * jit/jit-reg-alloc.h, jit/jit-reg-alloc.c: implement support of the
+       JIT_REGS_FREE_DEST flag for 3-argument instructions. Tweak reg alloc
+       API.
+
+       * tools/gen-rules-parser.y: adjust for reg alloc API changes. Use
+       '$0' pattern element to refer to destination register in 3-argument
+       instructions.
+
+       * jit/jit-rules-x86.ins: rewrite JIT_OP_IDIV, JIT_OP_IDIV_UN,
+       JIT_OP_IREM, JIT_OP_IREM_UN, JIT_OP_ADDRESS_OF_LABEL,
+       JIT_OP_LOAD_RELATIVE_FLOAT32, JIT_OP_LOAD_RELATIVE_FLOAT32,
+       JIT_OP_LOAD_RELATIVE_NFLOAT, JIT_OP_LOAD_ELEMENT_FLOAT32,
+       JIT_OP_LOAD_ELEMENT_FLOAT64, JIT_OP_LOAD_ELEMENT_NFLOAT rules.
+
 2006-06-16  Aleksey Demakov  <address@hidden>
 
        * jit/jit-rules-x86.sel, jit/jit-rules-x86.ins: fix JIT_OP_IDIV and

Index: jit/jit-reg-alloc.h
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-reg-alloc.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- jit/jit-reg-alloc.h 3 Jun 2006 13:39:53 -0000       1.15
+++ jit/jit-reg-alloc.h 16 Jun 2006 17:53:51 -0000      1.16
@@ -116,6 +116,7 @@
        unsigned        clobber : 1;
        unsigned        early_clobber : 1;
        unsigned        duplicate : 1;
+       unsigned        thrash : 1;
        unsigned        save : 1;
        unsigned        load : 1;
        unsigned        copy : 1;
@@ -158,7 +159,6 @@
 
        jit_regused_t   assigned;
        jit_regused_t   clobber;
-       jit_regused_t   spill;
 
        int             stack_start;
        int             current_stack_top;
@@ -166,16 +166,16 @@
        int             loaded_stack_count;
 } _jit_regs_t;
 
-void _jit_regs_init(_jit_regs_t *regs, int flags);
+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_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(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_dest_from(_jit_regs_t *regs, jit_regused_t regset);
 void _jit_regs_set_value1_from(_jit_regs_t *regs, jit_regused_t regset);
@@ -187,6 +187,7 @@
 int _jit_regs_select(_jit_regs_t *regs);
 void _jit_regs_commit(jit_gencode_t gen, _jit_regs_t *regs);
 void _jit_regs_abort(jit_gencode_t gen, _jit_regs_t *regs);
+
 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);

Index: jit/jit-reg-alloc.c
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-reg-alloc.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -b -r1.33 -r1.34
--- jit/jit-reg-alloc.c 3 Jun 2006 13:39:53 -0000       1.33
+++ jit/jit-reg-alloc.c 16 Jun 2006 17:53:51 -0000      1.34
@@ -1662,9 +1662,15 @@
 #define COST_SPILL_DIRTY_GLOBAL        2
 #define COST_SPILL_CLEAN       1
 #define COST_SPILL_CLEAN_GLOBAL        1
+#define COST_GLOBAL_BIAS       1
+#define COST_THRASH            32
 #define COST_CLOBBER_GLOBAL    1000
 
-#define ALLOW_CLOBBER_GLOBAL   1
+#ifdef JIT_BACKEND_X86
+# define ALLOW_CLOBBER_GLOBAL  1
+#else
+# define ALLOW_CLOBBER_GLOBAL  0
+#endif
 
 /* Value usage flags. */
 #define VALUE_INPUT            1
@@ -1750,7 +1756,7 @@
 static int
 are_values_equal(_jit_regdesc_t *desc1, _jit_regdesc_t *desc2)
 {
-       if(desc1->value && desc2->value)
+       if(desc1 && desc2 && desc1->value && desc2->value)
        {
                if(desc1->value == desc2->value)
                {
@@ -1766,11 +1772,40 @@
 
 
 /*
- * Check if the value is used in and after the current instruction.
+ * Get value usage and liveness information. The accurate liveness data is
+ * only available for values used by the current instruction.
+ *
+ * VALUE_INPUT flag is set if the value is one of the instruction's inputs.
+ *
+ * VALUE_LIVE and VALUE_USED flags are set for input values only according
+ * to the liveness flags provided along with the instruction.
+ *
+ * VALUE_DEAD flag is set in two cases. First, it is always set for output
+ * values. Second, it is set for input values that are neither live nor used.
+ *
+ * These flags are used when spilling a register. In this case we generally
+ * do not know if the values in the register are used by the instruction. If
+ * the VALUE_INPUT flag is present then it is so and the value has to be held
+ * in the register for the instruction to succeed. If the VALUE_DEAD flag is
+ * present then there is no need to spill the value and it may be discarded.
+ * Otherwise the value must be spilled.
  *
- * The value is dead if it is the output value of the instruction and hence
- * just about to be recomputed or if it is one of the input values and its
- * usage flags are not set. Otherwise the value is alive.
+ * The VALUE_LIVE and VALUE_USED flags may only be set for input values of
+ * the instruction. For other values these flags are not set even if they are
+ * perfectly alive. These flags are used as a hint for spill cost calculation.
+ *
+ * NOTE: The output value is considered to be dead because the instruction is
+ * just about to recompute it so there is no point to save it.
+ *
+ * Generally, a value becomes dead just after the instruction that used it
+ * last time. The allocator frees dead values after each instruction so it
+ * might seem that there is no chance to find any dead value on the current
+ * instruction. However if the value is used by the current instruction both
+ * as the input and output then it was alive after the last instruction and
+ * hence was not freed. Also the old allocator might sometimes leave a dead
+ * value in the register and as of this writing the old allocator is still
+ * used by some rules. And just in case if some dead value may creep through
+ * the new allocator...
  */
 static int
 value_usage(_jit_regs_t *regs, jit_value_t value)
@@ -1867,9 +1902,14 @@
 }
 
 /*
- * Determine the effect of assigning the value to a register. It finds out
- * if the old register contents is clobbered and so needs to be spilled and
- * if the newly assigned value will be clobbered by the instruction.
+ * Determine the effect of assigning a value to a register on the values
+ * the register contains. The following factors are taken into account:
+ for
+ * the instruction
+ *. It
+ * checks if the register contains any other values that might be clobbered
+ * by using the register or if the value in question is clobbered itself by
+ * the instruction.
  */
 static int
 clobbers_register(jit_gencode_t gen, _jit_regs_t *regs, int index, int reg, 
int other_reg)
@@ -1903,7 +1943,11 @@
        else
        {
                /* find out the input value that is going to be overwritten by 
the output */
-               if(!regs->descs[2].value)
+               if(regs->free_dest)
+               {
+                       out_index = 0;
+               }
+               else if(!regs->descs[2].value)
                {
                        /* a unary op */
                        out_index = 1;
@@ -1953,13 +1997,17 @@
                }
        }
 
-       /* does input value clobber the register? */
+       /* is input value clobbered? */
        if(regs->descs[index].clobber)
        {
                clobber = 1;
        }
 
-       if(!clobber)
+       if(clobber)
+       {
+               flags = CLOBBER_INPUT_VALUE;
+       }
+       else
        {
                if(regs->descs[index].value->has_global_register
                   && regs->descs[index].value->global_reg == reg)
@@ -1971,12 +2019,7 @@
                {
                        return CLOBBER_NONE;
                }
-       }
-
        flags = CLOBBER_NONE;
-       if(clobber)
-       {
-               flags |= CLOBBER_INPUT_VALUE;
        }
        if(is_alive)
        {
@@ -1990,31 +2033,24 @@
 }
 
 /*
- * Set assigned and clobber flags for a register.
+ * Assign scratch register.
  */
 static void
-set_register_flags(
-       jit_gencode_t gen,
-       _jit_regs_t *regs,
-       int reg,
-       int clobber_reg,
-       int clobber_input)
+set_scratch_register(jit_gencode_t gen, _jit_regs_t *regs, int index, int reg)
 {
        if(reg >= 0)
        {
+               regs->scratch[index].reg = reg;
+
                jit_reg_set_used(gen->touched, reg);
-               jit_reg_set_used(regs->assigned, reg);
-               if(clobber_reg)
-               {
-                       jit_reg_set_used(regs->spill, reg);
-               }
-               if(clobber_input)
-               {
                        jit_reg_set_used(regs->clobber, reg);
-               }
+               jit_reg_set_used(regs->assigned, reg);
        }
 }
 
+/*
+ * Initialize value descriptor.
+ */
 static void
 init_regdesc(_jit_regs_t *regs, int index)
 {
@@ -2031,6 +2067,7 @@
        desc->clobber = 0;
        desc->early_clobber = 0;
        desc->duplicate = 0;
+       desc->thrash = 0;
        desc->save = 0;
        desc->load = 0;
        desc->copy = 0;
@@ -2038,7 +2075,7 @@
 }
 
 /*
- * Initialize register descriptor.
+ * Set value information.
  */
 static void
 set_regdesc_value(_jit_regs_t *regs, int index, jit_value_t value, int flags, 
int live, int used)
@@ -2064,40 +2101,38 @@
 }
 
 /*
- * Set assigned and clobber flags for the register descriptor.
+ * Assign register to a value.
  */
 static void
 set_regdesc_register(jit_gencode_t gen, _jit_regs_t *regs, int index, int reg, 
int other_reg)
 {
-       int clobber;
-
        if(reg >= 0)
        {
                regs->descs[index].reg = reg;
                regs->descs[index].other_reg = other_reg;
 
-               clobber = clobbers_register(gen, regs, index, reg, other_reg);
-               set_register_flags(gen, regs, reg,
-                                  (clobber & CLOBBER_REG),
-                                  (clobber & CLOBBER_INPUT_VALUE));
+               jit_reg_set_used(gen->touched, reg);
+               jit_reg_set_used(regs->assigned, reg);
                if(other_reg >= 0)
                {
-                       set_register_flags(gen, regs, other_reg,
-                                          (clobber & CLOBBER_OTHER_REG),
-                                          (clobber & CLOBBER_INPUT_VALUE));
+                       jit_reg_set_used(gen->touched, other_reg);
+                       jit_reg_set_used(regs->assigned, other_reg);
                }
        }
 }
 
+/*
+ * Determine value flags.
+ */
 static int
-collect_register_info(jit_gencode_t gen, _jit_regs_t *regs, int index)
+set_regdesc_flags(jit_gencode_t gen, _jit_regs_t *regs, int index)
 {
        _jit_regdesc_t *desc;
        int reg, other_reg;
-       int stack_start;
+       int clobber, stack_start;
 
 #ifdef JIT_REG_DEBUG
-       printf("collect_register_info(index = %d)\n", index);
+       printf("set_regdesc_flags(index = %d)\n", index);
 #endif
 
        desc = &regs->descs[index];
@@ -2106,6 +2141,7 @@
                return 1;
        }
 
+       /* Find the registers the value is already in (if any). */
        if(desc->value->in_register)
        {
                reg = desc->value->reg;
@@ -2124,20 +2160,94 @@
                other_reg = -1;
        }
 
+       /* 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_REG) != 0)
+       {
+               jit_reg_set_used(regs->clobber, desc->reg);
+       }
+       if((clobber & CLOBBER_OTHER_REG) != 0)
+       {
+               jit_reg_set_used(regs->clobber, desc->other_reg);
+       }
+
+       /* 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))
+       {
+               if(index != 0)
+               {
+                       if(reg == regs->descs[0].reg
+                          || reg == regs->descs[0].other_reg
+                          || (other_reg >= 0
+                              && (other_reg == regs->descs[0].reg
+                                  || other_reg == regs->descs[0].other_reg)))
+                       {
+                               if(regs->ternary)
+                               {
+                                       if(!are_values_equal(desc, 
&regs->descs[0]))
+                                       {
+                                               desc->thrash = 1;
+                                       }
+                               }
+                               else
+                               {
+                                       if(desc->value != regs->descs[0].value)
+                                       {
+                                               clobber |= CLOBBER_INPUT_VALUE;
+                                       }
+                               }
+                       }
+               }
+               if(index != 1 && !are_values_equal(desc, &regs->descs[1]))
+               {
+                       if(reg == regs->descs[1].reg
+                          || reg == regs->descs[1].other_reg
+                          || (other_reg >= 0
+                              && (other_reg == regs->descs[1].reg
+                                  || other_reg == regs->descs[1].other_reg)))
+                       {
+                               desc->thrash = 1;
+                       }
+               }
+               if(index != 2 && !are_values_equal(desc, &regs->descs[2]))
+               {
+                       if(reg == regs->descs[2].reg
+                          || reg == regs->descs[2].other_reg
+                          || (other_reg >= 0
+                              && (other_reg == regs->descs[2].reg
+                                  || other_reg == regs->descs[2].other_reg)))
+                       {
+                               desc->thrash = 1;
+                       }
+               }
+
+               if(desc->thrash)
+               {
+                       reg = -1;
+                       other_reg = -1;
+                       desc->save = 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(desc->value->global_reg != desc->reg
-                          && !(desc->value->in_register && reg == desc->reg))
+                          && !(reg >= 0 && reg == desc->reg))
                        {
                                desc->copy = 1;
                        }
                }
                else
                {
-                       if(!desc->value->in_register)
+                       if(reg < 0)
                        {
                                desc->load = 1;
                        }
@@ -2154,13 +2264,11 @@
                {
                        desc->kill = 1;
                }
-               else if(desc->value->in_register)
+               else if(reg >= 0)
                {
                        if(desc->used)
                        {
-                               if(jit_reg_is_used(regs->clobber, reg)
-                                  || (other_reg >= 0
-                                      && jit_reg_is_used(regs->clobber, 
other_reg)))
+                               if(!desc->copy && (clobber & 
CLOBBER_INPUT_VALUE) != 0)
                                {
                                        desc->save = 1;
                                        desc->kill = 1;
@@ -2179,9 +2287,7 @@
                {
                        if(desc->used)
                        {
-                               if(jit_reg_is_used(regs->clobber, desc->reg)
-                                  || (desc->other_reg >= 0
-                                      && jit_reg_is_used(regs->clobber, 
desc->other_reg)))
+                               if((clobber & CLOBBER_INPUT_VALUE) != 0)
                                {
                                        desc->kill = 1;
                                }
@@ -2231,6 +2337,7 @@
        printf("\n");
        printf("value->in_register = %d\n", desc->value->in_register);
        printf("value->reg = %d\n", desc->value->reg);
+       printf("value->has_global_register = %d\n", 
desc->value->has_global_register);
        printf("value->in_global_register = %d\n", 
desc->value->in_global_register);
        printf("value->global_reg = %d\n", desc->value->global_reg);
        printf("value->in_frame = %d\n", desc->value->in_frame);
@@ -2241,6 +2348,7 @@
        printf("clobber = %d\n", desc->clobber);
        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("load = %d\n", desc->load);
        printf("copy = %d\n", desc->copy);
@@ -2251,16 +2359,42 @@
 }
 
 /*
- * To avoid circular movements of input values in place of each other
- * check if the current value overwrites any of the others.
+ * Check to see if loading one input value into the given register
+ * clobbers any other input values.
  */
 static int
-thrashes_register(jit_gencode_t gen, _jit_regs_t *regs,
-                 _jit_regdesc_t *desc, int reg, int other_reg)
+thrashes_register(jit_gencode_t gen, _jit_regs_t *regs, int index, int reg, 
int other_reg)
 {
+       _jit_regdesc_t *desc;
        int reg2, other_reg2;
-       if(regs->ternary && regs->descs[0].value && 
regs->descs[0].value->in_register
-          && !(desc && are_values_equal(&regs->descs[0], desc)))
+
+       if(index < 0)
+       {
+               desc = 0;
+       }
+       else
+       {
+               if(index == 0 && !regs->ternary)
+               {
+                       return 0;
+               }
+               desc = &regs->descs[index];
+               if(!desc->value)
+               {
+                       return 0;
+               }
+       }
+
+       if(index != 0 && regs->ternary && regs->descs[0].value)
+       {
+               if(!(desc && regs->descs[0].value == desc->value)
+                  && regs->descs[0].value->has_global_register
+                  && regs->descs[0].value->global_reg == reg)
+               {
+                       return 1;
+               }
+               if(regs->descs[0].value->in_register
+                  && !are_values_equal(&regs->descs[0], desc))
        {
                reg2 = regs->descs[0].value->reg;
                if(reg2 == reg || reg2 == other_reg)
@@ -2276,8 +2410,17 @@
                        }
                }
        }
-       if(regs->descs[1].value && regs->descs[1].value->in_register
-          && !(desc && are_values_equal(&regs->descs[1], desc)))
+       }
+       if(index != 1 && regs->descs[1].value)
+       {
+               if(!(desc && regs->descs[1].value == desc->value)
+                  && regs->descs[1].value->has_global_register
+                  && regs->descs[1].value->global_reg == reg)
+               {
+                       return 1;
+               }
+               if(regs->descs[1].value->in_register
+                  && !are_values_equal(&regs->descs[1], desc))
        {
                reg2 = regs->descs[1].value->reg;
                if(reg2 == reg || reg2 == other_reg)
@@ -2293,8 +2436,17 @@
                        }
                }
        }
-       if(regs->descs[2].value && regs->descs[2].value->in_register
-          && !(desc && are_values_equal(&regs->descs[2], desc)))
+       }
+       if(index != 2 && regs->descs[2].value)
+       {
+               if(!(desc && regs->descs[2].value == desc->value)
+                  && regs->descs[2].value->has_global_register
+                  && regs->descs[2].value->global_reg == reg)
+               {
+                       return 1;
+               }
+               if(regs->descs[2].value->in_register
+                  && !are_values_equal(&regs->descs[2], desc))
        {
                reg2 = regs->descs[2].value->reg;
                if(reg2 == reg || reg2 == other_reg)
@@ -2310,9 +2462,31 @@
                        }
                }
        }
+       }
        return 0;
 }
 
+/*
+ * Compute the register spill cost. The register spill cost is computed as
+ * the sum of spill costs of individual values the register contains. The
+ * spill cost of a value depends on the following factors:
+ *
+ * 1. Values that are not used after the current instruction may be safely
+ *    discareded so their spill cost is taken to be zero.
+ * 2. Values that are spilled to global registers are cheaper than values
+ *    that are spilled into stack frame.
+ * 3. Clean values are cheaper than dirty values.
+ *
+ * NOTE: A value is clean if it was loaded from the stack frame or from a
+ * global register and has not changed since then. Otherwise it is dirty.
+ * There is no need to spill clean values. However their spill cost is
+ * considered to be non-zero so that the register allocator will choose
+ * those registers that do not contain live values over those that contain
+ * live albeit clean values.
+ *
+ * For global registers this function returns the cost of zero. So global
+ * registers have to be handled separately.
+ */
 static int
 compute_spill_cost(jit_gencode_t gen, _jit_regs_t *regs, int reg, int 
other_reg)
 {
@@ -2379,16 +2553,24 @@
                        }
                        if(value->has_global_register)
                        {
-                               if(!value->in_global_register)
+                               if(value->in_global_register)
+                               {
+                                       cost += COST_SPILL_CLEAN_GLOBAL;
+                               }
+                               else
                                {
-                                       cost += 1;
+                                       cost += COST_SPILL_DIRTY_GLOBAL;
                                }
                        }
                        else
                        {
-                               if(!value->in_frame)
+                               if(value->in_frame)
+                               {
+                                       cost += COST_SPILL_CLEAN;
+                               }
+                               else
                                {
-                                       cost += 10;
+                                       cost += COST_SPILL_DIRTY;
                                }
                        }
                }
@@ -2445,17 +2627,19 @@
  *
  */
 static int
-use_cheapest_register(jit_gencode_t gen, _jit_regs_t *regs, int index, 
jit_regused_t regset)
+use_cheapest_register(jit_gencode_t gen, _jit_regs_t *regs, int index, 
jit_regused_t allowed)
 {
        _jit_regdesc_t *desc;
-       int output;
-       int type;
-       int need_pair;
+       _jit_regdesc_t *desc2;
+       _jit_regdesc_t *desc3;
+       int is_output, output_index;
+       int type, need_pair;
        int reg, other_reg;
        int cost, copy_cost;
        int suitable_reg;
        int suitable_cost;
        int suitable_age;
+       int clobber;
 
        if(index >= 0)
        {
@@ -2464,7 +2648,25 @@
                {
                        return -1;
                }
-               output = (index == 0 && !regs->ternary);
+
+               if(regs->ternary || regs->descs[0].value == 0)
+               {
+                       is_output = 0;
+                       output_index = 0;
+               }
+               else
+               {
+                       is_output = (index == 0);
+                       if(regs->free_dest)
+                       {
+                               output_index = 0;
+                       }
+                       else
+                       {
+                               output_index = 1 + (regs->reverse_dest ^ 
regs->reverse_args);
+                       }
+               }
+
                need_pair = _jit_regs_needs_long_pair(desc->value->type);
                type = get_register_type(desc->value, need_pair);
                if(!type)
@@ -2475,7 +2677,8 @@
        else
        {
                desc = 0;
-               output = 0;
+               is_output = 0;
+               output_index = 0;
                need_pair = 0;
                type = JIT_REG_WORD;
        }
@@ -2489,8 +2692,7 @@
                {
                        continue;
                }
-
-               if(!jit_reg_is_used(regset, reg)
+               if(!jit_reg_is_used(allowed, reg)
                   || jit_reg_is_used(gen->inhibit, reg)
                   || jit_reg_is_used(regs->assigned, reg))
                {
@@ -2503,125 +2705,122 @@
                        {
                                continue;
                        }
-                       else if(thrashes_register(gen, regs, desc, reg, -1))
+                       else if(thrashes_register(gen, regs, index, reg, -1))
                        {
                                continue;
                        }
-                       copy_cost = 0;
                        cost = compute_spill_cost(gen, regs, reg, -1);
+                       copy_cost = 0;
                }
-               else if(desc->value->has_global_register)
+               else
                {
-                       if(reg == desc->value->global_reg)
+                       if(need_pair)
                        {
-                               if(clobbers_register(gen, regs, index, reg, -1))
+                               other_reg = OTHER_REG(reg);
+                               if(jit_reg_is_used(gen->inhibit, other_reg)
+                                  || jit_reg_is_used(regs->assigned, 
other_reg))
                                {
                                        continue;
                                }
-                               copy_cost = ((output | 
desc->value->in_global_register) == 0);
-                               cost = 0;
                        }
-                       else if(jit_reg_is_used(gen->permanent, reg))
+                       else
                        {
-                               continue;
+                               other_reg = -1;
                        }
-                       else if(thrashes_register(gen, regs, desc, reg, -1))
+
+                       clobber = clobbers_register(gen, regs, index, reg, 
other_reg);
+                       if((clobber & ~CLOBBER_INPUT_VALUE) != 0)
+                       {
+                               if(jit_reg_is_used(gen->permanent, reg))
                        {
                                continue;
                        }
-                       else if(desc->value->in_register && reg == 
desc->value->reg)
-                       {
-                               copy_cost = ((output | 
desc->value->in_global_register) != 0);
-                               if(clobbers_register(gen, regs, index, reg, -1))
+#if !ALLOW_LONGS_USE_GLOBAL
+                               if(other_reg >= 0 && 
jit_reg_is_used(gen->permanent, other_reg))
                                {
-                                       cost = compute_spill_cost(gen, regs, 
reg, -1);
+                                       continue;
                                }
-                               else
+#endif
+                               if(jit_reg_is_used(regs->clobber, reg)
+                                  || (other_reg >= 0 && 
jit_reg_is_used(regs->clobber, other_reg)))
                                {
                                        cost = 0;
                                }
-                       }
                        else
                        {
-                               copy_cost = 1;
-                               cost = compute_spill_cost(gen, regs, reg, -1);
+                                       cost = compute_spill_cost(gen, regs, 
reg, other_reg);
+                               }
+#if ALLOW_LONGS_USE_GLOBAL
+                               if(other_reg >= 0 && 
jit_reg_is_used(gen->permanent, other_reg))
+                               {
+                                       cost += COST_CLOBBER_GLOBAL;
                        }
+#endif
                }
                else
                {
-                       if(jit_reg_is_used(gen->permanent, reg))
-                       {
-                               continue;
+                               cost = 0;
                        }
 
-                       if(need_pair)
+                       if(thrashes_register(gen, regs,
+                                            is_output ? output_index : index,
+                                            reg, other_reg))
                        {
-                               other_reg = OTHER_REG(reg);
-
-                               if(jit_reg_is_used(gen->inhibit, other_reg)
-                                  || jit_reg_is_used(regs->assigned, 
other_reg))
+                               if(jit_reg_is_used(gen->permanent, reg))
                                {
                                        continue;
                                }
-#if !ALLOW_CLOBBER_GLOBAL
-                               if(jit_reg_is_used(gen->permanent, other_reg))
+                               if(other_reg >= 0 && 
jit_reg_is_used(gen->permanent, other_reg))
                                {
                                        continue;
                                }
-#endif
-                       }
-                       else
+                               cost += COST_THRASH;
+                               if(other_reg >= 0)
                        {
-                               other_reg = -1;
+                                       cost += COST_THRASH;
+                               }
                        }
 
-                       if(thrashes_register(gen, regs, desc, reg, other_reg))
+                       if(is_output)
                        {
-                               continue;
+                               if(output_index && 
regs->descs[output_index].value)
+                               {
+                                       desc2 = &regs->descs[output_index];
                        }
-                       if(desc->value->in_register)
+                               else
                        {
-                               if(reg == desc->value->reg)
+                                       desc2 = 0;
+                               }
+                               desc3 = &regs->descs[0];
+                       }
+                       else
                                {
-                                       if(clobbers_register(gen, regs, index, 
reg, other_reg)
-                                          && !(jit_reg_is_used(regs->clobber, 
reg)
-                                               || (other_reg >= 0
-                                                   && 
jit_reg_is_used(regs->clobber, other_reg))))
+                               desc2 = desc;
+                               if(output_index && index == output_index)
                                        {
-                                               copy_cost = 0;
-                                               cost = compute_spill_cost(gen, 
regs, reg, other_reg);
+                                       desc3 = &regs->descs[0];
                                        }
                                        else
                                        {
-                                               copy_cost = 0;
-                                               cost = 0;
+                                       desc3 = desc;
                                        }
                                }
-                               else
+                       if(!desc2
+                          || (desc2->value->in_global_register && 
desc2->value->global_reg == reg)
+                          || (desc2->value->in_register && desc2->value->reg 
== reg))
                                {
-                                       copy_cost = 1;
-                                       cost = compute_spill_cost(gen, regs, 
reg, other_reg);
-                               }
+                               copy_cost = 0;
                        }
                        else
                        {
-                               copy_cost = 0;
-                               cost = compute_spill_cost(gen, regs, reg, 
other_reg);
+                               copy_cost = COST_COPY;
                        }
-#if ALLOW_CLOBBER_GLOBAL
-                       if(other_reg >= 0 && jit_reg_is_used(gen->permanent, 
other_reg))
+                       if(desc3->value->has_global_register && 
desc3->value->global_reg != reg)
                        {
-                               cost += COST_CLOBBER_GLOBAL;
+                               cost += COST_GLOBAL_BIAS;
                        }
-#endif
                }
 
-#if COST_COPY != 1
-               if(copy_cost)
-               {
-                       copy_cost = COST_COPY;
-               }
-#endif
                if((cost + copy_cost) < suitable_cost
                   || (cost > 0 && (cost + copy_cost) == suitable_cost
                       && gen->contents[reg].age < suitable_age))
@@ -2634,9 +2833,7 @@
        }
 
        reg = suitable_reg;
-       if(reg >= 0)
-       {
-               if(desc)
+       if(desc && reg >= 0)
                {
                        if(need_pair)
                        {
@@ -2648,11 +2845,6 @@
                        }
                        set_regdesc_register(gen, regs, index, reg, other_reg);
                }
-               else
-               {
-                       set_register_flags(gen, regs, reg, 1, 0);
-               }
-       }
 
        return reg;
 }
@@ -2694,7 +2886,7 @@
        int keep1, keep2;
        int out_index;
 
-       if(regs->ternary || !(regs->commutative || regs->x87_arith))
+       if(regs->ternary || regs->free_dest || !(regs->commutative || 
regs->x87_arith))
        {
                /* Bail out on ternary or non-commutative and non-x87 
instruction. */
                return;
@@ -2711,7 +2903,7 @@
        }
 
        /* Determine if we might want to keep either of input values
-          in registers after the operation completion. */
+          in registers after the instruction completion. */
        if(regs->clobber_all)
        {
                keep1 = 0;
@@ -3003,6 +3195,11 @@
                return;
        }
 
+       if(value->is_constant)
+       {
+               still_in_frame = 0;
+       }
+
        gen->contents[reg].values[0] = value;
        gen->contents[reg].num_values = 1;
        gen->contents[reg].age = gen->current_age;
@@ -3397,7 +3594,14 @@
                other_reg = -1;
        }
 
+       if(desc->thrash)
+       {
+               save_value(gen, desc->value, reg, other_reg, 1);
+       }
+       else
+       {
        save_value(gen, desc->value, reg, other_reg, 0);
+       }
 }
 
 static void
@@ -3721,7 +3925,7 @@
 }
 
 void
-_jit_regs_init(_jit_regs_t *regs, int flags)
+_jit_regs_init(jit_gencode_t gen, _jit_regs_t *regs, int flags)
 {
        int index;
 
@@ -3750,9 +3954,22 @@
        }
        regs->num_scratch = 0;
 
-       regs->assigned = jit_regused_init;
+       /* Set clobber flags. */
        regs->clobber = jit_regused_init;
-       regs->spill = jit_regused_init;
+       if(regs->clobber_all)
+       {
+               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;
+                       }
+                       jit_reg_set_used(regs->clobber, index);
+               }
+       }
+
+       regs->assigned = jit_regused_init;
 
        regs->stack_start = -1;
        regs->current_stack_top = 0;
@@ -3794,39 +4011,55 @@
 }
 
 void
-_jit_regs_set_dest(_jit_regs_t *regs, int reg, int other_reg)
+_jit_regs_set_dest(jit_gencode_t gen, _jit_regs_t *regs, int reg, int 
other_reg)
 {
-       regs->descs[0].reg = reg;
-       regs->descs[0].other_reg = other_reg;
+       if(reg >= 0 && !IS_STACK_REG(reg))
+       {
+               set_regdesc_register(gen, regs, 0, reg, other_reg);
+       }
 }
 
 void
-_jit_regs_set_value1(_jit_regs_t *regs, int reg, int other_reg)
+_jit_regs_set_value1(jit_gencode_t gen, _jit_regs_t *regs, int reg, int 
other_reg)
 {
-       regs->descs[1].reg = reg;
-       regs->descs[1].other_reg = other_reg;
+       if(reg >= 0 && !IS_STACK_REG(reg))
+       {
+               set_regdesc_register(gen, regs, 1, reg, other_reg);
+       }
 }
 
 void
-_jit_regs_set_value2(_jit_regs_t *regs, int reg, int other_reg)
+_jit_regs_set_value2(jit_gencode_t gen, _jit_regs_t *regs, int reg, int 
other_reg)
 {
-       regs->descs[2].reg = reg;
-       regs->descs[2].other_reg = other_reg;
+       if(reg >= 0 && !IS_STACK_REG(reg))
+       {
+               set_regdesc_register(gen, regs, 2, reg, other_reg);
+       }
 }
 
 void
-_jit_regs_add_scratch(_jit_regs_t *regs, int reg)
+_jit_regs_add_scratch(jit_gencode_t gen, _jit_regs_t *regs, int reg)
 {
        if(regs->num_scratch < _JIT_REGS_SCRATCH_MAX)
        {
-               regs->scratch[regs->num_scratch++].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_regs_t *regs, int reg)
+_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
@@ -3905,84 +4138,25 @@
 int
 _jit_regs_assign(jit_gencode_t gen, _jit_regs_t *regs)
 {
-       int index, out_index;
+       int reg, index, out_index;
 
 #ifdef JIT_REG_DEBUG
        printf("_jit_regs_assign()\n");
 #endif
 
-       /* Set clobber flags. */
-       if(regs->clobber_all)
-       {
-               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;
-                       }
-                       jit_reg_set_used(regs->clobber, index);
-               }
-       }
-
-       /* Spill all clobbered registers. */
-       regs->spill = regs->clobber;
-
        /* Process pre-assigned registers. */
 
-       if(regs->descs[0].reg >= 0)
-       {
-               if(IS_STACK_REG(regs->descs[0].reg))
-               {
-                       return 0;
-               }
-               set_regdesc_register(gen, regs, 0,
-                                    regs->descs[0].reg,
-                                    regs->descs[0].other_reg);
-       }
-       if(regs->descs[1].reg >= 0)
-       {
-               if(IS_STACK_REG(regs->descs[1].reg))
-               {
-                       return 0;
-               }
-               set_regdesc_register(gen, regs, 1,
-                                    regs->descs[1].reg,
-                                    regs->descs[1].other_reg);
-       }
-       if(regs->descs[2].reg >= 0)
-       {
-               if(IS_STACK_REG(regs->descs[2].reg))
-               {
-                       return 0;
-               }
-               set_regdesc_register(gen, regs, 2,
-                                    regs->descs[2].reg,
-                                    regs->descs[2].other_reg);
-       }
-
-       for(index = 0; index < regs->num_scratch; index++)
-       {
-               if(regs->scratch[index].reg >= 0)
-               {
-                       if(IS_STACK_REG(regs->scratch[index].reg))
-                       {
-                               return 0;
-                       }
-                       set_register_flags(gen, regs, regs->scratch[index].reg, 
1, 0);
-               }
-       }
        for(index = 0; index < regs->num_scratch; index++)
        {
                if(regs->scratch[index].reg < 0
                   && regs->scratch[index].regset != jit_regused_init_used)
                {
-                       regs->scratch[index].reg = use_cheapest_register(
-                               gen, regs, -1, regs->scratch[index].regset);
-                       if(regs->scratch[index].reg < 0)
+                       reg = use_cheapest_register(gen, regs, -1, 
regs->scratch[index].regset);
+                       if(reg < 0)
                        {
                                return 0;
                        }
+                       set_scratch_register(gen, regs, index, reg);
                }
        }
 
@@ -4006,41 +4180,12 @@
                check_duplicate_value(regs, &regs->descs[0], &regs->descs[1]);
                check_duplicate_value(regs, &regs->descs[0], &regs->descs[2]);
        }
-       else if(regs->descs[0].value && regs->descs[out_index].value)
-       {
-               if(regs->descs[0].reg < 0 && regs->descs[out_index].reg < 0)
-               {
-                       if(regs->descs[out_index].value->in_register
-                          && 
gen->contents[regs->descs[out_index].value->reg].num_values == 1
-                          && !(/*regs->descs[out_index].live 
||*/regs->descs[out_index].used))
-                       {
-                               /* NOTE: The last condition makes sense for 
local register
-                                  allocation, review it for future global 
allocator. */
-                               use_cheapest_register(
-                                       gen, regs, out_index, 
regs->descs[out_index].regset);
-                               if(regs->descs[out_index].reg < 0)
-                               {
-                                       return 0;
-                               }
-                       }
-                       else if(regs->descs[0].value->has_global_register
-                               || (regs->descs[0].value->in_register
-                                   && 
gen->contents[regs->descs[0].value->reg].num_values == 1))
-                       {
-                               use_cheapest_register(gen, regs, 0, 
regs->descs[0].regset);
-                               if(regs->descs[0].reg < 0)
-                               {
-                                       return 0;
-                               }
-                       }
-               }
-               if(regs->descs[0].reg >= 0)
+       else if(!regs->free_dest && regs->descs[0].reg >= 0 && 
regs->descs[out_index].value)
                {
                        set_regdesc_register(gen, regs, out_index,
                                             regs->descs[0].reg,
                                             regs->descs[0].other_reg);
                }
-       }
        if(regs->descs[1].value && regs->descs[1].reg < 0)
        {
                use_cheapest_register(gen, regs, 1, regs->descs[1].regset);
@@ -4060,7 +4205,7 @@
        }
        if(regs->descs[0].value && regs->descs[0].reg < 0)
        {
-               if(regs->descs[out_index].reg < 0)
+               if(regs->free_dest || regs->descs[out_index].reg < 0)
                {
                        use_cheapest_register(gen, regs, 0, 
regs->descs[0].regset);
                        if(regs->descs[0].reg < 0)
@@ -4080,25 +4225,25 @@
        {
                if(regs->scratch[index].reg < 0)
                {
-                       regs->scratch[index].reg = use_cheapest_register(
-                               gen, regs, -1, jit_regused_init_used);
-                       if(regs->scratch[index].reg < 0)
+                       reg = use_cheapest_register(gen, regs, -1, 
jit_regused_init_used);
+                       if(reg < 0)
                        {
                                return 0;
                        }
+                       set_scratch_register(gen, regs, index, reg);
                }
        }
 
        /* Collect information about registers. */
-       if(!collect_register_info(gen, regs, 0))
+       if(!set_regdesc_flags(gen, regs, 0))
        {
                return 0;
        }
-       if(!collect_register_info(gen, regs, 1))
+       if(!set_regdesc_flags(gen, regs, 1))
        {
                return 0;
        }
-       if(!collect_register_info(gen, regs, 2))
+       if(!set_regdesc_flags(gen, regs, 2))
        {
                return 0;
        }
@@ -4130,7 +4275,7 @@
                        stack_start = reg;
                }
 
-               if(!jit_reg_is_used(regs->spill, reg))
+               if(!jit_reg_is_used(regs->clobber, reg))
                {
                        continue;
                }
@@ -4143,7 +4288,7 @@
                        if(regs->branch)
                        {
                                /* After the branch is taken there is no way
-                                  to load global register back. */
+                                  to load the global register back. */
                                return 0;
                        }
                        _jit_gen_spill_global(gen, reg, 0);
@@ -4157,7 +4302,7 @@
                if(IS_STACK_REG(reg))
                {
                        top = get_stack_top(gen, stack_start);
-                       while(top > reg && jit_reg_is_used(regs->spill, top))
+                       while(top > reg && jit_reg_is_used(regs->clobber, top))
                        {
                                spill_reg(gen, regs, top);
                                /* If one of the input values is on the top
@@ -4311,7 +4456,7 @@
        /* Load clobbered global registers. */
        for(reg = JIT_NUM_REGS - 1; reg >= 0; reg--)
        {
-               if(jit_reg_is_used(regs->spill, reg) && 
jit_reg_is_used(gen->permanent, reg))
+               if(jit_reg_is_used(regs->clobber, reg) && 
jit_reg_is_used(gen->permanent, reg))
                {
                        _jit_gen_load_global(gen, reg, 0);
                }

Index: jit/jit-rules-x86.ins
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/jit/jit-rules-x86.ins,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- jit/jit-rules-x86.ins       16 Jun 2006 02:35:16 -0000      1.7
+++ jit/jit-rules-x86.ins       16 Jun 2006 17:53:51 -0000      1.8
@@ -431,22 +431,13 @@
                x86_imul_reg_reg(inst, $1, $2);
        }
 
-/* Spill before division to ensure that the arguments end up in
-   EAX and ECX, and that EDX is free */
-JIT_OP_IDIV: binary, spill_before, more_space
-       [reg, imm] -> {
-               switch($2)
-               {
-                       case 0:
-                       {
+JIT_OP_IDIV: more_space
+       [any, immzero] -> {
                                inst = throw_builtin(inst, func, 
JIT_RESULT_DIVISION_BY_ZERO);
                        }
-                       break;
-
-                       case 1: break;
-
-                       case -1:
-                       {
+       [reg, imm, if("$2 == 1")] -> {
+       }
+       [reg, imm, if("$2 == -1")] -> {
                                /* Dividing by -1 gives an exception if the 
argument
                                   is minint, or simply negates for other 
values */
                                unsigned char *patch;
@@ -457,204 +448,21 @@
                                x86_patch(patch, inst);
                                x86_neg_reg(inst, $1);
                        }
-                       break;
-
-                       case 2:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 1);
-                       }
-                       break;
-
-                       case 4:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 2);
-                       }
-                       break;
-
-                       case 8:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 3);
-                       }
-                       break;
-
-                       case 16:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 4);
-                       }
-                       break;
-
-                       case 32:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 5);
-                       }
-                       break;
-
-                       case 64:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 6);
-                       }
-                       break;
-
-                       case 128:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 7);
-                       }
-                       break;
-
-                       case 256:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 8);
-                       }
-                       break;
-
-                       case 512:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 9);
-                       }
-                       break;
-
-                       case 1024:
+       [reg, imm, if("(((jit_nuint)$2) & (((jit_nuint)$2) - 1)) == 0")] -> {
+               /* x & (x - 1) is equal to zero if x is a power of 2  */
+               jit_nuint shift, value;
+               for(shift = 0, value = $2; value; value >>= 1)
                        {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 10);
+                   ++shift;
                        }
-                       break;
-
-                       case 2048:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 11);
+               x86_shift_reg_imm(inst, X86_SAR, $1, shift);
                        }
-                       break;
-
-                       case 4096:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 12);
-                       }
-                       break;
-
-                       case 8192:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 13);
-                       }
-                       break;
-
-                       case 16384:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 14);
-                       }
-                       break;
-
-                       case 32768:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 15);
-                       }
-                       break;
-
-                       case 65536:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 16);
-                       }
-                       break;
-
-                       case 0x00020000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 17);
-                       }
-                       break;
-
-                       case 0x00040000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 18);
-                       }
-                       break;
-
-                       case 0x00080000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 19);
-                       }
-                       break;
-
-                       case 0x00100000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 20);
-                       }
-                       break;
-
-                       case 0x00200000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 21);
-                       }
-                       break;
-
-                       case 0x00400000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 22);
-                       }
-                       break;
-
-                       case 0x00800000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 23);
-                       }
-                       break;
-
-                       case 0x01000000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 24);
-                       }
-                       break;
-
-                       case 0x02000000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 25);
-                       }
-                       break;
-
-                       case 0x04000000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 26);
-                       }
-                       break;
-
-                       case 0x08000000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 27);
-                       }
-                       break;
-
-                       case 0x10000000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 28);
-                       }
-                       break;
-
-                       case 0x20000000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 29);
-                       }
-                       break;
-
-                       case 0x40000000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 30);
-                       }
-                       break;
-
-                       case (jit_nint)0x80000000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SAR, $1, 31);
-                       }
-                       break;
-
-                       default:
-                       {
-                               x86_mov_reg_imm(inst, X86_ECX, $2);
+       [reg("eax"), imm, scratch("?", "edx")] -> {
+               x86_mov_reg_imm(inst, $3, $2);
                                x86_cdq(inst);
-                               x86_div_reg(inst, X86_ECX, 1);
-                       }
-                       break;
-               }
+               x86_div_reg(inst, $3, 1);
        }
-       [reg, reg] -> {
+       [reg("eax"), reg, scratch("edx")] -> {
                unsigned char *patch, *patch2;
                x86_alu_reg_reg(inst, X86_OR, $2, $2);
                patch = inst;
@@ -674,214 +482,27 @@
                x86_div_reg(inst, $2, 1);
        }
 
-JIT_OP_IDIV_UN: binary, spill_before, more_space
-       [reg, imm] -> {
-               switch($2)
-               {
-                       case 0:
-                       {
+JIT_OP_IDIV_UN: more_space
+       [any, immzero] -> {
                                inst = throw_builtin(inst, func, 
JIT_RESULT_DIVISION_BY_ZERO);
                        }
-                       break;
-
-                       case 1: break;
-
-                       case 2:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 1);
-                       }
-                       break;
-
-                       case 4:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 2);
-                       }
-                       break;
-
-                       case 8:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 3);
-                       }
-                       break;
-
-                       case 16:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 4);
-                       }
-                       break;
-
-                       case 32:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 5);
-                       }
-                       break;
-
-                       case 64:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 6);
-                       }
-                       break;
-
-                       case 128:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 7);
-                       }
-                       break;
-
-                       case 256:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 8);
-                       }
-                       break;
-
-                       case 512:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 9);
-                       }
-                       break;
-
-                       case 1024:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 10);
-                       }
-                       break;
-
-                       case 2048:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 11);
-                       }
-                       break;
-
-                       case 4096:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 12);
-                       }
-                       break;
-
-                       case 8192:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 13);
-                       }
-                       break;
-
-                       case 16384:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 14);
-                       }
-                       break;
-
-                       case 32768:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 15);
-                       }
-                       break;
-
-                       case 65536:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 16);
-                       }
-                       break;
-
-                       case 0x00020000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 17);
-                       }
-                       break;
-
-                       case 0x00040000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 18);
-                       }
-                       break;
-
-                       case 0x00080000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 19);
-                       }
-                       break;
-
-                       case 0x00100000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 20);
-                       }
-                       break;
-
-                       case 0x00200000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 21);
-                       }
-                       break;
-
-                       case 0x00400000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 22);
-                       }
-                       break;
-
-                       case 0x00800000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 23);
-                       }
-                       break;
-
-                       case 0x01000000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 24);
-                       }
-                       break;
-
-                       case 0x02000000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 25);
-                       }
-                       break;
-
-                       case 0x04000000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 26);
-                       }
-                       break;
-
-                       case 0x08000000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 27);
-                       }
-                       break;
-
-                       case 0x10000000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 28);
+       [reg, imm, if("$2 == 1")] -> {
                        }
-                       break;
-
-                       case 0x20000000:
+       [reg, imm, if("(((jit_nuint)$2) & (((jit_nuint)$2) - 1)) == 0")] -> {
+               /* x & (x - 1) is equal to zero if x is a power of 2  */
+               jit_nuint shift, value;
+               for(shift = 0, value = $2; value; value >>= 1)
                        {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 29);
+                   ++shift;
                        }
-                       break;
-
-                       case 0x40000000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 30);
-                       }
-                       break;
-
-                       case (jit_nint)0x80000000:
-                       {
-                               x86_shift_reg_imm(inst, X86_SHR, $1, 31);
+               x86_shift_reg_imm(inst, X86_SAR, $1, shift);
                        }
-                       break;
-
-                       default:
-                       {
-                               x86_mov_reg_imm(inst, X86_ECX, $2);
+       [reg("eax"), imm, scratch("?", "edx")] -> {
+               x86_mov_reg_imm(inst, $3, $2);
                                x86_clear_reg(inst, X86_EDX);
-                               x86_div_reg(inst, X86_ECX, 0);
-                       }
-                       break;
+               x86_div_reg(inst, $3, 0);
                }
-       }
-       [reg, reg] -> {
+       [reg("eax"), reg, scratch("edx")] -> {
                unsigned char *patch;
                x86_alu_reg_reg(inst, X86_OR, $2, $2);
                patch = inst;
@@ -892,24 +513,14 @@
                x86_div_reg(inst, $2, 0);
        }
 
-JIT_OP_IREM: binary, spill_before, more_space
-       [reg, imm] -> {
-               switch($2)
-               {
-                       case 0:
-                       {
+JIT_OP_IREM: more_space
+       [any, immzero] -> {
                                inst = throw_builtin(inst, func, 
JIT_RESULT_DIVISION_BY_ZERO);
                        }
-                       break;
-
-                       case 1:
-                       {
+       [reg, imm, if("$2 == 1")] -> {
                                x86_clear_reg(inst, $1);
                        }
-                       break;
-
-                       case -1:
-                       {
+       [reg, imm, if("$2 == -1")] -> {
                                /* Dividing by -1 gives an exception if the 
argument
                                   is minint, or simply gives a remainder of 
zero */
                                unsigned char *patch;
@@ -920,20 +531,12 @@
                                x86_patch(patch, inst);
                                x86_clear_reg(inst, $1);
                        }
-                       break;
-
-                       default:
-                       {
-                               x86_mov_reg_imm(inst, X86_ECX, $2);
+       [=reg("edx"), *reg("eax"), imm, scratch("?")] -> {
+               x86_mov_reg_imm(inst, $3, $2);
                                x86_cdq(inst);
-                               x86_div_reg(inst, X86_ECX, 1);
-                               /* TODO: rearrange register assignments to 
avoid the move */
-                               x86_mov_reg_reg(inst, X86_EAX, X86_EDX, 4);
+               x86_div_reg(inst, $3, 1);
                        }
-                       break;
-               }
-       }
-       [reg, reg] -> {
+       [=reg("edx"), *reg("eax"), reg] -> {
                unsigned char *patch, *patch2;
                x86_alu_reg_reg(inst, X86_OR, $2, $2);
                patch = inst;
@@ -951,72 +554,25 @@
                x86_patch(patch2, inst);
                x86_cdq(inst);
                x86_div_reg(inst, $2, 1);
-               x86_mov_reg_reg(inst, X86_EAX, X86_EDX, 4);
        }
 
-JIT_OP_IREM_UN: binary, spill_before, more_space
-       [reg, imm] -> {
-               switch($2)
-               {
-                       case 0:
-                       {
+JIT_OP_IREM_UN: more_space
+       [any, immzero] -> {
                                inst = throw_builtin(inst, func, 
JIT_RESULT_DIVISION_BY_ZERO);
                        }
-                       break;
-
-                       case 1:
-                       {
+       [reg, imm, if("$2 == 1")] -> {
                                x86_clear_reg(inst, $1);
                        }
-                       break;
-
-                       case 2:
-                       case 4:
-                       case 8:
-                       case 16:
-                       case 32:
-                       case 64:
-                       case 128:
-                       case 256:
-                       case 512:
-                       case 1024:
-                       case 2048:
-                       case 4096:
-                       case 8192:
-                       case 16384:
-                       case 32768:
-                       case 65536:
-                       case 0x00020000:
-                       case 0x00040000:
-                       case 0x00080000:
-                       case 0x00100000:
-                       case 0x00200000:
-                       case 0x00400000:
-                       case 0x00800000:
-                       case 0x01000000:
-                       case 0x02000000:
-                       case 0x04000000:
-                       case 0x08000000:
-                       case 0x10000000:
-                       case 0x20000000:
-                       case 0x40000000:
-                       case (jit_nint)0x80000000:
-                       {
+       [reg, imm, if("(((jit_nuint)$2) & (((jit_nuint)$2) - 1)) == 0")] -> {
+               /* x & (x - 1) is equal to zero if x is a power of 2  */
                                x86_alu_reg_imm(inst, X86_AND, $1, $2 - 1);
                        }
-                       break;
-
-                       default:
-                       {
-                               x86_mov_reg_imm(inst, X86_ECX, $2);
+       [=reg("edx"), *reg("eax"), imm, scratch("?")] -> {
+               x86_mov_reg_imm(inst, $3, $2);
                                x86_clear_reg(inst, X86_EDX);
-                               x86_div_reg(inst, X86_ECX, 0);
-                               x86_mov_reg_reg(inst, X86_EAX, X86_EDX, 4);
-                       }
-                       break;
-               }
+               x86_div_reg(inst, $3, 0);
        }
-       [reg, reg] -> {
+       [=reg("edx"), *reg("eax"), reg] -> {
                unsigned char *patch;
                x86_alu_reg_reg(inst, X86_OR, $2, $2);
                patch = inst;
@@ -1025,7 +581,6 @@
                x86_patch(patch, inst);
                x86_clear_reg(inst, X86_EDX);
                x86_div_reg(inst, $2, 0);
-               x86_mov_reg_reg(inst, X86_EAX, X86_EDX, 4);
        }
 
 JIT_OP_INEG: unary
@@ -1916,35 +1471,19 @@
                TODO();
        }
 
-JIT_OP_ADDRESS_OF_LABEL: manual
-       [] -> {
-               unsigned char *inst;
-               jit_block_t block;
-               int reg;
-
-               reg = _jit_regs_dest_value(gen, insn->dest);
-
-               inst = gen->posn.ptr;
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
-               }
-               reg = _jit_reg_info[reg].cpu_reg;
-
+JIT_OP_ADDRESS_OF_LABEL:
+       [=reg] -> {
                block = jit_block_from_label(func, (jit_label_t)(insn->value1));
                if(block->address)
                {
-                       x86_mov_reg_imm(inst, reg, block->address);
+                       x86_mov_reg_imm(inst, $0, block->address);
                }
                else
                {
                        /* Output a placeholder and record on the block's fixup 
list */
-                       x86_mov_reg_imm(inst, reg, 
(int)(block->fixup_absolute_list));
+                       x86_mov_reg_imm(inst, $0, 
(int)(block->fixup_absolute_list));
                        block->fixup_absolute_list = (void *)(inst - 4);
                }
-
-               gen->posn.ptr = inst;
        }
 
 /*
@@ -2289,68 +1828,22 @@
                gen->posn.ptr = inst;
        }
 
-JIT_OP_LOAD_RELATIVE_FLOAT32: manual
-       [] -> {
-               unsigned char *inst;
-               int reg = _jit_regs_load_value
-                       (gen, insn->value1, 0,
-                        (insn->flags & (JIT_INSN_VALUE1_NEXT_USE |
-                                                        
JIT_INSN_VALUE1_LIVE)));
-               _jit_regs_new_top(gen, insn->dest, 8);
-               inst = gen->posn.ptr;
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
-               }
-               reg = _jit_reg_info[reg].cpu_reg;
-               x86_fld_membase(inst, reg, insn->value2->address, 0);
-               gen->posn.ptr = inst;
+JIT_OP_LOAD_RELATIVE_FLOAT32:
+       [=freg, reg, imm] -> {
+               x86_fld_membase(inst, $1, $2, 0);
        }
 
-JIT_OP_LOAD_RELATIVE_FLOAT64: manual
-       [] -> {
-               unsigned char *inst;
-               int reg = _jit_regs_load_value
-                       (gen, insn->value1, 0,
-                        (insn->flags & (JIT_INSN_VALUE1_NEXT_USE |
-                                                        
JIT_INSN_VALUE1_LIVE)));
-               _jit_regs_new_top(gen, insn->dest, 8);
-               inst = gen->posn.ptr;
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
-               }
-               reg = _jit_reg_info[reg].cpu_reg;
-               x86_fld_membase(inst, reg, insn->value2->address, 1);
-               gen->posn.ptr = inst;
+JIT_OP_LOAD_RELATIVE_FLOAT64:
+       [=freg, reg, imm] -> {
+               x86_fld_membase(inst, $1, $2, 1);
        }
 
-JIT_OP_LOAD_RELATIVE_NFLOAT: manual
-       [] -> {
-               unsigned char *inst;
-               int reg = _jit_regs_load_value
-                       (gen, insn->value1, 0,
-                        (insn->flags & (JIT_INSN_VALUE1_NEXT_USE |
-                                                        
JIT_INSN_VALUE1_LIVE)));
-               _jit_regs_new_top(gen, insn->dest, 8);
-               inst = gen->posn.ptr;
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
+JIT_OP_LOAD_RELATIVE_NFLOAT:
+       [=freg, reg, imm, if("sizeof(jit_nfloat) != sizeof(jit_float64)")] -> {
+               x86_fld80_membase(inst, $1, $2);
                }
-               reg = _jit_reg_info[reg].cpu_reg;
-               if(sizeof(jit_nfloat) != sizeof(jit_float64))
-               {
-                       x86_fld80_membase(inst, reg, insn->value2->address);
-               }
-               else
-               {
-                       x86_fld_membase(inst, reg, insn->value2->address, 1);
-               }
-               gen->posn.ptr = inst;
+       [=freg, reg, imm, if("sizeof(jit_nfloat) == sizeof(jit_float64)")] -> {
+               x86_fld_membase(inst, $1, $2, 1);
        }
 
 JIT_OP_LOAD_RELATIVE_STRUCT: unary_branch, more_space
@@ -2547,94 +2040,25 @@
                gen->posn.ptr = inst;
        }
 
-JIT_OP_LOAD_ELEMENT_FLOAT32: manual
-       [] -> {
-               unsigned char *inst;
-               int reg, reg2;
-
-               reg = _jit_regs_load_value(gen, insn->value1, 0,
-                       (insn->flags & (JIT_INSN_VALUE1_NEXT_USE | 
JIT_INSN_VALUE1_LIVE)));
-               reg2 = _jit_regs_load_value(gen, insn->value2, 0,
-                        (insn->flags & (JIT_INSN_VALUE2_NEXT_USE | 
JIT_INSN_VALUE2_LIVE)));
-               _jit_regs_new_top(gen, insn->dest, 8);
-
-               inst = gen->posn.ptr;
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
-               }
-
-               reg = _jit_reg_info[reg].cpu_reg;
-               reg2 = _jit_reg_info[reg2].cpu_reg;
-
-               x86_fld_memindex(inst, reg, 0, reg2, 2, 0);
-
-               gen->posn.ptr = inst;
-       }
-
-JIT_OP_LOAD_ELEMENT_FLOAT64: manual
-       [] -> {
-               unsigned char *inst;
-               int reg, reg2, reg3;
-
-               reg = _jit_regs_load_value(gen, insn->value1, 0,
-                       (insn->flags & (JIT_INSN_VALUE1_NEXT_USE | 
JIT_INSN_VALUE1_LIVE)));
-               reg2 = _jit_regs_load_value(gen, insn->value2, 0,
-                        (insn->flags & (JIT_INSN_VALUE2_NEXT_USE | 
JIT_INSN_VALUE2_LIVE)));
-               reg3 = _jit_regs_new_top(gen, insn->dest, 8);
-
-               inst = gen->posn.ptr;
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
+JIT_OP_LOAD_ELEMENT_FLOAT32:
+       [=freg, reg, reg] -> {
+               x86_fld_memindex(inst, $1, 0, $2, 2, 0);
                }
 
-               reg = _jit_reg_info[reg].cpu_reg;
-               reg2 = _jit_reg_info[reg2].cpu_reg;
-
-               x86_fld_memindex(inst, reg, 0, reg2, 3, 1);
-
-               gen->posn.ptr = inst;
+JIT_OP_LOAD_ELEMENT_FLOAT64:
+       [=freg, reg, reg] -> {
+               x86_fld_memindex(inst, $1, 0, $2, 3, 1);
        }
 
-JIT_OP_LOAD_ELEMENT_NFLOAT: manual
-       [] -> {
-               unsigned char *inst;
-               int reg, reg2, reg3;
-
-               reg = _jit_regs_load_value
-                       (gen, insn->value1, 0,
-                        (insn->flags & (JIT_INSN_VALUE1_NEXT_USE | 
JIT_INSN_VALUE1_LIVE)));
-               reg2 = _jit_regs_load_value
-                       (gen, insn->value2, sizeof(jit_nfloat) != 
sizeof(jit_float64),
-                        (insn->flags & (JIT_INSN_VALUE2_NEXT_USE | 
JIT_INSN_VALUE2_LIVE)));
-               reg3 = _jit_regs_new_top(gen, insn->dest, 8);
-
-               inst = gen->posn.ptr;
-               if(!jit_cache_check_for_n(&(gen->posn), 32))
-               {
-                       jit_cache_mark_full(&(gen->posn));
-                       return;
-               }
-
-               reg = _jit_reg_info[reg].cpu_reg;
-               reg2 = _jit_reg_info[reg2].cpu_reg;
-
-               if(sizeof(jit_nfloat) != sizeof(jit_float64))
-               {
-                       /* lea reg2, [reg2 + reg2 * 2]  */
-                       x86_lea_memindex(inst, reg2, reg2, 0, reg2, 1);
-                       /* fld [reg2 * 4] */
-                       x86_fld80_memindex(inst, reg, 0, reg2, 2);
-               }
-               else
-               {
-                       x86_fld_memindex(inst, reg, 0, reg2, 3, 1);
+JIT_OP_LOAD_ELEMENT_NFLOAT:
+       [=freg, reg, +reg, if("sizeof(jit_nfloat) != sizeof(jit_float64)")] -> {
+               /* lea $2, [$2 + $2 * 2]  */
+               x86_lea_memindex(inst, $2, $2, 0, $2, 1);
+               /* fld [$2 * 4] */
+               x86_fld80_memindex(inst, $1, 0, $2, 2);
                }
-
-               gen->posn.ptr = inst;
+       [=freg, reg, reg, if("sizeof(jit_nfloat) == sizeof(jit_float64)")] -> {
+               x86_fld_memindex(inst, $1, 0, $2, 3, 1);
        }
 
 JIT_OP_STORE_ELEMENT_BYTE: ternary

Index: tools/gen-rules-parser.y
===================================================================
RCS file: /sources/dotgnu-pnet/libjit/tools/gen-rules-parser.y,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- tools/gen-rules-parser.y    3 Jun 2006 13:39:53 -0000       1.8
+++ tools/gen-rules-parser.y    16 Jun 2006 17:53:52 -0000      1.9
@@ -822,8 +822,10 @@
        char *code,
        char *names[MAX_PATTERN],
        char *other_names[MAX_PATTERN],
+       int free_dest,
        int in_line)
 {
+       char first;
        int index;
        
        /* Output the clause code */
@@ -833,15 +835,16 @@
        }
        while(*code != '\0')
        {
-               if(*code == '$' && code[1] >= '1' && code[1] <= '9')
+               first = free_dest ? '0' : '1';
+               if(*code == '$' && code[1] >= first && code[1] <= (first + 
MAX_PATTERN))
                {
-                       index = code[1] - '1';
+                       index = code[1] - first;
                        printf(names[index]);
                        code += 2;
                }
-               else if(*code == '%' && code[1] >= '1' && code[1] <= '9')
+               else if(*code == '%' && code[1] >= first && code[1] <= (first + 
MAX_PATTERN))
                {
-                       index = code[1] - '1';
+                       index = code[1] - first;
                        printf(other_names[index]);
                        code += 2;
                }
@@ -870,14 +873,15 @@
 gensel_output_clause_code(
        gensel_clause_t clause,
        char *names[MAX_PATTERN],
-       char *other_names[MAX_PATTERN])
+       char *other_names[MAX_PATTERN],
+       int free_dest)
 {
        /* Output the line number information from the original file */
 #if 0
        printf("#line %ld \"%s\"\n", clause->linenum, clause->filename);
 #endif
 
-       gensel_output_code(clause->pattern, clause->code, names, other_names, 
0);
+       gensel_output_code(clause->pattern, clause->code, names, other_names, 
free_dest, 0);
 }
 
 /*
@@ -905,7 +909,7 @@
                        printf("\t_jit_regs_spill_all(gen);\n");
                }
                gensel_init_names(MAX_PATTERN, names, other_names);
-               gensel_output_clause_code(clauses, names, other_names);
+               gensel_output_clause_code(clauses, names, other_names, 0);
                return;
        }
 
@@ -1087,7 +1091,7 @@
                                        gensel_output_code(
                                                clause->pattern,
                                                pattern->values->value,
-                                               names, other_names, 1);
+                                               names, other_names, free_dest, 
1);
                                        printf(")");
                                        seen_option = 1;
                                        break;
@@ -1137,7 +1141,7 @@
                if(contains_registers)
                {
                        seen_option = 0;
-                       printf("\t\t_jit_regs_init(&regs, ");
+                       printf("\t\t_jit_regs_init(gen, &regs, ");
                        if(clobber_all)
                        {
                                seen_option = 1;
@@ -1275,7 +1279,7 @@
                                {
                                        if(pattern->values->type == 
GENSEL_VALUE_STRING)
                                        {
-                                               
printf("\t\t_jit_regs_set_%s(&regs, _jit_regs_lookup(\"%s\"), -1);\n",
+                                               
printf("\t\t_jit_regs_set_%s(gen, &regs, _jit_regs_lookup(\"%s\"), -1);\n",
                                                       args[index], 
pattern->values->value);
                                        }
                                        else
@@ -1308,12 +1312,12 @@
                                        {
                                                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",
+                                                       
printf("\t\t_jit_regs_set_%s(gen, &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",
+                                                       
printf("\t\t_jit_regs_set_%s(gen, &regs, _jit_regs_lookup(\"%s\"), -1);\n",
                                                               args[index], 
pattern->values->value);
                                                }
                                        }
@@ -1358,7 +1362,7 @@
                                        {
                                                if(values->type == 
GENSEL_VALUE_STRING)
                                                {
-                                                       
printf("\t\t_jit_regs_add_scratch(&regs, _jit_regs_lookup(\"%s\"));\n",
+                                                       
printf("\t\t_jit_regs_add_scratch(gen, &regs, _jit_regs_lookup(\"%s\"));\n",
                                                               values->value);
                                                }
                                                else
@@ -1379,7 +1383,7 @@
                                        }
                                        else
                                        {
-                                               
printf("\t\t_jit_regs_add_scratch(&regs, -1);\n");
+                                               
printf("\t\t_jit_regs_add_scratch(gen, &regs, -1);\n");
                                        }
                                        ++regs;
                                        ++index;
@@ -1393,7 +1397,7 @@
                                {
                                        if(values->value && 
strcmp(values->value, "*") != 0)
                                        {
-                                               
printf("\t\t_jit_regs_set_clobber(&regs, _jit_regs_lookup(\"%s\"));\n",
+                                               
printf("\t\t_jit_regs_set_clobber(gen, &regs, _jit_regs_lookup(\"%s\"));\n",
                                                       values->value);
                                        }
                                        values = values->next;
@@ -1441,7 +1445,7 @@
                                gensel_output_code(
                                        clause->pattern,
                                        space->values->value,
-                                       names, other_names, 1);
+                                       names, other_names, free_dest, 1);
                                printf(")");
                        }
                        else
@@ -1538,7 +1542,7 @@
                }
 
                gensel_build_var_index(clause->pattern, names, other_names);
-               gensel_output_clause_code(clause, names, other_names);
+               gensel_output_clause_code(clause, names, other_names, 
free_dest);
 
                /* Copy "inst" back into the generation context */
                if(gensel_new_inst_type)




reply via email to

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