]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
make register pair handling more flexible
authorAleksey Demakov <ademakov@gmail.com>
Sat, 28 Mar 2009 00:11:38 +0000 (00:11 +0000)
committerAleksey Demakov <ademakov@gmail.com>
Sat, 28 Mar 2009 00:11:38 +0000 (00:11 +0000)
ChangeLog
jit/jit-reg-alloc.c
jit/jit-reg-alloc.h
jit/jit-rules-arm.c
jit/jit-rules-interp.c
jit/jit-rules-x86.c
jit/jit-rules.h

index e58df7fadc6a0b58d0e1967536029634cf2a3db5..846e839e1b1f5971a7606e37f439bb8cb20de5bd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,14 @@
 2009-03-28  Aleksey Demakov  <ademakov@gmail.com>
 
-       * jit/jit-reg-alloc.c, jit/jit-reg-alloc.c (_jit_regs_get_cpu):
-       remove unused function.
+       * jit/jit-rules.h (jit_reg_name, jit_reg_flags, jit_reg_code); add
+       convenience macros for register info access.
+       * jit/jit-rules.h, jit/jit-rules-interp.c, jit/jit-rules-x86.c,
+       * jit/jit-rules-arm.c (_jit_reg_get_pair, jit_reg_get_pair): add
+       function and macro for finding register pair.
+       * jit/jit-reg-alloc.c: replace use of _jit_regs_needs_long_pair with
+       jit_reg_get_pair().
+       * jit/jit-reg-alloc.h, jit/jit-reg-alloc.c (_jit_regs_get_cpu)
+       (_jit_regs_needs_long_pair): remove unused functions.
 
 2009-03-25  Michele Tartara  <mikyt@users.sourceforge.net>
 
index 15eb4b7d90d0148458e6d9926896bc58c72ac90c..696cf7c3790f74e0abd8d6e46e9fbb6e4728af21 100644 (file)
@@ -139,7 +139,7 @@ static void dump_regs(jit_gencode_t gen, const char *name)
 #endif
 
 /*
- * Find the start register of a long pair given the end register.
+ * Find the start register of a register pair given the end register.
  */
 static int
 get_long_pair_start(int other_reg)
@@ -155,43 +155,6 @@ get_long_pair_start(int other_reg)
        return -1;
 }
 
-/*
- * Determine the type of register that we need.
- */
-static int
-get_register_type(jit_value_t value, int need_pair)
-{
-       switch(jit_type_normalize(value->type)->kind)
-       {
-       case JIT_TYPE_SBYTE:
-       case JIT_TYPE_UBYTE:
-       case JIT_TYPE_SHORT:
-       case JIT_TYPE_USHORT:
-       case JIT_TYPE_INT:
-       case JIT_TYPE_UINT:
-       case JIT_TYPE_NINT:
-       case JIT_TYPE_NUINT:
-       case JIT_TYPE_SIGNATURE:
-       case JIT_TYPE_PTR:
-               return JIT_REG_WORD;
-
-       case JIT_TYPE_LONG:
-       case JIT_TYPE_ULONG:
-               return need_pair ? JIT_REG_LONG : JIT_REG_WORD;
-
-       case JIT_TYPE_FLOAT32:
-               return JIT_REG_FLOAT32;
-
-       case JIT_TYPE_FLOAT64:
-               return JIT_REG_FLOAT64;
-
-       case JIT_TYPE_NFLOAT:
-               return JIT_REG_NFLOAT;
-       }
-
-       return 0;
-}
-
 /*
  * Check if two values are known to be equal.
  */
@@ -1139,7 +1102,6 @@ static int
 choose_output_register(jit_gencode_t gen, _jit_regs_t *regs)
 {
        _jit_regclass_t *regclass;
-       int need_pair;
        int reg_index, reg, other_reg;
        int use_cost;
        int suitable_reg, suitable_other_reg;
@@ -1151,7 +1113,6 @@ choose_output_register(jit_gencode_t gen, _jit_regs_t *regs)
 #endif
 
        regclass = regs->descs[0].regclass;
-       need_pair = _jit_regs_needs_long_pair(regs->descs[0].value->type);
 
        suitable_reg = -1;
        suitable_other_reg = -1;
@@ -1165,17 +1126,10 @@ choose_output_register(jit_gencode_t gen, _jit_regs_t *regs)
                        continue;
                }
 
-               if(need_pair)
-               {
-                       other_reg = jit_reg_other_reg(reg);
-                       if(jit_reg_is_used(gen->inhibit, other_reg))
-                       {
-                               continue;
-                       }
-               }
-               else
+               other_reg = jit_reg_get_pair(regs->descs[0].value->type, reg);
+               if(other_reg >= 0 && jit_reg_is_used(gen->inhibit, other_reg))
                {
-                       other_reg = -1;
+                       continue;
                }
 
                if(jit_reg_is_used(gen->permanent, reg))
