]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
Move the code for loading/storing small structures into a central location.
authorRhys Weatherley <rweather@southern-storm.com.au>
Mon, 21 Jun 2004 02:09:44 +0000 (02:09 +0000)
committerRhys Weatherley <rweather@southern-storm.com.au>
Mon, 21 Jun 2004 02:09:44 +0000 (02:09 +0000)
ChangeLog
jit/jit-rules-x86.c
jit/jit-rules-x86.sel

index 9fb4eca6d567073f30a199abf11bb82aac36d62e..9b9cc5c926b1d741064fd0f8f1556666aa4cebf9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,9 @@
 
+2004-06-21  Rhys Weatherley  <rweather@southern-storm.com.au>
+
+       * jit/jit-rules-x86.c, jit/jit-rules-x86.sel: move the code
+       for loading/storing small structures into a central location.
+
 2004-06-18  Rhys Weatherley  <rweather@southern-storm.com.au>
 
        * jit/jit-dump.c, jit/jit-reg-alloc.c, jit/jit-rules-arm.c,
index 76c60e8a34084161750496032a0c04b0dc4a9db5..a814c66e982818d9a754347fb83451b9e59438bd 100644 (file)
@@ -400,6 +400,281 @@ void *_jit_gen_redirector(jit_gencode_t gen, jit_function_t func)
 #define        jit_cache_end_output()  \
        gen->posn.ptr = inst
 
