* 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.
+ * include/jit/jit-opcode.h, include/jit/jit-insn.h, jit/jit-insn.c
+ (jit_insn_jump_table), jit/jit-rules-x86.sel, jit/jit-rules-interp.c
+ (_jit_gen_insn), jit/jit-interp.c (_jit_run_function):
+ add JIT_OP_JUMP_TABLE opcode.
2006-01-08 Aleksey Demakov <ademakov@gmail.com>
}
VMBREAK;
+ VMCASE(JIT_OP_JUMP_TABLE):
+ {
+ if(VM_STK_INT0 < VM_NINT_ARG && VM_STK_INT0 >= 0)
+ {
+ pc = pc[2 + VM_STK_INT0];
+ VM_MODIFY_STACK(1);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2 + VM_NINT_ARG, 1);
+ }
+ }
+ VMBREAK;
+
/******************************************************************
* Comparison opcodes.
******************************************************************/
}
/* Not reached */
+ case JIT_OP_JUMP_TABLE:
+ {
+ jit_label_t *labels;
+ jit_nint num_labels;
+ jit_nint index;
+
+ labels = (jit_label_t *) insn->value1->address;
+ num_labels = insn->value2->address;
+
+ _jit_regs_spill_all(gen);
+ _jit_regs_load_to_top(gen,
+ insn->dest,
+ (insn->flags & (JIT_INSN_DEST_NEXT_USE |
+ JIT_INSN_DEST_LIVE)),
+ 0);
+
+ jit_cache_opcode(&(gen->posn), insn->opcode);
+ jit_cache_native(&(gen->posn), num_labels);
+ for(index = 0; index < num_labels; index++)
+ {
+ block = jit_block_from_label(func, labels[index]);
+ if(!block)
+ {
+ return;
+ }
+ if(block->address)
+ {
+ /* We already know the address of the block */
+ jit_cache_native(&(gen->posn), block->address);
+ }
+ else
+ {
+ /* Record this position on the block's fixup list */
+ pc = (void **)(gen->posn.ptr);
+ jit_cache_native(&(gen->posn), block->fixup_absolute_list);
+ block->fixup_absolute_list = pc;
+ }
+ }
+ }
+ break;
+
case JIT_OP_ADDRESS_OF_LABEL:
{
/* Get the address of a particular label */
}
block->fixup_list = 0;
+ fixup = (void **)(block->fixup_absolute_list);
+ while(fixup != 0)
+ {
+ next = (void **)(fixup[0]);
+ fixup[0] = (void *)(jit_nint)((void **)(block->address));
+ fixup = next;
+ }
+ block->fixup_absolute_list = 0;
+
/* If this is the exception catcher block, then we need to update
the exception cookie for the function to point to here */
if(block->label == block->func->builder->catcher_label &&