diff options
author | Tor Lillqvist <tml@iki.fi> | 2012-03-04 18:57:28 +0200 |
---|---|---|
committer | Tor Lillqvist <tml@iki.fi> | 2012-03-05 02:05:21 +0200 |
commit | 5ab3db2c2e2c622d19211f2c8c0714080af3bfe6 (patch) | |
tree | 577989a2a6c18f3de8f05f01fab6bce06f230ee0 /bridges | |
parent | cfde18d34978c2665f3ddb2473359c83c82337f6 (diff) |
Make the iOS device (ARM) stuff at least link, surely does not work yet
Diffstat (limited to 'bridges')
-rw-r--r-- | bridges/source/cpp_uno/gcc3_ios_arm/helper.S | 6 | ||||
-rw-r--r-- | bridges/source/cpp_uno/gcc3_ios_arm/uno2cpp.cxx | 117 |
2 files changed, 120 insertions, 3 deletions
diff --git a/bridges/source/cpp_uno/gcc3_ios_arm/helper.S b/bridges/source/cpp_uno/gcc3_ios_arm/helper.S index 0bd718b9b660..5a620b617b39 100644 --- a/bridges/source/cpp_uno/gcc3_ios_arm/helper.S +++ b/bridges/source/cpp_uno/gcc3_ios_arm/helper.S @@ -35,16 +35,16 @@ .file "helper.S" .text .align 4 - .globl privateSnippetExecutor + .globl _privateSnippetExecutor -privateSnippetExecutor: +_privateSnippetExecutor: stmfd sp!, {r0-r3} @ follow other parameters on stack mov r0, ip @ r0 points to functionoffset/vtable mov r1, sp @ r1 points to this and params @ (see cpp2uno.cxx:codeSnippet()) stmfd sp!, {r4,lr} @ save return address @ (r4 pushed to preserve stack alignment) - bl cpp_vtable_call + bl _cpp_vtable_call add sp, sp, #4 @ no need to restore r4 (we didn't touch it) ldr pc, [sp], #20 @ return, discarding function arguments diff --git a/bridges/source/cpp_uno/gcc3_ios_arm/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_ios_arm/uno2cpp.cxx index 5966a5e95158..dc58f33a016b 100644 --- a/bridges/source/cpp_uno/gcc3_ios_arm/uno2cpp.cxx +++ b/bridges/source/cpp_uno/gcc3_ios_arm/uno2cpp.cxx @@ -43,6 +43,123 @@ using namespace ::rtl; using namespace ::com::sun::star::uno; +#ifdef __arm + +namespace arm +{ + bool is_complex_struct(const typelib_TypeDescription * type) + { + const typelib_CompoundTypeDescription * p + = reinterpret_cast< const typelib_CompoundTypeDescription * >(type); + for (sal_Int32 i = 0; i < p->nMembers; ++i) + { + if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT || + p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION) + { + typelib_TypeDescription * t = 0; + TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]); + bool b = is_complex_struct(t); + TYPELIB_DANGER_RELEASE(t); + if (b) { + return true; + } + } + else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass)) + return true; + } + if (p->pBaseTypeDescription != 0) + return is_complex_struct(&p->pBaseTypeDescription->aBase); + return false; + } + +#ifdef __ARM_PCS_VFP + bool is_float_only_struct(const typelib_TypeDescription * type) + { + const typelib_CompoundTypeDescription * p + = reinterpret_cast< const typelib_CompoundTypeDescription * >(type); + for (sal_Int32 i = 0; i < p->nMembers; ++i) + { + if (p->ppTypeRefs[i]->eTypeClass != typelib_TypeClass_FLOAT && + p->ppTypeRefs[i]->eTypeClass != typelib_TypeClass_DOUBLE) + return false; + } + return true; + } +#endif + bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef ) + { + if (bridges::cpp_uno::shared::isSimpleType(pTypeRef)) + return false; + else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION) + { + typelib_TypeDescription * pTypeDescr = 0; + TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef ); + + //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 + + TYPELIB_DANGER_RELEASE( pTypeDescr ); + return bRet; + } + return true; + } +} + +#endif + +void MapReturn(sal_uInt32 r0, sal_uInt32 r1, typelib_TypeDescriptionReference * pReturnType, sal_uInt32* pRegisterReturn) +{ + switch( pReturnType->eTypeClass ) + { + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + pRegisterReturn[1] = r1; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + case typelib_TypeClass_ENUM: + case typelib_TypeClass_CHAR: + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + case typelib_TypeClass_BOOLEAN: + case typelib_TypeClass_BYTE: + pRegisterReturn[0] = r0; + break; + case typelib_TypeClass_FLOAT: +#if !defined(__ARM_PCS_VFP) && (defined(__ARM_EABI__) || defined(__SOFTFP__)) + pRegisterReturn[0] = r0; +#else + register float fret asm("s0"); + *(float*)pRegisterReturn = fret; +#endif + break; + case typelib_TypeClass_DOUBLE: +#if !defined(__ARM_PCS_VFP) && (defined(__ARM_EABI__) || defined(__SOFTFP__)) + pRegisterReturn[1] = r1; + pRegisterReturn[0] = r0; +#else + register double dret asm("d0"); + *(double*)pRegisterReturn = dret; +#endif + break; + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + if (!arm::return_in_hidden_param(pReturnType)) + pRegisterReturn[0] = r0; + break; + } + default: + break; + } +} + namespace { |