Diff for /embedaddon/pcre/sljit/sljitLir.h between versions 1.1.1.3 and 1.1.1.4

version 1.1.1.3, 2012/10/09 09:19:18 version 1.1.1.4, 2013/07/22 08:25:57
Line 34 Line 34
   
    Short description     Short description
     Advantages:      Advantages:
      - The execution can be continued from any LIR instruction      - The execution can be continued from any LIR instruction. In other
        In other words, jump into and out of the code is safe        words, it is possible to jump to any label from anywhere, even from
      - Both target of (conditional) jump and call instructions        a code fragment, which is compiled later, if both compiled code
        and constants can be dynamically modified during runtime        shares the same context. See sljit_emit_enter for more details
       - Supports self modifying code: target of (conditional) jump and call
         instructions and some constant values can be dynamically modified
         during runtime
         - although it is not suggested to do it frequently          - although it is not suggested to do it frequently
        - very effective to cache an important value once        - can be used for inline caching: save an important value once
           in the instruction stream
         - since this feature limits the optimization possibilities, a
           special flag must be passed at compile time when these
           instructions are emitted
       - A fixed stack space can be allocated for local variables        - A fixed stack space can be allocated for local variables
       - The compiler is thread-safe        - The compiler is thread-safe
       - The compiler is highly configurable through preprocessor macros.        - The compiler is highly configurable through preprocessor macros.
Line 47 Line 54
         threaded applications), and you can use your own system functions          threaded applications), and you can use your own system functions
         (including memory allocators). See sljitConfig.h          (including memory allocators). See sljitConfig.h
     Disadvantages:      Disadvantages:
         - No automatic register allocation, and temporary results are
           not stored on the stack. (hence the name comes)
       - Limited number of registers (only 6+4 integer registers, max 3+2        - Limited number of registers (only 6+4 integer registers, max 3+2
        temporary, max 3+2 saved and 4 floating point registers)        scratch, max 3+2 saved and 6 floating point registers)
     In practice:      In practice:
       - This approach is very effective for interpreters        - This approach is very effective for interpreters
         - One of the saved registers typically points to a stack interface          - One of the saved registers typically points to a stack interface
        - It can jump to any exception handler anytime (even for another        - It can jump to any exception handler anytime (even if it belongs
          function. It is safe for SLJIT.)          to another function)
        - Fast paths can be modified during runtime reflecting the changes        - Hot paths can be modified during runtime reflecting the changes
           of the fastest execution path of the dynamic language            of the fastest execution path of the dynamic language
         - SLJIT supports complex memory addressing modes          - SLJIT supports complex memory addressing modes
        - mainly position independent code        - mainly position and context independent code (except some cases)
      - Optimizations (perhaps later) 
        - Only for basic blocks (when no labels inserted between LIR instructions) 
   
     For valgrind users:      For valgrind users:
       - pass --smc-check=all argument to valgrind, since JIT is a "self-modifying code"        - pass --smc-check=all argument to valgrind, since JIT is a "self-modifying code"
Line 70 Line 77
 #endif  #endif
   
 /* The following header file defines useful macros for fine tuning  /* The following header file defines useful macros for fine tuning
sljit based code generators. They are listed in the beginingsljit based code generators. They are listed in the beginning
 of sljitConfigInternal.h */  of sljitConfigInternal.h */
   
 #include "sljitConfigInternal.h"  #include "sljitConfigInternal.h"
Line 99  of sljitConfigInternal.h */ Line 106  of sljitConfigInternal.h */
   
 #define SLJIT_UNUSED            0  #define SLJIT_UNUSED            0
   
/* Temporary (scratch) registers may not preserve their values across function calls. *//* Scratch (temporary) registers whose may not preserve their values
#define SLJIT_TEMPORARY_REG1   1   across function calls. */
#define SLJIT_TEMPORARY_REG2   2#define SLJIT_SCRATCH_REG1   1
#define SLJIT_TEMPORARY_REG3   3#define SLJIT_SCRATCH_REG2   2
/* Note: Extra Registers cannot be used for memory addressing. */#define SLJIT_SCRATCH_REG3   3
/* Note: on x86-32, these registers are emulated (using stack loads & stores). *//* Note: extra registers cannot be used for memory addressing. */
 /* Note: on x86-32, these registers are emulated (using stack
    loads & stores). */
 #define SLJIT_TEMPORARY_EREG1   4  #define SLJIT_TEMPORARY_EREG1   4
 #define SLJIT_TEMPORARY_EREG2   5  #define SLJIT_TEMPORARY_EREG2   5
   
Line 112  of sljitConfigInternal.h */ Line 121  of sljitConfigInternal.h */
 #define SLJIT_SAVED_REG1        6  #define SLJIT_SAVED_REG1        6
 #define SLJIT_SAVED_REG2        7  #define SLJIT_SAVED_REG2        7
 #define SLJIT_SAVED_REG3        8  #define SLJIT_SAVED_REG3        8
/* Note: Extra Registers cannot be used for memory addressing. *//* Note: extra registers cannot be used for memory addressing. */
/* Note: on x86-32, these registers are emulated (using stack loads & stores). *//* Note: on x86-32, these registers are emulated (using stack
    loads & stores). */
 #define SLJIT_SAVED_EREG1       9  #define SLJIT_SAVED_EREG1       9
 #define SLJIT_SAVED_EREG2       10  #define SLJIT_SAVED_EREG2       10
   
 /* Read-only register (cannot be the destination of an operation).  /* Read-only register (cannot be the destination of an operation).
    Only SLJIT_MEM1(SLJIT_LOCALS_REG) addressing mode is allowed since     Only SLJIT_MEM1(SLJIT_LOCALS_REG) addressing mode is allowed since
    several ABIs has certain limitations about the stack layout. However     several ABIs has certain limitations about the stack layout. However
   sljit_get_local_base() can be used to obtain the offset of a value. */   sljit_get_local_base() can be used to obtain the offset of a value
    on the stack. */
 #define SLJIT_LOCALS_REG        11  #define SLJIT_LOCALS_REG        11
   
 /* Number of registers. */  /* Number of registers. */
Line 130  of sljitConfigInternal.h */ Line 141  of sljitConfigInternal.h */
   
 /* Return with machine word. */  /* Return with machine word. */
   
#define SLJIT_RETURN_REG        SLJIT_TEMPORARY_REG1#define SLJIT_RETURN_REG        SLJIT_SCRATCH_REG1
   
 /* x86 prefers specific registers for special purposes. In case of shift  /* x86 prefers specific registers for special purposes. In case of shift
   by register it supports only SLJIT_TEMPORARY_REG3 for shift argument   by register it supports only SLJIT_SCRATCH_REG3 for shift argument
    (which is the src2 argument of sljit_emit_op2). If another register is     (which is the src2 argument of sljit_emit_op2). If another register is
    used, sljit must exchange data between registers which cause a minor     used, sljit must exchange data between registers which cause a minor
    slowdown. Other architectures has no such limitation. */     slowdown. Other architectures has no such limitation. */
   
