diff options
Diffstat (limited to 'sljit/sljitLir.h')
-rw-r--r-- | sljit/sljitLir.h | 96 |
1 files changed, 49 insertions, 47 deletions
diff --git a/sljit/sljitLir.h b/sljit/sljitLir.h index f64ddcb..a58ad6e 100644 --- a/sljit/sljitLir.h +++ b/sljit/sljitLir.h @@ -120,8 +120,8 @@ of sljitConfigInternal.h */ If an architecture provides two scratch and three saved registers, its scratch and saved register sets are the following: - R0 | [S4] | R0 and S4 represent the same physical register - R1 | [S3] | R1 and S3 represent the same physical register + R0 | | R0 is always a scratch register + R1 | | R1 is always a scratch register [R2] | S2 | R2 and S2 represent the same physical register [R3] | S1 | R3 and S1 represent the same physical register [R4] | S0 | R4 and S0 represent the same physical register @@ -129,38 +129,35 @@ of sljitConfigInternal.h */ Note: SLJIT_NUMBER_OF_SCRATCH_REGISTERS would be 2 and SLJIT_NUMBER_OF_SAVED_REGISTERS would be 3 for this architecture. - Note: On all supported architectures SLJIT_NUMBER_OF_REGISTERS >= 10 - and SLJIT_NUMBER_OF_SAVED_REGISTERS >= 5. However, 4 registers + Note: On all supported architectures SLJIT_NUMBER_OF_REGISTERS >= 12 + and SLJIT_NUMBER_OF_SAVED_REGISTERS >= 6. However, 6 registers are virtual on x86-32. See below. - The purpose of this definition is convenience. Although a register - is either scratch register or saved register, SLJIT allows accessing - them from the other set. For example, four registers can be used as - scratch registers and the fifth one as saved register on the architecture - above. Of course the last two scratch registers (R2 and R3) from this - four will be saved on the stack, because they are defined as saved - registers in the application binary interface. Still R2 and R3 can be - used for referencing to these registers instead of S2 and S1, which - makes easier to write platform independent code. Scratch registers - can be saved registers in a similar way, but these extra saved - registers will not be preserved across function calls! Hence the - application must save them on those platforms, where the number of - saved registers is too low. This can be done by copy them onto - the stack and restore them after a function call. + The purpose of this definition is convenience: saved registers can + be used as extra scratch registers. For example four registers can + be specified as scratch registers and the fifth one as saved register + on the CPU above and any user code which requires four scratch + registers can run unmodified. The SLJIT compiler automatically saves + the content of the two extra scrath register on the stack. Scratch + registers can also be preserved by saving their value on the stack + but this needs to be done manually. Note: To emphasize that registers assigned to R2-R4 are saved - registers, they are enclosed by square brackets. S3-S4 - are marked in a similar way. + registers, they are enclosed by square brackets. Note: sljit_emit_enter and sljit_set_context defines whether a register is S or R register. E.g: when 3 scratches and 1 saved is mapped by sljit_emit_enter, the allowed register set will be: R0-R2 and S0. Although S2 is mapped to the same position as R2, it does not - available in the current configuration. Furthermore the R3 (S1) - register does not available as well. + available in the current configuration. Furthermore the S1 register + is not available at all. */ -/* When SLJIT_UNUSED is specified as destination, the result is discarded. */ +/* When SLJIT_UNUSED is specified as the destination of sljit_emit_op1 and + and sljit_emit_op2 operations the result is discarded. If no status + flags are set, no instructions are emitted for these operations. Data + prefetch is a special exception, see SLJIT_MOV operation. Other SLJIT + operations do not support SLJIT_UNUSED as a destination operand. */ #define SLJIT_UNUSED 0 /* Scratch registers. */ @@ -489,21 +486,27 @@ static SLJIT_INLINE sljit_sw sljit_get_executable_offset(struct sljit_compiler * */ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler *compiler) { return compiler->executable_size; } -/* Returns with non-zero if the passed SLJIT_HAS_* feature is available. +/* Returns with non-zero if the feature or limitation type passed as its + argument is present on the current CPU. - Some features (e.g. floating point operations) require CPU support - while other (e.g. move with update) is emulated if not available. - However it might be worth to generate a special code path even in - the latter case in certain cases. */ + Some features (e.g. floating point operations) require hardware (CPU) + support while others (e.g. move with update) are emulated if not available. + However even if a feature is emulated, specialized code paths can be faster + than the emulation. Some limitations are emulated as well so their general + case is supported but it has extra performance costs. */ /* [Not emulated] Floating-point support is available. */ #define SLJIT_HAS_FPU 0 +/* [Limitation] Some registers are virtual registers. */ +#define SLJIT_HAS_VIRTUAL_REGISTERS 1 /* [Emulated] Some forms of move with pre update is supported. */ -#define SLJIT_HAS_PRE_UPDATE 1 +#define SLJIT_HAS_PRE_UPDATE 2 /* [Emulated] Count leading zero is supported. */ -#define SLJIT_HAS_CLZ 2 +#define SLJIT_HAS_CLZ 3 /* [Emulated] Conditional move is supported. */ -#define SLJIT_HAS_CMOV 3 +#define SLJIT_HAS_CMOV 4 +/* [Limitation] [Emulated] Shifting with register is limited to SLJIT_PREF_SHIFT_REG. */ +#define SLJIT_HAS_PREF_SHIFT_REG 5 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) /* [Not emulated] SSE2 support is available on x86. */ @@ -723,8 +726,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler Example: SLJIT_ADD can set the Z, OVERFLOW, CARRY flags hence sljit_op2(..., SLJIT_ADD, ...) - Both the zero and variable flags are undefined so their - they hold a random value after the operation is completed. + Both the zero and variable flags are undefined so they can + have any value after the operation is completed. sljit_op2(..., SLJIT_ADD | SLJIT_SET_Z, ...) Sets the zero flag if the result is zero, clears it otherwise. @@ -734,10 +737,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler Sets the variable flag if an integer overflow occurs, clears it otherwise. The zero flag is undefined. - sljit_op2(..., SLJIT_ADD | SLJIT_SET_NOT_OVERFLOW, ...) - Sets the variable flag if an integer overflow does NOT occur, - clears it otherwise. The zero flag is undefined. - sljit_op2(..., SLJIT_ADD | SLJIT_SET_Z | SLJIT_SET_CARRY, ...) Sets the zero flag if the result is zero, clears it otherwise. Sets the variable flag if unsigned overflow (carry) occurs, @@ -862,6 +861,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile sljit_emit_op1(..., SLJIT_MOVU_U8, SLJIT_MEM2(SLJIT_R0, SLJIT_R2), 0, SLJIT_MEM2(SLJIT_R1, SLJIT_R2), 0); + + If the destination of a MOV without update instruction is SLJIT_UNUSED + and the source operand is a memory address the compiler emits a prefetch + instruction if this instruction is supported by the current CPU. + Higher data sizes bring the data closer to the core: a MOV with word + size loads the data into a higher level cache than a byte size. Otherwise + the type does not affect the prefetch instruction. Furthermore a prefetch + instruction never fails, so it can be used to prefetch a data from an + address and check whether that address is NULL afterwards. */ /* Flags: - (does not modify flags) */ @@ -1090,14 +1098,12 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi #define SLJIT_SET_OVERFLOW SLJIT_SET(SLJIT_OVERFLOW) #define SLJIT_NOT_OVERFLOW 11 #define SLJIT_NOT_OVERFLOW32 (SLJIT_NOT_OVERFLOW | SLJIT_I32_OP) -#define SLJIT_SET_NOT_OVERFLOW SLJIT_SET(SLJIT_NOT_OVERFLOW) #define SLJIT_MUL_OVERFLOW 12 #define SLJIT_MUL_OVERFLOW32 (SLJIT_MUL_OVERFLOW | SLJIT_I32_OP) #define SLJIT_SET_MUL_OVERFLOW SLJIT_SET(SLJIT_MUL_OVERFLOW) #define SLJIT_MUL_NOT_OVERFLOW 13 #define SLJIT_MUL_NOT_OVERFLOW32 (SLJIT_MUL_NOT_OVERFLOW | SLJIT_I32_OP) -#define SLJIT_SET_MUL_NOT_OVERFLOW SLJIT_SET(SLJIT_MUL_NOT_OVERFLOW) /* There is no SLJIT_CARRY or SLJIT_NOT_CARRY. */ #define SLJIT_SET_CARRY SLJIT_SET(14) @@ -1194,19 +1200,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi represented by the type is 1, if the condition represented by the type is fulfilled, and 0 otherwise. - If op == SLJIT_MOV, SLJIT_MOV_S32, SLJIT_MOV_U32: + If op == SLJIT_MOV, SLJIT_MOV32: Set dst to the value represented by the type (0 or 1). - Src must be SLJIT_UNUSED, and srcw must be 0 Flags: - (does not modify flags) If op == SLJIT_OR, op == SLJIT_AND, op == SLJIT_XOR - Performs the binary operation using src as the first, and the value - represented by type as the second argument. - Important note: only dst=src and dstw=srcw is supported at the moment! - Flags: Z (may destroy flags) - Note: sljit_emit_op_flags does nothing, if dst is SLJIT_UNUSED (regardless of op). */ + Performs the binary operation using dst as the first, and the value + represented by type as the second argument. Result is written into dst. + Flags: Z (may destroy flags) */ 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); /* Emit a conditional mov instruction which moves source to destination, |