@@ -1377,7 +1331,6 @@ choose_input_register(jit_gencode_t gen, _jit_regs_t *regs, int index)
        _jit_regclass_t *regclass;
        _jit_regdesc_t *desc;
        _jit_regdesc_t *desc2;
-       int need_pair;
        int reg_index, reg, other_reg;
        int use_cost;
        int suitable_reg, suitable_other_reg;
@@ -1396,7 +1349,6 @@ choose_input_register(jit_gencode_t gen, _jit_regs_t *regs, int index)
        }
 
        regclass = regs->descs[index].regclass;
-       need_pair = _jit_regs_needs_long_pair(desc->value->type);
 
        if(index == regs->dest_input_index)
        {
@@ -1419,17 +1371,10 @@ choose_input_register(jit_gencode_t gen, _jit_regs_t *regs, int index)
                        continue;
                }
 
-               if(need_pair)
-               {
-                       other_reg = jit_reg_other_reg(reg);
-                       if(jit_reg_is_used(regs->assigned, other_reg))
-                       {
-                               continue;
-                       }
-               }
-               else
+               other_reg = jit_reg_get_pair(desc->value->type, reg);
+               if(other_reg >= 0 && jit_reg_is_used(regs->assigned, other_reg))
                {
-                       other_reg = -1;
+                       continue;
                }
 
                if((desc->value->in_global_register && desc->value->global_reg == reg)
@@ -2677,29 +2622,6 @@ _jit_regs_lookup(char *name)
        return -1;
 }
 
-/*@
- * @deftypefun int _jit_regs_needs_long_pair (jit_type_t type)
- * Determine if a type requires a long register pair.
- * @end deftypefun
-@*/
-int _jit_regs_needs_long_pair(jit_type_t type)
-{
-#if defined(JIT_NATIVE_INT32) && !defined(JIT_BACKEND_INTERP)
-       type = jit_type_normalize(type);
-       if(type)
-       {
-               if(type->kind == JIT_TYPE_LONG || type->kind == JIT_TYPE_ULONG)
-               {
-                       return 1;
-               }
-       }
-       return 0;
-#else
-       /* We don't register pairs on 64-bit platforms or the interpreter */
-       return 0;
-#endif
-}
-
 /*@
  * @deftypefun void _jit_regs_alloc_global (jit_gencode_t gen, jit_function_t func)
  * Perform global register allocation on the values in @code{func}.
@@ -2890,15 +2812,8 @@ _jit_regs_set_incoming(jit_gencode_t gen, int reg, jit_value_t value)
 {
        int other_reg;
 
-       /* Find the other register in a long pair */
-       if(_jit_regs_needs_long_pair(value->type))
-       {
-               other_reg = jit_reg_other_reg(reg);
-       }
-       else
-       {
-               other_reg = -1;
-       }
+       /* Find the other register in a register pair */
+       other_reg = jit_reg_get_pair(value->type, reg);
 
        /* avd: It's too late to spill here, if there was any
           value it is already cloberred by the incoming value.
@@ -2956,15 +2871,9 @@ _jit_regs_set_outgoing(jit_gencode_t gen, int reg, jit_value_t value)
                }
        }
 #else
-       if(_jit_regs_needs_long_pair(value->type))
-       {
-               other_reg = jit_reg_other_reg(reg);
-       }
-       else
-       {
-               other_reg = -1;
-       }
+       other_reg = jit_reg_get_pair(value->type, reg);
 #endif
+
        if(value->in_register && value->reg == reg)
        {
                /* The value is already in the register, but we may need to spill
@@ -2998,11 +2907,15 @@ _jit_regs_set_outgoing(jit_gencode_t gen, int reg, jit_value_t value)
        }
 }
 
+/* TODO: remove this function */
 /*@
  * @deftypefun void _jit_regs_force_out (jit_gencode_t gen, jit_value_t value, int is_dest)
  * If @code{value} is currently in a register, then force its value out
  * into the stack frame.  The @code{is_dest} flag indicates that the value
  * will be a destination, so we don't care about the original value.
+ *
+ * This function is deprecated and going to be removed soon.
+ *
  * @end deftypefun
 @*/
 void _jit_regs_force_out(jit_gencode_t gen, jit_value_t value, int is_dest)
