Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
core
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
LibreOffice
core
Commits
928c8c80
Kaydet (Commit)
928c8c80
authored
Ara 20, 2013
tarafından
Tor Lillqvist
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
iOS arm64 C++/UNO bridge WIP
Change-Id: I5eb994e4a48b043f463940d1c34ad7a9459b83cd
üst
c8b62432
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
193 additions
and
272 deletions
+193
-272
cpp2uno-arm64.cxx
bridges/source/cpp_uno/gcc3_ios_arm/cpp2uno-arm64.cxx
+26
-43
except.cxx
bridges/source/cpp_uno/gcc3_ios_arm/except.cxx
+0
-1
generate-snippets.pl
bridges/source/cpp_uno/gcc3_ios_arm/generate-snippets.pl
+4
-4
helper.s
bridges/source/cpp_uno/gcc3_ios_arm/helper.s
+15
-4
share.hxx
bridges/source/cpp_uno/gcc3_ios_arm/share.hxx
+12
-2
uno2cpp-arm64.cxx
bridges/source/cpp_uno/gcc3_ios_arm/uno2cpp-arm64.cxx
+136
-218
No files found.
bridges/source/cpp_uno/gcc3_ios_arm/cpp2uno-arm64.cxx
Dosyayı görüntüle @
928c8c80
...
@@ -20,9 +20,7 @@
...
@@ -20,9 +20,7 @@
#ifdef __arm64
#ifdef __arm64
// For iOS devices (64-bit ARM). Originally a copy of
// For iOS devices (64-bit ARM). Originally a copy of
// ../gcc3_linux_arm/cpp2uno.cxx with some cleanups and necessary
// ../gcc3_linux_arm/cpp2uno.cxx.
// changes: No dynamic code generation as that is prohibited for apps
// in the App Store. Instead we use a set of pre-generated snippets.
// No attempts at factoring out the large amounts of more or less
// No attempts at factoring out the large amounts of more or less
// common code in this, cpp2uno-arm.cxx and cpp2uno-i386.cxx have been
// common code in this, cpp2uno-arm.cxx and cpp2uno-i386.cxx have been
...
@@ -49,23 +47,19 @@ using namespace ::com::sun::star::uno;
...
@@ -49,23 +47,19 @@ using namespace ::com::sun::star::uno;
namespace
namespace
{
{
static
typelib_TypeClass
cpp2uno_call
(
static
typelib_TypeClass
cpp2uno_call
(
bridges
::
cpp_uno
::
shared
::
CppInterfaceProxy
*
pThis
,
bridges
::
cpp_uno
::
shared
::
CppInterfaceProxy
*
pThis
,
const
typelib_TypeDescription
*
pMemberTypeDescr
,
const
typelib_TypeDescription
*
pMemberTypeDescr
,
typelib_TypeDescriptionReference
*
pReturnTypeRef
,
typelib_TypeDescriptionReference
*
pReturnTypeRef
,
sal_Int32
nParams
,
typelib_MethodParameter
*
pParams
,
sal_Int32
nParams
,
typelib_MethodParameter
*
pParams
,
void
**
pCallStack
,
void
**
pCallStack
,
sal_Int64
*
pRegisterReturn
/* space for register return */
)
sal_Int64
*
pRegisterReturn
/* space for register return */
)
{
{
// pCallStack: ret, [return ptr], this, params
// pCallStack:
x8,
ret, [return ptr], this, params
char
*
pTopStack
=
(
char
*
)(
pCallStack
+
0
);
char
*
pTopStack
=
(
char
*
)(
pCallStack
+
0
);
char
*
pCppStack
=
pTopStack
;
char
*
pCppStack
=
pTopStack
;
#ifdef __ARM_PCS_VFP
int
dc
=
0
;
char
*
pFloatArgs
=
(
char
*
)(
pCppStack
-
64
);
#endif
// return
// return
typelib_TypeDescription
*
pReturnTypeDescr
=
0
;
typelib_TypeDescription
*
pReturnTypeDescr
=
0
;
if
(
pReturnTypeRef
)
if
(
pReturnTypeRef
)
...
@@ -77,7 +71,7 @@ namespace
...
@@ -77,7 +71,7 @@ namespace
if
(
pReturnTypeDescr
)
if
(
pReturnTypeDescr
)
{
{
if
(
!
arm
::
return_in_
hidden_param
(
pReturnTypeRef
))
if
(
!
arm
::
return_in_
x8
(
pReturnTypeRef
))
pUnoReturn
=
pRegisterReturn
;
// direct way for simple types
pUnoReturn
=
pRegisterReturn
;
// direct way for simple types
else
// complex return via ptr (pCppReturn)
else
// complex return via ptr (pCppReturn)
{
{
...
@@ -99,14 +93,14 @@ namespace
...
@@ -99,14 +93,14 @@ namespace
// Indices of values this have to be converted (interface conversion
// Indices of values this have to be converted (interface conversion
// cpp<=>uno)
// cpp<=>uno)
sal_Int32
*
pTempIndices
=
(
sal_Int32
*
)
alloca
(
sizeof
(
sal_Int32
)
*
nParams
);
int
*
pTempIndices
=
(
sal_Int32
*
)
alloca
(
sizeof
(
int
)
*
nParams
);
// Type descriptions for reconversions
// Type descriptions for reconversions
typelib_TypeDescription
**
ppTempParamTypeDescr
=
(
typelib_TypeDescription
**
)
alloca
(
sizeof
(
typelib_TypeDescription
*
)
*
nParams
);
typelib_TypeDescription
**
ppTempParamTypeDescr
=
(
typelib_TypeDescription
**
)
alloca
(
sizeof
(
typelib_TypeDescription
*
)
*
nParams
);
sal_Int32
nTempIndices
=
0
;
int
nTempIndices
=
0
;
for
(
sal_Int32
nPos
=
0
;
nPos
<
nParams
;
++
nPos
)
for
(
int
nPos
=
0
;
nPos
<
nParams
;
++
nPos
)
{
{
const
typelib_MethodParameter
&
rParam
=
pParams
[
nPos
];
const
typelib_MethodParameter
&
rParam
=
pParams
[
nPos
];
typelib_TypeDescription
*
pParamTypeDescr
=
0
;
typelib_TypeDescription
*
pParamTypeDescr
=
0
;
...
@@ -221,7 +215,7 @@ namespace
...
@@ -221,7 +215,7 @@ namespace
// destruct temporary in/inout params
// destruct temporary in/inout params
for
(
;
nTempIndices
--
;
)
for
(
;
nTempIndices
--
;
)
{
{
sal_Int32
nIndex
=
pTempIndices
[
nTempIndices
];
int
nIndex
=
pTempIndices
[
nTempIndices
];
if
(
pParams
[
nIndex
].
bIn
)
// is in/inout => was constructed
if
(
pParams
[
nIndex
].
bIn
)
// is in/inout => was constructed
uno_destructData
(
pUnoArgs
[
nIndex
],
uno_destructData
(
pUnoArgs
[
nIndex
],
...
@@ -241,7 +235,7 @@ namespace
...
@@ -241,7 +235,7 @@ namespace
// temporary params
// temporary params
for
(
;
nTempIndices
--
;
)
for
(
;
nTempIndices
--
;
)
{
{
sal_Int32
nIndex
=
pTempIndices
[
nTempIndices
];
int
nIndex
=
pTempIndices
[
nTempIndices
];
typelib_TypeDescription
*
pParamTypeDescr
=
typelib_TypeDescription
*
pParamTypeDescr
=
ppTempParamTypeDescr
[
nTempIndices
];
ppTempParamTypeDescr
[
nTempIndices
];
...
@@ -285,25 +279,15 @@ namespace
...
@@ -285,25 +279,15 @@ namespace
//=====================================================================
//=====================================================================
static
typelib_TypeClass
cpp_mediate
(
static
typelib_TypeClass
cpp_mediate
(
sal_Int32
nFunctionIndex
,
sal_Int32
nFunctionIndex
,
sal_Int32
nVtableOffset
,
sal_Int32
nVtableOffset
,
void
**
pCallStack
,
void
**
pCallStack
,
sal_Int64
*
pRegisterReturn
/* space for register return */
)
sal_Int64
*
pRegisterReturn
)
{
{
OSL_ENSURE
(
sizeof
(
sal_Int32
)
==
sizeof
(
void
*
),
"### unexpected!"
);
// pCallStack: x8, ret *, this, params
// pCallStack: [ret *], this, params
// _this_ ptr is patched cppu_XInterfaceProxy object
// _this_ ptr is patched cppu_XInterfaceProxy object
void
*
pThis
;
nFunctionIndex
&=
0x7fffffff
;
if
(
nFunctionIndex
&
0x80000000
)
void
*
pThis
=
pCallStack
[
2
];
{
nFunctionIndex
&=
0x7fffffff
;
pThis
=
pCallStack
[
1
];
}
else
{
pThis
=
pCallStack
[
0
];
}
pThis
=
static_cast
<
char
*
>
(
pThis
)
-
nVtableOffset
;
pThis
=
static_cast
<
char
*
>
(
pThis
)
-
nVtableOffset
;
bridges
::
cpp_uno
::
shared
::
CppInterfaceProxy
*
pCppI
=
bridges
::
cpp_uno
::
shared
::
CppInterfaceProxy
*
pCppI
=
...
@@ -427,12 +411,11 @@ namespace
...
@@ -427,12 +411,11 @@ namespace
* (called by asm snippets)
* (called by asm snippets)
*/
*/
extern
"C"
sal_Int64
cpp_vtable_call
(
long
*
pFunctionAndOffset
,
extern
"C"
sal_Int64
cpp_vtable_call
(
sal_Int32
*
pFunctionAndOffset
,
void
**
pCallStack
)
void
**
pCallStack
)
{
{
sal_Int64
nRegReturn
;
sal_Int64
nRegReturn
;
typelib_TypeClass
aType
=
cpp_mediate
(
pFunctionAndOffset
[
0
],
pFunctionAndOffset
[
1
],
pCallStack
,
typelib_TypeClass
aType
=
cpp_mediate
(
pFunctionAndOffset
[
0
],
pFunctionAndOffset
[
1
],
pCallStack
,
&
nRegReturn
);
&
nRegReturn
);
switch
(
aType
)
switch
(
aType
)
{
{
...
@@ -461,7 +444,7 @@ extern "C" sal_Int64 cpp_vtable_call( long *pFunctionAndOffset,
...
@@ -461,7 +444,7 @@ extern "C" sal_Int64 cpp_vtable_call( long *pFunctionAndOffset,
namespace
namespace
{
{
unsigned
char
*
codeSnippet
(
sal_Int32
functionIndex
,
unsigned
char
*
codeSnippet
(
sal_Int32
functionIndex
,
sal_Int32
vtableOffset
,
bool
b
HasHiddenParam
)
sal_Int32
vtableOffset
,
bool
b
ReturnThroughX8
)
{
{
assert
(
functionIndex
<
nFunIndexes
);
assert
(
functionIndex
<
nFunIndexes
);
if
(
!
(
functionIndex
<
nFunIndexes
))
if
(
!
(
functionIndex
<
nFunIndexes
))
...
@@ -472,14 +455,14 @@ namespace
...
@@ -472,14 +455,14 @@ namespace
return
NULL
;
return
NULL
;
// The codeSnippets table is indexed by functionIndex,
// The codeSnippets table is indexed by functionIndex,
// vtableOffset, and the
has-hidden-param
flag
// vtableOffset, and the
return-through-x8
flag
int
index
=
functionIndex
*
nVtableOffsets
*
2
+
vtableOffset
*
2
+
b
HasHiddenParam
;
int
index
=
functionIndex
*
nVtableOffsets
*
2
+
vtableOffset
*
2
+
b
ReturnThroughX8
;
unsigned
char
*
result
=
((
unsigned
char
*
)
&
codeSnippets
)
+
codeSnippets
[
index
];
unsigned
char
*
result
=
((
unsigned
char
*
)
&
codeSnippets
)
+
codeSnippets
[
index
];
SAL_INFO
(
"bridges.ios"
,
SAL_INFO
(
"bridges.ios"
,
"codeSnippet: ["
<<
"codeSnippet: ["
<<
functionIndex
<<
","
<<
vtableOffset
<<
","
<<
b
HasHiddenParam
<<
"]="
<<
functionIndex
<<
","
<<
vtableOffset
<<
","
<<
b
ReturnThroughX8
<<
"]="
<<
(
void
*
)
result
);
(
void
*
)
result
);
return
result
;
return
result
;
...
@@ -532,7 +515,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
...
@@ -532,7 +515,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
// Getter:
// Getter:
(
s
++
)
->
fn
=
codeSnippet
(
(
s
++
)
->
fn
=
codeSnippet
(
functionOffset
++
,
vtableOffset
,
functionOffset
++
,
vtableOffset
,
arm
::
return_in_
hidden_param
(
pAttrTD
->
pAttributeTypeRef
));
arm
::
return_in_
x8
(
pAttrTD
->
pAttributeTypeRef
));
// Setter:
// Setter:
if
(
!
pAttrTD
->
bReadOnly
)
if
(
!
pAttrTD
->
bReadOnly
)
...
@@ -549,7 +532,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
...
@@ -549,7 +532,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
typelib_InterfaceMethodTypeDescription
*
>
(
member
);
typelib_InterfaceMethodTypeDescription
*
>
(
member
);
(
s
++
)
->
fn
=
codeSnippet
(
functionOffset
++
,
vtableOffset
,
(
s
++
)
->
fn
=
codeSnippet
(
functionOffset
++
,
vtableOffset
,
arm
::
return_in_
hidden_param
(
pMethodTD
->
pReturnTypeRef
));
arm
::
return_in_
x8
(
pMethodTD
->
pReturnTypeRef
));
break
;
break
;
}
}
default
:
default
:
...
...
bridges/source/cpp_uno/gcc3_ios_arm/except.cxx
Dosyayı görüntüle @
928c8c80
...
@@ -17,7 +17,6 @@
...
@@ -17,7 +17,6 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
*/
#include <dlfcn.h>
#include <dlfcn.h>
#include <cxxabi.h>
#include <cxxabi.h>
#include <boost/unordered_map.hpp>
#include <boost/unordered_map.hpp>
...
...
bridges/source/cpp_uno/gcc3_ios_arm/generate-snippets.pl
Dosyayı görüntüle @
928c8c80
...
@@ -39,10 +39,10 @@ printf (".text\n");
...
@@ -39,10 +39,10 @@ printf (".text\n");
printf
(
"#if defined(__arm) || defined(__arm64)\n"
);
printf
(
"#if defined(__arm) || defined(__arm64)\n"
);
printf
(
"\n"
);
printf
(
"\n"
);
printf
(
"// Each codeSnippetX function stores into ip
/x15
an address and branches to _privateSnippetExecutor\n"
);
printf
(
"// Each codeSnippetX function stores into ip
(arm64: x15)
an address and branches to _privateSnippetExecutor\n"
);
printf
(
"// The
branch instruction is followed by two longs that ip/x15 points to
:\n"
);
printf
(
"// The
address is that following the branch instruction, containing two 32-bit ints
:\n"
);
printf
(
"// - the function index, as such
and
with the 0x80000000 bit set\n"
);
printf
(
"// - the function index, as such
or
with the 0x80000000 bit set\n"
);
printf
(
"// (to indicate
a hidden parameter
for returning large values)\n"
);
printf
(
"// (to indicate
that a hidden parameter (arm64: x8) is used
for returning large values)\n"
);
printf
(
"// - the vtable offset\n"
);
printf
(
"// - the vtable offset\n"
);
printf
(
"\n"
);
printf
(
"\n"
);
...
...
bridges/source/cpp_uno/gcc3_ios_arm/helper.s
Dosyayı görüntüle @
928c8c80
...
@@ -35,7 +35,7 @@ _privateSnippetExecutor:
...
@@ -35,7 +35,7 @@ _privateSnippetExecutor:
mov r0, ip // r0 points to functionoffset/vtable
mov r0, ip // r0 points to functionoffset/vtable
mov r1, sp // r1 points to this and params
mov r1, sp // r1 points to this and params
// (see cpp2uno.cxx:codeSnippet())
// (see cpp2uno.cxx:codeSnippet())
stmfd sp!, {r4,
lr} // save return address
stmfd sp!, {r4,
lr} // save return address
// (r4 pushed to preserve stack alignment)
// (r4 pushed to preserve stack alignment)
bl _cpp_vtable_call
bl _cpp_vtable_call
...
@@ -49,9 +49,20 @@ _privateSnippetExecutor:
...
@@ -49,9 +49,20 @@ _privateSnippetExecutor:
_privateSnippetExecutor:
_privateSnippetExecutor:
// Not done yet, intentionally crash for now...
stp x6, x7, [sp, #-16]!
mov x15, #0
stp x4, x5, [sp, #-16]!
ldr x15, [x15]
stp x2, x3, [sp, #-16]!
stp x0, x1, [sp, #-16]!
mov x0, x15
stp x8, lr, [sp, #-16]!
mov x1, sp
bl _cpp_vtable_call
ldp x8, lr, [sp, #0]
add sp, sp, #80
ret lr
#else
#else
.text
.text
...
...
bridges/source/cpp_uno/gcc3_ios_arm/share.hxx
Dosyayı görüntüle @
928c8c80
...
@@ -47,8 +47,18 @@ namespace CPPU_CURRENT_NAMESPACE
...
@@ -47,8 +47,18 @@ namespace CPPU_CURRENT_NAMESPACE
namespace
arm
namespace
arm
{
{
enum
armlimits
{
MAX_GPR_REGS
=
4
,
MAX_FPR_REGS
=
8
};
enum
armlimits
{
bool
return_in_hidden_param
(
typelib_TypeDescriptionReference
*
pTypeRef
);
#if defined(__arm)
MAX_GPR_REGS
=
4
,
MAX_FPR_REGS
=
8
#elif defined(__arm64)
MAX_GPR_REGS
=
8
,
MAX_FPR_REGS
=
8
#else
#error wtf
#endif
};
bool
return_in_x8
(
typelib_TypeDescriptionReference
*
pTypeRef
);
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bridges/source/cpp_uno/gcc3_ios_arm/uno2cpp-arm64.cxx
Dosyayı görüntüle @
928c8c80
...
@@ -32,46 +32,23 @@ using namespace ::com::sun::star::uno;
...
@@ -32,46 +32,23 @@ using namespace ::com::sun::star::uno;
namespace
arm
namespace
arm
{
{
bool
is_complex_struct
(
const
typelib_TypeDescription
*
type
)
bool
is_hfa_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
const
typelib_CompoundTypeDescription
*
p
=
reinterpret_cast
<
const
typelib_CompoundTypeDescription
*
>
(
type
);
=
reinterpret_cast
<
const
typelib_CompoundTypeDescription
*
>
(
type
);
if
(
p
->
nMembers
>=
4
)
return
false
;
for
(
sal_Int32
i
=
0
;
i
<
p
->
nMembers
;
++
i
)
for
(
sal_Int32
i
=
0
;
i
<
p
->
nMembers
;
++
i
)
{
{
if
(
p
->
ppTypeRefs
[
i
]
->
eTypeClass
!=
typelib_TypeClass_FLOAT
&&
if
((
p
->
ppTypeRefs
[
i
]
->
eTypeClass
!=
typelib_TypeClass_FLOAT
&&
p
->
ppTypeRefs
[
i
]
->
eTypeClass
!=
typelib_TypeClass_DOUBLE
)
p
->
ppTypeRefs
[
i
]
->
eTypeClass
!=
typelib_TypeClass_DOUBLE
)
||
p
->
ppTypeRefs
[
i
]
->
eTypeClass
!=
p
->
ppTypeRefs
[
0
]
->
eTypeClass
)
return
false
;
return
false
;
}
}
return
true
;
return
true
;
}
}
#endif
bool
return_in_
hidden_param
(
typelib_TypeDescriptionReference
*
pTypeRef
)
bool
return_in_
x8
(
typelib_TypeDescriptionReference
*
pTypeRef
)
{
{
if
(
bridges
::
cpp_uno
::
shared
::
isSimpleType
(
pTypeRef
))
if
(
bridges
::
cpp_uno
::
shared
::
isSimpleType
(
pTypeRef
))
return
false
;
return
false
;
...
@@ -81,15 +58,10 @@ namespace arm
...
@@ -81,15 +58,10 @@ namespace arm
TYPELIB_DANGER_GET
(
&
pTypeDescr
,
pTypeRef
);
TYPELIB_DANGER_GET
(
&
pTypeDescr
,
pTypeRef
);
// A Composite Type not larger than 16 bytes is returned in x0, x1
// A Composite Type not larger than 16 bytes is returned in x0, x1
// FIXME: what about the "complex struct" thing, is that relevant at all?
bool
bRet
=
pTypeDescr
->
nSize
>
16
;
bool
bRet
=
pTypeDescr
->
nSize
>
16
||
is_complex_struct
(
pTypeDescr
);
#ifdef __ARM_PCS_VFP
if
(
is_hfa_struct
(
pTypeDescr
))
// 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
;
bRet
=
false
;
#endif
TYPELIB_DANGER_RELEASE
(
pTypeDescr
);
TYPELIB_DANGER_RELEASE
(
pTypeDescr
);
return
bRet
;
return
bRet
;
...
@@ -98,174 +70,131 @@ namespace arm
...
@@ -98,174 +70,131 @@ namespace arm
}
}
}
}
void
MapReturn
(
sal_uInt
32
r0
,
sal_uInt32
r1
,
typelib_TypeDescriptionReference
*
pReturnType
,
sal_uInt32
*
pRegisterReturn
)
void
MapReturn
(
sal_uInt
64
x0
,
sal_uInt64
x1
,
typelib_TypeDescriptionReference
*
pReturnType
,
sal_uInt64
*
pRegisterReturn
)
{
{
switch
(
pReturnType
->
eTypeClass
)
switch
(
pReturnType
->
eTypeClass
)
{
{
case
typelib_TypeClass_HYPER
:
case
typelib_TypeClass_HYPER
:
case
typelib_TypeClass_UNSIGNED_HYPER
:
case
typelib_TypeClass_UNSIGNED_HYPER
:
pRegisterReturn
[
1
]
=
r1
;
pRegisterReturn
[
1
]
=
x1
;
case
typelib_TypeClass_LONG
:
// fallthrough
case
typelib_TypeClass_UNSIGNED_LONG
:
case
typelib_TypeClass_LONG
:
case
typelib_TypeClass_ENUM
:
case
typelib_TypeClass_UNSIGNED_LONG
:
case
typelib_TypeClass_CHAR
:
case
typelib_TypeClass_ENUM
:
case
typelib_TypeClass_SHORT
:
case
typelib_TypeClass_CHAR
:
case
typelib_TypeClass_UNSIGNED_SHORT
:
case
typelib_TypeClass_SHORT
:
case
typelib_TypeClass_BOOLEAN
:
case
typelib_TypeClass_UNSIGNED_SHORT
:
case
typelib_TypeClass_BYTE
:
case
typelib_TypeClass_BOOLEAN
:
pRegisterReturn
[
0
]
=
r0
;
case
typelib_TypeClass_BYTE
:
break
;
pRegisterReturn
[
0
]
=
x0
;
case
typelib_TypeClass_FLOAT
:
break
;
#if !defined(__ARM_PCS_VFP) && (defined(__ARM_EABI__) || defined(__SOFTFP__) || defined(IOS))
case
typelib_TypeClass_FLOAT
:
pRegisterReturn
[
0
]
=
r0
;
register
float
fret
asm
(
"s0"
);
#else
register
float
fret
asm
(
"s0"
);
#pragma GCC diagnostic push
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
#pragma GCC diagnostic ignored "-Wuninitialized"
*
(
float
*
)
pRegisterReturn
=
fret
;
*
(
float
*
)
pRegisterReturn
=
fret
;
#pragma GCC diagnostic pop
#pragma GCC diagnostic pop
#endif
break
;
break
;
case
typelib_TypeClass_DOUBLE
:
case
typelib_TypeClass_DOUBLE
:
register
double
dret
asm
(
"d0"
);
#if !defined(__ARM_PCS_VFP) && (defined(__ARM_EABI__) || defined(__SOFTFP__) || defined(IOS))
pRegisterReturn
[
1
]
=
r1
;
pRegisterReturn
[
0
]
=
r0
;
#else
register
double
dret
asm
(
"d0"
);
#pragma GCC diagnostic push
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
#pragma GCC diagnostic ignored "-Wuninitialized"
*
(
double
*
)
pRegisterReturn
=
dret
;
*
(
double
*
)
pRegisterReturn
=
dret
;
#pragma GCC diagnostic pop
#pragma GCC diagnostic pop
#endif
break
;
break
;
case
typelib_TypeClass_STRUCT
:
case
typelib_TypeClass_STRUCT
:
case
typelib_TypeClass_EXCEPTION
:
case
typelib_TypeClass_EXCEPTION
:
if
(
!
arm
::
return_in_x8
(
pReturnType
))
{
{
if
(
!
arm
::
return_in_hidden_param
(
pReturnType
))
pRegisterReturn
[
0
]
=
x0
;
pRegisterReturn
[
0
]
=
r0
;
pRegisterReturn
[
1
]
=
x1
;
break
;
}
}
default
:
break
;
break
;
default
:
break
;
}
}
}
}
namespace
namespace
{
{
//================================================================
void
callVirtualMethod
(
void
*
pThis
,
sal_Int32
nVtableIndex
,
void
*
pRegisterReturn
,
typelib_TypeDescriptionReference
*
pReturnType
,
sal_uInt32
*
pStack
,
sal_uInt32
nStack
,
sal_uInt32
*
pGPR
,
sal_uInt32
nGPR
,
double
*
pFPR
)
__attribute__
((
noinline
));
void
callVirtualMethod
(
void
callVirtualMethod
(
void
*
pThis
,
void
*
pThis
,
sal_Int32
nVtableIndex
,
sal_Int32
nVtableIndex
,
void
*
pRegisterReturn
,
void
*
pRegisterReturn
,
typelib_TypeDescriptionReference
*
pReturnType
,
typelib_TypeDescriptionReference
*
pReturnType
,
sal_uInt32
*
pStack
,
sal_uInt64
*
pStack
,
sal_uInt32
nStack
,
int
nStack
,
sal_uInt32
*
pGPR
,
sal_uInt64
*
pGPR
,
sal_uInt32
nGPR
,
int
nGPR
,
double
*
pFPR
)
double
*
pFPR
,
int
nFPR
)
{
{
abort
();
// arm64 code not yet implemented
// never called
if
(
!
pThis
)
(
void
)
pThis
;
CPPU_CURRENT_NAMESPACE
::
dummy_can_throw_anything
(
"xxx"
);
// address something
(
void
)
nVtableIndex
;
(
void
)
pRegisterReturn
;
if
(
nStack
)
(
void
)
pReturnType
;
{
(
void
)
pStack
;
// 16-bytes aligned
(
void
)
nStack
;
sal_uInt32
nStackBytes
=
(
(
nStack
+
3
)
>>
2
)
*
16
;
(
void
)
pGPR
;
sal_uInt32
*
stack
=
(
sal_uInt32
*
)
alloca
(
nStackBytes
);
(
void
)
nGPR
;
memcpy
(
stack
,
pStack
,
nStackBytes
);
(
void
)
pFPR
;
}
assert
(
nGPR
<=
arm
::
MAX_GPR_REGS
);
assert
(
nFPR
<=
arm
::
MAX_FPR_REGS
);
sal_uInt64
pMethod
=
*
((
sal_uInt64
*
)
pThis
);
pMethod
+=
8
*
nVtableIndex
;
pMethod
=
*
((
sal_uInt64
*
)
pMethod
);
// For value returned in registers
sal_uInt64
x0
;
sal_uInt64
x1
;
__asm__
__volatile__
(
" ldp x0, x1, %[pgpr_0]
\n
"
" ldp x2, x3, %[pgpr_2]
\n
"
" ldp x4, x5, %[pgpr_4]
\n
"
" ldp x6, x7, %[pgpr_6]
\n
"
" ldr x8, %[pregisterreturn]
\n
"
" ldp d0, d1, %[pfpr_0]
\n
"
" ldp d2, d3, %[pfpr_2]
\n
"
" ldp d4, d5, %[pfpr_4]
\n
"
" ldp d6, d7, %[pfpr_6]
\n
"
" blr %[pmethod]
\n
"
" str x0, %[x0]
\n
"
" str x1, %[x1]
\n
"
:
[
x0
]
"=m"
(
x0
),
[
x1
]
"=m"
(
x1
)
:
[
pgpr_0
]
"m"
(
pGPR
[
0
]),
[
pgpr_2
]
"m"
(
pGPR
[
2
]),
[
pgpr_4
]
"m"
(
pGPR
[
4
]),
[
pgpr_6
]
"m"
(
pGPR
[
6
]),
[
pregisterreturn
]
"m"
(
pRegisterReturn
),
[
pfpr_0
]
"m"
(
pFPR
[
0
]),
[
pfpr_2
]
"m"
(
pFPR
[
2
]),
[
pfpr_4
]
"m"
(
pFPR
[
4
]),
[
pfpr_6
]
"m"
(
pFPR
[
6
]),
[
pmethod
]
"r"
(
pMethod
)
:
"x0"
,
"x1"
,
"x2"
,
"x3"
,
"x4"
,
"x5"
,
"x6"
,
"x7"
,
"x8"
,
"d0"
,
"d1"
,
"d2"
,
"d3"
,
"d4"
,
"d5"
,
"d6"
,
"d7"
);
MapReturn
(
x0
,
x1
,
pReturnType
,
(
sal_uInt64
*
)
pRegisterReturn
);
}
}
}
}
#define INSERT_INT
32
( pSV, nr, pGPR, pDS ) \
#define INSERT_INT
64
( pSV, nr, pGPR, pDS ) \
if ( nr < arm::MAX_GPR_REGS ) \
if ( nr < arm::MAX_GPR_REGS ) \
pGPR[nr++] = *reinterpret_cast<sal_uInt
32
*>( pSV ); \
pGPR[nr++] = *reinterpret_cast<sal_uInt
64
*>( pSV ); \
else \
else \
*pDS++ = *reinterpret_cast<sal_uInt
32
*>( pSV );
*pDS++ = *reinterpret_cast<sal_uInt
64
*>( pSV );
#ifdef __ARM_EABI__
#define INSERT_INT32( pSV, nr, pGPR, pDS ) \
#define INSERT_INT64( pSV, nr, pGPR, pDS, pStart ) \
if ( (nr < arm::MAX_GPR_REGS) && (nr % 2) ) \
{ \
++nr; \
} \
if ( nr < arm::MAX_GPR_REGS ) \
if ( nr < arm::MAX_GPR_REGS ) \
{ \
pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
pGPR[nr++] = *(reinterpret_cast<sal_uInt32 *>( pSV ) + 1); \
} \
else \
else \
{ \
*pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
if ( (pDS - pStart) % 2) \
{ \
++pDS; \
} \
*pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[0]; \
*pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[1]; \
}
#else
#define INSERT_INT64( pSV, nr, pGPR, pDS, pStart ) \
INSERT_INT32( pSV, nr, pGPR, pDS ) \
INSERT_INT32( ((sal_uInt32*)pSV)+1, nr, pGPR, pDS )
#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++] = *reinterpret_cast<float *>( pSV ); \
if ((nSR % 2 == 1) && (nSR > 2*nDR)) {\
nDR++; \
}\
}\
else \
{\
*pDS++ = *reinterpret_cast<float *>( pSV );\
}
#define INSERT_DOUBLE( pSV, nr, pGPR, pDS, pStart ) \
if ( nDR < arm::MAX_FPR_REGS ) { \
pFPR[nDR++] = *reinterpret_cast<double *>( pSV ); \
}\
else\
{\
if ( (pDS - pStart) % 2) \
{ \
++pDS; \
} \
*(double *)pDS = *reinterpret_cast<double *>( pSV );\
pDS += 2;\
}
#else
#define INSERT_FLOAT( pSV, nr, pFPR, pDS ) \
INSERT_INT32( pSV, nr, pGPR, pDS )
#define INSERT_DOUBLE( pSV, nr, pFPR, pDS, pStart ) \
INSERT_INT64( pSV, nr, pGPR, pDS, pStart )
#endif
#define INSERT_INT16( pSV, nr, pGPR, pDS ) \
#define INSERT_INT16( pSV, nr, pGPR, pDS ) \
if ( nr < arm::MAX_GPR_REGS ) \
if ( nr < arm::MAX_GPR_REGS ) \
...
@@ -279,8 +208,16 @@ void callVirtualMethod(
...
@@ -279,8 +208,16 @@ void callVirtualMethod(
else \
else \
*pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
*pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
#define INSERT_DOUBLE( pSV, nr, pFPR, pDS ) \
if ( nr < arm::MAX_FPR_REGS ) \
pFPR[nr++] = *reinterpret_cast<double *>( pSV ); \
else \
*pDS++ = *reinterpret_cast<double *>( pSV );
#define INSERT_FLOAT( pSV, nr, pFPR, pDS ) \
INSERT_DOUBLE( pSV, nr, pGPR, pDS )
namespace
{
namespace
{
//=======================================================================
static
void
cpp_call
(
static
void
cpp_call
(
bridges
::
cpp_uno
::
shared
::
UnoInterfaceProxy
*
pThis
,
bridges
::
cpp_uno
::
shared
::
UnoInterfaceProxy
*
pThis
,
bridges
::
cpp_uno
::
shared
::
VtableSlot
aVtableSlot
,
bridges
::
cpp_uno
::
shared
::
VtableSlot
aVtableSlot
,
...
@@ -288,21 +225,16 @@ static void cpp_call(
...
@@ -288,21 +225,16 @@ static void cpp_call(
sal_Int32
nParams
,
typelib_MethodParameter
*
pParams
,
sal_Int32
nParams
,
typelib_MethodParameter
*
pParams
,
void
*
pUnoReturn
,
void
*
pUnoArgs
[],
uno_Any
**
ppUnoExc
)
void
*
pUnoReturn
,
void
*
pUnoArgs
[],
uno_Any
**
ppUnoExc
)
{
{
// max space for: [complex ret ptr], values|ptr ...
// max space for: values|ptr ...
sal_uInt32
*
pStack
=
(
sal_uInt32
*
)
__builtin_alloca
(
sal_uInt64
*
pStack
=
(
sal_uInt64
*
)
alloca
(
(
nParams
+
2
)
*
sizeof
(
sal_Int64
)
);
sizeof
(
sal_Int32
)
+
((
nParams
+
2
)
*
sizeof
(
sal_Int64
))
);
sal_uInt64
*
pStackStart
=
pStack
;
sal_uInt32
*
pStackStart
=
pStack
;
sal_uInt
32
pGPR
[
arm
::
MAX_GPR_REGS
];
sal_uInt
64
pGPR
[
arm
::
MAX_GPR_REGS
];
sal_uInt32
nGPR
=
0
;
int
nGPR
=
0
;
// storage and counter
s for single and double precision V
FP registers
// storage and counter
for SIMD/
FP registers
double
pFPR
[
arm
::
MAX_FPR_REGS
];
double
pFPR
[
arm
::
MAX_FPR_REGS
];
#ifdef __ARM_PCS_VFP
int
nFPR
=
0
;
sal_uInt32
nDR
=
0
;
float
*
pSPR
=
reinterpret_cast
<
float
*>
(
&
pFPR
);
sal_uInt32
nSR
=
0
;
#endif
// return
// return
typelib_TypeDescription
*
pReturnTypeDescr
=
0
;
typelib_TypeDescription
*
pReturnTypeDescr
=
0
;
...
@@ -311,22 +243,16 @@ static void cpp_call(
...
@@ -311,22 +243,16 @@ static void cpp_call(
void
*
pCppReturn
=
0
;
// if != 0 && != pUnoReturn, needs reconversion
void
*
pCppReturn
=
0
;
// if != 0 && != pUnoReturn, needs reconversion
bool
bSimpleReturn
=
true
;
if
(
pReturnTypeDescr
)
if
(
pReturnTypeDescr
)
{
{
if
(
arm
::
return_in_hidden_param
(
pReturnTypeRef
)
)
if
(
!
arm
::
return_in_x8
(
pReturnTypeRef
)
)
bSimpleReturn
=
false
;
if
(
bSimpleReturn
)
pCppReturn
=
pUnoReturn
;
// direct way for simple types
pCppReturn
=
pUnoReturn
;
// direct way for simple types
else
else
{
{
// complex return via
ptr
// complex return via
x8
pCppReturn
=
(
bridges
::
cpp_uno
::
shared
::
relatesToInterfaceType
(
pReturnTypeDescr
)
pCppReturn
=
(
bridges
::
cpp_uno
::
shared
::
relatesToInterfaceType
(
pReturnTypeDescr
)
?
__builtin_
alloca
(
pReturnTypeDescr
->
nSize
)
?
alloca
(
pReturnTypeDescr
->
nSize
)
:
pUnoReturn
);
// direct way
:
pUnoReturn
);
// direct way
INSERT_INT32
(
&
pCppReturn
,
nGPR
,
pGPR
,
pStack
);
}
}
}
}
// push this
// push this
...
@@ -335,15 +261,16 @@ static void cpp_call(
...
@@ -335,15 +261,16 @@ static void cpp_call(
INSERT_INT32
(
&
pAdjustedThisPtr
,
nGPR
,
pGPR
,
pStack
);
INSERT_INT32
(
&
pAdjustedThisPtr
,
nGPR
,
pGPR
,
pStack
);
// stack space
// stack space
OSL_ENSURE
(
sizeof
(
void
*
)
==
sizeof
(
sal_Int32
),
"### unexpected size!"
);
// args
// args
void
**
pCppArgs
=
(
void
**
)
alloca
(
3
*
sizeof
(
void
*
)
*
nParams
);
void
**
pCppArgs
=
(
void
**
)
alloca
(
sizeof
(
void
*
)
*
nParams
);
// indices of values this have to be converted (interface conversion cpp<=>uno)
// indices of values this have to be converted (interface conversion cpp<=>uno)
sal_Int32
*
pTempIndices
=
(
sal_Int32
*
)(
pCppArgs
+
nParams
);
int
*
pTempIndices
=
(
int
*
)
alloca
(
sizeof
(
int
)
*
nParams
);
// type descriptions for reconversions
// type descriptions for reconversions
typelib_TypeDescription
**
ppTempParamTypeDescr
=
(
typelib_TypeDescription
**
)
(
pCppArgs
+
(
2
*
nParams
)
);
typelib_TypeDescription
**
ppTempParamTypeDescr
=
(
typelib_TypeDescription
**
)
alloca
(
sizeof
(
void
*
)
*
nParams
);
sal_Int32
nTempIndices
=
0
;
sal_Int32
nTempIndices
=
0
;
for
(
sal_Int32
nPos
=
0
;
nPos
<
nParams
;
++
nPos
)
for
(
sal_Int32
nPos
=
0
;
nPos
<
nParams
;
++
nPos
)
{
{
...
@@ -353,7 +280,6 @@ static void cpp_call(
...
@@ -353,7 +280,6 @@ static void cpp_call(
if
(
!
rParam
.
bOut
&&
bridges
::
cpp_uno
::
shared
::
isSimpleType
(
pParamTypeDescr
))
if
(
!
rParam
.
bOut
&&
bridges
::
cpp_uno
::
shared
::
isSimpleType
(
pParamTypeDescr
))
{
{
// uno_copyAndConvertData( pCppArgs[nPos] = pStack, pUnoArgs[nPos],
uno_copyAndConvertData
(
pCppArgs
[
nPos
]
=
alloca
(
8
),
pUnoArgs
[
nPos
],
uno_copyAndConvertData
(
pCppArgs
[
nPos
]
=
alloca
(
8
),
pUnoArgs
[
nPos
],
pParamTypeDescr
,
pThis
->
getBridge
()
->
getUno2Cpp
()
);
pParamTypeDescr
,
pThis
->
getBridge
()
->
getUno2Cpp
()
);
...
@@ -361,17 +287,11 @@ static void cpp_call(
...
@@ -361,17 +287,11 @@ static void cpp_call(
{
{
case
typelib_TypeClass_HYPER
:
case
typelib_TypeClass_HYPER
:
case
typelib_TypeClass_UNSIGNED_HYPER
:
case
typelib_TypeClass_UNSIGNED_HYPER
:
INSERT_INT64
(
pCppArgs
[
nPos
],
nGPR
,
pGPR
,
pStack
);
SAL_INFO
(
"bridges.ios"
,
"hyper is "
<<
pCppArgs
[
nPos
]
);
INSERT_INT64
(
pCppArgs
[
nPos
],
nGPR
,
pGPR
,
pStack
,
pStackStart
);
break
;
break
;
case
typelib_TypeClass_LONG
:
case
typelib_TypeClass_LONG
:
case
typelib_TypeClass_UNSIGNED_LONG
:
case
typelib_TypeClass_UNSIGNED_LONG
:
case
typelib_TypeClass_ENUM
:
case
typelib_TypeClass_ENUM
:
SAL_INFO
(
"bridges.ios"
,
"long is "
<<
pCppArgs
[
nPos
]
);
INSERT_INT32
(
pCppArgs
[
nPos
],
nGPR
,
pGPR
,
pStack
);
INSERT_INT32
(
pCppArgs
[
nPos
],
nGPR
,
pGPR
,
pStack
);
break
;
break
;
case
typelib_TypeClass_SHORT
:
case
typelib_TypeClass_SHORT
:
...
@@ -384,10 +304,10 @@ static void cpp_call(
...
@@ -384,10 +304,10 @@ static void cpp_call(
INSERT_INT8
(
pCppArgs
[
nPos
],
nGPR
,
pGPR
,
pStack
);
INSERT_INT8
(
pCppArgs
[
nPos
],
nGPR
,
pGPR
,
pStack
);
break
;
break
;
case
typelib_TypeClass_FLOAT
:
case
typelib_TypeClass_FLOAT
:
INSERT_FLOAT
(
pCppArgs
[
nPos
],
n
GPR
,
pG
PR
,
pStack
);
INSERT_FLOAT
(
pCppArgs
[
nPos
],
n
FPR
,
pF
PR
,
pStack
);
break
;
break
;
case
typelib_TypeClass_DOUBLE
:
case
typelib_TypeClass_DOUBLE
:
INSERT_DOUBLE
(
pCppArgs
[
nPos
],
n
GPR
,
pGPR
,
pStack
,
pStackStart
);
INSERT_DOUBLE
(
pCppArgs
[
nPos
],
n
FPR
,
pFPR
,
pStack
);
break
;
break
;
default
:
default
:
break
;
break
;
...
@@ -436,7 +356,7 @@ static void cpp_call(
...
@@ -436,7 +356,7 @@ static void cpp_call(
pStackStart
,
pStackStart
,
(
pStack
-
pStackStart
),
(
pStack
-
pStackStart
),
pGPR
,
nGPR
,
pGPR
,
nGPR
,
pFPR
);
pFPR
,
nFPR
);
// NO exception occurred...
// NO exception occurred...
*
ppUnoExc
=
0
;
*
ppUnoExc
=
0
;
...
@@ -476,8 +396,6 @@ static void cpp_call(
...
@@ -476,8 +396,6 @@ static void cpp_call(
}
}
catch
(...)
catch
(...)
{
{
// __asm__ __volatile__ ("sub sp, sp, #2048\n");
// fill uno exception
// fill uno exception
CPPU_CURRENT_NAMESPACE
::
fillUnoException
(
abi
::
__cxa_get_globals
()
->
caughtExceptions
,
*
ppUnoExc
,
pThis
->
getBridge
()
->
getCpp2Uno
()
);
CPPU_CURRENT_NAMESPACE
::
fillUnoException
(
abi
::
__cxa_get_globals
()
->
caughtExceptions
,
*
ppUnoExc
,
pThis
->
getBridge
()
->
getCpp2Uno
()
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment