Mercurial > pub > dyncall > dyncall
annotate dyncallback/dyncall_args_arm32.c @ 521:a2de1d0a73f3
- more test code generator code sharing/abstraction/simplifications
author | Tassilo Philipp |
---|---|
date | Wed, 13 Apr 2022 10:06:40 +0200 |
parents | f5577f6bf97a |
children | 71c884e610f0 |
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 | |
281 | 9 Copyright (c) 2007-2018 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 | |
143 | 28 #include "dyncall_args_arm32.h" |
0 | 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
f01895437921
- armhf callback support: fixed alignment logic (only return type support still missing)
cslag
parents:
38
diff
changeset
|
39 #if defined(DC__ABI_ARM_EABI) || defined(DC__ABI_ARM_HF) |
0 | 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 | |
38 | 61 static DCfloat arm_float(DCArgs* args) |
62 { | |
63 #if defined(DC__ABI_ARM_HF) | |
64 DCfloat f; | |
65 if(args->freg_count < 16) { | |
66 f = args->f[args->freg_count++]; | |
67 | |
68 /* if freg_count was odd, sync with dreg_count */ | |
69 if(!(args->freg_count & 1) && (args->freg_count < args->dreg_count)) | |
70 args->freg_count = args->dreg_count; | |
71 | |
72 return f; | |
73 } | |
74 #endif | |
75 return *(DCfloat*)arm_word(args); | |
76 } | |
0 | 77 |
78 static DCdouble arm_double(DCArgs* args) | |
79 { | |
80 union { | |
81 DCdouble d; | |
82 DClong l[2]; | |
83 } d; | |
38 | 84 #if defined(DC__ABI_ARM_HF) |
85 if(args->dreg_count < args->freg_count) | |
86 args->dreg_count = (args->freg_count+1)&0x1e; /* clear last bit, counter won't be higher than 16, anyways */ | |
87 | |
88 if(args->dreg_count < 16) { | |
89 d.d = *(DCdouble*)&args->f[args->dreg_count]; | |
90 args->dreg_count += 2; | |
91 | |
92 /* freg_count is either odd (pointing to a gap), or always the same as dreg_count */ | |
93 if(!(args->freg_count & 1)) | |
94 args->freg_count = args->dreg_count; | |
95 return d.d; | |
96 } | |
47 | 97 args->freg_count = 16; /* fp registers all full - need to use stack now: stop filling gaps for single precision, also */ |
38 | 98 #endif |
0 | 99 arm_align_64(args); |
100 d.l[0] = *(DClong*)arm_word(args); | |
101 d.l[1] = *(DClong*)arm_word(args); | |
102 return d.d; | |
103 } | |
104 | |
105 static DClonglong arm_longlong(DCArgs* args) | |
106 { | |
107 union { | |
108 DClonglong ll; | |
109 DClong l[2]; | |
110 } ll; | |
111 arm_align_64(args); | |
112 ll.l[0] = *(DClong*)arm_word(args); | |
113 ll.l[1] = *(DClong*)arm_word(args); | |
114 return ll.ll; | |
115 } | |
116 | |
117 | |
118 | |
119 // ---------------------------------------------------------------------------- | |
120 // C API implementation: | |
121 | |
122 | |
123 // base operations: | |
124 | |
125 DClonglong dcbArgLongLong (DCArgs* p) { return arm_longlong(p); } | |
126 DClong dcbArgLong (DCArgs* p) { return *(DClong*)arm_word(p); } | |
127 DCint dcbArgInt (DCArgs* p) { return (DCint) dcbArgLong(p); } | |
128 DCchar dcbArgChar (DCArgs* p) { return (DCchar) dcbArgLong(p); } | |
129 DCshort dcbArgShort (DCArgs* p) { return (DCshort) dcbArgLong(p); } | |
130 DCbool dcbArgBool (DCArgs* p) { return (dcbArgLong(p) == 0) ? 0 : 1; } | |
131 | |
132 DCuint dcbArgUInt (DCArgs* p) { return (DCuint) dcbArgInt(p); } | |
133 DCuchar dcbArgUChar (DCArgs* p) { return (DCuchar) dcbArgChar(p); } | |
134 DCushort dcbArgUShort (DCArgs* p) { return (DCushort) dcbArgShort(p); } | |
135 DCulong dcbArgULong (DCArgs* p) { return (DCulong) dcbArgLong(p); } | |
136 DCulonglong dcbArgULongLong(DCArgs* p) { return (DCulonglong)dcbArgLongLong(p); } | |
137 | |
138 | |
139 DCpointer dcbArgPointer (DCArgs* p) { return (DCpointer) dcbArgLong(p); } | |
140 | |
141 DCdouble dcbArgDouble (DCArgs* p) { return arm_double(p); } | |
38 | 142 DCfloat dcbArgFloat (DCArgs* p) { return arm_float(p); } |
0 | 143 |