@@ -3011,16 +2924,7 @@ void _jit_regs_force_out(jit_gencode_t gen, jit_value_t value, int is_dest)
        if(value->in_register)
        {
                reg = value->reg;
-
-               /* Find the other register in a long pair */
-               if(_jit_regs_needs_long_pair(value->type))
-               {
-                       other_reg = jit_reg_other_reg(reg);
-               }
-               else
-               {
-                       other_reg = -1;
-               }
+               other_reg = jit_reg_get_pair(value->type, reg);
 
                if(is_dest)
                {
@@ -3033,6 +2937,7 @@ void _jit_regs_force_out(jit_gencode_t gen, jit_value_t value, int is_dest)
        }
 }
 
+/* TODO: remove this function */
 /*@
  * @deftypefun int _jit_regs_load_value (jit_gencode_t gen, jit_value_t value, int destroy, int used_again)
  * Load a value into any register that is suitable and return that register.
@@ -3045,12 +2950,15 @@ void _jit_regs_force_out(jit_gencode_t gen, jit_value_t value, int is_dest)
  *
  * If @code{used_again} is non-zero, then it indicates that the value is
  * used again further down the block.
+ *
+ * This function is deprecated and going to be removed soon.
+ *
  * @end deftypefun
 @*/
 int
 _jit_regs_load_value(jit_gencode_t gen, jit_value_t value, int destroy, int used_again)
 {
-       int type, need_pair;
+       int type;
        int reg, other_reg;
        int spill_cost;
        int suitable_reg, suitable_other_reg;
@@ -3065,30 +2973,46 @@ _jit_regs_load_value(jit_gencode_t gen, jit_value_t value, int destroy, int used
                return value->global_reg;
        }
 
-       need_pair = _jit_regs_needs_long_pair(value->type);
-
        /* If the value is already in a register, then try to use that register */
        if(value->in_register && (!destroy || !used_again))
        {
                reg = value->reg;
                if(!used_again)
                {
-                       if(need_pair)
-                       {
-                               other_reg = jit_reg_other_reg(reg);
-                       }
-                       else
-                       {
-                               other_reg = -1;
-                       }
+                       other_reg = jit_reg_get_pair(value->type, reg);
                        free_value(gen, value, reg, other_reg, 1);
                }
                return reg;
        }
 
-       type = get_register_type(value, need_pair);
-       if(!type)
+       switch(jit_type_normalize(value->type)->kind)
        {
+       case JIT_TYPE_SBYTE:
+       case JIT_TYPE_UBYTE:
+       case JIT_TYPE_SHORT:
+       case JIT_TYPE_USHORT:
+       case JIT_TYPE_INT:
+       case JIT_TYPE_UINT:
+       case JIT_TYPE_NINT:
+       case JIT_TYPE_NUINT:
+       case JIT_TYPE_SIGNATURE:
+       case JIT_TYPE_PTR:
+               type = JIT_REG_WORD;
+               break;
+       case JIT_TYPE_LONG:
+       case JIT_TYPE_ULONG:
+               type = JIT_REG_LONG;
+               break;
+       case JIT_TYPE_FLOAT32:
+               type = JIT_REG_FLOAT32;
+               break;
+       case JIT_TYPE_FLOAT64:
+               type = JIT_REG_FLOAT64;
+               break;
+       case JIT_TYPE_NFLOAT:
+               type = JIT_REG_NFLOAT;
+               break;
+       default:
                return 0;
        }
 
@@ -3111,9 +3035,9 @@ _jit_regs_load_value(jit_gencode_t gen, jit_value_t value, int destroy, int used
                        continue;
                }
 
-               if(need_pair)
+               other_reg = jit_reg_get_pair(value->type, reg);
+               if(other_reg >= 0)
                {
-                       other_reg = jit_reg_other_reg(reg);
                        if(jit_reg_is_used(gen->inhibit, other_reg))
                        {
                                continue;
@@ -3123,10 +3047,6 @@ _jit_regs_load_value(jit_gencode_t gen, jit_value_t value, int destroy, int used
                                continue;
                        }
                }
-               else
-               {
-                       other_reg = -1;
-               }
 
                spill_cost = compute_spill_cost(gen, 0, reg, other_reg);
 
index 416e227dc51bf5f8e7af30fca8c4ee2ed5c67217..483b5c68fa44441062d63f732f4706f5f9ea4afc 100644 (file)
@@ -141,8 +141,6 @@ typedef struct
 } _jit_regs_t;
 
 int _jit_regs_lookup(char *name);
-int _jit_regs_needs_long_pair(jit_type_t type);
-
 void _jit_regs_alloc_global(jit_gencode_t gen, jit_function_t func);
 void _jit_regs_init_for_block(jit_gencode_t gen);
 void _jit_regs_spill_all(jit_gencode_t gen);
index 2461f61aad0efefa8accd9ab7ac5f995833bd3b8..b1e9654a01c256b3d8991e3d26f99381375eded9 100644 (file)
@@ -1407,4 +1407,26 @@ void _jit_gen_return_to_float(jit_gencode_t gen, jit_value_t value, int reg)
        }
 }
 