#define SLJIT_PREF_SHIFT_REG    SLJIT_TEMPORARY_REG3#define SLJIT_PREF_SHIFT_REG    SLJIT_SCRATCH_REG3
   
 /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
 /*  Floating point registers                                             */  /*  Floating point registers                                             */
Line 147  of sljitConfigInternal.h */ Line 158  of sljitConfigInternal.h */
 /* Note: SLJIT_UNUSED as destination is not valid for floating point  /* Note: SLJIT_UNUSED as destination is not valid for floating point
      operations, since they cannot be used for setting flags. */       operations, since they cannot be used for setting flags. */
   
/* Floating point operations are performed on double precision values. *//* Floating point operations are performed on double or
    single precision values. */
   
#define SLJIT_FLOAT_REG1        1#define SLJIT_FLOAT_REG1                1
#define SLJIT_FLOAT_REG2        2#define SLJIT_FLOAT_REG2                2
#define SLJIT_FLOAT_REG3        3#define SLJIT_FLOAT_REG3                3
#define SLJIT_FLOAT_REG4        4#define SLJIT_FLOAT_REG4                4
 #define SLJIT_FLOAT_REG5                5
 #define SLJIT_FLOAT_REG6                6
   
   #define SLJIT_NO_FLOAT_REGISTERS        6
   
 /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
 /*  Main structures and functions                                        */  /*  Main structures and functions                                        */
 /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
Line 161  of sljitConfigInternal.h */ Line 177  of sljitConfigInternal.h */
 struct sljit_memory_fragment {  struct sljit_memory_fragment {
         struct sljit_memory_fragment *next;          struct sljit_memory_fragment *next;
         sljit_uw used_size;          sljit_uw used_size;
           /* Must be aligned to sljit_sw. */
         sljit_ub memory[1];          sljit_ub memory[1];
 };  };
   
Line 174  struct sljit_label { Line 191  struct sljit_label {
 struct sljit_jump {  struct sljit_jump {
         struct sljit_jump *next;          struct sljit_jump *next;
         sljit_uw addr;          sljit_uw addr;
        sljit_w flags;        sljit_sw flags;
         union {          union {
                 sljit_uw target;                  sljit_uw target;
                 struct sljit_label* label;                  struct sljit_label* label;
Line 187  struct sljit_const { Line 204  struct sljit_const {
 };  };
   
 struct sljit_compiler {  struct sljit_compiler {
        int error;        sljit_si error;
   
         struct sljit_label *labels;          struct sljit_label *labels;
         struct sljit_jump *jumps;          struct sljit_jump *jumps;
Line 200  struct sljit_compiler { Line 217  struct sljit_compiler {
         struct sljit_memory_fragment *abuf;          struct sljit_memory_fragment *abuf;
   
         /* Used local registers. */          /* Used local registers. */
        int temporaries;        sljit_si scratches;
         /* Used saved registers. */          /* Used saved registers. */
        int saveds;        sljit_si saveds;
         /* Local stack size. */          /* Local stack size. */
        int local_size;        sljit_si local_size;
         /* Code size. */          /* Code size. */
         sljit_uw size;          sljit_uw size;
         /* For statistical purposes. */          /* For statistical purposes. */
         sljit_uw executable_size;          sljit_uw executable_size;
   
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)  #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
        int args;        sljit_si args;
        int locals_offset;        sljit_si locals_offset;
        int temporaries_start;        sljit_si scratches_start;
        int saveds_start;        sljit_si saveds_start;
 #endif  #endif
   
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
        int mode32;        sljit_si mode32;
 #endif  #endif
   
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
        int flags_saved;        sljit_si flags_saved;
 #endif  #endif
   
 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)  #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
Line 239  struct sljit_compiler { Line 256  struct sljit_compiler {
 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)  #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
         /* Temporary fields. */          /* Temporary fields. */
         sljit_uw shift_imm;          sljit_uw shift_imm;
        int cache_arg;        sljit_si cache_arg;
        sljit_w cache_argw;        sljit_sw cache_argw;
 #endif  #endif
   
 #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)  #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
        int cache_arg;        sljit_si cache_arg;
        sljit_w cache_argw;        sljit_sw cache_argw;
 #endif  #endif
   
 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)  #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
        sljit_w imm;        sljit_sw imm;
        int cache_arg;        sljit_si cache_arg;
        sljit_w cache_argw;        sljit_sw cache_argw;
 #endif  #endif
   
 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)  #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
        int delay_slot;        sljit_si delay_slot;
        int cache_arg;        sljit_si cache_arg;
        sljit_w cache_argw;        sljit_sw cache_argw;
 #endif  #endif
   
   #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
           sljit_si delay_slot;
           sljit_si cache_arg;
           sljit_sw cache_argw;
   #endif
   
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)  #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
         FILE* verbose;          FILE* verbose;
 #endif  #endif
   
 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)  #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
         /* Local size passed to the functions. */          /* Local size passed to the functions. */
        int logical_local_size;        sljit_si logical_local_size;
 #endif  #endif
   
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)  #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
        int skip_checks;        sljit_si skip_checks;
 #endif  #endif
 };  };
   
Line 281  struct sljit_compiler { Line 304  struct sljit_compiler {
 /* Creates an sljit compiler.  /* Creates an sljit compiler.
    Returns NULL if failed. */     Returns NULL if failed. */
 SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void);  SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void);
/* Free everything except the codes. */
 /* Free everything except the compiled machine code. */
 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler);  SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler);
   
static SLJIT_INLINE int sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; }/* Returns the current error code. If an error is occurred, future sljit
    calls which uses the same compiler argument returns early with the same
    error code. Thus there is no need for checking the error after every
    call, it is enough to do it before the code is compiled. Removing
    these checks increases the performance of the compiling process. */
 static SLJIT_INLINE sljit_si sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; }
   
 /*  /*
    Allocate a small amount of memory. The size must be <= 64 bytes on 32 bit,     Allocate a small amount of memory. The size must be <= 64 bytes on 32 bit,
   and <= 128 bytes on 64 bit architectures. The memory area is owned by the compiler,   and <= 128 bytes on 64 bit architectures. The memory area is owned by the
   and freed by sljit_free_compiler. The returned pointer is sizeof(sljit_w) aligned.   compiler, and freed by sljit_free_compiler. The returned pointer is
   Excellent for allocating small blocks during the compiling, and no need to worry   sizeof(sljit_sw) aligned. Excellent for allocating small blocks during
   about freeing them. The size is enough to contain at most 16 pointers.   the compiling, and no need to worry about freeing them. The size is
   If the size is outside of the range, the function will return with NULL,   enough to contain at most 16 pointers. If the size is outside of the range,
   but this return value does not indicate that there is no more memory (does   the function will return with NULL. However, this return value does not
   not set the compiler to out-of-memory status).   indicate that there is no more memory (does not set the current error code
    of the compiler to out-of-memory status).
 */  */
SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, int size);SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si size);
   
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)  #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
 /* Passing NULL disables verbose. */  /* Passing NULL disables verbose. */
Line 307  SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(str Line 337  SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(str
 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code);  SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code);
   
 /*  /*
   After the code generation we can retrieve the allocated executable memory size,   After the machine code generation is finished we can retrieve the allocated
   although this area may not be fully filled with instructions depending on some   executable memory size, although this area may not be fully filled with
   optimizations. This function is useful only for statistical purposes.   instructions depending on some optimizations. This function is useful only
    for statistical purposes.
   
    Before a successful code generation, this function returns with 0.     Before a successful code generation, this function returns with 0.
 */  */
 static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler *compiler) { return compiler->executable_size; }  static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler *compiler) { return compiler->executable_size; }
   
/* Instruction generation. Returns with error code. *//* Instruction generation. Returns with any error code. If there is no
    error, they return with SLJIT_SUCCESS. */
   
 /*  /*
    The executable code is basically a function call from the viewpoint of     The executable code is basically a function call from the viewpoint of
Line 326  static SLJIT_INLINE sljit_uw sljit_get_generated_code_ Line 358  static SLJIT_INLINE sljit_uw sljit_get_generated_code_
    for the executable code and moves function arguments to the saved     for the executable code and moves function arguments to the saved
    registers. The number of arguments are specified in the "args"     registers. The number of arguments are specified in the "args"
    parameter and the first argument goes to SLJIT_SAVED_REG1, the second     parameter and the first argument goes to SLJIT_SAVED_REG1, the second
   goes to SLJIT_SAVED_REG2 and so on. The number of temporary and   goes to SLJIT_SAVED_REG2 and so on. The number of scratch and
   saved registers are passed in "temporaries" and "saveds" arguments   saved registers are passed in "scratches" and "saveds" arguments
    respectively. Since the saved registers contains the arguments,     respectively. Since the saved registers contains the arguments,
    "args" must be less or equal than "saveds". The sljit_emit_enter     "args" must be less or equal than "saveds". The sljit_emit_enter
    is also capable of allocating a stack space for local variables. The     is also capable of allocating a stack space for local variables. The
Line 338  static SLJIT_INLINE sljit_uw sljit_get_generated_code_ Line 370  static SLJIT_INLINE sljit_uw sljit_get_generated_code_
    SLJIT_LOCALS_REG + local_size (exclusive) can be modified freely     SLJIT_LOCALS_REG + local_size (exclusive) can be modified freely
    until the function returns. The stack space is uninitialized.     until the function returns. The stack space is uninitialized.
   
   Note: every call of sljit_emit_enter and sljit_set_context overwrites   Note: every call of sljit_emit_enter and sljit_set_context
         the previous context. */         overwrites the previous context. */
   
 #define SLJIT_MAX_LOCAL_SIZE    65536  #define SLJIT_MAX_LOCAL_SIZE    65536
   
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler,SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
        int args, int temporaries, int saveds, int local_size);        sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size);
   
 /* The machine code has a context (which contains the local stack space size,  /* The machine code has a context (which contains the local stack space size,
    number of used registers, etc.) which initialized by sljit_emit_enter. Several     number of used registers, etc.) which initialized by sljit_emit_enter. Several
    functions (like sljit_emit_return) requres this context to be able to generate     functions (like sljit_emit_return) requres this context to be able to generate
    the appropriate code. However, some code fragments (like inline cache) may have     the appropriate code. However, some code fragments (like inline cache) may have
    no normal entry point so their context is unknown for the compiler. Using the     no normal entry point so their context is unknown for the compiler. Using the
   function below we can specify thir context.   function below we can specify their context.
   
    Note: every call of sljit_emit_enter and sljit_set_context overwrites     Note: every call of sljit_emit_enter and sljit_set_context overwrites
          the previous context. */           the previous context. */
   
 /* Note: multiple calls of this function overwrites the previous call. */  
   
 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler,  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler,
        int args, int temporaries, int saveds, int local_size);        sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size);
   
 /* Return from machine code.  The op argument can be SLJIT_UNUSED which means the  /* Return from machine code.  The op argument can be SLJIT_UNUSED which means the
    function does not return with anything or any opcode between SLJIT_MOV and     function does not return with anything or any opcode between SLJIT_MOV and
   SLJIT_MOV_SI (see sljit_emit_op1). As for src and srcw they must be 0 if op   SLJIT_MOV_P (see sljit_emit_op1). As for src and srcw they must be 0 if op
    is SLJIT_UNUSED, otherwise see below the description about source and     is SLJIT_UNUSED, otherwise see below the description about source and
    destination arguments. */     destination arguments. */
 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op,  
         int src, sljit_w srcw);  
   
/* Really fast calling method for utility functions inside sljit (see SLJIT_FAST_CALL).SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op,
   All registers and even the stack frame is passed to the callee. The return address is        sljit_si src, sljit_sw srcw);
   preserved in dst/dstw by sljit_emit_fast_enter, and sljit_emit_fast_return can 
   use this as a return value later. */ 
   
/* Note: only for sljit specific, non ABI compilant calls. Fast, since only a few machine instructions/* Fast calling mechanism for utility functions (see SLJIT_FAST_CALL). All registers and
   are needed. Excellent for small uility functions, where saving registers and setting up   even the stack frame is passed to the callee. The return address is preserved in
   a new stack frame would cost too much performance. However, it is still possible to return   dst/dstw by sljit_emit_fast_enter (the type of the value stored by this function
   to the address of the caller (or anywhere else). */   is sljit_p), and sljit_emit_fast_return can use this as a return value later. */
   
   /* Note: only for sljit specific, non ABI compilant calls. Fast, since only a few machine
      instructions are needed. Excellent for small uility functions, where saving registers
      and setting up a new stack frame would cost too much performance. However, it is still
      possible to return to the address of the caller (or anywhere else). */
   
 /* Note: flags are not changed (unlike sljit_emit_enter / sljit_emit_return). */  /* Note: flags are not changed (unlike sljit_emit_enter / sljit_emit_return). */
   
 /* Note: although sljit_emit_fast_return could be replaced by an ijump, it is not suggested,  /* Note: although sljit_emit_fast_return could be replaced by an ijump, it is not suggested,
    since many architectures do clever branch prediction on call / return instruction pairs. */     since many architectures do clever branch prediction on call / return instruction pairs. */
   
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw);SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw);
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw);SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw);
   
 /*  /*
    Source and destination values for arithmetical instructions     Source and destination values for arithmetical instructions
Line 394  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(st Line 425  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(st
     [imm]            - absolute immediate memory address      [imm]            - absolute immediate memory address
     [reg+imm]        - indirect memory address      [reg+imm]        - indirect memory address
     [reg+(reg<<imm)] - indirect indexed memory address (shift must be between 0 and 3)      [reg+(reg<<imm)] - indirect indexed memory address (shift must be between 0 and 3)
                       useful for (byte, half, int, sljit_w) array access                       useful for (byte, half, int, sljit_sw) array access
                        (fully supported by both x86 and ARM architectures, and cheap operation on others)                         (fully supported by both x86 and ARM architectures, and cheap operation on others)
 */  */
   