+/*
+ * Get a temporary register that isn't one of the specified registers.
+ */
+static int get_temp_reg(int reg1, int reg2, int reg3)
+{
+       if(reg1 != X86_EAX && reg2 != X86_EAX && reg3 != X86_EAX)
+       {
+               return X86_EAX;
+       }
+       if(reg1 != X86_EDX && reg2 != X86_EDX && reg3 != X86_EDX)
+       {
+               return X86_EDX;
+       }
+       if(reg1 != X86_ECX && reg2 != X86_ECX && reg3 != X86_ECX)
+       {
+               return X86_ECX;
+       }
+       if(reg1 != X86_EBX && reg2 != X86_EBX && reg3 != X86_EBX)
+       {
+               return X86_EBX;
+       }
+       if(reg1 != X86_ESI && reg2 != X86_ESI && reg3 != X86_ESI)
+       {
+               return X86_ESI;
+       }
+       return X86_EDI;
+}
+
+/*
+ * Load a small structure from a pointer into registers.
+ */
+static unsigned char *load_small_struct
+       (unsigned char *inst, int reg, int other_reg,
+        int base_reg, jit_nint offset, jit_nint size, int save_temp)
+{
+       int temp_reg;
+       switch(size)
+       {
+               case 1:
+               {
+                       x86_widen_membase(inst, reg, base_reg, offset, 0, 0);
+               }
+               break;
+
+               case 2:
+               {
+                       x86_widen_membase(inst, reg, base_reg, offset, 0, 1);
+               }
+               break;
+
+               case 3:
+               {
+                       temp_reg = get_temp_reg(reg, -1, base_reg);
+                       if(save_temp || temp_reg >= X86_EBX)
+                       {
+                               x86_push_reg(inst, temp_reg);
+                       }
+                       x86_widen_membase(inst, temp_reg, base_reg, offset, 0, 1);
+                       x86_widen_membase(inst, reg, base_reg, offset + 2, 0, 0);
+                       x86_shift_reg_imm(inst, X86_SHL, reg, 16);
+                       x86_alu_reg_reg(inst, X86_OR, reg, temp_reg);
+                       if(save_temp || temp_reg >= X86_EBX)
+                       {
+                               x86_pop_reg(inst, temp_reg);
+                       }
+               }
+               break;
+
+               case 4:
+               {
+                       x86_mov_reg_membase(inst, reg, base_reg, offset, 4);
+               }
+               break;
+
+               case 5:
+               {
+                       if(reg != base_reg)
+                       {
+                               x86_mov_reg_membase(inst, reg, base_reg, offset, 4);
+                               x86_widen_membase(inst, other_reg, base_reg, offset + 4, 0, 0);
+                       }
+                       else
+                       {
+                               x86_widen_membase(inst, other_reg, base_reg, offset + 4, 0, 0);
+                               x86_mov_reg_membase(inst, reg, base_reg, offset, 4);
+                       }
+               }
+               break;
+
+               case 6:
+               {
+                       if(reg != base_reg)
+                       {
+                               x86_mov_reg_membase(inst, reg, base_reg, offset, 4);
+                               x86_widen_membase(inst, other_reg, base_reg, offset + 4, 0, 1);
+                       }
+                       else
+                       {
+                               x86_widen_membase(inst, other_reg, base_reg, offset + 4, 0, 1);
+                               x86_mov_reg_membase(inst, reg, base_reg, offset, 4);
+                       }
+               }
+               break;
+
+               case 7:
+               {
+                       temp_reg = get_temp_reg(reg, other_reg, base_reg);
+                       if(save_temp || temp_reg >= X86_EBX)
+                       {
+                               x86_push_reg(inst, temp_reg);
+                       }
+                       if(reg != base_reg && other_reg != base_reg)
+                       {
+                               x86_mov_reg_membase(inst, reg, base_reg, offset, 4);
+                               x86_widen_membase(inst, other_reg, base_reg, offset + 4, 0, 1);
+                               x86_widen_membase(inst, temp_reg, base_reg, offset + 6, 0, 0);
+                               x86_shift_reg_imm(inst, X86_SHL, temp_reg, 16);
+                               x86_alu_reg_reg(inst, X86_OR, other_reg, temp_reg);
+                       }
+                       else if(reg != base_reg)
+                       {
+                               /* other_reg == base_reg */
+                               x86_mov_reg_membase(inst, reg, base_reg, offset, 4);
+                               x86_widen_membase(inst, temp_reg, base_reg, offset + 6, 0, 0);
+                               x86_widen_membase(inst, other_reg, base_reg, offset + 4, 0, 1);
+                               x86_shift_reg_imm(inst, X86_SHL, temp_reg, 16);
+                               x86_alu_reg_reg(inst, X86_OR, other_reg, temp_reg);
+                       }
+                       else
+                       {
+                               /* reg == base_reg */
+                               x86_widen_membase(inst, other_reg, base_reg, offset + 4, 0, 1);
+                               x86_widen_membase(inst, temp_reg, base_reg, offset + 6, 0, 0);
+                               x86_shift_reg_imm(inst, X86_SHL, temp_reg, 16);
+                               x86_alu_reg_reg(inst, X86_OR, other_reg, temp_reg);
+                               x86_mov_reg_membase(inst, reg, base_reg, offset, 4);
+                       }
+                       if(save_temp || temp_reg >= X86_EBX)
+                       {
+                               x86_pop_reg(inst, temp_reg);
+                       }
+               }
+               break;
+
+               case 8:
+               {
+                       if(reg != base_reg)
+                       {
+                               x86_mov_reg_membase(inst, reg, base_reg, offset, 4);
+                               x86_mov_reg_membase(inst, other_reg, base_reg, offset + 4, 4);
+                       }
+                       else
+                       {
+                               x86_mov_reg_membase(inst, other_reg, base_reg, offset + 4, 4);
+                               x86_mov_reg_membase(inst, reg, base_reg, offset, 4);
+                       }
+               }
+               break;
+       }
+       return inst;
+}
+
+/*
+ * Store a byte value to a membase address.
+ */
+static unsigned char *mov_membase_reg_byte
+                       (unsigned char *inst, int basereg, int offset, int srcreg)
+{
+       if(srcreg == X86_EAX || srcreg == X86_EBX ||
+          srcreg == X86_ECX || srcreg == X86_EDX)
+       {
+               x86_mov_membase_reg(inst, basereg, offset, srcreg, 1);
+       }
+       else if(basereg != X86_EAX)
+       {
+               x86_push_reg(inst, X86_EAX);
+               x86_mov_reg_reg(inst, X86_EAX, srcreg, 4);
+               x86_mov_membase_reg(inst, basereg, offset, X86_EAX, 1);
+               x86_pop_reg(inst, X86_EAX);
+       }
+       else
+       {
+               x86_push_reg(inst, X86_EDX);
+               x86_mov_reg_reg(inst, X86_EDX, srcreg, 4);
+               x86_mov_membase_reg(inst, basereg, offset, X86_EDX, 1);
+               x86_pop_reg(inst, X86_EDX);
+       }
+       return inst;
+}
+
+/*
+ * Store a small structure from registers to a pointer.  The base
+ * register must not be either "reg" or "other_reg".
+ */
+static unsigned char *store_small_struct
+       (unsigned char *inst, int reg, int other_reg,
+        int base_reg, jit_nint offset, jit_nint size, int preserve)
+{
+       switch(size)
+       {
+               case 1:
+               {
+                       inst = mov_membase_reg_byte(inst, base_reg, offset, reg);
+               }
+               break;
+
+               case 2:
+               {
+                       x86_mov_membase_reg(inst, base_reg, offset, reg, 2);
+               }
+               break;
+
+               case 3:
+               {
+                       if(preserve)
+                       {
+                               x86_push_reg(inst, reg);
+                       }
+                       x86_mov_membase_reg(inst, base_reg, offset, reg, 2);
+                       x86_shift_reg_imm(inst, reg, X86_SHR, 16);
+                       inst = mov_membase_reg_byte(inst, base_reg, offset + 2, reg);
+                       if(preserve)
+                       {
+                               x86_pop_reg(inst, reg);
+                       }
+               }
+               break;
+
+               case 4:
+               {
+                       x86_mov_membase_reg(inst, base_reg, offset, reg, 4);
+               }
+               break;
+
+               case 5:
+               {
+                       x86_mov_membase_reg(inst, base_reg, offset, reg, 4);
+                       inst = mov_membase_reg_byte(inst, base_reg, offset + 4, other_reg);
+               }
+               break;
+
+               case 6:
+               {
+                       x86_mov_membase_reg(inst, base_reg, offset, reg, 4);
+                       x86_mov_membase_reg(inst, base_reg, offset + 4, other_reg, 2);
+               }
+               break;
+
+               case 7:
+               {
+                       if(preserve)
+                       {
+                               x86_push_reg(inst, other_reg);
+                       }
+                       x86_mov_membase_reg(inst, base_reg, offset, reg, 4);
+                       x86_mov_membase_reg(inst, base_reg, offset + 4, other_reg, 2);
+                       x86_shift_reg_imm(inst, other_reg, X86_SHR, 16);
+                       inst = mov_membase_reg_byte(inst, base_reg, offset + 6, other_reg);
+                       if(preserve)
+                       {
+                               x86_pop_reg(inst, other_reg);
+                       }
+               }
+               break;
+
+               case 8:
+               {
+                       x86_mov_membase_reg(inst, base_reg, offset, reg, 4);
+                       x86_mov_membase_reg(inst, base_reg, offset + 4, other_reg, 4);
+               }
+               break;
+       }
+       return inst;
+}
+
 void _jit_gen_spill_reg(jit_gencode_t gen, int reg,
                                                int other_reg, jit_value_t value)
 {
@@ -935,34 +1210,6 @@ static unsigned char *jump_to_epilog
        return inst;
 }
 
