Changeset 39121 in webkit for trunk/JavaScriptCore/assembler/MacroAssembler.h
- Timestamp:
- Dec 8, 2008, 6:10:41 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/assembler/MacroAssembler.h
r39083 r39121 47 47 TimesTwo = 2, 48 48 TimesFour = 4, 49 TimesEight = 8 49 TimesEight = 8, 50 #if PLATFORM(X86) 51 ScalePtr = TimesFour 52 #endif 53 #if PLATFORM(X86_64) 54 ScalePtr = TimesEight 55 #endif 50 56 }; 51 57 … … 249 255 250 256 257 // ImmPtr: 258 // 259 // A pointer sized immediate operand to an instruction - this is wrapped 260 // in a class requiring explicit construction in order to differentiate 261 // from pointers used as absolute addresses to memory operations 262 struct ImmPtr { 263 explicit ImmPtr(void* value) 264 : m_value(value) 265 { 266 } 267 268 void* m_value; 269 }; 270 271 251 272 // Integer arithmetic operations: 252 273 // … … 286 307 void add32(Address src, RegisterID dest) 287 308 { 288 m_assembler.addl_mr(src.offset, src.base, dest); 309 if (src.offset) 310 m_assembler.addl_mr(src.offset, src.base, dest); 311 else 312 m_assembler.addl_mr(src.base, dest); 289 313 } 290 314 … … 294 318 } 295 319 320 void and32(Imm32 imm, RegisterID dest) 321 { 322 if (CAN_SIGN_EXTEND_8_32(imm.m_value)) 323 m_assembler.andl_i8r(imm.m_value, dest); 324 else 325 m_assembler.andl_i32r(imm.m_value, dest); 326 } 327 296 328 void lshift32(Imm32 imm, RegisterID dest) 297 329 { … … 304 336 } 305 337 338 void or32(RegisterID src, RegisterID dest) 339 { 340 m_assembler.orl_rr(src, dest); 341 } 342 306 343 void or32(Imm32 imm, RegisterID dest) 307 344 { … … 327 364 void sub32(Address src, RegisterID dest) 328 365 { 329 m_assembler.subl_mr(src.offset, src.base, dest); 330 } 331 366 if (src.offset) 367 m_assembler.subl_mr(src.offset, src.base, dest); 368 else 369 m_assembler.subl_mr(src.base, dest); 370 } 371 372 void xor32(RegisterID src, RegisterID dest) 373 { 374 m_assembler.xorl_rr(src, dest); 375 } 376 377 void xor32(Imm32 imm, RegisterID dest) 378 { 379 if (CAN_SIGN_EXTEND_8_32(imm.m_value)) 380 m_assembler.xorl_i8r(imm.m_value, dest); 381 else 382 m_assembler.xorl_i32r(imm.m_value, dest); 383 } 384 332 385 333 386 // Memory access operations: … … 346 399 m_assembler.movq_mr(address.base, dest); 347 400 #else 401 load32(address, dest); 402 #endif 403 } 404 405 #if !PLATFORM(X86_64) 406 void loadPtr(BaseIndex address, RegisterID dest) 407 { 408 load32(address, dest); 409 } 410 411 void loadPtr(void* address, RegisterID dest) 412 { 413 load32(address, dest); 414 } 415 #endif 416 417 void load32(ImplicitAddress address, RegisterID dest) 418 { 348 419 if (address.offset) 349 420 m_assembler.movl_mr(address.offset, address.base, dest); 350 421 else 351 422 m_assembler.movl_mr(address.base, dest); 352 #endif353 }354 355 void load32(ImplicitAddress address, RegisterID dest)356 {357 if (address.offset)358 m_assembler.movl_mr(address.offset, address.base, dest);359 else360 m_assembler.movl_mr(address.base, dest);361 423 } 362 424 … … 368 430 m_assembler.movl_mr(address.base, address.index, address.scale, dest); 369 431 } 432 433 #if !PLATFORM(X86_64) 434 void load32(void* address, RegisterID dest) 435 { 436 m_assembler.movl_mr(address, dest); 437 } 438 #endif 370 439 371 440 void load16(BaseIndex address, RegisterID dest) … … 393 462 394 463 #if !PLATFORM(X86_64) 395 void storePtr(void* value, ImplicitAddress address) 396 { 397 if (address.offset) 398 m_assembler.movl_i32m(reinterpret_cast<unsigned>(value), address.offset, address.base); 399 else 400 m_assembler.movl_i32m(reinterpret_cast<unsigned>(value), address.base); 464 void storePtr(ImmPtr imm, ImplicitAddress address) 465 { 466 if (address.offset) 467 m_assembler.movl_i32m(reinterpret_cast<unsigned>(imm.m_value), address.offset, address.base); 468 else 469 m_assembler.movl_i32m(reinterpret_cast<unsigned>(imm.m_value), address.base); 470 } 471 472 void storePtr(RegisterID src, BaseIndex address) 473 { 474 store32(src, address); 401 475 } 402 476 #endif … … 409 483 m_assembler.movl_rm(src, address.base); 410 484 } 411 485 486 void store32(RegisterID src, BaseIndex address) 487 { 488 if (address.offset) 489 m_assembler.movl_rm(src, address.offset, address.base, address.index, address.scale); 490 else 491 m_assembler.movl_rm(src, address.base, address.index, address.scale); 492 } 493 412 494 void store32(Imm32 imm, ImplicitAddress address) 413 495 { … … 473 555 474 556 #if !PLATFORM(X86_64) 475 void poke( void* value, int index = 0)476 { 477 storePtr( value, Address(X86::esp, (index * sizeof(void *))));557 void poke(ImmPtr imm, int index = 0) 558 { 559 storePtr(imm, Address(X86::esp, (index * sizeof(void *)))); 478 560 } 479 561 #endif … … 505 587 506 588 #if !PLATFORM(X86_64) 507 void move( void* value, RegisterID dest)508 { 509 m_assembler.movl_i32r(reinterpret_cast<int32_t>( value), dest);589 void move(ImmPtr imm, RegisterID dest) 590 { 591 m_assembler.movl_i32r(reinterpret_cast<int32_t>(imm.m_value), dest); 510 592 } 511 593 #endif … … 526 608 // jle32(reg1, Imm32(5)) will branch if the value held in reg1, when 527 609 // treated as a signed 32bit value, is less than or equal to 5. 610 // 611 // jz and jnz test whether the first operand is equal to zero, and take 612 // an optional second operand of a mask under which to perform the test. 528 613 529 614 private: … … 561 646 } 562 647 648 void testImm32(RegisterID reg, Imm32 mask) 649 { 650 // if we are only interested in the low seven bits, this can be tested with a testb 651 if (mask.m_value == -1) 652 m_assembler.testl_rr(reg, reg); 653 else if ((mask.m_value & ~0x7f) == 0) 654 m_assembler.testb_i8r(mask.m_value, reg); 655 else 656 m_assembler.testl_i32r(mask.m_value, reg); 657 } 658 659 void testImm32(Address address, Imm32 mask) 660 { 661 if (address.offset) { 662 if (mask.m_value == -1) 663 m_assembler.cmpl_i8m(0, address.offset, address.base); 664 else 665 m_assembler.testl_i32m(mask.m_value, address.offset, address.base); 666 } else { 667 if (mask.m_value == -1) 668 m_assembler.cmpl_i8m(0, address.base); 669 else 670 m_assembler.testl_i32m(mask.m_value, address.base); 671 } 672 } 673 674 void testImm32(BaseIndex address, Imm32 mask) 675 { 676 if (address.offset) { 677 if (mask.m_value == -1) 678 m_assembler.cmpl_i8m(0, address.offset, address.base, address.index, address.scale); 679 else 680 m_assembler.testl_i32m(mask.m_value, address.offset, address.base, address.index, address.scale); 681 } else { 682 if (mask.m_value == -1) 683 m_assembler.cmpl_i8m(0, address.base, address.index, address.scale); 684 else 685 m_assembler.testl_i32m(mask.m_value, address.base, address.index, address.scale); 686 } 687 } 688 563 689 public: 564 690 Jump jae32(RegisterID left, Imm32 right) … … 568 694 } 569 695 696 Jump jae32(RegisterID left, Address right) 697 { 698 if (right.offset) 699 m_assembler.cmpl_mr(right.offset, right.base, left); 700 else 701 m_assembler.cmpl_mr(right.base, left); 702 return Jump(m_assembler.jae()); 703 } 704 705 Jump jb32(RegisterID left, Address right) 706 { 707 if (right.offset) 708 m_assembler.cmpl_mr(right.offset, right.base, left); 709 else 710 m_assembler.cmpl_mr(right.base, left); 711 return Jump(m_assembler.jb()); 712 } 713 714 #if !PLATFORM(X86_64) 715 Jump jePtr(RegisterID op1, RegisterID op2) 716 { 717 return je32(op1, op2); 718 } 719 #endif 720 570 721 Jump je32(RegisterID op1, RegisterID op2) 571 722 { … … 585 736 return Jump(m_assembler.je()); 586 737 } 738 739 Jump je32(Address address, Imm32 imm) 740 { 741 compareImm32ForBranchEquality(address, imm.m_value); 742 return Jump(m_assembler.je()); 743 } 587 744 588 745 Jump je16(RegisterID op1, BaseIndex op2) … … 639 796 640 797 #if !PLATFORM(X86_64) 641 Jump jnePtr(void* ptr, Address address) 642 { 643 compareImm32ForBranchEquality(address, reinterpret_cast<uint32_t>(ptr)); 798 Jump jnePtr(RegisterID reg, Address address) 799 { 800 if (address.offset) 801 m_assembler.cmpl_rm(reg, address.offset, address.base); 802 else 803 m_assembler.cmpl_rm(reg, address.base); 644 804 return Jump(m_assembler.jne()); 805 } 806 807 Jump jnePtr(Address address, ImmPtr imm) 808 { 809 return jne32(address, Imm32(reinterpret_cast<int32_t>(imm.m_value))); 645 810 } 646 811 #endif … … 658 823 } 659 824 660 Jump jnset32(Imm32 imm, RegisterID reg) 661 { 662 // if we are only interested in the low seven bits, this can be tested with a testb 663 if ((imm.m_value & ~0x7f) == 0) 664 m_assembler.testb_i8r(imm.m_value, reg); 665 else 666 m_assembler.testl_i32r(imm.m_value, reg); 825 Jump jne32(Address address, Imm32 imm) 826 { 827 compareImm32ForBranchEquality(address, imm.m_value); 828 return Jump(m_assembler.jne()); 829 } 830 831 Jump jne32(Address address, RegisterID reg) 832 { 833 if (address.offset) 834 m_assembler.cmpl_rm(reg, address.offset, address.base); 835 else 836 m_assembler.cmpl_rm(reg, address.base); 837 return Jump(m_assembler.jne()); 838 } 839 840 #if !PLATFORM(X86_64) 841 Jump jnzPtr(RegisterID reg, Imm32 mask = Imm32(-1)) 842 { 843 return jnz32(reg, mask); 844 } 845 #endif 846 847 Jump jnz32(RegisterID reg, Imm32 mask = Imm32(-1)) 848 { 849 testImm32(reg, mask); 850 return Jump(m_assembler.jne()); 851 } 852 853 Jump jnz32(Address address, Imm32 mask = Imm32(-1)) 854 { 855 testImm32(address, mask); 856 return Jump(m_assembler.jne()); 857 } 858 859 #if !PLATFORM(X86_64) 860 Jump jzPtr(RegisterID reg, Imm32 mask = Imm32(-1)) 861 { 862 return jz32(reg, mask); 863 } 864 865 Jump jzPtr(BaseIndex address, Imm32 mask = Imm32(-1)) 866 { 867 return jz32(address, mask); 868 } 869 #endif 870 871 Jump jz32(RegisterID reg, Imm32 mask = Imm32(-1)) 872 { 873 testImm32(reg, mask); 667 874 return Jump(m_assembler.je()); 668 875 } 669 876 670 Jump jset32(Imm32 imm, RegisterID reg) 671 { 672 // if we are only interested in the low seven bits, this can be tested with a testb 673 if ((imm.m_value & ~0x7f) == 0) 674 m_assembler.testb_i8r(imm.m_value, reg); 675 else 676 m_assembler.testl_i32r(imm.m_value, reg); 677 return Jump(m_assembler.jne()); 877 Jump jz32(Address address, Imm32 mask = Imm32(-1)) 878 { 879 testImm32(address, mask); 880 return Jump(m_assembler.je()); 881 } 882 883 Jump jz32(BaseIndex address, Imm32 mask = Imm32(-1)) 884 { 885 testImm32(address, mask); 886 return Jump(m_assembler.je()); 678 887 } 679 888 … … 774 983 } 775 984 985 Jump joSub32(Imm32 imm, RegisterID dest) 986 { 987 sub32(imm, dest); 988 return Jump(m_assembler.jo()); 989 } 990 776 991 Jump jzSub32(Imm32 imm, RegisterID dest) 777 992 { … … 793 1008 } 794 1009 1010 // FIXME: why does this return a Jump object? - it can't be linked. 1011 // This may be to get a reference to the return address of the call. 1012 // 1013 // This should probably be handled by a separate label type to a regular 1014 // jump. Todo: add a CallLabel type, for the regular call - can be linked 1015 // like a jump (possibly a subclass of jump?, or possibly casts to a Jump). 1016 // Also add a CallReturnLabel type for this to return (just a more JmpDsty 1017 // form of label, can get the void* after the code has been linked, but can't 1018 // try to link it like a Jump object), and let the CallLabel be cast into a 1019 // CallReturnLabel. 795 1020 Jump call(RegisterID target) 796 1021 { … … 798 1023 } 799 1024 1025 void jump(RegisterID target) 1026 { 1027 m_assembler.jmp_r(target); 1028 } 1029 800 1030 void ret() 801 1031 { 802 1032 m_assembler.ret(); 803 1033 } 1034 1035 void sete32(RegisterID src, RegisterID srcDest) 1036 { 1037 m_assembler.cmpl_rr(srcDest, src); 1038 m_assembler.sete_r(srcDest); 1039 m_assembler.movzbl_rr(srcDest, srcDest); 1040 } 1041 1042 void sete32(Imm32 imm, RegisterID srcDest) 1043 { 1044 compareImm32ForBranchEquality(srcDest, imm.m_value); 1045 m_assembler.sete_r(srcDest); 1046 m_assembler.movzbl_rr(srcDest, srcDest); 1047 } 1048 1049 void setne32(RegisterID src, RegisterID srcDest) 1050 { 1051 m_assembler.cmpl_rr(srcDest, src); 1052 m_assembler.setne_r(srcDest); 1053 m_assembler.movzbl_rr(srcDest, srcDest); 1054 } 1055 1056 void setne32(Imm32 imm, RegisterID srcDest) 1057 { 1058 compareImm32ForBranchEquality(srcDest, imm.m_value); 1059 m_assembler.setne_r(srcDest); 1060 m_assembler.movzbl_rr(srcDest, srcDest); 1061 } 1062 1063 // FIXME: 1064 // The mask should be optional... paerhaps the argument order should be 1065 // dest-src, operations always have a dest? ... possibly not true, considering 1066 // asm ops like test, or pseudo ops like pop(). 1067 void setnz32(Address address, Imm32 mask, RegisterID dest) 1068 { 1069 testImm32(address, mask); 1070 m_assembler.setnz_r(dest); 1071 m_assembler.movzbl_rr(dest, dest); 1072 } 1073 1074 void setz32(Address address, Imm32 mask, RegisterID dest) 1075 { 1076 testImm32(address, mask); 1077 m_assembler.setz_r(dest); 1078 m_assembler.movzbl_rr(dest, dest); 1079 } 804 1080 }; 805 1081
Note:
See TracChangeset
for help on using the changeset viewer.