Changeset 1728
- Timestamp:
- 07/05/10 01:13:33 (14 years ago)
- Files:
-
- branches/phobos-1.x/phobos/internal/alloca.d (modified) (2 diffs)
- branches/phobos-1.x/phobos/internal/deh2.d (modified) (2 diffs)
- branches/phobos-1.x/phobos/internal/gc/gcbits.d (modified) (1 diff)
- branches/phobos-1.x/phobos/internal/gc/gc.d (modified) (4 diffs)
- branches/phobos-1.x/phobos/internal/gc/gcx.d (modified) (1 diff)
- branches/phobos-1.x/phobos/internal/gc/win32.d (modified) (1 diff)
- branches/phobos-1.x/phobos/internal/llmath.d (modified) (7 diffs)
- branches/phobos-1.x/phobos/internal/trace.d (modified) (3 diffs)
- branches/phobos-1.x/phobos/std/cpuid.d (modified) (3 diffs)
- branches/phobos-1.x/phobos/std/math.d (modified) (1 diff)
- branches/phobos-1.x/phobos/std/thread.d (modified) (2 diffs)
- branches/phobos-1.x/phobos/std/windows/registry.d (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/phobos-1.x/phobos/internal/alloca.d
r1701 r1728 20 20 * nbytes number of bytes to allocate 21 21 * ECX address of variable with # of bytes in locals 22 22 * This is adjusted upon return to reflect the additional 23 23 * size of the stack frame. 24 24 * Returns: 25 25 * EAX allocated data, null if stack overflows 26 26 */ 27 27 28 28 extern (C) void* __alloca(int nbytes) 29 29 { 30 version (D_InlineAsm_X86) 31 { 30 32 asm 31 33 { 32 34 naked ; 33 35 mov EDX,ECX ; 34 36 mov EAX,4[ESP] ; // get nbytes 35 37 push EBX ; 36 38 push EDI ; 37 39 push ESI ; 38 40 } 39 41 … … 117 119 Aoverflow: 118 120 // Overflowed the stack. Return null 119 121 xor EAX,EAX ; 120 122 121 123 done: 122 124 pop ESI ; 123 125 pop EDI ; 124 126 pop EBX ; 125 127 ret ; 126 128 } 129 } 130 else version (D_InlineAsm_X86_64) 131 static assert(0); 132 else 133 static assert(0); 127 134 } 128 135 129 136 130 137 131 138 132 139 133 140 134 141 135 142 136 143 branches/phobos-1.x/phobos/internal/deh2.d
r1701 r1728 141 141 } 142 142 return bp; 143 143 } 144 144 145 145 /*********************************** 146 146 * Throw a D object. 147 147 */ 148 148 149 149 extern (Windows) void _d_throw(Object *h) 150 150 { 151 uint regebp;151 size_t regebp; 152 152 153 153 debug 154 154 { 155 155 printf("_d_throw(h = %p, &h = %p)\n", h, &h); 156 156 printf("\tvptr = %p\n", *cast(void **)h); 157 157 } 158 158 159 asm 160 { 161 mov regebp,EBP ; 162 } 159 version (D_InlineAsm_X86) 160 asm 161 { 162 mov regebp,EBP ; 163 } 164 else version (D_InlineAsm_X86_64) 165 asm 166 { 167 mov regebp,RBP ; 168 } 169 else 170 static assert(0); 163 171 164 172 //static uint abc; 165 173 //if (++abc == 2) *(char *)0=0; 166 174 167 175 //int count = 0; 168 176 while (1) // for each function on the stack 169 177 { 170 178 DHandlerTable *handler_table; 171 179 FuncTable *pfunc; 172 180 DHandlerInfo *phi; … … 254 262 pcb = &pci.catch_block[i]; 255 263 256 264 if (_d_isbaseof(ci, pcb.type)) 257 265 { // Matched the catch type, so we've found the handler. 258 266 259 267 // Initialize catch variable 260 268 *cast(void **)(regebp + (pcb.bpoffset)) = h; 261 269 262 270 // Jump to catch block. Does not return. 263 271 { 264 uint catch_esp;272 size_t catch_esp; 265 273 fp_t catch_addr; 266 274 267 275 catch_addr = cast(fp_t)(pcb.code); 268 276 catch_esp = regebp - handler_table.espoffset - fp_t.sizeof; 269 asm 270 { 271 mov EAX,catch_esp ; 272 mov ECX,catch_addr ; 273 mov [EAX],ECX ; 274 mov EBP,regebp ; 275 mov ESP,EAX ; // reset stack 276 ret ; // jump to catch block 277 } 277 version (D_InlineAsm_X86) 278 asm 279 { 280 mov EAX,catch_esp ; 281 mov ECX,catch_addr ; 282 mov [EAX],ECX ; 283 mov EBP,regebp ; 284 mov ESP,EAX ; // reset stack 285 ret ; // jump to catch block 286 } 287 else version (D_InlineAsm_X86_64) 288 asm 289 { 290 mov RAX,catch_esp ; 291 mov RCX,catch_addr ; 292 mov [RAX],RCX ; 293 mov RBP,regebp ; 294 mov RSP,RAX ; // reset stack 295 ret ; // jump to catch block 296 } 297 else 298 static assert(0); 278 299 } 279 300 } 280 301 } 281 302 } 282 303 else if (phi.finally_code) 283 304 { // Call finally block 284 305 // Note that it is unnecessary to adjust the ESP, as the finally block 285 306 // accesses all items on the stack as relative to EBP. 286 307 287 308 void *blockaddr = phi.finally_code; 288 309 289 310 version (OSX) 290 311 { 291 asm 292 { 293 sub ESP,4 ; 294 push EBX ; 295 mov EBX,blockaddr ; 296 push EBP ; 297 mov EBP,regebp ; 298 call EBX ; 299 pop EBP ; 300 pop EBX ; 301 add ESP,4 ; 302 } 312 version (D_InlineAsm_X86) 313 asm 314 { 315 sub ESP,4 ; 316 push EBX ; 317 mov EBX,blockaddr ; 318 push EBP ; 319 mov EBP,regebp ; 320 call EBX ; 321 pop EBP ; 322 pop EBX ; 323 add ESP,4 ; 324 } 325 else version (D_InlineAsm_X86_64) 326 asm 327 { 328 sub RSP,8 ; 329 push RBX ; 330 mov RBX,blockaddr ; 331 push RBP ; 332 mov RBP,regebp ; 333 call RBX ; 334 pop RBP ; 335 pop RBX ; 336 add RSP,8 ; 337 } 338 else 339 static assert(0); 303 340 } 304 341 else 305 342 { 306 asm 307 { 308 push EBX ; 309 mov EBX,blockaddr ; 310 push EBP ; 311 mov EBP,regebp ; 312 call EBX ; 313 pop EBP ; 314 pop EBX ; 315 } 343 version (D_InlineAsm_X86) 344 asm 345 { 346 push EBX ; 347 mov EBX,blockaddr ; 348 push EBP ; 349 mov EBP,regebp ; 350 call EBX ; 351 pop EBP ; 352 pop EBX ; 353 } 354 else version (D_InlineAsm_X86_64) 355 asm 356 { 357 sub RSP,8 ; 358 push RBX ; 359 mov RBX,blockaddr ; 360 push RBP ; 361 mov RBP,regebp ; 362 call RBX ; 363 pop RBP ; 364 pop RBX ; 365 add RSP,8 ; 366 } 367 else 368 static assert(0); 316 369 } 317 370 } 318 371 } 319 372 } 320 373 } 321 374 branches/phobos-1.x/phobos/internal/gc/gcbits.d
r295 r1728 80 80 //(cast(bit *)(data + 1))[i] = 0; 81 81 data[1 + (i >> BITS_SHIFT)] &= ~(1 << (i & BITS_MASK)); 82 82 } 83 83 84 84 uint testClear(uint i) 85 85 { 86 86 version (bitops) 87 87 { 88 88 return std.intrinsic.btr(data + 1, i); 89 89 } 90 else version ( Asm86)90 else version (D_InlineAsm_X86) 91 91 { 92 92 asm 93 93 { 94 94 naked ; 95 95 mov EAX,data[EAX] ; 96 96 mov ECX,i-4[ESP] ; 97 97 btr 4[EAX],ECX ; 98 98 sbb EAX,EAX ; 99 99 ret 4 ; 100 100 } branches/phobos-1.x/phobos/internal/gc/gc.d
r1334 r1728 273 273 version (D_InlineAsm_X86) 274 274 { 275 275 asm 276 276 { 277 277 mov EAX,size ; 278 278 mul EAX,length ; 279 279 mov size,EAX ; 280 280 jc Loverflow ; 281 281 } 282 282 } 283 else version (D_InlineAsm_X86_64) 284 asm 285 { 286 mov RAX,size ; 287 mul RAX,length ; 288 mov size,RAX ; 289 jc Loverflow ; 290 } 283 291 else 284 292 size *= length; 285 293 p = _gc.malloc(size + 1); 286 294 debug(PRINTF) printf(" p = %p\n", p); 287 295 if (!(ti.next.flags() & 1)) 288 296 _gc.hasNoPointers(p); 289 297 memset(p, 0, size); 290 298 result = cast(ulong)length + (cast(ulong)cast(uint)p << 32); 291 299 } 292 300 return result; … … 314 322 version (D_InlineAsm_X86) 315 323 { 316 324 asm 317 325 { 318 326 mov EAX,size ; 319 327 mul EAX,length ; 320 328 mov size,EAX ; 321 329 jc Loverflow ; 322 330 } 323 331 } 332 else version (D_InlineAsm_X86_64) 333 asm 334 { 335 mov RAX,size ; 336 mul RAX,length ; 337 mov size,RAX ; 338 jc Loverflow ; 339 } 324 340 else 325 341 size *= length; 326 342 auto p = _gc.malloc(size + 1); 327 343 debug(PRINTF) 328 344 printf(" p = %p, isize = %d\n", p, isize); 329 345 if (!(ti.next.flags() & 1)) 330 346 _gc.hasNoPointers(p); 331 347 if (isize == 1) 332 348 memset(p, *cast(ubyte*)q, size); 333 349 else if (isize == int.sizeof) … … 574 590 size_t newsize = void; 575 591 576 592 asm 577 593 { 578 594 mov EAX,newlength ; 579 595 mul EAX,sizeelem ; 580 596 mov newsize,EAX ; 581 597 jc Loverflow ; 582 598 } 583 599 } 600 else version (D_InlineAsm_X86_64) 601 asm 602 { 603 mov RAX,size ; 604 mul RAX,length ; 605 mov size,RAX ; 606 jc Loverflow ; 607 } 584 608 else 585 609 { 586 610 size_t newsize = sizeelem * newlength; 587 611 588 612 if (newsize / newlength != sizeelem) 589 613 goto Loverflow; 590 614 } 591 615 //printf("newsize = %x, newlength = %x\n", newsize, newlength); 592 616 593 617 if (p.data) … … 677 701 size_t newsize = void; 678 702 679 703 asm 680 704 { 681 705 mov EAX,newlength ; 682 706 mul EAX,sizeelem ; 683 707 mov newsize,EAX ; 684 708 jc Loverflow ; 685 709 } 686 710 } 711 else version (D_InlineAsm_X86_64) 712 asm 713 { 714 mov RAX,size ; 715 mul RAX,length ; 716 mov size,RAX ; 717 jc Loverflow ; 718 } 687 719 else 688 720 { 689 721 size_t newsize = sizeelem * newlength; 690 722 691 723 if (newsize / newlength != sizeelem) 692 724 goto Loverflow; 693 725 } 694 726 //printf("newsize = %x, newlength = %x\n", newsize, newlength); 695 727 696 728 size_t size = p.length * sizeelem; branches/phobos-1.x/phobos/internal/gc/gcx.d
r1371 r1728 1824 1824 1825 1825 /** 1826 1826 * Return number of full pages free'd. 1827 1827 */ 1828 1828 size_t fullcollectshell() 1829 1829 { 1830 1830 // The purpose of the 'shell' is to ensure all the registers 1831 1831 // get put on the stack so they'll be scanned 1832 1832 void *sp; 1833 1833 size_t result; 1834 asm 1835 { 1836 pushad ; 1837 mov sp[EBP],ESP ; 1838 } 1834 version (D_InlineAsm_X86) 1835 asm 1836 { 1837 pushad ; 1838 mov sp[EBP],ESP ; 1839 } 1840 else version (D_InlineAsm_X86_64) 1841 asm 1842 { 1843 pushad ; 1844 mov sp[EBP],ESP ; 1845 } 1846 else 1847 static assert(0); 1839 1848 result = fullcollect(sp); 1840 1849 asm 1841 1850 { 1842 1851 popad ; 1843 1852 } 1844 1853 return result; 1845 1854 } 1846 1855 1847 1856 1848 1857 /** branches/phobos-1.x/phobos/internal/gc/win32.d
r295 r1728 67 67 //printf("pthread_self() = %x\n", GetCurrentThreadId()); 68 68 return cast(pthread_t) GetCurrentThreadId(); 69 69 } 70 70 71 71 /********************************************** 72 72 * Determine "bottom" of stack (actually the top on Win32 systems). 73 73 */ 74 74 75 75 void *os_query_stackBottom() 76 76 { 77 asm 78 { 79 naked ; 80 mov EAX,FS:4 ; 81 ret ; 82 } 77 version (D_InlineAsm_X86) 78 asm 79 { 80 naked ; 81 mov EAX,FS:4 ; 82 ret ; 83 } 84 else version (D_InlineAsm_X86_64) 85 asm 86 { 87 naked ; 88 mov RAX,FS:8 ; 89 ret ; 90 } 91 else 92 static assert(0); 83 93 } 84 94 85 95 /********************************************** 86 96 * Determine base address and size of static data segment. 87 97 */ 88 98 89 99 extern (C) 90 100 { 91 101 extern int _xi_a; // &_xi_a just happens to be start of data segment 92 102 extern int _edata; // &_edata is start of BSS segment branches/phobos-1.x/phobos/internal/llmath.d
r1701 r1728 12 12 * Unsigned long divide. 13 13 * Input: 14 14 * [EDX,EAX],[ECX,EBX] 15 15 * Output: 16 16 * [EDX,EAX] = [EDX,EAX] / [ECX,EBX] 17 17 * [ECX,EBX] = [EDX,EAX] % [ECX,EBX] 18 18 */ 19 19 20 20 void __ULDIV__() 21 21 { 22 version (D_InlineAsm_X86) 22 23 asm 23 24 { 24 25 naked ; 25 26 test ECX,ECX ; 26 27 jz uldiv ; 27 28 28 29 // if ECX > EDX, then quotient is 0 and remainder is [EDX,EAX] 29 30 cmp ECX,EDX ; 30 31 ja quo0 ; 31 32 … … 169 170 quo1: // Quotient is 1 170 171 // Remainder is [EDX,EAX] - [ECX,EBX] 171 172 sub EAX,EBX ; 172 173 sbb EDX,ECX ; 173 174 mov EBX,EAX ; 174 175 mov ECX,EDX ; 175 176 mov EAX,1 ; 176 177 xor EDX,EDX ; 177 178 ret ; 178 179 } 180 else version (D_InlineAsm_X86_64) 181 static assert(0); 182 else 183 static assert(0); 179 184 } 180 185 181 186 182 187 /*************************************** 183 188 * Signed long divide. 184 189 * Input: 185 190 * [EDX,EAX],[ECX,EBX] 186 191 * Output: 187 192 * [EDX,EAX] = [EDX,EAX] / [ECX,EBX] 188 193 * [ECX,EBX] = [EDX,EAX] % [ECX,EBX] 189 194 * ESI,EDI destroyed 190 195 */ 191 196 192 197 void __LDIV__() 193 198 { 199 version (D_InlineAsm_X86) 194 200 asm 195 201 { 196 202 naked ; 197 203 test EDX,EDX ; // [EDX,EAX] negative? 198 204 jns L10 ; // no 199 205 //neg64 EDX,EAX ; // [EDX,EAX] = -[EDX,EAX] 200 206 neg EDX ; 201 207 neg EAX ; 202 208 sbb EDX,0 ; 203 209 test ECX,ECX ; // [ECX,EBX] negative? … … 232 238 sbb ECX,0 ; 233 239 call __ULDIV__ ; 234 240 //neg64 EDX,EAX ; // quotient is negative 235 241 neg EDX ; 236 242 neg EAX ; 237 243 sbb EDX,0 ; 238 244 ret ; 239 245 240 246 L12: jmp __ULDIV__ ; 241 247 } 248 else version (D_InlineAsm_X86_64) 249 static assert(0); 250 else 251 static assert(0); 242 252 } 243 253 244 254 245 255 /*************************************** 246 256 * Compare [EDX,EAX] with [ECX,EBX] 247 257 * Signed 248 258 * Returns result in flags 249 259 */ 250 260 251 261 void __LCMP__() 252 262 { 263 version (D_InlineAsm_X86) 253 264 asm 254 265 { 255 266 naked ; 256 267 cmp EDX,ECX ; 257 268 jne C1 ; 258 269 push EDX ; 259 270 xor EDX,EDX ; 260 271 cmp EAX,EBX ; 261 272 jz C2 ; 262 273 ja C3 ; 263 274 dec EDX ; 264 275 pop EDX ; 265 276 ret ; 266 277 267 278 C3: inc EDX ; 268 279 C2: pop EDX ; 269 280 C1: ret ; 270 281 } 282 else version (D_InlineAsm_X86_64) 283 static assert(0); 284 else 285 static assert(0); 271 286 } 272 287 273 288 274 289 275 290 276 291 // Convert ulong to real 277 292 278 293 private real adjust = cast(real)0x800_0000_0000_0000 * 0x10; 279 294 280 295 real __U64_LDBL() 281 296 { 282 297 version (OSX) 283 298 { 299 version (D_InlineAsm_X86) 284 300 asm 285 301 { naked ; 286 302 push EDX ; 287 303 push EAX ; 288 304 and dword ptr 4[ESP], 0x7FFFFFFF ; 289 305 fild qword ptr [ESP] ; 290 306 test EDX,EDX ; 291 307 jns L1 ; 292 308 push 0x0000403e ; 293 309 push 0x80000000 ; 294 310 push 0 ; 295 311 fld real ptr [ESP] ; // adjust 296 312 add ESP,12 ; 297 313 faddp ST(1), ST ; 298 314 L1: ; 299 315 add ESP, 8 ; 300 316 ret ; 301 317 } 318 else version (D_InlineAsm_X86_64) 319 static assert(0); 320 else 321 static assert(0); 302 322 } 303 323 else 304 324 { 325 version (D_InlineAsm_X86) 305 326 asm 306 327 { naked ; 307 328 push EDX ; 308 329 push EAX ; 309 330 and dword ptr 4[ESP], 0x7FFFFFFF ; 310 331 fild qword ptr [ESP] ; 311 332 test EDX,EDX ; 312 333 jns L1 ; 313 334 fld real ptr adjust ; 314 335 faddp ST(1), ST ; 315 336 L1: ; 316 337 add ESP, 8 ; 317 338 ret ; 318 339 } 340 else version (D_InlineAsm_X86_64) 341 static assert(0); 342 else 343 static assert(0); 319 344 } 320 345 } 321 346 322 347 // Same as __U64_LDBL, but return result as double in [EDX,EAX] 323 348 ulong __ULLNGDBL() 324 349 { 350 version (D_InlineAsm_X86) 325 351 asm 326 352 { naked ; 327 353 call __U64_LDBL ; 328 354 sub ESP,8 ; 329 355 fstp double ptr [ESP] ; 330 356 pop EAX ; 331 357 pop EDX ; 332 358 ret ; 333 359 } 360 else version (D_InlineAsm_X86_64) 361 static assert(0); 362 else 363 static assert(0); 334 364 } 335 365 336 366 // Convert double to ulong 337 367 338 368 private short roundTo0 = 0xFBF; 339 369 340 370 ulong __DBLULLNG() 341 371 { 342 372 // BUG: should handle NAN's and overflows 343 373 version (OSX) 344 374 { 375 version (D_InlineAsm_X86) 345 376 asm 346 377 { naked ; 347 378 push 0xFBF ; // roundTo0 348 379 push 0x0000403e ; 349 380 push 0x80000000 ; 350 381 push 0 ; // adjust 351 382 push EDX ; 352 383 push EAX ; 353 384 fld double ptr [ESP] ; 354 385 sub ESP,8 ; … … 369 400 add EDX,0x8000_0000 ; 370 401 ret ; 371 402 L1: ; 372 403 fistp qword ptr [ESP] ; 373 404 pop EAX ; 374 405 pop EDX ; 375 406 fldcw [ESP] ; 376 407 add ESP,24 ; 377 408 ret ; 378 409 } 410 else version (D_InlineAsm_X86_64) 411 static assert(0); 412 else 413 static assert(0); 379 414 } 380 415 else 381 416 { 417 version (D_InlineAsm_X86) 382 418 asm 383 419 { naked ; 384 420 push EDX ; 385 421 push EAX ; 386 422 fld double ptr [ESP] ; 387 423 sub ESP,8 ; 388 424 fld real ptr adjust ; 389 425 fcomp ; 390 426 fstsw AX ; 391 427 fstcw 8[ESP] ; … … 402 438 add EDX,0x8000_0000 ; 403 439 ret ; 404 440 L1: ; 405 441 fistp qword ptr [ESP] ; 406 442 pop EAX ; 407 443 pop EDX ; 408 444 fldcw [ESP] ; 409 445 add ESP,8 ; 410 446 ret ; 411 447 } 448 else version (D_InlineAsm_X86_64) 449 static assert(0); 450 else 451 static assert(0); 412 452 } 413 453 } 414 454 415 455 // Convert double in ST0 to uint 416 456 417 457 uint __DBLULNG() 418 458 { 419 459 // BUG: should handle NAN's and overflows 420 460 version (OSX) 421 461 { 462 version (D_InlineAsm_X86) 422 463 asm 423 464 { naked ; 424 465 push 0xFBF ; // roundTo0 425 466 sub ESP,12 ; 426 467 fstcw 8[ESP] ; 427 468 fldcw 12[ESP] ; // roundTo0 428 469 fistp qword ptr [ESP] ; 429 470 fldcw 8[ESP] ; 430 471 pop EAX ; 431 472 add ESP,12 ; 432 473 ret ; 433 474 } 475 else version (D_InlineAsm_X86_64) 476 static assert(0); 477 else 478 static assert(0); 434 479 } 435 480 else 436 481 { 482 version (D_InlineAsm_X86) 437 483 asm 438 484 { naked ; 439 485 sub ESP,16 ; 440 486 fstcw 8[ESP] ; 441 487 fldcw roundTo0 ; 442 488 fistp qword ptr [ESP] ; 443 489 fldcw 8[ESP] ; 444 490 pop EAX ; 445 491 add ESP,12 ; 446 492 ret ; 447 493 } 494 else version (D_InlineAsm_X86_64) 495 static assert(0); 496 else 497 static assert(0); 448 498 } 449 499 } 450 500 451 501 // Convert real in ST0 to ulong 452 502 453 503 ulong __LDBLULLNG() 454 504 { 455 505 version (OSX) 456 506 { 507 version (D_InlineAsm_X86) 457 508 asm 458 509 { naked ; 459 510 push 0xFBF ; // roundTo0 460 511 push 0x0000403e ; 461 512 push 0x80000000 ; 462 513 push 0 ; // adjust 463 514 sub ESP,16 ; 464 515 fld real ptr 16[ESP] ; // adjust 465 516 fcomp ; 466 517 fstsw AX ; … … 478 529 add EDX,0x8000_0000 ; 479 530 ret ; 480 531 L1: ; 481 532 fistp qword ptr [ESP] ; 482 533 pop EAX ; 483 534 pop EDX ; 484 535 fldcw [ESP] ; 485 536 add ESP,24 ; 486 537 ret ; 487 538 } 539 else version (D_InlineAsm_X86_64) 540 static assert(0); 541 else 542 static assert(0); 488 543 } 489 544 else 490 545 { 546 version (D_InlineAsm_X86) 491 547 asm 492 548 { naked ; 493 549 sub ESP,16 ; 494 550 fld real ptr adjust ; 495 551 fcomp ; 496 552 fstsw AX ; 497 553 fstcw 8[ESP] ; 498 554 fldcw roundTo0 ; 499 555 sahf ; 500 556 jae L1 ; … … 508 564 add EDX,0x8000_0000 ; 509 565 ret ; 510 566 L1: ; 511 567 fistp qword ptr [ESP] ; 512 568 pop EAX ; 513 569 pop EDX ; 514 570 fldcw [ESP] ; 515 571 add ESP,8 ; 516 572 ret ; 517 573 } 518 } 519 } 520 574 else version (D_InlineAsm_X86_64) 575 static assert(0); 576 else 577 static assert(0); 578 } 579 } 580 branches/phobos-1.x/phobos/internal/trace.d
r1701 r1728 775 775 * ascii string 776 776 * or: 777 777 * db 0x0FF 778 778 * db 0 779 779 * dw length 780 780 * ascii string 781 781 */ 782 782 783 783 version (OSX) 784 784 { // 16 byte align stack 785 version (D_InlineAsm_X86) 785 786 asm 786 787 { naked ; 787 788 pushad ; 788 789 mov ECX,8*4[ESP] ; 789 790 xor EAX,EAX ; 790 791 mov AL,[ECX] ; 791 792 cmp AL,0xFF ; 792 793 jne L1 ; 793 794 cmp byte ptr 1[ECX],0 ; 794 795 jne L1 ; … … 800 801 add 8*4[ESP],EAX ; 801 802 dec EAX ; 802 803 sub ESP,4 ; 803 804 push ECX ; 804 805 push EAX ; 805 806 call trace_pro ; 806 807 add ESP,12 ; 807 808 popad ; 808 809 ret ; 809 810 } 811 else version (D_InlineAsm_X86_64) 812 static assert(0); 813 else 814 static assert(0); 810 815 } 811 816 else 812 817 { 818 version (D_InlineAsm_X86) 813 819 asm 814 820 { naked ; 815 821 pushad ; 816 822 mov ECX,8*4[ESP] ; 817 823 xor EAX,EAX ; 818 824 mov AL,[ECX] ; 819 825 cmp AL,0xFF ; 820 826 jne L1 ; 821 827 cmp byte ptr 1[ECX],0 ; 822 828 jne L1 ; … … 827 833 inc ECX ; 828 834 add 8*4[ESP],EAX ; 829 835 dec EAX ; 830 836 push ECX ; 831 837 push EAX ; 832 838 call trace_pro ; 833 839 add ESP,8 ; 834 840 popad ; 835 841 ret ; 836 842 } 843 else version (D_InlineAsm_X86_64) 844 static assert(0); 845 else 846 static assert(0); 837 847 } 838 848 } 839 849 840 850 ///////////////////////////////////////////// 841 851 // Function called by trace code in function epilog. 842 852 843 853 844 854 void _trace_epi_n() 845 855 { 846 856 version (OSX) 847 857 { // 16 byte align stack 858 version (D_InlineAsm_X86) 859 { 848 860 asm 849 861 { naked ; 850 862 pushad ; 851 863 sub ESP,12 ; 852 864 } 853 865 trace_epi(); 854 866 asm 855 867 { 856 868 add ESP,12 ; 857 869 popad ; 858 870 ret ; 859 871 } 872 } 873 else version (D_InlineAsm_X86_64) 874 static assert(0); 875 else 876 static assert(0); 860 877 } 861 878 else 862 879 { 880 version (D_InlineAsm_X86) 881 { 863 882 asm 864 883 { naked ; 865 884 pushad ; 866 885 } 867 886 trace_epi(); 868 887 asm 869 888 { 870 889 popad ; 871 890 ret ; 872 891 } 892 } 893 else version (D_InlineAsm_X86_64) 894 static assert(0); 895 else 896 static assert(0); 873 897 } 874 898 } 875 899 876 900 877 901 version (Win32) 878 902 { 879 903 extern (Windows) 880 904 { 881 905 export int QueryPerformanceCounter(timer_t *); 882 906 export int QueryPerformanceFrequency(timer_t *); 883 907 } 884 908 } 885 909 else version (X86) 886 910 { 887 911 extern (D) 888 912 { 889 913 void QueryPerformanceCounter(timer_t* ctr) 890 914 { 915 version (D_InlineAsm_X86) 891 916 asm 892 917 { naked ; 893 918 mov ECX,EAX ; 894 919 rdtsc ; 895 920 mov [ECX],EAX ; 896 921 mov 4[ECX],EDX ; 897 922 ret ; 898 923 } 924 else version (D_InlineAsm_X86_64) 925 static assert(0); 926 else 927 static assert(0); 899 928 } 900 929 901 930 void QueryPerformanceFrequency(timer_t* freq) 902 931 { 903 932 *freq = 3579545; 904 933 } 905 934 } 906 935 } 907 936 else 908 937 { branches/phobos-1.x/phobos/std/cpuid.d
r1539 r1728 215 215 uint maxCores=1; 216 216 uint manufac=OTHER; 217 217 218 218 /* ** 219 219 * fetches the cpu vendor string 220 220 */ 221 221 private void getVendorString() 222 222 { 223 223 char* dst = vendorStr.ptr; 224 224 // puts the vendor string into dst 225 asm 226 { 227 mov EAX, 0 ; 228 cpuid ; 229 mov EAX, dst ; 230 mov [EAX], EBX ; 231 mov [EAX+4], EDX ; 232 mov [EAX+8], ECX ; 233 } 225 version (D_InlineAsm_X86) 226 asm 227 { 228 mov EAX, 0 ; 229 cpuid ; 230 mov EAX, dst ; 231 mov [EAX], EBX ; 232 mov [EAX+4], EDX ; 233 mov [EAX+8], ECX ; 234 } 235 else version (D_InlineAsm_X86_64) 236 static assert(0); 237 else 238 static assert(0); 234 239 } 235 240 236 241 private void getProcessorString() 237 242 { 238 243 char[48] buffer; 239 244 char* dst = buffer.ptr; 240 245 // puts the processor string into dst 246 version (D_InlineAsm_X86) 241 247 asm 242 248 { 243 249 mov EAX, 0x8000_0000 ; 244 250 cpuid ; 245 251 cmp EAX, 0x8000_0004 ; 246 252 jb PSLabel ; // no support 247 253 push EDI ; 248 254 mov EDI, dst ; 249 255 mov EAX, 0x8000_0002 ; 250 256 cpuid ; … … 260 266 mov [EDI+28], EDX ; 261 267 mov EAX, 0x8000_0004 ; 262 268 cpuid ; 263 269 mov [EDI+32], EAX ; 264 270 mov [EDI+36], EBX ; 265 271 mov [EDI+40], ECX ; 266 272 mov [EDI+44], EDX ; 267 273 pop EDI ; 268 274 PSLabel: ; 269 275 } 276 else version (D_InlineAsm_X86_64) 277 static assert(0); 278 else 279 static assert(0); 270 280 271 281 if (buffer[0] == char.init) // no support 272 282 return; 273 283 274 284 // seems many intel processors prepend whitespace 275 285 processorStr = std.string.strip(std.string.toString(dst)).dup; 276 286 } 277 287 278 288 private void getFeatureFlags() 279 289 { 280 290 uint f,m,e,a,s; 291 version (D_InlineAsm_X86) 281 292 asm 282 293 { 283 294 mov EAX, 0 ; 284 295 cpuid ; 285 296 cmp EAX, 1 ; 286 297 jb FeatLabel ; // no support 287 298 mov EAX, 1 ; 288 299 cpuid ; 289 300 mov f, EDX ; 290 301 mov m, ECX ; … … 296 307 cpuid ; 297 308 cmp EAX, 0x8000_0001 ; 298 309 jb FeatLabel2 ; // no support 299 310 mov EAX, 0x8000_0001 ; 300 311 cpuid ; 301 312 mov e, EDX ; 302 313 303 314 FeatLabel2: 304 315 ; 305 316 } 317 else version (D_InlineAsm_X86_64) 318 static assert(0); 319 else 320 static assert(0); 306 321 flags = f; 307 322 misc = m; 308 323 exflags = e; 309 324 apic = a; 310 325 signature = s; 311 326 } 312 327 313 328 private void getThreadingIntel() 314 329 { 315 330 uint n; 316 331 ubyte b = 0; 332 version (D_InlineAsm_X86) 317 333 asm 318 334 { 319 335 mov EAX, 0 ; 320 336 cpuid ; 321 337 cmp EAX, 4 ; 322 338 jb IntelSingle ; 323 339 mov EAX, 4 ; 324 340 mov ECX, 0 ; 325 341 cpuid ; 326 342 mov n, EAX ; 327 343 mov b, 1 ; 328 344 IntelSingle: ; 329 345 } 346 else version (D_InlineAsm_X86_64) 347 static assert(0); 348 else 349 static assert(0); 330 350 if (b != 0) 331 351 { 332 352 maxCores = ((n>>>26)&0x3F)+1; 333 353 maxThreads = (apic>>>16)&0xFF; 334 354 } 335 355 else 336 356 { 337 357 maxCores = maxThreads = 1; 338 358 } 339 359 } 340 360 341 361 private void getThreadingAMD() 342 362 { 343 363 ubyte n; 344 364 ubyte b = 0; 365 version (D_InlineAsm_X86) 345 366 asm 346 367 { 347 368 mov EAX, 0x8000_0000 ; 348 369 cpuid ; 349 370 cmp EAX, 0x8000_0008 ; 350 371 jb AMDSingle ; 351 372 mov EAX, 0x8000_0008 ; 352 373 cpuid ; 353 374 mov n, CL ; 354 375 mov b, 1 ; 355 376 AMDSingle: ; 356 377 } 378 else version (D_InlineAsm_X86_64) 379 static assert(0); 380 else 381 static assert(0); 357 382 if (b != 0) 358 383 { 359 384 maxCores = n+1; 360 385 maxThreads = (apic>>>16)&0xFF; 361 386 } 362 387 else 363 388 { 364 389 maxCores = maxThreads = 1; 365 390 } 366 391 } branches/phobos-1.x/phobos/std/math.d
r1539 r1728 384 384 * $(TABLE_SV 385 385 * $(TR $(TH x) $(TH tan(x)) $(TH invalid?)) 386 386 * $(TR $(TD $(NAN)) $(TD $(NAN)) $(TD yes)) 387 387 * $(TR $(TD $(PLUSMN)0.0) $(TD $(PLUSMN)0.0) $(TD no)) 388 388 * $(TR $(TD $(PLUSMNINF)) $(TD $(NAN)) $(TD yes)) 389 389 * ) 390 390 */ 391 391 392 392 real tan(real x) 393 393 { 394 version(Naked_D_InlineAsm_X86) { 394 version(Naked_D_InlineAsm_X86) 395 { 395 396 asm 396 397 { 397 398 fld x[EBP] ; // load theta 398 399 fxam ; // test for oddball values 399 400 fstsw AX ; 400 401 sahf ; 401 402 jc trigerr ; // x is NAN, infinity, or empty 402 403 // 387's can handle denormals 403 404 SC18: fptan ; 404 405 fstp ST(0) ; // dump X, which is always 1 branches/phobos-1.x/phobos/std/thread.d
r1539 r1728 599 599 } 600 600 } 601 601 602 602 603 603 /********************************************** 604 604 * Determine "bottom" of stack (actually the top on Win32 systems). 605 605 */ 606 606 607 607 void *os_query_stackBottom() 608 608 { 609 version (D_InlineAsm_X86) 609 610 asm 610 611 { 611 612 naked ; 612 613 mov EAX,FS:4 ; 613 614 ret ; 614 615 } 616 else version (D_InlineAsm_X86_64) 617 asm 618 { 619 naked ; 620 mov RAX,FS:8 ; 621 ret ; 622 } 623 else 624 static assert(0); 615 625 } 616 626 617 627 } 618 628 619 629 /* ================================ Posix ================================= */ 620 630 621 631 version (Posix) 622 632 { 623 633 private import std.c.posix.posix; 624 634 private import std.c.posix.pthread; … … 1193 1203 extern (C) static void resumeHandler(int sig) 1194 1204 { 1195 1205 Thread t = getThis(); 1196 1206 1197 1207 t.flags |= 1; 1198 1208 } 1199 1209 } 1200 1210 1201 1211 public static void* getESP() 1202 1212 { 1203 asm 1204 { naked ; 1205 mov EAX,ESP ; 1206 ret ; 1207 } 1213 version (D_InlineAsm_X86) 1214 asm 1215 { naked ; 1216 mov EAX,ESP ; 1217 ret ; 1218 } 1219 else version (D_InlineAsm_X86_64) 1220 asm 1221 { naked ; 1222 mov RAX,RSP ; 1223 ret ; 1224 } 1225 else 1226 static assert(0); 1208 1227 } 1209 1228 } 1210 1229 1211 1230 1212 1231 } 1213 1232 branches/phobos-1.x/phobos/std/windows/registry.d
r1539 r1728 353 353 case Endian.Little: 354 354 return REG_VALUE_TYPE.REG_DWORD_LITTLE_ENDIAN; 355 355 356 356 default: 357 357 throw new RegistryException("Invalid Endian specified"); 358 358 } 359 359 } 360 360 361 361 private uint swap(in uint i) 362 362 { 363 version(X86) 363 version (D_InlineAsm_X86) 364 { 365 asm 366 { naked; 367 bswap EAX ; 368 ret ; 369 } 370 } 371 else version (D_InlineAsm_X86_64) 364 372 { 365 373 asm 366 374 { naked; 367 375 bswap EAX ; 368 376 ret ; 369 377 } 370 378 } 371 379 else 372 380 { 373 381 uint v_swap = (i & 0xff) << 24