-/*
- * Store a byte value to a membase address.
- */
-static unsigned char *mov_membase_reg_byte
-                       (unsigned char *inst, int basereg, int offset, int srcreg)
-{
-       if(srcreg == X86_EAX || srcreg == X86_EBX ||
-          srcreg == X86_ECX || srcreg == X86_EDX)
-       {
-               x86_mov_membase_reg(inst, basereg, offset, srcreg, 1);
-       }
-       else if(basereg != X86_EAX)
-       {
-               x86_push_reg(inst, X86_EAX);
-               x86_mov_reg_reg(inst, X86_EAX, srcreg, 4);
-               x86_mov_membase_reg(inst, basereg, offset, X86_EAX, 1);
-               x86_pop_reg(inst, X86_EAX);
-       }
-       else
-       {
-               x86_push_reg(inst, X86_EDX);
-               x86_mov_reg_reg(inst, X86_EDX, srcreg, 4);
-               x86_mov_membase_reg(inst, basereg, offset, X86_EDX, 1);
-               x86_pop_reg(inst, X86_EDX);
-       }
-       return inst;
-}
-
 /*
  * Store a byte value to a memindex address.
  */
index 225d0d6e7b86daaf0687c32dfb792ab15062e7ae..734cf211cae7a64783b49e791ce8bad46379da26 100644 (file)
@@ -1706,107 +1706,9 @@ JIT_OP_RETURN_NFLOAT: unary_branch, stack, only
 
 JIT_OP_RETURN_SMALL_STRUCT: unary_branch
        [reg] -> {
-               int reg = $1;
-               switch(jit_value_get_nint_constant(insn->value2))
-               {
-                       case 1:
-                       {
-                               x86_widen_membase(inst, X86_EAX, reg, 0, 0, 0);
-                       }
-                       break;
-
-                       case 2:
-                       {
-                               x86_widen_membase(inst, X86_EAX, reg, 0, 0, 1);
-                               x86_mov_reg_membase(inst, X86_EAX, reg, 0, 2);
-                       }
-                       break;
-
-                       case 3:
-                       {
-                               if(reg != X86_EAX)
-                               {
-                                       x86_widen_membase(inst, X86_EAX, reg, 0, 0, 1);
-                                       x86_widen_membase(inst, reg, reg, 2, 0, 0);
-                                       x86_shift_reg_imm(inst, X86_SHL, reg, 16);
-                                       x86_alu_reg_reg(inst, X86_OR, X86_EAX, reg);
-                               }
-                               else
-                               {
-                                       x86_widen_membase(inst, X86_ECX, reg, 0, 0, 1);
-                                       x86_widen_membase(inst, X86_EAX, reg, 2, 0, 0);
-                                       x86_shift_reg_imm(inst, X86_SHL, X86_EAX, 16);
-                                       x86_alu_reg_reg(inst, X86_OR, X86_EAX, X86_ECX);
-                               }
-                       }
-                       break;
-
-                       case 4:
-                       {
-                               x86_mov_reg_membase(inst, X86_EAX, reg, 0, 4);
-                       }
-                       break;
-
-                       case 5:
-                       {
-                               if(reg != X86_EAX)
-                               {
-                                       x86_mov_reg_membase(inst, X86_EAX, reg, 0, 4);
-                                       x86_widen_membase(inst, X86_EDX, reg, 4, 0, 0);
-                               }
-                               else
-                               {
-                                       x86_widen_membase(inst, X86_EDX, reg, 4, 0, 0);
-                                       x86_mov_reg_membase(inst, X86_EAX, reg, 0, 4);
-                               }
-                       }
-                       break;
-
-                       case 6:
-                       {
-                               if(reg != X86_EAX)
-                               {
-                                       x86_mov_reg_membase(inst, X86_EAX, reg, 0, 4);
-                                       x86_widen_membase(inst, X86_EDX, reg, 4, 0, 1);
-                               }
-                               else
-                               {
-                                       x86_widen_membase(inst, X86_EDX, reg, 4, 0, 1);
-                                       x86_mov_reg_membase(inst, X86_EAX, reg, 0, 4);
-                               }
-                       }
-                       break;
-
-                       case 7:
-                       {
-                               if(reg == X86_EAX || reg == X86_EDX)
-                               {
-                                       x86_mov_reg_reg(inst, X86_ECX, reg, 4);
-                                       reg = X86_ECX;
-                               }
-                               x86_mov_reg_membase(inst, X86_EAX, reg, 0, 4);
-                               x86_widen_membase(inst, X86_EDX, reg, 4, 0, 1);
-                               x86_widen_membase(inst, X86_ECX, reg, 6, 0, 0);
-                               x86_shift_reg_imm(inst, X86_SHL, X86_ECX, 16);
-                               x86_alu_reg_reg(inst, X86_OR, X86_EAX, X86_ECX);
-                       }
-                       break;
-
-                       case 8:
-                       {
-                               if(reg != X86_EAX)
-                               {
-                                       x86_mov_reg_membase(inst, X86_EAX, reg, 0, 4);
-                                       x86_mov_reg_membase(inst, X86_EDX, reg, 4, 4);
-                               }
-                               else
-                               {
-                                       x86_mov_reg_membase(inst, X86_EDX, reg, 4, 4);
-                                       x86_mov_reg_membase(inst, X86_EAX, reg, 0, 4);
-                               }
-                       }
-                       break;
-               }
+               inst = load_small_struct
+                       (inst, X86_EAX, X86_EDX, $1, 0,
+                        jit_value_get_nint_constant(insn->value2), 0);
                inst = jump_to_epilog(gen, inst, block);
        }
 
@@ -2256,64 +2158,8 @@ JIT_OP_FLUSH_SMALL_STRUCT:
                _jit_gen_fix_value(insn->value1);
                size = jit_type_get_size(jit_value_get_type(insn->value1));
                offset = insn->value1->frame_offset;
-               switch(size)
-               {
-                       case 1:
-                       {
-                               x86_mov_membase_reg(inst, X86_EBP, offset, X86_EAX, 1);
-                       }
-                       break;
-
-                       case 2:
-                       {
-                               x86_mov_membase_reg(inst, X86_EBP, offset, X86_EAX, 2);
-                       }
-                       break;
-
-                       case 3:
-                       {
-                               x86_mov_membase_reg(inst, X86_EBP, offset, X86_EAX, 2);
-                               x86_shift_reg_imm(inst, X86_EAX, X86_SHR, 16);
-                               x86_mov_membase_reg(inst, X86_EBP, offset + 2, X86_EAX, 1);
-                       }
-                       break;
-
-                       case 4:
-                       {
-                               x86_mov_membase_reg(inst, X86_EBP, offset, X86_EAX, 4);
-                       }
-                       break;
-
-                       case 5:
-                       {
-                               x86_mov_membase_reg(inst, X86_EBP, offset, X86_EAX, 4);
-                               x86_mov_membase_reg(inst, X86_EBP, offset + 4, X86_EDX, 1);
-                       }
-                       break;
-
-                       case 6:
-                       {
-                               x86_mov_membase_reg(inst, X86_EBP, offset, X86_EAX, 4);
-                               x86_mov_membase_reg(inst, X86_EBP, offset + 4, X86_EDX, 2);
-                       }
-                       break;
-
-                       case 7:
-                       {
-                               x86_mov_membase_reg(inst, X86_EBP, offset, X86_EAX, 4);
-                               x86_mov_membase_reg(inst, X86_EBP, offset + 4, X86_EDX, 2);
-                               x86_shift_reg_imm(inst, X86_EDX, X86_SHR, 16);
-                               x86_mov_membase_reg(inst, X86_EBP, offset + 6, X86_EDX, 1);
-                       }
-                       break;
-
-                       case 8:
-                       {
-                               x86_mov_membase_reg(inst, X86_EBP, offset, X86_EAX, 4);
-                               x86_mov_membase_reg(inst, X86_EBP, offset + 4, X86_EDX, 4);
-                       }
-                       break;
-               }
+               inst = store_small_struct
+                       (inst, X86_EAX, X86_EDX, X86_EBP, offset, (jit_nint)size, 0);
        }
 
 /*