1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #include <malloc.h> 25 #include <rtl/alloc.h> 26 27 #include <com/sun/star/uno/genfunc.hxx> 28 #include "com/sun/star/uno/RuntimeException.hpp" 29 #include <uno/data.h> 30 31 #include <bridges/cpp_uno/shared/bridge.hxx> 32 #include <bridges/cpp_uno/shared/types.hxx> 33 #include <bridges/cpp_uno/shared/unointerfaceproxy.hxx> 34 #include <bridges/cpp_uno/shared/vtables.hxx> 35 36 #include "share.hxx" 37 38 #include <stdio.h> 39 #include <string.h> 40 41 using namespace ::rtl; 42 using namespace ::com::sun::star::uno; 43 44 void MapReturn(sal_uInt32 ret0, sal_uInt32 ret1, typelib_TypeDescription *pReturnTypeDescr, bool bRegisterReturn, sal_uInt32 *pRegisterReturn) 45 { 46 register float fret asm("fr4"); 47 register double dret asm("fr4"); 48 49 switch (pReturnTypeDescr->eTypeClass) 50 { 51 case typelib_TypeClass_HYPER: 52 case typelib_TypeClass_UNSIGNED_HYPER: 53 pRegisterReturn[1] = ret1; 54 case typelib_TypeClass_LONG: 55 case typelib_TypeClass_UNSIGNED_LONG: 56 case typelib_TypeClass_ENUM: 57 case typelib_TypeClass_CHAR: 58 case typelib_TypeClass_SHORT: 59 case typelib_TypeClass_UNSIGNED_SHORT: 60 case typelib_TypeClass_BOOLEAN: 61 case typelib_TypeClass_BYTE: 62 pRegisterReturn[0] = ret0; 63 break; 64 case typelib_TypeClass_FLOAT: 65 *(float*)pRegisterReturn = fret; 66 break; 67 case typelib_TypeClass_DOUBLE: 68 *(double*)pRegisterReturn = dret; 69 break; 70 case typelib_TypeClass_STRUCT: 71 case typelib_TypeClass_EXCEPTION: 72 { 73 if (bRegisterReturn) 74 { 75 pRegisterReturn[0] = ret0; 76 pRegisterReturn[1] = ret1; 77 } 78 break; 79 } 80 default: 81 break; 82 } 83 } 84 85 //Moved callVirtual into this .cxx so that I can do this and get gcc to not 86 //touch r28 without having to learn any more pa-risc assembly than is 87 //strictly necessary 88 register sal_uInt32 r28 __asm__("%r28"); 89 90 void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex, 91 void * pRegisterReturn, typelib_TypeDescription *pReturnTypeDescr, bool bRegisterReturn, 92 sal_uInt32 *pStack, sal_uInt32 nStack, sal_uInt32 *pGPR, double *pFPR) __attribute__((noinline)); 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) 97 { 98 register sal_uInt32* sp __asm__("%r30"); 99 100 sal_uInt32 pMethod = *((sal_uInt32*)pThis); 101 pMethod += 4 * nVtableIndex; 102 pMethod = *((sal_uInt32 *)pMethod); 103 104 #ifdef CMC_DEBUG 105 fprintf(stderr, "this is %p\n", pGPR[0]); 106 for (int i = 0; i < hppa::MAX_GPR_REGS ; ++i) 107 fprintf(stderr, "normal reg %d is %d %x\n", i, pGPR[i], pGPR[i]); 108 109 for (int i = 0; i < hppa::MAX_SSE_REGS ; ++i) 110 fprintf(stderr, "float reg %d is %x\n", i, pFPR[i]); 111 112 for (int i = 0; i < nStack; ++i) 113 fprintf(stderr, "stack bytes are %x\n", pStack[i]); 114 #endif 115 116 //Always reserve 4 slots, and align to 8 bytes 117 sal_uInt32 nStackBytes = ( ( nStack + 4 + 1 ) >> 1 ) * 8; 118 __builtin_alloca(nStackBytes); 119 sal_uInt32 *stack = sp-8; 120 int o = -5; 121 for (sal_uInt32 i = 0; i < nStack; ++i, --o) 122 stack[o] = pStack[i]; 123 124 typedef int (* FunctionCall )( sal_uInt32, sal_uInt32, sal_uInt32, sal_uInt32 ); 125 FunctionCall pFunc = (FunctionCall)pMethod; 126 127 asm volatile("fldd %0, %%fr4" : : "m"(pFPR[0]) : "fr4"); 128 asm volatile("fldd %0, %%fr5" : : "m"(pFPR[1]) : "fr5"); 129 asm volatile("fldd %0, %%fr6" : : "m"(pFPR[2]) : "fr6"); 130 asm volatile("fldd %0, %%fr7" : : "m"(pFPR[3]) : "fr7"); 131 asm volatile("ldw %0, %%r28" : : "m"(pRegisterReturn) : "r28"); 132 (*pFunc)(pGPR[0], pGPR[1], pGPR[2], pGPR[3]); 133 134 register sal_uInt32 r29 __asm__("%r29"); 135 MapReturn(r28, r29, pReturnTypeDescr, bRegisterReturn, (sal_uInt32*)pRegisterReturn); 136 } 137 138 /* vi:set tabstop=4 shiftwidth=4 expandtab: */ 139