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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[dotgnu-pnet-commits] libjit ./ChangeLog include/jit/jit-opcode.h inc...


From: Aleksey Demakov
Subject: [dotgnu-pnet-commits] libjit ./ChangeLog include/jit/jit-opcode.h inc...
Date: Tue, 10 Jan 2006 21:24:43 +0000

CVSROOT:        /sources/dotgnu-pnet
Module name:    libjit
Branch:         
Changes by:     Aleksey Demakov <address@hidden>        06/01/10 21:24:43

Modified files:
        .              : ChangeLog 
        include/jit    : jit-opcode.h jit-insn.h 
        jit            : jit-insn.c jit-rules-x86.sel 

Log message:
        added jit_insn_jump_table

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/libjit/ChangeLog.diff?tr1=1.189&tr2=1.190&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/libjit/include/jit/jit-opcode.h.diff?tr1=1.12&tr2=1.13&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/libjit/include/jit/jit-insn.h.diff?tr1=1.14&tr2=1.15&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/libjit/jit/jit-insn.c.diff?tr1=1.38&tr2=1.39&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/libjit/jit/jit-rules-x86.sel.diff?tr1=1.37&tr2=1.38&r1=text&r2=text

Patches:
Index: libjit/ChangeLog
diff -u libjit/ChangeLog:1.189 libjit/ChangeLog:1.190
--- libjit/ChangeLog:1.189      Tue Jan 10 21:03:44 2006
+++ libjit/ChangeLog    Tue Jan 10 21:24:42 2006
@@ -5,6 +5,10 @@
        * jit/jit-internal.h, jit/jit-function.c, jiy/jit-rules-x86.c:
        add fixup_absolute_list field to _jit_block struct for fixing up
        absolute address references to a block.
+       * include/jit/jit-opcode.h (JIT_OP_JUMP_TABLE),
+       * jit/jit-rules-x86.sel (JIT_OP_JUMP_TABLE),
+       * include/jit/jit-insn.h, jit/jit-insn.c (jit_insn_jump_table):
+       add new opcode.
 
 2006-01-08  Aleksey Demakov  <address@hidden>
 
Index: libjit/include/jit/jit-insn.h
diff -u libjit/include/jit/jit-insn.h:1.14 libjit/include/jit/jit-insn.h:1.15
--- libjit/include/jit/jit-insn.h:1.14  Mon Oct  4 02:26:41 2004
+++ libjit/include/jit/jit-insn.h       Tue Jan 10 21:24:42 2006
@@ -209,6 +209,9 @@
        (jit_function_t func, jit_value_t value, jit_label_t *label) 
JIT_NOTHROW;
 int jit_insn_branch_if_not
        (jit_function_t func, jit_value_t value, jit_label_t *label) 
JIT_NOTHROW;
+int jit_insn_jump_table
+       (jit_function_t func, jit_value_t value,
+        jit_label_t *labels, unsigned int num_labels) JIT_NOTHROW;
 jit_value_t jit_insn_address_of
        (jit_function_t func, jit_value_t value1) JIT_NOTHROW;
 jit_value_t jit_insn_address_of_label
Index: libjit/include/jit/jit-opcode.h
diff -u libjit/include/jit/jit-opcode.h:1.12 
libjit/include/jit/jit-opcode.h:1.13
--- libjit/include/jit/jit-opcode.h:1.12        Thu Nov 18 01:41:54 2004
+++ libjit/include/jit/jit-opcode.h     Tue Jan 10 21:24:42 2006
@@ -521,9 +521,14 @@
 #define        JIT_OP_MARK_BREAKPOINT                          0x01A4
 
 /*
+ * Switch statement support.
+ */
+#define JIT_OP_JUMP_TABLE                                      0x01A5
+
+/*
  * The number of opcodes in the above list.
  */
