[Top][All Lists]
[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;
+ }
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [dotgnu-pnet-commits] libjit ./ChangeLog include/jit/jit-opcode.h inc...,
Aleksey Demakov <=