1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include <malloc.h> 29 #include <rtl/alloc.h> 30 31 #include <com/sun/star/uno/genfunc.hxx> 32 #include "com/sun/star/uno/RuntimeException.hpp" 33 #include <uno/data.h> 34 35 #include <bridges/cpp_uno/shared/bridge.hxx> 36 #include <bridges/cpp_uno/shared/types.hxx> 37 #include <bridges/cpp_uno/shared/unointerfaceproxy.hxx> 38 #include <bridges/cpp_uno/shared/vtables.hxx> 39 40 #include "share.hxx" 41 42 #include <stdio.h> 43 #include <string.h> 44 45 using namespace ::rtl; 46 using namespace ::com::sun::star::uno; 47 48 void MapReturn(sal_uInt32 ret0, sal_uInt32 ret1, typelib_TypeDescription *pReturnTypeDescr, bool bRegisterReturn, sal_uInt32 *pRegisterReturn) 49 { 50 register float fret asm("fr4"); 51 register double dret asm("fr4"); 52 53 switch (pReturnTypeDescr->eTypeClass) 54 { 55 case typelib_TypeClass_HYPER: 56 case typelib_TypeClass_UNSIGNED_HYPER: 57 pRegisterReturn[1] = ret1; 58 case typelib_TypeClass_LONG: 59 case typelib_TypeClass_UNSIGNED_LONG: 60 case typelib_TypeClass_ENUM: 61 case typelib_TypeClass_CHAR: 62 case typelib_TypeClass_SHORT: 63 case typelib_TypeClass_UNSIGNED_SHORT: 64 case typelib_TypeClass_BOOLEAN: 65 case typelib_TypeClass_BYTE: 66 pRegisterReturn[0] = ret0; 67 break; 68 case typelib_TypeClass_FLOAT: 69 *(float*)pRegisterReturn = fret; 70 break; 71 case typelib_TypeClass_DOUBLE: 72 *(double*)pRegisterReturn = dret; 73 break; 74 case typelib_TypeClass_STRUCT: 75 case typelib_TypeClass_EXCEPTION: 76 { 77 if (bRegisterReturn) 78 { 79 pRegisterReturn[0] = ret0; 80 pRegisterReturn[1] = ret1; 81 } 82 break; 83 } 84 default: 85 break; 86 } 87 } 88 89 //Moved callVirtual into this .cxx so that I can do this and get gcc to not 90 //touch r28 without having to learn any more pa-risc assembly than is 91 //strictly necessary 92 register sal_uInt32 r28 __asm__("%r28"); 93 94 void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex, 95 void * pRegisterReturn, typelib_TypeDescription *pReturnTypeDescr, bool bRegisterReturn, 96 sal_uInt32 *pStack, sal_uInt32 nStack, sal_uInt32 *pGPR, double *pFPR) __attribute__((noinline)); 97 98 void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex, 99 void * pRegisterReturn, typelib_TypeDescription *pReturnTypeDescr, bool bRegisterReturn, 100 sal_uInt32 *pStack, sal_uInt32 nStack, sal_uInt32 *pGPR, double *pFPR) 101 { 102 register sal_uInt32* sp __asm__("%r30"); 103 104 sal_uInt32 pMethod = *((sal_uInt32*)pThis); 105 pMethod += 4 * nVtableIndex; 106 pMethod = *((sal_uInt32 *)pMethod); 107 108 #ifdef CMC_DEBUG 109 fprintf(stderr, "this is %p\n", pGPR[0]); 110 for (int i = 0; i < hppa::MAX_GPR_REGS ; ++i) 111 fprintf(stderr, "normal reg %d is %d %x\n", i, pGPR[i], pGPR[i]); 112 113 for (int i = 0; i < hppa::MAX_SSE_REGS ; ++i) 114 fprintf(stderr, "float reg %d is %x\n", i, pFPR[i]); 115 116 for (int i = 0; i < nStack; ++i) 117 fprintf(stderr, "stack bytes are %x\n", pStack[i]); 118 #endif 119 120 //Always reserve 4 slots, and align to 8 bytes 121 sal_uInt32 nStackBytes = ( ( nStack + 4 + 1 ) >> 1 ) * 8; 122 __builtin_alloca(nStackBytes); 123 sal_uInt32 *stack = sp-8; 124 int o = -5; 125 for (sal_uInt32 i = 0; i < nStack; ++i, --o) 126 stack[o] = pStack[i]; 127 128 typedef int (* FunctionCall )( sal_uInt32, sal_uInt32, sal_uInt32, sal_uInt32 ); 129 FunctionCall pFunc = (FunctionCall)pMethod; 130 131 asm volatile("fldd %0, %%fr4" : : "m"(pFPR[0]) : "fr4"); 132 asm volatile("fldd %0, %%fr5" : : "m"(pFPR[1]) : "fr5"); 133 asm volatile("fldd %0, %%fr6" : : "m"(pFPR[2]) : "fr6"); 134 asm volatile("fldd %0, %%fr7" : : "m"(pFPR[3]) : "fr7"); 135 asm volatile("ldw %0, %%r28" : : "m"(pRegisterReturn) : "r28"); 136 (*pFunc)(pGPR[0], pGPR[1], pGPR[2], pGPR[3]); 137 138 register sal_uInt32 r29 __asm__("%r29"); 139 MapReturn(r28, r29, pReturnTypeDescr, bRegisterReturn, (sal_uInt32*)pRegisterReturn); 140 } 141 142 /* vi:set tabstop=4 shiftwidth=4 expandtab: */ 143