Diff for /embedaddon/pcre/sljit/sljitLir.h between versions 1.1 and 1.1.1.5

version 1.1, 2012/02/21 23:05:52 version 1.1.1.5, 2014/06/15 19:46:05
Line 1 Line 1
 /*  /*
  *    Stack-less Just-In-Time compiler   *    Stack-less Just-In-Time compiler
  *   *
 *    Copyright 2009-2010 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. *    Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
  *   *
  * Redistribution and use in source and binary forms, with or without modification, are   * Redistribution and use in source and binary forms, with or without modification, are
  * permitted provided that the following conditions are met:   * permitted provided that the following conditions are met:
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.
           You can disable unneeded features (multithreading in single
           threaded applications), and you can use your own system functions
           (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 and max 3+2 general, 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 general 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 64 Line 75
 #if !(defined SLJIT_NO_DEFAULT_CONFIG && SLJIT_NO_DEFAULT_CONFIG)  #if !(defined SLJIT_NO_DEFAULT_CONFIG && SLJIT_NO_DEFAULT_CONFIG)
 #include "sljitConfig.h"  #include "sljitConfig.h"
 #endif  #endif
   
   /* The following header file defines useful macros for fine tuning
   sljit based code generators. They are listed in the beginning
   of sljitConfigInternal.h */
   
 #include "sljitConfigInternal.h"  #include "sljitConfigInternal.h"
   
 /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
Line 90 Line 106
   
 #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
   
/* General (saved) registers preserve their values across function calls. *//* Saved registers whose preserve their values across function calls. */
#define SLJIT_GENERAL_REG1   6#define SLJIT_SAVED_REG1   6
#define SLJIT_GENERAL_REG2   7#define SLJIT_SAVED_REG2   7
#define SLJIT_GENERAL_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
#define SLJIT_GENERAL_EREG1  9   loads & stores). */
#define SLJIT_GENERAL_EREG2  10#define SLJIT_SAVED_EREG1  9
 #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).
/* Note: SLJIT_MEM2( ... , SLJIT_LOCALS_REG) is not supported (x86 limitation). */   Only SLJIT_MEM1(SLJIT_LOCALS_REG) addressing mode is allowed since
/* Note: SLJIT_LOCALS_REG is not necessary the real stack pointer. See sljit_emit_enter. */   several ABIs has certain limitations about the stack layout. However
    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 120 Line 141
   
 /* Return with machine word. */  /* Return with machine word. */
   
#define SLJIT_RETURN_REG        SLJIT_TEMPORARY_REG1#define SLJIT_RETURN_REG        SLJIT_SCRATCH_REG1
   
/* x86 prefers temporary registers for special purposes. If other/* x86 prefers specific registers for special purposes. In case of shift
   registers are used such purpose, it costs a little performance   by register it supports only SLJIT_SCRATCH_REG3 for shift argument
   drawback. It doesn't matter for other archs. */   (which is the src2 argument of sljit_emit_op2). If another register is
    used, sljit must exchange data between registers which cause a minor
    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 135 Line 158
 /* 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 149 Line 177
 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 162  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 175  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 188  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 general registers. */        /* Used saved registers. */
        int generals;        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 temporaries_start;        sljit_si locals_offset;
        int generals_start;        sljit_si scratches_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;
#ifdef _WIN64 
        int has_locals; 
 #endif  #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 221  struct sljit_compiler { Line 248  struct sljit_compiler {
         sljit_ub *cpool_unique;          sljit_ub *cpool_unique;
         sljit_uw cpool_diff;          sljit_uw cpool_diff;
         sljit_uw cpool_fill;          sljit_uw cpool_fill;
        /* General fields. */        /* Other members. */
         /* Contains pointer, "ldr pc, [...]" pairs. */          /* Contains pointer, "ldr pc, [...]" pairs. */
         sljit_uw patches;          sljit_uw patches;
 #endif  #endif
