/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
/* * Based on http://gcc.gnu.org/PR41443 * References to __SOFTFP__ are incorrect for EABI; the __SOFTFP__ code * should be used for *soft-float ABI* whether or not VFP is enabled, * and __SOFTFP__ does specifically mean soft-float not soft-float ABI. * * Changing the conditionals to __SOFTFP__ || __ARM_EABI__ then * -mfloat-abi=softfp should work. -mfloat-abi=hard won't; that would * need both a new macro to identify the hard-VFP ABI.
*/ #if !defined(__ARM_EABI__) && !defined(__SOFTFP__) #errorNot Implemented
/* some possibly handy code to detect that we have VFP registers
*/
//A Composite Type not larger than 4 bytes is returned in r0 bool bRet = pTypeDescr->nSize > 4 || is_complex_struct(pTypeDescr);
#ifdef __ARM_PCS_VFP // In the VFP ABI, structs with only float/double values that fit in // 16 bytes are returned in registers if( pTypeDescr->nSize <= 16 && is_float_only_struct(pTypeDescr))
bRet = false; #endif
#ifdef __ARM_PCS_VFP // Since single and double arguments share the same register bank the filling of the // registers is not always linear. Single values go to the first available single register, // while doubles need to have an 8 byte alignment, so only go into double registers starting // at every other single register. For ex a float, double, float sequence will fill registers // s0, d1, and s1, actually corresponding to the linear order s0,s1, d1. // // These use the single/double register array and counters and ignore the pGPR argument // nSR and nDR are the number of single and double precision registers that are no longer // available #define INSERT_FLOAT( pSV, nr, pGPR, pDS ) \ if (nSR % 2 == 0) {\
nSR = 2*nDR; \
}\ if ( nSR < arm::MAX_FPR_REGS*2 ) {\
pSPR[nSR++] = *static_cast<floatconst *>( pSV ); \ if ((nSR % 2 == 1) && (nSR > 2*nDR)) {\
nDR++; \
}\
}\ else \
{\
*pDS++ = *static_cast<floatconst *>( pSV );\
} #define INSERT_DOUBLE( pSV, nr, pGPR, pDS, pStart ) \ if ( nDR < arm::MAX_FPR_REGS ) { \
pFPR[nDR++] = *static_cast<doubleconst *>( pSV ); \
}\ else\
{\ if ( (pDS - pStart) % 2) \
{ \
++pDS; \
} \
*reinterpret_cast<double *>(pDS) = *static_cast<doubleconst *>( pSV );\
pDS += 2;\
} #else #define INSERT_FLOAT( pSV, nr, pFPR, pDS ) \
INSERT_INT32( pSV, nr, pGPR, pDS )
if (pReturnTypeDescr)
{ bool bSimpleReturn = !arm::return_in_hidden_param( pReturnTypeRef );
if (bSimpleReturn)
pCppReturn = pUnoReturn; // direct way for simple types else
{ // complex return via ptr
pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
? __builtin_alloca( pReturnTypeDescr->nSize )
: pUnoReturn); // direct way
switch (pParamTypeDescr->eTypeClass)
{ case typelib_TypeClass_HYPER: case typelib_TypeClass_UNSIGNED_HYPER: #if OSL_DEBUG_LEVEL > 2
fprintf(stderr, "hyper is %p\n", pCppArgs[nPos]); #endif
INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack, pStackStart ); break; case typelib_TypeClass_LONG: case typelib_TypeClass_UNSIGNED_LONG: case typelib_TypeClass_ENUM: #if OSL_DEBUG_LEVEL > 2
fprintf(stderr, "long is %p\n", pCppArgs[nPos]); #endif
INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack ); break; case typelib_TypeClass_SHORT: case typelib_TypeClass_CHAR: case typelib_TypeClass_UNSIGNED_SHORT:
INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack ); break; case typelib_TypeClass_BOOLEAN: case typelib_TypeClass_BYTE:
INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack ); break; case typelib_TypeClass_FLOAT:
INSERT_FLOAT( pCppArgs[nPos], nGPR, pGPR, pStack ); break; case typelib_TypeClass_DOUBLE:
INSERT_DOUBLE( pCppArgs[nPos], nGPR, pGPR, pStack, pStackStart ); break; default: break;
} // no longer needed
TYPELIB_DANGER_RELEASE( pParamTypeDescr );
} else// ptr to complex value | ref
{ if (! rParam.bIn) // is pure out
{ // cpp out is constructed mem, uno out is not!
uno_constructData(
pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
pParamTypeDescr );
pTempIndices[nTempIndices] = nPos; // default constructed for cpp call // will be released at reconversion
ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
} // is in/inout elseif (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
{
uno_copyAndConvertData(
pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
pTempIndices[nTempIndices] = nPos; // has to be reconverted // will be released at reconversion
ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
} else// direct way
{
pCppArgs[nPos] = pUnoArgs[nPos]; // no longer needed
TYPELIB_DANGER_RELEASE( pParamTypeDescr );
}
INSERT_INT32( &(pCppArgs[nPos]), nGPR, pGPR, pStack );
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.