run64.S - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       run64.S (3076B)
       ---
            1 //
            2 // Assembly-language support code for vx32-to-x86-64 translation
            3 //
            4 
            5 #include "libvx32/asm.h"
            6 #include "libvx32/os.h"
            7 
            8         .text
            9 
           10         .globl        vx_run_S_start
           11 vx_run_S_start:
           12 
           13 // Set up the segment registers as necessary for the emulation environment.
           14 // Args:
           15 //        rdi: vxemu pointer
           16 //
           17         .code64
           18 
           19         .globl        vxrun_setup
           20 vxrun_setup:
           21 
           22         // Save the host's normal segment registers.
           23         movw        %ss,%dx
           24         movw        %dx,VXEMU_HOST_SS(%rdi)
           25         movw        %ds,VXEMU_HOST_DS(%rdi)
           26         movw        %es,VXEMU_HOST_ES(%rdi)
           27         movw        VSEG,VXEMU_HOST_VS(%rdi)
           28 
           29         // Load the special vxemu segment into VSEG (%fs or %gs).
           30         movw        VXEMU_EMUSEL(%rdi),VSEG
           31 
           32         ret
           33 
           34 
           35 // Start running translated vx32 code until something goes wrong -
           36 // usually, until we hit a piece of code that hasn't been translated yet.
           37 //
           38 // Args:
           39 //        rdi: vxemu pointer
           40 //        rsi: translated code entrypoint at which to start running
           41 //
           42         .p2align 4
           43         .code64
           44         .globl        vxrun
           45 vxrun:
           46 
           47         // Save important host registers in x86-64 registers
           48         // that the 32-bit vx32 environment code can't touch.
           49         movq        %rdi,%r8        // vxemu pointer argument in r8
           50         movq        %rbx,%r9         // callee-saved regs into r9,r10,r11
           51         movq        %rbp,%r10
           52         movq        %rsp,%r11
           53 
           54         // Save the translated code entrypoint into the vxemu struct
           55         // so that we can use it in the far indirect jmp below.
           56         movl        %esi,VXEMU_RUNPTR(%rdi)
           57 
           58         // Load the vx32 environment's data segment into %ds,%es,%ss.
           59         // The processor won't actually use the base and offset
           60         // of this segment until we jump into 32-bit compatibility mode.
           61         movw        VXEMU_DATASEL(%rdi),%ax
           62         movw        %ax,%ds
           63         movw        %ax,%es
           64         movw        %ax,%ss
           65 
           66         // Restore vx32 env's eflags register
           67         movl        VXEMU_EFLAGS(%rdi),%eax
           68         pushq        %rax
           69         popfq
           70 
           71         // Load vx32 env's registers
           72         movl        VXEMU_EAX(%r8),%eax
           73         movl        VXEMU_ECX(%r8),%ecx
           74         movl        VXEMU_EDX(%r8),%edx
           75         // translated code will restore %EBX
           76         movl        VXEMU_ESP(%r8),%esp
           77         movl        VXEMU_EBP(%r8),%ebp
           78         movl        VXEMU_ESI(%r8),%esi
           79         movl        VXEMU_EDI(%r8),%edi
           80 
           81         // Run translated code
           82 #ifndef __FreeBSD__
           83         ljmpl        *VXEMU_RUNPTR(%r8)        // 'ljmpq' doesn't work - gas bug??
           84 #else
           85         ljmpq        *VXEMU_RUNPTR(%r8)
           86 #endif
           87 
           88 
           89 // Return from running translated code to the normal host environment.
           90 // Assumes EAX, EBX, ECX, and EDX have already been saved.
           91 // Assumes return code for vxrun is already in eax.
           92 //
           93         .p2align 4
           94         .code64
           95         .globl        vxrun_return
           96 vxrun_return:
           97 
           98         // Save remaining vx32 registers
           99         movl        %esp,VXEMU_ESP(%r8)
          100         movl        %ebp,VXEMU_EBP(%r8)
          101         movl        %esi,VXEMU_ESI(%r8)
          102         movl        %edi,VXEMU_EDI(%r8)
          103 
          104         // Restore host's callee-saved registers
          105         movq        %r11,%rsp
          106         movq        %r10,%rbp
          107         movq        %r9,%rbx
          108 
          109         // Save vx32 env's eflags register
          110         pushfq
          111         popq        %rdx
          112         movl        %edx,VXEMU_EFLAGS(%r8)
          113 
          114         // Return to caller
          115         cld        // x86-64 ABI says DF must be cleared
          116         ret
          117 
          118 
          119 // Clean up segment registers after running emulated code.
          120 // Args:
          121 //        rdi: vxemu pointer
          122 //
          123         .code64
          124         .globl        vxrun_cleanup
          125 vxrun_cleanup:
          126 
          127         // Restore host's original segment registers.
          128         movw        VXEMU_HOST_SS(%rdi),%ss
          129         movw        VXEMU_HOST_DS(%rdi),%ds
          130         movw        VXEMU_HOST_ES(%rdi),%es
          131         movw        VXEMU_HOST_VS(%rdi),VSEG
          132 
          133         ret
          134         
          135 // Don't put anything here!
          136 // The signal handler knows that vxrun_cleanup
          137 // is at the bottom of this file.
          138