Changeset 798
- Timestamp:
- 12/12/10 05:49:13 (14 years ago)
- Files:
-
- branches/dmd-1.x/src/backend/cg87.c (modified) (1 diff)
- branches/dmd-1.x/src/backend/cod1.c (modified) (3 diffs)
- branches/dmd-1.x/src/backend/cod4.c (modified) (1 diff)
- branches/dmd-1.x/src/backend/dwarf.c (modified) (1 diff)
- branches/dmd-1.x/src/backend/ptrntab.c (modified) (1 diff)
- branches/dmd-1.x/src/expression.c (modified) (1 diff)
- branches/dmd-1.x/src/toobj.c (modified) (2 diffs)
- trunk/src/backend/cg87.c (modified) (1 diff)
- trunk/src/backend/cod1.c (modified) (3 diffs)
- trunk/src/backend/cod4.c (modified) (1 diff)
- trunk/src/backend/dwarf.c (modified) (1 diff)
- trunk/src/backend/ptrntab.c (modified) (1 diff)
- trunk/src/expression.c (modified) (2 diffs)
- trunk/src/toctype.c (modified) (1 diff)
- trunk/src/toobj.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/dmd-1.x/src/backend/cg87.c
r790 r798 1964 1964 */ 1965 1965 if (op1 == 0xDB) 1966 1966 { 1967 1967 cs.Iop = 0xC7; // MOV EA+10,0 1968 1968 NEWREG(cs.Irm, 0); 1969 1969 cs.IEV1.sp.Voffset += 10; 1970 1970 cs.IFL2 = FLconst; 1971 1971 cs.IEV2.Vint = 0; 1972 1972 cs.Iflags |= CFopsize; 1973 1973 c2 = gen(c2, &cs); 1974 1974 } 1975 1975 } 1976 1976 #endif 1977 1977 if (tysize[TYldouble] == 16) 1978 1978 { 1979 1979 /* This deals with the fact that 10 byte reals really 1980 1980 * occupy 16 bytes by zeroing the extra 6 bytes. 1981 1981 */ 1982 1982 if (op1 == 0xDB) 1983 1983 { 1984 cs.Irex &= ~REX_W; 1984 1985 cs.Iop = 0xC7; // MOV EA+10,0 1985 1986 NEWREG(cs.Irm, 0); 1986 1987 cs.IEV1.sp.Voffset += 10; 1987 1988 cs.IFL2 = FLconst; 1988 1989 cs.IEV2.Vint = 0; 1989 1990 cs.Iflags |= CFopsize; 1990 1991 c2 = gen(c2, &cs); 1991 1992 1992 1993 cs.IEV1.sp.Voffset += 2; 1993 1994 cs.Iflags &= ~CFopsize; 1994 1995 c2 = gen(c2, &cs); 1995 1996 } 1996 1997 } 1997 1998 #endif 1998 1999 c2 = genfwait(c2); 1999 2000 freenode(e->E1); 2000 2001 c1 = cat3(c1,c2,fixresult87(e,mST0 | mPSW,pretregs)); 2001 2002 return c1; 2002 2003 } 2003 2004 branches/dmd-1.x/src/backend/cod1.c
r790 r798 824 824 //elem_print(e); 825 825 assert(e); 826 826 elem_debug(e); 827 827 if (e->Eoper == OPvar || e->Eoper == OPrelconst) 828 828 { s = e->EV.sp.Vsym; 829 829 fl = s->Sfl; 830 830 if (tyfloating(s->ty())) 831 831 obj_fltused(); 832 832 } 833 833 else 834 834 fl = FLoper; 835 835 pcs->IFL1 = fl; 836 836 pcs->Iflags = CFoff; /* only want offsets */ 837 837 pcs->Irex = 0; 838 838 pcs->IEVoffset1 = 0; 839 839 840 840 tym_t ty = e->Ety; 841 841 unsigned sz = tysize(ty); 842 842 if (tyfloating(ty)) 843 843 obj_fltused(); 844 elseif (I64 && (sz == 8 || sz == 16))844 if (I64 && (sz == 8 || sz == 16)) 845 845 pcs->Irex |= REX_W; 846 846 if (!I16 && sz == SHORTSIZE) 847 847 pcs->Iflags |= CFopsize; 848 848 if (ty & mTYvolatile) 849 849 pcs->Iflags |= CFvolatile; 850 850 c = CNIL; 851 851 switch (fl) 852 852 { 853 853 #if 0 && TARGET_LINUX 854 854 case FLgot: 855 855 case FLgotoff: 856 856 gotref = 1; 857 857 pcs->IEVsym1 = s; 858 858 pcs->IEVoffset1 = e->EV.sp.Voffset; 859 859 if (e->Eoper == OPvar && fl == FLgot) 860 860 { 861 861 code *c1; 862 862 unsigned saveop = pcs->Iop; 863 863 idxregs = allregs & ~keepmsk; // get a scratch register 864 864 c = allocreg(&idxregs,®,TYptr); … … 3469 3469 while ((targ_int)(sz -= regsize) > 0) 3470 3470 { ce = cat(ce,loadea(e,&cs,0xFF,6,sz - regsize,RMload,0)); 3471 3471 code_orflag(ce,flag); 3472 3472 ce = genadjesp(ce,REGSIZE); 3473 3473 } 3474 3474 } 3475 3475 L2: 3476 3476 freenode(e); 3477 3477 c = cat(c,ce); 3478 3478 goto ret; 3479 3479 case OPconst: 3480 3480 { 3481 3481 char pushi = 0; 3482 3482 unsigned flag = 0; 3483 3483 int regsize = REGSIZE; 3484 3484 targ_int value; 3485 3485 3486 3486 if (tycomplex(tym)) 3487 3487 break; 3488 3488 3489 if (I64 && tyfloating(tym) && sz > 4 && boolres(e)) 3490 // Can't push 64 bit non-zero args directly 3491 break; 3492 3489 3493 if (I32 && szb == 10) // special case for long double constants 3490 3494 { 3491 3495 assert(sz == 12); 3492 3496 value = ((unsigned short *)&e->EV.Vldouble)[4]; 3493 3497 stackpush += sz; 3494 3498 ce = genadjesp(NULL,sz); 3495 3499 for (int i = 2; i >= 0; i--) 3496 3500 { 3497 3501 if (reghasvalue(allregs, value, ®)) 3498 3502 ce = gen1(ce,0x50 + reg); // PUSH reg 3499 3503 else 3500 3504 ce = genc2(ce,0x68,0,value); // PUSH value 3501 3505 value = ((unsigned *)&e->EV.Vldouble)[i - 1]; 3502 3506 } 3503 3507 goto L2; 3504 3508 } 3505 3509 3506 3510 assert(I64 || sz <= LNGDBLSIZE); 3507 3511 int i = sz; 3508 3512 if (!I16 && i == 2) … … 3518 3522 } 3519 3523 else if (i == REGSIZE) 3520 3524 break; 3521 3525 3522 3526 stackpush += sz; 3523 3527 ce = genadjesp(NULL,sz); 3524 3528 targ_uns *pi = (targ_uns *) &e->EV.Vdouble; 3525 3529 targ_ushort *ps = (targ_ushort *) pi; 3526 3530 targ_ullong *pl = (targ_ullong *)pi; 3527 3531 i /= regsize; 3528 3532 do 3529 3533 { code *cp; 3530 3534 3531 3535 if (i) /* be careful not to go negative */ 3532 3536 i--; 3533 3537 targ_size_t value = (regsize == 4) ? pi[i] : ps[i]; 3534 3538 if (regsize == 8) 3535 3539 value = pl[i]; 3536 3540 if (pushi) 3537 3541 { 3542 if (I64 && regsize == 8 && value != (int)value) 3543 { ce = regwithvalue(ce,allregs,value,®,64); 3544 goto Preg; // cannot push imm64 unless it is sign extended 32 bit value 3545 } 3538 3546 if (regsize == REGSIZE && reghasvalue(allregs,value,®)) 3539 3547 goto Preg; 3540 3548 ce = genc2(ce,(szb == 1) ? 0x6A : 0x68,0,value); // PUSH value 3541 3549 } 3542 3550 else 3543 3551 { 3544 3552 ce = regwithvalue(ce,allregs,value,®,0); 3545 3553 Preg: 3546 3554 ce = genpush(ce,reg); // PUSH reg 3547 3555 } 3548 3556 code_orflag(ce,flag); /* operand size */ 3549 3557 } while (i); 3550 3558 goto L2; 3551 3559 } 3552 3560 default: 3553 3561 break; 3554 3562 } 3555 3563 retregs = tybyte(tym) ? BYTEREGS : allregs; 3556 3564 if (tyfloating(tym)) 3557 3565 { if (config.inline8087) branches/dmd-1.x/src/backend/cod4.c
r772 r798 1883 1883 1884 1884 case OPconst: 1885 1885 // If compare against 0 1886 1886 if (sz <= REGSIZE && *pretregs == mPSW && !boolres(e2) && 1887 1887 isregvar(e1,&retregs,®) 1888 1888 ) 1889 1889 { // Just do a TEST instruction 1890 1890 c = genregs(NULL,0x85 ^ byte,reg,reg); // TEST reg,reg 1891 1891 c->Iflags |= (cs.Iflags & CFopsize) | CFpsw; 1892 1892 code_orrex(c, rex); 1893 1893 if (I64 && byte && reg >= 4) 1894 1894 c->Irex |= REX; // address byte registers 1895 1895 retregs = mPSW; 1896 1896 break; 1897 1897 } 1898 1898 1899 1899 if (!tyuns(tym) && !tyuns(e2->Ety) && 1900 1900 !boolres(e2) && !(*pretregs & mPSW) && 1901 1901 (sz == REGSIZE || (I64 && sz == 4)) && 1902 1902 (!I16 || op == OPlt || op == OPge)) 1903 { unsigned regi; 1904 1903 { 1905 1904 assert(*pretregs & (allregs)); 1906 1905 cl = codelem(e1,pretregs,FALSE); 1907 1906 reg = findreg(*pretregs); 1908 1907 c = getregs(mask[reg]); 1909 1908 switch (op) 1910 1909 { case OPle: 1911 1910 c = genc2(c,0x81,grex | modregrmx(3,0,reg & 7),(unsigned)-1); // ADD reg,-1 1912 1911 genc2(c,0x81,grex | modregrmx(3,2,reg & 7),0); // ADC reg,0 1913 1912 goto oplt; 1914 1913 case OPgt: 1915 1914 c = gen2(c,0xF7,grex | modregrmx(3,3,reg & 7)); // NEG reg 1916 1915 #if TARGET_WINDOS 1917 1916 // What does the Windows platform do? 1918 1917 // lower INT_MIN by 1? See test exe9.c 1919 1918 // BUG: fix later 1920 1919 genc2(c,0x81,grex | modregrmx(3,3,reg & 7),0); // SBB reg,0 1921 1920 #endif 1922 1921 goto oplt; 1923 1922 case OPlt: 1924 1923 oplt: 1925 1924 if (!I16) 1926 1925 c = genc2(c,0xC1,grex | modregrmx(3,5,reg & 7),sz * 8 - 1); // SHR reg,31 1927 1926 else 1928 1927 { /* 8088-286 do not have a barrel shifter, so use this 1929 1928 faster sequence 1930 1929 */ 1931 1930 c = genregs(c,0xD1,0,reg); /* ROL reg,1 */ 1931 unsigned regi; 1932 1932 if (reghasvalue(allregs,1,®i)) 1933 1933 c = genregs(c,0x23,reg,regi); /* AND reg,regi */ 1934 1934 else 1935 1935 c = genc2(c,0x81,modregrm(3,4,reg),1); /* AND reg,1 */ 1936 1936 } 1937 1937 break; 1938 1938 case OPge: 1939 1939 c = genregs(c,0xD1,4,reg); /* SHL reg,1 */ 1940 1940 code_orrex(c,rex); 1941 1941 genregs(c,0x19,reg,reg); /* SBB reg,reg */ 1942 1942 code_orrex(c,rex); 1943 1943 if (I64) 1944 1944 { 1945 1945 c = gen2(c,0xFF,modregrmx(3,0,reg)); // INC reg 1946 1946 code_orrex(c, rex); 1947 1947 } 1948 1948 else 1949 1949 c = gen1(c,0x40 + reg); // INC reg 1950 1950 break; 1951 1951 1952 1952 default: 1953 1953 assert(0); 1954 1954 } 1955 1955 freenode(e2); 1956 1956 goto ret; 1957 1957 } 1958 1958 1959 if (sz > REGSIZE) 1959 cs.IFL2 = FLconst; 1960 if (sz == 16) 1961 cs.IEV2.Vsize_t = e2->EV.Vcent.msw; 1962 else if (sz > REGSIZE) 1960 1963 cs.IEV2.Vint = MSREG(e2->EV.Vllong); 1961 1964 else 1962 cs.IEV2.Vint = e2->EV.Vint; 1963 cs.IFL2 = FLconst; 1965 cs.IEV2.Vsize_t = e2->EV.Vllong; 1966 1967 // The cmp immediate relies on sign extension of the 32 bit immediate value 1968 if (I64 && sz >= REGSIZE && cs.IEV2.Vsize_t != (int)cs.IEV2.Vint) 1969 goto L2; 1964 1970 L4: 1965 1971 cs.Iop = 0x81 ^ byte; 1966 1972 1967 1973 /* if ((e1 is data or a '*' reference) and it's not a 1968 1974 * common subexpression 1969 1975 */ 1970 1976 1971 1977 if ((e1->Eoper == OPvar && datafl[el_fl(e1)] || 1972 1978 e1->Eoper == OPind) && 1973 1979 !evalinregister(e1)) 1974 1980 { cl = getlvalue(&cs,e1,RMload); 1975 1981 freenode(e1); 1976 1982 if (evalinregister(e2)) 1977 1983 { 1978 1984 retregs = idxregm(&cs); 1979 1985 if ((cs.Iflags & CFSEG) == CFes) 1980 1986 retregs |= mES; /* take no chances */ 1981 1987 rretregs = allregs & ~retregs; 1982 1988 if (byte) 1983 1989 rretregs &= BYTEREGS; branches/dmd-1.x/src/backend/dwarf.c
r691 r798 100 100 #else 101 101 assert(0); 102 102 #endif 103 103 } 104 104 105 105 /************************ DWARF DEBUG OUTPUT ********************************/ 106 106 107 107 // Dwarf Symbolic Debugging Information 108 108 109 109 struct CFA_reg 110 110 { 111 111 int offset; // offset from CFA 112 112 }; 113 113 114 114 // Current CFA state for .debug_frame 115 115 struct CFA_state 116 116 { 117 117 size_t location; 118 118 int reg; // CFA register number 119 119 int offset; // CFA register offset 120 CFA_reg regstates[ 9];// register states120 CFA_reg regstates[17]; // register states 121 121 }; 122 122 123 123 static CFA_state CFA_state_init = // initial CFA state as defined by CIE 124 124 { 0, // location 125 125 SP, // register 126 126 4, // offset 127 127 { { 0 }, // 0: EAX 128 128 { 0 }, // 1: ECX 129 129 { 0 }, // 2: EDX 130 130 { 0 }, // 3: EBX 131 131 { 0 }, // 4: ESP 132 132 { 0 }, // 5: EBP 133 133 { 0 }, // 6: ESI 134 134 { 0 }, // 7: EDI 135 135 { -4 }, // 8: EIP 136 136 } 137 137 }; 138 138 static CFA_state CFA_state_current; // current CFA state 139 139 static Outbuffer cfa_buf; // CFA instructions 140 140 branches/dmd-1.x/src/backend/ptrntab.c
r714 r798 691 691 { 0xc1, op|_ib|_32_bit, _rm32, _imm8, }, \ 692 692 { 0xd3, op|_64_bit, _rm64, _cl }, \ 693 693 { 0xc1, op|_ib|_64_bit, _rm64, _imm8, }, \ 694 694 { ASM_END, 0, 0, 0 } \ 695 695 } 696 696 697 697 OPTABLE(ROL,_0); 698 698 OPTABLE(ROR,_1); 699 699 OPTABLE(RCL,_2); 700 700 OPTABLE(RCR,_3); 701 701 OPTABLE(SHL,_4); 702 702 OPTABLE(SHR,_5); 703 703 OPTABLE(SAR,_7); 704 704 705 705 #undef OPTABLE 706 706 707 707 PTRNTAB2 aptb2TEST[] = /* TEST */ { 708 708 { 0xa8, _ib|_modnot1, _al, _imm8 }, 709 709 { 0xa9, _iw|_16_bit|_modnot1, _ax, _imm16 }, 710 710 { 0xa9, _id|_32_bit|_modnot1, _eax, _imm32 }, 711 { 0xa9, _id|_64_bit|_modnot1, _rax, _imm32 }, 711 712 { 0xf6, _0|_modnot1, _rm8, _imm8 }, 712 713 { 0xf7, _0|_16_bit|_modnot1, _rm16, _imm16 }, 713 714 { 0xf7, _0|_32_bit|_modnot1, _rm32, _imm32 }, 715 { 0xf7, _0|_64_bit|_modnot1, _rm64, _imm32 }, 714 716 { 0x84, _r|_modnot1, _rm8, _r8 }, 715 717 { 0x85, _r|_16_bit|_modnot1, _rm16, _r16 }, 716 718 { 0x85, _r|_32_bit|_modnot1, _rm32, _r32 }, 719 { 0x85, _r|_64_bit|_modnot1, _rm64, _r64 }, 717 720 { ASM_END, 0, 0, 0 } 718 721 }; 719 722 PTRNTAB2 aptb2XADD[] = /* XADD */ { // 486 only instruction 720 723 // { 0x0fc0, _ib | _I386|_mod2, _rm8, _r8 }, 721 724 // { 0x0fc1, _iw | _I386|_16_bit|_mod2, _rm16, _r16 }, 722 725 // { 0x0fc1, _id | _I386|_32_bit|_mod2, _rm32, _r32 }, 723 726 { 0x0fc0, _r | _I386|_mod2, _rm8, _r8 }, 724 727 { 0x0fc1, _r | _I386|_16_bit|_mod2, _rm16, _r16 }, 725 728 { 0x0fc1, _r | _I386|_32_bit|_mod2, _rm32, _r32 }, 726 729 { ASM_END, 0, 0, 0 } 727 730 }; 728 731 PTRNTAB2 aptb2XCHG[] = /* XCHG */ { 729 732 { 0x90, _r|_16_bit|_mod2, _ax , _r16 | _plus_r }, 730 733 { 0x90, _r|_16_bit|_mod2, _r16 | _plus_r, _ax }, 731 734 { 0x90, _r|_32_bit|_mod2, _eax, _r32 | _plus_r }, 732 735 { 0x90, _r|_32_bit|_mod2, _r32 | _plus_r, _eax }, 733 736 { 0x86, _r|_mod2, _rm8, _r8 }, 734 737 { 0x86, _r|_mod2, _r8, _rm8 }, 735 738 { 0x87, _r|_16_bit|_mod2, _rm16, _r16 }, 736 739 { 0x87, _r|_16_bit|_mod2, _r16, _rm16 }, branches/dmd-1.x/src/expression.c
r779 r798 2673 2673 int StringExp::compare(Object *obj) 2674 2674 { 2675 2675 // Used to sort case statement expressions so we can do an efficient lookup 2676 2676 StringExp *se2 = (StringExp *)(obj); 2677 2677 2678 2678 // This is a kludge so isExpression() in template.c will return 5 2679 2679 // for StringExp's. 2680 2680 if (!se2) 2681 2681 return 5; 2682 2682 2683 2683 assert(se2->op == TOKstring); 2684 2684 2685 2685 int len1 = len; 2686 2686 int len2 = se2->len; 2687 2687 2688 2688 if (len1 == len2) 2689 2689 { 2690 2690 switch (sz) 2691 2691 { 2692 2692 case 1: 2693 return strcmp((char *)string, (char *)se2->string);2693 return memcmp((char *)string, (char *)se2->string, len1); 2694 2694 2695 2695 case 2: 2696 2696 { unsigned u; 2697 2697 d_wchar *s1 = (d_wchar *)string; 2698 2698 d_wchar *s2 = (d_wchar *)se2->string; 2699 2699 2700 2700 for (u = 0; u < len; u++) 2701 2701 { 2702 2702 if (s1[u] != s2[u]) 2703 2703 return s1[u] - s2[u]; 2704 2704 } 2705 2705 } 2706 2706 2707 2707 case 4: 2708 2708 { unsigned u; 2709 2709 d_dchar *s1 = (d_dchar *)string; 2710 2710 d_dchar *s2 = (d_dchar *)se2->string; 2711 2711 2712 2712 for (u = 0; u < len; u++) 2713 2713 { branches/dmd-1.x/src/toobj.c
r662 r798 87 87 // name[] 88 88 const char *name = toPrettyChars(); 89 89 size_t namelen = strlen(name); 90 90 dtsize_t(&dt, namelen); 91 91 dtabytes(&dt, TYnptr, 0, namelen + 1, name); 92 92 93 93 ClassDeclarations aclasses; 94 94 95 95 //printf("members->dim = %d\n", members->dim); 96 96 for (int i = 0; i < members->dim; i++) 97 97 { Dsymbol *member = (Dsymbol *)members->data[i]; 98 98 99 99 //printf("\tmember '%s'\n", member->toChars()); 100 100 member->addLocalClass(&aclasses); 101 101 } 102 102 103 103 // importedModules[] 104 104 int aimports_dim = aimports.dim; 105 105 for (int i = 0; i < aimports.dim; i++) 106 106 { Module *m = (Module *)aimports.data[i]; 107 if (!m->need ModuleInfo())107 if (!m->needmoduleinfo) 108 108 aimports_dim--; 109 109 } 110 110 dtsize_t(&dt, aimports_dim); 111 111 if (aimports_dim) 112 112 dtxoff(&dt, csym, sizeof_ModuleInfo, TYnptr); 113 113 else 114 114 dtsize_t(&dt, 0); 115 115 116 116 // localClasses[] 117 117 dtsize_t(&dt, aclasses.dim); 118 118 if (aclasses.dim) 119 119 dtxoff(&dt, csym, sizeof_ModuleInfo + aimports_dim * PTRSIZE, TYnptr); 120 120 else 121 121 dtsize_t(&dt, 0); 122 122 123 123 if (needmoduleinfo) 124 124 dtsize_t(&dt, 8|0); // flags (4 means MIstandalone) 125 125 else 126 126 dtsize_t(&dt, 8|4); // flags (4 means MIstandalone) 127 127 … … 148 148 #endif 149 149 dtsize_t(&dt, 0); // xgetMembers 150 150 151 151 if (sictor) 152 152 dtxoff(&dt, sictor, 0, TYnptr); 153 153 else 154 154 dtsize_t(&dt, 0); 155 155 156 156 #if DMDV2 157 157 // void*[4] reserved; 158 158 dtsize_t(&dt, 0); 159 159 dtsize_t(&dt, 0); 160 160 dtsize_t(&dt, 0); 161 161 dtsize_t(&dt, 0); 162 162 #endif 163 163 ////////////////////////////////////////////// 164 164 165 165 for (int i = 0; i < aimports.dim; i++) 166 166 { Module *m = (Module *)aimports.data[i]; 167 167 168 if (m->need ModuleInfo())168 if (m->needmoduleinfo) 169 169 { Symbol *s = m->toSymbol(); 170 170 171 171 /* Weak references don't pull objects in from the library, 172 172 * they resolve to 0 if not pulled in by something else. 173 173 * Don't pull in a module just because it was imported. 174 174 */ 175 175 #if !OMFOBJ // Optlink crashes with weak symbols at EIP 41AFE7, 402000 176 176 s->Sflags |= SFLweak; 177 177 #endif 178 178 dtxoff(&dt, s, 0, TYnptr); 179 179 } 180 180 } 181 181 182 182 for (int i = 0; i < aclasses.dim; i++) 183 183 { 184 184 ClassDeclaration *cd = (ClassDeclaration *)aclasses.data[i]; 185 185 dtxoff(&dt, cd->toSymbol(), 0, TYnptr); 186 186 } 187 187 188 188 csym->Sdt = dt; trunk/src/backend/cg87.c
r790 r798 1964 1964 */ 1965 1965 if (op1 == 0xDB) 1966 1966 { 1967 1967 cs.Iop = 0xC7; // MOV EA+10,0 1968 1968 NEWREG(cs.Irm, 0); 1969 1969 cs.IEV1.sp.Voffset += 10; 1970 1970 cs.IFL2 = FLconst; 1971 1971 cs.IEV2.Vint = 0; 1972 1972 cs.Iflags |= CFopsize; 1973 1973 c2 = gen(c2, &cs); 1974 1974 } 1975 1975 } 1976 1976 #endif 1977 1977 if (tysize[TYldouble] == 16) 1978 1978 { 1979 1979 /* This deals with the fact that 10 byte reals really 1980 1980 * occupy 16 bytes by zeroing the extra 6 bytes. 1981 1981 */ 1982 1982 if (op1 == 0xDB) 1983 1983 { 1984 cs.Irex &= ~REX_W; 1984 1985 cs.Iop = 0xC7; // MOV EA+10,0 1985 1986 NEWREG(cs.Irm, 0); 1986 1987 cs.IEV1.sp.Voffset += 10; 1987 1988 cs.IFL2 = FLconst; 1988 1989 cs.IEV2.Vint = 0; 1989 1990 cs.Iflags |= CFopsize; 1990 1991 c2 = gen(c2, &cs); 1991 1992 1992 1993 cs.IEV1.sp.Voffset += 2; 1993 1994 cs.Iflags &= ~CFopsize; 1994 1995 c2 = gen(c2, &cs); 1995 1996 } 1996 1997 } 1997 1998 #endif 1998 1999 c2 = genfwait(c2); 1999 2000 freenode(e->E1); 2000 2001 c1 = cat3(c1,c2,fixresult87(e,mST0 | mPSW,pretregs)); 2001 2002 return c1; 2002 2003 } 2003 2004 trunk/src/backend/cod1.c
r790 r798 824 824 //elem_print(e); 825 825 assert(e); 826 826 elem_debug(e); 827 827 if (e->Eoper == OPvar || e->Eoper == OPrelconst) 828 828 { s = e->EV.sp.Vsym; 829 829 fl = s->Sfl; 830 830 if (tyfloating(s->ty())) 831 831 obj_fltused(); 832 832 } 833 833 else 834 834 fl = FLoper; 835 835 pcs->IFL1 = fl; 836 836 pcs->Iflags = CFoff; /* only want offsets */ 837 837 pcs->Irex = 0; 838 838 pcs->IEVoffset1 = 0; 839 839 840 840 tym_t ty = e->Ety; 841 841 unsigned sz = tysize(ty); 842 842 if (tyfloating(ty)) 843 843 obj_fltused(); 844 elseif (I64 && (sz == 8 || sz == 16))844 if (I64 && (sz == 8 || sz == 16)) 845 845 pcs->Irex |= REX_W; 846 846 if (!I16 && sz == SHORTSIZE) 847 847 pcs->Iflags |= CFopsize; 848 848 if (ty & mTYvolatile) 849 849 pcs->Iflags |= CFvolatile; 850 850 c = CNIL; 851 851 switch (fl) 852 852 { 853 853 #if 0 && TARGET_LINUX 854 854 case FLgot: 855 855 case FLgotoff: 856 856 gotref = 1; 857 857 pcs->IEVsym1 = s; 858 858 pcs->IEVoffset1 = e->EV.sp.Voffset; 859 859 if (e->Eoper == OPvar && fl == FLgot) 860 860 { 861 861 code *c1; 862 862 unsigned saveop = pcs->Iop; 863 863 idxregs = allregs & ~keepmsk; // get a scratch register 864 864 c = allocreg(&idxregs,®,TYptr); … … 3469 3469 while ((targ_int)(sz -= regsize) > 0) 3470 3470 { ce = cat(ce,loadea(e,&cs,0xFF,6,sz - regsize,RMload,0)); 3471 3471 code_orflag(ce,flag); 3472 3472 ce = genadjesp(ce,REGSIZE); 3473 3473 } 3474 3474 } 3475 3475 L2: 3476 3476 freenode(e); 3477 3477 c = cat(c,ce); 3478 3478 goto ret; 3479 3479 case OPconst: 3480 3480 { 3481 3481 char pushi = 0; 3482 3482 unsigned flag = 0; 3483 3483 int regsize = REGSIZE; 3484 3484 targ_int value; 3485 3485 3486 3486 if (tycomplex(tym)) 3487 3487 break; 3488 3488 3489 if (I64 && tyfloating(tym) && sz > 4 && boolres(e)) 3490 // Can't push 64 bit non-zero args directly 3491 break; 3492 3489 3493 if (I32 && szb == 10) // special case for long double constants 3490 3494 { 3491 3495 assert(sz == 12); 3492 3496 value = ((unsigned short *)&e->EV.Vldouble)[4]; 3493 3497 stackpush += sz; 3494 3498 ce = genadjesp(NULL,sz); 3495 3499 for (int i = 2; i >= 0; i--) 3496 3500 { 3497 3501 if (reghasvalue(allregs, value, ®)) 3498 3502 ce = gen1(ce,0x50 + reg); // PUSH reg 3499 3503 else 3500 3504 ce = genc2(ce,0x68,0,value); // PUSH value 3501 3505 value = ((unsigned *)&e->EV.Vldouble)[i - 1]; 3502 3506 } 3503 3507 goto L2; 3504 3508 } 3505 3509 3506 3510 assert(I64 || sz <= LNGDBLSIZE); 3507 3511 int i = sz; 3508 3512 if (!I16 && i == 2) … … 3518 3522 } 3519 3523 else if (i == REGSIZE) 3520 3524 break; 3521 3525 3522 3526 stackpush += sz; 3523 3527 ce = genadjesp(NULL,sz); 3524 3528 targ_uns *pi = (targ_uns *) &e->EV.Vdouble; 3525 3529 targ_ushort *ps = (targ_ushort *) pi; 3526 3530 targ_ullong *pl = (targ_ullong *)pi; 3527 3531 i /= regsize; 3528 3532 do 3529 3533 { code *cp; 3530 3534 3531 3535 if (i) /* be careful not to go negative */ 3532 3536 i--; 3533 3537 targ_size_t value = (regsize == 4) ? pi[i] : ps[i]; 3534 3538 if (regsize == 8) 3535 3539 value = pl[i]; 3536 3540 if (pushi) 3537 3541 { 3542 if (I64 && regsize == 8 && value != (int)value) 3543 { ce = regwithvalue(ce,allregs,value,®,64); 3544 goto Preg; // cannot push imm64 unless it is sign extended 32 bit value 3545 } 3538 3546 if (regsize == REGSIZE && reghasvalue(allregs,value,®)) 3539 3547 goto Preg; 3540 3548 ce = genc2(ce,(szb == 1) ? 0x6A : 0x68,0,value); // PUSH value 3541 3549 } 3542 3550 else 3543 3551 { 3544 3552 ce = regwithvalue(ce,allregs,value,®,0); 3545 3553 Preg: 3546 3554 ce = genpush(ce,reg); // PUSH reg 3547 3555 } 3548 3556 code_orflag(ce,flag); /* operand size */ 3549 3557 } while (i); 3550 3558 goto L2; 3551 3559 } 3552 3560 default: 3553 3561 break; 3554 3562 } 3555 3563 retregs = tybyte(tym) ? BYTEREGS : allregs; 3556 3564 if (tyfloating(tym)) 3557 3565 { if (config.inline8087) trunk/src/backend/cod4.c
r772 r798 1883 1883 1884 1884 case OPconst: 1885 1885 // If compare against 0 1886 1886 if (sz <= REGSIZE && *pretregs == mPSW && !boolres(e2) && 1887 1887 isregvar(e1,&retregs,®) 1888 1888 ) 1889 1889 { // Just do a TEST instruction 1890 1890 c = genregs(NULL,0x85 ^ byte,reg,reg); // TEST reg,reg 1891 1891 c->Iflags |= (cs.Iflags & CFopsize) | CFpsw; 1892 1892 code_orrex(c, rex); 1893 1893 if (I64 && byte && reg >= 4) 1894 1894 c->Irex |= REX; // address byte registers 1895 1895 retregs = mPSW; 1896 1896 break; 1897 1897 } 1898 1898 1899 1899 if (!tyuns(tym) && !tyuns(e2->Ety) && 1900 1900 !boolres(e2) && !(*pretregs & mPSW) && 1901 1901 (sz == REGSIZE || (I64 && sz == 4)) && 1902 1902 (!I16 || op == OPlt || op == OPge)) 1903 { unsigned regi; 1904 1903 { 1905 1904 assert(*pretregs & (allregs)); 1906 1905 cl = codelem(e1,pretregs,FALSE); 1907 1906 reg = findreg(*pretregs); 1908 1907 c = getregs(mask[reg]); 1909 1908 switch (op) 1910 1909 { case OPle: 1911 1910 c = genc2(c,0x81,grex | modregrmx(3,0,reg & 7),(unsigned)-1); // ADD reg,-1 1912 1911 genc2(c,0x81,grex | modregrmx(3,2,reg & 7),0); // ADC reg,0 1913 1912 goto oplt; 1914 1913 case OPgt: 1915 1914 c = gen2(c,0xF7,grex | modregrmx(3,3,reg & 7)); // NEG reg 1916 1915 #if TARGET_WINDOS 1917 1916 // What does the Windows platform do? 1918 1917 // lower INT_MIN by 1? See test exe9.c 1919 1918 // BUG: fix later 1920 1919 genc2(c,0x81,grex | modregrmx(3,3,reg & 7),0); // SBB reg,0 1921 1920 #endif 1922 1921 goto oplt; 1923 1922 case OPlt: 1924 1923 oplt: 1925 1924 if (!I16) 1926 1925 c = genc2(c,0xC1,grex | modregrmx(3,5,reg & 7),sz * 8 - 1); // SHR reg,31 1927 1926 else 1928 1927 { /* 8088-286 do not have a barrel shifter, so use this 1929 1928 faster sequence 1930 1929 */ 1931 1930 c = genregs(c,0xD1,0,reg); /* ROL reg,1 */ 1931 unsigned regi; 1932 1932 if (reghasvalue(allregs,1,®i)) 1933 1933 c = genregs(c,0x23,reg,regi); /* AND reg,regi */ 1934 1934 else 1935 1935 c = genc2(c,0x81,modregrm(3,4,reg),1); /* AND reg,1 */ 1936 1936 } 1937 1937 break; 1938 1938 case OPge: 1939 1939 c = genregs(c,0xD1,4,reg); /* SHL reg,1 */ 1940 1940 code_orrex(c,rex); 1941 1941 genregs(c,0x19,reg,reg); /* SBB reg,reg */ 1942 1942 code_orrex(c,rex); 1943 1943 if (I64) 1944 1944 { 1945 1945 c = gen2(c,0xFF,modregrmx(3,0,reg)); // INC reg 1946 1946 code_orrex(c, rex); 1947 1947 } 1948 1948 else 1949 1949 c = gen1(c,0x40 + reg); // INC reg 1950 1950 break; 1951 1951 1952 1952 default: 1953 1953 assert(0); 1954 1954 } 1955 1955 freenode(e2); 1956 1956 goto ret; 1957 1957 } 1958 1958 1959 if (sz > REGSIZE) 1959 cs.IFL2 = FLconst; 1960 if (sz == 16) 1961 cs.IEV2.Vsize_t = e2->EV.Vcent.msw; 1962 else if (sz > REGSIZE) 1960 1963 cs.IEV2.Vint = MSREG(e2->EV.Vllong); 1961 1964 else 1962 cs.IEV2.Vint = e2->EV.Vint; 1963 cs.IFL2 = FLconst; 1965 cs.IEV2.Vsize_t = e2->EV.Vllong; 1966 1967 // The cmp immediate relies on sign extension of the 32 bit immediate value 1968 if (I64 && sz >= REGSIZE && cs.IEV2.Vsize_t != (int)cs.IEV2.Vint) 1969 goto L2; 1964 1970 L4: 1965 1971 cs.Iop = 0x81 ^ byte; 1966 1972 1967 1973 /* if ((e1 is data or a '*' reference) and it's not a 1968 1974 * common subexpression 1969 1975 */ 1970 1976 1971 1977 if ((e1->Eoper == OPvar && datafl[el_fl(e1)] || 1972 1978 e1->Eoper == OPind) && 1973 1979 !evalinregister(e1)) 1974 1980 { cl = getlvalue(&cs,e1,RMload); 1975 1981 freenode(e1); 1976 1982 if (evalinregister(e2)) 1977 1983 { 1978 1984 retregs = idxregm(&cs); 1979 1985 if ((cs.Iflags & CFSEG) == CFes) 1980 1986 retregs |= mES; /* take no chances */ 1981 1987 rretregs = allregs & ~retregs; 1982 1988 if (byte) 1983 1989 rretregs &= BYTEREGS; trunk/src/backend/dwarf.c
r691 r798 100 100 #else 101 101 assert(0); 102 102 #endif 103 103 } 104 104 105 105 /************************ DWARF DEBUG OUTPUT ********************************/ 106 106 107 107 // Dwarf Symbolic Debugging Information 108 108 109 109 struct CFA_reg 110 110 { 111 111 int offset; // offset from CFA 112 112 }; 113 113 114 114 // Current CFA state for .debug_frame 115 115 struct CFA_state 116 116 { 117 117 size_t location; 118 118 int reg; // CFA register number 119 119 int offset; // CFA register offset 120 CFA_reg regstates[ 9];// register states120 CFA_reg regstates[17]; // register states 121 121 }; 122 122 123 123 static CFA_state CFA_state_init = // initial CFA state as defined by CIE 124 124 { 0, // location 125 125 SP, // register 126 126 4, // offset 127 127 { { 0 }, // 0: EAX 128 128 { 0 }, // 1: ECX 129 129 { 0 }, // 2: EDX 130 130 { 0 }, // 3: EBX 131 131 { 0 }, // 4: ESP 132 132 { 0 }, // 5: EBP 133 133 { 0 }, // 6: ESI 134 134 { 0 }, // 7: EDI 135 135 { -4 }, // 8: EIP 136 136 } 137 137 }; 138 138 static CFA_state CFA_state_current; // current CFA state 139 139 static Outbuffer cfa_buf; // CFA instructions 140 140 trunk/src/backend/ptrntab.c
r714 r798 691 691 { 0xc1, op|_ib|_32_bit, _rm32, _imm8, }, \ 692 692 { 0xd3, op|_64_bit, _rm64, _cl }, \ 693 693 { 0xc1, op|_ib|_64_bit, _rm64, _imm8, }, \ 694 694 { ASM_END, 0, 0, 0 } \ 695 695 } 696 696 697 697 OPTABLE(ROL,_0); 698 698 OPTABLE(ROR,_1); 699 699 OPTABLE(RCL,_2); 700 700 OPTABLE(RCR,_3); 701 701 OPTABLE(SHL,_4); 702 702 OPTABLE(SHR,_5); 703 703 OPTABLE(SAR,_7); 704 704 705 705 #undef OPTABLE 706 706 707 707 PTRNTAB2 aptb2TEST[] = /* TEST */ { 708 708 { 0xa8, _ib|_modnot1, _al, _imm8 }, 709 709 { 0xa9, _iw|_16_bit|_modnot1, _ax, _imm16 }, 710 710 { 0xa9, _id|_32_bit|_modnot1, _eax, _imm32 }, 711 { 0xa9, _id|_64_bit|_modnot1, _rax, _imm32 }, 711 712 { 0xf6, _0|_modnot1, _rm8, _imm8 }, 712 713 { 0xf7, _0|_16_bit|_modnot1, _rm16, _imm16 }, 713 714 { 0xf7, _0|_32_bit|_modnot1, _rm32, _imm32 }, 715 { 0xf7, _0|_64_bit|_modnot1, _rm64, _imm32 }, 714 716 { 0x84, _r|_modnot1, _rm8, _r8 }, 715 717 { 0x85, _r|_16_bit|_modnot1, _rm16, _r16 }, 716 718 { 0x85, _r|_32_bit|_modnot1, _rm32, _r32 }, 719 { 0x85, _r|_64_bit|_modnot1, _rm64, _r64 }, 717 720 { ASM_END, 0, 0, 0 } 718 721 }; 719 722 PTRNTAB2 aptb2XADD[] = /* XADD */ { // 486 only instruction 720 723 // { 0x0fc0, _ib | _I386|_mod2, _rm8, _r8 }, 721 724 // { 0x0fc1, _iw | _I386|_16_bit|_mod2, _rm16, _r16 }, 722 725 // { 0x0fc1, _id | _I386|_32_bit|_mod2, _rm32, _r32 }, 723 726 { 0x0fc0, _r | _I386|_mod2, _rm8, _r8 }, 724 727 { 0x0fc1, _r | _I386|_16_bit|_mod2, _rm16, _r16 }, 725 728 { 0x0fc1, _r | _I386|_32_bit|_mod2, _rm32, _r32 }, 726 729 { ASM_END, 0, 0, 0 } 727 730 }; 728 731 PTRNTAB2 aptb2XCHG[] = /* XCHG */ { 729 732 { 0x90, _r|_16_bit|_mod2, _ax , _r16 | _plus_r }, 730 733 { 0x90, _r|_16_bit|_mod2, _r16 | _plus_r, _ax }, 731 734 { 0x90, _r|_32_bit|_mod2, _eax, _r32 | _plus_r }, 732 735 { 0x90, _r|_32_bit|_mod2, _r32 | _plus_r, _eax }, 733 736 { 0x86, _r|_mod2, _rm8, _r8 }, 734 737 { 0x86, _r|_mod2, _r8, _rm8 }, 735 738 { 0x87, _r|_16_bit|_mod2, _rm16, _r16 }, 736 739 { 0x87, _r|_16_bit|_mod2, _r16, _rm16 }, trunk/src/expression.c
r789 r798 2704 2704 StringExp::StringExp(Loc loc, void *string, size_t len, unsigned char postfix) 2705 2705 : Expression(loc, TOKstring, sizeof(StringExp)) 2706 2706 { 2707 2707 this->string = string; 2708 2708 this->len = len; 2709 2709 this->sz = 1; 2710 2710 this->committed = 0; 2711 2711 this->postfix = postfix; 2712 2712 } 2713 2713 2714 2714 #if 0 2715 2715 Expression *StringExp::syntaxCopy() 2716 2716 { 2717 2717 printf("StringExp::syntaxCopy() %s\n", toChars()); 2718 2718 return copy(); 2719 2719 } 2720 2720 #endif 2721 2721 2722 2722 int StringExp::equals(Object *o) 2723 2723 { 2724 //printf("StringExp::equals('%s') \n", o->toChars());2724 //printf("StringExp::equals('%s') %s\n", o->toChars(), toChars()); 2725 2725 if (o && o->dyncast() == DYNCAST_EXPRESSION) 2726 2726 { Expression *e = (Expression *)o; 2727 2727 2728 2728 if (e->op == TOKstring) 2729 2729 { 2730 2730 return compare(o) == 0; 2731 2731 } 2732 2732 } 2733 2733 return FALSE; 2734 2734 } 2735 2735 2736 2736 char *StringExp::toChars() 2737 2737 { 2738 2738 OutBuffer buf; 2739 2739 HdrGenState hgs; 2740 2740 char *p; 2741 2741 2742 2742 memset(&hgs, 0, sizeof(hgs)); 2743 2743 toCBuffer(&buf, &hgs); 2744 2744 buf.writeByte(0); … … 2873 2873 * Convert string to char[]. 2874 2874 */ 2875 2875 2876 2876 StringExp *StringExp::toUTF8(Scope *sc) 2877 2877 { 2878 2878 if (sz != 1) 2879 2879 { // Convert to UTF-8 string 2880 2880 committed = 0; 2881 2881 Expression *e = castTo(sc, Type::tchar->arrayOf()); 2882 2882 e = e->optimize(WANTvalue); 2883 2883 assert(e->op == TOKstring); 2884 2884 StringExp *se = (StringExp *)e; 2885 2885 assert(se->sz == 1); 2886 2886 return se; 2887 2887 } 2888 2888 return this; 2889 2889 } 2890 2890 2891 2891 int StringExp::compare(Object *obj) 2892 2892 { 2893 //printf("StringExp::compare()\n"); 2893 2894 // Used to sort case statement expressions so we can do an efficient lookup 2894 2895 StringExp *se2 = (StringExp *)(obj); 2895 2896 2896 2897 // This is a kludge so isExpression() in template.c will return 5 2897 2898 // for StringExp's. 2898 2899 if (!se2) 2899 2900 return 5; 2900 2901 2901 2902 assert(se2->op == TOKstring); 2902 2903 2903 2904 int len1 = len; 2904 2905 int len2 = se2->len; 2905 2906 2907 //printf("sz = %d, len1 = %d, len2 = %d\n", sz, len1, len2); 2906 2908 if (len1 == len2) 2907 2909 { 2908 2910 switch (sz) 2909 2911 { 2910 2912 case 1: 2911 return strcmp((char *)string, (char *)se2->string);2913 return memcmp((char *)string, (char *)se2->string, len1); 2912 2914 2913 2915 case 2: 2914 2916 { unsigned u; 2915 2917 d_wchar *s1 = (d_wchar *)string; 2916 2918 d_wchar *s2 = (d_wchar *)se2->string; 2917 2919 2918 2920 for (u = 0; u < len; u++) 2919 2921 { 2920 2922 if (s1[u] != s2[u]) 2921 2923 return s1[u] - s2[u]; 2922 2924 } 2923 2925 } 2924 2926 2925 2927 case 4: 2926 2928 { unsigned u; 2927 2929 d_dchar *s1 = (d_dchar *)string; 2928 2930 d_dchar *s2 = (d_dchar *)se2->string; 2929 2931 2930 2932 for (u = 0; u < len; u++) 2931 2933 { trunk/src/toctype.c
r762 r798 388 388 389 389 //printf("t = %p, Tflags = x%x\n", t, t->Tflags); 390 390 return t; 391 391 } 392 392 393 393 type *TypeEnum::toCtype() 394 394 { 395 395 if (ctype) 396 396 return ctype; 397 397 398 398 //printf("TypeEnum::toCtype() '%s'\n", sym->toChars()); 399 399 type *t; 400 400 Type *tm = mutableOf(); 401 401 if (tm->ctype && tybasic(tm->ctype->Tty) == TYenum) 402 402 { 403 403 Symbol *s = tm->ctype->Ttag; 404 404 assert(s); 405 405 t = type_alloc(TYenum); 406 406 t->Ttag = (Classsym *)s; // enum tag name 407 407 t->Tcount++; 408 t->Tnext = tm->ctype->Tnext; 409 t->Tnext->Tcount++; 408 410 // Add modifiers 409 411 switch (mod) 410 412 { 411 413 case 0: 412 414 assert(0); 413 415 break; 414 416 case MODconst: 415 417 case MODwild: 416 418 t->Tty |= mTYconst; 417 419 break; 418 420 case MODimmutable: 419 421 t->Tty |= mTYimmutable; 420 422 break; 421 423 case MODshared: 422 424 t->Tty |= mTYshared; 423 425 break; 424 426 case MODshared | MODwild: 425 427 case MODshared | MODconst: 426 428 t->Tty |= mTYshared | mTYconst; 427 429 break; trunk/src/toobj.c
r684 r798 62 62 63 63 csym->Sclass = SCglobal; 64 64 csym->Sfl = FLdata; 65 65 66 66 #if 1 67 67 dt_t *dt = NULL; 68 68 ClassDeclarations aclasses; 69 69 70 70 //printf("members->dim = %d\n", members->dim); 71 71 for (int i = 0; i < members->dim; i++) 72 72 { Dsymbol *member = (Dsymbol *)members->data[i]; 73 73 74 74 //printf("\tmember '%s'\n", member->toChars()); 75 75 member->addLocalClass(&aclasses); 76 76 } 77 77 78 78 // importedModules[] 79 79 int aimports_dim = aimports.dim; 80 80 for (int i = 0; i < aimports.dim; i++) 81 81 { Module *m = (Module *)aimports.data[i]; 82 if (!m->need ModuleInfo())82 if (!m->needmoduleinfo) 83 83 aimports_dim--; 84 84 } 85 85 86 86 FuncDeclaration *sgetmembers = findGetMembers(); 87 87 88 88 // These must match the values in druntime/src/object_.d 89 89 #define MIstandalone 4 90 90 #define MItlsctor 8 91 91 #define MItlsdtor 0x10 92 92 #define MIctor 0x20 93 93 #define MIdtor 0x40 94 94 #define MIxgetMembers 0x80 95 95 #define MIictor 0x100 96 96 #define MIunitTest 0x200 97 97 #define MIimportedModules 0x400 98 98 #define MIlocalClasses 0x800 99 99 #define MInew 0x80000000 // it's the "new" layout 100 100 101 101 unsigned flags = MInew; 102 102 if (sctor) … … 127 127 if (flags & MItlsctor) 128 128 dtxoff(&dt, sctor, 0, TYnptr); 129 129 if (flags & MItlsdtor) 130 130 dtxoff(&dt, sdtor, 0, TYnptr); 131 131 if (flags & MIctor) 132 132 dtxoff(&dt, ssharedctor, 0, TYnptr); 133 133 if (flags & MIdtor) 134 134 dtxoff(&dt, sshareddtor, 0, TYnptr); 135 135 if (flags & MIxgetMembers) 136 136 dtxoff(&dt, sgetmembers->toSymbol(), 0, TYnptr); 137 137 if (flags & MIictor) 138 138 dtxoff(&dt, sictor, 0, TYnptr); 139 139 if (flags & MIunitTest) 140 140 dtxoff(&dt, stest, 0, TYnptr); 141 141 if (flags & MIimportedModules) 142 142 { 143 143 dtsize_t(&dt, aimports_dim); 144 144 for (int i = 0; i < aimports.dim; i++) 145 145 { Module *m = (Module *)aimports.data[i]; 146 146 147 if (m->need ModuleInfo())147 if (m->needmoduleinfo) 148 148 { Symbol *s = m->toSymbol(); 149 149 150 150 /* Weak references don't pull objects in from the library, 151 151 * they resolve to 0 if not pulled in by something else. 152 152 * Don't pull in a module just because it was imported. 153 153 */ 154 154 #if !OMFOBJ // Optlink crashes with weak symbols at EIP 41AFE7, 402000 155 155 s->Sflags |= SFLweak; 156 156 #endif 157 157 dtxoff(&dt, s, 0, TYnptr); 158 158 } 159 159 } 160 160 } 161 161 if (flags & MIlocalClasses) 162 162 { 163 163 dtsize_t(&dt, aclasses.dim); 164 164 for (int i = 0; i < aclasses.dim; i++) 165 165 { 166 166 ClassDeclaration *cd = (ClassDeclaration *)aclasses.data[i]; 167 167 dtxoff(&dt, cd->toSymbol(), 0, TYnptr);
