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

Changeset 810

Show
Ignore:
Timestamp:
12/21/10 09:44:03 (14 years ago)
Author:
walter
Message:

more 64

Files:

Legend:

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

    r805 r810  
    20002000        freenode(e->E1); 
    20012001        c1 = cat3(c1,c2,fixresult87(e,mST0 | mPSW,pretregs)); 
    20022002        return c1; 
    20032003} 
    20042004 
    20052005/******************************* 
    20062006 * Perform an assignment to a long double/double/float. 
    20072007 */ 
    20082008 
    20092009code *complex_eq87(elem *e,regm_t *pretregs) 
    20102010{ 
    20112011        regm_t retregs; 
    20122012        code *c1,*c2; 
    20132013        code cs; 
    20142014        unsigned op1; 
    20152015        unsigned op2; 
    20162016        unsigned sz; 
    20172017        tym_t ty1; 
    20182018        int fxch = 0; 
    20192019 
     2020        //printf("complex_eq87(e = %p, *pretregs = %s)\n", e, regm_str(*pretregs)); 
    20202021        assert(e->Eoper == OPeq); 
    20212022        cs.Iflags = ADDFWAIT() ? CFwait : 0; 
    20222023        cs.Irex = 0; 
    20232024        retregs = mST01 | (*pretregs & mPSW); 
    20242025        c1 = codelem(e->E2,&retregs,FALSE); 
    20252026        ty1 = tybasic(e->E1->Ety); 
    20262027        switch (ty1) 
    20272028        { 
    20282029            case TYcdouble:     op1 = ESC(MFdouble,1);  op2 = 3; break; 
    20292030            case TYcfloat:      op1 = ESC(MFfloat,1);   op2 = 3; break; 
    20302031            case TYcldouble:    op1 = 0xDB;             op2 = 7; break; 
    20312032            default: 
    20322033                assert(0); 
    20332034        } 
    2034         if (*pretregs & mST01)  // if want result on stack too 
     2035        if (*pretregs & (mST01 | mXMM0 | mXMM1))  // if want result on stack too 
    20352036        { 
    20362037            if (ty1 == TYcldouble) 
    20372038            { 
    20382039                c1 = cat(c1,push87()); 
    20392040                c1 = cat(c1,push87()); 
    20402041                c1 = genf2(c1,0xD9,0xC0 + 1);   // FLD ST(1) 
    20412042                genf2(c1,0xD9,0xC0 + 1);        // FLD ST(1) 
    20422043                pop87(); 
    20432044                pop87(); 
    20442045            } 
    20452046            else 
    20462047            {   op2 = 2;                        // FST e->E1 
    20472048                fxch = 1; 
    20482049            } 
    20492050        } 
    20502051        else 
    20512052        {                                       // FSTP e->E1 
    20522053            pop87(); 
    20532054            pop87(); 
    20542055        } 
    20552056        sz = tysize(ty1) / 2; 
    2056         if (*pretregs & mST01
     2057        if (*pretregs & (mST01 | mXMM0 | mXMM1)
    20572058        { 
    20582059            cs.Iflags = 0; 
    20592060            cs.Irex = 0; 
    20602061            cs.Iop = op1; 
    20612062            c2 = getlvalue(&cs, e->E1, 0); 
    20622063            cs.IEVoffset1 += sz; 
    20632064            cs.Irm |= modregrm(0, op2, 0); 
    20642065            c2 = cat(c2, makesure87(e->E2, sz, 0, 0)); 
    20652066            c2 = gen(c2, &cs); 
    20662067            c2 = genfwait(c2); 
    20672068            c2 = cat(c2, makesure87(e->E2,  0, 1, 0)); 
    20682069        } 
    20692070        else 
    20702071        { 
    20712072            c2 = loadea(e->E1,&cs,op1,op2,sz,0,0); 
    20722073            c2 = genfwait(c2); 
    20732074        } 
    20742075        if (fxch) 
    20752076            c2 = genf2(c2,0xD9,0xC8 + 1);       // FXCH ST(1) 
    20762077        cs.IEVoffset1 -= sz; 
  • branches/dmd-1.x/src/backend/cod1.c

    r805 r810  
    17281728        } 
    17291729    } 
    17301730    return c; 
    17311731} 
    17321732 
    17331733 
    17341734/***************************** 
    17351735 * Given a result in registers, test it for TRUE or FALSE. 
    17361736 * Will fail if TYfptr and the reg is ES! 
    17371737 * If saveflag is TRUE, preserve the contents of the 
    17381738 * registers. 
    17391739 */ 
    17401740 
    17411741code *tstresult(regm_t regm,tym_t tym,unsigned saveflag) 
    17421742{ 
    17431743  unsigned scrreg;                      /* scratch register             */ 
    17441744  regm_t scrregm; 
    17451745 
    17461746#ifdef DEBUG 
    17471747  if (!(regm & (mBP | ALLREGS))) 
    1748         printf("tstresult(regm = x%x, tym = x%x, saveflag = %d)\n", 
    1749             regm,tym,saveflag); 
    1750 #endif 
    1751   assert(regm & (mBP | ALLREGS)); 
     1748        printf("tstresult(regm = %s, tym = x%x, saveflag = %d)\n", 
     1749            regm_str(regm),tym,saveflag); 
     1750#endif 
     1751  assert(regm & (XMMREGS | mBP | ALLREGS)); 
    17521752  tym = tybasic(tym); 
    17531753  code *ce = CNIL; 
    17541754  unsigned reg = findreg(regm); 
    17551755  unsigned sz = tysize[tym]; 
    17561756  if (sz == 1) 
    17571757  {     assert(regm & BYTEREGS); 
    17581758        return genregs(ce,0x84,reg,reg);        // TEST regL,regL 
     1759  } 
     1760  if (regm & XMMREGS) 
     1761  { 
     1762        unsigned xreg; 
     1763        regm_t xregs = XMMREGS & ~regm; 
     1764        ce = allocreg(&xregs, &xreg, TYdouble); 
     1765        unsigned op = 0; 
     1766        if (tym == TYdouble || tym == TYidouble || tym == TYcdouble) 
     1767            op = 0x660000; 
     1768        ce = gen2(ce,op | 0x0F57,modregrm(3,xreg-XMM0,xreg-XMM0));      // XORPS xreg,xreg 
     1769        gen2(ce,op | 0x0F2E,modregrm(3,xreg-XMM0,reg-XMM0));    // UCOMISS xreg,reg 
     1770        if (tym == TYcfloat || tym == TYcdouble) 
     1771        {   code *cnop = gennop(CNIL); 
     1772            genjmp(ce,JNE,FLcode,(block *) cnop); // JNE     L1 
     1773            genjmp(ce,JP, FLcode,(block *) cnop); // JP      L1 
     1774            reg = findreg(regm & ~mask[reg]); 
     1775            gen2(ce,op | 0x0F2E,modregrm(3,xreg-XMM0,reg-XMM0));        // UCOMISS xreg,reg 
     1776            ce = cat(ce, cnop); 
     1777        } 
     1778        return ce; 
    17591779  } 
    17601780  if (sz <= REGSIZE) 
    17611781  { 
    17621782    if (!I16) 
    17631783    { 
    17641784        if (tym == TYfloat) 
    17651785        {   if (saveflag) 
    17661786            { 
    17671787                scrregm = allregs & ~regm;              /* possible scratch regs */ 
    17681788                ce = allocreg(&scrregm,&scrreg,TYoffset); /* allocate scratch reg */ 
    17691789                ce = genmovreg(ce,scrreg,reg);  /* MOV scrreg,msreg     */ 
    17701790                reg = scrreg; 
    17711791            } 
    17721792            ce = cat(ce,getregs(mask[reg])); 
    17731793            return gen2(ce,0xD1,modregrmx(3,4,reg)); // SHL reg,1 
    17741794        } 
    17751795        ce = gentstreg(ce,reg);                 // TEST reg,reg 
    17761796        if (sz == SHORTSIZE) 
    17771797            ce->Iflags |= CFopsize;             /* 16 bit operands      */ 
    17781798        else if (sz == 8) 
  • branches/dmd-1.x/src/backend/cod2.c

    r772 r810  
    200200        /* Therefore, numwords can never be 2.                          */ 
    201201        assert(!(tyfv(ty1) && tyfv(ty2))); 
    202202        if (sz == 2 * REGSIZE) 
    203203        { 
    204204            numwords++; 
    205205        } 
    206206  } 
    207207  else 
    208208  {     /* If ty is a TYfptr, but both operands are long, treat the     */ 
    209209        /* operation as a long.                                         */ 
    210210        if ((tylong(ty1) || ty1 == TYhptr) && 
    211211            (tylong(ty2) || ty2 == TYhptr)) 
    212212            numwords++; 
    213213  } 
    214214 
    215215  // Special cases where only flags are set 
    216216  if (test && tysize[ty1] <= REGSIZE && 
    217217      (e1->Eoper == OPvar || (e1->Eoper == OPind && !e1->Ecount))) 
    218218  { 
    219219        // Handle the case of (var & const) 
    220         if (e2->Eoper == OPconst
     220        if (e2->Eoper == OPconst && el_signx32(e2)
    221221        { 
    222222            c = getlvalue(&cs,e1,0); 
    223223            targ_size_t value = e2->EV.Vpointer; 
    224224            if (sz == 2) 
    225225                value &= 0xFFFF; 
    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) 
     
    278278            (!I16 && e1->Ecount) 
    279279           ) 
    280280        { 
    281281            int inc = e->Ecount != 0; 
    282282            nest += inc; 
    283283            c = getlvalue(&cs,e,0); 
    284284            nest -= inc; 
    285285            unsigned reg; 
    286286            c = cat(c,allocreg(pretregs,&reg,ty)); 
    287287            cs.Iop = 0x8D; 
    288288            code_newreg(&cs, reg); 
    289289            c = gen(c,&cs);          // LEA reg,EA 
    290290            if (rex) 
    291291                code_orrex(c, rex); 
    292292            return c; 
    293293        } 
    294294 
    295295        // Handle the case of ((e + c) + e2) 
    296296        if (!I16 && 
    297297            e1oper == OPadd && 
    298             (e1->E2->Eoper == OPconst || e2oper == OPconst) && 
     298            (e1->E2->Eoper == OPconst && el_signx32(e1->E2) || 
     299             e2oper == OPconst && el_signx32(e2)) && 
    299300            !e1->Ecount 
    300301           ) 
    301302        {   elem *e11; 
    302303            elem *ebase; 
    303304            elem *edisp; 
    304305            int ss; 
    305306            int ss2; 
    306307            unsigned reg1,reg2; 
    307308            code *c1,*c2,*c3; 
    308309 
    309             if (e2oper == OPconst
     310            if (e2oper == OPconst && el_signx32(e2)
    310311            {   edisp = e2; 
    311312                ebase = e1->E2; 
    312313            } 
    313314            else 
    314315            {   edisp = e1->E2; 
    315316                ebase = e2; 
    316317            } 
    317318 
    318319            e11 = e1->E1; 
    319320            retregs = *pretregs & ALLREGS; 
    320321            if (!retregs) 
    321322                retregs = ALLREGS; 
    322323            ss = 0; 
    323324            ss2 = 0; 
    324325 
    325326            // Handle the case of (((e *  c1) + c2) + e2) 
    326327            // Handle the case of (((e << c1) + c2) + e2) 
    327328            if ((e11->Eoper == OPmul || e11->Eoper == OPshl) && 
    328329                e11->E2->Eoper == OPconst && 
    329330                !e11->Ecount 
     
    611612 
    612613    case OPrelconst: 
    613614        if (sz != REGSIZE) 
    614615                goto L2; 
    615616        if (segfl[el_fl(e2)] != 3)              /* if not in data segment */ 
    616617                goto L2; 
    617618        if (evalinregister(e2)) 
    618619                goto L2; 
    619620        cs.IEVoffset2 = e2->EV.sp.Voffset; 
    620621        cs.IEVsym2 = e2->EV.sp.Vsym; 
    621622        cs.Iflags |= CFoff; 
    622623        i = 0;                          /* no INC or DEC opcode         */ 
    623624        rval = 0; 
    624625        goto L3; 
    625626 
    626627    case OPconst: 
    627628        if (tyfv(ty2)) 
    628629            goto L2; 
    629630        if (numwords == 1) 
    630631        { 
     632                if (!el_signx32(e2)) 
     633                    goto L2; 
    631634                i = e2->EV.Vpointer; 
    632635                if (word) 
    633636                { 
    634637                    if (!(*pretregs & mPSW) && 
    635638                        config.flags4 & CFG4speed && 
    636639                        (e->Eoper == OPor || e->Eoper == OPxor || test || 
    637640                         (e1->Eoper != OPvar && e1->Eoper != OPind))) 
    638641                    {   word = 0; 
    639642                        i &= 0xFFFF; 
    640643                    } 
    641644                } 
    642645                rval = reghasvalue(byte ? BYTEREGS : ALLREGS,i,&rreg); 
    643646                cs.IEV2.Vint = i; 
    644647        L3: 
    645648                op1 ^= byte; 
    646649                cs.Iflags |= word; 
    647650                if (rval) 
    648651                {   cs.Iop = op1 ^ 2; 
    649652                    mode = rreg; 
    650653                } 
  • trunk/src/backend/cg87.c

    r805 r810  
    20002000        freenode(e->E1); 
    20012001        c1 = cat3(c1,c2,fixresult87(e,mST0 | mPSW,pretregs)); 
    20022002        return c1; 
    20032003} 
    20042004 
    20052005/******************************* 
    20062006 * Perform an assignment to a long double/double/float. 
    20072007 */ 
    20082008 
    20092009code *complex_eq87(elem *e,regm_t *pretregs) 
    20102010{ 
    20112011        regm_t retregs; 
    20122012        code *c1,*c2; 
    20132013        code cs; 
    20142014        unsigned op1; 
    20152015        unsigned op2; 
    20162016        unsigned sz; 
    20172017        tym_t ty1; 
    20182018        int fxch = 0; 
    20192019 
     2020        //printf("complex_eq87(e = %p, *pretregs = %s)\n", e, regm_str(*pretregs)); 
    20202021        assert(e->Eoper == OPeq); 
    20212022        cs.Iflags = ADDFWAIT() ? CFwait : 0; 
    20222023        cs.Irex = 0; 
    20232024        retregs = mST01 | (*pretregs & mPSW); 
    20242025        c1 = codelem(e->E2,&retregs,FALSE); 
    20252026        ty1 = tybasic(e->E1->Ety); 
    20262027        switch (ty1) 
    20272028        { 
    20282029            case TYcdouble:     op1 = ESC(MFdouble,1);  op2 = 3; break; 
    20292030            case TYcfloat:      op1 = ESC(MFfloat,1);   op2 = 3; break; 
    20302031            case TYcldouble:    op1 = 0xDB;             op2 = 7; break; 
    20312032            default: 
    20322033                assert(0); 
    20332034        } 
    2034         if (*pretregs & mST01)  // if want result on stack too 
     2035        if (*pretregs & (mST01 | mXMM0 | mXMM1))  // if want result on stack too 
    20352036        { 
    20362037            if (ty1 == TYcldouble) 
    20372038            { 
    20382039                c1 = cat(c1,push87()); 
    20392040                c1 = cat(c1,push87()); 
    20402041                c1 = genf2(c1,0xD9,0xC0 + 1);   // FLD ST(1) 
    20412042                genf2(c1,0xD9,0xC0 + 1);        // FLD ST(1) 
    20422043                pop87(); 
    20432044                pop87(); 
    20442045            } 
    20452046            else 
    20462047            {   op2 = 2;                        // FST e->E1 
    20472048                fxch = 1; 
    20482049            } 
    20492050        } 
    20502051        else 
    20512052        {                                       // FSTP e->E1 
    20522053            pop87(); 
    20532054            pop87(); 
    20542055        } 
    20552056        sz = tysize(ty1) / 2; 
    2056         if (*pretregs & mST01
     2057        if (*pretregs & (mST01 | mXMM0 | mXMM1)
    20572058        { 
    20582059            cs.Iflags = 0; 
    20592060            cs.Irex = 0; 
    20602061            cs.Iop = op1; 
    20612062            c2 = getlvalue(&cs, e->E1, 0); 
    20622063            cs.IEVoffset1 += sz; 
    20632064            cs.Irm |= modregrm(0, op2, 0); 
    20642065            c2 = cat(c2, makesure87(e->E2, sz, 0, 0)); 
    20652066            c2 = gen(c2, &cs); 
    20662067            c2 = genfwait(c2); 
    20672068            c2 = cat(c2, makesure87(e->E2,  0, 1, 0)); 
    20682069        } 
    20692070        else 
    20702071        { 
    20712072            c2 = loadea(e->E1,&cs,op1,op2,sz,0,0); 
    20722073            c2 = genfwait(c2); 
    20732074        } 
    20742075        if (fxch) 
    20752076            c2 = genf2(c2,0xD9,0xC8 + 1);       // FXCH ST(1) 
    20762077        cs.IEVoffset1 -= sz; 
  • trunk/src/backend/cod1.c

    r805 r810  
    17281728        } 
    17291729    } 
    17301730    return c; 
    17311731} 
    17321732 
    17331733 
    17341734/***************************** 
    17351735 * Given a result in registers, test it for TRUE or FALSE. 
    17361736 * Will fail if TYfptr and the reg is ES! 
    17371737 * If saveflag is TRUE, preserve the contents of the 
    17381738 * registers. 
    17391739 */ 
    17401740 
    17411741code *tstresult(regm_t regm,tym_t tym,unsigned saveflag) 
    17421742{ 
    17431743  unsigned scrreg;                      /* scratch register             */ 
    17441744  regm_t scrregm; 
    17451745 
    17461746#ifdef DEBUG 
    17471747  if (!(regm & (mBP | ALLREGS))) 
    1748         printf("tstresult(regm = x%x, tym = x%x, saveflag = %d)\n", 
    1749             regm,tym,saveflag); 
    1750 #endif 
    1751   assert(regm & (mBP | ALLREGS)); 
     1748        printf("tstresult(regm = %s, tym = x%x, saveflag = %d)\n", 
     1749            regm_str(regm),tym,saveflag); 
     1750#endif 
     1751  assert(regm & (XMMREGS | mBP | ALLREGS)); 
    17521752  tym = tybasic(tym); 
    17531753  code *ce = CNIL; 
    17541754  unsigned reg = findreg(regm); 
    17551755  unsigned sz = tysize[tym]; 
    17561756  if (sz == 1) 
    17571757  {     assert(regm & BYTEREGS); 
    17581758        return genregs(ce,0x84,reg,reg);        // TEST regL,regL 
     1759  } 
     1760  if (regm & XMMREGS) 
     1761  { 
     1762        unsigned xreg; 
     1763        regm_t xregs = XMMREGS & ~regm; 
     1764        ce = allocreg(&xregs, &xreg, TYdouble); 
     1765        unsigned op = 0; 
     1766        if (tym == TYdouble || tym == TYidouble || tym == TYcdouble) 
     1767            op = 0x660000; 
     1768        ce = gen2(ce,op | 0x0F57,modregrm(3,xreg-XMM0,xreg-XMM0));      // XORPS xreg,xreg 
     1769        gen2(ce,op | 0x0F2E,modregrm(3,xreg-XMM0,reg-XMM0));    // UCOMISS xreg,reg 
     1770        if (tym == TYcfloat || tym == TYcdouble) 
     1771        {   code *cnop = gennop(CNIL); 
     1772            genjmp(ce,JNE,FLcode,(block *) cnop); // JNE     L1 
     1773            genjmp(ce,JP, FLcode,(block *) cnop); // JP      L1 
     1774            reg = findreg(regm & ~mask[reg]); 
     1775            gen2(ce,op | 0x0F2E,modregrm(3,xreg-XMM0,reg-XMM0));        // UCOMISS xreg,reg 
     1776            ce = cat(ce, cnop); 
     1777        } 
     1778        return ce; 
    17591779  } 
    17601780  if (sz <= REGSIZE) 
    17611781  { 
    17621782    if (!I16) 
    17631783    { 
    17641784        if (tym == TYfloat) 
    17651785        {   if (saveflag) 
    17661786            { 
    17671787                scrregm = allregs & ~regm;              /* possible scratch regs */ 
    17681788                ce = allocreg(&scrregm,&scrreg,TYoffset); /* allocate scratch reg */ 
    17691789                ce = genmovreg(ce,scrreg,reg);  /* MOV scrreg,msreg     */ 
    17701790                reg = scrreg; 
    17711791            } 
    17721792            ce = cat(ce,getregs(mask[reg])); 
    17731793            return gen2(ce,0xD1,modregrmx(3,4,reg)); // SHL reg,1 
    17741794        } 
    17751795        ce = gentstreg(ce,reg);                 // TEST reg,reg 
    17761796        if (sz == SHORTSIZE) 
    17771797            ce->Iflags |= CFopsize;             /* 16 bit operands      */ 
    17781798        else if (sz == 8) 
  • trunk/src/backend/cod2.c

    r772 r810  
    200200        /* Therefore, numwords can never be 2.                          */ 
    201201        assert(!(tyfv(ty1) && tyfv(ty2))); 
    202202        if (sz == 2 * REGSIZE) 
    203203        { 
    204204            numwords++; 
    205205        } 
    206206  } 
    207207  else 
    208208  {     /* If ty is a TYfptr, but both operands are long, treat the     */ 
    209209        /* operation as a long.                                         */ 
    210210        if ((tylong(ty1) || ty1 == TYhptr) && 
    211211            (tylong(ty2) || ty2 == TYhptr)) 
    212212            numwords++; 
    213213  } 
    214214 
    215215  // Special cases where only flags are set 
    216216  if (test && tysize[ty1] <= REGSIZE && 
    217217      (e1->Eoper == OPvar || (e1->Eoper == OPind && !e1->Ecount))) 
    218218  { 
    219219        // Handle the case of (var & const) 
    220         if (e2->Eoper == OPconst
     220        if (e2->Eoper == OPconst && el_signx32(e2)
    221221        { 
    222222            c = getlvalue(&cs,e1,0); 
    223223            targ_size_t value = e2->EV.Vpointer; 
    224224            if (sz == 2) 
    225225                value &= 0xFFFF; 
    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) 
     
    278278            (!I16 && e1->Ecount) 
    279279           ) 
    280280        { 
    281281            int inc = e->Ecount != 0; 
    282282            nest += inc; 
    283283            c = getlvalue(&cs,e,0); 
    284284            nest -= inc; 
    285285            unsigned reg; 
    286286            c = cat(c,allocreg(pretregs,&reg,ty)); 
    287287            cs.Iop = 0x8D; 
    288288            code_newreg(&cs, reg); 
    289289            c = gen(c,&cs);          // LEA reg,EA 
    290290            if (rex) 
    291291                code_orrex(c, rex); 
    292292            return c; 
    293293        } 
    294294 
    295295        // Handle the case of ((e + c) + e2) 
    296296        if (!I16 && 
    297297            e1oper == OPadd && 
    298             (e1->E2->Eoper == OPconst || e2oper == OPconst) && 
     298            (e1->E2->Eoper == OPconst && el_signx32(e1->E2) || 
     299             e2oper == OPconst && el_signx32(e2)) && 
    299300            !e1->Ecount 
    300301           ) 
    301302        {   elem *e11; 
    302303            elem *ebase; 
    303304            elem *edisp; 
    304305            int ss; 
    305306            int ss2; 
    306307            unsigned reg1,reg2; 
    307308            code *c1,*c2,*c3; 
    308309 
    309             if (e2oper == OPconst
     310            if (e2oper == OPconst && el_signx32(e2)
    310311            {   edisp = e2; 
    311312                ebase = e1->E2; 
    312313            } 
    313314            else 
    314315            {   edisp = e1->E2; 
    315316                ebase = e2; 
    316317            } 
    317318 
    318319            e11 = e1->E1; 
    319320            retregs = *pretregs & ALLREGS; 
    320321            if (!retregs) 
    321322                retregs = ALLREGS; 
    322323            ss = 0; 
    323324            ss2 = 0; 
    324325 
    325326            // Handle the case of (((e *  c1) + c2) + e2) 
    326327            // Handle the case of (((e << c1) + c2) + e2) 
    327328            if ((e11->Eoper == OPmul || e11->Eoper == OPshl) && 
    328329                e11->E2->Eoper == OPconst && 
    329330                !e11->Ecount 
     
    611612 
    612613    case OPrelconst: 
    613614        if (sz != REGSIZE) 
    614615                goto L2; 
    615616        if (segfl[el_fl(e2)] != 3)              /* if not in data segment */ 
    616617                goto L2; 
    617618        if (evalinregister(e2)) 
    618619                goto L2; 
    619620        cs.IEVoffset2 = e2->EV.sp.Voffset; 
    620621        cs.IEVsym2 = e2->EV.sp.Vsym; 
    621622        cs.Iflags |= CFoff; 
    622623        i = 0;                          /* no INC or DEC opcode         */ 
    623624        rval = 0; 
    624625        goto L3; 
    625626 
    626627    case OPconst: 
    627628        if (tyfv(ty2)) 
    628629            goto L2; 
    629630        if (numwords == 1) 
    630631        { 
     632                if (!el_signx32(e2)) 
     633                    goto L2; 
    631634                i = e2->EV.Vpointer; 
    632635                if (word) 
    633636                { 
    634637                    if (!(*pretregs & mPSW) && 
    635638                        config.flags4 & CFG4speed && 
    636639                        (e->Eoper == OPor || e->Eoper == OPxor || test || 
    637640                         (e1->Eoper != OPvar && e1->Eoper != OPind))) 
    638641                    {   word = 0; 
    639642                        i &= 0xFFFF; 
    640643                    } 
    641644                } 
    642645                rval = reghasvalue(byte ? BYTEREGS : ALLREGS,i,&rreg); 
    643646                cs.IEV2.Vint = i; 
    644647        L3: 
    645648                op1 ^= byte; 
    646649                cs.Iflags |= word; 
    647650                if (rval) 
    648651                {   cs.Iop = op1 ^ 2; 
    649652                    mode = rreg; 
    650653                } 
  • trunk/src/template.c

    r809 r810  
    12981298            } 
    12991299            declareParameter(paramscope, tparam, oded); 
    13001300            dedargs->data[i] = (void *)oded; 
    13011301        } 
    13021302    } 
    13031303 
    13041304#if DMDV2 
    13051305    if (constraint) 
    13061306    {   /* Check to see if constraint is satisfied. 
    13071307         */ 
    13081308        makeParamNamesVisibleInConstraint(paramscope); 
    13091309        Expression *e = constraint->syntaxCopy(); 
    13101310        paramscope->flags |= SCOPEstaticif; 
    13111311 
    13121312        /* Detect recursive attempts to instantiate this template declaration, 
    13131313         * Bugzilla 4072 
    13141314         *  void foo(T)(T x) if (is(typeof(foo(x)))) { } 
    13151315         *  static assert(!is(typeof(foo(7)))); 
    13161316         * Recursive attempts are regarded as a constraint failure. 
    13171317         */ 
     1318        /* Previous should also store the scope, as instantiations along a different scope branch 
     1319         * should not conflict 
     1320         */ 
    13181321        int nmatches = 0; 
    13191322        for (Previous *p = previous; p; p = p->prev) 
    13201323        { 
    13211324            if (arrayObjectMatch(p->dedargs, dedargs, this, sc)) 
    13221325            { 
    13231326                //printf("recursive, no match %p %s\n", this, this->toChars()); 
    13241327                nmatches++; 
    13251328            } 
    13261329            /* BUG: should also check for ref param differences 
    13271330             */ 
    13281331        } 
    13291332        /* Look for 2 matches at least, because sometimes semantic3() gets run causing what appears to 
    13301333         * be recursion but isn't. 
    13311334         * Template A's constraint instantiates B, B's semantic3() run includes something that has A in its constraint. 
    13321335         * Perhaps a better solution is to always defer semantic3() rather than doing it eagerly. The risk 
    13331336         * with that is what if semantic3() fails, but our constraint "succeeded"? 
    13341337         */ 
    13351338        if (nmatches >= 2) 
    13361339            goto Lnomatch; 
    13371340