// File: /workspace/github_c_makefile_star2_O0/MikeGray-APH[P]LibLouisAPH/source/translate.c
// Function: translate_start
int translate_start(unichar *dots,
                    const int dots_len,
                    const unichar *chars,
                    const int chars_len,
                    const struct table *const*tables,
                    const int table_cnt,
                    const struct conversion *conversion,
                    const enum rule_direction direction,
                    int *chars_to_dots_map,
                    int *dots_to_chars_map,
                    int *cursor)
{
	struct translate translate_auto;
	int input_len, i, status;

	/*   nothing to translate   */
	if(chars_len == 0)
		return 0;

	/*   get true chars_len   */
	for(input_len = 0; input_len < chars_len; input_len++)
	if(!chars[input_len])
		break;

	memset(&translate_auto, 0, sizeof(struct translate));

	translate_auto.tables = tables;
	translate_auto.table_cnt = table_cnt;
	translate_auto.dots = dots;
	translate_auto.dots_len = dots_len;
	translate_auto.chars = chars;
	translate_auto.chars_len = chars_len;
	translate_auto.chars_to_dots_map = chars_to_dots_map;
	translate_auto.dots_to_chars_map = dots_to_chars_map;

	if(chars_to_dots_map == NULL || dots_to_chars_map == NULL)
		translate_auto.maps_use = 0;
	else
		translate_auto.maps_use = 1;

	/*   initialize input/output   */

	translate_auto.input = MALLOC((input_len + 1) * sizeof(unichar));
	if(!translate_auto.input)
	{
		LOG_ALLOCATE_FAIL
		return -1;
	}
	utf16_copy(translate_auto.input, chars, (input_len + 1));
	translate_auto.input_len = input_len;
	translate_auto.input_crs = 0;

	translate_auto.input_mask = MALLOC(input_len + 1);
	if(!translate_auto.input_mask)
	{
		LOG_ALLOCATE_FAIL
		return -1;
	}
	memset(translate_auto.input_mask, 0, input_len + 1);

	translate_auto.output_max = input_len;
	translate_auto.output_inc = ((translate_auto.output_max * 3) / 2) - translate_auto.output_max;
	if(translate_auto.output_inc < 0x100)
		translate_auto.output_inc = 0x100;
	translate_auto.output_max += translate_auto.output_inc - input_len;
	translate_auto.output = MALLOC(translate_auto.output_max * sizeof(unichar));
	if(!translate_auto.output)
	{
		LOG_ALLOCATE_FAIL
		FREE(translate_auto.input);
		return -1;
	}
	DB_MEMSET(translate_auto.output, 0, translate_auto.output_max * sizeof(unichar));

	translate_auto.output_mask = MALLOC(translate_auto.output_max);
	if(!translate_auto.output_mask)
	{
		LOG_ALLOCATE_FAIL
		return -1;
	}
	memset(translate_auto.output_mask, 0, translate_auto.output_max);

	if(cursor)
		translate_auto.cursor_pos = *cursor;

#ifndef CHECK_FOR_CHANGE
	utf16_copy(translate_auto.output, chars, (input_len + 1));
	translate_auto.output_len = input_len;
#endif

	if(translate_auto.maps_use)
	{
		translate_auto.input_map = MALLOC((input_len + 1) * sizeof(int));
		if(!translate_auto.input_map)
		{
			LOG_ALLOCATE_FAIL
			FREE(translate_auto.input);
			FREE(translate_auto.output);
			return -1;
		}
		for(i = 0; i <= input_len; i++)
			translate_auto.input_map[i] = i;

		translate_auto.input_to_output_map = MALLOC((input_len + 1) * sizeof(int));
		if(!translate_auto.input_to_output_map)
		{
			LOG_ALLOCATE_FAIL
			FREE(translate_auto.input);
			FREE(translate_auto.output);
			FREE(translate_auto.input_map);
			return -1;
		}

		/*   prevent input block mappings   */
		for(i = 0; i <= input_len; i++)
			translate_auto.input_to_output_map[i] = i;

		translate_auto.output_to_input_map = MALLOC(translate_auto.output_max * sizeof(int));
		if(!translate_auto.output_to_input_map)
		{
			LOG_ALLOCATE_FAIL
			FREE(translate_auto.input);
			FREE(translate_auto.output);
			FREE(translate_auto.input_map);
			FREE(translate_auto.input_to_output_map);
			return -1;
		}
		DB_MEMSET(translate_auto.output_to_input_map, 0, translate_auto.output_max * sizeof(int));

#ifndef CHECK_FOR_CHANGE
		ASSERT(translate_auto.output_max >= input_len + 1)
		memcpy(translate_auto.output_to_input_map, translate_auto.input_map, (input_len + 1) * sizeof(int));
#endif
	}

	/*   start processing   */
	if(direction == FORWARD)
	{
		/*   only process from last table in tables   */
		switch(translate_auto.tables[translate_auto.table_cnt - 1]->process)
		{
		case PROCESS_GENERIC:     status = translate_generic_forward(&translate_auto);  break;
		case PROCESS_NEMETH_UEB:  status = translate_nemeth_forward(&translate_auto);   break;
		default:                  status = 0;
		}
		if(status < 1)
		{
			if(status == 0)
				log_message(LOG_WARNING, "no processing done");
			translate_auto.output_len = status;
			goto free_and_return;
		}

		if(conversion)
			convert_output(&translate_auto, conversion);
	}
	else
	{
		ASSERT(direction == BACKWARD)

		if(conversion)
			convert_input(&translate_auto, conversion);

		/*   only process from last table in tables   */
		switch(translate_auto.tables[translate_auto.table_cnt - 1]->process)
		{
		case PROCESS_GENERIC:  status = translate_generic_backward(&translate_auto);  break;
		default:               status = 0;
		}
		if(status < 1)
		{
			if(status == 0)
				log_message(LOG_WARNING, "no processing done");
			translate_auto.output_len = status;
			goto free_and_return;
		}
	}

	/*   copy input/output   */

	if(translate_auto.output_len > translate_auto.dots_len)
	{
		//log_message(LOG_WARNING, "output exceeded dots_len:  %d > %d", translate_auto.output_len, translate_auto.dots_len);
		memcpy(dots, translate_auto.output, dots_len * sizeof(unichar));
		if(dots_to_chars_map)
			memcpy(dots_to_chars_map, translate_auto.output_to_input_map, dots_len * sizeof(int));
	}
	else
	{
		memcpy(dots, translate_auto.output, translate_auto.output_len * sizeof(unichar));
		if(dots_to_chars_map)
			memcpy(dots_to_chars_map, translate_auto.output_to_input_map, translate_auto.output_len * sizeof(int));
	}
	if(chars_to_dots_map)
		memcpy(chars_to_dots_map, translate_auto.input_to_output_map, input_len * sizeof(int));
	if(cursor)
		*cursor = translate_auto.cursor_pos;

	/*   finalize input/output   */

	free_and_return:

	FREE(translate_auto.input);
	FREE(translate_auto.output);
	FREE(translate_auto.input_mask);
	FREE(translate_auto.output_mask);
	if(translate_auto.maps_use)
	{
		FREE(translate_auto.input_map);
		FREE(translate_auto.input_to_output_map);
		FREE(translate_auto.output_to_input_map);
	}

	return translate_auto.output_len;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movq 0x30(%rbp), %rax
movq 0x28(%rbp), %rax
movq 0x20(%rbp), %rax
movl 0x18(%rbp), %eax
movq 0x10(%rbp), %rax
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movl %ecx, -0x24(%rbp)
movq %r8, -0x30(%rbp)
movl %r9d, -0x34(%rbp)
cmpl $0x0, -0x24(%rbp)
jne 0xb5b6
movl $0x0, -0x4(%rbp)
jmp 0xbc65
movl $0x0, -0xd4(%rbp)
movl -0xd4(%rbp), %eax
cmpl -0x24(%rbp), %eax
jge 0xb5f2
movq -0x20(%rbp), %rax
movslq -0xd4(%rbp), %rcx
cmpw $0x0, (%rax,%rcx,2)
jne 0xb5df
jmp 0xb5f2
jmp 0xb5e1
movl -0xd4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xd4(%rbp)
jmp 0xb5c0
leaq -0xd0(%rbp), %rdi
xorl %esi, %esi
movl $0x98, %edx
callq 0x1100
movq -0x30(%rbp), %rax
movq %rax, -0xd0(%rbp)
movl -0x34(%rbp), %eax
movl %eax, -0xc4(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xb8(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0xac(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0xc0(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0xb0(%rbp)
movq 0x20(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq 0x28(%rbp), %rax
movq %rax, -0xa0(%rbp)
cmpq $0x0, 0x20(%rbp)
je 0xb665
cmpq $0x0, 0x28(%rbp)
jne 0xb66e
movl $0x0, -0x40(%rbp)
jmp 0xb675
movl $0x1, -0x40(%rbp)
movl -0xd4(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rdi
shlq %rdi
callq 0x1160
movq %rax, -0x98(%rbp)
cmpq $0x0, -0x98(%rbp)
jne 0xb6c5
movl $0x7, %edi
leaq 0x12bd2(%rip), %rsi     # 0x1e278
leaq 0x133a7(%rip), %rdx     # 0x1ea54
movl $0x1aa, %ecx            # imm = 0x1AA
movb $0x0, %al
callq 0xf610
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xbc65
movq -0x98(%rbp), %rdi
movq -0x20(%rbp), %rsi
movl -0xd4(%rbp), %edx
addl $0x1, %edx
callq 0xbc80
movl -0xd4(%rbp), %eax
movl %eax, -0x8c(%rbp)
movl $0x0, -0x90(%rbp)
movl -0xd4(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rdi
callq 0x1160
movq %rax, -0x78(%rbp)
cmpq $0x0, -0x78(%rbp)
jne 0xb73b
movl $0x7, %edi
leaq 0x12b5c(%rip), %rsi     # 0x1e278
leaq 0x13331(%rip), %rdx     # 0x1ea54
movl $0x1b4, %ecx            # imm = 0x1B4
movb $0x0, %al
callq 0xf610
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xbc65
movq -0x78(%rbp), %rdi
movl -0xd4(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rdx
xorl %esi, %esi
callq 0x1100
movl -0xd4(%rbp), %eax
movl %eax, -0x64(%rbp)
imull $0x3, -0x64(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
subl -0x64(%rbp), %eax
movl %eax, -0x60(%rbp)
cmpl $0x100, -0x60(%rbp)     # imm = 0x100
jge 0xb77d
movl $0x100, -0x60(%rbp)     # imm = 0x100
movl -0x60(%rbp), %eax
subl -0xd4(%rbp), %eax
addl -0x64(%rbp), %eax
movl %eax, -0x64(%rbp)
movslq -0x64(%rbp), %rdi
shlq %rdi
callq 0x1160
movq %rax, -0x70(%rbp)
cmpq $0x0, -0x70(%rbp)
jne 0xb7da
movl $0x7, %edi
leaq 0x12ac9(%rip), %rsi     # 0x1e278
leaq 0x1329e(%rip), %rdx     # 0x1ea54
movl $0x1c1, %ecx            # imm = 0x1C1
movb $0x0, %al
callq 0xf610
movq -0x98(%rbp), %rdi
callq 0x1040
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xbc65
movq -0x70(%rbp), %rdi
movslq -0x64(%rbp), %rdx
shlq %rdx
xorl %esi, %esi
callq 0x1100
movslq -0x64(%rbp), %rdi
callq 0x1160
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x50(%rbp)
jne 0xb82b
movl $0x7, %edi
leaq 0x12a6c(%rip), %rsi     # 0x1e278
leaq 0x13241(%rip), %rdx     # 0x1ea54
movl $0x1ca, %ecx            # imm = 0x1CA
movb $0x0, %al
callq 0xf610
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xbc65
movq -0x50(%rbp), %rdi
movslq -0x64(%rbp), %rdx
xorl %esi, %esi
callq 0x1100
cmpq $0x0, 0x30(%rbp)
je 0xb84a
movq 0x30(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x48(%rbp)
cmpl $0x0, -0x40(%rbp)
je 0xba20
movl -0xd4(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rdi
shlq $0x2, %rdi
callq 0x1160
movq %rax, -0x80(%rbp)
cmpq $0x0, -0x80(%rbp)
jne 0xb8b4
movl $0x7, %edi
leaq 0x129f8(%rip), %rsi     # 0x1e278
leaq 0x131cd(%rip), %rdx     # 0x1ea54
movl $0x1dc, %ecx            # imm = 0x1DC
movb $0x0, %al
callq 0xf610
movq -0x98(%rbp), %rdi
callq 0x1040
movq -0x70(%rbp), %rdi
callq 0x1040
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xbc65
movl $0x0, -0xd8(%rbp)
movl -0xd8(%rbp), %eax
cmpl -0xd4(%rbp), %eax
jg 0xb8f1
movl -0xd8(%rbp), %edx
movq -0x80(%rbp), %rax
movslq -0xd8(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movl -0xd8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xd8(%rbp)
jmp 0xb8be
movl -0xd4(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rdi
shlq $0x2, %rdi
callq 0x1160
movq %rax, -0x88(%rbp)
cmpq $0x0, -0x88(%rbp)
jne 0xb960
movl $0x7, %edi
leaq 0x12955(%rip), %rsi     # 0x1e278
leaq 0x1312a(%rip), %rdx     # 0x1ea54
movl $0x1e7, %ecx            # imm = 0x1E7
movb $0x0, %al
callq 0xf610
movq -0x98(%rbp), %rdi
callq 0x1040
movq -0x70(%rbp), %rdi
callq 0x1040
movq -0x80(%rbp), %rdi
callq 0x1040
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xbc65
movl $0x0, -0xd8(%rbp)
movl -0xd8(%rbp), %eax
cmpl -0xd4(%rbp), %eax
jg 0xb9a0
movl -0xd8(%rbp), %edx
movq -0x88(%rbp), %rax
movslq -0xd8(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movl -0xd8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xd8(%rbp)
jmp 0xb96a
movslq -0x64(%rbp), %rdi
shlq $0x2, %rdi
callq 0x1160
movq %rax, -0x58(%rbp)
cmpq $0x0, -0x58(%rbp)
jne 0xba0d
movl $0x7, %edi
leaq 0x128b4(%rip), %rsi     # 0x1e278
leaq 0x13089(%rip), %rdx     # 0x1ea54
movl $0x1f5, %ecx            # imm = 0x1F5
movb $0x0, %al
callq 0xf610
movq -0x98(%rbp), %rdi
callq 0x1040
movq -0x70(%rbp), %rdi
callq 0x1040
movq -0x80(%rbp), %rdi
callq 0x1040
movq -0x88(%rbp), %rdi
callq 0x1040
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xbc65
movq -0x58(%rbp), %rdi
movslq -0x64(%rbp), %rdx
shlq $0x2, %rdx
xorl %esi, %esi
callq 0x1100
cmpl $0x1, 0x18(%rbp)
jne 0xbadd
movq -0xd0(%rbp), %rax
movl -0xc4(%rbp), %ecx
decl %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movl 0x18(%rax), %eax
movl %eax, -0xe0(%rbp)
testl %eax, %eax
je 0xba5c
jmp 0xba4f
movl -0xe0(%rbp), %eax
subl $0x1, %eax
je 0xba70
jmp 0xba84
leaq -0xd0(%rbp), %rdi
callq 0x113d0
movl %eax, -0xdc(%rbp)
jmp 0xba8e
leaq -0xd0(%rbp), %rdi
callq 0x18380
movl %eax, -0xdc(%rbp)
jmp 0xba8e
movl $0x0, -0xdc(%rbp)
cmpl $0x1, -0xdc(%rbp)
jge 0xbac1
cmpl $0x0, -0xdc(%rbp)
jne 0xbab3
movl $0x5, %edi
leaq 0x12fbb(%rip), %rsi     # 0x1ea67
movb $0x0, %al
callq 0xf610
movl -0xdc(%rbp), %eax
movl %eax, -0x68(%rbp)
jmp 0xbc14
cmpq $0x0, 0x10(%rbp)
je 0xbad8
movq 0x10(%rbp), %rsi
leaq -0xd0(%rbp), %rdi
callq 0xbce0
jmp 0xbb71
cmpl $-0x1, 0x18(%rbp)
je 0xbae8
callq 0x1050
cmpq $0x0, 0x10(%rbp)
je 0xbaff
movq 0x10(%rbp), %rsi
leaq -0xd0(%rbp), %rdi
callq 0xbdc0
movq -0xd0(%rbp), %rax
movl -0xc4(%rbp), %ecx
decl %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movl 0x18(%rax), %eax
testl %eax, %eax
jne 0xbb32
jmp 0xbb1e
leaq -0xd0(%rbp), %rdi
callq 0x16440
movl %eax, -0xdc(%rbp)
jmp 0xbb3c
movl $0x0, -0xdc(%rbp)
cmpl $0x1, -0xdc(%rbp)
jge 0xbb6f
cmpl $0x0, -0xdc(%rbp)
jne 0xbb61
movl $0x5, %edi
leaq 0x12f0d(%rip), %rsi     # 0x1ea67
movb $0x0, %al
callq 0xf610
movl -0xdc(%rbp), %eax
movl %eax, -0x68(%rbp)
jmp 0xbc14
jmp 0xbb71
movl -0x68(%rbp), %eax
cmpl -0xac(%rbp), %eax
jle 0xbbae
movq -0x10(%rbp), %rdi
movq -0x70(%rbp), %rsi
movslq -0x14(%rbp), %rdx
shlq %rdx
callq 0x1150
cmpq $0x0, 0x28(%rbp)
je 0xbbac
movq 0x28(%rbp), %rdi
movq -0x58(%rbp), %rsi
movslq -0x14(%rbp), %rdx
shlq $0x2, %rdx
callq 0x1150
jmp 0xbbe0
movq -0x10(%rbp), %rdi
movq -0x70(%rbp), %rsi
movslq -0x68(%rbp), %rdx
shlq %rdx
callq 0x1150
cmpq $0x0, 0x28(%rbp)
je 0xbbde
movq 0x28(%rbp), %rdi
movq -0x58(%rbp), %rsi
movslq -0x68(%rbp), %rdx
shlq $0x2, %rdx
callq 0x1150
jmp 0xbbe0
cmpq $0x0, 0x20(%rbp)
je 0xbc02
movq 0x20(%rbp), %rdi
movq -0x88(%rbp), %rsi
movslq -0xd4(%rbp), %rdx
shlq $0x2, %rdx
callq 0x1150
cmpq $0x0, 0x30(%rbp)
je 0xbc12
movl -0x48(%rbp), %ecx
movq 0x30(%rbp), %rax
movl %ecx, (%rax)
jmp 0xbc14
movq -0x98(%rbp), %rdi
callq 0x1040
movq -0x70(%rbp), %rdi
callq 0x1040
movq -0x78(%rbp), %rdi
callq 0x1040
movq -0x50(%rbp), %rdi
callq 0x1040
cmpl $0x0, -0x40(%rbp)
je 0xbc5f
movq -0x80(%rbp), %rdi
callq 0x1040
movq -0x88(%rbp), %rdi
callq 0x1040
movq -0x58(%rbp), %rdi
callq 0x1040
movl -0x68(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xe0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)