+
+int
+_jit_reg_get_pair(jit_type_t type, int reg)
+{
+       type = jit_type_normalize(type);
+       if(type)
+       {
+               if(type->kind == JIT_TYPE_LONG || type->kind == JIT_TYPE_ULONG)
+               {
+                       return jit_reg_other_reg(reg);
+               }
+               else if(type->kind == JIT_TYPE_FLOAT64 || type->kind == JIT_TYPE_NFLOAT)
+               {
+                       if(reg == JIT_REG_R0)
+                       {
+                               return jit_reg_other_reg(reg);
+                       }
+               }
+       }
+       return -1;
+}
+
 #endif /* JIT_BACKEND_ARM */
index 683f579534feacee34b108d1090f9a460fcd1378..24a4b292785d0c3742a9020b81d4051de571f2b0 100644 (file)
@@ -1643,4 +1643,19 @@ int _jit_gen_is_global_candidate(jit_type_t type)
        return 0;
 }
 
+/*@
+ * @deftypefun int _jit_reg_get_pair (jit_type_t @var{type}, int @var{reg})
+ * Determine if a type requires a register pair. If so then for the specified
+ * register @var{reg} return the other register of the corresponding pair.
+ * Return -1 if no pair is required.
+ *
+ * This function is used only for native 32-bit backends.
+ * @end deftypefun
+@*/
+int _jit_reg_get_pair(jit_type_t type, int reg)
+{
+       /* We don't register pairs on 64-bit platforms or the interpreter */
+       return -1;
+}
+
 #endif /* JIT_BACKEND_INTERP */
index a79e3bf6b653f095aff272d7c57bde8c61229191..abac940faa747db086382977f6631039c7112ee4 100644 (file)
@@ -1522,4 +1522,18 @@ int _jit_gen_is_global_candidate(jit_type_t type)
        return 0;
 }
 
+int
+_jit_reg_get_pair(jit_type_t type, int reg)
+{
+       type = jit_type_normalize(type);
+       if(type)
+       {
+               if(type->kind == JIT_TYPE_LONG || type->kind == JIT_TYPE_ULONG)
+               {
+                       return jit_reg_other_reg(reg);
+               }
+       }
+       return -1;
+}
+
 #endif /* JIT_BACKEND_X86 */
index 3ca8ef97bf186f458ff6c2809494e983957db78b..3093cdd5cb29f8b4952d1a8d87abec4524572678 100644 (file)
@@ -110,10 +110,30 @@ typedef struct
 extern jit_reginfo_t const _jit_reg_info[JIT_NUM_REGS];
 
 /*
- * Given the first register of a long pair get the other register.
+ * Macros for getting register information
  */
+
+/* Get register name. */
+#define jit_reg_name(reg)              (_jit_reg_info[reg].name)
+
+/* Get register flags. */
+#define jit_reg_flags(reg)             (_jit_reg_info[reg].flags)
+
+/* Get CPU register number for machine instruction encoding. */
+#define jit_reg_code(reg)              (_jit_reg_info[reg].cpu_reg)
+
+/* Given the first register of a register pair get the other one. */
 #define jit_reg_other_reg(reg)         (_jit_reg_info[reg].other_reg)
 
+/* Given a register find if a value of the specified type requires
+ * a register pair. Return the other register of the pair if it is
+ * required and return -1 otherwise. */
+#if defined(JIT_NATIVE_INT32) && !defined(JIT_BACKEND_INTERP)
+# define jit_reg_get_pair(type,reg)    _jit_reg_get_pair(type, reg)
+#else
+# define jit_reg_get_pair(type,reg)    (-1)
+#endif
+
 /*
  * Manipulate register usage masks.  The backend may override these
  * definitions if it has more registers than can fit in a "jit_uint".
@@ -196,6 +216,7 @@ struct jit_elf_info
 /*
  * External function defintions.
  */
+
 void _jit_init_backend(void);
 void _jit_gen_get_elf_info(jit_elf_info_t *info);
 int _jit_create_entry_insns(jit_function_t func);
@@ -230,6 +251,10 @@ void _jit_gen_start_block(jit_gencode_t gen, jit_block_t block);
 void _jit_gen_end_block(jit_gencode_t gen, jit_block_t block);
 int _jit_gen_is_global_candidate(jit_type_t type);
 
+#if defined(JIT_NATIVE_INT32) && !defined(JIT_BACKEND_INTERP)
+int _jit_reg_get_pair(jit_type_t type, int reg);
+#endif
+
 /*
  * Determine the byte number within a "jit_int" where the low
  * order byte can be found.