Line 404  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(st Line 435  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(st
   
      length | alignment       length | alignment
    ---------+-----------     ---------+-----------
     byte   | 1 byte (not aligned)     byte   | 1 byte (any physical_address is accepted)
     half   | 2 byte (real_address & 0x1 == 0)     half   | 2 byte (physical_address & 0x1 == 0)
     int    | 4 byte (real_address & 0x3 == 0)     int    | 4 byte (physical_address & 0x3 == 0)
    sljit_w | 4 byte if SLJIT_32BIT_ARCHITECTURE is defined and its value is 1     word   | 4 byte if SLJIT_32BIT_ARCHITECTURE is defined and its value is 1
             | 8 byte if SLJIT_64BIT_ARCHITECTURE is defined and its value is 1              | 8 byte if SLJIT_64BIT_ARCHITECTURE is defined and its value is 1
       pointer | size of sljit_p type (4 byte on 32 bit machines, 4 or 8 byte
               | on 64 bit machines)
   
   Note: different architectures have different addressing limitations   Note:   Different architectures have different addressing limitations.
         Thus sljit may generate several instructions for other addressing modes           A single instruction is enough for the following addressing
   x86:  all addressing modes supported, but write-back is not supported           modes. Other adrressing modes are emulated by instruction
         (requires an extra instruction). On x86-64 only 32 bit signed           sequences. This information could help to improve those code
         integers are supported by the architecture.           generators which focuses only a few architectures.
   arm:  [reg+imm] supported for small immediates (-4095 <= imm <= 4095
         or -255 <= imm <= 255 for loading signed bytes, any halfs or doubles)   x86:    [reg+imm], -2^32+1 <= imm <= 2^32-1 (full address space on x86-32)
         [reg+(reg<<imm)] are supported or requires only two instructions           [reg+(reg<<imm)] is supported
         Write back is limited to small immediates on thumb2           [imm], -2^32+1 <= imm <= 2^32-1 is supported
   ppc:  [reg+imm], -65535 <= imm <= 65535. 64 bit moves requires immediates           Write-back is not supported
         divisible by 4. [reg+reg] supported, write-back supported   arm:    [reg+imm], -4095 <= imm <= 4095 or -255 <= imm <= 255 for signed
         [reg+(reg<<imm)] (imm != 0) is cheap (requires two instructions)                bytes, any halfs or floating point values)
            [reg+(reg<<imm)] is supported
            Write-back is supported
    arm-t2: [reg+imm], -255 <= imm <= 4095
            [reg+(reg<<imm)] is supported
            Write back is supported only for [reg+imm], where -255 <= imm <= 255
    ppc:    [reg+imm], -65536 <= imm <= 65535. 64 bit loads/stores and 32 bit
                 signed load on 64 bit requires immediates divisible by 4.
                 [reg+imm] is not supported for signed 8 bit values.
            [reg+reg] is supported
            Write-back is supported except for one instruction: 32 bit signed
                 load with [reg+imm] addressing mode on 64 bit.
    mips:   [reg+imm], -65536 <= imm <= 65535
    sparc:  [reg+imm], -4096 <= imm <= 4095
            [reg+reg] is supported
 */  */
   
 /* Register output: simply the name of the register.  /* Register output: simply the name of the register.
Line 433  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(st Line 480  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(st
 #define SLJIT_IMM               0x200  #define SLJIT_IMM               0x200
   
 /* Set 32 bit operation mode (I) on 64 bit CPUs. The flag is totally ignored on  /* Set 32 bit operation mode (I) on 64 bit CPUs. The flag is totally ignored on
   32 bit CPUs. The arithmetic instruction uses only the lower 32 bit of the   32 bit CPUs. If this flag is set for an arithmetic operation, it uses only the
   input register(s), and set the flags according to the 32 bit result. If the   lower 32 bit of the input register(s), and set the CPU status flags according
   destination is a register, the higher 32 bit of the result is undefined.   to the 32 bit result. The higher 32 bits are undefined for both the input and
   The addressing modes (SLJIT_MEM1/SLJIT_MEM2 macros) are unaffected by this flag. */   output. However, the CPU might not ignore those higher 32 bits, like MIPS, which
    expects it to be the sign extension of the lower 32 bit. All 32 bit operations
    are undefined, if this condition is not fulfilled. Therefore, when SLJIT_INT_OP
    is specified, all register arguments must be the result of other operations with
    the same SLJIT_INT_OP flag. In other words, although a register can hold either
    a 64 or 32 bit value, these values cannot be mixed. The only exceptions are
    SLJIT_IMOV and SLJIT_IMOVU (SLJIT_MOV_SI/SLJIT_MOV_UI/SLJIT_MOVU_SI/SLJIT_MOV_UI
    with SLJIT_INT_OP flag) which can convert any source argument to SLJIT_INT_OP
    compatible result. This conversion might be unnecessary on some CPUs like x86-64,
    since the upper 32 bit is always ignored. In this case SLJIT is clever enough
    to not generate any instructions if the source and destination operands are the
    same registers. Affects sljit_emit_op0, sljit_emit_op1 and sljit_emit_op2. */
 #define SLJIT_INT_OP            0x100  #define SLJIT_INT_OP            0x100
   
   /* Single precision mode (SP). This flag is similar to SLJIT_INT_OP, just
      it applies to floating point registers (it is even the same bit). When
      this flag is passed, the CPU performs single precision floating point
      operations. Similar to SLJIT_INT_OP, all register arguments must be the
      result of other floating point operations with this flag. Affects
      sljit_emit_fop1, sljit_emit_fop2 and sljit_emit_fcmp. */
   #define SLJIT_SINGLE_OP         0x100
   
 /* Common CPU status flags for all architectures (x86, ARM, PPC)  /* Common CPU status flags for all architectures (x86, ARM, PPC)
     - carry flag      - carry flag
     - overflow flag      - overflow flag
Line 480  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(st Line 546  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(st
    Note: may or may not cause an extra cycle wait     Note: may or may not cause an extra cycle wait
          it can even decrease the runtime in a few cases. */           it can even decrease the runtime in a few cases. */
 #define SLJIT_NOP                       1  #define SLJIT_NOP                       1
/* Flags: may destroy flags/* Flags: - (may destroy flags)
   Unsigned multiplication of SLJIT_TEMPORARY_REG1 and SLJIT_TEMPORARY_REG2.   Unsigned multiplication of SLJIT_SCRATCH_REG1 and SLJIT_SCRATCH_REG2.
   Result goes to SLJIT_TEMPORARY_REG2:SLJIT_TEMPORARY_REG1 (high:low) word */   Result goes to SLJIT_SCRATCH_REG2:SLJIT_SCRATCH_REG1 (high:low) word */
 #define SLJIT_UMUL                      2  #define SLJIT_UMUL                      2
/* Flags: may destroy flags/* Flags: - (may destroy flags)
   Signed multiplication of SLJIT_TEMPORARY_REG1 and SLJIT_TEMPORARY_REG2.   Signed multiplication of SLJIT_SCRATCH_REG1 and SLJIT_SCRATCH_REG2.
   Result goes to SLJIT_TEMPORARY_REG2:SLJIT_TEMPORARY_REG1 (high:low) word */   Result goes to SLJIT_SCRATCH_REG2:SLJIT_SCRATCH_REG1 (high:low) word */
 #define SLJIT_SMUL                      3  #define SLJIT_SMUL                      3
/* Flags: I | may destroy flags/* Flags: I - (may destroy flags)
   Unsigned divide of the value in SLJIT_TEMPORARY_REG1 by the value in SLJIT_TEMPORARY_REG2.   Unsigned divide of the value in SLJIT_SCRATCH_REG1 by the value in SLJIT_SCRATCH_REG2.
   The result is placed in SLJIT_TEMPORARY_REG1 and the remainder goes to SLJIT_TEMPORARY_REG2.   The result is placed in SLJIT_SCRATCH_REG1 and the remainder goes to SLJIT_SCRATCH_REG2.
   Note: if SLJIT_TEMPORARY_REG2 contains 0, the behaviour is undefined. */   Note: if SLJIT_SCRATCH_REG2 contains 0, the behaviour is undefined. */
 #define SLJIT_UDIV                      4  #define SLJIT_UDIV                      4
/* Flags: I | may destroy flags#define SLJIT_IUDIV                     (SLJIT_UDIV | SLJIT_INT_OP)
   Signed divide of the value in SLJIT_TEMPORARY_REG1 by the value in SLJIT_TEMPORARY_REG2./* Flags: I - (may destroy flags)
   The result is placed in SLJIT_TEMPORARY_REG1 and the remainder goes to SLJIT_TEMPORARY_REG2.   Signed divide of the value in SLJIT_SCRATCH_REG1 by the value in SLJIT_SCRATCH_REG2.
   Note: if SLJIT_TEMPORARY_REG2 contains 0, the behaviour is undefined. */   The result is placed in SLJIT_SCRATCH_REG1 and the remainder goes to SLJIT_SCRATCH_REG2.
    Note: if SLJIT_SCRATCH_REG2 contains 0, the behaviour is undefined. */
 #define SLJIT_SDIV                      5  #define SLJIT_SDIV                      5
   #define SLJIT_ISDIV                     (SLJIT_SDIV | SLJIT_INT_OP)
   
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op);SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op);
   
 /* Notes for MOV instructions:  /* Notes for MOV instructions:
    U = Mov with update (post form). If source or destination defined as SLJIT_MEM1(r1)     U = Mov with update (post form). If source or destination defined as SLJIT_MEM1(r1)
        or SLJIT_MEM2(r1, r2), r1 is increased by the sum of r2 and the constant argument         or SLJIT_MEM2(r1, r2), r1 is increased by the sum of r2 and the constant argument
    UB = unsigned byte (8 bit)     UB = unsigned byte (8 bit)
    SB = signed byte (8 bit)     SB = signed byte (8 bit)
   UH = unsgined half (16 bit)   UH = unsigned half (16 bit)
   SH = unsgined half (16 bit) */   SH = signed half (16 bit)
    UI = unsigned int (32 bit)
    SI = signed int (32 bit)
    P  = pointer (sljit_p) size */
   
 /* Flags: - (never set any flags) */  /* Flags: - (never set any flags) */
 #define SLJIT_MOV                       6  #define SLJIT_MOV                       6
