Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changeset 768

Show
Ignore:
Timestamp:
11/28/10 23:17:41 (14 years ago)
Author:
walter
Message:

more 64

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/dmd-1.x/src/backend/cg87.c

    r767 r768  
    20452045            cs.Iop = op1; 
    20462046            c2 = getlvalue(&cs, e->E1, 0); 
    20472047            cs.IEVoffset1 += sz; 
    20482048            cs.Irm |= modregrm(0, op2, 0); 
    20492049            c2 = cat(c2, makesure87(e->E2, sz, 0, 0)); 
    20502050            c2 = gen(c2, &cs); 
    20512051            c2 = genfwait(c2); 
    20522052            c2 = cat(c2, makesure87(e->E2,  0, 1, 0)); 
    20532053        } 
    20542054        else 
    20552055        { 
    20562056            c2 = loadea(e->E1,&cs,op1,op2,sz,0,0); 
    20572057            c2 = genfwait(c2); 
    20582058        } 
    20592059        if (fxch) 
    20602060            c2 = genf2(c2,0xD9,0xC8 + 1);       // FXCH ST(1) 
    20612061        cs.IEVoffset1 -= sz; 
    20622062        gen(c2, &cs); 
    20632063        if (fxch) 
    20642064            genf2(c2,0xD9,0xC8 + 1);            // FXCH ST(1) 
    2065 #if LNGDBLSIZE == 12 
    2066         if (op1 == 0xDB) 
    2067         { 
    2068             cs.Iop = 0xC7;                      // MOV EA+10,0 
    2069             NEWREG(cs.Irm, 0); 
    2070             cs.IEV1.sp.Voffset += 10; 
    2071             cs.IFL2 = FLconst; 
    2072             cs.IEV2.Vint = 0; 
    2073             cs.Iflags |= CFopsize; 
    2074             c2 = gen(c2, &cs); 
    2075             cs.IEVoffset1 += 12; 
    2076             c2 = gen(c2, &cs);                  // MOV EA+22,0 
    2077         } 
    2078 #endif 
     2065        if (tysize[TYldouble] == 12) 
     2066        { 
     2067            if (op1 == 0xDB) 
     2068            { 
     2069                cs.Iop = 0xC7;                      // MOV EA+10,0 
     2070                NEWREG(cs.Irm, 0); 
     2071                cs.IEV1.sp.Voffset += 10; 
     2072                cs.IFL2 = FLconst; 
     2073                cs.IEV2.Vint = 0; 
     2074                cs.Iflags |= CFopsize; 
     2075                c2 = gen(c2, &cs); 
     2076                cs.IEVoffset1 += 12; 
     2077                c2 = gen(c2, &cs);                  // MOV EA+22,0 
     2078            } 
     2079        } 
    20792080        if (tysize[TYldouble] == 16) 
    20802081        { 
    2081         if (op1 == 0xDB) 
    2082        
    2083             cs.Iop = 0xC7;                      // MOV EA+10,0 
    2084             NEWREG(cs.Irm, 0); 
    2085             cs.IEV1.sp.Voffset += 10; 
    2086             cs.IFL2 = FLconst; 
    2087             cs.IEV2.Vint = 0; 
    2088             cs.Iflags |= CFopsize; 
    2089             c2 = gen(c2, &cs); 
    2090  
    2091             cs.IEV1.sp.Voffset += 2; 
    2092             cs.Iflags &= ~CFopsize; 
    2093             c2 = gen(c2, &cs); 
    2094  
    2095             cs.IEVoffset1 += 14; 
    2096             cs.Iflags |= CFopsize; 
    2097             c2 = gen(c2, &cs); 
    2098  
    2099             cs.IEV1.sp.Voffset += 2; 
    2100             cs.Iflags &= ~CFopsize; 
    2101             c2 = gen(c2, &cs); 
    2102        
     2082            if (op1 == 0xDB) 
     2083           
     2084                cs.Iop = 0xC7;                      // MOV EA+10,0 
     2085                NEWREG(cs.Irm, 0); 
     2086                cs.IEV1.sp.Voffset += 10; 
     2087                cs.IFL2 = FLconst; 
     2088                cs.IEV2.Vint = 0; 
     2089                cs.Iflags |= CFopsize; 
     2090                c2 = gen(c2, &cs); 
     2091 
     2092                cs.IEV1.sp.Voffset += 2; 
     2093                cs.Iflags &= ~CFopsize; 
     2094                c2 = gen(c2, &cs); 
     2095 
     2096                cs.IEV1.sp.Voffset += 14; 
     2097                cs.Iflags |= CFopsize; 
     2098                c2 = gen(c2, &cs); 
     2099 
     2100                cs.IEV1.sp.Voffset += 2; 
     2101                cs.Iflags &= ~CFopsize; 
     2102                c2 = gen(c2, &cs); 
     2103           
    21032104        } 
    21042105        c2 = genfwait(c2); 
    21052106        freenode(e->E1); 
    21062107        return cat3(c1,c2,fixresult_complex87(e,mST01 | mPSW,pretregs)); 
    21072108} 
    21082109 
    21092110/******************************* 
    21102111 * Perform an assignment while converting to integral type, 
    21112112 * i.e. handle (e1 = (int) e2) 
    21122113 */ 
    21132114 
    21142115code *cnvteq87(elem *e,regm_t *pretregs) 
    21152116{ 
    21162117        regm_t retregs; 
    21172118        code *c1,*c2; 
    21182119        code cs; 
    21192120        unsigned op1; 
    21202121        unsigned op2; 
    21212122        tym_t ty1; 
    21222123 
  • branches/dmd-1.x/src/backend/cgcod.c

    r767 r768  
    15341534        case TYint: 
    15351535        case TYuint: 
    15361536#if JHANDLE 
    15371537        case TYjhandle: 
    15381538#endif 
    15391539        case TYnullptr: 
    15401540        case TYnptr: 
    15411541        case TYsptr: 
    15421542        case TYcptr: 
    15431543            return mAX; 
    15441544 
    15451545        case TYfloat: 
    15461546        case TYifloat: 
    15471547            if (I64) 
    15481548                return mXMM0; 
    15491549            if (config.exe & EX_flat) 
    15501550                return mST0; 
    15511551        case TYlong: 
    15521552        case TYulong: 
    15531553        case TYdchar: 
    1554             if (I32
     1554            if (!I16
    15551555                return mAX; 
    15561556        case TYfptr: 
    15571557        case TYhptr: 
    15581558            return mDX | mAX; 
    15591559 
    15601560        case TYcent: 
    15611561        case TYucent: 
    15621562            assert(I64); 
    15631563            return mDX | mAX; 
    15641564 
    15651565        case TYvptr: 
    15661566            return mDX | mBX; 
    15671567 
    15681568        case TYdouble: 
    15691569        case TYdouble_alias: 
    15701570        case TYidouble: 
    15711571            if (I64) 
    15721572                return mXMM0; 
    15731573            if (config.exe & EX_flat) 
    15741574                return mST0; 
  • branches/dmd-1.x/src/backend/cod1.c

    r767 r768  
    171171            if (index == -1) 
    172172                rm = modregrm(0,0,5); 
    173173            else 
    174174            { 
    175175                rm  = modregrm(0,0,4); 
    176176                sib = modregrm(ss,index & 7,5); 
    177177                if (index & 8) 
    178178                    rex |= REX_X; 
    179179            } 
    180180        } 
    181181        else if (index == -1) 
    182182        { 
    183183            if (base == SP) 
    184184            { 
    185185                rm  = modregrm(2,0,4); 
    186186                sib = modregrm(0,4,SP); 
    187187            } 
    188188            else 
    189189            {   rm = modregrm(2,0,base & 7); 
    190190                if (base & 8) 
    191                     rex |= REX_B; 
     191                {   rex |= REX_B; 
     192                    if (base == R12) 
     193                    { 
     194                        rm = modregrm(2,0,4); 
     195                        sib = modregrm(0,4,4); 
     196                    } 
     197                } 
    192198            } 
    193199        } 
    194200        else 
    195201        { 
    196202            rm  = modregrm(2,0,4); 
    197203            sib = modregrm(ss,index & 7,base & 7); 
    198204            if (index & 8) 
    199205                rex |= REX_X; 
    200206            if (base & 8) 
    201207                rex |= REX_B; 
    202208        } 
    203209    } 
    204210    else 
    205211    { 
    206212        // -1 AX CX DX BX SP BP SI DI 
    207213        static unsigned char EA16rm[9][9] = 
    208214        { 
    209215            {   0x06,0x09,0x09,0x09,0x87,0x09,0x86,0x84,0x85,   },      // -1 
    210216            {   0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,   },      // AX 
    211217            {   0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,   },      // CX 
    212218            {   0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,   },      // DX 
    213219            {   0x87,0x09,0x09,0x09,0x09,0x09,0x09,0x80,0x81,   },      // BX 
    214220            {   0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,   },      // SP 
    215221            {   0x86,0x09,0x09,0x09,0x09,0x09,0x09,0x82,0x83,   },      // BP 
    216222            {   0x84,0x09,0x09,0x09,0x80,0x09,0x82,0x09,0x09,   },      // SI 
    217223            {   0x85,0x09,0x09,0x09,0x81,0x09,0x83,0x09,0x09,   }       // DI 
    218224        }; 
    219225 
    220226        assert(scale == 1); 
    221227        rm = EA16rm[base + 1][index + 1]; 
    222228        assert(rm != 9); 
    223229    } 
    224230    c->Irm = rm; 
    225231    c->Isib = sib; 
    226232    c->Irex = rex; 
    227233    c->IFL1 = FLconst; 
    228234    c->IEV1.Vuns = disp; 
     235} 
     236 
     237/********************************************* 
     238 * Build REX, modregrm and sib bytes 
     239 */ 
     240 
     241unsigned buildModregrm(int mod, int reg, int rm) 
     242{   unsigned m; 
     243    if (I16) 
     244        m = modregrm(mod, reg, rm); 
     245    else 
     246    { 
     247        unsigned rex = 0; 
     248        if ((rm & 7) == SP && mod != 3) 
     249            m = (modregrm(0,4,SP) << 8) | modregrm(mod,reg & 7,4); 
     250        else 
     251            m = modregrm(mod,reg & 7,rm & 7); 
     252        if (reg & 8) 
     253            m |= REX_R << 16; 
     254        if (rm & 8) 
     255            m |= REX_B << 16; 
     256    } 
     257    return m; 
    229258} 
    230259 
    231260/************************** 
    232261 * For elems in regcon that don't match regconsave, 
    233262 * clear the corresponding bit in regcon.cse.mval. 
    234263 * Do same for regcon.immed. 
    235264 */ 
    236265 
    237266void andregcon(con_t *pregconsave) 
    238267{ 
    239268    regm_t m = ~1; 
    240269    for (int i = 0; i < REGMAX; i++) 
    241270    {   if (pregconsave->cse.value[i] != regcon.cse.value[i]) 
    242271            regcon.cse.mval &= m; 
    243272        if (pregconsave->immed.value[i] != regcon.immed.value[i]) 
    244273            regcon.immed.mval &= m; 
    245274        m <<= 1; 
    246275        m |= 1; 
    247276    } 
    248277    //printf("regcon.cse.mval = x%x, regconsave->mval = x%x ",regcon.cse.mval,pregconsave->cse.mval); 
     
    860889                break; 
    861890            default: 
    862891#ifdef DEBUG 
    863892                elem_print(e); 
    864893#endif 
    865894                assert(0); 
    866895        } 
    867896        e1ty = tybasic(e1->Ety); 
    868897        if (e1isadd) 
    869898        {   e12 = e1->E2; 
    870899            e11 = e1->E1; 
    871900        } 
    872901 
    873902        /* First see if we can replace *(e+&v) with 
    874903         *      MOV     idxreg,e 
    875904         *      EA =    [ES:] &v+idxreg 
    876905         */ 
    877906 
    878907        if (e1isadd && 
    879908            e12->Eoper == OPrelconst && 
     909            !(I64 && config.flags3 & CFG3pic) && 
    880910            (f = el_fl(e12)) != FLfardata && 
    881911            e1->Ecount == e1->Ecomsub && 
    882912            (!e1->Ecount || (~keepmsk & ALLREGS & mMSW) || (e1ty != TYfptr && e1ty != TYhptr)) && 
    883913            tysize(e11->Ety) == REGSIZE 
    884914           ) 
    885915        {   unsigned char t;            /* component of r/m field */ 
    886916            int ss; 
    887917            int ssi; 
    888918 
    889919            /*assert(datafl[f]);*/              /* what if addr of func? */ 
    890920            if (!I16) 
    891921            {   /* Any register can be an index register        */ 
    892922                regm_t idxregs = allregs & ~keepmsk; 
    893923                assert(idxregs); 
    894924 
    895925                /* See if e1->E1 can be a scaled index  */ 
    896926                ss = isscaledindex(e11); 
    897927                if (ss) 
    898928                { 
    899929                    /* Load index register with result of e11->E1       */ 
     
    942972                        assert(!stackfl[f]); 
    943973                        pcs->Irm = modregrm(2,0,4); 
    944974                        pcs->Isib = modregrm(ss1,reg & 7,reg & 7); 
    945975                        if (reg & 8) 
    946976                            pcs->Irex |= REX_X | REX_B; 
    947977                    } 
    948978                    else 
    949979                    {   int rbase; 
    950980                        unsigned r; 
    951981 
    952982                        scratchm = ALLREGS & ~keepmsk; 
    953983                        c = cat(c,allocreg(&scratchm,&r,TYint)); 
    954984 
    955985                        if (ssflags & SSFLnobase1) 
    956986                        {   t = 0; 
    957987                            rbase = 5; 
    958988                        } 
    959989                        else 
    960990                        {   t = 0; 
    961991                            rbase = reg; 
    962                             if (rbase == BP
     992                            if (rbase == BP || rbase == R13
    963993                            {   static unsigned imm32[4] = {1+1,2+1,4+1,8+1}; 
    964994 
    965995                                // IMUL r,BP,imm32 
    966                                 c = genc2(c,0x69,modregxrm(3,r,BP),imm32[ss1]); 
     996                                c = genc2(c,0x69,modregxrmx(3,r,rbase),imm32[ss1]); 
    967997                                goto L7; 
    968998                            } 
    969999                        } 
    9701000 
    9711001                        c = gen2sib(c,0x8D,modregxrm(t,r,4),modregrm(ss1,reg & 7,rbase & 7)); 
    9721002                        if (reg & 8) 
    9731003                            code_orrex(c, REX_X); 
    9741004                        if (rbase & 8) 
    9751005                            code_orrex(c, REX_B); 
    9761006                        if (I64) 
    9771007                            code_orrex(c, REX_W); 
    9781008 
    9791009                        if (ssflags & SSFLnobase1) 
    9801010                        {   code_last(c)->IFL1 = FLconst; 
    9811011                            code_last(c)->IEV1.Vuns = 0; 
    9821012                        } 
    9831013                    L7: 
    9841014                        if (ssflags & SSFLnobase) 
    9851015                        {   t = stackfl[f] ? 2 : 0; 
    9861016                            rbase = 5; 
     
    32193249                        if (!(config.exe & EX_flat)) 
    32203250                        {   seg = CFes; 
    32213251                            retregs |= mES; 
    32223252                        } 
    32233253                        c1 = codelem(e1,&retregs,FALSE); 
    32243254                        break; 
    32253255                    default: 
    32263256#ifdef DEBUG 
    32273257                        elem_print(e1); 
    32283258#endif 
    32293259                        assert(0); 
    32303260                } 
    32313261                reg = findreglsw(retregs); 
    32323262                rm = I16 ? regtorm[reg] : regtorm32[reg]; 
    32333263                if (op16) 
    32343264                    seg |= CFopsize;            // operand size 
    32353265                if (npushes <= 4) 
    32363266                { 
    32373267                    assert(!doneoff); 
    32383268                    for (c2 = CNIL; npushes > 1; npushes--) 
    3239                     {   c2 = genc1(c2,0xFF,modregrmx(2,6,rm),FLconst,pushsize * (npushes - 1));  // PUSH [reg] 
     3269                    {   c2 = genc1(c2,0xFF,buildModregrm(2,6,rm),FLconst,pushsize * (npushes - 1));  // PUSH [reg] 
    32403270                        code_orflag(c2,seg); 
    32413271                        genadjesp(c2,pushsize); 
    32423272                    } 
    3243                     c3 = gen2(CNIL,0xFF,modregrmx(0,6,rm));     // PUSH [reg] 
     3273                    c3 = gen2(CNIL,0xFF,buildModregrm(0,6,rm));     // PUSH [reg] 
    32443274                    c3->Iflags |= seg; 
    32453275                    genadjesp(c3,pushsize); 
    32463276                    ce = cat4(cc,c1,c2,c3); 
    32473277                } 
    32483278                else if (sz) 
    32493279                {   int size; 
    32503280 
    32513281                    c2 = getregs_imm(mCX | retregs); 
    32523282                                                        /* MOV CX,sz/2  */ 
    32533283                    c2 = movregconst(c2,CX,npushes,0); 
    32543284                    if (!doneoff) 
    32553285                    {   /* This disgusting thing should be done when    */ 
    32563286                        /* reg is loaded. Too lazy to fix it now.       */ 
    32573287                                                        /* ADD reg,sz-2 */ 
    32583288                        c2 = genc2(c2,0x81,grex | modregrmx(3,0,reg),sz-pushsize); 
    32593289                    } 
    3260                     c3 = gen2(CNIL,0xFF,modregrmx(0,6,rm));      // PUSH [reg] 
     3290                    c3 = gen2(CNIL,0xFF,buildModregrm(0,6,rm));      // PUSH [reg] 
    32613291                    c3->Iflags |= seg | CFtarg2; 
    3262                     genc2(c3,0x81,grex | modregrmx(3,5,reg),pushsize);  // SUB reg,2 
     3292                    genc2(c3,0x81,grex | buildModregrm(3,5,reg),pushsize);  // SUB reg,2 
    32633293                    size = ((seg & CFSEG) ? -8 : -7) - op16; 
    32643294                    if (code_next(c3)->Iop != 0x81) 
    32653295                        size++; 
    32663296                    //genc2(c3,0xE2,0,size);    // LOOP .-7 or .-8 
    32673297                    genjmp(c3,0xE2,FLcode,(block *)c3);         // LOOP c3 
    32683298                    regimmed_set(CX,0); 
    32693299                    genadjesp(c3,sz); 
    32703300                    ce = cat4(cc,c1,c2,c3); 
    32713301                } 
    32723302                else 
    32733303                    ce = cat(cc,c1); 
    32743304                stackpush += sz; 
    32753305                goto L2; 
    32763306        } 
    32773307    case OPind: 
    32783308        if (!e->Ecount)                         /* if *e1       */ 
    32793309        {       if (sz <= REGSIZE) 
    32803310                {   // Watch out for single byte quantities being up 
    32813311                    // against the end of a segment or in memory-mapped I/O 
    32823312                    if (!(config.exe & EX_flat) && szb == 1) 
     
    36763706  { 
    36773707        regm = allregs; 
    36783708        if (e->Eoper == OPconst) 
    36793709        {       /* TRUE:        OR SP,SP        (SP is never 0)         */ 
    36803710                /* FALSE:       CMP SP,SP       (always equal)          */ 
    36813711                c = genregs(CNIL,(boolres(e)) ? 0x09 : 0x39,SP,SP); 
    36823712                if (I64) 
    36833713                    code_orrex(c, REX_W); 
    36843714        } 
    36853715        else if (sz <= REGSIZE) 
    36863716        { 
    36873717            if (!I16 && (tym == TYfloat || tym == TYifloat)) 
    36883718            {   c = allocreg(&regm,&reg,TYoffset);      /* get a register */ 
    36893719                ce = loadea(e,&cs,0x8B,reg,0,0,0);      // MOV reg,data 
    36903720                c = cat(c,ce); 
    36913721                ce = gen2(CNIL,0xD1,modregrmx(3,4,reg)); /* SHL reg,1      */ 
    36923722                c = cat(c,ce); 
    36933723            } 
    36943724            else 
    36953725            {   cs.IFL2 = FLconst; 
    3696                 cs.IEV2.Vint = 0; 
     3726                cs.IEV2.Vsize_t = 0; 
    36973727                op = (sz == 1) ? 0x80 : 0x81; 
    36983728                c = loadea(e,&cs,op,7,0,0,0);           /* CMP EA,0     */ 
    36993729 
    37003730                // Convert to TEST instruction if EA is a register 
    37013731                // (to avoid register contention on Pentium) 
    37023732                if ((c->Iop & ~1) == 0x38 && 
    37033733                    (c->Irm & modregrm(3,0,0)) == modregrm(3,0,0) 
    37043734                   ) 
    37053735                {   c->Iop = (c->Iop & 1) | 0x84; 
    37063736                    code_newreg(c, c->Irm & 7); 
    37073737                    if (c->Irex & REX_B) 
    3708                         c->Irex = (c->Irex & ~REX_B) | REX_R; 
     3738                        //c->Irex = (c->Irex & ~REX_B) | REX_R; 
     3739                        c->Irex |= REX_R; 
    37093740                } 
    37103741            } 
    37113742        } 
    37123743        else if (sz < 8) 
    37133744        { 
    37143745            c = allocreg(&regm,&reg,TYoffset);          /* get a register */ 
    37153746            if (I32)                                    // it's a 48 bit pointer 
    37163747                ce = loadea(e,&cs,0x0FB7,reg,REGSIZE,0,0); /* MOVZX reg,data+4 */ 
    37173748            else 
    37183749            {   ce = loadea(e,&cs,0x8B,reg,REGSIZE,0,0); /* MOV reg,data+2 */ 
    37193750                if (tym == TYfloat || tym == TYifloat)  // dump sign bit 
    37203751                    gen2(ce,0xD1,modregrm(3,4,reg));    /* SHL reg,1      */ 
    37213752            } 
    37223753            c = cat(c,ce); 
    37233754            ce = loadea(e,&cs,0x0B,reg,0,regm,0);       /* OR reg,data */ 
    37243755            c = cat(c,ce); 
    37253756        } 
    37263757        else if (sz == 8 || (I64 && sz == 2 * REGSIZE && !tyfloating(tym))) 
    37273758        { 
    37283759            c = allocreg(&regm,&reg,TYoffset);  /* get a register */ 
  • branches/dmd-1.x/src/backend/cod2.c

    r767 r768  
    226226            else if (sz == 4) 
    227227                value &= 0xFFFFFFFF; 
    228228            if (reghasvalue(byte ? BYTEREGS : ALLREGS,value,&reg)) 
    229229                goto L11; 
    230230            if (sz == 8 && !I64) 
    231231            { 
    232232                assert(value == (int)value);    // sign extend imm32 
    233233            } 
    234234            op1 = 0xF7; 
    235235            cs.IEV2.Vint = value; 
    236236            cs.IFL2 = FLconst; 
    237237            goto L10; 
    238238        } 
    239239 
    240240        // Handle (exp & reg) 
    241241        if (isregvar(e2,&retregs,&reg)) 
    242242        { 
    243243            c = getlvalue(&cs,e1,0); 
    244244        L11: 
    245245            code_newreg(&cs, reg); 
     246            if (I64 && byte && reg >= 4) 
     247                cs.Irex |= REX; 
    246248        L10: 
    247249            cs.Iop = op1 ^ byte; 
    248250            cs.Iflags |= word | CFpsw; 
    249251            freenode(e1); 
    250252            freenode(e2); 
    251253            return gen(c,&cs); 
    252254        } 
    253255  } 
    254256 
    255257  // Look for possible uses of LEA 
    256258  if (e->Eoper == OPadd && 
    257259      !(*pretregs & mPSW) &&            /* flags aren't set by LEA      */ 
    258260      !nest &&                          // could cause infinite recursion if e->Ecount 
    259261      (sz == REGSIZE || (I64 && sz == 4)))  // far pointers aren't handled 
    260262  { 
    261263        unsigned rex = (sz == 8) ? REX_W : 0; 
    262264 
    263265        // Handle the case of (e + &var) 
    264266        int e1oper = e1->Eoper; 
    265267        if ((e2oper == OPrelconst && (config.target_cpu >= TARGET_Pentium || (!e2->Ecount && stackfl[el_fl(e2)]))) 
     
    571573            rretregs &= BYTEREGS; 
    572574 
    573575        cr = scodelem(e2,&rretregs,retregs,TRUE);       /* get rvalue   */ 
    574576        rreg = (tysize[ty2] > REGSIZE) ? findreglsw(rretregs) : findreg(rretregs); 
    575577        c = CNIL; 
    576578        if (numwords == 1)                              /* ADD reg,rreg */ 
    577579        { 
    578580                /* reverse operands to avoid moving around the segment value */ 
    579581                if (tysize[ty2] > REGSIZE) 
    580582                {       c = cat(c,getregs(rretregs)); 
    581583                        c = genregs(c,op1,rreg,reg); 
    582584                        retregs = rretregs;     /* reverse operands     */ 
    583585                } 
    584586                else 
    585587                {   c = genregs(c,op1,reg,rreg); 
    586588                    if (!I16 && *pretregs & mPSW) 
    587589                        c->Iflags |= word; 
    588590                } 
    589591                if (I64 && sz == 8) 
    590592                    code_orrex(c, REX_W); 
     593                if (I64 && byte && reg >= 4) 
     594                    code_orrex(c, REX); 
    591595        } 
    592596        else /* numwords == 2 */                /* ADD lsreg,lsrreg     */ 
    593597        { 
    594598            reg = findreglsw(retregs); 
    595599            rreg = findreglsw(rretregs); 
    596600            c = genregs(c,op1,reg,rreg); 
    597601            if (e->Eoper == OPadd || e->Eoper == OPmin) 
    598602                code_orflag(c,CFpsw); 
    599603            reg = findregmsw(retregs); 
    600604            rreg = findregmsw(rretregs); 
    601605            if (!(e2oper == OPu16_32 && // if second operand is 0 
    602606                  (op2 == 0x0B || op2 == 0x33)) // and OR or XOR 
    603607               ) 
    604608                genregs(c,op2,reg,rreg);        // ADC msreg,msrreg 
    605609        } 
    606610        break; 
    607611 
    608612    case OPrelconst: 
    609613        if (sz != REGSIZE) 
    610614                goto L2; 
     
    32033207 
    32043208/********************************* 
    32053209 * Generate code for memset(s,val,n) intrinsic. 
    32063210 *      (s OPmemset (n OPparam val)) 
    32073211 */ 
    32083212 
    32093213#if 1 
    32103214code *cdmemset(elem *e,regm_t *pretregs) 
    32113215{   code *c1,*c2,*c3 = NULL,*c4; 
    32123216    regm_t retregs1; 
    32133217    regm_t retregs2; 
    32143218    regm_t retregs3; 
    32153219    unsigned reg,vreg; 
    32163220    tym_t ty1; 
    32173221    elem *e2,*e1; 
    32183222    int segreg; 
    32193223    unsigned remainder; 
    32203224    targ_uns numbytes,numwords; 
    32213225    int op; 
    32223226    targ_size_t value; 
     3227    unsigned m; 
    32233228 
    32243229    //printf("cdmemset(*pretregs = x%x)\n", *pretregs); 
    32253230    e1 = e->E1; 
    32263231    e2 = e->E2; 
    32273232    assert(e2->Eoper == OPparam); 
    32283233 
    32293234    unsigned char rex = I64 ? REX_W : 0; 
    32303235 
    32313236    if (e2->E2->Eoper == OPconst) 
    32323237    { 
    32333238        value = el_tolong(e2->E2); 
    32343239        value &= 0xFF; 
    32353240        value |= value << 8; 
    32363241        value |= value << 16; 
    32373242        value |= value << 32; 
    32383243    } 
    32393244 
    32403245    if (e2->E1->Eoper == OPconst) 
    32413246    { 
    32423247        numbytes = el_tolong(e2->E1); 
    32433248        if (numbytes <= REP_THRESHOLD && 
    32443249            !I16 &&                     // doesn't work for 16 bits 
    32453250            e2->E2->Eoper == OPconst) 
    32463251        { 
    32473252            targ_uns offset = 0; 
    32483253            retregs1 = *pretregs; 
    32493254            if (!retregs1) 
    32503255                retregs1 = ALLREGS; 
    32513256            c1 = codelem(e->E1,&retregs1,FALSE); 
    32523257            reg = findreg(retregs1); 
    32533258            if (e2->E2->Eoper == OPconst) 
    32543259            { 
     3260                unsigned m = buildModregrm(0,0,reg); 
    32553261                switch (numbytes) 
    32563262                { 
    32573263                    case 4:                     // MOV [reg],imm32 
    3258                         c3 = genc2(CNIL,0xC7,modregrmx(0,0,reg),value); 
     3264                        c3 = genc2(CNIL,0xC7,m,value); 
    32593265                        goto fixres; 
    32603266                    case 2:                     // MOV [reg],imm16 
    3261                         c3 = genc2(CNIL,0xC7,modregrmx(0,0,reg),value); 
     3267                        c3 = genc2(CNIL,0xC7,m,value); 
    32623268                        c3->Iflags = CFopsize; 
    32633269                        goto fixres; 
    32643270                    case 1:                     // MOV [reg],imm8 
    3265                         c3 = genc2(CNIL,0xC6,modregrmx(0,0,reg),value); 
     3271                        c3 = genc2(CNIL,0xC6,m,value); 
    32663272                        goto fixres; 
    32673273                } 
    32683274            } 
    32693275 
    32703276            c1 = regwithvalue(c1, BYTEREGS & ~retregs1, value, &vreg, I64 ? 64 : 0); 
    32713277            freenode(e2->E2); 
    32723278            freenode(e2); 
    32733279 
     3280            m = (rex << 16) | buildModregrm(2,vreg,reg); 
    32743281            while (numbytes >= REGSIZE) 
    32753282            {                           // MOV dword ptr offset[reg],vreg 
    3276                 c2 = gen2(CNIL,0x89,(rex << 16) | modregxrmx(2,vreg,reg)); 
     3283                c2 = gen2(CNIL,0x89,m); 
    32773284                c2->IEVoffset1 = offset; 
    32783285                c2->IFL1 = FLconst; 
    32793286                numbytes -= REGSIZE; 
    32803287                offset += REGSIZE; 
    32813288                c3 = cat(c3,c2); 
    32823289            } 
    32833290            if (numbytes & 4) 
    32843291            {                           // MOV dword ptr offset[reg],vreg 
    3285                 c2 = gen2(CNIL,0x89,modregxrmx(2,vreg,reg)); 
     3292                c2 = gen2(CNIL,0x89,m); 
    32863293                c2->IEVoffset1 = offset; 
    32873294                c2->IFL1 = FLconst; 
    32883295                offset += 4; 
    32893296                c3 = cat(c3,c2); 
    32903297            } 
    32913298            if (numbytes & 2) 
    32923299            {                           // MOV word ptr offset[reg],vreg 
    3293                 c2 = gen2(CNIL,0x89,modregxrmx(2,vreg,reg)); 
     3300                c2 = gen2(CNIL,0x89,m); 
    32943301                c2->IEVoffset1 = offset; 
    32953302                c2->IFL1 = FLconst; 
    32963303                c2->Iflags = CFopsize; 
    32973304                offset += 2; 
    32983305                c3 = cat(c3,c2); 
    32993306            } 
    33003307            if (numbytes & 1) 
    33013308            {                           // MOV byte ptr offset[reg],vreg 
    3302                 c2 = gen2(CNIL,0x88,modregxrmx(2,vreg,reg)); 
     3309                c2 = gen2(CNIL,0x88,m); 
    33033310                c2->IEVoffset1 = offset; 
    33043311                c2->IFL1 = FLconst; 
     3312                if (I64 && vreg >= 4) 
     3313                    c2->Irex |= REX; 
    33053314                c3 = cat(c3,c2); 
    33063315            } 
    33073316fixres: 
    33083317            return cat3(c1,c3,fixresult(e,retregs1,pretregs)); 
    33093318        } 
    33103319    } 
    33113320 
    33123321    // Get nbytes into CX 
    33133322    retregs2 = mCX; 
    33143323    if (!I16 && e2->E1->Eoper == OPconst && e2->E2->Eoper == OPconst) 
    33153324    { 
    33163325        remainder = numbytes & (4 - 1); 
    33173326        numwords  = numbytes / 4;               // number of words 
    33183327        op = 0xAB;                              // moving by words 
    33193328        c1 = getregs(mCX); 
    33203329        c1 = movregconst(c1,CX,numwords,I64?64:0);     // # of bytes/words 
    33213330    } 
    33223331    else 
    33233332    { 
    33243333        remainder = 0; 
     
    33653374    if (*pretregs)                              // if need return value 
    33663375    {   c3 = getregs(mBX); 
    33673376        c3 = genmovreg(c3,BX,DI); 
    33683377        code_orrex(c3,rex); 
    33693378    } 
    33703379 
    33713380    c3 = cat(c3,getregs(mDI | mCX)); 
    33723381    if (I16 && config.flags4 & CFG4speed)      // if speed optimization 
    33733382    { 
    33743383        c3 = cat(c3,getregs(mAX)); 
    33753384        c3 = gen2(c3,0x8A,modregrm(3,AH,AL));   // MOV AH,AL 
    33763385        gen2(c3,0xD1,modregrm(3,5,CX));         // SHR CX,1 
    33773386        gen1(c3,0xF3);                          // REP 
    33783387        gen1(c3,0xAB);                          // STOSW 
    33793388        gen2(c3,0x11,modregrm(3,CX,CX));        // ADC CX,CX 
    33803389        op = 0xAA; 
    33813390    } 
    33823391 
    33833392    c3 = gen1(c3,0xF3);                         // REP 
    33843393    gen1(c3,op);                                // STOSD 
     3394    m = buildModregrm(2,AX,reg); 
    33853395    if (remainder & 4) 
    33863396    { 
    33873397        code *ctmp; 
    3388         ctmp = gen2(CNIL,0x89,modregrmx(2,AX,reg)); 
     3398        ctmp = gen2(CNIL,0x89,m); 
    33893399        ctmp->IFL1 = FLconst; 
    33903400        c3 = cat(c3,ctmp); 
    33913401    } 
    33923402    if (remainder & 2) 
    33933403    { 
    33943404        code *ctmp; 
    3395         ctmp = gen2(CNIL,0x89,modregrmx(2,AX,reg)); 
     3405        ctmp = gen2(CNIL,0x89,m); 
    33963406        ctmp->Iflags = CFopsize; 
    33973407        ctmp->IEVoffset1 = remainder & 4; 
    33983408        ctmp->IFL1 = FLconst; 
    33993409        c3 = cat(c3,ctmp); 
    34003410    } 
    34013411    if (remainder & 1) 
    34023412    { 
    34033413        code *ctmp; 
    3404         ctmp = gen2(CNIL,0x88,modregrmx(2,AX,reg)); 
     3414        ctmp = gen2(CNIL,0x88,m); 
    34053415        ctmp->IEVoffset1 = remainder & ~1; 
    34063416        ctmp->IFL1 = FLconst; 
    34073417        c3 = cat(c3,ctmp); 
    34083418    } 
    34093419    regimmed_set(CX,0); 
    34103420    return cat4(c1,c2,c3,fixresult(e,mES|mBX,pretregs)); 
    34113421} 
    34123422#else 
    34133423// BUG: Pat made many improvements in the linux version, I need 
    34143424// to verify they work for 16 bits and fold them in. -Walter 
    34153425 
    34163426code *cdmemset(elem *e,regm_t *pretregs) 
    34173427{   code *c1,*c2,*c3 = NULL,*c4; 
    34183428    regm_t retregs1; 
    34193429    regm_t retregs2; 
    34203430    regm_t retregs3; 
    34213431    tym_t ty1; 
    34223432    elem *e2; 
    34233433    targ_size_t value; 
    34243434 
     
    41434153  } 
    41444154  else 
    41454155        assert(0); 
    41464156  return cat4(c1,cg,c,fixresult(e,retregs,pretregs)); 
    41474157} 
    41484158 
    41494159/************************** 
    41504160 * Post increment and post decrement. 
    41514161 */ 
    41524162 
    41534163code *cdpost(elem *e,regm_t *pretregs) 
    41544164{ code cs,*c1,*c2,*c3,*c4,*c5,*c6; 
    41554165  unsigned reg,op,byte; 
    41564166  tym_t tyml; 
    41574167  regm_t retregs,possregs,idxregs; 
    41584168  targ_int n; 
    41594169  elem *e2; 
    41604170  int sz; 
    41614171  int stackpushsave; 
    41624172 
     4173  //printf("cdpost(pretregs = %s)\n", regm_str(*pretregs)); 
    41634174  retregs = *pretregs; 
    41644175  op = e->Eoper;                                /* OPxxxx               */ 
    41654176  if (retregs == 0)                             /* if nothing to return */ 
    41664177        return cdaddass(e,pretregs); 
    41674178  c4 = c5 = CNIL; 
    41684179  tyml = tybasic(e->E1->Ety); 
    41694180  sz = tysize[tyml]; 
    41704181  e2 = e->E2; 
    41714182  unsigned rex = (I64 && sz == 8) ? REX_W : 0; 
    41724183 
    41734184  if (tyfloating(tyml)) 
    41744185  { 
    41754186#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 
    41764187        return post87(e,pretregs); 
    41774188#else 
    41784189        if (config.inline8087) 
    41794190                return post87(e,pretregs); 
    41804191        assert(sz <= 8); 
    41814192        c1 = getlvalue(&cs,e->E1,DOUBLEREGS); 
    41824193        freenode(e->E1); 
     
    42834294        //      LEA     reg,n[reg]      // don't affect flags 
    42844295        int rm; 
    42854296 
    42864297        reg = cs.Irm & 7; 
    42874298        if (cs.Irex & REX_B) 
    42884299            reg |= 8; 
    42894300        cs.Iop = 0x85 ^ byte; 
    42904301        code_newreg(&cs, reg); 
    42914302        cs.Iflags |= CFpsw; 
    42924303        c2 = gen(NULL,&cs);             // TEST reg,reg 
    42934304 
    42944305        // If lvalue is a register variable, we must mark it as modified 
    42954306        c3 = modEA(&cs); 
    42964307 
    42974308        n = e2->EV.Vint; 
    42984309        if (op == OPpostdec) 
    42994310            n = -n; 
    43004311        rm = reg; 
    43014312        if (I16) 
    43024313            rm = regtorm[reg]; 
    4303         c4 = genc1(NULL,0x8D,(rex << 16) | modregxrmx(2,reg,rm),FLconst,n); // LEA reg,n[reg] 
     4314        c4 = genc1(NULL,0x8D,(rex << 16) | buildModregrm(2,reg,rm),FLconst,n); // LEA reg,n[reg] 
    43044315        return cat4(c1,c2,c3,c4); 
    43054316  } 
    43064317  else if (sz <= REGSIZE || tyfv(tyml)) 
    43074318  {     code cs2; 
    43084319 
    43094320        cs.Iop = 0x8B ^ byte; 
    43104321        retregs = possregs & ~idxregs & *pretregs; 
    43114322        if (!tyfv(tyml)) 
    43124323        {       if (retregs == 0) 
    43134324                        retregs = possregs & ~idxregs; 
    43144325        } 
    43154326        else /* tyfv(tyml) */ 
    43164327        {       if ((retregs &= mLSW) == 0) 
    43174328                        retregs = mLSW & ~idxregs; 
    43184329                /* Can't use LES if the EA uses ES as a seg override    */ 
    43194330                if (*pretregs & mES && (cs.Iflags & CFSEG) != CFes) 
    43204331                {   cs.Iop = 0xC4;                      /* LES          */ 
    43214332                    c1 = cat(c1,getregs(mES));          /* allocate ES  */ 
    43224333                } 
    43234334        } 
     
    46854696 
    46864697/**************************************** 
    46874698 * Check to see if pointer is NULL. 
    46884699 */ 
    46894700 
    46904701code *cdnullcheck(elem *e,regm_t *pretregs) 
    46914702{   regm_t retregs; 
    46924703    regm_t scratch; 
    46934704    unsigned reg; 
    46944705    code *c; 
    46954706    code *cs; 
    46964707 
    46974708    assert(!I16); 
    46984709    retregs = *pretregs; 
    46994710    if ((retregs & allregs) == 0) 
    47004711        retregs |= allregs; 
    47014712    c = codelem(e->E1,&retregs,FALSE); 
    47024713    scratch = allregs & ~retregs; 
    47034714    cs = allocreg(&scratch,&reg,TYint); 
    47044715    unsigned rex = I64 ? REX_W : 0; 
    4705     cs = genc1(cs,0x8B,(rex << 16) | modregxrmx(2,reg,findreg(retregs)),FLconst,0); // MOV reg,0[e] 
     4716    cs = genc1(cs,0x8B,(rex << 16) | buildModregrm(2,reg,findreg(retregs)),FLconst,0); // MOV reg,0[e] 
    47064717    return cat3(c,cs,fixresult(e,retregs,pretregs)); 
    47074718} 
    47084719 
    47094720#endif // !SPP 
  • branches/dmd-1.x/src/backend/cod3.c

    r767 r768  
    22992299            ADD p[ESP],d 
    23002300           For direct call: 
    23012301            JMP sfunc 
    23022302           For virtual call: 
    23032303            MOV EAX, p[ESP]                     EAX = this 
    23042304            MOV EAX, d2[EAX]                    EAX = this->vptr 
    23052305            JMP i[EAX]                          jump to virtual function 
    23062306         */ 
    23072307        unsigned reg = 0; 
    23082308        if ((targ_ptrdiff_t)d < 0) 
    23092309        { 
    23102310            d = -d; 
    23112311            reg = 5;                            // switch from ADD to SUB 
    23122312        } 
    23132313        if (thunkty == TYmfunc) 
    23142314        {                                       // ADD ECX,d 
    23152315            c = CNIL; 
    23162316            if (d) 
    23172317                c = genc2(c,0x81,modregrm(3,reg,CX),d); 
    23182318        } 
    2319         else if (thunkty == TYjfunc
     2319        else if (thunkty == TYjfunc || (I64 && thunkty == TYnfunc)
    23202320        {                                       // ADD EAX,d 
    23212321            c = CNIL; 
    23222322            if (d) 
    23232323                c = genc2(c,0x81,modregrm(3,reg,I64 ? DI : AX),d); 
    23242324        } 
    23252325        else 
    23262326        { 
    23272327            c = genc(CNIL,0x81,modregrm(2,reg,4), 
    23282328                FLconst,p,                      // to this 
    23292329                FLconst,d);                     // ADD p[ESP],d 
    23302330            c->Isib = modregrm(0,4,SP); 
    23312331        } 
    23322332        if (I64) 
    23332333            c->Irex |= REX_W; 
    23342334    } 
    23352335    else 
    23362336    { 
    23372337        /* 
    23382338           Generate: 
    23392339            MOV BX,SP 
     
    34283428                     config.target_cpu >= TARGET_80486) 
    34293429            { 
    34303430                c->Iop &= 1; 
    34313431                c->Irm = (rm & modregrm(3,0,7)) | (ereg << 3); 
    34323432                if (c->Irex & REX_B) 
    34333433                    c->Irex |= REX_R; 
    34343434                if (!(c->Iflags & CFpsw) && !I16) 
    34353435                    c->Iflags &= ~CFopsize; 
    34363436                goto L1; 
    34373437            } 
    34383438 
    34393439            /* Look for sign extended modregrm displacement, or 0 
    34403440             * displacement. 
    34413441             */ 
    34423442 
    34433443            if (((rm & 0xC0) == 0x80) && // it's a 16/32 bit disp 
    34443444                c->IFL1 == FLconst)      // and it's a constant 
    34453445            { 
    34463446                a = c->IEVpointer1; 
    34473447                if (a == 0 && (rm & 7) != local_BPRM &&         // if 0[disp] 
    3448                     !(local_BPRM == 5 && (rm & 7) == 4 && (c->Isib & 7) == BP && !(c->Irex & REX_B)
     3448                    !(local_BPRM == 5 && (rm & 7) == 4 && (c->Isib & 7) == BP
    34493449                   ) 
    34503450                    c->Irm &= 0x3F; 
    34513451                else if (!I16) 
    34523452                { 
    34533453                    if ((targ_size_t)(targ_schar)a == a) 
    34543454                        c->Irm ^= 0xC0;                 /* do 8 sx      */ 
    34553455                } 
    34563456                else if (((targ_size_t)(targ_schar)a & 0xFFFF) == (a & 0xFFFF)) 
    34573457                    c->Irm ^= 0xC0;                     /* do 8 sx      */ 
    34583458            } 
    34593459 
    34603460            /* Look for LEA reg,[ireg], replace with MOV reg,ireg       */ 
    34613461            else if (op == 0x8D) 
    34623462            {   rm = c->Irm & 7; 
    34633463                mod = c->Irm & modregrm(3,0,0); 
    34643464                if (mod == 0) 
    34653465                { 
    34663466                    if (!I16) 
    34673467                    { 
    34683468                        switch (rm) 
     
    52575257                    break; 
    52585258                case FLswitch: 
    52595259                case FLblockoff: 
    52605260                case FLlocalsize: 
    52615261                case FLframehandler: 
    52625262                case 0: 
    52635263                    break; 
    52645264                case FLdatseg: 
    52655265                    printf(" %d.%llx",c->IEVseg1,(unsigned long long)c->IEVpointer1); 
    52665266                    break; 
    52675267                case FLauto: 
    52685268                case FLreg: 
    52695269                case FLdata: 
    52705270                case FLudata: 
    52715271                case FLpara: 
    52725272                case FLtmp: 
    52735273                case FLbprel: 
    52745274                case FLtlsdata: 
    52755275                    printf(" sym='%s'",c->IEVsym1->Sident); 
    52765276                    break; 
     5277                case FLextern: 
     5278                    printf(" FLextern offset = %4d",(int)c->IEVoffset1); 
     5279                    break; 
    52775280                default: 
    52785281                    WRFL((enum FL)c->IFL1); 
    52795282                    break; 
    52805283            } 
    52815284        } 
    52825285  } 
    52835286  if (ins & T) 
    52845287  {     printf(" "); WRFL((enum FL)c->IFL2); 
    52855288        switch (c->IFL2) 
    52865289        { 
    52875290            case FLconst: 
    52885291                printf(" int = %4d",c->IEV2.Vuns); 
    52895292                break; 
    52905293            case FLblock: 
    52915294                printf(" block = %p",c->IEV2.Vblock); 
    52925295                break; 
    52935296            case FLswitch: 
    52945297            case FLblockoff: 
    52955298            case 0: 
    52965299            case FLlocalsize: 
  • branches/dmd-1.x/src/backend/cod4.c

    r767 r768  
    346346        if (!(retregs == 0 && 
    347347              (e2oper == OPconst || e2oper == OPvar || e2oper == OPind)) 
    348348           ) 
    349349            return eq87(e,pretregs); 
    350350        if (config.target_cpu >= TARGET_PentiumPro && 
    351351            (e2oper == OPvar || e2oper == OPind) 
    352352           ) 
    353353            return eq87(e,pretregs); 
    354354        if (tyml == TYldouble || tyml == TYildouble) 
    355355            return eq87(e,pretregs); 
    356356  } 
    357357 
    358358  unsigned sz = tysize[tyml];           // # of bytes to transfer 
    359359  assert((int)sz > 0); 
    360360 
    361361  if (retregs == 0)                     /* if no return value           */ 
    362362  {     int fl; 
    363363 
    364364        if ((e2oper == OPconst ||       /* if rvalue is a constant      */ 
    365365             e2oper == OPrelconst && 
     366             !(I64 && config.flags3 & CFG3pic) && 
    366367             ((fl = el_fl(e2)) == FLdata || 
    367368              fl==FLudata || fl == FLextern) && 
    368369             !(e2->EV.sp.Vsym->ty() & mTYcs) 
    369370            ) && 
    370371            !evalinregister(e2) && 
    371372            !e1->Ecount)        /* and no CSE headaches */ 
    372373        { 
    373374            // Look for special case of (*p++ = ...), where p is a register variable 
    374375            if (e1->Eoper == OPind && 
    375376                ((e11 = e1->E1)->Eoper == OPpostinc || e11->Eoper == OPpostdec) && 
    376377                e11->E1->Eoper == OPvar && 
    377378                e11->E1->EV.sp.Vsym->Sfl == FLreg && 
    378379                (!I16 || e11->E1->EV.sp.Vsym->Sregm & IDXREGS) 
    379380               ) 
    380381            { 
    381382                postinc = e11->E2->EV.Vint; 
    382383                if (e11->Eoper == OPpostdec) 
    383384                    postinc = -postinc; 
    384385                cl = getlvalue(&cs,e11,RMstore); 
    385386                freenode(e11->E2); 
    386387            } 
    387388            else 
    388389            {   postinc = 0; 
    389390                cl = getlvalue(&cs,e1,RMstore); 
    390391 
    391392                if (e2oper == OPconst && 
    392393                    config.flags4 & CFG4speed && 
    393394                    (config.target_cpu == TARGET_Pentium || 
    394395                     config.target_cpu == TARGET_PentiumMMX) && 
    395396                    (cs.Irm & 0xC0) == 0x80 
    396397                   ) 
    397398                { 
    398399                    if (I64 && sz == 8 && e2->EV.Vpointer) 
    399400                    { 
    400401                        // MOV reg,imm64 
    401402                        // MOV EA,reg 
    402403                        regm_t rregm = allregs & ~idxregm(&cs); 
    403404                        unsigned reg; 
    404                         cl = regwithvalue(cl,rregm,e2->EV.Vpointer,&reg,CFoffset64); 
     405                        cl = regwithvalue(cl,rregm,e2->EV.Vpointer,&reg,64); 
    405406                        cs.Iop = 0x89; 
    406407                        cs.Irm |= modregrm(0,reg & 7,0); 
    407408                        if (reg & 8) 
    408409                            cs.Irex |= REX_R; 
    409410                        c = gen(cl,&cs); 
    410411                        freenode(e2); 
    411412                        goto Lp; 
    412413                    } 
    413414                    if ((sz == REGSIZE || (I64 && sz == 4)) && e2->EV.Vint) 
    414415                    { 
    415416                        // MOV reg,imm 
    416417                        // MOV EA,reg 
    417418                        regm_t rregm = allregs & ~idxregm(&cs); 
    418419                        unsigned reg; 
    419420                        cl = regwithvalue(cl,rregm,e2->EV.Vint,&reg,0); 
    420421                        cs.Iop = 0x89; 
    421422                        cs.Irm |= modregrm(0,reg & 7,0); 
    422423                        if (reg & 8) 
    423424                            cs.Irex |= REX_R; 
    424425                        c = gen(cl,&cs); 
     
    475476            else 
    476477            { 
    477478                assert(e2oper == OPconst); 
    478479                cs.IFL2 = FLconst; 
    479480                targ_size_t *p = (targ_size_t *) &(e2->EV); 
    480481                cs.IEV2.Vsize_t = *p; 
    481482                // Look for loading a register variable 
    482483                if ((cs.Irm & 0xC0) == 0xC0) 
    483484                {   unsigned reg = cs.Irm & 7; 
    484485 
    485486                    if (cs.Irex & REX_B) 
    486487                        reg |= 8; 
    487488                    if (I64 && sz == 8) 
    488489                        cl = movregconst(cl,reg,*p,CFoffset64); 
    489490                    else 
    490491                        cl = movregconst(cl,reg,*p,1 ^ (cs.Iop & 1)); 
    491492                    if (sz == 2 * REGSIZE) 
    492493                    {   getlvalue_msw(&cs); 
    493494                        cl = movregconst(cl,cs.Irm & 7,p[1],0); 
    494495                    } 
     496                } 
     497                else if (I64 && sz == 8 && *p != *(unsigned *)p) 
     498                { 
     499                    // MOV reg,imm64 
     500                    // MOV EA,reg 
     501                    regm_t rregm = allregs & ~idxregm(&cs); 
     502                    unsigned reg; 
     503                    cl = regwithvalue(cl,rregm,e2->EV.Vpointer,&reg,64); 
     504                    cs.Iop = 0x89; 
     505                    cs.Irm |= modregrm(0,reg & 7,0); 
     506                    if (reg & 8) 
     507                        cs.Irex |= REX_R; 
     508                    c = gen(cl,&cs); 
     509                    freenode(e2); 
     510                    goto Lp; 
    495511                } 
    496512                else 
    497513                {   int regsize; 
    498514 
    499515                    i = sz; 
    500516                    do 
    501517                    {   regsize = REGSIZE; 
    502518                        retregs = (sz == 1) ? BYTEREGS : allregs; 
    503519                        if (i >= 4 && I16 && I386) 
    504520                        { 
    505521                            regsize = 4; 
    506522                            cs.Iflags |= CFopsize;      // use opsize to do 32 bit operation 
    507523                        } 
    508524                        else 
    509525                        { 
    510526                            if (reghasvalue(retregs,*p,&reg)) 
    511527                            { 
    512528                                cs.Iop = (cs.Iop & 1) | 0x88; 
    513529                                cs.Irm |= modregrm(0,reg & 7,0); // MOV EA,reg 
    514530                                if (reg & 8) 
     
    673689  } 
    674690  if (e1->Ecount ||                     /* if lvalue is a CSE or        */ 
    675691      regvar)                           /* rvalue can't be a CSE        */ 
    676692  { 
    677693        c = cat(c,getregs_imm(retregs));        // necessary if both lvalue and 
    678694                                        //  rvalue are CSEs (since a reg 
    679695                                        //  can hold only one e at a time) 
    680696        cssave(e1,retregs,EOP(e1));     /* if lvalue is a CSE           */ 
    681697  } 
    682698 
    683699    c = cat4(cr,cl,c,fixresult(e,retregs,pretregs)); 
    684700Lp: 
    685701    if (postinc) 
    686702    { 
    687703        int reg = findreg(idxregm(&cs)); 
    688704        if (*pretregs & mPSW) 
    689705        {   // Use LEA to avoid touching the flags 
    690706            unsigned rm = cs.Irm & 7; 
    691707            if (cs.Irex & REX_B) 
    692708                rm |= 8; 
    693             c = genc1(c,0x8D,modregxrmx(2,reg,rm),FLconst,postinc); 
     709            c = genc1(c,0x8D,buildModregrm(2,reg,rm),FLconst,postinc); 
    694710            if (sz == 8) 
    695711                code_orrex(c, REX_W); 
    696712        } 
    697713        else if (I64) 
    698714        { 
    699715            c = genc2(c,0x81,modregrmx(3,0,reg),postinc); 
    700716            if (sz == 8) 
    701717                code_orrex(c, REX_W); 
    702718        } 
    703719        else 
    704720        { 
    705721            if (postinc == 1) 
    706722                c = gen1(c,0x40 + reg);         // INC reg 
    707723            else if (postinc == -(targ_int)1) 
    708724                c = gen1(c,0x48 + reg);         // DEC reg 
    709725            else 
    710726            { 
    711727                c = genc2(c,0x81,modregrm(3,0,reg),postinc); 
    712728            } 
    713729        } 
     
    18171833            if (I64 && byte && (reg >= 4 || rreg >= 4)) 
    18181834                c->Irex |= REX;                 // address byte registers 
    18191835        } 
    18201836        else 
    18211837        {   assert(sz <= 2 * REGSIZE); 
    18221838 
    18231839            /* Compare MSW, if they're equal then compare the LSW       */ 
    18241840            reg = findregmsw(retregs); 
    18251841            rreg = findregmsw(rretregs); 
    18261842            c = genregs(CNIL,0x3B ^ reverse,reg,rreg);  /* CMP reg,rreg */ 
    18271843            if (!I16 && sz == 6) 
    18281844                c->Iflags |= CFopsize;          /* seg is only 16 bits  */ 
    18291845            genjmp(c,JNE,FLcode,(block *) ce);          /* JNE nop      */ 
    18301846 
    18311847            reg = findreglsw(retregs); 
    18321848            rreg = findreglsw(rretregs); 
    18331849            genregs(c,0x3B ^ reverse,reg,rreg);         /* CMP reg,rreg */ 
    18341850        } 
    18351851        break; 
    18361852      case OPrelconst: 
     1853        if (I64 && config.flags3 & CFG3pic) 
     1854            goto L2; 
    18371855        fl = el_fl(e2); 
    18381856        switch (fl) 
    18391857        {   case FLfunc: 
    18401858                fl = FLextern;          // so it won't be self-relative 
    18411859                break; 
    18421860            case FLdata: 
    18431861            case FLudata: 
    18441862            case FLextern: 
    18451863                if (sz > REGSIZE)       // compare against DS, not DGROUP 
    18461864                    goto L2; 
    18471865                break; 
    18481866            case FLfardata: 
    18491867                break; 
    18501868            default: 
    18511869                goto L2; 
    18521870        } 
    18531871        cs.IFL2 = fl; 
    18541872        cs.IEVsym2 = e2->EV.sp.Vsym; 
    18551873        offset2 = e2->EV.sp.Voffset; 
    18561874        if (sz > REGSIZE) 
  • branches/dmd-1.x/src/backend/code.h

    r738 r768  
    635635#else 
    636636code *allocreg (regm_t *pretregs , unsigned *preg , tym_t tym ); 
    637637#endif 
    638638void useregs (regm_t regm ); 
    639639code *getregs (regm_t r ); 
    640640code *getregs_imm (regm_t r ); 
    641641code *cse_flush(int); 
    642642void cssave (elem *e , regm_t regm , unsigned opsflag ); 
    643643bool evalinregister (elem *e ); 
    644644regm_t getscratch(); 
    645645code *codelem (elem *e , regm_t *pretregs , bool constflag ); 
    646646const char *regm_str(regm_t rm); 
    647647int numbitsset(regm_t); 
    648648 
    649649/* cod1.c */ 
    650650extern int clib_inited; 
    651651 
    652652int isscaledindex(elem *); 
    653653int ssindex(int op,targ_uns product); 
    654654void buildEA(code *c,int base,int index,int scale,targ_size_t disp); 
     655unsigned buildModregrm(int mod, int reg, int rm); 
    655656void andregcon (con_t *pregconsave); 
    656657code *docommas (elem **pe ); 
    657658code *gencodelem(code *c,elem *e,regm_t *pretregs,bool constflag); 
    658659void gensaverestore(regm_t, code **, code **); 
    659660code *genstackclean(code *c,unsigned numpara,regm_t keepmsk); 
    660661code *logexp (elem *e , int jcond , unsigned fltarg , code *targ ); 
    661662code *loadea (elem *e , code *cs , unsigned op , unsigned reg , targ_size_t offset , regm_t keepmsk , regm_t desmsk ); 
    662663unsigned getaddrmode (regm_t idxregs ); 
    663664void setaddrmode(code *c, regm_t idxregs); 
    664665void getlvalue_msw(code *); 
    665666void getlvalue_lsw(code *); 
    666667code *getlvalue (code *pcs , elem *e , regm_t keepmsk ); 
    667668code *scodelem (elem *e , regm_t *pretregs , regm_t keepmsk , bool constflag ); 
    668669code *fltregs (code *pcs , tym_t tym ); 
    669670code *tstresult (regm_t regm , tym_t tym , unsigned saveflag ); 
    670671code *fixresult (elem *e , regm_t retregs , regm_t *pretregs ); 
    671672code *callclib (elem *e , unsigned clib , regm_t *pretregs , regm_t keepmask ); 
    672673cd_t cdfunc; 
    673674cd_t cdstrthis; 
    674675code *params(elem *, unsigned); 
  • branches/dmd-1.x/src/backend/el.c

    r738 r768  
    32053205  } 
    32063206  WROP(e->Eoper); 
    32073207  dbg_printf(" "); 
    32083208  if (SCPP && PARSER) 
    32093209  { 
    32103210        if (e->ET) 
    32113211        {   type_debug(e->ET); 
    32123212            if (tybasic(e->ET->Tty) == TYstruct 
    32133213#if !TX86 
    32143214 && (e->PEFflags & PEFstrsize) 
    32153215#endif 
    32163216               ) 
    32173217                dbg_printf("%d ", (int)type_size(e->ET)); 
    32183218            WRTYxx(e->ET->Tty); 
    32193219        } 
    32203220  } 
    32213221  else 
    32223222  { 
    32233223        if ((e->Eoper == OPstrpar || e->Eoper == OPstrctor || e->Eoper == OPstreq) || 
    32243224            e->Ety == TYstruct) 
    3225             dbg_printf("%d ", (int)type_size(e->ET)); 
     3225            if (e->ET) 
     3226                dbg_printf("%d ", (int)type_size(e->ET)); 
    32263227        WRTYxx(e->Ety); 
    32273228  } 
    32283229  if (OTunary(e->Eoper)) 
    32293230  { 
    32303231        if (e->E2) 
    32313232            dbg_printf("%p %p\n",e->E1,e->E2); 
    32323233        else 
    32333234            dbg_printf("%p\n",e->E1); 
    32343235        elem_print(e->E1); 
    32353236  } 
    32363237  else if (OTbinary(e->Eoper)) 
    32373238  { 
    32383239        if (!PARSER && e->Eoper == OPstreq) 
    32393240                dbg_printf("bytes=%d ", (int)type_size(e->ET)); 
    32403241        dbg_printf("%p %p\n",e->E1,e->E2); 
    32413242        elem_print(e->E1); 
    32423243        elem_print(e->E2); 
    32433244  } 
    32443245  else 
    32453246  { 
  • branches/dmd-1.x/src/backend/gloop.c

    r738 r768  
    21342134                c.Vchar = 1; 
    21352135                break; 
    21362136            case TYshort: 
    21372137            case TYushort: 
    21382138            case TYchar16: 
    21392139            case TYwchar_t:             // BUG: what about 4 byte wchar_t's? 
    21402140                c.Vshort = 1; 
    21412141                break; 
    21422142#if TX86 
    21432143            case TYsptr: 
    21442144            case TYcptr: 
    21452145#if JHANDLE 
    21462146            case TYjhandle: 
    21472147#endif 
    21482148            case TYnptr: 
    21492149#endif 
    21502150            case TYnullptr: 
    21512151            case TYfptr: 
    21522152            case TYvptr: 
    21532153                ty = TYint; 
     2154                if (I64) 
     2155                    ty = TYllong; 
    21542156                /* FALL-THROUGH */ 
    21552157            case TYint: 
    21562158            case TYuint: 
    21572159                c.Vint = 1; 
    21582160                break; 
    21592161#if TX86 
    21602162            case TYhptr: 
    21612163                ty = TYlong; 
    21622164#endif 
    21632165            case TYlong: 
    21642166            case TYulong: 
    21652167            case TYdchar: 
    21662168            default: 
    21672169                c.Vlong = 1; 
    21682170                break; 
    21692171#if 0 
    21702172            default: 
    21712173                printf("ty = x%x\n", tybasic(ty)); 
    21722174                assert(0); 
    21732175#endif 
  • branches/dmd-1.x/src/e2ir.c

    r767 r768  
    31253125        if (!func->isThis()) 
    31263126            error("delegates are only for non-static functions"); 
    31273127 
    31283128        if (!func->isVirtual() || 
    31293129            directcall || 
    31303130            func->isFinal()) 
    31313131        { 
    31323132            ep = el_ptr(sfunc); 
    31333133        } 
    31343134        else 
    31353135        { 
    31363136            // Get pointer to function out of virtual table 
    31373137            unsigned vindex; 
    31383138 
    31393139            assert(ethis); 
    31403140            ep = el_same(&ethis); 
    31413141            ep = el_una(OPind, TYnptr, ep); 
    31423142            vindex = func->vtblIndex; 
    31433143 
    31443144            // Build *(ep + vindex * 4) 
    3145             ep = el_bin(OPadd,TYnptr,ep,el_long(TYsize_t, vindex * 4)); 
     3145            ep = el_bin(OPadd,TYnptr,ep,el_long(TYsize_t, vindex * PTRSIZE)); 
    31463146            ep = el_una(OPind,TYnptr,ep); 
    31473147        } 
    31483148 
    31493149//      if (func->tintro) 
    31503150//          func->error(loc, "cannot form delegate due to covariant return type"); 
    31513151    } 
    31523152    if (ethis->Eoper == OPcomma) 
    31533153    { 
    31543154        ethis->E2 = el_pair(TYdarray, ethis->E2, ep); 
    31553155        ethis->Ety = TYdarray; 
    31563156        e = ethis; 
    31573157    } 
    31583158    else 
    31593159        e = el_pair(TYdarray, ethis, ep); 
    31603160    el_setLoc(e,loc); 
    31613161    return e; 
    31623162} 
    31633163 
    31643164elem *DotTypeExp::toElem(IRState *irs) 
    31653165{ 
  • branches/dmd-1.x/src/msc.c

    r729 r768  
    309309{ 
    310310    int sz = (tybasic(ty) == TYvoid) ? 1 : tysize(ty); 
    311311#ifdef DEBUG 
    312312    if (sz == -1) 
    313313        WRTYxx(ty); 
    314314#endif 
    315315    assert(sz!= -1); 
    316316    return sz; 
    317317} 
    318318 
    319319/******************************* 
    320320 * Replace (e) with ((stmp = e),stmp) 
    321321 */ 
    322322 
    323323elem *exp2_copytotemp(elem *e) 
    324324{ 
    325325    //printf("exp2_copytotemp()\n"); 
    326326    elem_debug(e); 
    327327    Symbol *stmp = symbol_genauto(e); 
    328328    elem *eeq = el_bin(OPeq,e->Ety,el_var(stmp),e); 
    329     if (e->Ety == TYstruct) 
     329    elem *er = el_bin(OPcomma,e->Ety,eeq,el_var(stmp)); 
     330    if (tybasic(e->Ety) == TYstruct || tybasic(e->Ety) == TYarray) 
    330331    { 
    331332        eeq->Eoper = OPstreq; 
    332333        eeq->ET = e->ET; 
    333     } 
    334     return el_bin(OPcomma,e->Ety,eeq,el_var(stmp)); 
     334        eeq->E1->ET = e->ET; 
     335        er->ET = e->ET; 
     336        er->E2->ET = e->ET; 
     337    } 
     338    return er; 
    335339} 
    336340 
    337341/**************************** 
    338342 * Generate symbol of type ty at DATA:offset 
    339343 */ 
    340344 
    341345symbol *symboldata(targ_size_t offset,tym_t ty) 
    342346{ 
    343347    symbol *s = symbol_generate(SClocstat, type_fake(ty)); 
    344348    s->Sfl = FLdata; 
    345349    s->Soffset = offset; 
    346350    s->Sseg = DATA; 
    347351    symbol_keep(s);             // keep around 
    348352    return s; 
    349353} 
    350354 
    351355/************************************ 
    352356 * Add symbol to slist. 
    353357 */ 
    354358 
  • branches/dmd-1.x/src/mtype.h

    r729 r768  
    140140    #define tfloat80    basic[Tfloat80] 
    141141 
    142142    #define timaginary32 basic[Timaginary32] 
    143143    #define timaginary64 basic[Timaginary64] 
    144144    #define timaginary80 basic[Timaginary80] 
    145145 
    146146    #define tcomplex32  basic[Tcomplex32] 
    147147    #define tcomplex64  basic[Tcomplex64] 
    148148    #define tcomplex80  basic[Tcomplex80] 
    149149 
    150150    #define tbit        basic[Tbit] 
    151151    #define tbool       basic[Tbool] 
    152152    #define tchar       basic[Tchar] 
    153153    #define twchar      basic[Twchar] 
    154154    #define tdchar      basic[Tdchar] 
    155155 
    156156    // Some special types 
    157157    #define tshiftcnt   tint32          // right side of shift expression 
    158158//    #define tboolean  tint32          // result of boolean expression 
    159159    #define tboolean    tbool           // result of boolean expression 
    160     #define tindex      tint32          // array/ptr index 
     160    #define tindex      tsize_t         // array/ptr index 
    161161    static Type *tvoidptr;              // void* 
    162162    #define terror      basic[Terror]   // for error recovery 
    163163 
    164164    #define tsize_t     basic[Tsize_t]          // matches size_t alias 
    165165    #define tptrdiff_t  basic[Tptrdiff_t]       // matches ptrdiff_t alias 
    166166    #define thash_t     tsize_t                 // matches hash_t alias 
    167167 
    168168    static ClassDeclaration *typeinfo; 
    169169    static ClassDeclaration *typeinfoclass; 
    170170    static ClassDeclaration *typeinfointerface; 
    171171    static ClassDeclaration *typeinfostruct; 
    172172    static ClassDeclaration *typeinfotypedef; 
    173173    static ClassDeclaration *typeinfopointer; 
    174174    static ClassDeclaration *typeinfoarray; 
    175175    static ClassDeclaration *typeinfostaticarray; 
    176176    static ClassDeclaration *typeinfoassociativearray; 
    177177    static ClassDeclaration *typeinfoenum; 
    178178    static ClassDeclaration *typeinfofunction; 
    179179    static ClassDeclaration *typeinfodelegate; 
    180180    static ClassDeclaration *typeinfotypelist; 
  • branches/dmd-1.x/src/template.c

    r754 r768  
    36223622            --nest; 
    36233623#if WINDOWS_SEH 
    36243624        } 
    36253625        __except (__ehfilter(GetExceptionInformation())) 
    36263626        { 
    36273627            global.gag = 0;            // ensure error message gets printed 
    36283628            error("recursive expansion"); 
    36293629            fatal(); 
    36303630        } 
    36313631#endif 
    36323632    } 
    36333633 
    36343634  Laftersemantic: 
    36353635    sc2->pop(); 
    36363636 
    36373637    scope->pop(); 
    36383638 
    36393639    // Give additional context info if error occurred during instantiation 
    36403640    if (global.errors != errorsave) 
    36413641    { 
    3642         error("error instantiating"); 
     3642        error(loc, "error instantiating"); 
    36433643        if (tinst) 
    36443644        {   tinst->printInstantiationTrace(); 
    36453645            if (!global.gag) 
    36463646                fatal(); 
    36473647        } 
    36483648        errors = 1; 
    36493649        if (global.gag) 
    36503650        {   // Try to reset things so we can try again later to instantiate it 
    36513651            tempdecl->instances.remove(tempdecl_instance_idx); 
    36523652            if (!(sc->flags & SCOPEstaticif)) 
    36533653            {   // Bugzilla 4302 for discussion 
    36543654                semanticRun = 0; 
    36553655                inst = NULL; 
    36563656            } 
    36573657        } 
    36583658    } 
    36593659 
    36603660#if LOG 
    36613661    printf("-TemplateInstance::semantic('%s', this=%p)\n", toChars(), this); 
    36623662#endif 
  • trunk/src/backend/cg87.c

    r767 r768  
    20452045            cs.Iop = op1; 
    20462046            c2 = getlvalue(&cs, e->E1, 0); 
    20472047            cs.IEVoffset1 += sz; 
    20482048            cs.Irm |= modregrm(0, op2, 0); 
    20492049            c2 = cat(c2, makesure87(e->E2, sz, 0, 0)); 
    20502050            c2 = gen(c2, &cs); 
    20512051            c2 = genfwait(c2); 
    20522052            c2 = cat(c2, makesure87(e->E2,  0, 1, 0)); 
    20532053        } 
    20542054        else 
    20552055        { 
    20562056            c2 = loadea(e->E1,&cs,op1,op2,sz,0,0); 
    20572057            c2 = genfwait(c2); 
    20582058        } 
    20592059        if (fxch) 
    20602060            c2 = genf2(c2,0xD9,0xC8 + 1);       // FXCH ST(1) 
    20612061        cs.IEVoffset1 -= sz; 
    20622062        gen(c2, &cs); 
    20632063        if (fxch) 
    20642064            genf2(c2,0xD9,0xC8 + 1);            // FXCH ST(1) 
    2065 #if LNGDBLSIZE == 12 
    2066         if (op1 == 0xDB) 
    2067         { 
    2068             cs.Iop = 0xC7;                      // MOV EA+10,0 
    2069             NEWREG(cs.Irm, 0); 
    2070             cs.IEV1.sp.Voffset += 10; 
    2071             cs.IFL2 = FLconst; 
    2072             cs.IEV2.Vint = 0; 
    2073             cs.Iflags |= CFopsize; 
    2074             c2 = gen(c2, &cs); 
    2075             cs.IEVoffset1 += 12; 
    2076             c2 = gen(c2, &cs);                  // MOV EA+22,0 
    2077         } 
    2078 #endif 
     2065        if (tysize[TYldouble] == 12) 
     2066        { 
     2067            if (op1 == 0xDB) 
     2068            { 
     2069                cs.Iop = 0xC7;                      // MOV EA+10,0 
     2070                NEWREG(cs.Irm, 0); 
     2071                cs.IEV1.sp.Voffset += 10; 
     2072                cs.IFL2 = FLconst; 
     2073                cs.IEV2.Vint = 0; 
     2074                cs.Iflags |= CFopsize; 
     2075                c2 = gen(c2, &cs); 
     2076                cs.IEVoffset1 += 12; 
     2077                c2 = gen(c2, &cs);                  // MOV EA+22,0 
     2078            } 
     2079        } 
    20792080        if (tysize[TYldouble] == 16) 
    20802081        { 
    2081         if (op1 == 0xDB) 
    2082        
    2083             cs.Iop = 0xC7;                      // MOV EA+10,0 
    2084             NEWREG(cs.Irm, 0); 
    2085             cs.IEV1.sp.Voffset += 10; 
    2086             cs.IFL2 = FLconst; 
    2087             cs.IEV2.Vint = 0; 
    2088             cs.Iflags |= CFopsize; 
    2089             c2 = gen(c2, &cs); 
    2090  
    2091             cs.IEV1.sp.Voffset += 2; 
    2092             cs.Iflags &= ~CFopsize; 
    2093             c2 = gen(c2, &cs); 
    2094  
    2095             cs.IEVoffset1 += 14; 
    2096             cs.Iflags |= CFopsize; 
    2097             c2 = gen(c2, &cs); 
    2098  
    2099             cs.IEV1.sp.Voffset += 2; 
    2100             cs.Iflags &= ~CFopsize; 
    2101             c2 = gen(c2, &cs); 
    2102        
     2082            if (op1 == 0xDB) 
     2083           
     2084                cs.Iop = 0xC7;                      // MOV EA+10,0 
     2085                NEWREG(cs.Irm, 0); 
     2086                cs.IEV1.sp.Voffset += 10; 
     2087                cs.IFL2 = FLconst; 
     2088                cs.IEV2.Vint = 0; 
     2089                cs.Iflags |= CFopsize; 
     2090                c2 = gen(c2, &cs); 
     2091 
     2092                cs.IEV1.sp.Voffset += 2; 
     2093                cs.Iflags &= ~CFopsize; 
     2094                c2 = gen(c2, &cs); 
     2095 
     2096                cs.IEV1.sp.Voffset += 14; 
     2097                cs.Iflags |= CFopsize; 
     2098                c2 = gen(c2, &cs); 
     2099 
     2100                cs.IEV1.sp.Voffset += 2; 
     2101                cs.Iflags &= ~CFopsize; 
     2102                c2 = gen(c2, &cs); 
     2103           
    21032104        } 
    21042105        c2 = genfwait(c2); 
    21052106        freenode(e->E1); 
    21062107        return cat3(c1,c2,fixresult_complex87(e,mST01 | mPSW,pretregs)); 
    21072108} 
    21082109 
    21092110/******************************* 
    21102111 * Perform an assignment while converting to integral type, 
    21112112 * i.e. handle (e1 = (int) e2) 
    21122113 */ 
    21132114 
    21142115code *cnvteq87(elem *e,regm_t *pretregs) 
    21152116{ 
    21162117        regm_t retregs; 
    21172118        code *c1,*c2; 
    21182119        code cs; 
    21192120        unsigned op1; 
    21202121        unsigned op2; 
    21212122        tym_t ty1; 
    21222123 
  • trunk/src/backend/cgcod.c

    r767 r768  
    15341534        case TYint: 
    15351535        case TYuint: 
    15361536#if JHANDLE 
    15371537        case TYjhandle: 
    15381538#endif 
    15391539        case TYnullptr: 
    15401540        case TYnptr: 
    15411541        case TYsptr: 
    15421542        case TYcptr: 
    15431543            return mAX; 
    15441544 
    15451545        case TYfloat: 
    15461546        case TYifloat: 
    15471547            if (I64) 
    15481548                return mXMM0; 
    15491549            if (config.exe & EX_flat) 
    15501550                return mST0; 
    15511551        case TYlong: 
    15521552        case TYulong: 
    15531553        case TYdchar: 
    1554             if (I32
     1554            if (!I16
    15551555                return mAX; 
    15561556        case TYfptr: 
    15571557        case TYhptr: 
    15581558            return mDX | mAX; 
    15591559 
    15601560        case TYcent: 
    15611561        case TYucent: 
    15621562            assert(I64); 
    15631563            return mDX | mAX; 
    15641564 
    15651565        case TYvptr: 
    15661566            return mDX | mBX; 
    15671567 
    15681568        case TYdouble: 
    15691569        case TYdouble_alias: 
    15701570        case TYidouble: 
    15711571            if (I64) 
    15721572                return mXMM0; 
    15731573            if (config.exe & EX_flat) 
    15741574                return mST0; 
  • trunk/src/backend/cod1.c

    r767 r768  
    171171            if (index == -1) 
    172172                rm = modregrm(0,0,5); 
    173173            else 
    174174            { 
    175175                rm  = modregrm(0,0,4); 
    176176                sib = modregrm(ss,index & 7,5); 
    177177                if (index & 8) 
    178178                    rex |= REX_X; 
    179179            } 
    180180        } 
    181181        else if (index == -1) 
    182182        { 
    183183            if (base == SP) 
    184184            { 
    185185                rm  = modregrm(2,0,4); 
    186186                sib = modregrm(0,4,SP); 
    187187            } 
    188188            else 
    189189            {   rm = modregrm(2,0,base & 7); 
    190190                if (base & 8) 
    191                     rex |= REX_B; 
     191                {   rex |= REX_B; 
     192                    if (base == R12) 
     193                    { 
     194                        rm = modregrm(2,0,4); 
     195                        sib = modregrm(0,4,4); 
     196                    } 
     197                } 
    192198            } 
    193199        } 
    194200        else 
    195201        { 
    196202            rm  = modregrm(2,0,4); 
    197203            sib = modregrm(ss,index & 7,base & 7); 
    198204            if (index & 8) 
    199205                rex |= REX_X; 
    200206            if (base & 8) 
    201207                rex |= REX_B; 
    202208        } 
    203209    } 
    204210    else 
    205211    { 
    206212        // -1 AX CX DX BX SP BP SI DI 
    207213        static unsigned char EA16rm[9][9] = 
    208214        { 
    209215            {   0x06,0x09,0x09,0x09,0x87,0x09,0x86,0x84,0x85,   },      // -1 
    210216            {   0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,   },      // AX 
    211217            {   0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,   },      // CX 
    212218            {   0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,   },      // DX 
    213219            {   0x87,0x09,0x09,0x09,0x09,0x09,0x09,0x80,0x81,   },      // BX 
    214220            {   0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,0x09,   },      // SP 
    215221            {   0x86,0x09,0x09,0x09,0x09,0x09,0x09,0x82,0x83,   },      // BP 
    216222            {   0x84,0x09,0x09,0x09,0x80,0x09,0x82,0x09,0x09,   },      // SI 
    217223            {   0x85,0x09,0x09,0x09,0x81,0x09,0x83,0x09,0x09,   }       // DI 
    218224        }; 
    219225 
    220226        assert(scale == 1); 
    221227        rm = EA16rm[base + 1][index + 1]; 
    222228        assert(rm != 9); 
    223229    } 
    224230    c->Irm = rm; 
    225231    c->Isib = sib; 
    226232    c->Irex = rex; 
    227233    c->IFL1 = FLconst; 
    228234    c->IEV1.Vuns = disp; 
     235} 
     236 
     237/********************************************* 
     238 * Build REX, modregrm and sib bytes 
     239 */ 
     240 
     241unsigned buildModregrm(int mod, int reg, int rm) 
     242{   unsigned m; 
     243    if (I16) 
     244        m = modregrm(mod, reg, rm); 
     245    else 
     246    { 
     247        unsigned rex = 0; 
     248        if ((rm & 7) == SP && mod != 3) 
     249            m = (modregrm(0,4,SP) << 8) | modregrm(mod,reg & 7,4); 
     250        else 
     251            m = modregrm(mod,reg & 7,rm & 7); 
     252        if (reg & 8) 
     253            m |= REX_R << 16; 
     254        if (rm & 8) 
     255            m |= REX_B << 16; 
     256    } 
     257    return m; 
    229258} 
    230259 
    231260/************************** 
    232261 * For elems in regcon that don't match regconsave, 
    233262 * clear the corresponding bit in regcon.cse.mval. 
    234263 * Do same for regcon.immed. 
    235264 */ 
    236265 
    237266void andregcon(con_t *pregconsave) 
    238267{ 
    239268    regm_t m = ~1; 
    240269    for (int i = 0; i < REGMAX; i++) 
    241270    {   if (pregconsave->cse.value[i] != regcon.cse.value[i]) 
    242271            regcon.cse.mval &= m; 
    243272        if (pregconsave->immed.value[i] != regcon.immed.value[i]) 
    244273            regcon.immed.mval &= m; 
    245274        m <<= 1; 
    246275        m |= 1; 
    247276    } 
    248277    //printf("regcon.cse.mval = x%x, regconsave->mval = x%x ",regcon.cse.mval,pregconsave->cse.mval); 
     
    860889                break; 
    861890            default: 
    862891#ifdef DEBUG 
    863892                elem_print(e); 
    864893#endif 
    865894                assert(0); 
    866895        } 
    867896        e1ty = tybasic(e1->Ety); 
    868897        if (e1isadd) 
    869898        {   e12 = e1->E2; 
    870899            e11 = e1->E1; 
    871900        } 
    872901 
    873902        /* First see if we can replace *(e+&v) with 
    874903         *      MOV     idxreg,e 
    875904         *      EA =    [ES:] &v+idxreg 
    876905         */ 
    877906 
    878907        if (e1isadd && 
    879908            e12->Eoper == OPrelconst && 
     909            !(I64 && config.flags3 & CFG3pic) && 
    880910            (f = el_fl(e12)) != FLfardata && 
    881911            e1->Ecount == e1->Ecomsub && 
    882912            (!e1->Ecount || (~keepmsk & ALLREGS & mMSW) || (e1ty != TYfptr && e1ty != TYhptr)) && 
    883913            tysize(e11->Ety) == REGSIZE 
    884914           ) 
    885915        {   unsigned char t;            /* component of r/m field */ 
    886916            int ss; 
    887917            int ssi; 
    888918 
    889919            /*assert(datafl[f]);*/              /* what if addr of func? */ 
    890920            if (!I16) 
    891921            {   /* Any register can be an index register        */ 
    892922                regm_t idxregs = allregs & ~keepmsk; 
    893923                assert(idxregs); 
    894924 
    895925                /* See if e1->E1 can be a scaled index  */ 
    896926                ss = isscaledindex(e11); 
    897927                if (ss) 
    898928                { 
    899929                    /* Load index register with result of e11->E1       */ 
     
    942972                        assert(!stackfl[f]); 
    943973                        pcs->Irm = modregrm(2,0,4); 
    944974                        pcs->Isib = modregrm(ss1,reg & 7,reg & 7); 
    945975                        if (reg & 8) 
    946976                            pcs->Irex |= REX_X | REX_B; 
    947977                    } 
    948978                    else 
    949979                    {   int rbase; 
    950980                        unsigned r; 
    951981 
    952982                        scratchm = ALLREGS & ~keepmsk; 
    953983                        c = cat(c,allocreg(&scratchm,&r,TYint)); 
    954984 
    955985                        if (ssflags & SSFLnobase1) 
    956986                        {   t = 0; 
    957987                            rbase = 5; 
    958988                        } 
    959989                        else 
    960990                        {   t = 0; 
    961991                            rbase = reg; 
    962                             if (rbase == BP
     992                            if (rbase == BP || rbase == R13
    963993                            {   static unsigned imm32[4] = {1+1,2+1,4+1,8+1}; 
    964994 
    965995                                // IMUL r,BP,imm32 
    966                                 c = genc2(c,0x69,modregxrm(3,r,BP),imm32[ss1]); 
     996                                c = genc2(c,0x69,modregxrmx(3,r,rbase),imm32[ss1]); 
    967997                                goto L7; 
    968998                            } 
    969999                        } 
    9701000 
    9711001                        c = gen2sib(c,0x8D,modregxrm(t,r,4),modregrm(ss1,reg & 7,rbase & 7)); 
    9721002                        if (reg & 8) 
    9731003                            code_orrex(c, REX_X); 
    9741004                        if (rbase & 8) 
    9751005                            code_orrex(c, REX_B); 
    9761006                        if (I64) 
    9771007                            code_orrex(c, REX_W); 
    9781008 
    9791009                        if (ssflags & SSFLnobase1) 
    9801010                        {   code_last(c)->IFL1 = FLconst; 
    9811011                            code_last(c)->IEV1.Vuns = 0; 
    9821012                        } 
    9831013                    L7: 
    9841014                        if (ssflags & SSFLnobase) 
    9851015                        {   t = stackfl[f] ? 2 : 0; 
    9861016                            rbase = 5; 
     
    32193249                        if (!(config.exe & EX_flat)) 
    32203250                        {   seg = CFes; 
    32213251                            retregs |= mES; 
    32223252                        } 
    32233253                        c1 = codelem(e1,&retregs,FALSE); 
    32243254                        break; 
    32253255                    default: 
    32263256#ifdef DEBUG 
    32273257                        elem_print(e1); 
    32283258#endif 
    32293259                        assert(0); 
    32303260                } 
    32313261                reg = findreglsw(retregs); 
    32323262                rm = I16 ? regtorm[reg] : regtorm32[reg]; 
    32333263                if (op16) 
    32343264                    seg |= CFopsize;            // operand size 
    32353265                if (npushes <= 4) 
    32363266                { 
    32373267                    assert(!doneoff); 
    32383268                    for (c2 = CNIL; npushes > 1; npushes--) 
    3239                     {   c2 = genc1(c2,0xFF,modregrmx(2,6,rm),FLconst,pushsize * (npushes - 1));  // PUSH [reg] 
     3269                    {   c2 = genc1(c2,0xFF,buildModregrm(2,6,rm),FLconst,pushsize * (npushes - 1));  // PUSH [reg] 
    32403270                        code_orflag(c2,seg); 
    32413271                        genadjesp(c2,pushsize); 
    32423272                    } 
    3243                     c3 = gen2(CNIL,0xFF,modregrmx(0,6,rm));     // PUSH [reg] 
     3273                    c3 = gen2(CNIL,0xFF,buildModregrm(0,6,rm));     // PUSH [reg] 
    32443274                    c3->Iflags |= seg; 
    32453275                    genadjesp(c3,pushsize); 
    32463276                    ce = cat4(cc,c1,c2,c3); 
    32473277                } 
    32483278                else if (sz) 
    32493279                {   int size; 
    32503280 
    32513281                    c2 = getregs_imm(mCX | retregs); 
    32523282                                                        /* MOV CX,sz/2  */ 
    32533283                    c2 = movregconst(c2,CX,npushes,0); 
    32543284                    if (!doneoff) 
    32553285                    {   /* This disgusting thing should be done when    */ 
    32563286                        /* reg is loaded. Too lazy to fix it now.       */ 
    32573287                                                        /* ADD reg,sz-2 */ 
    32583288                        c2 = genc2(c2,0x81,grex | modregrmx(3,0,reg),sz-pushsize); 
    32593289                    } 
    3260                     c3 = gen2(CNIL,0xFF,modregrmx(0,6,rm));      // PUSH [reg] 
     3290                    c3 = gen2(CNIL,0xFF,buildModregrm(0,6,rm));      // PUSH [reg] 
    32613291                    c3->Iflags |= seg | CFtarg2; 
    3262                     genc2(c3,0x81,grex | modregrmx(3,5,reg),pushsize);  // SUB reg,2 
     3292                    genc2(c3,0x81,grex | buildModregrm(3,5,reg),pushsize);  // SUB reg,2 
    32633293                    size = ((seg & CFSEG) ? -8 : -7) - op16; 
    32643294                    if (code_next(c3)->Iop != 0x81) 
    32653295                        size++; 
    32663296                    //genc2(c3,0xE2,0,size);    // LOOP .-7 or .-8 
    32673297                    genjmp(c3,0xE2,FLcode,(block *)c3);         // LOOP c3 
    32683298                    regimmed_set(CX,0); 
    32693299                    genadjesp(c3,sz); 
    32703300                    ce = cat4(cc,c1,c2,c3); 
    32713301                } 
    32723302                else 
    32733303                    ce = cat(cc,c1); 
    32743304                stackpush += sz; 
    32753305                goto L2; 
    32763306        } 
    32773307    case OPind: 
    32783308        if (!e->Ecount)                         /* if *e1       */ 
    32793309        {       if (sz <= REGSIZE) 
    32803310                {   // Watch out for single byte quantities being up 
    32813311                    // against the end of a segment or in memory-mapped I/O 
    32823312                    if (!(config.exe & EX_flat) && szb == 1) 
     
    36763706  { 
    36773707        regm = allregs; 
    36783708        if (e->Eoper == OPconst) 
    36793709        {       /* TRUE:        OR SP,SP        (SP is never 0)         */ 
    36803710                /* FALSE:       CMP SP,SP       (always equal)          */ 
    36813711                c = genregs(CNIL,(boolres(e)) ? 0x09 : 0x39,SP,SP); 
    36823712                if (I64) 
    36833713                    code_orrex(c, REX_W); 
    36843714        } 
    36853715        else if (sz <= REGSIZE) 
    36863716        { 
    36873717            if (!I16 && (tym == TYfloat || tym == TYifloat)) 
    36883718            {   c = allocreg(&regm,&reg,TYoffset);      /* get a register */ 
    36893719                ce = loadea(e,&cs,0x8B,reg,0,0,0);      // MOV reg,data 
    36903720                c = cat(c,ce); 
    36913721                ce = gen2(CNIL,0xD1,modregrmx(3,4,reg)); /* SHL reg,1      */ 
    36923722                c = cat(c,ce); 
    36933723            } 
    36943724            else 
    36953725            {   cs.IFL2 = FLconst; 
    3696                 cs.IEV2.Vint = 0; 
     3726                cs.IEV2.Vsize_t = 0; 
    36973727                op = (sz == 1) ? 0x80 : 0x81; 
    36983728                c = loadea(e,&cs,op,7,0,0,0);           /* CMP EA,0     */ 
    36993729 
    37003730                // Convert to TEST instruction if EA is a register 
    37013731                // (to avoid register contention on Pentium) 
    37023732                if ((c->Iop & ~1) == 0x38 && 
    37033733                    (c->Irm & modregrm(3,0,0)) == modregrm(3,0,0) 
    37043734                   ) 
    37053735                {   c->Iop = (c->Iop & 1) | 0x84; 
    37063736                    code_newreg(c, c->Irm & 7); 
    37073737                    if (c->Irex & REX_B) 
    3708                         c->Irex = (c->Irex & ~REX_B) | REX_R; 
     3738                        //c->Irex = (c->Irex & ~REX_B) | REX_R; 
     3739                        c->Irex |= REX_R; 
    37093740                } 
    37103741            } 
    37113742        } 
    37123743        else if (sz < 8) 
    37133744        { 
    37143745            c = allocreg(&regm,&reg,TYoffset);          /* get a register */ 
    37153746            if (I32)                                    // it's a 48 bit pointer 
    37163747                ce = loadea(e,&cs,0x0FB7,reg,REGSIZE,0,0); /* MOVZX reg,data+4 */ 
    37173748            else 
    37183749            {   ce = loadea(e,&cs,0x8B,reg,REGSIZE,0,0); /* MOV reg,data+2 */ 
    37193750                if (tym == TYfloat || tym == TYifloat)  // dump sign bit 
    37203751                    gen2(ce,0xD1,modregrm(3,4,reg));    /* SHL reg,1      */ 
    37213752            } 
    37223753            c = cat(c,ce); 
    37233754            ce = loadea(e,&cs,0x0B,reg,0,regm,0);       /* OR reg,data */ 
    37243755            c = cat(c,ce); 
    37253756        } 
    37263757        else if (sz == 8 || (I64 && sz == 2 * REGSIZE && !tyfloating(tym))) 
    37273758        { 
    37283759            c = allocreg(&regm,&reg,TYoffset);  /* get a register */ 
  • trunk/src/backend/cod2.c

    r767 r768  
    226226            else if (sz == 4) 
    227227                value &= 0xFFFFFFFF; 
    228228            if (reghasvalue(byte ? BYTEREGS : ALLREGS,value,&reg)) 
    229229                goto L11; 
    230230            if (sz == 8 && !I64) 
    231231            { 
    232232                assert(value == (int)value);    // sign extend imm32 
    233233            } 
    234234            op1 = 0xF7; 
    235235            cs.IEV2.Vint = value; 
    236236            cs.IFL2 = FLconst; 
    237237            goto L10; 
    238238        } 
    239239 
    240240        // Handle (exp & reg) 
    241241        if (isregvar(e2,&retregs,&reg)) 
    242242        { 
    243243            c = getlvalue(&cs,e1,0); 
    244244        L11: 
    245245            code_newreg(&cs, reg); 
     246            if (I64 && byte && reg >= 4) 
     247                cs.Irex |= REX; 
    246248        L10: 
    247249            cs.Iop = op1 ^ byte; 
    248250            cs.Iflags |= word | CFpsw; 
    249251            freenode(e1); 
    250252            freenode(e2); 
    251253            return gen(c,&cs); 
    252254        } 
    253255  } 
    254256 
    255257  // Look for possible uses of LEA 
    256258  if (e->Eoper == OPadd && 
    257259      !(*pretregs & mPSW) &&            /* flags aren't set by LEA      */ 
    258260      !nest &&                          // could cause infinite recursion if e->Ecount 
    259261      (sz == REGSIZE || (I64 && sz == 4)))  // far pointers aren't handled 
    260262  { 
    261263        unsigned rex = (sz == 8) ? REX_W : 0; 
    262264 
    263265        // Handle the case of (e + &var) 
    264266        int e1oper = e1->Eoper; 
    265267        if ((e2oper == OPrelconst && (config.target_cpu >= TARGET_Pentium || (!e2->Ecount && stackfl[el_fl(e2)]))) 
     
    571573            rretregs &= BYTEREGS; 
    572574 
    573575        cr = scodelem(e2,&rretregs,retregs,TRUE);       /* get rvalue   */ 
    574576        rreg = (tysize[ty2] > REGSIZE) ? findreglsw(rretregs) : findreg(rretregs); 
    575577        c = CNIL; 
    576578        if (numwords == 1)                              /* ADD reg,rreg */ 
    577579        { 
    578580                /* reverse operands to avoid moving around the segment value */ 
    579581                if (tysize[ty2] > REGSIZE) 
    580582                {       c = cat(c,getregs(rretregs)); 
    581583                        c = genregs(c,op1,rreg,reg); 
    582584                        retregs = rretregs;     /* reverse operands     */ 
    583585                } 
    584586                else 
    585587                {   c = genregs(c,op1,reg,rreg); 
    586588                    if (!I16 && *pretregs & mPSW) 
    587589                        c->Iflags |= word; 
    588590                } 
    589591                if (I64 && sz == 8) 
    590592                    code_orrex(c, REX_W); 
     593                if (I64 && byte && reg >= 4) 
     594                    code_orrex(c, REX); 
    591595        } 
    592596        else /* numwords == 2 */                /* ADD lsreg,lsrreg     */ 
    593597        { 
    594598            reg = findreglsw(retregs); 
    595599            rreg = findreglsw(rretregs); 
    596600            c = genregs(c,op1,reg,rreg); 
    597601            if (e->Eoper == OPadd || e->Eoper == OPmin) 
    598602                code_orflag(c,CFpsw); 
    599603            reg = findregmsw(retregs); 
    600604            rreg = findregmsw(rretregs); 
    601605            if (!(e2oper == OPu16_32 && // if second operand is 0 
    602606                  (op2 == 0x0B || op2 == 0x33)) // and OR or XOR 
    603607               ) 
    604608                genregs(c,op2,reg,rreg);        // ADC msreg,msrreg 
    605609        } 
    606610        break; 
    607611 
    608612    case OPrelconst: 
    609613        if (sz != REGSIZE) 
    610614                goto L2; 
     
    32033207 
    32043208/********************************* 
    32053209 * Generate code for memset(s,val,n) intrinsic. 
    32063210 *      (s OPmemset (n OPparam val)) 
    32073211 */ 
    32083212 
    32093213#if 1 
    32103214code *cdmemset(elem *e,regm_t *pretregs) 
    32113215{   code *c1,*c2,*c3 = NULL,*c4; 
    32123216    regm_t retregs1; 
    32133217    regm_t retregs2; 
    32143218    regm_t retregs3; 
    32153219    unsigned reg,vreg; 
    32163220    tym_t ty1; 
    32173221    elem *e2,*e1; 
    32183222    int segreg; 
    32193223    unsigned remainder; 
    32203224    targ_uns numbytes,numwords; 
    32213225    int op; 
    32223226    targ_size_t value; 
     3227    unsigned m; 
    32233228 
    32243229    //printf("cdmemset(*pretregs = x%x)\n", *pretregs); 
    32253230    e1 = e->E1; 
    32263231    e2 = e->E2; 
    32273232    assert(e2->Eoper == OPparam); 
    32283233 
    32293234    unsigned char rex = I64 ? REX_W : 0; 
    32303235 
    32313236    if (e2->E2->Eoper == OPconst) 
    32323237    { 
    32333238        value = el_tolong(e2->E2); 
    32343239        value &= 0xFF; 
    32353240        value |= value << 8; 
    32363241        value |= value << 16; 
    32373242        value |= value << 32; 
    32383243    } 
    32393244 
    32403245    if (e2->E1->Eoper == OPconst) 
    32413246    { 
    32423247        numbytes = el_tolong(e2->E1); 
    32433248        if (numbytes <= REP_THRESHOLD && 
    32443249            !I16 &&                     // doesn't work for 16 bits 
    32453250            e2->E2->Eoper == OPconst) 
    32463251        { 
    32473252            targ_uns offset = 0; 
    32483253            retregs1 = *pretregs; 
    32493254            if (!retregs1) 
    32503255                retregs1 = ALLREGS; 
    32513256            c1 = codelem(e->E1,&retregs1,FALSE); 
    32523257            reg = findreg(retregs1); 
    32533258            if (e2->E2->Eoper == OPconst) 
    32543259            { 
     3260                unsigned m = buildModregrm(0,0,reg); 
    32553261                switch (numbytes) 
    32563262                { 
    32573263                    case 4:                     // MOV [reg],imm32 
    3258                         c3 = genc2(CNIL,0xC7,modregrmx(0,0,reg),value); 
     3264                        c3 = genc2(CNIL,0xC7,m,value); 
    32593265                        goto fixres; 
    32603266                    case 2:                     // MOV [reg],imm16 
    3261                         c3 = genc2(CNIL,0xC7,modregrmx(0,0,reg),value); 
     3267                        c3 = genc2(CNIL,0xC7,m,value); 
    32623268                        c3->Iflags = CFopsize; 
    32633269                        goto fixres; 
    32643270                    case 1:                     // MOV [reg],imm8 
    3265                         c3 = genc2(CNIL,0xC6,modregrmx(0,0,reg),value); 
     3271                        c3 = genc2(CNIL,0xC6,m,value); 
    32663272                        goto fixres; 
    32673273                } 
    32683274            } 
    32693275 
    32703276            c1 = regwithvalue(c1, BYTEREGS & ~retregs1, value, &vreg, I64 ? 64 : 0); 
    32713277            freenode(e2->E2); 
    32723278            freenode(e2); 
    32733279 
     3280            m = (rex << 16) | buildModregrm(2,vreg,reg); 
    32743281            while (numbytes >= REGSIZE) 
    32753282            {                           // MOV dword ptr offset[reg],vreg 
    3276                 c2 = gen2(CNIL,0x89,(rex << 16) | modregxrmx(2,vreg,reg)); 
     3283                c2 = gen2(CNIL,0x89,m); 
    32773284                c2->IEVoffset1 = offset; 
    32783285                c2->IFL1 = FLconst; 
    32793286                numbytes -= REGSIZE; 
    32803287                offset += REGSIZE; 
    32813288                c3 = cat(c3,c2); 
    32823289            } 
    32833290            if (numbytes & 4) 
    32843291            {                           // MOV dword ptr offset[reg],vreg 
    3285                 c2 = gen2(CNIL,0x89,modregxrmx(2,vreg,reg)); 
     3292                c2 = gen2(CNIL,0x89,m); 
    32863293                c2->IEVoffset1 = offset; 
    32873294                c2->IFL1 = FLconst; 
    32883295                offset += 4; 
    32893296                c3 = cat(c3,c2); 
    32903297            } 
    32913298            if (numbytes & 2) 
    32923299            {                           // MOV word ptr offset[reg],vreg 
    3293                 c2 = gen2(CNIL,0x89,modregxrmx(2,vreg,reg)); 
     3300                c2 = gen2(CNIL,0x89,m); 
    32943301                c2->IEVoffset1 = offset; 
    32953302                c2->IFL1 = FLconst; 
    32963303                c2->Iflags = CFopsize; 
    32973304                offset += 2; 
    32983305                c3 = cat(c3,c2); 
    32993306            } 
    33003307            if (numbytes & 1) 
    33013308            {                           // MOV byte ptr offset[reg],vreg 
    3302                 c2 = gen2(CNIL,0x88,modregxrmx(2,vreg,reg)); 
     3309                c2 = gen2(CNIL,0x88,m); 
    33033310                c2->IEVoffset1 = offset; 
    33043311                c2->IFL1 = FLconst; 
     3312                if (I64 && vreg >= 4) 
     3313                    c2->Irex |= REX; 
    33053314                c3 = cat(c3,c2); 
    33063315            } 
    33073316fixres: 
    33083317            return cat3(c1,c3,fixresult(e,retregs1,pretregs)); 
    33093318        } 
    33103319    } 
    33113320 
    33123321    // Get nbytes into CX 
    33133322    retregs2 = mCX; 
    33143323    if (!I16 && e2->E1->Eoper == OPconst && e2->E2->Eoper == OPconst) 
    33153324    { 
    33163325        remainder = numbytes & (4 - 1); 
    33173326        numwords  = numbytes / 4;               // number of words 
    33183327        op = 0xAB;                              // moving by words 
    33193328        c1 = getregs(mCX); 
    33203329        c1 = movregconst(c1,CX,numwords,I64?64:0);     // # of bytes/words 
    33213330    } 
    33223331    else 
    33233332    { 
    33243333        remainder = 0; 
     
    33653374    if (*pretregs)                              // if need return value 
    33663375    {   c3 = getregs(mBX); 
    33673376        c3 = genmovreg(c3,BX,DI); 
    33683377        code_orrex(c3,rex); 
    33693378    } 
    33703379 
    33713380    c3 = cat(c3,getregs(mDI | mCX)); 
    33723381    if (I16 && config.flags4 & CFG4speed)      // if speed optimization 
    33733382    { 
    33743383        c3 = cat(c3,getregs(mAX)); 
    33753384        c3 = gen2(c3,0x8A,modregrm(3,AH,AL));   // MOV AH,AL 
    33763385        gen2(c3,0xD1,modregrm(3,5,CX));         // SHR CX,1 
    33773386        gen1(c3,0xF3);                          // REP 
    33783387        gen1(c3,0xAB);                          // STOSW 
    33793388        gen2(c3,0x11,modregrm(3,CX,CX));        // ADC CX,CX 
    33803389        op = 0xAA; 
    33813390    } 
    33823391 
    33833392    c3 = gen1(c3,0xF3);                         // REP 
    33843393    gen1(c3,op);                                // STOSD 
     3394    m = buildModregrm(2,AX,reg); 
    33853395    if (remainder & 4) 
    33863396    { 
    33873397        code *ctmp; 
    3388         ctmp = gen2(CNIL,0x89,modregrmx(2,AX,reg)); 
     3398        ctmp = gen2(CNIL,0x89,m); 
    33893399        ctmp->IFL1 = FLconst; 
    33903400        c3 = cat(c3,ctmp); 
    33913401    } 
    33923402    if (remainder & 2) 
    33933403    { 
    33943404        code *ctmp; 
    3395         ctmp = gen2(CNIL,0x89,modregrmx(2,AX,reg)); 
     3405        ctmp = gen2(CNIL,0x89,m); 
    33963406        ctmp->Iflags = CFopsize; 
    33973407        ctmp->IEVoffset1 = remainder & 4; 
    33983408        ctmp->IFL1 = FLconst; 
    33993409        c3 = cat(c3,ctmp); 
    34003410    } 
    34013411    if (remainder & 1) 
    34023412    { 
    34033413        code *ctmp; 
    3404         ctmp = gen2(CNIL,0x88,modregrmx(2,AX,reg)); 
     3414        ctmp = gen2(CNIL,0x88,m); 
    34053415        ctmp->IEVoffset1 = remainder & ~1; 
    34063416        ctmp->IFL1 = FLconst; 
    34073417        c3 = cat(c3,ctmp); 
    34083418    } 
    34093419    regimmed_set(CX,0); 
    34103420    return cat4(c1,c2,c3,fixresult(e,mES|mBX,pretregs)); 
    34113421} 
    34123422#else 
    34133423// BUG: Pat made many improvements in the linux version, I need 
    34143424// to verify they work for 16 bits and fold them in. -Walter 
    34153425 
    34163426code *cdmemset(elem *e,regm_t *pretregs) 
    34173427{   code *c1,*c2,*c3 = NULL,*c4; 
    34183428    regm_t retregs1; 
    34193429    regm_t retregs2; 
    34203430    regm_t retregs3; 
    34213431    tym_t ty1; 
    34223432    elem *e2; 
    34233433    targ_size_t value; 
    34243434 
     
    41434153  } 
    41444154  else 
    41454155        assert(0); 
    41464156  return cat4(c1,cg,c,fixresult(e,retregs,pretregs)); 
    41474157} 
    41484158 
    41494159/************************** 
    41504160 * Post increment and post decrement. 
    41514161 */ 
    41524162 
    41534163code *cdpost(elem *e,regm_t *pretregs) 
    41544164{ code cs,*c1,*c2,*c3,*c4,*c5,*c6; 
    41554165  unsigned reg,op,byte; 
    41564166  tym_t tyml; 
    41574167  regm_t retregs,possregs,idxregs; 
    41584168  targ_int n; 
    41594169  elem *e2; 
    41604170  int sz; 
    41614171  int stackpushsave; 
    41624172 
     4173  //printf("cdpost(pretregs = %s)\n", regm_str(*pretregs)); 
    41634174  retregs = *pretregs; 
    41644175  op = e->Eoper;                                /* OPxxxx               */ 
    41654176  if (retregs == 0)                             /* if nothing to return */ 
    41664177        return cdaddass(e,pretregs); 
    41674178  c4 = c5 = CNIL; 
    41684179  tyml = tybasic(e->E1->Ety); 
    41694180  sz = tysize[tyml]; 
    41704181  e2 = e->E2; 
    41714182  unsigned rex = (I64 && sz == 8) ? REX_W : 0; 
    41724183 
    41734184  if (tyfloating(tyml)) 
    41744185  { 
    41754186#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 
    41764187        return post87(e,pretregs); 
    41774188#else 
    41784189        if (config.inline8087) 
    41794190                return post87(e,pretregs); 
    41804191        assert(sz <= 8); 
    41814192        c1 = getlvalue(&cs,e->E1,DOUBLEREGS); 
    41824193        freenode(e->E1); 
     
    42834294        //      LEA     reg,n[reg]      // don't affect flags 
    42844295        int rm; 
    42854296 
    42864297        reg = cs.Irm & 7; 
    42874298        if (cs.Irex & REX_B) 
    42884299            reg |= 8; 
    42894300        cs.Iop = 0x85 ^ byte; 
    42904301        code_newreg(&cs, reg); 
    42914302        cs.Iflags |= CFpsw; 
    42924303        c2 = gen(NULL,&cs);             // TEST reg,reg 
    42934304 
    42944305        // If lvalue is a register variable, we must mark it as modified 
    42954306        c3 = modEA(&cs); 
    42964307 
    42974308        n = e2->EV.Vint; 
    42984309        if (op == OPpostdec) 
    42994310            n = -n; 
    43004311        rm = reg; 
    43014312        if (I16) 
    43024313            rm = regtorm[reg]; 
    4303         c4 = genc1(NULL,0x8D,(rex << 16) | modregxrmx(2,reg,rm),FLconst,n); // LEA reg,n[reg] 
     4314        c4 = genc1(NULL,0x8D,(rex << 16) | buildModregrm(2,reg,rm),FLconst,n); // LEA reg,n[reg] 
    43044315        return cat4(c1,c2,c3,c4); 
    43054316  } 
    43064317  else if (sz <= REGSIZE || tyfv(tyml)) 
    43074318  {     code cs2; 
    43084319 
    43094320        cs.Iop = 0x8B ^ byte; 
    43104321        retregs = possregs & ~idxregs & *pretregs; 
    43114322        if (!tyfv(tyml)) 
    43124323        {       if (retregs == 0) 
    43134324                        retregs = possregs & ~idxregs; 
    43144325        } 
    43154326        else /* tyfv(tyml) */ 
    43164327        {       if ((retregs &= mLSW) == 0) 
    43174328                        retregs = mLSW & ~idxregs; 
    43184329                /* Can't use LES if the EA uses ES as a seg override    */ 
    43194330                if (*pretregs & mES && (cs.Iflags & CFSEG) != CFes) 
    43204331                {   cs.Iop = 0xC4;                      /* LES          */ 
    43214332                    c1 = cat(c1,getregs(mES));          /* allocate ES  */ 
    43224333                } 
    43234334        } 
     
    46854696 
    46864697/**************************************** 
    46874698 * Check to see if pointer is NULL. 
    46884699 */ 
    46894700 
    46904701code *cdnullcheck(elem *e,regm_t *pretregs) 
    46914702{   regm_t retregs; 
    46924703    regm_t scratch; 
    46934704    unsigned reg; 
    46944705    code *c; 
    46954706    code *cs; 
    46964707 
    46974708    assert(!I16); 
    46984709    retregs = *pretregs; 
    46994710    if ((retregs & allregs) == 0) 
    47004711        retregs |= allregs; 
    47014712    c = codelem(e->E1,&retregs,FALSE); 
    47024713    scratch = allregs & ~retregs; 
    47034714    cs = allocreg(&scratch,&reg,TYint); 
    47044715    unsigned rex = I64 ? REX_W : 0; 
    4705     cs = genc1(cs,0x8B,(rex << 16) | modregxrmx(2,reg,findreg(retregs)),FLconst,0); // MOV reg,0[e] 
     4716    cs = genc1(cs,0x8B,(rex << 16) | buildModregrm(2,reg,findreg(retregs)),FLconst,0); // MOV reg,0[e] 
    47064717    return cat3(c,cs,fixresult(e,retregs,pretregs)); 
    47074718} 
    47084719 
    47094720#endif // !SPP 
  • trunk/src/backend/cod3.c

    r767 r768  
    22992299            ADD p[ESP],d 
    23002300           For direct call: 
    23012301            JMP sfunc 
    23022302           For virtual call: 
    23032303            MOV EAX, p[ESP]                     EAX = this 
    23042304            MOV EAX, d2[EAX]                    EAX = this->vptr 
    23052305            JMP i[EAX]                          jump to virtual function 
    23062306         */ 
    23072307        unsigned reg = 0; 
    23082308        if ((targ_ptrdiff_t)d < 0) 
    23092309        { 
    23102310            d = -d; 
    23112311            reg = 5;                            // switch from ADD to SUB 
    23122312        } 
    23132313        if (thunkty == TYmfunc) 
    23142314        {                                       // ADD ECX,d 
    23152315            c = CNIL; 
    23162316            if (d) 
    23172317                c = genc2(c,0x81,modregrm(3,reg,CX),d); 
    23182318        } 
    2319         else if (thunkty == TYjfunc
     2319        else if (thunkty == TYjfunc || (I64 && thunkty == TYnfunc)
    23202320        {                                       // ADD EAX,d 
    23212321            c = CNIL; 
    23222322            if (d) 
    23232323                c = genc2(c,0x81,modregrm(3,reg,I64 ? DI : AX),d); 
    23242324        } 
    23252325        else 
    23262326        { 
    23272327            c = genc(CNIL,0x81,modregrm(2,reg,4), 
    23282328                FLconst,p,                      // to this 
    23292329                FLconst,d);                     // ADD p[ESP],d 
    23302330            c->Isib = modregrm(0,4,SP); 
    23312331        } 
    23322332        if (I64) 
    23332333            c->Irex |= REX_W; 
    23342334    } 
    23352335    else 
    23362336    { 
    23372337        /* 
    23382338           Generate: 
    23392339            MOV BX,SP 
     
    34283428                     config.target_cpu >= TARGET_80486) 
    34293429            { 
    34303430                c->Iop &= 1; 
    34313431                c->Irm = (rm & modregrm(3,0,7)) | (ereg << 3); 
    34323432                if (c->Irex & REX_B) 
    34333433                    c->Irex |= REX_R; 
    34343434                if (!(c->Iflags & CFpsw) && !I16) 
    34353435                    c->Iflags &= ~CFopsize; 
    34363436                goto L1; 
    34373437            } 
    34383438 
    34393439            /* Look for sign extended modregrm displacement, or 0 
    34403440             * displacement. 
    34413441             */ 
    34423442 
    34433443            if (((rm & 0xC0) == 0x80) && // it's a 16/32 bit disp 
    34443444                c->IFL1 == FLconst)      // and it's a constant 
    34453445            { 
    34463446                a = c->IEVpointer1; 
    34473447                if (a == 0 && (rm & 7) != local_BPRM &&         // if 0[disp] 
    3448                     !(local_BPRM == 5 && (rm & 7) == 4 && (c->Isib & 7) == BP && !(c->Irex & REX_B)
     3448                    !(local_BPRM == 5 && (rm & 7) == 4 && (c->Isib & 7) == BP
    34493449                   ) 
    34503450                    c->Irm &= 0x3F; 
    34513451                else if (!I16) 
    34523452                { 
    34533453                    if ((targ_size_t)(targ_schar)a == a) 
    34543454                        c->Irm ^= 0xC0;                 /* do 8 sx      */ 
    34553455                } 
    34563456                else if (((targ_size_t)(targ_schar)a & 0xFFFF) == (a & 0xFFFF)) 
    34573457                    c->Irm ^= 0xC0;                     /* do 8 sx      */ 
    34583458            } 
    34593459 
    34603460            /* Look for LEA reg,[ireg], replace with MOV reg,ireg       */ 
    34613461            else if (op == 0x8D) 
    34623462            {   rm = c->Irm & 7; 
    34633463                mod = c->Irm & modregrm(3,0,0); 
    34643464                if (mod == 0) 
    34653465                { 
    34663466                    if (!I16) 
    34673467                    { 
    34683468                        switch (rm) 
     
    52575257                    break; 
    52585258                case FLswitch: 
    52595259                case FLblockoff: 
    52605260                case FLlocalsize: 
    52615261                case FLframehandler: 
    52625262                case 0: 
    52635263                    break; 
    52645264                case FLdatseg: 
    52655265                    printf(" %d.%llx",c->IEVseg1,(unsigned long long)c->IEVpointer1); 
    52665266                    break; 
    52675267                case FLauto: 
    52685268                case FLreg: 
    52695269                case FLdata: 
    52705270                case FLudata: 
    52715271                case FLpara: 
    52725272                case FLtmp: 
    52735273                case FLbprel: 
    52745274                case FLtlsdata: 
    52755275                    printf(" sym='%s'",c->IEVsym1->Sident); 
    52765276                    break; 
     5277                case FLextern: 
     5278                    printf(" FLextern offset = %4d",(int)c->IEVoffset1); 
     5279                    break; 
    52775280                default: 
    52785281                    WRFL((enum FL)c->IFL1); 
    52795282                    break; 
    52805283            } 
    52815284        } 
    52825285  } 
    52835286  if (ins & T) 
    52845287  {     printf(" "); WRFL((enum FL)c->IFL2); 
    52855288        switch (c->IFL2) 
    52865289        { 
    52875290            case FLconst: 
    52885291                printf(" int = %4d",c->IEV2.Vuns); 
    52895292                break; 
    52905293            case FLblock: 
    52915294                printf(" block = %p",c->IEV2.Vblock); 
    52925295                break; 
    52935296            case FLswitch: 
    52945297            case FLblockoff: 
    52955298            case 0: 
    52965299            case FLlocalsize: 
  • trunk/src/backend/cod4.c

    r767 r768  
    346346        if (!(retregs == 0 && 
    347347              (e2oper == OPconst || e2oper == OPvar || e2oper == OPind)) 
    348348           ) 
    349349            return eq87(e,pretregs); 
    350350        if (config.target_cpu >= TARGET_PentiumPro && 
    351351            (e2oper == OPvar || e2oper == OPind) 
    352352           ) 
    353353            return eq87(e,pretregs); 
    354354        if (tyml == TYldouble || tyml == TYildouble) 
    355355            return eq87(e,pretregs); 
    356356  } 
    357357 
    358358  unsigned sz = tysize[tyml];           // # of bytes to transfer 
    359359  assert((int)sz > 0); 
    360360 
    361361  if (retregs == 0)                     /* if no return value           */ 
    362362  {     int fl; 
    363363 
    364364        if ((e2oper == OPconst ||       /* if rvalue is a constant      */ 
    365365             e2oper == OPrelconst && 
     366             !(I64 && config.flags3 & CFG3pic) && 
    366367             ((fl = el_fl(e2)) == FLdata || 
    367368              fl==FLudata || fl == FLextern) && 
    368369             !(e2->EV.sp.Vsym->ty() & mTYcs) 
    369370            ) && 
    370371            !evalinregister(e2) && 
    371372            !e1->Ecount)        /* and no CSE headaches */ 
    372373        { 
    373374            // Look for special case of (*p++ = ...), where p is a register variable 
    374375            if (e1->Eoper == OPind && 
    375376                ((e11 = e1->E1)->Eoper == OPpostinc || e11->Eoper == OPpostdec) && 
    376377                e11->E1->Eoper == OPvar && 
    377378                e11->E1->EV.sp.Vsym->Sfl == FLreg && 
    378379                (!I16 || e11->E1->EV.sp.Vsym->Sregm & IDXREGS) 
    379380               ) 
    380381            { 
    381382                postinc = e11->E2->EV.Vint; 
    382383                if (e11->Eoper == OPpostdec) 
    383384                    postinc = -postinc; 
    384385                cl = getlvalue(&cs,e11,RMstore); 
    385386                freenode(e11->E2); 
    386387            } 
    387388            else 
    388389            {   postinc = 0; 
    389390                cl = getlvalue(&cs,e1,RMstore); 
    390391 
    391392                if (e2oper == OPconst && 
    392393                    config.flags4 & CFG4speed && 
    393394                    (config.target_cpu == TARGET_Pentium || 
    394395                     config.target_cpu == TARGET_PentiumMMX) && 
    395396                    (cs.Irm & 0xC0) == 0x80 
    396397                   ) 
    397398                { 
    398399                    if (I64 && sz == 8 && e2->EV.Vpointer) 
    399400                    { 
    400401                        // MOV reg,imm64 
    401402                        // MOV EA,reg 
    402403                        regm_t rregm = allregs & ~idxregm(&cs); 
    403404                        unsigned reg; 
    404                         cl = regwithvalue(cl,rregm,e2->EV.Vpointer,&reg,CFoffset64); 
     405                        cl = regwithvalue(cl,rregm,e2->EV.Vpointer,&reg,64); 
    405406                        cs.Iop = 0x89; 
    406407                        cs.Irm |= modregrm(0,reg & 7,0); 
    407408                        if (reg & 8) 
    408409                            cs.Irex |= REX_R; 
    409410                        c = gen(cl,&cs); 
    410411                        freenode(e2); 
    411412                        goto Lp; 
    412413                    } 
    413414                    if ((sz == REGSIZE || (I64 && sz == 4)) && e2->EV.Vint) 
    414415                    { 
    415416                        // MOV reg,imm 
    416417                        // MOV EA,reg 
    417418                        regm_t rregm = allregs & ~idxregm(&cs); 
    418419                        unsigned reg; 
    419420                        cl = regwithvalue(cl,rregm,e2->EV.Vint,&reg,0); 
    420421                        cs.Iop = 0x89; 
    421422                        cs.Irm |= modregrm(0,reg & 7,0); 
    422423                        if (reg & 8) 
    423424                            cs.Irex |= REX_R; 
    424425                        c = gen(cl,&cs); 
     
    475476            else 
    476477            { 
    477478                assert(e2oper == OPconst); 
    478479                cs.IFL2 = FLconst; 
    479480                targ_size_t *p = (targ_size_t *) &(e2->EV); 
    480481                cs.IEV2.Vsize_t = *p; 
    481482                // Look for loading a register variable 
    482483                if ((cs.Irm & 0xC0) == 0xC0) 
    483484                {   unsigned reg = cs.Irm & 7; 
    484485 
    485486                    if (cs.Irex & REX_B) 
    486487                        reg |= 8; 
    487488                    if (I64 && sz == 8) 
    488489                        cl = movregconst(cl,reg,*p,CFoffset64); 
    489490                    else 
    490491                        cl = movregconst(cl,reg,*p,1 ^ (cs.Iop & 1)); 
    491492                    if (sz == 2 * REGSIZE) 
    492493                    {   getlvalue_msw(&cs); 
    493494                        cl = movregconst(cl,cs.Irm & 7,p[1],0); 
    494495                    } 
     496                } 
     497                else if (I64 && sz == 8 && *p != *(unsigned *)p) 
     498                { 
     499                    // MOV reg,imm64 
     500                    // MOV EA,reg 
     501                    regm_t rregm = allregs & ~idxregm(&cs); 
     502                    unsigned reg; 
     503                    cl = regwithvalue(cl,rregm,e2->EV.Vpointer,&reg,64); 
     504                    cs.Iop = 0x89; 
     505                    cs.Irm |= modregrm(0,reg & 7,0); 
     506                    if (reg & 8) 
     507                        cs.Irex |= REX_R; 
     508                    c = gen(cl,&cs); 
     509                    freenode(e2); 
     510                    goto Lp; 
    495511                } 
    496512                else 
    497513                {   int regsize; 
    498514 
    499515                    i = sz; 
    500516                    do 
    501517                    {   regsize = REGSIZE; 
    502518                        retregs = (sz == 1) ? BYTEREGS : allregs; 
    503519                        if (i >= 4 && I16 && I386) 
    504520                        { 
    505521                            regsize = 4; 
    506522                            cs.Iflags |= CFopsize;      // use opsize to do 32 bit operation 
    507523                        } 
    508524                        else 
    509525                        { 
    510526                            if (reghasvalue(retregs,*p,&reg)) 
    511527                            { 
    512528                                cs.Iop = (cs.Iop & 1) | 0x88; 
    513529                                cs.Irm |= modregrm(0,reg & 7,0); // MOV EA,reg 
    514530                                if (reg & 8) 
     
    673689  } 
    674690  if (e1->Ecount ||                     /* if lvalue is a CSE or        */ 
    675691      regvar)                           /* rvalue can't be a CSE        */ 
    676692  { 
    677693        c = cat(c,getregs_imm(retregs));        // necessary if both lvalue and 
    678694                                        //  rvalue are CSEs (since a reg 
    679695                                        //  can hold only one e at a time) 
    680696        cssave(e1,retregs,EOP(e1));     /* if lvalue is a CSE           */ 
    681697  } 
    682698 
    683699    c = cat4(cr,cl,c,fixresult(e,retregs,pretregs)); 
    684700Lp: 
    685701    if (postinc) 
    686702    { 
    687703        int reg = findreg(idxregm(&cs)); 
    688704        if (*pretregs & mPSW) 
    689705        {   // Use LEA to avoid touching the flags 
    690706            unsigned rm = cs.Irm & 7; 
    691707            if (cs.Irex & REX_B) 
    692708                rm |= 8; 
    693             c = genc1(c,0x8D,modregxrmx(2,reg,rm),FLconst,postinc); 
     709            c = genc1(c,0x8D,buildModregrm(2,reg,rm),FLconst,postinc); 
    694710            if (sz == 8) 
    695711                code_orrex(c, REX_W); 
    696712        } 
    697713        else if (I64) 
    698714        { 
    699715            c = genc2(c,0x81,modregrmx(3,0,reg),postinc); 
    700716            if (sz == 8) 
    701717                code_orrex(c, REX_W); 
    702718        } 
    703719        else 
    704720        { 
    705721            if (postinc == 1) 
    706722                c = gen1(c,0x40 + reg);         // INC reg 
    707723            else if (postinc == -(targ_int)1) 
    708724                c = gen1(c,0x48 + reg);         // DEC reg 
    709725            else 
    710726            { 
    711727                c = genc2(c,0x81,modregrm(3,0,reg),postinc); 
    712728            } 
    713729        } 
     
    18171833            if (I64 && byte && (reg >= 4 || rreg >= 4)) 
    18181834                c->Irex |= REX;                 // address byte registers 
    18191835        } 
    18201836        else 
    18211837        {   assert(sz <= 2 * REGSIZE); 
    18221838 
    18231839            /* Compare MSW, if they're equal then compare the LSW       */ 
    18241840            reg = findregmsw(retregs); 
    18251841            rreg = findregmsw(rretregs); 
    18261842            c = genregs(CNIL,0x3B ^ reverse,reg,rreg);  /* CMP reg,rreg */ 
    18271843            if (!I16 && sz == 6) 
    18281844                c->Iflags |= CFopsize;          /* seg is only 16 bits  */ 
    18291845            genjmp(c,JNE,FLcode,(block *) ce);          /* JNE nop      */ 
    18301846 
    18311847            reg = findreglsw(retregs); 
    18321848            rreg = findreglsw(rretregs); 
    18331849            genregs(c,0x3B ^ reverse,reg,rreg);         /* CMP reg,rreg */ 
    18341850        } 
    18351851        break; 
    18361852      case OPrelconst: 
     1853        if (I64 && config.flags3 & CFG3pic) 
     1854            goto L2; 
    18371855        fl = el_fl(e2); 
    18381856        switch (fl) 
    18391857        {   case FLfunc: 
    18401858                fl = FLextern;          // so it won't be self-relative 
    18411859                break; 
    18421860            case FLdata: 
    18431861            case FLudata: 
    18441862            case FLextern: 
    18451863                if (sz > REGSIZE)       // compare against DS, not DGROUP 
    18461864                    goto L2; 
    18471865                break; 
    18481866            case FLfardata: 
    18491867                break; 
    18501868            default: 
    18511869                goto L2; 
    18521870        } 
    18531871        cs.IFL2 = fl; 
    18541872        cs.IEVsym2 = e2->EV.sp.Vsym; 
    18551873        offset2 = e2->EV.sp.Voffset; 
    18561874        if (sz > REGSIZE) 
  • trunk/src/backend/code.h

    r738 r768  
    635635#else 
    636636code *allocreg (regm_t *pretregs , unsigned *preg , tym_t tym ); 
    637637#endif 
    638638void useregs (regm_t regm ); 
    639639code *getregs (regm_t r ); 
    640640code *getregs_imm (regm_t r ); 
    641641code *cse_flush(int); 
    642642void cssave (elem *e , regm_t regm , unsigned opsflag ); 
    643643bool evalinregister (elem *e ); 
    644644regm_t getscratch(); 
    645645code *codelem (elem *e , regm_t *pretregs , bool constflag ); 
    646646const char *regm_str(regm_t rm); 
    647647int numbitsset(regm_t); 
    648648 
    649649/* cod1.c */ 
    650650extern int clib_inited; 
    651651 
    652652int isscaledindex(elem *); 
    653653int ssindex(int op,targ_uns product); 
    654654void buildEA(code *c,int base,int index,int scale,targ_size_t disp); 
     655unsigned buildModregrm(int mod, int reg, int rm); 
    655656void andregcon (con_t *pregconsave); 
    656657code *docommas (elem **pe ); 
    657658code *gencodelem(code *c,elem *e,regm_t *pretregs,bool constflag); 
    658659void gensaverestore(regm_t, code **, code **); 
    659660code *genstackclean(code *c,unsigned numpara,regm_t keepmsk); 
    660661code *logexp (elem *e , int jcond , unsigned fltarg , code *targ ); 
    661662code *loadea (elem *e , code *cs , unsigned op , unsigned reg , targ_size_t offset , regm_t keepmsk , regm_t desmsk ); 
    662663unsigned getaddrmode (regm_t idxregs ); 
    663664void setaddrmode(code *c, regm_t idxregs); 
    664665void getlvalue_msw(code *); 
    665666void getlvalue_lsw(code *); 
    666667code *getlvalue (code *pcs , elem *e , regm_t keepmsk ); 
    667668code *scodelem (elem *e , regm_t *pretregs , regm_t keepmsk , bool constflag ); 
    668669code *fltregs (code *pcs , tym_t tym ); 
    669670code *tstresult (regm_t regm , tym_t tym , unsigned saveflag ); 
    670671code *fixresult (elem *e , regm_t retregs , regm_t *pretregs ); 
    671672code *callclib (elem *e , unsigned clib , regm_t *pretregs , regm_t keepmask ); 
    672673cd_t cdfunc; 
    673674cd_t cdstrthis; 
    674675code *params(elem *, unsigned); 
  • trunk/src/backend/el.c

    r738 r768  
    32053205  } 
    32063206  WROP(e->Eoper); 
    32073207  dbg_printf(" "); 
    32083208  if (SCPP && PARSER) 
    32093209  { 
    32103210        if (e->ET) 
    32113211        {   type_debug(e->ET); 
    32123212            if (tybasic(e->ET->Tty) == TYstruct 
    32133213#if !TX86 
    32143214 && (e->PEFflags & PEFstrsize) 
    32153215#endif 
    32163216               ) 
    32173217                dbg_printf("%d ", (int)type_size(e->ET)); 
    32183218            WRTYxx(e->ET->Tty); 
    32193219        } 
    32203220  } 
    32213221  else 
    32223222  { 
    32233223        if ((e->Eoper == OPstrpar || e->Eoper == OPstrctor || e->Eoper == OPstreq) || 
    32243224            e->Ety == TYstruct) 
    3225             dbg_printf("%d ", (int)type_size(e->ET)); 
     3225            if (e->ET) 
     3226                dbg_printf("%d ", (int)type_size(e->ET)); 
    32263227        WRTYxx(e->Ety); 
    32273228  } 
    32283229  if (OTunary(e->Eoper)) 
    32293230  { 
    32303231        if (e->E2) 
    32313232            dbg_printf("%p %p\n",e->E1,e->E2); 
    32323233        else 
    32333234            dbg_printf("%p\n",e->E1); 
    32343235        elem_print(e->E1); 
    32353236  } 
    32363237  else if (OTbinary(e->Eoper)) 
    32373238  { 
    32383239        if (!PARSER && e->Eoper == OPstreq) 
    32393240                dbg_printf("bytes=%d ", (int)type_size(e->ET)); 
    32403241        dbg_printf("%p %p\n",e->E1,e->E2); 
    32413242        elem_print(e->E1); 
    32423243        elem_print(e->E2); 
    32433244  } 
    32443245  else 
    32453246  { 
  • trunk/src/backend/gloop.c

    r738 r768  
    21342134                c.Vchar = 1; 
    21352135                break; 
    21362136            case TYshort: 
    21372137            case TYushort: 
    21382138            case TYchar16: 
    21392139            case TYwchar_t:             // BUG: what about 4 byte wchar_t's? 
    21402140                c.Vshort = 1; 
    21412141                break; 
    21422142#if TX86 
    21432143            case TYsptr: 
    21442144            case TYcptr: 
    21452145#if JHANDLE 
    21462146            case TYjhandle: 
    21472147#endif 
    21482148            case TYnptr: 
    21492149#endif 
    21502150            case TYnullptr: 
    21512151            case TYfptr: 
    21522152            case TYvptr: 
    21532153                ty = TYint; 
     2154                if (I64) 
     2155                    ty = TYllong; 
    21542156                /* FALL-THROUGH */ 
    21552157            case TYint: 
    21562158            case TYuint: 
    21572159                c.Vint = 1; 
    21582160                break; 
    21592161#if TX86 
    21602162            case TYhptr: 
    21612163                ty = TYlong; 
    21622164#endif 
    21632165            case TYlong: 
    21642166            case TYulong: 
    21652167            case TYdchar: 
    21662168            default: 
    21672169                c.Vlong = 1; 
    21682170                break; 
    21692171#if 0 
    21702172            default: 
    21712173                printf("ty = x%x\n", tybasic(ty)); 
    21722174                assert(0); 
    21732175#endif 
  • trunk/src/e2ir.c

    r767 r768  
    33093309        if (!func->isThis()) 
    33103310            error("delegates are only for non-static functions"); 
    33113311 
    33123312        if (!func->isVirtual() || 
    33133313            directcall || 
    33143314            func->isFinal()) 
    33153315        { 
    33163316            ep = el_ptr(sfunc); 
    33173317        } 
    33183318        else 
    33193319        { 
    33203320            // Get pointer to function out of virtual table 
    33213321            unsigned vindex; 
    33223322 
    33233323            assert(ethis); 
    33243324            ep = el_same(&ethis); 
    33253325            ep = el_una(OPind, TYnptr, ep); 
    33263326            vindex = func->vtblIndex; 
    33273327 
    33283328            // Build *(ep + vindex * 4) 
    3329             ep = el_bin(OPadd,TYnptr,ep,el_long(TYsize_t, vindex * 4)); 
     3329            ep = el_bin(OPadd,TYnptr,ep,el_long(TYsize_t, vindex * PTRSIZE)); 
    33303330            ep = el_una(OPind,TYnptr,ep); 
    33313331        } 
    33323332 
    33333333//      if (func->tintro) 
    33343334//          func->error(loc, "cannot form delegate due to covariant return type"); 
    33353335    } 
    33363336    if (ethis->Eoper == OPcomma) 
    33373337    { 
    33383338        ethis->E2 = el_pair(TYdelegate, ethis->E2, ep); 
    33393339        ethis->Ety = TYdelegate; 
    33403340        e = ethis; 
    33413341    } 
    33423342    else 
    33433343        e = el_pair(TYdelegate, ethis, ep); 
    33443344    el_setLoc(e,loc); 
    33453345    return e; 
    33463346} 
    33473347 
    33483348elem *DotTypeExp::toElem(IRState *irs) 
    33493349{ 
  • trunk/src/msc.c

    r729 r768  
    309309{ 
    310310    int sz = (tybasic(ty) == TYvoid) ? 1 : tysize(ty); 
    311311#ifdef DEBUG 
    312312    if (sz == -1) 
    313313        WRTYxx(ty); 
    314314#endif 
    315315    assert(sz!= -1); 
    316316    return sz; 
    317317} 
    318318 
    319319/******************************* 
    320320 * Replace (e) with ((stmp = e),stmp) 
    321321 */ 
    322322 
    323323elem *exp2_copytotemp(elem *e) 
    324324{ 
    325325    //printf("exp2_copytotemp()\n"); 
    326326    elem_debug(e); 
    327327    Symbol *stmp = symbol_genauto(e); 
    328328    elem *eeq = el_bin(OPeq,e->Ety,el_var(stmp),e); 
    329     if (e->Ety == TYstruct) 
     329    elem *er = el_bin(OPcomma,e->Ety,eeq,el_var(stmp)); 
     330    if (tybasic(e->Ety) == TYstruct || tybasic(e->Ety) == TYarray) 
    330331    { 
    331332        eeq->Eoper = OPstreq; 
    332333        eeq->ET = e->ET; 
    333     } 
    334     return el_bin(OPcomma,e->Ety,eeq,el_var(stmp)); 
     334        eeq->E1->ET = e->ET; 
     335        er->ET = e->ET; 
     336        er->E2->ET = e->ET; 
     337    } 
     338    return er; 
    335339} 
    336340 
    337341/**************************** 
    338342 * Generate symbol of type ty at DATA:offset 
    339343 */ 
    340344 
    341345symbol *symboldata(targ_size_t offset,tym_t ty) 
    342346{ 
    343347    symbol *s = symbol_generate(SClocstat, type_fake(ty)); 
    344348    s->Sfl = FLdata; 
    345349    s->Soffset = offset; 
    346350    s->Sseg = DATA; 
    347351    symbol_keep(s);             // keep around 
    348352    return s; 
    349353} 
    350354 
    351355/************************************ 
    352356 * Add symbol to slist. 
    353357 */ 
    354358 
  • trunk/src/mtype.h

    r767 r768  
    156156    #define tfloat80    basic[Tfloat80] 
    157157 
    158158    #define timaginary32 basic[Timaginary32] 
    159159    #define timaginary64 basic[Timaginary64] 
    160160    #define timaginary80 basic[Timaginary80] 
    161161 
    162162    #define tcomplex32  basic[Tcomplex32] 
    163163    #define tcomplex64  basic[Tcomplex64] 
    164164    #define tcomplex80  basic[Tcomplex80] 
    165165 
    166166    #define tbit        basic[Tbit] 
    167167    #define tbool       basic[Tbool] 
    168168    #define tchar       basic[Tchar] 
    169169    #define twchar      basic[Twchar] 
    170170    #define tdchar      basic[Tdchar] 
    171171 
    172172    // Some special types 
    173173    #define tshiftcnt   tint32          // right side of shift expression 
    174174//    #define tboolean  tint32          // result of boolean expression 
    175175    #define tboolean    tbool           // result of boolean expression 
    176     #define tindex      tint32          // array/ptr index 
     176    #define tindex      tsize_t         // array/ptr index 
    177177    static Type *tvoidptr;              // void* 
    178178    static Type *tstring;               // immutable(char)[] 
    179179    #define terror      basic[Terror]   // for error recovery 
    180180 
    181181    #define tsize_t     basic[Tsize_t]          // matches size_t alias 
    182182    #define tptrdiff_t  basic[Tptrdiff_t]       // matches ptrdiff_t alias 
    183183    #define thash_t     tsize_t                 // matches hash_t alias 
    184184 
    185185    static ClassDeclaration *typeinfo; 
    186186    static ClassDeclaration *typeinfoclass; 
    187187    static ClassDeclaration *typeinfointerface; 
    188188    static ClassDeclaration *typeinfostruct; 
    189189    static ClassDeclaration *typeinfotypedef; 
    190190    static ClassDeclaration *typeinfopointer; 
    191191    static ClassDeclaration *typeinfoarray; 
    192192    static ClassDeclaration *typeinfostaticarray; 
    193193    static ClassDeclaration *typeinfoassociativearray; 
    194194    static ClassDeclaration *typeinfoenum; 
    195195    static ClassDeclaration *typeinfofunction; 
    196196    static ClassDeclaration *typeinfodelegate; 
  • trunk/src/template.c

    r754 r768  
    40684068            --nest; 
    40694069#if WINDOWS_SEH 
    40704070        } 
    40714071        __except (__ehfilter(GetExceptionInformation())) 
    40724072        { 
    40734073            global.gag = 0;            // ensure error message gets printed 
    40744074            error("recursive expansion"); 
    40754075            fatal(); 
    40764076        } 
    40774077#endif 
    40784078    } 
    40794079 
    40804080  Laftersemantic: 
    40814081    sc2->pop(); 
    40824082 
    40834083    scope->pop(); 
    40844084 
    40854085    // Give additional context info if error occurred during instantiation 
    40864086    if (global.errors != errorsave) 
    40874087    { 
    4088         error("error instantiating"); 
     4088        error(loc, "error instantiating"); 
    40894089        if (tinst) 
    40904090        {   tinst->printInstantiationTrace(); 
    40914091        } 
    40924092        errors = 1; 
    40934093        if (global.gag) 
    40944094        {   // Try to reset things so we can try again later to instantiate it 
    40954095            tempdecl->instances.remove(tempdecl_instance_idx); 
    40964096            if (!(sc->flags & SCOPEstaticif)) 
    40974097            {   // Bugzilla 4302 for discussion 
    40984098                semanticRun = 0; 
    40994099                inst = NULL; 
    41004100            } 
    41014101        } 
    41024102    } 
    41034103 
    41044104#if LOG 
    41054105    printf("-TemplateInstance::semantic('%s', this=%p)\n", toChars(), this); 
    41064106#endif 
    41074107} 
    41084108