-#define        JIT_OP_NUM_OPCODES                                      0x01A5
+#define        JIT_OP_NUM_OPCODES                                      0x01A6
 
 /*
  * Opcode information.
Index: libjit/jit/jit-insn.c
diff -u libjit/jit/jit-insn.c:1.38 libjit/jit/jit-insn.c:1.39
--- libjit/jit/jit-insn.c:1.38  Thu Dec 15 18:10:10 2005
+++ libjit/jit/jit-insn.c       Tue Jan 10 21:24:43 2006
@@ -3941,6 +3941,106 @@
 }
 
 /*@
+ * @deftypefun jit_insn_jump_table(jit_function_t func, jit_value_t value, 
jit_label_t *labels, unsigned int num_labels)
+ *
+ * @end deftypefun
address@hidden/
+int jit_insn_jump_table
+       (jit_function_t func, jit_value_t value,
+        jit_label_t *labels, unsigned int num_labels)
+{
+       jit_insn_t insn;
+       unsigned int index;
+       jit_label_t *new_labels;
+       jit_value_t value_labels;
+       jit_value_t value_num_labels;
+
+       /* Bail out if the parameters are invalid */
+       if(!value || !labels || !num_labels)
+       {
+               return 0;
+       }
+
+       /* Ensure that we have a function builder */
+       if(!_jit_function_ensure_builder(func))
+       {
+               return 0;
+       }
+
+       /* Flush any stack pops that were deferred previously */
+       if(!jit_insn_flush_defer_pop(func, 0))
+       {
+               return 0;
+       }
+
+       /* Allocate new label identifiers, if necessary */
+       for(index = 0; index < num_labels; index++)
+       {
+               if(labels[index] == jit_label_undefined)
+               {
+                       labels[index] = (func->builder->next_label)++;
+               }
+       }
+
+       /* If the condition is constant, then convert it into either
+          an unconditional branch or a fall-through, as appropriate */
+       if(jit_value_is_constant(value))
+       {
+               index = jit_value_get_nint_constant(value);
+               if(index < num_labels && index >= 0)
+               {
+                       return jit_insn_branch(func, &labels[index]);
+               }
+               else
+               {
+                       return 1;
+               }
+       }
+
+       new_labels = jit_malloc(num_labels * sizeof(jit_label_t));
+       if(!new_labels)
+       {
+               return 0;
+       }
+       for(index = 0; index < num_labels; index++)
+       {
+               new_labels[index] = labels[index];
+       }
+
+       value_labels = jit_value_create_nint_constant(func, jit_type_void_ptr, 
(jit_nint) new_labels);
+       if(!value_labels)
+       {
+               jit_free(new_labels);
+               return 0;
+       }
+       value_labels->free_address = 1;
+
+       value_num_labels = jit_value_create_nint_constant(func, jit_type_uint, 
num_labels);
+       if(!value_num_labels)
+       {
+               _jit_value_free(value_labels);
+               return 0;
+       }
+
+       /* Add a new branch instruction */
+       insn = _jit_block_add_insn(func->builder->current_block);
+       if(!insn)
+       {
+               return 0;
+       }
+       jit_value_ref(func, value);
+
+       insn->opcode = JIT_OP_JUMP_TABLE;
+       insn->flags = JIT_INSN_DEST_IS_VALUE;
+       insn->dest = value;
+       insn->value1 = value_labels;
+       insn->value2 = value_num_labels;
+
+       /* Add a new block for the fall-through case */
+       return jit_insn_new_block(func);
+}
+
+/*@
  * @deftypefun jit_value_t jit_insn_address_of (jit_function_t func, 
jit_value_t value1)
  * Get the address of a value into a new temporary.
  * @end deftypefun
Index: libjit/jit/jit-rules-x86.sel
diff -u libjit/jit/jit-rules-x86.sel:1.37 libjit/jit/jit-rules-x86.sel:1.38
--- libjit/jit/jit-rules-x86.sel:1.37   Wed Dec 28 14:11:38 2005
+++ libjit/jit/jit-rules-x86.sel        Tue Jan 10 21:24:43 2006
@@ -3125,6 +3125,9 @@
                        reg3 = _jit_regs_load_value
                                (gen, insn->value2, 0,
                                 (insn->flags & (JIT_INSN_VALUE2_NEXT_USE | 
JIT_INSN_VALUE2_LIVE)));
+
+                       /* A function call may destroy EAX,EBX,ECX,EDX 
registers. */
+                       /* TODO: do not spill ESI and EDI. */
                        _jit_regs_spill_all(gen);
 
                        inst = gen->posn.ptr;
@@ -3374,3 +3377,69 @@
                x86_mov_reg_reg(inst, $1, X86_ESP, 4);
                gen->stack_changed = 1;
        }
+
+JIT_OP_JUMP_TABLE: manual
+       [] -> {
+               unsigned char *inst;
+               unsigned char *patch_jump_table;
+               unsigned char *patch_fall_through;
+               int reg;
+               int index;
+               jit_label_t *labels;
+               jit_nint num_labels;
+               jit_block_t block;
+               int address;
+
+               reg = _jit_regs_load_value
+                       (gen, insn->dest, 0,
+                        (insn->flags & (JIT_INSN_DEST_NEXT_USE | 
JIT_INSN_DEST_LIVE)));
+               _jit_regs_spill_all(gen);
+
+               labels = (jit_label_t *) insn->value1->address;
+               num_labels = insn->value2->address;
+
+               inst = gen->posn.ptr;
+               if(!jit_cache_check_for_n(&(gen->posn), 32 + sizeof(void) * 
num_labels))
+               {
+                       jit_cache_mark_full(&(gen->posn));
+                       return;
+               }
+
+               x86_alu_reg_imm(inst, X86_CMP, reg, num_labels);
+               patch_fall_through = inst;
+               x86_branch32(inst, X86_CC_GE, 0, 1);
+
+               patch_jump_table = inst;
+               x86_jump_memindex(inst, X86_NOBASEREG, 0, reg, 2);
+               while(((jit_nint) inst & (sizeof(void*) - 1)) != 0)
+               {
+                       x86_nop(inst);
+               }
+
+               // displacement goes after opcode. ModR/M, and SIB bytes
+               *((void **)(patch_jump_table + 3)) = inst;
+
+               for(index = 0; index < num_labels; index++)
+               {
+                       block = jit_block_from_label(func, labels[index]);
+                       if(!block)
+                       {
+                               return;
+                       }
+
+                       if(block->address)
+                       {
+                               x86_imm_emit32(inst, address);
+                       }
+                       else
+                       {
+                               /* Output a placeholder and record on the 
block's fixup list */
+                               x86_imm_emit32(inst, 
(int)(block->fixup_absolute_list));
+                               block->fixup_absolute_list = (void *)(inst - 4);
+                       }
+               }
+
+               x86_patch(patch_fall_through, inst);
+
+               gen->posn.ptr = inst;
+       }




reply via email to

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