Mercurial > pub > dyncall > dyncall
annotate dyncallback/dyncall_args_arm32.c @ 663:127b569978cc default tip
- another tweak handling clang trying to be too smart (see last commit)
author | Tassilo Philipp |
---|---|
date | Sun, 24 Mar 2024 13:52:44 +0100 |
parents | 93ce63d72d59 |
children |
rev | line source |
---|---|
0 | 1 /* |
2 | |
3 Package: dyncall | |
4 Library: dyncallback | |
143 | 5 File: dyncallback/dyncall_args_arm32.c |
6 Description: Callback's Arguments VM - Implementation for ARM32 (ARM and THUMB mode) | |
0 | 7 License: |
8 | |
661
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
582
diff
changeset
|
9 Copyright (c) 2007-2024 Daniel Adler <dadler@uni-goettingen.de>, |
0 | 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 | |
661
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
582
diff
changeset
|
28 #include "dyncall_args.h" |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
582
diff
changeset
|
29 |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
582
diff
changeset
|
30 struct DCArgs |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
582
diff
changeset
|
31 { |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
582
diff
changeset
|
32 /* Don't change order! */ |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
582
diff
changeset
|
33 long reg_data[4]; |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
582
diff
changeset
|
34 int reg_count; |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
582
diff
changeset
|
35 long* stack_ptr; |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
582
diff
changeset
|
36 #if defined(DC__ABI_ARM_HF) |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
582
diff
changeset
|
37 DCfloat f[16]; |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
582
diff
changeset
|
38 int freg_count; |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
582
diff
changeset
|
39 int dreg_count; |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
582
diff
changeset
|
40 #endif |
93ce63d72d59
- dyncallback code cleanup: removed unneeded headers
Tassilo Philipp
parents:
582
diff
changeset
|
41 }; |
0 | 42 |
43 | |
44 static void arm_align_64(DCArgs* args) | |
45 { | |
46 /* Look at signature to see if current calling convention needs alignment */ | |
47 /* or not (e.g. EABI has different alignment). If nothing specified, fall */ | |
48 /* back to default behaviour for this platform. */ | |
49 /* @@@ check signature string */ | |
50 | |
51 int sig = | |
39
f01895437921
- armhf callback support: fixed alignment logic (only return type support still missing)
cslag
parents:
38
diff
changeset
|
52 #if defined(DC__ABI_ARM_EABI) || defined(DC__ABI_ARM_HF) |
0 | 53 0; /* EABI */ |
54 #else | |
55 1; /* ATPCS */ | |
56 #endif | |
57 if(sig == 0) { | |
58 if(args->reg_count < 4) | |
59 args->reg_count = (args->reg_count+1)&~1; | |
60 if(args->reg_count >= 4 && (int)args->stack_ptr & 4) | |
61 ++args->stack_ptr; | |
62 } | |
63 } | |
64 | |
65 | |
66 static void* arm_word(DCArgs* args) | |
67 { | |
68 if(args->reg_count < 4) | |
69 return &args->reg_data[args->reg_count++]; | |
70 else | |
71 return (void*)args->stack_ptr++; | |
72 } | |
73 | |
38 | 74 static DCfloat arm_float(DCArgs* args) |
75 { | |
76 #if defined(DC__ABI_ARM_HF) | |
77 DCfloat f; | |
78 if(args->freg_count < 16) { | |
79 f = args->f[args->freg_count++]; | |
80 | |
81 /* if freg_count was odd, sync with dreg_count */ | |
82 if(!(args->freg_count & 1) && (args->freg_count < args->dreg_count)) | |
83 args->freg_count = args->dreg_count; | |
84 | |
85 return f; | |
86 } | |
87 #endif | |
88 return *(DCfloat*)arm_word(args); | |
89 } | |
0 | 90 |
91 static DCdouble arm_double(DCArgs* args) | |
92 { | |
93 union { | |
94 DCdouble d; | |
95 DClong l[2]; | |
96 } d; | |
38 | 97 #if defined(DC__ABI_ARM_HF) |
98 if(args->dreg_count < args->freg_count) | |
99 args->dreg_count = (args->freg_count+1)&0x1e; /* clear last bit, counter won't be higher than 16, anyways */ | |
100 | |
101 if(args->dreg_count < 16) { | |
102 d.d = *(DCdouble*)&args->f[args->dreg_count]; | |
103 args->dreg_count += 2; | |
104 | |
105 /* freg_count is either odd (pointing to a gap), or always the same as dreg_count */ | |
106 if(!(args->freg_count & 1)) | |
107 args->freg_count = args->dreg_count; | |
108 return d.d; | |
109 } | |
47 | 110 args->freg_count = 16; /* fp registers all full - need to use stack now: stop filling gaps for single precision, also */ |
38 | 111 #endif |
0 | 112 arm_align_64(args); |
113 d.l[0] = *(DClong*)arm_word(args); | |
114 d.l[1] = *(DClong*)arm_word(args); | |
115 return d.d; | |
116 } | |
117 | |
118 static DClonglong arm_longlong(DCArgs* args) | |
119 { | |
120 union { | |
121 DClonglong ll; | |
122 DClong l[2]; | |
123 } ll; | |
124 arm_align_64(args); | |
125 ll.l[0] = *(DClong*)arm_word(args); | |
126 ll.l[1] = *(DClong*)arm_word(args); | |
127 return ll.ll; | |
128 } | |
129 | |
130 | |
131 DClonglong dcbArgLongLong (DCArgs* p) { return arm_longlong(p); } | |
132 DClong dcbArgLong (DCArgs* p) { return *(DClong*)arm_word(p); } | |
133 DCint dcbArgInt (DCArgs* p) { return (DCint) dcbArgLong(p); } | |
134 DCchar dcbArgChar (DCArgs* p) { return (DCchar) dcbArgLong(p); } | |
135 DCshort dcbArgShort (DCArgs* p) { return (DCshort) dcbArgLong(p); } | |
136 DCbool dcbArgBool (DCArgs* p) { return (dcbArgLong(p) == 0) ? 0 : 1; } | |
137 | |
138 DCuint dcbArgUInt (DCArgs* p) { return (DCuint) dcbArgInt(p); } | |
139 DCuchar dcbArgUChar (DCArgs* p) { return (DCuchar) dcbArgChar(p); } | |
140 DCushort dcbArgUShort (DCArgs* p) { return (DCushort) dcbArgShort(p); } | |
141 DCulong dcbArgULong (DCArgs* p) { return (DCulong) dcbArgLong(p); } | |
142 DCulonglong dcbArgULongLong(DCArgs* p) { return (DCulonglong)dcbArgLongLong(p); } | |
143 | |
144 | |
145 DCpointer dcbArgPointer (DCArgs* p) { return (DCpointer) dcbArgLong(p); } | |
146 | |
147 DCdouble dcbArgDouble (DCArgs* p) { return arm_double(p); } | |
38 | 148 DCfloat dcbArgFloat (DCArgs* p) { return arm_float(p); } |
0 | 149 |
582
3bad4cb40445
- arm32 dyncallback impl: fixed wrong type def
Tassilo Philipp
parents:
580
diff
changeset
|
150 DCpointer dcbArgAggr (DCArgs* p, DCpointer target) { /* @@@AGGR not impl */ return NULL; } |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
151 void dcbReturnAggr (DCArgs *args, DCValue *result, DCpointer ret) { /* @@@AGGR not impl */ } |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
281
diff
changeset
|
152 |