// File: /workspace/github_c_makefile_star2_O3/mmcco[P]sljit/sljit_src/sljitNativeX86_64.c
// Function: emit_x86_instruction
static u_char* emit_x86_instruction(struct sljit_compiler *compiler, int size,
	/* The reg or immediate operand. */
	int a, long imma,
	/* The general operand (not immediate). */
	int b, long immb)
{
	u_char *inst;
	u_char *buf_ptr;
	u_char rex = 0;
	int flags = size & ~0xf;
	int inst_size;

	/* The immediate operand must be 32 bit. */
	SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma));
	/* Both cannot be switched on. */
	SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));
	/* Size flags not allowed for typed instructions. */
	SLJIT_ASSERT(!(flags & (EX86_BIN_INS | EX86_SHIFT_INS)) || (flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) == 0);
	/* Both size flags cannot be switched on. */
	SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG));
	/* SSE2 and immediate is not possible. */
	SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));
	SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3)
		&& (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66)
		&& (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66));

	size &= 0xf;
	inst_size = size;

	if (!compiler->mode32 && !(flags & EX86_NO_REXW))
		rex |= REX_W;
	else if (flags & EX86_REX)
		rex |= REX;

	if (flags & (EX86_PREF_F2 | EX86_PREF_F3))
		inst_size++;
	if (flags & EX86_PREF_66)
		inst_size++;

	/* Calculate size of b. */
	inst_size += 1; /* mod r/m byte. */
	if (b & SLJIT_MEM) {
		if (!(b & OFFS_REG_MASK)) {
			if (NOT_HALFWORD(immb)) {
				if (emit_load_imm64(compiler, TMP_REG3, immb))
					return NULL;
				immb = 0;
				if (b & REG_MASK)
					b |= TO_OFFS_REG(TMP_REG3);
				else
					b |= TMP_REG3;
			}
			else if (reg_lmap[b & REG_MASK] == 4)
				b |= TO_OFFS_REG(SLJIT_SP);
		}

		if ((b & REG_MASK) == SLJIT_UNUSED)
			inst_size += 1 + sizeof(int); /* SIB byte required to avoid RIP based addressing. */
		else {
			if (reg_map[b & REG_MASK] >= 8)
				rex |= REX_B;

			if (immb != 0 && (!(b & OFFS_REG_MASK) || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP))) {
				/* Immediate operand. */
				if (immb <= 127 && immb >= -128)
					inst_size += sizeof(s_char);
				else
					inst_size += sizeof(int);
			}
			else if (reg_lmap[b & REG_MASK] == 5)
				inst_size += sizeof(s_char);

			if ((b & OFFS_REG_MASK) != SLJIT_UNUSED) {
				inst_size += 1; /* SIB byte. */
				if (reg_map[OFFS_REG(b)] >= 8)
					rex |= REX_X;
			}
		}
	}
	else if (!(flags & EX86_SSE2_OP2) && reg_map[b] >= 8)
		rex |= REX_B;

	if (a & SLJIT_IMM) {
		if (flags & EX86_BIN_INS) {
			if (imma <= 127 && imma >= -128) {
				inst_size += 1;
				flags |= EX86_BYTE_ARG;
			} else
				inst_size += 4;
		}
		else if (flags & EX86_SHIFT_INS) {
			imma &= compiler->mode32 ? 0x1f : 0x3f;
			if (imma != 1) {
				inst_size ++;
				flags |= EX86_BYTE_ARG;
			}
		} else if (flags & EX86_BYTE_ARG)
			inst_size++;
		else if (flags & EX86_HALF_ARG)
			inst_size += sizeof(short);
		else
			inst_size += sizeof(int);
	}
	else {
		SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
		/* reg_map[SLJIT_PREF_SHIFT_REG] is less than 8. */
		if (!(flags & EX86_SSE2_OP1) && reg_map[a] >= 8)
			rex |= REX_R;
	}

	if (rex)
		inst_size++;

	inst = ensure_buf(compiler, 1 + inst_size);
	if (!inst)
		return NULL;

	/* Encoding the byte. */
	INC_SIZE(inst_size);
	if (flags & EX86_PREF_F2)
		*inst++ = 0xf2;
	if (flags & EX86_PREF_F3)
		*inst++ = 0xf3;
	if (flags & EX86_PREF_66)
		*inst++ = 0x66;
	if (rex)
		*inst++ = rex;
	buf_ptr = inst + size;

	/* Encode mod/rm byte. */
	if (!(flags & EX86_SHIFT_INS)) {
		if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
			*inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81;

		if ((a & SLJIT_IMM) || (a == 0))
			*buf_ptr = 0;
		else if (!(flags & EX86_SSE2_OP1))
			*buf_ptr = reg_lmap[a] << 3;
		else
			*buf_ptr = a << 3;
	}
	else {
		if (a & SLJIT_IMM) {
			if (imma == 1)
				*inst = GROUP_SHIFT_1;
			else
				*inst = GROUP_SHIFT_N;
		} else
			*inst = GROUP_SHIFT_CL;
		*buf_ptr = 0;
	}

	if (!(b & SLJIT_MEM))
		*buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2_OP2)) ? reg_lmap[b] : b);
	else if ((b & REG_MASK) != SLJIT_UNUSED) {
		if ((b & OFFS_REG_MASK) == SLJIT_UNUSED || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP)) {
			if (immb != 0 || reg_lmap[b & REG_MASK] == 5) {
				if (immb <= 127 && immb >= -128)
					*buf_ptr |= 0x40;
				else
					*buf_ptr |= 0x80;
			}

			if ((b & OFFS_REG_MASK) == SLJIT_UNUSED)
				*buf_ptr++ |= reg_lmap[b & REG_MASK];
			else {
				*buf_ptr++ |= 0x04;
				*buf_ptr++ = reg_lmap[b & REG_MASK] | (reg_lmap[OFFS_REG(b)] << 3);
			}

			if (immb != 0 || reg_lmap[b & REG_MASK] == 5) {
				if (immb <= 127 && immb >= -128)
					*buf_ptr++ = immb; /* 8 bit displacement. */
				else {
					*(int*)buf_ptr = immb; /* 32 bit displacement. */
					buf_ptr += sizeof(int);
				}
			}
		}
		else {
			if (reg_lmap[b & REG_MASK] == 5)
				*buf_ptr |= 0x40;
			*buf_ptr++ |= 0x04;
			*buf_ptr++ = reg_lmap[b & REG_MASK] | (reg_lmap[OFFS_REG(b)] << 3) | (immb << 6);
			if (reg_lmap[b & REG_MASK] == 5)
				*buf_ptr++ = 0;
		}
	}
	else {
		*buf_ptr++ |= 0x04;
		*buf_ptr++ = 0x25;
		*(int*)buf_ptr = immb; /* 32 bit displacement. */
		buf_ptr += sizeof(int);
	}

	if (a & SLJIT_IMM) {
		if (flags & EX86_BYTE_ARG)
			*buf_ptr = imma;
		else if (flags & EX86_HALF_ARG)
			*(short*)buf_ptr = imma;
		else if (!(flags & EX86_SHIFT_INS))
			*(int*)buf_ptr = imma;
	}

	return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl %r8d, %r12d
