138 lines · 3.0 KB · Assembly
RawDownload
//// Assembly-language support code for vx32-to-x86-64 translation// #include "libvx32/asm.h"#include "libvx32/os.h" 	.text 	.globl	vx_run_S_startvx_run_S_start: // Set up the segment registers as necessary for the emulation environment.// Args://	rdi: vxemu pointer//	.code64 	.globl	vxrun_setupvxrun_setup: 	// Save the host's normal segment registers.	movw	%ss,%dx	movw	%dx,VXEMU_HOST_SS(%rdi)	movw	%ds,VXEMU_HOST_DS(%rdi)	movw	%es,VXEMU_HOST_ES(%rdi)	movw	VSEG,VXEMU_HOST_VS(%rdi) 	// Load the special vxemu segment into VSEG (%fs or %gs).	movw	VXEMU_EMUSEL(%rdi),VSEG 	ret  // Start running translated vx32 code until something goes wrong -// usually, until we hit a piece of code that hasn't been translated yet.//// Args://	rdi: vxemu pointer//	rsi: translated code entrypoint at which to start running//	.p2align 4	.code64	.globl	vxrunvxrun: 	// Save important host registers in x86-64 registers	// that the 32-bit vx32 environment code can't touch.	movq	%rdi,%r8	// vxemu pointer argument in r8	movq	%rbx,%r9 	// callee-saved regs into r9,r10,r11	movq	%rbp,%r10	movq	%rsp,%r11 	// Save the translated code entrypoint into the vxemu struct	// so that we can use it in the far indirect jmp below.	movl	%esi,VXEMU_RUNPTR(%rdi) 	// Load the vx32 environment's data segment into %ds,%es,%ss.	// The processor won't actually use the base and offset	// of this segment until we jump into 32-bit compatibility mode.	movw	VXEMU_DATASEL(%rdi),%ax	movw	%ax,%ds	movw	%ax,%es	movw	%ax,%ss 	// Restore vx32 env's eflags register	movl	VXEMU_EFLAGS(%rdi),%eax	pushq	%rax	popfq 	// Load vx32 env's registers	movl	VXEMU_EAX(%r8),%eax	movl	VXEMU_ECX(%r8),%ecx	movl	VXEMU_EDX(%r8),%edx	// translated code will restore %EBX	movl	VXEMU_ESP(%r8),%esp	movl	VXEMU_EBP(%r8),%ebp	movl	VXEMU_ESI(%r8),%esi	movl	VXEMU_EDI(%r8),%edi 	// Run translated code#ifndef __FreeBSD__	ljmpl	*VXEMU_RUNPTR(%r8)	// 'ljmpq' doesn't work - gas bug??#else	ljmpq	*VXEMU_RUNPTR(%r8)#endif  // Return from running translated code to the normal host environment.// Assumes EAX, EBX, ECX, and EDX have already been saved.// Assumes return code for vxrun is already in eax.//	.p2align 4	.code64	.globl	vxrun_returnvxrun_return: 	// Save remaining vx32 registers	movl	%esp,VXEMU_ESP(%r8)	movl	%ebp,VXEMU_EBP(%r8)	movl	%esi,VXEMU_ESI(%r8)	movl	%edi,VXEMU_EDI(%r8) 	// Restore host's callee-saved registers	movq	%r11,%rsp	movq	%r10,%rbp	movq	%r9,%rbx 	// Save vx32 env's eflags register	pushfq	popq	%rdx	movl	%edx,VXEMU_EFLAGS(%r8) 	// Return to caller	cld	// x86-64 ABI says DF must be cleared	ret  // Clean up segment registers after running emulated code.// Args://	rdi: vxemu pointer//	.code64	.globl	vxrun_cleanupvxrun_cleanup: 	// Restore host's original segment registers.	movw	VXEMU_HOST_SS(%rdi),%ss	movw	VXEMU_HOST_DS(%rdi),%ds	movw	VXEMU_HOST_ES(%rdi),%es	movw	VXEMU_HOST_VS(%rdi),VSEG 	ret	// Don't put anything here!// The signal handler knows that vxrun_cleanup// is at the bottom of this file.