diff options
Diffstat (limited to 'thirdparty/pcre2/src/sljit/sljitNativeARM_32.c')
| -rw-r--r-- | thirdparty/pcre2/src/sljit/sljitNativeARM_32.c | 126 | 
1 files changed, 92 insertions, 34 deletions
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c b/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c index 6d61eed9a7..71f7bcdadb 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c @@ -583,8 +583,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	sljit_uw *buf_end;  	sljit_uw size;  	sljit_uw word_count; +	sljit_uw next_addr;  	sljit_sw executable_offset; -	sljit_sw jump_addr; +	sljit_sw addr;  #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)  	sljit_uw cpool_size;  	sljit_uw cpool_skip_alignment; @@ -597,6 +598,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	struct sljit_label *label;  	struct sljit_jump *jump;  	struct sljit_const *const_; +	struct sljit_put_label *put_label;  	CHECK_ERROR_PTR();  	CHECK_PTR(check_sljit_generate_code(compiler)); @@ -625,11 +627,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	code_ptr = code;  	word_count = 0; +	next_addr = 1;  	executable_offset = SLJIT_EXEC_OFFSET(code);  	label = compiler->labels;  	jump = compiler->jumps;  	const_ = compiler->consts; +	put_label = compiler->put_labels;  	if (label && label->size == 0) {  		label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset); @@ -669,35 +673,45 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  			else if ((*buf_ptr & 0xff000000) != PUSH_POOL) {  #endif  				*code_ptr = *buf_ptr++; +				if (next_addr == word_count) { +					SLJIT_ASSERT(!label || label->size >= word_count); +					SLJIT_ASSERT(!jump || jump->addr >= word_count); +					SLJIT_ASSERT(!const_ || const_->addr >= word_count); +					SLJIT_ASSERT(!put_label || put_label->addr >= word_count); +  				/* These structures are ordered by their address. */ -				SLJIT_ASSERT(!label || label->size >= word_count); -				SLJIT_ASSERT(!jump || jump->addr >= word_count); -				SLJIT_ASSERT(!const_ || const_->addr >= word_count); -				if (jump && jump->addr == word_count) { +					if (jump && jump->addr == word_count) {  #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) -					if (detect_jump_type(jump, code_ptr, code, executable_offset)) -						code_ptr--; -					jump->addr = (sljit_uw)code_ptr; +						if (detect_jump_type(jump, code_ptr, code, executable_offset)) +							code_ptr--; +						jump->addr = (sljit_uw)code_ptr;  #else -					jump->addr = (sljit_uw)(code_ptr - 2); -					if (detect_jump_type(jump, code_ptr, code, executable_offset)) -						code_ptr -= 2; +						jump->addr = (sljit_uw)(code_ptr - 2); +						if (detect_jump_type(jump, code_ptr, code, executable_offset)) +							code_ptr -= 2;  #endif -					jump = jump->next; -				} -				if (label && label->size == word_count) { -					/* code_ptr can be affected above. */ -					label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr + 1, executable_offset); -					label->size = (code_ptr + 1) - code; -					label = label->next; -				} -				if (const_ && const_->addr == word_count) { +						jump = jump->next; +					} +					if (label && label->size == word_count) { +						/* code_ptr can be affected above. */ +						label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr + 1, executable_offset); +						label->size = (code_ptr + 1) - code; +						label = label->next; +					} +					if (const_ && const_->addr == word_count) {  #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) -					const_->addr = (sljit_uw)code_ptr; +						const_->addr = (sljit_uw)code_ptr;  #else -					const_->addr = (sljit_uw)(code_ptr - 1); +						const_->addr = (sljit_uw)(code_ptr - 1);  #endif -					const_ = const_->next; +						const_ = const_->next; +					} +					if (put_label && put_label->addr == word_count) { +						SLJIT_ASSERT(put_label->label); +						put_label->addr = (sljit_uw)code_ptr; +						put_label = put_label->next; +					} +					next_addr = compute_next_addr(label, jump, const_, put_label);  				}  				code_ptr++;  #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) @@ -725,6 +739,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	SLJIT_ASSERT(!label);  	SLJIT_ASSERT(!jump);  	SLJIT_ASSERT(!const_); +	SLJIT_ASSERT(!put_label);  #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)  	SLJIT_ASSERT(cpool_size == 0); @@ -755,15 +770,15 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  		buf_ptr = (sljit_uw *)jump->addr;  		if (jump->flags & PATCH_B) { -			jump_addr = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset); +			addr = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset);  			if (!(jump->flags & JUMP_ADDR)) {  				SLJIT_ASSERT(jump->flags & JUMP_LABEL); -				SLJIT_ASSERT(((sljit_sw)jump->u.label->addr - jump_addr) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - jump_addr) >= -0x02000000); -				*buf_ptr |= (((sljit_sw)jump->u.label->addr - jump_addr) >> 2) & 0x00ffffff; +				SLJIT_ASSERT(((sljit_sw)jump->u.label->addr - addr) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - addr) >= -0x02000000); +				*buf_ptr |= (((sljit_sw)jump->u.label->addr - addr) >> 2) & 0x00ffffff;  			}  			else { -				SLJIT_ASSERT(((sljit_sw)jump->u.target - jump_addr) <= 0x01ffffff && ((sljit_sw)jump->u.target - jump_addr) >= -0x02000000); -				*buf_ptr |= (((sljit_sw)jump->u.target - jump_addr) >> 2) & 0x00ffffff; +				SLJIT_ASSERT(((sljit_sw)jump->u.target - addr) <= 0x01ffffff && ((sljit_sw)jump->u.target - addr) >= -0x02000000); +				*buf_ptr |= (((sljit_sw)jump->u.target - addr) >> 2) & 0x00ffffff;  			}  		}  		else if (jump->flags & SLJIT_REWRITABLE_JUMP) { @@ -813,6 +828,22 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil  	}  #endif +	put_label = compiler->put_labels; +	while (put_label) { +		addr = put_label->label->addr; +		buf_ptr = (sljit_uw*)put_label->addr; + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +		SLJIT_ASSERT((buf_ptr[0] & 0xffff0000) == 0xe59f0000); +		buf_ptr[((buf_ptr[0] & 0xfff) >> 2) + 2] = addr; +#else +		SLJIT_ASSERT((buf_ptr[-1] & 0xfff00000) == MOVW && (buf_ptr[0] & 0xfff00000) == MOVT); +		buf_ptr[-1] |= ((addr << 4) & 0xf0000) | (addr & 0xfff); +		buf_ptr[0] |= ((addr >> 12) & 0xf0000) | ((addr >> 16) & 0xfff); +#endif +		put_label = put_label->next; +	} +  	SLJIT_ASSERT(code_ptr - code <= (sljit_s32)size);  	compiler->error = SLJIT_ERR_COMPILED; @@ -2639,28 +2670,55 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile  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_s32 reg; +	sljit_s32 dst_r;  	CHECK_ERROR_PTR();  	CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));  	ADJUST_LOCAL_OFFSET(dst, dstw); +	dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG2; + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +	PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), init_value)); +	compiler->patches++; +#else +	PTR_FAIL_IF(emit_imm(compiler, dst_r, init_value)); +#endif +  	const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));  	PTR_FAIL_IF(!const_); +	set_const(const_, compiler); -	reg = SLOW_IS_REG(dst) ? dst : TMP_REG2; +	if (dst & SLJIT_MEM) +		PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1)); +	return const_; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +{ +	struct sljit_put_label *put_label; +	sljit_s32 dst_r; + +	CHECK_ERROR_PTR(); +	CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); +	ADJUST_LOCAL_OFFSET(dst, dstw); + +	dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG2;  #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) -	PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, reg, TMP_PC, 0), init_value)); +	PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), 0));  	compiler->patches++;  #else -	PTR_FAIL_IF(emit_imm(compiler, reg, init_value)); +	PTR_FAIL_IF(emit_imm(compiler, dst_r, 0));  #endif -	set_const(const_, compiler); + +	put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); +	PTR_FAIL_IF(!put_label); +	set_put_label(put_label, compiler, 0);  	if (dst & SLJIT_MEM)  		PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1)); -	return const_; +	return put_label;  }  SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)  |