Line 229  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)
        int has_locals;        sljit_sw imm;
        sljit_w imm;        sljit_si cache_arg;
        int cache_arg;        sljit_sw cache_argw;
        sljit_w 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 has_locals;        sljit_si delay_slot;
        int delay_slot;        sljit_si cache_arg;
        int cache_arg;        sljit_sw cache_argw;
        sljit_w 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_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
           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)
           /* Local size passed to the functions. */
           sljit_si logical_local_size;
   #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 268  struct sljit_compiler { Line 309  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 294  SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(str Line 342  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. */
   
 /*  /*
   Entry instruction. The instruction has "args" number of arguments   The executable code is basically a function call from the viewpoint of
   and will use the first "general" number of general registers.   the C language. The function calls must obey to the ABI (Application
   The arguments are passed into the general registers (arg1 to general_reg1, and so on).   Binary Interface) of the platform, which specify the purpose of machine
   Thus, "args" must be less or equal than "general". A local_size extra   registers and stack handling among other things. The sljit_emit_enter
   stack space is allocated for the jit code (must be less or equal than   function emits the necessary instructions for setting up a new context
   SLJIT_MAX_LOCAL_SIZE), which can accessed through SLJIT_LOCALS_REG (see   for the executable code and moves function arguments to the saved
   the notes there). SLJIT_LOCALS_REG is not necessary the real stack pointer!   registers. The number of arguments are specified in the "args"
   It just points somewhere in the stack if local_size > 0 (!). Thus, the only   parameter and the first argument goes to SLJIT_SAVED_REG1, the second
   thing which is known that the memory area between SLJIT_LOCALS_REG and   goes to SLJIT_SAVED_REG2 and so on. The number of scratch and
   SLJIT_LOCALS_REG + local_size is a valid stack area if local_size > 0   saved registers are passed in "scratches" and "saveds" arguments
*/   respectively. Since the saved registers contains the arguments,
    "args" must be less or equal than "saveds". The sljit_emit_enter
    is also capable of allocating a stack space for local variables. The
    "local_size" argument contains the size in bytes of this local area
    and its staring address is stored in SLJIT_LOCALS_REG. However
    the SLJIT_LOCALS_REG is not necessary the machine stack pointer.
    The memory bytes between SLJIT_LOCALS_REG (inclusive) and
    SLJIT_LOCALS_REG + local_size (exclusive) can be modified freely
    until the function returns. The stack space is uninitialized.
   
/* Note: multiple calls of this function overwrites the previous call. */   Note: every call of sljit_emit_enter and sljit_set_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, int args, int temporaries, int generals, int local_size);SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
         sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size);
   
/* Since sljit_emit_return (and many asserts) uses variables which are initialized/* The machine code has a context (which contains the local stack space size,
   by sljit_emit_enter, a simple return is not possible if these variables are not   number of used registers, etc.) which initialized by sljit_emit_enter. Several
   initialized. sljit_fake_enter does not emit any instruction, just initialize   functions (like sljit_emit_return) requres this context to be able to generate
   those variables. */   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
    function below we can specify their context.
   
/* Note: multiple calls of this function overwrites the previous call. */   Note: every call of sljit_emit_enter and sljit_set_context overwrites
          the previous context. */
   
SLJIT_API_FUNC_ATTRIBUTE void sljit_fake_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size);SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler,
         sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size);
   
/* Return from jit. See below the possible values for src and srcw. *//* Return from machine code.  The op argument can be SLJIT_UNUSED which means the
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int src, sljit_w srcw);   function does not return with anything or any opcode between SLJIT_MOV and
    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
    destination arguments. */
   
/* 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 general 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, int args, int temporaries, int generals, int local_size);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 360  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(st Line 430  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)
 */  */
   
 /*  /*
   IMPORATNT NOTE: memory access MUST be naturally aligned.   IMPORATNT NOTE: memory access MUST be naturally aligned except
                    SLJIT_UNALIGNED macro is defined and its value is 1.
 
      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 defined     word   | 4 byte if SLJIT_32BIT_ARCHITECTURE is defined and its value is 1
            | 8 byte if SLJIT_64BIT_ARCHITECTURE defined            | 8 byte if SLJIT_64BIT_ARCHITECTURE is defined and its value is 1
   (This is a strict requirement for embedded systems.)    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 398  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(st Line 485  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 445  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(st Line 551  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)
      Unsigned multiplication of SLJIT_SCRATCH_REG1 and SLJIT_SCRATCH_REG2.
      Result goes to SLJIT_SCRATCH_REG2:SLJIT_SCRATCH_REG1 (high:low) word */
   #define SLJIT_UMUL                      2
   /* Flags: - (may destroy flags)
      Signed multiplication of SLJIT_SCRATCH_REG1 and SLJIT_SCRATCH_REG2.
      Result goes to SLJIT_SCRATCH_REG2:SLJIT_SCRATCH_REG1 (high:low) word */
   #define SLJIT_SMUL                      3
   /* Flags: I - (may destroy flags)
      Unsigned divide of the value in SLJIT_SCRATCH_REG1 by the value in SLJIT_SCRATCH_REG2.
      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_UDIV                      4
   #define SLJIT_IUDIV                     (SLJIT_UDIV | SLJIT_INT_OP)
   /* Flags: I - (may destroy flags)
      Signed divide of the value in SLJIT_SCRATCH_REG1 by the value in SLJIT_SCRATCH_REG2.
      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_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                       2#define SLJIT_MOV                       6
 /* Flags: I - (never set any flags) */
 #define SLJIT_MOV_UB                    7
 #define SLJIT_IMOV_UB                   (SLJIT_MOV_UB | SLJIT_INT_OP)
 /* Flags: I - (never set any flags) */
 #define SLJIT_MOV_SB                    8
 #define SLJIT_IMOV_SB                   (SLJIT_MOV_SB | SLJIT_INT_OP)
 /* Flags: I - (never set any flags) */
 #define SLJIT_MOV_UH                    9
 #define SLJIT_IMOV_UH                   (SLJIT_MOV_UH | SLJIT_INT_OP)
 /* Flags: I - (never set any flags) */
 #define SLJIT_MOV_SH                    10
 #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
 /* 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_IMOV                      (SLJIT_MOV_SI | SLJIT_INT_OP)
 /* Flags: - (never set any flags) */  /* Flags: - (never set any flags) */
