Changeset 618
- Timestamp:
- 08/15/10 20:25:05 (14 years ago)
- Files:
-
- branches/dmd-1.x/src/aggregate.h (modified) (1 diff)
- branches/dmd-1.x/src/backend/cdef.h (modified) (1 diff)
- branches/dmd-1.x/src/backend/cgcod.c (modified) (2 diffs)
- branches/dmd-1.x/src/backend/cgelem.c (modified) (3 diffs)
- branches/dmd-1.x/src/backend/cgreg.c (modified) (2 diffs)
- branches/dmd-1.x/src/backend/cgsched.c (modified) (1 diff)
- branches/dmd-1.x/src/backend/cod1.c (modified) (4 diffs)
- branches/dmd-1.x/src/backend/cod4.c (modified) (2 diffs)
- branches/dmd-1.x/src/backend/code.h (modified) (2 diffs)
- branches/dmd-1.x/src/backend/debug.c (modified) (2 diffs)
- branches/dmd-1.x/src/backend/dt.c (modified) (1 diff)
- branches/dmd-1.x/src/backend/dt.h (modified) (2 diffs)
- branches/dmd-1.x/src/backend/el.c (modified) (2 diffs)
- branches/dmd-1.x/src/backend/evalu8.c (modified) (3 diffs)
- branches/dmd-1.x/src/backend/ptrntab.c (modified) (4 diffs)
- branches/dmd-1.x/src/backend/ty.h (modified) (2 diffs)
- branches/dmd-1.x/src/backend/var.c (modified) (1 diff)
- branches/dmd-1.x/src/e2ir.c (modified) (9 diffs)
- branches/dmd-1.x/src/iasm.c (modified) (1 diff)
- branches/dmd-1.x/src/mars.c (modified) (1 diff)
- branches/dmd-1.x/src/s2ir.c (modified) (1 diff)
- branches/dmd-1.x/src/toobj.c (modified) (5 diffs)
- trunk/src/aggregate.h (modified) (1 diff)
- trunk/src/backend/cdef.h (modified) (1 diff)
- trunk/src/backend/cgcod.c (modified) (2 diffs)
- trunk/src/backend/cgelem.c (modified) (3 diffs)
- trunk/src/backend/cgreg.c (modified) (2 diffs)
- trunk/src/backend/cgsched.c (modified) (1 diff)
- trunk/src/backend/cod1.c (modified) (4 diffs)
- trunk/src/backend/cod4.c (modified) (2 diffs)
- trunk/src/backend/code.h (modified) (2 diffs)
- trunk/src/backend/debug.c (modified) (2 diffs)
- trunk/src/backend/dt.c (modified) (1 diff)
- trunk/src/backend/dt.h (modified) (2 diffs)
- trunk/src/backend/el.c (modified) (2 diffs)
- trunk/src/backend/evalu8.c (modified) (3 diffs)
- trunk/src/backend/ptrntab.c (modified) (4 diffs)
- trunk/src/backend/ty.h (modified) (2 diffs)
- trunk/src/backend/var.c (modified) (1 diff)
- trunk/src/e2ir.c (modified) (9 diffs)
- trunk/src/iasm.c (modified) (1 diff)
- trunk/src/s2ir.c (modified) (1 diff)
- trunk/src/toobj.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/dmd-1.x/src/aggregate.h
r520 r618 172 172 ClassDeclaration *base; 173 173 int offset; // 'this' pointer offset 174 174 Array vtbl; // for interfaces: Array of FuncDeclaration's 175 175 // making up the vtbl[] 176 176 177 177 int baseInterfaces_dim; 178 178 BaseClass *baseInterfaces; // if BaseClass is an interface, these 179 179 // are a copy of the InterfaceDeclaration::interfaces 180 180 181 181 BaseClass(); 182 182 BaseClass(Type *type, enum PROT protection); 183 183 184 184 int fillVtbl(ClassDeclaration *cd, Array *vtbl, int newinstance); 185 185 void copyBaseInterfaces(BaseClasses *); 186 186 }; 187 187 188 188 #if DMDV2 189 189 #define CLASSINFO_SIZE (0x3C+16+4) // value of ClassInfo.size 190 190 #else 191 191 #define CLASSINFO_SIZE (0x3C+12+4) // value of ClassInfo.size 192 #define CLASSINFO_SIZE_64 (0x98) // value of ClassInfo.size 192 193 #endif 193 194 194 195 struct ClassDeclaration : AggregateDeclaration 195 196 { 196 197 static ClassDeclaration *object; 197 198 static ClassDeclaration *classinfo; 198 199 199 200 ClassDeclaration *baseClass; // NULL only if this is Object 200 201 #if DMDV1 201 202 CtorDeclaration *ctor; 202 203 CtorDeclaration *defaultCtor; // default constructor 203 204 #endif 204 205 FuncDeclaration *staticCtor; 205 206 FuncDeclaration *staticDtor; 206 207 Array vtbl; // Array of FuncDeclaration's making up the vtbl[] 207 208 Array vtblFinal; // More FuncDeclaration's that aren't in vtbl[] 208 209 209 210 BaseClasses *baseclasses; // Array of BaseClass's; first is super, 210 211 // rest are Interface's 211 212 branches/dmd-1.x/src/backend/cdef.h
r593 r618 879 879 immed_t immed; // immediate values in registers 880 880 regm_t mvar; // mask of register variables 881 881 regm_t mpvar; // mask of SCfastpar register variables 882 882 regm_t indexregs; // !=0 if more than 1 uncommitted index register 883 883 regm_t used; // mask of registers used 884 884 regm_t params; // mask of registers which still contain register 885 885 // function parameters 886 886 }; 887 887 888 888 /********************************* 889 889 * Bootstrap complex types. 890 890 */ 891 891 892 892 #include "bcomplex.h" 893 893 894 894 /********************************* 895 895 * Union of all data types. Storage allocated must be the right 896 896 * size of the data on the TARGET, not the host. 897 897 */ 898 898 899 struct Cent 900 { 901 targ_ullong lsw; 902 targ_ullong msw; 903 }; 904 899 905 union eve 900 906 { 901 907 targ_char Vchar; 902 908 targ_schar Vschar; 903 909 targ_uchar Vuchar; 904 910 targ_short Vshort; 905 911 targ_ushort Vushort; 906 912 targ_int Vint; // also used for tmp numbers (FLtmp) 907 913 targ_uns Vuns; 908 914 targ_long Vlong; 909 915 targ_ulong Vulong; 910 916 targ_llong Vllong; 911 917 targ_ullong Vullong; 918 Cent Vcent; 912 919 targ_float Vfloat; 913 920 targ_double Vdouble; 914 921 targ_ldouble Vldouble; 915 922 Complex_f Vcfloat; // 2x float 916 923 Complex_d Vcdouble; // 2x double 917 924 Complex_ld Vcldouble; // 2x long double 918 925 targ_size_t Vpointer; 919 926 targ_ptrdiff_t Vptrdiff; 920 927 targ_uchar Vreg; // register number for OPreg elems 921 928 struct // 48 bit 386 far pointer 922 929 { targ_long Voff; 923 930 targ_ushort Vseg; 924 931 } Vfp; 925 932 struct 926 933 { 927 934 targ_size_t Voffset;// offset from symbol 928 935 Symbol *Vsym; // pointer to symbol table 929 936 union 930 937 { struct PARAM *Vtal; // template-argument-list for SCfunctempl, 931 938 // used only to transmit it to cpp_overload() branches/dmd-1.x/src/backend/cgcod.c
r596 r618 1833 1833 r = retregs & ~(msavereg | regcon.cse.mops); 1834 1834 if (!r) 1835 1835 { r = retregs & ~msavereg; 1836 1836 if (!r) 1837 1837 r = retregs; 1838 1838 } 1839 1839 } 1840 1840 } 1841 1841 if (0 && r & ~fregsaved) 1842 1842 r &= ~fregsaved; 1843 1843 1844 1844 if (size <= REGSIZE) 1845 1845 { 1846 1846 if (r & ~mBP) 1847 1847 r &= ~mBP; 1848 1848 1849 1849 // If only one index register, prefer to not use LSW registers 1850 1850 if (!regcon.indexregs && r & ~mLSW) 1851 1851 r &= ~mLSW; 1852 1852 1853 if (pass == PASSfinal && r & ~lastretregs && I32)1853 if (pass == PASSfinal && r & ~lastretregs && !I16) 1854 1854 { // Try not to always allocate the same register, 1855 1855 // to schedule better 1856 1856 1857 1857 r &= ~lastretregs; 1858 1858 if (r & ~last2retregs) 1859 1859 { r &= ~last2retregs; 1860 1860 if (r & ~last3retregs) 1861 1861 { r &= ~last3retregs; 1862 1862 if (r & ~last4retregs) 1863 1863 { r &= ~last4retregs; 1864 1864 // if (r & ~last5retregs) 1865 1865 // r &= ~last5retregs; 1866 1866 } 1867 1867 } 1868 1868 } 1869 1869 if (r & ~mfuncreg) 1870 1870 r &= ~mfuncreg; 1871 1871 } 1872 1872 reg = findreg(r); 1873 1873 retregs = mask[reg]; … … 2714 2714 #define SMAX 64 2715 2715 static char str[NUM][SMAX + 1]; 2716 2716 static int i; 2717 2717 char *p; 2718 2718 char *s; 2719 2719 int j; 2720 2720 2721 2721 if (rm == 0) 2722 2722 return "0"; 2723 2723 if (rm == ALLREGS) 2724 2724 return "ALLREGS"; 2725 2725 if (rm == BYTEREGS) 2726 2726 return "BYTEREGS"; 2727 2727 if (rm == allregs) 2728 2728 return "allregs"; 2729 2729 p = str[i]; 2730 2730 if (++i == NUM) 2731 2731 i = 0; 2732 2732 s = p; 2733 2733 *p = 0; 2734 for (j = 0; j < 23; j++)2734 for (j = 0; j < 32; j++) 2735 2735 { 2736 2736 if (mask[j] & rm) 2737 2737 { 2738 2738 strcat(p,regstring[j]); 2739 2739 rm &= ~mask[j]; 2740 2740 if (rm) 2741 2741 strcat(p,"|"); 2742 2742 } 2743 2743 } 2744 2744 if (rm) 2745 2745 { s = p + strlen(p); 2746 2746 sprintf(s,"x%02x",rm); 2747 2747 } 2748 2748 assert(strlen(p) <= SMAX); 2749 2749 return strdup(p); 2750 2750 } 2751 2751 2752 2752 #endif 2753 2753 2754 2754 #endif // !SPP branches/dmd-1.x/src/backend/cgelem.c
r500 r618 1993 1993 e->E1->Ety = touns(tym); 1994 1994 break; 1995 1995 1996 1996 case OPmod: 1997 1997 op = OPand; 1998 1998 goto L3; 1999 1999 case OPmodass: 2000 2000 op = OPandass; 2001 2001 L3: 2002 2002 e2->EV.Vullong = el_tolong(e2) - 1; 2003 2003 break; 2004 2004 2005 2005 default: 2006 2006 assert(0); 2007 2007 } 2008 2008 e->Eoper = op; 2009 2009 return optelem(e,TRUE); 2010 2010 } 2011 2011 #if TARGET_MAC 2012 2012 if (j != -1) 2013 { elem *ea; 2014 2015 ea = el_copytree(e->E1); 2013 { 2014 elem *ea = el_copytree(e->E1); 2016 2015 e2->EV.Vint = j; 2017 2016 e->Eoper = OPshr; 2018 2017 e->E1->Ety = touns(tym); 2019 2018 e2->Ety = TYint; 2020 2019 e = el_una(OPneg,tym,e); 2021 2020 e = el_bin(OPeq,tym,ea,e); 2022 2021 return optelem(e,TRUE); 2023 2022 } 2024 2023 #endif 2025 2024 } 2026 2025 #if TARGET_MAC 2027 2026 unsigned short op; 2028 2027 tym_t tym2; 2029 2028 elem *e1 = e->E1; 2030 2029 2031 2030 tym = e->E1->Ety; 2032 2031 op = e1->Eoper; 2033 2032 if (op == OPu16_32 && e2->EV.Vulong <= (targ_ulong) SHORTMASK || 2034 2033 op == OPshtlng && e2->EV.Vlong == (targ_short) e2->EV.Vlong) 2035 2034 { … … 2080 2079 2081 2080 if (OPTIMIZER) 2082 2081 { 2083 2082 if (tyintegral(tym) && (e->Eoper == OPdiv || e->Eoper == OPmod)) 2084 2083 { int sz = tysize(tym); 2085 2084 2086 2085 // See if we can replace with OPremquo 2087 2086 if (sz == intsize) 2088 2087 { 2089 2088 // Don't do it if there are special code sequences in the 2090 2089 // code generator (see cdmul()) 2091 2090 int pow2; 2092 2091 if (e->E2->Eoper == OPconst && 2093 2092 sz == REGSIZE && !uns && 2094 2093 (pow2 = ispow2(el_tolong(e->E2))) != -1 && 2095 2094 !(config.target_cpu < TARGET_80286 && pow2 != 1 && e->Eoper == OPdiv) 2096 2095 ) 2097 2096 ; 2098 2097 else 2099 2098 { 2100 int op; 2101 2102 op = OPmsw; 2099 assert(sz == 2 || sz == 4); 2100 int op = OPmsw; 2103 2101 if (e->Eoper == OPdiv) 2104 2102 { 2105 2103 op = (sz == 2) ? OP32_16 : OP64_32; 2106 2104 } 2107 2105 e->Eoper = OPremquo; 2108 2106 e = el_una(op, tym, e); 2109 2107 e->E1->Ety = (sz == 2) ? TYlong : TYllong; 2110 2108 } 2111 2109 } 2112 2110 } 2113 2111 } 2114 2112 2115 2113 return e; 2116 2114 } 2117 2115 2118 2116 2119 2117 /************************** 2120 2118 * Convert (a op b) op c to a op (b op c). 2121 2119 */ 2122 2120 … … 3824 3822 if (tysize(ty) != tysize(e->E1->E1->Ety)) 3825 3823 break; 3826 3824 e = el_selecte1(el_selecte1(e)); 3827 3825 e->Ety = ty; 3828 3826 break; 3829 3827 3830 3828 case OPrpair: 3831 3829 if (tysize(ty) != tysize(e->E1->E2->Ety)) 3832 3830 break; 3833 3831 e = el_selecte2(el_selecte1(e)); 3834 3832 e->Ety = ty; 3835 3833 break; 3836 3834 3837 3835 case OPvar: // simply paint type of variable 3838 3836 case OPind: 3839 3837 e = el_selecte1(e); 3840 3838 break; 3841 3839 3842 3840 case OPshr: // OP64_32(x >> 32) => OPmsw(x) 3843 3841 if (e1->E2->Eoper == OPconst && 3844 el_tolong(e1->E2) == 32 )3842 el_tolong(e1->E2) == 32 && !I64) 3845 3843 { 3846 3844 e->Eoper = OPmsw; 3847 3845 e->E1 = el_selecte1(e->E1); 3848 3846 } 3849 3847 break; 3850 3848 } 3851 3849 return e; 3852 3850 } 3853 3851 3854 3852 3855 3853 /******************************* 3856 3854 * Convert complex to real. 3857 3855 */ 3858 3856 3859 3857 STATIC elem *elc_r(elem *e) 3860 3858 { 3861 3859 elem *e1 = e->E1; 3862 3860 3863 3861 if (e1->Eoper == OPvar || e1->Eoper == OPind) 3864 3862 { branches/dmd-1.x/src/backend/cgreg.c
r569 r618 675 675 } 676 676 if (inoutp == 1) 677 677 cstore = cat(cstore,c); 678 678 else 679 679 cload = cat(cload,c); 680 680 break; 681 681 } 682 682 el_free(e); 683 683 684 684 // Store old register values before loading in new ones 685 685 *pcstore = cstore; 686 686 *pcload = cload; 687 687 } 688 688 689 689 /*************************** 690 690 * Map symbol s into registers [NOREG,reglsw] or [regmsw, reglsw]. 691 691 */ 692 692 693 693 void cgreg_map(Symbol *s, unsigned regmsw, unsigned reglsw) 694 694 { 695 assert( reglsw < 8);695 assert(I64 || reglsw < 8); 696 696 697 697 if (vec_disjoint(s->Srange,regrange[reglsw]) && 698 698 (regmsw == NOREG || vec_disjoint(s->Srange,regrange[regmsw])) 699 699 ) 700 700 { 701 701 s->Sfl = FLreg; 702 702 vec_copy(s->Slvreg,s->Srange); 703 703 } 704 704 else 705 705 { 706 706 s->Sflags |= SFLspill; 707 707 708 708 // Already computed by cgreg_benefit() 709 709 //vec_sub(s->Slvreg,s->Srange,regrange[reglsw]); 710 710 711 711 if (s->Sfl == FLreg) // if reassigned 712 712 { 713 713 switch (s->Sclass) 714 714 { 715 715 case SCauto: … … 897 897 #ifdef DEBUG 898 898 if (debugr) 899 899 if (s->Sfl == FLreg) 900 900 printf("symbol '%s' is in reg %s\n",s->Sident,regm_str(s->Sregm)); 901 901 else if (s->Sflags & SFLspill) 902 902 printf("symbol '%s' spilled in reg %s\n",s->Sident,regm_str(s->Sregm)); 903 903 else 904 904 printf("symbol '%s' is not a candidate\n",s->Sident); 905 905 #endif 906 906 continue; 907 907 } 908 908 909 909 char *pseq; 910 910 char *pseqmsw = NULL; 911 911 912 912 ty = s->ty(); 913 913 sz = tysize(ty); 914 914 915 915 #ifdef DEBUG 916 916 if (debugr) 917 { printf("symbol '%3s', ty x% lx weight x%x sz %d\n ",918 s->Sident,ty,s->Sweight, sz);917 { printf("symbol '%3s', ty x%x weight x%x sz %d\n ", 918 s->Sident,ty,s->Sweight,(int)sz); 919 919 vec_println(s->Srange); 920 920 } 921 921 #endif 922 922 923 923 if (I64) 924 924 { 925 925 if (sz == REGSIZE * 2) 926 926 { 927 927 static char seqmsw[] = {CX,DX,NOREG}; 928 928 static char seqlsw[] = {AX,BX,SI,DI,NOREG}; 929 929 pseq = seqlsw; 930 930 pseqmsw = seqmsw; 931 931 } 932 932 else 933 933 { // R10 is reserved for the static link 934 934 static char sequence[] = {AX,CX,DX,SI,DI,R8,R9,R11,BX,R12,R13,R14,R15,BP,NOREG}; 935 935 pseq = sequence; 936 936 } 937 937 } 938 938 else if (I32) branches/dmd-1.x/src/backend/cgsched.c
r596 r618 3161 3161 3162 3162 if (ci == NULL) 3163 3163 { 3164 3164 printf("Cinfo 0\n"); 3165 3165 return; 3166 3166 } 3167 3167 3168 3168 printf("Cinfo %p: c %p, pair %x, sz %d, isz %d, flags - ", 3169 3169 ci,c,pair,sz,isz); 3170 3170 if (ci->flags & CIFLarraybounds) 3171 3171 printf("arraybounds,"); 3172 3172 if (ci->flags & CIFLea) 3173 3173 printf("ea,"); 3174 3174 if (ci->flags & CIFLnostage) 3175 3175 printf("nostage,"); 3176 3176 if (ci->flags & CIFLpush) 3177 3177 printf("push,"); 3178 3178 if (ci->flags & ~(CIFLarraybounds|CIFLnostage|CIFLpush|CIFLea)) 3179 3179 printf("bad flag,"); 3180 3180 printf("\n\tr %lx w %lx a %lx reg %x uops %x sibmodrm %x spadjust %ld\n", 3181 r,w,a,reg,uops,sibmodrm,spadjust);3181 (long)r,(long)w,(long)a,reg,uops,sibmodrm,(long)spadjust); 3182 3182 if (ci->fp_op) 3183 3183 printf("\tfp_op %s, fxch_pre %x, fxch_post %x\n", 3184 3184 fpops[fp_op-1],fxch_pre,fxch_post); 3185 3185 } 3186 3186 #endif 3187 3187 #endif branches/dmd-1.x/src/backend/cod1.c
r606 r618 1784 1784 else 1785 1785 assert(0); 1786 1786 } 1787 1787 code_orflag(ce,CFpsw); 1788 1788 return ce; 1789 1789 } 1790 1790 1791 1791 1792 1792 /****************************** 1793 1793 * Given the result of an expression is in retregs, 1794 1794 * generate necessary code to return result in *pretregs. 1795 1795 */ 1796 1796 1797 1797 code *fixresult(elem *e,regm_t retregs,regm_t *pretregs) 1798 1798 { code *c,*ce; 1799 1799 unsigned reg,rreg; 1800 1800 regm_t forccs,forregs; 1801 1801 tym_t tym; 1802 1802 int sz; 1803 1803 1804 // printf("fixresult(e = %p, retregs = %s, *pretregs = %s)\n", 1805 // e,regm_str(retregs),regm_str(*pretregs)); 1804 //printf("fixresult(e = %p, retregs = %s, *pretregs = %s)\n",e,regm_str(retregs),regm_str(*pretregs)); 1806 1805 if (*pretregs == 0) return CNIL; /* if don't want result */ 1807 1806 assert(e && retregs); /* need something to work with */ 1808 1807 forccs = *pretregs & mPSW; 1809 1808 forregs = *pretregs & (mST01 | mST0 | mBP | ALLREGS | mES | mSTACK); 1810 1809 tym = tybasic(e->Ety); 1811 1810 #if 0 1812 1811 if (tym == TYstruct) 1813 1812 // Hack to support cdstreq() 1814 1813 tym = TYfptr; 1815 1814 #else 1816 1815 if (tym == TYstruct) 1817 1816 // Hack to support cdstreq() 1818 1817 tym = (forregs & mMSW) ? TYfptr : TYnptr; 1819 1818 #endif 1820 1819 c = CNIL; 1821 1820 sz = tysize[tym]; 1822 1821 if (sz == 1) 1823 1822 { 1824 1823 assert(retregs & BYTEREGS); 1825 1824 unsigned reg = findreg(retregs); … … 3309 3308 if (I16 && config.target_cpu >= TARGET_80386 && sz > 2 && 3310 3309 !e->Ecount) 3311 3310 { regsize = 4; 3312 3311 flag |= CFopsize; 3313 3312 } 3314 3313 ce = loadea(e,&cs,0xFF,6,sz - regsize,RMload,0); // PUSH EA+sz-2 3315 3314 code_orflag(ce,flag); 3316 3315 ce = genadjesp(ce,REGSIZE); 3317 3316 stackpush += sz; 3318 3317 while ((targ_int)(sz -= regsize) > 0) 3319 3318 { ce = cat(ce,loadea(e,&cs,0xFF,6,sz - regsize,RMload,0)); 3320 3319 code_orflag(ce,flag); 3321 3320 ce = genadjesp(ce,REGSIZE); 3322 3321 } 3323 3322 } 3324 3323 L2: 3325 3324 freenode(e); 3326 3325 c = cat(c,ce); 3327 3326 goto ret; 3328 3327 case OPconst: 3329 { targ_int *pi; 3330 targ_short *ps; 3328 { 3331 3329 char pushi = 0; 3332 3330 unsigned flag = 0; 3333 int i;3334 3331 int regsize = REGSIZE; 3335 3332 targ_int value; 3336 3333 3337 3334 if (tycomplex(tym)) 3338 3335 break; 3339 3336 3340 3337 if (I32 && szb == 10) // special case for long double constants 3341 3338 { 3342 3339 assert(sz == 12); 3343 3340 value = ((unsigned short *)&e->EV.Vldouble)[4]; 3344 3341 stackpush += sz; 3345 3342 ce = genadjesp(NULL,sz); 3346 for (i = 2; i >= 0; i--)3343 for (int i = 2; i >= 0; i--) 3347 3344 { 3348 3345 if (reghasvalue(allregs, value, ®)) 3349 3346 ce = gen1(ce,0x50 + reg); // PUSH reg 3350 3347 else 3351 3348 ce = genc2(ce,0x68,0,value); // PUSH value 3352 3349 value = ((unsigned *)&e->EV.Vldouble)[i - 1]; 3353 3350 } 3354 3351 goto L2; 3355 3352 } 3356 3353 3357 assert( sz <= LNGDBLSIZE);3358 i = sz;3359 if ( I32&& i == 2)3354 assert(I64 || sz <= LNGDBLSIZE); 3355 int i = sz; 3356 if (!I16 && i == 2) 3360 3357 flag = CFopsize; 3361 3358 3362 3359 if (config.target_cpu >= TARGET_80286) 3363 3360 // && (e->Ecount == 0 || e->Ecount != e->Ecomsub)) 3364 3361 { pushi = 1; 3365 3362 if (I16 && config.target_cpu >= TARGET_80386 && i >= 4) 3366 3363 { regsize = 4; 3367 3364 flag = CFopsize; 3368 3365 } 3369 3366 } 3370 3367 else if (i == REGSIZE) 3371 3368 break; 3372 3369 3373 3370 stackpush += sz; 3374 3371 ce = genadjesp(NULL,sz); 3375 pi = (targ_long *) &e->EV.Vdouble; 3376 ps = (targ_short *) pi; 3372 targ_uns *pi = (targ_uns *) &e->EV.Vdouble; 3373 targ_ushort *ps = (targ_ushort *) pi; 3374 targ_ullong *pl = (targ_ullong *)pi; 3377 3375 i /= regsize; 3378 3376 do 3379 3377 { code *cp; 3380 3378 3381 3379 if (i) /* be careful not to go negative */ 3382 3380 i--; 3383 value = (regsize == 4) ? pi[i] : ps[i]; 3381 targ_size_t value = (regsize == 4) ? pi[i] : ps[i]; 3382 if (regsize == 8) 3383 value = pl[i]; 3384 3384 if (pushi) 3385 3385 { 3386 3386 if (regsize == REGSIZE && reghasvalue(allregs,value,®)) 3387 3387 goto Preg; 3388 3388 ce = genc2(ce,(szb == 1) ? 0x6A : 0x68,0,value); // PUSH value 3389 3389 } 3390 3390 else 3391 3391 { 3392 3392 ce = regwithvalue(ce,allregs,value,®,0); 3393 3393 Preg: 3394 3394 ce = genpush(ce,reg); // PUSH reg 3395 3395 } 3396 3396 code_orflag(ce,flag); /* operand size */ 3397 3397 } while (i); 3398 3398 goto L2; 3399 3399 } 3400 3400 default: 3401 3401 break; 3402 3402 } 3403 3403 retregs = tybyte(tym) ? BYTEREGS : allregs; … … 3449 3449 c2 = genc1(CNIL,op,(modregrm(0,4,SP) << 8) | modregxrm(2,r,4),FLconst,sz/2); 3450 3450 pop87(); 3451 3451 } 3452 3452 pop87(); 3453 3453 c2 = gen2sib(c2,op,modregrm(0,r,4),modregrm(0,4,SP)); // FSTP [ESP] 3454 3454 } 3455 3455 else 3456 3456 { 3457 3457 retregs = IDXREGS; /* get an index reg */ 3458 3458 c1 = allocreg(&retregs,®,TYoffset); 3459 3459 c1 = genregs(c1,0x89,SP,reg); /* MOV reg,SP */ 3460 3460 pop87(); 3461 3461 c2 = gen2(CNIL,op,modregrm(0,r,regtorm[reg])); // FSTP [reg] 3462 3462 } 3463 3463 if (LARGEDATA) 3464 3464 c2->Iflags |= CFss; /* want to store into stack */ 3465 3465 genfwait(c2); // FWAIT 3466 3466 c = cat3(c,c1,c2); 3467 3467 goto ret; 3468 3468 } 3469 else if ( !I32&& (tym == TYdouble || tym == TYdouble_alias))3469 else if (I16 && (tym == TYdouble || tym == TYdouble_alias)) 3470 3470 retregs = mSTACK; 3471 3471 } 3472 3472 #if LONGLONG 3473 else if ( !I32&& sz == 8) // if long long3473 else if (I16 && sz == 8) // if long long 3474 3474 retregs = mSTACK; 3475 3475 #endif 3476 3476 c = cat(c,scodelem(e,&retregs,0,TRUE)); 3477 3477 if (retregs != mSTACK) /* if stackpush not already inc'd */ 3478 3478 stackpush += sz; 3479 3479 if (sz <= REGSIZE) 3480 3480 { 3481 3481 c = genpush(c,findreg(retregs)); // PUSH reg 3482 3482 genadjesp(c,REGSIZE); 3483 3483 } 3484 3484 else if (sz == REGSIZE * 2) 3485 3485 { c = genpush(c,findregmsw(retregs)); // PUSH msreg 3486 3486 genpush(c,findreglsw(retregs)); // PUSH lsreg 3487 3487 genadjesp(c,sz); 3488 3488 } 3489 3489 ret: 3490 3490 return cat(cp,c); 3491 3491 } 3492 3492 3493 3493 … … 3693 3693 } 3694 3694 ce = movregconst(ce,reg,msw,mswflags); 3695 3695 } 3696 3696 else if (sz == 8) 3697 3697 { 3698 3698 if (I32) 3699 3699 { targ_long *p = (targ_long *) &e->EV.Vdouble; 3700 3700 ce = movregconst(CNIL,findreglsw(forregs),p[0],0); 3701 3701 ce = movregconst(ce,findregmsw(forregs),p[1],0); 3702 3702 } 3703 3703 else 3704 3704 { targ_short *p = (targ_short *) &e->EV.Vdouble; 3705 3705 3706 3706 assert(reg == AX); 3707 3707 ce = movregconst(CNIL,AX,p[3],0); /* MOV AX,p[3] */ 3708 3708 ce = movregconst(ce,DX,p[0],0); 3709 3709 ce = movregconst(ce,CX,p[1],0); 3710 3710 ce = movregconst(ce,BX,p[2],0); 3711 3711 } 3712 3712 } 3713 else if (I64 && sz == 16) 3714 { 3715 ce = movregconst(CNIL,findreglsw(forregs),e->EV.Vcent.lsw,0); 3716 ce = movregconst(ce,findregmsw(forregs),e->EV.Vcent.msw,0); 3717 } 3713 3718 else 3714 3719 assert(0); 3715 3720 c = cat(c,ce); 3716 3721 } 3717 3722 else 3718 3723 { 3719 3724 // See if we can use register that parameter was passed in 3720 3725 if (regcon.params && e->EV.sp.Vsym->Sclass == SCfastpar && 3721 3726 regcon.params & mask[e->EV.sp.Vsym->Spreg] && 3722 3727 !(e->Eoper == OPvar && e->EV.sp.Voffset > 0) && // Must be at the base of that variable 3723 3728 sz <= REGSIZE) // make sure no 'paint' to a larger size happened 3724 3729 { 3725 3730 reg = e->EV.sp.Vsym->Spreg; 3726 3731 forregs = mask[reg]; 3727 3732 mfuncreg &= ~forregs; 3728 3733 regcon.used |= forregs; 3729 3734 return fixresult(e,forregs,pretregs); 3730 3735 } 3731 3736 3732 3737 c = allocreg(&forregs,®,tym); /* allocate registers */ branches/dmd-1.x/src/backend/cod4.c
r596 r618 2461 2461 { assert(i < arraysize(clib)); 2462 2462 if (clib[i][0] == e->Eoper) 2463 2463 { c2 = callclib(e,clib[i][1],pretregs,0); 2464 2464 break; 2465 2465 } 2466 2466 } 2467 2467 return cat(c1,c2); 2468 2468 } 2469 2469 2470 2470 2471 2471 /*************************** 2472 2472 * Convert short to long. 2473 2473 * For OPs16_32, OPu16_32, OPptrlptr, OPu32_64, OPs32_64 2474 2474 */ 2475 2475 2476 2476 code *cdshtlng(elem *e,regm_t *pretregs) 2477 2477 { code *c,*ce,*c1,*c2,*c3,*c4; 2478 2478 unsigned reg; 2479 2479 unsigned char op; 2480 2480 regm_t retregs; 2481 int e1comsub; 2482 2483 e1comsub = e->E1->Ecount;2481 2482 //printf("cdshtlng(e = %p, *pretregs = %s)\n", e, regm_str(*pretregs)); 2483 int e1comsub = e->E1->Ecount; 2484 2484 if ((*pretregs & (ALLREGS | mBP)) == 0) // if don't need result in regs 2485 2485 c = codelem(e->E1,pretregs,FALSE); /* then conversion isn't necessary */ 2486 2486 2487 2487 else if ((op = e->Eoper) == OPptrlptr || 2488 2488 (I16 && op == OPu16_32) || 2489 2489 (I32 && op == OPu32_64) 2490 2490 ) 2491 2491 { 2492 2492 regm_t regm; 2493 2493 tym_t tym1; 2494 2494 2495 2495 retregs = *pretregs & mLSW; 2496 2496 assert(retregs); 2497 2497 tym1 = tybasic(e->E1->Ety); 2498 2498 c = codelem(e->E1,&retregs,FALSE); 2499 2499 2500 2500 regm = *pretregs & (mMSW & ALLREGS); 2501 2501 if (regm == 0) /* *pretregs could be mES */ 2502 2502 regm = mMSW & ALLREGS; 2503 2503 ce = allocreg(®m,®,TYint); 2504 2504 if (e1comsub) 2505 2505 ce = cat(ce,getregs(retregs)); 2506 2506 if (op == OPptrlptr) 2507 2507 { int segreg; 2508 2508 2509 2509 /* BUG: what about pointers to functions? */ 2510 2510 switch (tym1) 2511 2511 { 2512 2512 case TYnptr: segreg = SEG_DS; break; 2513 2513 case TYcptr: segreg = SEG_CS; break; 2514 2514 case TYsptr: segreg = SEG_SS; break; 2515 2515 default: assert(0); 2516 2516 } 2517 2517 ce = gen2(ce,0x8C,modregrm(3,segreg,reg)); /* MOV reg,segreg */ 2518 2518 } 2519 2519 else 2520 2520 ce = movregconst(ce,reg,0,0); /* 0 extend */ 2521 2521 2522 2522 c = cat3(c,ce,fixresult(e,retregs | regm,pretregs)); 2523 2523 } 2524 else if (!I16 && (op == OPs16_32 || op == OPu16_32)) 2524 else if (I64 && op == OPu32_64) 2525 { 2526 elem *e1 = e->E1; 2527 retregs = *pretregs; 2528 if (e1->Eoper == OPvar || (e1->Eoper == OPind && !e1->Ecount)) 2529 { code cs; 2530 2531 c1 = allocreg(&retregs,®,TYint); 2532 c2 = NULL; 2533 c3 = loadea(e1,&cs,0x8B,reg,0,retregs,retregs); // MOV Ereg,EA 2534 freenode(e1); 2535 } 2536 else 2537 { 2538 *pretregs &= ~mPSW; // flags are set by eval of e1 2539 c1 = codelem(e1,&retregs,FALSE); 2540 c2 = getregs(retregs); 2541 reg = findreg(retregs); 2542 c3 = genregs(NULL,0x89,reg,reg); // MOV Ereg,Ereg 2543 } 2544 c4 = fixresult(e,retregs,pretregs); 2545 c = cat4(c1,c2,c3,c4); 2546 } 2547 else if (!I16 && (op == OPs16_32 || op == OPu16_32) || 2548 I64 && op == OPs32_64) 2525 2549 { 2526 2550 elem *e11; 2527 2551 2528 2552 elem *e1 = e->E1; 2529 2553 2530 2554 if (e1->Eoper == OPu8_16 && !e1->Ecount && 2531 2555 ((e11 = e1->E1)->Eoper == OPvar || (e11->Eoper == OPind && !e11->Ecount)) 2532 2556 ) 2533 2557 { code cs; 2534 2558 2535 2559 retregs = *pretregs & BYTEREGS; 2536 2560 if (!retregs) 2537 2561 retregs = BYTEREGS; 2538 2562 c1 = allocreg(&retregs,®,TYint); 2539 2563 c2 = movregconst(NULL,reg,0,0); // XOR reg,reg 2540 2564 c3 = loadea(e11,&cs,0x8A,reg,0,retregs,retregs); // MOV regL,EA 2541 2565 freenode(e11); 2542 2566 freenode(e1); 2543 2567 } 2544 else if (e1->Eoper == OPvar ||2568 else if (e1->Eoper == OPvar && op != OPs32_64 || 2545 2569 (e1->Eoper == OPind && !e1->Ecount)) 2546 2570 { code cs; 2547 2571 unsigned opcode; 2548 2572 2549 2573 if (op == OPu16_32 && config.flags4 & CFG4speed) 2550 2574 goto L2; 2551 2575 retregs = *pretregs; 2552 2576 c1 = allocreg(&retregs,®,TYint); 2553 2577 opcode = (op == OPu16_32) ? 0x0FB7 : 0x0FBF; /* MOVZX/MOVSX reg,EA */ 2554 2578 c2 = loadea(e1,&cs,opcode,reg,0,0,retregs); 2555 2579 c3 = CNIL; 2556 2580 freenode(e1); 2557 2581 } 2558 2582 else 2559 2583 { 2560 2584 L2: 2561 2585 retregs = *pretregs; 2562 2586 *pretregs &= ~mPSW; /* flags are already set */ 2587 if (op == OPs32_64) 2588 retregs = mAX; 2563 2589 c1 = codelem(e1,&retregs,FALSE); 2564 2590 c2 = getregs(retregs); 2565 2591 if (op == OPu16_32 && c1) 2566 { code *cx; 2567 2568 cx = code_last(c1); 2592 { 2593 code *cx = code_last(c1); 2569 2594 if (cx->Iop == 0x81 && (cx->Irm & modregrm(3,7,0)) == modregrm(3,4,0)) 2570 2595 { 2571 2596 // Convert AND of a word to AND of a dword, zeroing upper word 2572 2597 retregs = mask[cx->Irm & 7]; 2573 2598 cx->Iflags &= ~CFopsize; 2574 2599 cx->IEV2.Vint &= 0xFFFF; 2575 2600 goto L1; 2576 2601 } 2577 2602 } 2578 2603 if (op == OPs16_32 && retregs == mAX) 2579 2604 c2 = gen1(c2,0x98); /* CWDE */ 2605 else if (op == OPs32_64 && retregs == mAX) 2606 { c2 = gen1(c2,0x98); /* CDQE */ 2607 code_orrex(c2, REX_W); 2608 } 2580 2609 else 2581 2610 { 2582 2611 reg = findreg(retregs); 2583 2612 if (config.flags4 & CFG4speed && op == OPu16_32) 2584 2613 { // AND reg,0xFFFF 2585 2614 c3 = genc2(NULL,0x81,modregrm(3,4,reg),0xFFFFu); 2586 2615 } 2587 2616 else 2588 2617 { 2589 2618 unsigned iop = (op == OPu16_32) ? 0x0FB7 : 0x0FBF; /* MOVZX/MOVSX reg,reg */ 2590 2619 c3 = genregs(CNIL,iop,reg,reg); 2591 2620 } 2592 2621 c2 = cat(c2,c3); 2593 2622 } 2594 2623 L1: 2595 2624 c3 = e1comsub ? getregs(retregs) : CNIL; 2596 2625 } 2597 2626 c4 = fixresult(e,retregs,pretregs); 2598 2627 c = cat4(c1,c2,c3,c4); 2599 2628 } … … 2806 2835 2807 2836 /* We "destroy" a reg by assigning it the result of a new e, even */ 2808 2837 /* though the values are the same. Weakness of our CSE strategy that */ 2809 2838 /* a register can only hold the contents of one elem at a time. */ 2810 2839 if (e->Ecount) 2811 2840 c = cat(c,getregs(retregs)); 2812 2841 else 2813 2842 useregs(retregs); 2814 2843 2815 2844 #ifdef DEBUG 2816 2845 if (!(!*pretregs || retregs)) 2817 2846 WROP(e->Eoper), 2818 2847 printf(" *pretregs = x%x, retregs = x%x, e = %p\n",*pretregs,retregs,e); 2819 2848 #endif 2820 2849 assert(!*pretregs || retregs); 2821 2850 return cat(c,fixresult(e,retregs,pretregs)); /* lsw only */ 2822 2851 } 2823 2852 2824 2853 /********************************************** 2825 2854 * Get top 32 bits of 64 bit value (I32) 2826 * or top 16 bits of 32 bit value (16 bit code). 2855 * or top 16 bits of 32 bit value (I16) 2856 * or top 64 bits of 128 bit value (I64). 2827 2857 * OPmsw 2828 2858 */ 2829 2859 2830 2860 code *cdmsw(elem *e,regm_t *pretregs) 2831 2861 { regm_t retregs; 2832 2862 code *c; 2833 2863 2834 2864 //printf("cdmsw(e->Ecount = %d)\n", e->Ecount); 2835 2865 assert(e->Eoper == OPmsw); 2836 2866 2837 2867 retregs = *pretregs ? ALLREGS : 0; 2838 2868 c = codelem(e->E1,&retregs,FALSE); 2839 retregs &= mMSW; // want LSW only2869 retregs &= mMSW; // want MSW only 2840 2870 2841 2871 // We "destroy" a reg by assigning it the result of a new e, even 2842 2872 // though the values are the same. Weakness of our CSE strategy that 2843 2873 // a register can only hold the contents of one elem at a time. 2844 2874 if (e->Ecount) 2845 2875 c = cat(c,getregs(retregs)); 2846 2876 else 2847 2877 useregs(retregs); 2848 2878 2849 2879 #ifdef DEBUG 2850 2880 if (!(!*pretregs || retregs)) 2851 2881 { WROP(e->Eoper); 2852 2882 printf(" *pretregs = x%x, retregs = x%x\n",*pretregs,retregs); 2853 2883 } 2854 2884 #endif 2855 2885 assert(!*pretregs || retregs); 2856 2886 return cat(c,fixresult(e,retregs,pretregs)); // msw only 2857 2887 } 2858 2888 2859 2889 branches/dmd-1.x/src/backend/code.h
r596 r618 81 81 82 82 #define mR8 (1 << R8) 83 83 #define mR9 (1 << R9) 84 84 #define mR10 (1 << R10) 85 85 #define mR11 (1 << R11) 86 86 #define mR12 (1 << R12) 87 87 #define mR13 (1 << R13) 88 88 #define mR14 (1 << R14) 89 89 #define mR15 (1 << R15) 90 90 91 91 #define mXMM0 (1 << XMM0) 92 92 #define mXMM1 (1 << XMM1) 93 93 #define mXMM2 (1 << XMM2) 94 94 #define mXMM3 (1 << XMM3) 95 95 #define mXMM4 (1 << XMM4) 96 96 #define mXMM5 (1 << XMM5) 97 97 #define mXMM6 (1 << XMM6) 98 98 #define mXMM7 (1 << XMM7) 99 99 #define XMMREGS (mXMM0 |mXMM1 |mXMM2 |mXMM3 |mXMM4 |mXMM5 |mXMM6 |mXMM7) 100 100 101 #define mES (1 << ES) // 0x10000 102 #define mPSW (1 << PSW) // 0x20000 103 104 #define mSTACK (1 << STACK) // 0x40000 105 106 #define mST0 (1 << ST0) // 0x200000 107 #define mST01 (1 << ST01) // 0x400000 101 #define mES (1 << ES) // 0x1000000 102 #define mPSW (1 << PSW) // 0x2000000 103 104 #define mSTACK (1 << STACK) // 0x4000000 105 106 #define mST0 (1 << ST0) // 0x20000000 107 #define mST01 (1 << ST01) // 0x40000000 108 108 109 109 // Flags for getlvalue (must fit in regm_t) 110 110 #define RMload (1 << 30) 111 111 #define RMstore (1 << 31) 112 112 113 113 #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 114 114 // To support positional independent code, 115 115 // must be able to remove BX from available registers 116 116 extern regm_t ALLREGS; 117 117 #define ALLREGS_INIT (mAX|mBX|mCX|mDX|mSI|mDI) 118 118 #define ALLREGS_INIT_PIC (mAX|mCX|mDX|mSI|mDI) 119 119 extern regm_t BYTEREGS; 120 120 #define BYTEREGS_INIT (mAX|mBX|mCX|mDX) 121 121 #define BYTEREGS_INIT_PIC (mAX|mCX|mDX) 122 122 #else 123 123 #define ALLREGS (mAX|mBX|mCX|mDX|mSI|mDI) 124 124 #define ALLREGS_INIT ALLREGS 125 125 #undef BYTEREGS 126 126 #define BYTEREGS (mAX|mBX|mCX|mDX) 127 127 #endif … … 379 379 #define CFpsw 0x40 // we need the flags result after this instruction 380 380 #define CFopsize 0x80 // prefix with operand size 381 381 #define CFaddrsize 0x100 // prefix with address size 382 382 #define CFds 0x200 // need DS override (not with es, ss, or cs ) 383 383 #define CFcs 0x400 // need CS override 384 384 #define CFfs 0x800 // need FS override 385 385 #define CFgs (CFcs | CFfs) // need GS override 386 386 #define CFwait 0x1000 // If I32 it indicates when to output a WAIT 387 387 #define CFselfrel 0x2000 // if self-relative 388 388 #define CFunambig 0x4000 // indicates cannot be accessed by other addressing 389 389 // modes 390 390 #define CFtarg2 0x8000 // like CFtarg, but we can't optimize this away 391 391 #define CFvolatile 0x10000 // volatile reference, do not schedule 392 392 #define CFclassinit 0x20000 // class init code 393 393 #define CFoffset64 0x40000 // offset is 64 bits 394 394 #define CFpc32 0x80000 // I64: PC relative 32 bit fixup 395 395 396 396 #define CFPREFIX (CFSEG | CFopsize | CFaddrsize) 397 397 #define CFSEG (CFes | CFss | CFds | CFcs | CFfs | CFgs) 398 398 399 399 /* The op code can be 1 to 3 bytes 400 */ 400 401 unsigned Iop; 401 402 403 /* The _EA is the "effective address" for the instruction, and consists of the modregrm byte, 404 * the sib byte, and the REX prefix byte. The 16 bit code generator just used the modregrm, 405 * the 32 bit x86 added the sib, and the 64 bit one added the rex. 406 */ 402 407 union 403 408 { unsigned _Iea; 404 409 struct 405 410 { 406 411 unsigned char _Irm; // reg/mode 407 412 unsigned char _Isib; // SIB byte 408 413 unsigned char _Irex; // REX prefix 409 414 } _ea; 410 415 } _EA; 411 416 412 417 #define Iea _EA._Iea 413 418 #define Irm _EA._ea._Irm 414 419 #define Isib _EA._ea._Isib 415 420 #define Irex _EA._ea._Irex 421 422 423 /* IFL1 and IEV1 are the first operand, which usually winds up being the offset to the Effective 424 * Address. IFL1 is the tag saying which variant type is in IEV1. IFL2 and IEV2 is the second 425 * operand, usually for immediate instructions. 426 */ 416 427 417 428 unsigned char IFL1,IFL2; // FLavors of 1st, 2nd operands 418 429 union evc IEV1; // 1st operand, if any 419 430 #define IEVpointer1 IEV1._EP.Vpointer 420 431 #define IEVseg1 IEV1._EP.Vseg 421 432 #define IEVsym1 IEV1.sp.Vsym 422 433 #define IEVdsym1 IEV1.dsp.Vsym 423 434 #define IEVoffset1 IEV1.sp.Voffset 424 435 #define IEVlsym1 IEV1.lab.Vsym 425 436 #define IEVint1 IEV1.Vint 426 437 union evc IEV2; // 2nd operand, if any 427 438 #define IEVpointer2 IEV2._EP.Vpointer 428 439 #define IEVseg2 IEV2._EP.Vseg 429 440 #define IEVsym2 IEV2.sp.Vsym 430 441 #define IEVdsym2 IEV2.dsp.Vsym 431 442 #define IEVoffset2 IEV2.sp.Voffset 432 443 #define IEVlsym2 IEV2.lab.Vsym 433 444 #define IEVint2 IEV2.Vint 434 445 void print(); // pretty-printer 435 446 branches/dmd-1.x/src/backend/debug.c
r487 r618 90 90 dbg_printf("mTYcs|"); 91 91 #endif 92 92 if (t & mTYconst) 93 93 dbg_printf("mTYconst|"); 94 94 if (t & mTYvolatile) 95 95 dbg_printf("mTYvolatile|"); 96 96 #if TARGET_MAC 97 97 if (t & mTYpasret) 98 98 dbg_printf("mTYpasret|"); 99 99 if (t & mTYmachdl) 100 100 dbg_printf("mTYmachdl|"); 101 101 if (t & mTYpasobj) 102 102 dbg_printf("mTYpasobj|"); 103 103 #endif 104 104 #if linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 105 105 if (t & mTYtransu) 106 106 dbg_printf("mTYtransu|"); 107 107 #endif 108 108 t = tybasic(t); 109 109 if (t >= TYMAX) 110 { dbg_printf("TY %lx\n", t);110 { dbg_printf("TY %lx\n",(long)t); 111 111 assert(0); 112 112 } 113 113 dbg_printf("TY%s ",tystring[tybasic(t)]); 114 114 } 115 115 116 116 void WRBC(unsigned bc) 117 117 { static char bcs[][7] = 118 118 {"unde ","goto ","true ","ret ","retexp", 119 119 "exit ","asm ","switch","ifthen","jmptab", 120 120 "try ","catch ","jump ", 121 121 "_try ","_filte","_final","_ret ","_excep", 122 122 "jcatch", 123 123 "jplace", 124 124 }; 125 125 126 126 assert(sizeof(bcs) / sizeof(bcs[0]) == BCMAX); 127 127 assert(bc < BCMAX); 128 128 dbg_printf("BC%s",bcs[bc]); 129 129 } 130 130 … … 170 170 } 171 171 else if (e->Eoper == OPcomma && !nest) 172 172 { WReqn(e->E1); 173 173 dbg_printf(";\n\t"); 174 174 WReqn(e->E2); 175 175 } 176 176 else if (OTbinary(e->Eoper)) 177 177 { 178 178 if (OTbinary(e->E1->Eoper)) 179 179 { nest++; 180 180 ferr("("); 181 181 WReqn(e->E1); 182 182 ferr(")"); 183 183 nest--; 184 184 } 185 185 else 186 186 WReqn(e->E1); 187 187 ferr(" "); 188 188 WROP(e->Eoper); 189 189 if (e->Eoper == OPstreq) 190 dbg_printf("%ld", e->Enumbytes);190 dbg_printf("%ld",(long)e->Enumbytes); 191 191 ferr(" "); 192 192 if (OTbinary(e->E2->Eoper)) 193 193 { nest++; 194 194 ferr("("); 195 195 WReqn(e->E2); 196 196 ferr(")"); 197 197 nest--; 198 198 } 199 199 else 200 200 WReqn(e->E2); 201 201 } 202 202 else 203 203 { 204 204 switch (e->Eoper) 205 205 { case OPconst: 206 206 switch (tybasic(e->Ety)) 207 207 { 208 208 case TYfloat: 209 209 dbg_printf("%g <float> ",e->EV.Vfloat); 210 210 break; 211 211 case TYdouble: 212 212 dbg_printf("%g ",e->EV.Vdouble); 213 213 break; 214 214 default: 215 215 dbg_printf("%lld ",el_tolong(e)); 216 216 break; 217 217 } 218 218 break; 219 219 case OPrelconst: 220 220 ferr("#"); 221 221 /* FALL-THROUGH */ 222 222 case OPvar: 223 223 dbg_printf("%s",e->EV.sp.Vsym->Sident); 224 224 if (e->EV.sp.Vsym->Ssymnum != -1) 225 225 dbg_printf("(%d)",e->EV.sp.Vsym->Ssymnum); 226 226 if (e->Eoffset != 0) 227 dbg_printf(".%ld", e->Eoffset);227 dbg_printf(".%ld",(long)e->Eoffset); 228 228 break; 229 229 case OPasm: 230 230 #if TARGET_MAC 231 231 if (e->Eflags & EFsmasm) 232 232 { 233 233 if (e->EV.mac.Vasmdat[1]) 234 234 dbg_printf("\"%c%c\"",e->EV.mac.Vasmdat[0],e->EV.mac.Vasmdat[1]); 235 235 else 236 236 dbg_printf("\"%c\"",e->EV.mac.Vasmdat[0]); 237 237 break; 238 238 }; 239 239 #endif 240 240 case OPstring: 241 241 dbg_printf("\"%s\"",e->EV.ss.Vstring); 242 242 if (e->EV.ss.Voffset) 243 dbg_printf("+%ld", e->EV.ss.Voffset);243 dbg_printf("+%ld",(long)e->EV.ss.Voffset); 244 244 break; 245 245 case OPmark: 246 246 case OPgot: 247 247 case OPframeptr: 248 248 WROP(e->Eoper); 249 249 break; 250 250 case OPstrthis: 251 251 break; 252 252 default: 253 253 WROP(e->Eoper); 254 254 assert(0); 255 255 } 256 256 } 257 257 } 258 258 259 259 void WRblocklist(list_t bl) 260 260 { 261 261 for (; bl; bl = list_next(bl)) 262 262 { register block *b = list_block(bl); 263 263 branches/dmd-1.x/src/backend/dt.c
r569 r618 185 185 *pdtend = dt; 186 186 pdtend = &dt->DTnext; 187 187 return pdtend; 188 188 } 189 189 190 190 /********************** 191 191 * Construct a DTibytes record, and return it. 192 192 */ 193 193 194 194 dt_t ** dtdword(dt_t **pdtend, int value) 195 195 { dt_t *dt; 196 196 197 197 while (*pdtend) 198 198 pdtend = &((*pdtend)->DTnext); 199 199 dt = dt_calloc(DT_ibytes); 200 200 dt->DTn = 4; 201 201 202 202 union { char* cp; int* lp; } u; 203 203 u.cp = dt->DTdata; 204 204 *u.lp = value; 205 206 *pdtend = dt; 207 pdtend = &dt->DTnext; 208 return pdtend; 209 } 210 211 dt_t ** dtsize_t(dt_t **pdtend, targ_size_t value) 212 { dt_t *dt; 213 214 while (*pdtend) 215 pdtend = &((*pdtend)->DTnext); 216 dt = dt_calloc(DT_ibytes); 217 dt->DTn = NPTRSIZE; 218 219 union { char* cp; int* lp; } u; 220 u.cp = dt->DTdata; 221 *u.lp = value; 222 if (NPTRSIZE == 8) 223 u.lp[1] = value >> 32; 205 224 206 225 *pdtend = dt; 207 226 pdtend = &dt->DTnext; 208 227 return pdtend; 209 228 } 210 229 211 230 /********************** 212 231 * Concatenate two dt_t's. 213 232 */ 214 233 215 234 dt_t ** dtcat(dt_t **pdtend,dt_t *dt) 216 235 { 217 236 while (*pdtend) 218 237 pdtend = &((*pdtend)->DTnext); 219 238 *pdtend = dt; 220 239 pdtend = &dt->DTnext; 221 240 return pdtend; 222 241 } 223 242 224 243 /********************** branches/dmd-1.x/src/backend/dt.h
r569 r618 30 30 * the size 31 31 * DTcommon # of 0 bytes (in a common block) 32 32 * a 33 33 * DTxoff offset from symbol 34 34 * w a 35 35 * w = symbol number (pointer for CPP) 36 36 * a = offset 37 37 * DTcoff offset into code segment 38 38 * DTend mark end of list 39 39 */ 40 40 41 41 struct dt_t 42 42 { dt_t *DTnext; // next in list 43 43 char dt; // type (DTxxxx) 44 44 unsigned char Dty; // pointer type 45 45 union 46 46 { 47 47 struct // DTibytes 48 48 { char DTn_; // number of bytes 49 49 #define DTn _DU._DI.DTn_ 50 char DTdata_[ 7]; // data50 char DTdata_[8]; // data 51 51 #define DTdata _DU._DI.DTdata_ 52 52 }_DI; 53 53 char DTonebyte_; // DT1byte 54 54 #define DTonebyte _DU.DTonebyte_ 55 55 targ_size_t DTazeros_; // DTazeros,DTcommon,DTsymsize 56 56 #define DTazeros _DU.DTazeros_ 57 57 struct // DTabytes 58 58 { 59 59 char *DTpbytes_; // pointer to the bytes 60 60 #define DTpbytes _DU._DN.DTpbytes_ 61 61 unsigned DTnbytes_; // # of bytes 62 62 #define DTnbytes _DU._DN.DTnbytes_ 63 63 #if TX86 64 64 int DTseg_; // segment it went into 65 65 #define DTseg _DU._DN.DTseg_ 66 66 #endif 67 67 targ_size_t DTabytes_; // offset of abytes for DTabytes 68 68 #define DTabytes _DU._DN.DTabytes_ 69 69 }_DN; 70 70 struct // DTxoff … … 85 85 DT_1byte, 86 86 DT_nbytes, 87 87 DT_common, 88 88 DT_symsize, 89 89 DT_coff, 90 90 DT_ibytes, // 8 91 91 }; 92 92 93 93 #if TX86 94 94 dt_t *dt_calloc(char dtx); 95 95 void dt_free(dt_t *); 96 96 void dt_term(void); 97 97 #elif TARGET_MAC 98 98 dt_t *dt_calloc(void); 99 99 void dt_free(dt_t *); 100 100 #endif 101 101 102 102 dt_t **dtnbytes(dt_t **,targ_size_t,const char *); 103 103 dt_t **dtabytes(dt_t **pdtend,tym_t ty, targ_size_t offset, targ_size_t size, const char *ptr); 104 104 dt_t **dtdword(dt_t **, int value); 105 dt_t **dtsize_t(dt_t **, targ_size_t value); 105 106 dt_t **dtnzeros(dt_t **pdtend,targ_size_t size); 106 107 dt_t **dtxoff(dt_t **pdtend,symbol *s,targ_size_t offset,tym_t ty); 107 108 dt_t **dtselfoff(dt_t **pdtend,targ_size_t offset,tym_t ty); 108 109 dt_t **dtcoff(dt_t **pdtend,targ_size_t offset); 109 110 dt_t ** dtcat(dt_t **pdtend,dt_t *dt); 110 111 void dt_optimize(dt_t *dt); 111 112 void dtsymsize(symbol *); 112 113 void init_common(symbol *); 113 114 unsigned dt_size(dt_t *dtstart); 114 115 115 116 #endif /* DT_H */ 116 117 branches/dmd-1.x/src/backend/el.c
r581 r618 2944 2944 case TYcldouble: 2945 2945 case TYcdouble: 2946 2946 case TYcfloat: 2947 2947 #if !DDRT 2948 2948 result = (targ_llong)el_toldouble(e); 2949 2949 #else 2950 2950 result = Xxtoi(el_toldouble(e)); 2951 2951 #endif 2952 2952 break; 2953 2953 2954 2954 #if SCPP 2955 2955 case TYmemptr: 2956 2956 ty = tybasic(tym_conv(e->ET)); 2957 2957 goto L1; 2958 2958 #endif 2959 2959 default: 2960 2960 #if SCPP 2961 2961 // Can happen as result of syntax errors 2962 2962 assert(errcnt); 2963 2963 #else 2964 #ifdef DEBUG 2965 elem_print(e); 2966 *(char*)0=0; 2967 #endif 2964 2968 assert(0); 2965 2969 #endif 2966 2970 } 2967 2971 return result; 2968 2972 } 2969 2973 2970 2974 /*********************************** 2971 2975 * Determine if constant e is all ones or all zeros. 2972 2976 * Input: 2973 2977 * bit 0: all zeros 2974 2978 * 1: 1 2975 2979 * -1: all ones 2976 2980 */ 2977 2981 2978 2982 int el_allbits(elem *e,int bit) 2979 2983 { targ_llong value; 2980 2984 2981 2985 elem_debug(e); 2982 2986 assert(e->Eoper == OPconst); 2983 2987 value = e->EV.Vullong; … … 3272 3276 case TYulong: 3273 3277 case TYdchar: 3274 3278 case TYfptr: 3275 3279 #if TX86 3276 3280 case TYvptr: 3277 3281 case TYhptr: 3278 3282 #endif 3279 3283 L1: 3280 3284 dbg_printf("%dL ",e->EV.Vlong); 3281 3285 break; 3282 3286 3283 3287 case TYllong: 3284 3288 L2: 3285 3289 dbg_printf("%lldLL ",e->EV.Vllong); 3286 3290 break; 3287 3291 3288 3292 case TYullong: 3289 3293 dbg_printf("%lluLL ",e->EV.Vullong); 3290 3294 break; 3291 3295 3296 case TYcent: 3297 case TYucent: 3298 dbg_printf("%lluLL+%lluLL ", e->EV.Vcent.msw, e->EV.Vcent.lsw); 3299 break; 3300 3292 3301 case TYfloat: 3293 3302 dbg_printf("%gf ",(double)e->EV.Vfloat); 3294 3303 break; 3295 3304 case TYdouble: 3296 3305 case TYdouble_alias: 3297 3306 dbg_printf("%g ",(double)e->EV.Vdouble); 3298 3307 break; 3299 3308 case TYldouble: 3300 3309 #if TARGET_MAC 3301 3310 #if (TARGET_POWERPC) 3302 3311 if (config.flags & CFGldblisdbl) 3303 3312 dbg_printf("%gL ",e->EV.Vdouble); 3304 3313 else 3305 3314 #endif 3306 3315 #if !DDRT 3307 3316 dbg_printf("%LgL ",e->EV.Vldouble); 3308 3317 #else /* DDRT */ 3309 3318 { 3310 3319 static char buffer[75]; 3311 3320 __g_fmt(buffer, (DD)e->EV.Vldouble); branches/dmd-1.x/src/backend/evalu8.c
r569 r618 565 565 { elem *e1,*e2; 566 566 tym_t tym,tym2,uns; 567 567 unsigned op; 568 568 #if TARGET_MAC 569 569 targ_short i1,i2; 570 570 targ_char c1,c2; 571 571 #else 572 572 targ_int i1,i2; 573 573 #endif 574 574 int i; 575 575 targ_llong l1,l2; 576 576 targ_ldouble d1,d2; 577 577 elem esave; 578 578 579 579 // assert((_status87() & 0x3800) == 0); 580 580 assert(e && EOP(e)); 581 581 op = e->Eoper; 582 582 elem_debug(e); 583 583 e1 = e->E1; 584 584 585 //printf("evalu8(): "); //elem_print(e);585 //printf("evalu8(): "); elem_print(e); 586 586 elem_debug(e1); 587 587 if (e1->Eoper == OPconst) 588 588 { 589 589 tym2 = 0; 590 590 e2 = NULL; 591 591 if (EBIN(e)) 592 592 { e2 = e->E2; 593 593 elem_debug(e2); 594 594 if (e2->Eoper == OPconst) 595 595 { 596 596 T68000(c2 =) i2 = l2 = el_tolong(e2); 597 597 d2 = el_toldouble(e2); 598 598 } 599 599 else 600 600 return e; 601 601 tym2 = tybasic(typemask(e2)); 602 602 } 603 603 T68000(c1 =) i1 = l1 = el_tolong(e1); 604 604 d1 = el_toldouble(e1); 605 605 tym = tybasic(typemask(e1)); /* type of op is type of left child */ … … 1183 1183 case TYcldouble: 1184 1184 switch (tym2) 1185 1185 { 1186 1186 case TYldouble: 1187 1187 e->EV.Vcldouble.re = e1->EV.Vcldouble.re * d2; 1188 1188 e->EV.Vcldouble.im = e1->EV.Vcldouble.im * d2; 1189 1189 break; 1190 1190 case TYildouble: 1191 1191 e->EV.Vcldouble.re = -e1->EV.Vcldouble.im * d2; 1192 1192 e->EV.Vcldouble.im = e1->EV.Vcldouble.re * d2; 1193 1193 break; 1194 1194 case TYcldouble: 1195 1195 e->EV.Vcldouble = Complex_ld::mul(e1->EV.Vcldouble, e2->EV.Vcldouble); 1196 1196 break; 1197 1197 default: 1198 1198 assert(0); 1199 1199 } 1200 1200 break; 1201 1201 default: 1202 1202 #ifdef DEBUG 1203 dbg_printf("tym = x% lx\n",tym);1203 dbg_printf("tym = x%x\n",tym); 1204 1204 elem_print(e); 1205 1205 #endif 1206 1206 assert(0); 1207 1207 } 1208 1208 } 1209 1209 break; 1210 1210 case OPdiv: 1211 1211 if (!boolres(e2)) // divide by 0 1212 1212 { 1213 1213 #if SCPP 1214 1214 if (!tyfloating(tym)) 1215 1215 #endif 1216 1216 goto div0; 1217 1217 } 1218 1218 if (uns) 1219 1219 e->EV.Vullong = ((targ_ullong) l1) / ((targ_ullong) l2); 1220 1220 else 1221 1221 { switch (tym) 1222 1222 { 1223 1223 case TYfloat: … … 2030 2030 #endif 2031 2031 e->EV.Vint = l1; 2032 2032 break; 2033 2033 case OP64_32: 2034 2034 e->EV.Vlong = l1; 2035 2035 break; 2036 2036 case OPlngllng: 2037 2037 e->EV.Vllong = (targ_long) l1; 2038 2038 break; 2039 2039 case OPulngllng: 2040 2040 e->EV.Vllong = (targ_ulong) l1; 2041 2041 break; 2042 2042 case OPmsw: 2043 2043 switch (tysize(tym)) 2044 2044 { 2045 2045 case 4: 2046 2046 e->EV.Vllong = (l1 >> 16) & 0xFFFF; 2047 2047 break; 2048 2048 case 8: 2049 2049 e->EV.Vllong = (l1 >> 32) & 0xFFFFFFFF; 2050 break; 2051 case 16: 2052 e->EV.Vllong = e1->EV.Vcent.msw; 2050 2053 break; 2051 2054 default: 2052 2055 assert(0); 2053 2056 } 2054 2057 break; 2055 2058 case OPb_8: 2056 2059 e->EV.Vlong = i1 & 1; 2057 2060 break; 2058 2061 case OPbswap: 2059 2062 e->EV.Vint = ((i1 >> 24) & 0x000000FF) | 2060 2063 ((i1 >> 8) & 0x0000FF00) | 2061 2064 ((i1 << 8) & 0x00FF0000) | 2062 2065 ((i1 << 24) & 0xFF000000); 2063 2066 break; 2064 2067 case OPind: 2065 2068 #if 0 && MARS 2066 2069 /* The problem with this is that although the only reaching definition 2067 2070 * of the variable is null, it still may never get executed, as in: 2068 2071 * int* p = null; if (p) *p = 3; 2069 2072 * and the error will be spurious. branches/dmd-1.x/src/backend/ptrntab.c
r606 r618 1 1 // Copyright (C) 1985-1998 by Symantec 2 // Copyright (C) 2000-20 09by Digital Mars2 // Copyright (C) 2000-2010 by Digital Mars 3 3 // All Rights Reserved 4 4 // http://www.digitalmars.com 5 5 /* 6 6 * This source file is made available for personal use 7 7 * only. The license is in /dmd/src/dmd/backendlicense.txt 8 8 * or /dm/src/dmd/backendlicense.txt 9 9 * For any other uses, please contact Digital Mars. 10 10 */ 11 11 12 12 #if !DEMO && !SPP 13 13 14 14 #include <stdio.h> 15 15 #include <stdlib.h> 16 16 #include <string.h> 17 17 #include <time.h> 18 18 19 19 #include "cc.h" 20 20 #include "code.h" 21 21 #include "iasm.h" 22 22 … … 35 35 PTRNTAB0 aptb0AAA[] = /* AAA */ { 36 36 { 0x37, _modax }, 37 37 }; 38 38 39 39 PTRNTAB0 aptb0AAD[] = /* AAD */ { 40 40 { 0xd50a, _modax } 41 41 }; 42 42 43 43 PTRNTAB0 aptb0AAM[] = /* AAM */ { 44 44 { 0xd40a, _modax } 45 45 }; 46 46 PTRNTAB0 aptb0AAS[] = /* AAS */ { 47 47 { 0x3f, _modax } 48 48 }; 49 49 PTRNTAB0 aptb0CBW[] = /* CBW */ { 50 50 { 0x98, _16_bit | _modax } 51 51 }; 52 52 PTRNTAB0 aptb0CWDE[] = /* CWDE */ { 53 53 { 0x98, _32_bit | _I386 | _modax } 54 54 }; 55 PTRNTAB0 aptb0CDQE[] = /* CDQE */ { 56 { 0x98, _64_bit | _modax } 57 }; 55 58 PTRNTAB0 aptb0CLC[] = /* CLC */ { 56 59 { 0xf8, 0 } 57 60 }; 58 61 59 62 PTRNTAB0 aptb0CLD[] = /* CLD */ { 60 63 { 0xfc, 0 } 61 64 }; 62 65 PTRNTAB0 aptb0CLI[] = /* CLI */ { 63 66 { 0xfa, 0 } 64 67 }; 65 68 66 69 PTRNTAB0 aptb0CLTS[] = /* CLTS */ { 67 70 { 0x0f06, 0 } 68 71 }; 69 72 70 73 PTRNTAB0 aptb0CMC[] = /* CMC */ { 71 74 { 0xf5, 0 } 72 75 }; 73 76 74 77 PTRNTAB0 aptb0CMPSB[] = /* CMPSB */ { 75 78 { 0xa6, _modsidi } 76 79 }; 77 80 78 81 PTRNTAB0 aptb0CMPSW[] = /* CMPSW */ { 79 82 { 0xa7, _16_bit | _modsidi } 80 83 }; 81 84 82 85 #if 0 83 86 PTRNTAB0 aptb0CMPSD[] = /* CMPSD */ { 84 87 { 0xa7, _32_bit | _I386 | _modsidi } 85 88 }; 86 89 #endif 87 90 88 91 PTRNTAB0 aptb0CWD[] = /* CWD */ { 89 92 { 0x99, _16_bit | _modaxdx } 90 93 }; 91 94 92 95 PTRNTAB0 aptb0CDQ[] = /* CDQ */ { 93 96 { 0x99, _32_bit | _I386 | _modaxdx } 97 }; 98 99 PTRNTAB0 aptb0CQO[] = /* CQO */ { 100 { 0x99, _64_bit | _modaxdx } 94 101 }; 95 102 96 103 PTRNTAB0 aptb0DAA[] = /* DAA */ { 97 104 { 0x27, _modax } 98 105 }; 99 106 100 107 PTRNTAB0 aptb0DAS[] = /* DAS */ { 101 108 { 0x2f, _modax } 102 109 }; 103 110 104 111 PTRNTAB0 aptb0HLT[] = /* HLT */ { 105 112 { 0xf4, 0 } 106 113 }; 107 114 108 115 PTRNTAB0 aptb0INSB[] = /* INSB */ { 109 116 { 0x6c, _I386 | _modsi } 110 117 }; 111 118 112 119 PTRNTAB0 aptb0INSW[] = /* INSW */ { 113 120 { 0x6d, _16_bit | _I386 | _modsi } … … 3141 3148 X("addss", 2, (P) aptb2ADDSS ) \ 3142 3149 X("addsubpd", 2, (P) aptb2ADDSUBPD ) \ 3143 3150 X("addsubps", 2, (P) aptb2ADDSUBPS ) \ 3144 3151 X("and", 2, (P) aptb2AND ) \ 3145 3152 X("andnpd", 2, (P) aptb2ANDNPD ) \ 3146 3153 X("andnps", 2, (P) aptb2ANDNPS ) \ 3147 3154 X("andpd", 2, (P) aptb2ANDPD ) \ 3148 3155 X("andps", 2, (P) aptb2ANDPS ) \ 3149 3156 X("arpl", 2, (P) aptb2ARPL ) \ 3150 3157 X("bound", 2, (P) aptb2BOUND ) \ 3151 3158 X("bsf", 2, (P) aptb2BSF ) \ 3152 3159 X("bsr", 2, (P) aptb2BSR ) \ 3153 3160 X("bswap", 1, (P) aptb1BSWAP ) \ 3154 3161 X("bt", 2, (P) aptb2BT ) \ 3155 3162 X("btc", 2, (P) aptb2BTC ) \ 3156 3163 X("btr", 2, (P) aptb2BTR ) \ 3157 3164 X("bts", 2, (P) aptb2BTS ) \ 3158 3165 X("call", ITjump | 1, (P) aptb1CALL ) \ 3159 3166 X("cbw", 0, aptb0CBW ) \ 3160 3167 X("cdq", 0, aptb0CDQ ) \ 3168 X("cdqe", 0, aptb0CDQE ) \ 3161 3169 X("clc", 0, aptb0CLC ) \ 3162 3170 X("cld", 0, aptb0CLD ) \ 3163 3171 X("clflush", 1, (P) aptb1CLFLUSH ) \ 3164 3172 X("cli", 0, aptb0CLI ) \ 3165 3173 X("clts", 0, aptb0CLTS ) \ 3166 3174 X("cmc", 0, aptb0CMC ) \ 3167 3175 X("cmova", 2, (P) aptb2CMOVNBE ) \ 3168 3176 X("cmovae", 2, (P) aptb2CMOVNB ) \ 3169 3177 X("cmovb", 2, (P) aptb2CMOVB ) \ 3170 3178 X("cmovbe", 2, (P) aptb2CMOVBE ) \ 3171 3179 X("cmovc", 2, (P) aptb2CMOVB ) \ 3172 3180 X("cmove", 2, (P) aptb2CMOVZ ) \ 3173 3181 X("cmovg", 2, (P) aptb2CMOVNLE ) \ 3174 3182 X("cmovge", 2, (P) aptb2CMOVNL ) \ 3175 3183 X("cmovl", 2, (P) aptb2CMOVL ) \ 3176 3184 X("cmovle", 2, (P) aptb2CMOVLE ) \ 3177 3185 X("cmovna", 2, (P) aptb2CMOVBE ) \ 3178 3186 X("cmovnae", 2, (P) aptb2CMOVB ) \ 3179 3187 X("cmovnb", 2, (P) aptb2CMOVNB ) \ 3180 3188 X("cmovnbe", 2, (P) aptb2CMOVNBE ) \ … … 3191 3199 X("cmovo", 2, (P) aptb2CMOVO ) \ 3192 3200 X("cmovp", 2, (P) aptb2CMOVP ) \ 3193 3201 X("cmovpe", 2, (P) aptb2CMOVP ) \ 3194 3202 X("cmovpo", 2, (P) aptb2CMOVNP ) \ 3195 3203 X("cmovs", 2, (P) aptb2CMOVS ) \ 3196 3204 X("cmovz", 2, (P) aptb2CMOVZ ) \ 3197 3205 X("cmp", 2, (P) aptb2CMP ) \ 3198 3206 X("cmppd", 3, (P) aptb3CMPPD ) \ 3199 3207 X("cmpps", 3, (P) aptb3CMPPS ) \ 3200 3208 X("cmps", 2, (P) aptb2CMPS ) \ 3201 3209 X("cmpsb", 0, aptb0CMPSB ) \ 3202 3210 /*X("cmpsd", 0, aptb0CMPSD )*/ \ 3203 3211 X("cmpsd", ITopt|3, (P) aptb3CMPSD ) \ 3204 3212 X("cmpss", 3, (P) aptb3CMPSS ) \ 3205 3213 X("cmpsw", 0, aptb0CMPSW ) \ 3206 3214 X("cmpxch8b", 1, (P) aptb1CMPXCH8B ) \ 3207 3215 X("cmpxchg", 2, (P) aptb2CMPXCHG ) \ 3208 3216 X("comisd", 2, (P) aptb2COMISD ) \ 3209 3217 X("comiss", 2, (P) aptb2COMISS ) \ 3210 3218 X("cpuid", 0, aptb0CPUID ) \ 3219 X("cqo", 0, aptb0CQO ) \ 3211 3220 X("cvtdq2pd", 2, (P) aptb2CVTDQ2PD ) \ 3212 3221 X("cvtdq2ps", 2, (P) aptb2CVTDQ2PS ) \ 3213 3222 X("cvtpd2dq", 2, (P) aptb2CVTPD2DQ ) \ 3214 3223 X("cvtpd2pi", 2, (P) aptb2CVTPD2PI ) \ 3215 3224 X("cvtpd2ps", 2, (P) aptb2CVTPD2PS ) \ 3216 3225 X("cvtpi2pd", 2, (P) aptb2CVTPI2PD ) \ 3217 3226 X("cvtpi2ps", 2, (P) aptb2CVTPI2PS ) \ 3218 3227 X("cvtps2dq", 2, (P) aptb2CVTPS2DQ ) \ 3219 3228 X("cvtps2pd", 2, (P) aptb2CVTPS2PD ) \ 3220 3229 X("cvtps2pi", 2, (P) aptb2CVTPS2PI ) \ 3221 3230 X("cvtsd2si", 2, (P) aptb2CVTSD2SI ) \ 3222 3231 X("cvtsd2ss", 2, (P) aptb2CVTSD2SS ) \ 3223 3232 X("cvtsi2sd", 2, (P) aptb2CVTSI2SD ) \ 3224 3233 X("cvtsi2ss", 2, (P) aptb2CVTSI2SS ) \ 3225 3234 X("cvtss2sd", 2, (P) aptb2CVTSS2SD ) \ 3226 3235 X("cvtss2si", 2, (P) aptb2CVTSS2SI ) \ 3227 3236 X("cvttpd2dq", 2, (P) aptb2CVTTPD2DQ ) \ 3228 3237 X("cvttpd2pi", 2, (P) aptb2CVTTPD2PI ) \ 3229 3238 X("cvttps2dq", 2, (P) aptb2CVTTPS2DQ ) \ 3230 3239 X("cvttps2pi", 2, (P) aptb2CVTTPS2PI ) \ branches/dmd-1.x/src/backend/ty.h
r606 r618 90 90 TYident = 0x30, // type-argument 91 91 TYtemplate = 0x31, // unexpanded class template 92 92 TYvtshape = 0x32, // virtual function table 93 93 TYptr = 0x33, // generic pointer type 94 94 TYf16func = 0x34, // _far16 _pascal function 95 95 TYnsysfunc = 0x35, // near __syscall func 96 96 TYfsysfunc = 0x36, // far __syscall func 97 97 TYmfunc = 0x37, // NT C++ member func 98 98 TYjfunc = 0x38, // LINKd D function 99 99 TYhfunc = 0x39, // C function with hidden parameter 100 100 TYnref = 0x3A, // near reference 101 101 TYfref = 0x3B, // far reference 102 102 103 103 TYcent = 0x3C, // 128 bit signed integer 104 104 TYucent = 0x3D, // 128 bit unsigned integer 105 105 106 106 TYMAX = 0x3E, 107 107 108 108 #if MARS 109 109 #define TYaarray TYnptr 110 #define TYdelegate TYllong111 #define TYdarray TYullong110 #define TYdelegate (I64 ? TYcent : TYllong) 111 #define TYdarray (I64 ? TYucent : TYullong) 112 112 #endif 113 113 }; 114 114 115 115 // These change depending on memory model 116 116 extern int TYptrdiff, TYsize, TYsize_t; 117 117 118 118 /* Linkage type */ 119 119 #define mTYnear 0x100 120 120 #define mTYfar 0x200 121 121 #define mTYcs 0x400 // in code segment 122 122 #define mTYthread 0x800 123 123 #define mTYLINK 0xF00 // all linkage bits 124 124 125 125 #define mTYloadds 0x1000 126 126 #define mTYexport 0x2000 127 127 #define mTYweak 0x0000 128 128 #define mTYimport 0x4000 129 129 #define mTYnaked 0x8000 130 130 #define mTYMOD 0xF000 // all modifier bits 131 131 … … 181 181 182 182 /* Groupings of types */ 183 183 184 184 #define tyintegral(ty) (tytab[(ty) & 0xFF] & TYFLintegral) 185 185 186 186 #define tyarithmetic(ty) (tytab[(ty) & 0xFF] & (TYFLintegral | TYFLreal | TYFLimaginary | TYFLcomplex)) 187 187 188 188 #define tyaggregate(ty) (tytab[(ty) & 0xFF] & TYFLaggregate) 189 189 190 190 #define tyscalar(ty) (tytab[(ty) & 0xFF] & (TYFLintegral | TYFLreal | TYFLimaginary | TYFLcomplex | TYFLptr | TYFLmptr | TYFLnullptr)) 191 191 192 192 #define tyfloating(ty) (tytab[(ty) & 0xFF] & (TYFLreal | TYFLimaginary | TYFLcomplex)) 193 193 194 194 #define tyimaginary(ty) (tytab[(ty) & 0xFF] & TYFLimaginary) 195 195 196 196 #define tycomplex(ty) (tytab[(ty) & 0xFF] & TYFLcomplex) 197 197 198 198 #define tyreal(ty) (tytab[(ty) & 0xFF] & TYFLreal) 199 199 200 200 // Fits into 64 bit register 201 #define ty64reg(ty) (tytab[(ty) & 0xFF] & (TYFLintegral | TYFLptr) )201 #define ty64reg(ty) (tytab[(ty) & 0xFF] & (TYFLintegral | TYFLptr) && tysize(ty) <= NPTRSIZE) 202 202 203 203 #ifndef tyshort 204 204 /* Types that are chars or shorts */ 205 205 #define tyshort(ty) (tytab[(ty) & 0xFF] & TYFLshort) 206 206 #endif 207 207 208 208 /* Detect TYlong or TYulong */ 209 209 #ifndef tylong 210 210 #define tylong(ty) (tybasic(ty) == TYlong || tybasic(ty) == TYulong) 211 211 #endif 212 212 213 213 /* Use to detect a pointer type */ 214 214 #ifndef typtr 215 215 #define typtr(ty) (tytab[(ty) & 0xFF] & TYFLptr) 216 216 #endif 217 217 218 218 /* Use to detect a reference type */ 219 219 #ifndef tyref 220 220 #define tyref(ty) (tytab[(ty) & 0xFF] & TYFLref) 221 221 #endif branches/dmd-1.x/src/backend/var.c
r558 r618 222 222 unsigned 223 223 maxblks = 0, /* array max for all block stuff */ 224 224 /* dfoblks <= numblks <= maxblks */ 225 225 numcse, /* number of common subexpressions */ 226 226 deftop = 0, /* # of entries in defnod[] */ 227 227 exptop = 0; /* top of expnod[] */ 228 228 229 229 vec_t defkill = NULL, /* vector of AEs killed by an ambiguous */ 230 230 /* definition */ 231 231 starkill = NULL, /* vector of AEs killed by a definition */ 232 232 /* of something that somebody could be */ 233 233 /* pointing to */ 234 234 vptrkill = NULL; /* vector of AEs killed by an access */ 235 235 /* to a vptr */ 236 236 237 237 /* From debug.c */ 238 238 #if DEBUG 239 239 const char *regstring[32] = {"AX","CX","DX","BX","SP","BP","SI","DI", 240 240 "R8","R9","R10","R11","R12","R13","R14","R15", 241 241 "XMM0","XMM1","XMM2","XMM3","XMM4","XMM5","XMM6","XMM7", 242 "ES","PSW","STACK","ST0", "ST01"};242 "ES","PSW","STACK","ST0","ST01","NOREG","RMload","RMstore"}; 243 243 #endif 244 244 245 245 /* From nwc.c */ 246 246 247 247 type *chartype; /* default 'char' type */ 248 248 branches/dmd-1.x/src/e2ir.c
r600 r618 408 408 * Convert array to a dynamic array. 409 409 */ 410 410 411 411 elem *array_toDarray(Type *t, elem *e) 412 412 { 413 413 unsigned dim; 414 414 elem *ef = NULL; 415 415 elem *ex; 416 416 417 417 //printf("array_toDarray(t = %s)\n", t->toChars()); 418 418 //elem_print(e); 419 419 t = t->toBasetype(); 420 420 switch (t->ty) 421 421 { 422 422 case Tarray: 423 423 break; 424 424 425 425 case Tsarray: 426 426 e = el_una(OPaddr, TYnptr, e); 427 427 dim = ((TypeSArray *)t)->dim->toInteger(); 428 e = el_pair(TY ullong, el_long(TYint, dim), e);428 e = el_pair(TYdarray, el_long(TYint, dim), e); 429 429 break; 430 430 431 431 default: 432 432 L1: 433 433 switch (e->Eoper) 434 434 { 435 435 case OPconst: 436 436 { 437 437 size_t len = tysize[tybasic(e->Ety)]; 438 438 elem *es = el_calloc(); 439 439 es->Eoper = OPstring; 440 440 441 441 // Match MEM_PH_FREE for OPstring in ztc\el.c 442 442 es->EV.ss.Vstring = (char *)mem_malloc(len); 443 443 memcpy(es->EV.ss.Vstring, &e->EV, len); 444 444 445 445 es->EV.ss.Vstrlen = len; 446 446 es->Ety = TYnptr; 447 447 e = es; 448 448 break; … … 474 474 // Copy expression to a variable and take the 475 475 // address of that variable. 476 476 Symbol *stmp; 477 477 tym_t ty = tybasic(e->Ety); 478 478 479 479 if (ty == TYstruct) 480 480 { 481 481 if (e->Enumbytes == 4) 482 482 ty = TYint; 483 483 else if (e->Enumbytes == 8) 484 484 ty = TYllong; 485 485 } 486 486 e->Ety = ty; 487 487 stmp = symbol_genauto(type_fake(ty)); 488 488 e = el_bin(OPeq, e->Ety, el_var(stmp), e); 489 489 e = el_bin(OPcomma, TYnptr, e, el_una(OPaddr, TYnptr, el_var(stmp))); 490 490 break; 491 491 } 492 492 } 493 493 dim = 1; 494 e = el_pair(TY ullong, el_long(TYint, dim), e);494 e = el_pair(TYdarray, el_long(TYint, dim), e); 495 495 break; 496 496 } 497 497 return el_combine(ef, e); 498 498 } 499 499 500 500 /***************************************** 501 501 * Evaluate elem and convert to dynamic array. 502 502 */ 503 503 504 504 elem *eval_Darray(IRState *irs, Expression *e) 505 505 { 506 506 elem *ex; 507 507 508 508 ex = e->toElem(irs); 509 509 return array_toDarray(e->type, ex); 510 510 } 511 511 512 512 /************************************ 513 513 */ 514 514 … … 518 518 //elem_print(e); 519 519 520 520 elem *elen; 521 521 unsigned dim = ((TypeSArray *)tfrom)->dim->toInteger(); 522 522 523 523 if (tto) 524 524 { 525 525 unsigned fsize = tfrom->nextOf()->size(); 526 526 unsigned tsize = tto->nextOf()->size(); 527 527 528 528 if ((dim * fsize) % tsize != 0) 529 529 { 530 530 Lerr: 531 531 error(loc, "cannot cast %s to %s since sizes don't line up", tfrom->toChars(), tto->toChars()); 532 532 } 533 533 dim = (dim * fsize) / tsize; 534 534 } 535 535 L1: 536 536 elen = el_long(TYint, dim); 537 537 e = el_una(OPaddr, TYnptr, e); 538 e = el_pair(TY ullong, elen, e);538 e = el_pair(TYdarray, elen, e); 539 539 return e; 540 540 } 541 541 542 542 /******************************************* 543 543 * Set an array pointed to by eptr to evalue: 544 544 * eptr[0..edim] = evalue; 545 545 * Input: 546 546 * eptr where to write the data to 547 547 * evalue value to write 548 548 * edim number of times to write evalue to eptr[] 549 549 * tb type of evalue 550 550 */ 551 551 552 552 elem *setArray(elem *eptr, elem *edim, Type *tb, elem *evalue) 553 553 { int r; 554 554 elem *e; 555 555 int sz = tb->size(); 556 556 557 557 if (tb->ty == Tfloat80 || tb->ty == Timaginary80) 558 558 r = RTLSYM_MEMSET80; 559 559 else if (tb->ty == Tcomplex80) 560 560 r = RTLSYM_MEMSET160; 561 561 else if (tb->ty == Tcomplex64) 562 562 r = RTLSYM_MEMSET128; 563 563 else 564 564 { 565 565 switch (sz) 566 566 { 567 567 case 1: r = RTLSYM_MEMSET8; break; 568 568 case 2: r = RTLSYM_MEMSET16; break; 569 569 case 4: r = RTLSYM_MEMSET32; break; 570 570 case 8: r = RTLSYM_MEMSET64; break; 571 case 16: r = RTLSYM_MEMSET128; break; 571 572 572 573 default: 573 574 r = RTLSYM_MEMSETN; 574 575 evalue = el_una(OPaddr, TYnptr, evalue); 575 576 elem *esz = el_long(TYint, sz); 576 577 e = el_params(esz, edim, evalue, eptr, NULL); 577 578 e = el_bin(OPcall,TYnptr,el_var(rtlsym[r]),e); 578 579 return e; 579 580 } 580 581 } 581 582 if (sz > 1 && sz <= 8 && 582 583 evalue->Eoper == OPconst && el_allbits(evalue, 0)) 583 584 { 584 585 r = RTLSYM_MEMSET8; 585 586 edim = el_bin(OPmul, TYuint, edim, el_long(TYuint, sz)); 586 587 } 587 588 588 589 if (tybasic(evalue->Ety) == TYstruct) 589 590 { 590 591 evalue = el_una(OPstrpar, TYstruct, evalue); … … 722 723 } 723 724 el_setLoc(e,loc); 724 725 return e; 725 726 } 726 727 #endif 727 728 728 729 /************************************** 729 730 */ 730 731 731 732 elem *FuncExp::toElem(IRState *irs) 732 733 { 733 734 elem *e; 734 735 Symbol *s; 735 736 736 737 //printf("FuncExp::toElem() %s\n", toChars()); 737 738 s = fd->toSymbol(); 738 739 e = el_ptr(s); 739 740 if (fd->isNested()) 740 741 { 741 742 elem *ethis = getEthis(loc, irs, fd); 742 e = el_pair(TY ullong, ethis, e);743 e = el_pair(TYdelegate, ethis, e); 743 744 } 744 745 745 746 irs->deferToObj->push(fd); 746 747 el_setLoc(e,loc); 747 748 return e; 748 749 } 749 750 750 751 /************************************** 751 752 */ 752 753 753 754 elem *Dsymbol_toElem(Dsymbol *s, IRState *irs) 754 755 { 755 756 elem *e = NULL; 756 757 Symbol *sp; 757 758 AttribDeclaration *ad; 758 759 VarDeclaration *vd; 759 760 ClassDeclaration *cd; 760 761 StructDeclaration *sd; 761 762 FuncDeclaration *fd; 762 763 TemplateMixin *tm; … … 2256 2257 } 2257 2258 #endif 2258 2259 2259 2260 e = el_bin(OPcall, type->totym(), el_var(rtlsym[r]), ep); 2260 2261 el_setLoc(e, loc); 2261 2262 return e; 2262 2263 } 2263 2264 2264 2265 // Look for array[]=n 2265 2266 if (e1->op == TOKslice) 2266 2267 { 2267 2268 SliceExp *are = (SliceExp *)(e1); 2268 2269 Type *t1 = t1b; 2269 2270 Type *t2 = e2->type->toBasetype(); 2270 2271 2271 2272 // which we do if the 'next' types match 2272 2273 if (ismemset) 2273 2274 { // Do a memset for array[]=v 2274 2275 //printf("Lpair %s\n", toChars()); 2275 2276 SliceExp *are = (SliceExp *)e1; 2276 elem *elwr;2277 elem *eupr;2278 elem *n1;2279 2277 elem *evalue; 2280 2278 elem *enbytes; 2281 2279 elem *elength; 2282 2280 elem *einit; 2283 2281 dinteger_t value; 2284 2282 Type *ta = are->e1->type->toBasetype(); 2285 2283 Type *tb = ta->nextOf()->toBasetype(); 2286 2284 int sz = tb->size(); 2287 2285 tym_t tym = type->totym(); 2288 2286 2289 n1 = are->e1->toElem(irs);2290 el wr = are->lwr ? are->lwr->toElem(irs) : NULL;2291 e upr = are->upr ? are->upr->toElem(irs) : NULL;2287 elem *n1 = are->e1->toElem(irs); 2288 elem *elwr = are->lwr ? are->lwr->toElem(irs) : NULL; 2289 elem *eupr = are->upr ? are->upr->toElem(irs) : NULL; 2292 2290 2293 2291 elem *n1x = n1; 2294 2292 2295 2293 // Look for array[]=n 2296 2294 if (ta->ty == Tsarray) 2297 2295 { 2298 TypeSArray *ts; 2299 2300 ts = (TypeSArray *) ta; 2296 TypeSArray *ts = (TypeSArray *) ta; 2301 2297 n1 = array_toPtr(ta, n1); 2302 2298 enbytes = ts->dim->toElem(irs); 2303 2299 n1x = n1; 2304 2300 n1 = el_same(&n1x); 2305 2301 einit = resolveLengthVar(are->lengthVar, &n1, ta); 2306 2302 } 2307 2303 else if (ta->ty == Tarray) 2308 2304 { 2309 2305 n1 = el_same(&n1x); 2310 2306 einit = resolveLengthVar(are->lengthVar, &n1, ta); 2311 2307 enbytes = el_copytree(n1); 2312 2308 n1 = array_toPtr(ta, n1); 2313 2309 enbytes = el_una(OP64_32, TYint, enbytes); 2314 2310 } 2315 2311 else if (ta->ty == Tpointer) 2316 2312 { 2317 2313 n1 = el_same(&n1x); 2318 2314 enbytes = el_long(TYint, -1); // largest possible index 2319 2315 einit = NULL; 2320 2316 } … … 2378 2374 sassert = irs->blx->module->toModuleArray(); 2379 2375 ea = el_bin(OPcall,TYvoid,el_var(sassert), el_long(TYint, loc.linnum)); 2380 2376 eb = el_bin(OPoror,TYvoid,c1,ea); 2381 2377 einit = el_combine(einit, eb); 2382 2378 } 2383 2379 2384 2380 if (elwr) 2385 2381 { elem *elwr2; 2386 2382 2387 2383 el_free(enbytes); 2388 2384 elwr2 = el_copytree(elwr); 2389 2385 elwr2 = el_bin(OPmul, TYint, elwr2, el_long(TYint, sz)); 2390 2386 n1 = el_bin(OPadd, TYnptr, n1, elwr2); 2391 2387 enbytes = el_bin(OPmin, TYint, eupr, elwr); 2392 2388 elength = el_copytree(enbytes); 2393 2389 } 2394 2390 else 2395 2391 elength = el_copytree(enbytes); 2396 2392 e = setArray(n1, enbytes, tb, evalue); 2397 2393 Lpair: 2398 e = el_pair(TY ullong, elength, e);2394 e = el_pair(TYdarray, elength, e); 2399 2395 Lret2: 2400 2396 e = el_combine(einit, e); 2401 2397 //elem_print(e); 2402 2398 goto Lret; 2403 2399 } 2404 2400 #if 0 2405 2401 else if (e2->op == TOKadd || e2->op == TOKmin) 2406 2402 { 2407 2403 /* It's ea[] = eb[] +- ec[] 2408 2404 */ 2409 2405 BinExp *e2a = (BinExp *)e2; 2410 2406 Type *t = e2->type->toBasetype()->nextOf()->toBasetype(); 2411 2407 if (t->ty != Tfloat32 && t->ty != Tfloat64 && t->ty != Tfloat80) 2412 2408 { 2413 2409 e2->error("array add/min for %s not supported", t->toChars()); 2414 2410 return el_long(TYint, 0); 2415 2411 } 2416 2412 elem *ea = e1->toElem(irs); 2417 2413 ea = array_toDarray(e1->type, ea); 2418 2414 elem *eb = e2a->e1->toElem(irs); … … 3010 3006 else 3011 3007 { 3012 3008 // Get pointer to function out of virtual table 3013 3009 unsigned vindex; 3014 3010 3015 3011 assert(ethis); 3016 3012 ep = el_same(ðis); 3017 3013 ep = el_una(OPind, TYnptr, ep); 3018 3014 vindex = func->vtblIndex; 3019 3015 3020 3016 // Build *(ep + vindex * 4) 3021 3017 ep = el_bin(OPadd,TYnptr,ep,el_long(TYint, vindex * 4)); 3022 3018 ep = el_una(OPind,TYnptr,ep); 3023 3019 } 3024 3020 3025 3021 // if (func->tintro) 3026 3022 // func->error(loc, "cannot form delegate due to covariant return type"); 3027 3023 } 3028 3024 if (ethis->Eoper == OPcomma) 3029 3025 { 3030 ethis->E2 = el_pair(TY ullong, ethis->E2, ep);3031 ethis->Ety = TY ullong;3026 ethis->E2 = el_pair(TYdarray, ethis->E2, ep); 3027 ethis->Ety = TYdarray; 3032 3028 e = ethis; 3033 3029 } 3034 3030 else 3035 e = el_pair(TY ullong, ethis, ep);3031 e = el_pair(TYdarray, ethis, ep); 3036 3032 el_setLoc(e,loc); 3037 3033 return e; 3038 3034 } 3039 3035 3040 3036 elem *DotTypeExp::toElem(IRState *irs) 3041 3037 { 3042 3038 // Just a pass-thru to e1 3043 3039 elem *e; 3044 3040 3045 3041 //printf("DotTypeExp::toElem() %s\n", toChars()); 3046 3042 e = e1->toElem(irs); 3047 3043 el_setLoc(e,loc); 3048 3044 return e; 3049 3045 } 3050 3046 3051 3047 elem *CallExp::toElem(IRState *irs) 3052 3048 { 3053 3049 //printf("CallExp::toElem('%s')\n", toChars()); 3054 3050 assert(e1->type); 3055 3051 elem *ec; … … 4012 4008 4013 4009 L2: 4014 4010 // Construct: (c1 || ModuleArray(line)) 4015 4011 Symbol *sassert; 4016 4012 4017 4013 sassert = irs->blx->module->toModuleArray(); 4018 4014 ea = el_bin(OPcall,TYvoid,el_var(sassert), el_long(TYint, loc.linnum)); 4019 4015 eb = el_bin(OPoror,TYvoid,c1,ea); 4020 4016 elwr = el_combine(elwr, eb); 4021 4017 4022 4018 elwr2 = el_copytree(elwr2); 4023 4019 eupr = el_copytree(eupr2); 4024 4020 } 4025 4021 } 4026 4022 4027 4023 eptr = array_toPtr(e1->type, e); 4028 4024 4029 4025 elem *elength = el_bin(OPmin, TYint, eupr, elwr2); 4030 4026 eptr = el_bin(OPadd, TYnptr, eptr, el_bin(OPmul, TYint, el_copytree(elwr2), el_long(TYint, sz))); 4031 4027 4032 e = el_pair(TY ullong, elength, eptr);4028 e = el_pair(TYdarray, elength, eptr); 4033 4029 e = el_combine(elwr, e); 4034 4030 e = el_combine(einit, e); 4035 4031 } 4036 4032 else if (t1->ty == Tsarray) 4037 4033 { 4038 4034 e = sarray_toDarray(loc, t1, NULL, e); 4039 4035 } 4040 4036 el_setLoc(e,loc); 4041 4037 return e; 4042 4038 } 4043 4039 4044 4040 elem *IndexExp::toElem(IRState *irs) 4045 4041 { elem *e; 4046 4042 elem *n1 = e1->toElem(irs); 4047 4043 elem *eb = NULL; 4048 4044 Type *t1; 4049 4045 4050 4046 //printf("IndexExp::toElem() %s\n", toChars()); 4051 4047 t1 = e1->type->toBasetype(); 4052 4048 if (t1->ty == Taarray) … … 4219 4215 else 4220 4216 { dim = 0; 4221 4217 e = el_long(TYint, 0); 4222 4218 } 4223 4219 Type *tb = type->toBasetype(); 4224 4220 #if 1 4225 4221 e = el_param(e, type->getTypeInfo(NULL)->toElem(irs)); 4226 4222 4227 4223 // call _d_arrayliteralT(ti, dim, ...) 4228 4224 e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ARRAYLITERALT]),e); 4229 4225 e->Eflags |= EFLAGS_variadic; 4230 4226 #else 4231 4227 e = el_param(e, el_long(TYint, tb->next->size())); 4232 4228 4233 4229 // call _d_arrayliteral(size, dim, ...) 4234 4230 e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ARRAYLITERAL]),e); 4235 4231 e->Eflags |= EFLAGS_variadic; 4236 4232 #endif 4237 4233 if (tb->ty == Tarray) 4238 4234 { 4239 e = el_pair(TY ullong, el_long(TYint, dim), e);4235 e = el_pair(TYdarray, el_long(TYint, dim), e); 4240 4236 } 4241 4237 else if (tb->ty == Tpointer) 4242 4238 { 4243 4239 } 4244 4240 else 4245 4241 { 4246 4242 e = el_una(OPind,TYstruct,e); 4247 4243 e->Enumbytes = type->size(); 4248 4244 } 4249 4245 4250 4246 el_setLoc(e,loc); 4251 4247 return e; 4252 4248 } 4253 4249 4254 4250 4255 4251 elem *AssocArrayLiteralExp::toElem(IRState *irs) 4256 4252 { elem *e; 4257 4253 size_t dim; 4258 4254 4259 4255 //printf("AssocArrayLiteralExp::toElem() %s\n", toChars()); branches/dmd-1.x/src/iasm.c
r606 r618 1231 1231 L386_WARNING2: 1232 1232 if (config.target_cpu < TARGET_80386) 1233 1233 { // Reference to %s caused a 386 instruction to be generated 1234 1234 //warerr(WM_386_op, id->toChars()); 1235 1235 } 1236 1236 } 1237 1237 break; 1238 1238 case 2: 1239 1239 case 3: // The third operand is always an _imm 1240 1240 if (popnd1 && popnd1->s) 1241 1241 goto L386_WARNING; 1242 1242 if (popnd2 && popnd2->s) 1243 1243 { 1244 1244 id = popnd2->s->ident; 1245 1245 goto L386_WARNING2; 1246 1246 } 1247 1247 break; 1248 1248 } 1249 1249 } 1250 1250 1251 if (ptb.pptb0->usFlags & _64_bit && !I64) 1252 error(asmstate.loc, "use -m64 to compile 64 bit instructions"); 1253 1251 1254 switch (usNumops) 1252 1255 { 1253 1256 case 0: 1254 if (( I32&& (ptb.pptb0->usFlags & _16_bit)) ||1257 if (((I32 | I64) && (ptb.pptb0->usFlags & _16_bit)) || 1255 1258 (I16 && (ptb.pptb0->usFlags & _32_bit))) 1256 1259 { 1257 1260 emit(0x66); 1258 1261 pc->Iflags |= CFopsize; 1262 } 1263 else if (I64 && (ptb.pptb0->usFlags & _64_bit)) 1264 { 1265 emit(REX | REX_W); 1266 pc->Irex |= REX_W; 1259 1267 } 1260 1268 break; 1261 1269 1262 1270 // 3 and 2 are the same because the third operand is always 1263 1271 // an immediate and does not affect operation size 1264 1272 case 3: 1265 1273 case 2: 1266 1274 if ((I32 && 1267 1275 (amod2 == _addr16 || 1268 1276 (uSizemaskTable2 & _16 && aoptyTable2 == _rel) || 1269 1277 (uSizemaskTable2 & _32 && aoptyTable2 == _mnoi) || 1270 1278 (ptb.pptb2->usFlags & _16_bit_addr) 1271 1279 ) 1272 1280 ) || 1273 1281 (I16 && 1274 1282 (amod2 == _addr32 || 1275 1283 (uSizemaskTable2 & _32 && aoptyTable2 == _rel) || 1276 1284 (uSizemaskTable2 & _48 && aoptyTable2 == _mnoi) || 1277 1285 (ptb.pptb2->usFlags & _32_bit_addr))) 1278 1286 ) branches/dmd-1.x/src/mars.c
r584 r618 74 74 #else 75 75 #error "fix this" 76 76 #endif 77 77 78 78 #if TARGET_WINDOS 79 79 dll_ext = "dll"; 80 80 #elif TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS 81 81 dll_ext = "so"; 82 82 #elif TARGET_OSX 83 83 dll_ext = "dylib"; 84 84 #else 85 85 #error "fix this" 86 86 #endif 87 87 88 88 copyright = "Copyright (c) 1999-2010 by Digital Mars"; 89 89 written = "written by Walter Bright" 90 90 #if TARGET_NET 91 91 "\nMSIL back-end (alpha release) by Cristian L. Vlasceanu and associates."; 92 92 #endif 93 93 ; 94 version = "v1.06 3";94 version = "v1.064"; 95 95 global.structalign = 8; 96 96 97 97 memset(¶ms, 0, sizeof(Param)); 98 98 } 99 99 100 100 char *Loc::toChars() 101 101 { 102 102 OutBuffer buf; 103 103 char *p; 104 104 105 105 if (filename) 106 106 { 107 107 buf.printf("%s", filename); 108 108 } 109 109 110 110 if (linnum) 111 111 buf.printf("(%d)", linnum); 112 112 buf.writeByte(0); 113 113 return (char *)buf.extractData(); 114 114 } branches/dmd-1.x/src/s2ir.c
r567 r618 957 957 */ 958 958 block_goto(blx, BCgoto, mystate.breakBlock); 959 959 return; 960 960 } 961 961 #endif 962 962 963 963 if (condition->type->isString()) 964 964 { 965 965 // Number the cases so we can unscramble things after the sort() 966 966 for (int i = 0; i < numcases; i++) 967 967 { CaseStatement *cs = (CaseStatement *)cases->data[i]; 968 968 cs->index = i; 969 969 } 970 970 971 971 cases->sort(); 972 972 973 973 /* Create a sorted array of the case strings, and si 974 974 * will be the symbol for it. 975 975 */ 976 976 dt_t *dt = NULL; 977 Symbol *si = symbol_generate(SCstatic,type_fake(TY ullong));977 Symbol *si = symbol_generate(SCstatic,type_fake(TYdarray)); 978 978 #if MACHOBJ 979 979 si->Sseg = DATA; 980 980 #endif 981 dt dword(&dt, numcases);982 dtxoff(&dt, si, 8, TYnptr);981 dtsize_t(&dt, numcases); 982 dtxoff(&dt, si, PTRSIZE * 2, TYnptr); 983 983 984 984 for (int i = 0; i < numcases; i++) 985 985 { CaseStatement *cs = (CaseStatement *)cases->data[i]; 986 986 987 987 if (cs->exp->op != TOKstring) 988 988 { error("case '%s' is not a string", cs->exp->toChars()); // BUG: this should be an assert 989 989 } 990 990 else 991 991 { 992 992 StringExp *se = (StringExp *)(cs->exp); 993 993 unsigned len = se->len; 994 994 dtdword(&dt, len); 995 995 dtabytes(&dt, TYnptr, 0, se->len * se->sz, (char *)se->string); 996 996 } 997 997 } 998 998 999 999 si->Sdt = dt; 1000 1000 si->Sfl = FLdata; 1001 1001 outdata(si); 1002 1002 branches/dmd-1.x/src/toobj.c
r428 r618 334 334 /* The layout is: 335 335 { 336 336 void **vptr; 337 337 monitor_t monitor; 338 338 byte[] initializer; // static initialization data 339 339 char[] name; // class name 340 340 void *[] vtbl; 341 341 Interface[] interfaces; 342 342 ClassInfo *base; // base class 343 343 void *destructor; 344 344 void *invariant; // class invariant 345 345 uint flags; 346 346 void *deallocator; 347 347 OffsetTypeInfo[] offTi; 348 348 void *defaultConstructor; 349 349 const(MemberInfo[]) function(string) xgetMembers; // module getMembers() function 350 350 TypeInfo typeinfo; 351 351 } 352 352 */ 353 353 dt_t *dt = NULL; 354 offset = CLASSINFO_SIZE; // must be ClassInfo.size 354 unsigned classinfo_size = global.params.isX86_64 ? CLASSINFO_SIZE_64 : CLASSINFO_SIZE; // must be ClassInfo.size 355 offset = classinfo_size; 355 356 if (classinfo) 356 357 { 357 if (classinfo->structsize != CLASSINFO_SIZE) 358 { 358 if (classinfo->structsize != classinfo_size) 359 { 360 #ifdef DEBUG 361 printf("CLASSINFO_SIZE = x%x, classinfo->structsize = x%x\n", offset, classinfo->structsize); 362 #endif 359 363 error("mismatch between dmd and object.d or object.di found. Check installation and import paths with -v compiler switch."); 360 364 fatal(); 361 365 } 362 366 } 363 367 364 368 if (classinfo) 365 369 dtxoff(&dt, classinfo->toVtblSymbol(), 0, TYnptr); // vtbl for ClassInfo 366 370 else 367 371 dtdword(&dt, 0); // BUG: should be an assert() 368 372 dtdword(&dt, 0); // monitor 369 373 370 374 // initializer[] 371 375 assert(structsize >= 8); 372 376 dtdword(&dt, structsize); // size 373 377 dtxoff(&dt, sinit, 0, TYnptr); // initializer 374 378 375 379 // name[] 376 380 const char *name = ident->toChars(); 377 381 size_t namelen = strlen(name); 378 382 if (!(namelen > 9 && memcmp(name, "TypeInfo_", 9) == 0)) … … 485 489 // Fill in vtbl[] 486 490 b->fillVtbl(this, &b->vtbl, 1); 487 491 488 492 dtxoff(&dt, id->toSymbol(), 0, TYnptr); // ClassInfo 489 493 490 494 // vtbl[] 491 495 dtdword(&dt, id->vtbl.dim); 492 496 dtxoff(&dt, csym, offset, TYnptr); 493 497 494 498 dtdword(&dt, b->offset); // this offset 495 499 496 500 offset += id->vtbl.dim * PTRSIZE; 497 501 } 498 502 499 503 // Put out the vtblInterfaces->data[].vtbl[] 500 504 // This must be mirrored with ClassDeclaration::baseVtblOffset() 501 505 //printf("putting out %d interface vtbl[]s for '%s'\n", vtblInterfaces->dim, toChars()); 502 506 for (i = 0; i < vtblInterfaces->dim; i++) 503 507 { BaseClass *b = (BaseClass *)vtblInterfaces->data[i]; 504 508 ClassDeclaration *id = b->base; 505 int j;506 509 507 510 //printf(" interface[%d] is '%s'\n", i, id->toChars()); 508 j = 0;511 int j = 0; 509 512 if (id->vtblOffset()) 510 513 { 511 514 // First entry is ClassInfo reference 512 515 //dtxoff(&dt, id->toSymbol(), 0, TYnptr); 513 516 514 517 // First entry is struct Interface reference 515 518 dtxoff(&dt, csym, CLASSINFO_SIZE + i * (4 * PTRSIZE), TYnptr); 516 519 j = 1; 517 520 } 518 521 assert(id->vtbl.dim == b->vtbl.dim); 519 522 for (; j < id->vtbl.dim; j++) 520 523 { 521 FuncDeclaration *fd;522 523 524 assert(j < b->vtbl.dim); 524 525 #if 0 525 526 Object *o = (Object *)b->vtbl.data[j]; 526 527 if (o) 527 528 { 528 529 printf("o = %p\n", o); 529 530 assert(o->dyncast() == DYNCAST_DSYMBOL); 530 531 Dsymbol *s = (Dsymbol *)o; 531 532 printf("s->kind() = '%s'\n", s->kind()); 532 533 } 533 534 #endif 534 fd = (FuncDeclaration *)b->vtbl.data[j];535 FuncDeclaration *fd = (FuncDeclaration *)b->vtbl.data[j]; 535 536 if (fd) 536 537 dtxoff(&dt, fd->toThunkSymbol(b->offset), 0, TYnptr); 537 538 else 538 539 dtdword(&dt, 0); 539 540 } 540 541 } 541 542 542 543 #if 1 543 544 // Put out the overriding interface vtbl[]s. 544 545 // This must be mirrored with ClassDeclaration::baseVtblOffset() 545 546 //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); 546 547 ClassDeclaration *cd; 547 548 Array bvtbl; 548 549 549 550 for (cd = this->baseClass; cd; cd = cd->baseClass) 550 551 { 551 552 for (int k = 0; k < cd->vtblInterfaces->dim; k++) 552 553 { BaseClass *bs = (BaseClass *)cd->vtblInterfaces->data[k]; 553 554 554 555 if (bs->fillVtbl(this, &bvtbl, 0)) … … 700 701 #endif 701 702 #if MACHOBJ 702 703 vtblsym->Sseg = DATA; 703 704 #endif 704 705 outdata(vtblsym); 705 706 if (isExport()) 706 707 obj_export(vtblsym,0); 707 708 } 708 709 709 710 /****************************************** 710 711 * Get offset of base class's vtbl[] initializer from start of csym. 711 712 * Returns ~0 if not this csym. 712 713 */ 713 714 714 715 unsigned ClassDeclaration::baseVtblOffset(BaseClass *bc) 715 716 { 716 717 unsigned csymoffset; 717 718 int i; 718 719 719 720 //printf("ClassDeclaration::baseVtblOffset('%s', bc = %p)\n", toChars(), bc); 720 csymoffset = CLASSINFO_SIZE;721 csymoffset = global.params.isX86_64 ? CLASSINFO_SIZE_64 : CLASSINFO_SIZE; // must be ClassInfo.size 721 722 csymoffset += vtblInterfaces->dim * (4 * PTRSIZE); 722 723 723 724 for (i = 0; i < vtblInterfaces->dim; i++) 724 725 { 725 726 BaseClass *b = (BaseClass *)vtblInterfaces->data[i]; 726 727 727 728 if (b == bc) 728 729 return csymoffset; 729 730 csymoffset += b->base->vtbl.dim * PTRSIZE; 730 731 } 731 732 732 733 #if 1 733 734 // Put out the overriding interface vtbl[]s. 734 735 // This must be mirrored with ClassDeclaration::baseVtblOffset() 735 736 //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); 736 737 ClassDeclaration *cd; 737 738 Array bvtbl; 738 739 739 740 for (cd = this->baseClass; cd; cd = cd->baseClass) 740 741 { … … 782 783 void InterfaceDeclaration::toObjFile(int multiobj) 783 784 { unsigned i; 784 785 unsigned offset; 785 786 Symbol *sinit; 786 787 enum_SC scclass; 787 788 788 789 //printf("InterfaceDeclaration::toObjFile('%s')\n", toChars()); 789 790 790 791 if (!members) 791 792 return; 792 793 793 794 if (global.params.symdebug) 794 795 toDebug(); 795 796 796 797 scclass = SCglobal; 797 798 if (inTemplateInstance()) 798 799 scclass = SCcomdat; 799 800 800 801 // Put out the members 801 802 for (i = 0; i < members->dim; i++) 802 { 803 Dsymbol *member; 804 805 member = (Dsymbol *)members->data[i]; 803 { Dsymbol *member = (Dsymbol *)members->data[i]; 806 804 if (!member->isFuncDeclaration()) 807 805 member->toObjFile(0); 808 806 } 809 807 810 808 // Generate C symbols 811 809 toSymbol(); 812 810 813 811 ////////////////////////////////////////////// 814 812 815 813 // Put out the TypeInfo 816 814 type->getTypeInfo(NULL); 817 815 type->vtinfo->toObjFile(multiobj); 818 816 819 817 ////////////////////////////////////////////// 820 818 821 819 // Put out the ClassInfo 822 820 csym->Sclass = scclass; 823 821 csym->Sfl = FLdata; 824 822 825 823 /* The layout is: … … 852 850 dtdword(&dt, 0); // monitor 853 851 854 852 // initializer[] 855 853 dtdword(&dt, 0); // size 856 854 dtdword(&dt, 0); // initializer 857 855 858 856 // name[] 859 857 const char *name = toPrettyChars(); 860 858 size_t namelen = strlen(name); 861 859 dtdword(&dt, namelen); 862 860 dtabytes(&dt, TYnptr, 0, namelen + 1, name); 863 861 864 862 // vtbl[] 865 863 dtdword(&dt, 0); 866 864 dtdword(&dt, 0); 867 865 868 866 // vtblInterfaces->data[] 869 867 dtdword(&dt, vtblInterfaces->dim); 870 868 if (vtblInterfaces->dim) 871 869 { 870 offset = global.params.isX86_64 ? CLASSINFO_SIZE_64 : CLASSINFO_SIZE; // must be ClassInfo.size 872 871 if (classinfo) 873 872 { 874 if (classinfo->structsize != CLASSINFO_SIZE)873 if (classinfo->structsize != offset) 875 874 { 876 875 error("mismatch between dmd and object.d or object.di found. Check installation and import paths with -v compiler switch."); 877 876 fatal(); 878 877 } 879 878 } 880 offset = CLASSINFO_SIZE;881 879 dtxoff(&dt, csym, offset, TYnptr); // (*) 882 880 } 883 881 else 884 882 dtdword(&dt, 0); 885 883 886 884 // base 887 885 assert(!baseClass); 888 886 dtdword(&dt, 0); 889 887 890 888 // dtor 891 889 dtdword(&dt, 0); 892 890 893 891 // invariant 894 892 dtdword(&dt, 0); 895 893 896 894 // flags 897 895 dtdword(&dt, 4 | isCOMinterface() | 32); 898 896 899 897 // deallocator 900 898 dtdword(&dt, 0); trunk/src/aggregate.h
r520 r618 172 172 Type *type; // (before semantic processing) 173 173 enum PROT protection; // protection for the base interface 174 174 175 175 ClassDeclaration *base; 176 176 int offset; // 'this' pointer offset 177 177 Array vtbl; // for interfaces: Array of FuncDeclaration's 178 178 // making up the vtbl[] 179 179 180 180 int baseInterfaces_dim; 181 181 BaseClass *baseInterfaces; // if BaseClass is an interface, these 182 182 // are a copy of the InterfaceDeclaration::interfaces 183 183 184 184 BaseClass(); 185 185 BaseClass(Type *type, enum PROT protection); 186 186 187 187 int fillVtbl(ClassDeclaration *cd, Array *vtbl, int newinstance); 188 188 void copyBaseInterfaces(BaseClasses *); 189 189 }; 190 190 191 191 #if DMDV2 192 #define CLASSINFO_SIZE_64 (0x3C+12+4) // value of ClassInfo.size 192 193 #define CLASSINFO_SIZE (0x3C+12+4) // value of ClassInfo.size 193 194 #else 194 195 #define CLASSINFO_SIZE (0x3C+12+4) // value of ClassInfo.size 195 196 #endif 196 197 197 198 struct ClassDeclaration : AggregateDeclaration 198 199 { 199 200 static ClassDeclaration *object; 200 201 static ClassDeclaration *classinfo; 201 202 202 203 ClassDeclaration *baseClass; // NULL only if this is Object 203 204 #if DMDV1 204 205 CtorDeclaration *ctor; 205 206 CtorDeclaration *defaultCtor; // default constructor 206 207 #endif 207 208 FuncDeclaration *staticCtor; 208 209 FuncDeclaration *staticDtor; 209 210 Array vtbl; // Array of FuncDeclaration's making up the vtbl[] 210 211 Array vtblFinal; // More FuncDeclaration's that aren't in vtbl[] 211 212 trunk/src/backend/cdef.h
r593 r618 879 879 immed_t immed; // immediate values in registers 880 880 regm_t mvar; // mask of register variables 881 881 regm_t mpvar; // mask of SCfastpar register variables 882 882 regm_t indexregs; // !=0 if more than 1 uncommitted index register 883 883 regm_t used; // mask of registers used 884 884 regm_t params; // mask of registers which still contain register 885 885 // function parameters 886 886 }; 887 887 888 888 /********************************* 889 889 * Bootstrap complex types. 890 890 */ 891 891 892 892 #include "bcomplex.h" 893 893 894 894 /********************************* 895 895 * Union of all data types. Storage allocated must be the right 896 896 * size of the data on the TARGET, not the host. 897 897 */ 898 898 899 struct Cent 900 { 901 targ_ullong lsw; 902 targ_ullong msw; 903 }; 904 899 905 union eve 900 906 { 901 907 targ_char Vchar; 902 908 targ_schar Vschar; 903 909 targ_uchar Vuchar; 904 910 targ_short Vshort; 905 911 targ_ushort Vushort; 906 912 targ_int Vint; // also used for tmp numbers (FLtmp) 907 913 targ_uns Vuns; 908 914 targ_long Vlong; 909 915 targ_ulong Vulong; 910 916 targ_llong Vllong; 911 917 targ_ullong Vullong; 918 Cent Vcent; 912 919 targ_float Vfloat; 913 920 targ_double Vdouble; 914 921 targ_ldouble Vldouble; 915 922 Complex_f Vcfloat; // 2x float 916 923 Complex_d Vcdouble; // 2x double 917 924 Complex_ld Vcldouble; // 2x long double 918 925 targ_size_t Vpointer; 919 926 targ_ptrdiff_t Vptrdiff; 920 927 targ_uchar Vreg; // register number for OPreg elems 921 928 struct // 48 bit 386 far pointer 922 929 { targ_long Voff; 923 930 targ_ushort Vseg; 924 931 } Vfp; 925 932 struct 926 933 { 927 934 targ_size_t Voffset;// offset from symbol 928 935 Symbol *Vsym; // pointer to symbol table 929 936 union 930 937 { struct PARAM *Vtal; // template-argument-list for SCfunctempl, 931 938 // used only to transmit it to cpp_overload() trunk/src/backend/cgcod.c
r596 r618 1833 1833 r = retregs & ~(msavereg | regcon.cse.mops); 1834 1834 if (!r) 1835 1835 { r = retregs & ~msavereg; 1836 1836 if (!r) 1837 1837 r = retregs; 1838 1838 } 1839 1839 } 1840 1840 } 1841 1841 if (0 && r & ~fregsaved) 1842 1842 r &= ~fregsaved; 1843 1843 1844 1844 if (size <= REGSIZE) 1845 1845 { 1846 1846 if (r & ~mBP) 1847 1847 r &= ~mBP; 1848 1848 1849 1849 // If only one index register, prefer to not use LSW registers 1850 1850 if (!regcon.indexregs && r & ~mLSW) 1851 1851 r &= ~mLSW; 1852 1852 1853 if (pass == PASSfinal && r & ~lastretregs && I32)1853 if (pass == PASSfinal && r & ~lastretregs && !I16) 1854 1854 { // Try not to always allocate the same register, 1855 1855 // to schedule better 1856 1856 1857 1857 r &= ~lastretregs; 1858 1858 if (r & ~last2retregs) 1859 1859 { r &= ~last2retregs; 1860 1860 if (r & ~last3retregs) 1861 1861 { r &= ~last3retregs; 1862 1862 if (r & ~last4retregs) 1863 1863 { r &= ~last4retregs; 1864 1864 // if (r & ~last5retregs) 1865 1865 // r &= ~last5retregs; 1866 1866 } 1867 1867 } 1868 1868 } 1869 1869 if (r & ~mfuncreg) 1870 1870 r &= ~mfuncreg; 1871 1871 } 1872 1872 reg = findreg(r); 1873 1873 retregs = mask[reg]; … … 2714 2714 #define SMAX 64 2715 2715 static char str[NUM][SMAX + 1]; 2716 2716 static int i; 2717 2717 char *p; 2718 2718 char *s; 2719 2719 int j; 2720 2720 2721 2721 if (rm == 0) 2722 2722 return "0"; 2723 2723 if (rm == ALLREGS) 2724 2724 return "ALLREGS"; 2725 2725 if (rm == BYTEREGS) 2726 2726 return "BYTEREGS"; 2727 2727 if (rm == allregs) 2728 2728 return "allregs"; 2729 2729 p = str[i]; 2730 2730 if (++i == NUM) 2731 2731 i = 0; 2732 2732 s = p; 2733 2733 *p = 0; 2734 for (j = 0; j < 23; j++)2734 for (j = 0; j < 32; j++) 2735 2735 { 2736 2736 if (mask[j] & rm) 2737 2737 { 2738 2738 strcat(p,regstring[j]); 2739 2739 rm &= ~mask[j]; 2740 2740 if (rm) 2741 2741 strcat(p,"|"); 2742 2742 } 2743 2743 } 2744 2744 if (rm) 2745 2745 { s = p + strlen(p); 2746 2746 sprintf(s,"x%02x",rm); 2747 2747 } 2748 2748 assert(strlen(p) <= SMAX); 2749 2749 return strdup(p); 2750 2750 } 2751 2751 2752 2752 #endif 2753 2753 2754 2754 #endif // !SPP trunk/src/backend/cgelem.c
r500 r618 1993 1993 e->E1->Ety = touns(tym); 1994 1994 break; 1995 1995 1996 1996 case OPmod: 1997 1997 op = OPand; 1998 1998 goto L3; 1999 1999 case OPmodass: 2000 2000 op = OPandass; 2001 2001 L3: 2002 2002 e2->EV.Vullong = el_tolong(e2) - 1; 2003 2003 break; 2004 2004 2005 2005 default: 2006 2006 assert(0); 2007 2007 } 2008 2008 e->Eoper = op; 2009 2009 return optelem(e,TRUE); 2010 2010 } 2011 2011 #if TARGET_MAC 2012 2012 if (j != -1) 2013 { elem *ea; 2014 2015 ea = el_copytree(e->E1); 2013 { 2014 elem *ea = el_copytree(e->E1); 2016 2015 e2->EV.Vint = j; 2017 2016 e->Eoper = OPshr; 2018 2017 e->E1->Ety = touns(tym); 2019 2018 e2->Ety = TYint; 2020 2019 e = el_una(OPneg,tym,e); 2021 2020 e = el_bin(OPeq,tym,ea,e); 2022 2021 return optelem(e,TRUE); 2023 2022 } 2024 2023 #endif 2025 2024 } 2026 2025 #if TARGET_MAC 2027 2026 unsigned short op; 2028 2027 tym_t tym2; 2029 2028 elem *e1 = e->E1; 2030 2029 2031 2030 tym = e->E1->Ety; 2032 2031 op = e1->Eoper; 2033 2032 if (op == OPu16_32 && e2->EV.Vulong <= (targ_ulong) SHORTMASK || 2034 2033 op == OPshtlng && e2->EV.Vlong == (targ_short) e2->EV.Vlong) 2035 2034 { … … 2080 2079 2081 2080 if (OPTIMIZER) 2082 2081 { 2083 2082 if (tyintegral(tym) && (e->Eoper == OPdiv || e->Eoper == OPmod)) 2084 2083 { int sz = tysize(tym); 2085 2084 2086 2085 // See if we can replace with OPremquo 2087 2086 if (sz == intsize) 2088 2087 { 2089 2088 // Don't do it if there are special code sequences in the 2090 2089 // code generator (see cdmul()) 2091 2090 int pow2; 2092 2091 if (e->E2->Eoper == OPconst && 2093 2092 sz == REGSIZE && !uns && 2094 2093 (pow2 = ispow2(el_tolong(e->E2))) != -1 && 2095 2094 !(config.target_cpu < TARGET_80286 && pow2 != 1 && e->Eoper == OPdiv) 2096 2095 ) 2097 2096 ; 2098 2097 else 2099 2098 { 2100 int op; 2101 2102 op = OPmsw; 2099 assert(sz == 2 || sz == 4); 2100 int op = OPmsw; 2103 2101 if (e->Eoper == OPdiv) 2104 2102 { 2105 2103 op = (sz == 2) ? OP32_16 : OP64_32; 2106 2104 } 2107 2105 e->Eoper = OPremquo; 2108 2106 e = el_una(op, tym, e); 2109 2107 e->E1->Ety = (sz == 2) ? TYlong : TYllong; 2110 2108 } 2111 2109 } 2112 2110 } 2113 2111 } 2114 2112 2115 2113 return e; 2116 2114 } 2117 2115 2118 2116 2119 2117 /************************** 2120 2118 * Convert (a op b) op c to a op (b op c). 2121 2119 */ 2122 2120 … … 3824 3822 if (tysize(ty) != tysize(e->E1->E1->Ety)) 3825 3823 break; 3826 3824 e = el_selecte1(el_selecte1(e)); 3827 3825 e->Ety = ty; 3828 3826 break; 3829 3827 3830 3828 case OPrpair: 3831 3829 if (tysize(ty) != tysize(e->E1->E2->Ety)) 3832 3830 break; 3833 3831 e = el_selecte2(el_selecte1(e)); 3834 3832 e->Ety = ty; 3835 3833 break; 3836 3834 3837 3835 case OPvar: // simply paint type of variable 3838 3836 case OPind: 3839 3837 e = el_selecte1(e); 3840 3838 break; 3841 3839 3842 3840 case OPshr: // OP64_32(x >> 32) => OPmsw(x) 3843 3841 if (e1->E2->Eoper == OPconst && 3844 el_tolong(e1->E2) == 32 )3842 el_tolong(e1->E2) == 32 && !I64) 3845 3843 { 3846 3844 e->Eoper = OPmsw; 3847 3845 e->E1 = el_selecte1(e->E1); 3848 3846 } 3849 3847 break; 3850 3848 } 3851 3849 return e; 3852 3850 } 3853 3851 3854 3852 3855 3853 /******************************* 3856 3854 * Convert complex to real. 3857 3855 */ 3858 3856 3859 3857 STATIC elem *elc_r(elem *e) 3860 3858 { 3861 3859 elem *e1 = e->E1; 3862 3860 3863 3861 if (e1->Eoper == OPvar || e1->Eoper == OPind) 3864 3862 { trunk/src/backend/cgreg.c
r569 r618 675 675 } 676 676 if (inoutp == 1) 677 677 cstore = cat(cstore,c); 678 678 else 679 679 cload = cat(cload,c); 680 680 break; 681 681 } 682 682 el_free(e); 683 683 684 684 // Store old register values before loading in new ones 685 685 *pcstore = cstore; 686 686 *pcload = cload; 687 687 } 688 688 689 689 /*************************** 690 690 * Map symbol s into registers [NOREG,reglsw] or [regmsw, reglsw]. 691 691 */ 692 692 693 693 void cgreg_map(Symbol *s, unsigned regmsw, unsigned reglsw) 694 694 { 695 assert( reglsw < 8);695 assert(I64 || reglsw < 8); 696 696 697 697 if (vec_disjoint(s->Srange,regrange[reglsw]) && 698 698 (regmsw == NOREG || vec_disjoint(s->Srange,regrange[regmsw])) 699 699 ) 700 700 { 701 701 s->Sfl = FLreg; 702 702 vec_copy(s->Slvreg,s->Srange); 703 703 } 704 704 else 705 705 { 706 706 s->Sflags |= SFLspill; 707 707 708 708 // Already computed by cgreg_benefit() 709 709 //vec_sub(s->Slvreg,s->Srange,regrange[reglsw]); 710 710 711 711 if (s->Sfl == FLreg) // if reassigned 712 712 { 713 713 switch (s->Sclass) 714 714 { 715 715 case SCauto: … … 897 897 #ifdef DEBUG 898 898 if (debugr) 899 899 if (s->Sfl == FLreg) 900 900 printf("symbol '%s' is in reg %s\n",s->Sident,regm_str(s->Sregm)); 901 901 else if (s->Sflags & SFLspill) 902 902 printf("symbol '%s' spilled in reg %s\n",s->Sident,regm_str(s->Sregm)); 903 903 else 904 904 printf("symbol '%s' is not a candidate\n",s->Sident); 905 905 #endif 906 906 continue; 907 907 } 908 908 909 909 char *pseq; 910 910 char *pseqmsw = NULL; 911 911 912 912 ty = s->ty(); 913 913 sz = tysize(ty); 914 914 915 915 #ifdef DEBUG 916 916 if (debugr) 917 { printf("symbol '%3s', ty x% lx weight x%x sz %d\n ",918 s->Sident,ty,s->Sweight, sz);917 { printf("symbol '%3s', ty x%x weight x%x sz %d\n ", 918 s->Sident,ty,s->Sweight,(int)sz); 919 919 vec_println(s->Srange); 920 920 } 921 921 #endif 922 922 923 923 if (I64) 924 924 { 925 925 if (sz == REGSIZE * 2) 926 926 { 927 927 static char seqmsw[] = {CX,DX,NOREG}; 928 928 static char seqlsw[] = {AX,BX,SI,DI,NOREG}; 929 929 pseq = seqlsw; 930 930 pseqmsw = seqmsw; 931 931 } 932 932 else 933 933 { // R10 is reserved for the static link 934 934 static char sequence[] = {AX,CX,DX,SI,DI,R8,R9,R11,BX,R12,R13,R14,R15,BP,NOREG}; 935 935 pseq = sequence; 936 936 } 937 937 } 938 938 else if (I32) trunk/src/backend/cgsched.c
r596 r618 3161 3161 3162 3162 if (ci == NULL) 3163 3163 { 3164 3164 printf("Cinfo 0\n"); 3165 3165 return; 3166 3166 } 3167 3167 3168 3168 printf("Cinfo %p: c %p, pair %x, sz %d, isz %d, flags - ", 3169 3169 ci,c,pair,sz,isz); 3170 3170 if (ci->flags & CIFLarraybounds) 3171 3171 printf("arraybounds,"); 3172 3172 if (ci->flags & CIFLea) 3173 3173 printf("ea,"); 3174 3174 if (ci->flags & CIFLnostage) 3175 3175 printf("nostage,"); 3176 3176 if (ci->flags & CIFLpush) 3177 3177 printf("push,"); 3178 3178 if (ci->flags & ~(CIFLarraybounds|CIFLnostage|CIFLpush|CIFLea)) 3179 3179 printf("bad flag,"); 3180 3180 printf("\n\tr %lx w %lx a %lx reg %x uops %x sibmodrm %x spadjust %ld\n", 3181 r,w,a,reg,uops,sibmodrm,spadjust);3181 (long)r,(long)w,(long)a,reg,uops,sibmodrm,(long)spadjust); 3182 3182 if (ci->fp_op) 3183 3183 printf("\tfp_op %s, fxch_pre %x, fxch_post %x\n", 3184 3184 fpops[fp_op-1],fxch_pre,fxch_post); 3185 3185 } 3186 3186 #endif 3187 3187 #endif trunk/src/backend/cod1.c
r605 r618 1784 1784 else 1785 1785 assert(0); 1786 1786 } 1787 1787 code_orflag(ce,CFpsw); 1788 1788 return ce; 1789 1789 } 1790 1790 1791 1791 1792 1792 /****************************** 1793 1793 * Given the result of an expression is in retregs, 1794 1794 * generate necessary code to return result in *pretregs. 1795 1795 */ 1796 1796 1797 1797 code *fixresult(elem *e,regm_t retregs,regm_t *pretregs) 1798 1798 { code *c,*ce; 1799 1799 unsigned reg,rreg; 1800 1800 regm_t forccs,forregs; 1801 1801 tym_t tym; 1802 1802 int sz; 1803 1803 1804 // printf("fixresult(e = %p, retregs = %s, *pretregs = %s)\n", 1805 // e,regm_str(retregs),regm_str(*pretregs)); 1804 //printf("fixresult(e = %p, retregs = %s, *pretregs = %s)\n",e,regm_str(retregs),regm_str(*pretregs)); 1806 1805 if (*pretregs == 0) return CNIL; /* if don't want result */ 1807 1806 assert(e && retregs); /* need something to work with */ 1808 1807 forccs = *pretregs & mPSW; 1809 1808 forregs = *pretregs & (mST01 | mST0 | mBP | ALLREGS | mES | mSTACK); 1810 1809 tym = tybasic(e->Ety); 1811 1810 #if 0 1812 1811 if (tym == TYstruct) 1813 1812 // Hack to support cdstreq() 1814 1813 tym = TYfptr; 1815 1814 #else 1816 1815 if (tym == TYstruct) 1817 1816 // Hack to support cdstreq() 1818 1817 tym = (forregs & mMSW) ? TYfptr : TYnptr; 1819 1818 #endif 1820 1819 c = CNIL; 1821 1820 sz = tysize[tym]; 1822 1821 if (sz == 1) 1823 1822 { 1824 1823 assert(retregs & BYTEREGS); 1825 1824 unsigned reg = findreg(retregs); … … 3309 3308 if (I16 && config.target_cpu >= TARGET_80386 && sz > 2 && 3310 3309 !e->Ecount) 3311 3310 { regsize = 4; 3312 3311 flag |= CFopsize; 3313 3312 } 3314 3313 ce = loadea(e,&cs,0xFF,6,sz - regsize,RMload,0); // PUSH EA+sz-2 3315 3314 code_orflag(ce,flag); 3316 3315 ce = genadjesp(ce,REGSIZE); 3317 3316 stackpush += sz; 3318 3317 while ((targ_int)(sz -= regsize) > 0) 3319 3318 { ce = cat(ce,loadea(e,&cs,0xFF,6,sz - regsize,RMload,0)); 3320 3319 code_orflag(ce,flag); 3321 3320 ce = genadjesp(ce,REGSIZE); 3322 3321 } 3323 3322 } 3324 3323 L2: 3325 3324 freenode(e); 3326 3325 c = cat(c,ce); 3327 3326 goto ret; 3328 3327 case OPconst: 3329 { targ_int *pi; 3330 targ_short *ps; 3328 { 3331 3329 char pushi = 0; 3332 3330 unsigned flag = 0; 3333 int i;3334 3331 int regsize = REGSIZE; 3335 3332 targ_int value; 3336 3333 3337 3334 if (tycomplex(tym)) 3338 3335 break; 3339 3336 3340 3337 if (I32 && szb == 10) // special case for long double constants 3341 3338 { 3342 3339 assert(sz == 12); 3343 3340 value = ((unsigned short *)&e->EV.Vldouble)[4]; 3344 3341 stackpush += sz; 3345 3342 ce = genadjesp(NULL,sz); 3346 for (i = 2; i >= 0; i--)3343 for (int i = 2; i >= 0; i--) 3347 3344 { 3348 3345 if (reghasvalue(allregs, value, ®)) 3349 3346 ce = gen1(ce,0x50 + reg); // PUSH reg 3350 3347 else 3351 3348 ce = genc2(ce,0x68,0,value); // PUSH value 3352 3349 value = ((unsigned *)&e->EV.Vldouble)[i - 1]; 3353 3350 } 3354 3351 goto L2; 3355 3352 } 3356 3353 3357 assert( sz <= LNGDBLSIZE);3358 i = sz;3359 if ( I32&& i == 2)3354 assert(I64 || sz <= LNGDBLSIZE); 3355 int i = sz; 3356 if (!I16 && i == 2) 3360 3357 flag = CFopsize; 3361 3358 3362 3359 if (config.target_cpu >= TARGET_80286) 3363 3360 // && (e->Ecount == 0 || e->Ecount != e->Ecomsub)) 3364 3361 { pushi = 1; 3365 3362 if (I16 && config.target_cpu >= TARGET_80386 && i >= 4) 3366 3363 { regsize = 4; 3367 3364 flag = CFopsize; 3368 3365 } 3369 3366 } 3370 3367 else if (i == REGSIZE) 3371 3368 break; 3372 3369 3373 3370 stackpush += sz; 3374 3371 ce = genadjesp(NULL,sz); 3375 pi = (targ_long *) &e->EV.Vdouble; 3376 ps = (targ_short *) pi; 3372 targ_uns *pi = (targ_uns *) &e->EV.Vdouble; 3373 targ_ushort *ps = (targ_ushort *) pi; 3374 targ_ullong *pl = (targ_ullong *)pi; 3377 3375 i /= regsize; 3378 3376 do 3379 3377 { code *cp; 3380 3378 3381 3379 if (i) /* be careful not to go negative */ 3382 3380 i--; 3383 value = (regsize == 4) ? pi[i] : ps[i]; 3381 targ_size_t value = (regsize == 4) ? pi[i] : ps[i]; 3382 if (regsize == 8) 3383 value = pl[i]; 3384 3384 if (pushi) 3385 3385 { 3386 3386 if (regsize == REGSIZE && reghasvalue(allregs,value,®)) 3387 3387 goto Preg; 3388 3388 ce = genc2(ce,(szb == 1) ? 0x6A : 0x68,0,value); // PUSH value 3389 3389 } 3390 3390 else 3391 3391 { 3392 3392 ce = regwithvalue(ce,allregs,value,®,0); 3393 3393 Preg: 3394 3394 ce = genpush(ce,reg); // PUSH reg 3395 3395 } 3396 3396 code_orflag(ce,flag); /* operand size */ 3397 3397 } while (i); 3398 3398 goto L2; 3399 3399 } 3400 3400 default: 3401 3401 break; 3402 3402 } 3403 3403 retregs = tybyte(tym) ? BYTEREGS : allregs; … … 3449 3449 c2 = genc1(CNIL,op,(modregrm(0,4,SP) << 8) | modregxrm(2,r,4),FLconst,sz/2); 3450 3450 pop87(); 3451 3451 } 3452 3452 pop87(); 3453 3453 c2 = gen2sib(c2,op,modregrm(0,r,4),modregrm(0,4,SP)); // FSTP [ESP] 3454 3454 } 3455 3455 else 3456 3456 { 3457 3457 retregs = IDXREGS; /* get an index reg */ 3458 3458 c1 = allocreg(&retregs,®,TYoffset); 3459 3459 c1 = genregs(c1,0x89,SP,reg); /* MOV reg,SP */ 3460 3460 pop87(); 3461 3461 c2 = gen2(CNIL,op,modregrm(0,r,regtorm[reg])); // FSTP [reg] 3462 3462 } 3463 3463 if (LARGEDATA) 3464 3464 c2->Iflags |= CFss; /* want to store into stack */ 3465 3465 genfwait(c2); // FWAIT 3466 3466 c = cat3(c,c1,c2); 3467 3467 goto ret; 3468 3468 } 3469 else if ( !I32&& (tym == TYdouble || tym == TYdouble_alias))3469 else if (I16 && (tym == TYdouble || tym == TYdouble_alias)) 3470 3470 retregs = mSTACK; 3471 3471 } 3472 3472 #if LONGLONG 3473 else if ( !I32&& sz == 8) // if long long3473 else if (I16 && sz == 8) // if long long 3474 3474 retregs = mSTACK; 3475 3475 #endif 3476 3476 c = cat(c,scodelem(e,&retregs,0,TRUE)); 3477 3477 if (retregs != mSTACK) /* if stackpush not already inc'd */ 3478 3478 stackpush += sz; 3479 3479 if (sz <= REGSIZE) 3480 3480 { 3481 3481 c = genpush(c,findreg(retregs)); // PUSH reg 3482 3482 genadjesp(c,REGSIZE); 3483 3483 } 3484 3484 else if (sz == REGSIZE * 2) 3485 3485 { c = genpush(c,findregmsw(retregs)); // PUSH msreg 3486 3486 genpush(c,findreglsw(retregs)); // PUSH lsreg 3487 3487 genadjesp(c,sz); 3488 3488 } 3489 3489 ret: 3490 3490 return cat(cp,c); 3491 3491 } 3492 3492 3493 3493 … … 3693 3693 } 3694 3694 ce = movregconst(ce,reg,msw,mswflags); 3695 3695 } 3696 3696 else if (sz == 8) 3697 3697 { 3698 3698 if (I32) 3699 3699 { targ_long *p = (targ_long *) &e->EV.Vdouble; 3700 3700 ce = movregconst(CNIL,findreglsw(forregs),p[0],0); 3701 3701 ce = movregconst(ce,findregmsw(forregs),p[1],0); 3702 3702 } 3703 3703 else 3704 3704 { targ_short *p = (targ_short *) &e->EV.Vdouble; 3705 3705 3706 3706 assert(reg == AX); 3707 3707 ce = movregconst(CNIL,AX,p[3],0); /* MOV AX,p[3] */ 3708 3708 ce = movregconst(ce,DX,p[0],0); 3709 3709 ce = movregconst(ce,CX,p[1],0); 3710 3710 ce = movregconst(ce,BX,p[2],0); 3711 3711 } 3712 3712 } 3713 else if (I64 && sz == 16) 3714 { 3715 ce = movregconst(CNIL,findreglsw(forregs),e->EV.Vcent.lsw,0); 3716 ce = movregconst(ce,findregmsw(forregs),e->EV.Vcent.msw,0); 3717 } 3713 3718 else 3714 3719 assert(0); 3715 3720 c = cat(c,ce); 3716 3721 } 3717 3722 else 3718 3723 { 3719 3724 // See if we can use register that parameter was passed in 3720 3725 if (regcon.params && e->EV.sp.Vsym->Sclass == SCfastpar && 3721 3726 regcon.params & mask[e->EV.sp.Vsym->Spreg] && 3722 3727 !(e->Eoper == OPvar && e->EV.sp.Voffset > 0) && // Must be at the base of that variable 3723 3728 sz <= REGSIZE) // make sure no 'paint' to a larger size happened 3724 3729 { 3725 3730 reg = e->EV.sp.Vsym->Spreg; 3726 3731 forregs = mask[reg]; 3727 3732 mfuncreg &= ~forregs; 3728 3733 regcon.used |= forregs; 3729 3734 return fixresult(e,forregs,pretregs); 3730 3735 } 3731 3736 3732 3737 c = allocreg(&forregs,®,tym); /* allocate registers */ trunk/src/backend/cod4.c
r596 r618 2461 2461 { assert(i < arraysize(clib)); 2462 2462 if (clib[i][0] == e->Eoper) 2463 2463 { c2 = callclib(e,clib[i][1],pretregs,0); 2464 2464 break; 2465 2465 } 2466 2466 } 2467 2467 return cat(c1,c2); 2468 2468 } 2469 2469 2470 2470 2471 2471 /*************************** 2472 2472 * Convert short to long. 2473 2473 * For OPs16_32, OPu16_32, OPptrlptr, OPu32_64, OPs32_64 2474 2474 */ 2475 2475 2476 2476 code *cdshtlng(elem *e,regm_t *pretregs) 2477 2477 { code *c,*ce,*c1,*c2,*c3,*c4; 2478 2478 unsigned reg; 2479 2479 unsigned char op; 2480 2480 regm_t retregs; 2481 int e1comsub; 2482 2483 e1comsub = e->E1->Ecount;2481 2482 //printf("cdshtlng(e = %p, *pretregs = %s)\n", e, regm_str(*pretregs)); 2483 int e1comsub = e->E1->Ecount; 2484 2484 if ((*pretregs & (ALLREGS | mBP)) == 0) // if don't need result in regs 2485 2485 c = codelem(e->E1,pretregs,FALSE); /* then conversion isn't necessary */ 2486 2486 2487 2487 else if ((op = e->Eoper) == OPptrlptr || 2488 2488 (I16 && op == OPu16_32) || 2489 2489 (I32 && op == OPu32_64) 2490 2490 ) 2491 2491 { 2492 2492 regm_t regm; 2493 2493 tym_t tym1; 2494 2494 2495 2495 retregs = *pretregs & mLSW; 2496 2496 assert(retregs); 2497 2497 tym1 = tybasic(e->E1->Ety); 2498 2498 c = codelem(e->E1,&retregs,FALSE); 2499 2499 2500 2500 regm = *pretregs & (mMSW & ALLREGS); 2501 2501 if (regm == 0) /* *pretregs could be mES */ 2502 2502 regm = mMSW & ALLREGS; 2503 2503 ce = allocreg(®m,®,TYint); 2504 2504 if (e1comsub) 2505 2505 ce = cat(ce,getregs(retregs)); 2506 2506 if (op == OPptrlptr) 2507 2507 { int segreg; 2508 2508 2509 2509 /* BUG: what about pointers to functions? */ 2510 2510 switch (tym1) 2511 2511 { 2512 2512 case TYnptr: segreg = SEG_DS; break; 2513 2513 case TYcptr: segreg = SEG_CS; break; 2514 2514 case TYsptr: segreg = SEG_SS; break; 2515 2515 default: assert(0); 2516 2516 } 2517 2517 ce = gen2(ce,0x8C,modregrm(3,segreg,reg)); /* MOV reg,segreg */ 2518 2518 } 2519 2519 else 2520 2520 ce = movregconst(ce,reg,0,0); /* 0 extend */ 2521 2521 2522 2522 c = cat3(c,ce,fixresult(e,retregs | regm,pretregs)); 2523 2523 } 2524 else if (!I16 && (op == OPs16_32 || op == OPu16_32)) 2524 else if (I64 && op == OPu32_64) 2525 { 2526 elem *e1 = e->E1; 2527 retregs = *pretregs; 2528 if (e1->Eoper == OPvar || (e1->Eoper == OPind && !e1->Ecount)) 2529 { code cs; 2530 2531 c1 = allocreg(&retregs,®,TYint); 2532 c2 = NULL; 2533 c3 = loadea(e1,&cs,0x8B,reg,0,retregs,retregs); // MOV Ereg,EA 2534 freenode(e1); 2535 } 2536 else 2537 { 2538 *pretregs &= ~mPSW; // flags are set by eval of e1 2539 c1 = codelem(e1,&retregs,FALSE); 2540 c2 = getregs(retregs); 2541 reg = findreg(retregs); 2542 c3 = genregs(NULL,0x89,reg,reg); // MOV Ereg,Ereg 2543 } 2544 c4 = fixresult(e,retregs,pretregs); 2545 c = cat4(c1,c2,c3,c4); 2546 } 2547 else if (!I16 && (op == OPs16_32 || op == OPu16_32) || 2548 I64 && op == OPs32_64) 2525 2549 { 2526 2550 elem *e11; 2527 2551 2528 2552 elem *e1 = e->E1; 2529 2553 2530 2554 if (e1->Eoper == OPu8_16 && !e1->Ecount && 2531 2555 ((e11 = e1->E1)->Eoper == OPvar || (e11->Eoper == OPind && !e11->Ecount)) 2532 2556 ) 2533 2557 { code cs; 2534 2558 2535 2559 retregs = *pretregs & BYTEREGS; 2536 2560 if (!retregs) 2537 2561 retregs = BYTEREGS; 2538 2562 c1 = allocreg(&retregs,®,TYint); 2539 2563 c2 = movregconst(NULL,reg,0,0); // XOR reg,reg 2540 2564 c3 = loadea(e11,&cs,0x8A,reg,0,retregs,retregs); // MOV regL,EA 2541 2565 freenode(e11); 2542 2566 freenode(e1); 2543 2567 } 2544 else if (e1->Eoper == OPvar ||2568 else if (e1->Eoper == OPvar && op != OPs32_64 || 2545 2569 (e1->Eoper == OPind && !e1->Ecount)) 2546 2570 { code cs; 2547 2571 unsigned opcode; 2548 2572 2549 2573 if (op == OPu16_32 && config.flags4 & CFG4speed) 2550 2574 goto L2; 2551 2575 retregs = *pretregs; 2552 2576 c1 = allocreg(&retregs,®,TYint); 2553 2577 opcode = (op == OPu16_32) ? 0x0FB7 : 0x0FBF; /* MOVZX/MOVSX reg,EA */ 2554 2578 c2 = loadea(e1,&cs,opcode,reg,0,0,retregs); 2555 2579 c3 = CNIL; 2556 2580 freenode(e1); 2557 2581 } 2558 2582 else 2559 2583 { 2560 2584 L2: 2561 2585 retregs = *pretregs; 2562 2586 *pretregs &= ~mPSW; /* flags are already set */ 2587 if (op == OPs32_64) 2588 retregs = mAX; 2563 2589 c1 = codelem(e1,&retregs,FALSE); 2564 2590 c2 = getregs(retregs); 2565 2591 if (op == OPu16_32 && c1) 2566 { code *cx; 2567 2568 cx = code_last(c1); 2592 { 2593 code *cx = code_last(c1); 2569 2594 if (cx->Iop == 0x81 && (cx->Irm & modregrm(3,7,0)) == modregrm(3,4,0)) 2570 2595 { 2571 2596 // Convert AND of a word to AND of a dword, zeroing upper word 2572 2597 retregs = mask[cx->Irm & 7]; 2573 2598 cx->Iflags &= ~CFopsize; 2574 2599 cx->IEV2.Vint &= 0xFFFF; 2575 2600 goto L1; 2576 2601 } 2577 2602 } 2578 2603 if (op == OPs16_32 && retregs == mAX) 2579 2604 c2 = gen1(c2,0x98); /* CWDE */ 2605 else if (op == OPs32_64 && retregs == mAX) 2606 { c2 = gen1(c2,0x98); /* CDQE */ 2607 code_orrex(c2, REX_W); 2608 } 2580 2609 else 2581 2610 { 2582 2611 reg = findreg(retregs); 2583 2612 if (config.flags4 & CFG4speed && op == OPu16_32) 2584 2613 { // AND reg,0xFFFF 2585 2614 c3 = genc2(NULL,0x81,modregrm(3,4,reg),0xFFFFu); 2586 2615 } 2587 2616 else 2588 2617 { 2589 2618 unsigned iop = (op == OPu16_32) ? 0x0FB7 : 0x0FBF; /* MOVZX/MOVSX reg,reg */ 2590 2619 c3 = genregs(CNIL,iop,reg,reg); 2591 2620 } 2592 2621 c2 = cat(c2,c3); 2593 2622 } 2594 2623 L1: 2595 2624 c3 = e1comsub ? getregs(retregs) : CNIL; 2596 2625 } 2597 2626 c4 = fixresult(e,retregs,pretregs); 2598 2627 c = cat4(c1,c2,c3,c4); 2599 2628 } … … 2806 2835 2807 2836 /* We "destroy" a reg by assigning it the result of a new e, even */ 2808 2837 /* though the values are the same. Weakness of our CSE strategy that */ 2809 2838 /* a register can only hold the contents of one elem at a time. */ 2810 2839 if (e->Ecount) 2811 2840 c = cat(c,getregs(retregs)); 2812 2841 else 2813 2842 useregs(retregs); 2814 2843 2815 2844 #ifdef DEBUG 2816 2845 if (!(!*pretregs || retregs)) 2817 2846 WROP(e->Eoper), 2818 2847 printf(" *pretregs = x%x, retregs = x%x, e = %p\n",*pretregs,retregs,e); 2819 2848 #endif 2820 2849 assert(!*pretregs || retregs); 2821 2850 return cat(c,fixresult(e,retregs,pretregs)); /* lsw only */ 2822 2851 } 2823 2852 2824 2853 /********************************************** 2825 2854 * Get top 32 bits of 64 bit value (I32) 2826 * or top 16 bits of 32 bit value (16 bit code). 2855 * or top 16 bits of 32 bit value (I16) 2856 * or top 64 bits of 128 bit value (I64). 2827 2857 * OPmsw 2828 2858 */ 2829 2859 2830 2860 code *cdmsw(elem *e,regm_t *pretregs) 2831 2861 { regm_t retregs; 2832 2862 code *c; 2833 2863 2834 2864 //printf("cdmsw(e->Ecount = %d)\n", e->Ecount); 2835 2865 assert(e->Eoper == OPmsw); 2836 2866 2837 2867 retregs = *pretregs ? ALLREGS : 0; 2838 2868 c = codelem(e->E1,&retregs,FALSE); 2839 retregs &= mMSW; // want LSW only2869 retregs &= mMSW; // want MSW only 2840 2870 2841 2871 // We "destroy" a reg by assigning it the result of a new e, even 2842 2872 // though the values are the same. Weakness of our CSE strategy that 2843 2873 // a register can only hold the contents of one elem at a time. 2844 2874 if (e->Ecount) 2845 2875 c = cat(c,getregs(retregs)); 2846 2876 else 2847 2877 useregs(retregs); 2848 2878 2849 2879 #ifdef DEBUG 2850 2880 if (!(!*pretregs || retregs)) 2851 2881 { WROP(e->Eoper); 2852 2882 printf(" *pretregs = x%x, retregs = x%x\n",*pretregs,retregs); 2853 2883 } 2854 2884 #endif 2855 2885 assert(!*pretregs || retregs); 2856 2886 return cat(c,fixresult(e,retregs,pretregs)); // msw only 2857 2887 } 2858 2888 2859 2889 trunk/src/backend/code.h
r596 r618 81 81 82 82 #define mR8 (1 << R8) 83 83 #define mR9 (1 << R9) 84 84 #define mR10 (1 << R10) 85 85 #define mR11 (1 << R11) 86 86 #define mR12 (1 << R12) 87 87 #define mR13 (1 << R13) 88 88 #define mR14 (1 << R14) 89 89 #define mR15 (1 << R15) 90 90 91 91 #define mXMM0 (1 << XMM0) 92 92 #define mXMM1 (1 << XMM1) 93 93 #define mXMM2 (1 << XMM2) 94 94 #define mXMM3 (1 << XMM3) 95 95 #define mXMM4 (1 << XMM4) 96 96 #define mXMM5 (1 << XMM5) 97 97 #define mXMM6 (1 << XMM6) 98 98 #define mXMM7 (1 << XMM7) 99 99 #define XMMREGS (mXMM0 |mXMM1 |mXMM2 |mXMM3 |mXMM4 |mXMM5 |mXMM6 |mXMM7) 100 100 101 #define mES (1 << ES) // 0x10000 102 #define mPSW (1 << PSW) // 0x20000 103 104 #define mSTACK (1 << STACK) // 0x40000 105 106 #define mST0 (1 << ST0) // 0x200000 107 #define mST01 (1 << ST01) // 0x400000 101 #define mES (1 << ES) // 0x1000000 102 #define mPSW (1 << PSW) // 0x2000000 103 104 #define mSTACK (1 << STACK) // 0x4000000 105 106 #define mST0 (1 << ST0) // 0x20000000 107 #define mST01 (1 << ST01) // 0x40000000 108 108 109 109 // Flags for getlvalue (must fit in regm_t) 110 110 #define RMload (1 << 30) 111 111 #define RMstore (1 << 31) 112 112 113 113 #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 114 114 // To support positional independent code, 115 115 // must be able to remove BX from available registers 116 116 extern regm_t ALLREGS; 117 117 #define ALLREGS_INIT (mAX|mBX|mCX|mDX|mSI|mDI) 118 118 #define ALLREGS_INIT_PIC (mAX|mCX|mDX|mSI|mDI) 119 119 extern regm_t BYTEREGS; 120 120 #define BYTEREGS_INIT (mAX|mBX|mCX|mDX) 121 121 #define BYTEREGS_INIT_PIC (mAX|mCX|mDX) 122 122 #else 123 123 #define ALLREGS (mAX|mBX|mCX|mDX|mSI|mDI) 124 124 #define ALLREGS_INIT ALLREGS 125 125 #undef BYTEREGS 126 126 #define BYTEREGS (mAX|mBX|mCX|mDX) 127 127 #endif … … 379 379 #define CFpsw 0x40 // we need the flags result after this instruction 380 380 #define CFopsize 0x80 // prefix with operand size 381 381 #define CFaddrsize 0x100 // prefix with address size 382 382 #define CFds 0x200 // need DS override (not with es, ss, or cs ) 383 383 #define CFcs 0x400 // need CS override 384 384 #define CFfs 0x800 // need FS override 385 385 #define CFgs (CFcs | CFfs) // need GS override 386 386 #define CFwait 0x1000 // If I32 it indicates when to output a WAIT 387 387 #define CFselfrel 0x2000 // if self-relative 388 388 #define CFunambig 0x4000 // indicates cannot be accessed by other addressing 389 389 // modes 390 390 #define CFtarg2 0x8000 // like CFtarg, but we can't optimize this away 391 391 #define CFvolatile 0x10000 // volatile reference, do not schedule 392 392 #define CFclassinit 0x20000 // class init code 393 393 #define CFoffset64 0x40000 // offset is 64 bits 394 394 #define CFpc32 0x80000 // I64: PC relative 32 bit fixup 395 395 396 396 #define CFPREFIX (CFSEG | CFopsize | CFaddrsize) 397 397 #define CFSEG (CFes | CFss | CFds | CFcs | CFfs | CFgs) 398 398 399 399 /* The op code can be 1 to 3 bytes 400 */ 400 401 unsigned Iop; 401 402 403 /* The _EA is the "effective address" for the instruction, and consists of the modregrm byte, 404 * the sib byte, and the REX prefix byte. The 16 bit code generator just used the modregrm, 405 * the 32 bit x86 added the sib, and the 64 bit one added the rex. 406 */ 402 407 union 403 408 { unsigned _Iea; 404 409 struct 405 410 { 406 411 unsigned char _Irm; // reg/mode 407 412 unsigned char _Isib; // SIB byte 408 413 unsigned char _Irex; // REX prefix 409 414 } _ea; 410 415 } _EA; 411 416 412 417 #define Iea _EA._Iea 413 418 #define Irm _EA._ea._Irm 414 419 #define Isib _EA._ea._Isib 415 420 #define Irex _EA._ea._Irex 421 422 423 /* IFL1 and IEV1 are the first operand, which usually winds up being the offset to the Effective 424 * Address. IFL1 is the tag saying which variant type is in IEV1. IFL2 and IEV2 is the second 425 * operand, usually for immediate instructions. 426 */ 416 427 417 428 unsigned char IFL1,IFL2; // FLavors of 1st, 2nd operands 418 429 union evc IEV1; // 1st operand, if any 419 430 #define IEVpointer1 IEV1._EP.Vpointer 420 431 #define IEVseg1 IEV1._EP.Vseg 421 432 #define IEVsym1 IEV1.sp.Vsym 422 433 #define IEVdsym1 IEV1.dsp.Vsym 423 434 #define IEVoffset1 IEV1.sp.Voffset 424 435 #define IEVlsym1 IEV1.lab.Vsym 425 436 #define IEVint1 IEV1.Vint 426 437 union evc IEV2; // 2nd operand, if any 427 438 #define IEVpointer2 IEV2._EP.Vpointer 428 439 #define IEVseg2 IEV2._EP.Vseg 429 440 #define IEVsym2 IEV2.sp.Vsym 430 441 #define IEVdsym2 IEV2.dsp.Vsym 431 442 #define IEVoffset2 IEV2.sp.Voffset 432 443 #define IEVlsym2 IEV2.lab.Vsym 433 444 #define IEVint2 IEV2.Vint 434 445 void print(); // pretty-printer 435 446 trunk/src/backend/debug.c
r487 r618 90 90 dbg_printf("mTYcs|"); 91 91 #endif 92 92 if (t & mTYconst) 93 93 dbg_printf("mTYconst|"); 94 94 if (t & mTYvolatile) 95 95 dbg_printf("mTYvolatile|"); 96 96 #if TARGET_MAC 97 97 if (t & mTYpasret) 98 98 dbg_printf("mTYpasret|"); 99 99 if (t & mTYmachdl) 100 100 dbg_printf("mTYmachdl|"); 101 101 if (t & mTYpasobj) 102 102 dbg_printf("mTYpasobj|"); 103 103 #endif 104 104 #if linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 105 105 if (t & mTYtransu) 106 106 dbg_printf("mTYtransu|"); 107 107 #endif 108 108 t = tybasic(t); 109 109 if (t >= TYMAX) 110 { dbg_printf("TY %lx\n", t);110 { dbg_printf("TY %lx\n",(long)t); 111 111 assert(0); 112 112 } 113 113 dbg_printf("TY%s ",tystring[tybasic(t)]); 114 114 } 115 115 116 116 void WRBC(unsigned bc) 117 117 { static char bcs[][7] = 118 118 {"unde ","goto ","true ","ret ","retexp", 119 119 "exit ","asm ","switch","ifthen","jmptab", 120 120 "try ","catch ","jump ", 121 121 "_try ","_filte","_final","_ret ","_excep", 122 122 "jcatch", 123 123 "jplace", 124 124 }; 125 125 126 126 assert(sizeof(bcs) / sizeof(bcs[0]) == BCMAX); 127 127 assert(bc < BCMAX); 128 128 dbg_printf("BC%s",bcs[bc]); 129 129 } 130 130 … … 170 170 } 171 171 else if (e->Eoper == OPcomma && !nest) 172 172 { WReqn(e->E1); 173 173 dbg_printf(";\n\t"); 174 174 WReqn(e->E2); 175 175 } 176 176 else if (OTbinary(e->Eoper)) 177 177 { 178 178 if (OTbinary(e->E1->Eoper)) 179 179 { nest++; 180 180 ferr("("); 181 181 WReqn(e->E1); 182 182 ferr(")"); 183 183 nest--; 184 184 } 185 185 else 186 186 WReqn(e->E1); 187 187 ferr(" "); 188 188 WROP(e->Eoper); 189 189 if (e->Eoper == OPstreq) 190 dbg_printf("%ld", e->Enumbytes);190 dbg_printf("%ld",(long)e->Enumbytes); 191 191 ferr(" "); 192 192 if (OTbinary(e->E2->Eoper)) 193 193 { nest++; 194 194 ferr("("); 195 195 WReqn(e->E2); 196 196 ferr(")"); 197 197 nest--; 198 198 } 199 199 else 200 200 WReqn(e->E2); 201 201 } 202 202 else 203 203 { 204 204 switch (e->Eoper) 205 205 { case OPconst: 206 206 switch (tybasic(e->Ety)) 207 207 { 208 208 case TYfloat: 209 209 dbg_printf("%g <float> ",e->EV.Vfloat); 210 210 break; 211 211 case TYdouble: 212 212 dbg_printf("%g ",e->EV.Vdouble); 213 213 break; 214 214 default: 215 215 dbg_printf("%lld ",el_tolong(e)); 216 216 break; 217 217 } 218 218 break; 219 219 case OPrelconst: 220 220 ferr("#"); 221 221 /* FALL-THROUGH */ 222 222 case OPvar: 223 223 dbg_printf("%s",e->EV.sp.Vsym->Sident); 224 224 if (e->EV.sp.Vsym->Ssymnum != -1) 225 225 dbg_printf("(%d)",e->EV.sp.Vsym->Ssymnum); 226 226 if (e->Eoffset != 0) 227 dbg_printf(".%ld", e->Eoffset);227 dbg_printf(".%ld",(long)e->Eoffset); 228 228 break; 229 229 case OPasm: 230 230 #if TARGET_MAC 231 231 if (e->Eflags & EFsmasm) 232 232 { 233 233 if (e->EV.mac.Vasmdat[1]) 234 234 dbg_printf("\"%c%c\"",e->EV.mac.Vasmdat[0],e->EV.mac.Vasmdat[1]); 235 235 else 236 236 dbg_printf("\"%c\"",e->EV.mac.Vasmdat[0]); 237 237 break; 238 238 }; 239 239 #endif 240 240 case OPstring: 241 241 dbg_printf("\"%s\"",e->EV.ss.Vstring); 242 242 if (e->EV.ss.Voffset) 243 dbg_printf("+%ld", e->EV.ss.Voffset);243 dbg_printf("+%ld",(long)e->EV.ss.Voffset); 244 244 break; 245 245 case OPmark: 246 246 case OPgot: 247 247 case OPframeptr: 248 248 WROP(e->Eoper); 249 249 break; 250 250 case OPstrthis: 251 251 break; 252 252 default: 253 253 WROP(e->Eoper); 254 254 assert(0); 255 255 } 256 256 } 257 257 } 258 258 259 259 void WRblocklist(list_t bl) 260 260 { 261 261 for (; bl; bl = list_next(bl)) 262 262 { register block *b = list_block(bl); 263 263 trunk/src/backend/dt.c
r569 r618 185 185 *pdtend = dt; 186 186 pdtend = &dt->DTnext; 187 187 return pdtend; 188 188 } 189 189 190 190 /********************** 191 191 * Construct a DTibytes record, and return it. 192 192 */ 193 193 194 194 dt_t ** dtdword(dt_t **pdtend, int value) 195 195 { dt_t *dt; 196 196 197 197 while (*pdtend) 198 198 pdtend = &((*pdtend)->DTnext); 199 199 dt = dt_calloc(DT_ibytes); 200 200 dt->DTn = 4; 201 201 202 202 union { char* cp; int* lp; } u; 203 203 u.cp = dt->DTdata; 204 204 *u.lp = value; 205 206 *pdtend = dt; 207 pdtend = &dt->DTnext; 208 return pdtend; 209 } 210 211 dt_t ** dtsize_t(dt_t **pdtend, targ_size_t value) 212 { dt_t *dt; 213 214 while (*pdtend) 215 pdtend = &((*pdtend)->DTnext); 216 dt = dt_calloc(DT_ibytes); 217 dt->DTn = NPTRSIZE; 218 219 union { char* cp; int* lp; } u; 220 u.cp = dt->DTdata; 221 *u.lp = value; 222 if (NPTRSIZE == 8) 223 u.lp[1] = value >> 32; 205 224 206 225 *pdtend = dt; 207 226 pdtend = &dt->DTnext; 208 227 return pdtend; 209 228 } 210 229 211 230 /********************** 212 231 * Concatenate two dt_t's. 213 232 */ 214 233 215 234 dt_t ** dtcat(dt_t **pdtend,dt_t *dt) 216 235 { 217 236 while (*pdtend) 218 237 pdtend = &((*pdtend)->DTnext); 219 238 *pdtend = dt; 220 239 pdtend = &dt->DTnext; 221 240 return pdtend; 222 241 } 223 242 224 243 /********************** trunk/src/backend/dt.h
r569 r618 30 30 * the size 31 31 * DTcommon # of 0 bytes (in a common block) 32 32 * a 33 33 * DTxoff offset from symbol 34 34 * w a 35 35 * w = symbol number (pointer for CPP) 36 36 * a = offset 37 37 * DTcoff offset into code segment 38 38 * DTend mark end of list 39 39 */ 40 40 41 41 struct dt_t 42 42 { dt_t *DTnext; // next in list 43 43 char dt; // type (DTxxxx) 44 44 unsigned char Dty; // pointer type 45 45 union 46 46 { 47 47 struct // DTibytes 48 48 { char DTn_; // number of bytes 49 49 #define DTn _DU._DI.DTn_ 50 char DTdata_[ 7]; // data50 char DTdata_[8]; // data 51 51 #define DTdata _DU._DI.DTdata_ 52 52 }_DI; 53 53 char DTonebyte_; // DT1byte 54 54 #define DTonebyte _DU.DTonebyte_ 55 55 targ_size_t DTazeros_; // DTazeros,DTcommon,DTsymsize 56 56 #define DTazeros _DU.DTazeros_ 57 57 struct // DTabytes 58 58 { 59 59 char *DTpbytes_; // pointer to the bytes 60 60 #define DTpbytes _DU._DN.DTpbytes_ 61 61 unsigned DTnbytes_; // # of bytes 62 62 #define DTnbytes _DU._DN.DTnbytes_ 63 63 #if TX86 64 64 int DTseg_; // segment it went into 65 65 #define DTseg _DU._DN.DTseg_ 66 66 #endif 67 67 targ_size_t DTabytes_; // offset of abytes for DTabytes 68 68 #define DTabytes _DU._DN.DTabytes_ 69 69 }_DN; 70 70 struct // DTxoff … … 85 85 DT_1byte, 86 86 DT_nbytes, 87 87 DT_common, 88 88 DT_symsize, 89 89 DT_coff, 90 90 DT_ibytes, // 8 91 91 }; 92 92 93 93 #if TX86 94 94 dt_t *dt_calloc(char dtx); 95 95 void dt_free(dt_t *); 96 96 void dt_term(void); 97 97 #elif TARGET_MAC 98 98 dt_t *dt_calloc(void); 99 99 void dt_free(dt_t *); 100 100 #endif 101 101 102 102 dt_t **dtnbytes(dt_t **,targ_size_t,const char *); 103 103 dt_t **dtabytes(dt_t **pdtend,tym_t ty, targ_size_t offset, targ_size_t size, const char *ptr); 104 104 dt_t **dtdword(dt_t **, int value); 105 dt_t **dtsize_t(dt_t **, targ_size_t value); 105 106 dt_t **dtnzeros(dt_t **pdtend,targ_size_t size); 106 107 dt_t **dtxoff(dt_t **pdtend,symbol *s,targ_size_t offset,tym_t ty); 107 108 dt_t **dtselfoff(dt_t **pdtend,targ_size_t offset,tym_t ty); 108 109 dt_t **dtcoff(dt_t **pdtend,targ_size_t offset); 109 110 dt_t ** dtcat(dt_t **pdtend,dt_t *dt); 110 111 void dt_optimize(dt_t *dt); 111 112 void dtsymsize(symbol *); 112 113 void init_common(symbol *); 113 114 unsigned dt_size(dt_t *dtstart); 114 115 115 116 #endif /* DT_H */ 116 117 trunk/src/backend/el.c
r581 r618 2944 2944 case TYcldouble: 2945 2945 case TYcdouble: 2946 2946 case TYcfloat: 2947 2947 #if !DDRT 2948 2948 result = (targ_llong)el_toldouble(e); 2949 2949 #else 2950 2950 result = Xxtoi(el_toldouble(e)); 2951 2951 #endif 2952 2952 break; 2953 2953 2954 2954 #if SCPP 2955 2955 case TYmemptr: 2956 2956 ty = tybasic(tym_conv(e->ET)); 2957 2957 goto L1; 2958 2958 #endif 2959 2959 default: 2960 2960 #if SCPP 2961 2961 // Can happen as result of syntax errors 2962 2962 assert(errcnt); 2963 2963 #else 2964 #ifdef DEBUG 2965 elem_print(e); 2966 *(char*)0=0; 2967 #endif 2964 2968 assert(0); 2965 2969 #endif 2966 2970 } 2967 2971 return result; 2968 2972 } 2969 2973 2970 2974 /*********************************** 2971 2975 * Determine if constant e is all ones or all zeros. 2972 2976 * Input: 2973 2977 * bit 0: all zeros 2974 2978 * 1: 1 2975 2979 * -1: all ones 2976 2980 */ 2977 2981 2978 2982 int el_allbits(elem *e,int bit) 2979 2983 { targ_llong value; 2980 2984 2981 2985 elem_debug(e); 2982 2986 assert(e->Eoper == OPconst); 2983 2987 value = e->EV.Vullong; … … 3272 3276 case TYulong: 3273 3277 case TYdchar: 3274 3278 case TYfptr: 3275 3279 #if TX86 3276 3280 case TYvptr: 3277 3281 case TYhptr: 3278 3282 #endif 3279 3283 L1: 3280 3284 dbg_printf("%dL ",e->EV.Vlong); 3281 3285 break; 3282 3286 3283 3287 case TYllong: 3284 3288 L2: 3285 3289 dbg_printf("%lldLL ",e->EV.Vllong); 3286 3290 break; 3287 3291 3288 3292 case TYullong: 3289 3293 dbg_printf("%lluLL ",e->EV.Vullong); 3290 3294 break; 3291 3295 3296 case TYcent: 3297 case TYucent: 3298 dbg_printf("%lluLL+%lluLL ", e->EV.Vcent.msw, e->EV.Vcent.lsw); 3299 break; 3300 3292 3301 case TYfloat: 3293 3302 dbg_printf("%gf ",(double)e->EV.Vfloat); 3294 3303 break; 3295 3304 case TYdouble: 3296 3305 case TYdouble_alias: 3297 3306 dbg_printf("%g ",(double)e->EV.Vdouble); 3298 3307 break; 3299 3308 case TYldouble: 3300 3309 #if TARGET_MAC 3301 3310 #if (TARGET_POWERPC) 3302 3311 if (config.flags & CFGldblisdbl) 3303 3312 dbg_printf("%gL ",e->EV.Vdouble); 3304 3313 else 3305 3314 #endif 3306 3315 #if !DDRT 3307 3316 dbg_printf("%LgL ",e->EV.Vldouble); 3308 3317 #else /* DDRT */ 3309 3318 { 3310 3319 static char buffer[75]; 3311 3320 __g_fmt(buffer, (DD)e->EV.Vldouble); trunk/src/backend/evalu8.c
r569 r618 565 565 { elem *e1,*e2; 566 566 tym_t tym,tym2,uns; 567 567 unsigned op; 568 568 #if TARGET_MAC 569 569 targ_short i1,i2; 570 570 targ_char c1,c2; 571 571 #else 572 572 targ_int i1,i2; 573 573 #endif 574 574 int i; 575 575 targ_llong l1,l2; 576 576 targ_ldouble d1,d2; 577 577 elem esave; 578 578 579 579 // assert((_status87() & 0x3800) == 0); 580 580 assert(e && EOP(e)); 581 581 op = e->Eoper; 582 582 elem_debug(e); 583 583 e1 = e->E1; 584 584 585 //printf("evalu8(): "); //elem_print(e);585 //printf("evalu8(): "); elem_print(e); 586 586 elem_debug(e1); 587 587 if (e1->Eoper == OPconst) 588 588 { 589 589 tym2 = 0; 590 590 e2 = NULL; 591 591 if (EBIN(e)) 592 592 { e2 = e->E2; 593 593 elem_debug(e2); 594 594 if (e2->Eoper == OPconst) 595 595 { 596 596 T68000(c2 =) i2 = l2 = el_tolong(e2); 597 597 d2 = el_toldouble(e2); 598 598 } 599 599 else 600 600 return e; 601 601 tym2 = tybasic(typemask(e2)); 602 602 } 603 603 T68000(c1 =) i1 = l1 = el_tolong(e1); 604 604 d1 = el_toldouble(e1); 605 605 tym = tybasic(typemask(e1)); /* type of op is type of left child */ … … 1183 1183 case TYcldouble: 1184 1184 switch (tym2) 1185 1185 { 1186 1186 case TYldouble: 1187 1187 e->EV.Vcldouble.re = e1->EV.Vcldouble.re * d2; 1188 1188 e->EV.Vcldouble.im = e1->EV.Vcldouble.im * d2; 1189 1189 break; 1190 1190 case TYildouble: 1191 1191 e->EV.Vcldouble.re = -e1->EV.Vcldouble.im * d2; 1192 1192 e->EV.Vcldouble.im = e1->EV.Vcldouble.re * d2; 1193 1193 break; 1194 1194 case TYcldouble: 1195 1195 e->EV.Vcldouble = Complex_ld::mul(e1->EV.Vcldouble, e2->EV.Vcldouble); 1196 1196 break; 1197 1197 default: 1198 1198 assert(0); 1199 1199 } 1200 1200 break; 1201 1201 default: 1202 1202 #ifdef DEBUG 1203 dbg_printf("tym = x% lx\n",tym);1203 dbg_printf("tym = x%x\n",tym); 1204 1204 elem_print(e); 1205 1205 #endif 1206 1206 assert(0); 1207 1207 } 1208 1208 } 1209 1209 break; 1210 1210 case OPdiv: 1211 1211 if (!boolres(e2)) // divide by 0 1212 1212 { 1213 1213 #if SCPP 1214 1214 if (!tyfloating(tym)) 1215 1215 #endif 1216 1216 goto div0; 1217 1217 } 1218 1218 if (uns) 1219 1219 e->EV.Vullong = ((targ_ullong) l1) / ((targ_ullong) l2); 1220 1220 else 1221 1221 { switch (tym) 1222 1222 { 1223 1223 case TYfloat: … … 2030 2030 #endif 2031 2031 e->EV.Vint = l1; 2032 2032 break; 2033 2033 case OP64_32: 2034 2034 e->EV.Vlong = l1; 2035 2035 break; 2036 2036 case OPlngllng: 2037 2037 e->EV.Vllong = (targ_long) l1; 2038 2038 break; 2039 2039 case OPulngllng: 2040 2040 e->EV.Vllong = (targ_ulong) l1; 2041 2041 break; 2042 2042 case OPmsw: 2043 2043 switch (tysize(tym)) 2044 2044 { 2045 2045 case 4: 2046 2046 e->EV.Vllong = (l1 >> 16) & 0xFFFF; 2047 2047 break; 2048 2048 case 8: 2049 2049 e->EV.Vllong = (l1 >> 32) & 0xFFFFFFFF; 2050 break; 2051 case 16: 2052 e->EV.Vllong = e1->EV.Vcent.msw; 2050 2053 break; 2051 2054 default: 2052 2055 assert(0); 2053 2056 } 2054 2057 break; 2055 2058 case OPb_8: 2056 2059 e->EV.Vlong = i1 & 1; 2057 2060 break; 2058 2061 case OPbswap: 2059 2062 e->EV.Vint = ((i1 >> 24) & 0x000000FF) | 2060 2063 ((i1 >> 8) & 0x0000FF00) | 2061 2064 ((i1 << 8) & 0x00FF0000) | 2062 2065 ((i1 << 24) & 0xFF000000); 2063 2066 break; 2064 2067 case OPind: 2065 2068 #if 0 && MARS 2066 2069 /* The problem with this is that although the only reaching definition 2067 2070 * of the variable is null, it still may never get executed, as in: 2068 2071 * int* p = null; if (p) *p = 3; 2069 2072 * and the error will be spurious. trunk/src/backend/ptrntab.c
r605 r618 1 1 // Copyright (C) 1985-1998 by Symantec 2 // Copyright (C) 2000-20 09by Digital Mars2 // Copyright (C) 2000-2010 by Digital Mars 3 3 // All Rights Reserved 4 4 // http://www.digitalmars.com 5 5 /* 6 6 * This source file is made available for personal use 7 7 * only. The license is in /dmd/src/dmd/backendlicense.txt 8 8 * or /dm/src/dmd/backendlicense.txt 9 9 * For any other uses, please contact Digital Mars. 10 10 */ 11 11 12 12 #if !DEMO && !SPP 13 13 14 14 #include <stdio.h> 15 15 #include <stdlib.h> 16 16 #include <string.h> 17 17 #include <time.h> 18 18 19 19 #include "cc.h" 20 20 #include "code.h" 21 21 #include "iasm.h" 22 22 … … 35 35 PTRNTAB0 aptb0AAA[] = /* AAA */ { 36 36 { 0x37, _modax }, 37 37 }; 38 38 39 39 PTRNTAB0 aptb0AAD[] = /* AAD */ { 40 40 { 0xd50a, _modax } 41 41 }; 42 42 43 43 PTRNTAB0 aptb0AAM[] = /* AAM */ { 44 44 { 0xd40a, _modax } 45 45 }; 46 46 PTRNTAB0 aptb0AAS[] = /* AAS */ { 47 47 { 0x3f, _modax } 48 48 }; 49 49 PTRNTAB0 aptb0CBW[] = /* CBW */ { 50 50 { 0x98, _16_bit | _modax } 51 51 }; 52 52 PTRNTAB0 aptb0CWDE[] = /* CWDE */ { 53 53 { 0x98, _32_bit | _I386 | _modax } 54 54 }; 55 PTRNTAB0 aptb0CDQE[] = /* CDQE */ { 56 { 0x98, _64_bit | _modax } 57 }; 55 58 PTRNTAB0 aptb0CLC[] = /* CLC */ { 56 59 { 0xf8, 0 } 57 60 }; 58 61 59 62 PTRNTAB0 aptb0CLD[] = /* CLD */ { 60 63 { 0xfc, 0 } 61 64 }; 62 65 PTRNTAB0 aptb0CLI[] = /* CLI */ { 63 66 { 0xfa, 0 } 64 67 }; 65 68 66 69 PTRNTAB0 aptb0CLTS[] = /* CLTS */ { 67 70 { 0x0f06, 0 } 68 71 }; 69 72 70 73 PTRNTAB0 aptb0CMC[] = /* CMC */ { 71 74 { 0xf5, 0 } 72 75 }; 73 76 74 77 PTRNTAB0 aptb0CMPSB[] = /* CMPSB */ { 75 78 { 0xa6, _modsidi } 76 79 }; 77 80 78 81 PTRNTAB0 aptb0CMPSW[] = /* CMPSW */ { 79 82 { 0xa7, _16_bit | _modsidi } 80 83 }; 81 84 82 85 #if 0 83 86 PTRNTAB0 aptb0CMPSD[] = /* CMPSD */ { 84 87 { 0xa7, _32_bit | _I386 | _modsidi } 85 88 }; 86 89 #endif 87 90 88 91 PTRNTAB0 aptb0CWD[] = /* CWD */ { 89 92 { 0x99, _16_bit | _modaxdx } 90 93 }; 91 94 92 95 PTRNTAB0 aptb0CDQ[] = /* CDQ */ { 93 96 { 0x99, _32_bit | _I386 | _modaxdx } 97 }; 98 99 PTRNTAB0 aptb0CQO[] = /* CQO */ { 100 { 0x99, _64_bit | _modaxdx } 94 101 }; 95 102 96 103 PTRNTAB0 aptb0DAA[] = /* DAA */ { 97 104 { 0x27, _modax } 98 105 }; 99 106 100 107 PTRNTAB0 aptb0DAS[] = /* DAS */ { 101 108 { 0x2f, _modax } 102 109 }; 103 110 104 111 PTRNTAB0 aptb0HLT[] = /* HLT */ { 105 112 { 0xf4, 0 } 106 113 }; 107 114 108 115 PTRNTAB0 aptb0INSB[] = /* INSB */ { 109 116 { 0x6c, _I386 | _modsi } 110 117 }; 111 118 112 119 PTRNTAB0 aptb0INSW[] = /* INSW */ { 113 120 { 0x6d, _16_bit | _I386 | _modsi } … … 3141 3148 X("addss", 2, (P) aptb2ADDSS ) \ 3142 3149 X("addsubpd", 2, (P) aptb2ADDSUBPD ) \ 3143 3150 X("addsubps", 2, (P) aptb2ADDSUBPS ) \ 3144 3151 X("and", 2, (P) aptb2AND ) \ 3145 3152 X("andnpd", 2, (P) aptb2ANDNPD ) \ 3146 3153 X("andnps", 2, (P) aptb2ANDNPS ) \ 3147 3154 X("andpd", 2, (P) aptb2ANDPD ) \ 3148 3155 X("andps", 2, (P) aptb2ANDPS ) \ 3149 3156 X("arpl", 2, (P) aptb2ARPL ) \ 3150 3157 X("bound", 2, (P) aptb2BOUND ) \ 3151 3158 X("bsf", 2, (P) aptb2BSF ) \ 3152 3159 X("bsr", 2, (P) aptb2BSR ) \ 3153 3160 X("bswap", 1, (P) aptb1BSWAP ) \ 3154 3161 X("bt", 2, (P) aptb2BT ) \ 3155 3162 X("btc", 2, (P) aptb2BTC ) \ 3156 3163 X("btr", 2, (P) aptb2BTR ) \ 3157 3164 X("bts", 2, (P) aptb2BTS ) \ 3158 3165 X("call", ITjump | 1, (P) aptb1CALL ) \ 3159 3166 X("cbw", 0, aptb0CBW ) \ 3160 3167 X("cdq", 0, aptb0CDQ ) \ 3168 X("cdqe", 0, aptb0CDQE ) \ 3161 3169 X("clc", 0, aptb0CLC ) \ 3162 3170 X("cld", 0, aptb0CLD ) \ 3163 3171 X("clflush", 1, (P) aptb1CLFLUSH ) \ 3164 3172 X("cli", 0, aptb0CLI ) \ 3165 3173 X("clts", 0, aptb0CLTS ) \ 3166 3174 X("cmc", 0, aptb0CMC ) \ 3167 3175 X("cmova", 2, (P) aptb2CMOVNBE ) \ 3168 3176 X("cmovae", 2, (P) aptb2CMOVNB ) \ 3169 3177 X("cmovb", 2, (P) aptb2CMOVB ) \ 3170 3178 X("cmovbe", 2, (P) aptb2CMOVBE ) \ 3171 3179 X("cmovc", 2, (P) aptb2CMOVB ) \ 3172 3180 X("cmove", 2, (P) aptb2CMOVZ ) \ 3173 3181 X("cmovg", 2, (P) aptb2CMOVNLE ) \ 3174 3182 X("cmovge", 2, (P) aptb2CMOVNL ) \ 3175 3183 X("cmovl", 2, (P) aptb2CMOVL ) \ 3176 3184 X("cmovle", 2, (P) aptb2CMOVLE ) \ 3177 3185 X("cmovna", 2, (P) aptb2CMOVBE ) \ 3178 3186 X("cmovnae", 2, (P) aptb2CMOVB ) \ 3179 3187 X("cmovnb", 2, (P) aptb2CMOVNB ) \ 3180 3188 X("cmovnbe", 2, (P) aptb2CMOVNBE ) \ … … 3191 3199 X("cmovo", 2, (P) aptb2CMOVO ) \ 3192 3200 X("cmovp", 2, (P) aptb2CMOVP ) \ 3193 3201 X("cmovpe", 2, (P) aptb2CMOVP ) \ 3194 3202 X("cmovpo", 2, (P) aptb2CMOVNP ) \ 3195 3203 X("cmovs", 2, (P) aptb2CMOVS ) \ 3196 3204 X("cmovz", 2, (P) aptb2CMOVZ ) \ 3197 3205 X("cmp", 2, (P) aptb2CMP ) \ 3198 3206 X("cmppd", 3, (P) aptb3CMPPD ) \ 3199 3207 X("cmpps", 3, (P) aptb3CMPPS ) \ 3200 3208 X("cmps", 2, (P) aptb2CMPS ) \ 3201 3209 X("cmpsb", 0, aptb0CMPSB ) \ 3202 3210 /*X("cmpsd", 0, aptb0CMPSD )*/ \ 3203 3211 X("cmpsd", ITopt|3, (P) aptb3CMPSD ) \ 3204 3212 X("cmpss", 3, (P) aptb3CMPSS ) \ 3205 3213 X("cmpsw", 0, aptb0CMPSW ) \ 3206 3214 X("cmpxch8b", 1, (P) aptb1CMPXCH8B ) \ 3207 3215 X("cmpxchg", 2, (P) aptb2CMPXCHG ) \ 3208 3216 X("comisd", 2, (P) aptb2COMISD ) \ 3209 3217 X("comiss", 2, (P) aptb2COMISS ) \ 3210 3218 X("cpuid", 0, aptb0CPUID ) \ 3219 X("cqo", 0, aptb0CQO ) \ 3211 3220 X("cvtdq2pd", 2, (P) aptb2CVTDQ2PD ) \ 3212 3221 X("cvtdq2ps", 2, (P) aptb2CVTDQ2PS ) \ 3213 3222 X("cvtpd2dq", 2, (P) aptb2CVTPD2DQ ) \ 3214 3223 X("cvtpd2pi", 2, (P) aptb2CVTPD2PI ) \ 3215 3224 X("cvtpd2ps", 2, (P) aptb2CVTPD2PS ) \ 3216 3225 X("cvtpi2pd", 2, (P) aptb2CVTPI2PD ) \ 3217 3226 X("cvtpi2ps", 2, (P) aptb2CVTPI2PS ) \ 3218 3227 X("cvtps2dq", 2, (P) aptb2CVTPS2DQ ) \ 3219 3228 X("cvtps2pd", 2, (P) aptb2CVTPS2PD ) \ 3220 3229 X("cvtps2pi", 2, (P) aptb2CVTPS2PI ) \ 3221 3230 X("cvtsd2si", 2, (P) aptb2CVTSD2SI ) \ 3222 3231 X("cvtsd2ss", 2, (P) aptb2CVTSD2SS ) \ 3223 3232 X("cvtsi2sd", 2, (P) aptb2CVTSI2SD ) \ 3224 3233 X("cvtsi2ss", 2, (P) aptb2CVTSI2SS ) \ 3225 3234 X("cvtss2sd", 2, (P) aptb2CVTSS2SD ) \ 3226 3235 X("cvtss2si", 2, (P) aptb2CVTSS2SI ) \ 3227 3236 X("cvttpd2dq", 2, (P) aptb2CVTTPD2DQ ) \ 3228 3237 X("cvttpd2pi", 2, (P) aptb2CVTTPD2PI ) \ 3229 3238 X("cvttps2dq", 2, (P) aptb2CVTTPS2DQ ) \ 3230 3239 X("cvttps2pi", 2, (P) aptb2CVTTPS2PI ) \ trunk/src/backend/ty.h
r605 r618 90 90 TYident = 0x30, // type-argument 91 91 TYtemplate = 0x31, // unexpanded class template 92 92 TYvtshape = 0x32, // virtual function table 93 93 TYptr = 0x33, // generic pointer type 94 94 TYf16func = 0x34, // _far16 _pascal function 95 95 TYnsysfunc = 0x35, // near __syscall func 96 96 TYfsysfunc = 0x36, // far __syscall func 97 97 TYmfunc = 0x37, // NT C++ member func 98 98 TYjfunc = 0x38, // LINKd D function 99 99 TYhfunc = 0x39, // C function with hidden parameter 100 100 TYnref = 0x3A, // near reference 101 101 TYfref = 0x3B, // far reference 102 102 103 103 TYcent = 0x3C, // 128 bit signed integer 104 104 TYucent = 0x3D, // 128 bit unsigned integer 105 105 106 106 TYMAX = 0x3E, 107 107 108 108 #if MARS 109 109 #define TYaarray TYnptr 110 #define TYdelegate TYllong111 #define TYdarray TYullong110 #define TYdelegate (I64 ? TYcent : TYllong) 111 #define TYdarray (I64 ? TYucent : TYullong) 112 112 #endif 113 113 }; 114 114 115 115 // These change depending on memory model 116 116 extern int TYptrdiff, TYsize, TYsize_t; 117 117 118 118 /* Linkage type */ 119 119 #define mTYnear 0x100 120 120 #define mTYfar 0x200 121 121 #define mTYcs 0x400 // in code segment 122 122 #define mTYthread 0x800 123 123 #define mTYLINK 0xF00 // all linkage bits 124 124 125 125 #define mTYloadds 0x1000 126 126 #define mTYexport 0x2000 127 127 #define mTYweak 0x0000 128 128 #define mTYimport 0x4000 129 129 #define mTYnaked 0x8000 130 130 #define mTYMOD 0xF000 // all modifier bits 131 131 … … 181 181 182 182 /* Groupings of types */ 183 183 184 184 #define tyintegral(ty) (tytab[(ty) & 0xFF] & TYFLintegral) 185 185 186 186 #define tyarithmetic(ty) (tytab[(ty) & 0xFF] & (TYFLintegral | TYFLreal | TYFLimaginary | TYFLcomplex)) 187 187 188 188 #define tyaggregate(ty) (tytab[(ty) & 0xFF] & TYFLaggregate) 189 189 190 190 #define tyscalar(ty) (tytab[(ty) & 0xFF] & (TYFLintegral | TYFLreal | TYFLimaginary | TYFLcomplex | TYFLptr | TYFLmptr | TYFLnullptr)) 191 191 192 192 #define tyfloating(ty) (tytab[(ty) & 0xFF] & (TYFLreal | TYFLimaginary | TYFLcomplex)) 193 193 194 194 #define tyimaginary(ty) (tytab[(ty) & 0xFF] & TYFLimaginary) 195 195 196 196 #define tycomplex(ty) (tytab[(ty) & 0xFF] & TYFLcomplex) 197 197 198 198 #define tyreal(ty) (tytab[(ty) & 0xFF] & TYFLreal) 199 199 200 200 // Fits into 64 bit register 201 #define ty64reg(ty) (tytab[(ty) & 0xFF] & (TYFLintegral | TYFLptr) )201 #define ty64reg(ty) (tytab[(ty) & 0xFF] & (TYFLintegral | TYFLptr) && tysize(ty) <= NPTRSIZE) 202 202 203 203 #ifndef tyshort 204 204 /* Types that are chars or shorts */ 205 205 #define tyshort(ty) (tytab[(ty) & 0xFF] & TYFLshort) 206 206 #endif 207 207 208 208 /* Detect TYlong or TYulong */ 209 209 #ifndef tylong 210 210 #define tylong(ty) (tybasic(ty) == TYlong || tybasic(ty) == TYulong) 211 211 #endif 212 212 213 213 /* Use to detect a pointer type */ 214 214 #ifndef typtr 215 215 #define typtr(ty) (tytab[(ty) & 0xFF] & TYFLptr) 216 216 #endif 217 217 218 218 /* Use to detect a reference type */ 219 219 #ifndef tyref 220 220 #define tyref(ty) (tytab[(ty) & 0xFF] & TYFLref) 221 221 #endif trunk/src/backend/var.c
r558 r618 222 222 unsigned 223 223 maxblks = 0, /* array max for all block stuff */ 224 224 /* dfoblks <= numblks <= maxblks */ 225 225 numcse, /* number of common subexpressions */ 226 226 deftop = 0, /* # of entries in defnod[] */ 227 227 exptop = 0; /* top of expnod[] */ 228 228 229 229 vec_t defkill = NULL, /* vector of AEs killed by an ambiguous */ 230 230 /* definition */ 231 231 starkill = NULL, /* vector of AEs killed by a definition */ 232 232 /* of something that somebody could be */ 233 233 /* pointing to */ 234 234 vptrkill = NULL; /* vector of AEs killed by an access */ 235 235 /* to a vptr */ 236 236 237 237 /* From debug.c */ 238 238 #if DEBUG 239 239 const char *regstring[32] = {"AX","CX","DX","BX","SP","BP","SI","DI", 240 240 "R8","R9","R10","R11","R12","R13","R14","R15", 241 241 "XMM0","XMM1","XMM2","XMM3","XMM4","XMM5","XMM6","XMM7", 242 "ES","PSW","STACK","ST0", "ST01"};242 "ES","PSW","STACK","ST0","ST01","NOREG","RMload","RMstore"}; 243 243 #endif 244 244 245 245 /* From nwc.c */ 246 246 247 247 type *chartype; /* default 'char' type */ 248 248 trunk/src/e2ir.c
r612 r618 420 420 * Convert array to a dynamic array. 421 421 */ 422 422 423 423 elem *array_toDarray(Type *t, elem *e) 424 424 { 425 425 unsigned dim; 426 426 elem *ef = NULL; 427 427 elem *ex; 428 428 429 429 //printf("array_toDarray(t = %s)\n", t->toChars()); 430 430 //elem_print(e); 431 431 t = t->toBasetype(); 432 432 switch (t->ty) 433 433 { 434 434 case Tarray: 435 435 break; 436 436 437 437 case Tsarray: 438 438 e = addressElem(e, t); 439 439 dim = ((TypeSArray *)t)->dim->toInteger(); 440 e = el_pair(TY ullong, el_long(TYint, dim), e);440 e = el_pair(TYdarray, el_long(TYint, dim), e); 441 441 break; 442 442 443 443 default: 444 444 L1: 445 445 switch (e->Eoper) 446 446 { 447 447 case OPconst: 448 448 { 449 449 size_t len = tysize[tybasic(e->Ety)]; 450 450 elem *es = el_calloc(); 451 451 es->Eoper = OPstring; 452 452 453 453 // Match MEM_PH_FREE for OPstring in ztc\el.c 454 454 es->EV.ss.Vstring = (char *)mem_malloc(len); 455 455 memcpy(es->EV.ss.Vstring, &e->EV, len); 456 456 457 457 es->EV.ss.Vstrlen = len; 458 458 es->Ety = TYnptr; 459 459 e = es; 460 460 break; … … 486 486 // Copy expression to a variable and take the 487 487 // address of that variable. 488 488 Symbol *stmp; 489 489 tym_t ty = tybasic(e->Ety); 490 490 491 491 if (ty == TYstruct) 492 492 { 493 493 if (e->Enumbytes == 4) 494 494 ty = TYint; 495 495 else if (e->Enumbytes == 8) 496 496 ty = TYllong; 497 497 } 498 498 e->Ety = ty; 499 499 stmp = symbol_genauto(type_fake(ty)); 500 500 e = el_bin(OPeq, e->Ety, el_var(stmp), e); 501 501 e = el_bin(OPcomma, TYnptr, e, el_una(OPaddr, TYnptr, el_var(stmp))); 502 502 break; 503 503 } 504 504 } 505 505 dim = 1; 506 e = el_pair(TY ullong, el_long(TYint, dim), e);506 e = el_pair(TYdarray, el_long(TYint, dim), e); 507 507 break; 508 508 } 509 509 return el_combine(ef, e); 510 510 } 511 511 512 512 /***************************************** 513 513 * Evaluate elem and convert to dynamic array. 514 514 */ 515 515 516 516 elem *eval_Darray(IRState *irs, Expression *e) 517 517 { 518 518 elem *ex; 519 519 520 520 ex = e->toElem(irs); 521 521 return array_toDarray(e->type, ex); 522 522 } 523 523 524 524 /************************************ 525 525 */ 526 526 … … 529 529 //printf("sarray_toDarray()\n"); 530 530 //elem_print(e); 531 531 532 532 unsigned dim = ((TypeSArray *)tfrom)->dim->toInteger(); 533 533 534 534 if (tto) 535 535 { 536 536 unsigned fsize = tfrom->nextOf()->size(); 537 537 unsigned tsize = tto->nextOf()->size(); 538 538 539 539 if ((dim * fsize) % tsize != 0) 540 540 { 541 541 Lerr: 542 542 error(loc, "cannot cast %s to %s since sizes don't line up", tfrom->toChars(), tto->toChars()); 543 543 } 544 544 dim = (dim * fsize) / tsize; 545 545 } 546 546 L1: 547 547 elem *elen = el_long(TYint, dim); 548 548 e = addressElem(e, tfrom); 549 e = el_pair(TY ullong, elen, e);549 e = el_pair(TYdarray, elen, e); 550 550 return e; 551 551 } 552 552 553 553 /******************************************** 554 554 * Determine if t is an array of structs that need a postblit. 555 555 */ 556 556 557 557 StructDeclaration *needsPostblit(Type *t) 558 558 { 559 559 t = t->toBasetype(); 560 560 while (t->ty == Tsarray) 561 561 t = t->nextOf()->toBasetype(); 562 562 if (t->ty == Tstruct) 563 563 { StructDeclaration *sd = ((TypeStruct *)t)->sym; 564 564 if (sd->postblit) 565 565 return sd; 566 566 } 567 567 return NULL; 568 568 } 569 569 … … 579 579 580 580 elem *setArray(elem *eptr, elem *edim, Type *tb, elem *evalue, IRState *irs, int op) 581 581 { int r; 582 582 elem *e; 583 583 int sz = tb->size(); 584 584 585 585 if (tb->ty == Tfloat80 || tb->ty == Timaginary80) 586 586 r = RTLSYM_MEMSET80; 587 587 else if (tb->ty == Tcomplex80) 588 588 r = RTLSYM_MEMSET160; 589 589 else if (tb->ty == Tcomplex64) 590 590 r = RTLSYM_MEMSET128; 591 591 else 592 592 { 593 593 switch (sz) 594 594 { 595 595 case 1: r = RTLSYM_MEMSET8; break; 596 596 case 2: r = RTLSYM_MEMSET16; break; 597 597 case 4: r = RTLSYM_MEMSET32; break; 598 598 case 8: r = RTLSYM_MEMSET64; break; 599 case 16: r = RTLSYM_MEMSET128; break; 599 600 default: r = RTLSYM_MEMSETN; break; 600 601 } 601 602 602 603 /* Determine if we need to do postblit 603 604 */ 604 605 if (op != TOKblit) 605 606 { 606 607 StructDeclaration *sd = needsPostblit(tb); 607 608 if (sd) 608 609 { /* Need to do postblit. 609 610 * void *_d_arraysetassign(void *p, void *value, int dim, TypeInfo ti); 610 611 */ 611 612 r = (op == TOKconstruct) ? RTLSYM_ARRAYSETCTOR : RTLSYM_ARRAYSETASSIGN; 612 613 evalue = el_una(OPaddr, TYnptr, evalue); 613 614 Expression *ti = tb->getTypeInfo(NULL); 614 615 elem *eti = ti->toElem(irs); 615 616 e = el_params(eti, edim, evalue, eptr, NULL); 616 617 e = el_bin(OPcall,TYnptr,el_var(rtlsym[r]),e); 617 618 return e; 618 619 } … … 1053 1054 L1: 1054 1055 el_setLoc(e,loc); 1055 1056 return e; 1056 1057 } 1057 1058 #endif 1058 1059 1059 1060 /************************************** 1060 1061 */ 1061 1062 1062 1063 elem *FuncExp::toElem(IRState *irs) 1063 1064 { 1064 1065 elem *e; 1065 1066 Symbol *s; 1066 1067 1067 1068 //printf("FuncExp::toElem() %s\n", toChars()); 1068 1069 s = fd->toSymbol(); 1069 1070 e = el_ptr(s); 1070 1071 if (fd->isNested()) 1071 1072 { 1072 1073 elem *ethis = getEthis(loc, irs, fd); 1073 e = el_pair(TY ullong, ethis, e);1074 e = el_pair(TYdelegate, ethis, e); 1074 1075 } 1075 1076 1076 1077 irs->deferToObj->push(fd); 1077 1078 el_setLoc(e,loc); 1078 1079 return e; 1079 1080 } 1080 1081 1081 1082 /************************************** 1082 1083 */ 1083 1084 1084 1085 elem *Dsymbol_toElem(Dsymbol *s, IRState *irs) 1085 1086 { 1086 1087 elem *e = NULL; 1087 1088 Symbol *sp; 1088 1089 AttribDeclaration *ad; 1089 1090 VarDeclaration *vd; 1090 1091 ClassDeclaration *cd; 1091 1092 StructDeclaration *sd; 1092 1093 FuncDeclaration *fd; 1093 1094 TemplateMixin *tm; … … 2643 2644 sassert = irs->blx->module->toModuleArray(); 2644 2645 ea = el_bin(OPcall,TYvoid,el_var(sassert), el_long(TYint, loc.linnum)); 2645 2646 eb = el_bin(OPoror,TYvoid,c1,ea); 2646 2647 einit = el_combine(einit, eb); 2647 2648 } 2648 2649 2649 2650 if (elwr) 2650 2651 { elem *elwr2; 2651 2652 2652 2653 el_free(enbytes); 2653 2654 elwr2 = el_copytree(elwr); 2654 2655 elwr2 = el_bin(OPmul, TYint, elwr2, el_long(TYint, sz)); 2655 2656 n1 = el_bin(OPadd, TYnptr, n1, elwr2); 2656 2657 enbytes = el_bin(OPmin, TYint, eupr, elwr); 2657 2658 elength = el_copytree(enbytes); 2658 2659 } 2659 2660 else 2660 2661 elength = el_copytree(enbytes); 2661 2662 e = setArray(n1, enbytes, tb, evalue, irs, op); 2662 2663 Lpair: 2663 e = el_pair(TY ullong, elength, e);2664 e = el_pair(TYdarray, elength, e); 2664 2665 Lret2: 2665 2666 e = el_combine(einit, e); 2666 2667 //elem_print(e); 2667 2668 goto Lret; 2668 2669 } 2669 2670 #if 0 2670 2671 else if (e2->op == TOKadd || e2->op == TOKmin) 2671 2672 { 2672 2673 /* It's ea[] = eb[] +- ec[] 2673 2674 */ 2674 2675 BinExp *e2a = (BinExp *)e2; 2675 2676 Type *t = e2->type->toBasetype()->nextOf()->toBasetype(); 2676 2677 if (t->ty != Tfloat32 && t->ty != Tfloat64 && t->ty != Tfloat80) 2677 2678 { 2678 2679 e2->error("array add/min for %s not supported", t->toChars()); 2679 2680 return el_long(TYint, 0); 2680 2681 } 2681 2682 elem *ea = e1->toElem(irs); 2682 2683 ea = array_toDarray(e1->type, ea); 2683 2684 elem *eb = e2a->e1->toElem(irs); … … 3298 3299 else 3299 3300 { 3300 3301 // Get pointer to function out of virtual table 3301 3302 unsigned vindex; 3302 3303 3303 3304 assert(ethis); 3304 3305 ep = el_same(ðis); 3305 3306 ep = el_una(OPind, TYnptr, ep); 3306 3307 vindex = func->vtblIndex; 3307 3308 3308 3309 // Build *(ep + vindex * 4) 3309 3310 ep = el_bin(OPadd,TYnptr,ep,el_long(TYint, vindex * 4)); 3310 3311 ep = el_una(OPind,TYnptr,ep); 3311 3312 } 3312 3313 3313 3314 // if (func->tintro) 3314 3315 // func->error(loc, "cannot form delegate due to covariant return type"); 3315 3316 } 3316 3317 if (ethis->Eoper == OPcomma) 3317 3318 { 3318 ethis->E2 = el_pair(TY ullong, ethis->E2, ep);3319 ethis->Ety = TY ullong;3319 ethis->E2 = el_pair(TYdelegate, ethis->E2, ep); 3320 ethis->Ety = TYdelegate; 3320 3321 e = ethis; 3321 3322 } 3322 3323 else 3323 e = el_pair(TY ullong, ethis, ep);3324 e = el_pair(TYdelegate, ethis, ep); 3324 3325 el_setLoc(e,loc); 3325 3326 return e; 3326 3327 } 3327 3328 3328 3329 elem *DotTypeExp::toElem(IRState *irs) 3329 3330 { 3330 3331 // Just a pass-thru to e1 3331 3332 elem *e; 3332 3333 3333 3334 //printf("DotTypeExp::toElem() %s\n", toChars()); 3334 3335 e = e1->toElem(irs); 3335 3336 el_setLoc(e,loc); 3336 3337 return e; 3337 3338 } 3338 3339 3339 3340 elem *CallExp::toElem(IRState *irs) 3340 3341 { 3341 3342 //printf("CallExp::toElem('%s')\n", toChars()); 3342 3343 assert(e1->type); 3343 3344 elem *ec; … … 4353 4354 4354 4355 L2: 4355 4356 // Construct: (c1 || ModuleArray(line)) 4356 4357 Symbol *sassert; 4357 4358 4358 4359 sassert = irs->blx->module->toModuleArray(); 4359 4360 ea = el_bin(OPcall,TYvoid,el_var(sassert), el_long(TYint, loc.linnum)); 4360 4361 eb = el_bin(OPoror,TYvoid,c1,ea); 4361 4362 elwr = el_combine(elwr, eb); 4362 4363 4363 4364 elwr2 = el_copytree(elwr2); 4364 4365 eupr = el_copytree(eupr2); 4365 4366 } 4366 4367 } 4367 4368 4368 4369 elem *eptr = array_toPtr(e1->type, e); 4369 4370 4370 4371 elem *elength = el_bin(OPmin, TYint, eupr, elwr2); 4371 4372 eptr = el_bin(OPadd, TYnptr, eptr, el_bin(OPmul, TYint, el_copytree(elwr2), el_long(TYint, sz))); 4372 4373 4373 e = el_pair(TY ullong, elength, eptr);4374 e = el_pair(TYdarray, elength, eptr); 4374 4375 e = el_combine(elwr, e); 4375 4376 e = el_combine(einit, e); 4376 4377 } 4377 4378 else if (t1->ty == Tsarray) 4378 4379 { 4379 4380 e = sarray_toDarray(loc, t1, NULL, e); 4380 4381 } 4381 4382 el_setLoc(e,loc); 4382 4383 return e; 4383 4384 } 4384 4385 4385 4386 elem *IndexExp::toElem(IRState *irs) 4386 4387 { elem *e; 4387 4388 elem *n1 = e1->toElem(irs); 4388 4389 elem *eb = NULL; 4389 4390 4390 4391 //printf("IndexExp::toElem() %s\n", toChars()); 4391 4392 Type *t1 = e1->type->toBasetype(); 4392 4393 if (t1->ty == Taarray) 4393 4394 { … … 4566 4567 else 4567 4568 { dim = 0; 4568 4569 e = el_long(TYint, 0); 4569 4570 } 4570 4571 Type *tb = type->toBasetype(); 4571 4572 #if 1 4572 4573 e = el_param(e, type->getTypeInfo(NULL)->toElem(irs)); 4573 4574 4574 4575 // call _d_arrayliteralT(ti, dim, ...) 4575 4576 e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ARRAYLITERALT]),e); 4576 4577 e->Eflags |= EFLAGS_variadic; 4577 4578 #else 4578 4579 e = el_param(e, el_long(TYint, tb->next->size())); 4579 4580 4580 4581 // call _d_arrayliteral(size, dim, ...) 4581 4582 e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ARRAYLITERAL]),e); 4582 4583 e->Eflags |= EFLAGS_variadic; 4583 4584 #endif 4584 4585 if (tb->ty == Tarray) 4585 4586 { 4586 e = el_pair(TY ullong, el_long(TYint, dim), e);4587 e = el_pair(TYdarray, el_long(TYint, dim), e); 4587 4588 } 4588 4589 else if (tb->ty == Tpointer) 4589 4590 { 4590 4591 } 4591 4592 else 4592 4593 { 4593 4594 e = el_una(OPind,TYstruct,e); 4594 4595 e->Enumbytes = type->size(); 4595 4596 } 4596 4597 4597 4598 el_setLoc(e,loc); 4598 4599 return e; 4599 4600 } 4600 4601 4601 4602 4602 4603 elem *AssocArrayLiteralExp::toElem(IRState *irs) 4603 4604 { elem *e; 4604 4605 size_t dim; 4605 4606 4606 4607 //printf("AssocArrayLiteralExp::toElem() %s\n", toChars()); trunk/src/iasm.c
r605 r618 1231 1231 L386_WARNING2: 1232 1232 if (config.target_cpu < TARGET_80386) 1233 1233 { // Reference to %s caused a 386 instruction to be generated 1234 1234 //warerr(WM_386_op, id->toChars()); 1235 1235 } 1236 1236 } 1237 1237 break; 1238 1238 case 2: 1239 1239 case 3: // The third operand is always an _imm 1240 1240 if (popnd1 && popnd1->s) 1241 1241 goto L386_WARNING; 1242 1242 if (popnd2 && popnd2->s) 1243 1243 { 1244 1244 id = popnd2->s->ident; 1245 1245 goto L386_WARNING2; 1246 1246 } 1247 1247 break; 1248 1248 } 1249 1249 } 1250 1250 1251 if (ptb.pptb0->usFlags & _64_bit && !I64) 1252 error(asmstate.loc, "use -m64 to compile 64 bit instructions"); 1253 1251 1254 switch (usNumops) 1252 1255 { 1253 1256 case 0: 1254 if (( I32&& (ptb.pptb0->usFlags & _16_bit)) ||1257 if (((I32 | I64) && (ptb.pptb0->usFlags & _16_bit)) || 1255 1258 (I16 && (ptb.pptb0->usFlags & _32_bit))) 1256 1259 { 1257 1260 emit(0x66); 1258 1261 pc->Iflags |= CFopsize; 1262 } 1263 else if (I64 && (ptb.pptb0->usFlags & _64_bit)) 1264 { 1265 emit(REX | REX_W); 1266 pc->Irex |= REX_W; 1259 1267 } 1260 1268 break; 1261 1269 1262 1270 // 3 and 2 are the same because the third operand is always 1263 1271 // an immediate and does not affect operation size 1264 1272 case 3: 1265 1273 case 2: 1266 1274 if ((I32 && 1267 1275 (amod2 == _addr16 || 1268 1276 (uSizemaskTable2 & _16 && aoptyTable2 == _rel) || 1269 1277 (uSizemaskTable2 & _32 && aoptyTable2 == _mnoi) || 1270 1278 (ptb.pptb2->usFlags & _16_bit_addr) 1271 1279 ) 1272 1280 ) || 1273 1281 (I16 && 1274 1282 (amod2 == _addr32 || 1275 1283 (uSizemaskTable2 & _32 && aoptyTable2 == _rel) || 1276 1284 (uSizemaskTable2 & _48 && aoptyTable2 == _mnoi) || 1277 1285 (ptb.pptb2->usFlags & _32_bit_addr))) 1278 1286 ) trunk/src/s2ir.c
r567 r618 967 967 */ 968 968 block_goto(blx, BCgoto, mystate.breakBlock); 969 969 return; 970 970 } 971 971 #endif 972 972 973 973 if (condition->type->isString()) 974 974 { 975 975 // Number the cases so we can unscramble things after the sort() 976 976 for (int i = 0; i < numcases; i++) 977 977 { CaseStatement *cs = (CaseStatement *)cases->data[i]; 978 978 cs->index = i; 979 979 } 980 980 981 981 cases->sort(); 982 982 983 983 /* Create a sorted array of the case strings, and si 984 984 * will be the symbol for it. 985 985 */ 986 986 dt_t *dt = NULL; 987 Symbol *si = symbol_generate(SCstatic,type_fake(TY ullong));987 Symbol *si = symbol_generate(SCstatic,type_fake(TYdarray)); 988 988 #if MACHOBJ 989 989 si->Sseg = DATA; 990 990 #endif 991 dt dword(&dt, numcases);992 dtxoff(&dt, si, 8, TYnptr);991 dtsize_t(&dt, numcases); 992 dtxoff(&dt, si, PTRSIZE * 2, TYnptr); 993 993 994 994 for (int i = 0; i < numcases; i++) 995 995 { CaseStatement *cs = (CaseStatement *)cases->data[i]; 996 996 997 997 if (cs->exp->op != TOKstring) 998 998 { error("case '%s' is not a string", cs->exp->toChars()); // BUG: this should be an assert 999 999 } 1000 1000 else 1001 1001 { 1002 1002 StringExp *se = (StringExp *)(cs->exp); 1003 1003 unsigned len = se->len; 1004 1004 dtdword(&dt, len); 1005 1005 dtabytes(&dt, TYnptr, 0, se->len * se->sz, (char *)se->string); 1006 1006 } 1007 1007 } 1008 1008 1009 1009 si->Sdt = dt; 1010 1010 si->Sfl = FLdata; 1011 1011 outdata(si); 1012 1012 trunk/src/toobj.c
r428 r618 466 466 /* The layout is: 467 467 { 468 468 void **vptr; 469 469 monitor_t monitor; 470 470 byte[] initializer; // static initialization data 471 471 char[] name; // class name 472 472 void *[] vtbl; 473 473 Interface[] interfaces; 474 474 ClassInfo *base; // base class 475 475 void *destructor; 476 476 void *invariant; // class invariant 477 477 uint flags; 478 478 void *deallocator; 479 479 OffsetTypeInfo[] offTi; 480 480 void *defaultConstructor; 481 481 const(MemberInfo[]) function(string) xgetMembers; // module getMembers() function 482 482 //TypeInfo typeinfo; 483 483 } 484 484 */ 485 485 dt_t *dt = NULL; 486 offset = CLASSINFO_SIZE; // must be ClassInfo.size 486 unsigned classinfo_size = global.params.isX86_64 ? CLASSINFO_SIZE_64 : CLASSINFO_SIZE; // must be ClassInfo.size 487 offset = classinfo_size; 487 488 if (classinfo) 488 489 { 489 if (classinfo->structsize != CLASSINFO_SIZE) 490 { 490 if (classinfo->structsize != classinfo_size) 491 { 492 #ifdef DEBUG 493 printf("CLASSINFO_SIZE = x%x, classinfo->structsize = x%x\n", offset, classinfo->structsize); 494 #endif 491 495 error("mismatch between dmd and object.d or object.di found. Check installation and import paths with -v compiler switch."); 492 496 fatal(); 493 497 } 494 498 } 495 499 496 500 if (classinfo) 497 501 dtxoff(&dt, classinfo->toVtblSymbol(), 0, TYnptr); // vtbl for ClassInfo 498 502 else 499 503 dtdword(&dt, 0); // BUG: should be an assert() 500 504 dtdword(&dt, 0); // monitor 501 505 502 506 // initializer[] 503 507 assert(structsize >= 8); 504 508 dtdword(&dt, structsize); // size 505 509 dtxoff(&dt, sinit, 0, TYnptr); // initializer 506 510 507 511 // name[] 508 512 const char *name = ident->toChars(); 509 513 size_t namelen = strlen(name); 510 514 if (!(namelen > 9 && memcmp(name, "TypeInfo_", 9) == 0)) … … 829 833 #endif 830 834 #if MACHOBJ 831 835 vtblsym->Sseg = DATA; 832 836 #endif 833 837 outdata(vtblsym); 834 838 if (isExport()) 835 839 obj_export(vtblsym,0); 836 840 } 837 841 838 842 /****************************************** 839 843 * Get offset of base class's vtbl[] initializer from start of csym. 840 844 * Returns ~0 if not this csym. 841 845 */ 842 846 843 847 unsigned ClassDeclaration::baseVtblOffset(BaseClass *bc) 844 848 { 845 849 unsigned csymoffset; 846 850 int i; 847 851 848 852 //printf("ClassDeclaration::baseVtblOffset('%s', bc = %p)\n", toChars(), bc); 849 csymoffset = CLASSINFO_SIZE;853 csymoffset = global.params.isX86_64 ? CLASSINFO_SIZE_64 : CLASSINFO_SIZE; // must be ClassInfo.size 850 854 csymoffset += vtblInterfaces->dim * (4 * PTRSIZE); 851 855 852 856 for (i = 0; i < vtblInterfaces->dim; i++) 853 857 { 854 858 BaseClass *b = (BaseClass *)vtblInterfaces->data[i]; 855 859 856 860 if (b == bc) 857 861 return csymoffset; 858 862 csymoffset += b->base->vtbl.dim * PTRSIZE; 859 863 } 860 864 861 865 #if 1 862 866 // Put out the overriding interface vtbl[]s. 863 867 // This must be mirrored with ClassDeclaration::baseVtblOffset() 864 868 //printf("putting out overriding interface vtbl[]s for '%s' at offset x%x\n", toChars(), offset); 865 869 ClassDeclaration *cd; 866 870 Array bvtbl; 867 871 868 872 for (cd = this->baseClass; cd; cd = cd->baseClass) 869 873 { … … 978 982 dtdword(&dt, 0); // monitor 979 983 980 984 // initializer[] 981 985 dtdword(&dt, 0); // size 982 986 dtdword(&dt, 0); // initializer 983 987 984 988 // name[] 985 989 const char *name = toPrettyChars(); 986 990 size_t namelen = strlen(name); 987 991 dtdword(&dt, namelen); 988 992 dtabytes(&dt, TYnptr, 0, namelen + 1, name); 989 993 990 994 // vtbl[] 991 995 dtdword(&dt, 0); 992 996 dtdword(&dt, 0); 993 997 994 998 // vtblInterfaces->data[] 995 999 dtdword(&dt, vtblInterfaces->dim); 996 1000 if (vtblInterfaces->dim) 997 1001 { 1002 offset = global.params.isX86_64 ? CLASSINFO_SIZE_64 : CLASSINFO_SIZE; // must be ClassInfo.size 998 1003 if (classinfo) 999 1004 { 1000 if (classinfo->structsize != CLASSINFO_SIZE)1005 if (classinfo->structsize != offset) 1001 1006 { 1002 1007 error("mismatch between dmd and object.d or object.di found. Check installation and import paths with -v compiler switch."); 1003 1008 fatal(); 1004 1009 } 1005 1010 } 1006 offset = CLASSINFO_SIZE;1007 1011 dtxoff(&dt, csym, offset, TYnptr); // (*) 1008 1012 } 1009 1013 else 1010 1014 dtdword(&dt, 0); 1011 1015 1012 1016 // base 1013 1017 assert(!baseClass); 1014 1018 dtdword(&dt, 0); 1015 1019 1016 1020 // dtor 1017 1021 dtdword(&dt, 0); 1018 1022 1019 1023 // invariant 1020 1024 dtdword(&dt, 0); 1021 1025 1022 1026 // flags 1023 1027 dtdword(&dt, 4 | isCOMinterface() | 32); 1024 1028 1025 1029 // deallocator 1026 1030 dtdword(&dt, 0);
