.ad 8
.bm 8
.fm 4
.bt $Copyright (c) 1998-2004 SAP AG$$Page %$
.tm 12
.hm 6
.hs 3
.tt 1 $NME$Project Distributed Database System$vos38a$
.tt 2 $$$
.tt 3 $FerdiF$ N A M E $2000-10-02$
***********************************************************
.nf

.nf


    ========== licence begin  GPL
    Copyright (c) 1998-2004 SAP AG

    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.
    ========== licence end

.fo


.fo
.nf
.sp
Module  :
=========
.sp
Purpose :
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define  :

.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :

.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :

.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  :
.sp
.cp 3
Created :
.sp
.cp 3
Version :
.sp
.cp 3
Release :      Date : 2000-10-02
.br
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:

.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:

.CM *-END-* description ---------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:

.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
.CM -lll-
Code    :


&if  $MACH = I386 AND $OS = WIN32 AND $BIT64 = 1

//****************************************************************************
//*                                                                          *
//*  I N T E L ( W I N 6 4)                                                  *
//*                                                                          *
//****************************************************************************

//
//  EXTERN_C LONG __stdcall sql38aVdcomCall( IUnknown *lpIUnknown,
//                                           PROC  pProc,
//                                           void* pBufAddr,
//                                           long  BufLen,
//                                           void* pfBufAddr,
//                                           long  fBufLen,
//                                           long  StackSize );
//


// Parameters:
// 
// r32 = lpIUnknown
// r33 = pProc
// r34 = pBufAddr
// r35 = BufLen
// r36 = pfBufAddr,
// r37 = fBufLen
// r38 = StackSize  :	is not needed here


.section .text
.proc sql38aVdcomCall#
.align 32
.global sql38aVdcomCall#

sql38aVdcomCall::

// Allocate the register stack for 7 input parameters, 4 local 
// variables, 8 output registers, and 0 rotating registers.  Note 
// that we may or may not use all 8 output registers.

	alloc	r39 = ar.pfs, 7, 4, 8, 0 ;;

// save preserved registers
	mov	r40 = rp ;; // save return pointer 
	mov	r41 = gp ;; // save global data pointer
	mov	r42 = sp ;; // save stack pointer

// Setup the target function information
	mov	r8  = r33 ;; // get pProc (pointer to function descriptor)
	ld8	r3 = [r8], 8 ;; // load the function's address into B6
	mov	b6 = r3 ;;
	ld8	gp = [r8] ;; // load the function's gp into GP.

// Copy the first 8 floating point parameters into F8 through F15
	mov	r9 = r36 ;; // pfBufAddr
	mov	r10 = r37 ;; // fBufLen

	//mov	r3 = 0x07 ;; // round up fBufLen to a multiple of 8 bytes, note 
	//add	r10 = r10, r3 ;;  // that this should not be necessary.
	//andcm	r10 = r10, r3 ;;

	cmp.eq	p1, p2 = r10, r0 ;;
(p2)	ld8	r8 = [r9], 8 ;;
(p2)	setf.d	f8 = r8 ;;
(p2)	add	r10 = -0x08, r10 ;;

	cmp.eq	p1, p2 = r10, r0 ;;
(p2)	ld8	r8 = [r9], 8 ;;
(p2)	setf.d	f9 = r8 ;;
(p2)	add	r10 = -0x08, r10 ;;

	cmp.eq	p1, p2 = r10, r0 ;;
(p2)	ld8	r8 = [r9], 8 ;;
(p2)	setf.d	f10 = r8 ;;
(p2)	add	r10 = -0x08, r10 ;;

	cmp.eq	p1, p2 = r10, r0 ;;
(p2)	ld8	r8 = [r9], 8 ;;
(p2)	setf.d	f11 = r8 ;;
(p2)	add	r10 = -0x08, r10 ;;

	cmp.eq	p1, p2 = r10, r0 ;;
(p2)	ld8	r8 = [r9], 8 ;;
(p2)	setf.d	f12 = r8 ;;
(p2)	add	r10 = -0x08, r10 ;;

	cmp.eq	p1, p2 = r10, r0 ;;
(p2)	ld8	r8 = [r9], 8 ;;
(p2)	setf.d	f13 = r8 ;;
(p2)	add	r10 = -0x08, r10 ;;

	cmp.eq	p1, p2 = r10, r0 ;;
(p2)	ld8	r8 = [r9], 8 ;;
(p2)	setf.d	f14 = r8 ;;
(p2)	add	r10 = -0x08, r10 ;;

	cmp.eq	p1, p2 = r10, r0 ;;
(p2)	ld8	r8 = [r9], 8 ;;
(p2)	setf.d	f15 = r8 ;;


// Copy the first 8 general parameters into registers R43 through R50.
// Note that R43 through R50 are the output registers for sql38aVdcomCall.
// However, they will be the input registers R32 through R39 for the 
// target function.

	mov	r9  = r34 ;; // pBufAddr
	mov	r10 = r35 ;; // BufLen

	//mov	r3 = 0x07 ;; // round up BufLen to a multiple of 8 bytes, note 
	//add	r10 = r10, r3 ;; // that this should not be necessary
	//andcm	r10 = r10, r3 ;;

	mov	r43 = r32 ;; // lpIUnknown ("this" ptr)

	cmp.eq	p1, p2 = r10, r0 ;;