/* Flags: - (never set any flags) *//* Flags: I - (never set any flags) */
 #define SLJIT_MOV_UB                    7  #define SLJIT_MOV_UB                    7
/* Flags: - (never set any flags) */#define SLJIT_IMOV_UB                   (SLJIT_MOV_UB | SLJIT_INT_OP)
 /* Flags: I - (never set any flags) */
 #define SLJIT_MOV_SB                    8  #define SLJIT_MOV_SB                    8
/* Flags: - (never set any flags) */#define SLJIT_IMOV_SB                   (SLJIT_MOV_SB | SLJIT_INT_OP)
 /* Flags: I - (never set any flags) */
 #define SLJIT_MOV_UH                    9  #define SLJIT_MOV_UH                    9
/* Flags: - (never set any flags) */#define SLJIT_IMOV_UH                   (SLJIT_MOV_UH | SLJIT_INT_OP)
 /* Flags: I - (never set any flags) */
 #define SLJIT_MOV_SH                    10  #define SLJIT_MOV_SH                    10
/* Flags: - (never set any flags) */#define SLJIT_IMOV_SH                   (SLJIT_MOV_SH | SLJIT_INT_OP)
 /* Flags: I - (never set any flags)
    Note: see SLJIT_INT_OP for further details. */
 #define SLJIT_MOV_UI                    11  #define SLJIT_MOV_UI                    11
/* Flags: - (never set any flags) *//* No SLJIT_INT_OP form, since it the same as SLJIT_IMOVU. */
 /* Flags: I - (never set any flags)
    Note: see SLJIT_INT_OP for further details. */
 #define SLJIT_MOV_SI                    12  #define SLJIT_MOV_SI                    12
   #define SLJIT_IMOV                      (SLJIT_MOV_SI | SLJIT_INT_OP)
 /* Flags: - (never set any flags) */  /* Flags: - (never set any flags) */
#define SLJIT_MOVU                        13#define SLJIT_MOV_P                        13
 /* Flags: - (never set any flags) */  /* Flags: - (never set any flags) */
#define SLJIT_MOVU_UB                   14#define SLJIT_MOVU                      14
 /* Flags: I - (never set any flags) */
 #define SLJIT_MOVU_UB                   15
 #define SLJIT_IMOVU_UB                  (SLJIT_MOVU_UB | SLJIT_INT_OP)
 /* Flags: I - (never set any flags) */
 #define SLJIT_MOVU_SB                   16
 #define SLJIT_IMOVU_SB                  (SLJIT_MOVU_SB | SLJIT_INT_OP)
 /* Flags: I - (never set any flags) */
 #define SLJIT_MOVU_UH                   17
 #define SLJIT_IMOVU_UH                  (SLJIT_MOVU_UH | SLJIT_INT_OP)
 /* Flags: I - (never set any flags) */
 #define SLJIT_MOVU_SH                   18
 #define SLJIT_IMOVU_SH                  (SLJIT_MOVU_SH | SLJIT_INT_OP)
 /* Flags: I - (never set any flags)
    Note: see SLJIT_INT_OP for further details. */
 #define SLJIT_MOVU_UI                   19
 /* No SLJIT_INT_OP form, since it the same as SLJIT_IMOVU. */
 /* Flags: I - (never set any flags)
    Note: see SLJIT_INT_OP for further details. */
 #define SLJIT_MOVU_SI                   20
 #define SLJIT_IMOVU                     (SLJIT_MOVU_SI | SLJIT_INT_OP)
 /* Flags: - (never set any flags) */  /* Flags: - (never set any flags) */
