Changeset 756:a58784e0f035
- Timestamp:
- 11/08/08 16:29:19 (2 months ago)
- Files:
-
- dmd/statement.h (modified) (1 diff)
- gen/asm-x86-32.h (moved) (moved from gen/d-asm-i386.h) (10 diffs)
- gen/asm-x86-64.h (moved) (moved from gen/d-asm-i386.h) (45 diffs)
- gen/asmstmt.cpp (modified) (9 diffs)
- tests/mini/asm1.d (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
dmd/statement.h
r664 r756 891 891 unsigned refparam; // !=0 if function parameter is referenced 892 892 unsigned naked; // !=0 if function is to be naked 893 unsigned regs; // mask of registers modified894 893 895 894 AsmStatement(Loc loc, Token *tokens); gen/asm-x86-32.h
r751 r756 3 3 4 4 #include "id.h" 5 6 namespace AsmParserx8632 { 5 7 6 8 typedef enum { … … 18 20 Reg_MM0, Reg_MM1, Reg_MM2, Reg_MM3, Reg_MM4, Reg_MM5, Reg_MM6, Reg_MM7, 19 21 Reg_XMM0, Reg_XMM1, Reg_XMM2, Reg_XMM3, Reg_XMM4, Reg_XMM5, Reg_XMM6, Reg_XMM7, 20 // will need 64-bit rax,etc. eventually21 22 // xmm8-15? 22 23 Reg_EFLAGS, … … 1349 1350 1350 1351 if ( matchOperands(operand_i) ) { 1351 AsmCode * asmcode = new AsmCode ;1352 AsmCode * asmcode = new AsmCode(N_Regs); 1352 1353 1353 1354 if (formatInstruction(operand_i, asmcode)) … … 1357 1358 1358 1359 void setAsmCode() { 1359 AsmCode * asmcode = new AsmCode ;1360 AsmCode * asmcode = new AsmCode(N_Regs); 1360 1361 asmcode->insnTemplateLen = insnTemplate->offset; 1361 1362 asmcode->insnTemplate = (char*) insnTemplate->extractData(); … … 1694 1695 case Clb_SizeAX: 1695 1696 case Clb_EAX: 1696 stmt->regs |= (1<<Reg_EAX);1697 asmcode->regs[Reg_EAX] = true; 1697 1698 break; 1698 1699 case Clb_SizeDXAX: 1699 stmt->regs |= (1<<Reg_EAX);1700 asmcode->regs[Reg_EAX] = true; 1700 1701 if (type_char != 'b') 1701 stmt->regs |= (1<<Reg_EDX);1702 asmcode->regs[Reg_EDX] = true; 1702 1703 break; 1703 1704 default: … … 1707 1708 1708 1709 if (opInfo->implicitClobbers & Clb_DI) 1709 stmt->regs |= (1 << Reg_EDI);1710 asmcode->regs[Reg_EDI] = true; 1710 1711 if (opInfo->implicitClobbers & Clb_SI) 1711 stmt->regs |= (1 << Reg_ESI);1712 asmcode->regs[Reg_ESI] = true; 1712 1713 if (opInfo->implicitClobbers & Clb_CX) 1713 stmt->regs |= (1 << Reg_ECX);1714 asmcode->regs[Reg_ECX] = true; 1714 1715 if (opInfo->implicitClobbers & Clb_SP) 1715 stmt->regs |= (1 << Reg_ESP);1716 asmcode->regs[Reg_ESP] = true; 1716 1717 if (opInfo->implicitClobbers & Clb_ST) 1717 1718 { … … 1721 1722 operand it would work... In any case, clobbering 1722 1723 all FP prevents incorrect code generation. */ 1723 stmt->regs |= (1 << Reg_ST);1724 stmt->regs |= (1 << Reg_ST1);1725 stmt->regs |= (1 << Reg_ST2);1726 stmt->regs |= (1 << Reg_ST3);1727 stmt->regs |= (1 << Reg_ST4);1728 stmt->regs |= (1 << Reg_ST5);1729 stmt->regs |= (1 << Reg_ST6);1730 stmt->regs |= (1 << Reg_ST7);1724 asmcode->regs[Reg_ST] = true; 1725 asmcode->regs[Reg_ST1] = true; 1726 asmcode->regs[Reg_ST2] = true; 1727 asmcode->regs[Reg_ST3] = true; 1728 asmcode->regs[Reg_ST4] = true; 1729 asmcode->regs[Reg_ST5] = true; 1730 asmcode->regs[Reg_ST6] = true; 1731 asmcode->regs[Reg_ST7] = true; 1731 1732 } 1732 1733 if (opInfo->implicitClobbers & Clb_Flags) 1733 asmcode->moreRegs |= (1 << (Reg_EFLAGS - 32)); 1734 if (op == Op_cpuid) 1735 stmt->regs |= (1 << Reg_EAX)| 1736 (1 << Reg_ECX)|(1 << Reg_EDX); 1734 asmcode->regs[Reg_EFLAGS] = true; 1735 if (op == Op_cpuid) { 1736 asmcode->regs[Reg_EAX] = true; 1737 asmcode->regs[Reg_ECX] = true; 1738 asmcode->regs[Reg_EDX] = true; 1739 } 1737 1740 1738 1741 insnTemplate->writebyte(' '); … … 1807 1810 Reg clbr_reg = (Reg) regInfo[operand->reg].baseReg; 1808 1811 if (clbr_reg != Reg_Invalid) { 1809 if (clbr_reg < 32) 1810 stmt->regs |= (1 << clbr_reg); 1811 else 1812 asmcode->moreRegs |= (1 << (clbr_reg - 32)); 1812 asmcode->regs[clbr_reg] = true; 1813 1813 } 1814 1814 } … … 2637 2637 bool getFrameRelativeValue(LLValue* decl, HOST_WIDE_INT * result) 2638 2638 { 2639 assert(0); 2639 2640 // FIXME 2640 2641 // // Using this instead of DECL_RTL for struct args seems like a … … 2669 2670 return false; 2670 2671 } 2672 2673 2674 struct AsmParser : public AsmParserCommon 2675 { 2676 virtual void run(Scope* sc, AsmStatement* asmst) { 2677 AsmProcessor ap(sc, asmst); 2678 ap.run(); 2679 } 2680 2681 virtual std::string getRegName(int i) { 2682 return regInfo[i].gccName; 2683 } 2684 }; 2685 2686 } gen/asm-x86-64.h
r751 r756 3 3 4 4 #include "id.h" 5 6 namespace AsmParserx8664 { 5 7 6 8 typedef enum { … … 18 20 Reg_MM0, Reg_MM1, Reg_MM2, Reg_MM3, Reg_MM4, Reg_MM5, Reg_MM6, Reg_MM7, 19 21 Reg_XMM0, Reg_XMM1, Reg_XMM2, Reg_XMM3, Reg_XMM4, Reg_XMM5, Reg_XMM6, Reg_XMM7, 20 // will need 64-bit rax,etc. eventually 21 // xmm8-15? 22 23 Reg_RAX, Reg_RBX, Reg_RCX, Reg_RDX, Reg_RSI, Reg_RDI, Reg_RBP, Reg_RSP, 24 Reg_R8, Reg_R9, Reg_R10, Reg_R11, Reg_R12, Reg_R13, Reg_R14, Reg_R15, 25 Reg_R8B, Reg_R9B, Reg_R10B, Reg_R11B, Reg_R12B, Reg_R13B, Reg_R14B, Reg_R15B, 26 Reg_R8W, Reg_R9W, Reg_R10W, Reg_R11W, Reg_R12W, Reg_R13W, Reg_R14W, Reg_R15W, 27 Reg_R8D, Reg_R9D, Reg_R10D, Reg_R11D, Reg_R12D, Reg_R13D, Reg_R14D, Reg_R15D, 28 Reg_XMM8, Reg_XMM9, Reg_XMM10, Reg_XMM11, Reg_XMM12, Reg_XMM13, Reg_XMM14, Reg_XMM15, 29 Reg_RIP, 30 Reg_SIL, Reg_DIL, Reg_BPL, Reg_SPL, 31 22 32 Reg_EFLAGS, 23 33 Reg_CS, … … 35 45 36 46 static const int N_Regs = /*gp*/ 8 + /*fp*/ 8 + /*mmx*/ 8 + /*sse*/ 8 + 37 /*seg*/ 6 + /*16bit*/ 8 + /*8bit*/ 8 + /*sys*/ 4+6+5 + /*flags*/ + 1; 47 /*seg*/ 6 + /*16bit*/ 8 + /*8bit*/ 8 + /*sys*/ 4+6+5 + /*flags*/ + 1 48 + 8 /*RAX, etc*/ 49 + 8 /*R8-15*/ 50 + 4 /*SIL, etc. 8-bit*/ 51 + 8 /*R8-15B*/ 52 + 8 /*R8-15W*/ 53 + 8 /*R8-15D*/ 54 + 8 /*XMM8-15*/ 55 + 1 /*RIP*/ 56 57 ; 38 58 39 59 #define NULL_TREE "" … … 78 98 { "XMM6", NULL_TREE, NULL, 16, Reg_XMM6 }, 79 99 { "XMM7", NULL_TREE, NULL, 16, Reg_XMM7 }, 100 101 { "RAX", NULL_TREE, NULL, 8, Reg_RAX }, 102 { "RBX", NULL_TREE, NULL, 8, Reg_RBX }, 103 { "RCX", NULL_TREE, NULL, 8, Reg_RCX }, 104 { "RDX", NULL_TREE, NULL, 8, Reg_RDX }, 105 { "RSI", NULL_TREE, NULL, 8, Reg_RSI }, 106 { "RDI", NULL_TREE, NULL, 8, Reg_RDI }, 107 { "RBP", NULL_TREE, NULL, 8, Reg_RBP }, 108 { "RSP", NULL_TREE, NULL, 8, Reg_RSP }, 109 { "R8", NULL_TREE, NULL, 8, Reg_R8 }, 110 { "R9", NULL_TREE, NULL, 8, Reg_R9 }, 111 { "R10", NULL_TREE, NULL, 8, Reg_R10 }, 112 { "R11", NULL_TREE, NULL, 8, Reg_R11 }, 113 { "R12", NULL_TREE, NULL, 8, Reg_R12 }, 114 { "R13", NULL_TREE, NULL, 8, Reg_R13 }, 115 { "R14", NULL_TREE, NULL, 8, Reg_R14 }, 116 { "R15", NULL_TREE, NULL, 8, Reg_R15 }, 117 { "R8B", NULL_TREE, NULL, 1, Reg_R8 }, 118 { "R9B", NULL_TREE, NULL, 1, Reg_R9 }, 119 { "R10B", NULL_TREE, NULL, 1, Reg_R10 }, 120 { "R11B", NULL_TREE, NULL, 1, Reg_R11 }, 121 { "R12B", NULL_TREE, NULL, 1, Reg_R12 }, 122 { "R13B", NULL_TREE, NULL, 1, Reg_R13 }, 123 { "R14B", NULL_TREE, NULL, 1, Reg_R14 }, 124 { "R15B", NULL_TREE, NULL, 1, Reg_R15 }, 125 { "R8W", NULL_TREE, NULL, 2, Reg_R8 }, 126 { "R9W", NULL_TREE, NULL, 2, Reg_R9 }, 127 { "R10W", NULL_TREE, NULL, 2, Reg_R10 }, 128 { "R11W", NULL_TREE, NULL, 2, Reg_R11 }, 129 { "R12W", NULL_TREE, NULL, 2, Reg_R12 }, 130 { "R13W", NULL_TREE, NULL, 2, Reg_R13 }, 131 { "R14W", NULL_TREE, NULL, 2, Reg_R14 }, 132 { "R15W", NULL_TREE, NULL, 2, Reg_R15 }, 133 { "R8D", NULL_TREE, NULL, 4, Reg_R8 }, 134 { "R9D", NULL_TREE, NULL, 4, Reg_R9 }, 135 { "R10D", NULL_TREE, NULL, 4, Reg_R10 }, 136 { "R11D", NULL_TREE, NULL, 4, Reg_R11 }, 137 { "R12D", NULL_TREE, NULL, 4, Reg_R12 }, 138 { "R13D", NULL_TREE, NULL, 4, Reg_R13 }, 139 { "R14D", NULL_TREE, NULL, 4, Reg_R14 }, 140 { "R15D", NULL_TREE, NULL, 4, Reg_R15 }, 141 { "XMM8", NULL_TREE, NULL, 16, Reg_XMM8 }, 142 { "XMM9", NULL_TREE, NULL, 16, Reg_XMM9 }, 143 { "XMM10", NULL_TREE, NULL, 16, Reg_XMM10 }, 144 { "XMM11", NULL_TREE, NULL, 16, Reg_XMM11 }, 145 { "XMM12", NULL_TREE, NULL, 16, Reg_XMM12 }, 146 { "XMM13", NULL_TREE, NULL, 16, Reg_XMM13 }, 147 { "XMM14", NULL_TREE, NULL, 16, Reg_XMM14 }, 148 { "XMM15", NULL_TREE, NULL, 16, Reg_XMM15 }, 149 { "RIP", NULL_TREE, NULL, 8, Reg_RIP }, 150 { "SIL", NULL_TREE, NULL, 1, Reg_SIL }, 151 { "DIL", NULL_TREE, NULL, 1, Reg_DIL }, 152 { "BPL", NULL_TREE, NULL, 1, Reg_BPL }, 153 { "SPL", NULL_TREE, NULL, 1, Reg_SPL }, 154 80 155 { "FLAGS", NULL_TREE, NULL, 0, Reg_EFLAGS }, // the gcc name is "flags"; not used in assembler input 81 156 { "CS", NULL_TREE, NULL, 2, -1 }, … … 486 561 /* Op_outs */ { N|dx, mem, 0, 1, Clb_SI }, 487 562 /* Op_outsX */ { 0, 0, 0, 0, Clb_SI }, 488 /* Op_push */ { mri, 0, 0, Word_Types, Clb_SP }, // would be Op_SrcW, but DMD defaults to 32-bit for immediate form563 /* Op_push */ { mri, 0, 0, 0, Clb_SP }, // would be Op_SrcW, but DMD defaults to 32-bit for immediate form 489 564 /* Op_ret */ { imm, 0, 0, 0, 0, Next_Form, Op_0 }, 490 565 /* Op_retf */ { 0, 0, 0, 0, 0, Out_Mnemonic, Mn_lret }, … … 537 612 538 613 static AsmOpEnt opData[] = { 539 { "aaa", Op_Adjust },540 { "aad", Op_Adjust },541 { "aam", Op_Adjust },542 { "aas", Op_Adjust },543 614 { "adc", Op_UpdSrcF }, 544 { "add", Op_UpdSrcF }, 615 616 { "add", Op_DstSrcNT }, //Op_UpdSrcF }, 545 617 { "addpd", Op_DstSrcSSE }, 546 618 { "addps", Op_DstSrcSSE }, … … 549 621 { "addsubpd", Op_DstSrcSSE }, 550 622 { "addsubps", Op_DstSrcSSE }, 551 { "align", Op_Align },552 623 { "and", Op_UpdSrcF }, 553 624 { "andnpd", Op_DstSrcSSE }, … … 555 626 { "andpd", Op_DstSrcSSE }, 556 627 { "andps", Op_DstSrcSSE }, 557 { "arpl", Op_UpdSrcNT },558 { "bound", Op_bound },559 628 { "bsf", Op_SrcSrcFW }, 560 629 { "bsr", Op_SrcSrcFW }, … … 565 634 { "bts", Op_UpdSrcFW }, 566 635 { "call", Op_Branch }, 636 { "callf", Op_Branch }, 567 637 { "cbw", Op_0_AX }, 568 { "cdq ", Op_0_DXAX },638 { "cdqe", Op_0_DXAX }, 569 639 { "clc", Op_Flags }, 570 640 { "cld", Op_Flags }, … … 611 681 { "cmpss", Op_DstSrcImmS }, 612 682 { "cmpsw", Op_cmpsX }, 683 { "cmpsq", Op_cmpsX }, 684 /* 685 { "cdqe", Op_0_DXAX }, 686 { "cmpsq", Op_cmpsX }, 687 { "cmpxch16b", Op_cmpxchg16b }, 688 { "cqo", Op_0_DXAX }, 689 { "lodsq", Op_lodsX }, 690 { "movsq", Op_movsX }, 691 { "popfq", Op_SizedStack }, 692 { "pushfq", Op_SizedStack }, 693 { "scasq", Op_scasX }, 694 { "stosq", Op_stosX }, 695 { "iretq", Op_iretd }, 696 { "swapgs", Op_0 }, 697 { "extrq", Op_Extrq }, 698 { "movsxq", Op_movsxq }, 699 700 { "clgi", Op_Flags }, 701 { "invlpga", Op_SrcMemNT }, 702 { "rdtscp", Op_0_DXAX }, 703 { "stgi", Op_Flags }, 704 { "sysret", Op_0 }, 705 */ 706 707 { "cmpxch16b", Op_cmpxchg8b }, 613 708 { "cmpxch8b", Op_cmpxchg8b }, // %% DMD opcode typo? 614 709 { "cmpxchg", Op_cmpxchg }, … … 639 734 { "cvttss2si", Op_DstSrcSSE }, 640 735 { "cwd", Op_0_DXAX }, 641 { "cwde", Op_0_ AX },736 { "cwde", Op_0_DXAX }, 642 737 //{ "da", Op_ },// dunno what this is -- takes labels? 643 { "daa", Op_Adjust },644 { "das", Op_Adjust },645 738 { "db", Op_db }, 646 739 { "dd", Op_dd }, … … 661 754 { "emms", Op_0 }, // clobber all mmx/fp? 662 755 { "enter", Op_enter }, 663 { "even", Op_Even },664 756 { "f2xm1", Op_F0_ST }, // %% most of these are update... 665 757 { "fabs", Op_F0_ST }, … … 768 860 { "hsubps", Op_DstSrcSSE }, 769 861 { "idiv", Op_Src_DXAXF }, 770 { "imul", Op_imul},862 { "imul", Op_DstSrcNT }, 771 863 { "in", Op_in }, 772 864 { "inc", Op_UpdF }, … … 781 873 { "iret", Op_iret }, 782 874 { "iretd", Op_iretd }, 875 { "iretq", Op_iretd }, 783 876 { "ja", Op_CBranch }, 784 877 { "jae", Op_CBranch }, … … 794 887 { "jle", Op_CBranch }, 795 888 { "jmp", Op_Branch }, 889 { "jmpe", Op_Branch }, 890 { "jmpf", Op_Branch }, 796 891 { "jna", Op_CBranch }, 797 892 { "jnae", Op_CBranch }, … … 812 907 { "jpe", Op_CBranch }, 813 908 { "jpo", Op_CBranch }, 909 { "jrcxz", Op_CBranch }, 814 910 { "js", Op_CBranch }, 815 911 { "jz", Op_CBranch }, … … 820 916 { "lds", Op_DstSrc }, // reg dest only 821 917 { "lea", Op_DstSrc }, // " 918 { "leaq", Op_DstSrcSSE }, // " 822 919 { "leave", Op_0 }, // EBP,ESP clobbers 823 { "les", Op_DstSrc },824 920 { "lfence",Op_0 }, 825 921 { "lfs", Op_DstSrc }, … … 834 930 { "lodsd", Op_lodsX }, 835 931 { "lodsw", Op_lodsX }, 932 { "lodsq", Op_lodsX }, 836 933 { "loop", Op_Loop }, 837 934 { "loope", Op_Loop }, … … 855 952 { "monitor", Op_0 }, 856 953 { "mov", Op_DstSrc }, 954 { "movb", Op_DstSrcNT }, 857 955 { "movapd", Op_DstSrcSSE }, 858 956 { "movaps", Op_DstSrcSSE }, … … 880 978 { "movsb", Op_movsX }, 881 979 { "movsd", Op_movsd }, 980 { "movsq", Op_movsd }, 882 981 { "movshdup", Op_DstSrcSSE }, 883 982 { "movsldup", Op_DstSrcSSE }, … … 885 984 { "movsw", Op_movsX }, 886 985 { "movsx", Op_movsx }, // word-only, reg dest 986 { "movsxd", Op_movsx }, 887 987 { "movupd",Op_DstSrcSSE }, 888 988 { "movups",Op_DstSrcSSE }, 989 { "movzbl", Op_DstSrcNT }, 889 990 { "movzx", Op_movzx }, 890 { "mul", Op_ mul},991 { "mul", Op_DstSrcNT }, 891 992 { "mulpd", Op_DstSrcSSE }, 892 993 { "mulps", Op_DstSrcSSE }, … … 894 995 { "mulss", Op_DstSrcSSE }, 895 996 { "mwait", Op_0 }, 896 { "naked", Op_Naked },897 997 { "neg", Op_UpdF }, 898 998 { "nop", Op_0 }, … … 906 1006 { "outsd", Op_outsX }, 907 1007 { "outsw", Op_outsX }, 1008 { "pabsb", Op_DstSrcSSE }, 1009 { "pabsw", Op_DstSrcSSE }, 1010 { "pabsq", Op_DstSrcSSE }, 908 1011 { "packssdw", Op_DstSrcMMX }, // %% also SSE 909 1012 { "packsswb", Op_DstSrcMMX }, … … 917 1020 { "paddusw", Op_DstSrcMMX }, 918 1021 { "paddw", Op_DstSrcMMX }, 1022 { "palignr", Op_DstSrcSSE }, 919 1023 { "pand", Op_DstSrcMMX }, 920 1024 { "pandn", Op_DstSrcMMX }, 1025 { "pause", Op_DstSrcMMX }, 921 1026 { "pavgb", Op_DstSrcMMX }, 922 1027 { "pavgw", Op_DstSrcMMX }, … … 928 1033 { "pcmpgtw", Op_DstSrcMMX }, 929 1034 { "pextrw", Op_DstSrcImmM }, // gpr32 dest 1035 { "phaddd", Op_DstSrcSSE }, 1036 { "phaddsw", Op_DstSrcSSE }, 1037 { "phaddw", Op_DstSrcSSE }, 1038 { "phsubd", Op_DstSrcSSE }, 1039 { "phsubsw", Op_DstSrcSSE }, 1040 { "phsubw", Op_DstSrcSSE }, 930 1041 { "pinsrw", Op_DstSrcImmM }, // gpr32(16), mem16 src, sse too 1042 { "pmaddubsw", Op_DstSrcSSE }, 931 1043 { "pmaddwd", Op_DstSrcMMX }, 932 1044 { "pmaxsw", Op_DstSrcMMX }, … … 935 1047 { "pminub", Op_DstSrcMMX }, 936 1048 { "pmovmskb", Op_DstSrcMMX }, 1049 { "pmulhrsw", Op_DstSrcMMX }, 937 1050 { "pmulhuw", Op_DstSrcMMX }, 938 1051 { "pmulhw", Op_DstSrcMMX }, … … 940 1053 { "pmuludq", Op_DstSrcMMX }, // also sse 941 1054 { "pop", Op_DstW }, 942 { "popa", Op_SizedStack }, // For intel this is always 16-bit943 { "popad", Op_SizedStack }, // GAS doesn't accept 'popad' -- these clobber everything, but supposedly it would be used to preserve clobbered regs944 1055 { "popf", Op_SizedStack }, // rewrite the insn with a special case 945 { "popfd", Op_SizedStack }, 1056 { "popfq", Op_SizedStack }, 1057 { "popq", Op_push }, 946 1058 { "por", Op_DstSrcMMX }, 947 1059 { "prefetchnta", Op_SrcMemNT }, … … 950 1062 { "prefetcht2", Op_SrcMemNT }, 951 1063 { "psadbw", Op_DstSrcMMX }, 1064 { "pshufb", Op_DstSrcImmM }, 952 1065 { "pshufd", Op_DstSrcImmM }, 953 1066 { "pshufhw", Op_DstSrcImmM }, 954 1067 { "pshuflw", Op_DstSrcImmM }, 955 1068 { "pshufw", Op_DstSrcImmM }, 1069 { "psignb", Op_DstSrcSSE }, 1070 { "psignd", Op_DstSrcSSE }, 1071 { "psignw", Op_DstSrcSSE }, 956 1072 { "pslld", Op_DstSrcMMX }, // immediate operands... 957 1073 { "pslldq", Op_DstSrcMMX }, … … 981 1097 { "punpcklwd", Op_DstSrcMMX }, 982 1098 { "push", Op_push }, 983 { "pusha", Op_SizedStack },984 { "pushad", Op_SizedStack },985 1099 { "pushf", Op_SizedStack }, 986 { "pushfd", Op_SizedStack }, 1100 { "pushfq", Op_SizedStack }, 1101 { "pushq", Op_push }, 987 1102 { "pxor", Op_DstSrcMMX }, 988 1103 { "rcl", Op_Shift }, // limited src operands -- change to shift … … 1000 1115 { "ret", Op_ret }, 1001 1116 { "retf", Op_retf }, 1117 { "retn", Op_retf }, 1002 1118 { "rol", Op_Shift }, 1003 1119 { "ror", Op_Shift }, … … 1007 1123 { "sahf", Op_Flags }, 1008 1124 { "sal", Op_Shift }, 1125 { "salq", Op_DstSrcNT }, 1009 1126 { "sar", Op_Shift }, 1010 1127 { "sbb", Op_UpdSrcF }, … … 1013 1130 { "scasd", Op_scasX }, 1014 1131 { "scasw", Op_scasX }, 1132 { "scasq", Op_scasX }, 1015 1133 { "seta", Op_DstRMBNT }, // also gpr8 1016 1134 { "setae", Op_DstRMBNT }, … … 1066 1184 { "stosd", Op_stosX }, 1067 1185 { "stosw", Op_stosX }, 1186 { "stosq", Op_stosX }, 1068 1187 { "str", Op_DstMemNT }, // also r16 1069 1188 { "sub", Op_UpdSrcF }, … … 1072 1191 { "subsd", Op_DstSrcSSE }, 1073 1192 { "subss", Op_DstSrcSSE }, 1193 { "swapgs", Op_DstSrcSSE }, 1074 1194 { "sysenter",Op_0 }, 1075 1195 { "sysexit", Op_0 }, 1076 { "test", Op_SrcSrcF }, 1196 { "sysret", Op_0 }, 1197 { "testl", Op_DstSrcNT }, 1077 1198 { "ucomisd", Op_SrcSrcSSEF }, 1078 1199 { "ucomiss", Op_SrcSrcSSEF }, … … 1084 1205 { "verr", Op_SrcMemNTF }, 1085 1206 { "verw", Op_SrcMemNTF }, 1086 { "wait", Op_0 },1087 1207 { "wbinvd", Op_0 }, 1088 1208 { "wrmsr", Op_0 }, … … 1094 1214 { "xorpd", Op_DstSrcSSE }, 1095 1215 { "xorps", Op_DstSrcSSE }, 1216 { "xorq", Op_DstSrcNT }, 1096 1217 }; 1097 1218 … … 1349 1470 1350 1471 if ( matchOperands(operand_i) ) { 1351 AsmCode * asmcode = new AsmCode ;1472 AsmCode * asmcode = new AsmCode(N_Regs); 1352 1473 1353 1474 if (formatInstruction(operand_i, asmcode)) … … 1357 1478 1358 1479 void setAsmCode() { 1359 AsmCode * asmcode = new AsmCode ;1480 AsmCode * asmcode = new AsmCode(N_Regs); 1360 1481 asmcode->insnTemplateLen = insnTemplate->offset; 1361 1482 asmcode->insnTemplate = (char*) insnTemplate->extractData(); … … 1694 1815 case Clb_SizeAX: 1695 1816 case Clb_EAX: 1696 stmt->regs |= (1<<Reg_EAX);1817 asmcode->regs[Reg_EAX] = true; 1697 1818 break; 1698 1819 case Clb_SizeDXAX: 1699 stmt->regs |= (1<<Reg_EAX);1820 asmcode->regs[Reg_EAX] = true; 1700 1821 if (type_char != 'b') 1701 stmt->regs |= (1<<Reg_EDX);1822 asmcode->regs[Reg_EDX] = true; 1702 1823 break; 1703 1824 default: … … 1707 1828 1708 1829 if (opInfo->implicitClobbers & Clb_DI) 1709 stmt->regs |= (1 << Reg_EDI);1830 asmcode->regs[Reg_EDI] = true; 1710 1831 if (opInfo->implicitClobbers & Clb_SI) 1711 stmt->regs |= (1 << Reg_ESI);1832 asmcode->regs[Reg_ESI] = true; 1712 1833 if (opInfo->implicitClobbers & Clb_CX) 1713 stmt->regs |= (1 << Reg_ECX);1834 asmcode->regs[Reg_ECX] = true; 1714 1835 if (opInfo->implicitClobbers & Clb_SP) 1715 stmt->regs |= (1 << Reg_ESP);1836 asmcode->regs[Reg_ESP] = true; 1716 1837 if (opInfo->implicitClobbers & Clb_ST) 1717 1838 { … … 1721 1842 operand it would work... In any case, clobbering 1722 1843 all FP prevents incorrect code generation. */ 1723 stmt->regs |= (1 << Reg_ST);1724 stmt->regs |= (1 << Reg_ST1);1725 stmt->regs |= (1 << Reg_ST2);1726 stmt->regs |= (1 << Reg_ST3);1727 stmt->regs |= (1 << Reg_ST4);1728 stmt->regs |= (1 << Reg_ST5);1729 stmt->regs |= (1 << Reg_ST6);1730 stmt->regs |= (1 << Reg_ST7);1844 asmcode->regs[Reg_ST] = true; 1845 asmcode->regs[Reg_ST1] = true; 1846 asmcode->regs[Reg_ST2] = true; 1847 asmcode->regs[Reg_ST3] = true; 1848 asmcode->regs[Reg_ST4] = true; 1849 asmcode->regs[Reg_ST5] = true; 1850 asmcode->regs[Reg_ST6] = true; 1851 asmcode->regs[Reg_ST7] = true; 1731 1852 } 1732 1853 if (opInfo->implicitClobbers & Clb_Flags) 1733 asmcode->moreRegs |= (1 << (Reg_EFLAGS - 32)); 1734 if (op == Op_cpuid) 1735 stmt->regs |= (1 << Reg_EAX)| 1736 (1 << Reg_ECX)|(1 << Reg_EDX); 1854 asmcode->regs[Reg_EFLAGS] = true; 1855 if (op == Op_cpuid) { 1856 asmcode->regs[Reg_EAX] = true; 1857 asmcode->regs[Reg_ECX] = true; 1858 asmcode->regs[Reg_EDX] = true; 1859 } 1737 1860 1738 1861 insnTemplate->writebyte(' '); … … 1807 1930 Reg clbr_reg = (Reg) regInfo[operand->reg].baseReg; 1808 1931 if (clbr_reg != Reg_Invalid) { 1809 if (clbr_reg < 32) 1810 stmt->regs |= (1 << clbr_reg); 1811 else 1812 asmcode->moreRegs |= (1 << (clbr_reg - 32)); 1932 asmcode->regs[clbr_reg] = true; 1813 1933 } 1814 1934 } … … 1858 1978 if (operand->indexReg == Reg_Invalid && 1859 1979 decl->isVarDeclaration() && 1860 ((operand->baseReg == Reg_EBP && ! sc->func->naked ) || 1861 (operand->baseReg == Reg_ESP && sc->func->naked)) ) { 1980 ( ((operand->baseReg == Reg_EBP || (operand->baseReg == Reg_RBP)) && ! sc->func->naked ) || 1981 ((operand->baseReg == Reg_ESP || (operand->baseReg == Reg_RSP)) && sc->func->naked)) ) 1982 { 1862 1983 1863 1984 if (mode == Mode_Output) … … 2637 2758 bool getFrameRelativeValue(LLValue* decl, HOST_WIDE_INT * result) 2638 2759 { 2760 assert(0); 2639 2761 // FIXME 2640 2762 // // Using this instead of DECL_RTL for struct args seems like a … … 2669 2791 return false; 2670 2792 } 2793 2794 2795 struct AsmParser : public AsmParserCommon 2796 { 2797 virtual void run(Scope* sc, AsmStatement* asmst) { 2798 AsmProcessor ap(sc, asmst); 2799 ap.run(); 2800 } 2801 2802 virtual std::string getRegName(int i) { 2803 return regInfo[i].gccName; 2804 } 2805 }; 2806 2807 } gen/asmstmt.cpp
r622 r756 58 58 unsigned insnTemplateLen; 59 59 Array args; // of AsmArg 60 unsigned moreRegs;60 std::vector<bool> regs; 61 61 unsigned dollarLabel; 62 62 int clobbersMemory; 63 AsmCode( ) {63 AsmCode(int n_regs) { 64 64 insnTemplate = NULL; 65 65 insnTemplateLen = 0; 66 moreRegs = 0;66 regs.resize(n_regs, false); 67 67 dollarLabel = 0; 68 68 clobbersMemory = 0; … … 78 78 refparam = 0; 79 79 naked = 0; 80 regs = 0;81 80 82 81 isBranchToLabel = NULL; … … 90 89 a_s->refparam = refparam; 91 90 a_s->naked = naked; 92 a_s->regs = a_s->regs;93 91 return a_s; 94 92 } … … 131 129 } 132 130 133 134 #include "d-asm-i386.h" 131 struct AsmParserCommon 132 { 133 virtual void run(Scope* sc, AsmStatement* asmst) = 0; 134 virtual std::string getRegName(int i) = 0; 135 }; 136 AsmParserCommon* asmparser = NULL; 137 138 #include "asm-x86-32.h" 139 #include "asm-x86-64.h" 135 140 136 141 bool d_have_inline_asm() { return true; } … … 139 144 { 140 145 bool err = false; 141 if ( global.params.cpu != ARCHx86)146 if ((global.params.cpu != ARCHx86) && (global.params.cpu != ARCHx86_64)) 142 147 { 143 148 error("inline asm is not supported for the \"%s\" architecture", global.params.llvmArch); … … 161 166 return this; 162 167 163 AsmProcessor ap(sc, this); 164 ap.run(); 168 if (!asmparser) 169 if (global.params.cpu == ARCHx86) 170 asmparser = new AsmParserx8632::AsmParser; 171 else if (global.params.cpu == ARCHx86_64) 172 asmparser = new AsmParserx8664::AsmParser; 173 174 asmparser->run(sc, this); 175 165 176 return this; 166 177 } … … 252 263 arg_val = ((VarExp *) arg->expr)->var->toSymbol()->Stree; 253 264 else 254 assert(0); */265 assert(0); 255 266 if ( getFrameRelativeValue(arg_val, & var_frame_offset) ) { 256 267 // arg_val = irs->integerConstant(var_frame_offset); … … 262 273 if (arg->mode != Mode_Input) 263 274 clobbers_mem = true; 264 break; 275 break;*/ 265 276 case Arg_LocalSize: 266 277 // FIXME … … 295 306 // FIXME 296 307 // if (! irs->func->naked) { 297 for (int i = 0; i < 32; i++) { 298 if (regs & (1 << i)) { 308 assert(asmparser); 309 for (int i = 0; i < code->regs.size(); i++) { 310 if (code->regs[i]) { 299 311 //clobbers.cons(NULL_TREE, regInfo[i].gccName); 300 clobbers.push_back(regInfo[i].gccName); 301 } 302 } 303 for (int i = 0; i < 32; i++) { 304 if (code->moreRegs & (1 << (i-32))) { 305 //clobbers.cons(NULL_TREE, regInfo[i].gccName); 306 clobbers.push_back(regInfo[i].gccName); 312 clobbers.push_back(asmparser->getRegName(i)); 307 313 } 308 314 } tests/mini/asm1.d
r741 r756 5 5 void main() 6 6 { 7 version( D_InlineAsm_X86)7 version(LLVM_InlineAsm_X86) 8 8 { 9 9 int x;

