#
#  vtxsys.S
#
#  Copyright (C) 2002 Intel Corporation
#  Author/Maintainer - George W Artz <george.w.artz@intel.com>
#                      Tony Luck (tony.luck@intel.com)
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
        .file "vtxsys64.s"
        

        .text
        .align 16
        .global vt_sys_mmap_stub
vt_sys_mmap_stub:
        alloc   r2=ar.pfs,8,4,8,0
        ;;
        movl    r8=original_sys_mmap
        mov     loc0=r2
        mov     loc1=rp
        ;;
        ld8     r8=[r8]
        mov     loc3=gp

        mov     out0=in0
        mov     out1=in1
        mov     out2=in2
        mov     out3=in3
        mov     out4=in4
        mov     out5=in5
        mov     out6=in6
        mov     out7=in7
        ;;
        mov     b6=r8

        br.call.sptk.many rp=b6

        mov     loc2=r8

        movl    r9=@fptr(vt_sys_mmap)

        mov     out0=r8
        mov     out1=in1        // length
        mov     out2=in2        // prot
        mov     out3=in4        // fd
        ;;
        add     r8=8,r9
        ;;
        ld8     gp=[r8]
        br.call.sptk.many rp=vt_sys_mmap

        mov     rp=loc1
        mov     r8=loc2
        mov     gp=loc3
        mov     ar.pfs=loc0
        ;;
        br.ret.sptk.many rp



        .text
        .align 16
        .global vt_sys_mmap2_stub
vt_sys_mmap2_stub:
        alloc   r2=ar.pfs,8,4,8,0
        ;;
        movl    r8=original_sys_mmap2
        mov     loc0=r2
        mov     loc1=rp
        ;;
        ld8     r8=[r8]
        mov     loc3=gp

        mov     out0=in0
        mov     out1=in1
        mov     out2=in2
        mov     out3=in3
        mov     out4=in4
        mov     out5=in5
        mov     out6=in6
        mov     out7=in7
        ;;
        mov     b6=r8

        br.call.sptk.many rp=b6

        mov     loc2=r8

        movl    r9=@fptr(vt_sys_mmap2)

        mov     out0=r8
        mov     out1=in1        // length
        mov     out2=in2        // prot
        mov     out3=in4        // fd
        ;;
        add     r8=8,r9
        ;;
        ld8     gp=[r8]
        br.call.sptk.many rp=vt_sys_mmap2

        mov     rp=loc1
        mov     r8=loc2
        mov     gp=loc3
        mov     ar.pfs=loc0
        ;;
        br.ret.sptk.many rp


        .text
        .align 16
        .global vt_sys_clone2_stub
vt_sys_clone2_stub:
        alloc   r2=ar.pfs,3,2,3,0
        ;;
        mov     loc0=gp
        mov     loc1=r2
        mov     out0=gp
        mov     out1=rp
        mov     out2=r2

        movl    r9=@fptr(vt_sys_clone2_before)
        ;;
        add     r8=8,r9
        ;;
        ld8     gp=[r8]
        br.call.sptk.many rp=vt_sys_clone2_before

        movl    r8=original_sys_clone2
        ;;
        ld8     r8=[r8]
        ;;
        mov     b6=r8
        movl    r9=vt_sys_clone2_stub_ret
        mov     gp=loc0
        ;;
        mov     rp=r9
        mov     ar.pfs=loc1 /* Does this undo alloc? */
        br.sptk.many b6

vt_sys_clone2_stub_ret:
        alloc   r2=ar.pfs,0,1,1,0
        mov     out0=r8
        mov     loc0=r8

        movl    r9=@fptr(vt_sys_clone2_after)
        ;;
        add     r8=8,r9
        ;;
        ld8     gp=[r8]
        br.call.sptk.many rp=vt_sys_clone2_after

        mov     gp=r8
        mov     rp=r9
        mov     r8=loc0
        mov     ar.pfs=r10
        ;;
        br.ret.sptk.many rp


        .text
        .align 16
        .global vt_sys_clone_stub