movq %rcx, %r8
movl %esi, %ebp
movq %rdi, %rbx
testb $0x40, %dl
je 0x15dd2
movslq %r8d, %rax
cmpq %r8, %rax
je 0x15dd2
cmpl $0x0, 0x70(%rbx)
je 0x16375
movl %ebp, %ecx
movl %ebp, %eax
notl %eax
andl $0x30, %ecx
je 0x15dff
cmpl $0x30, %ecx
je 0x16383
testl $0x300, %ebp            # imm = 0x300
je 0x15e0a
leaq 0xd514(%rip), %rdi      # 0x23309
movl $0x16b, %esi            # imm = 0x16B
jmp 0x163ab
testl $0x300, %eax            # imm = 0x300
je 0x16391
testb $0x40, %dl
sete %cl
testl $0x6000, %ebp           # imm = 0x6000
sete %sil
orb %cl, %sil
je 0x16359
testl $0x1400, %eax           # imm = 0x1400
je 0x16367
movl %ebp, %eax
andl $0x1800, %eax           # imm = 0x1800
cmpl $0x1800, %eax           # imm = 0x1800
je 0x16367
movl %ebp, %ecx
andl $0xc00, %ecx            # imm = 0xC00
cmpl $0xc00, %ecx            # imm = 0xC00
je 0x16367
movl %ebp, %r10d
andl $0xf, %r10d
movl %ebp, %ecx
andl $0x80, %ecx
movl %ebp, %esi
andb $0x40, %sil
orl 0x70(%rbx), %ecx
movzbl %sil, %ecx
movl $0x48, %r15d
cmovnel %ecx, %r15d
xorl %r14d, %r14d
testl %eax, %eax
setne %r14b
btl $0xa, %ebp
movl %r10d, 0x14(%rsp)
adcl %r10d, %r14d
leal 0x1(%r14), %r13d
testb %r12b, %r12b
movq %rdx, 0x8(%rsp)
js 0x15ec5
btl $0xe, %ebp
jb 0x15fb4
movzbl %r15b, %eax
orb $0x41, %r15b
movl $0x10ef0, %ecx          # imm = 0x10EF0
btq %r12, %rcx
movzbl %r15b, %r15d
cmovael %eax, %r15d
jmp 0x15fb4
testl $0x3f00, %r12d          # imm = 0x3F00
je 0x15f16
movl %r12d, %eax
andl $0x3f, %eax
je 0x15f50
movzbl %r15b, %ecx
orb $0x41, %r15b
movl $0x10ef0, %esi          # imm = 0x10EF0
btq %rax, %rsi
movzbl %r15b, %r15d
cmovael %ecx, %r15d
movl %r12d, %eax
andl $0x3f00, %eax           # imm = 0x3F00
testq %r9, %r9
je 0x15f59
cmpl $0xd00, %eax            # imm = 0xD00
je 0x15f07
testl %eax, %eax
jne 0x15f59
movsbq %r9b, %rcx
cmpq %r9, %rcx
jne 0x15f8c
addl $0x2, %r14d
jmp 0x15f90
movslq %r9d, %rax
cmpq %r9, %rax
je 0x15f6c
movq %r8, (%rsp)
movq %rbx, %rdi
movl $0x10, %esi
movq %r9, %rdx
callq 0x1683c
testl %eax, %eax
jne 0x1609f
testb $0x3f, %r12b
je 0x16344
orl $0x1000, %r12d          # imm = 0x1000
jmp 0x16348
addl $0x6, %r14d
movl %r14d, %r13d
jmp 0x15fb4
movl %r12d, %ecx
andl $0x3e, %ecx
addl $0x2, %r14d
cmpl $0x8, %ecx
cmovel %r14d, %r13d
jmp 0x15f93
movl %r12d, %eax
andl $0x3f, %eax
cmpl $0xd, %eax
je 0x15f80
cmpl $0x7, %eax
jne 0x15ece
orl $0xd00, %r12d           # imm = 0xD00
jmp 0x15ece
addl $0x5, %r14d
movl %r14d, %r13d
testl %eax, %eax
je 0x15fb4
incl %r13d
movl %r12d, %eax
shrl $0x8, %eax
movzbl %r15b, %ecx
orb $0x42, %r15b
btq %rax, %rsi
movzbl %r15b, %r15d
cmovael %ecx, %r15d
movq %r9, (%rsp)
testb $0x40, %dl
je 0x15fe5
testb $0x10, %bpl
jne 0x1601e
testb $0x20, %bpl
jne 0x1603e
btl $0x8, %ebp
jb 0x1605d
btl $0x9, %ebp
jae 0x16035
movq %r8, %r14
addl $0x2, %r13d
jmp 0x16071
testb $0x20, %bpl
sete %al
cmpl $0x3, %edx
sete %cl
orb %al, %cl
je 0x1639f
movq %r8, %r14
btl $0xd, %ebp
jb 0x16071
movzbl %r15b, %eax
orb $0x44, %r15b
movl $0x10ef0, %ecx          # imm = 0x10EF0
btq %rdx, %rcx
movzbl %r15b, %r15d
cmovael %eax, %r15d
jmp 0x16071
movsbq %r8b, %rax
cmpq %r8, %rax
jne 0x16035
movq %r8, %r14
incl %r13d
orl $0x100, %ebp            # imm = 0x100
jmp 0x16071
movq %r8, %r14
addl $0x4, %r13d
jmp 0x16071
xorl %eax, %eax
cmpl $0x0, 0x70(%rbx)
sete %al
shll $0x5, %eax
orl $0x1f, %eax
andl %r8d, %eax
cmpl $0x1, %eax
jne 0x16065
movl $0x1, %r14d
jmp 0x16071
movq %r8, %r14
incl %r13d
jmp 0x16071
incl %r13d
orl $0x100, %ebp            # imm = 0x100
movq %rax, %r14
cmpb $0x1, %r15b
sbbl $-0x1, %r13d
leal 0x1(%r13), %esi
movq %rbx, %rdi
callq 0x15218
testq %rax, %rax
je 0x1609f
movb %r13b, (%rax)
movl %r13d, %ecx
addq %rcx, 0x60(%rbx)
btl $0xb, %ebp
jb 0x160a6
incq %rax
jmp 0x160ae
xorl %eax, %eax
jmp 0x16335
movb $-0xe, 0x1(%rax)
addq $0x2, %rax
movq %r14, %r11
movq 0x8(%rsp), %r9
btl $0xc, %ebp
jae 0x160c2
movb $-0xd, (%rax)
incq %rax
btl $0xa, %ebp
jae 0x160ce
movb $0x66, (%rax)
incq %rax
testb %r15b, %r15b
je 0x160d9
movb %r15b, (%rax)
incq %rax
movl 0x14(%rsp), %edx
movl %ebp, %ecx
andl $0x20, %ecx
jne 0x16111
testb $0x40, %r9b
sete %sil
testb $0x10, %bpl
sete %dil
orb %sil, %dil
jne 0x161cc
movl %ebp, %esi
shrl $0x8, %esi
andl $0x1, %esi
addb %sil, %sil
orb $-0x7f, %sil
movb %sil, (%rax)
jmp 0x16134
cmpq $0x1, %r11
sete %sil
shlb $0x4, %sil
orb $-0x3f, %sil
movzbl %sil, %esi
testb $0x40, %r9b
movl $0xd3, %edi
cmovnel %esi, %edi
movb %dil, (%rax)
xorl %esi, %esi
addq %rax, %rdx
testb %r12b, %r12b
js 0x16164
btl $0xe, %ebp
jb 0x16152
movslq %r12d, %rdi
leaq 0xd0a2(%rip), %r8       # 0x231f0
movb (%rdi,%r8), %r12b
addb $-0x40, %r12b
orb %sil, %r12b
movb %r12b, (%rdx)
incq %rdx
jmp 0x1621c
movl %r12d, %edi
andl $0x3f, %edi
je 0x16206
movq %r9, %rbx
movl %r12d, %r9d
andl $0x3f00, %r9d           # imm = 0x3F00
cmpl $0xd00, %r9d            # imm = 0xD00
je 0x1618f
testl %r9d, %r9d
jne 0x16224
movq (%rsp), %r14
testq %r14, %r14
setne %r10b
movl %r12d, %r8d
andl $0x3e, %r8d
cmpl $0x8, %r8d
sete %r8b
orb %r10b, %r8b
cmpb $0x1, %r8b
jne 0x1629a
movsbq %r14b, %r10
cmpq %r14, %r10
jne 0x16296
orb $0x40, %sil
jmp 0x1629a
movl %r9d, %esi
andl $0x40, %esi
shrl $0x6, %esi
testl %r9d, %r9d
sete %dil
orb %sil, %dil
jne 0x16134
btl $0xd, %ebp
jb 0x16289
movslq %r9d, %rsi
leaq 0xcff7(%rip), %rdi      # 0x231f0
movb (%rsi,%rdi), %sil
shlb $0x3, %sil
jmp 0x16136
orb $0x4, %sil
movb %sil, (%rdx)
movb $0x25, 0x1(%rdx)
movq (%rsp), %rsi
movl %esi, 0x2(%rdx)
addq $0x6, %rdx
movq %rdx, %rdi
jmp 0x1630b
leaq 0xcfc5(%rip), %r9       # 0x231f0
movl %r12d, %r8d
andl $0x3e, %r8d
movzbl %sil, %r10d
orb $0x40, %sil
cmpl $0x8, %r8d
movzbl %sil, %esi
cmovnel %r10d, %esi
orb $0x4, %sil
movzbl (%rdi,%r9), %edi
shrl $0x8, %r12d
andl $0x3f, %r12d
movzbl (%r12,%r9), %r9d
shll $0x3, %r9d
movq (%rsp), %r10
shll $0x6, %r10d
orl %edi, %r10d
orl %r9d, %r10d
movb %sil, (%rdx)
movb %r10b, 0x1(%rdx)
cmpl $0x8, %r8d
jne 0x16301
movb $0x0, 0x2(%rdx)
addq $0x3, %rdx
jmp 0x16305
leal (,%r9,8), %esi
jmp 0x16136
orb $-0x80, %sil
testl %r9d, %r9d
je 0x162c7
leaq 0xcf4a(%rip), %r9       # 0x231f0
shrl $0x8, %r12d
andl $0x3f, %r12d
movb (%r12,%r9), %r10b
shlb $0x3, %r10b
orb (%rdi,%r9), %r10b
leaq 0x2(%rdx), %rdi
movb %r10b, 0x1(%rdx)
movb $0x4, %r9b
jmp 0x162d6
leaq 0xcf22(%rip), %r9       # 0x231f0
movb (%rdi,%r9), %r9b
leaq 0x1(%rdx), %rdi
orb %r9b, %sil
movb %sil, (%rdx)
testb %r8b, %r8b
je 0x16308
movq (%rsp), %rsi
movsbq %sil, %rdx
cmpq %rsi, %rdx
movq %rbx, %r9
jne 0x162f9
movb %sil, (%rdi)
incq %rdi
jmp 0x1630b
movl %esi, (%rdi)
addq $0x4, %rdi
jmp 0x1630b
addq $0x2, %rdx
movq %rdx, %rdi
movq %rbx, %r9
testb $0x40, %r9b
je 0x1632f
btl $0x8, %ebp
jb 0x16326
btl $0x9, %ebp
jb 0x1632b
testl %ecx, %ecx
jne 0x1632f
movl %r11d, (%rdi)
jmp 0x1632f
movb %r11b, (%rdi)
jmp 0x1632f
movw %r11w, (%rdi)
shrl $0x5, %ecx
addq %rcx, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
orl $0x10, %r12d
xorl %r9d, %r9d
movq (%rsp), %r8
movq 0x8(%rsp), %rdx
jmp 0x15ece
leaq 0xcfa9(%rip), %rdi      # 0x23309
movl $0x16f, %esi            # imm = 0x16F
jmp 0x163ab
leaq 0xcf9b(%rip), %rdi      # 0x23309
movl $0x172, %esi            # imm = 0x172
jmp 0x163ab
leaq 0xcf8d(%rip), %rdi      # 0x23309
movl $0x167, %esi            # imm = 0x167
jmp 0x163ab
leaq 0xcf7f(%rip), %rdi      # 0x23309
movl $0x169, %esi            # imm = 0x169
jmp 0x163ab
leaq 0xcf71(%rip), %rdi      # 0x23309
movl $0x16d, %esi            # imm = 0x16D
jmp 0x163ab
leaq 0xcf63(%rip), %rdi      # 0x23309
movl $0x1c2, %esi            # imm = 0x1C2
xorl %eax, %eax
callq 0x2080
callq 0x2040