#define SLJIT_MOV_UB                      3#define SLJIT_MOV_P                       13
 /* Flags: - (never set any flags) */  /* Flags: - (never set any flags) */
#define SLJIT_MOV_SB                     4#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_MOV_UH                    5#define SLJIT_MOVU_P                       21
/* Flags: - (never set any flags) */ 
#define SLJIT_MOV_SH                    6 
/* Flags: - (never set any flags) */ 
#define SLJIT_MOV_UI                    7 
/* Flags: - (never set any flags) */ 
#define SLJIT_MOV_SI                    8 
/* Flags: - (never set any flags) */ 
#define SLJIT_MOVU                      9 
/* Flags: - (never set any flags) */ 
#define SLJIT_MOVU_UB                      10 
/* Flags: - (never set any flags) */ 
#define SLJIT_MOVU_SB                   11 
/* Flags: - (never set any flags) */ 
#define SLJIT_MOVU_UH                   12 
/* Flags: - (never set any flags) */ 
#define SLJIT_MOVU_SH                   13 
/* Flags: - (never set any flags) */ 
#define SLJIT_MOVU_UI                   14 
/* Flags: - (never set any flags) */ 
#define SLJIT_MOVU_SI                   15 
 /* Flags: I | E | K */  /* Flags: I | E | K */
#define SLJIT_NOT                       16#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                       17#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                       18   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                       19#define SLJIT_ADD                       25
 #define SLJIT_IADD                      (SLJIT_ADD | SLJIT_INT_OP)
 /* Flags: I | C | K */  /* Flags: I | C | K */
#define SLJIT_ADDC                      20#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                       21#define SLJIT_SUB                       27
 #define SLJIT_ISUB                      (SLJIT_SUB | SLJIT_INT_OP)
 /* Flags: I | C | K */  /* Flags: I | C | K */
#define SLJIT_SUBC                      22#define SLJIT_SUBC                      28
/* Note: integer mul */#define SLJIT_ISUBC                     (SLJIT_SUBC | SLJIT_INT_OP)
/* Flags: I | O (see SLJIT_C_MUL_*) | K *//* Note: integer mul
#define SLJIT_MUL                       23   Flags: I | O (see SLJIT_C_MUL_*) | K */
 #define SLJIT_MUL                       29
 #define SLJIT_IMUL                      (SLJIT_MUL | SLJIT_INT_OP)
 /* Flags: I | E | K */  /* Flags: I | E | K */
#define SLJIT_AND                       24#define SLJIT_AND                       30
 #define SLJIT_IAND                      (SLJIT_AND | SLJIT_INT_OP)
 /* Flags: I | E | K */  /* Flags: I | E | K */
#define SLJIT_OR                        25#define SLJIT_OR                        31
 #define SLJIT_IOR                       (SLJIT_OR | SLJIT_INT_OP)
 /* Flags: I | E | K */  /* Flags: I | E | K */