(p2)	ld8	r44 = [r9], 8 ;;
(p2)	add	r10 = -0x08, r10 ;;

	cmp.eq	p1, p2 = r10, r0 ;;
(p2)	ld8	r45 = [r9], 8 ;;
(p2)	add	r10 = -0x08, r10 ;;

	cmp.eq	p1, p2 = r10, r0 ;;
(p2)	ld8	r46 = [r9], 8 ;;
(p2)	add	r10 = -0x08, r10 ;;

	cmp.eq	p1, p2 = r10, r0 ;;
(p2)	ld8	r47 = [r9], 8 ;;
(p2)	add	r10 = -0x08, r10 ;;

	cmp.eq	p1, p2 = r10, r0 ;;
(p2)	ld8	r48 = [r9], 8 ;;
(p2)	add	r10 = -0x08, r10 ;;

	cmp.eq	p1, p2 = r10, r0 ;;
(p2)	ld8	r49 = [r9], 8 ;;
(p2)	add	r10 = -0x08, r10 ;;

	cmp.eq	p1, p2 = r10, r0 ;;
(p2)	ld8	r50 = [r9], 8 ;;
(p2)	add	r10 = -0x08, r10 ;;

	cmp.eq	p1, p2 = r10, r0 ;;
(p1)	br.cond.spnt.few e38a_call


// Copy all parameters beyond the first 8 parameters and onto 
// the memory stack.

	sub	r3 = sp, r10 ;; // Make space for the rest of the parameters on 
	mov	r2 = 0x0F    ;; // stack.  This space must be a multiple of 16 
	andcm	r3 = r3, r2  ;; // bytes in size.
	mov	sp = r3 ;;

e38a_copy:
	ld8	r2 = [r9], 8 ;;
	st8	[r3] = r2, 8 ;;
	add	r10 = -0x08, r10 ;;
	cmp.eq	p1, p2 = r10, r0 ;;
(p2)	br.cond.sptk.few e38a_copy ;;


e38a_call:
	mov 	r2 = 0x10
	sub	sp = sp, r2 ;; 	// Make space for the parameter scratch area on 
		                // the stack.

	br.call.sptk rp = b6 ;; // Call the target function.

// Restore the saved registers and the previous function state for the register stack.
	mov	rp = r40 ;;
	mov	gp = r41 ;;
	mov	sp = r42 ;;
	mov.i	ar.pfs = r39 ;;

	mov	ret0 = r0 ;; // return value is always zero

	br.ret.sptk rp ;; // return

.endp	sql38aVdcomCall#


&else if  $MACH = I386 AND $OS = WIN32


;****************************************************************************
;*                                                                          *
;*  I N T E L ( W I N 3 2 )                                                 *
;*                                                                          *
;****************************************************************************

 TITLE   vos38a.asm
 PAGE    ,80
.386
.MODEL   SMALL,C
 SYSTEM_LINKAGE=1

 ASSUME  CS: CODE32

 CODE32 SEGMENT DWORD USE32 PUBLIC 'CODE'

 ;
 ;  EXTERN_C LONG __stdcall sql38aVdcomCall( IUnknown *lpIUnknown,
 ;                                           PROC  pProc,
 ;                                           void* pDebugStackBufAddr,
 ;                                           long  DebugStackSize,
 ;                                           long  RealStackSize);
 ;
 PUBLIC  sql38aVdcomCall@20
    sql38aVdcomCall@20 PROC NEAR

       push    ebp                     ; enter-sequence
       mov     ebp , esp

       pushfd                          ; save registers
       push    esi
       push    edi
       push    edx
       push    ecx
       push    ebx
       mov     ebx,esp                 ; save param beginn
       sub esp, dword ptr[ebp + 018h]  ; reserve real stack size
       mov ecx, dword ptr[ebp + 014h]  ; load debug stack size (16B elements)
       add esp, 4                      ; this pointer is pushed extra, we don't need reserved space
       shr ecx, 4                      ; convert into count of elements
       mov esi, [ebp + 010h]           ; load source address of debug stack
       mov edi, esp                    ; load destination for parameters in stack

       cld
       test ecx, ecx
       jz short l1
l0:
       movs dword ptr es:[edi], dword ptr[esi]
       add esi, 12                     ; point to the next debug stack frame
       loop l0
l1:

       mov edx, dword ptr[ebp + 008h]
       push edx                        ; this Pointer
       mov edx, dword ptr[ebp + 00Ch]
       call edx
       mov  esp,ebx                    ; in case call-stack was wrong
	                                   ; don't crash ...
    sql38aVdcomCall_ret:
       mov     eax, 0                  ; NO ERROR
       pop     ebx                     ; restore registers
       pop     ecx
       pop     edx
       pop     edi
       pop     esi
       popfd
       pop     ebp                     ; imcomplete leave-sequence
       ret     20                      ; remove 20 bytes parameter
       sql38aVdcomCall@20   ENDP
     CODE32 ENDS
    END
&endif

.CM *-END-* code ----------------------------------------
.SP 2
***********************************************************
.PA