vt_sys_clone_stub:
        alloc   r2=ar.pfs,2,5,2,0
        ;;
        mov     loc3=gp
        mov     loc0=r2
        mov     loc1=rp

        movl    r9=@fptr(vt_sys_clone_before)
        ;;
        add     r8=8,r9
        ;;
        ld8     gp=[r8]
        br.call.sptk.many rp=vt_sys_clone_before
        mov     loc4=r8
        ;;
        movl    r8=original_sys_clone
        ;;
        ld8     r8=[r8]

        mov     out0=in0
        mov     out1=in1
        ;;
        mov     b6=r8

        mov     gp=loc3
        br.call.sptk.many rp=b6

        mov     loc2=r8

        movl    r9=@fptr(vt_sys_clone_after)

        mov     out0=r8
        ;;
        add     r8=8,r9
        ;;
        ld8     gp=[r8]
        mov     out1=loc4
        br.call.sptk.many rp=vt_sys_clone_after

        mov     rp=loc1
        mov     r8=loc2
        mov     gp=loc3
        mov     ar.pfs=loc0
        ;;
        br.ret.sptk.many rp

        .text
        .align 16
        .global vt_sys_create_module_stub
vt_sys_create_module_stub:
        alloc   r2=ar.pfs,8,4,8,0
        ;;
        movl    r8=original_sys_create_module
        mov     loc0=r2
        mov     loc1=rp
        ;;
        ld8     r8=[r8]
        mov     loc3=gp

        mov     out0=in0
        mov     out1=in1
        mov     out2=in2
        mov     out3=in3
        mov     out4=in4
        mov     out5=in5
        mov     out6=in6
        mov     out7=in7
        ;;
        mov     b6=r8

        br.call.sptk.many rp=b6

        mov     loc2=r8

        movl    r9=@fptr(vt_sys_create_module)

        mov     out0=r8
        ;;
        add     r8=8,r9
        ;;
        ld8     gp=[r8]
        br.call.sptk.many rp=vt_sys_create_module

        mov     rp=loc1
        mov     r8=loc2
        mov     gp=loc3
        mov     ar.pfs=loc0
        ;;
        br.ret.sptk.many rp

        .text
        .align 16
        .global vt_sys_execve_stub
vt_sys_execve_stub:
        alloc   r2=ar.pfs,3,2,3,0
        ;;
        movl    r8=original_sys_execve
        movl    r9=vt_save_execve_ret
        mov     loc0=r2
        mov     loc1=rp
        ;;
        ld8     r8=[r8]
        st8     [r9]=loc1

        mov     out0=in0
        mov     out1=in1
        mov     out2=in2
        ;;
        mov     b6=r8

        /* call original exec function in kernel */
        br.call.sptk.many rp=b6

        cmp4.ge p6,p7=r8,r0
        ;;

        /*
         * if exec failed, we still have a frame, so we can restore
         * registers and return.
         */
(p7)    mov     rp=loc1
(p7)    mov     ar.pfs=loc0
        ;;
(p7)    br.ret.sptk.many rp

        /*
         * exec succeeded, we are on a new register window frame
         * set gp for module and call our stub
         */
        alloc   r4=ar.pfs,0,3,0,0
        ;;
        mov     loc1=r8
        mov     loc2=gp

        mov     loc0=r4
        movl    r9=@fptr(vt_sys_execve)
        ;;
        add     r8=8,r9
        ;;
        ld8     gp=[r8]
        br.call.sptk.many rp=vt_sys_execve

        movl    r9=vt_save_execve_ret
        ;;
        ld8     r4=[r9]
        mov     gp=loc2
        mov     r8=loc1
        mov     ar.pfs=loc0
        ;;
        mov     rp=r4
        ;;
        mov     r4=r0
        

        br.ret.sptk.many rp
