|
51 | 51 | {
|
52 | 52 | version (ARM)
|
53 | 53 | version = AAPCS32;
|
| 54 | + version (AArch64) |
| 55 | + version = AAPCS64; |
54 | 56 | }
|
55 | 57 |
|
56 |
| -version (MIPS32) version = MIPS_Any; |
57 |
| -version (MIPS64) version = MIPS_Any; |
58 |
| -version (PPC) version = PPC_Any; |
59 |
| -version (PPC64) version = PPC_Any; |
| 58 | +version (ARM) version = ARM_Any; |
| 59 | +version (AArch64) version = ARM_Any; |
| 60 | +version (MIPS32) version = MIPS_Any; |
| 61 | +version (MIPS64) version = MIPS_Any; |
| 62 | +version (PPC) version = PPC_Any; |
| 63 | +version (PPC64) version = PPC_Any; |
60 | 64 |
|
61 | 65 |
|
62 | 66 | T alignUp(size_t alignment = size_t.sizeof, T)(T base) pure
|
@@ -96,6 +100,20 @@ else version (AAPCS32)
|
96 | 100 | void* __ap;
|
97 | 101 | }
|
98 | 102 | }
|
| 103 | +else version (AAPCS64) |
| 104 | +{ |
| 105 | + alias va_list = __va_list; |
| 106 | + |
| 107 | + // https://github.com/ARM-software/abi-aa/blob/master/aapcs64/aapcs64.rst#definition-of-va-list |
| 108 | + extern (C++, std) struct __va_list |
| 109 | + { |
| 110 | + void* __stack; |
| 111 | + void* __gr_top; |
| 112 | + void* __vr_top; |
| 113 | + int __gr_offs; |
| 114 | + int __vr_offs; |
| 115 | + } |
| 116 | +} |
99 | 117 | else
|
100 | 118 | {
|
101 | 119 | alias va_list = char*;
|
@@ -171,24 +189,25 @@ void va_arg(T)(ref va_list ap, ref T parmn)
|
171 | 189 | {
|
172 | 190 | core.internal.vararg.sysv_x64.va_arg!T(ap, parmn);
|
173 | 191 | }
|
174 |
| - else version (ARM) |
| 192 | + else version (AAPCS32) |
175 | 193 | {
|
176 |
| - version (AAPCS32) |
177 |
| - { |
178 |
| - // AAPCS32 section 6.5 B.5: type with alignment >= 8 is 8-byte |
179 |
| - // aligned instead of normal 4-byte alignment (APCS doesn't do |
180 |
| - // this). |
181 |
| - if (T.alignof >= 8) |
182 |
| - ap.__ap = ap.__ap.alignUp!8; |
183 |
| - auto p = ap.__ap; |
184 |
| - ap.__ap += T.sizeof.alignUp; |
185 |
| - } |
186 |
| - else |
187 |
| - { |
188 |
| - auto p = ap; |
189 |
| - ap += T.sizeof.alignUp; |
190 |
| - } |
| 194 | + // AAPCS32 section 6.5 B.5: type with alignment >= 8 is 8-byte aligned |
| 195 | + // instead of normal 4-byte alignment (APCS doesn't do this). |
| 196 | + if (T.alignof >= 8) |
| 197 | + ap.__ap = ap.__ap.alignUp!8; |
| 198 | + auto p = ap.__ap; // TODO: big-endian adjustment? |
| 199 | + parmn = *cast(T*) p; |
| 200 | + ap.__ap += T.sizeof.alignUp; |
| 201 | + } |
| 202 | + else version (AAPCS64) |
| 203 | + { |
| 204 | + static assert(0, "Unsupported platform"); |
| 205 | + } |
| 206 | + else version (ARM_Any) |
| 207 | + { |
| 208 | + auto p = ap; // TODO: big-endian adjustment? |
191 | 209 | parmn = *cast(T*) p;
|
| 210 | + ap += T.sizeof.alignUp; |
192 | 211 | }
|
193 | 212 | else version (PPC_Any)
|
194 | 213 | {
|
@@ -254,21 +273,24 @@ void va_arg()(ref va_list ap, TypeInfo ti, void* parmn)
|
254 | 273 | {
|
255 | 274 | core.internal.vararg.sysv_x64.va_arg(ap, ti, parmn);
|
256 | 275 | }
|
257 |
| - else version (ARM) |
| 276 | + else version (AAPCS32) |
258 | 277 | {
|
259 | 278 | const tsize = ti.tsize;
|
260 |
| - version (AAPCS32) |
261 |
| - { |
262 |
| - if (ti.talign >= 8) |
263 |
| - ap.__ap = ap.__ap.alignUp!8; |
264 |
| - auto p = ap.__ap; |
265 |
| - ap.__ap += tsize.alignUp; |
266 |
| - } |
267 |
| - else |
268 |
| - { |
269 |
| - auto p = cast(void*) ap; |
270 |
| - ap += tsize.alignUp; |
271 |
| - } |
| 279 | + if (ti.talign >= 8) |
| 280 | + ap.__ap = ap.__ap.alignUp!8; |
| 281 | + auto p = ap.__ap; // TODO: big-endian adjustment? |
| 282 | + ap.__ap += tsize.alignUp; |
| 283 | + parmn[0..tsize] = p[0..tsize]; |
| 284 | + } |
| 285 | + else version (AAPCS64) |
| 286 | + { |
| 287 | + static assert(0, "Unsupported platform"); |
| 288 | + } |
| 289 | + else version (ARM_Any) |
| 290 | + { |
| 291 | + const tsize = ti.tsize; |
| 292 | + auto p = cast(void*) ap; // TODO: big-endian adjustment? |
| 293 | + ap += tsize.alignUp; |
272 | 294 | parmn[0..tsize] = p[0..tsize];
|
273 | 295 | }
|
274 | 296 | else version (PPC_Any)
|
|
0 commit comments