// File: /workspace/github_c_makefile_star2_O0/markdryan[P]subtilis/frontend/string_type.c
// Function: prv_mid_str_cc
static subtilis_exp_t *prv_mid_str_cc(subtilis_parser_t *p, subtilis_exp_t *str,
				      subtilis_exp_t *start,
				      subtilis_exp_t *len,
				      subtilis_error_t *err)
{
	int32_t len_const;
	int32_t start_const;
	int32_t const_str_len =
	    (int32_t)subtilis_buffer_get_size(&str->exp.str) - 1;
	subtilis_exp_t *ret = NULL;

	start_const = start->exp.ir_op.integer - 1;
	if (start_const == -1)
		start_const = 0;
	if (start_const < 0 || start_const >= const_str_len) {
		subtilis_buffer_reset(&str->exp.str);
		if (err->type != SUBTILIS_ERROR_OK)
			goto cleanup;
		subtilis_buffer_zero_terminate(&str->exp.str, err);
		if (err->type == SUBTILIS_ERROR_OK) {
			ret = str;
			str = NULL;
		}
		goto cleanup;
	}

	if (start_const > 0) {
		subtilis_buffer_delete(&str->exp.str, 0, start_const, err);
		if (err->type != SUBTILIS_ERROR_OK)
			goto cleanup;
		const_str_len -= start_const;
		start_const = 0;
	}

	if (!len || (len->type.type == SUBTILIS_TYPE_CONST_INTEGER)) {
		if (!len) {
			len_const = const_str_len;
		} else {
			len_const = len->exp.ir_op.integer;
			if (len_const > const_str_len)
				len_const = const_str_len;
		}

		if (len_const < const_str_len)
			subtilis_buffer_delete(&str->exp.str, len_const,
					       const_str_len - len_const, err);
		if (err->type == SUBTILIS_ERROR_OK) {
			ret = str;
			str = NULL;
		}
		goto cleanup;
	}

	/* len has been specified and is non_const */

	ret = prv_mid_str_ccv(p, str, len->exp.ir_op.reg, err);

cleanup:

	subtilis_exp_delete(str);
	subtilis_exp_delete(start);
	subtilis_exp_delete(len);

	return ret;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq -0x10(%rbp), %rdi
addq $0x148, %rdi            # imm = 0x148
callq 0x16270
subl $0x1, %eax
movl %eax, -0x34(%rbp)
movq $0x0, -0x40(%rbp)
movq -0x18(%rbp), %rax
movl 0x148(%rax), %eax
subl $0x1, %eax
movl %eax, -0x30(%rbp)
cmpl $-0x1, -0x30(%rbp)
jne 0x69027
movl $0x0, -0x30(%rbp)
cmpl $0x0, -0x30(%rbp)
jl 0x69035
movl -0x30(%rbp), %eax
cmpl -0x34(%rbp), %eax
jl 0x69085
movq -0x10(%rbp), %rdi
addq $0x148, %rdi            # imm = 0x148
callq 0x16690
movq -0x28(%rbp), %rax
cmpl $0x0, (%rax)
je 0x69053
jmp 0x69167
movq -0x10(%rbp), %rdi
addq $0x148, %rdi            # imm = 0x148
movq -0x28(%rbp), %rsi
callq 0x16560
movq -0x28(%rbp), %rax
cmpl $0x0, (%rax)
jne 0x69080
movq -0x10(%rbp), %rax
movq %rax, -0x40(%rbp)
movq $0x0, -0x10(%rbp)
jmp 0x69167
cmpl $0x0, -0x30(%rbp)
jle 0x690c7
movq -0x10(%rbp), %rdi
addq $0x148, %rdi            # imm = 0x148
movslq -0x30(%rbp), %rdx
movq -0x28(%rbp), %rcx
xorl %eax, %eax
movl %eax, %esi
callq 0x16450
movq -0x28(%rbp), %rax
cmpl $0x0, (%rax)
je 0x690b5
jmp 0x69167
movl -0x30(%rbp), %ecx
movl -0x34(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x34(%rbp)
movl $0x0, -0x30(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x690d7
movq -0x20(%rbp), %rax
cmpl $0x1, (%rax)
jne 0x69147
cmpq $0x0, -0x20(%rbp)
jne 0x690e6
movl -0x34(%rbp), %eax
movl %eax, -0x2c(%rbp)
jmp 0x69103
movq -0x20(%rbp), %rax
movl 0x148(%rax), %eax
movl %eax, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x34(%rbp), %eax
jle 0x69101
movl -0x34(%rbp), %eax
movl %eax, -0x2c(%rbp)
jmp 0x69103
movl -0x2c(%rbp), %eax
cmpl -0x34(%rbp), %eax
jge 0x6912c
movq -0x10(%rbp), %rdi
addq $0x148, %rdi            # imm = 0x148
movslq -0x2c(%rbp), %rsi
movl -0x34(%rbp), %eax
subl -0x2c(%rbp), %eax
movslq %eax, %rdx
movq -0x28(%rbp), %rcx
callq 0x16450
movq -0x28(%rbp), %rax
cmpl $0x0, (%rax)
jne 0x69145
movq -0x10(%rbp), %rax
movq %rax, -0x40(%rbp)
movq $0x0, -0x10(%rbp)
jmp 0x69167
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rax
movq 0x148(%rax), %rdx
movq -0x28(%rbp), %rcx
callq 0x6b940
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rdi
callq 0x36ee0
movq -0x18(%rbp), %rdi
callq 0x36ee0
movq -0x20(%rbp), %rdi
callq 0x36ee0
movq -0x40(%rbp), %rax
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax)