0
|
1 /*
|
|
2
|
|
3 Package: dyncall
|
|
4 Library: dyncallback
|
|
5 File: dyncallback/dyncall_args_arm32_arm.c
|
|
6 Description: Callback's Arguments VM - Implementation for ARM32 (ARM mode)
|
|
7 License:
|
|
8
|
|
9 Copyright (c) 2007-2015 Daniel Adler <dadler@uni-goettingen.de>,
|
|
10 Tassilo Philipp <tphilipp@potion-studios.com>
|
|
11
|
|
12 Permission to use, copy, modify, and distribute this software for any
|
|
13 purpose with or without fee is hereby granted, provided that the above
|
|
14 copyright notice and this permission notice appear in all copies.
|
|
15
|
|
16 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
17 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
18 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
19 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
22 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
23
|
|
24 */
|
|
25
|
|
26
|
|
27
|
|
28 #include "dyncall_args_arm32_arm.h"
|
|
29
|
|
30
|
|
31 static void arm_align_64(DCArgs* args)
|
|
32 {
|
|
33 /* Look at signature to see if current calling convention needs alignment */
|
|
34 /* or not (e.g. EABI has different alignment). If nothing specified, fall */
|
|
35 /* back to default behaviour for this platform. */
|
|
36 /* @@@ check signature string */
|
|
37
|
|
38 int sig =
|
|
39 #if defined(DC__ABI_ARM_EABI)
|
|
40 0; /* EABI */
|
|
41 #else
|
|
42 1; /* ATPCS */
|
|
43 #endif
|
|
44 if(sig == 0) {
|
|
45 if(args->reg_count < 4)
|
|
46 args->reg_count = (args->reg_count+1)&~1;
|
|
47 if(args->reg_count >= 4 && (int)args->stack_ptr & 4)
|
|
48 ++args->stack_ptr;
|
|
49 }
|
|
50 }
|
|
51
|
|
52
|
|
53 static void* arm_word(DCArgs* args)
|
|
54 {
|
|
55 if(args->reg_count < 4)
|
|
56 return &args->reg_data[args->reg_count++];
|
|
57 else
|
|
58 return (void*)args->stack_ptr++;
|
|
59 }
|
|
60
|
|
61
|
|
62 static DCdouble arm_double(DCArgs* args)
|
|
63 {
|
|
64 union {
|
|
65 DCdouble d;
|
|
66 DClong l[2];
|
|
67 } d;
|
|
68 arm_align_64(args);
|
|
69 d.l[0] = *(DClong*)arm_word(args);
|
|
70 d.l[1] = *(DClong*)arm_word(args);
|
|
71 return d.d;
|
|
72 }
|
|
73
|
|
74
|
|
75 static DClonglong arm_longlong(DCArgs* args)
|
|
76 {
|
|
77 union {
|
|
78 DClonglong ll;
|
|
79 DClong l[2];
|
|
80 } ll;
|
|
81 arm_align_64(args);
|
|
82 ll.l[0] = *(DClong*)arm_word(args);
|
|
83 ll.l[1] = *(DClong*)arm_word(args);
|
|
84 return ll.ll;
|
|
85 }
|
|
86
|
|
87
|
|
88
|
|
89 // ----------------------------------------------------------------------------
|
|
90 // C API implementation:
|
|
91
|
|
92
|
|
93 // base operations:
|
|
94
|
|
95 DClonglong dcbArgLongLong (DCArgs* p) { return arm_longlong(p); }
|
|
96 DClong dcbArgLong (DCArgs* p) { return *(DClong*)arm_word(p); }
|
|
97 DCint dcbArgInt (DCArgs* p) { return (DCint) dcbArgLong(p); }
|
|
98 DCchar dcbArgChar (DCArgs* p) { return (DCchar) dcbArgLong(p); }
|
|
99 DCshort dcbArgShort (DCArgs* p) { return (DCshort) dcbArgLong(p); }
|
|
100 DCbool dcbArgBool (DCArgs* p) { return (dcbArgLong(p) == 0) ? 0 : 1; }
|
|
101
|
|
102 DCuint dcbArgUInt (DCArgs* p) { return (DCuint) dcbArgInt(p); }
|
|
103 DCuchar dcbArgUChar (DCArgs* p) { return (DCuchar) dcbArgChar(p); }
|
|
104 DCushort dcbArgUShort (DCArgs* p) { return (DCushort) dcbArgShort(p); }
|
|
105 DCulong dcbArgULong (DCArgs* p) { return (DCulong) dcbArgLong(p); }
|
|
106 DCulonglong dcbArgULongLong(DCArgs* p) { return (DCulonglong)dcbArgLongLong(p); }
|
|
107
|
|
108
|
|
109 DCpointer dcbArgPointer (DCArgs* p) { return (DCpointer) dcbArgLong(p); }
|
|
110
|
|
111 DCdouble dcbArgDouble (DCArgs* p) { return arm_double(p); }
|
|
112 DCfloat dcbArgFloat (DCArgs* p) { return *(DCfloat*) arm_word(p); }
|
|
113
|