
.intel_syntax noprefix

.global ContextDirective
.global ContextSaveState
.global ContextInit

.extern sym_Cpu
.extern GetStdAssumeTable
.extern SetStdAssumeTable
.extern GetSegAssumeTable
.extern SetSegAssumeTable
.extern LclAlloc
.extern asmerr
.extern Options
.extern tstricmp


.SECTION .text
	.ALIGN	16

ContextDirective:
	mov	qword ptr [rsp+0x8], rcx
	mov	qword ptr [rsp+0x10], rdx
	push	rsi
	push	rdi
	push	rbx
	push	rbp
	mov	rbp, rsp
	sub	rsp, 72
	imul	ebx, dword ptr [rbp+0x28], 32
	add	rbx, qword ptr [rbp+0x30]
	mov	qword ptr [rbp-0x8], rbx
	mov	eax, dword ptr [rbx+0x4]
	mov	dword ptr [rbp-0xC], eax
	inc	dword ptr [rbp+0x28]
	add	rbx, 32
	jmp	$_033

$_001:	lea	rsi, [contextnames+rip]
	mov	dword ptr [rbp-0x10], 0
	mov	edi, 4294967295
$_002:	cmp	dword ptr [rbp-0x10], 6
	jge	$_004
	mov	ecx, dword ptr [rbp-0x10]
	mov	rdx, qword ptr [rbx+0x10]
	mov	rcx, qword ptr [rsi+rcx*8]
	call	tstricmp@PLT
	test	rax, rax
	jnz	$_003
	mov	edx, dword ptr [rbp-0x10]
	lea	rcx, [typetab+rip]
	mov	edi, dword ptr [rcx+rdx*4]
	jmp	$_004

$_003:	inc	dword ptr [rbp-0x10]
	jmp	$_002

$_004:	cmp	edi, -1
	je	$_034
	test	byte ptr [Options+0x6+rip], 0x10
	jz	$_006
	cmp	edi, 16
	jnz	$_005
	jmp	$_034

	jmp	$_006

$_005:	and	edi, 0xFFFFFFEF
$_006:	mov	dword ptr [rbp-0x14], edi
	cmp	dword ptr [rbp-0xC], 626
	jne	$_021
	mov	qword ptr [rbp-0x20], 0
	mov	rdi, qword ptr [r14+0x310]
$_007:	test	rdi, rdi
	je	$_019
	cmp	dword ptr [rbp-0x14], 0
	je	$_019
	mov	rax, qword ptr [rdi]
	mov	qword ptr [rbp-0x28], rax
	mov	ecx, dword ptr [rdi+0x8]
	test	dword ptr [rbp-0x14], ecx
	jnz	$_008
	mov	qword ptr [rbp-0x20], rdi
	jmp	$_018

$_008:	not	ecx
	and	dword ptr [rbp-0x14], ecx
	cmp	qword ptr [rbp-0x20], 0
	jz	$_009
	mov	rcx, qword ptr [rbp-0x20]
	mov	qword ptr [rcx], rax
	jmp	$_010

$_009:	mov	qword ptr [r14+0x310], rax
$_010:	mov	rax, qword ptr [r14+0x318]
	mov	qword ptr [rdi], rax
	mov	qword ptr [r14+0x318], rdi
	mov	eax, dword ptr [rdi+0x8]
	jmp	$_017

$_011:	lea	rcx, [rdi+0x10]
	call	SetSegAssumeTable@PLT
	lea	rdx, [rdi+0x170]
	lea	rcx, [rdi+0x70]
	call	SetStdAssumeTable@PLT
	jmp	$_018

$_012:	mov	al, byte ptr [rdi+0x10]
	mov	byte ptr [r14+0x8], al
	jmp	$_018

$_013:	mov	al, byte ptr [rdi+0x10]
	mov	byte ptr [r14+0xA], al
	mov	al, byte ptr [rdi+0x11]
	mov	byte ptr [r14+0x1B], al
	jmp	$_018

