view release on metacpan or search on metacpan
libjit/configure.ac view on Meta::CPAN
dnl Check for computed goto support in the compiler.
AC_MSG_CHECKING(for computed goto support)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[
static void *labels[] = {&&label0, &&label1, &&label2};
unsigned char *pc = 0;
goto *labels[*pc];
label0: ;
label1: ;
label2: ;
]])], [AC_DEFINE(HAVE_COMPUTED_GOTO, 1, Define if you have support for computed gotos) compgoto=yes], [compgoto=no])
AC_MSG_RESULT($compgoto)
AC_MSG_CHECKING(for pic computed goto support)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[
static int labelOffsets[] =
{&&label0 - &&label0, &&label1 - &&label0, &&label2 - &&label0};
unsigned char *pc = 0;
goto *(&&label0 + labelOffsets[*pc]);
label0: ;
label1: ;
label2: ;
]])], [AC_DEFINE(HAVE_PIC_COMPUTED_GOTO, 1, Define if you have PIC support for computed gotos) piccompgoto=yes], [piccompgoto=no])
AC_MSG_RESULT($piccompgoto)
dnl Check for building on a multi os system
if test x$GCC = xyes ; then
multi_os_directory=`$CC -print-multi-os-directory`
case $multi_os_directory in
.) ;; # Avoid trailing /.
*) libdir=$libdir/$multi_os_directory ;;
esac
fi
libjit/configure.ac view on Meta::CPAN
include/jit/Makefile
include/jit/jit-defs.h
tools/Makefile
jit/Makefile
jitdynamic/Makefile
jitplus/Makefile
dpas/Makefile
tutorial/Makefile
tests/Makefile
doc/Makefile])
AC_OUTPUT
libjit/include/jit/jit-type.h view on Meta::CPAN
/*
* Special tag types.
*/
#define JIT_TYPETAG_NAME 10000
#define JIT_TYPETAG_STRUCT_NAME 10001
#define JIT_TYPETAG_UNION_NAME 10002
#define JIT_TYPETAG_ENUM_NAME 10003
#define JIT_TYPETAG_CONST 10004
#define JIT_TYPETAG_VOLATILE 10005
#define JIT_TYPETAG_REFERENCE 10006
#define JIT_TYPETAG_OUTPUT 10007
#define JIT_TYPETAG_RESTRICT 10008
#define JIT_TYPETAG_SYS_BOOL 10009
#define JIT_TYPETAG_SYS_CHAR 10010
#define JIT_TYPETAG_SYS_SCHAR 10011
#define JIT_TYPETAG_SYS_UCHAR 10012
#define JIT_TYPETAG_SYS_SHORT 10013
#define JIT_TYPETAG_SYS_USHORT 10014
#define JIT_TYPETAG_SYS_INT 10015
#define JIT_TYPETAG_SYS_UINT 10016
#define JIT_TYPETAG_SYS_LONG 10017
libjit/jit/jit-interp.c view on Meta::CPAN
#define alloca _alloca
#endif
#endif
#include "jit-setjmp.h"
#if defined(JIT_BACKEND_INTERP)
/*
* Determine what kind of interpreter dispatch to use.
*/
#ifdef HAVE_COMPUTED_GOTO
#if defined(PIC) && defined(HAVE_PIC_COMPUTED_GOTO)
#define JIT_INTERP_TOKEN_PIC 1
#elif defined(PIC)
#define JIT_INTERP_SWITCH 1
#else
#define JIT_INTERP_TOKEN 1
#endif
#else /* !HAVE_COMPUTED_GOTO */
#define JIT_INTERP_SWITCH 1
#endif /* !HAVE_COMPUTED_GOTO */
/*
* Modify the program counter and stack pointer.
*/
#define VM_MODIFY_PC_AND_STACK(pcmod,stkmod) \
do { \
pc += (jit_nint)(int)(pcmod); \
stacktop += (jit_nint)(int)(stkmod); \
} while (0)
#define VM_MODIFY_PC(pcmod) \
libjit/jit/jit-reg-alloc.c view on Meta::CPAN
#define COST_THRASH 100
#define COST_CLOBBER_GLOBAL 1000
#ifdef JIT_BACKEND_X86
# define ALLOW_CLOBBER_GLOBAL 1
#else
# define ALLOW_CLOBBER_GLOBAL 0
#endif
/* Value usage flags. */
#define VALUE_INPUT 1
#define VALUE_USED 2
#define VALUE_LIVE 4
#define VALUE_DEAD 8
/* Clobber flags. */
#define CLOBBER_NONE 0
#define CLOBBER_INPUT_VALUE 1
#define CLOBBER_REG 2
#define CLOBBER_OTHER_REG 4
#ifdef JIT_REG_DEBUG
#include <stdlib.h>
static void dump_regs(jit_gencode_t gen, const char *name)
{
int reg, index;
jit_value_t value;
libjit/jit/jit-reg-alloc.c view on Meta::CPAN
_jit_regdesc_t tdesc;
tdesc = *desc1;
*desc1 = *desc2;
*desc2 = tdesc;
}
/*
* Get value usage and liveness information. The accurate liveness data is
* only available for values used by the current instruction.
*
* VALUE_INPUT flag is set if the value is one of the instruction's inputs.
*
* VALUE_LIVE and VALUE_USED flags are set for input values only according
* to the liveness flags provided along with the instruction.
*
* VALUE_DEAD flag is set in two cases. First, it is always set for output
* values. Second, it is set for input values that are neither live nor used.
*
* These flags are used when spilling a register. In this case we generally
* do not know if the values in the register are used by the instruction. If
* the VALUE_INPUT flag is present then it is so and the value has to be held
* in the register for the instruction to succeed. If the VALUE_DEAD flag is
* present then there is no need to spill the value and it may be discarded.
* Otherwise the value must be spilled.
*
* The VALUE_LIVE and VALUE_USED flags may only be set for input values of
* the instruction. For other values these flags are not set even if they are
* perfectly alive. These flags are used as a hint for spill cost calculation.
*
* NOTE: The output value is considered to be dead because the instruction is
* just about to recompute it so there is no point to save it.
libjit/jit/jit-reg-alloc.c view on Meta::CPAN
flags |= VALUE_DEAD;
}
if(!regs)
{
return flags;
}
if(value == regs->descs[0].value)
{
if(regs->ternary)
{
flags |= VALUE_INPUT;
if(regs->descs[0].used)
{
flags |= VALUE_LIVE | VALUE_USED;
}
else if(regs->descs[0].live)
{
flags |= VALUE_LIVE;
}
else
{
flags |= VALUE_DEAD;
}
}
else
{
flags |= VALUE_DEAD;
}
}
if(value == regs->descs[1].value)
{
flags |= VALUE_INPUT;
if(regs->descs[1].used)
{
flags |= VALUE_LIVE | VALUE_USED;
}
else if(regs->descs[1].live)
{
flags |= VALUE_LIVE;
}
else
{
flags |= VALUE_DEAD;
}
}
if(value == regs->descs[2].value)
{
flags |= VALUE_INPUT;
if(regs->descs[2].used)
{
flags |= VALUE_LIVE | VALUE_USED;
}
else if(regs->descs[2].live)
{
flags |= VALUE_LIVE;
}
else
{
libjit/jit/jit-reg-alloc.c view on Meta::CPAN
/*
* Determine the effect of using a register for a value. This includes the
* following:
* - whether the value is clobbered by the instruction;
* - whether the previous contents of the register is clobbered.
*
* The value is clobbered by the instruction if it is used as input value
* and the output value will go to the same register and these two values
* are not equal. Or the instruction has a side effect that destroys the
* input value regardless of the output. This is indicated with the
* CLOBBER_INPUT_VALUE flag.
*
* The previous content is clobbered if the register contains any non-dead
* values that are destroyed by loading the input value, by computing the
* output value, or as a side effect of the instruction.
*
* The previous content is not clobbered if the register contains only dead
* values or it is used for input value that is already in the register so
* there is no need to load it and at the same time the instruction has no
* side effects that destroy the input value or the register is used for
* output value and the only value it contained before is the same value.
libjit/jit/jit-reg-alloc.c view on Meta::CPAN
if(!regs->descs[index].value)
{
return CLOBBER_NONE;
}
if(regs->ternary || !regs->descs[0].value)
{
/* this is either a ternary or binary or unary note */
if(regs->descs[index].clobber)
{
flags = CLOBBER_INPUT_VALUE;
}
#ifdef JIT_REG_STACK
else if(IS_STACK_REG(reg) && !regs->no_pop)
{
flags = CLOBBER_INPUT_VALUE;
}
#endif
else
{
flags = CLOBBER_NONE;
}
}
else if(index == 0)
{
/* this is the output value of a binary or unary op */
libjit/jit/jit-reg-alloc.c view on Meta::CPAN
}
else if(regs->copy)
{
flags = CLOBBER_NONE;
}
#ifdef JIT_REG_STACK
else if(IS_STACK_REG(reg) && !regs->no_pop)
{
/* this is a binary or unary stack op -- the input value
is either popped or overwritten by the output */
flags = CLOBBER_INPUT_VALUE;
}
#endif
else if(reg == regs->descs[0].reg
|| reg == regs->descs[0].other_reg
|| other_reg == regs->descs[0].reg)
{
/* the input value of a binary or unary op is clobbered
by the output value */
flags = CLOBBER_INPUT_VALUE;
}
else if(regs->descs[index].clobber)
{
flags = CLOBBER_INPUT_VALUE;
}
else
{
flags = CLOBBER_NONE;
}
if(flags == CLOBBER_NONE)
{
if(regs->descs[index].value->has_global_register
&& regs->descs[index].value->global_reg == reg)
libjit/jit/jit-reg-alloc.c view on Meta::CPAN
desc = ®s->descs[index];
if(desc->reg < 0 || desc->duplicate)
{
return;
}
/* See if the value clobbers the register it is assigned to. */
clobber = clobbers_register(gen, regs, index, desc->reg, desc->other_reg);
#ifdef JIT_REG_DEBUG
if((clobber & CLOBBER_INPUT_VALUE) != 0)
{
printf("clobber input\n");
}
if((clobber & CLOBBER_REG) != 0)
{
printf("clobber reg\n");
}
if((clobber & CLOBBER_OTHER_REG) != 0)
{
printf("clobber other reg\n");
libjit/jit/jit-reg-alloc.c view on Meta::CPAN
/* See if the input value is destroyed by the instruction. */
clobber_input = 0;
if(!desc->copy)
{
if(jit_reg_is_used(regs->clobber, desc->reg)
|| (desc->other_reg >= 0
&& jit_reg_is_used(regs->clobber, desc->other_reg)))
{
clobber_input = 1;
}
else if ((clobber & CLOBBER_INPUT_VALUE) != 0)
{
clobber_input = 1;
}
}
else if(reg >= 0)
{
if(jit_reg_is_used(regs->clobber, reg)
|| (other_reg >= 0
&& jit_reg_is_used(regs->clobber, other_reg)))
{
libjit/jit/jit-reg-alloc.c view on Meta::CPAN
{
use_cost += COST_THRASH;
}
else if(index != 2 && regs->descs[2].value
&& thrashes_value(gen, desc, reg, other_reg, ®s->descs[2]))
{
use_cost += COST_THRASH;
}
clobber = clobbers_register(gen, regs, index, reg, other_reg);
if((clobber & CLOBBER_INPUT_VALUE) != 0)
{
if(desc->used)
{
use_cost += COST_SPILL_CLEAN;
}
}
if((clobber & (CLOBBER_REG | CLOBBER_OTHER_REG)) != 0)
{
if(jit_reg_is_used(gen->permanent, reg))
{
libjit/jit/jit-reg-alloc.c view on Meta::CPAN
{
for(index = gen->contents[reg].num_values - 1; index >= 0; --index)
{
if(gen->contents[reg].num_values == 1)
{
break;
}
value = gen->contents[reg].values[index];
usage = value_usage(regs, value);
if((usage & VALUE_INPUT) != 0)
{
continue;
}
if((usage & VALUE_DEAD) != 0 || value->in_frame)
{
unbind_value(gen, value, reg, -1);
}
}
for(index = gen->contents[reg].num_values - 1; index >= 0; --index)
{
int top;
value = gen->contents[reg].values[index];
usage = value_usage(regs, value);
if((usage & VALUE_INPUT) != 0)
{
if((usage & VALUE_DEAD) != 0 || value->in_frame)
{
continue;
}
top = gen->reg_stack_top - 1;
if(reg != top)
{
exch_stack_top(gen, reg, 0);
libjit/jit/jit-reg-alloc.c view on Meta::CPAN
{
other_reg = -1;
}
for(index = gen->contents[reg].num_values - 1; index >= 0; --index)
{
value = gen->contents[reg].values[index];
usage = value_usage(regs, value);
if((usage & VALUE_DEAD) == 0)
{
if((usage & VALUE_INPUT) == 0)
{
save_value(gen, value, reg, other_reg, 1);
}
else
{
save_value(gen, value, reg, other_reg, 0);
}
}
else
{
if((usage & VALUE_INPUT) == 0)
{
free_value(gen, value, reg, other_reg, 0);
}
}
}
}
}
static void
update_age(jit_gencode_t gen, _jit_regdesc_t *desc)
libjit/jit/jit-type.c view on Meta::CPAN
* @item JIT_TYPETAG_VOLATILE
* The underlying value is assumed to be volatile. The @code{libjit}
* library will automatically call @code{jit_value_set_volatile} when a
* value is constructed using this type.
*
* @vindex JIT_TYPETAG_REFERENCE
* @item JIT_TYPETAG_REFERENCE
* The underlying value is a pointer, but it is assumed to refer to a
* pass-by-reference parameter.
*
* @vindex JIT_TYPETAG_OUTPUT
* @item JIT_TYPETAG_OUTPUT
* This is similar to @code{JIT_TYPETAG_REFERENCE}, except that the
* underlying parameter is assumed to be output-only.
*
* @vindex JIT_TYPETAG_RESTRICT
* @item JIT_TYPETAG_RESTRICT
* The underlying type is marked as @code{restrict}. Normally ignored.
*
* @vindex JIT_TYPETAG_SYS_BOOL
* @vindex JIT_TYPETAG_SYS_CHAR
* @vindex JIT_TYPETAG_SYS_SCHAR
libjit/jitdynamic/jit-cpp-mangle.c view on Meta::CPAN
case JIT_TYPE_FIRST_TAGGED + JIT_TYPETAG_UNION_NAME:
case JIT_TYPE_FIRST_TAGGED + JIT_TYPETAG_ENUM_NAME:
{
/* Output the qualified name of the type */
mangle_name_gcc2
(mangler, (const char *)jit_type_get_tagged_data(type));
}
break;
case JIT_TYPE_FIRST_TAGGED + JIT_TYPETAG_REFERENCE:
case JIT_TYPE_FIRST_TAGGED + JIT_TYPETAG_OUTPUT:
{
add_ch(mangler, 'R');
mangle_type_gcc2
(mangler, jit_type_get_ref(jit_type_remove_tags(type)));
}
break;
case JIT_TYPE_FIRST_TAGGED + JIT_TYPETAG_SYS_BOOL:
add_ch(mangler, 'b'); break;
case JIT_TYPE_FIRST_TAGGED + JIT_TYPETAG_SYS_CHAR:
libjit/jitdynamic/jit-cpp-mangle.c view on Meta::CPAN
case JIT_TYPE_FIRST_TAGGED + JIT_TYPETAG_UNION_NAME:
case JIT_TYPE_FIRST_TAGGED + JIT_TYPETAG_ENUM_NAME:
{
/* Output the qualified name of the type */
mangle_name_gcc3
(mangler, (const char *)jit_type_get_tagged_data(type), 0);
}
break;
case JIT_TYPE_FIRST_TAGGED + JIT_TYPETAG_REFERENCE:
case JIT_TYPE_FIRST_TAGGED + JIT_TYPETAG_OUTPUT:
{
add_ch(mangler, 'R');
mangle_type_gcc3
(mangler, jit_type_get_ref(jit_type_remove_tags(type)));
}
break;
case JIT_TYPE_FIRST_TAGGED + JIT_TYPETAG_SYS_BOOL:
add_ch(mangler, 'b'); break;
case JIT_TYPE_FIRST_TAGGED + JIT_TYPETAG_SYS_CHAR:
libjit/jitdynamic/jit-cpp-mangle.c view on Meta::CPAN
{
add_ch(mangler, 'W');
add_ch(mangler, (int)('0' + jit_type_get_size(type)));
mangle_name_msvc6
(mangler, (const char *)jit_type_get_tagged_data(type));
add_string(mangler, "@@");
}
break;
case JIT_TYPE_FIRST_TAGGED + JIT_TYPETAG_REFERENCE:
case JIT_TYPE_FIRST_TAGGED + JIT_TYPETAG_OUTPUT:
{
add_ch(mangler, 'A');
sub_type = jit_type_get_ref(jit_type_remove_tags(type));
if(jit_type_has_tag(sub_type, JIT_TYPETAG_CONST))
{
if(jit_type_has_tag(sub_type, JIT_TYPETAG_VOLATILE))
{
add_ch(mangler, 'D');
}
else
libjit/tools/gen-rules-parser.y view on Meta::CPAN
/*
* Amount of space to reserve for the primary instruction output.
*/
static int gensel_reserve_space = 32;
static int gensel_reserve_more_space = 128;
/*
* Maximal number of input values in a pattern.
*/
#define MAX_INPUT 3
/*
* Maximal number of scratch registers in a pattern.
*/
#define MAX_SCRATCH 6
/*
* Maximal number of pattern elements.
*/
#define MAX_PATTERN (MAX_INPUT + MAX_SCRATCH)
/*
* Rule Options.
*/
#define GENSEL_OPT_TERNARY 1
#define GENSEL_OPT_BRANCH 2
#define GENSEL_OPT_NOTE 3
#define GENSEL_OPT_COPY 4
#define GENSEL_OPT_COMMUTATIVE 5
#define GENSEL_OPT_STACK 6
libjit/tools/gen-rules-parser.y view on Meta::CPAN
case GENSEL_PATT_LOCAL:
case GENSEL_PATT_FRAME:
++locals;
break;
case GENSEL_PATT_SCRATCH:
++scratch;
}
pattern = pattern->next;
}
if((regs + imms + locals + others) > MAX_INPUT)
{
gensel_error(
clauses->filename,
clauses->linenum,
"too many input args in the pattern");
}
if(scratch > MAX_SCRATCH)
{
gensel_error(
clauses->filename,
libjit/tools/gen-rules-parser.y view on Meta::CPAN
}
return string;
}
/*
* Output the clauses for a rule.
*/
static void gensel_output_clauses(gensel_clause_t clauses, gensel_option_t options)
{
char *name;
char *args[MAX_INPUT];
char *names[MAX_PATTERN];
char *other_names[MAX_PATTERN];
gensel_clause_t clause;
gensel_option_t pattern;
gensel_option_t space, more_space;
gensel_value_t values;
int regs, imms, locals, scratch, index;
int first, seen_option;
int ternary, free_dest;
int contains_registers;