 |
- Timestamp:
- 05/09/11 11:08:40
(1 year ago)
- Author:
- Marenz
- Message:
Merged branch dmd-1.067 into trunk
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r4378 |
r5652 |
|
| 17 | 17 | |
|---|
| 18 | 18 | // |
|---|
| 19 | | // Required |
|---|
| | 19 | // Required |
|---|
| 20 | 20 | // |
|---|
| 21 | 21 | /* |
|---|
| … | … | |
| 223 | 223 | } |
|---|
| 224 | 224 | } |
|---|
| 225 | | |
|---|
| | 225 | |
|---|
| 226 | 226 | struct sockaddr_in6 |
|---|
| 227 | 227 | { |
|---|
| … | … | |
| 232 | 232 | uint32_t sin6_scope_id; |
|---|
| 233 | 233 | } |
|---|
| 234 | | |
|---|
| | 234 | |
|---|
| 235 | 235 | extern in6_addr in6addr_any; |
|---|
| 236 | 236 | extern in6_addr in6addr_loopback; |
|---|
| 237 | | |
|---|
| | 237 | |
|---|
| 238 | 238 | struct ipv6_mreq |
|---|
| 239 | 239 | { |
|---|
| … | … | |
| 241 | 241 | uint ipv6mr_interface; |
|---|
| 242 | 242 | } |
|---|
| 243 | | |
|---|
| | 243 | |
|---|
| 244 | 244 | enum : uint |
|---|
| 245 | 245 | { |
|---|
| 246 | 246 | IPPROTO_IPV6 = 41, |
|---|
| 247 | | |
|---|
| | 247 | |
|---|
| 248 | 248 | INET6_ADDRSTRLEN = 46, |
|---|
| 249 | | |
|---|
| | 249 | |
|---|
| 250 | 250 | IPV6_JOIN_GROUP = 20, |
|---|
| 251 | 251 | IPV6_LEAVE_GROUP = 21, |
|---|
| … | … | |
| 345 | 345 | } |
|---|
| 346 | 346 | } |
|---|
| 347 | | |
|---|
| | 347 | |
|---|
| 348 | 348 | struct sockaddr_in6 |
|---|
| 349 | 349 | { |
|---|
| … | … | |
| 355 | 355 | uint32_t __sin6_src_id; /* Impl. specific - UDP replies */ |
|---|
| 356 | 356 | } |
|---|
| 357 | | |
|---|
| | 357 | |
|---|
| 358 | 358 | extern in6_addr in6addr_any; |
|---|
| 359 | 359 | extern in6_addr in6addr_loopback; |
|---|
| 360 | | |
|---|
| | 360 | |
|---|
| 361 | 361 | struct ipv6_mreq |
|---|
| 362 | 362 | { |
|---|
| … | … | |
| 364 | 364 | uint ipv6mr_interface; |
|---|
| 365 | 365 | } |
|---|
| 366 | | |
|---|
| | 366 | |
|---|
| 367 | 367 | enum : uint |
|---|
| 368 | 368 | { |
|---|
| 369 | 369 | IPPROTO_IPV6 = 41, |
|---|
| 370 | | |
|---|
| | 370 | |
|---|
| 371 | 371 | INET6_ADDRSTRLEN = 46, |
|---|
| 372 | | |
|---|
| | 372 | |
|---|
| 373 | 373 | IPV6_JOIN_GROUP = 0x9, |
|---|
| 374 | 374 | IPV6_LEAVE_GROUP = 0xa, |
|---|
| … | … | |
| 395 | 395 | version(BigEndian) enum : uint { N = 0x00000001 } |
|---|
| 396 | 396 | else enum : uint { N = 0x01000000 } |
|---|
| 397 | | |
|---|
| | 397 | |
|---|
| 398 | 398 | return addr.s6_addr32[3] == N && |
|---|
| 399 | 399 | addr.s6_addr32[2] == 0 && |
|---|
| … | … | |
| 411 | 411 | { |
|---|
| 412 | 412 | version(BigEndian) |
|---|
| 413 | | return addr.s6_addr32[0] & 0xff000000 == 0xff000000; |
|---|
| 414 | | else |
|---|
| 415 | | return addr.s6_addr32[0] & 0x000000ff == 0x000000ff; |
|---|
| | 413 | return (addr.s6_addr32[0] & 0xff000000) == 0xff000000; |
|---|
| | 414 | else |
|---|
| | 415 | return (addr.s6_addr32[0] & 0x000000ff) == 0x000000ff; |
|---|
| 416 | 416 | } |
|---|
| 417 | 417 | |
|---|
| … | … | |
| 419 | 419 | { |
|---|
| 420 | 420 | version(BigEndian) |
|---|
| 421 | | return addr.s6_addr32[0] & 0xffc00000 == 0xfe800000; |
|---|
| 422 | | else |
|---|
| 423 | | return addr.s6_addr32[0] & 0x0000c0ff == 0x000080fe; |
|---|
| | 421 | return (addr.s6_addr32[0] & 0xffc00000) == 0xfe800000; |
|---|
| | 422 | else |
|---|
| | 423 | return (addr.s6_addr32[0] & 0x0000c0ff) == 0x000080fe; |
|---|
| 424 | 424 | } |
|---|
| 425 | 425 | |
|---|
| … | … | |
| 427 | 427 | { |
|---|
| 428 | 428 | version(BigEndian) |
|---|
| 429 | | return addr.s6_addr32[0] & 0xffc00000 == 0xfec00000; |
|---|
| 430 | | else |
|---|
| 431 | | return addr.s6_addr32[0] & 0x0000c0ff == 0x0000c0fe; |
|---|
| | 429 | return (addr.s6_addr32[0] & 0xffc00000) == 0xfec00000; |
|---|
| | 430 | else |
|---|
| | 431 | return (addr.s6_addr32[0] & 0x0000c0ff) == 0x0000c0fe; |
|---|
| 432 | 432 | } |
|---|
| 433 | 433 | |
|---|
| … | … | |
| 436 | 436 | version(BigEndian) enum : uint { N = 0x0000ffff } |
|---|
| 437 | 437 | else enum : uint { N = 0xffff0000 } |
|---|
| 438 | | |
|---|
| | 438 | |
|---|
| 439 | 439 | return addr.s6_addr32[2] == N && |
|---|
| 440 | 440 | addr.s6_addr32[1] == 0 && |
|---|
| … | … | |
| 446 | 446 | version(BigEndian) enum : uint { N = 0x00000001 } |
|---|
| 447 | 447 | else enum : uint { N = 0x01000000 } |
|---|
| 448 | | |
|---|
| | 448 | |
|---|
| 449 | 449 | return addr.s6_addr32[2] == 0 && |
|---|
| 450 | 450 | addr.s6_addr32[1] == 0 && |
|---|
| … | … | |
| 457 | 457 | { |
|---|
| 458 | 458 | version(BigEndian) |
|---|
| 459 | | return addr.s6_addr32[0] & 0xff0f0000 == 0xff010000; |
|---|
| 460 | | else |
|---|
| 461 | | return addr.s6_addr32[0] & 0x00000fff == 0x000001ff; |
|---|
| | 459 | return (addr.s6_addr32[0] & 0xff0f0000) == 0xff010000; |
|---|
| | 460 | else |
|---|
| | 461 | return (addr.s6_addr32[0] & 0x00000fff) == 0x000001ff; |
|---|
| 462 | 462 | } |
|---|
| 463 | 463 | |
|---|
| … | … | |
| 465 | 465 | { |
|---|
| 466 | 466 | version(BigEndian) |
|---|
| 467 | | return addr.s6_addr32[0] & 0xff0f0000 == 0xff020000; |
|---|
| 468 | | else |
|---|
| 469 | | return addr.s6_addr32[0] & 0x00000fff == 0x000002ff; |
|---|
| | 467 | return (addr.s6_addr32[0] & 0xff0f0000) == 0xff020000; |
|---|
| | 468 | else |
|---|
| | 469 | return (addr.s6_addr32[0] & 0x00000fff) == 0x000002ff; |
|---|
| 470 | 470 | } |
|---|
| 471 | 471 | |
|---|
| … | … | |
| 473 | 473 | { |
|---|
| 474 | 474 | version(BigEndian) |
|---|
| 475 | | return addr.s6_addr32[0] & 0xff0f0000 == 0xff050000; |
|---|
| 476 | | else |
|---|
| 477 | | return addr.s6_addr32[0] & 0x00000fff == 0x000005ff; |
|---|
| | 475 | return (addr.s6_addr32[0] & 0xff0f0000) == 0xff050000; |
|---|
| | 476 | else |
|---|
| | 477 | return (addr.s6_addr32[0] & 0x00000fff) == 0x000005ff; |
|---|
| 478 | 478 | } |
|---|
| 479 | 479 | |
|---|
| … | … | |
| 481 | 481 | { |
|---|
| 482 | 482 | version(BigEndian) |
|---|
| 483 | | return addr.s6_addr32[0] & 0xff0f0000 == 0xff080000; |
|---|
| 484 | | else |
|---|
| 485 | | return addr.s6_addr32[0] & 0x00000fff == 0x000008ff; |
|---|
| | 483 | return (addr.s6_addr32[0] & 0xff0f0000) == 0xff080000; |
|---|
| | 484 | else |
|---|
| | 485 | return (addr.s6_addr32[0] & 0x00000fff) == 0x000008ff; |
|---|
| 486 | 486 | } |
|---|
| 487 | 487 | |
|---|
| … | … | |
| 489 | 489 | { |
|---|
| 490 | 490 | version(BigEndian) |
|---|
| 491 | | return addr.s6_addr32[0] & 0xff0f0000 == 0xff0e0000; |
|---|
| 492 | | else |
|---|
| 493 | | return addr.s6_addr32[0] & 0x00000fff == 0x00000eff; |
|---|
| | 491 | return (addr.s6_addr32[0] & 0xff0f0000) == 0xff0e0000; |
|---|
| | 492 | else |
|---|
| | 493 | return (addr.s6_addr32[0] & 0x00000fff) == 0x00000eff; |
|---|
| 494 | 494 | } |
|---|
| 495 | 495 | } |
|---|
| r5248 |
r5652 |
|
| 10 | 10 | |
|---|
| 11 | 11 | |
|---|
| | 12 | debug(PRINTF) import tango.stdc.stdio: printf; |
|---|
| | 13 | |
|---|
| | 14 | |
|---|
| 12 | 15 | version( GNU ) |
|---|
| 13 | 16 | { |
|---|
| … | … | |
| 20 | 23 | else |
|---|
| 21 | 24 | { |
|---|
| | 25 | version (X86) |
|---|
| | 26 | { |
|---|
| | 27 | /********************* |
|---|
| | 28 | * The argument pointer type. |
|---|
| | 29 | */ |
|---|
| 22 | 30 | alias void* va_list; |
|---|
| 23 | 31 | |
|---|
| 24 | | template va_start( T ) |
|---|
| 25 | | { |
|---|
| 26 | | void va_start( out va_list ap, ref T parmn ) |
|---|
| | 32 | /********** |
|---|
| | 33 | * Initialize ap. |
|---|
| | 34 | * For 32 bit code, parmn should be the last named parameter. |
|---|
| | 35 | * For 64 bit code, parmn should be __va_argsave. |
|---|
| | 36 | */ |
|---|
| | 37 | void va_start(T)(out va_list ap, ref T parmn) |
|---|
| | 38 | { |
|---|
| | 39 | ap = cast(va_list)(cast(void*)&parmn + ((T.sizeof + int.sizeof - 1) & ~(int.sizeof - 1))); |
|---|
| | 40 | } |
|---|
| | 41 | |
|---|
| | 42 | /************ |
|---|
| | 43 | * Retrieve and return the next value that is type T. |
|---|
| | 44 | * Should use the other va_arg instead, as this won't work for 64 bit code. |
|---|
| | 45 | */ |
|---|
| | 46 | T va_arg(T)(ref va_list ap) |
|---|
| | 47 | { |
|---|
| | 48 | T arg = *cast(T*)ap; |
|---|
| | 49 | ap = cast(va_list)(cast(void*)ap + ((T.sizeof + int.sizeof - 1) & ~(int.sizeof - 1))); |
|---|
| | 50 | return arg; |
|---|
| | 51 | } |
|---|
| | 52 | |
|---|
| | 53 | /************ |
|---|
| | 54 | * Retrieve and return the next value that is type T. |
|---|
| | 55 | * This is the preferred version. |
|---|
| | 56 | */ |
|---|
| | 57 | void va_arg(T)(ref va_list ap, ref T parmn) |
|---|
| | 58 | { |
|---|
| | 59 | parmn = *cast(T*)ap; |
|---|
| | 60 | ap = cast(va_list)(cast(void*)ap + ((T.sizeof + int.sizeof - 1) & ~(int.sizeof - 1))); |
|---|
| | 61 | } |
|---|
| | 62 | |
|---|
| | 63 | /************* |
|---|
| | 64 | * Retrieve and store through parmn the next value that is of TypeInfo ti. |
|---|
| | 65 | * Used when the static type is not known. |
|---|
| | 66 | */ |
|---|
| | 67 | void va_arg()(ref va_list ap, TypeInfo ti, void* parmn) |
|---|
| | 68 | { |
|---|
| | 69 | // Wait until everyone updates to get TypeInfo.talign() |
|---|
| | 70 | //auto talign = ti.talign(); |
|---|
| | 71 | //auto p = cast(void*)(cast(size_t)ap + talign - 1) & ~(talign - 1); |
|---|
| | 72 | auto p = ap; |
|---|
| | 73 | auto tsize = ti.tsize(); |
|---|
| | 74 | ap = cast(void*)(cast(size_t)p + ((tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1))); |
|---|
| | 75 | parmn[0..tsize] = p[0..tsize]; |
|---|
| | 76 | } |
|---|
| | 77 | |
|---|
| | 78 | /*********************** |
|---|
| | 79 | * End use of ap. |
|---|
| | 80 | */ |
|---|
| | 81 | void va_end(va_list ap) |
|---|
| | 82 | { |
|---|
| | 83 | } |
|---|
| | 84 | |
|---|
| | 85 | void va_copy(out va_list dest, va_list src) |
|---|
| | 86 | { |
|---|
| | 87 | dest = src; |
|---|
| | 88 | } |
|---|
| | 89 | } |
|---|
| | 90 | else version (X86_64) |
|---|
| | 91 | { |
|---|
| | 92 | // Layout of this struct must match __gnuc_va_list for C ABI compatibility |
|---|
| | 93 | struct __va_list |
|---|
| | 94 | { |
|---|
| | 95 | uint offset_regs = 6 * 8; // no regs |
|---|
| | 96 | uint offset_fpregs = 6 * 8 + 8 * 16; // no fp regs |
|---|
| | 97 | void* stack_args; |
|---|
| | 98 | void* reg_args; |
|---|
| | 99 | } |
|---|
| | 100 | |
|---|
| | 101 | struct __va_argsave_t |
|---|
| | 102 | { |
|---|
| | 103 | size_t[6] regs; // RDI,RSI,RDX,RCX,R8,R9 |
|---|
| | 104 | real[8] fpregs; // XMM0..XMM7 |
|---|
| | 105 | __va_list va; |
|---|
| | 106 | } |
|---|
| | 107 | |
|---|
| | 108 | /* |
|---|
| | 109 | * Making it an array of 1 causes va_list to be passed as a pointer in |
|---|
| | 110 | * function argument lists |
|---|
| | 111 | */ |
|---|
| | 112 | alias void* va_list; |
|---|
| | 113 | |
|---|
| | 114 | void va_start(T)(out va_list ap, ref T parmn) |
|---|
| | 115 | { |
|---|
| | 116 | ap = &parmn.va; |
|---|
| | 117 | } |
|---|
| | 118 | |
|---|
| | 119 | T va_arg(T)(va_list ap) |
|---|
| | 120 | { T a; |
|---|
| | 121 | va_arg(ap, a); |
|---|
| | 122 | return a; |
|---|
| | 123 | } |
|---|
| | 124 | |
|---|
| | 125 | void va_arg(T)(va_list apx, ref T parmn) |
|---|
| | 126 | { |
|---|
| | 127 | debug(PRINTF) printf("va_arg(T) called\n"); |
|---|
| | 128 | __va_list* ap = cast(__va_list*)apx; |
|---|
| | 129 | static if (is(T U == __argTypes)) |
|---|
| 27 | 130 | { |
|---|
| 28 | | ap = cast(va_list) ( cast(void*) &parmn + ( ( T.sizeof + int.sizeof - 1 ) & ~( int.sizeof - 1 ) ) ); |
|---|
| | 131 | static if (U.length == 0 || T.sizeof > 16 || U[0].sizeof > 8) |
|---|
| | 132 | { // Always passed in memory |
|---|
| | 133 | // The arg may have more strict alignment than the stack |
|---|
| | 134 | auto p = (cast(size_t)ap.stack_args + T.alignof - 1) & ~(T.alignof - 1); |
|---|
| | 135 | ap.stack_args = cast(void*)(p + ((T.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1))); |
|---|
| | 136 | parmn = *cast(T*)p; |
|---|
| | 137 | } |
|---|
| | 138 | else static if (U.length == 1) |
|---|
| | 139 | { // Arg is passed in one register |
|---|
| | 140 | alias U[0] T1; |
|---|
| | 141 | static if (is(T1 == double) || is(T1 == float)) |
|---|
| | 142 | { // Passed in XMM register |
|---|
| | 143 | if (ap.offset_fpregs < (6 * 8 + 16 * 8)) |
|---|
| | 144 | { |
|---|
| | 145 | parmn = *cast(T*)(ap.reg_args + ap.offset_fpregs); |
|---|
| | 146 | ap.offset_fpregs += 16; |
|---|
| | 147 | } |
|---|
| | 148 | else |
|---|
| | 149 | { |
|---|
| | 150 | parmn = *cast(T*)ap.stack_args; |
|---|
| | 151 | ap.stack_args += (T1.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1); |
|---|
| | 152 | } |
|---|
| | 153 | } |
|---|
| | 154 | else |
|---|
| | 155 | { // Passed in regular register |
|---|
| | 156 | if (ap.offset_regs < 6 * 8 && T.sizeof <= 8) |
|---|
| | 157 | { |
|---|
| | 158 | parmn = *cast(T*)(ap.reg_args + ap.offset_regs); |
|---|
| | 159 | ap.offset_regs += 8; |
|---|
| | 160 | } |
|---|
| | 161 | else |
|---|
| | 162 | { |
|---|
| | 163 | auto p = (cast(size_t)ap.stack_args + T.alignof - 1) & ~(T.alignof - 1); |
|---|
| | 164 | ap.stack_args = cast(void*)(p + ((T.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1))); |
|---|
| | 165 | parmn = *cast(T*)p; |
|---|
| | 166 | } |
|---|
| | 167 | } |
|---|
| | 168 | } |
|---|
| | 169 | else static if (U.length == 2) |
|---|
| | 170 | { // Arg is passed in two registers |
|---|
| | 171 | alias U[0] T1; |
|---|
| | 172 | alias U[1] T2; |
|---|
| | 173 | |
|---|
| | 174 | static if (is(T1 == double) || is(T1 == float)) |
|---|
| | 175 | { |
|---|
| | 176 | if (ap.offset_fpregs < (6 * 8 + 16 * 8)) |
|---|
| | 177 | { |
|---|
| | 178 | *cast(T1*)&parmn = *cast(T1*)(ap.reg_args + ap.offset_fpregs); |
|---|
| | 179 | ap.offset_fpregs += 16; |
|---|
| | 180 | } |
|---|
| | 181 | else |
|---|
| | 182 | { |
|---|
| | 183 | *cast(T1*)&parmn = *cast(T1*)ap.stack_args; |
|---|
| | 184 | ap.stack_args += (T1.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1); |
|---|
| | 185 | } |
|---|
| | 186 | } |
|---|
| | 187 | else |
|---|
| | 188 | { |
|---|
| | 189 | if (ap.offset_regs < 6 * 8 && T1.sizeof <= 8) |
|---|
| | 190 | { |
|---|
| | 191 | *cast(T1*)&parmn = *cast(T1*)(ap.reg_args + ap.offset_regs); |
|---|
| | 192 | ap.offset_regs += 8; |
|---|
| | 193 | } |
|---|
| | 194 | else |
|---|
| | 195 | { |
|---|
| | 196 | *cast(T1*)&parmn = *cast(T1*)ap.stack_args; |
|---|
| | 197 | ap.stack_args += 8; |
|---|
| | 198 | } |
|---|
| | 199 | } |
|---|
| | 200 | |
|---|
| | 201 | auto p = cast(void*)&parmn + 8; |
|---|
| | 202 | static if (is(T2 == double) || is(T2 == float)) |
|---|
| | 203 | { |
|---|
| | 204 | if (ap.offset_fpregs < (6 * 8 + 16 * 8)) |
|---|
| | 205 | { |
|---|
| | 206 | *cast(T2*)p = *cast(T2*)(ap.reg_args + ap.offset_fpregs); |
|---|
| | 207 | ap.offset_fpregs += 16; |
|---|
| | 208 | } |
|---|
| | 209 | else |
|---|
| | 210 | { |
|---|
| | 211 | *cast(T2*)p = *cast(T2*)ap.stack_args; |
|---|
| | 212 | ap.stack_args += (T2.sizeof + size_t.sizeof - 1) & ~(size_t.sizeof - 1); |
|---|
| | 213 | } |
|---|
| | 214 | } |
|---|
| | 215 | else |
|---|
| | 216 | { |
|---|
| | 217 | void* a = void; |
|---|
| | 218 | if (ap.offset_regs < 6 * 8 && T2.sizeof <= 8) |
|---|
| | 219 | { |
|---|
| | 220 | a = ap.reg_args + ap.offset_regs; |
|---|
| | 221 | ap.offset_regs += 8; |
|---|
| | 222 | } |
|---|
| | 223 | else |
|---|
| | 224 | { |
|---|
| | 225 | a = ap.stack_args; |
|---|
| | 226 | ap.stack_args += 8; |
|---|
| | 227 | } |
|---|
| | 228 | // Be careful not to go past the size of the actual argument |
|---|
| | 229 | const sz2 = T.sizeof - 8; |
|---|
| | 230 | p[0..sz2] = a[0..sz2]; |
|---|
| | 231 | } |
|---|
| | 232 | } |
|---|
| | 233 | else |
|---|
| | 234 | { |
|---|
| | 235 | static assert(0); |
|---|
| | 236 | } |
|---|
| 29 | 237 | } |
|---|
| 30 | | } |
|---|
| 31 | | |
|---|
| 32 | | template va_arg( T ) |
|---|
| 33 | | { |
|---|
| 34 | | T va_arg( ref va_list ap ) |
|---|
| | 238 | else |
|---|
| 35 | 239 | { |
|---|
| 36 | | T arg = *cast(T*) ap; |
|---|
| 37 | | ap = cast(va_list) ( cast(void*) ap + ( ( T.sizeof + int.sizeof - 1 ) & ~( int.sizeof - 1 ) ) ); |
|---|
| 38 | | return arg; |
|---|
| | 240 | static assert(0, "not a valid argument type for va_arg"); |
|---|
| 39 | 241 | } |
|---|
| 40 | 242 | } |
|---|
| 41 | 243 | |
|---|
| 42 | | void va_end( va_list ap ) |
|---|
| 43 | | { |
|---|
| 44 | | |
|---|
| 45 | | } |
|---|
| 46 | | |
|---|
| 47 | | void va_copy( out va_list dest, va_list src ) |
|---|
| | 244 | void va_arg()(va_list apx, TypeInfo ti, void* parmn) |
|---|
| | 245 | { |
|---|
| | 246 | __va_list* ap = cast(__va_list*)apx; |
|---|
| | 247 | TypeInfo arg1, arg2; |
|---|
| | 248 | if (!ti.argTypes(arg1, arg2)) |
|---|
| | 249 | { |
|---|
| | 250 | if (arg1 && arg1.tsize() <= 8) |
|---|
| | 251 | { |
|---|
| | 252 | // Arg is passed in one register |
|---|
| | 253 | auto tsize = arg1.tsize(); |
|---|
| | 254 | void* p; |
|---|
| | 255 | auto s = arg1.toString(); |
|---|
| | 256 | if (s == "double" || s == "float" || s == "idouble" || s == "ifloat") |
|---|
| | 257 | { // Passed in XMM register |
|---|
| | 258 | if (ap.offset_fpregs < (6 * 8 + 16 * 8)) |
|---|
| | 259 | { |
|---|
| | 260 | p = ap.reg_args + ap.offset_fpregs; |
|---|
| | 261 | ap.offset_fpregs += 16; |
|---|
| | 262 | } |
|---|
| | 263 | else |
|---|
| | 264 | { |
|---|
| | 265 | p = ap.stack_args; |
|---|
| | 266 | ap.stack_args += (tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1); |
|---|
| | 267 | } |
|---|
| | 268 | } |
|---|
| | 269 | else |
|---|
| | 270 | { // Passed in regular register |
|---|
| | 271 | if (ap.offset_regs < 6 * 8) |
|---|
| | 272 | { |
|---|
| | 273 | p = ap.reg_args + ap.offset_regs; |
|---|
| | 274 | ap.offset_regs += 8; |
|---|
| | 275 | } |
|---|
| | 276 | else |
|---|
| | 277 | { |
|---|
| | 278 | p = ap.stack_args; |
|---|
| | 279 | ap.stack_args += 8; |
|---|
| | 280 | } |
|---|
| | 281 | } |
|---|
| | 282 | parmn[0..tsize] = p[0..tsize]; |
|---|
| | 283 | |
|---|
| | 284 | if (arg2) |
|---|
| | 285 | { |
|---|
| | 286 | parmn += 8; |
|---|
| | 287 | tsize = arg2.tsize(); |
|---|
| | 288 | s = arg2.toString(); |
|---|
| | 289 | if (s == "double" || s == "float" || s == "idouble" || s == "ifloat") |
|---|
| | 290 | { // Passed in XMM register |
|---|
| | 291 | if (ap.offset_fpregs < (6 * 8 + 16 * 8)) |
|---|
| | 292 | { |
|---|
| | 293 | p = ap.reg_args + ap.offset_fpregs; |
|---|
| | 294 | ap.offset_fpregs += 16; |
|---|
| | 295 | } |
|---|
| | 296 | else |
|---|
| | 297 | { |
|---|
| | 298 | p = ap.stack_args; |
|---|
| | 299 | ap.stack_args += (tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1); |
|---|
| | 300 | } |
|---|
| | 301 | } |
|---|
| | 302 | else |
|---|
| | 303 | { // Passed in regular register |
|---|
| | 304 | if (ap.offset_regs < 6 * 8) |
|---|
| | 305 | { |
|---|
| | 306 | p = ap.reg_args + ap.offset_regs; |
|---|
| | 307 | ap.offset_regs += 8; |
|---|
| | 308 | } |
|---|
| | 309 | else |
|---|
| | 310 | { |
|---|
| | 311 | p = ap.stack_args; |
|---|
| | 312 | ap.stack_args += 8; |
|---|
| | 313 | } |
|---|
| | 314 | } |
|---|
| | 315 | tsize = ti.tsize() - 8; |
|---|
| | 316 | parmn[0..tsize] = p[0..tsize]; |
|---|
| | 317 | } |
|---|
| | 318 | } |
|---|
| | 319 | else |
|---|
| | 320 | { |
|---|
| | 321 | // Always passed in memory |
|---|
| | 322 | // The arg may have more strict alignment than the stack |
|---|
| | 323 | auto talign = ti.talign(); |
|---|
| | 324 | auto tsize = ti.tsize(); |
|---|
| | 325 | |
|---|
| | 326 | |
|---|
| | 327 | auto p = cast(void*)((cast(size_t)ap.stack_args + talign - 1) & ~(talign - 1)); |
|---|
| | 328 | ap.stack_args = cast(void*)(cast(size_t)p + ((tsize + size_t.sizeof - 1) & ~(size_t.sizeof - 1))); |
|---|
| | 329 | parmn[0..tsize] = p[0..tsize]; |
|---|
| | 330 | } |
|---|
| | 331 | } |
|---|
| | 332 | else |
|---|
| | 333 | { |
|---|
| | 334 | assert(0, "not a valid argument type for va_arg"); |
|---|
| | 335 | } |
|---|
| | 336 | } |
|---|
| | 337 | |
|---|
| | 338 | void va_end(va_list ap) |
|---|
| | 339 | { |
|---|
| | 340 | } |
|---|
| | 341 | |
|---|
| | 342 | void va_copy(out va_list dest, va_list src) |
|---|
| 48 | 343 | { |
|---|
| 49 | 344 | dest = src; |
|---|
| 50 | 345 | } |
|---|
| 51 | 346 | } |
|---|
| | 347 | else |
|---|
| | 348 | { |
|---|
| | 349 | static assert(0); |
|---|
| | 350 | } |
|---|
| | 351 | } |
|---|
Download in other formats:
|
 |
 |
|
 |
Copyright © 2006-2012 Tango. All Rights Reserved. | Page Width:
Static or
Dynamic