version 1.1.1.1, 2012/02/21 23:05:52
|
version 1.1.1.3, 2012/10/09 09:19:18
|
Line 1
|
Line 1
|
/* |
/* |
* Stack-less Just-In-Time compiler |
* Stack-less Just-In-Time compiler |
* |
* |
* Copyright 2009-2010 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. | * Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. |
* |
* |
* Redistribution and use in source and binary forms, with or without modification, are |
* Redistribution and use in source and binary forms, with or without modification, are |
* permitted provided that the following conditions are met: |
* permitted provided that the following conditions are met: |
Line 27
|
Line 27
|
SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name() |
SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name() |
{ |
{ |
#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) |
#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) |
return "arm-v7"; | return "ARMv7" SLJIT_CPUINFO; |
#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) |
#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) |
return "arm-v5"; | return "ARMv5" SLJIT_CPUINFO; |
#else |
#else |
#error "Internal error: Unknown ARM architecture" |
#error "Internal error: Unknown ARM architecture" |
#endif |
#endif |
Line 54 SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_p
|
Line 54 SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_p
|
#define MAX_DIFFERENCE(max_diff) \ |
#define MAX_DIFFERENCE(max_diff) \ |
(((max_diff) / (int)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1)) |
(((max_diff) / (int)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1)) |
|
|
/* See sljit_emit_enter if you want to change them. */ | /* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */ |
static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = { |
static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = { |
0, 0, 1, 2, 10, 11, 4, 5, 6, 7, 8, 13, 3, 12, 14, 15 |
0, 0, 1, 2, 10, 11, 4, 5, 6, 7, 8, 13, 3, 12, 14, 15 |
}; |
}; |
Line 84 static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS
|
Line 84 static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS
|
#define BX 0xe12fff10 |
#define BX 0xe12fff10 |
#define CLZ 0xe16f0f10 |
#define CLZ 0xe16f0f10 |
#define CMP_DP 0xa |
#define CMP_DP 0xa |
#define DEBUGGER 0xe1200070 | #define BKPT 0xe1200070 |
#define EOR_DP 0x1 |
#define EOR_DP 0x1 |
#define MOV_DP 0xd |
#define MOV_DP 0xd |
#define MUL 0xe0000090 |
#define MUL 0xe0000090 |
Line 98 static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS
|
Line 98 static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS
|
#define SBC_DP 0x6 |
#define SBC_DP 0x6 |
#define SMULL 0xe0c00090 |
#define SMULL 0xe0c00090 |
#define SUB_DP 0x2 |
#define SUB_DP 0x2 |
|
#define UMULL 0xe0800090 |
#define VABS_F64 0xeeb00bc0 |
#define VABS_F64 0xeeb00bc0 |
#define VADD_F64 0xee300b00 |
#define VADD_F64 0xee300b00 |
#define VCMP_F64 0xeeb40b40 |
#define VCMP_F64 0xeeb40b40 |
Line 819 static int emit_op(struct sljit_compiler *compiler, in
|
Line 820 static int emit_op(struct sljit_compiler *compiler, in
|
int src1, sljit_w src1w, |
int src1, sljit_w src1w, |
int src2, sljit_w src2w); |
int src2, sljit_w src2w); |
|
|
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size) | SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) |
{ |
{ |
int size; |
int size; |
sljit_uw push; |
sljit_uw push; |
|
|
CHECK_ERROR(); |
CHECK_ERROR(); |
check_sljit_emit_enter(compiler, args, temporaries, generals, local_size); | check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); |
|
|
compiler->temporaries = temporaries; |
compiler->temporaries = temporaries; |
compiler->generals = generals; | compiler->saveds = saveds; |
| #if (defined SLJIT_DEBUG && SLJIT_DEBUG) |
| compiler->logical_local_size = local_size; |
| #endif |
|
|
/* Push general registers, temporary registers | /* Push saved registers, temporary registers |
stmdb sp!, {..., lr} */ |
stmdb sp!, {..., lr} */ |
push = PUSH | (1 << 14); |
push = PUSH | (1 << 14); |
if (temporaries >= 5) |
if (temporaries >= 5) |
push |= 1 << 11; |
push |= 1 << 11; |
if (temporaries >= 4) |
if (temporaries >= 4) |
push |= 1 << 10; |
push |= 1 << 10; |
if (generals >= 5) | if (saveds >= 5) |
push |= 1 << 8; |
push |= 1 << 8; |
if (generals >= 4) | if (saveds >= 4) |
push |= 1 << 7; |
push |= 1 << 7; |
if (generals >= 3) | if (saveds >= 3) |
push |= 1 << 6; |
push |= 1 << 6; |
if (generals >= 2) | if (saveds >= 2) |
push |= 1 << 5; |
push |= 1 << 5; |
if (generals >= 1) | if (saveds >= 1) |
push |= 1 << 4; |
push |= 1 << 4; |
EMIT_INSTRUCTION(push); |
EMIT_INSTRUCTION(push); |
|
|
/* Stack must be aligned to 8 bytes: */ |
/* Stack must be aligned to 8 bytes: */ |
size = (1 + generals) * sizeof(sljit_uw); | size = (1 + saveds) * sizeof(sljit_uw); |
if (temporaries >= 4) |
if (temporaries >= 4) |
size += (temporaries - 3) * sizeof(sljit_uw); |
size += (temporaries - 3) * sizeof(sljit_uw); |
local_size += size; |
local_size += size; |
Line 861 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct s
|
Line 865 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct s
|
FAIL_IF(emit_op(compiler, SLJIT_SUB, ALLOW_IMM, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size)); |
FAIL_IF(emit_op(compiler, SLJIT_SUB, ALLOW_IMM, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size)); |
|
|
if (args >= 1) |
if (args >= 1) |
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_GENERAL_REG1, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG1))); | EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG1, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG1))); |
if (args >= 2) |
if (args >= 2) |
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_GENERAL_REG2, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG2))); | EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG2, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG2))); |
if (args >= 3) |
if (args >= 3) |
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_GENERAL_REG3, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG3))); | EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG3, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG3))); |
|
|
return SLJIT_SUCCESS; |
return SLJIT_SUCCESS; |
} |
} |
|
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_fake_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size) | SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) |
{ |
{ |
int size; |
int size; |
|
|
CHECK_ERROR_VOID(); |
CHECK_ERROR_VOID(); |
check_sljit_fake_enter(compiler, args, temporaries, generals, local_size); | check_sljit_set_context(compiler, args, temporaries, saveds, local_size); |
|
|
compiler->temporaries = temporaries; |
compiler->temporaries = temporaries; |
compiler->generals = generals; | compiler->saveds = saveds; |
| #if (defined SLJIT_DEBUG && SLJIT_DEBUG) |
| compiler->logical_local_size = local_size; |
| #endif |
|
|
size = (1 + generals) * sizeof(sljit_uw); | size = (1 + saveds) * sizeof(sljit_uw); |
if (temporaries >= 4) |
if (temporaries >= 4) |
size += (temporaries - 3) * sizeof(sljit_uw); |
size += (temporaries - 3) * sizeof(sljit_uw); |
local_size += size; |
local_size += size; |
Line 889 SLJIT_API_FUNC_ATTRIBUTE void sljit_fake_enter(struct
|
Line 896 SLJIT_API_FUNC_ATTRIBUTE void sljit_fake_enter(struct
|
compiler->local_size = local_size; |
compiler->local_size = local_size; |
} |
} |
|
|
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int src, sljit_w srcw) | SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) |
{ |
{ |
sljit_uw pop; |
sljit_uw pop; |
|
|
CHECK_ERROR(); |
CHECK_ERROR(); |
check_sljit_emit_return(compiler, src, srcw); | check_sljit_emit_return(compiler, op, src, srcw); |
| ADJUST_LOCAL_OFFSET(src, srcw); |
|
|
if (src != SLJIT_UNUSED && src != SLJIT_RETURN_REG) | FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); |
FAIL_IF(emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, SLJIT_RETURN_REG, 0, TMP_REG1, 0, src, srcw)); | |
|
|
if (compiler->local_size > 0) |
if (compiler->local_size > 0) |
FAIL_IF(emit_op(compiler, SLJIT_ADD, ALLOW_IMM, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size)); |
FAIL_IF(emit_op(compiler, SLJIT_ADD, ALLOW_IMM, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size)); |
|
|
pop = POP | (1 << 15); |
pop = POP | (1 << 15); |
/* Push general registers, temporary registers | /* Push saved registers, temporary registers |
ldmia sp!, {..., pc} */ |
ldmia sp!, {..., pc} */ |
if (compiler->temporaries >= 5) |
if (compiler->temporaries >= 5) |
pop |= 1 << 11; |
pop |= 1 << 11; |
if (compiler->temporaries >= 4) |
if (compiler->temporaries >= 4) |
pop |= 1 << 10; |
pop |= 1 << 10; |
if (compiler->generals >= 5) | if (compiler->saveds >= 5) |
pop |= 1 << 8; |
pop |= 1 << 8; |
if (compiler->generals >= 4) | if (compiler->saveds >= 4) |
pop |= 1 << 7; |
pop |= 1 << 7; |
if (compiler->generals >= 3) | if (compiler->saveds >= 3) |
pop |= 1 << 6; |
pop |= 1 << 6; |
if (compiler->generals >= 2) | if (compiler->saveds >= 2) |
pop |= 1 << 5; |
pop |= 1 << 5; |
if (compiler->generals >= 1) | if (compiler->saveds >= 1) |
pop |= 1 << 4; |
pop |= 1 << 4; |
|
|
return push_inst(compiler, pop); |
return push_inst(compiler, pop); |
Line 992 static sljit_w data_transfer_insts[16] = {
|
Line 999 static sljit_w data_transfer_insts[16] = {
|
if (compiler->shift_imm != 0x20) { \ |
if (compiler->shift_imm != 0x20) { \ |
SLJIT_ASSERT(src1 == TMP_REG1); \ |
SLJIT_ASSERT(src1 == TMP_REG1); \ |
SLJIT_ASSERT(!(flags & ARGS_SWAPPED)); \ |
SLJIT_ASSERT(!(flags & ARGS_SWAPPED)); \ |
return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (compiler->shift_imm << 7) | (opcode << 5) | reg_map[src2])); \ | if (compiler->shift_imm != 0) \ |
| return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (compiler->shift_imm << 7) | (opcode << 5) | reg_map[src2])); \ |
| return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, reg_map[src2])); \ |
} \ |
} \ |
return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (reg_map[(flags & ARGS_SWAPPED) ? src1 : src2] << 8) | (opcode << 5) | 0x10 | ((flags & ARGS_SWAPPED) ? reg_map[src2] : reg_map[src1]))); |
return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (reg_map[(flags & ARGS_SWAPPED) ? src1 : src2] << 8) | (opcode << 5) | 0x10 | ((flags & ARGS_SWAPPED) ? reg_map[src2] : reg_map[src1]))); |
|
|
Line 1646 static int emit_op(struct sljit_compiler *compiler, in
|
Line 1655 static int emit_op(struct sljit_compiler *compiler, in
|
src2 = src1; |
src2 = src1; |
src2w = src1w; |
src2w = src1w; |
} |
} |
else { | else do { /* do { } while(0) is used because of breaks. */ |
| src1_r = 0; |
if ((inp_flags & ALLOW_ANY_IMM) && (src1 & SLJIT_IMM)) { |
if ((inp_flags & ALLOW_ANY_IMM) && (src1 & SLJIT_IMM)) { |
/* The second check will generate a hit. */ |
/* The second check will generate a hit. */ |
src2_r = get_immediate(src1w); |
src2_r = get_immediate(src1w); |
Line 1654 static int emit_op(struct sljit_compiler *compiler, in
|
Line 1664 static int emit_op(struct sljit_compiler *compiler, in
|
flags |= ARGS_SWAPPED; |
flags |= ARGS_SWAPPED; |
src1 = src2; |
src1 = src2; |
src1w = src2w; |
src1w = src2w; |
|
break; |
} |
} |
if (inp_flags & ALLOW_INV_IMM) { |
if (inp_flags & ALLOW_INV_IMM) { |
src2_r = get_immediate(~src1w); |
src2_r = get_immediate(~src1w); |
Line 1661 static int emit_op(struct sljit_compiler *compiler, in
|
Line 1672 static int emit_op(struct sljit_compiler *compiler, in
|
flags |= ARGS_SWAPPED | INV_IMM; |
flags |= ARGS_SWAPPED | INV_IMM; |
src1 = src2; |
src1 = src2; |
src1w = src2w; |
src1w = src2w; |
|
break; |
} |
} |
} |
} |
|
if (GET_OPCODE(op) == SLJIT_ADD) { |
|
src2_r = get_immediate(-src1w); |
|
if (src2_r) { |
|
/* Note: ARGS_SWAPPED is intentionally not applied! */ |
|
src1 = src2; |
|
src1w = src2w; |
|
op = SLJIT_SUB | GET_ALL_FLAGS(op); |
|
break; |
|
} |
|
} |
} |
} |
|
|
src1_r = 0; |
|
if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w)) { |
if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w)) { |
FAIL_IF(compiler->error); |
FAIL_IF(compiler->error); |
src1_r = TMP_REG1; |
src1_r = TMP_REG1; |
} |
} |
} | } while (0); |
|
|
/* Source 2. */ |
/* Source 2. */ |
if (src2_r == 0) { |
if (src2_r == 0) { |
Line 1692 static int emit_op(struct sljit_compiler *compiler, in
|
Line 1713 static int emit_op(struct sljit_compiler *compiler, in
|
break; |
break; |
} |
} |
} |
} |
|
if (GET_OPCODE(op) == SLJIT_ADD) { |
|
src2_r = get_immediate(-src2w); |
|
if (src2_r) { |
|
op = SLJIT_SUB | GET_ALL_FLAGS(op); |
|
flags &= ~ARGS_SWAPPED; |
|
break; |
|
} |
|
} |
|
if (GET_OPCODE(op) == SLJIT_SUB && !(flags & ARGS_SWAPPED)) { |
|
src2_r = get_immediate(-src2w); |
|
if (src2_r) { |
|
op = SLJIT_ADD | GET_ALL_FLAGS(op); |
|
flags &= ~ARGS_SWAPPED; |
|
break; |
|
} |
|
} |
} |
} |
|
|
/* src2_r is 0. */ |
/* src2_r is 0. */ |
Line 1755 static int emit_op(struct sljit_compiler *compiler, in
|
Line 1792 static int emit_op(struct sljit_compiler *compiler, in
|
return SLJIT_SUCCESS; |
return SLJIT_SUCCESS; |
} |
} |
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
#if defined(__GNUC__) |
|
extern unsigned int __aeabi_uidivmod(unsigned numerator, unsigned denominator); |
|
extern unsigned int __aeabi_idivmod(unsigned numerator, unsigned denominator); |
|
#else |
|
#error "Software divmod functions are needed" |
|
#endif |
|
|
|
#ifdef __cplusplus |
|
} |
|
#endif |
|
|
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op) |
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op) |
{ |
{ |
CHECK_ERROR(); |
CHECK_ERROR(); |
Line 1763 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct slj
|
Line 1815 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct slj
|
op = GET_OPCODE(op); |
op = GET_OPCODE(op); |
switch (op) { |
switch (op) { |
case SLJIT_BREAKPOINT: |
case SLJIT_BREAKPOINT: |
EMIT_INSTRUCTION(DEBUGGER); | EMIT_INSTRUCTION(BKPT); |
break; |
break; |
case SLJIT_NOP: |
case SLJIT_NOP: |
EMIT_INSTRUCTION(NOP); |
EMIT_INSTRUCTION(NOP); |
break; |
break; |
|
case SLJIT_UMUL: |
|
case SLJIT_SMUL: |
|
#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) |
|
return push_inst(compiler, (op == SLJIT_UMUL ? UMULL : SMULL) |
|
| (reg_map[SLJIT_TEMPORARY_REG2] << 16) |
|
| (reg_map[SLJIT_TEMPORARY_REG1] << 12) |
|
| (reg_map[SLJIT_TEMPORARY_REG1] << 8) |
|
| reg_map[SLJIT_TEMPORARY_REG2]); |
|
#else |
|
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG2))); |
|
return push_inst(compiler, (op == SLJIT_UMUL ? UMULL : SMULL) |
|
| (reg_map[SLJIT_TEMPORARY_REG2] << 16) |
|
| (reg_map[SLJIT_TEMPORARY_REG1] << 12) |
|
| (reg_map[SLJIT_TEMPORARY_REG1] << 8) |
|
| reg_map[TMP_REG1]); |
|
#endif |
|
case SLJIT_UDIV: |
|
case SLJIT_SDIV: |
|
if (compiler->temporaries >= 3) |
|
EMIT_INSTRUCTION(0xe52d2008 /* str r2, [sp, #-8]! */); |
|
#if defined(__GNUC__) |
|
FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM, |
|
(op == SLJIT_UDIV ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod)))); |
|
#else |
|
#error "Software divmod functions are needed" |
|
#endif |
|
if (compiler->temporaries >= 3) |
|
return push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */); |
|
return SLJIT_SUCCESS; |
} |
} |
|
|
return SLJIT_SUCCESS; |
return SLJIT_SUCCESS; |
Line 1779 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct slj
|
Line 1860 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct slj
|
{ |
{ |
CHECK_ERROR(); |
CHECK_ERROR(); |
check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw); |
check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw); |
|
ADJUST_LOCAL_OFFSET(dst, dstw); |
|
ADJUST_LOCAL_OFFSET(src, srcw); |
|
|
switch (GET_OPCODE(op)) { |
switch (GET_OPCODE(op)) { |
case SLJIT_MOV: |
case SLJIT_MOV: |
Line 1822 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct slj
|
Line 1905 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct slj
|
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) |
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) |
compiler->skip_checks = 1; |
compiler->skip_checks = 1; |
#endif |
#endif |
return sljit_emit_op2(compiler, SLJIT_SUB | GET_FLAGS(op), dst, dstw, SLJIT_IMM, 0, src, srcw); | return sljit_emit_op2(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), dst, dstw, SLJIT_IMM, 0, src, srcw); |
|
|
case SLJIT_CLZ: |
case SLJIT_CLZ: |
return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw); |
return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw); |
Line 1838 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct slj
|
Line 1921 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct slj
|
{ |
{ |
CHECK_ERROR(); |
CHECK_ERROR(); |
check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w); |
check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w); |
|
ADJUST_LOCAL_OFFSET(dst, dstw); |
|
ADJUST_LOCAL_OFFSET(src1, src1w); |
|
ADJUST_LOCAL_OFFSET(src2, src2w); |
|
|
switch (GET_OPCODE(op)) { |
switch (GET_OPCODE(op)) { |
case SLJIT_ADD: |
case SLJIT_ADD: |
Line 1870 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct slj
|
Line 1956 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct slj
|
return SLJIT_SUCCESS; |
return SLJIT_SUCCESS; |
} |
} |
|
|
|
SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg) |
|
{ |
|
check_sljit_get_register_index(reg); |
|
return reg_map[reg]; |
|
} |
|
|
|
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler, |
|
void *instruction, int size) |
|
{ |
|
CHECK_ERROR(); |
|
check_sljit_emit_op_custom(compiler, instruction, size); |
|
SLJIT_ASSERT(size == 4); |
|
|
|
return push_inst(compiler, *(sljit_uw*)instruction); |
|
} |
|
|
/* --------------------------------------------------------------------- */ |
/* --------------------------------------------------------------------- */ |
/* Floating point operators */ |
/* Floating point operators */ |
/* --------------------------------------------------------------------- */ |
/* --------------------------------------------------------------------- */ |
Line 2079 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sl
|
Line 2181 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sl
|
/* Other instructions */ |
/* Other instructions */ |
/* --------------------------------------------------------------------- */ |
/* --------------------------------------------------------------------- */ |
|
|
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int generals, int local_size) | SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) |
{ |
{ |
int size; |
|
|
|
CHECK_ERROR(); |
CHECK_ERROR(); |
check_sljit_emit_fast_enter(compiler, dst, dstw, args, temporaries, generals, local_size); | check_sljit_emit_fast_enter(compiler, dst, dstw); |
| ADJUST_LOCAL_OFFSET(dst, dstw); |
|
|
compiler->temporaries = temporaries; |
|
compiler->generals = generals; |
|
|
|
size = (1 + generals) * sizeof(sljit_uw); |
|
if (temporaries >= 4) |
|
size += (temporaries - 3) * sizeof(sljit_uw); |
|
local_size += size; |
|
local_size = (local_size + 7) & ~7; |
|
local_size -= size; |
|
compiler->local_size = local_size; |
|
|
|
if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) |
if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) |
return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, RM(TMP_REG3))); |
return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, RM(TMP_REG3))); |
else if (dst & SLJIT_MEM) { |
else if (dst & SLJIT_MEM) { |
Line 2115 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(st
|
Line 2205 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(st
|
{ |
{ |
CHECK_ERROR(); |
CHECK_ERROR(); |
check_sljit_emit_fast_return(compiler, src, srcw); |
check_sljit_emit_fast_return(compiler, src, srcw); |
|
ADJUST_LOCAL_OFFSET(src, srcw); |
|
|
if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) |
if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) |
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(src))); |
EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(src))); |
Line 2254 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct s
|
Line 2345 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct s
|
|
|
CHECK_ERROR(); |
CHECK_ERROR(); |
check_sljit_emit_ijump(compiler, type, src, srcw); |
check_sljit_emit_ijump(compiler, type, src, srcw); |
|
ADJUST_LOCAL_OFFSET(src, srcw); |
|
|
/* In ARM, we don't need to touch the arguments. */ |
/* In ARM, we don't need to touch the arguments. */ |
if (src & SLJIT_IMM) { |
if (src & SLJIT_IMM) { |
Line 2293 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(str
|
Line 2385 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(str
|
|
|
CHECK_ERROR(); |
CHECK_ERROR(); |
check_sljit_emit_cond_value(compiler, op, dst, dstw, type); |
check_sljit_emit_cond_value(compiler, op, dst, dstw, type); |
|
ADJUST_LOCAL_OFFSET(dst, dstw); |
|
|
if (dst == SLJIT_UNUSED) |
if (dst == SLJIT_UNUSED) |
return SLJIT_SUCCESS; |
return SLJIT_SUCCESS; |
Line 2331 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emi
|
Line 2424 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emi
|
|
|
CHECK_ERROR_PTR(); |
CHECK_ERROR_PTR(); |
check_sljit_emit_const(compiler, dst, dstw, init_value); |
check_sljit_emit_const(compiler, dst, dstw, init_value); |
|
ADJUST_LOCAL_OFFSET(dst, dstw); |
|
|
const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); |
const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); |
PTR_FAIL_IF(!const_); |
PTR_FAIL_IF(!const_); |