#define SLJIT_MOVU_SB                      15#define SLJIT_MOVU_P                       21
/* Flags: - (never set any flags) */ 
#define SLJIT_MOVU_UH                   16 
/* Flags: - (never set any flags) */ 
#define SLJIT_MOVU_SH                   17 
/* Flags: - (never set any flags) */ 
#define SLJIT_MOVU_UI                   18 
/* Flags: - (never set any flags) */ 
#define SLJIT_MOVU_SI                   19 
 /* Flags: I | E | K */  /* Flags: I | E | K */
#define SLJIT_NOT                       20#define SLJIT_NOT                       22
 #define SLJIT_INOT                      (SLJIT_NOT | SLJIT_INT_OP)
 /* Flags: I | E | O | K */  /* Flags: I | E | O | K */
#define SLJIT_NEG                       21#define SLJIT_NEG                       23
 #define SLJIT_INEG                      (SLJIT_NEG | SLJIT_INT_OP)
 /* Count leading zeroes  /* Count leading zeroes
   Flags: I | E | K */   Flags: I | E | K
#define SLJIT_CLZ                       22   Important note! Sparc 32 does not support K flag, since
    the required popc instruction is introduced only in sparc 64. */
 #define SLJIT_CLZ                       24
 #define SLJIT_ICLZ                      (SLJIT_CLZ | SLJIT_INT_OP)
   
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op,SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op,
        int dst, sljit_w dstw,        sljit_si dst, sljit_sw dstw,
        int src, sljit_w srcw);        sljit_si src, sljit_sw srcw);
   
 /* Flags: I | E | O | C | K */  /* Flags: I | E | O | C | K */
#define SLJIT_ADD                       23#define SLJIT_ADD                       25
 #define SLJIT_IADD                      (SLJIT_ADD | SLJIT_INT_OP)
 /* Flags: I | C | K */  /* Flags: I | C | K */
#define SLJIT_ADDC                      24#define SLJIT_ADDC                      26
 #define SLJIT_IADDC                     (SLJIT_ADDC | SLJIT_INT_OP)
 /* Flags: I | E | S | U | O | C | K */  /* Flags: I | E | S | U | O | C | K */
#define SLJIT_SUB                       25#define SLJIT_SUB                       27
 #define SLJIT_ISUB                      (SLJIT_SUB | SLJIT_INT_OP)
 /* Flags: I | C | K */  /* Flags: I | C | K */
#define SLJIT_SUBC                      26#define SLJIT_SUBC                      28
 #define SLJIT_ISUBC                     (SLJIT_SUBC | SLJIT_INT_OP)
 /* Note: integer mul  /* Note: integer mul
    Flags: I | O (see SLJIT_C_MUL_*) | K */     Flags: I | O (see SLJIT_C_MUL_*) | K */
#define SLJIT_MUL                       27#define SLJIT_MUL                       29
 #define SLJIT_IMUL                      (SLJIT_MUL | SLJIT_INT_OP)
 /* Flags: I | E | K */  /* Flags: I | E | K */
#define SLJIT_AND                       28#define SLJIT_AND                       30
 #define SLJIT_IAND                      (SLJIT_AND | SLJIT_INT_OP)
 /* Flags: I | E | K */  /* Flags: I | E | K */
#define SLJIT_OR                        29#define SLJIT_OR                        31
 #define SLJIT_IOR                       (SLJIT_OR | SLJIT_INT_OP)
 /* Flags: I | E | K */  /* Flags: I | E | K */
#define SLJIT_XOR                       30#define SLJIT_XOR                       32
 #define SLJIT_IXOR                      (SLJIT_XOR | SLJIT_INT_OP)
 /* Flags: I | E | K  /* Flags: I | E | K
    Let bit_length be the length of the shift operation: 32 or 64.     Let bit_length be the length of the shift operation: 32 or 64.
    If src2 is immediate, src2w is masked by (bit_length - 1).     If src2 is immediate, src2w is masked by (bit_length - 1).
    Otherwise, if the content of src2 is outside the range from 0     Otherwise, if the content of src2 is outside the range from 0
    to bit_length - 1, the operation is undefined. */     to bit_length - 1, the operation is undefined. */
#define SLJIT_SHL                       31#define SLJIT_SHL                       33
 #define SLJIT_ISHL                      (SLJIT_SHL | SLJIT_INT_OP)
 /* Flags: I | E | K  /* Flags: I | E | K
    Let bit_length be the length of the shift operation: 32 or 64.     Let bit_length be the length of the shift operation: 32 or 64.
    If src2 is immediate, src2w is masked by (bit_length - 1).     If src2 is immediate, src2w is masked by (bit_length - 1).
    Otherwise, if the content of src2 is outside the range from 0     Otherwise, if the content of src2 is outside the range from 0
    to bit_length - 1, the operation is undefined. */     to bit_length - 1, the operation is undefined. */
#define SLJIT_LSHR                      32#define SLJIT_LSHR                      34
 #define SLJIT_ILSHR                     (SLJIT_LSHR | SLJIT_INT_OP)
 /* Flags: I | E | K  /* Flags: I | E | K
    Let bit_length be the length of the shift operation: 32 or 64.     Let bit_length be the length of the shift operation: 32 or 64.
    If src2 is immediate, src2w is masked by (bit_length - 1).     If src2 is immediate, src2w is masked by (bit_length - 1).
    Otherwise, if the content of src2 is outside the range from 0     Otherwise, if the content of src2 is outside the range from 0
    to bit_length - 1, the operation is undefined. */     to bit_length - 1, the operation is undefined. */
#define SLJIT_ASHR                      33#define SLJIT_ASHR                      35
 #define SLJIT_IASHR                     (SLJIT_ASHR | SLJIT_INT_OP)
   
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op,
        int dst, sljit_w dstw,        sljit_si dst, sljit_sw dstw,
        int src1, sljit_w src1w,        sljit_si src1, sljit_sw src1w,
        int src2, sljit_w src2w);        sljit_si src2, sljit_sw src2w);
   
 /* The following function is a helper function for sljit_emit_op_custom.  /* The following function is a helper function for sljit_emit_op_custom.
   It returns with the real machine register index of any SLJIT_TEMPORARY   It returns with the real machine register index of any SLJIT_SCRATCH
    SLJIT_SAVED or SLJIT_LOCALS register.     SLJIT_SAVED or SLJIT_LOCALS register.
   Note: it returns with -1 for virtual registers (all EREGs on x86-32).   Note: it returns with -1 for virtual registers (all EREGs on x86-32). */
   Note: register returned by SLJIT_LOCALS_REG is not necessary the real 
         stack pointer register of the target architecture. */ 
   
SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg);SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg);
   
   /* The following function is a helper function for sljit_emit_op_custom.
      It returns with the real machine register index of any SLJIT_FLOAT register.
      Note: the index is divided by 2 on ARM 32 bit architectures. */
   
   SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg);
   
 /* Any instruction can be inserted into the instruction stream by  /* Any instruction can be inserted into the instruction stream by
    sljit_emit_op_custom. It has a similar purpose as inline assembly.     sljit_emit_op_custom. It has a similar purpose as inline assembly.
    The size parameter must match to the instruction size of the target     The size parameter must match to the instruction size of the target
Line 609  SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index( Line 720  SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(
               if size == 4, the instruction argument must be 4 byte aligned.                if size == 4, the instruction argument must be 4 byte aligned.
    Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */     Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */
   
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
        void *instruction, int size);        void *instruction, sljit_si size);
   
 /* Returns with non-zero if fpu is available. */  /* Returns with non-zero if fpu is available. */
   
SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void);SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void);
   
 /* Note: dst is the left and src is the right operand for SLJIT_FCMP.  /* Note: dst is the left and src is the right operand for SLJIT_FCMP.
   Note: NaN check is always performed. If SLJIT_C_FLOAT_NAN is set,   Note: NaN check is always performed. If SLJIT_C_FLOAT_UNORDERED is set,
          the comparison result is unpredictable.           the comparison result is unpredictable.
   Flags: E | S (see SLJIT_C_FLOAT_*) */   Flags: SP | E | S (see SLJIT_C_FLOAT_*) */
#define SLJIT_FCMP                        34#define SLJIT_CMPD                        36
/* Flags: - (never set any flags) */#define SLJIT_CMPS                      (SLJIT_CMPD | SLJIT_SINGLE_OP)
#define SLJIT_FMOV                        35/* Flags: SP - (never set any flags) */
/* Flags: - (never set any flags) */#define SLJIT_MOVD                        37
#define SLJIT_FNEG                        36#define SLJIT_MOVS                      (SLJIT_MOVD | SLJIT_SINGLE_OP)
/* Flags: - (never set any flags) *//* Flags: SP - (never set any flags) */
#define SLJIT_FABS                       37#define SLJIT_NEGD                        38
 #define SLJIT_NEGS                      (SLJIT_NEGD | SLJIT_SINGLE_OP)
 /* Flags: SP - (never set any flags) */
 #define SLJIT_ABSD                    39
 #define SLJIT_ABSS                       (SLJIT_ABSD | SLJIT_SINGLE_OP)
   
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
        int dst, sljit_w dstw,        sljit_si dst, sljit_sw dstw,
        int src, sljit_w srcw);        sljit_si src, sljit_sw srcw);
   
/* Flags: - (never set any flags) *//* Flags: SP - (never set any flags) */
#define SLJIT_FADD                      38#define SLJIT_ADDD                      40
/* Flags: - (never set any flags) */#define SLJIT_ADDS                      (SLJIT_ADDD | SLJIT_SINGLE_OP)
#define SLJIT_FSUB                    39/* Flags: SP - (never set any flags) */
/* Flags: - (never set any flags) */#define SLJIT_SUBD                    41
#define SLJIT_FMUL                        40#define SLJIT_SUBS                      (SLJIT_SUBD | SLJIT_SINGLE_OP)
/* Flags: - (never set any flags) *//* Flags: SP - (never set any flags) */
#define SLJIT_FDIV                        41#define SLJIT_MULD                        42
 #define SLJIT_MULS                      (SLJIT_MULD | SLJIT_SINGLE_OP)
 /* Flags: SP - (never set any flags) */
 #define SLJIT_DIVD                        43
 #define SLJIT_DIVS                      (SLJIT_DIVD | SLJIT_SINGLE_OP)
   
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
        int dst, sljit_w dstw,        sljit_si dst, sljit_sw dstw,
        int src1, sljit_w src1w,        sljit_si src1, sljit_sw src1w,
        int src2, sljit_w src2w);        sljit_si src2, sljit_sw src2w);
   
 /* Label and jump instructions. */  /* Label and jump instructions. */
   
Line 677  SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emi Line 796  SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emi
 #define SLJIT_C_FLOAT_GREATER_EQUAL     17  #define SLJIT_C_FLOAT_GREATER_EQUAL     17
 #define SLJIT_C_FLOAT_GREATER           18  #define SLJIT_C_FLOAT_GREATER           18
 #define SLJIT_C_FLOAT_LESS_EQUAL        19  #define SLJIT_C_FLOAT_LESS_EQUAL        19
#define SLJIT_C_FLOAT_NAN                20#define SLJIT_C_FLOAT_UNORDERED                20
#define SLJIT_C_FLOAT_NOT_NAN                21#define SLJIT_C_FLOAT_ORDERED                21
   
 #define SLJIT_JUMP                      22  #define SLJIT_JUMP                      22
 #define SLJIT_FAST_CALL                 23  #define SLJIT_FAST_CALL                 23
Line 697  SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emi Line 816  SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emi
     type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP      type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
    Flags: - (never set any flags) for both conditional and unconditional jumps.     Flags: - (never set any flags) for both conditional and unconditional jumps.
    Flags: destroy all flags for calls. */     Flags: destroy all flags for calls. */
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type);SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type);
   
 /* Basic arithmetic comparison. In most architectures it is implemented as  /* Basic arithmetic comparison. In most architectures it is implemented as
    an SLJIT_SUB operation (with SLJIT_UNUSED destination and setting     an SLJIT_SUB operation (with SLJIT_UNUSED destination and setting
Line 707  SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit Line 826  SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit
     type must be between SLJIT_C_EQUAL and SLJIT_C_SIG_LESS_EQUAL      type must be between SLJIT_C_EQUAL and SLJIT_C_SIG_LESS_EQUAL
     type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP or SLJIT_INT_OP      type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP or SLJIT_INT_OP
    Flags: destroy flags. */     Flags: destroy flags. */
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, int type,SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type,
        int src1, sljit_w src1w,        sljit_si src1, sljit_sw src1w,
        int src2, sljit_w src2w);        sljit_si src2, sljit_sw src2w);
   
 /* Basic floating point comparison. In most architectures it is implemented as  /* Basic floating point comparison. In most architectures it is implemented as
    an SLJIT_FCMP operation (setting appropriate flags) followed by a     an SLJIT_FCMP operation (setting appropriate flags) followed by a
    sljit_emit_jump. However some architectures (i.e: MIPS) may employ     sljit_emit_jump. However some architectures (i.e: MIPS) may employ
    special optimizations here. It is suggested to use this comparison form     special optimizations here. It is suggested to use this comparison form
    when appropriate.     when appropriate.
    type must be between SLJIT_C_FLOAT_EQUAL and SLJIT_C_FLOAT_NOT_NAN    type must be between SLJIT_C_FLOAT_EQUAL and SLJIT_C_FLOAT_ORDERED
    type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP    type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP and SLJIT_SINGLE_OP
    Flags: destroy flags.     Flags: destroy flags.
    Note: if either operand is NaN, the behaviour is undefined for     Note: if either operand is NaN, the behaviour is undefined for
          type <= SLJIT_C_FLOAT_LESS_EQUAL. */           type <= SLJIT_C_FLOAT_LESS_EQUAL. */
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, int type,SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type,
        int src1, sljit_w src1w,        sljit_si src1, sljit_sw src1w,
        int src2, sljit_w src2w);        sljit_si src2, sljit_sw src2w);
   
 /* Set the destination of the jump to this label. */  /* Set the destination of the jump to this label. */
 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label);  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label);
