Update bundled PCRE2-library to version 10.23
Some manual changes done to the library were lost with this update. They will be added in the next commit.
This commit is contained in:
@ -82,7 +82,7 @@
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/* If SLJIT_STD_MACROS_DEFINED is not defined, the application should
|
||||
define SLJIT_MALLOC, SLJIT_FREE, SLJIT_MEMMOVE, and NULL. */
|
||||
define SLJIT_MALLOC, SLJIT_FREE, SLJIT_MEMCPY, and NULL. */
|
||||
#ifndef SLJIT_STD_MACROS_DEFINED
|
||||
/* Disabled by default. */
|
||||
#define SLJIT_STD_MACROS_DEFINED 0
|
||||
@ -90,10 +90,20 @@
|
||||
|
||||
/* Executable code allocation:
|
||||
If SLJIT_EXECUTABLE_ALLOCATOR is not defined, the application should
|
||||
define both SLJIT_MALLOC_EXEC and SLJIT_FREE_EXEC. */
|
||||
define SLJIT_MALLOC_EXEC, SLJIT_FREE_EXEC, and SLJIT_EXEC_OFFSET. */
|
||||
#ifndef SLJIT_EXECUTABLE_ALLOCATOR
|
||||
/* Enabled by default. */
|
||||
#define SLJIT_EXECUTABLE_ALLOCATOR 1
|
||||
|
||||
/* When SLJIT_PROT_EXECUTABLE_ALLOCATOR is enabled SLJIT uses
|
||||
an allocator which does not set writable and executable
|
||||
permission flags at the same time. The trade-of is increased
|
||||
memory consumption and disabled dynamic code modifications. */
|
||||
#ifndef SLJIT_PROT_EXECUTABLE_ALLOCATOR
|
||||
/* Disabled by default. */
|
||||
#define SLJIT_PROT_EXECUTABLE_ALLOCATOR 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Force cdecl calling convention even if a better calling
|
||||
|
||||
@ -31,14 +31,14 @@
|
||||
SLJIT defines the following architecture dependent types and macros:
|
||||
|
||||
Types:
|
||||
sljit_sb, sljit_ub : signed and unsigned 8 bit byte
|
||||
sljit_sh, sljit_uh : signed and unsigned 16 bit half-word (short) type
|
||||
sljit_si, sljit_ui : signed and unsigned 32 bit integer type
|
||||
sljit_sw, sljit_uw : signed and unsigned machine word, enough to store a pointer
|
||||
sljit_p : unsgined pointer value (usually the same as sljit_uw, but
|
||||
some 64 bit ABIs may use 32 bit pointers)
|
||||
sljit_s : single precision floating point value
|
||||
sljit_d : double precision floating point value
|
||||
sljit_s8, sljit_u8 : signed and unsigned 8 bit integer type
|
||||
sljit_s16, sljit_u16 : signed and unsigned 16 bit integer type
|
||||
sljit_s32, sljit_u32 : signed and unsigned 32 bit integer type
|
||||
sljit_sw, sljit_uw : signed and unsigned machine word, enough to store a pointer
|
||||
sljit_p : unsgined pointer value (usually the same as sljit_uw, but
|
||||
some 64 bit ABIs may use 32 bit pointers)
|
||||
sljit_f32 : 32 bit single precision floating point value
|
||||
sljit_f64 : 64 bit double precision floating point value
|
||||
|
||||
Macros for feature detection (boolean):
|
||||
SLJIT_32BIT_ARCHITECTURE : 32 bit architecture
|
||||
@ -56,10 +56,10 @@
|
||||
SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS : number of available floating point scratch registers
|
||||
SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS : number of available floating point saved registers
|
||||
SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_sw/sljit_uw array by index
|
||||
SLJIT_DOUBLE_SHIFT : the shift required to apply when accessing
|
||||
a double precision floating point array by index
|
||||
SLJIT_SINGLE_SHIFT : the shift required to apply when accessing
|
||||
a single precision floating point array by index
|
||||
SLJIT_F32_SHIFT : the shift required to apply when accessing
|
||||
a single precision floating point array by index
|
||||
SLJIT_F64_SHIFT : the shift required to apply when accessing
|
||||
a double precision floating point array by index
|
||||
SLJIT_LOCALS_OFFSET : local space starting offset (SLJIT_SP + SLJIT_LOCALS_OFFSET)
|
||||
SLJIT_RETURN_ADDRESS_OFFSET : a return instruction always adds this offset to the return address
|
||||
|
||||
@ -187,14 +187,6 @@
|
||||
/* External function definitions. */
|
||||
/**********************************/
|
||||
|
||||
#if !(defined SLJIT_STD_MACROS_DEFINED && SLJIT_STD_MACROS_DEFINED)
|
||||
|
||||
/* These libraries are needed for the macros below. */
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#endif /* SLJIT_STD_MACROS_DEFINED */
|
||||
|
||||
/* General macros:
|
||||
Note: SLJIT is designed to be independent from them as possible.
|
||||
|
||||
@ -210,8 +202,8 @@
|
||||
#define SLJIT_FREE(ptr, allocator_data) free(ptr)
|
||||
#endif
|
||||
|
||||
#ifndef SLJIT_MEMMOVE
|
||||
#define SLJIT_MEMMOVE(dest, src, len) memmove(dest, src, len)
|
||||
#ifndef SLJIT_MEMCPY
|
||||
#define SLJIT_MEMCPY(dest, src, len) memcpy(dest, src, len)
|
||||
#endif
|
||||
|
||||
#ifndef SLJIT_ZEROMEM
|
||||
@ -252,11 +244,6 @@
|
||||
#endif
|
||||
#endif /* !SLJIT_INLINE */
|
||||
|
||||
#ifndef SLJIT_CONST
|
||||
/* Const variables. */
|
||||
#define SLJIT_CONST const
|
||||
#endif
|
||||
|
||||
#ifndef SLJIT_UNUSED_ARG
|
||||
/* Unused arguments. */
|
||||
#define SLJIT_UNUSED_ARG(arg) (void)arg
|
||||
@ -284,6 +271,15 @@
|
||||
/* Instruction cache flush. */
|
||||
/****************************/
|
||||
|
||||
#if (!defined SLJIT_CACHE_FLUSH && defined __has_builtin)
|
||||
#if __has_builtin(__builtin___clear_cache)
|
||||
|
||||
#define SLJIT_CACHE_FLUSH(from, to) \
|
||||
__builtin___clear_cache((char*)from, (char*)to)
|
||||
|
||||
#endif /* __has_builtin(__builtin___clear_cache) */
|
||||
#endif /* (!defined SLJIT_CACHE_FLUSH && defined __has_builtin) */
|
||||
|
||||
#ifndef SLJIT_CACHE_FLUSH
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
|
||||
@ -300,6 +296,11 @@
|
||||
#define SLJIT_CACHE_FLUSH(from, to) \
|
||||
sys_icache_invalidate((char*)(from), (char*)(to) - (char*)(from))
|
||||
|
||||
#elif (defined(__GNUC__) && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
|
||||
|
||||
#define SLJIT_CACHE_FLUSH(from, to) \
|
||||
__builtin___clear_cache((char*)from, (char*)to)
|
||||
|
||||
#elif defined __ANDROID__
|
||||
|
||||
/* Android lacks __clear_cache; instead, cacheflush should be used. */
|
||||
@ -312,12 +313,14 @@
|
||||
/* The __clear_cache() implementation of GCC is a dummy function on PowerPC. */
|
||||
#define SLJIT_CACHE_FLUSH(from, to) \
|
||||
ppc_cache_flush((from), (to))
|
||||
#define SLJIT_CACHE_FLUSH_OWN_IMPL 1
|
||||
|
||||
#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
|
||||
/* The __clear_cache() implementation of GCC is a dummy function on Sparc. */
|
||||
#define SLJIT_CACHE_FLUSH(from, to) \
|
||||
sparc_cache_flush((from), (to))
|
||||
#define SLJIT_CACHE_FLUSH_OWN_IMPL 1
|
||||
|
||||
#else
|
||||
|
||||
@ -330,20 +333,20 @@
|
||||
#endif /* !SLJIT_CACHE_FLUSH */
|
||||
|
||||
/******************************************************/
|
||||
/* Byte/half/int/word/single/double type definitions. */
|
||||
/* Integer and floating point type definitions. */
|
||||
/******************************************************/
|
||||
|
||||
/* 8 bit byte type. */
|
||||
typedef unsigned char sljit_ub;
|
||||
typedef signed char sljit_sb;
|
||||
typedef unsigned char sljit_u8;
|
||||
typedef signed char sljit_s8;
|
||||
|
||||
/* 16 bit half-word type. */
|
||||
typedef unsigned short int sljit_uh;
|
||||
typedef signed short int sljit_sh;
|
||||
typedef unsigned short int sljit_u16;
|
||||
typedef signed short int sljit_s16;
|
||||
|
||||
/* 32 bit integer type. */
|
||||
typedef unsigned int sljit_ui;
|
||||
typedef signed int sljit_si;
|
||||
typedef unsigned int sljit_u32;
|
||||
typedef signed int sljit_s32;
|
||||
|
||||
/* Machine word type. Enough for storing a pointer.
|
||||
32 bit for 32 bit machines.
|
||||
@ -377,15 +380,15 @@ typedef long int sljit_sw;
|
||||
typedef sljit_uw sljit_p;
|
||||
|
||||
/* Floating point types. */
|
||||
typedef float sljit_s;
|
||||
typedef double sljit_d;
|
||||
typedef float sljit_f32;
|
||||
typedef double sljit_f64;
|
||||
|
||||
/* Shift for pointer sized data. */
|
||||
#define SLJIT_POINTER_SHIFT SLJIT_WORD_SHIFT
|
||||
|
||||
/* Shift for double precision sized data. */
|
||||
#define SLJIT_DOUBLE_SHIFT 3
|
||||
#define SLJIT_SINGLE_SHIFT 2
|
||||
#define SLJIT_F32_SHIFT 2
|
||||
#define SLJIT_F64_SHIFT 3
|
||||
|
||||
#ifndef SLJIT_W
|
||||
|
||||
@ -534,6 +537,14 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr);
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void);
|
||||
#define SLJIT_MALLOC_EXEC(size) sljit_malloc_exec(size)
|
||||
#define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr)
|
||||
|
||||
#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
|
||||
#define SLJIT_EXEC_OFFSET(ptr) sljit_exec_offset(ptr)
|
||||
#else
|
||||
#define SLJIT_EXEC_OFFSET(ptr) 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**********************************************/
|
||||
@ -613,6 +624,12 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void);
|
||||
#define SLJIT_LOCALS_OFFSET_BASE ((23 + 1) * sizeof(sljit_sw))
|
||||
#endif
|
||||
|
||||
#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 10
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 5
|
||||
#define SLJIT_LOCALS_OFFSET_BASE 0
|
||||
|
||||
#elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 0
|
||||
|
||||
@ -86,7 +86,7 @@ static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
|
||||
return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size)
|
||||
static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(size);
|
||||
VirtualFree(chunk, 0, MEM_RELEASE);
|
||||
@ -96,7 +96,7 @@ static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size)
|
||||
|
||||
static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
|
||||
{
|
||||
void* retval;
|
||||
void *retval;
|
||||
|
||||
#ifdef MAP_ANON
|
||||
retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
@ -111,7 +111,7 @@ static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
|
||||
return (retval != MAP_FAILED) ? retval : NULL;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size)
|
||||
static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
|
||||
{
|
||||
munmap(chunk, size);
|
||||
}
|
||||
@ -137,10 +137,10 @@ struct free_block {
|
||||
};
|
||||
|
||||
#define AS_BLOCK_HEADER(base, offset) \
|
||||
((struct block_header*)(((sljit_ub*)base) + offset))
|
||||
((struct block_header*)(((sljit_u8*)base) + offset))
|
||||
#define AS_FREE_BLOCK(base, offset) \
|
||||
((struct free_block*)(((sljit_ub*)base) + offset))
|
||||
#define MEM_START(base) ((void*)(((sljit_ub*)base) + sizeof(struct block_header)))
|
||||
((struct free_block*)(((sljit_u8*)base) + offset))
|
||||
#define MEM_START(base) ((void*)(((sljit_u8*)base) + sizeof(struct block_header)))
|
||||
#define ALIGN_SIZE(size) (((size) + sizeof(struct block_header) + 7) & ~7)
|
||||
|
||||
static struct free_block* free_blocks;
|
||||
@ -153,7 +153,7 @@ static SLJIT_INLINE void sljit_insert_free_block(struct free_block *free_block,
|
||||
free_block->size = size;
|
||||
|
||||
free_block->next = free_blocks;
|
||||
free_block->prev = 0;
|
||||
free_block->prev = NULL;
|
||||
if (free_blocks)
|
||||
free_blocks->prev = free_block;
|
||||
free_blocks = free_block;
|
||||
@ -180,8 +180,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
|
||||
sljit_uw chunk_size;
|
||||
|
||||
allocator_grab_lock();
|
||||
if (size < sizeof(struct free_block))
|
||||
size = sizeof(struct free_block);
|
||||
if (size < (64 - sizeof(struct block_header)))
|
||||
size = (64 - sizeof(struct block_header));
|
||||
size = ALIGN_SIZE(size);
|
||||
|
||||
free_block = free_blocks;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -99,6 +99,8 @@ of sljitConfigInternal.h */
|
||||
#define SLJIT_ERR_UNSUPPORTED 4
|
||||
/* An ivalid argument is passed to any SLJIT function. */
|
||||
#define SLJIT_ERR_BAD_ARGUMENT 5
|
||||
/* Dynamic code modification is not enabled. */
|
||||
#define SLJIT_ERR_DYN_CODE_MOD 6
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Registers */
|
||||
@ -226,7 +228,7 @@ of sljitConfigInternal.h */
|
||||
/* Floating point registers */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/* Each floating point register can store a double or single precision
|
||||
/* Each floating point register can store a 32 or a 64 bit precision
|
||||
value. The FR and FS register sets are overlap in the same way as R
|
||||
and S register sets. See above. */
|
||||
|
||||
@ -271,7 +273,7 @@ struct sljit_memory_fragment {
|
||||
struct sljit_memory_fragment *next;
|
||||
sljit_uw used_size;
|
||||
/* Must be aligned to sljit_sw. */
|
||||
sljit_ub memory[1];
|
||||
sljit_u8 memory[1];
|
||||
};
|
||||
|
||||
struct sljit_label {
|
||||
@ -297,8 +299,8 @@ struct sljit_const {
|
||||
};
|
||||
|
||||
struct sljit_compiler {
|
||||
sljit_si error;
|
||||
sljit_si options;
|
||||
sljit_s32 error;
|
||||
sljit_s32 options;
|
||||
|
||||
struct sljit_label *labels;
|
||||
struct sljit_jump *jumps;
|
||||
@ -312,36 +314,38 @@ struct sljit_compiler {
|
||||
struct sljit_memory_fragment *abuf;
|
||||
|
||||
/* Used scratch registers. */
|
||||
sljit_si scratches;
|
||||
sljit_s32 scratches;
|
||||
/* Used saved registers. */
|
||||
sljit_si saveds;
|
||||
sljit_s32 saveds;
|
||||
/* Used float scratch registers. */
|
||||
sljit_si fscratches;
|
||||
sljit_s32 fscratches;
|
||||
/* Used float saved registers. */
|
||||
sljit_si fsaveds;
|
||||
sljit_s32 fsaveds;
|
||||
/* Local stack size. */
|
||||
sljit_si local_size;
|
||||
sljit_s32 local_size;
|
||||
/* Code size. */
|
||||
sljit_uw size;
|
||||
/* For statistical purposes. */
|
||||
/* Relative offset of the executable mapping from the writable mapping. */
|
||||
sljit_uw executable_offset;
|
||||
/* Executable size for statistical purposes. */
|
||||
sljit_uw executable_size;
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
sljit_si args;
|
||||
sljit_s32 args;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
sljit_si mode32;
|
||||
sljit_s32 mode32;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
|
||||
sljit_si flags_saved;
|
||||
sljit_s32 flags_saved;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
|
||||
/* Constant pool handling. */
|
||||
sljit_uw *cpool;
|
||||
sljit_ub *cpool_unique;
|
||||
sljit_u8 *cpool_unique;
|
||||
sljit_uw cpool_diff;
|
||||
sljit_uw cpool_fill;
|
||||
/* Other members. */
|
||||
@ -352,40 +356,40 @@ struct sljit_compiler {
|
||||
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
|
||||
/* Temporary fields. */
|
||||
sljit_uw shift_imm;
|
||||
sljit_si cache_arg;
|
||||
sljit_s32 cache_arg;
|
||||
sljit_sw cache_argw;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
|
||||
sljit_si cache_arg;
|
||||
sljit_s32 cache_arg;
|
||||
sljit_sw cache_argw;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
|
||||
sljit_si cache_arg;
|
||||
sljit_s32 cache_arg;
|
||||
sljit_sw cache_argw;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
|
||||
sljit_sw imm;
|
||||
sljit_si cache_arg;
|
||||
sljit_s32 cache_arg;
|
||||
sljit_sw cache_argw;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
|
||||
sljit_si delay_slot;
|
||||
sljit_si cache_arg;
|
||||
sljit_s32 delay_slot;
|
||||
sljit_s32 cache_arg;
|
||||
sljit_sw cache_argw;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
sljit_si delay_slot;
|
||||
sljit_si cache_arg;
|
||||
sljit_s32 delay_slot;
|
||||
sljit_s32 cache_arg;
|
||||
sljit_sw cache_argw;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
|
||||
sljit_si cache_arg;
|
||||
sljit_s32 cache_arg;
|
||||
sljit_sw cache_argw;
|
||||
#endif
|
||||
|
||||
@ -396,13 +400,13 @@ struct sljit_compiler {
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
|
||||
|| (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
/* Local size passed to the functions. */
|
||||
sljit_si logical_local_size;
|
||||
sljit_s32 logical_local_size;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
|
||||
|| (defined SLJIT_DEBUG && SLJIT_DEBUG) \
|
||||
|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
sljit_si skip_checks;
|
||||
sljit_s32 skip_checks;
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -427,7 +431,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compile
|
||||
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; }
|
||||
static SLJIT_INLINE sljit_s32 sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; }
|
||||
|
||||
/* Sets the compiler error code to SLJIT_ERR_ALLOC_FAILED except
|
||||
if an error was detected before. After the error code is set
|
||||
@ -448,21 +452,40 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compi
|
||||
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, sljit_si size);
|
||||
SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size);
|
||||
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
/* Passing NULL disables verbose. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose);
|
||||
#endif
|
||||
|
||||
/*
|
||||
Create executable code from the sljit instruction stream. This is the final step
|
||||
of the code generation so no more instructions can be added after this call.
|
||||
*/
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler);
|
||||
|
||||
/* Free executable code. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code);
|
||||
|
||||
/*
|
||||
After the machine code generation is finished we can retrieve the allocated
|
||||
executable memory size, although this area may not be fully filled with
|
||||
instructions depending on some optimizations. This function is useful only
|
||||
for statistical purposes.
|
||||
When the protected executable allocator is used the JIT code is mapped
|
||||
twice. The first mapping has read/write and the second mapping has read/exec
|
||||
permissions. This function returns with the relative offset of the executable
|
||||
mapping using the writable mapping as the base after the machine code is
|
||||
successfully generated. The returned value is always 0 for the normal executable
|
||||
allocator, since it uses only one mapping with read/write/exec permissions.
|
||||
Dynamic code modifications requires this value.
|
||||
|
||||
Before a successful code generation, this function returns with 0.
|
||||
*/
|
||||
static SLJIT_INLINE sljit_sw sljit_get_executable_offset(struct sljit_compiler *compiler) { return compiler->executable_offset; }
|
||||
|
||||
/*
|
||||
The executable memory consumption of the generated code can be retrieved by
|
||||
this function. The returned value can be used for statistical purposes.
|
||||
|
||||
Before a successful code generation, this function returns with 0.
|
||||
*/
|
||||
@ -518,9 +541,9 @@ offset 0 is aligned to sljit_d. Otherwise it is aligned to sljit_uw. */
|
||||
/* The local_size must be >= 0 and <= SLJIT_MAX_LOCAL_SIZE. */
|
||||
#define SLJIT_MAX_LOCAL_SIZE 65536
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_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
|
||||
@ -532,9 +555,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
Note: every call of sljit_emit_enter and sljit_set_context overwrites
|
||||
the previous context. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size);
|
||||
|
||||
/* 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
|
||||
@ -542,8 +565,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi
|
||||
is SLJIT_UNUSED, otherwise see below the description about source and
|
||||
destination arguments. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si src, sljit_sw srcw);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 src, sljit_sw srcw);
|
||||
|
||||
/* Fast calling mechanism for utility functions (see SLJIT_FAST_CALL). All registers and
|
||||
even the stack frame is passed to the callee. The return address is preserved in
|
||||
@ -560,8 +583,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
||||
/* 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. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw);
|
||||
|
||||
/*
|
||||
Source and destination values for arithmetical instructions
|
||||
@ -624,31 +647,29 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
|
||||
#define SLJIT_MEM2(r1, r2) (SLJIT_MEM | (r1) | ((r2) << 8))
|
||||
#define SLJIT_IMM 0x40
|
||||
|
||||
/* Set 32 bit operation mode (I) on 64 bit CPUs. The flag is totally ignored on
|
||||
32 bit CPUs. If this flag is set for an arithmetic operation, it uses only the
|
||||
lower 32 bit of the input register(s), and set the CPU status flags according
|
||||
to the 32 bit result. The higher 32 bits are undefined for both the input and
|
||||
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_MOVU_SI 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
|
||||
/* Set 32 bit operation mode (I) on 64 bit CPUs. This flag is ignored on 32
|
||||
bit CPUs. When this flag is set for an arithmetic operation, only the
|
||||
lower 32 bit of the input register(s) are used, and the CPU status flags
|
||||
are set according to the 32 bit result. Although the higher 32 bit of
|
||||
the input and the result registers are not defined by SLJIT, it might be
|
||||
defined by the CPU architecture (e.g. MIPS). To satisfy these requirements
|
||||
all source registers must be computed by operations where this flag is
|
||||
also set. In other words 32 and 64 bit arithmetic operations cannot be
|
||||
mixed. The only exception is SLJIT_IMOV and SLJIT_IMOVU whose source
|
||||
register can hold any 32 or 64 bit value. This source register is
|
||||
converted to a 32 bit compatible format. SLJIT does not generate any
|
||||
instructions on certain CPUs (e.g. on x86 and ARM) if the source and
|
||||
destination operands are the same registers. Affects sljit_emit_op0,
|
||||
sljit_emit_op1 and sljit_emit_op2. */
|
||||
#define SLJIT_I32_OP 0x100
|
||||
|
||||
/* Single precision mode (SP). This flag is similar to SLJIT_INT_OP, just
|
||||
/* F32 precision mode (SP). This flag is similar to SLJIT_I32_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
|
||||
this flag is passed, the CPU performs 32 bit floating point operations.
|
||||
Similar to SLJIT_I32_OP, all register arguments must be computed by
|
||||
floating point operations where this flag is also set. Affects
|
||||
sljit_emit_fop1, sljit_emit_fop2 and sljit_emit_fcmp. */
|
||||
#define SLJIT_SINGLE_OP 0x100
|
||||
#define SLJIT_F32_OP 0x100
|
||||
|
||||
/* Common CPU status flags for all architectures (x86, ARM, PPC)
|
||||
- carry flag
|
||||
@ -697,43 +718,41 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
|
||||
/* Flags: - (may destroy flags)
|
||||
Unsigned multiplication of SLJIT_R0 and SLJIT_R1.
|
||||
Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */
|
||||
#define SLJIT_LUMUL (SLJIT_OP0_BASE + 2)
|
||||
#define SLJIT_LMUL_UW (SLJIT_OP0_BASE + 2)
|
||||
/* Flags: - (may destroy flags)
|
||||
Signed multiplication of SLJIT_R0 and SLJIT_R1.
|
||||
Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */
|
||||
#define SLJIT_LSMUL (SLJIT_OP0_BASE + 3)
|
||||
#define SLJIT_LMUL_SW (SLJIT_OP0_BASE + 3)
|
||||
/* Flags: I - (may destroy flags)
|
||||
Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1.
|
||||
The result is placed into SLJIT_R0 and the remainder into SLJIT_R1.
|
||||
Note: if SLJIT_R1 is 0, the behaviour is undefined. */
|
||||
#define SLJIT_UDIVMOD (SLJIT_OP0_BASE + 4)
|
||||
#define SLJIT_IUDIVMOD (SLJIT_UDIVMOD | SLJIT_INT_OP)
|
||||
#define SLJIT_DIVMOD_UW (SLJIT_OP0_BASE + 4)
|
||||
#define SLJIT_DIVMOD_U32 (SLJIT_DIVMOD_UW | SLJIT_I32_OP)
|
||||
/* Flags: I - (may destroy flags)
|
||||
Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1.
|
||||
The result is placed into SLJIT_R0 and the remainder into SLJIT_R1.
|
||||
Note: if SLJIT_R1 is 0, the behaviour is undefined.
|
||||
Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00),
|
||||
the behaviour is undefined. */
|
||||
#define SLJIT_SDIVMOD (SLJIT_OP0_BASE + 5)
|
||||
#define SLJIT_ISDIVMOD (SLJIT_SDIVMOD | SLJIT_INT_OP)
|
||||
#define SLJIT_DIVMOD_SW (SLJIT_OP0_BASE + 5)
|
||||
#define SLJIT_DIVMOD_S32 (SLJIT_DIVMOD_SW | SLJIT_I32_OP)
|
||||
/* Flags: I - (may destroy flags)
|
||||
Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1.
|
||||
The result is placed into SLJIT_R0. SLJIT_R1 preserves its value.
|
||||
Note: if SLJIT_R1 is 0, the behaviour is undefined.
|
||||
Note: SLJIT_SDIV is single precision divide. */
|
||||
#define SLJIT_UDIVI (SLJIT_OP0_BASE + 6)
|
||||
#define SLJIT_IUDIVI (SLJIT_UDIVI | SLJIT_INT_OP)
|
||||
Note: if SLJIT_R1 is 0, the behaviour is undefined. */
|
||||
#define SLJIT_DIV_UW (SLJIT_OP0_BASE + 6)
|
||||
#define SLJIT_DIV_U32 (SLJIT_DIV_UW | SLJIT_I32_OP)
|
||||
/* Flags: I - (may destroy flags)
|
||||
Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1.
|
||||
The result is placed into SLJIT_R0. SLJIT_R1 preserves its value.
|
||||
Note: if SLJIT_R1 is 0, the behaviour is undefined.
|
||||
Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00),
|
||||
the behaviour is undefined.
|
||||
Note: SLJIT_SDIV is single precision divide. */
|
||||
#define SLJIT_SDIVI (SLJIT_OP0_BASE + 7)
|
||||
#define SLJIT_ISDIVI (SLJIT_SDIVI | SLJIT_INT_OP)
|
||||
the behaviour is undefined. */
|
||||
#define SLJIT_DIV_SW (SLJIT_OP0_BASE + 7)
|
||||
#define SLJIT_DIV_S32 (SLJIT_DIV_SW | SLJIT_I32_OP)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op);
|
||||
|
||||
/* Starting index of opcodes for sljit_emit_op1. */
|
||||
#define SLJIT_OP1_BASE 32
|
||||
@ -752,216 +771,188 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_MOV (SLJIT_OP1_BASE + 0)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOV_UB (SLJIT_OP1_BASE + 1)
|
||||
#define SLJIT_IMOV_UB (SLJIT_MOV_UB | SLJIT_INT_OP)
|
||||
#define SLJIT_MOV_U8 (SLJIT_OP1_BASE + 1)
|
||||
#define SLJIT_MOV32_U8 (SLJIT_MOV_U8 | SLJIT_I32_OP)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOV_SB (SLJIT_OP1_BASE + 2)
|
||||
#define SLJIT_IMOV_SB (SLJIT_MOV_SB | SLJIT_INT_OP)
|
||||
#define SLJIT_MOV_S8 (SLJIT_OP1_BASE + 2)
|
||||
#define SLJIT_MOV32_S8 (SLJIT_MOV_S8 | SLJIT_I32_OP)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOV_UH (SLJIT_OP1_BASE + 3)
|
||||
#define SLJIT_IMOV_UH (SLJIT_MOV_UH | SLJIT_INT_OP)
|
||||
#define SLJIT_MOV_U16 (SLJIT_OP1_BASE + 3)
|
||||
#define SLJIT_MOV32_U16 (SLJIT_MOV_U16 | SLJIT_I32_OP)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOV_SH (SLJIT_OP1_BASE + 4)
|
||||
#define SLJIT_IMOV_SH (SLJIT_MOV_SH | SLJIT_INT_OP)
|
||||
#define SLJIT_MOV_S16 (SLJIT_OP1_BASE + 4)
|
||||
#define SLJIT_MOV32_S16 (SLJIT_MOV_S16 | SLJIT_I32_OP)
|
||||
/* Flags: I - (never set any flags)
|
||||
Note: see SLJIT_INT_OP for further details. */
|
||||
#define SLJIT_MOV_UI (SLJIT_OP1_BASE + 5)
|
||||
/* No SLJIT_INT_OP form, since it is the same as SLJIT_IMOV. */
|
||||
Note: no SLJIT_MOV32_U32 form, since it is the same as SLJIT_MOV32 */
|
||||
#define SLJIT_MOV_U32 (SLJIT_OP1_BASE + 5)
|
||||
/* Flags: I - (never set any flags)
|
||||
Note: see SLJIT_INT_OP for further details. */
|
||||
#define SLJIT_MOV_SI (SLJIT_OP1_BASE + 6)
|
||||
#define SLJIT_IMOV (SLJIT_MOV_SI | SLJIT_INT_OP)
|
||||
Note: no SLJIT_MOV32_S32 form, since it is the same as SLJIT_MOV32 */
|
||||
#define SLJIT_MOV_S32 (SLJIT_OP1_BASE + 6)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOV32 (SLJIT_MOV_S32 | SLJIT_I32_OP)
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_MOV_P (SLJIT_OP1_BASE + 7)
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_MOVU (SLJIT_OP1_BASE + 8)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOVU_UB (SLJIT_OP1_BASE + 9)
|
||||
#define SLJIT_IMOVU_UB (SLJIT_MOVU_UB | SLJIT_INT_OP)
|
||||
#define SLJIT_MOVU_U8 (SLJIT_OP1_BASE + 9)
|
||||
#define SLJIT_MOVU32_U8 (SLJIT_MOVU_U8 | SLJIT_I32_OP)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOVU_SB (SLJIT_OP1_BASE + 10)
|
||||
#define SLJIT_IMOVU_SB (SLJIT_MOVU_SB | SLJIT_INT_OP)
|
||||
#define SLJIT_MOVU_S8 (SLJIT_OP1_BASE + 10)
|
||||
#define SLJIT_MOVU32_S8 (SLJIT_MOVU_S8 | SLJIT_I32_OP)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOVU_UH (SLJIT_OP1_BASE + 11)
|
||||
#define SLJIT_IMOVU_UH (SLJIT_MOVU_UH | SLJIT_INT_OP)
|
||||
#define SLJIT_MOVU_U16 (SLJIT_OP1_BASE + 11)
|
||||
#define SLJIT_MOVU32_U16 (SLJIT_MOVU_U16 | SLJIT_I32_OP)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOVU_SH (SLJIT_OP1_BASE + 12)
|
||||
#define SLJIT_IMOVU_SH (SLJIT_MOVU_SH | SLJIT_INT_OP)
|
||||
#define SLJIT_MOVU_S16 (SLJIT_OP1_BASE + 12)
|
||||
#define SLJIT_MOVU32_S16 (SLJIT_MOVU_S16 | SLJIT_I32_OP)
|
||||
/* Flags: I - (never set any flags)
|
||||
Note: see SLJIT_INT_OP for further details. */
|
||||
#define SLJIT_MOVU_UI (SLJIT_OP1_BASE + 13)
|
||||
/* No SLJIT_INT_OP form, since it is the same as SLJIT_IMOVU. */
|
||||
Note: no SLJIT_MOVU32_U32 form, since it is the same as SLJIT_MOVU32 */
|
||||
#define SLJIT_MOVU_U32 (SLJIT_OP1_BASE + 13)
|
||||
/* Flags: I - (never set any flags)
|
||||
Note: see SLJIT_INT_OP for further details. */
|
||||
#define SLJIT_MOVU_SI (SLJIT_OP1_BASE + 14)
|
||||
#define SLJIT_IMOVU (SLJIT_MOVU_SI | SLJIT_INT_OP)
|
||||
Note: no SLJIT_MOVU32_S32 form, since it is the same as SLJIT_MOVU32 */
|
||||
#define SLJIT_MOVU_S32 (SLJIT_OP1_BASE + 14)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOVU32 (SLJIT_MOVU_S32 | SLJIT_I32_OP)
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_MOVU_P (SLJIT_OP1_BASE + 15)
|
||||
/* Flags: I | E | K */
|
||||
#define SLJIT_NOT (SLJIT_OP1_BASE + 16)
|
||||
#define SLJIT_INOT (SLJIT_NOT | SLJIT_INT_OP)
|
||||
#define SLJIT_NOT32 (SLJIT_NOT | SLJIT_I32_OP)
|
||||
/* Flags: I | E | O | K */
|
||||
#define SLJIT_NEG (SLJIT_OP1_BASE + 17)
|
||||
#define SLJIT_INEG (SLJIT_NEG | SLJIT_INT_OP)
|
||||
#define SLJIT_NEG32 (SLJIT_NEG | SLJIT_I32_OP)
|
||||
/* Count leading zeroes
|
||||
Flags: I | E | K
|
||||
Important note! Sparc 32 does not support K flag, since
|
||||
the required popc instruction is introduced only in sparc 64. */
|
||||
#define SLJIT_CLZ (SLJIT_OP1_BASE + 18)
|
||||
#define SLJIT_ICLZ (SLJIT_CLZ | SLJIT_INT_OP)
|
||||
#define SLJIT_CLZ32 (SLJIT_CLZ | SLJIT_I32_OP)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw);
|
||||
|
||||
/* Starting index of opcodes for sljit_emit_op2. */
|
||||
#define SLJIT_OP2_BASE 96
|
||||
|
||||
/* Flags: I | E | O | C | K */
|
||||
#define SLJIT_ADD (SLJIT_OP2_BASE + 0)
|
||||
#define SLJIT_IADD (SLJIT_ADD | SLJIT_INT_OP)
|
||||
#define SLJIT_ADD32 (SLJIT_ADD | SLJIT_I32_OP)
|
||||
/* Flags: I | C | K */
|
||||
#define SLJIT_ADDC (SLJIT_OP2_BASE + 1)
|
||||
#define SLJIT_IADDC (SLJIT_ADDC | SLJIT_INT_OP)
|
||||
#define SLJIT_ADDC32 (SLJIT_ADDC | SLJIT_I32_OP)
|
||||
/* Flags: I | E | U | S | O | C | K */
|
||||
#define SLJIT_SUB (SLJIT_OP2_BASE + 2)
|
||||
#define SLJIT_ISUB (SLJIT_SUB | SLJIT_INT_OP)
|
||||
#define SLJIT_SUB32 (SLJIT_SUB | SLJIT_I32_OP)
|
||||
/* Flags: I | C | K */
|
||||
#define SLJIT_SUBC (SLJIT_OP2_BASE + 3)
|
||||
#define SLJIT_ISUBC (SLJIT_SUBC | SLJIT_INT_OP)
|
||||
#define SLJIT_SUBC32 (SLJIT_SUBC | SLJIT_I32_OP)
|
||||
/* Note: integer mul
|
||||
Flags: I | O (see SLJIT_C_MUL_*) | K */
|
||||
#define SLJIT_MUL (SLJIT_OP2_BASE + 4)
|
||||
#define SLJIT_IMUL (SLJIT_MUL | SLJIT_INT_OP)
|
||||
#define SLJIT_MUL32 (SLJIT_MUL | SLJIT_I32_OP)
|
||||
/* Flags: I | E | K */
|
||||
#define SLJIT_AND (SLJIT_OP2_BASE + 5)
|
||||
#define SLJIT_IAND (SLJIT_AND | SLJIT_INT_OP)
|
||||
#define SLJIT_AND32 (SLJIT_AND | SLJIT_I32_OP)
|
||||
/* Flags: I | E | K */
|
||||
#define SLJIT_OR (SLJIT_OP2_BASE + 6)
|
||||
#define SLJIT_IOR (SLJIT_OR | SLJIT_INT_OP)
|
||||
#define SLJIT_OR32 (SLJIT_OR | SLJIT_I32_OP)
|
||||
/* Flags: I | E | K */
|
||||
#define SLJIT_XOR (SLJIT_OP2_BASE + 7)
|
||||
#define SLJIT_IXOR (SLJIT_XOR | SLJIT_INT_OP)
|
||||
#define SLJIT_XOR32 (SLJIT_XOR | SLJIT_I32_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 result is undefined. */
|
||||
#define SLJIT_SHL (SLJIT_OP2_BASE + 8)
|
||||
#define SLJIT_ISHL (SLJIT_SHL | SLJIT_INT_OP)
|
||||
#define SLJIT_SHL32 (SLJIT_SHL | SLJIT_I32_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 result is undefined. */
|
||||
#define SLJIT_LSHR (SLJIT_OP2_BASE + 9)
|
||||
#define SLJIT_ILSHR (SLJIT_LSHR | SLJIT_INT_OP)
|
||||
#define SLJIT_LSHR32 (SLJIT_LSHR | SLJIT_I32_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 result is undefined. */
|
||||
#define SLJIT_ASHR (SLJIT_OP2_BASE + 10)
|
||||
#define SLJIT_IASHR (SLJIT_ASHR | SLJIT_INT_OP)
|
||||
#define SLJIT_ASHR32 (SLJIT_ASHR | SLJIT_I32_OP)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w);
|
||||
|
||||
/* The following function is a helper function for sljit_emit_op_custom.
|
||||
It returns with the real machine register index ( >=0 ) of any SLJIT_R,
|
||||
SLJIT_S and SLJIT_SP registers.
|
||||
|
||||
Note: it returns with -1 for virtual registers (only 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 always an even number on ARM (except ARM-64), MIPS, and SPARC. */
|
||||
|
||||
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);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w);
|
||||
|
||||
/* Returns with non-zero if fpu is available. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void);
|
||||
|
||||
/* Starting index of opcodes for sljit_emit_fop1. */
|
||||
#define SLJIT_FOP1_BASE 128
|
||||
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_DMOV (SLJIT_FOP1_BASE + 0)
|
||||
#define SLJIT_SMOV (SLJIT_DMOV | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_MOV_F64 (SLJIT_FOP1_BASE + 0)
|
||||
#define SLJIT_MOV_F32 (SLJIT_MOV_F64 | SLJIT_F32_OP)
|
||||
/* Convert opcodes: CONV[DST_TYPE].FROM[SRC_TYPE]
|
||||
SRC/DST TYPE can be: D - double, S - single, W - signed word, I - signed int
|
||||
Rounding mode when the destination is W or I: round towards zero. */
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_CONVD_FROMS (SLJIT_FOP1_BASE + 1)
|
||||
#define SLJIT_CONVS_FROMD (SLJIT_CONVD_FROMS | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_CONV_F64_FROM_F32 (SLJIT_FOP1_BASE + 1)
|
||||
#define SLJIT_CONV_F32_FROM_F64 (SLJIT_CONV_F64_FROM_F32 | SLJIT_F32_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_CONVW_FROMD (SLJIT_FOP1_BASE + 2)
|
||||
#define SLJIT_CONVW_FROMS (SLJIT_CONVW_FROMD | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_CONV_SW_FROM_F64 (SLJIT_FOP1_BASE + 2)
|
||||
#define SLJIT_CONV_SW_FROM_F32 (SLJIT_CONV_SW_FROM_F64 | SLJIT_F32_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_CONVI_FROMD (SLJIT_FOP1_BASE + 3)
|
||||
#define SLJIT_CONVI_FROMS (SLJIT_CONVI_FROMD | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_CONV_S32_FROM_F64 (SLJIT_FOP1_BASE + 3)
|
||||
#define SLJIT_CONV_S32_FROM_F32 (SLJIT_CONV_S32_FROM_F64 | SLJIT_F32_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_CONVD_FROMW (SLJIT_FOP1_BASE + 4)
|
||||
#define SLJIT_CONVS_FROMW (SLJIT_CONVD_FROMW | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_CONV_F64_FROM_SW (SLJIT_FOP1_BASE + 4)
|
||||
#define SLJIT_CONV_F32_FROM_SW (SLJIT_CONV_F64_FROM_SW | SLJIT_F32_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_CONVD_FROMI (SLJIT_FOP1_BASE + 5)
|
||||
#define SLJIT_CONVS_FROMI (SLJIT_CONVD_FROMI | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_CONV_F64_FROM_S32 (SLJIT_FOP1_BASE + 5)
|
||||
#define SLJIT_CONV_F32_FROM_S32 (SLJIT_CONV_F64_FROM_S32 | SLJIT_F32_OP)
|
||||
/* Note: dst is the left and src is the right operand for SLJIT_CMPD.
|
||||
Note: NaN check is always performed. If SLJIT_C_FLOAT_UNORDERED flag
|
||||
is set, the comparison result is unpredictable.
|
||||
Flags: SP | E | S (see SLJIT_C_FLOAT_*) */
|
||||
#define SLJIT_DCMP (SLJIT_FOP1_BASE + 6)
|
||||
#define SLJIT_SCMP (SLJIT_DCMP | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_CMP_F64 (SLJIT_FOP1_BASE + 6)
|
||||
#define SLJIT_CMP_F32 (SLJIT_CMP_F64 | SLJIT_F32_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_DNEG (SLJIT_FOP1_BASE + 7)
|
||||
#define SLJIT_SNEG (SLJIT_DNEG | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_NEG_F64 (SLJIT_FOP1_BASE + 7)
|
||||
#define SLJIT_NEG_F32 (SLJIT_NEG_F64 | SLJIT_F32_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_DABS (SLJIT_FOP1_BASE + 8)
|
||||
#define SLJIT_SABS (SLJIT_DABS | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_ABS_F64 (SLJIT_FOP1_BASE + 8)
|
||||
#define SLJIT_ABS_F32 (SLJIT_ABS_F64 | SLJIT_F32_OP)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw);
|
||||
|
||||
/* Starting index of opcodes for sljit_emit_fop2. */
|
||||
#define SLJIT_FOP2_BASE 160
|
||||
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_DADD (SLJIT_FOP2_BASE + 0)
|
||||
#define SLJIT_SADD (SLJIT_DADD | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_ADD_F64 (SLJIT_FOP2_BASE + 0)
|
||||
#define SLJIT_ADD_F32 (SLJIT_ADD_F64 | SLJIT_F32_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_DSUB (SLJIT_FOP2_BASE + 1)
|
||||
#define SLJIT_SSUB (SLJIT_DSUB | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_SUB_F64 (SLJIT_FOP2_BASE + 1)
|
||||
#define SLJIT_SUB_F32 (SLJIT_SUB_F64 | SLJIT_F32_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_DMUL (SLJIT_FOP2_BASE + 2)
|
||||
#define SLJIT_SMUL (SLJIT_DMUL | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_MUL_F64 (SLJIT_FOP2_BASE + 2)
|
||||
#define SLJIT_MUL_F32 (SLJIT_MUL_F64 | SLJIT_F32_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_DDIV (SLJIT_FOP2_BASE + 3)
|
||||
#define SLJIT_SDIV (SLJIT_DDIV | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_DIV_F64 (SLJIT_FOP2_BASE + 3)
|
||||
#define SLJIT_DIV_F32 (SLJIT_DIV_F64 | SLJIT_F32_OP)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w);
|
||||
|
||||
/* Label and jump instructions. */
|
||||
|
||||
@ -971,58 +962,58 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
||||
|
||||
/* Integer comparison types. */
|
||||
#define SLJIT_EQUAL 0
|
||||
#define SLJIT_I_EQUAL (SLJIT_EQUAL | SLJIT_INT_OP)
|
||||
#define SLJIT_EQUAL32 (SLJIT_EQUAL | SLJIT_I32_OP)
|
||||
#define SLJIT_ZERO 0
|
||||
#define SLJIT_I_ZERO (SLJIT_ZERO | SLJIT_INT_OP)
|
||||
#define SLJIT_ZERO32 (SLJIT_ZERO | SLJIT_I32_OP)
|
||||
#define SLJIT_NOT_EQUAL 1
|
||||
#define SLJIT_I_NOT_EQUAL (SLJIT_NOT_EQUAL | SLJIT_INT_OP)
|
||||
#define SLJIT_NOT_EQUAL32 (SLJIT_NOT_EQUAL | SLJIT_I32_OP)
|
||||
#define SLJIT_NOT_ZERO 1
|
||||
#define SLJIT_I_NOT_ZERO (SLJIT_NOT_ZERO | SLJIT_INT_OP)
|
||||
#define SLJIT_NOT_ZERO32 (SLJIT_NOT_ZERO | SLJIT_I32_OP)
|
||||
|
||||
#define SLJIT_LESS 2
|
||||
#define SLJIT_I_LESS (SLJIT_LESS | SLJIT_INT_OP)
|
||||
#define SLJIT_LESS32 (SLJIT_LESS | SLJIT_I32_OP)
|
||||
#define SLJIT_GREATER_EQUAL 3
|
||||
#define SLJIT_I_GREATER_EQUAL (SLJIT_GREATER_EQUAL | SLJIT_INT_OP)
|
||||
#define SLJIT_GREATER_EQUAL32 (SLJIT_GREATER_EQUAL | SLJIT_I32_OP)
|
||||
#define SLJIT_GREATER 4
|
||||
#define SLJIT_I_GREATER (SLJIT_GREATER | SLJIT_INT_OP)
|
||||
#define SLJIT_GREATER32 (SLJIT_GREATER | SLJIT_I32_OP)
|
||||
#define SLJIT_LESS_EQUAL 5
|
||||
#define SLJIT_I_LESS_EQUAL (SLJIT_LESS_EQUAL | SLJIT_INT_OP)
|
||||
#define SLJIT_LESS_EQUAL32 (SLJIT_LESS_EQUAL | SLJIT_I32_OP)
|
||||
#define SLJIT_SIG_LESS 6
|
||||
#define SLJIT_I_SIG_LESS (SLJIT_SIG_LESS | SLJIT_INT_OP)
|
||||
#define SLJIT_SIG_LESS32 (SLJIT_SIG_LESS | SLJIT_I32_OP)
|
||||
#define SLJIT_SIG_GREATER_EQUAL 7
|
||||
#define SLJIT_I_SIG_GREATER_EQUAL (SLJIT_SIG_GREATER_EQUAL | SLJIT_INT_OP)
|
||||
#define SLJIT_SIG_GREATER_EQUAL32 (SLJIT_SIG_GREATER_EQUAL | SLJIT_I32_OP)
|
||||
#define SLJIT_SIG_GREATER 8
|
||||
#define SLJIT_I_SIG_GREATER (SLJIT_SIG_GREATER | SLJIT_INT_OP)
|
||||
#define SLJIT_SIG_GREATER32 (SLJIT_SIG_GREATER | SLJIT_I32_OP)
|
||||
#define SLJIT_SIG_LESS_EQUAL 9
|
||||
#define SLJIT_I_SIG_LESS_EQUAL (SLJIT_SIG_LESS_EQUAL | SLJIT_INT_OP)
|
||||
#define SLJIT_SIG_LESS_EQUAL32 (SLJIT_SIG_LESS_EQUAL | SLJIT_I32_OP)
|
||||
|
||||
#define SLJIT_OVERFLOW 10
|
||||
#define SLJIT_I_OVERFLOW (SLJIT_OVERFLOW | SLJIT_INT_OP)
|
||||
#define SLJIT_OVERFLOW32 (SLJIT_OVERFLOW | SLJIT_I32_OP)
|
||||
#define SLJIT_NOT_OVERFLOW 11
|
||||
#define SLJIT_I_NOT_OVERFLOW (SLJIT_NOT_OVERFLOW | SLJIT_INT_OP)
|
||||
#define SLJIT_NOT_OVERFLOW32 (SLJIT_NOT_OVERFLOW | SLJIT_I32_OP)
|
||||
|
||||
#define SLJIT_MUL_OVERFLOW 12
|
||||
#define SLJIT_I_MUL_OVERFLOW (SLJIT_MUL_OVERFLOW | SLJIT_INT_OP)
|
||||
#define SLJIT_MUL_OVERFLOW32 (SLJIT_MUL_OVERFLOW | SLJIT_I32_OP)
|
||||
#define SLJIT_MUL_NOT_OVERFLOW 13
|
||||
#define SLJIT_I_MUL_NOT_OVERFLOW (SLJIT_MUL_NOT_OVERFLOW | SLJIT_INT_OP)
|
||||
#define SLJIT_MUL_NOT_OVERFLOW32 (SLJIT_MUL_NOT_OVERFLOW | SLJIT_I32_OP)
|
||||
|
||||
/* Floating point comparison types. */
|
||||
#define SLJIT_D_EQUAL 14
|
||||
#define SLJIT_S_EQUAL (SLJIT_D_EQUAL | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_D_NOT_EQUAL 15
|
||||
#define SLJIT_S_NOT_EQUAL (SLJIT_D_NOT_EQUAL | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_D_LESS 16
|
||||
#define SLJIT_S_LESS (SLJIT_D_LESS | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_D_GREATER_EQUAL 17
|
||||
#define SLJIT_S_GREATER_EQUAL (SLJIT_D_GREATER_EQUAL | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_D_GREATER 18
|
||||
#define SLJIT_S_GREATER (SLJIT_D_GREATER | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_D_LESS_EQUAL 19
|
||||
#define SLJIT_S_LESS_EQUAL (SLJIT_D_LESS_EQUAL | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_D_UNORDERED 20
|
||||
#define SLJIT_S_UNORDERED (SLJIT_D_UNORDERED | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_D_ORDERED 21
|
||||
#define SLJIT_S_ORDERED (SLJIT_D_ORDERED | SLJIT_SINGLE_OP)
|
||||
#define SLJIT_EQUAL_F64 14
|
||||
#define SLJIT_EQUAL_F32 (SLJIT_EQUAL_F64 | SLJIT_F32_OP)
|
||||
#define SLJIT_NOT_EQUAL_F64 15
|
||||
#define SLJIT_NOT_EQUAL_F32 (SLJIT_NOT_EQUAL_F64 | SLJIT_F32_OP)
|
||||
#define SLJIT_LESS_F64 16
|
||||
#define SLJIT_LESS_F32 (SLJIT_LESS_F64 | SLJIT_F32_OP)
|
||||
#define SLJIT_GREATER_EQUAL_F64 17
|
||||
#define SLJIT_GREATER_EQUAL_F32 (SLJIT_GREATER_EQUAL_F64 | SLJIT_F32_OP)
|
||||
#define SLJIT_GREATER_F64 18
|
||||
#define SLJIT_GREATER_F32 (SLJIT_GREATER_F64 | SLJIT_F32_OP)
|
||||
#define SLJIT_LESS_EQUAL_F64 19
|
||||
#define SLJIT_LESS_EQUAL_F32 (SLJIT_LESS_EQUAL_F64 | SLJIT_F32_OP)
|
||||
#define SLJIT_UNORDERED_F64 20
|
||||
#define SLJIT_UNORDERED_F32 (SLJIT_UNORDERED_F64 | SLJIT_F32_OP)
|
||||
#define SLJIT_ORDERED_F64 21
|
||||
#define SLJIT_ORDERED_F32 (SLJIT_ORDERED_F64 | SLJIT_F32_OP)
|
||||
|
||||
/* Unconditional jump types. */
|
||||
#define SLJIT_JUMP 22
|
||||
@ -1042,7 +1033,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
||||
type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
|
||||
Flags: - (never set any flags) for both conditional and unconditional jumps.
|
||||
Flags: destroy all flags for calls. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type);
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type);
|
||||
|
||||
/* Basic arithmetic comparison. In most architectures it is implemented as
|
||||
an SLJIT_SUB operation (with SLJIT_UNUSED destination and setting
|
||||
@ -1052,23 +1043,23 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||
type must be between SLJIT_EQUAL and SLJIT_I_SIG_LESS_EQUAL
|
||||
type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
|
||||
Flags: destroy flags. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w);
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 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_D_EQUAL and SLJIT_S_ORDERED
|
||||
type must be between SLJIT_EQUAL_F64 and SLJIT_ORDERED_F32
|
||||
type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
|
||||
Flags: destroy flags.
|
||||
Note: if either operand is NaN, the behaviour is undefined for
|
||||
types up to SLJIT_S_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);
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w);
|
||||
|
||||
/* 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);
|
||||
@ -1081,14 +1072,14 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw
|
||||
Indirect form: any other valid addressing mode
|
||||
Flags: - (never set any flags) for unconditional jumps.
|
||||
Flags: destroy all flags for calls. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw);
|
||||
|
||||
/* Perform the operation using the conditional flags as the second argument.
|
||||
Type must always be between SLJIT_EQUAL and SLJIT_S_ORDERED. The 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:
|
||||
If op == SLJIT_MOV, SLJIT_MOV_S32, SLJIT_MOV_U32:
|
||||
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)
|
||||
@ -1098,18 +1089,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil
|
||||
Important note: only dst=src and dstw=srcw is supported at the moment!
|
||||
Flags: I | E | K
|
||||
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);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw,
|
||||
sljit_s32 type);
|
||||
|
||||
/* Copies the base address of SLJIT_SP + 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);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset);
|
||||
|
||||
/* The constant can be changed runtime (see: sljit_set_const)
|
||||
Flags: - (never set any flags) */
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value);
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value);
|
||||
|
||||
/* After the code generation the address for label, jump and const instructions
|
||||
are computed. Since these structures are freed by sljit_free_compiler, the
|
||||
@ -1118,9 +1109,10 @@ static SLJIT_INLINE sljit_uw sljit_get_label_addr(struct sljit_label *label) { r
|
||||
static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; }
|
||||
static SLJIT_INLINE sljit_uw sljit_get_const_addr(struct sljit_const *const_) { return const_->addr; }
|
||||
|
||||
/* 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_const(sljit_uw addr, sljit_sw new_constant);
|
||||
/* Only the address and executable offset are required to perform dynamic
|
||||
code modifications. See sljit_get_executable_offset function. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset);
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset);
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Miscellaneous utility functions */
|
||||
@ -1132,7 +1124,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta
|
||||
/* Get the human readable name of the platform. Can be useful on platforms
|
||||
like ARM, where ARM and Thumb2 functions can be mixed, and
|
||||
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 const char* sljit_get_platform_name(void);
|
||||
|
||||
/* Portable helper function to get an offset of a member. */
|
||||
#define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((base*)0x10)->member) - 0x10)
|
||||
@ -1214,4 +1206,64 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct
|
||||
|
||||
#endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* CPU specific functions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/* The following function is a helper function for sljit_emit_op_custom.
|
||||
It returns with the real machine register index ( >=0 ) of any SLJIT_R,
|
||||
SLJIT_S and SLJIT_SP registers.
|
||||
|
||||
Note: it returns with -1 for virtual registers (only on x86-32). */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 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 always an even number on ARM (except ARM-64), MIPS, and SPARC. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 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_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
|
||||
void *instruction, sljit_s32 size);
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
|
||||
|
||||
/* Returns with non-zero if sse2 is available. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_is_sse2_available(void);
|
||||
|
||||
/* Returns with non-zero if cmov instruction is available. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_is_cmov_available(void);
|
||||
|
||||
/* Emit a conditional mov instruction on x86 CPUs. This instruction
|
||||
moves src to destination, if the condition is satisfied. Unlike
|
||||
other arithmetic instructions, destination must be a register.
|
||||
Before such instructions are emitted, cmov support should be
|
||||
checked by sljit_x86_is_cmov_available function.
|
||||
type must be between SLJIT_EQUAL and SLJIT_S_ORDERED
|
||||
dst_reg must be a valid register and it can be combined
|
||||
with SLJIT_I32_OP to perform 32 bit arithmetic
|
||||
Flags: I - (never set any flags)
|
||||
*/
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_emit_cmov(struct sljit_compiler *compiler,
|
||||
sljit_s32 type,
|
||||
sljit_s32 dst_reg,
|
||||
sljit_s32 src, sljit_sw srcw);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _SLJIT_LIR_H_ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -24,13 +24,13 @@
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void)
|
||||
SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
|
||||
{
|
||||
return "ARM-64" SLJIT_CPUINFO;
|
||||
}
|
||||
|
||||
/* Length of an instruction word */
|
||||
typedef sljit_ui sljit_ins;
|
||||
typedef sljit_u32 sljit_ins;
|
||||
|
||||
#define TMP_ZERO (0)
|
||||
|
||||
@ -43,7 +43,7 @@ typedef sljit_ui sljit_ins;
|
||||
#define TMP_FREG1 (0)
|
||||
#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
|
||||
|
||||
static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 8] = {
|
||||
static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 8] = {
|
||||
31, 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 16, 17, 8, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 29, 9, 10, 11, 30, 31
|
||||
};
|
||||
|
||||
@ -124,7 +124,7 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 8] = {
|
||||
|
||||
/* dest_reg is the absolute name of the register
|
||||
Useful for reordering instructions in the delay slot. */
|
||||
static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins)
|
||||
static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)
|
||||
{
|
||||
sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
|
||||
FAIL_IF(!ptr);
|
||||
@ -133,7 +133,7 @@ static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins)
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si emit_imm64_const(struct sljit_compiler *compiler, sljit_si dst, sljit_uw imm)
|
||||
static SLJIT_INLINE sljit_s32 emit_imm64_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm)
|
||||
{
|
||||
FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((imm & 0xffff) << 5)));
|
||||
FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((imm >> 16) & 0xffff) << 5) | (1 << 21)));
|
||||
@ -143,7 +143,7 @@ static SLJIT_INLINE sljit_si emit_imm64_const(struct sljit_compiler *compiler, s
|
||||
|
||||
static SLJIT_INLINE void modify_imm64_const(sljit_ins* inst, sljit_uw new_imm)
|
||||
{
|
||||
sljit_si dst = inst[0] & 0x1f;
|
||||
sljit_s32 dst = inst[0] & 0x1f;
|
||||
SLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ && (inst[1] & 0xffe00000) == (MOVK | (1 << 21)));
|
||||
inst[0] = MOVZ | dst | ((new_imm & 0xffff) << 5);
|
||||
inst[1] = MOVK | dst | (((new_imm >> 16) & 0xffff) << 5) | (1 << 21);
|
||||
@ -151,7 +151,7 @@ static SLJIT_INLINE void modify_imm64_const(sljit_ins* inst, sljit_uw new_imm)
|
||||
inst[3] = MOVK | dst | ((new_imm >> 48) << 5) | (3 << 21);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
|
||||
static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_sw diff;
|
||||
sljit_uw target_addr;
|
||||
@ -165,9 +165,10 @@ static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_ins
|
||||
target_addr = jump->u.target;
|
||||
else {
|
||||
SLJIT_ASSERT(jump->flags & JUMP_LABEL);
|
||||
target_addr = (sljit_uw)(code + jump->u.label->size);
|
||||
target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
|
||||
}
|
||||
diff = (sljit_sw)target_addr - (sljit_sw)(code_ptr + 4);
|
||||
|
||||
diff = (sljit_sw)target_addr - (sljit_sw)(code_ptr + 4) - executable_offset;
|
||||
|
||||
if (jump->flags & IS_COND) {
|
||||
diff += sizeof(sljit_ins);
|
||||
@ -211,8 +212,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
sljit_ins *buf_ptr;
|
||||
sljit_ins *buf_end;
|
||||
sljit_uw word_count;
|
||||
sljit_sw executable_offset;
|
||||
sljit_uw addr;
|
||||
sljit_si dst;
|
||||
sljit_s32 dst;
|
||||
|
||||
struct sljit_label *label;
|
||||
struct sljit_jump *jump;
|
||||
@ -228,6 +230,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
|
||||
code_ptr = code;
|
||||
word_count = 0;
|
||||
executable_offset = SLJIT_EXEC_OFFSET(code);
|
||||
|
||||
label = compiler->labels;
|
||||
jump = compiler->jumps;
|
||||
const_ = compiler->consts;
|
||||
@ -242,13 +246,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
SLJIT_ASSERT(!jump || jump->addr >= word_count);
|
||||
SLJIT_ASSERT(!const_ || const_->addr >= word_count);
|
||||
if (label && label->size == word_count) {
|
||||
label->addr = (sljit_uw)code_ptr;
|
||||
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
label->size = code_ptr - code;
|
||||
label = label->next;
|
||||
}
|
||||
if (jump && jump->addr == word_count) {
|
||||
jump->addr = (sljit_uw)(code_ptr - 4);
|
||||
code_ptr -= detect_jump_type(jump, code_ptr, code);
|
||||
code_ptr -= detect_jump_type(jump, code_ptr, code, executable_offset);
|
||||
jump = jump->next;
|
||||
}
|
||||
if (const_ && const_->addr == word_count) {
|
||||
@ -263,7 +267,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
} while (buf);
|
||||
|
||||
if (label && label->size == word_count) {
|
||||
label->addr = (sljit_uw)code_ptr;
|
||||
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
label->size = code_ptr - code;
|
||||
label = label->next;
|
||||
}
|
||||
@ -277,9 +281,10 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
while (jump) {
|
||||
do {
|
||||
addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
|
||||
buf_ptr = (sljit_ins*)jump->addr;
|
||||
buf_ptr = (sljit_ins *)jump->addr;
|
||||
|
||||
if (jump->flags & PATCH_B) {
|
||||
addr = (sljit_sw)(addr - jump->addr) >> 2;
|
||||
addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
|
||||
SLJIT_ASSERT((sljit_sw)addr <= 0x1ffffff && (sljit_sw)addr >= -0x2000000);
|
||||
buf_ptr[0] = ((jump->flags & IS_BL) ? BL : B) | (addr & 0x3ffffff);
|
||||
if (jump->flags & IS_COND)
|
||||
@ -287,7 +292,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
break;
|
||||
}
|
||||
if (jump->flags & PATCH_COND) {
|
||||
addr = (sljit_sw)(addr - jump->addr) >> 2;
|
||||
addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
|
||||
SLJIT_ASSERT((sljit_sw)addr <= 0x3ffff && (sljit_sw)addr >= -0x40000);
|
||||
buf_ptr[0] = (buf_ptr[0] & ~0xffffe0) | ((addr & 0x7ffff) << 5);
|
||||
break;
|
||||
@ -308,7 +313,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
}
|
||||
|
||||
compiler->error = SLJIT_ERR_COMPILED;
|
||||
compiler->executable_offset = executable_offset;
|
||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
||||
|
||||
code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
|
||||
code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
|
||||
SLJIT_CACHE_FLUSH(code, code_ptr);
|
||||
return code;
|
||||
}
|
||||
@ -346,9 +356,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
|
||||
#define LOGICAL_IMM_CHECK 0x100
|
||||
|
||||
static sljit_ins logical_imm(sljit_sw imm, sljit_si len)
|
||||
static sljit_ins logical_imm(sljit_sw imm, sljit_s32 len)
|
||||
{
|
||||
sljit_si negated, ones, right;
|
||||
sljit_s32 negated, ones, right;
|
||||
sljit_uw mask, uimm;
|
||||
sljit_ins ins;
|
||||
|
||||
@ -356,12 +366,12 @@ static sljit_ins logical_imm(sljit_sw imm, sljit_si len)
|
||||
len &= ~LOGICAL_IMM_CHECK;
|
||||
if (len == 32 && (imm == 0 || imm == -1))
|
||||
return 0;
|
||||
if (len == 16 && ((sljit_si)imm == 0 || (sljit_si)imm == -1))
|
||||
if (len == 16 && ((sljit_s32)imm == 0 || (sljit_s32)imm == -1))
|
||||
return 0;
|
||||
}
|
||||
|
||||
SLJIT_ASSERT((len == 32 && imm != 0 && imm != -1)
|
||||
|| (len == 16 && (sljit_si)imm != 0 && (sljit_si)imm != -1));
|
||||
|| (len == 16 && (sljit_s32)imm != 0 && (sljit_s32)imm != -1));
|
||||
uimm = (sljit_uw)imm;
|
||||
while (1) {
|
||||
if (len <= 0) {
|
||||
@ -410,10 +420,10 @@ static sljit_ins logical_imm(sljit_sw imm, sljit_si len)
|
||||
|
||||
#undef COUNT_TRAILING_ZERO
|
||||
|
||||
static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sljit_sw simm)
|
||||
static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw simm)
|
||||
{
|
||||
sljit_uw imm = (sljit_uw)simm;
|
||||
sljit_si i, zeros, ones, first;
|
||||
sljit_s32 i, zeros, ones, first;
|
||||
sljit_ins bitmask;
|
||||
|
||||
if (imm <= 0xffff)
|
||||
@ -512,15 +522,15 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sl
|
||||
dst = TMP_ZERO; \
|
||||
}
|
||||
|
||||
static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, sljit_si dst, sljit_sw arg1, sljit_sw arg2)
|
||||
static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 dst, sljit_sw arg1, sljit_sw arg2)
|
||||
{
|
||||
/* dst must be register, TMP_REG1
|
||||
arg1 must be register, TMP_REG1, imm
|
||||
arg2 must be register, TMP_REG2, imm */
|
||||
sljit_ins inv_bits = (flags & INT_OP) ? (1 << 31) : 0;
|
||||
sljit_ins inst_bits;
|
||||
sljit_si op = (flags & 0xffff);
|
||||
sljit_si reg;
|
||||
sljit_s32 op = (flags & 0xffff);
|
||||
sljit_s32 reg;
|
||||
sljit_sw imm, nimm;
|
||||
|
||||
if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) {
|
||||
@ -667,34 +677,34 @@ static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, slj
|
||||
if (dst == arg2)
|
||||
return SLJIT_SUCCESS;
|
||||
return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(arg2));
|
||||
case SLJIT_MOV_UB:
|
||||
case SLJIT_MOVU_UB:
|
||||
case SLJIT_MOV_U8:
|
||||
case SLJIT_MOVU_U8:
|
||||
SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
|
||||
return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (7 << 10));
|
||||
case SLJIT_MOV_SB:
|
||||
case SLJIT_MOVU_SB:
|
||||
case SLJIT_MOV_S8:
|
||||
case SLJIT_MOVU_S8:
|
||||
SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
|
||||
if (!(flags & INT_OP))
|
||||
inv_bits |= 1 << 22;
|
||||
return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (7 << 10));
|
||||
case SLJIT_MOV_UH:
|
||||
case SLJIT_MOVU_UH:
|
||||
case SLJIT_MOV_U16:
|
||||
case SLJIT_MOVU_U16:
|
||||
SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
|
||||
return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (15 << 10));
|
||||
case SLJIT_MOV_SH:
|
||||
case SLJIT_MOVU_SH:
|
||||
case SLJIT_MOV_S16:
|
||||
case SLJIT_MOVU_S16:
|
||||
SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
|
||||
if (!(flags & INT_OP))
|
||||
inv_bits |= 1 << 22;
|
||||
return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (15 << 10));
|
||||
case SLJIT_MOV_UI:
|
||||
case SLJIT_MOVU_UI:
|
||||
case SLJIT_MOV_U32:
|
||||
case SLJIT_MOVU_U32:
|
||||
SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
|
||||
if ((flags & INT_OP) && dst == arg2)
|
||||
return SLJIT_SUCCESS;
|
||||
return push_inst(compiler, (ORR ^ (1 << 31)) | RD(dst) | RN(TMP_ZERO) | RM(arg2));
|
||||
case SLJIT_MOV_SI:
|
||||
case SLJIT_MOVU_SI:
|
||||
case SLJIT_MOV_S32:
|
||||
case SLJIT_MOVU_S32:
|
||||
SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
|
||||
if ((flags & INT_OP) && dst == arg2)
|
||||
return SLJIT_SUCCESS;
|
||||
@ -777,28 +787,28 @@ set_flags:
|
||||
|
||||
#define MEM_SIZE_SHIFT(flags) ((flags) >> 8)
|
||||
|
||||
static SLJIT_CONST sljit_ins sljit_mem_imm[4] = {
|
||||
static const sljit_ins sljit_mem_imm[4] = {
|
||||
/* u l */ 0x39400000 /* ldrb [reg,imm] */,
|
||||
/* u s */ 0x39000000 /* strb [reg,imm] */,
|
||||
/* s l */ 0x39800000 /* ldrsb [reg,imm] */,
|
||||
/* s s */ 0x39000000 /* strb [reg,imm] */,
|
||||
};
|
||||
|
||||
static SLJIT_CONST sljit_ins sljit_mem_simm[4] = {
|
||||
static const sljit_ins sljit_mem_simm[4] = {
|
||||
/* u l */ 0x38400000 /* ldurb [reg,imm] */,
|
||||
/* u s */ 0x38000000 /* sturb [reg,imm] */,
|
||||
/* s l */ 0x38800000 /* ldursb [reg,imm] */,
|
||||
/* s s */ 0x38000000 /* sturb [reg,imm] */,
|
||||
};
|
||||
|
||||
static SLJIT_CONST sljit_ins sljit_mem_pre_simm[4] = {
|
||||
static const sljit_ins sljit_mem_pre_simm[4] = {
|
||||
/* u l */ 0x38400c00 /* ldrb [reg,imm]! */,
|
||||
/* u s */ 0x38000c00 /* strb [reg,imm]! */,
|
||||
/* s l */ 0x38800c00 /* ldrsb [reg,imm]! */,
|
||||
/* s s */ 0x38000c00 /* strb [reg,imm]! */,
|
||||
};
|
||||
|
||||
static SLJIT_CONST sljit_ins sljit_mem_reg[4] = {
|
||||
static const sljit_ins sljit_mem_reg[4] = {
|
||||
/* u l */ 0x38606800 /* ldrb [reg,reg] */,
|
||||
/* u s */ 0x38206800 /* strb [reg,reg] */,
|
||||
/* s l */ 0x38a06800 /* ldrsb [reg,reg] */,
|
||||
@ -806,7 +816,7 @@ static SLJIT_CONST sljit_ins sljit_mem_reg[4] = {
|
||||
};
|
||||
|
||||
/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */
|
||||
static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw value)
|
||||
static sljit_s32 emit_set_delta(struct sljit_compiler *compiler, sljit_s32 dst, sljit_s32 reg, sljit_sw value)
|
||||
{
|
||||
if (value >= 0) {
|
||||
if (value <= 0xfff)
|
||||
@ -825,9 +835,9 @@ static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sl
|
||||
}
|
||||
|
||||
/* Can perform an operation using at most 1 instruction. */
|
||||
static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)
|
||||
static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
|
||||
{
|
||||
sljit_ui shift = MEM_SIZE_SHIFT(flags);
|
||||
sljit_u32 shift = MEM_SIZE_SHIFT(flags);
|
||||
|
||||
SLJIT_ASSERT(arg & SLJIT_MEM);
|
||||
|
||||
@ -882,7 +892,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags,
|
||||
/* see getput_arg below.
|
||||
Note: can_cache is called only for binary operators. Those
|
||||
operators always uses word arguments without write back. */
|
||||
static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
|
||||
static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
|
||||
{
|
||||
sljit_sw diff;
|
||||
if ((arg & OFFS_REG_MASK) || !(next_arg & SLJIT_MEM))
|
||||
@ -906,11 +916,11 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_
|
||||
}
|
||||
|
||||
/* Emit the necessary instructions. See can_cache above. */
|
||||
static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg,
|
||||
sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
|
||||
static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg,
|
||||
sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
|
||||
{
|
||||
sljit_ui shift = MEM_SIZE_SHIFT(flags);
|
||||
sljit_si tmp_r, other_r;
|
||||
sljit_u32 shift = MEM_SIZE_SHIFT(flags);
|
||||
sljit_s32 tmp_r, other_r;
|
||||
sljit_sw diff;
|
||||
|
||||
SLJIT_ASSERT(arg & SLJIT_MEM);
|
||||
@ -1040,7 +1050,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji
|
||||
return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(TMP_REG3));
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)
|
||||
static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
|
||||
{
|
||||
if (getput_arg_fast(compiler, flags, reg, arg, argw))
|
||||
return compiler->error;
|
||||
@ -1049,7 +1059,7 @@ static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_
|
||||
return getput_arg(compiler, flags, reg, arg, argw, 0, 0);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w)
|
||||
static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
|
||||
{
|
||||
if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
|
||||
return compiler->error;
|
||||
@ -1060,11 +1070,11 @@ static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit
|
||||
/* Entry, exit */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
sljit_si i, tmp, offs, prev, saved_regs_size;
|
||||
sljit_s32 i, tmp, offs, prev, saved_regs_size;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
@ -1148,9 +1158,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
@ -1162,10 +1172,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si local_size;
|
||||
sljit_si i, tmp, offs, prev, saved_regs_size;
|
||||
sljit_s32 local_size;
|
||||
sljit_s32 i, tmp, offs, prev, saved_regs_size;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_return(compiler, op, src, srcw));
|
||||
@ -1243,9 +1253,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
||||
/* Operators */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
|
||||
{
|
||||
sljit_ins inv_bits = (op & SLJIT_INT_OP) ? (1 << 31) : 0;
|
||||
sljit_ins inv_bits = (op & SLJIT_I32_OP) ? (1 << 31) : 0;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op0(compiler, op));
|
||||
@ -1256,31 +1266,31 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
return push_inst(compiler, BRK);
|
||||
case SLJIT_NOP:
|
||||
return push_inst(compiler, NOP);
|
||||
case SLJIT_LUMUL:
|
||||
case SLJIT_LSMUL:
|
||||
case SLJIT_LMUL_UW:
|
||||
case SLJIT_LMUL_SW:
|
||||
FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0)));
|
||||
FAIL_IF(push_inst(compiler, MADD | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO)));
|
||||
return push_inst(compiler, (op == SLJIT_LUMUL ? UMULH : SMULH) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));
|
||||
case SLJIT_UDIVMOD:
|
||||
case SLJIT_SDIVMOD:
|
||||
return push_inst(compiler, (op == SLJIT_LMUL_UW ? UMULH : SMULH) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));
|
||||
case SLJIT_DIVMOD_UW:
|
||||
case SLJIT_DIVMOD_SW:
|
||||
FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0)));
|
||||
FAIL_IF(push_inst(compiler, ((op == SLJIT_UDIVMOD ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)));
|
||||
FAIL_IF(push_inst(compiler, ((op == SLJIT_DIVMOD_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)));
|
||||
FAIL_IF(push_inst(compiler, (MADD ^ inv_bits) | RD(SLJIT_R1) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO)));
|
||||
return push_inst(compiler, (SUB ^ inv_bits) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));
|
||||
case SLJIT_UDIVI:
|
||||
case SLJIT_SDIVI:
|
||||
return push_inst(compiler, ((op == SLJIT_UDIVI ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1));
|
||||
case SLJIT_DIV_UW:
|
||||
case SLJIT_DIV_SW:
|
||||
return push_inst(compiler, ((op == SLJIT_DIV_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1));
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si dst_r, flags, mem_flags;
|
||||
sljit_si op_flags = GET_ALL_FLAGS(op);
|
||||
sljit_s32 dst_r, flags, mem_flags;
|
||||
sljit_s32 op_flags = GET_ALL_FLAGS(op);
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
|
||||
@ -1299,69 +1309,69 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
|
||||
case SLJIT_MOV_P:
|
||||
flags = WORD_SIZE;
|
||||
break;
|
||||
case SLJIT_MOV_UB:
|
||||
case SLJIT_MOV_U8:
|
||||
flags = BYTE_SIZE;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_ub)srcw;
|
||||
srcw = (sljit_u8)srcw;
|
||||
break;
|
||||
case SLJIT_MOV_SB:
|
||||
case SLJIT_MOV_S8:
|
||||
flags = BYTE_SIZE | SIGNED;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_sb)srcw;
|
||||
srcw = (sljit_s8)srcw;
|
||||
break;
|
||||
case SLJIT_MOV_UH:
|
||||
case SLJIT_MOV_U16:
|
||||
flags = HALF_SIZE;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_uh)srcw;
|
||||
srcw = (sljit_u16)srcw;
|
||||
break;
|
||||
case SLJIT_MOV_SH:
|
||||
case SLJIT_MOV_S16:
|
||||
flags = HALF_SIZE | SIGNED;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_sh)srcw;
|
||||
srcw = (sljit_s16)srcw;
|
||||
break;
|
||||
case SLJIT_MOV_UI:
|
||||
case SLJIT_MOV_U32:
|
||||
flags = INT_SIZE;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_ui)srcw;
|
||||
srcw = (sljit_u32)srcw;
|
||||
break;
|
||||
case SLJIT_MOV_SI:
|
||||
case SLJIT_MOV_S32:
|
||||
flags = INT_SIZE | SIGNED;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_si)srcw;
|
||||
srcw = (sljit_s32)srcw;
|
||||
break;
|
||||
case SLJIT_MOVU:
|
||||
case SLJIT_MOVU_P:
|
||||
flags = WORD_SIZE | UPDATE;
|
||||
break;
|
||||
case SLJIT_MOVU_UB:
|
||||
case SLJIT_MOVU_U8:
|
||||
flags = BYTE_SIZE | UPDATE;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_ub)srcw;
|
||||
srcw = (sljit_u8)srcw;
|
||||
break;
|
||||
case SLJIT_MOVU_SB:
|
||||
case SLJIT_MOVU_S8:
|
||||
flags = BYTE_SIZE | SIGNED | UPDATE;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_sb)srcw;
|
||||
srcw = (sljit_s8)srcw;
|
||||
break;
|
||||
case SLJIT_MOVU_UH:
|
||||
case SLJIT_MOVU_U16:
|
||||
flags = HALF_SIZE | UPDATE;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_uh)srcw;
|
||||
srcw = (sljit_u16)srcw;
|
||||
break;
|
||||
case SLJIT_MOVU_SH:
|
||||
case SLJIT_MOVU_S16:
|
||||
flags = HALF_SIZE | SIGNED | UPDATE;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_sh)srcw;
|
||||
srcw = (sljit_s16)srcw;
|
||||
break;
|
||||
case SLJIT_MOVU_UI:
|
||||
case SLJIT_MOVU_U32:
|
||||
flags = INT_SIZE | UPDATE;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_ui)srcw;
|
||||
srcw = (sljit_u32)srcw;
|
||||
break;
|
||||
case SLJIT_MOVU_SI:
|
||||
case SLJIT_MOVU_S32:
|
||||
flags = INT_SIZE | SIGNED | UPDATE;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_si)srcw;
|
||||
srcw = (sljit_s32)srcw;
|
||||
break;
|
||||
default:
|
||||
SLJIT_ASSERT_STOP();
|
||||
@ -1378,7 +1388,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
|
||||
FAIL_IF(getput_arg(compiler, flags, dst_r, src, srcw, dst, dstw));
|
||||
} else {
|
||||
if (dst_r != TMP_REG1)
|
||||
return emit_op_imm(compiler, op | ((op_flags & SLJIT_INT_OP) ? INT_OP : 0), dst_r, TMP_REG1, src);
|
||||
return emit_op_imm(compiler, op | ((op_flags & SLJIT_I32_OP) ? INT_OP : 0), dst_r, TMP_REG1, src);
|
||||
dst_r = src;
|
||||
}
|
||||
|
||||
@ -1393,7 +1403,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
|
||||
|
||||
flags = GET_FLAGS(op_flags) ? SET_FLAGS : 0;
|
||||
mem_flags = WORD_SIZE;
|
||||
if (op_flags & SLJIT_INT_OP) {
|
||||
if (op_flags & SLJIT_I32_OP) {
|
||||
flags |= INT_OP;
|
||||
mem_flags = INT_SIZE;
|
||||
}
|
||||
@ -1411,8 +1421,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
|
||||
|
||||
if (src & SLJIT_IMM) {
|
||||
flags |= ARG2_IMM;
|
||||
if (op_flags & SLJIT_INT_OP)
|
||||
srcw = (sljit_si)srcw;
|
||||
if (op_flags & SLJIT_I32_OP)
|
||||
srcw = (sljit_s32)srcw;
|
||||
} else
|
||||
srcw = src;
|
||||
|
||||
@ -1427,12 +1437,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w)
|
||||
{
|
||||
sljit_si dst_r, flags, mem_flags;
|
||||
sljit_s32 dst_r, flags, mem_flags;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
||||
@ -1446,7 +1456,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler
|
||||
dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
|
||||
flags = GET_FLAGS(op) ? SET_FLAGS : 0;
|
||||
mem_flags = WORD_SIZE;
|
||||
if (op & SLJIT_INT_OP) {
|
||||
if (op & SLJIT_I32_OP) {
|
||||
flags |= INT_OP;
|
||||
mem_flags = INT_SIZE;
|
||||
}
|
||||
@ -1512,20 +1522,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
|
||||
{
|
||||
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
|
||||
return reg_map[reg];
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
|
||||
{
|
||||
CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
|
||||
return reg;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
|
||||
void *instruction, sljit_si size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
|
||||
void *instruction, sljit_s32 size)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
|
||||
@ -1537,7 +1547,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co
|
||||
/* Floating point operators */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
|
||||
{
|
||||
#ifdef SLJIT_IS_FPU_AVAILABLE
|
||||
return SLJIT_IS_FPU_AVAILABLE;
|
||||
@ -1547,11 +1557,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)
|
||||
static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
|
||||
{
|
||||
sljit_ui shift = MEM_SIZE_SHIFT(flags);
|
||||
sljit_u32 shift = MEM_SIZE_SHIFT(flags);
|
||||
sljit_ins ins_bits = (shift << 30);
|
||||
sljit_si other_r;
|
||||
sljit_s32 other_r;
|
||||
sljit_sw diff;
|
||||
|
||||
SLJIT_ASSERT(arg & SLJIT_MEM);
|
||||
@ -1600,45 +1610,45 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl
|
||||
return push_inst(compiler, STR_FI | ins_bits | VT(reg) | RN(TMP_REG3));
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
|
||||
sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0;
|
||||
sljit_s32 dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
|
||||
sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0;
|
||||
|
||||
if (GET_OPCODE(op) == SLJIT_CONVI_FROMD)
|
||||
if (GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64)
|
||||
inv_bits |= (1 << 31);
|
||||
|
||||
if (src & SLJIT_MEM) {
|
||||
emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src, srcw);
|
||||
emit_fop_mem(compiler, (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src, srcw);
|
||||
src = TMP_FREG1;
|
||||
}
|
||||
|
||||
FAIL_IF(push_inst(compiler, (FCVTZS ^ inv_bits) | RD(dst_r) | VN(src)));
|
||||
|
||||
if (dst_r == TMP_REG1 && dst != SLJIT_UNUSED)
|
||||
return emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONVI_FROMD) ? INT_SIZE : WORD_SIZE) | STORE, TMP_REG1, dst, dstw);
|
||||
return emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) ? INT_SIZE : WORD_SIZE) | STORE, TMP_REG1, dst, dstw);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0;
|
||||
sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0;
|
||||
|
||||
if (GET_OPCODE(op) == SLJIT_CONVD_FROMI)
|
||||
if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
|
||||
inv_bits |= (1 << 31);
|
||||
|
||||
if (src & SLJIT_MEM) {
|
||||
emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONVD_FROMI) ? INT_SIZE : WORD_SIZE), TMP_REG1, src, srcw);
|
||||
emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) ? INT_SIZE : WORD_SIZE), TMP_REG1, src, srcw);
|
||||
src = TMP_REG1;
|
||||
} else if (src & SLJIT_IMM) {
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if (GET_OPCODE(op) == SLJIT_CONVD_FROMI)
|
||||
srcw = (sljit_si)srcw;
|
||||
if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
|
||||
srcw = (sljit_s32)srcw;
|
||||
#endif
|
||||
FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
|
||||
src = TMP_REG1;
|
||||
@ -1647,16 +1657,16 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *
|
||||
FAIL_IF(push_inst(compiler, (SCVTF ^ inv_bits) | VD(dst_r) | RN(src)));
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
return emit_fop_mem(compiler, ((op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE) | STORE, TMP_FREG1, dst, dstw);
|
||||
return emit_fop_mem(compiler, ((op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE) | STORE, TMP_FREG1, dst, dstw);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w)
|
||||
static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w)
|
||||
{
|
||||
sljit_si mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE;
|
||||
sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0;
|
||||
sljit_s32 mem_flags = (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE;
|
||||
sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0;
|
||||
|
||||
if (src1 & SLJIT_MEM) {
|
||||
emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w);
|
||||
@ -1671,11 +1681,11 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler
|
||||
return push_inst(compiler, (FCMP ^ inv_bits) | VN(src1) | VM(src2));
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si dst_r, mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE;
|
||||
sljit_s32 dst_r, mem_flags = (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE;
|
||||
sljit_ins inv_bits;
|
||||
|
||||
CHECK_ERROR();
|
||||
@ -1685,16 +1695,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile
|
||||
SLJIT_COMPILE_ASSERT((INT_SIZE ^ 0x100) == WORD_SIZE, must_be_one_bit_difference);
|
||||
SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
|
||||
|
||||
inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0;
|
||||
inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0;
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
|
||||
if (src & SLJIT_MEM) {
|
||||
emit_fop_mem(compiler, (GET_OPCODE(op) == SLJIT_CONVD_FROMS) ? (mem_flags ^ 0x100) : mem_flags, dst_r, src, srcw);
|
||||
emit_fop_mem(compiler, (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) ? (mem_flags ^ 0x100) : mem_flags, dst_r, src, srcw);
|
||||
src = dst_r;
|
||||
}
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_DMOV:
|
||||
case SLJIT_MOV_F64:
|
||||
if (src != dst_r) {
|
||||
if (dst_r != TMP_FREG1)
|
||||
FAIL_IF(push_inst(compiler, (FMOV ^ inv_bits) | VD(dst_r) | VN(src)));
|
||||
@ -1702,14 +1712,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile
|
||||
dst_r = src;
|
||||
}
|
||||
break;
|
||||
case SLJIT_DNEG:
|
||||
case SLJIT_NEG_F64:
|
||||
FAIL_IF(push_inst(compiler, (FNEG ^ inv_bits) | VD(dst_r) | VN(src)));
|
||||
break;
|
||||
case SLJIT_DABS:
|
||||
case SLJIT_ABS_F64:
|
||||
FAIL_IF(push_inst(compiler, (FABS ^ inv_bits) | VD(dst_r) | VN(src)));
|
||||
break;
|
||||
case SLJIT_CONVD_FROMS:
|
||||
FAIL_IF(push_inst(compiler, FCVT | ((op & SLJIT_SINGLE_OP) ? (1 << 22) : (1 << 15)) | VD(dst_r) | VN(src)));
|
||||
case SLJIT_CONV_F64_FROM_F32:
|
||||
FAIL_IF(push_inst(compiler, FCVT | ((op & SLJIT_F32_OP) ? (1 << 22) : (1 << 15)) | VD(dst_r) | VN(src)));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1718,13 +1728,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w)
|
||||
{
|
||||
sljit_si dst_r, mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE;
|
||||
sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0;
|
||||
sljit_s32 dst_r, mem_flags = (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE;
|
||||
sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
||||
@ -1746,16 +1756,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
||||
}
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_DADD:
|
||||
case SLJIT_ADD_F64:
|
||||
FAIL_IF(push_inst(compiler, (FADD ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
|
||||
break;
|
||||
case SLJIT_DSUB:
|
||||
case SLJIT_SUB_F64:
|
||||
FAIL_IF(push_inst(compiler, (FSUB ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
|
||||
break;
|
||||
case SLJIT_DMUL:
|
||||
case SLJIT_MUL_F64:
|
||||
FAIL_IF(push_inst(compiler, (FMUL ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
|
||||
break;
|
||||
case SLJIT_DDIV:
|
||||
case SLJIT_DIV_F64:
|
||||
FAIL_IF(push_inst(compiler, (FDIV ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2)));
|
||||
break;
|
||||
}
|
||||
@ -1769,7 +1779,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
||||
/* Other instructions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
|
||||
@ -1786,7 +1796,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c
|
||||
return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_LR, dst, dstw);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
||||
@ -1806,33 +1816,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
|
||||
/* Conditional instructions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static sljit_uw get_cc(sljit_si type)
|
||||
static sljit_uw get_cc(sljit_s32 type)
|
||||
{
|
||||
switch (type) {
|
||||
case SLJIT_EQUAL:
|
||||
case SLJIT_MUL_NOT_OVERFLOW:
|
||||
case SLJIT_D_EQUAL:
|
||||
case SLJIT_EQUAL_F64:
|
||||
return 0x1;
|
||||
|
||||
case SLJIT_NOT_EQUAL:
|
||||
case SLJIT_MUL_OVERFLOW:
|
||||
case SLJIT_D_NOT_EQUAL:
|
||||
case SLJIT_NOT_EQUAL_F64:
|
||||
return 0x0;
|
||||
|
||||
case SLJIT_LESS:
|
||||
case SLJIT_D_LESS:
|
||||
case SLJIT_LESS_F64:
|
||||
return 0x2;
|
||||
|
||||
case SLJIT_GREATER_EQUAL:
|
||||
case SLJIT_D_GREATER_EQUAL:
|
||||
case SLJIT_GREATER_EQUAL_F64:
|
||||
return 0x3;
|
||||
|
||||
case SLJIT_GREATER:
|
||||
case SLJIT_D_GREATER:
|
||||
case SLJIT_GREATER_F64:
|
||||
return 0x9;
|
||||
|
||||
case SLJIT_LESS_EQUAL:
|
||||
case SLJIT_D_LESS_EQUAL:
|
||||
case SLJIT_LESS_EQUAL_F64:
|
||||
return 0x8;
|
||||
|
||||
case SLJIT_SIG_LESS:
|
||||
@ -1848,11 +1858,11 @@ static sljit_uw get_cc(sljit_si type)
|
||||
return 0xc;
|
||||
|
||||
case SLJIT_OVERFLOW:
|
||||
case SLJIT_D_UNORDERED:
|
||||
case SLJIT_UNORDERED_F64:
|
||||
return 0x7;
|
||||
|
||||
case SLJIT_NOT_OVERFLOW:
|
||||
case SLJIT_D_ORDERED:
|
||||
case SLJIT_ORDERED_F64:
|
||||
return 0x6;
|
||||
|
||||
default:
|
||||
@ -1877,7 +1887,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
||||
return label;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type)
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
|
||||
{
|
||||
struct sljit_jump *jump;
|
||||
|
||||
@ -1903,11 +1913,11 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||
return jump;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compiler, sljit_si type,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
struct sljit_jump *jump;
|
||||
sljit_ins inv_bits = (type & SLJIT_INT_OP) ? (1 << 31) : 0;
|
||||
sljit_ins inv_bits = (type & SLJIT_I32_OP) ? (1 << 31) : 0;
|
||||
|
||||
SLJIT_ASSERT((type & 0xff) == SLJIT_EQUAL || (type & 0xff) == SLJIT_NOT_EQUAL);
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
@ -1937,7 +1947,7 @@ static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compi
|
||||
return jump;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
struct sljit_jump *jump;
|
||||
|
||||
@ -1964,12 +1974,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil
|
||||
return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1));
|
||||
}
|
||||
|
||||
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)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw,
|
||||
sljit_s32 type)
|
||||
{
|
||||
sljit_si dst_r, flags, mem_flags;
|
||||
sljit_s32 dst_r, flags, mem_flags;
|
||||
sljit_ins cc;
|
||||
|
||||
CHECK_ERROR();
|
||||
@ -1994,7 +2004,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
||||
compiler->cache_argw = 0;
|
||||
flags = GET_FLAGS(op) ? SET_FLAGS : 0;
|
||||
mem_flags = WORD_SIZE;
|
||||
if (op & SLJIT_INT_OP) {
|
||||
if (op & SLJIT_I32_OP) {
|
||||
flags |= INT_OP;
|
||||
mem_flags = INT_SIZE;
|
||||
}
|
||||
@ -2014,10 +2024,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
||||
return emit_op_mem2(compiler, mem_flags | STORE, TMP_REG1, dst, dstw, 0, 0);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value)
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
|
||||
{
|
||||
struct sljit_const *const_;
|
||||
sljit_si dst_r;
|
||||
sljit_s32 dst_r;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||
@ -2035,16 +2045,18 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||
return const_;
|
||||
}
|
||||
|
||||
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_target, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins* inst = (sljit_ins*)addr;
|
||||
modify_imm64_const(inst, new_addr);
|
||||
modify_imm64_const(inst, new_target);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 4);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins* inst = (sljit_ins*)addr;
|
||||
modify_imm64_const(inst, new_constant);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 4);
|
||||
}
|
||||
|
||||
@ -24,13 +24,13 @@
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void)
|
||||
SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
|
||||
{
|
||||
return "ARM-Thumb2" SLJIT_CPUINFO;
|
||||
}
|
||||
|
||||
/* Length of an instruction word. */
|
||||
typedef sljit_ui sljit_ins;
|
||||
typedef sljit_u32 sljit_ins;
|
||||
|
||||
/* Last register + 1. */
|
||||
#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
|
||||
@ -42,7 +42,7 @@ typedef sljit_ui sljit_ins;
|
||||
#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
|
||||
|
||||
/* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */
|
||||
static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
|
||||
static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
|
||||
0, 0, 1, 2, 12, 11, 10, 9, 8, 7, 6, 5, 13, 3, 4, 14, 15
|
||||
};
|
||||
|
||||
@ -181,21 +181,21 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
|
||||
#define VSTR_F32 0xed000a00
|
||||
#define VSUB_F32 0xee300a40
|
||||
|
||||
static sljit_si push_inst16(struct sljit_compiler *compiler, sljit_ins inst)
|
||||
static sljit_s32 push_inst16(struct sljit_compiler *compiler, sljit_ins inst)
|
||||
{
|
||||
sljit_uh *ptr;
|
||||
sljit_u16 *ptr;
|
||||
SLJIT_ASSERT(!(inst & 0xffff0000));
|
||||
|
||||
ptr = (sljit_uh*)ensure_buf(compiler, sizeof(sljit_uh));
|
||||
ptr = (sljit_u16*)ensure_buf(compiler, sizeof(sljit_u16));
|
||||
FAIL_IF(!ptr);
|
||||
*ptr = inst;
|
||||
compiler->size++;
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static sljit_si push_inst32(struct sljit_compiler *compiler, sljit_ins inst)
|
||||
static sljit_s32 push_inst32(struct sljit_compiler *compiler, sljit_ins inst)
|
||||
{
|
||||
sljit_uh *ptr = (sljit_uh*)ensure_buf(compiler, sizeof(sljit_ins));
|
||||
sljit_u16 *ptr = (sljit_u16*)ensure_buf(compiler, sizeof(sljit_ins));
|
||||
FAIL_IF(!ptr);
|
||||
*ptr++ = inst >> 16;
|
||||
*ptr = inst;
|
||||
@ -203,7 +203,7 @@ static sljit_si push_inst32(struct sljit_compiler *compiler, sljit_ins inst)
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si emit_imm32_const(struct sljit_compiler *compiler, sljit_si dst, sljit_uw imm)
|
||||
static SLJIT_INLINE sljit_s32 emit_imm32_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm)
|
||||
{
|
||||
FAIL_IF(push_inst32(compiler, MOVW | RD4(dst) |
|
||||
COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)));
|
||||
@ -211,9 +211,9 @@ static SLJIT_INLINE sljit_si emit_imm32_const(struct sljit_compiler *compiler, s
|
||||
COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16));
|
||||
}
|
||||
|
||||
static SLJIT_INLINE void modify_imm32_const(sljit_uh *inst, sljit_uw new_imm)
|
||||
static SLJIT_INLINE void modify_imm32_const(sljit_u16 *inst, sljit_uw new_imm)
|
||||
{
|
||||
sljit_si dst = inst[1] & 0x0f00;
|
||||
sljit_s32 dst = inst[1] & 0x0f00;
|
||||
SLJIT_ASSERT(((inst[0] & 0xfbf0) == (MOVW >> 16)) && ((inst[2] & 0xfbf0) == (MOVT >> 16)) && dst == (inst[3] & 0x0f00));
|
||||
inst[0] = (MOVW >> 16) | COPY_BITS(new_imm, 12, 0, 4) | COPY_BITS(new_imm, 11, 10, 1);
|
||||
inst[1] = dst | COPY_BITS(new_imm, 8, 12, 3) | (new_imm & 0xff);
|
||||
@ -221,7 +221,7 @@ static SLJIT_INLINE void modify_imm32_const(sljit_uh *inst, sljit_uw new_imm)
|
||||
inst[3] = dst | COPY_BITS(new_imm, 8 + 16, 12, 3) | ((new_imm & 0xff0000) >> 16);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uh *code_ptr, sljit_uh *code)
|
||||
static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_sw diff;
|
||||
|
||||
@ -232,7 +232,7 @@ static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uh
|
||||
/* Branch to ARM code is not optimized yet. */
|
||||
if (!(jump->u.target & 0x1))
|
||||
return 0;
|
||||
diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2)) >> 1;
|
||||
diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2) - executable_offset) >> 1;
|
||||
}
|
||||
else {
|
||||
SLJIT_ASSERT(jump->flags & JUMP_LABEL);
|
||||
@ -276,25 +276,27 @@ static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uh
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump)
|
||||
static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_si type = (jump->flags >> 4) & 0xf;
|
||||
sljit_s32 type = (jump->flags >> 4) & 0xf;
|
||||
sljit_sw diff;
|
||||
sljit_uh *jump_inst;
|
||||
sljit_si s, j1, j2;
|
||||
sljit_u16 *jump_inst;
|
||||
sljit_s32 s, j1, j2;
|
||||
|
||||
if (SLJIT_UNLIKELY(type == 0)) {
|
||||
modify_imm32_const((sljit_uh*)jump->addr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target);
|
||||
modify_imm32_const((sljit_u16*)jump->addr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target);
|
||||
return;
|
||||
}
|
||||
|
||||
if (jump->flags & JUMP_ADDR) {
|
||||
SLJIT_ASSERT(jump->u.target & 0x1);
|
||||
diff = ((sljit_sw)jump->u.target - (sljit_sw)(jump->addr + 4)) >> 1;
|
||||
diff = ((sljit_sw)jump->u.target - (sljit_sw)(jump->addr + sizeof(sljit_u32)) - executable_offset) >> 1;
|
||||
}
|
||||
else
|
||||
diff = ((sljit_sw)(jump->u.label->addr) - (sljit_sw)(jump->addr + 4)) >> 1;
|
||||
jump_inst = (sljit_uh*)jump->addr;
|
||||
else {
|
||||
SLJIT_ASSERT(jump->u.label->addr & 0x1);
|
||||
diff = ((sljit_sw)(jump->u.label->addr) - (sljit_sw)(jump->addr + sizeof(sljit_u32)) - executable_offset) >> 1;
|
||||
}
|
||||
jump_inst = (sljit_u16*)jump->addr;
|
||||
|
||||
switch (type) {
|
||||
case 1:
|
||||
@ -342,11 +344,12 @@ static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
|
||||
{
|
||||
struct sljit_memory_fragment *buf;
|
||||
sljit_uh *code;
|
||||
sljit_uh *code_ptr;
|
||||
sljit_uh *buf_ptr;
|
||||
sljit_uh *buf_end;
|
||||
sljit_u16 *code;
|
||||
sljit_u16 *code_ptr;
|
||||
sljit_u16 *buf_ptr;
|
||||
sljit_u16 *buf_end;
|
||||
sljit_uw half_count;
|
||||
sljit_sw executable_offset;
|
||||
|
||||
struct sljit_label *label;
|
||||
struct sljit_jump *jump;
|
||||
@ -356,18 +359,20 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
CHECK_PTR(check_sljit_generate_code(compiler));
|
||||
reverse_buf(compiler);
|
||||
|
||||
code = (sljit_uh*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_uh));
|
||||
code = (sljit_u16*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_u16));
|
||||
PTR_FAIL_WITH_EXEC_IF(code);
|
||||
buf = compiler->buf;
|
||||
|
||||
code_ptr = code;
|
||||
half_count = 0;
|
||||
executable_offset = SLJIT_EXEC_OFFSET(code);
|
||||
|
||||
label = compiler->labels;
|
||||
jump = compiler->jumps;
|
||||
const_ = compiler->consts;
|
||||
|
||||
do {
|
||||
buf_ptr = (sljit_uh*)buf->memory;
|
||||
buf_ptr = (sljit_u16*)buf->memory;
|
||||
buf_end = buf_ptr + (buf->used_size >> 1);
|
||||
do {
|
||||
*code_ptr = *buf_ptr++;
|
||||
@ -376,13 +381,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
SLJIT_ASSERT(!jump || jump->addr >= half_count);
|
||||
SLJIT_ASSERT(!const_ || const_->addr >= half_count);
|
||||
if (label && label->size == half_count) {
|
||||
label->addr = ((sljit_uw)code_ptr) | 0x1;
|
||||
label->addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;
|
||||
label->size = code_ptr - code;
|
||||
label = label->next;
|
||||
}
|
||||
if (jump && jump->addr == half_count) {
|
||||
jump->addr = (sljit_uw)code_ptr - ((jump->flags & IS_COND) ? 10 : 8);
|
||||
code_ptr -= detect_jump_type(jump, code_ptr, code);
|
||||
code_ptr -= detect_jump_type(jump, code_ptr, code, executable_offset);
|
||||
jump = jump->next;
|
||||
}
|
||||
if (const_ && const_->addr == half_count) {
|
||||
@ -397,7 +402,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
} while (buf);
|
||||
|
||||
if (label && label->size == half_count) {
|
||||
label->addr = ((sljit_uw)code_ptr) | 0x1;
|
||||
label->addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;
|
||||
label->size = code_ptr - code;
|
||||
label = label->next;
|
||||
}
|
||||
@ -409,12 +414,17 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
|
||||
jump = compiler->jumps;
|
||||
while (jump) {
|
||||
set_jump_instruction(jump);
|
||||
set_jump_instruction(jump, executable_offset);
|
||||
jump = jump->next;
|
||||
}
|
||||
|
||||
compiler->error = SLJIT_ERR_COMPILED;
|
||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_uh);
|
||||
compiler->executable_offset = executable_offset;
|
||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_u16);
|
||||
|
||||
code = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
|
||||
code_ptr = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
|
||||
SLJIT_CACHE_FLUSH(code, code_ptr);
|
||||
/* Set thumb mode flag. */
|
||||
return (void*)((sljit_uw)code | 0x1);
|
||||
@ -428,7 +438,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
static sljit_uw get_imm(sljit_uw imm)
|
||||
{
|
||||
/* Thumb immediate form. */
|
||||
sljit_si counter;
|
||||
sljit_s32 counter;
|
||||
|
||||
if (imm <= 0xff)
|
||||
return imm;
|
||||
@ -474,7 +484,7 @@ static sljit_uw get_imm(sljit_uw imm)
|
||||
return ((imm >> 24) & 0x7f) | COPY_BITS(counter, 4, 26, 1) | COPY_BITS(counter, 1, 12, 3) | COPY_BITS(counter, 0, 7, 1);
|
||||
}
|
||||
|
||||
static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sljit_uw imm)
|
||||
static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm)
|
||||
{
|
||||
sljit_uw tmp;
|
||||
|
||||
@ -508,12 +518,12 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sl
|
||||
#define SLOW_SRC1 0x0800000
|
||||
#define SLOW_SRC2 0x1000000
|
||||
|
||||
static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, sljit_si dst, sljit_uw arg1, sljit_uw arg2)
|
||||
static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 dst, sljit_uw arg1, sljit_uw arg2)
|
||||
{
|
||||
/* dst must be register, TMP_REG1
|
||||
arg1 must be register, TMP_REG1, imm
|
||||
arg2 must be register, TMP_REG2, imm */
|
||||
sljit_si reg;
|
||||
sljit_s32 reg;
|
||||
sljit_uw imm, nimm;
|
||||
|
||||
if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) {
|
||||
@ -677,37 +687,37 @@ static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, slj
|
||||
/* Both arguments are registers. */
|
||||
switch (flags & 0xffff) {
|
||||
case SLJIT_MOV:
|
||||
case SLJIT_MOV_UI:
|
||||
case SLJIT_MOV_SI:
|
||||
case SLJIT_MOV_U32:
|
||||
case SLJIT_MOV_S32:
|
||||
case SLJIT_MOV_P:
|
||||
case SLJIT_MOVU:
|
||||
case SLJIT_MOVU_UI:
|
||||
case SLJIT_MOVU_SI:
|
||||
case SLJIT_MOVU_U32:
|
||||
case SLJIT_MOVU_S32:
|
||||
case SLJIT_MOVU_P:
|
||||
SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
|
||||
if (dst == arg2)
|
||||
return SLJIT_SUCCESS;
|
||||
return push_inst16(compiler, MOV | SET_REGS44(dst, arg2));
|
||||
case SLJIT_MOV_UB:
|
||||
case SLJIT_MOVU_UB:
|
||||
case SLJIT_MOV_U8:
|
||||
case SLJIT_MOVU_U8:
|
||||
SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
|
||||
if (IS_2_LO_REGS(dst, arg2))
|
||||
return push_inst16(compiler, UXTB | RD3(dst) | RN3(arg2));
|
||||
return push_inst32(compiler, UXTB_W | RD4(dst) | RM4(arg2));
|
||||
case SLJIT_MOV_SB:
|
||||
case SLJIT_MOVU_SB:
|
||||
case SLJIT_MOV_S8:
|
||||
case SLJIT_MOVU_S8:
|
||||
SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
|
||||
if (IS_2_LO_REGS(dst, arg2))
|
||||
return push_inst16(compiler, SXTB | RD3(dst) | RN3(arg2));
|
||||
return push_inst32(compiler, SXTB_W | RD4(dst) | RM4(arg2));
|
||||
case SLJIT_MOV_UH:
|
||||
case SLJIT_MOVU_UH:
|
||||
case SLJIT_MOV_U16:
|
||||
case SLJIT_MOVU_U16:
|
||||
SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
|
||||
if (IS_2_LO_REGS(dst, arg2))
|
||||
return push_inst16(compiler, UXTH | RD3(dst) | RN3(arg2));
|
||||
return push_inst32(compiler, UXTH_W | RD4(dst) | RM4(arg2));
|
||||
case SLJIT_MOV_SH:
|
||||
case SLJIT_MOVU_SH:
|
||||
case SLJIT_MOV_S16:
|
||||
case SLJIT_MOVU_S16:
|
||||
SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
|
||||
if (IS_2_LO_REGS(dst, arg2))
|
||||
return push_inst16(compiler, SXTH | RD3(dst) | RN3(arg2));
|
||||
@ -813,7 +823,7 @@ static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, slj
|
||||
s = store
|
||||
*/
|
||||
|
||||
static SLJIT_CONST sljit_ins sljit_mem16[12] = {
|
||||
static const sljit_ins sljit_mem16[12] = {
|
||||
/* w u l */ 0x5800 /* ldr */,
|
||||
/* w u s */ 0x5000 /* str */,
|
||||
/* w s l */ 0x5800 /* ldr */,
|
||||
@ -830,7 +840,7 @@ static SLJIT_CONST sljit_ins sljit_mem16[12] = {
|
||||
/* h s s */ 0x5200 /* strh */,
|
||||
};
|
||||
|
||||
static SLJIT_CONST sljit_ins sljit_mem16_imm5[12] = {
|
||||
static const sljit_ins sljit_mem16_imm5[12] = {
|
||||
/* w u l */ 0x6800 /* ldr imm5 */,
|
||||
/* w u s */ 0x6000 /* str imm5 */,
|
||||
/* w s l */ 0x6800 /* ldr imm5 */,
|
||||
@ -849,7 +859,7 @@ static SLJIT_CONST sljit_ins sljit_mem16_imm5[12] = {
|
||||
|
||||
#define MEM_IMM8 0xc00
|
||||
#define MEM_IMM12 0x800000
|
||||
static SLJIT_CONST sljit_ins sljit_mem32[12] = {
|
||||
static const sljit_ins sljit_mem32[12] = {
|
||||
/* w u l */ 0xf8500000 /* ldr.w */,
|
||||
/* w u s */ 0xf8400000 /* str.w */,
|
||||
/* w s l */ 0xf8500000 /* ldr.w */,
|
||||
@ -867,7 +877,7 @@ static SLJIT_CONST sljit_ins sljit_mem32[12] = {
|
||||
};
|
||||
|
||||
/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */
|
||||
static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw value)
|
||||
static sljit_s32 emit_set_delta(struct sljit_compiler *compiler, sljit_s32 dst, sljit_s32 reg, sljit_sw value)
|
||||
{
|
||||
if (value >= 0) {
|
||||
if (value <= 0xfff)
|
||||
@ -888,9 +898,9 @@ static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sl
|
||||
}
|
||||
|
||||
/* Can perform an operation using at most 1 instruction. */
|
||||
static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)
|
||||
static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
|
||||
{
|
||||
sljit_si other_r, shift;
|
||||
sljit_s32 other_r, shift;
|
||||
|
||||
SLJIT_ASSERT(arg & SLJIT_MEM);
|
||||
|
||||
@ -975,7 +985,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags,
|
||||
/* see getput_arg below.
|
||||
Note: can_cache is called only for binary operators. Those
|
||||
operators always uses word arguments without write back. */
|
||||
static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
|
||||
static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
|
||||
{
|
||||
sljit_sw diff;
|
||||
if ((arg & OFFS_REG_MASK) || !(next_arg & SLJIT_MEM))
|
||||
@ -999,10 +1009,10 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_
|
||||
}
|
||||
|
||||
/* Emit the necessary instructions. See can_cache above. */
|
||||
static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg,
|
||||
sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
|
||||
static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg,
|
||||
sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
|
||||
{
|
||||
sljit_si tmp_r, other_r;
|
||||
sljit_s32 tmp_r, other_r;
|
||||
sljit_sw diff;
|
||||
|
||||
SLJIT_ASSERT(arg & SLJIT_MEM);
|
||||
@ -1107,7 +1117,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji
|
||||
return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | 0);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)
|
||||
static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
|
||||
{
|
||||
if (getput_arg_fast(compiler, flags, reg, arg, argw))
|
||||
return compiler->error;
|
||||
@ -1116,7 +1126,7 @@ static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_
|
||||
return getput_arg(compiler, flags, reg, arg, argw, 0, 0);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w)
|
||||
static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
|
||||
{
|
||||
if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
|
||||
return compiler->error;
|
||||
@ -1127,11 +1137,11 @@ static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit
|
||||
/* Entry, exit */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
sljit_si size, i, tmp;
|
||||
sljit_s32 size, i, tmp;
|
||||
sljit_ins push;
|
||||
|
||||
CHECK_ERROR();
|
||||
@ -1172,11 +1182,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
sljit_si size;
|
||||
sljit_s32 size;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
@ -1187,9 +1197,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si i, tmp;
|
||||
sljit_s32 i, tmp;
|
||||
sljit_ins pop;
|
||||
|
||||
CHECK_ERROR();
|
||||
@ -1237,7 +1247,7 @@ extern int __aeabi_idivmod(int numerator, int denominator);
|
||||
}
|
||||
#endif
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
|
||||
{
|
||||
sljit_sw saved_reg_list[3];
|
||||
sljit_sw saved_reg_count;
|
||||
@ -1251,18 +1261,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
return push_inst16(compiler, BKPT);
|
||||
case SLJIT_NOP:
|
||||
return push_inst16(compiler, NOP);
|
||||
case SLJIT_LUMUL:
|
||||
case SLJIT_LSMUL:
|
||||
return push_inst32(compiler, (op == SLJIT_LUMUL ? UMULL : SMULL)
|
||||
case SLJIT_LMUL_UW:
|
||||
case SLJIT_LMUL_SW:
|
||||
return push_inst32(compiler, (op == SLJIT_LMUL_UW ? UMULL : SMULL)
|
||||
| (reg_map[SLJIT_R1] << 8)
|
||||
| (reg_map[SLJIT_R0] << 12)
|
||||
| (reg_map[SLJIT_R0] << 16)
|
||||
| reg_map[SLJIT_R1]);
|
||||
case SLJIT_UDIVMOD:
|
||||
case SLJIT_SDIVMOD:
|
||||
case SLJIT_UDIVI:
|
||||
case SLJIT_SDIVI:
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments);
|
||||
case SLJIT_DIVMOD_UW:
|
||||
case SLJIT_DIVMOD_SW:
|
||||
case SLJIT_DIV_UW:
|
||||
case SLJIT_DIV_SW:
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
|
||||
SLJIT_COMPILE_ASSERT(reg_map[2] == 1 && reg_map[3] == 2 && reg_map[4] == 12, bad_register_mapping);
|
||||
|
||||
saved_reg_count = 0;
|
||||
@ -1270,7 +1280,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
saved_reg_list[saved_reg_count++] = 12;
|
||||
if (compiler->scratches >= 3)
|
||||
saved_reg_list[saved_reg_count++] = 2;
|
||||
if (op >= SLJIT_UDIVI)
|
||||
if (op >= SLJIT_DIV_UW)
|
||||
saved_reg_list[saved_reg_count++] = 1;
|
||||
|
||||
if (saved_reg_count > 0) {
|
||||
@ -1288,7 +1298,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
|
||||
#if defined(__GNUC__)
|
||||
FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,
|
||||
((op | 0x2) == SLJIT_UDIVI ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
|
||||
((op | 0x2) == SLJIT_DIV_UW ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
|
||||
#else
|
||||
#error "Software divmod functions are needed"
|
||||
#endif
|
||||
@ -1311,12 +1321,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si dst_r, flags;
|
||||
sljit_si op_flags = GET_ALL_FLAGS(op);
|
||||
sljit_s32 dst_r, flags;
|
||||
sljit_s32 op_flags = GET_ALL_FLAGS(op);
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
|
||||
@ -1332,56 +1342,56 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
|
||||
if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) {
|
||||
switch (op) {
|
||||
case SLJIT_MOV:
|
||||
case SLJIT_MOV_UI:
|
||||
case SLJIT_MOV_SI:
|
||||
case SLJIT_MOV_U32:
|
||||
case SLJIT_MOV_S32:
|
||||
case SLJIT_MOV_P:
|
||||
flags = WORD_SIZE;
|
||||
break;
|
||||
case SLJIT_MOV_UB:
|
||||
case SLJIT_MOV_U8:
|
||||
flags = BYTE_SIZE;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_ub)srcw;
|
||||
srcw = (sljit_u8)srcw;
|
||||
break;
|
||||
case SLJIT_MOV_SB:
|
||||
case SLJIT_MOV_S8:
|
||||
flags = BYTE_SIZE | SIGNED;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_sb)srcw;
|
||||
srcw = (sljit_s8)srcw;
|
||||
break;
|
||||
case SLJIT_MOV_UH:
|
||||
case SLJIT_MOV_U16:
|
||||
flags = HALF_SIZE;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_uh)srcw;
|
||||
srcw = (sljit_u16)srcw;
|
||||
break;
|
||||
case SLJIT_MOV_SH:
|
||||
case SLJIT_MOV_S16:
|
||||
flags = HALF_SIZE | SIGNED;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_sh)srcw;
|
||||
srcw = (sljit_s16)srcw;
|
||||
break;
|
||||
case SLJIT_MOVU:
|
||||
case SLJIT_MOVU_UI:
|
||||
case SLJIT_MOVU_SI:
|
||||
case SLJIT_MOVU_U32:
|
||||
case SLJIT_MOVU_S32:
|
||||
case SLJIT_MOVU_P:
|
||||
flags = WORD_SIZE | UPDATE;
|
||||
break;
|
||||
case SLJIT_MOVU_UB:
|
||||
case SLJIT_MOVU_U8:
|
||||
flags = BYTE_SIZE | UPDATE;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_ub)srcw;
|
||||
srcw = (sljit_u8)srcw;
|
||||
break;
|
||||
case SLJIT_MOVU_SB:
|
||||
case SLJIT_MOVU_S8:
|
||||
flags = BYTE_SIZE | SIGNED | UPDATE;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_sb)srcw;
|
||||
srcw = (sljit_s8)srcw;
|
||||
break;
|
||||
case SLJIT_MOVU_UH:
|
||||
case SLJIT_MOVU_U16:
|
||||
flags = HALF_SIZE | UPDATE;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_uh)srcw;
|
||||
srcw = (sljit_u16)srcw;
|
||||
break;
|
||||
case SLJIT_MOVU_SH:
|
||||
case SLJIT_MOVU_S16:
|
||||
flags = HALF_SIZE | SIGNED | UPDATE;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_sh)srcw;
|
||||
srcw = (sljit_s16)srcw;
|
||||
break;
|
||||
default:
|
||||
SLJIT_ASSERT_STOP();
|
||||
@ -1444,12 +1454,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w)
|
||||
{
|
||||
sljit_si dst_r, flags;
|
||||
sljit_s32 dst_r, flags;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
||||
@ -1523,26 +1533,26 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
|
||||
{
|
||||
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
|
||||
return reg_map[reg];
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
|
||||
{
|
||||
CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
|
||||
return reg << 1;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
|
||||
void *instruction, sljit_si size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
|
||||
void *instruction, sljit_s32 size)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
|
||||
|
||||
if (size == 2)
|
||||
return push_inst16(compiler, *(sljit_uh*)instruction);
|
||||
return push_inst16(compiler, *(sljit_u16*)instruction);
|
||||
return push_inst32(compiler, *(sljit_ins*)instruction);
|
||||
}
|
||||
|
||||
@ -1550,7 +1560,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co
|
||||
/* Floating point operators */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
|
||||
{
|
||||
#ifdef SLJIT_IS_FPU_AVAILABLE
|
||||
return SLJIT_IS_FPU_AVAILABLE;
|
||||
@ -1562,11 +1572,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
|
||||
|
||||
#define FPU_LOAD (1 << 20)
|
||||
|
||||
static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)
|
||||
static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
|
||||
{
|
||||
sljit_sw tmp;
|
||||
sljit_uw imm;
|
||||
sljit_sw inst = VSTR_F32 | (flags & (SLJIT_SINGLE_OP | FPU_LOAD));
|
||||
sljit_sw inst = VSTR_F32 | (flags & (SLJIT_F32_OP | FPU_LOAD));
|
||||
|
||||
SLJIT_ASSERT(arg & SLJIT_MEM);
|
||||
|
||||
@ -1626,16 +1636,16 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl
|
||||
return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg));
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
if (src & SLJIT_MEM) {
|
||||
FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src, srcw));
|
||||
FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src, srcw));
|
||||
src = TMP_FREG1;
|
||||
}
|
||||
|
||||
FAIL_IF(push_inst32(compiler, VCVT_S32_F32 | (op & SLJIT_SINGLE_OP) | DD4(TMP_FREG1) | DM4(src)));
|
||||
FAIL_IF(push_inst32(compiler, VCVT_S32_F32 | (op & SLJIT_F32_OP) | DD4(TMP_FREG1) | DM4(src)));
|
||||
|
||||
if (dst == SLJIT_UNUSED)
|
||||
return SLJIT_SUCCESS;
|
||||
@ -1647,11 +1657,11 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *
|
||||
return emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
|
||||
if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst32(compiler, VMOV | RT4(src) | DN4(TMP_FREG1)));
|
||||
@ -1664,85 +1674,85 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *
|
||||
FAIL_IF(push_inst32(compiler, VMOV | RT4(TMP_REG1) | DN4(TMP_FREG1)));
|
||||
}
|
||||
|
||||
FAIL_IF(push_inst32(compiler, VCVT_F32_S32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(TMP_FREG1)));
|
||||
FAIL_IF(push_inst32(compiler, VCVT_F32_S32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(TMP_FREG1)));
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw);
|
||||
return emit_fop_mem(compiler, (op & SLJIT_F32_OP), TMP_FREG1, dst, dstw);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w)
|
||||
static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w)
|
||||
{
|
||||
if (src1 & SLJIT_MEM) {
|
||||
emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w);
|
||||
emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src1, src1w);
|
||||
src1 = TMP_FREG1;
|
||||
}
|
||||
|
||||
if (src2 & SLJIT_MEM) {
|
||||
emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w);
|
||||
emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG2, src2, src2w);
|
||||
src2 = TMP_FREG2;
|
||||
}
|
||||
|
||||
FAIL_IF(push_inst32(compiler, VCMP_F32 | (op & SLJIT_SINGLE_OP) | DD4(src1) | DM4(src2)));
|
||||
FAIL_IF(push_inst32(compiler, VCMP_F32 | (op & SLJIT_F32_OP) | DD4(src1) | DM4(src2)));
|
||||
return push_inst32(compiler, VMRS);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si dst_r;
|
||||
sljit_s32 dst_r;
|
||||
|
||||
CHECK_ERROR();
|
||||
compiler->cache_arg = 0;
|
||||
compiler->cache_argw = 0;
|
||||
if (GET_OPCODE(op) != SLJIT_CONVD_FROMS)
|
||||
op ^= SLJIT_SINGLE_OP;
|
||||
if (GET_OPCODE(op) != SLJIT_CONV_F64_FROM_F32)
|
||||
op ^= SLJIT_F32_OP;
|
||||
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100), float_transfer_bit_error);
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100), float_transfer_bit_error);
|
||||
SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
|
||||
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
|
||||
if (src & SLJIT_MEM) {
|
||||
emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, dst_r, src, srcw);
|
||||
emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, dst_r, src, srcw);
|
||||
src = dst_r;
|
||||
}
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_DMOV:
|
||||
case SLJIT_MOV_F64:
|
||||
if (src != dst_r) {
|
||||
if (dst_r != TMP_FREG1)
|
||||
FAIL_IF(push_inst32(compiler, VMOV_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src)));
|
||||
FAIL_IF(push_inst32(compiler, VMOV_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(src)));
|
||||
else
|
||||
dst_r = src;
|
||||
}
|
||||
break;
|
||||
case SLJIT_DNEG:
|
||||
FAIL_IF(push_inst32(compiler, VNEG_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src)));
|
||||
case SLJIT_NEG_F64:
|
||||
FAIL_IF(push_inst32(compiler, VNEG_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(src)));
|
||||
break;
|
||||
case SLJIT_DABS:
|
||||
FAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src)));
|
||||
case SLJIT_ABS_F64:
|
||||
FAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(src)));
|
||||
break;
|
||||
case SLJIT_CONVD_FROMS:
|
||||
FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src)));
|
||||
op ^= SLJIT_SINGLE_OP;
|
||||
case SLJIT_CONV_F64_FROM_F32:
|
||||
FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(src)));
|
||||
op ^= SLJIT_F32_OP;
|
||||
break;
|
||||
}
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), dst_r, dst, dstw);
|
||||
return emit_fop_mem(compiler, (op & SLJIT_F32_OP), dst_r, dst, dstw);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w)
|
||||
{
|
||||
sljit_si dst_r;
|
||||
sljit_s32 dst_r;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
||||
@ -1752,36 +1762,36 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
||||
|
||||
compiler->cache_arg = 0;
|
||||
compiler->cache_argw = 0;
|
||||
op ^= SLJIT_SINGLE_OP;
|
||||
op ^= SLJIT_F32_OP;
|
||||
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
if (src1 & SLJIT_MEM) {
|
||||
emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w);
|
||||
emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src1, src1w);
|
||||
src1 = TMP_FREG1;
|
||||
}
|
||||
if (src2 & SLJIT_MEM) {
|
||||
emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w);
|
||||
emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG2, src2, src2w);
|
||||
src2 = TMP_FREG2;
|
||||
}
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_DADD:
|
||||
FAIL_IF(push_inst32(compiler, VADD_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2)));
|
||||
case SLJIT_ADD_F64:
|
||||
FAIL_IF(push_inst32(compiler, VADD_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DN4(src1) | DM4(src2)));
|
||||
break;
|
||||
case SLJIT_DSUB:
|
||||
FAIL_IF(push_inst32(compiler, VSUB_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2)));
|
||||
case SLJIT_SUB_F64:
|
||||
FAIL_IF(push_inst32(compiler, VSUB_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DN4(src1) | DM4(src2)));
|
||||
break;
|
||||
case SLJIT_DMUL:
|
||||
FAIL_IF(push_inst32(compiler, VMUL_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2)));
|
||||
case SLJIT_MUL_F64:
|
||||
FAIL_IF(push_inst32(compiler, VMUL_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DN4(src1) | DM4(src2)));
|
||||
break;
|
||||
case SLJIT_DDIV:
|
||||
FAIL_IF(push_inst32(compiler, VDIV_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2)));
|
||||
case SLJIT_DIV_F64:
|
||||
FAIL_IF(push_inst32(compiler, VDIV_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DN4(src1) | DM4(src2)));
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(dst & SLJIT_MEM))
|
||||
return SLJIT_SUCCESS;
|
||||
return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw);
|
||||
return emit_fop_mem(compiler, (op & SLJIT_F32_OP), TMP_FREG1, dst, dstw);
|
||||
}
|
||||
|
||||
#undef FPU_LOAD
|
||||
@ -1790,7 +1800,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
||||
/* Other instructions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
|
||||
@ -1813,7 +1823,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c
|
||||
return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
||||
@ -1840,33 +1850,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
|
||||
/* Conditional instructions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static sljit_uw get_cc(sljit_si type)
|
||||
static sljit_uw get_cc(sljit_s32 type)
|
||||
{
|
||||
switch (type) {
|
||||
case SLJIT_EQUAL:
|
||||
case SLJIT_MUL_NOT_OVERFLOW:
|
||||
case SLJIT_D_EQUAL:
|
||||
case SLJIT_EQUAL_F64:
|
||||
return 0x0;
|
||||
|
||||
case SLJIT_NOT_EQUAL:
|
||||
case SLJIT_MUL_OVERFLOW:
|
||||
case SLJIT_D_NOT_EQUAL:
|
||||
case SLJIT_NOT_EQUAL_F64:
|
||||
return 0x1;
|
||||
|
||||
case SLJIT_LESS:
|
||||
case SLJIT_D_LESS:
|
||||
case SLJIT_LESS_F64:
|
||||
return 0x3;
|
||||
|
||||
case SLJIT_GREATER_EQUAL:
|
||||
case SLJIT_D_GREATER_EQUAL:
|
||||
case SLJIT_GREATER_EQUAL_F64:
|
||||
return 0x2;
|
||||
|
||||
case SLJIT_GREATER:
|
||||
case SLJIT_D_GREATER:
|
||||
case SLJIT_GREATER_F64:
|
||||
return 0x8;
|
||||
|
||||
case SLJIT_LESS_EQUAL:
|
||||
case SLJIT_D_LESS_EQUAL:
|
||||
case SLJIT_LESS_EQUAL_F64:
|
||||
return 0x9;
|
||||
|
||||
case SLJIT_SIG_LESS:
|
||||
@ -1882,11 +1892,11 @@ static sljit_uw get_cc(sljit_si type)
|
||||
return 0xd;
|
||||
|
||||
case SLJIT_OVERFLOW:
|
||||
case SLJIT_D_UNORDERED:
|
||||
case SLJIT_UNORDERED_F64:
|
||||
return 0x6;
|
||||
|
||||
case SLJIT_NOT_OVERFLOW:
|
||||
case SLJIT_D_ORDERED:
|
||||
case SLJIT_ORDERED_F64:
|
||||
return 0x7;
|
||||
|
||||
default: /* SLJIT_JUMP */
|
||||
@ -1911,7 +1921,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
||||
return label;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type)
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
|
||||
{
|
||||
struct sljit_jump *jump;
|
||||
sljit_ins cc;
|
||||
@ -1944,7 +1954,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||
return jump;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
struct sljit_jump *jump;
|
||||
|
||||
@ -1972,12 +1982,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil
|
||||
return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(TMP_REG1));
|
||||
}
|
||||
|
||||
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)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw,
|
||||
sljit_s32 type)
|
||||
{
|
||||
sljit_si dst_r, flags = GET_ALL_FLAGS(op);
|
||||
sljit_s32 dst_r, flags = GET_ALL_FLAGS(op);
|
||||
sljit_ins cc, ins;
|
||||
|
||||
CHECK_ERROR();
|
||||
@ -2054,10 +2064,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value)
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
|
||||
{
|
||||
struct sljit_const *const_;
|
||||
sljit_si dst_r;
|
||||
sljit_s32 dst_r;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||
@ -2075,16 +2085,18 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||
return const_;
|
||||
}
|
||||
|
||||
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_target, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_uh *inst = (sljit_uh*)addr;
|
||||
modify_imm32_const(inst, new_addr);
|
||||
sljit_u16 *inst = (sljit_u16*)addr;
|
||||
modify_imm32_const(inst, new_target);
|
||||
inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 4);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_uh *inst = (sljit_uh*)addr;
|
||||
sljit_u16 *inst = (sljit_u16*)addr;
|
||||
modify_imm32_const(inst, new_constant);
|
||||
inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 4);
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
|
||||
/* mips 32-bit arch dependent functions. */
|
||||
|
||||
static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm)
|
||||
static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm)
|
||||
{
|
||||
if (!(imm & ~0xffff))
|
||||
return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);
|
||||
@ -66,24 +66,24 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar,
|
||||
FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | D(dst), DR(dst))); \
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags,
|
||||
sljit_si dst, sljit_si src1, sljit_sw src2)
|
||||
static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
|
||||
sljit_s32 dst, sljit_s32 src1, sljit_sw src2)
|
||||
{
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_MOV:
|
||||
case SLJIT_MOV_UI:
|
||||
case SLJIT_MOV_SI:
|
||||
case SLJIT_MOV_U32:
|
||||
case SLJIT_MOV_S32:
|
||||
case SLJIT_MOV_P:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if (dst != src2)
|
||||
return push_inst(compiler, ADDU | S(src2) | TA(0) | D(dst), DR(dst));
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UB:
|
||||
case SLJIT_MOV_SB:
|
||||
case SLJIT_MOV_U8:
|
||||
case SLJIT_MOV_S8:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SB) {
|
||||
if (op == SLJIT_MOV_S8) {
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
|
||||
#else
|
||||
@ -97,11 +97,11 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
||||
SLJIT_ASSERT_STOP();
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UH:
|
||||
case SLJIT_MOV_SH:
|
||||
case SLJIT_MOV_U16:
|
||||
case SLJIT_MOV_S16:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SH) {
|
||||
if (op == SLJIT_MOV_S16) {
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
|
||||
#else
|
||||
@ -341,26 +341,28 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value)
|
||||
static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value)
|
||||
{
|
||||
FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 16), DR(dst)));
|
||||
return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst));
|
||||
}
|
||||
|
||||
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_target, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins*)addr;
|
||||
sljit_ins *inst = (sljit_ins *)addr;
|
||||
|
||||
inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff);
|
||||
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins*)addr;
|
||||
sljit_ins *inst = (sljit_ins *)addr;
|
||||
|
||||
inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||
}
|
||||
|
||||
@ -26,11 +26,11 @@
|
||||
|
||||
/* mips 64-bit arch dependent functions. */
|
||||
|
||||
static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm)
|
||||
static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm)
|
||||
{
|
||||
sljit_si shift = 32;
|
||||
sljit_si shift2;
|
||||
sljit_si inv = 0;
|
||||
sljit_s32 shift = 32;
|
||||
sljit_s32 shift2;
|
||||
sljit_s32 inv = 0;
|
||||
sljit_ins ins;
|
||||
sljit_uw uimm;
|
||||
|
||||
@ -119,7 +119,7 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar,
|
||||
}
|
||||
|
||||
#define SELECT_OP(a, b) \
|
||||
(!(op & SLJIT_INT_OP) ? a : b)
|
||||
(!(op & SLJIT_I32_OP) ? a : b)
|
||||
|
||||
#define EMIT_LOGICAL(op_imm, op_norm) \
|
||||
if (flags & SRC2_IMM) { \
|
||||
@ -138,27 +138,27 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar,
|
||||
#define EMIT_SHIFT(op_dimm, op_dimm32, op_imm, op_dv, op_v) \
|
||||
if (flags & SRC2_IMM) { \
|
||||
if (src2 >= 32) { \
|
||||
SLJIT_ASSERT(!(op & SLJIT_INT_OP)); \
|
||||
SLJIT_ASSERT(!(op & SLJIT_I32_OP)); \
|
||||
ins = op_dimm32; \
|
||||
src2 -= 32; \
|
||||
} \
|
||||
else \
|
||||
ins = (op & SLJIT_INT_OP) ? op_imm : op_dimm; \
|
||||
ins = (op & SLJIT_I32_OP) ? op_imm : op_dimm; \
|
||||
if (op & SLJIT_SET_E) \
|
||||
FAIL_IF(push_inst(compiler, ins | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \
|
||||
if (CHECK_FLAGS(SLJIT_SET_E)) \
|
||||
FAIL_IF(push_inst(compiler, ins | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \
|
||||
} \
|
||||
else { \
|
||||
ins = (op & SLJIT_INT_OP) ? op_v : op_dv; \
|
||||
ins = (op & SLJIT_I32_OP) ? op_v : op_dv; \
|
||||
if (op & SLJIT_SET_E) \
|
||||
FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
|
||||
if (CHECK_FLAGS(SLJIT_SET_E)) \
|
||||
FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | D(dst), DR(dst))); \
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags,
|
||||
sljit_si dst, sljit_si src1, sljit_sw src2)
|
||||
static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
|
||||
sljit_s32 dst, sljit_s32 src1, sljit_sw src2)
|
||||
{
|
||||
sljit_ins ins;
|
||||
|
||||
@ -170,11 +170,11 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
||||
return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(dst), DR(dst));
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UB:
|
||||
case SLJIT_MOV_SB:
|
||||
case SLJIT_MOV_U8:
|
||||
case SLJIT_MOV_S8:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SB) {
|
||||
if (op == SLJIT_MOV_S8) {
|
||||
FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
|
||||
return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(24), DR(dst));
|
||||
}
|
||||
@ -184,11 +184,11 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
||||
SLJIT_ASSERT_STOP();
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UH:
|
||||
case SLJIT_MOV_SH:
|
||||
case SLJIT_MOV_U16:
|
||||
case SLJIT_MOV_S16:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SH) {
|
||||
if (op == SLJIT_MOV_S16) {
|
||||
FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
|
||||
return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(16), DR(dst));
|
||||
}
|
||||
@ -198,12 +198,12 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
||||
SLJIT_ASSERT_STOP();
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UI:
|
||||
SLJIT_ASSERT(!(op & SLJIT_INT_OP));
|
||||
case SLJIT_MOV_U32:
|
||||
SLJIT_ASSERT(!(op & SLJIT_I32_OP));
|
||||
FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(0), DR(dst)));
|
||||
return push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst));
|
||||
|
||||
case SLJIT_MOV_SI:
|
||||
case SLJIT_MOV_S32:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
return push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(0), DR(dst));
|
||||
|
||||
@ -231,7 +231,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
|
||||
/* Check zero. */
|
||||
FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(5), UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM((op & SLJIT_INT_OP) ? 32 : 64), UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM((op & SLJIT_I32_OP) ? 32 : 64), UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | T(dst) | IMM(-1), DR(dst)));
|
||||
/* Loop for searching the highest bit. */
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(dst) | T(dst) | IMM(1), DR(dst)));
|
||||
@ -392,7 +392,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
||||
SLJIT_ASSERT(!(flags & SRC2_IMM));
|
||||
if (!(op & SLJIT_SET_O)) {
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
if (op & SLJIT_INT_OP)
|
||||
if (op & SLJIT_I32_OP)
|
||||
return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
|
||||
FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS));
|
||||
return push_inst(compiler, MFLO | D(dst), DR(dst));
|
||||
@ -436,7 +436,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value)
|
||||
static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value)
|
||||
{
|
||||
FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 48), DR(dst)));
|
||||
FAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 32), DR(dst)));
|
||||
@ -446,24 +446,26 @@ static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_s
|
||||
return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst));
|
||||
}
|
||||
|
||||
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_target, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins*)addr;
|
||||
sljit_ins *inst = (sljit_ins *)addr;
|
||||
|
||||
inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 48) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000) | ((new_addr >> 32) & 0xffff);
|
||||
inst[3] = (inst[3] & 0xffff0000) | ((new_addr >> 16) & 0xffff);
|
||||
inst[5] = (inst[5] & 0xffff0000) | (new_addr & 0xffff);
|
||||
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 48) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000) | ((new_target >> 32) & 0xffff);
|
||||
inst[3] = (inst[3] & 0xffff0000) | ((new_target >> 16) & 0xffff);
|
||||
inst[5] = (inst[5] & 0xffff0000) | (new_target & 0xffff);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 6);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins*)addr;
|
||||
sljit_ins *inst = (sljit_ins *)addr;
|
||||
|
||||
inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff);
|
||||
inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
|
||||
inst[5] = (inst[5] & 0xffff0000) | (new_constant & 0xffff);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 6);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -26,7 +26,7 @@
|
||||
|
||||
/* ppc 32-bit arch dependent functions. */
|
||||
|
||||
static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm)
|
||||
static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)
|
||||
{
|
||||
if (imm <= SIMM_MAX && imm >= SIMM_MIN)
|
||||
return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm));
|
||||
@ -41,39 +41,39 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sl
|
||||
#define INS_CLEAR_LEFT(dst, src, from) \
|
||||
(RLWINM | S(src) | A(dst) | ((from) << 6) | (31 << 1))
|
||||
|
||||
static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags,
|
||||
sljit_si dst, sljit_si src1, sljit_si src2)
|
||||
static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
|
||||
sljit_s32 dst, sljit_s32 src1, sljit_s32 src2)
|
||||
{
|
||||
switch (op) {
|
||||
case SLJIT_MOV:
|
||||
case SLJIT_MOV_UI:
|
||||
case SLJIT_MOV_SI:
|
||||
case SLJIT_MOV_U32:
|
||||
case SLJIT_MOV_S32:
|
||||
case SLJIT_MOV_P:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if (dst != src2)
|
||||
return push_inst(compiler, OR | S(src2) | A(dst) | B(src2));
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UB:
|
||||
case SLJIT_MOV_SB:
|
||||
case SLJIT_MOV_U8:
|
||||
case SLJIT_MOV_S8:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SB)
|
||||
if (op == SLJIT_MOV_S8)
|
||||
return push_inst(compiler, EXTSB | S(src2) | A(dst));
|
||||
return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24));
|
||||
}
|
||||
else if ((flags & REG_DEST) && op == SLJIT_MOV_SB)
|
||||
else if ((flags & REG_DEST) && op == SLJIT_MOV_S8)
|
||||
return push_inst(compiler, EXTSB | S(src2) | A(dst));
|
||||
else {
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
}
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UH:
|
||||
case SLJIT_MOV_SH:
|
||||
case SLJIT_MOV_U16:
|
||||
case SLJIT_MOV_S16:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SH)
|
||||
if (op == SLJIT_MOV_S16)
|
||||
return push_inst(compiler, EXTSH | S(src2) | A(dst));
|
||||
return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16));
|
||||
}
|
||||
@ -244,26 +244,28 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si reg, sljit_sw init_value)
|
||||
static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw init_value)
|
||||
{
|
||||
FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 16)));
|
||||
return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
|
||||
}
|
||||
|
||||
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_target, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins*)addr;
|
||||
sljit_ins *inst = (sljit_ins *)addr;
|
||||
|
||||
inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 16) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000) | (new_addr & 0xffff);
|
||||
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins*)addr;
|
||||
sljit_ins *inst = (sljit_ins *)addr;
|
||||
|
||||
inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
#define PUSH_RLDICR(reg, shift) \
|
||||
push_inst(compiler, RLDI(reg, reg, 63 - shift, shift, 1))
|
||||
|
||||
static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm)
|
||||
static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)
|
||||
{
|
||||
sljit_uw tmp;
|
||||
sljit_uw shift;
|
||||
@ -145,8 +145,8 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sl
|
||||
src1 = TMP_REG1; \
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags,
|
||||
sljit_si dst, sljit_si src1, sljit_si src2)
|
||||
static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
|
||||
sljit_s32 dst, sljit_s32 src1, sljit_s32 src2)
|
||||
{
|
||||
switch (op) {
|
||||
case SLJIT_MOV:
|
||||
@ -156,11 +156,11 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
||||
return push_inst(compiler, OR | S(src2) | A(dst) | B(src2));
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UI:
|
||||
case SLJIT_MOV_SI:
|
||||
case SLJIT_MOV_U32:
|
||||
case SLJIT_MOV_S32:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SI)
|
||||
if (op == SLJIT_MOV_S32)
|
||||
return push_inst(compiler, EXTSW | S(src2) | A(dst));
|
||||
return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 0));
|
||||
}
|
||||
@ -169,26 +169,26 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
||||
}
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UB:
|
||||
case SLJIT_MOV_SB:
|
||||
case SLJIT_MOV_U8:
|
||||
case SLJIT_MOV_S8:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SB)
|
||||
if (op == SLJIT_MOV_S8)
|
||||
return push_inst(compiler, EXTSB | S(src2) | A(dst));
|
||||
return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24));
|
||||
}
|
||||
else if ((flags & REG_DEST) && op == SLJIT_MOV_SB)
|
||||
else if ((flags & REG_DEST) && op == SLJIT_MOV_S8)
|
||||
return push_inst(compiler, EXTSB | S(src2) | A(dst));
|
||||
else {
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
}
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UH:
|
||||
case SLJIT_MOV_SH:
|
||||
case SLJIT_MOV_U16:
|
||||
case SLJIT_MOV_S16:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SH)
|
||||
if (op == SLJIT_MOV_S16)
|
||||
return push_inst(compiler, EXTSH | S(src2) | A(dst));
|
||||
return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16));
|
||||
}
|
||||
@ -389,7 +389,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si reg, sljit_sw init_value)
|
||||
static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw init_value)
|
||||
{
|
||||
FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 48)));
|
||||
FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value >> 32)));
|
||||
@ -398,18 +398,19 @@ static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_s
|
||||
return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
|
||||
}
|
||||
|
||||
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_target, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins*)addr;
|
||||
|
||||
inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 48) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000) | ((new_addr >> 32) & 0xffff);
|
||||
inst[3] = (inst[3] & 0xffff0000) | ((new_addr >> 16) & 0xffff);
|
||||
inst[4] = (inst[4] & 0xffff0000) | (new_addr & 0xffff);
|
||||
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 48) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000) | ((new_target >> 32) & 0xffff);
|
||||
inst[3] = (inst[3] & 0xffff0000) | ((new_target >> 16) & 0xffff);
|
||||
inst[4] = (inst[4] & 0xffff0000) | (new_target & 0xffff);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 5);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins*)addr;
|
||||
|
||||
@ -417,5 +418,6 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta
|
||||
inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff);
|
||||
inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
|
||||
inst[4] = (inst[4] & 0xffff0000) | (new_constant & 0xffff);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 5);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -24,7 +24,7 @@
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sljit_sw imm)
|
||||
static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw imm)
|
||||
{
|
||||
if (imm <= SIMM_MAX && imm >= SIMM_MIN)
|
||||
return push_inst(compiler, OR | D(dst) | S1(0) | IMM(imm), DR(dst));
|
||||
@ -35,26 +35,26 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sl
|
||||
|
||||
#define ARG2(flags, src2) ((flags & SRC2_IMM) ? IMM(src2) : S2(src2))
|
||||
|
||||
static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags,
|
||||
sljit_si dst, sljit_si src1, sljit_sw src2)
|
||||
static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
|
||||
sljit_s32 dst, sljit_s32 src1, sljit_sw src2)
|
||||
{
|
||||
SLJIT_COMPILE_ASSERT(ICC_IS_SET == SET_FLAGS, icc_is_set_and_set_flags_must_be_the_same);
|
||||
|
||||
switch (op) {
|
||||
case SLJIT_MOV:
|
||||
case SLJIT_MOV_UI:
|
||||
case SLJIT_MOV_SI:
|
||||
case SLJIT_MOV_U32:
|
||||
case SLJIT_MOV_S32:
|
||||
case SLJIT_MOV_P:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if (dst != src2)
|
||||
return push_inst(compiler, OR | D(dst) | S1(0) | S2(src2), DR(dst));
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UB:
|
||||
case SLJIT_MOV_SB:
|
||||
case SLJIT_MOV_U8:
|
||||
case SLJIT_MOV_S8:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_UB)
|
||||
if (op == SLJIT_MOV_U8)
|
||||
return push_inst(compiler, AND | D(dst) | S1(src2) | IMM(0xff), DR(dst));
|
||||
FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src2) | IMM(24), DR(dst)));
|
||||
return push_inst(compiler, SRA | D(dst) | S1(dst) | IMM(24), DR(dst));
|
||||
@ -63,12 +63,12 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
||||
SLJIT_ASSERT_STOP();
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UH:
|
||||
case SLJIT_MOV_SH:
|
||||
case SLJIT_MOV_U16:
|
||||
case SLJIT_MOV_S16:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src2) | IMM(16), DR(dst)));
|
||||
return push_inst(compiler, (op == SLJIT_MOV_SH ? SRA : SRL) | D(dst) | S1(dst) | IMM(16), DR(dst));
|
||||
return push_inst(compiler, (op == SLJIT_MOV_S16 ? SRA : SRL) | D(dst) | S1(dst) | IMM(16), DR(dst));
|
||||
}
|
||||
else if (dst != src2)
|
||||
SLJIT_ASSERT_STOP();
|
||||
@ -139,26 +139,28 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value)
|
||||
static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value)
|
||||
{
|
||||
FAIL_IF(push_inst(compiler, SETHI | D(dst) | ((init_value >> 10) & 0x3fffff), DR(dst)));
|
||||
return push_inst(compiler, OR | D(dst) | S1(dst) | IMM_ARG | (init_value & 0x3ff), DR(dst));
|
||||
}
|
||||
|
||||
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_target, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins*)addr;
|
||||
sljit_ins *inst = (sljit_ins *)addr;
|
||||
|
||||
inst[0] = (inst[0] & 0xffc00000) | ((new_addr >> 10) & 0x3fffff);
|
||||
inst[1] = (inst[1] & 0xfffffc00) | (new_addr & 0x3ff);
|
||||
inst[0] = (inst[0] & 0xffc00000) | ((new_target >> 10) & 0x3fffff);
|
||||
inst[1] = (inst[1] & 0xfffffc00) | (new_target & 0x3ff);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins*)addr;
|
||||
sljit_ins *inst = (sljit_ins *)addr;
|
||||
|
||||
inst[0] = (inst[0] & 0xffc00000) | ((new_constant >> 10) & 0x3fffff);
|
||||
inst[1] = (inst[1] & 0xfffffc00) | (new_constant & 0x3ff);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||
}
|
||||
|
||||
@ -24,14 +24,16 @@
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void)
|
||||
SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
|
||||
{
|
||||
return "SPARC" SLJIT_CPUINFO;
|
||||
}
|
||||
|
||||
/* Length of an instruction word
|
||||
Both for sparc-32 and sparc-64 */
|
||||
typedef sljit_ui sljit_ins;
|
||||
typedef sljit_u32 sljit_ins;
|
||||
|
||||
#if (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL)
|
||||
|
||||
static void sparc_cache_flush(sljit_ins *from, sljit_ins *to)
|
||||
{
|
||||
@ -82,6 +84,8 @@ static void sparc_cache_flush(sljit_ins *from, sljit_ins *to)
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) */
|
||||
|
||||
/* TMP_REG2 is not used by getput_arg */
|
||||
#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
|
||||
#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
|
||||
@ -91,7 +95,7 @@ static void sparc_cache_flush(sljit_ins *from, sljit_ins *to)
|
||||
#define TMP_FREG1 (0)
|
||||
#define TMP_FREG2 ((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) << 1)
|
||||
|
||||
static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
|
||||
static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
|
||||
0, 8, 9, 10, 13, 29, 28, 27, 23, 22, 21, 20, 19, 18, 17, 16, 26, 25, 24, 14, 1, 11, 12, 15
|
||||
};
|
||||
|
||||
@ -181,7 +185,7 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
|
||||
|
||||
/* dest_reg is the absolute name of the register
|
||||
Useful for reordering instructions in the delay slot. */
|
||||
static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_si delay_slot)
|
||||
static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 delay_slot)
|
||||
{
|
||||
sljit_ins *ptr;
|
||||
SLJIT_ASSERT((delay_slot & DST_INS_MASK) == UNMOVABLE_INS
|
||||
@ -195,7 +199,7 @@ static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
|
||||
static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_sw diff;
|
||||
sljit_uw target_addr;
|
||||
@ -209,7 +213,7 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i
|
||||
target_addr = jump->u.target;
|
||||
else {
|
||||
SLJIT_ASSERT(jump->flags & JUMP_LABEL);
|
||||
target_addr = (sljit_uw)(code + jump->u.label->size);
|
||||
target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
|
||||
}
|
||||
inst = (sljit_ins*)jump->addr;
|
||||
|
||||
@ -235,8 +239,9 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i
|
||||
if (jump->flags & IS_COND)
|
||||
inst--;
|
||||
|
||||
diff = ((sljit_sw)target_addr - (sljit_sw)(inst - 1) - executable_offset) >> 2;
|
||||
|
||||
if (jump->flags & IS_MOVABLE) {
|
||||
diff = ((sljit_sw)target_addr - (sljit_sw)(inst - 1)) >> 2;
|
||||
if (diff <= MAX_DISP && diff >= MIN_DISP) {
|
||||
jump->flags |= PATCH_B;
|
||||
inst--;
|
||||
@ -253,7 +258,8 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i
|
||||
}
|
||||
}
|
||||
|
||||
diff = ((sljit_sw)target_addr - (sljit_sw)(inst)) >> 2;
|
||||
diff += sizeof(sljit_ins);
|
||||
|
||||
if (diff <= MAX_DISP && diff >= MIN_DISP) {
|
||||
jump->flags |= PATCH_B;
|
||||
if (jump->flags & IS_COND)
|
||||
@ -276,6 +282,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
sljit_ins *buf_ptr;
|
||||
sljit_ins *buf_end;
|
||||
sljit_uw word_count;
|
||||
sljit_sw executable_offset;
|
||||
sljit_uw addr;
|
||||
|
||||
struct sljit_label *label;
|
||||
@ -292,9 +299,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
|
||||
code_ptr = code;
|
||||
word_count = 0;
|
||||
executable_offset = SLJIT_EXEC_OFFSET(code);
|
||||
|
||||
label = compiler->labels;
|
||||
jump = compiler->jumps;
|
||||
const_ = compiler->consts;
|
||||
|
||||
do {
|
||||
buf_ptr = (sljit_ins*)buf->memory;
|
||||
buf_end = buf_ptr + (buf->used_size >> 2);
|
||||
@ -306,7 +316,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
/* These structures are ordered by their address. */
|
||||
if (label && label->size == word_count) {
|
||||
/* Just recording the address. */
|
||||
label->addr = (sljit_uw)code_ptr;
|
||||
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
label->size = code_ptr - code;
|
||||
label = label->next;
|
||||
}
|
||||
@ -316,7 +326,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
#else
|
||||
jump->addr = (sljit_uw)(code_ptr - 6);
|
||||
#endif
|
||||
code_ptr = detect_jump_type(jump, code_ptr, code);
|
||||
code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);
|
||||
jump = jump->next;
|
||||
}
|
||||
if (const_ && const_->addr == word_count) {
|
||||
@ -332,7 +342,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
} while (buf);
|
||||
|
||||
if (label && label->size == word_count) {
|
||||
label->addr = (sljit_uw)code_ptr;
|
||||
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
label->size = code_ptr - code;
|
||||
label = label->next;
|
||||
}
|
||||
@ -340,22 +350,22 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
SLJIT_ASSERT(!label);
|
||||
SLJIT_ASSERT(!jump);
|
||||
SLJIT_ASSERT(!const_);
|
||||
SLJIT_ASSERT(code_ptr - code <= (sljit_si)compiler->size);
|
||||
SLJIT_ASSERT(code_ptr - code <= (sljit_s32)compiler->size);
|
||||
|
||||
jump = compiler->jumps;
|
||||
while (jump) {
|
||||
do {
|
||||
addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
|
||||
buf_ptr = (sljit_ins*)jump->addr;
|
||||
buf_ptr = (sljit_ins *)jump->addr;
|
||||
|
||||
if (jump->flags & PATCH_CALL) {
|
||||
addr = (sljit_sw)(addr - jump->addr) >> 2;
|
||||
addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
|
||||
SLJIT_ASSERT((sljit_sw)addr <= 0x1fffffff && (sljit_sw)addr >= -0x20000000);
|
||||
buf_ptr[0] = CALL | (addr & 0x3fffffff);
|
||||
break;
|
||||
}
|
||||
if (jump->flags & PATCH_B) {
|
||||
addr = (sljit_sw)(addr - jump->addr) >> 2;
|
||||
addr = (sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
|
||||
SLJIT_ASSERT((sljit_sw)addr <= MAX_DISP && (sljit_sw)addr >= MIN_DISP);
|
||||
buf_ptr[0] = (buf_ptr[0] & ~DISP_MASK) | (addr & DISP_MASK);
|
||||
break;
|
||||
@ -374,7 +384,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
|
||||
|
||||
compiler->error = SLJIT_ERR_COMPILED;
|
||||
compiler->executable_offset = executable_offset;
|
||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
||||
|
||||
code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
|
||||
code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
|
||||
SLJIT_CACHE_FLUSH(code, code_ptr);
|
||||
return code;
|
||||
}
|
||||
@ -418,9 +433,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
#include "sljitNativeSPARC_64.c"
|
||||
#endif
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
@ -442,9 +457,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
@ -454,7 +469,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_return(compiler, op, src, srcw));
|
||||
@ -478,7 +493,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
||||
#define ARCH_32_64(a, b) b
|
||||
#endif
|
||||
|
||||
static SLJIT_CONST sljit_ins data_transfer_insts[16 + 4] = {
|
||||
static const sljit_ins data_transfer_insts[16 + 4] = {
|
||||
/* u w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */),
|
||||
/* u w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */),
|
||||
/* u b s */ OPC1(3) | OPC3(0x05) /* stb */,
|
||||
@ -506,7 +521,7 @@ static SLJIT_CONST sljit_ins data_transfer_insts[16 + 4] = {
|
||||
#undef ARCH_32_64
|
||||
|
||||
/* Can perform an operation using at most 1 instruction. */
|
||||
static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)
|
||||
static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
|
||||
{
|
||||
SLJIT_ASSERT(arg & SLJIT_MEM);
|
||||
|
||||
@ -529,7 +544,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags,
|
||||
/* See getput_arg below.
|
||||
Note: can_cache is called only for binary operators. Those
|
||||
operators always uses word arguments without write back. */
|
||||
static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
|
||||
static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
|
||||
{
|
||||
SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
|
||||
|
||||
@ -549,9 +564,9 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_
|
||||
}
|
||||
|
||||
/* Emit the necessary instructions. See can_cache above. */
|
||||
static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw)
|
||||
static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
|
||||
{
|
||||
sljit_si base, arg2, delay_slot;
|
||||
sljit_s32 base, arg2, delay_slot;
|
||||
sljit_ins dest;
|
||||
|
||||
SLJIT_ASSERT(arg & SLJIT_MEM);
|
||||
@ -613,7 +628,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji
|
||||
return push_inst(compiler, ADD | D(base) | S1(base) | S2(arg2), DR(base));
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)
|
||||
static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
|
||||
{
|
||||
if (getput_arg_fast(compiler, flags, reg, arg, argw))
|
||||
return compiler->error;
|
||||
@ -622,26 +637,26 @@ static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_
|
||||
return getput_arg(compiler, flags, reg, arg, argw, 0, 0);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w)
|
||||
static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
|
||||
{
|
||||
if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
|
||||
return compiler->error;
|
||||
return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
|
||||
}
|
||||
|
||||
static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w)
|
||||
static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w)
|
||||
{
|
||||
/* arg1 goes to TMP_REG1 or src reg
|
||||
arg2 goes to TMP_REG2, imm or src reg
|
||||
TMP_REG3 can be used for caching
|
||||
result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
|
||||
sljit_si dst_r = TMP_REG2;
|
||||
sljit_si src1_r;
|
||||
sljit_s32 dst_r = TMP_REG2;
|
||||
sljit_s32 src1_r;
|
||||
sljit_sw src2_r = 0;
|
||||
sljit_si sugg_src2_r = TMP_REG2;
|
||||
sljit_s32 sugg_src2_r = TMP_REG2;
|
||||
|
||||
if (!(flags & ALT_KEEP_CACHE)) {
|
||||
compiler->cache_arg = 0;
|
||||
@ -649,13 +664,13 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f
|
||||
}
|
||||
|
||||
if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
|
||||
if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM))
|
||||
if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM))
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
else if (FAST_IS_REG(dst)) {
|
||||
dst_r = dst;
|
||||
flags |= REG_DEST;
|
||||
if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
|
||||
if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
|
||||
sugg_src2_r = dst_r;
|
||||
}
|
||||
else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw))
|
||||
@ -705,7 +720,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f
|
||||
if (FAST_IS_REG(src2)) {
|
||||
src2_r = src2;
|
||||
flags |= REG2_SOURCE;
|
||||
if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI)
|
||||
if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
|
||||
dst_r = src2_r;
|
||||
}
|
||||
else if (src2 & SLJIT_IMM) {
|
||||
@ -716,7 +731,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f
|
||||
}
|
||||
else {
|
||||
src2_r = 0;
|
||||
if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM))
|
||||
if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) && (dst & SLJIT_MEM))
|
||||
dst_r = 0;
|
||||
}
|
||||
}
|
||||
@ -758,7 +773,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op0(compiler, op));
|
||||
@ -769,30 +784,30 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
return push_inst(compiler, TA, UNMOVABLE_INS);
|
||||
case SLJIT_NOP:
|
||||
return push_inst(compiler, NOP, UNMOVABLE_INS);
|
||||
case SLJIT_LUMUL:
|
||||
case SLJIT_LSMUL:
|
||||
case SLJIT_LMUL_UW:
|
||||
case SLJIT_LMUL_SW:
|
||||
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LUMUL ? UMUL : SMUL) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0)));
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? UMUL : SMUL) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0)));
|
||||
return push_inst(compiler, RDY | D(SLJIT_R1), DR(SLJIT_R1));
|
||||
#else
|
||||
#error "Implementation required"
|
||||
#endif
|
||||
case SLJIT_UDIVMOD:
|
||||
case SLJIT_SDIVMOD:
|
||||
case SLJIT_UDIVI:
|
||||
case SLJIT_SDIVI:
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments);
|
||||
case SLJIT_DIVMOD_UW:
|
||||
case SLJIT_DIVMOD_SW:
|
||||
case SLJIT_DIV_UW:
|
||||
case SLJIT_DIV_SW:
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
|
||||
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
if ((op | 0x2) == SLJIT_UDIVI)
|
||||
if ((op | 0x2) == SLJIT_DIV_UW)
|
||||
FAIL_IF(push_inst(compiler, WRY | S1(0), MOVABLE_INS));
|
||||
else {
|
||||
FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(SLJIT_R0) | IMM(31), DR(TMP_REG1)));
|
||||
FAIL_IF(push_inst(compiler, WRY | S1(TMP_REG1), MOVABLE_INS));
|
||||
}
|
||||
if (op <= SLJIT_SDIVMOD)
|
||||
if (op <= SLJIT_DIVMOD_SW)
|
||||
FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_R0), DR(TMP_REG2)));
|
||||
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? UDIV : SDIV) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0)));
|
||||
if (op >= SLJIT_UDIVI)
|
||||
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? UDIV : SDIV) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0)));
|
||||
if (op >= SLJIT_DIV_UW)
|
||||
return SLJIT_SUCCESS;
|
||||
FAIL_IF(push_inst(compiler, SMUL | D(SLJIT_R1) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R1)));
|
||||
return push_inst(compiler, SUB | D(SLJIT_R1) | S1(TMP_REG2) | S2(SLJIT_R1), DR(SLJIT_R1));
|
||||
@ -804,11 +819,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0;
|
||||
sljit_s32 flags = GET_FLAGS(op) ? SET_FLAGS : 0;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
|
||||
@ -821,45 +836,45 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
|
||||
case SLJIT_MOV_P:
|
||||
return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
|
||||
case SLJIT_MOV_UI:
|
||||
return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
case SLJIT_MOV_U32:
|
||||
return emit_op(compiler, SLJIT_MOV_U32, flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
|
||||
case SLJIT_MOV_SI:
|
||||
return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
case SLJIT_MOV_S32:
|
||||
return emit_op(compiler, SLJIT_MOV_S32, flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
|
||||
case SLJIT_MOV_UB:
|
||||
return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw);
|
||||
case SLJIT_MOV_U8:
|
||||
return emit_op(compiler, SLJIT_MOV_U8, flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
|
||||
|
||||
case SLJIT_MOV_SB:
|
||||
return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw);
|
||||
case SLJIT_MOV_S8:
|
||||
return emit_op(compiler, SLJIT_MOV_S8, flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
|
||||
|
||||
case SLJIT_MOV_UH:
|
||||
return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw);
|
||||
case SLJIT_MOV_U16:
|
||||
return emit_op(compiler, SLJIT_MOV_U16, flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
|
||||
|
||||
case SLJIT_MOV_SH:
|
||||
return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw);
|
||||
case SLJIT_MOV_S16:
|
||||
return emit_op(compiler, SLJIT_MOV_S16, flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
|
||||
|
||||
case SLJIT_MOVU:
|
||||
case SLJIT_MOVU_P:
|
||||
return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
|
||||
case SLJIT_MOVU_UI:
|
||||
return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
case SLJIT_MOVU_U32:
|
||||
return emit_op(compiler, SLJIT_MOV_U32, flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
|
||||
case SLJIT_MOVU_SI:
|
||||
return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
case SLJIT_MOVU_S32:
|
||||
return emit_op(compiler, SLJIT_MOV_S32, flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
|
||||
case SLJIT_MOVU_UB:
|
||||
return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw);
|
||||
case SLJIT_MOVU_U8:
|
||||
return emit_op(compiler, SLJIT_MOV_U8, flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
|
||||
|
||||
case SLJIT_MOVU_SB:
|
||||
return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw);
|
||||
case SLJIT_MOVU_S8:
|
||||
return emit_op(compiler, SLJIT_MOV_S8, flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
|
||||
|
||||
case SLJIT_MOVU_UH:
|
||||
return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw);
|
||||
case SLJIT_MOVU_U16:
|
||||
return emit_op(compiler, SLJIT_MOV_U16, flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
|
||||
|
||||
case SLJIT_MOVU_SH:
|
||||
return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw);
|
||||
case SLJIT_MOVU_S16:
|
||||
return emit_op(compiler, SLJIT_MOV_S16, flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
|
||||
|
||||
case SLJIT_NOT:
|
||||
case SLJIT_CLZ:
|
||||
@ -872,12 +887,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w)
|
||||
{
|
||||
sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0;
|
||||
sljit_s32 flags = GET_FLAGS(op) ? SET_FLAGS : 0;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
||||
@ -914,20 +929,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
|
||||
{
|
||||
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
|
||||
return reg_map[reg];
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
|
||||
{
|
||||
CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
|
||||
return reg << 1;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
|
||||
void *instruction, sljit_si size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
|
||||
void *instruction, sljit_s32 size)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
|
||||
@ -939,7 +954,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co
|
||||
/* Floating point operators */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void)
|
||||
{
|
||||
#ifdef SLJIT_IS_FPU_AVAILABLE
|
||||
return SLJIT_IS_FPU_AVAILABLE;
|
||||
@ -949,13 +964,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 7))
|
||||
#define SELECT_FOP(op, single, double) ((op & SLJIT_SINGLE_OP) ? single : double)
|
||||
#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 7))
|
||||
#define SELECT_FOP(op, single, double) ((op & SLJIT_F32_OP) ? single : double)
|
||||
#define FLOAT_TMP_MEM_OFFSET (22 * sizeof(sljit_sw))
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
if (src & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
|
||||
@ -978,16 +993,16 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *
|
||||
return emit_op_mem2(compiler, SINGLE_DATA, TMP_FREG1, dst, dstw, 0, 0);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1;
|
||||
sljit_s32 dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1;
|
||||
|
||||
if (src & SLJIT_IMM) {
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if (GET_OPCODE(op) == SLJIT_CONVD_FROMI)
|
||||
srcw = (sljit_si)srcw;
|
||||
if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
|
||||
srcw = (sljit_s32)srcw;
|
||||
#endif
|
||||
FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
|
||||
src = TMP_REG1;
|
||||
@ -1008,9 +1023,9 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w)
|
||||
static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w)
|
||||
{
|
||||
if (src1 & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
|
||||
@ -1029,21 +1044,21 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler
|
||||
return push_inst(compiler, SELECT_FOP(op, FCMPS, FCMPD) | S1A(src1) | S2A(src2), FCC_IS_SET | MOVABLE_INS);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si dst_r;
|
||||
sljit_s32 dst_r;
|
||||
|
||||
CHECK_ERROR();
|
||||
compiler->cache_arg = 0;
|
||||
compiler->cache_argw = 0;
|
||||
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);
|
||||
SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
|
||||
|
||||
if (GET_OPCODE(op) == SLJIT_CONVD_FROMS)
|
||||
op ^= SLJIT_SINGLE_OP;
|
||||
if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
|
||||
op ^= SLJIT_F32_OP;
|
||||
|
||||
dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1;
|
||||
|
||||
@ -1055,30 +1070,30 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile
|
||||
src <<= 1;
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_DMOV:
|
||||
case SLJIT_MOV_F64:
|
||||
if (src != dst_r) {
|
||||
if (dst_r != TMP_FREG1) {
|
||||
FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r) | S2A(src), MOVABLE_INS));
|
||||
if (!(op & SLJIT_SINGLE_OP))
|
||||
if (!(op & SLJIT_F32_OP))
|
||||
FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS));
|
||||
}
|
||||
else
|
||||
dst_r = src;
|
||||
}
|
||||
break;
|
||||
case SLJIT_DNEG:
|
||||
case SLJIT_NEG_F64:
|
||||
FAIL_IF(push_inst(compiler, FNEGS | DA(dst_r) | S2A(src), MOVABLE_INS));
|
||||
if (dst_r != src && !(op & SLJIT_SINGLE_OP))
|
||||
if (dst_r != src && !(op & SLJIT_F32_OP))
|
||||
FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS));
|
||||
break;
|
||||
case SLJIT_DABS:
|
||||
case SLJIT_ABS_F64:
|
||||
FAIL_IF(push_inst(compiler, FABSS | DA(dst_r) | S2A(src), MOVABLE_INS));
|
||||
if (dst_r != src && !(op & SLJIT_SINGLE_OP))
|
||||
if (dst_r != src && !(op & SLJIT_F32_OP))
|
||||
FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS));
|
||||
break;
|
||||
case SLJIT_CONVD_FROMS:
|
||||
case SLJIT_CONV_F64_FROM_F32:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOD, FDTOS) | DA(dst_r) | S2A(src), MOVABLE_INS));
|
||||
op ^= SLJIT_SINGLE_OP;
|
||||
op ^= SLJIT_F32_OP;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1087,12 +1102,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w)
|
||||
{
|
||||
sljit_si dst_r, flags = 0;
|
||||
sljit_s32 dst_r, flags = 0;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
||||
@ -1146,19 +1161,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
||||
src2 = TMP_FREG2;
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_DADD:
|
||||
case SLJIT_ADD_F64:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADDD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
|
||||
break;
|
||||
|
||||
case SLJIT_DSUB:
|
||||
case SLJIT_SUB_F64:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUBD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
|
||||
break;
|
||||
|
||||
case SLJIT_DMUL:
|
||||
case SLJIT_MUL_F64:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMULD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
|
||||
break;
|
||||
|
||||
case SLJIT_DDIV:
|
||||
case SLJIT_DIV_F64:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIVD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
|
||||
break;
|
||||
}
|
||||
@ -1176,7 +1191,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile
|
||||
/* Other instructions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
|
||||
@ -1193,7 +1208,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c
|
||||
return emit_op_mem(compiler, WORD_DATA, TMP_LINK, dst, dstw);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
||||
@ -1231,33 +1246,33 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
||||
return label;
|
||||
}
|
||||
|
||||
static sljit_ins get_cc(sljit_si type)
|
||||
static sljit_ins get_cc(sljit_s32 type)
|
||||
{
|
||||
switch (type) {
|
||||
case SLJIT_EQUAL:
|
||||
case SLJIT_MUL_NOT_OVERFLOW:
|
||||
case SLJIT_D_NOT_EQUAL: /* Unordered. */
|
||||
case SLJIT_NOT_EQUAL_F64: /* Unordered. */
|
||||
return DA(0x1);
|
||||
|
||||
case SLJIT_NOT_EQUAL:
|
||||
case SLJIT_MUL_OVERFLOW:
|
||||
case SLJIT_D_EQUAL:
|
||||
case SLJIT_EQUAL_F64:
|
||||
return DA(0x9);
|
||||
|
||||
case SLJIT_LESS:
|
||||
case SLJIT_D_GREATER: /* Unordered. */
|
||||
case SLJIT_GREATER_F64: /* Unordered. */
|
||||
return DA(0x5);
|
||||
|
||||
case SLJIT_GREATER_EQUAL:
|
||||
case SLJIT_D_LESS_EQUAL:
|
||||
case SLJIT_LESS_EQUAL_F64:
|
||||
return DA(0xd);
|
||||
|
||||
case SLJIT_GREATER:
|
||||
case SLJIT_D_GREATER_EQUAL: /* Unordered. */
|
||||
case SLJIT_GREATER_EQUAL_F64: /* Unordered. */
|
||||
return DA(0xc);
|
||||
|
||||
case SLJIT_LESS_EQUAL:
|
||||
case SLJIT_D_LESS:
|
||||
case SLJIT_LESS_F64:
|
||||
return DA(0x4);
|
||||
|
||||
case SLJIT_SIG_LESS:
|
||||
@ -1273,11 +1288,11 @@ static sljit_ins get_cc(sljit_si type)
|
||||
return DA(0x2);
|
||||
|
||||
case SLJIT_OVERFLOW:
|
||||
case SLJIT_D_UNORDERED:
|
||||
case SLJIT_UNORDERED_F64:
|
||||
return DA(0x7);
|
||||
|
||||
case SLJIT_NOT_OVERFLOW:
|
||||
case SLJIT_D_ORDERED:
|
||||
case SLJIT_ORDERED_F64:
|
||||
return DA(0xf);
|
||||
|
||||
default:
|
||||
@ -1286,7 +1301,7 @@ static sljit_ins get_cc(sljit_si type)
|
||||
}
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type)
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
|
||||
{
|
||||
struct sljit_jump *jump;
|
||||
|
||||
@ -1298,7 +1313,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||
set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
|
||||
type &= 0xff;
|
||||
|
||||
if (type < SLJIT_D_EQUAL) {
|
||||
if (type < SLJIT_EQUAL_F64) {
|
||||
jump->flags |= IS_COND;
|
||||
if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & ICC_IS_SET))
|
||||
jump->flags |= IS_MOVABLE;
|
||||
@ -1332,10 +1347,10 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||
return jump;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
struct sljit_jump *jump = NULL;
|
||||
sljit_si src_r;
|
||||
sljit_s32 src_r;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
|
||||
@ -1367,12 +1382,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil
|
||||
return push_inst(compiler, NOP, UNMOVABLE_INS);
|
||||
}
|
||||
|
||||
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)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw,
|
||||
sljit_s32 type)
|
||||
{
|
||||
sljit_si reg, flags = (GET_FLAGS(op) ? SET_FLAGS : 0);
|
||||
sljit_s32 reg, flags = (GET_FLAGS(op) ? SET_FLAGS : 0);
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
|
||||
@ -1395,7 +1410,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
||||
}
|
||||
|
||||
type &= 0xff;
|
||||
if (type < SLJIT_D_EQUAL)
|
||||
if (type < SLJIT_EQUAL_F64)
|
||||
FAIL_IF(push_inst(compiler, BICC | get_cc(type) | 3, UNMOVABLE_INS));
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, FBFCC | get_cc(type) | 3, UNMOVABLE_INS));
|
||||
@ -1412,9 +1427,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com
|
||||
#endif
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value)
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
|
||||
{
|
||||
sljit_si reg;
|
||||
sljit_s32 reg;
|
||||
struct sljit_const *const_;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -26,19 +26,19 @@
|
||||
|
||||
/* x86 32-bit arch dependent functions. */
|
||||
|
||||
static sljit_si emit_do_imm(struct sljit_compiler *compiler, sljit_ub opcode, sljit_sw imm)
|
||||
static sljit_s32 emit_do_imm(struct sljit_compiler *compiler, sljit_u8 opcode, sljit_sw imm)
|
||||
{
|
||||
sljit_ub *inst;
|
||||
sljit_u8 *inst;
|
||||
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_sw));
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_sw));
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(1 + sizeof(sljit_sw));
|
||||
*inst++ = opcode;
|
||||
*(sljit_sw*)inst = imm;
|
||||
sljit_unaligned_store_sw(inst, imm);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type)
|
||||
static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type, sljit_sw executable_offset)
|
||||
{
|
||||
if (type == SLJIT_JUMP) {
|
||||
*code_ptr++ = JMP_i32;
|
||||
@ -57,18 +57,18 @@ static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_
|
||||
if (jump->flags & JUMP_LABEL)
|
||||
jump->flags |= PATCH_MW;
|
||||
else
|
||||
*(sljit_sw*)code_ptr = jump->u.target - (jump->addr + 4);
|
||||
sljit_unaligned_store_sw(code_ptr, jump->u.target - (jump->addr + 4) - (sljit_uw)executable_offset);
|
||||
code_ptr += 4;
|
||||
|
||||
return code_ptr;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
sljit_si size;
|
||||
sljit_ub *inst;
|
||||
sljit_s32 size;
|
||||
sljit_u8 *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
@ -83,7 +83,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
#else
|
||||
size += (args > 0 ? (2 + args * 3) : 0);
|
||||
#endif
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(size);
|
||||
@ -143,7 +143,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
if (options & SLJIT_DOUBLE_ALIGNMENT) {
|
||||
local_size = SLJIT_LOCALS_OFFSET + ((local_size + 7) & ~7);
|
||||
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 17);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 17);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(17);
|
||||
@ -151,12 +151,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
inst[1] = MOD_REG | (reg_map[TMP_REG1] << 3) | reg_map[SLJIT_SP];
|
||||
inst[2] = GROUP_F7;
|
||||
inst[3] = MOD_REG | (0 << 3) | reg_map[SLJIT_SP];
|
||||
*(sljit_sw*)(inst + 4) = 0x4;
|
||||
sljit_unaligned_store_sw(inst + 4, 0x4);
|
||||
inst[8] = JNE_i8;
|
||||
inst[9] = 6;
|
||||
inst[10] = GROUP_BINARY_81;
|
||||
inst[11] = MOD_REG | (5 << 3) | reg_map[SLJIT_SP];
|
||||
*(sljit_sw*)(inst + 12) = 0x4;
|
||||
sljit_unaligned_store_sw(inst + 12, 0x4);
|
||||
inst[16] = PUSH_r + reg_map[TMP_REG1];
|
||||
}
|
||||
else
|
||||
@ -183,9 +183,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
@ -205,10 +205,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si size;
|
||||
sljit_ub *inst;
|
||||
sljit_s32 size;
|
||||
sljit_u8 *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_return(compiler, op, src, srcw));
|
||||
@ -223,7 +223,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
||||
|
||||
#if !defined(__APPLE__)
|
||||
if (compiler->options & SLJIT_DOUBLE_ALIGNMENT) {
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 3);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 3);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(3);
|
||||
@ -242,7 +242,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
||||
if (compiler->args > 0)
|
||||
size += 2;
|
||||
#endif
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(size);
|
||||
@ -271,16 +271,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/* Size contains the flags as well. */
|
||||
static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size,
|
||||
static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_s32 size,
|
||||
/* The register or immediate operand. */
|
||||
sljit_si a, sljit_sw imma,
|
||||
sljit_s32 a, sljit_sw imma,
|
||||
/* The general operand (not immediate). */
|
||||
sljit_si b, sljit_sw immb)
|
||||
sljit_s32 b, sljit_sw immb)
|
||||
{
|
||||
sljit_ub *inst;
|
||||
sljit_ub *buf_ptr;
|
||||
sljit_si flags = size & ~0xf;
|
||||
sljit_si inst_size;
|
||||
sljit_u8 *inst;
|
||||
sljit_u8 *buf_ptr;
|
||||
sljit_s32 flags = size & ~0xf;
|
||||
sljit_s32 inst_size;
|
||||
|
||||
/* Both cannot be switched on. */
|
||||
SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));
|
||||
@ -310,7 +310,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
||||
else if (immb != 0 && !(b & OFFS_REG_MASK)) {
|
||||
/* Immediate operand. */
|
||||
if (immb <= 127 && immb >= -128)
|
||||
inst_size += sizeof(sljit_sb);
|
||||
inst_size += sizeof(sljit_s8);
|
||||
else
|
||||
inst_size += sizeof(sljit_sw);
|
||||
}
|
||||
@ -347,7 +347,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
||||
else
|
||||
SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
|
||||
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + inst_size);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + inst_size);
|
||||
PTR_FAIL_IF(!inst);
|
||||
|
||||
/* Encoding the byte. */
|
||||
@ -406,7 +406,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
||||
if (immb <= 127 && immb >= -128)
|
||||
*buf_ptr++ = immb; /* 8 bit displacement. */
|
||||
else {
|
||||
*(sljit_sw*)buf_ptr = immb; /* 32 bit displacement. */
|
||||
sljit_unaligned_store_sw(buf_ptr, immb); /* 32 bit displacement. */
|
||||
buf_ptr += sizeof(sljit_sw);
|
||||
}
|
||||
}
|
||||
@ -418,7 +418,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
||||
}
|
||||
else {
|
||||
*buf_ptr++ |= 0x05;
|
||||
*(sljit_sw*)buf_ptr = immb; /* 32 bit displacement. */
|
||||
sljit_unaligned_store_sw(buf_ptr, immb); /* 32 bit displacement. */
|
||||
buf_ptr += sizeof(sljit_sw);
|
||||
}
|
||||
|
||||
@ -426,9 +426,9 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
||||
if (flags & EX86_BYTE_ARG)
|
||||
*buf_ptr = imma;
|
||||
else if (flags & EX86_HALF_ARG)
|
||||
*(short*)buf_ptr = imma;
|
||||
sljit_unaligned_store_s16(buf_ptr, imma);
|
||||
else if (!(flags & EX86_SHIFT_INS))
|
||||
*(sljit_sw*)buf_ptr = imma;
|
||||
sljit_unaligned_store_sw(buf_ptr, imma);
|
||||
}
|
||||
|
||||
return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1);
|
||||
@ -438,12 +438,12 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
||||
/* Call / return instructions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, sljit_si type)
|
||||
static SLJIT_INLINE sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 type)
|
||||
{
|
||||
sljit_ub *inst;
|
||||
sljit_u8 *inst;
|
||||
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
inst = (sljit_ub*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(type >= SLJIT_CALL3 ? 2 + 1 : 2);
|
||||
|
||||
@ -452,7 +452,7 @@ static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, slj
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_R2] << 3) | reg_map[SLJIT_R0];
|
||||
#else
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 * (type - SLJIT_CALL0));
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 * (type - SLJIT_CALL0));
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(4 * (type - SLJIT_CALL0));
|
||||
|
||||
@ -476,9 +476,9 @@ static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, slj
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
|
||||
{
|
||||
sljit_ub *inst;
|
||||
sljit_u8 *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
|
||||
@ -492,7 +492,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c
|
||||
|
||||
if (FAST_IS_REG(dst)) {
|
||||
/* Unused dest is possible here. */
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(1);
|
||||
@ -507,9 +507,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_ub *inst;
|
||||
sljit_u8 *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
||||
@ -518,7 +518,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
|
||||
CHECK_EXTRA_REGS(src, srcw, (void)0);
|
||||
|
||||
if (FAST_IS_REG(src)) {
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 1);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(1 + 1);
|
||||
@ -530,18 +530,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
|
||||
*inst++ = GROUP_FF;
|
||||
*inst |= PUSH_rm;
|
||||
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(1);
|
||||
}
|
||||
else {
|
||||
/* SLJIT_IMM. */
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 5 + 1);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(5 + 1);
|
||||
*inst++ = PUSH_i32;
|
||||
*(sljit_sw*)inst = srcw;
|
||||
sljit_unaligned_store_sw(inst, srcw);
|
||||
inst += sizeof(sljit_sw);
|
||||
}
|
||||
|
||||
|
||||
@ -26,20 +26,20 @@
|
||||
|
||||
/* x86 64-bit arch dependent functions. */
|
||||
|
||||
static sljit_si emit_load_imm64(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm)
|
||||
static sljit_s32 emit_load_imm64(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm)
|
||||
{
|
||||
sljit_ub *inst;
|
||||
sljit_u8 *inst;
|
||||
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_sw));
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_sw));
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(2 + sizeof(sljit_sw));
|
||||
*inst++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B);
|
||||
*inst++ = MOV_r_i32 + (reg_map[reg] & 0x7);
|
||||
*(sljit_sw*)inst = imm;
|
||||
sljit_unaligned_store_sw(inst, imm);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type)
|
||||
static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type)
|
||||
{
|
||||
if (type < SLJIT_JUMP) {
|
||||
/* Invert type. */
|
||||
@ -55,7 +55,7 @@ static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_
|
||||
if (jump->flags & JUMP_LABEL)
|
||||
jump->flags |= PATCH_MD;
|
||||
else
|
||||
*(sljit_sw*)code_ptr = jump->u.target;
|
||||
sljit_unaligned_store_sw(code_ptr, jump->u.target);
|
||||
|
||||
code_ptr += sizeof(sljit_sw);
|
||||
*code_ptr++ = REX_B;
|
||||
@ -65,34 +65,12 @@ static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_
|
||||
return code_ptr;
|
||||
}
|
||||
|
||||
static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_sw addr, sljit_si type)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
sljit_sw delta = addr - ((sljit_sw)code_ptr + 1 + sizeof(sljit_si));
|
||||
|
||||
if (delta <= HALFWORD_MAX && delta >= HALFWORD_MIN) {
|
||||
*code_ptr++ = (type == 2) ? CALL_i32 : JMP_i32;
|
||||
*(sljit_sw*)code_ptr = delta;
|
||||
}
|
||||
else {
|
||||
SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_second);
|
||||
*code_ptr++ = REX_W | REX_B;
|
||||
*code_ptr++ = MOV_r_i32 + 1;
|
||||
*(sljit_sw*)code_ptr = addr;
|
||||
code_ptr += sizeof(sljit_sw);
|
||||
*code_ptr++ = REX_B;
|
||||
*code_ptr++ = GROUP_FF;
|
||||
*code_ptr++ = (type == 2) ? (MOD_REG | CALL_rm | 1) : (MOD_REG | JMP_rm | 1);
|
||||
}
|
||||
|
||||
return code_ptr;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
{
|
||||
sljit_si i, tmp, size, saved_register_size;
|
||||
sljit_ub *inst;
|
||||
sljit_s32 i, tmp, size, saved_register_size;
|
||||
sljit_u8 *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
@ -106,7 +84,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
|
||||
for (i = SLJIT_S0; i >= tmp; i--) {
|
||||
size = reg_map[i] >= 8 ? 2 : 1;
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(size);
|
||||
if (reg_map[i] >= 8)
|
||||
@ -116,7 +94,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
|
||||
for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
|
||||
size = reg_map[i] >= 8 ? 2 : 1;
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(size);
|
||||
if (reg_map[i] >= 8)
|
||||
@ -126,7 +104,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
|
||||
if (args > 0) {
|
||||
size = args * 3;
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(size);
|
||||
@ -172,9 +150,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
#ifdef _WIN64
|
||||
if (local_size > 1024) {
|
||||
/* Allocate stack for the callback, which grows the stack. */
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + (3 + sizeof(sljit_si)));
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 + (3 + sizeof(sljit_s32)));
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(4 + (3 + sizeof(sljit_si)));
|
||||
INC_SIZE(4 + (3 + sizeof(sljit_s32)));
|
||||
*inst++ = REX_W;
|
||||
*inst++ = GROUP_BINARY_83;
|
||||
*inst++ = MOD_REG | SUB | 4;
|
||||
@ -193,7 +171,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
*inst++ = REX_W;
|
||||
*inst++ = MOV_rm_i32;
|
||||
*inst++ = MOD_REG | reg_lmap[SLJIT_R0];
|
||||
*(sljit_si*)inst = local_size;
|
||||
sljit_unaligned_store_s32(inst, local_size);
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|
||||
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
compiler->skip_checks = 1;
|
||||
@ -204,7 +182,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
|
||||
SLJIT_ASSERT(local_size > 0);
|
||||
if (local_size <= 127) {
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 4);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(4);
|
||||
*inst++ = REX_W;
|
||||
@ -213,35 +191,35 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
*inst++ = local_size;
|
||||
}
|
||||
else {
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 7);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 7);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(7);
|
||||
*inst++ = REX_W;
|
||||
*inst++ = GROUP_BINARY_81;
|
||||
*inst++ = MOD_REG | SUB | 4;
|
||||
*(sljit_si*)inst = local_size;
|
||||
inst += sizeof(sljit_si);
|
||||
sljit_unaligned_store_s32(inst, local_size);
|
||||
inst += sizeof(sljit_s32);
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
/* Save xmm6 register: movaps [rsp + 0x20], xmm6 */
|
||||
if (fscratches >= 6 || fsaveds >= 1) {
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 5);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 5);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(5);
|
||||
*inst++ = GROUP_0F;
|
||||
*(sljit_si*)inst = 0x20247429;
|
||||
sljit_unaligned_store_s32(inst, 0x20247429);
|
||||
}
|
||||
#endif
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
||||
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
sljit_si saved_register_size;
|
||||
sljit_s32 saved_register_size;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
@ -253,10 +231,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_si i, tmp, size;
|
||||
sljit_ub *inst;
|
||||
sljit_s32 i, tmp, size;
|
||||
sljit_u8 *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_return(compiler, op, src, srcw));
|
||||
@ -267,17 +245,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
||||
#ifdef _WIN64
|
||||
/* Restore xmm6 register: movaps xmm6, [rsp + 0x20] */
|
||||
if (compiler->fscratches >= 6 || compiler->fsaveds >= 1) {
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 5);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 5);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(5);
|
||||
*inst++ = GROUP_0F;
|
||||
*(sljit_si*)inst = 0x20247428;
|
||||
sljit_unaligned_store_s32(inst, 0x20247428);
|
||||
}
|
||||
#endif
|
||||
|
||||
SLJIT_ASSERT(compiler->local_size > 0);
|
||||
if (compiler->local_size <= 127) {
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 4);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(4);
|
||||
*inst++ = REX_W;
|
||||
@ -286,19 +264,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
||||
*inst = compiler->local_size;
|
||||
}
|
||||
else {
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 7);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 7);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(7);
|
||||
*inst++ = REX_W;
|
||||
*inst++ = GROUP_BINARY_81;
|
||||
*inst++ = MOD_REG | ADD | 4;
|
||||
*(sljit_si*)inst = compiler->local_size;
|
||||
sljit_unaligned_store_s32(inst, compiler->local_size);
|
||||
}
|
||||
|
||||
tmp = compiler->scratches;
|
||||
for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) {
|
||||
size = reg_map[i] >= 8 ? 2 : 1;
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(size);
|
||||
if (reg_map[i] >= 8)
|
||||
@ -309,7 +287,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
||||
tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
|
||||
for (i = tmp; i <= SLJIT_S0; i++) {
|
||||
size = reg_map[i] >= 8 ? 2 : 1;
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(size);
|
||||
if (reg_map[i] >= 8)
|
||||
@ -317,7 +295,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
||||
POP_REG(reg_lmap[i]);
|
||||
}
|
||||
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(1);
|
||||
RET();
|
||||
@ -328,32 +306,32 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
||||
/* Operators */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static sljit_si emit_do_imm32(struct sljit_compiler *compiler, sljit_ub rex, sljit_ub opcode, sljit_sw imm)
|
||||
static sljit_s32 emit_do_imm32(struct sljit_compiler *compiler, sljit_u8 rex, sljit_u8 opcode, sljit_sw imm)
|
||||
{
|
||||
sljit_ub *inst;
|
||||
sljit_si length = 1 + (rex ? 1 : 0) + sizeof(sljit_si);
|
||||
sljit_u8 *inst;
|
||||
sljit_s32 length = 1 + (rex ? 1 : 0) + sizeof(sljit_s32);
|
||||
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + length);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + length);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(length);
|
||||
if (rex)
|
||||
*inst++ = rex;
|
||||
*inst++ = opcode;
|
||||
*(sljit_si*)inst = imm;
|
||||
sljit_unaligned_store_s32(inst, imm);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size,
|
||||
static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_s32 size,
|
||||
/* The register or immediate operand. */
|
||||
sljit_si a, sljit_sw imma,
|
||||
sljit_s32 a, sljit_sw imma,
|
||||
/* The general operand (not immediate). */
|
||||
sljit_si b, sljit_sw immb)
|
||||
sljit_s32 b, sljit_sw immb)
|
||||
{
|
||||
sljit_ub *inst;
|
||||
sljit_ub *buf_ptr;
|
||||
sljit_ub rex = 0;
|
||||
sljit_si flags = size & ~0xf;
|
||||
sljit_si inst_size;
|
||||
sljit_u8 *inst;
|
||||
sljit_u8 *buf_ptr;
|
||||
sljit_u8 rex = 0;
|
||||
sljit_s32 flags = size & ~0xf;
|
||||
sljit_s32 inst_size;
|
||||
|
||||
/* The immediate operand must be 32 bit. */
|
||||
SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma));
|
||||
@ -400,7 +378,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
||||
}
|
||||
|
||||
if ((b & REG_MASK) == SLJIT_UNUSED)
|
||||
inst_size += 1 + sizeof(sljit_si); /* SIB byte required to avoid RIP based addressing. */
|
||||
inst_size += 1 + sizeof(sljit_s32); /* SIB byte required to avoid RIP based addressing. */
|
||||
else {
|
||||
if (reg_map[b & REG_MASK] >= 8)
|
||||
rex |= REX_B;
|
||||
@ -408,12 +386,12 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
||||
if (immb != 0 && (!(b & OFFS_REG_MASK) || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP))) {
|
||||
/* Immediate operand. */
|
||||
if (immb <= 127 && immb >= -128)
|
||||
inst_size += sizeof(sljit_sb);
|
||||
inst_size += sizeof(sljit_s8);
|
||||
else
|
||||
inst_size += sizeof(sljit_si);
|
||||
inst_size += sizeof(sljit_s32);
|
||||
}
|
||||
else if (reg_lmap[b & REG_MASK] == 5)
|
||||
inst_size += sizeof(sljit_sb);
|
||||
inst_size += sizeof(sljit_s8);
|
||||
|
||||
if ((b & OFFS_REG_MASK) != SLJIT_UNUSED) {
|
||||
inst_size += 1; /* SIB byte. */
|
||||
@ -444,7 +422,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
||||
else if (flags & EX86_HALF_ARG)
|
||||
inst_size += sizeof(short);
|
||||
else
|
||||
inst_size += sizeof(sljit_si);
|
||||
inst_size += sizeof(sljit_s32);
|
||||
}
|
||||
else {
|
||||
SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
|
||||
@ -456,7 +434,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
||||
if (rex)
|
||||
inst_size++;
|
||||
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + inst_size);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + inst_size);
|
||||
PTR_FAIL_IF(!inst);
|
||||
|
||||
/* Encoding the byte. */
|
||||
@ -516,8 +494,8 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
||||
if (immb <= 127 && immb >= -128)
|
||||
*buf_ptr++ = immb; /* 8 bit displacement. */
|
||||
else {
|
||||
*(sljit_si*)buf_ptr = immb; /* 32 bit displacement. */
|
||||
buf_ptr += sizeof(sljit_si);
|
||||
sljit_unaligned_store_s32(buf_ptr, immb); /* 32 bit displacement. */
|
||||
buf_ptr += sizeof(sljit_s32);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -533,17 +511,17 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
||||
else {
|
||||
*buf_ptr++ |= 0x04;
|
||||
*buf_ptr++ = 0x25;
|
||||
*(sljit_si*)buf_ptr = immb; /* 32 bit displacement. */
|
||||
buf_ptr += sizeof(sljit_si);
|
||||
sljit_unaligned_store_s32(buf_ptr, immb); /* 32 bit displacement. */
|
||||
buf_ptr += sizeof(sljit_s32);
|
||||
}
|
||||
|
||||
if (a & SLJIT_IMM) {
|
||||
if (flags & EX86_BYTE_ARG)
|
||||
*buf_ptr = imma;
|
||||
else if (flags & EX86_HALF_ARG)
|
||||
*(short*)buf_ptr = imma;
|
||||
sljit_unaligned_store_s16(buf_ptr, imma);
|
||||
else if (!(flags & EX86_SHIFT_INS))
|
||||
*(sljit_si*)buf_ptr = imma;
|
||||
sljit_unaligned_store_s32(buf_ptr, imma);
|
||||
}
|
||||
|
||||
return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1);
|
||||
@ -553,14 +531,14 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
|
||||
/* Call / return instructions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, sljit_si type)
|
||||
static SLJIT_INLINE sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 type)
|
||||
{
|
||||
sljit_ub *inst;
|
||||
sljit_u8 *inst;
|
||||
|
||||
#ifndef _WIN64
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R1] == 6 && reg_map[SLJIT_R0] < 8 && reg_map[SLJIT_R2] < 8, args_registers);
|
||||
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
|
||||
if (type >= SLJIT_CALL3) {
|
||||
@ -574,7 +552,7 @@ static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, slj
|
||||
#else
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R1] == 2 && reg_map[SLJIT_R0] < 8 && reg_map[SLJIT_R2] < 8, args_registers);
|
||||
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
|
||||
if (type >= SLJIT_CALL3) {
|
||||
@ -589,9 +567,9 @@ static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, slj
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
|
||||
{
|
||||
sljit_ub *inst;
|
||||
sljit_u8 *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
|
||||
@ -603,14 +581,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c
|
||||
|
||||
if (FAST_IS_REG(dst)) {
|
||||
if (reg_map[dst] < 8) {
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(1);
|
||||
POP_REG(reg_lmap[dst]);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 2);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(2);
|
||||
*inst++ = REX_B;
|
||||
@ -626,9 +604,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_ub *inst;
|
||||
sljit_u8 *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
||||
@ -641,14 +619,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
|
||||
|
||||
if (FAST_IS_REG(src)) {
|
||||
if (reg_map[src] < 8) {
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 1);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(1 + 1);
|
||||
PUSH_REG(reg_lmap[src]);
|
||||
}
|
||||
else {
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 1);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + 1);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(2 + 1);
|
||||
@ -664,20 +642,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
|
||||
*inst++ = GROUP_FF;
|
||||
*inst |= PUSH_rm;
|
||||
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(1);
|
||||
}
|
||||
else {
|
||||
SLJIT_ASSERT(IS_HALFWORD(srcw));
|
||||
/* SLJIT_IMM. */
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1);
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 5 + 1);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(5 + 1);
|
||||
*inst++ = PUSH_i32;
|
||||
*(sljit_si*)inst = srcw;
|
||||
inst += sizeof(sljit_si);
|
||||
sljit_unaligned_store_s32(inst, srcw);
|
||||
inst += sizeof(sljit_s32);
|
||||
}
|
||||
|
||||
RET();
|
||||
@ -689,12 +667,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
|
||||
/* Extend input */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
static sljit_s32 emit_mov_int(struct sljit_compiler *compiler, sljit_s32 sign,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_ub* inst;
|
||||
sljit_si dst_r;
|
||||
sljit_u8* inst;
|
||||
sljit_s32 dst_r;
|
||||
|
||||
compiler->mode32 = 0;
|
||||
|
||||
@ -704,7 +682,7 @@ static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign,
|
||||
if (src & SLJIT_IMM) {
|
||||
if (FAST_IS_REG(dst)) {
|
||||
if (sign || ((sljit_uw)srcw <= 0x7fffffff)) {
|
||||
inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw);
|
||||
inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_s32)srcw, dst, dstw);
|
||||
FAIL_IF(!inst);
|
||||
*inst = MOV_rm_i32;
|
||||
return SLJIT_SUCCESS;
|
||||
@ -712,7 +690,7 @@ static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign,
|
||||
return emit_load_imm64(compiler, dst, srcw);
|
||||
}
|
||||
compiler->mode32 = 1;
|
||||
inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw);
|
||||
inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_s32)srcw, dst, dstw);
|
||||
FAIL_IF(!inst);
|
||||
*inst = MOV_rm_i32;
|
||||
compiler->mode32 = 0;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -163,11 +163,11 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
|
||||
#include <fcntl.h>
|
||||
|
||||
/* Some old systems does not have MAP_ANON. */
|
||||
static sljit_si dev_zero = -1;
|
||||
static sljit_s32 dev_zero = -1;
|
||||
|
||||
#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
|
||||
|
||||
static SLJIT_INLINE sljit_si open_dev_zero(void)
|
||||
static SLJIT_INLINE sljit_s32 open_dev_zero(void)
|
||||
{
|
||||
dev_zero = open("/dev/zero", O_RDWR);
|
||||
return dev_zero < 0;
|
||||
@ -179,10 +179,13 @@ static SLJIT_INLINE sljit_si open_dev_zero(void)
|
||||
|
||||
static pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static SLJIT_INLINE sljit_si open_dev_zero(void)
|
||||
static SLJIT_INLINE sljit_s32 open_dev_zero(void)
|
||||
{
|
||||
pthread_mutex_lock(&dev_zero_mutex);
|
||||
dev_zero = open("/dev/zero", O_RDWR);
|
||||
/* The dev_zero might be initialized by another thread during the waiting. */
|
||||
if (dev_zero < 0) {
|
||||
dev_zero = open("/dev/zero", O_RDWR);
|
||||
}
|
||||
pthread_mutex_unlock(&dev_zero_mutex);
|
||||
return dev_zero < 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user