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

Changeset 627

Show
Ignore:
Timestamp:
08/25/10 21:37:50 (14 years ago)
Author:
walter
Message:

64 bit stuff

Files:

Legend:

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

    r622 r627  
    193193#endif 
    194194{ 
    195195        int i; 
    196196 
    197197#if NDPP 
    198198        dbg_printf("pop87(%s(%d): stackused=%d)\n", file, line, stackused); 
    199199#endif 
    200200        --stackused; 
    201201        assert(stackused >= 0); 
    202202        for (i = 0; i < arraysize(_8087elems) - 1; i++) 
    203203                _8087elems[i] = _8087elems[i + 1]; 
    204204        /* end of stack is nothing      */ 
    205205        _8087elems[arraysize(_8087elems) - 1] = ndp_zero; 
    206206} 
    207207 
    208208/******************************* 
    209209 * Push 8087 stack. Generate and return any code 
    210210 * necessary to preserve anything that might run off the end of the stack. 
    211211 */ 
    212212 
    213 code *push87() 
     213#undef push87 
     214 
     215#ifdef DEBUG 
     216code *push87(int line, const char *file); 
     217code *push87() { return push87(__LINE__,__FILE__); } 
     218#endif 
     219 
     220code *push87( 
     221#ifdef DEBUG 
     222        int line, const char *file 
     223#endif 
     224        ) 
     225#ifdef DEBUG 
     226#define push87() push87(__LINE__,__FILE__) 
     227#endif 
    214228{ 
    215229        code *c; 
    216230        int i; 
    217231 
    218232        c = CNIL; 
    219233        // if we would lose the top register off of the stack 
    220234        if (_8087elems[7].e != NULL) 
    221235        { 
    222236                i = getemptyslot(); 
    223237                NDP::save[i] = _8087elems[7]; 
    224238                c = genf2(c,0xD9,0xF6);         // FDECSTP 
    225239                c = genfwait(c); 
    226240                c = ndp_fstp(c, i, _8087elems[7].e->Ety);       // FSTP i[BP] 
    227241                assert(stackused == 8); 
    228242                if (NDPP) dbg_printf("push87() : overflow\n"); 
    229243        } 
    230244        else 
    231245        { 
    232                 if (NDPP) dbg_printf("push87(%d)\n",stackused); 
     246#ifdef DEBUG 
     247                if (NDPP) dbg_printf("push87(%s(%d): %d)\n", file, line, stackused); 
     248#endif 
    233249                stackused++; 
    234250                assert(stackused <= 8); 
    235251        } 
    236252        // Shift the stack up 
    237253        for (i = 7; i > 0; i--) 
    238254                _8087elems[i] = _8087elems[i - 1]; 
    239255        _8087elems[0] = ndp_zero; 
    240256        return c; 
    241257} 
    242258 
    243259/***************************** 
    244260 * Note elem e as being in ST(i) as being a value we want to keep. 
    245261 */ 
    246262 
    247263#ifdef DEBUG 
    248264void note87(elem *e, unsigned offset, int i, int linnum); 
    249265void note87(elem *e, unsigned offset, int i) 
    250266{ 
    251267    return note87(e, offset, i, 0); 
    252268} 
     
    472488            c = cat(c,fixresult(e,mST0,pretregs)); 
    473489        } 
    474490        else 
    475491            // Reload 
    476492            c = loaddata(e,pretregs); 
    477493    } 
    478494 
    479495    freenode(e); 
    480496    return c; 
    481497} 
    482498 
    483499 
    484500/************************** 
    485501 * Generate code to deal with floatreg. 
    486502 */ 
    487503 
    488504code * genfltreg(code *c,unsigned opcode,unsigned reg,targ_size_t offset) 
    489505{ 
    490506        floatreg = TRUE; 
    491507        reflocal = TRUE; 
    492         if ((opcode & 0xF8) == 0xD8) 
     508        if ((opcode & ~7) == 0xD8) 
    493509            c = genfwait(c); 
    494         unsigned grex = I64 ? (REX_W << 16) : 0; 
    495         return genc1(c,opcode,grex | modregxrm(2,reg,BPRM),FLfltreg,offset); 
     510        return genc1(c,opcode,modregxrm(2,reg,BPRM),FLfltreg,offset); 
    496511} 
    497512 
    498513/******************************* 
    499514 * Decide if we need to gen an FWAIT. 
    500515 */ 
    501516 
    502517code *genfwait(code *c) 
    503518{ 
    504519    if (ADDFWAIT()) 
    505520        c = gen1(c,FWAIT); 
    506521    return c; 
    507522} 
    508523 
    509524/*************************************** 
    510525 * Generate floating point instruction. 
    511526 */ 
    512527 
    513528STATIC code * genf2(code *c,unsigned op,unsigned rm) 
    514529{ 
    515530    return gen2(genfwait(c),op,rm); 
     
    824839            else 
    825840            {   c2 = genfltreg(c2,0x8B,AX,6); 
    826841                genfltreg(c2,0x8B,BX,4); 
    827842                genfltreg(c2,0x8B,CX,2); 
    828843                genfltreg(c2,0x8B,DX,0); 
    829844            } 
    830845        } 
    831846    } 
    832847    else if (*pretregs == 0 && retregs == mST0) 
    833848    { 
    834849        c1 = genf2(c1,0xDD,modregrm(3,3,0));    // FPOP 
    835850        pop87(); 
    836851    } 
    837852    else 
    838853    {   if (*pretregs & mPSW) 
    839854        {   if (!(retregs & mPSW)) 
    840855            {   assert(retregs & mST0); 
    841856                c1 = genftst(c1,e,!(*pretregs & mST0)); // FTST 
    842857            } 
    843858        } 
    844         assert(!(*pretregs & mST0) || (retregs & mST0)); 
     859        if (*pretregs & mST0 && retregs & XMMREGS) 
     860        { 
     861            assert(sz <= DOUBLESIZE); 
     862            unsigned mf = (sz == FLOATSIZE) ? MFfloat : MFdouble; 
     863            // MOVD floatreg,XMM? 
     864            unsigned reg = findreg(retregs); 
     865            c1 = genfltreg(c1,0xF20F11,reg - XMM0,0); 
     866            c2 = push87(); 
     867            c2 = genfltreg(c2,ESC(mf,1),0,0);                 // FLD float/double ptr fltreg 
     868        } 
     869        else if (retregs & mST0 && *pretregs & XMMREGS) 
     870        { 
     871            assert(sz <= DOUBLESIZE); 
     872            unsigned mf = (sz == FLOATSIZE) ? MFfloat : MFdouble; 
     873            // FSTP floatreg 
     874            pop87(); 
     875            c1 = genfltreg(c1,ESC(mf,1),3,0); 
     876            genfwait(c1); 
     877            // MOVD XMM?,floatreg 
     878            unsigned reg; 
     879            c2 = allocreg(pretregs,&reg,(sz == FLOATSIZE) ? TYfloat : TYdouble); 
     880            c2 = genfltreg(c2,0xF20F10,reg -XMM0,0); 
     881        } 
     882        else 
     883            assert(!(*pretregs & mST0) || (retregs & mST0)); 
    845884    } 
    846885    if (*pretregs & mST0) 
    847886        note87(e,0,0); 
    848887    return cat(c1,c2); 
    849888} 
    850889 
    851890/******************************** 
    852891 * Generate in-line 8087 code for the following operators: 
    853892 *      add 
    854893 *      min 
    855894 *      mul 
    856895 *      div 
    857896 *      cmp 
    858897 */ 
    859898 
    860899// Reverse the order that the op is done in 
    861900static const char oprev[9] = { -1,0,1,2,3,5,4,7,6 }; 
    862901 
    863902code *orth87(elem *e,regm_t *pretregs) 
    864903{ 
     
    16991738                c = regwithvalue(c,ALLREGS & mMSW,0,&reg,0);  // 0-extend 
    17001739                retregs |= mask[reg]; 
    17011740                mf1 = MFlong; 
    17021741                goto L3; 
    17031742            } 
    17041743            case OPs16_d:       mf1 = MFword;   goto L6; 
    17051744            case OPs32_d:       mf1 = MFlong;   goto L6; 
    17061745            L6: 
    17071746                if (op != -1) 
    17081747                    note87(eleft,eoffset,0);    // don't trash this value 
    17091748                if (e->E1->Eoper == OPvar || 
    17101749                    (e->E1->Eoper == OPind && e->E1->Ecount == 0)) 
    17111750                { 
    17121751                    goto L4; 
    17131752                } 
    17141753                else 
    17151754                { 
    17161755                    retregs = ALLREGS; 
    17171756                    c = codelem(e->E1,&retregs,FALSE); 
    17181757                L3: 
    1719                     if (!I32 && e->Eoper != OPs16_d) 
     1758                    if (I16 && e->Eoper != OPs16_d) 
    17201759                    { 
    17211760                        /* MOV floatreg+2,reg   */ 
    17221761                        reg = findregmsw(retregs); 
    17231762                        c = genfltreg(c,0x89,reg,REGSIZE); 
    17241763                        retregs &= mLSW; 
    17251764                    } 
    17261765                    reg = findreg(retregs); 
    17271766                    c = genfltreg(c,0x89,reg,0);        /* MOV floatreg,reg */ 
    17281767                    if (op != -1) 
    17291768                    {   c = cat(c,makesure87(eleft,eoffset,0,0)); 
    17301769                        genfltreg(c,ESC(mf1,0),op,0);   /* Fop floatreg */ 
    17311770                    } 
    17321771                    else 
    17331772                    { 
    17341773                        /* FLD long ptr floatreg        */ 
    17351774                        c = cat(c,push87()); 
    17361775                        c = genfltreg(c,ESC(mf1,1),0,0); 
    17371776                    } 
    17381777                } 
    17391778                break; 
     
    33043343        c2 = genfltreg(c2, 0x8B, DX, 0);        // MOV EDX,floatreg 
    33053344 
    33063345        pop87(); 
    33073346        c2 = genfltreg(c2, ESC(MFfloat,1),3,0); // FSTP floatreg 
    33083347        genfwait(c2); 
    33093348        c2 = genfltreg(c2, 0x8B, AX, 0);        // MOV EAX,floatreg 
    33103349    } 
    33113350    else if (tym == TYcfloat && retregs & (mAX|mDX) && *pretregs & mST01) 
    33123351    { 
    33133352        c1 = push87(); 
    33143353        c1 = genfltreg(c1, 0x89, AX, 0);        // MOV floatreg, EAX 
    33153354        genfltreg(c1, 0xD9, 0, 0);              // FLD float ptr floatreg 
    33163355 
    33173356        c2 = push87(); 
    33183357        c2 = genfltreg(c2, 0x89, DX, 0);        // MOV floatreg, EDX 
    33193358        genfltreg(c2, 0xD9, 0, 0);              // FLD float ptr floatreg 
    33203359 
    33213360        if (*pretregs & mPSW) 
    33223361            c2 = genctst(c2,e,0);               // FTST 
    33233362    } 
     3363    else if ((tym == TYcfloat || tym == TYcdouble) && 
     3364             *pretregs & (mXMM0|mXMM1) && retregs & mST01) 
     3365    { 
     3366        if (*pretregs & mPSW && !(retregs & mPSW)) 
     3367            c1 = genctst(c1,e,0);               // FTST 
     3368        pop87(); 
     3369        c1 = genfltreg(c1, ESC(MFdouble,1),3,0); // FSTP floatreg 
     3370        genfwait(c1); 
     3371        c2 = getregs(mXMM0|mXMM1); 
     3372        c2 = genfltreg(c2, 0xF20F10, XMM1 - XMM0, 0);    // MOVD XMM1,floatreg 
     3373 
     3374        pop87(); 
     3375        c2 = genfltreg(c2, ESC(MFdouble,1),3,0); // FSTP floatreg 
     3376        genfwait(c2); 
     3377        c2 = genfltreg(c2, 0xF20F10, XMM0 - XMM0, 0);    // MOVD XMM0,floatreg 
     3378    } 
     3379    else if ((tym == TYcfloat || tym == TYcdouble) && 
     3380             retregs & (mXMM0|mXMM1) && *pretregs & mST01) 
     3381    { 
     3382        c1 = push87(); 
     3383        c1 = genfltreg(c1, 0xF20F11, XMM0-XMM0, 0);        // MOVD floatreg, XMM0 
     3384        genfltreg(c1, 0xDD, 0, 0);              // FLD double ptr floatreg 
     3385 
     3386        c2 = push87(); 
     3387        c2 = genfltreg(c2, 0xF20F11, XMM1-XMM0, 0);        // MOV floatreg, XMM1 
     3388        genfltreg(c2, 0xDD, 0, 0);              // FLD double ptr floatreg 
     3389 
     3390        if (*pretregs & mPSW) 
     3391            c2 = genctst(c2,e,0);               // FTST 
     3392    } 
    33243393    else 
    33253394    {   if (*pretregs & mPSW) 
    33263395        {   if (!(retregs & mPSW)) 
    33273396            {   assert(retregs & mST01); 
    33283397                c1 = genctst(c1,e,!(*pretregs & mST01));        // FTST 
    33293398            } 
    33303399        } 
    33313400        assert(!(*pretregs & mST01) || (retregs & mST01)); 
    33323401    } 
    33333402    if (*pretregs & mST01) 
    33343403    {   note87(e,0,1); 
    33353404        note87(e,sz/2,0); 
    33363405    } 
    33373406    return cat(c1,c2); 
    33383407} 
    33393408 
    33403409/***************************************** 
    33413410 * Operators OPc_r and OPc_i 
    33423411 */ 
    33433412 
     
    33813450    assert(*pretregs & (mST01 | mPSW)); 
    33823451    assert(!(*pretregs & ~(mST01 | mPSW))); 
    33833452} 
    33843453__out (result) 
    33853454{ 
    33863455} 
    33873456__body 
    33883457#endif 
    33893458{ 
    33903459    tym_t ty = tybasic(e->Ety); 
    33913460    code *c = NULL; 
    33923461    code *cpush = NULL; 
    33933462    code cs; 
    33943463    unsigned mf; 
    33953464    unsigned sz; 
    33963465    unsigned char ldop; 
    33973466    regm_t retregs; 
    33983467    symbol *s; 
    33993468    int i; 
    34003469 
     3470    //printf("cload87(e = %p, *pretregs = %s)\n", e, regm_str(*pretregs)); 
    34013471    sz = tysize[ty] / 2; 
    34023472    memset(&cs, 0, sizeof(cs)); 
    34033473    if (ADDFWAIT()) 
    34043474        cs.Iflags = CFwait; 
    34053475    switch (ty) 
    34063476    { 
    34073477        case TYcfloat:      mf = MFfloat;           break; 
    34083478        case TYcdouble:     mf = MFdouble;          break; 
    34093479        case TYcldouble:    break; 
    34103480        default:            assert(0); 
    34113481    } 
    34123482    switch (e->Eoper) 
    34133483    { 
    34143484        case OPvar: 
    34153485            notreg(e);                  // never enregister this variable 
    34163486        case OPind: 
    34173487            cpush = cat(push87(), push87()); 
    34183488            switch (ty) 
    34193489            { 
    34203490                case TYcfloat: 
  • branches/dmd-1.x/src/backend/cgcod.c

    r619 r627  
    377377            i = branch(b,0);            // see if jmp => jmp short 
    378378            if (i)                      /* if any bytes saved           */ 
    379379            {   targ_size_t offset; 
    380380 
    381381                b->Bsize -= i; 
    382382                offset = b->Boffset + b->Bsize; 
    383383                for (bn = b->Bnext; bn; bn = bn->Bnext) 
    384384                { 
    385385                    if (bn->Balign) 
    386386                    {   targ_size_t u = bn->Balign - 1; 
    387387 
    388388                        offset = (offset + u) & ~u; 
    389389                    } 
    390390                    bn->Boffset = offset; 
    391391                    offset += bn->Bsize; 
    392392                } 
    393393                coffset = offset; 
    394394                flag = TRUE; 
    395395            } 
    396396        } 
    397         if (I32 && !(config.flags4 & CFG4optimized)) 
     397        if (!I16 && !(config.flags4 & CFG4optimized)) 
    398398            break;                      // use the long conditional jmps 
    399399    } while (flag);                     // loop till no more bytes saved 
    400400#ifdef DEBUG 
    401401    debugw && printf("code jump optimization complete\n"); 
    402402#endif 
    403403 
    404404    // Compute starting offset for switch tables 
    405405#if ELFOBJ || MACHOBJ 
    406406    swoffset = (config.flags & CFGromable) ? coffset : CDoffset; 
    407407#else 
    408408    swoffset = (config.flags & CFGromable) ? coffset : Doffset; 
    409409#endif 
    410410    swoffset = align(0,swoffset); 
    411411 
    412412    // Emit the generated code 
    413413    if (eecontext.EEcompile == 1) 
    414414    { 
    415415        codout(eecontext.EEcode); 
    416416        code_free(eecontext.EEcode); 
    417417#if SCPP 
  • branches/dmd-1.x/src/backend/cgelem.c

    r618 r627  
    20662066            return optelem(e,TRUE); 
    20672067        } 
    20682068#else 
    20692069        { 
    20702070            e->Eoper = OPeq; 
    20712071            el_free(e->E2); 
    20722072            e->E2 = el_copytree(e1); 
    20732073            e->E2 = el_una(OPneg,tym,e->E2); 
    20742074            return optelem(e,TRUE); 
    20752075        } 
    20762076#endif 
    20772077#endif 
    20782078    } 
    20792079 
    20802080    if (OPTIMIZER) 
    20812081    { 
    20822082        if (tyintegral(tym) && (e->Eoper == OPdiv || e->Eoper == OPmod)) 
    20832083        {   int sz = tysize(tym); 
    20842084 
    20852085            // See if we can replace with OPremquo 
    2086             if (sz == intsize) 
     2086            if (sz == REGSIZE && !I64)  // need cent and ucent working for I64 to work 
    20872087            { 
    20882088                // Don't do it if there are special code sequences in the 
    20892089                // code generator (see cdmul()) 
    20902090                int pow2; 
    20912091                if (e->E2->Eoper == OPconst && 
    20922092                    sz == REGSIZE && !uns && 
    20932093                    (pow2 = ispow2(el_tolong(e->E2))) != -1 && 
    20942094                    !(config.target_cpu < TARGET_80286 && pow2 != 1 && e->Eoper == OPdiv) 
    20952095                   ) 
    20962096                    ; 
    20972097                else 
    20982098                { 
    20992099                    assert(sz == 2 || sz == 4); 
    21002100                    int op = OPmsw; 
    21012101                    if (e->Eoper == OPdiv) 
    21022102                    { 
    21032103                        op = (sz == 2) ? OP32_16 : OP64_32; 
    21042104                    } 
    21052105                    e->Eoper = OPremquo; 
    21062106                    e = el_una(op, tym, e); 
  • branches/dmd-1.x/src/backend/cgen.c

    r606 r627  
    144144 * Add code to end of linked list. 
    145145 * Note that unused operands are garbage. 
    146146 * gen1() and gen2() are shortcut routines. 
    147147 * Input: 
    148148 *      c ->    linked list that code is to be added to end of 
    149149 *      cs ->   data for the code 
    150150 * Returns: 
    151151 *      pointer to start of code list 
    152152 */ 
    153153 
    154154code *gen(code *c,code *cs) 
    155155{   code *ce,*cstart; 
    156156    unsigned reg; 
    157157 
    158158#ifdef DEBUG                            /* this is a high usage routine */ 
    159159    assert(cs); 
    160160#endif 
    161161    assert(I64 || cs->Irex == 0); 
    162162    ce = code_calloc(); 
    163163    *ce = *cs; 
     164    //printf("ce = %p %02x\n", ce, ce->Iop); 
     165    if (ce->Iop == LEA && ce->Irm == 4 && ce->Isib == 0x6D && ce->IFL1 == FLunde) *(char*)0=0; 
    164166    if (config.flags4 & CFG4optimized && 
    165167        ce->IFL2 == FLconst && 
    166168        (ce->Iop == 0x81 || ce->Iop == 0x80) && 
    167169        reghasvalue((ce->Iop == 0x80) ? BYTEREGS : ALLREGS,ce->IEV2.Vlong,&reg) && 
    168170        !(ce->Iflags & CFopsize && I16) 
    169171       ) 
    170172    {   // See if we can replace immediate instruction with register instruction 
    171173        static unsigned char regop[8] = 
    172174                { 0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38 }; 
    173175 
    174176//printf("replacing 0x%02x, val = x%lx\n",ce->Iop,ce->IEV2.Vlong); 
    175177        ce->Iop = regop[(ce->Irm & modregrm(0,7,0)) >> 3] | (ce->Iop & 1); 
    176178        code_newreg(ce, reg); 
    177179    } 
    178180    code_next(ce) = CNIL; 
    179181    if (c) 
    180182    {   cstart = c; 
    181183        while (code_next(c)) c = code_next(c);  /* find end of list     */ 
    182184        code_next(c) = ce;                      /* link into list       */ 
    183185        return cstart; 
    184186    } 
    185187    return ce; 
    186188} 
    187189 
    188190code *gen1(code *c,unsigned op) 
    189191{ code *ce,*cstart; 
    190192 
    191193  ce = code_calloc(); 
    192194  ce->Iop = op; 
     195  assert(op != LEA); 
    193196  if (c) 
    194197  {     cstart = c; 
    195198        while (code_next(c)) c = code_next(c);  /* find end of list     */ 
    196199        code_next(c) = ce;                      /* link into list       */ 
    197200        return cstart; 
    198201  } 
    199202  return ce; 
    200203} 
    201204 
    202205code *gen2(code *c,unsigned op,unsigned rm) 
    203206{ code *ce,*cstart; 
    204207 
    205208  cstart = ce = code_calloc(); 
    206209  /*cxcalloc++;*/ 
    207210  ce->Iop = op; 
    208211  ce->Iea = rm; 
    209212  if (c) 
    210213  {     cstart = c; 
    211214        while (code_next(c)) c = code_next(c);  /* find end of list     */ 
    212215        code_next(c) = ce;                      /* link into list       */ 
    213216  } 
    214217  return cstart; 
    215218} 
    216219 
    217220code *gen2sib(code *c,unsigned op,unsigned rm,unsigned sib) 
    218221{ code *ce,*cstart; 
    219222 
    220223  cstart = ce = code_calloc(); 
    221224  /*cxcalloc++;*/ 
     225  if (op == LEA && (rm & 0xFF) == 4 && (sib & 0xFF) == 0x6D) *(char*)0=0; 
    222226  ce->Iop = op; 
    223227  ce->Irm = rm; 
    224228  ce->Isib = sib; 
    225229  ce->Irex = (rm | (sib & (REX_B << 16))) >> 16; 
    226230  if (sib & (REX_R << 16)) 
    227231        ce->Irex |= REX_X; 
    228232  if (c) 
    229233  {     cstart = c; 
    230234        while (code_next(c)) c = code_next(c);  /* find end of list     */ 
    231235        code_next(c) = ce;                      /* link into list       */ 
    232236  } 
    233237  return cstart; 
    234238} 
    235239 
    236240code *genregs(code *c,unsigned op,unsigned dstreg,unsigned srcreg) 
    237241{ return gen2(c,op,modregxrmx(3,dstreg,srcreg)); } 
    238242 
    239243code *gentstreg(code *c,unsigned t) 
    240244{ 
    241245    c = gen2(c,0x85,modregxrmx(3,t,t));   // TEST t,t 
     
    370374    cs.Iea = ea; 
    371375    cs.Iflags = CFoff; 
    372376    cs.IFL2 = FLconst; 
    373377    cs.IEV2.Vsize_t = EV2; 
    374378    return gen(c,&cs); 
    375379} 
    376380 
    377381/***************** 
    378382 * Generate code. 
    379383 */ 
    380384 
    381385code *genc1(code *c,unsigned op,unsigned ea,unsigned FL1,targ_size_t EV1) 
    382386{   code cs; 
    383387 
    384388    assert(FL1 < FLMAX); 
    385389    cs.Iop = op; 
    386390    cs.Iflags = CFoff; 
    387391    cs.Iea = ea; 
    388392    cs.IFL1 = FL1; 
    389393    cs.IEV1.Vsize_t = EV1; 
     394if (cs.Iop == LEA && cs.IFL1 == FLunde) *(char*)0=0; 
    390395    return gen(c,&cs); 
    391396} 
    392397 
    393398/***************** 
    394399 * Generate code. 
    395400 */ 
    396401 
    397402code *genc(code *c,unsigned op,unsigned ea,unsigned FL1,targ_size_t EV1,unsigned FL2,targ_size_t EV2) 
    398403{   code cs; 
    399404 
    400405    assert(FL1 < FLMAX); 
    401406    cs.Iop = op; 
    402407    cs.Iea = ea; 
    403408    cs.Iflags = CFoff; 
    404409    cs.IFL1 = FL1; 
    405410    cs.IEV1.Vsize_t = EV1; 
    406411    assert(FL2 < FLMAX); 
    407412    cs.IFL2 = FL2; 
    408413    cs.IEV2.Vsize_t = EV2; 
    409414    return gen(c,&cs); 
  • branches/dmd-1.x/src/backend/cod1.c

    r621 r627  
    18551855                c = getregs(forregs); 
    18561856                ce = gen1(ce,0x58 + DX); 
    18571857                gen1(ce,0x58 + CX); 
    18581858                gen1(ce,0x58 + BX); 
    18591859                gen1(ce,0x58 + AX); 
    18601860                stackpush -= DOUBLESIZE; 
    18611861                retregs = DOUBLEREGS_16; /* for tstresult() below       */ 
    18621862            } 
    18631863            else 
    18641864#ifdef DEBUG 
    18651865                printf("retregs = x%x, forregs = x%x\n",retregs,forregs), 
    18661866#endif 
    18671867                assert(0); 
    18681868            if (EOP(e)) 
    18691869                opsflag = TRUE; 
    18701870        } 
    18711871        else 
    18721872        { 
    18731873            c = allocreg(pretregs,&rreg,tym); /* allocate return regs   */ 
    18741874            if (sz > REGSIZE) 
    1875             {   unsigned msreg,lsreg; 
    1876                 unsigned msrreg,lsrreg; 
    1877  
    1878                 msreg = findregmsw(retregs); 
    1879                 lsreg = findreglsw(retregs); 
    1880                 msrreg = findregmsw(*pretregs); 
    1881                 lsrreg = findreglsw(*pretregs); 
     1875            { 
     1876                unsigned msreg = findregmsw(retregs); 
     1877                unsigned lsreg = findreglsw(retregs); 
     1878                unsigned msrreg = findregmsw(*pretregs); 
     1879                unsigned lsrreg = findreglsw(*pretregs); 
    18821880 
    18831881                ce = genmovreg(ce,msrreg,msreg); /* MOV msrreg,msreg    */ 
    18841882                ce = genmovreg(ce,lsrreg,lsreg); /* MOV lsrreg,lsreg    */ 
    18851883            } 
     1884            else if (retregs & XMMREGS) 
     1885            { 
     1886                reg = findreg(retregs & XMMREGS); 
     1887                // MOVD floatreg, XMM? 
     1888                ce = genfltreg(ce,0xF20F11,reg - XMM0,0); 
     1889                // MOV rreg,floatreg 
     1890                ce = genfltreg(ce,0x8B,rreg,0); 
     1891                if (sz == 8) 
     1892                    code_orrex(ce,REX_W); 
     1893            } 
    18861894            else 
    1887             {   reg = findreg(retregs & (mBP | ALLREGS)); 
     1895            { 
     1896                reg = findreg(retregs & (mBP | ALLREGS)); 
    18881897                ce = genmovreg(ce,rreg,reg);    /* MOV rreg,reg         */ 
    18891898            } 
    18901899        } 
    18911900        c = cat(c,ce); 
    18921901        cssave(e,retregs | *pretregs,opsflag); 
    18931902        forregs = 0;                    /* don't care about result in reg  */ 
    18941903                                        /* cuz we have real result in rreg */ 
    18951904        retregs = *pretregs & ~mPSW; 
    18961905  } 
    18971906  if (forccs)                           /* if return result in flags    */ 
    18981907        c = cat(c,tstresult(retregs,tym,forregs)); 
    18991908  return c; 
    19001909} 
    19011910 
    19021911 
    19031912/******************************** 
    19041913 * Generate code sequence to call C runtime library support routine. 
    19051914 *      clib = CLIBxxxx 
    19061915 *      keepmask = mask of registers not to destroy. Currently can 
    19071916 *              handle only 1. Should use a temporary rather than 
    19081917 *              push/pop for speed. 
    19091918 */ 
    19101919 
    19111920int clib_inited = 0;            // != 0 if initialized 
    19121921 
    19131922code *callclib(elem *e,unsigned clib,regm_t *pretregs,regm_t keepmask) 
    19141923{ 
     1924    //printf("callclib(e = %p, clib = %d, *pretregs = %s, keepmask = %s\n", e, clib, regm_str(*pretregs), regm_str(keepmask)); 
     1925    //elem_print(e); 
    19151926#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 
    19161927  static symbol lib[] = 
    19171928  { 
    19181929/* Convert destroyed regs into saved regs       */ 
    19191930#define Z(desregs)      (~(desregs) & (mBP| mES | ALLREGS)) 
    19201931#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 
    19211932#define N(name) "_" name 
    19221933#else 
    19231934#define N(name) name 
    19241935#endif 
    19251936 
    19261937/* Shorthand to map onto SYMBOLY()              */ 
    19271938#define Y(desregs,name)  SYMBOLY(FLfunc,Z(desregs),N(name),0) 
    19281939 
    19291940    Y(0,"_LCMP__"),                     // CLIBlcmp 
    19301941    Y(mAX|mCX|mDX,"_LMUL__"),           // CLIBlmul 
    19311942#if 1 
    19321943    Y(mAX|mBX|mCX|mDX,"_LDIV__"),       // CLIBldiv 
    19331944    Y(mAX|mBX|mCX|mDX,"_LDIV__"),       // CLIBlmod 
    19341945    Y(mAX|mBX|mCX|mDX,"_ULDIV__"),      // CLIBuldiv 
     
    20812092 
    20822093    // NOTE: desregs is wrong for 16 bit code, mBX should be included 
    20832094    Y(mST0|mST01,"_Cmul"),              // CLIBcmul 
    20842095    Y(mAX|mCX|mDX|mST0|mST01,"_Cdiv"),  // CLIBcdiv 
    20852096    Y(mAX|mST0|mST01,"_Ccmp"),          // CLIBccmp 
    20862097 
    20872098    Y(mST0,"_U64_LDBL"),                // CLIBu64_ldbl 
    20882099    Y(mST0|mAX|mDX,"__LDBLULLNG"),      // CLIBld_u64 
    20892100  }; 
    20902101#endif 
    20912102 
    20922103  static struct 
    20932104  { 
    20942105    regm_t retregs16;   /* registers that 16 bit result is returned in  */ 
    20952106    regm_t retregs32;   /* registers that 32 bit result is returned in  */ 
    20962107    char pop;           /* # of bytes popped off of stack upon return   */ 
    20972108    char flags; 
    20982109        #define INF32           1       // if 32 bit only 
    20992110        #define INFfloat        2       // if this is floating point 
    21002111        #define INFwkdone       4       // if weak extern is already done 
     2112        #define INF64           8       // if 64 bit only 
    21012113    char push87;                        // # of pushes onto the 8087 stack 
    21022114    char pop87;                         // # of pops off of the 8087 stack 
    21032115  } info[CLIBMAX] = 
    21042116  { 
    21052117    {0,0,0,0},                          /* _LCMP@       lcmp    */ 
    21062118    {mDX|mAX,mDX|mAX,0,0},              // _LMUL@       lmul 
    21072119    {mDX|mAX,mDX|mAX,0,0},              // _LDIV@       ldiv 
    21082120    {mCX|mBX,mCX|mBX,0,0},              /* _LDIV@       lmod    */ 
    21092121    {mDX|mAX,mDX|mAX,0,0},              /* _ULDIV@      uldiv   */ 
    21102122    {mCX|mBX,mCX|mBX,0,0},              /* _ULDIV@      ulmod   */ 
    21112123 
    21122124#if TARGET_WINDOS 
    21132125    {DOUBLEREGS_16,DOUBLEREGS_32,8,INFfloat,1,1},       // _DMUL@       dmul 
    21142126    {DOUBLEREGS_16,DOUBLEREGS_32,8,INFfloat,1,1},       // _DDIV@       ddiv 
    21152127    {0,0,0,2},                                          // _DTST0@ 
    21162128    {0,0,0,2},                                          // _DTST0EXC@ 
    21172129    {0,0,8,INFfloat,1,1},                               // _DCMP@       dcmp 
    21182130    {0,0,8,INFfloat,1,1},                               // _DCMPEXC@    dcmp 
    21192131    {DOUBLEREGS_16,DOUBLEREGS_32,0,2},                  // _DNEG@       dneg 
    21202132    {DOUBLEREGS_16,DOUBLEREGS_32,8,INFfloat,1,1},       // _DADD@       dadd 
     
    21582170    {DOUBLEREGS_16,DOUBLEREGS_32,0,INFfloat,1,1},       // _ULLNGDBL@ 
    21592171 
    21602172    {0,0,0,2},                          // _DTST@       dtst 
    21612173    {mES|mBX,mES|mBX,0,0},              // _HTOFPTR@    vptrfptr 
    21622174    {mES|mBX,mES|mBX,0,0},              // _HCTOFPTR@   cvptrfptr 
    21632175    {0,0,0,2},                          // _87TOPSW@    87topsw 
    21642176    {mST0,mST0,0,INFfloat,1,0},         // _FLTTO87@    fltto87 
    21652177    {mST0,mST0,0,INFfloat,1,0},         // _DBLTO87@    dblto87 
    21662178    {mAX,mAX,0,2},                      // _DBLINT87@   dblint87 
    21672179    {mDX|mAX,mAX,0,2},                  // _DBLLNG87@   dbllng87 
    21682180    {0,0,0,2},                          // _FTST@ 
    21692181    {mPSW,mPSW,0,INFfloat,0,2},         // _FCOMPP@ 
    21702182    {mPSW,mPSW,0,2},                    // _FTEST@ 
    21712183    {mPSW,mPSW,0,2},                    // _FTEST0@ 
    21722184    {mST0,mST0,0,INFfloat,1,1},         // _FDIV@ 
    21732185 
    21742186    {mST01,mST01,0,INF32|INFfloat,3,5}, // _Cmul 
    21752187    {mST01,mST01,0,INF32|INFfloat,0,2}, // _Cdiv 
    21762188    {mPSW, mPSW, 0,INF32|INFfloat,0,4}, // _Ccmp 
    21772189 
    2178     {mST0,mST0,0,INF32|INFfloat,2,1},   // _U64_LDBL 
    2179     {0,mDX|mAX,0,INF32|INFfloat,1,2},   // __LDBLULLNG 
     2190    {mST0,mST0,0,INF32|INF64|INFfloat,2,1},   // _U64_LDBL 
     2191    {0,mDX|mAX,0,INF32|INF64|INFfloat,1,2},   // __LDBLULLNG 
    21802192  }; 
    21812193 
    21822194  if (!clib_inited)                             /* if not initialized   */ 
    21832195  { 
    21842196        assert(sizeof(lib) / sizeof(lib[0]) == CLIBMAX); 
    21852197        assert(sizeof(info) / sizeof(info[0]) == CLIBMAX); 
    21862198        for (int i = 0; i < CLIBMAX; i++) 
    21872199        {   lib[i].Stype = tsclib; 
    21882200#if MARS 
    21892201            lib[i].Sxtrnnum = 0; 
    21902202            lib[i].Stypidx = 0; 
    21912203#endif 
    21922204        } 
    21932205 
    21942206        if (!I16) 
    21952207        {   /* Adjust table for 386     */ 
    21962208            lib[CLIBdbllng].Sregsaved  = Z(DOUBLEREGS_32); 
    21972209            lib[CLIBlngdbl].Sregsaved  = Z(DOUBLEREGS_32); 
    21982210            lib[CLIBdblint].Sregsaved  = Z(DOUBLEREGS_32); 
    21992211            lib[CLIBintdbl].Sregsaved  = Z(DOUBLEREGS_32); 
     
    22022214            lib[CLIBdneg].Sregsaved    = Z(DOUBLEREGS_32); 
    22032215            lib[CLIBdbluns].Sregsaved  = Z(DOUBLEREGS_32); 
    22042216            lib[CLIBunsdbl].Sregsaved  = Z(DOUBLEREGS_32); 
    22052217            lib[CLIBdblulng].Sregsaved = Z(DOUBLEREGS_32); 
    22062218            lib[CLIBulngdbl].Sregsaved = Z(DOUBLEREGS_32); 
    22072219#endif 
    22082220            lib[CLIBdblflt].Sregsaved  = Z(DOUBLEREGS_32); 
    22092221            lib[CLIBfltdbl].Sregsaved  = Z(DOUBLEREGS_32); 
    22102222 
    22112223            lib[CLIBdblllng].Sregsaved = Z(DOUBLEREGS_32); 
    22122224            lib[CLIBllngdbl].Sregsaved = Z(DOUBLEREGS_32); 
    22132225            lib[CLIBdblullng].Sregsaved = Z(DOUBLEREGS_32); 
    22142226            lib[CLIBullngdbl].Sregsaved = Z(DOUBLEREGS_32); 
    22152227        } 
    22162228        clib_inited++; 
    22172229  } 
    22182230#undef Z 
    22192231 
    22202232  assert(clib < CLIBMAX); 
    22212233  symbol *s = &lib[clib]; 
    2222   assert(I32 || !(info[clib].flags & INF32)); 
     2234  if (I16) 
     2235        assert(!(info[clib].flags & (INF32 | INF64))); 
    22232236  code *cpop = CNIL; 
    22242237  code *c = getregs((~s->Sregsaved & (mES | mBP | ALLREGS)) & ~keepmask); // mask of regs destroyed 
    22252238  keepmask &= ~s->Sregsaved; 
    22262239    int npushed = numbitsset(keepmask); 
    22272240    gensaverestore2(keepmask, &c, &cpop); 
    22282241#if 0 
    22292242  while (keepmask) 
    22302243  {     unsigned keepreg; 
    22312244 
    22322245        if (keepmask & (mBP|ALLREGS)) 
    22332246        {       keepreg = findreg(keepmask & (mBP|ALLREGS)); 
    22342247                c = gen1(c,0x50 + keepreg);             /* PUSH keepreg */ 
    22352248                cpop = cat(gen1(CNIL,0x58 + keepreg),cpop);     // POP keepreg 
    22362249                keepmask &= ~mask[keepreg]; 
    22372250                npushed++; 
    22382251        } 
    22392252        if (keepmask & mES) 
    22402253        {       c = gen1(c,0x06);                       /* PUSH ES      */ 
    22412254                cpop = cat(gen1(CNIL,0x07),cpop);       /* POP ES       */ 
    22422255                keepmask &= ~mES; 
     
    35933606                    code_newreg(c, c->Irm & 7); 
    35943607                    if (c->Irex & REX_B) 
    35953608                        c->Irex = (c->Irex & ~REX_B) | REX_R; 
    35963609                } 
    35973610            } 
    35983611        } 
    35993612        else if (sz < 8) 
    36003613        { 
    36013614            c = allocreg(&regm,&reg,TYoffset);          /* get a register */ 
    36023615            if (I32)                                    // it's a 48 bit pointer 
    36033616                ce = loadea(e,&cs,0x0FB7,reg,REGSIZE,0,0); /* MOVZX reg,data+4 */ 
    36043617            else 
    36053618            {   ce = loadea(e,&cs,0x8B,reg,REGSIZE,0,0); /* MOV reg,data+2 */ 
    36063619                if (tym == TYfloat || tym == TYifloat)  // dump sign bit 
    36073620                    gen2(ce,0xD1,modregrm(3,4,reg));    /* SHL reg,1      */ 
    36083621            } 
    36093622            c = cat(c,ce); 
    36103623            ce = loadea(e,&cs,0x0B,reg,0,regm,0);       /* OR reg,data */ 
    36113624            c = cat(c,ce); 
    36123625        } 
    3613         else if (sz == 8) 
    3614         {   code *c1; 
    3615             int i; 
    3616  
     3626        else if (sz == 8 || (I64 && sz == 2 * REGSIZE && !tyfloating(tym))) 
     3627        { 
    36173628            c = allocreg(&regm,&reg,TYoffset);  /* get a register */ 
    3618             i = sz - REGSIZE; 
     3629            int i = sz - REGSIZE; 
    36193630            ce = loadea(e,&cs,0x8B,reg,i,0,0);  /* MOV reg,data+6 */ 
    36203631            if (tyfloating(tym))                // TYdouble or TYdouble_alias 
    36213632                gen2(ce,0xD1,modregrm(3,4,reg));        // SHL reg,1 
    36223633            c = cat(c,ce); 
    36233634 
    36243635            while ((i -= REGSIZE) >= 0) 
    36253636            { 
    3626                 c1 = loadea(e,&cs,0x0B,reg,i,regm,0);   // OR reg,data+i 
     3637                code *c1 = loadea(e,&cs,0x0B,reg,i,regm,0);   // OR reg,data+i 
    36273638                if (i == 0) 
    36283639                    c1->Iflags |= CFpsw;                // need the flags on last OR 
    36293640                c = cat(c,c1); 
    36303641            } 
    36313642        } 
    3632         else if (sz == LNGDBLSIZE)                      // TYldouble 
     3643        else if (sz == tysize[TYldouble])               // TYldouble 
    36333644            return load87(e,0,pretregs,NULL,-1); 
    36343645        else 
     3646        { 
     3647#ifdef DEBUG 
     3648            elem_print(e); 
     3649#endif 
    36353650            assert(0); 
     3651        } 
    36363652        return c; 
    36373653  } 
    36383654  /* not for flags only */ 
    36393655  flags = *pretregs & mPSW;             /* save original                */ 
    36403656  forregs = *pretregs & (mBP | ALLREGS | mES | XMMREGS); 
    36413657  if (*pretregs & mSTACK) 
    36423658        forregs |= DOUBLEREGS; 
    36433659  if (e->Eoper == OPconst) 
    36443660  {     regm_t save; 
    36453661 
    36463662        if (sz == REGSIZE && reghasvalue(forregs,e->EV.Vint,&reg)) 
    36473663            forregs = mask[reg]; 
    36483664 
    36493665        save = regcon.immed.mval; 
    36503666        c = allocreg(&forregs,&reg,tym);        /* allocate registers   */ 
    36513667        regcon.immed.mval = save;               // KLUDGE! 
    36523668        if (sz <= REGSIZE) 
    36533669        { 
    36543670            if (sz == 1) 
    36553671                flags |= 1; 
  • branches/dmd-1.x/src/backend/cod2.c

    r601 r627  
    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) 
    220220        if (e2->Eoper == OPconst) 
    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; 
    230             if (sz == 8
     230            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); 
    246246        L10: 
    247247            cs.Iop = op1 ^ byte; 
    248248            cs.Iflags |= word | CFpsw; 
    249249            freenode(e1); 
    250250            freenode(e2); 
     
    392392 
    393393                    // IMUL reg,imm32 
    394394                    c = genc2(CNIL,0x69,modregxrm(3,reg,BP),imm32[ss]); 
    395395                } 
    396396                else 
    397397                {   // LEA reg,[reg1*ss][reg1] 
    398398                    c = gen2sib(CNIL,0x8D,modregxrm(0,reg,4),modregrm(ss,reg1 & 7,reg1 & 7)); 
    399399                    if (reg1 & 8) 
    400400                        code_orrex(c, REX_X | REX_B); 
    401401                } 
    402402                reg1 = reg; 
    403403                ss = ss2;                               // use *2 for scale 
    404404            } 
    405405            else 
    406406                c = NULL; 
    407407            c = cat4(c1,c2,c3,c); 
    408408 
    409409            cs.Iop = 0x8D;                      // LEA reg,c[reg1*ss][reg2] 
    410410            cs.Irm = modregrm(2,reg & 7,4); 
    411411            cs.Isib = modregrm(ss,reg1 & 7,reg2 & 7); 
     412            assert(reg2 != BP); 
    412413            cs.Iflags = CFoff; 
    413414            cs.Irex = 0; 
    414415            if (reg & 8) 
    415416                cs.Irex |= REX_R; 
    416417            if (reg1 & 8) 
    417418                cs.Irex |= REX_X; 
    418419            if (reg2 & 8) 
    419420                cs.Irex |= REX_B; 
    420421            cs.IFL1 = FLconst; 
    421422            cs.IEV1.Vuns = edisp->EV.Vuns; 
    422423 
    423424            freenode(edisp); 
    424425            freenode(e1); 
    425426            c = gen(c,&cs); 
    426427            return cat(c,fixresult(e,mask[reg],pretregs)); 
    427428        } 
    428429  } 
    429430 
    430431  posregs = (byte) ? BYTEREGS : (mES | ALLREGS | mBP); 
    431432  retregs = *pretregs & posregs; 
     
    759760 
    760761code *cdmul(elem *e,regm_t *pretregs) 
    761762{   unsigned rreg,op,oper,lib,byte; 
    762763    regm_t resreg,retregs,rretregs; 
    763764    regm_t keepregs; 
    764765    tym_t uns;                          // 1 if unsigned operation, 0 if not 
    765766    tym_t tyml; 
    766767    code *c,*cg,*cl,*cr,cs; 
    767768    elem *e1,*e2; 
    768769    int sz; 
    769770    targ_size_t e2factor; 
    770771    int opunslng; 
    771772    int pow2; 
    772773 
    773774    if (*pretregs == 0)                         // if don't want result 
    774775    {   c = codelem(e->E1,pretregs,FALSE);      // eval left leaf 
    775776        *pretregs = 0;                          // in case they got set 
    776777        return cat(c,codelem(e->E2,pretregs,FALSE)); 
    777778    } 
    778779 
     780    //printf("cdmul(e = %p, *pretregs = %s)\n", e, regm_str(*pretregs)); 
    779781    keepregs = 0; 
    780782    cs.Iflags = 0; 
    781783    cs.Irex = 0; 
    782784    c = cg = cr = CNIL;                         // initialize 
    783785    e2 = e->E2; 
    784786    e1 = e->E1; 
    785787    tyml = tybasic(e1->Ety); 
    786788    sz = tysize[tyml]; 
    787789    byte = tybyte(e->Ety) != 0; 
    788790    uns = tyuns(tyml) || tyuns(e2->Ety); 
    789791    oper = e->Eoper; 
    790792    unsigned rex = (I64 && sz == 8) ? REX_W : 0; 
    791793    unsigned grex = rex << 16; 
    792794 
    793795    if (tyfloating(tyml)) 
    794796#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 
    795797        return orth87(e,pretregs); 
    796798#else 
    797799        return opdouble(e,pretregs,(oper == OPmul) ? CLIBdmul : CLIBddiv); 
    798800#endif 
     
    10101012                    case 24:    ss = 1; ss2 = 3; goto L4; 
    10111013 
    10121014                    case 6: 
    10131015                    case 3:     ss = 1; goto L4; 
    10141016 
    10151017                    case 20:    ss = 2; ss2 = 2; goto L4; 
    10161018                    case 40:    ss = 2; ss2 = 3; goto L4; 
    10171019 
    10181020                    case 10: 
    10191021                    case 5:     ss = 2; goto L4; 
    10201022 
    10211023                    case 36:    ss = 3; ss2 = 2; goto L4; 
    10221024                    case 72:    ss = 3; ss2 = 3; goto L4; 
    10231025 
    10241026                    case 18: 
    10251027                    case 9:     ss = 3; goto L4; 
    10261028 
    10271029                    L4: 
    10281030                    { 
    10291031#if 1 
    1030                         regm_t regm = byte ? BYTEREGS : ALLREGS;        // don't use EBP 
     1032                        regm_t regm = byte ? BYTEREGS : ALLREGS; 
     1033                        regm &= ~(mBP | mR13);                  // don't use EBP 
    10311034                        cl = codelem(e->E1,&regm,TRUE); 
    10321035                        unsigned r = findreg(regm); 
    10331036 
    10341037                        if (ss2) 
    10351038                        {   // Don't use EBP 
    1036                             resreg &= ~mBP
     1039                            resreg &= ~(mBP | mR13)
    10371040                            if (!resreg) 
    10381041                                resreg = retregs; 
    10391042                        } 
    10401043                        cg = allocreg(&resreg,&reg,tyml); 
    10411044 
    10421045                        c = gen2sib(CNIL,0x8D,grex | modregxrm(0,reg,4), 
    10431046                                              modregxrmx(ss,r,r)); 
     1047                        assert((r & 7) != BP); 
    10441048                        if (ss2) 
    10451049                        { 
    10461050                            gen2sib(c,0x8D,grex | modregxrm(0,reg,4), 
    10471051                                           modregxrm(ss2,reg,5)); 
    10481052                            code_last(c)->IFL1 = FLconst; 
    10491053                            code_last(c)->IEV1.Vint = 0; 
    10501054                        } 
    10511055                        else if (!(e2factor & 1))    // if even factor 
    10521056                        {   genregs(c,0x03,reg,reg); // ADD reg,reg 
    10531057                            code_orrex(c,rex); 
    10541058                        } 
    10551059                        cg = cat(cg,c); 
    10561060                        goto L3; 
    10571061#else 
    10581062 
    10591063                                // Don't use EBP 
    10601064                                resreg &= ~mBP; 
    10611065                                if (!resreg) 
    10621066                                    resreg = retregs; 
    10631067 
     
    10711075                                    gen2sib(c,0x8D,modregrm(0,reg,4), 
    10721076                                                   modregrm(ss2,reg,5)); 
    10731077                                    code_last(c)->IFL1 = FLconst; 
    10741078                                    code_last(c)->IEV1.Vint = 0; 
    10751079                                } 
    10761080                                else if (!(e2factor & 1))    // if even factor 
    10771081                                    genregs(c,0x03,reg,reg); // ADD reg,reg 
    10781082                                cg = cat(cg,c); 
    10791083                                goto L3; 
    10801084#endif 
    10811085                    } 
    10821086                    case 37: 
    10831087                    case 74:    shift = 2; 
    10841088                                goto L5; 
    10851089                    case 13: 
    10861090                    case 26:    shift = 0; 
    10871091                                goto L5; 
    10881092                    L5: 
    10891093                    { 
    10901094                                // Don't use EBP 
    1091                                 resreg &= ~mBP
     1095                                resreg &= ~(mBP | mR13)
    10921096                                if (!resreg) 
    10931097                                    resreg = retregs; 
    10941098                                cl = allocreg(&resreg,&reg,TYint); 
    10951099 
    1096                                 regm_t sregm = ALLREGS & ~resreg; 
     1100                                regm_t sregm = (ALLREGS & ~mR13) & ~resreg; 
    10971101                                cl = cat(cl,codelem(e->E1,&sregm,FALSE)); 
    10981102                                unsigned sreg = findreg(sregm); 
    10991103                                cg = getregs(resreg | sregm); 
    11001104                                // LEA reg,[sreg * 4][sreg] 
    11011105                                // SHL sreg,shift 
    11021106                                // LEA reg,[sreg * 8][reg] 
     1107                                assert((sreg & 7) != BP); 
     1108                                assert((reg & 7) != BP); 
    11031109                                c = gen2sib(CNIL,0x8D,grex | modregxrm(0,reg,4), 
    11041110                                                      modregxrmx(2,sreg,sreg)); 
    11051111                                if (shift) 
    11061112                                    genc2(c,0xC1,grex | modregrmx(3,4,sreg),shift); 
    11071113                                gen2sib(c,0x8D,grex | modregxrm(0,reg,4), 
    11081114                                                      modregxrmx(3,sreg,reg)); 
    11091115                                if (!(e2factor & 1))         // if even factor 
    11101116                                {   genregs(c,0x03,reg,reg); // ADD reg,reg 
    11111117                                    code_orrex(c,rex); 
    11121118                                } 
    11131119                                cg = cat(cg,c); 
    11141120                                goto L3; 
    11151121                    } 
    11161122                } 
    11171123            } 
    11181124 
    11191125            cl = scodelem(e->E1,&retregs,0,TRUE);       // eval left leaf 
    11201126            reg = findreg(retregs); 
    11211127            cg = allocreg(&resreg,&rreg,e->Ety); 
    11221128 
     
    11911197                    genc2(cg,0xC1,grex | modregrm(3,7,AX),pow2); // SAR AX,pow2 
    11921198                } 
    11931199                else // OPmod 
    11941200                {   gen2(cg,0x33,grex | modregrm(3,AX,DX));    // XOR AX,DX 
    11951201                    gen2(cg,0x2B,grex | modregrm(3,AX,DX));    // SUB AX,DX 
    11961202                    genc2(cg,0x81,grex | modregrm(3,4,AX),m);  // AND AX,mask 
    11971203                    gen2(cg,0x33,grex | modregrm(3,AX,DX));    // XOR AX,DX 
    11981204                    gen2(cg,0x2B,grex | modregrm(3,AX,DX));    // SUB AX,DX 
    11991205                    resreg = mAX; 
    12001206                } 
    12011207            } 
    12021208            goto L3; 
    12031209        } 
    12041210        goto L2; 
    12051211    case OPind: 
    12061212        if (!e2->Ecount)                        /* if not CSE           */ 
    12071213                goto L1;                        /* try OP reg,EA        */ 
    12081214        goto L2; 
    12091215    default:                                    /* OPconst and operators */ 
    12101216    L2: 
     1217        //printf("test2 %p, retregs = %s rretregs = %s resreg = %s\n", e, regm_str(retregs), regm_str(rretregs), regm_str(resreg)); 
    12111218        cl = codelem(e1,&retregs,FALSE);        /* eval left leaf       */ 
    12121219        cr = scodelem(e2,&rretregs,retregs,TRUE);       /* get rvalue   */ 
    12131220        if (sz <= REGSIZE) 
    12141221        {   cg = getregs(mAX | mDX);            /* trash these regs     */ 
    12151222            if (op == 7)                        /* signed divide        */ 
    12161223            {   cg = gen1(cg,0x99);             // CWD 
    12171224                code_orrex(cg,rex); 
    12181225            } 
    12191226            else if (op == 6)                   /* unsigned divide      */ 
    12201227            { 
    12211228                cg = movregconst(cg,DX,0,(sz == 8) ? 64 : 0);    // MOV DX,0 
    12221229                cg = cat(cg,getregs(mDX)); 
    12231230            } 
    12241231            rreg = findreg(rretregs); 
    12251232            cg = gen2(cg,0xF7 ^ byte,grex | modregrmx(3,op,rreg)); // OP AX,rreg 
    12261233        L3: 
    12271234            c = fixresult(e,resreg,pretregs); 
    12281235        } 
    12291236        else if (sz == 2 * REGSIZE) 
    12301237        { 
  • branches/dmd-1.x/src/backend/cod3.c

    r619 r627  
    34843484  unsigned char op; 
    34853485 
    34863486  //printf("jmpaddr()\n"); 
    34873487  cstart = c;                           /* remember start of code       */ 
    34883488  while (c) 
    34893489  { 
    34903490        op = c->Iop; 
    34913491        if (inssize[op & 0xFF] & T &&   // if second operand 
    34923492            c->IFL2 == FLcode && 
    34933493            ((op & ~0x0F) == 0x70 || op == JMP || op == JMPS || op == JCXZ)) 
    34943494        {       ci = code_next(c); 
    34953495                ctarg = c->IEV2.Vcode;  /* target code                  */ 
    34963496                ad = 0;                 /* IP displacement              */ 
    34973497                while (ci && ci != ctarg) 
    34983498                { 
    34993499                        ad += calccodsize(ci); 
    35003500                        ci = code_next(ci); 
    35013501                } 
    35023502                if (!ci) 
    35033503                    goto Lbackjmp;      // couldn't find it 
    3504                 if (I32 || op == JMP || op == JMPS || op == JCXZ) 
     3504                if (!I16 || op == JMP || op == JMPS || op == JCXZ) 
    35053505                        c->IEVpointer2 = ad; 
    35063506                else                    /* else conditional             */ 
    35073507                {       if (!(c->Iflags & CFjmp16))     /* if branch    */ 
    35083508                                c->IEVpointer2 = ad; 
    35093509                        else            /* branch around a long jump    */ 
    35103510                        {       cn = code_next(c); 
    35113511                                code_next(c) = code_calloc(); 
    35123512                                code_next(code_next(c)) = cn; 
    35133513                                c->Iop = op ^ 1;        /* converse jmp */ 
    35143514                                c->Iflags &= ~CFjmp16; 
    3515                                 c->IEVpointer2 = I32 ? 5 : 3
     3515                                c->IEVpointer2 = I16 ? 3 : 5
    35163516                                cn = code_next(c); 
    35173517                                cn->Iop = JMP;          /* long jump    */ 
    35183518                                cn->IFL2 = FLconst; 
    35193519                                cn->IEVpointer2 = ad; 
    35203520                        } 
    35213521                } 
    35223522                c->IFL2 = FLconst; 
    35233523        } 
    35243524        if (op == LOOP && c->IFL2 == FLcode)    /* backwards refs       */ 
    35253525        { 
    35263526            Lbackjmp: 
    35273527                ctarg = c->IEV2.Vcode; 
    35283528                for (ci = cstart; ci != ctarg; ci = code_next(ci)) 
    35293529                        if (!ci || ci == c) 
    35303530                                assert(0); 
    35313531                ad = 2;                 /* - IP displacement            */ 
    35323532                while (ci != c) 
    35333533                {       assert(ci); 
    35343534                        ad += calccodsize(ci); 
    35353535                        ci = code_next(ci); 
    35363536                } 
    35373537                c->IEVpointer2 = (-ad) & 0xFF; 
    35383538                c->IFL2 = FLconst; 
    35393539        } 
    35403540        c = code_next(c); 
    35413541  } 
    35423542} 
    35433543 
    35443544 
    35453545/******************************* 
    35463546 * Calculate bl->Bsize. 
    35473547 */ 
    35483548 
    35493549unsigned calcblksize(code *c) 
    35503550{   unsigned size; 
    35513551 
    35523552    for (size = 0; c; c = code_next(c)) 
    3553         size += calccodsize(c); 
     3553    { 
     3554        unsigned sz = calccodsize(c); 
     3555        //printf("off=%02x, sz = %d, code %p: op=%02x\n", size, sz, c, c->Iop); 
     3556        size += sz; 
     3557    } 
    35543558//printf("calcblksize(c = x%x) = %d\n", c, size); 
    35553559    return size; 
    35563560} 
    35573561 
    35583562/***************************** 
    35593563 * Calculate and return code size of a code. 
    35603564 * Note that NOPs are sometimes used as markers, but are 
    35613565 * never output. LINNUMs are never output. 
    35623566 * Note: This routine must be fast. Profiling shows it is significant. 
    35633567 */ 
    35643568 
    35653569unsigned calccodsize(code *c) 
    35663570{   unsigned size; 
    35673571    unsigned op; 
    35683572    unsigned char rm,mod,ins; 
    35693573    unsigned iflags; 
    35703574    unsigned i32 = I32 || I64; 
    35713575    unsigned a32 = i32; 
    35723576 
    35733577#ifdef DEBUG 
     
    50335037    else 
    50345038        ins = inssize[op & 0xFF]; 
    50355039 
    50365040    printf("code %p: nxt=%p ",c,code_next(c)); 
    50375041    if (c->Irex) 
    50385042        printf("rex=%x ", c->Irex); 
    50395043    printf("op=%02x",op); 
    50405044 
    50415045  if ((op & 0xFF) == ESCAPE) 
    50425046  {     if ((op & 0xFF00) == ESClinnum) 
    50435047        {   printf(" linnum = %d\n",c->IEV2.Vsrcpos.Slinnum); 
    50445048            return; 
    50455049        } 
    50465050        printf(" ESCAPE %d",c->Iop >> 8); 
    50475051  } 
    50485052  if (c->Iflags) 
    50495053        printf(" flg=%x",c->Iflags); 
    50505054  if (ins & M) 
    50515055  {     unsigned rm = c->Irm; 
    50525056        printf(" rm=%02x=%d,%d,%d",rm,(rm>>6)&3,(rm>>3)&7,rm&7); 
    5053         if (I32 && issib(rm)) 
     5057        if (!I16 && issib(rm)) 
    50545058        {   unsigned char sib = c->Isib; 
    50555059            printf(" sib=%02x=%d,%d,%d",sib,(sib>>6)&3,(sib>>3)&7,sib&7); 
    50565060        } 
    50575061        if ((rm & 0xC7) == BPRM || (rm & 0xC0) == 0x80 || (rm & 0xC0) == 0x40) 
    50585062        { 
    50595063            switch (c->IFL1) 
    50605064            { 
    50615065                case FLconst: 
    50625066                case FLoffset: 
    50635067                    printf(" int = %4d",c->IEV1.Vuns); 
    50645068                    break; 
    50655069                case FLblock: 
    50665070                    printf(" block = %p",c->IEV1.Vblock); 
    50675071                    break; 
    50685072                case FLswitch: 
    50695073                case FLblockoff: 
    50705074                case FLlocalsize: 
    50715075                case FLframehandler: 
    50725076                case 0: 
    50735077                    break; 
  • branches/dmd-1.x/src/backend/cod4.c

    r618 r627  
    28622862    code *c; 
    28632863 
    28642864    //printf("cdmsw(e->Ecount = %d)\n", e->Ecount); 
    28652865    assert(e->Eoper == OPmsw); 
    28662866 
    28672867    retregs = *pretregs ? ALLREGS : 0; 
    28682868    c = codelem(e->E1,&retregs,FALSE); 
    28692869    retregs &= mMSW;                    // want MSW only 
    28702870 
    28712871    // We "destroy" a reg by assigning it the result of a new e, even 
    28722872    // though the values are the same. Weakness of our CSE strategy that 
    28732873    // a register can only hold the contents of one elem at a time. 
    28742874    if (e->Ecount) 
    28752875        c = cat(c,getregs(retregs)); 
    28762876    else 
    28772877        useregs(retregs); 
    28782878 
    28792879#ifdef DEBUG 
    28802880    if (!(!*pretregs || retregs)) 
    28812881    {   WROP(e->Eoper); 
    2882         printf(" *pretregs = x%x, retregs = x%x\n",*pretregs,retregs); 
     2882        printf(" *pretregs = %s, retregs = %s\n",regm_str(*pretregs),regm_str(retregs)); 
     2883        elem_print(e); 
    28832884    } 
    28842885#endif 
    28852886    assert(!*pretregs || retregs); 
    28862887    return cat(c,fixresult(e,retregs,pretregs));        // msw only 
    28872888} 
    28882889 
    28892890 
    28902891 
    28912892/****************************** 
    28922893 * Handle operators OPinp and OPoutp. 
    28932894 */ 
    28942895 
    28952896code *cdport(elem *e,regm_t *pretregs) 
    28962897{   regm_t retregs; 
    28972898    code *c1,*c2,*c3; 
    28982899    unsigned char op,port; 
    28992900    unsigned sz; 
    29002901    elem *e1; 
    29012902 
    29022903    //printf("cdport\n"); 
  • branches/dmd-1.x/src/backend/debug.c

    r618 r627  
    193193        {       nest++; 
    194194                ferr("("); 
    195195                WReqn(e->E2); 
    196196                ferr(")"); 
    197197                nest--; 
    198198        } 
    199199        else 
    200200                WReqn(e->E2); 
    201201  } 
    202202  else 
    203203  { 
    204204        switch (e->Eoper) 
    205205        {   case OPconst: 
    206206                switch (tybasic(e->Ety)) 
    207207                { 
    208208                    case TYfloat: 
    209209                        dbg_printf("%g <float> ",e->EV.Vfloat); 
    210210                        break; 
    211211                    case TYdouble: 
    212212                        dbg_printf("%g ",e->EV.Vdouble); 
     213                        break; 
     214                    case TYcent: 
     215                    case TYucent: 
     216                        dbg_printf("%lld+%lld ", e->EV.Vcent.msw, e->EV.Vcent.lsw); 
    213217                        break; 
    214218                    default: 
    215219                        dbg_printf("%lld ",el_tolong(e)); 
    216220                        break; 
    217221                } 
    218222                break; 
    219223            case OPrelconst: 
    220224                ferr("#"); 
    221225                /* FALL-THROUGH */ 
    222226            case OPvar: 
    223227                dbg_printf("%s",e->EV.sp.Vsym->Sident); 
    224228                if (e->EV.sp.Vsym->Ssymnum != -1) 
    225229                    dbg_printf("(%d)",e->EV.sp.Vsym->Ssymnum); 
    226230                if (e->Eoffset != 0) 
    227231                        dbg_printf(".%ld",(long)e->Eoffset); 
    228232                break; 
    229233            case OPasm: 
    230234#if TARGET_MAC 
    231235                if (e->Eflags & EFsmasm) 
    232236                    { 
  • branches/dmd-1.x/src/backend/el.c

    r618 r627  
    25472547                        if (n1->EV.Vshort != n2->EV.Vshort) 
    25482548                                goto nomatch; 
    25492549                        break; 
    25502550                    case TYlong: 
    25512551                    case TYulong: 
    25522552                    case TYdchar: 
    25532553#if TARGET_MAC 
    25542554                    case TYfptr: 
    25552555                    case TYvptr: 
    25562556#endif 
    25572557                    case_long: 
    25582558                        if (n1->EV.Vlong != n2->EV.Vlong) 
    25592559                                goto nomatch; 
    25602560                        break; 
    25612561                    case TYllong: 
    25622562                    case TYullong: 
    25632563                    case_llong: 
    25642564                        if (n1->EV.Vllong != n2->EV.Vllong) 
    25652565                                goto nomatch; 
    25662566                        break; 
     2567                    case TYcent: 
     2568                    case TYucent: 
     2569                        if (n1->EV.Vcent.lsw != n2->EV.Vcent.lsw || 
     2570                            n1->EV.Vcent.msw != n2->EV.Vcent.msw) 
     2571                                goto nomatch; 
     2572                        break; 
    25672573                    case TYenum: 
    25682574                        if (PARSER) 
    25692575                        {   tym = n1->ET->Tnext->Tty; 
    25702576                            goto Lagain; 
    25712577                        } 
    25722578                    case TYint: 
    25732579                    case TYuint: 
    25742580                        if (intsize == SHORTSIZE) 
    25752581                            goto case_short; 
    25762582                        else 
    25772583                            goto case_long; 
    25782584 
    25792585#if TX86 
    25802586#if JHANDLE 
    25812587                    case TYjhandle: 
    25822588#endif 
    25832589                    case TYnullptr: 
    25842590                    case TYnptr: 
    25852591                    case TYsptr: 
    25862592                    case TYcptr: 
  • branches/dmd-1.x/src/backend/evalu8.c

    r618 r627  
    175175                        b = 1; 
    176176                    else 
    177177                        b = e->EV.Vcdouble.re != 0 || e->EV.Vcdouble.im != 0; 
    178178                    break; 
    179179                case TYcldouble: 
    180180                    if (isnan(e->EV.Vcldouble.re) || isnan(e->EV.Vcldouble.im)) 
    181181                        b = 1; 
    182182                    else 
    183183                        b = e->EV.Vcldouble.re != 0 || e->EV.Vcldouble.im != 0; 
    184184                    break; 
    185185                case TYstruct:  // happens on syntax error of (struct x)0 
    186186#if SCPP 
    187187                    assert(errcnt); 
    188188#else 
    189189                    assert(0); 
    190190#endif 
    191191                case TYvoid:    /* happens if we get syntax errors or 
    192192                                       on RHS of && || expressions */ 
    193193                    b = 0; 
    194194                    break; 
     195 
     196                case TYcent: 
     197                case TYucent: 
     198                    b = e->EV.Vcent.lsw || e->EV.Vcent.msw; 
     199                    break; 
     200 
    195201                default: 
    196202#ifdef DEBUG 
    197203                    WRTYxx(typemask(e)); 
    198204#endif 
    199205                    assert(0); 
    200206            } 
    201207            break; 
    202208        default: 
    203209            assert(0); 
    204210    } 
    205211    return b; 
    206212} 
    207213 
    208214/*************************** 
    209215 * Return TRUE if expression will always evaluate to TRUE. 
    210216 */ 
    211217 
    212218HINT iftrue(elem *e) 
    213219{ 
    214220  while (1) 
  • branches/dmd-1.x/src/todt.c

    r602 r627  
    269269            else if (dim > tadim) 
    270270            { 
    271271#ifdef DEBUG 
    272272                printf("1: "); 
    273273#endif 
    274274                error(loc, "too many initializers, %d, for array[%d]", dim, tadim); 
    275275            } 
    276276            break; 
    277277        } 
    278278 
    279279        case Tpointer: 
    280280        case Tarray: 
    281281            // Create symbol, and then refer to it 
    282282            Symbol *s; 
    283283            s = static_sym(); 
    284284            s->Sdt = d; 
    285285            outdata(s); 
    286286 
    287287            d = NULL; 
    288288            if (tb->ty == Tarray) 
    289                 dtdword(&d, dim); 
     289                dtsize_t(&d, dim); 
    290290            dtxoff(&d, s, 0, TYnptr); 
    291291            break; 
    292292 
    293293        default: 
    294294            assert(0); 
    295295    } 
    296296    return d; 
    297297} 
    298298 
    299299 
    300300dt_t *ArrayInitializer::toDtBit() 
    301301{ 
    302302#if DMDV1 
    303303    unsigned size; 
    304304    unsigned length; 
    305305    unsigned i; 
    306306    unsigned tadim; 
    307307    dt_t *d; 
    308308    dt_t **pdtend; 
    309309    Type *tb = type->toBasetype(); 
     
    384384            } 
    385385            else 
    386386            { 
    387387                tadim = (tadim + 31) / 32; 
    388388                if (databits.allocdim < tadim) 
    389389                    pdtend = dtnzeros(pdtend, size * (tadim - databits.allocdim));      // pad out end of array 
    390390            } 
    391391            break; 
    392392        } 
    393393 
    394394        case Tpointer: 
    395395        case Tarray: 
    396396            // Create symbol, and then refer to it 
    397397            Symbol *s; 
    398398            s = static_sym(); 
    399399            s->Sdt = d; 
    400400            outdata(s); 
    401401 
    402402            d = NULL; 
    403403            if (tb->ty == Tarray) 
    404                 dtdword(&d, dim); 
     404                dtsize_t(&d, dim); 
    405405            dtxoff(&d, s, 0, TYnptr); 
    406406            break; 
    407407 
    408408        default: 
    409409            assert(0); 
    410410    } 
    411411    return d; 
    412412#else 
    413413    return NULL; 
    414414#endif 
    415415} 
    416416 
    417417 
    418418dt_t *ExpInitializer::toDt() 
    419419{ 
    420420    dt_t *dt = NULL; 
    421421 
    422422    exp = exp->optimize(WANTvalue); 
    423423    exp->toDt(&dt); 
    424424    return dt; 
     
    526526            break; 
    527527    } 
    528528    return pdt; 
    529529} 
    530530 
    531531dt_t **NullExp::toDt(dt_t **pdt) 
    532532{ 
    533533    assert(type); 
    534534    return dtnzeros(pdt, type->size()); 
    535535} 
    536536 
    537537dt_t **StringExp::toDt(dt_t **pdt) 
    538538{ 
    539539    //printf("StringExp::toDt() '%s', type = %s\n", toChars(), type->toChars()); 
    540540    Type *t = type->toBasetype(); 
    541541 
    542542    // BUG: should implement some form of static string pooling 
    543543    switch (t->ty) 
    544544    { 
    545545        case Tarray: 
    546             dtdword(pdt, len); 
     546            dtsize_t(pdt, len); 
    547547            pdt = dtabytes(pdt, TYnptr, 0, (len + 1) * sz, (char *)string); 
    548548            break; 
    549549 
    550550        case Tsarray: 
    551551        {   TypeSArray *tsa = (TypeSArray *)type; 
    552552            dinteger_t dim; 
    553553 
    554554            pdt = dtnbytes(pdt, len * sz, (const char *)string); 
    555555            if (tsa->dim) 
    556556            { 
    557557                dim = tsa->dim->toInteger(); 
    558558                if (len < dim) 
    559559                { 
    560560                    // Pad remainder with 0 
    561561                    pdt = dtnzeros(pdt, (dim - len) * tsa->next->size()); 
    562562                } 
    563563            } 
    564564            break; 
    565565        } 
    566566        case Tpointer: 
     
    582582    dt_t **pdtend; 
    583583 
    584584    d = NULL; 
    585585    pdtend = &d; 
    586586    for (int i = 0; i < elements->dim; i++) 
    587587    {   Expression *e = (Expression *)elements->data[i]; 
    588588 
    589589        pdtend = e->toDt(pdtend); 
    590590    } 
    591591    Type *t = type->toBasetype(); 
    592592 
    593593    switch (t->ty) 
    594594    { 
    595595        case Tsarray: 
    596596            pdt = dtcat(pdt, d); 
    597597            break; 
    598598 
    599599        case Tpointer: 
    600600        case Tarray: 
    601601            if (t->ty == Tarray) 
    602                 dtdword(pdt, elements->dim); 
     602                dtsize_t(pdt, elements->dim); 
    603603            if (d) 
    604604            { 
    605605                // Create symbol, and then refer to it 
    606606                Symbol *s; 
    607607                s = static_sym(); 
    608608                s->Sdt = d; 
    609609                outdata(s); 
    610610 
    611611                dtxoff(pdt, s, 0, TYnptr); 
    612612            } 
    613613            else 
    614                 dtdword(pdt, 0); 
     614                dtsize_t(pdt, 0); 
    615615 
    616616            break; 
    617617 
    618618        default: 
    619619            assert(0); 
    620620    } 
    621621    return pdt; 
    622622} 
    623623 
    624624dt_t **StructLiteralExp::toDt(dt_t **pdt) 
    625625{ 
    626626    Array dts; 
    627627    unsigned i; 
    628628    unsigned j; 
    629629    dt_t *dt; 
    630630    dt_t *d; 
    631631    unsigned offset; 
    632632 
    633633    //printf("StructLiteralExp::toDt() %s)\n", toChars()); 
    634634    dts.setDim(sd->fields.dim); 
     
    772772        return pdt; 
    773773    } 
    774774#ifdef DEBUG 
    775775    printf("VarExp::toDt(), kind = %s\n", var->kind()); 
    776776#endif 
    777777    error("non-constant expression %s", toChars()); 
    778778    pdt = dtnzeros(pdt, 1); 
    779779    return pdt; 
    780780} 
    781781 
    782782/* ================================================================= */ 
    783783 
    784784// Generate the data for the static initializer. 
    785785 
    786786void ClassDeclaration::toDt(dt_t **pdt) 
    787787{ 
    788788    //printf("ClassDeclaration::toDt(this = '%s')\n", toChars()); 
    789789 
    790790    // Put in first two members, the vtbl[] and the monitor 
    791791    dtxoff(pdt, toVtblSymbol(), 0, TYnptr); 
    792     dtdword(pdt, 0);                    // monitor 
     792    dtsize_t(pdt, 0);                    // monitor 
    793793 
    794794    // Put in the rest 
    795795    toDt2(pdt, this); 
    796796 
    797797    //printf("-ClassDeclaration::toDt(this = '%s')\n", toChars()); 
    798798} 
    799799 
    800800void ClassDeclaration::toDt2(dt_t **pdt, ClassDeclaration *cd) 
    801801{ 
    802802    unsigned offset; 
    803803    unsigned i; 
    804804    dt_t *dt; 
    805805    unsigned csymoffset; 
    806806 
    807807#define LOG 0 
    808808 
    809809#if LOG 
    810810    printf("ClassDeclaration::toDt2(this = '%s', cd = '%s')\n", toChars(), cd->toChars()); 
    811811#endif 
    812812    if (baseClass) 
  • trunk/src/backend/cg87.c

    r622 r627  
    193193#endif 
    194194{ 
    195195        int i; 
    196196 
    197197#if NDPP 
    198198        dbg_printf("pop87(%s(%d): stackused=%d)\n", file, line, stackused); 
    199199#endif 
    200200        --stackused; 
    201201        assert(stackused >= 0); 
    202202        for (i = 0; i < arraysize(_8087elems) - 1; i++) 
    203203                _8087elems[i] = _8087elems[i + 1]; 
    204204        /* end of stack is nothing      */ 
    205205        _8087elems[arraysize(_8087elems) - 1] = ndp_zero; 
    206206} 
    207207 
    208208/******************************* 
    209209 * Push 8087 stack. Generate and return any code 
    210210 * necessary to preserve anything that might run off the end of the stack. 
    211211 */ 
    212212 
    213 code *push87() 
     213#undef push87 
     214 
     215#ifdef DEBUG 
     216code *push87(int line, const char *file); 
     217code *push87() { return push87(__LINE__,__FILE__); } 
     218#endif 
     219 
     220code *push87( 
     221#ifdef DEBUG 
     222        int line, const char *file 
     223#endif 
     224        ) 
     225#ifdef DEBUG 
     226#define push87() push87(__LINE__,__FILE__) 
     227#endif 
    214228{ 
    215229        code *c; 
    216230        int i; 
    217231 
    218232        c = CNIL; 
    219233        // if we would lose the top register off of the stack 
    220234        if (_8087elems[7].e != NULL) 
    221235        { 
    222236                i = getemptyslot(); 
    223237                NDP::save[i] = _8087elems[7]; 
    224238                c = genf2(c,0xD9,0xF6);         // FDECSTP 
    225239                c = genfwait(c); 
    226240                c = ndp_fstp(c, i, _8087elems[7].e->Ety);       // FSTP i[BP] 
    227241                assert(stackused == 8); 
    228242                if (NDPP) dbg_printf("push87() : overflow\n"); 
    229243        } 
    230244        else 
    231245        { 
    232                 if (NDPP) dbg_printf("push87(%d)\n",stackused); 
     246#ifdef DEBUG 
     247                if (NDPP) dbg_printf("push87(%s(%d): %d)\n", file, line, stackused); 
     248#endif 
    233249                stackused++; 
    234250                assert(stackused <= 8); 
    235251        } 
    236252        // Shift the stack up 
    237253        for (i = 7; i > 0; i--) 
    238254                _8087elems[i] = _8087elems[i - 1]; 
    239255        _8087elems[0] = ndp_zero; 
    240256        return c; 
    241257} 
    242258 
    243259/***************************** 
    244260 * Note elem e as being in ST(i) as being a value we want to keep. 
    245261 */ 
    246262 
    247263#ifdef DEBUG 
    248264void note87(elem *e, unsigned offset, int i, int linnum); 
    249265void note87(elem *e, unsigned offset, int i) 
    250266{ 
    251267    return note87(e, offset, i, 0); 
    252268} 
     
    472488            c = cat(c,fixresult(e,mST0,pretregs)); 
    473489        } 
    474490        else 
    475491            // Reload 
    476492            c = loaddata(e,pretregs); 
    477493    } 
    478494 
    479495    freenode(e); 
    480496    return c; 
    481497} 
    482498 
    483499 
    484500/************************** 
    485501 * Generate code to deal with floatreg. 
    486502 */ 
    487503 
    488504code * genfltreg(code *c,unsigned opcode,unsigned reg,targ_size_t offset) 
    489505{ 
    490506        floatreg = TRUE; 
    491507        reflocal = TRUE; 
    492         if ((opcode & 0xF8) == 0xD8) 
     508        if ((opcode & ~7) == 0xD8) 
    493509            c = genfwait(c); 
    494         unsigned grex = I64 ? (REX_W << 16) : 0; 
    495         return genc1(c,opcode,grex | modregxrm(2,reg,BPRM),FLfltreg,offset); 
     510        return genc1(c,opcode,modregxrm(2,reg,BPRM),FLfltreg,offset); 
    496511} 
    497512 
    498513/******************************* 
    499514 * Decide if we need to gen an FWAIT. 
    500515 */ 
    501516 
    502517code *genfwait(code *c) 
    503518{ 
    504519    if (ADDFWAIT()) 
    505520        c = gen1(c,FWAIT); 
    506521    return c; 
    507522} 
    508523 
    509524/*************************************** 
    510525 * Generate floating point instruction. 
    511526 */ 
    512527 
    513528STATIC code * genf2(code *c,unsigned op,unsigned rm) 
    514529{ 
    515530    return gen2(genfwait(c),op,rm); 
     
    824839            else 
    825840            {   c2 = genfltreg(c2,0x8B,AX,6); 
    826841                genfltreg(c2,0x8B,BX,4); 
    827842                genfltreg(c2,0x8B,CX,2); 
    828843                genfltreg(c2,0x8B,DX,0); 
    829844            } 
    830845        } 
    831846    } 
    832847    else if (*pretregs == 0 && retregs == mST0) 
    833848    { 
    834849        c1 = genf2(c1,0xDD,modregrm(3,3,0));    // FPOP 
    835850        pop87(); 
    836851    } 
    837852    else 
    838853    {   if (*pretregs & mPSW) 
    839854        {   if (!(retregs & mPSW)) 
    840855            {   assert(retregs & mST0); 
    841856                c1 = genftst(c1,e,!(*pretregs & mST0)); // FTST 
    842857            } 
    843858        } 
    844         assert(!(*pretregs & mST0) || (retregs & mST0)); 
     859        if (*pretregs & mST0 && retregs & XMMREGS) 
     860        { 
     861            assert(sz <= DOUBLESIZE); 
     862            unsigned mf = (sz == FLOATSIZE) ? MFfloat : MFdouble; 
     863            // MOVD floatreg,XMM? 
     864            unsigned reg = findreg(retregs); 
     865            c1 = genfltreg(c1,0xF20F11,reg - XMM0,0); 
     866            c2 = push87(); 
     867            c2 = genfltreg(c2,ESC(mf,1),0,0);                 // FLD float/double ptr fltreg 
     868        } 
     869        else if (retregs & mST0 && *pretregs & XMMREGS) 
     870        { 
     871            assert(sz <= DOUBLESIZE); 
     872            unsigned mf = (sz == FLOATSIZE) ? MFfloat : MFdouble; 
     873            // FSTP floatreg 
     874            pop87(); 
     875            c1 = genfltreg(c1,ESC(mf,1),3,0); 
     876            genfwait(c1); 
     877            // MOVD XMM?,floatreg 
     878            unsigned reg; 
     879            c2 = allocreg(pretregs,&reg,(sz == FLOATSIZE) ? TYfloat : TYdouble); 
     880            c2 = genfltreg(c2,0xF20F10,reg -XMM0,0); 
     881        } 
     882        else 
     883            assert(!(*pretregs & mST0) || (retregs & mST0)); 
    845884    } 
    846885    if (*pretregs & mST0) 
    847886        note87(e,0,0); 
    848887    return cat(c1,c2); 
    849888} 
    850889 
    851890/******************************** 
    852891 * Generate in-line 8087 code for the following operators: 
    853892 *      add 
    854893 *      min 
    855894 *      mul 
    856895 *      div 
    857896 *      cmp 
    858897 */ 
    859898 
    860899// Reverse the order that the op is done in 
    861900static const char oprev[9] = { -1,0,1,2,3,5,4,7,6 }; 
    862901 
    863902code *orth87(elem *e,regm_t *pretregs) 
    864903{ 
     
    16991738                c = regwithvalue(c,ALLREGS & mMSW,0,&reg,0);  // 0-extend 
    17001739                retregs |= mask[reg]; 
    17011740                mf1 = MFlong; 
    17021741                goto L3; 
    17031742            } 
    17041743            case OPs16_d:       mf1 = MFword;   goto L6; 
    17051744            case OPs32_d:       mf1 = MFlong;   goto L6; 
    17061745            L6: 
    17071746                if (op != -1) 
    17081747                    note87(eleft,eoffset,0);    // don't trash this value 
    17091748                if (e->E1->Eoper == OPvar || 
    17101749                    (e->E1->Eoper == OPind && e->E1->Ecount == 0)) 
    17111750                { 
    17121751                    goto L4; 
    17131752                } 
    17141753                else 
    17151754                { 
    17161755                    retregs = ALLREGS; 
    17171756                    c = codelem(e->E1,&retregs,FALSE); 
    17181757                L3: 
    1719                     if (!I32 && e->Eoper != OPs16_d) 
     1758                    if (I16 && e->Eoper != OPs16_d) 
    17201759                    { 
    17211760                        /* MOV floatreg+2,reg   */ 
    17221761                        reg = findregmsw(retregs); 
    17231762                        c = genfltreg(c,0x89,reg,REGSIZE); 
    17241763                        retregs &= mLSW; 
    17251764                    } 
    17261765                    reg = findreg(retregs); 
    17271766                    c = genfltreg(c,0x89,reg,0);        /* MOV floatreg,reg */ 
    17281767                    if (op != -1) 
    17291768                    {   c = cat(c,makesure87(eleft,eoffset,0,0)); 
    17301769                        genfltreg(c,ESC(mf1,0),op,0);   /* Fop floatreg */ 
    17311770                    } 
    17321771                    else 
    17331772                    { 
    17341773                        /* FLD long ptr floatreg        */ 
    17351774                        c = cat(c,push87()); 
    17361775                        c = genfltreg(c,ESC(mf1,1),0,0); 
    17371776                    } 
    17381777                } 
    17391778                break; 
     
    33043343        c2 = genfltreg(c2, 0x8B, DX, 0);        // MOV EDX,floatreg 
    33053344 
    33063345        pop87(); 
    33073346        c2 = genfltreg(c2, ESC(MFfloat,1),3,0); // FSTP floatreg 
    33083347        genfwait(c2); 
    33093348        c2 = genfltreg(c2, 0x8B, AX, 0);        // MOV EAX,floatreg 
    33103349    } 
    33113350    else if (tym == TYcfloat && retregs & (mAX|mDX) && *pretregs & mST01) 
    33123351    { 
    33133352        c1 = push87(); 
    33143353        c1 = genfltreg(c1, 0x89, AX, 0);        // MOV floatreg, EAX 
    33153354        genfltreg(c1, 0xD9, 0, 0);              // FLD float ptr floatreg 
    33163355 
    33173356        c2 = push87(); 
    33183357        c2 = genfltreg(c2, 0x89, DX, 0);        // MOV floatreg, EDX 
    33193358        genfltreg(c2, 0xD9, 0, 0);              // FLD float ptr floatreg 
    33203359 
    33213360        if (*pretregs & mPSW) 
    33223361            c2 = genctst(c2,e,0);               // FTST 
    33233362    } 
     3363    else if ((tym == TYcfloat || tym == TYcdouble) && 
     3364             *pretregs & (mXMM0|mXMM1) && retregs & mST01) 
     3365    { 
     3366        if (*pretregs & mPSW && !(retregs & mPSW)) 
     3367            c1 = genctst(c1,e,0);               // FTST 
     3368        pop87(); 
     3369        c1 = genfltreg(c1, ESC(MFdouble,1),3,0); // FSTP floatreg 
     3370        genfwait(c1); 
     3371        c2 = getregs(mXMM0|mXMM1); 
     3372        c2 = genfltreg(c2, 0xF20F10, XMM1 - XMM0, 0);    // MOVD XMM1,floatreg 
     3373 
     3374        pop87(); 
     3375        c2 = genfltreg(c2, ESC(MFdouble,1),3,0); // FSTP floatreg 
     3376        genfwait(c2); 
     3377        c2 = genfltreg(c2, 0xF20F10, XMM0 - XMM0, 0);    // MOVD XMM0,floatreg 
     3378    } 
     3379    else if ((tym == TYcfloat || tym == TYcdouble) && 
     3380             retregs & (mXMM0|mXMM1) && *pretregs & mST01) 
     3381    { 
     3382        c1 = push87(); 
     3383        c1 = genfltreg(c1, 0xF20F11, XMM0-XMM0, 0);        // MOVD floatreg, XMM0 
     3384        genfltreg(c1, 0xDD, 0, 0);              // FLD double ptr floatreg 
     3385 
     3386        c2 = push87(); 
     3387        c2 = genfltreg(c2, 0xF20F11, XMM1-XMM0, 0);        // MOV floatreg, XMM1 
     3388        genfltreg(c2, 0xDD, 0, 0);              // FLD double ptr floatreg 
     3389 
     3390        if (*pretregs & mPSW) 
     3391            c2 = genctst(c2,e,0);               // FTST 
     3392    } 
    33243393    else 
    33253394    {   if (*pretregs & mPSW) 
    33263395        {   if (!(retregs & mPSW)) 
    33273396            {   assert(retregs & mST01); 
    33283397                c1 = genctst(c1,e,!(*pretregs & mST01));        // FTST 
    33293398            } 
    33303399        } 
    33313400        assert(!(*pretregs & mST01) || (retregs & mST01)); 
    33323401    } 
    33333402    if (*pretregs & mST01) 
    33343403    {   note87(e,0,1); 
    33353404        note87(e,sz/2,0); 
    33363405    } 
    33373406    return cat(c1,c2); 
    33383407} 
    33393408 
    33403409/***************************************** 
    33413410 * Operators OPc_r and OPc_i 
    33423411 */ 
    33433412 
     
    33813450    assert(*pretregs & (mST01 | mPSW)); 
    33823451    assert(!(*pretregs & ~(mST01 | mPSW))); 
    33833452} 
    33843453__out (result) 
    33853454{ 
    33863455} 
    33873456__body 
    33883457#endif 
    33893458{ 
    33903459    tym_t ty = tybasic(e->Ety); 
    33913460    code *c = NULL; 
    33923461    code *cpush = NULL; 
    33933462    code cs; 
    33943463    unsigned mf; 
    33953464    unsigned sz; 
    33963465    unsigned char ldop; 
    33973466    regm_t retregs; 
    33983467    symbol *s; 
    33993468    int i; 
    34003469 
     3470    //printf("cload87(e = %p, *pretregs = %s)\n", e, regm_str(*pretregs)); 
    34013471    sz = tysize[ty] / 2; 
    34023472    memset(&cs, 0, sizeof(cs)); 
    34033473    if (ADDFWAIT()) 
    34043474        cs.Iflags = CFwait; 
    34053475    switch (ty) 
    34063476    { 
    34073477        case TYcfloat:      mf = MFfloat;           break; 
    34083478        case TYcdouble:     mf = MFdouble;          break; 
    34093479        case TYcldouble:    break; 
    34103480        default:            assert(0); 
    34113481    } 
    34123482    switch (e->Eoper) 
    34133483    { 
    34143484        case OPvar: 
    34153485            notreg(e);                  // never enregister this variable 
    34163486        case OPind: 
    34173487            cpush = cat(push87(), push87()); 
    34183488            switch (ty) 
    34193489            { 
    34203490                case TYcfloat: 
  • trunk/src/backend/cgcod.c

    r619 r627  
    377377            i = branch(b,0);            // see if jmp => jmp short 
    378378            if (i)                      /* if any bytes saved           */ 
    379379            {   targ_size_t offset; 
    380380 
    381381                b->Bsize -= i; 
    382382                offset = b->Boffset + b->Bsize; 
    383383                for (bn = b->Bnext; bn; bn = bn->Bnext) 
    384384                { 
    385385                    if (bn->Balign) 
    386386                    {   targ_size_t u = bn->Balign - 1; 
    387387 
    388388                        offset = (offset + u) & ~u; 
    389389                    } 
    390390                    bn->Boffset = offset; 
    391391                    offset += bn->Bsize; 
    392392                } 
    393393                coffset = offset; 
    394394                flag = TRUE; 
    395395            } 
    396396        } 
    397         if (I32 && !(config.flags4 & CFG4optimized)) 
     397        if (!I16 && !(config.flags4 & CFG4optimized)) 
    398398            break;                      // use the long conditional jmps 
    399399    } while (flag);                     // loop till no more bytes saved 
    400400#ifdef DEBUG 
    401401    debugw && printf("code jump optimization complete\n"); 
    402402#endif 
    403403 
    404404    // Compute starting offset for switch tables 
    405405#if ELFOBJ || MACHOBJ 
    406406    swoffset = (config.flags & CFGromable) ? coffset : CDoffset; 
    407407#else 
    408408    swoffset = (config.flags & CFGromable) ? coffset : Doffset; 
    409409#endif 
    410410    swoffset = align(0,swoffset); 
    411411 
    412412    // Emit the generated code 
    413413    if (eecontext.EEcompile == 1) 
    414414    { 
    415415        codout(eecontext.EEcode); 
    416416        code_free(eecontext.EEcode); 
    417417#if SCPP 
  • trunk/src/backend/cgelem.c

    r618 r627  
    20662066            return optelem(e,TRUE); 
    20672067        } 
    20682068#else 
    20692069        { 
    20702070            e->Eoper = OPeq; 
    20712071            el_free(e->E2); 
    20722072            e->E2 = el_copytree(e1); 
    20732073            e->E2 = el_una(OPneg,tym,e->E2); 
    20742074            return optelem(e,TRUE); 
    20752075        } 
    20762076#endif 
    20772077#endif 
    20782078    } 
    20792079 
    20802080    if (OPTIMIZER) 
    20812081    { 
    20822082        if (tyintegral(tym) && (e->Eoper == OPdiv || e->Eoper == OPmod)) 
    20832083        {   int sz = tysize(tym); 
    20842084 
    20852085            // See if we can replace with OPremquo 
    2086             if (sz == intsize) 
     2086            if (sz == REGSIZE && !I64)  // need cent and ucent working for I64 to work 
    20872087            { 
    20882088                // Don't do it if there are special code sequences in the 
    20892089                // code generator (see cdmul()) 
    20902090                int pow2; 
    20912091                if (e->E2->Eoper == OPconst && 
    20922092                    sz == REGSIZE && !uns && 
    20932093                    (pow2 = ispow2(el_tolong(e->E2))) != -1 && 
    20942094                    !(config.target_cpu < TARGET_80286 && pow2 != 1 && e->Eoper == OPdiv) 
    20952095                   ) 
    20962096                    ; 
    20972097                else 
    20982098                { 
    20992099                    assert(sz == 2 || sz == 4); 
    21002100                    int op = OPmsw; 
    21012101                    if (e->Eoper == OPdiv) 
    21022102                    { 
    21032103                        op = (sz == 2) ? OP32_16 : OP64_32; 
    21042104                    } 
    21052105                    e->Eoper = OPremquo; 
    21062106                    e = el_una(op, tym, e); 
  • trunk/src/backend/cgen.c

    r605 r627  
    144144 * Add code to end of linked list. 
    145145 * Note that unused operands are garbage. 
    146146 * gen1() and gen2() are shortcut routines. 
    147147 * Input: 
    148148 *      c ->    linked list that code is to be added to end of 
    149149 *      cs ->   data for the code 
    150150 * Returns: 
    151151 *      pointer to start of code list 
    152152 */ 
    153153 
    154154code *gen(code *c,code *cs) 
    155155{   code *ce,*cstart; 
    156156    unsigned reg; 
    157157 
    158158#ifdef DEBUG                            /* this is a high usage routine */ 
    159159    assert(cs); 
    160160#endif 
    161161    assert(I64 || cs->Irex == 0); 
    162162    ce = code_calloc(); 
    163163    *ce = *cs; 
     164    //printf("ce = %p %02x\n", ce, ce->Iop); 
     165    if (ce->Iop == LEA && ce->Irm == 4 && ce->Isib == 0x6D && ce->IFL1 == FLunde) *(char*)0=0; 
    164166    if (config.flags4 & CFG4optimized && 
    165167        ce->IFL2 == FLconst && 
    166168        (ce->Iop == 0x81 || ce->Iop == 0x80) && 
    167169        reghasvalue((ce->Iop == 0x80) ? BYTEREGS : ALLREGS,ce->IEV2.Vlong,&reg) && 
    168170        !(ce->Iflags & CFopsize && I16) 
    169171       ) 
    170172    {   // See if we can replace immediate instruction with register instruction 
    171173        static unsigned char regop[8] = 
    172174                { 0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38 }; 
    173175 
    174176//printf("replacing 0x%02x, val = x%lx\n",ce->Iop,ce->IEV2.Vlong); 
    175177        ce->Iop = regop[(ce->Irm & modregrm(0,7,0)) >> 3] | (ce->Iop & 1); 
    176178        code_newreg(ce, reg); 
    177179    } 
    178180    code_next(ce) = CNIL; 
    179181    if (c) 
    180182    {   cstart = c; 
    181183        while (code_next(c)) c = code_next(c);  /* find end of list     */ 
    182184        code_next(c) = ce;                      /* link into list       */ 
    183185        return cstart; 
    184186    } 
    185187    return ce; 
    186188} 
    187189 
    188190code *gen1(code *c,unsigned op) 
    189191{ code *ce,*cstart; 
    190192 
    191193  ce = code_calloc(); 
    192194  ce->Iop = op; 
     195  assert(op != LEA); 
    193196  if (c) 
    194197  {     cstart = c; 
    195198        while (code_next(c)) c = code_next(c);  /* find end of list     */ 
    196199        code_next(c) = ce;                      /* link into list       */ 
    197200        return cstart; 
    198201  } 
    199202  return ce; 
    200203} 
    201204 
    202205code *gen2(code *c,unsigned op,unsigned rm) 
    203206{ code *ce,*cstart; 
    204207 
    205208  cstart = ce = code_calloc(); 
    206209  /*cxcalloc++;*/ 
    207210  ce->Iop = op; 
    208211  ce->Iea = rm; 
    209212  if (c) 
    210213  {     cstart = c; 
    211214        while (code_next(c)) c = code_next(c);  /* find end of list     */ 
    212215        code_next(c) = ce;                      /* link into list       */ 
    213216  } 
    214217  return cstart; 
    215218} 
    216219 
    217220code *gen2sib(code *c,unsigned op,unsigned rm,unsigned sib) 
    218221{ code *ce,*cstart; 
    219222 
    220223  cstart = ce = code_calloc(); 
    221224  /*cxcalloc++;*/ 
     225  if (op == LEA && (rm & 0xFF) == 4 && (sib & 0xFF) == 0x6D) *(char*)0=0; 
    222226  ce->Iop = op; 
    223227  ce->Irm = rm; 
    224228  ce->Isib = sib; 
    225229  ce->Irex = (rm | (sib & (REX_B << 16))) >> 16; 
    226230  if (sib & (REX_R << 16)) 
    227231        ce->Irex |= REX_X; 
    228232  if (c) 
    229233  {     cstart = c; 
    230234        while (code_next(c)) c = code_next(c);  /* find end of list     */ 
    231235        code_next(c) = ce;                      /* link into list       */ 
    232236  } 
    233237  return cstart; 
    234238} 
    235239 
    236240code *genregs(code *c,unsigned op,unsigned dstreg,unsigned srcreg) 
    237241{ return gen2(c,op,modregxrmx(3,dstreg,srcreg)); } 
    238242 
    239243code *gentstreg(code *c,unsigned t) 
    240244{ 
    241245    c = gen2(c,0x85,modregxrmx(3,t,t));   // TEST t,t 
     
    370374    cs.Iea = ea; 
    371375    cs.Iflags = CFoff; 
    372376    cs.IFL2 = FLconst; 
    373377    cs.IEV2.Vsize_t = EV2; 
    374378    return gen(c,&cs); 
    375379} 
    376380 
    377381/***************** 
    378382 * Generate code. 
    379383 */ 
    380384 
    381385code *genc1(code *c,unsigned op,unsigned ea,unsigned FL1,targ_size_t EV1) 
    382386{   code cs; 
    383387 
    384388    assert(FL1 < FLMAX); 
    385389    cs.Iop = op; 
    386390    cs.Iflags = CFoff; 
    387391    cs.Iea = ea; 
    388392    cs.IFL1 = FL1; 
    389393    cs.IEV1.Vsize_t = EV1; 
     394if (cs.Iop == LEA && cs.IFL1 == FLunde) *(char*)0=0; 
    390395    return gen(c,&cs); 
    391396} 
    392397 
    393398/***************** 
    394399 * Generate code. 
    395400 */ 
    396401 
    397402code *genc(code *c,unsigned op,unsigned ea,unsigned FL1,targ_size_t EV1,unsigned FL2,targ_size_t EV2) 
    398403{   code cs; 
    399404 
    400405    assert(FL1 < FLMAX); 
    401406    cs.Iop = op; 
    402407    cs.Iea = ea; 
    403408    cs.Iflags = CFoff; 
    404409    cs.IFL1 = FL1; 
    405410    cs.IEV1.Vsize_t = EV1; 
    406411    assert(FL2 < FLMAX); 
    407412    cs.IFL2 = FL2; 
    408413    cs.IEV2.Vsize_t = EV2; 
    409414    return gen(c,&cs); 
  • trunk/src/backend/cod1.c

    r621 r627  
    18551855                c = getregs(forregs); 
    18561856                ce = gen1(ce,0x58 + DX); 
    18571857                gen1(ce,0x58 + CX); 
    18581858                gen1(ce,0x58 + BX); 
    18591859                gen1(ce,0x58 + AX); 
    18601860                stackpush -= DOUBLESIZE; 
    18611861                retregs = DOUBLEREGS_16; /* for tstresult() below       */ 
    18621862            } 
    18631863            else 
    18641864#ifdef DEBUG 
    18651865                printf("retregs = x%x, forregs = x%x\n",retregs,forregs), 
    18661866#endif 
    18671867                assert(0); 
    18681868            if (EOP(e)) 
    18691869                opsflag = TRUE; 
    18701870        } 
    18711871        else 
    18721872        { 
    18731873            c = allocreg(pretregs,&rreg,tym); /* allocate return regs   */ 
    18741874            if (sz > REGSIZE) 
    1875             {   unsigned msreg,lsreg; 
    1876                 unsigned msrreg,lsrreg; 
    1877  
    1878                 msreg = findregmsw(retregs); 
    1879                 lsreg = findreglsw(retregs); 
    1880                 msrreg = findregmsw(*pretregs); 
    1881                 lsrreg = findreglsw(*pretregs); 
     1875            { 
     1876                unsigned msreg = findregmsw(retregs); 
     1877                unsigned lsreg = findreglsw(retregs); 
     1878                unsigned msrreg = findregmsw(*pretregs); 
     1879                unsigned lsrreg = findreglsw(*pretregs); 
    18821880 
    18831881                ce = genmovreg(ce,msrreg,msreg); /* MOV msrreg,msreg    */ 
    18841882                ce = genmovreg(ce,lsrreg,lsreg); /* MOV lsrreg,lsreg    */ 
    18851883            } 
     1884            else if (retregs & XMMREGS) 
     1885            { 
     1886                reg = findreg(retregs & XMMREGS); 
     1887                // MOVD floatreg, XMM? 
     1888                ce = genfltreg(ce,0xF20F11,reg - XMM0,0); 
     1889                // MOV rreg,floatreg 
     1890                ce = genfltreg(ce,0x8B,rreg,0); 
     1891                if (sz == 8) 
     1892                    code_orrex(ce,REX_W); 
     1893            } 
    18861894            else 
    1887             {   reg = findreg(retregs & (mBP | ALLREGS)); 
     1895            { 
     1896                reg = findreg(retregs & (mBP | ALLREGS)); 
    18881897                ce = genmovreg(ce,rreg,reg);    /* MOV rreg,reg         */ 
    18891898            } 
    18901899        } 
    18911900        c = cat(c,ce); 
    18921901        cssave(e,retregs | *pretregs,opsflag); 
    18931902        forregs = 0;                    /* don't care about result in reg  */ 
    18941903                                        /* cuz we have real result in rreg */ 
    18951904        retregs = *pretregs & ~mPSW; 
    18961905  } 
    18971906  if (forccs)                           /* if return result in flags    */ 
    18981907        c = cat(c,tstresult(retregs,tym,forregs)); 
    18991908  return c; 
    19001909} 
    19011910 
    19021911 
    19031912/******************************** 
    19041913 * Generate code sequence to call C runtime library support routine. 
    19051914 *      clib = CLIBxxxx 
    19061915 *      keepmask = mask of registers not to destroy. Currently can 
    19071916 *              handle only 1. Should use a temporary rather than 
    19081917 *              push/pop for speed. 
    19091918 */ 
    19101919 
    19111920int clib_inited = 0;            // != 0 if initialized 
    19121921 
    19131922code *callclib(elem *e,unsigned clib,regm_t *pretregs,regm_t keepmask) 
    19141923{ 
     1924    //printf("callclib(e = %p, clib = %d, *pretregs = %s, keepmask = %s\n", e, clib, regm_str(*pretregs), regm_str(keepmask)); 
     1925    //elem_print(e); 
    19151926#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 
    19161927  static symbol lib[] = 
    19171928  { 
    19181929/* Convert destroyed regs into saved regs       */ 
    19191930#define Z(desregs)      (~(desregs) & (mBP| mES | ALLREGS)) 
    19201931#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 
    19211932#define N(name) "_" name 
    19221933#else 
    19231934#define N(name) name 
    19241935#endif 
    19251936 
    19261937/* Shorthand to map onto SYMBOLY()              */ 
    19271938#define Y(desregs,name)  SYMBOLY(FLfunc,Z(desregs),N(name),0) 
    19281939 
    19291940    Y(0,"_LCMP__"),                     // CLIBlcmp 
    19301941    Y(mAX|mCX|mDX,"_LMUL__"),           // CLIBlmul 
    19311942#if 1 
    19321943    Y(mAX|mBX|mCX|mDX,"_LDIV__"),       // CLIBldiv 
    19331944    Y(mAX|mBX|mCX|mDX,"_LDIV__"),       // CLIBlmod 
    19341945    Y(mAX|mBX|mCX|mDX,"_ULDIV__"),      // CLIBuldiv 
     
    20812092 
    20822093    // NOTE: desregs is wrong for 16 bit code, mBX should be included 
    20832094    Y(mST0|mST01,"_Cmul"),              // CLIBcmul 
    20842095    Y(mAX|mCX|mDX|mST0|mST01,"_Cdiv"),  // CLIBcdiv 
    20852096    Y(mAX|mST0|mST01,"_Ccmp"),          // CLIBccmp 
    20862097 
    20872098    Y(mST0,"_U64_LDBL"),                // CLIBu64_ldbl 
    20882099    Y(mST0|mAX|mDX,"__LDBLULLNG"),      // CLIBld_u64 
    20892100  }; 
    20902101#endif 
    20912102 
    20922103  static struct 
    20932104  { 
    20942105    regm_t retregs16;   /* registers that 16 bit result is returned in  */ 
    20952106    regm_t retregs32;   /* registers that 32 bit result is returned in  */ 
    20962107    char pop;           /* # of bytes popped off of stack upon return   */ 
    20972108    char flags; 
    20982109        #define INF32           1       // if 32 bit only 
    20992110        #define INFfloat        2       // if this is floating point 
    21002111        #define INFwkdone       4       // if weak extern is already done 
     2112        #define INF64           8       // if 64 bit only 
    21012113    char push87;                        // # of pushes onto the 8087 stack 
    21022114    char pop87;                         // # of pops off of the 8087 stack 
    21032115  } info[CLIBMAX] = 
    21042116  { 
    21052117    {0,0,0,0},                          /* _LCMP@       lcmp    */ 
    21062118    {mDX|mAX,mDX|mAX,0,0},              // _LMUL@       lmul 
    21072119    {mDX|mAX,mDX|mAX,0,0},              // _LDIV@       ldiv 
    21082120    {mCX|mBX,mCX|mBX,0,0},              /* _LDIV@       lmod    */ 
    21092121    {mDX|mAX,mDX|mAX,0,0},              /* _ULDIV@      uldiv   */ 
    21102122    {mCX|mBX,mCX|mBX,0,0},              /* _ULDIV@      ulmod   */ 
    21112123 
    21122124#if TARGET_WINDOS 
    21132125    {DOUBLEREGS_16,DOUBLEREGS_32,8,INFfloat,1,1},       // _DMUL@       dmul 
    21142126    {DOUBLEREGS_16,DOUBLEREGS_32,8,INFfloat,1,1},       // _DDIV@       ddiv 
    21152127    {0,0,0,2},                                          // _DTST0@ 
    21162128    {0,0,0,2},                                          // _DTST0EXC@ 
    21172129    {0,0,8,INFfloat,1,1},                               // _DCMP@       dcmp 
    21182130    {0,0,8,INFfloat,1,1},                               // _DCMPEXC@    dcmp 
    21192131    {DOUBLEREGS_16,DOUBLEREGS_32,0,2},                  // _DNEG@       dneg 
    21202132    {DOUBLEREGS_16,DOUBLEREGS_32,8,INFfloat,1,1},       // _DADD@       dadd 
     
    21582170    {DOUBLEREGS_16,DOUBLEREGS_32,0,INFfloat,1,1},       // _ULLNGDBL@ 
    21592171 
    21602172    {0,0,0,2},                          // _DTST@       dtst 
    21612173    {mES|mBX,mES|mBX,0,0},              // _HTOFPTR@    vptrfptr 
    21622174    {mES|mBX,mES|mBX,0,0},              // _HCTOFPTR@   cvptrfptr 
    21632175    {0,0,0,2},                          // _87TOPSW@    87topsw 
    21642176    {mST0,mST0,0,INFfloat,1,0},         // _FLTTO87@    fltto87 
    21652177    {mST0,mST0,0,INFfloat,1,0},         // _DBLTO87@    dblto87 
    21662178    {mAX,mAX,0,2},                      // _DBLINT87@   dblint87 
    21672179    {mDX|mAX,mAX,0,2},                  // _DBLLNG87@   dbllng87 
    21682180    {0,0,0,2},                          // _FTST@ 
    21692181    {mPSW,mPSW,0,INFfloat,0,2},         // _FCOMPP@ 
    21702182    {mPSW,mPSW,0,2},                    // _FTEST@ 
    21712183    {mPSW,mPSW,0,2},                    // _FTEST0@ 
    21722184    {mST0,mST0,0,INFfloat,1,1},         // _FDIV@ 
    21732185 
    21742186    {mST01,mST01,0,INF32|INFfloat,3,5}, // _Cmul 
    21752187    {mST01,mST01,0,INF32|INFfloat,0,2}, // _Cdiv 
    21762188    {mPSW, mPSW, 0,INF32|INFfloat,0,4}, // _Ccmp 
    21772189 
    2178     {mST0,mST0,0,INF32|INFfloat,2,1},   // _U64_LDBL 
    2179     {0,mDX|mAX,0,INF32|INFfloat,1,2},   // __LDBLULLNG 
     2190    {mST0,mST0,0,INF32|INF64|INFfloat,2,1},   // _U64_LDBL 
     2191    {0,mDX|mAX,0,INF32|INF64|INFfloat,1,2},   // __LDBLULLNG 
    21802192  }; 
    21812193 
    21822194  if (!clib_inited)                             /* if not initialized   */ 
    21832195  { 
    21842196        assert(sizeof(lib) / sizeof(lib[0]) == CLIBMAX); 
    21852197        assert(sizeof(info) / sizeof(info[0]) == CLIBMAX); 
    21862198        for (int i = 0; i < CLIBMAX; i++) 
    21872199        {   lib[i].Stype = tsclib; 
    21882200#if MARS 
    21892201            lib[i].Sxtrnnum = 0; 
    21902202            lib[i].Stypidx = 0; 
    21912203#endif 
    21922204        } 
    21932205 
    21942206        if (!I16) 
    21952207        {   /* Adjust table for 386     */ 
    21962208            lib[CLIBdbllng].Sregsaved  = Z(DOUBLEREGS_32); 
    21972209            lib[CLIBlngdbl].Sregsaved  = Z(DOUBLEREGS_32); 
    21982210            lib[CLIBdblint].Sregsaved  = Z(DOUBLEREGS_32); 
    21992211            lib[CLIBintdbl].Sregsaved  = Z(DOUBLEREGS_32); 
     
    22022214            lib[CLIBdneg].Sregsaved    = Z(DOUBLEREGS_32); 
    22032215            lib[CLIBdbluns].Sregsaved  = Z(DOUBLEREGS_32); 
    22042216            lib[CLIBunsdbl].Sregsaved  = Z(DOUBLEREGS_32); 
    22052217            lib[CLIBdblulng].Sregsaved = Z(DOUBLEREGS_32); 
    22062218            lib[CLIBulngdbl].Sregsaved = Z(DOUBLEREGS_32); 
    22072219#endif 
    22082220            lib[CLIBdblflt].Sregsaved  = Z(DOUBLEREGS_32); 
    22092221            lib[CLIBfltdbl].Sregsaved  = Z(DOUBLEREGS_32); 
    22102222 
    22112223            lib[CLIBdblllng].Sregsaved = Z(DOUBLEREGS_32); 
    22122224            lib[CLIBllngdbl].Sregsaved = Z(DOUBLEREGS_32); 
    22132225            lib[CLIBdblullng].Sregsaved = Z(DOUBLEREGS_32); 
    22142226            lib[CLIBullngdbl].Sregsaved = Z(DOUBLEREGS_32); 
    22152227        } 
    22162228        clib_inited++; 
    22172229  } 
    22182230#undef Z 
    22192231 
    22202232  assert(clib < CLIBMAX); 
    22212233  symbol *s = &lib[clib]; 
    2222   assert(I32 || !(info[clib].flags & INF32)); 
     2234  if (I16) 
     2235        assert(!(info[clib].flags & (INF32 | INF64))); 
    22232236  code *cpop = CNIL; 
    22242237  code *c = getregs((~s->Sregsaved & (mES | mBP | ALLREGS)) & ~keepmask); // mask of regs destroyed 
    22252238  keepmask &= ~s->Sregsaved; 
    22262239    int npushed = numbitsset(keepmask); 
    22272240    gensaverestore2(keepmask, &c, &cpop); 
    22282241#if 0 
    22292242  while (keepmask) 
    22302243  {     unsigned keepreg; 
    22312244 
    22322245        if (keepmask & (mBP|ALLREGS)) 
    22332246        {       keepreg = findreg(keepmask & (mBP|ALLREGS)); 
    22342247                c = gen1(c,0x50 + keepreg);             /* PUSH keepreg */ 
    22352248                cpop = cat(gen1(CNIL,0x58 + keepreg),cpop);     // POP keepreg 
    22362249                keepmask &= ~mask[keepreg]; 
    22372250                npushed++; 
    22382251        } 
    22392252        if (keepmask & mES) 
    22402253        {       c = gen1(c,0x06);                       /* PUSH ES      */ 
    22412254                cpop = cat(gen1(CNIL,0x07),cpop);       /* POP ES       */ 
    22422255                keepmask &= ~mES; 
     
    35933606                    code_newreg(c, c->Irm & 7); 
    35943607                    if (c->Irex & REX_B) 
    35953608                        c->Irex = (c->Irex & ~REX_B) | REX_R; 
    35963609                } 
    35973610            } 
    35983611        } 
    35993612        else if (sz < 8) 
    36003613        { 
    36013614            c = allocreg(&regm,&reg,TYoffset);          /* get a register */ 
    36023615            if (I32)                                    // it's a 48 bit pointer 
    36033616                ce = loadea(e,&cs,0x0FB7,reg,REGSIZE,0,0); /* MOVZX reg,data+4 */ 
    36043617            else 
    36053618            {   ce = loadea(e,&cs,0x8B,reg,REGSIZE,0,0); /* MOV reg,data+2 */ 
    36063619                if (tym == TYfloat || tym == TYifloat)  // dump sign bit 
    36073620                    gen2(ce,0xD1,modregrm(3,4,reg));    /* SHL reg,1      */ 
    36083621            } 
    36093622            c = cat(c,ce); 
    36103623            ce = loadea(e,&cs,0x0B,reg,0,regm,0);       /* OR reg,data */ 
    36113624            c = cat(c,ce); 
    36123625        } 
    3613         else if (sz == 8) 
    3614         {   code *c1; 
    3615             int i; 
    3616  
     3626        else if (sz == 8 || (I64 && sz == 2 * REGSIZE && !tyfloating(tym))) 
     3627        { 
    36173628            c = allocreg(&regm,&reg,TYoffset);  /* get a register */ 
    3618             i = sz - REGSIZE; 
     3629            int i = sz - REGSIZE; 
    36193630            ce = loadea(e,&cs,0x8B,reg,i,0,0);  /* MOV reg,data+6 */ 
    36203631            if (tyfloating(tym))                // TYdouble or TYdouble_alias 
    36213632                gen2(ce,0xD1,modregrm(3,4,reg));        // SHL reg,1 
    36223633            c = cat(c,ce); 
    36233634 
    36243635            while ((i -= REGSIZE) >= 0) 
    36253636            { 
    3626                 c1 = loadea(e,&cs,0x0B,reg,i,regm,0);   // OR reg,data+i 
     3637                code *c1 = loadea(e,&cs,0x0B,reg,i,regm,0);   // OR reg,data+i 
    36273638                if (i == 0) 
    36283639                    c1->Iflags |= CFpsw;                // need the flags on last OR 
    36293640                c = cat(c,c1); 
    36303641            } 
    36313642        } 
    3632         else if (sz == LNGDBLSIZE)                      // TYldouble 
     3643        else if (sz == tysize[TYldouble])               // TYldouble 
    36333644            return load87(e,0,pretregs,NULL,-1); 
    36343645        else 
     3646        { 
     3647#ifdef DEBUG 
     3648            elem_print(e); 
     3649#endif 
    36353650            assert(0); 
     3651        } 
    36363652        return c; 
    36373653  } 
    36383654  /* not for flags only */ 
    36393655  flags = *pretregs & mPSW;             /* save original                */ 
    36403656  forregs = *pretregs & (mBP | ALLREGS | mES | XMMREGS); 
    36413657  if (*pretregs & mSTACK) 
    36423658        forregs |= DOUBLEREGS; 
    36433659  if (e->Eoper == OPconst) 
    36443660  {     regm_t save; 
    36453661 
    36463662        if (sz == REGSIZE && reghasvalue(forregs,e->EV.Vint,&reg)) 
    36473663            forregs = mask[reg]; 
    36483664 
    36493665        save = regcon.immed.mval; 
    36503666        c = allocreg(&forregs,&reg,tym);        /* allocate registers   */ 
    36513667        regcon.immed.mval = save;               // KLUDGE! 
    36523668        if (sz <= REGSIZE) 
    36533669        { 
    36543670            if (sz == 1) 
    36553671                flags |= 1; 
  • trunk/src/backend/cod2.c

    r601 r627  
    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) 
    220220        if (e2->Eoper == OPconst) 
    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; 
    230             if (sz == 8
     230            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); 
    246246        L10: 
    247247            cs.Iop = op1 ^ byte; 
    248248            cs.Iflags |= word | CFpsw; 
    249249            freenode(e1); 
    250250            freenode(e2); 
     
    392392 
    393393                    // IMUL reg,imm32 
    394394                    c = genc2(CNIL,0x69,modregxrm(3,reg,BP),imm32[ss]); 
    395395                } 
    396396                else 
    397397                {   // LEA reg,[reg1*ss][reg1] 
    398398                    c = gen2sib(CNIL,0x8D,modregxrm(0,reg,4),modregrm(ss,reg1 & 7,reg1 & 7)); 
    399399                    if (reg1 & 8) 
    400400                        code_orrex(c, REX_X | REX_B); 
    401401                } 
    402402                reg1 = reg; 
    403403                ss = ss2;                               // use *2 for scale 
    404404            } 
    405405            else 
    406406                c = NULL; 
    407407            c = cat4(c1,c2,c3,c); 
    408408 
    409409            cs.Iop = 0x8D;                      // LEA reg,c[reg1*ss][reg2] 
    410410            cs.Irm = modregrm(2,reg & 7,4); 
    411411            cs.Isib = modregrm(ss,reg1 & 7,reg2 & 7); 
     412            assert(reg2 != BP); 
    412413            cs.Iflags = CFoff; 
    413414            cs.Irex = 0; 
    414415            if (reg & 8) 
    415416                cs.Irex |= REX_R; 
    416417            if (reg1 & 8) 
    417418                cs.Irex |= REX_X; 
    418419            if (reg2 & 8) 
    419420                cs.Irex |= REX_B; 
    420421            cs.IFL1 = FLconst; 
    421422            cs.IEV1.Vuns = edisp->EV.Vuns; 
    422423 
    423424            freenode(edisp); 
    424425            freenode(e1); 
    425426            c = gen(c,&cs); 
    426427            return cat(c,fixresult(e,mask[reg],pretregs)); 
    427428        } 
    428429  } 
    429430 
    430431  posregs = (byte) ? BYTEREGS : (mES | ALLREGS | mBP); 
    431432  retregs = *pretregs & posregs; 
     
    759760 
    760761code *cdmul(elem *e,regm_t *pretregs) 
    761762{   unsigned rreg,op,oper,lib,byte; 
    762763    regm_t resreg,retregs,rretregs; 
    763764    regm_t keepregs; 
    764765    tym_t uns;                          // 1 if unsigned operation, 0 if not 
    765766    tym_t tyml; 
    766767    code *c,*cg,*cl,*cr,cs; 
    767768    elem *e1,*e2; 
    768769    int sz; 
    769770    targ_size_t e2factor; 
    770771    int opunslng; 
    771772    int pow2; 
    772773 
    773774    if (*pretregs == 0)                         // if don't want result 
    774775    {   c = codelem(e->E1,pretregs,FALSE);      // eval left leaf 
    775776        *pretregs = 0;                          // in case they got set 
    776777        return cat(c,codelem(e->E2,pretregs,FALSE)); 
    777778    } 
    778779 
     780    //printf("cdmul(e = %p, *pretregs = %s)\n", e, regm_str(*pretregs)); 
    779781    keepregs = 0; 
    780782    cs.Iflags = 0; 
    781783    cs.Irex = 0; 
    782784    c = cg = cr = CNIL;                         // initialize 
    783785    e2 = e->E2; 
    784786    e1 = e->E1; 
    785787    tyml = tybasic(e1->Ety); 
    786788    sz = tysize[tyml]; 
    787789    byte = tybyte(e->Ety) != 0; 
    788790    uns = tyuns(tyml) || tyuns(e2->Ety); 
    789791    oper = e->Eoper; 
    790792    unsigned rex = (I64 && sz == 8) ? REX_W : 0; 
    791793    unsigned grex = rex << 16; 
    792794 
    793795    if (tyfloating(tyml)) 
    794796#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 
    795797        return orth87(e,pretregs); 
    796798#else 
    797799        return opdouble(e,pretregs,(oper == OPmul) ? CLIBdmul : CLIBddiv); 
    798800#endif 
     
    10101012                    case 24:    ss = 1; ss2 = 3; goto L4; 
    10111013 
    10121014                    case 6: 
    10131015                    case 3:     ss = 1; goto L4; 
    10141016 
    10151017                    case 20:    ss = 2; ss2 = 2; goto L4; 
    10161018                    case 40:    ss = 2; ss2 = 3; goto L4; 
    10171019 
    10181020                    case 10: 
    10191021                    case 5:     ss = 2; goto L4; 
    10201022 
    10211023                    case 36:    ss = 3; ss2 = 2; goto L4; 
    10221024                    case 72:    ss = 3; ss2 = 3; goto L4; 
    10231025 
    10241026                    case 18: 
    10251027                    case 9:     ss = 3; goto L4; 
    10261028 
    10271029                    L4: 
    10281030                    { 
    10291031#if 1 
    1030                         regm_t regm = byte ? BYTEREGS : ALLREGS;        // don't use EBP 
     1032                        regm_t regm = byte ? BYTEREGS : ALLREGS; 
     1033                        regm &= ~(mBP | mR13);                  // don't use EBP 
    10311034                        cl = codelem(e->E1,&regm,TRUE); 
    10321035                        unsigned r = findreg(regm); 
    10331036 
    10341037                        if (ss2) 
    10351038                        {   // Don't use EBP 
    1036                             resreg &= ~mBP
     1039                            resreg &= ~(mBP | mR13)
    10371040                            if (!resreg) 
    10381041                                resreg = retregs; 
    10391042                        } 
    10401043                        cg = allocreg(&resreg,&reg,tyml); 
    10411044 
    10421045                        c = gen2sib(CNIL,0x8D,grex | modregxrm(0,reg,4), 
    10431046                                              modregxrmx(ss,r,r)); 
     1047                        assert((r & 7) != BP); 
    10441048                        if (ss2) 
    10451049                        { 
    10461050                            gen2sib(c,0x8D,grex | modregxrm(0,reg,4), 
    10471051                                           modregxrm(ss2,reg,5)); 
    10481052                            code_last(c)->IFL1 = FLconst; 
    10491053                            code_last(c)->IEV1.Vint = 0; 
    10501054                        } 
    10511055                        else if (!(e2factor & 1))    // if even factor 
    10521056                        {   genregs(c,0x03,reg,reg); // ADD reg,reg 
    10531057                            code_orrex(c,rex); 
    10541058                        } 
    10551059                        cg = cat(cg,c); 
    10561060                        goto L3; 
    10571061#else 
    10581062 
    10591063                                // Don't use EBP 
    10601064                                resreg &= ~mBP; 
    10611065                                if (!resreg) 
    10621066                                    resreg = retregs; 
    10631067 
     
    10711075                                    gen2sib(c,0x8D,modregrm(0,reg,4), 
    10721076                                                   modregrm(ss2,reg,5)); 
    10731077                                    code_last(c)->IFL1 = FLconst; 
    10741078                                    code_last(c)->IEV1.Vint = 0; 
    10751079                                } 
    10761080                                else if (!(e2factor & 1))    // if even factor 
    10771081                                    genregs(c,0x03,reg,reg); // ADD reg,reg 
    10781082                                cg = cat(cg,c); 
    10791083                                goto L3; 
    10801084#endif 
    10811085                    } 
    10821086                    case 37: 
    10831087                    case 74:    shift = 2; 
    10841088                                goto L5; 
    10851089                    case 13: 
    10861090                    case 26:    shift = 0; 
    10871091                                goto L5; 
    10881092                    L5: 
    10891093                    { 
    10901094                                // Don't use EBP 
    1091                                 resreg &= ~mBP
     1095                                resreg &= ~(mBP | mR13)
    10921096                                if (!resreg) 
    10931097                                    resreg = retregs; 
    10941098                                cl = allocreg(&resreg,&reg,TYint); 
    10951099 
    1096                                 regm_t sregm = ALLREGS & ~resreg; 
     1100                                regm_t sregm = (ALLREGS & ~mR13) & ~resreg; 
    10971101                                cl = cat(cl,codelem(e->E1,&sregm,FALSE)); 
    10981102                                unsigned sreg = findreg(sregm); 
    10991103                                cg = getregs(resreg | sregm); 
    11001104                                // LEA reg,[sreg * 4][sreg] 
    11011105                                // SHL sreg,shift 
    11021106                                // LEA reg,[sreg * 8][reg] 
     1107                                assert((sreg & 7) != BP); 
     1108                                assert((reg & 7) != BP); 
    11031109                                c = gen2sib(CNIL,0x8D,grex | modregxrm(0,reg,4), 
    11041110                                                      modregxrmx(2,sreg,sreg)); 
    11051111                                if (shift) 
    11061112                                    genc2(c,0xC1,grex | modregrmx(3,4,sreg),shift); 
    11071113                                gen2sib(c,0x8D,grex | modregxrm(0,reg,4), 
    11081114                                                      modregxrmx(3,sreg,reg)); 
    11091115                                if (!(e2factor & 1))         // if even factor 
    11101116                                {   genregs(c,0x03,reg,reg); // ADD reg,reg 
    11111117                                    code_orrex(c,rex); 
    11121118                                } 
    11131119                                cg = cat(cg,c); 
    11141120                                goto L3; 
    11151121                    } 
    11161122                } 
    11171123            } 
    11181124 
    11191125            cl = scodelem(e->E1,&retregs,0,TRUE);       // eval left leaf 
    11201126            reg = findreg(retregs); 
    11211127            cg = allocreg(&resreg,&rreg,e->Ety); 
    11221128 
     
    11911197                    genc2(cg,0xC1,grex | modregrm(3,7,AX),pow2); // SAR AX,pow2 
    11921198                } 
    11931199                else // OPmod 
    11941200                {   gen2(cg,0x33,grex | modregrm(3,AX,DX));    // XOR AX,DX 
    11951201                    gen2(cg,0x2B,grex | modregrm(3,AX,DX));    // SUB AX,DX 
    11961202                    genc2(cg,0x81,grex | modregrm(3,4,AX),m);  // AND AX,mask 
    11971203                    gen2(cg,0x33,grex | modregrm(3,AX,DX));    // XOR AX,DX 
    11981204                    gen2(cg,0x2B,grex | modregrm(3,AX,DX));    // SUB AX,DX 
    11991205                    resreg = mAX; 
    12001206                } 
    12011207            } 
    12021208            goto L3; 
    12031209        } 
    12041210        goto L2; 
    12051211    case OPind: 
    12061212        if (!e2->Ecount)                        /* if not CSE           */ 
    12071213                goto L1;                        /* try OP reg,EA        */ 
    12081214        goto L2; 
    12091215    default:                                    /* OPconst and operators */ 
    12101216    L2: 
     1217        //printf("test2 %p, retregs = %s rretregs = %s resreg = %s\n", e, regm_str(retregs), regm_str(rretregs), regm_str(resreg)); 
    12111218        cl = codelem(e1,&retregs,FALSE);        /* eval left leaf       */ 
    12121219        cr = scodelem(e2,&rretregs,retregs,TRUE);       /* get rvalue   */ 
    12131220        if (sz <= REGSIZE) 
    12141221        {   cg = getregs(mAX | mDX);            /* trash these regs     */ 
    12151222            if (op == 7)                        /* signed divide        */ 
    12161223            {   cg = gen1(cg,0x99);             // CWD 
    12171224                code_orrex(cg,rex); 
    12181225            } 
    12191226            else if (op == 6)                   /* unsigned divide      */ 
    12201227            { 
    12211228                cg = movregconst(cg,DX,0,(sz == 8) ? 64 : 0);    // MOV DX,0 
    12221229                cg = cat(cg,getregs(mDX)); 
    12231230            } 
    12241231            rreg = findreg(rretregs); 
    12251232            cg = gen2(cg,0xF7 ^ byte,grex | modregrmx(3,op,rreg)); // OP AX,rreg 
    12261233        L3: 
    12271234            c = fixresult(e,resreg,pretregs); 
    12281235        } 
    12291236        else if (sz == 2 * REGSIZE) 
    12301237        { 
  • trunk/src/backend/cod3.c

    r619 r627  
    34843484  unsigned char op; 
    34853485 
    34863486  //printf("jmpaddr()\n"); 
    34873487  cstart = c;                           /* remember start of code       */ 
    34883488  while (c) 
    34893489  { 
    34903490        op = c->Iop; 
    34913491        if (inssize[op & 0xFF] & T &&   // if second operand 
    34923492            c->IFL2 == FLcode && 
    34933493            ((op & ~0x0F) == 0x70 || op == JMP || op == JMPS || op == JCXZ)) 
    34943494        {       ci = code_next(c); 
    34953495                ctarg = c->IEV2.Vcode;  /* target code                  */ 
    34963496                ad = 0;                 /* IP displacement              */ 
    34973497                while (ci && ci != ctarg) 
    34983498                { 
    34993499                        ad += calccodsize(ci); 
    35003500                        ci = code_next(ci); 
    35013501                } 
    35023502                if (!ci) 
    35033503                    goto Lbackjmp;      // couldn't find it 
    3504                 if (I32 || op == JMP || op == JMPS || op == JCXZ) 
     3504                if (!I16 || op == JMP || op == JMPS || op == JCXZ) 
    35053505                        c->IEVpointer2 = ad; 
    35063506                else                    /* else conditional             */ 
    35073507                {       if (!(c->Iflags & CFjmp16))     /* if branch    */ 
    35083508                                c->IEVpointer2 = ad; 
    35093509                        else            /* branch around a long jump    */ 
    35103510                        {       cn = code_next(c); 
    35113511                                code_next(c) = code_calloc(); 
    35123512                                code_next(code_next(c)) = cn; 
    35133513                                c->Iop = op ^ 1;        /* converse jmp */ 
    35143514                                c->Iflags &= ~CFjmp16; 
    3515                                 c->IEVpointer2 = I32 ? 5 : 3
     3515                                c->IEVpointer2 = I16 ? 3 : 5
    35163516                                cn = code_next(c); 
    35173517                                cn->Iop = JMP;          /* long jump    */ 
    35183518                                cn->IFL2 = FLconst; 
    35193519                                cn->IEVpointer2 = ad; 
    35203520                        } 
    35213521                } 
    35223522                c->IFL2 = FLconst; 
    35233523        } 
    35243524        if (op == LOOP && c->IFL2 == FLcode)    /* backwards refs       */ 
    35253525        { 
    35263526            Lbackjmp: 
    35273527                ctarg = c->IEV2.Vcode; 
    35283528                for (ci = cstart; ci != ctarg; ci = code_next(ci)) 
    35293529                        if (!ci || ci == c) 
    35303530                                assert(0); 
    35313531                ad = 2;                 /* - IP displacement            */ 
    35323532                while (ci != c) 
    35333533                {       assert(ci); 
    35343534                        ad += calccodsize(ci); 
    35353535                        ci = code_next(ci); 
    35363536                } 
    35373537                c->IEVpointer2 = (-ad) & 0xFF; 
    35383538                c->IFL2 = FLconst; 
    35393539        } 
    35403540        c = code_next(c); 
    35413541  } 
    35423542} 
    35433543 
    35443544 
    35453545/******************************* 
    35463546 * Calculate bl->Bsize. 
    35473547 */ 
    35483548 
    35493549unsigned calcblksize(code *c) 
    35503550{   unsigned size; 
    35513551 
    35523552    for (size = 0; c; c = code_next(c)) 
    3553         size += calccodsize(c); 
     3553    { 
     3554        unsigned sz = calccodsize(c); 
     3555        //printf("off=%02x, sz = %d, code %p: op=%02x\n", size, sz, c, c->Iop); 
     3556        size += sz; 
     3557    } 
    35543558//printf("calcblksize(c = x%x) = %d\n", c, size); 
    35553559    return size; 
    35563560} 
    35573561 
    35583562/***************************** 
    35593563 * Calculate and return code size of a code. 
    35603564 * Note that NOPs are sometimes used as markers, but are 
    35613565 * never output. LINNUMs are never output. 
    35623566 * Note: This routine must be fast. Profiling shows it is significant. 
    35633567 */ 
    35643568 
    35653569unsigned calccodsize(code *c) 
    35663570{   unsigned size; 
    35673571    unsigned op; 
    35683572    unsigned char rm,mod,ins; 
    35693573    unsigned iflags; 
    35703574    unsigned i32 = I32 || I64; 
    35713575    unsigned a32 = i32; 
    35723576 
    35733577#ifdef DEBUG 
     
    50335037    else 
    50345038        ins = inssize[op & 0xFF]; 
    50355039 
    50365040    printf("code %p: nxt=%p ",c,code_next(c)); 
    50375041    if (c->Irex) 
    50385042        printf("rex=%x ", c->Irex); 
    50395043    printf("op=%02x",op); 
    50405044 
    50415045  if ((op & 0xFF) == ESCAPE) 
    50425046  {     if ((op & 0xFF00) == ESClinnum) 
    50435047        {   printf(" linnum = %d\n",c->IEV2.Vsrcpos.Slinnum); 
    50445048            return; 
    50455049        } 
    50465050        printf(" ESCAPE %d",c->Iop >> 8); 
    50475051  } 
    50485052  if (c->Iflags) 
    50495053        printf(" flg=%x",c->Iflags); 
    50505054  if (ins & M) 
    50515055  {     unsigned rm = c->Irm; 
    50525056        printf(" rm=%02x=%d,%d,%d",rm,(rm>>6)&3,(rm>>3)&7,rm&7); 
    5053         if (I32 && issib(rm)) 
     5057        if (!I16 && issib(rm)) 
    50545058        {   unsigned char sib = c->Isib; 
    50555059            printf(" sib=%02x=%d,%d,%d",sib,(sib>>6)&3,(sib>>3)&7,sib&7); 
    50565060        } 
    50575061        if ((rm & 0xC7) == BPRM || (rm & 0xC0) == 0x80 || (rm & 0xC0) == 0x40) 
    50585062        { 
    50595063            switch (c->IFL1) 
    50605064            { 
    50615065                case FLconst: 
    50625066                case FLoffset: 
    50635067                    printf(" int = %4d",c->IEV1.Vuns); 
    50645068                    break; 
    50655069                case FLblock: 
    50665070                    printf(" block = %p",c->IEV1.Vblock); 
    50675071                    break; 
    50685072                case FLswitch: 
    50695073                case FLblockoff: 
    50705074                case FLlocalsize: 
    50715075                case FLframehandler: 
    50725076                case 0: 
    50735077                    break; 
  • trunk/src/backend/cod4.c

    r618 r627  
    28622862    code *c; 
    28632863 
    28642864    //printf("cdmsw(e->Ecount = %d)\n", e->Ecount); 
    28652865    assert(e->Eoper == OPmsw); 
    28662866 
    28672867    retregs = *pretregs ? ALLREGS : 0; 
    28682868    c = codelem(e->E1,&retregs,FALSE); 
    28692869    retregs &= mMSW;                    // want MSW only 
    28702870 
    28712871    // We "destroy" a reg by assigning it the result of a new e, even 
    28722872    // though the values are the same. Weakness of our CSE strategy that 
    28732873    // a register can only hold the contents of one elem at a time. 
    28742874    if (e->Ecount) 
    28752875        c = cat(c,getregs(retregs)); 
    28762876    else 
    28772877        useregs(retregs); 
    28782878 
    28792879#ifdef DEBUG 
    28802880    if (!(!*pretregs || retregs)) 
    28812881    {   WROP(e->Eoper); 
    2882         printf(" *pretregs = x%x, retregs = x%x\n",*pretregs,retregs); 
     2882        printf(" *pretregs = %s, retregs = %s\n",regm_str(*pretregs),regm_str(retregs)); 
     2883        elem_print(e); 
    28832884    } 
    28842885#endif 
    28852886    assert(!*pretregs || retregs); 
    28862887    return cat(c,fixresult(e,retregs,pretregs));        // msw only 
    28872888} 
    28882889 
    28892890 
    28902891 
    28912892/****************************** 
    28922893 * Handle operators OPinp and OPoutp. 
    28932894 */ 
    28942895 
    28952896code *cdport(elem *e,regm_t *pretregs) 
    28962897{   regm_t retregs; 
    28972898    code *c1,*c2,*c3; 
    28982899    unsigned char op,port; 
    28992900    unsigned sz; 
    29002901    elem *e1; 
    29012902 
    29022903    //printf("cdport\n"); 
  • trunk/src/backend/debug.c

    r618 r627  
    193193        {       nest++; 
    194194                ferr("("); 
    195195                WReqn(e->E2); 
    196196                ferr(")"); 
    197197                nest--; 
    198198        } 
    199199        else 
    200200                WReqn(e->E2); 
    201201  } 
    202202  else 
    203203  { 
    204204        switch (e->Eoper) 
    205205        {   case OPconst: 
    206206                switch (tybasic(e->Ety)) 
    207207                { 
    208208                    case TYfloat: 
    209209                        dbg_printf("%g <float> ",e->EV.Vfloat); 
    210210                        break; 
    211211                    case TYdouble: 
    212212                        dbg_printf("%g ",e->EV.Vdouble); 
     213                        break; 
     214                    case TYcent: 
     215                    case TYucent: 
     216                        dbg_printf("%lld+%lld ", e->EV.Vcent.msw, e->EV.Vcent.lsw); 
    213217                        break; 
    214218                    default: 
    215219                        dbg_printf("%lld ",el_tolong(e)); 
    216220                        break; 
    217221                } 
    218222                break; 
    219223            case OPrelconst: 
    220224                ferr("#"); 
    221225                /* FALL-THROUGH */ 
    222226            case OPvar: 
    223227                dbg_printf("%s",e->EV.sp.Vsym->Sident); 
    224228                if (e->EV.sp.Vsym->Ssymnum != -1) 
    225229                    dbg_printf("(%d)",e->EV.sp.Vsym->Ssymnum); 
    226230                if (e->Eoffset != 0) 
    227231                        dbg_printf(".%ld",(long)e->Eoffset); 
    228232                break; 
    229233            case OPasm: 
    230234#if TARGET_MAC 
    231235                if (e->Eflags & EFsmasm) 
    232236                    { 
  • trunk/src/backend/el.c

    r618 r627  
    25472547                        if (n1->EV.Vshort != n2->EV.Vshort) 
    25482548                                goto nomatch; 
    25492549                        break; 
    25502550                    case TYlong: 
    25512551                    case TYulong: 
    25522552                    case TYdchar: 
    25532553#if TARGET_MAC 
    25542554                    case TYfptr: 
    25552555                    case TYvptr: 
    25562556#endif 
    25572557                    case_long: 
    25582558                        if (n1->EV.Vlong != n2->EV.Vlong) 
    25592559                                goto nomatch; 
    25602560                        break; 
    25612561                    case TYllong: 
    25622562                    case TYullong: 
    25632563                    case_llong: 
    25642564                        if (n1->EV.Vllong != n2->EV.Vllong) 
    25652565                                goto nomatch; 
    25662566                        break; 
     2567                    case TYcent: 
     2568                    case TYucent: 
     2569                        if (n1->EV.Vcent.lsw != n2->EV.Vcent.lsw || 
     2570                            n1->EV.Vcent.msw != n2->EV.Vcent.msw) 
     2571                                goto nomatch; 
     2572                        break; 
    25672573                    case TYenum: 
    25682574                        if (PARSER) 
    25692575                        {   tym = n1->ET->Tnext->Tty; 
    25702576                            goto Lagain; 
    25712577                        } 
    25722578                    case TYint: 
    25732579                    case TYuint: 
    25742580                        if (intsize == SHORTSIZE) 
    25752581                            goto case_short; 
    25762582                        else 
    25772583                            goto case_long; 
    25782584 
    25792585#if TX86 
    25802586#if JHANDLE 
    25812587                    case TYjhandle: 
    25822588#endif 
    25832589                    case TYnullptr: 
    25842590                    case TYnptr: 
    25852591                    case TYsptr: 
    25862592                    case TYcptr: 
  • trunk/src/backend/evalu8.c

    r618 r627  
    175175                        b = 1; 
    176176                    else 
    177177                        b = e->EV.Vcdouble.re != 0 || e->EV.Vcdouble.im != 0; 
    178178                    break; 
    179179                case TYcldouble: 
    180180                    if (isnan(e->EV.Vcldouble.re) || isnan(e->EV.Vcldouble.im)) 
    181181                        b = 1; 
    182182                    else 
    183183                        b = e->EV.Vcldouble.re != 0 || e->EV.Vcldouble.im != 0; 
    184184                    break; 
    185185                case TYstruct:  // happens on syntax error of (struct x)0 
    186186#if SCPP 
    187187                    assert(errcnt); 
    188188#else 
    189189                    assert(0); 
    190190#endif 
    191191                case TYvoid:    /* happens if we get syntax errors or 
    192192                                       on RHS of && || expressions */ 
    193193                    b = 0; 
    194194                    break; 
     195 
     196                case TYcent: 
     197                case TYucent: 
     198                    b = e->EV.Vcent.lsw || e->EV.Vcent.msw; 
     199                    break; 
     200 
    195201                default: 
    196202#ifdef DEBUG 
    197203                    WRTYxx(typemask(e)); 
    198204#endif 
    199205                    assert(0); 
    200206            } 
    201207            break; 
    202208        default: 
    203209            assert(0); 
    204210    } 
    205211    return b; 
    206212} 
    207213 
    208214/*************************** 
    209215 * Return TRUE if expression will always evaluate to TRUE. 
    210216 */ 
    211217 
    212218HINT iftrue(elem *e) 
    213219{ 
    214220  while (1) 
  • trunk/src/todt.c

    r602 r627  
    134134                        break;                  // overlap 
    135135                } 
    136136            } 
    137137        } 
    138138        if (d) 
    139139        { 
    140140            if (v->offset < offset) 
    141141                error(loc, "duplicate union initialization for %s", v->toChars()); 
    142142            else 
    143143            {   unsigned sz = dt_size(d); 
    144144                unsigned vsz = v->type->size(); 
    145145                unsigned voffset = v->offset; 
    146146 
    147147                unsigned dim = 1; 
    148148                for (Type *vt = v->type->toBasetype(); 
    149149                     vt->ty == Tsarray; 
    150150                     vt = vt->nextOf()->toBasetype()) 
    151151                {   TypeSArray *tsa = (TypeSArray *)vt; 
    152152                    dim *= tsa->dim->toInteger(); 
    153153                } 
     154                //printf("sz = %d, dim = %d, vsz = %d\n", sz, dim, vsz); 
    154155                assert(sz == vsz || sz * dim <= vsz); 
    155156 
    156157                for (size_t i = 0; i < dim; i++) 
    157158                { 
    158159                    if (offset < voffset) 
    159160                        pdtend = dtnzeros(pdtend, voffset - offset); 
    160161                    if (!d) 
    161162                    { 
    162163                        if (v->init) 
    163164                            d = v->init->toDt(); 
    164165                        else 
    165166                            v->type->toDt(&d); 
    166167                    } 
    167168                    pdtend = dtcat(pdtend, d); 
    168169                    d = NULL; 
    169170                    offset = voffset + sz; 
    170171                    voffset += vsz / dim; 
    171172                    if (sz == vsz) 
    172173                        break; 
    173174                } 
     
    265266            else if (dim > tadim) 
    266267            { 
    267268#ifdef DEBUG 
    268269                printf("1: "); 
    269270#endif 
    270271                error(loc, "too many initializers, %d, for array[%d]", dim, tadim); 
    271272            } 
    272273            break; 
    273274        } 
    274275 
    275276        case Tpointer: 
    276277        case Tarray: 
    277278            // Create symbol, and then refer to it 
    278279            Symbol *s; 
    279280            s = static_sym(); 
    280281            s->Sdt = d; 
    281282            outdata(s); 
    282283 
    283284            d = NULL; 
    284285            if (tb->ty == Tarray) 
    285                 dtdword(&d, dim); 
     286                dtsize_t(&d, dim); 
    286287            dtxoff(&d, s, 0, TYnptr); 
    287288            break; 
    288289 
    289290        default: 
    290291            assert(0); 
    291292    } 
    292293    return d; 
    293294} 
    294295 
    295296 
    296297dt_t *ArrayInitializer::toDtBit() 
    297298{ 
    298299#if DMDV1 
    299300    unsigned size; 
    300301    unsigned length; 
    301302    unsigned i; 
    302303    unsigned tadim; 
    303304    dt_t *d; 
    304305    dt_t **pdtend; 
    305306    Type *tb = type->toBasetype(); 
     
    380381            } 
    381382            else 
    382383            { 
    383384                tadim = (tadim + 31) / 32; 
    384385                if (databits.allocdim < tadim) 
    385386                    pdtend = dtnzeros(pdtend, size * (tadim - databits.allocdim));      // pad out end of array 
    386387            } 
    387388            break; 
    388389        } 
    389390 
    390391        case Tpointer: 
    391392        case Tarray: 
    392393            // Create symbol, and then refer to it 
    393394            Symbol *s; 
    394395            s = static_sym(); 
    395396            s->Sdt = d; 
    396397            outdata(s); 
    397398 
    398399            d = NULL; 
    399400            if (tb->ty == Tarray) 
    400                 dtdword(&d, dim); 
     401                dtsize_t(&d, dim); 
    401402            dtxoff(&d, s, 0, TYnptr); 
    402403            break; 
    403404 
    404405        default: 
    405406            assert(0); 
    406407    } 
    407408    return d; 
    408409#else 
    409410    return NULL; 
    410411#endif 
    411412} 
    412413 
    413414 
    414415dt_t *ExpInitializer::toDt() 
    415416{ 
    416417    dt_t *dt = NULL; 
    417418 
    418419    exp = exp->optimize(WANTvalue); 
    419420    exp->toDt(&dt); 
    420421    return dt; 
     
    522523            break; 
    523524    } 
    524525    return pdt; 
    525526} 
    526527 
    527528dt_t **NullExp::toDt(dt_t **pdt) 
    528529{ 
    529530    assert(type); 
    530531    return dtnzeros(pdt, type->size()); 
    531532} 
    532533 
    533534dt_t **StringExp::toDt(dt_t **pdt) 
    534535{ 
    535536    //printf("StringExp::toDt() '%s', type = %s\n", toChars(), type->toChars()); 
    536537    Type *t = type->toBasetype(); 
    537538 
    538539    // BUG: should implement some form of static string pooling 
    539540    switch (t->ty) 
    540541    { 
    541542        case Tarray: 
    542             dtdword(pdt, len); 
     543            dtsize_t(pdt, len); 
    543544            pdt = dtabytes(pdt, TYnptr, 0, (len + 1) * sz, (char *)string); 
    544545            break; 
    545546 
    546547        case Tsarray: 
    547548        {   TypeSArray *tsa = (TypeSArray *)type; 
    548549            dinteger_t dim; 
    549550 
    550551            pdt = dtnbytes(pdt, len * sz, (const char *)string); 
    551552            if (tsa->dim) 
    552553            { 
    553554                dim = tsa->dim->toInteger(); 
    554555                if (len < dim) 
    555556                { 
    556557                    // Pad remainder with 0 
    557558                    pdt = dtnzeros(pdt, (dim - len) * tsa->next->size()); 
    558559                } 
    559560            } 
    560561            break; 
    561562        } 
    562563        case Tpointer: 
     
    578579    dt_t **pdtend; 
    579580 
    580581    d = NULL; 
    581582    pdtend = &d; 
    582583    for (int i = 0; i < elements->dim; i++) 
    583584    {   Expression *e = (Expression *)elements->data[i]; 
    584585 
    585586        pdtend = e->toDt(pdtend); 
    586587    } 
    587588    Type *t = type->toBasetype(); 
    588589 
    589590    switch (t->ty) 
    590591    { 
    591592        case Tsarray: 
    592593            pdt = dtcat(pdt, d); 
    593594            break; 
    594595 
    595596        case Tpointer: 
    596597        case Tarray: 
    597598            if (t->ty == Tarray) 
    598                 dtdword(pdt, elements->dim); 
     599                dtsize_t(pdt, elements->dim); 
    599600            if (d) 
    600601            { 
    601602                // Create symbol, and then refer to it 
    602603                Symbol *s; 
    603604                s = static_sym(); 
    604605                s->Sdt = d; 
    605606                outdata(s); 
    606607 
    607608                dtxoff(pdt, s, 0, TYnptr); 
    608609            } 
    609610            else 
    610                 dtdword(pdt, 0); 
     611                dtsize_t(pdt, 0); 
    611612 
    612613            break; 
    613614 
    614615        default: 
    615616            assert(0); 
    616617    } 
    617618    return pdt; 
    618619} 
    619620 
    620621dt_t **StructLiteralExp::toDt(dt_t **pdt) 
    621622{ 
    622623    Array dts; 
    623624    unsigned i; 
    624625    unsigned j; 
    625626    dt_t *dt; 
    626627    dt_t *d; 
    627628    unsigned offset; 
    628629 
    629630    //printf("StructLiteralExp::toDt() %s)\n", toChars()); 
    630631    dts.setDim(sd->fields.dim); 
     
    770772        return pdt; 
    771773    } 
    772774#ifdef DEBUG 
    773775    printf("VarExp::toDt(), kind = %s\n", var->kind()); 
    774776#endif 
    775777    error("non-constant expression %s", toChars()); 
    776778    pdt = dtnzeros(pdt, 1); 
    777779    return pdt; 
    778780} 
    779781 
    780782/* ================================================================= */ 
    781783 
    782784// Generate the data for the static initializer. 
    783785 
    784786void ClassDeclaration::toDt(dt_t **pdt) 
    785787{ 
    786788    //printf("ClassDeclaration::toDt(this = '%s')\n", toChars()); 
    787789 
    788790    // Put in first two members, the vtbl[] and the monitor 
    789791    dtxoff(pdt, toVtblSymbol(), 0, TYnptr); 
    790     dtdword(pdt, 0);                    // monitor 
     792    dtsize_t(pdt, 0);                    // monitor 
    791793 
    792794    // Put in the rest 
    793795    toDt2(pdt, this); 
    794796 
    795797    //printf("-ClassDeclaration::toDt(this = '%s')\n", toChars()); 
    796798} 
    797799 
    798800void ClassDeclaration::toDt2(dt_t **pdt, ClassDeclaration *cd) 
    799801{ 
    800802    unsigned offset; 
    801803    unsigned i; 
    802804    dt_t *dt; 
    803805    unsigned csymoffset; 
    804806 
    805807#define LOG 0 
    806808 
    807809#if LOG 
    808810    printf("ClassDeclaration::toDt2(this = '%s', cd = '%s')\n", toChars(), cd->toChars()); 
    809811#endif 
    810812    if (baseClass)