Line 737  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct  Line 856  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct 
     Indirect form: any other valid addressing mode      Indirect form: any other valid addressing mode
    Flags: - (never set any flags) for unconditional jumps.     Flags: - (never set any flags) for unconditional jumps.
    Flags: destroy all flags for calls. */     Flags: destroy all flags for calls. */
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw);SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw);
   
/* If op == SLJIT_MOV:/* Perform the operation using the conditional flags as the second argument.
     Set dst to 1 if condition is fulfilled, 0 otherwise   Type must always be between SLJIT_C_EQUAL and SLJIT_C_FLOAT_ORDERED. The
       type must be between SLJIT_C_EQUAL and SLJIT_C_FLOAT_NOT_NAN   value represented by the type is 1, if the condition represented by the type
    is fulfilled, and 0 otherwise.
 
    If op == SLJIT_MOV, SLJIT_MOV_SI, SLJIT_MOV_UI:
      Set dst to the value represented by the type (0 or 1).
      Src must be SLJIT_UNUSED, and srcw must be 0
      Flags: - (never set any flags)       Flags: - (never set any flags)
   If op == SLJIT_OR   If op == SLJIT_OR, op == SLJIT_AND, op == SLJIT_XOR
     Dst is used as src as well, and set its lowest bit to 1 if     Performs the binary operation using src as the first, and the value
     the condition is fulfilled. Otherwise it does nothing.     represented by type as the second argument.
     Flags: E | K     Important note: only dst=src and dstw=srcw is supported at the moment!
   Note: sljit_emit_cond_value does nothing, if dst is SLJIT_UNUSED (regardless of op). */     Flags: I | E | K
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type);   Note: sljit_emit_op_flags does nothing, if dst is SLJIT_UNUSED (regardless of op). */
 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op,
         sljit_si dst, sljit_sw dstw,
         sljit_si src, sljit_sw srcw,
         sljit_si type);
   
/* Copies the base address of SLJIT_MEM1(SLJIT_LOCALS_REG)+offset to dst./* Copies the base address of SLJIT_LOCALS_REG+offset to dst.
    Flags: - (never set any flags) */     Flags: - (never set any flags) */
SLJIT_API_FUNC_ATTRIBUTE int sljit_get_local_base(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w offset);SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset);
   
 /* The constant can be changed runtime (see: sljit_set_const)  /* The constant can be changed runtime (see: sljit_set_const)
    Flags: - (never set any flags) */     Flags: - (never set any flags) */
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value);SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value);
   
 /* After the code generation the address for label, jump and const instructions  /* After the code generation the address for label, jump and const instructions
   are computed. Since these structures are freed sljit_free_compiler, the   are computed. Since these structures are freed by sljit_free_compiler, the
    addresses must be preserved by the user program elsewere. */     addresses must be preserved by the user program elsewere. */
 static SLJIT_INLINE sljit_uw sljit_get_label_addr(struct sljit_label *label) { return label->addr; }  static SLJIT_INLINE sljit_uw sljit_get_label_addr(struct sljit_label *label) { return label->addr; }
 static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; }  static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; }
Line 767  static SLJIT_INLINE sljit_uw sljit_get_const_addr(stru Line 895  static SLJIT_INLINE sljit_uw sljit_get_const_addr(stru
   
 /* Only the address is required to rewrite the code. */  /* Only the address is required to rewrite the code. */
 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr);  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr);
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant);SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant);
   
 /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
 /*  Miscellaneous utility functions                                      */  /*  Miscellaneous utility functions                                      */
 /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
   
 #define SLJIT_MAJOR_VERSION     0  #define SLJIT_MAJOR_VERSION     0
#define SLJIT_MINOR_VERSION     88#define SLJIT_MINOR_VERSION     91
   
/* Get the human readable name of the platfrom./* Get the human readable name of the platform. Can be useful on platforms
   Can be useful for debugging on platforms like ARM, where ARM and   like ARM, where ARM and Thumb2 functions can be mixed, and
   Thumb2 functions can be mixed. */   it is useful to know the type of the code generator. */
 SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void);  SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void);
   
/* Portble helper function to get an offset of a member. *//* Portable helper function to get an offset of a member. */
#define SLJIT_OFFSETOF(base, member) ((sljit_w)(&((base*)0x10)->member) - 0x10)#define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((base*)0x10)->member) - 0x10)
   
 #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)  #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
 /* This global lock is useful to compile common functions. */  /* This global lock is useful to compile common functions. */
Line 831  SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_st Line 959  SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_st
    since the growth ratio can be added to the current limit, and sljit_stack_resize     since the growth ratio can be added to the current limit, and sljit_stack_resize
    will do all the necessary checks. The fields of the stack are not changed if     will do all the necessary checks. The fields of the stack are not changed if
    sljit_stack_resize fails. */     sljit_stack_resize fails. */
SLJIT_API_FUNC_ATTRIBUTE sljit_w SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit);SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit);
   
 #endif /* (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) */  #endif /* (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) */
   
 #if !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)  #if !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
   
 /* Get the entry address of a given function. */  /* Get the entry address of a given function. */
#define SLJIT_FUNC_OFFSET(func_name)    ((sljit_w)func_name)#define SLJIT_FUNC_OFFSET(func_name)    ((sljit_sw)func_name)
   
 #else /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */  #else /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */
   
 /* All JIT related code should be placed in the same context (library, binary, etc.). */  /* All JIT related code should be placed in the same context (library, binary, etc.). */
   
#define SLJIT_FUNC_OFFSET(func_name)    ((sljit_w)*(void**)func_name)#define SLJIT_FUNC_OFFSET(func_name)    (*(sljit_sw*)(void*)func_name)
   
 /* For powerpc64, the function pointers point to a context descriptor. */  /* For powerpc64, the function pointers point to a context descriptor. */
 struct sljit_function_context {  struct sljit_function_context {
        sljit_w addr;        sljit_sw addr;
        sljit_w r2;        sljit_sw r2;
        sljit_w r11;        sljit_sw r11;
 };  };
   
 /* Fill the context arguments using the addr and the function.  /* Fill the context arguments using the addr and the function.
    If func_ptr is NULL, it will not be set to the address of context     If func_ptr is NULL, it will not be set to the address of context
    If addr is NULL, the function address also comes from the func pointer. */     If addr is NULL, the function address also comes from the func pointer. */
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_w addr, void* func);SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func);
   
 #endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */  #endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */
   

Removed from v.1.1.1.3  
changed lines
  Added in v.1.1.1.4


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>