Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
71ab74a1
Commit
71ab74a1
authored
Sep 26, 2019
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
oleaut32: Implement DispCallFunc() for ARM64.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
25d0c662
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
159 additions
and
1 deletion
+159
-1
typelib.c
dlls/oleaut32/typelib.c
+159
-1
No files found.
dlls/oleaut32/typelib.c
View file @
71ab74a1
...
...
@@ -6809,7 +6809,165 @@ HRESULT WINAPI DispCallFunc( void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VART
return
S_OK
;
}
#else
/* __arm__ */
#elif defined(__aarch64__)
extern
DWORD_PTR
CDECL
call_method
(
void
*
func
,
int
nb_stk_args
,
const
DWORD_PTR
*
stk_args
,
const
DWORD_PTR
*
reg_args
);
extern
float
CDECL
call_float_method
(
void
*
func
,
int
nb_stk_args
,
const
DWORD_PTR
*
stk_args
,
const
DWORD_PTR
*
reg_args
);
extern
double
CDECL
call_double_method
(
void
*
func
,
int
nb_stk_args
,
const
DWORD_PTR
*
stk_args
,
const
DWORD_PTR
*
reg_args
);
__ASM_GLOBAL_FUNC
(
call_method
,
"stp x29, x30, [sp, #-16]!
\n\t
"
"mov x29, sp
\n\t
"
"sub sp, sp, x1, lsl #3
\n\t
"
"cbz x1, 2f
\n
"
"1:
\t
sub x1, x1, #1
\n\t
"
"ldr x4, [x2, x1, lsl #3]
\n\t
"
"str x4, [sp, x1, lsl #3]
\n\t
"
"cbnz x1, 1b
\n
"
"2:
\t
mov x8, x0
\n\t
"
"mov x9, x3
\n\t
"
"ldp d0, d1, [x9]
\n\t
"
"ldp d2, d3, [x9, #0x10]
\n\t
"
"ldp d4, d5, [x9, #0x20]
\n\t
"
"ldp d6, d7, [x9, #0x30]
\n\t
"
"ldp x0, x1, [x9, #0x40]
\n\t
"
"ldp x2, x3, [x9, #0x50]
\n\t
"
"ldp x4, x5, [x9, #0x60]
\n\t
"
"ldp x6, x7, [x9, #0x70]
\n\t
"
"blr x8
\n\t
"
"mov sp, x29
\n\t
"
"ldp x29, x30, [sp], #16
\n\t
"
"ret"
)
__ASM_GLOBAL_FUNC
(
call_float_method
,
"b "
__ASM_NAME
(
"call_method"
)
)
__ASM_GLOBAL_FUNC
(
call_double_method
,
"b "
__ASM_NAME
(
"call_method"
)
)
HRESULT
WINAPI
DispCallFunc
(
void
*
instance
,
ULONG_PTR
offset
,
CALLCONV
cc
,
VARTYPE
ret_type
,
UINT
count
,
VARTYPE
*
types
,
VARIANTARG
**
vargs
,
VARIANT
*
result
)
{
int
argspos
;
void
*
func
;
UINT
i
;
DWORD_PTR
*
args
;
struct
{
union
{
float
f
;
double
d
;
}
fp
[
8
];
DWORD_PTR
x
[
8
];
}
regs
;
int
rcount
;
/* 64-bit register index count */
int
fpcount
=
0
;
/* float register index count */
TRACE
(
"(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d))
\n
"
,
instance
,
offset
,
cc
,
ret_type
,
count
,
types
,
vargs
,
result
,
V_VT
(
result
));
if
(
cc
!=
CC_STDCALL
&&
cc
!=
CC_CDECL
)
{
FIXME
(
"unsupported calling convention %d
\n
"
,
cc
);
return
E_INVALIDARG
;
}
argspos
=
0
;
rcount
=
0
;
if
(
instance
)
{
const
FARPROC
*
vtable
=
*
(
FARPROC
**
)
instance
;
func
=
vtable
[
offset
/
sizeof
(
void
*
)];
regs
.
x
[
rcount
++
]
=
(
DWORD_PTR
)
instance
;
/* the This pointer is always the first parameter */
}
else
func
=
(
void
*
)
offset
;
/* Determine if we need to pass a pointer for the return value as arg 0. If so, do that */
/* first as it will need to be in the 'x' registers: */
switch
(
ret_type
)
{
case
VT_DECIMAL
:
case
VT_VARIANT
:
regs
.
x
[
rcount
++
]
=
(
DWORD_PTR
)
result
;
/* arg 0 is a pointer to the result */
break
;
case
VT_HRESULT
:
WARN
(
"invalid return type %u
\n
"
,
ret_type
);
return
E_INVALIDARG
;
default
:
break
;
}
/* maximum size for an argument is sizeof(VARIANT). Also allow for return pointer and stack alignment. */
args
=
heap_alloc
(
sizeof
(
VARIANT
)
*
count
+
sizeof
(
DWORD_PTR
)
*
4
);
for
(
i
=
0
;
i
<
count
;
i
++
)
{
VARIANT
*
arg
=
vargs
[
i
];
switch
(
types
[
i
])
{
case
VT_EMPTY
:
break
;
case
VT_R4
:
if
(
fpcount
<
8
)
regs
.
fp
[
fpcount
++
].
f
=
V_R4
(
arg
);
else
*
(
float
*
)
&
args
[
argspos
++
]
=
V_R4
(
arg
);
break
;
case
VT_R8
:
case
VT_DATE
:
if
(
fpcount
<
8
)
regs
.
fp
[
fpcount
++
].
d
=
V_R8
(
arg
);
else
*
(
double
*
)
&
args
[
argspos
++
]
=
V_R8
(
arg
);
break
;
case
VT_DECIMAL
:
case
VT_VARIANT
:
if
(
rcount
<
7
)
{
memcpy
(
&
regs
.
x
[
rcount
],
arg
,
sizeof
(
*
arg
)
);
rcount
+=
2
;
}
else
{
memcpy
(
&
args
[
argspos
],
arg
,
sizeof
(
*
arg
)
);
argspos
+=
2
;
}
break
;
case
VT_BOOL
:
/* VT_BOOL is 16-bit but BOOL is 32-bit, needs to be extended */
if
(
rcount
<
8
)
regs
.
x
[
rcount
++
]
=
V_BOOL
(
arg
);
else
args
[
argspos
++
]
=
V_BOOL
(
arg
);
break
;
default
:
if
(
rcount
<
8
)
regs
.
x
[
rcount
++
]
=
V_UI8
(
arg
);
else
args
[
argspos
++
]
=
V_UI8
(
arg
);
break
;
}
TRACE
(
"arg %u: type %s %s
\n
"
,
i
,
debugstr_vt
(
types
[
i
]),
debugstr_variant
(
arg
));
}
argspos
+=
(
argspos
%
2
);
/* Make sure stack function alignment is 16-byte */
switch
(
ret_type
)
{
case
VT_EMPTY
:
/* EMPTY = no return value */
case
VT_DECIMAL
:
/* DECIMAL and VARIANT already have a pointer argument passed (see above) */
case
VT_VARIANT
:
call_method
(
func
,
argspos
,
args
,
(
DWORD_PTR
*
)
&
regs
);
break
;
case
VT_R4
:
V_R4
(
result
)
=
call_float_method
(
func
,
argspos
,
args
,
(
DWORD_PTR
*
)
&
regs
);
break
;
case
VT_R8
:
case
VT_DATE
:
V_R8
(
result
)
=
call_double_method
(
func
,
argspos
,
args
,
(
DWORD_PTR
*
)
&
regs
);
break
;
default
:
V_UI8
(
result
)
=
call_method
(
func
,
argspos
,
args
,
(
DWORD_PTR
*
)
&
regs
);
break
;
}
heap_free
(
args
);
if
(
ret_type
!=
VT_VARIANT
)
V_VT
(
result
)
=
ret_type
;
TRACE
(
"retval: %s
\n
"
,
debugstr_variant
(
result
));
return
S_OK
;
}
#else
/* __aarch64__ */
HRESULT
WINAPI
DispCallFunc
(
void
*
pvInstance
,
ULONG_PTR
oVft
,
CALLCONV
cc
,
VARTYPE
vtReturn
,
UINT
cActuals
,
VARTYPE
*
prgvt
,
VARIANTARG
**
prgpvarg
,
VARIANT
*
pvargResult
)
...
...
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