#define SLJIT_XOR                       26#define SLJIT_XOR                       32
/* Flags: I | E | K */#define SLJIT_IXOR                      (SLJIT_XOR | SLJIT_INT_OP)
#define SLJIT_SHL                       27/* Flags: I | E | K
/* Flags: I | E | K */   Let bit_length be the length of the shift operation: 32 or 64.
#define SLJIT_LSHR                      28   If src2 is immediate, src2w is masked by (bit_length - 1).
/* Flags: I | E | K */   Otherwise, if the content of src2 is outside the range from 0
#define SLJIT_ASHR                      29   to bit_length - 1, the operation is undefined. */
 #define SLJIT_SHL                       33
 #define SLJIT_ISHL                      (SLJIT_SHL | SLJIT_INT_OP)
 /* Flags: I | E | K
    Let bit_length be the length of the shift operation: 32 or 64.
    If src2 is immediate, src2w is masked by (bit_length - 1).
    Otherwise, if the content of src2 is outside the range from 0
    to bit_length - 1, the operation is undefined. */
 #define SLJIT_LSHR                      34
 #define SLJIT_ILSHR                     (SLJIT_LSHR | SLJIT_INT_OP)
 /* Flags: I | E | K
    Let bit_length be the length of the shift operation: 32 or 64.
    If src2 is immediate, src2w is masked by (bit_length - 1).
    Otherwise, if the content of src2 is outside the range from 0
    to bit_length - 1, the operation is undefined. */
 #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);
   
SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void);/* The following function is a helper function for sljit_emit_op_custom.
    It returns with the real machine register index of any SLJIT_SCRATCH
    SLJIT_SAVED or SLJIT_LOCALS register.
    Note: it returns with -1 for virtual registers (all EREGs on x86-32). */
   
   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
      sljit_emit_op_custom. It has a similar purpose as inline assembly.
      The size parameter must match to the instruction size of the target
      architecture:
   
            x86: 0 < size <= 15. The instruction argument can be byte aligned.
         Thumb2: if size == 2, the instruction argument must be 2 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. */
   
   SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
           void *instruction, sljit_si size);
   
   /* Returns with non-zero if fpu is available. */
   
   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                        30#define SLJIT_CMPD                        36
/* Flags: - (never set any flags) */#define SLJIT_CMPS                      (SLJIT_CMPD | SLJIT_SINGLE_OP)
#define SLJIT_FMOV                        31/* Flags: SP - (never set any flags) */
/* Flags: - (never set any flags) */#define SLJIT_MOVD                        37
#define SLJIT_FNEG                        32#define SLJIT_MOVS                      (SLJIT_MOVD | SLJIT_SINGLE_OP)
/* Flags: - (never set any flags) *//* Flags: SP - (never set any flags) */
#define SLJIT_FABS                       33#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                      34#define SLJIT_ADDD                      40
/* Flags: - (never set any flags) */#define SLJIT_ADDS                      (SLJIT_ADDD | SLJIT_SINGLE_OP)
#define SLJIT_FSUB                    35/* Flags: SP - (never set any flags) */
/* Flags: - (never set any flags) */#define SLJIT_SUBD                    41
#define SLJIT_FMUL                    36#define SLJIT_SUBS                      (SLJIT_SUBD | SLJIT_SINGLE_OP)
/* Flags: - (never set any flags) *//* Flags: SP - (never set any flags) */
#define SLJIT_FDIV                    37#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 588  SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emi Line 801  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 608  SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emi Line 821  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 equal to/* Basic arithmetic comparison. In most architectures it is implemented as
   an SLJIT_SUB operation (with SLJIT_UNUSED destination) followed by a   an SLJIT_SUB operation (with SLJIT_UNUSED destination and setting
   sljit_emit_jump. However some architectures (i.e: MIPS) may employ   appropriate flags) followed by a sljit_emit_jump. However some
   special optimizations here. It is suggested to use this comparison   architectures (i.e: MIPS) may employ special optimizations here. It is
   form when flags are unimportant.   suggested to use this comparison form when appropriate.
     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
      an SLJIT_FCMP operation (setting appropriate flags) followed by a
      sljit_emit_jump. However some architectures (i.e: MIPS) may employ
      special optimizations here. It is suggested to use this comparison form
      when appropriate.
       type must be between SLJIT_C_FLOAT_EQUAL and SLJIT_C_FLOAT_ORDERED
       type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP and SLJIT_SINGLE_OP
      Flags: destroy flags.
      Note: if either operand is NaN, the behaviour is undefined for
            type <= SLJIT_C_FLOAT_LESS_EQUAL. */
   SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type,
           sljit_si src1, sljit_sw src1w,
           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);
 /* Only for jumps defined with SLJIT_REWRITABLE_JUMP flag.  /* Only for jumps defined with SLJIT_REWRITABLE_JUMP flag.
Line 634  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct  Line 861  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_LOCALS_REG+offset to dst.
      Flags: - (never set any flags) */
   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 660  static SLJIT_INLINE sljit_uw sljit_get_const_addr(stru Line 900  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     82#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 724  SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_st Line 964  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  
changed lines
  Added in v.1.1.1.5


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