$_014:	mov	eax, dword ptr [rdi+0x10]
	mov	dword ptr [r14+0x1CC], eax
	movzx	eax, byte ptr [rdi+0x14]
	shl	al, 3
	and	byte ptr [r14], 0xF7
	or	byte ptr [r14], al
	movzx	eax, byte ptr [rdi+0x15]
	shl	al, 4
	and	byte ptr [r14+0x3], 0xEF
	or	byte ptr [r14+0x3], al
	movzx	eax, byte ptr [rdi+0x16]
	shl	al, 4
	and	byte ptr [r14], 0xEF
	or	byte ptr [r14], al
	movzx	eax, byte ptr [rdi+0x17]
	shl	al, 5
	and	byte ptr [r14], 0xDF
	or	byte ptr [r14], al
	jmp	$_018

$_015:	mov	eax, dword ptr [rdi+0x10]
	mov	dword ptr [r14+0xC], eax
	mov	rcx, qword ptr [sym_Cpu+rip]
	test	rcx, rcx
	jz	$_016
	mov	eax, dword ptr [rdi+0x10]
	mov	dword ptr [rcx+0x30], eax
$_016:	mov	al, byte ptr [rdi+0x14]
	mov	byte ptr [r14+0x14], al
	jmp	$_018

$_017:	cmp	eax, 1
	je	$_011
	cmp	eax, 2
	je	$_012
	cmp	eax, 16
	je	$_013
	cmp	eax, 4
	je	$_014
	cmp	eax, 8
	jz	$_015
$_018:	mov	rdi, qword ptr [rbp-0x28]
	jmp	$_007

$_019:	cmp	dword ptr [rbp-0x14], 0
	jz	$_020
	mov	rcx, qword ptr [rbp-0x8]
	mov	rdx, qword ptr [rcx+0x18]
	mov	ecx, 1010
	call	asmerr@PLT
	jmp	$_037

$_020:	jmp	$_032

$_021:	xor	esi, esi
$_022:	cmp	esi, 6
	jnc	$_032
	cmp	dword ptr [rbp-0x14], 0
	je	$_032
	lea	rcx, [typetab+rip]
	mov	eax, dword ptr [rcx+rsi*4]
	test	dword ptr [rbp-0x14], eax
	je	$_031
	not	eax
	and	dword ptr [rbp-0x14], eax
	cmp	qword ptr [r14+0x318], 0
	jz	$_023
	mov	rdi, qword ptr [r14+0x318]
	mov	rax, qword ptr [rdi]
	mov	qword ptr [r14+0x318], rax
	jmp	$_024

$_023:	mov	ecx, 752
	call	LclAlloc@PLT
	mov	rdi, rax
$_024:	mov	rax, qword ptr [r14+0x310]
	mov	qword ptr [rdi], rax
	lea	rcx, [typetab+rip]
	mov	eax, dword ptr [rcx+rsi*4]
	mov	dword ptr [rdi+0x8], eax
	mov	qword ptr [r14+0x310], rdi
	jmp	$_030

$_025:	lea	rcx, [rdi+0x10]
	call	GetSegAssumeTable@PLT
	lea	rdx, [rdi+0x170]
	lea	rcx, [rdi+0x70]
	call	GetStdAssumeTable@PLT
	jmp	$_031

$_026:	mov	al, byte ptr [r14+0x8]
	mov	byte ptr [rdi+0x10], al
	jmp	$_031

$_027:	mov	al, byte ptr [r14+0xA]
	mov	byte ptr [rdi+0x10], al
	mov	al, byte ptr [r14+0x1B]
	mov	byte ptr [rdi+0x11], al
	jmp	$_031

$_028:	mov	eax, dword ptr [r14+0x1CC]
	mov	dword ptr [rdi+0x10], eax
	movzx	eax, byte ptr [r14]
	and	eax, 0x08
	shr	eax, 3
	mov	byte ptr [rdi+0x14], al
	movzx	eax, byte ptr [r14+0x3]
	and	eax, 0x10
	shr	eax, 4
	mov	byte ptr [rdi+0x15], 1
	movzx	eax, byte ptr [r14]
	and	eax, 0x10
	shr	eax, 4
	mov	byte ptr [rdi+0x16], al
	movzx	eax, byte ptr [r14]
	and	eax, 0x20
	shr	eax, 5
	mov	byte ptr [rdi+0x17], al
	jmp	$_031

$_029:	mov	eax, dword ptr [r14+0xC]
	mov	dword ptr [rdi+0x10], eax
	mov	al, byte ptr [r14+0x14]
	mov	byte ptr [rdi+0x14], al
	jmp	$_031

$_030:	cmp	eax, 1
	je	$_025
	cmp	eax, 2
	jz	$_026
	cmp	eax, 16
	jz	$_027
	cmp	eax, 4
	jz	$_028
	cmp	eax, 8
	jz	$_029
$_031:	inc	esi
	jmp	$_022

$_032:	add	rbx, 32
	cmp	byte ptr [rbx], 44
	jnz	$_033
	cmp	byte ptr [rbx+0x20], 0
	jz	$_033
	add	rbx, 32
$_033:	cmp	byte ptr [rbx], 8
	je	$_001
$_034:	cmp	byte ptr [rbx], 0
	jnz	$_035
	cmp	dword ptr [rbp-0x14], -1
	jnz	$_036
$_035:	mov	rdx, qword ptr [rbx+0x18]
	mov	ecx, 2008
	call	asmerr@PLT
	jmp	$_037

$_036:	xor	eax, eax
$_037:	leave
	pop	rbx
	pop	rdi
	pop	rsi
	ret

ContextSaveState:
	push	rsi
	push	rdi
	push	rbx
	sub	rsp, 32
	xor	ecx, ecx
	mov	rdx, qword ptr [r14+0x310]
$_038:	test	rdx, rdx
	jz	$_039
	inc	ecx
	mov	rdx, qword ptr [rdx]
	jmp	$_038

$_039:
	test	ecx, ecx
	jz	$_041
	mov	dword ptr [r14+0x328], ecx
	imul	ecx, ecx, 752
	call	LclAlloc@PLT
	mov	qword ptr [r14+0x320], rax
	mov	rsi, qword ptr [r14+0x310]
	mov	rdi, rax
$_040:	test	rsi, rsi
	jz	$_041
	mov	rdx, rsi
	mov	ecx, 752
	rep movsb
	mov	rsi, rdx
	mov	rsi, qword ptr [rsi]
	jmp	$_040

$_041:
	add	rsp, 32
	pop	rbx
	pop	rdi
	pop	rsi
	ret

$_042:
	push	rsi
	push	rdi
	push	rbx
	sub	rsp, 32
	mov	ebx, dword ptr [r14+0x328]
$_043:	test	ebx, ebx
	jz	$_046
	cmp	qword ptr [r14+0x318], 0
	jz	$_044
	mov	rdi, qword ptr [r14+0x318]
	mov	rax, qword ptr [rdi]
	mov	qword ptr [r14+0x318], rax
	jmp	$_045

$_044:	mov	ecx, 752
	call	LclAlloc@PLT
	mov	rdi, rax
$_045:	lea	rax, [rbx-0x1]
	imul	esi, eax, 752
	add	rsi, qword ptr [r14+0x320]
	mov	ecx, 752
	mov	rdx, rdi
	rep movsb
	mov	rdi, rdx
	mov	rax, qword ptr [r14+0x310]
	mov	qword ptr [rdi], rax
	mov	qword ptr [r14+0x310], rdi
	dec	ebx
	jmp	$_043

$_046:
	add	rsp, 32
	pop	rbx
	pop	rdi
	pop	rsi
	ret

ContextInit:
	mov	qword ptr [rsp+0x8], rcx
	push	rbp
	mov	rbp, rsp
	cmp	dword ptr [rbp+0x10], 0
	jle	$_047
	call	$_042
$_047:	leave
	ret


.SECTION .data
	.ALIGN	16

typetab:
	.byte  0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00
	.byte  0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00
	.byte  0x10, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00

contextnames:
	.quad  DS0000
	.quad  DS0001
	.quad  DS0002
	.quad  DS0003
	.quad  DS0004
	.quad  DS0005


.SECTION .rodata
	.ALIGN	16

DS0000:
	.byte  0x41, 0x53, 0x53, 0x55, 0x4D, 0x45, 0x53, 0x00

DS0001:
	.byte  0x52, 0x41, 0x44, 0x49, 0x58, 0x00

DS0002:
	.byte  0x4C, 0x49, 0x53, 0x54, 0x49, 0x4E, 0x47, 0x00

DS0003:
	.byte  0x43, 0x50, 0x55, 0x00

DS0004:
	.byte  0x41, 0x4C, 0x49, 0x47, 0x4E, 0x4D, 0x45, 0x4E
	.byte  0x54, 0x00

DS0005:
	.byte  0x41, 0x4C, 0x4C, 0x00


.att_syntax prefix
