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

Changeset 790

Show
Ignore:
Timestamp:
12/07/10 10:39:21 (14 years ago)
Author:
walter
Message:

more 64

Files:

Legend:

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

    r772 r790  
    443443            //elem_print(e); 
    444444            break; 
    445445        } 
    446446        if (_8087elems[i].e == e && 
    447447            _8087elems[i].offset == offset) 
    448448        {   //printf("cse found %d\n",i); 
    449449            //elem_print(e); 
    450450            break; 
    451451        } 
    452452    } 
    453453    return i; 
    454454} 
    455455 
    456456/************************************* 
    457457 * Reload common subexpression. 
    458458 */ 
    459459 
    460460code *comsub87(elem *e,regm_t *pretregs) 
    461461{   code *c; 
    462462 
     463    //printf("comsub87(e = %p, *pretregs = %s)\n", e, regm_str(*pretregs)); 
    463464    // Look on 8087 stack 
    464465    int i = cse_get(e, 0); 
    465466 
    466467    if (tycomplex(e->Ety)) 
    467468    { 
    468469        unsigned sz = tysize(e->Ety); 
    469470        int j = cse_get(e, sz / 2); 
    470471        if (i >= 0 && j >= 0) 
    471472        { 
    472473            c = push87(); 
    473474            c = cat(c, push87()); 
    474475            c = genf2(c,0xD9,0xC0 + i);         // FLD ST(i) 
    475476            c = genf2(c,0xD9,0xC0 + j + 1);     // FLD ST(j + 1) 
    476477            c = cat(c,fixresult_complex87(e,mST01,pretregs)); 
    477478        } 
    478479        else 
    479480            // Reload 
    480481            c = loaddata(e,pretregs); 
    481482    } 
    482483    else 
    483484    { 
    484485        if (i >= 0) 
    485486        { 
    486487            c = push87(); 
    487488            c = genf2(c,0xD9,0xC0 + i); // FLD ST(i) 
    488             c = cat(c,fixresult(e,mST0,pretregs)); 
     489            if (*pretregs & XMMREGS) 
     490                c = cat(c,fixresult87(e,mST0,pretregs)); 
     491            else 
     492                c = cat(c,fixresult(e,mST0,pretregs)); 
    489493        } 
    490494        else 
    491495            // Reload 
    492496            c = loaddata(e,pretregs); 
    493497    } 
    494498 
    495499    freenode(e); 
    496500    return c; 
    497501} 
    498502 
    499503 
    500504/************************** 
    501505 * Generate code to deal with floatreg. 
    502506 */ 
    503507 
    504508code * genfltreg(code *c,unsigned opcode,unsigned reg,targ_size_t offset) 
    505509{ 
    506510        floatreg = TRUE; 
    507511        reflocal = TRUE; 
    508512        if ((opcode & ~7) == 0xD8) 
     
    15351539 
    15361540/************************* 
    15371541 * If op == -1, load expression e into ST0. 
    15381542 * else compute (eleft op e), eleft is in ST0. 
    15391543 * Must follow same logic as cmporder87(); 
    15401544 */ 
    15411545 
    15421546code *load87(elem *e,unsigned eoffset,regm_t *pretregs,elem *eleft,int op) 
    15431547{ 
    15441548        elem *e1; 
    15451549        code *ccomma,*c,*c2,*cpush; 
    15461550        code cs; 
    15471551        regm_t retregs; 
    15481552        unsigned reg,mf,mf1; 
    15491553        int opr; 
    15501554        unsigned char ldop; 
    15511555        tym_t ty; 
    15521556        int i; 
    15531557 
    15541558#if NDPP 
    1555         printf("+load87(e=%p, eoffset=%d, *pretregs=x%x, eleft=%p, op=%d, stackused = %d)\n",e,eoffset,*pretregs,eleft,op,stackused); 
     1559        printf("+load87(e=%p, eoffset=%d, *pretregs=%s, eleft=%p, op=%d, stackused = %d)\n",e,eoffset,regm_str(*pretregs),eleft,op,stackused); 
    15561560#endif 
    15571561        elem_debug(e); 
    15581562        ccomma = NULL; 
    15591563        cpush = NULL; 
    15601564        if (ADDFWAIT()) 
    15611565            cs.Iflags = CFwait; 
    15621566        else 
    15631567            cs.Iflags = 0; 
    15641568        cs.Irex = 0; 
    15651569        opr = oprev[op + 1]; 
    15661570        ty = tybasic(e->Ety); 
    15671571        if ((ty == TYldouble || ty == TYildouble) && 
    15681572            op != -1 && e->Eoper != OPd_ld) 
    15691573            goto Ldefault; 
    15701574        mf = (ty == TYfloat || ty == TYifloat || ty == TYcfloat) ? MFfloat : MFdouble; 
    15711575    L5: 
    15721576        switch (e->Eoper) 
    15731577        { 
    15741578            case OPcomma: 
    15751579                ccomma = docommas(&e); 
     
    18061810                    pop87(); 
    18071811                    if (op == 4 || op == 6)     // sub or div 
    18081812                    {   code *cl; 
    18091813 
    18101814                        cl = code_last(c); 
    18111815                        if (cl && cl->Iop == 0xD9 && cl->Irm == 0xC9)   // FXCH ST(1) 
    18121816                        {   cl->Iop = NOP; 
    18131817                            opr = op;           // reverse operands 
    18141818                        } 
    18151819                    } 
    18161820                    c = genf2(c,0xDE,modregrm(3,opr,1));        // FopRP 
    18171821                } 
    18181822                break; 
    18191823        } 
    18201824        if (op == 3)                    // FCOMP 
    18211825        {   pop87();                    // extra pop was done 
    18221826            cg87_87topsw(c); 
    18231827        } 
    18241828        c2 = fixresult87(e,((op == 3) ? mPSW : mST0),pretregs); 
    18251829#if NDPP 
    1826         printf("-load87(e=%p, eoffset=%d, *pretregs=x%x, eleft=%p, op=%d, stackused = %d)\n",e,eoffset,*pretregs,eleft,op,stackused); 
     1830        printf("-load87(e=%p, eoffset=%d, *pretregs=%s, eleft=%p, op=%d, stackused = %d)\n",e,eoffset,regm_str(*pretregs),eleft,op,stackused); 
    18271831#endif 
    18281832        return cat4(ccomma,cpush,c,c2); 
    18291833} 
    18301834 
    18311835/******************************** 
    18321836 * Determine if a compare is to be done forwards (return 0) 
    18331837 * or backwards (return 1). 
    18341838 * Must follow same logic as load87(). 
    18351839 */ 
    18361840 
    18371841int cmporder87(elem *e) 
    18381842{ 
    18391843    //printf("cmporder87(%p)\n",e); 
    18401844L1: 
    18411845        switch (e->Eoper) 
    18421846        { 
    18431847            case OPcomma: 
    18441848                e = e->E2; 
    18451849                goto L1; 
    18461850 
     
    18781882                goto ret1; 
    18791883        } 
    18801884 
    18811885ret1:   return 1; 
    18821886ret0:   return 0; 
    18831887} 
    18841888 
    18851889/******************************* 
    18861890 * Perform an assignment to a long double/double/float. 
    18871891 */ 
    18881892 
    18891893code *eq87(elem *e,regm_t *pretregs) 
    18901894{ 
    18911895        regm_t retregs; 
    18921896        code *c1,*c2; 
    18931897        code cs; 
    18941898        unsigned op1; 
    18951899        unsigned op2; 
    18961900        tym_t ty1; 
    18971901 
    1898         //printf("+eq87(e = %p, *pretregs = x%x)\n", e, *pretregs); 
     1902        //printf("+eq87(e = %p, *pretregs = %s)\n", e, regm_str(*pretregs)); 
    18991903        assert(e->Eoper == OPeq); 
    19001904        retregs = mST0 | (*pretregs & mPSW); 
    19011905        c1 = codelem(e->E2,&retregs,FALSE); 
    19021906        ty1 = tybasic(e->E1->Ety); 
    19031907        switch (ty1) 
    19041908        {   case TYdouble_alias: 
    19051909            case TYidouble: 
    19061910            case TYdouble:      op1 = ESC(MFdouble,1);  op2 = 3; break; 
    19071911            case TYifloat: 
    19081912            case TYfloat:       op1 = ESC(MFfloat,1);   op2 = 3; break; 
    19091913            case TYildouble: 
    19101914            case TYldouble:     op1 = 0xDB;             op2 = 7; break; 
    19111915            default: 
    19121916                assert(0); 
    19131917        } 
    1914         if (*pretregs & (mST0 | ALLREGS | mBP)) // if want result on stack too 
     1918        if (*pretregs & (mST0 | ALLREGS | mBP | XMMREGS)) // if want result on stack too 
    19151919        { 
    19161920            if (ty1 == TYldouble || ty1 == TYildouble) 
    19171921            { 
    19181922                c1 = cat(c1,push87()); 
    19191923                c1 = genf2(c1,0xD9,0xC0);       // FLD ST(0) 
    19201924                pop87(); 
    19211925            } 
    19221926            else 
    19231927                op2 = 2;                        // FST e->E1 
    19241928        } 
    19251929        else 
    19261930        {                                       // FSTP e->E1 
    19271931            pop87(); 
    19281932        } 
    19291933#if 0 
    19301934        // Doesn't work if ST(0) gets saved to the stack by getlvalue() 
    19311935        c2 = loadea(e->E1,&cs,op1,op2,0,0,0); 
    19321936#else 
    19331937        cs.Irex = 0; 
    19341938        cs.Iflags = 0; 
  • branches/dmd-1.x/src/backend/cgen.c

    r772 r790  
    552552 *      set flags based on result 
    553553 * Else if flags & 8 
    554554 *      do not disturb flags 
    555555 * Else 
    556556 *      don't care about flags 
    557557 * If flags & 1 then byte move 
    558558 * If flags & 2 then short move (for I32 and I64) 
    559559 * If flags & 4 then don't disturb unused portion of register 
    560560 * If flags & 16 then reg is a byte register AL..BH 
    561561 * If flags & 64 then 64 bit move (I64 only) 
    562562 * Returns: 
    563563 *      code (if any) generated 
    564564 */ 
    565565 
    566566code *movregconst(code *c,unsigned reg,targ_size_t value,regm_t flags) 
    567567{   unsigned r; 
    568568    regm_t regm; 
    569569    regm_t mreg; 
    570570    targ_size_t regv; 
    571571 
    572     //printf("movregconst(%llx)\n", value); 
     572    //printf("movregconst(%lld (%llx))\n", value, value); 
    573573#define genclrreg(a,r) genregs(a,0x31,r,r) 
    574574 
    575575    regm = regcon.immed.mval & mask[reg]; 
    576576    regv = regcon.immed.value[reg]; 
    577577 
    578578    if (flags & 1)      // 8 bits 
    579579    {   unsigned msk; 
    580580 
    581581        value &= 0xFF; 
    582582        regm &= BYTEREGS; 
    583583 
    584584        // If we already have the right value in the right register 
    585585        if (regm && (regv & 0xFF) == value) 
    586586            goto L2; 
    587587 
    588588        if (flags & 16 && reg & 4 &&    // if an H byte register 
    589589            regcon.immed.mval & mask[reg & 3] && 
    590590            (((regv = regcon.immed.value[reg & 3]) >> 8) & 0xFF) == value) 
    591591            goto L2; 
    592592 
  • branches/dmd-1.x/src/backend/cod1.c

    r772 r790  
    37863786        } 
    37873787        else if (sz == tysize[TYldouble])               // TYldouble 
    37883788            return load87(e,0,pretregs,NULL,-1); 
    37893789        else 
    37903790        { 
    37913791#ifdef DEBUG 
    37923792            elem_print(e); 
    37933793#endif 
    37943794            assert(0); 
    37953795        } 
    37963796        return c; 
    37973797  } 
    37983798  /* not for flags only */ 
    37993799  flags = *pretregs & mPSW;             /* save original                */ 
    38003800  forregs = *pretregs & (mBP | ALLREGS | mES | XMMREGS); 
    38013801  if (*pretregs & mSTACK) 
    38023802        forregs |= DOUBLEREGS; 
    38033803  if (e->Eoper == OPconst) 
    38043804  {     regm_t save; 
    38053805 
    3806         if (sz == REGSIZE && reghasvalue(forregs,e->EV.Vint,&reg)) 
     3806        targ_size_t value = e->EV.Vint; 
     3807        if (sz == 8) 
     3808            value = e->EV.Vullong; 
     3809 
     3810        if (sz == REGSIZE && reghasvalue(forregs,value,&reg)) 
    38073811            forregs = mask[reg]; 
    38083812 
    38093813        save = regcon.immed.mval; 
    38103814        c = allocreg(&forregs,&reg,tym);        /* allocate registers   */ 
    38113815        regcon.immed.mval = save;               // KLUDGE! 
    38123816        if (sz <= REGSIZE) 
    38133817        { 
    38143818            if (sz == 1) 
    38153819                flags |= 1; 
    38163820            else if (!I16 && sz == SHORTSIZE && 
    38173821                     !(mask[reg] & regcon.mvar) && 
    38183822                     !(config.flags4 & CFG4speed) 
    38193823                    ) 
    38203824                flags |= 2; 
    38213825            if (sz == 8) 
    38223826                flags |= 64; 
    38233827            if (reg >= XMM0) 
    38243828            {   /* This comes about because 0, 1, pi, etc., constants don't get stored 
    38253829                 * in the data segment, because they are x87 opcodes. 
    38263830                 * Not so efficient. We should at least do a PXOR for 0. 
    38273831                 */ 
    38283832                unsigned r; 
    38293833                targ_size_t value = e->EV.Vuns; 
    38303834                if (sz == 8) 
    38313835                    value = e->EV.Vullong; 
    38323836                ce = regwithvalue(CNIL,ALLREGS,value,&r,flags); 
    38333837                flags = 0;                              // flags are already set 
    38343838                ce = genfltreg(ce,0x89,r,0);            // MOV floatreg,r 
    38353839                if (sz == 8) 
    38363840                    code_orrex(ce, REX_W); 
    38373841                assert(sz == 4 || sz == 8);             // float or double 
    38383842                unsigned op = (sz == 4) ? 0xF30F10 : 0xF20F10; 
    38393843                ce = genfltreg(ce,op,reg - XMM0,0);     // MOVSS/MOVSD XMMreg,floatreg 
    38403844            } 
    38413845            else 
    3842             {   ce = movregconst(CNIL,reg,e->EV.Vint,flags); 
     3846            {   ce = movregconst(CNIL,reg,value,flags); 
    38433847                flags = 0;                          // flags are already set 
    38443848            } 
    38453849        } 
    38463850        else if (sz < 8)        // far pointers, longs for 16 bit targets 
    38473851        { 
    38483852            targ_int msw,lsw; 
    38493853            regm_t mswflags; 
    38503854 
    38513855            msw = I32   ? e->EV.Vfp.Vseg 
    38523856                        : (e->EV.Vulong >> 16); 
    38533857            lsw = e->EV.Vfp.Voff; 
    38543858            mswflags = 0; 
    38553859            if (forregs & mES) 
    38563860            { 
    38573861                ce = movregconst(CNIL,reg,msw,0);       // MOV reg,segment 
    38583862                genregs(ce,0x8E,0,reg);                 // MOV ES,reg 
    38593863                msw = lsw;                              // MOV reg,offset 
    38603864            } 
    38613865            else 
    38623866            { 
  • branches/dmd-1.x/src/backend/el.c

    r773 r790  
    30223022                assert(0); 
    30233023    } 
    30243024    if (bit == -1) 
    30253025        value++; 
    30263026    else if (bit == 1) 
    30273027        value--; 
    30283028    return value == 0; 
    30293029} 
    30303030 
    30313031/****************************** 
    30323032 * Extract long double value from constant elem. 
    30333033 * Silently ignore types which are not floating point values. 
    30343034 */ 
    30353035 
    30363036targ_ldouble el_toldouble(elem *e) 
    30373037{   targ_ldouble result; 
    30383038 
    30393039    elem_debug(e); 
    30403040    assert(cnst(e)); 
    30413041#if TX86 
    3042     switch (tysize(typemask(e))) 
    3043     { 
    3044         case FLOATSIZE:         // TYfloat 
     3042    switch (tybasic(typemask(e))) 
     3043    { 
     3044        case TYfloat: 
     3045        case TYifloat: 
    30453046            result = e->EV.Vfloat; 
    30463047            break; 
    3047         case DOUBLESIZE:        // TYdouble 
     3048        case TYdouble: 
     3049        case TYidouble: 
     3050        case TYdouble_alias: 
    30483051            result = e->EV.Vdouble; 
    30493052            break; 
    3050         case LNGDBLSIZE:        // TYldouble 
     3053        case TYldouble: 
     3054        case TYildouble: 
    30513055            result = e->EV.Vldouble; 
    30523056            break; 
    30533057    } 
    30543058#else 
    30553059#if !DDRT 
    30563060    switch (tysize[tybasic(typemask(e))]) 
    30573061    { 
    30583062    case FLOATSIZE:             // TYfloat 
    30593063        result = e->EV.Vfloat; 
    30603064        break; 
    30613065    case DOUBLESIZE:    // TYdouble 
    30623066        result = e->EV.Vdouble; 
    30633067        break; 
    30643068#if DOUBLESIZE != LNGDBLSIZE 
    30653069    case LNGDBLSIZE:    // TYldouble 
    30663070#ifdef LNGHDBLSIZE 
    30673071    case LNGHDBLSIZE: 
    30683072#endif 
    30693073#if (TARGET_POWERPC) 
    30703074        if (config.flags & CFGldblisdbl) 
  • branches/dmd-1.x/src/interpret.c

    r752 r790  
    13281328        Dsymbol *s = v->toAlias(); 
    13291329        if (s == v && !v->isStatic() && v->init) 
    13301330        { 
    13311331            ExpInitializer *ie = v->init->isExpInitializer(); 
    13321332            if (ie) 
    13331333                e = ie->exp->interpret(istate); 
    13341334            else if (v->init->isVoidInitializer()) 
    13351335                e = NULL; 
    13361336        } 
    13371337#if DMDV2 
    13381338        else if (s == v && (v->isConst() || v->isImmutable()) && v->init) 
    13391339#else 
    13401340        else if (s == v && v->isConst() && v->init) 
    13411341#endif 
    13421342        {   e = v->init->toExpression(); 
    13431343            if (!e) 
    13441344                e = EXP_CANT_INTERPRET; 
    13451345            else if (!e->type) 
    13461346                e->type = v->type; 
    13471347        } 
     1348#if 0 // currently fails test interpret3.d 
     1349        else 
     1350        { 
     1351            error("%s cannot be interpreted at compile time"); 
     1352            e = EXP_CANT_INTERPRET; 
     1353        } 
     1354#endif 
    13481355    } 
    13491356    else if (declaration->isAttribDeclaration() || 
    13501357             declaration->isTemplateMixin() || 
    13511358             declaration->isTupleDeclaration()) 
    13521359    {   // These can be made to work, too lazy now 
    13531360    error("Declaration %s is not yet implemented in CTFE", toChars()); 
    13541361 
    13551362        e = EXP_CANT_INTERPRET; 
    13561363    } 
    13571364    else 
    13581365    {   // Others should not contain executable code, so are trivial to evaluate 
    13591366        e = NULL; 
    13601367    } 
    13611368#if LOG 
    13621369    printf("-DeclarationExp::interpret(%s): %p\n", toChars(), e); 
    13631370#endif 
    13641371    return e; 
    13651372} 
    13661373 
    13671374Expression *TupleExp::interpret(InterState *istate) 
  • branches/dmd-1.x/src/tocsym.c

    r557 r790  
    218218            if (nestedref) 
    219219            { 
    220220                /* Symbol is accessed by a nested function. Make sure 
    221221                 * it is not put in a register, and that the optimizer 
    222222                 * assumes it is modified across function calls and pointer 
    223223                 * dereferences. 
    224224                 */ 
    225225                //printf("\tnested ref, not register\n"); 
    226226                type_setcv(&t, t->Tty | mTYvolatile); 
    227227            } 
    228228        } 
    229229        if (storage_class & STCconst) 
    230230        { 
    231231            // Insert const modifiers 
    232232            tym_t tym = 0; 
    233233 
    234234            if (storage_class & STCconst) 
    235235                tym |= mTYconst; 
    236236            type_setcv(&t, tym); 
    237237        } 
     238 
     239        if (ident == Id::va_argsave) 
     240            /* __va_argsave is set outside of the realm of the optimizer, 
     241             * so we tell the optimizer to leave it alone 
     242             */ 
     243            type_setcv(&t, t->Tty | mTYvolatile); 
     244 
    238245        switch (linkage) 
    239246        { 
    240247            case LINKwindows: 
    241248                m = mTYman_std; 
    242249                break; 
    243250 
    244251            case LINKpascal: 
    245252                m = mTYman_pas; 
    246253                break; 
    247254 
    248255            case LINKc: 
    249256                m = mTYman_c; 
    250257                break; 
    251258 
    252259            case LINKd: 
    253260                m = mTYman_d; 
    254261                break; 
    255262 
    256263            case LINKcpp: 
    257264                m = mTYman_cpp; 
  • trunk/src/backend/cg87.c

    r772 r790  
    443443            //elem_print(e); 
    444444            break; 
    445445        } 
    446446        if (_8087elems[i].e == e && 
    447447            _8087elems[i].offset == offset) 
    448448        {   //printf("cse found %d\n",i); 
    449449            //elem_print(e); 
    450450            break; 
    451451        } 
    452452    } 
    453453    return i; 
    454454} 
    455455 
    456456/************************************* 
    457457 * Reload common subexpression. 
    458458 */ 
    459459 
    460460code *comsub87(elem *e,regm_t *pretregs) 
    461461{   code *c; 
    462462 
     463    //printf("comsub87(e = %p, *pretregs = %s)\n", e, regm_str(*pretregs)); 
    463464    // Look on 8087 stack 
    464465    int i = cse_get(e, 0); 
    465466 
    466467    if (tycomplex(e->Ety)) 
    467468    { 
    468469        unsigned sz = tysize(e->Ety); 
    469470        int j = cse_get(e, sz / 2); 
    470471        if (i >= 0 && j >= 0) 
    471472        { 
    472473            c = push87(); 
    473474            c = cat(c, push87()); 
    474475            c = genf2(c,0xD9,0xC0 + i);         // FLD ST(i) 
    475476            c = genf2(c,0xD9,0xC0 + j + 1);     // FLD ST(j + 1) 
    476477            c = cat(c,fixresult_complex87(e,mST01,pretregs)); 
    477478        } 
    478479        else 
    479480            // Reload 
    480481            c = loaddata(e,pretregs); 
    481482    } 
    482483    else 
    483484    { 
    484485        if (i >= 0) 
    485486        { 
    486487            c = push87(); 
    487488            c = genf2(c,0xD9,0xC0 + i); // FLD ST(i) 
    488             c = cat(c,fixresult(e,mST0,pretregs)); 
     489            if (*pretregs & XMMREGS) 
     490                c = cat(c,fixresult87(e,mST0,pretregs)); 
     491            else 
     492                c = cat(c,fixresult(e,mST0,pretregs)); 
    489493        } 
    490494        else 
    491495            // Reload 
    492496            c = loaddata(e,pretregs); 
    493497    } 
    494498 
    495499    freenode(e); 
    496500    return c; 
    497501} 
    498502 
    499503 
    500504/************************** 
    501505 * Generate code to deal with floatreg. 
    502506 */ 
    503507 
    504508code * genfltreg(code *c,unsigned opcode,unsigned reg,targ_size_t offset) 
    505509{ 
    506510        floatreg = TRUE; 
    507511        reflocal = TRUE; 
    508512        if ((opcode & ~7) == 0xD8) 
     
    15351539 
    15361540/************************* 
    15371541 * If op == -1, load expression e into ST0. 
    15381542 * else compute (eleft op e), eleft is in ST0. 
    15391543 * Must follow same logic as cmporder87(); 
    15401544 */ 
    15411545 
    15421546code *load87(elem *e,unsigned eoffset,regm_t *pretregs,elem *eleft,int op) 
    15431547{ 
    15441548        elem *e1; 
    15451549        code *ccomma,*c,*c2,*cpush; 
    15461550        code cs; 
    15471551        regm_t retregs; 
    15481552        unsigned reg,mf,mf1; 
    15491553        int opr; 
    15501554        unsigned char ldop; 
    15511555        tym_t ty; 
    15521556        int i; 
    15531557 
    15541558#if NDPP 
    1555         printf("+load87(e=%p, eoffset=%d, *pretregs=x%x, eleft=%p, op=%d, stackused = %d)\n",e,eoffset,*pretregs,eleft,op,stackused); 
     1559        printf("+load87(e=%p, eoffset=%d, *pretregs=%s, eleft=%p, op=%d, stackused = %d)\n",e,eoffset,regm_str(*pretregs),eleft,op,stackused); 
    15561560#endif 
    15571561        elem_debug(e); 
    15581562        ccomma = NULL; 
    15591563        cpush = NULL; 
    15601564        if (ADDFWAIT()) 
    15611565            cs.Iflags = CFwait; 
    15621566        else 
    15631567            cs.Iflags = 0; 
    15641568        cs.Irex = 0; 
    15651569        opr = oprev[op + 1]; 
    15661570        ty = tybasic(e->Ety); 
    15671571        if ((ty == TYldouble || ty == TYildouble) && 
    15681572            op != -1 && e->Eoper != OPd_ld) 
    15691573            goto Ldefault; 
    15701574        mf = (ty == TYfloat || ty == TYifloat || ty == TYcfloat) ? MFfloat : MFdouble; 
    15711575    L5: 
    15721576        switch (e->Eoper) 
    15731577        { 
    15741578            case OPcomma: 
    15751579                ccomma = docommas(&e); 
     
    18061810                    pop87(); 
    18071811                    if (op == 4 || op == 6)     // sub or div 
    18081812                    {   code *cl; 
    18091813 
    18101814                        cl = code_last(c); 
    18111815                        if (cl && cl->Iop == 0xD9 && cl->Irm == 0xC9)   // FXCH ST(1) 
    18121816                        {   cl->Iop = NOP; 
    18131817                            opr = op;           // reverse operands 
    18141818                        } 
    18151819                    } 
    18161820                    c = genf2(c,0xDE,modregrm(3,opr,1));        // FopRP 
    18171821                } 
    18181822                break; 
    18191823        } 
    18201824        if (op == 3)                    // FCOMP 
    18211825        {   pop87();                    // extra pop was done 
    18221826            cg87_87topsw(c); 
    18231827        } 
    18241828        c2 = fixresult87(e,((op == 3) ? mPSW : mST0),pretregs); 
    18251829#if NDPP 
    1826         printf("-load87(e=%p, eoffset=%d, *pretregs=x%x, eleft=%p, op=%d, stackused = %d)\n",e,eoffset,*pretregs,eleft,op,stackused); 
     1830        printf("-load87(e=%p, eoffset=%d, *pretregs=%s, eleft=%p, op=%d, stackused = %d)\n",e,eoffset,regm_str(*pretregs),eleft,op,stackused); 
    18271831#endif 
    18281832        return cat4(ccomma,cpush,c,c2); 
    18291833} 
    18301834 
    18311835/******************************** 
    18321836 * Determine if a compare is to be done forwards (return 0) 
    18331837 * or backwards (return 1). 
    18341838 * Must follow same logic as load87(). 
    18351839 */ 
    18361840 
    18371841int cmporder87(elem *e) 
    18381842{ 
    18391843    //printf("cmporder87(%p)\n",e); 
    18401844L1: 
    18411845        switch (e->Eoper) 
    18421846        { 
    18431847            case OPcomma: 
    18441848                e = e->E2; 
    18451849                goto L1; 
    18461850 
     
    18781882                goto ret1; 
    18791883        } 
    18801884 
    18811885ret1:   return 1; 
    18821886ret0:   return 0; 
    18831887} 
    18841888 
    18851889/******************************* 
    18861890 * Perform an assignment to a long double/double/float. 
    18871891 */ 
    18881892 
    18891893code *eq87(elem *e,regm_t *pretregs) 
    18901894{ 
    18911895        regm_t retregs; 
    18921896        code *c1,*c2; 
    18931897        code cs; 
    18941898        unsigned op1; 
    18951899        unsigned op2; 
    18961900        tym_t ty1; 
    18971901 
    1898         //printf("+eq87(e = %p, *pretregs = x%x)\n", e, *pretregs); 
     1902        //printf("+eq87(e = %p, *pretregs = %s)\n", e, regm_str(*pretregs)); 
    18991903        assert(e->Eoper == OPeq); 
    19001904        retregs = mST0 | (*pretregs & mPSW); 
    19011905        c1 = codelem(e->E2,&retregs,FALSE); 
    19021906        ty1 = tybasic(e->E1->Ety); 
    19031907        switch (ty1) 
    19041908        {   case TYdouble_alias: 
    19051909            case TYidouble: 
    19061910            case TYdouble:      op1 = ESC(MFdouble,1);  op2 = 3; break; 
    19071911            case TYifloat: 
    19081912            case TYfloat:       op1 = ESC(MFfloat,1);   op2 = 3; break; 
    19091913            case TYildouble: 
    19101914            case TYldouble:     op1 = 0xDB;             op2 = 7; break; 
    19111915            default: 
    19121916                assert(0); 
    19131917        } 
    1914         if (*pretregs & (mST0 | ALLREGS | mBP)) // if want result on stack too 
     1918        if (*pretregs & (mST0 | ALLREGS | mBP | XMMREGS)) // if want result on stack too 
    19151919        { 
    19161920            if (ty1 == TYldouble || ty1 == TYildouble) 
    19171921            { 
    19181922                c1 = cat(c1,push87()); 
    19191923                c1 = genf2(c1,0xD9,0xC0);       // FLD ST(0) 
    19201924                pop87(); 
    19211925            } 
    19221926            else 
    19231927                op2 = 2;                        // FST e->E1 
    19241928        } 
    19251929        else 
    19261930        {                                       // FSTP e->E1 
    19271931            pop87(); 
    19281932        } 
    19291933#if 0 
    19301934        // Doesn't work if ST(0) gets saved to the stack by getlvalue() 
    19311935        c2 = loadea(e->E1,&cs,op1,op2,0,0,0); 
    19321936#else 
    19331937        cs.Irex = 0; 
    19341938        cs.Iflags = 0; 
  • trunk/src/backend/cgen.c

    r772 r790  
    552552 *      set flags based on result 
    553553 * Else if flags & 8 
    554554 *      do not disturb flags 
    555555 * Else 
    556556 *      don't care about flags 
    557557 * If flags & 1 then byte move 
    558558 * If flags & 2 then short move (for I32 and I64) 
    559559 * If flags & 4 then don't disturb unused portion of register 
    560560 * If flags & 16 then reg is a byte register AL..BH 
    561561 * If flags & 64 then 64 bit move (I64 only) 
    562562 * Returns: 
    563563 *      code (if any) generated 
    564564 */ 
    565565 
    566566code *movregconst(code *c,unsigned reg,targ_size_t value,regm_t flags) 
    567567{   unsigned r; 
    568568    regm_t regm; 
    569569    regm_t mreg; 
    570570    targ_size_t regv; 
    571571 
    572     //printf("movregconst(%llx)\n", value); 
     572    //printf("movregconst(%lld (%llx))\n", value, value); 
    573573#define genclrreg(a,r) genregs(a,0x31,r,r) 
    574574 
    575575    regm = regcon.immed.mval & mask[reg]; 
    576576    regv = regcon.immed.value[reg]; 
    577577 
    578578    if (flags & 1)      // 8 bits 
    579579    {   unsigned msk; 
    580580 
    581581        value &= 0xFF; 
    582582        regm &= BYTEREGS; 
    583583 
    584584        // If we already have the right value in the right register 
    585585        if (regm && (regv & 0xFF) == value) 
    586586            goto L2; 
    587587 
    588588        if (flags & 16 && reg & 4 &&    // if an H byte register 
    589589            regcon.immed.mval & mask[reg & 3] && 
    590590            (((regv = regcon.immed.value[reg & 3]) >> 8) & 0xFF) == value) 
    591591            goto L2; 
    592592 
  • trunk/src/backend/cod1.c

    r772 r790  
    37863786        } 
    37873787        else if (sz == tysize[TYldouble])               // TYldouble 
    37883788            return load87(e,0,pretregs,NULL,-1); 
    37893789        else 
    37903790        { 
    37913791#ifdef DEBUG 
    37923792            elem_print(e); 
    37933793#endif 
    37943794            assert(0); 
    37953795        } 
    37963796        return c; 
    37973797  } 
    37983798  /* not for flags only */ 
    37993799  flags = *pretregs & mPSW;             /* save original                */ 
    38003800  forregs = *pretregs & (mBP | ALLREGS | mES | XMMREGS); 
    38013801  if (*pretregs & mSTACK) 
    38023802        forregs |= DOUBLEREGS; 
    38033803  if (e->Eoper == OPconst) 
    38043804  {     regm_t save; 
    38053805 
    3806         if (sz == REGSIZE && reghasvalue(forregs,e->EV.Vint,&reg)) 
     3806        targ_size_t value = e->EV.Vint; 
     3807        if (sz == 8) 
     3808            value = e->EV.Vullong; 
     3809 
     3810        if (sz == REGSIZE && reghasvalue(forregs,value,&reg)) 
    38073811            forregs = mask[reg]; 
    38083812 
    38093813        save = regcon.immed.mval; 
    38103814        c = allocreg(&forregs,&reg,tym);        /* allocate registers   */ 
    38113815        regcon.immed.mval = save;               // KLUDGE! 
    38123816        if (sz <= REGSIZE) 
    38133817        { 
    38143818            if (sz == 1) 
    38153819                flags |= 1; 
    38163820            else if (!I16 && sz == SHORTSIZE && 
    38173821                     !(mask[reg] & regcon.mvar) && 
    38183822                     !(config.flags4 & CFG4speed) 
    38193823                    ) 
    38203824                flags |= 2; 
    38213825            if (sz == 8) 
    38223826                flags |= 64; 
    38233827            if (reg >= XMM0) 
    38243828            {   /* This comes about because 0, 1, pi, etc., constants don't get stored 
    38253829                 * in the data segment, because they are x87 opcodes. 
    38263830                 * Not so efficient. We should at least do a PXOR for 0. 
    38273831                 */ 
    38283832                unsigned r; 
    38293833                targ_size_t value = e->EV.Vuns; 
    38303834                if (sz == 8) 
    38313835                    value = e->EV.Vullong; 
    38323836                ce = regwithvalue(CNIL,ALLREGS,value,&r,flags); 
    38333837                flags = 0;                              // flags are already set 
    38343838                ce = genfltreg(ce,0x89,r,0);            // MOV floatreg,r 
    38353839                if (sz == 8) 
    38363840                    code_orrex(ce, REX_W); 
    38373841                assert(sz == 4 || sz == 8);             // float or double 
    38383842                unsigned op = (sz == 4) ? 0xF30F10 : 0xF20F10; 
    38393843                ce = genfltreg(ce,op,reg - XMM0,0);     // MOVSS/MOVSD XMMreg,floatreg 
    38403844            } 
    38413845            else 
    3842             {   ce = movregconst(CNIL,reg,e->EV.Vint,flags); 
     3846            {   ce = movregconst(CNIL,reg,value,flags); 
    38433847                flags = 0;                          // flags are already set 
    38443848            } 
    38453849        } 
    38463850        else if (sz < 8)        // far pointers, longs for 16 bit targets 
    38473851        { 
    38483852            targ_int msw,lsw; 
    38493853            regm_t mswflags; 
    38503854 
    38513855            msw = I32   ? e->EV.Vfp.Vseg 
    38523856                        : (e->EV.Vulong >> 16); 
    38533857            lsw = e->EV.Vfp.Voff; 
    38543858            mswflags = 0; 
    38553859            if (forregs & mES) 
    38563860            { 
    38573861                ce = movregconst(CNIL,reg,msw,0);       // MOV reg,segment 
    38583862                genregs(ce,0x8E,0,reg);                 // MOV ES,reg 
    38593863                msw = lsw;                              // MOV reg,offset 
    38603864            } 
    38613865            else 
    38623866            { 
  • trunk/src/backend/el.c

    r773 r790  
    30223022                assert(0); 
    30233023    } 
    30243024    if (bit == -1) 
    30253025        value++; 
    30263026    else if (bit == 1) 
    30273027        value--; 
    30283028    return value == 0; 
    30293029} 
    30303030 
    30313031/****************************** 
    30323032 * Extract long double value from constant elem. 
    30333033 * Silently ignore types which are not floating point values. 
    30343034 */ 
    30353035 
    30363036targ_ldouble el_toldouble(elem *e) 
    30373037{   targ_ldouble result; 
    30383038 
    30393039    elem_debug(e); 
    30403040    assert(cnst(e)); 
    30413041#if TX86 
    3042     switch (tysize(typemask(e))) 
    3043     { 
    3044         case FLOATSIZE:         // TYfloat 
     3042    switch (tybasic(typemask(e))) 
     3043    { 
     3044        case TYfloat: 
     3045        case TYifloat: 
    30453046            result = e->EV.Vfloat; 
    30463047            break; 
    3047         case DOUBLESIZE:        // TYdouble 
     3048        case TYdouble: 
     3049        case TYidouble: 
     3050        case TYdouble_alias: 
    30483051            result = e->EV.Vdouble; 
    30493052            break; 
    3050         case LNGDBLSIZE:        // TYldouble 
     3053        case TYldouble: 
     3054        case TYildouble: 
    30513055            result = e->EV.Vldouble; 
    30523056            break; 
    30533057    } 
    30543058#else 
    30553059#if !DDRT 
    30563060    switch (tysize[tybasic(typemask(e))]) 
    30573061    { 
    30583062    case FLOATSIZE:             // TYfloat 
    30593063        result = e->EV.Vfloat; 
    30603064        break; 
    30613065    case DOUBLESIZE:    // TYdouble 
    30623066        result = e->EV.Vdouble; 
    30633067        break; 
    30643068#if DOUBLESIZE != LNGDBLSIZE 
    30653069    case LNGDBLSIZE:    // TYldouble 
    30663070#ifdef LNGHDBLSIZE 
    30673071    case LNGHDBLSIZE: 
    30683072#endif 
    30693073#if (TARGET_POWERPC) 
    30703074        if (config.flags & CFGldblisdbl) 
  • trunk/src/interpret.c

    r752 r790  
    13281328        Dsymbol *s = v->toAlias(); 
    13291329        if (s == v && !v->isStatic() && v->init) 
    13301330        { 
    13311331            ExpInitializer *ie = v->init->isExpInitializer(); 
    13321332            if (ie) 
    13331333                e = ie->exp->interpret(istate); 
    13341334            else if (v->init->isVoidInitializer()) 
    13351335                e = NULL; 
    13361336        } 
    13371337#if DMDV2 
    13381338        else if (s == v && (v->isConst() || v->isImmutable()) && v->init) 
    13391339#else 
    13401340        else if (s == v && v->isConst() && v->init) 
    13411341#endif 
    13421342        {   e = v->init->toExpression(); 
    13431343            if (!e) 
    13441344                e = EXP_CANT_INTERPRET; 
    13451345            else if (!e->type) 
    13461346                e->type = v->type; 
    13471347        } 
     1348#if 0 // currently fails test interpret3.d 
     1349        else 
     1350        { 
     1351            error("%s cannot be interpreted at compile time"); 
     1352            e = EXP_CANT_INTERPRET; 
     1353        } 
     1354#endif 
    13481355    } 
    13491356    else if (declaration->isAttribDeclaration() || 
    13501357             declaration->isTemplateMixin() || 
    13511358             declaration->isTupleDeclaration()) 
    13521359    {   // These can be made to work, too lazy now 
    13531360    error("Declaration %s is not yet implemented in CTFE", toChars()); 
    13541361 
    13551362        e = EXP_CANT_INTERPRET; 
    13561363    } 
    13571364    else 
    13581365    {   // Others should not contain executable code, so are trivial to evaluate 
    13591366        e = NULL; 
    13601367    } 
    13611368#if LOG 
    13621369    printf("-DeclarationExp::interpret(%s): %p\n", toChars(), e); 
    13631370#endif 
    13641371    return e; 
    13651372} 
    13661373 
    13671374Expression *TupleExp::interpret(InterState *istate) 
  • trunk/src/tocsym.c

    r557 r790  
    219219            s->Sclass = SCextern; 
    220220            s->Sfl = FLextern; 
    221221            slist_add(s); 
    222222        } 
    223223        else 
    224224        { 
    225225            s->Sclass = SCauto; 
    226226            s->Sfl = FLauto; 
    227227 
    228228            if (nestedrefs.dim) 
    229229            { 
    230230                /* Symbol is accessed by a nested function. Make sure 
    231231                 * it is not put in a register, and that the optimizer 
    232232                 * assumes it is modified across function calls and pointer 
    233233                 * dereferences. 
    234234                 */ 
    235235                //printf("\tnested ref, not register\n"); 
    236236                type_setcv(&t, t->Tty | mTYvolatile); 
    237237            } 
    238238        } 
     239 
     240        if (ident == Id::va_argsave) 
     241            /* __va_argsave is set outside of the realm of the optimizer, 
     242             * so we tell the optimizer to leave it alone 
     243             */ 
     244            type_setcv(&t, t->Tty | mTYvolatile); 
    239245 
    240246        mangle_t m = 0; 
    241247        switch (linkage) 
    242248        { 
    243249            case LINKwindows: 
    244250                m = mTYman_std; 
    245251                break; 
    246252 
    247253            case LINKpascal: 
    248254                m = mTYman_pas; 
    249255                break; 
    250256 
    251257            case LINKc: 
    252258                m = mTYman_c; 
    253259                break; 
    254260 
    255261            case LINKd: 
    256262                m = mTYman_d; 
    257263                break; 
    258264