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

Changeset 767

Show
Ignore:
Timestamp:
11/21/10 10:29:42 (14 years ago)
Author:
walter
Message:

-m

Files:

Legend:

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

    r720 r767  
    29082908            //  fldcw   roundto0 
    29092909            //  fistp   long64 ptr [ESP] 
    29102910            //  fldcw   8[ESP] 
    29112911            //  pop     lsw 
    29122912            //  pop     msw 
    29132913            //  add     ESP,4 
    29142914 
    29152915            unsigned szpush = szoff + 2; 
    29162916            if (config.flags3 & CFG3pic) 
    29172917                szpush += 2; 
    29182918            szpush = (szpush + REGSIZE - 1) & ~(REGSIZE - 1); 
    29192919 
    29202920            retregs = mST0; 
    29212921            c1 = codelem(e->E1,&retregs,FALSE); 
    29222922 
    29232923            if (szpush == REGSIZE) 
    29242924                c1 = gen1(c1,0x50 + AX);                // PUSH EAX 
    29252925            else 
    29262926                c1 = genc2(c1,0x81,grex | modregrm(3,5,SP), szpush);   // SUB ESP,12 
    29272927            c1 = genfwait(c1); 
    2928             genc1(c1,0xD9,grex | modregrm(2,7,4) + 256*modregrm(0,4,SP),FLconst,szoff); // FSTCW szoff[ESP] 
     2928            genc1(c1,0xD9,modregrm(2,7,4) + 256*modregrm(0,4,SP),FLconst,szoff); // FSTCW szoff[ESP] 
    29292929 
    29302930            c1 = genfwait(c1); 
    29312931 
    29322932            if (config.flags3 & CFG3pic) 
    29332933            { 
    2934                 genc(c1,0xC7,grex | modregrm(2,0,4) + 256*modregrm(0,4,SP),FLconst,szoff+2,FLconst,CW_roundto0); // MOV szoff+2[ESP], CW_roundto0 
     2934                genc(c1,0xC7,modregrm(2,0,4) + 256*modregrm(0,4,SP),FLconst,szoff+2,FLconst,CW_roundto0); // MOV szoff+2[ESP], CW_roundto0 
    29352935                code_orflag(c1, CFopsize); 
    2936                 genc1(c1,0xD9,grex | modregrm(2,5,4) + 256*modregrm(0,4,SP),FLconst,szoff+2); // FLDCW szoff+2[ESP] 
     2936                genc1(c1,0xD9,modregrm(2,5,4) + 256*modregrm(0,4,SP),FLconst,szoff+2); // FLDCW szoff+2[ESP] 
    29372937            } 
    29382938            else 
    29392939                c1 = genrnd(c1, CW_roundto0);   // FLDCW roundto0 
    29402940 
    29412941            pop87(); 
    29422942 
    29432943            c1 = genfwait(c1); 
    29442944            gen2sib(c1,mf,grex | modregrm(0,rf,4),modregrm(0,4,SP));                   // FISTP [ESP] 
    29452945 
    29462946            retregs = *pretregs & (ALLREGS | mBP); 
    29472947            if (!retregs) 
    29482948                    retregs = ALLREGS; 
    29492949            c2 = allocreg(&retregs,&reg,tym); 
    29502950 
    29512951            c2 = genfwait(c2);                                                          // FWAIT 
    29522952            c2 = genc1(c2,0xD9,grex | modregrm(2,5,4) + 256*modregrm(0,4,SP),FLconst,szoff);   // FLDCW szoff[ESP] 
    29532953 
    29542954            if (szoff > REGSIZE) 
    29552955            {   szpush -= REGSIZE; 
    29562956                c2 = genpop(c2,findreglsw(retregs));       // POP lsw 
  • branches/dmd-1.x/src/backend/cgcod.c

    r738 r767  
    10901090            goto L2; 
    10911091 
    10921092        case BC_try: 
    10931093            if (config.flags2 & CFG2seh) 
    10941094            {   usednteh |= NTEH_try; 
    10951095                nteh_usevars(); 
    10961096            } 
    10971097            else 
    10981098                usednteh |= EHtry; 
    10991099            goto case_goto; 
    11001100 
    11011101        case BC_finally: 
    11021102            // Mark all registers as destroyed. This will prevent 
    11031103            // register assignments to variables used in finally blocks. 
    11041104            assert(!getregs(allregs)); 
    11051105            assert(!e); 
    11061106            assert(!bl->Bcode); 
    11071107#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 
    11081108            if (config.flags3 & CFG3pic) 
    11091109            { 
     1110                int nalign = 0; 
    11101111                if (STACKALIGN == 16) 
    1111                 {   c = genc2(c,0x81,modregrm(3,5,SP),12); // SUB ESP,12 
     1112                {   nalign = STACKALIGN - REGSIZE; 
     1113                    c = genc2(c,0x81,modregrm(3,5,SP),nalign); // SUB ESP,nalign 
    11121114                    if (I64) 
    11131115                        code_orrex(c, REX_W); 
    11141116                } 
    11151117                // CALL bl->Bsucc 
    11161118                c = genc(c,0xE8,0,0,0,FLblock,(long)list_block(bl->Bsucc)); 
    1117                 if (STACKALIGN == 16
    1118                 {   c = genc2(c,0x81,modregrm(3,0,SP),12); // ADD ESP,12 
     1119                if (nalign
     1120                {   c = genc2(c,0x81,modregrm(3,0,SP),nalign); // ADD ESP,nalign 
    11191121                    if (I64) 
    11201122                        code_orrex(c, REX_W); 
    11211123                } 
    11221124                // JMP list_next(bl->Bsucc) 
    11231125                nextb = list_block(list_next(bl->Bsucc)); 
    11241126                goto L2; 
    11251127            } 
    11261128            else 
    11271129#endif 
    11281130            { 
    11291131                // Generate a PUSH of the address of the successor to the 
    11301132                // corresponding BC_ret 
    11311133                //assert(list_block(list_next(bl->Bsucc))->BC == BC_ret); 
    11321134                // PUSH &succ 
    11331135                c = genc(c,0x68,0,0,0,FLblock,(long)list_block(list_next(bl->Bsucc))); 
    11341136                nextb = list_block(bl->Bsucc); 
    11351137                goto L2; 
    11361138            } 
    11371139 
    11381140        case BC_ret: 
  • branches/dmd-1.x/src/backend/cgelem.c

    r738 r767  
    41374137 
    41384138STATIC elem * elarray(elem *e) 
    41394139{ 
    41404140    return e; 
    41414141} 
    41424142 
    41434143/******************************************** 
    41444144 */ 
    41454145 
    41464146STATIC elem * elfield(elem *e) 
    41474147{ 
    41484148    return e; 
    41494149} 
    41504150 
    41514151/****************************************** 
    41524152 * OPparam 
    41534153 */ 
    41544154 
    41554155STATIC void elparamx(elem *e) 
    41564156{ 
    4157     elem *ex; 
    4158  
    41594157    //printf("elparam()\n"); 
    41604158    if (e->E1->Eoper == OPrpair) 
    41614159    { 
    41624160        e->E1->Eoper = OPparam; 
    41634161    } 
    41644162    else if (e->E1->Eoper == OPpair && !el_sideeffect(e->E1)) 
    41654163    { 
    41664164        e->E1->Eoper = OPparam; 
    4167         ex = e->E1->E2; 
     4165        elem *ex = e->E1->E2; 
    41684166        e->E1->E2 = e->E1->E1; 
    41694167        e->E1->E1 = ex; 
    41704168    } 
    41714169#if 0 
    41724170    // Unfortunately, these don't work because if the last parameter 
    41734171    // is a pair, and it is a D function, the last parameter will get 
    41744172    // passed in EAX. 
    41754173    else if (e->E2->Eoper == OPrpair) 
    41764174    { 
    41774175        e->E2->Eoper = OPparam; 
    41784176    } 
    41794177    else if (e->E2->Eoper == OPpair) 
    41804178    { 
    41814179        e->E2->Eoper = OPparam; 
    4182         ex = e->E2->E2; 
     4180        elem *ex = e->E2->E2; 
    41834181        e->E2->E2 = e->E2->E1; 
    41844182        e->E2->E1 = ex; 
    41854183    } 
    41864184#endif 
    41874185} 
    41884186 
    41894187STATIC elem * elparam(elem *e) 
    41904188{ 
    41914189    if (!OPTIMIZER) 
    41924190    { 
    41934191        if (!I64) 
    41944192            elparamx(e); 
    41954193    } 
    41964194    return e; 
    41974195} 
    41984196 
    41994197/******************************** 
    42004198 * Optimize an element. This routine is recursive! 
    42014199 * Be careful not to do this if VBEs have been done (else the VBE 
    42024200 * work will be undone), or it DAGs have been built (will crash if 
     
    46904688                { 
    46914689                    error(filename, linnum, "null dereference in function %s", funcsym_p->Sident); 
    46924690                    e->E1->EV.Vlong = 4096;     // suppress redundant messages 
    46934691                } 
    46944692#endif 
    46954693            } 
    46964694            e = e->E1; 
    46974695        } 
    46984696        else if (OTbinary(e->Eoper)) 
    46994697        { 
    47004698#if MARS 
    47014699            /* This is necessary as the optimizer tends to lose this information 
    47024700             */ 
    47034701            if (e->Esrcpos.Slinnum > linnum) 
    47044702            {   linnum = e->Esrcpos.Slinnum; 
    47054703                filename = e->Esrcpos.Sfilename; 
    47064704            } 
    47074705#endif 
    47084706            if (e->Eoper == OPparam) 
    47094707            { 
    4710                 elparamx(e); 
     4708                if (!I64) 
     4709                    elparamx(e); 
    47114710            } 
    47124711            postoptelem(e->E2); 
    47134712            e = e->E1; 
    47144713        } 
    47154714        else 
    47164715            break; 
    47174716    } 
    47184717} 
    47194718 
    47204719#endif // !SPP 
  • branches/dmd-1.x/src/backend/cod1.c

    r738 r767  
    956956                        {   t = 0; 
    957957                            rbase = 5; 
    958958                        } 
    959959                        else 
    960960                        {   t = 0; 
    961961                            rbase = reg; 
    962962                            if (rbase == BP) 
    963963                            {   static unsigned imm32[4] = {1+1,2+1,4+1,8+1}; 
    964964 
    965965                                // IMUL r,BP,imm32 
    966966                                c = genc2(c,0x69,modregxrm(3,r,BP),imm32[ss1]); 
    967967                                goto L7; 
    968968                            } 
    969969                        } 
    970970 
    971971                        c = gen2sib(c,0x8D,modregxrm(t,r,4),modregrm(ss1,reg & 7,rbase & 7)); 
    972972                        if (reg & 8) 
    973973                            code_orrex(c, REX_X); 
    974974                        if (rbase & 8) 
    975975                            code_orrex(c, REX_B); 
     976                        if (I64) 
     977                            code_orrex(c, REX_W); 
    976978 
    977979                        if (ssflags & SSFLnobase1) 
    978980                        {   code_last(c)->IFL1 = FLconst; 
    979981                            code_last(c)->IEV1.Vuns = 0; 
    980982                        } 
    981983                    L7: 
    982984                        if (ssflags & SSFLnobase) 
    983985                        {   t = stackfl[f] ? 2 : 0; 
    984986                            rbase = 5; 
    985987                        } 
    986988                        else 
    987989                        {   t = 2; 
    988990                            rbase = r; 
    989991                            assert(rbase != BP); 
    990992                        } 
    991993                        pcs->Irm = modregrm(t,0,4); 
    992994                        pcs->Isib = modregrm(ssindex_array[ssi].ss2,r & 7,rbase & 7); 
    993995                        if (r & 8) 
    994996                            code_orrex(pcs, REX_X); 
    995997                        if (rbase & 8) 
     
    10661068                c = cat(c,allocreg(&idxregs,&reg,TYoffset)); 
    10671069 
    10681070                /* If desired result is a far pointer, we'll have       */ 
    10691071                /* to load another register with the segment of v       */ 
    10701072                if (e1ty == TYfptr) 
    10711073                { 
    10721074                    unsigned msreg; 
    10731075 
    10741076                    idxregs |= mMSW & ALLREGS & ~keepmsk; 
    10751077                    c = cat(c,allocreg(&idxregs,&msreg,TYfptr)); 
    10761078                    msreg = findregmsw(idxregs); 
    10771079                                                /* MOV msreg,segreg     */ 
    10781080                    c = genregs(c,0x8C,segfl[f],msreg); 
    10791081                } 
    10801082                opsave = pcs->Iop; 
    10811083                flagsave = pcs->Iflags; 
    10821084                pcs->Iop = 0x8D; 
    10831085                code_newreg(pcs, reg); 
    10841086                if (!I16) 
    10851087                    pcs->Iflags &= ~CFopsize; 
     1088                if (I64) 
     1089                    pcs->Irex |= REX_W; 
    10861090                c = gen(c,pcs);                 /* LEA idxreg,EA        */ 
    10871091                cssave(e1,idxregs,TRUE); 
    10881092                if (!I16) 
    10891093                    pcs->Iflags = flagsave; 
    10901094                if (stackfl[f] && (config.wflags & WFssneds))   // if pointer into stack 
    10911095                    pcs->Iflags |= CFss;        // add SS: override 
    10921096                pcs->Iop = opsave; 
    10931097                pcs->IFL1 = FLoffset; 
    10941098                pcs->IEV1.Vuns = 0; 
    10951099                setaddrmode(pcs, idxregs); 
    10961100            } 
    10971101            freenode(e12); 
    10981102            if (e1free) 
    10991103                freenode(e1); 
    11001104            goto Lptr; 
    11011105        } 
    11021106 
    11031107        L1: 
    11041108 
    11051109        /* The rest of the cases could be a far pointer */ 
     
    28462850            {   unsigned lsreg; 
    28472851             LF1: 
    28482852                reg = findregmsw(retregs); 
    28492853                lsreg = findreglsw(retregs); 
    28502854                floatreg = TRUE;                /* use float register   */ 
    28512855                reflocal = TRUE; 
    28522856                ce = genc1(ce,0x89,             /* MOV floatreg+2,reg   */ 
    28532857                        modregrm(2,reg,BPRM),FLfltreg,REGSIZE); 
    28542858                genc1(ce,0x89,                  /* MOV floatreg,lsreg   */ 
    28552859                        modregrm(2,lsreg,BPRM),FLfltreg,0); 
    28562860                if (tym1 == TYifunc) 
    28572861                    gen1(ce,0x9C);              // PUSHF 
    28582862                genc1(ce,0xFF,                  /* CALL [floatreg]      */ 
    28592863                        modregrm(2,3,BPRM),FLfltreg,0); 
    28602864            } 
    28612865            else 
    28622866            { 
    28632867             LF2: 
    28642868                reg = findreg(retregs); 
    28652869                ce = gen2(ce,0xFF,modregrmx(3,2,reg));   /* CALL reg     */ 
     2870                if (I64) 
     2871                    code_orrex(ce, REX_W); 
    28662872            } 
    28672873        } 
    28682874        else 
    28692875        { 
    28702876            if (tym1 == TYifunc) 
    28712877                c = gen1(c,0x9C);               // PUSHF 
    28722878                                                // CALL [function] 
    28732879            cs.Iflags = 0; 
    28742880            cgstate.stackclean++; 
    28752881            ce = loadea(e11,&cs,0xFF,farfunc ? 3 : 2,0,keepmsk,(ALLREGS|mES|mBP) & ~fregsaved); 
    28762882            cgstate.stackclean--; 
    28772883            freenode(e11); 
    28782884        } 
    28792885        s = NULL; 
    28802886  } 
    28812887  c = cat(c,ce); 
    28822888  freenode(e1); 
    28832889 
    28842890  /* See if we will need the frame pointer. 
    28852891     Calculate it here so we can possibly use BP to fix the stack. 
  • branches/dmd-1.x/src/backend/cod2.c

    r738 r767  
    636636                    } 
    637637                } 
    638638                rval = reghasvalue(byte ? BYTEREGS : ALLREGS,i,&rreg); 
    639639                cs.IEV2.Vint = i; 
    640640        L3: 
    641641                op1 ^= byte; 
    642642                cs.Iflags |= word; 
    643643                if (rval) 
    644644                {   cs.Iop = op1 ^ 2; 
    645645                    mode = rreg; 
    646646                } 
    647647                else 
    648648                    cs.Iop = 0x81; 
    649649                cs.Irm = modregrm(3,mode&7,reg&7); 
    650650                if (mode & 8) 
    651651                    cs.Irex |= REX_R; 
    652652                if (reg & 8) 
    653653                    cs.Irex |= REX_B; 
    654654                if (I64 && sz == 8) 
    655655                    cs.Irex |= REX_W; 
     656                if (I64 && byte && reg >= 4) 
     657                    cs.Irex |= REX; 
    656658                cs.IFL2 = (e2->Eoper == OPconst) ? FLconst : el_fl(e2); 
    657659                /* Modify instruction for special cases */ 
    658660                switch (e->Eoper) 
    659661                {   case OPadd: 
    660662                    {   int iop; 
    661663 
    662664                        if (i == 1) 
    663665                            iop = 0;                    /* INC reg      */ 
    664666                        else if (i == -1) 
    665667                            iop = 8;                    /* DEC reg      */ 
    666668                        else 
    667669                            break; 
    668670                        cs.Iop = (0x40 | iop | reg) ^ byte; 
    669671                        if ((byte && *pretregs & mPSW) || I64) 
    670672                        {   cs.Irm = modregrm(3,0,reg & 7) | iop; 
    671673                            cs.Iop = 0xFF; 
    672674                        } 
    673675                        break; 
    674676                    } 
    675677                    case OPand: 
     
    32943296                c2->Iflags = CFopsize; 
    32953297                offset += 2; 
    32963298                c3 = cat(c3,c2); 
    32973299            } 
    32983300            if (numbytes & 1) 
    32993301            {                           // MOV byte ptr offset[reg],vreg 
    33003302                c2 = gen2(CNIL,0x88,modregxrmx(2,vreg,reg)); 
    33013303                c2->IEVoffset1 = offset; 
    33023304                c2->IFL1 = FLconst; 
    33033305                c3 = cat(c3,c2); 
    33043306            } 
    33053307fixres: 
    33063308            return cat3(c1,c3,fixresult(e,retregs1,pretregs)); 
    33073309        } 
    33083310    } 
    33093311 
    33103312    // Get nbytes into CX 
    33113313    retregs2 = mCX; 
    33123314    if (!I16 && e2->E1->Eoper == OPconst && e2->E2->Eoper == OPconst) 
    33133315    { 
    3314         remainder = numbytes & (REGSIZE - 1); 
    3315         numwords  = numbytes / REGSIZE;         // number of words 
     3316        remainder = numbytes & (4 - 1); 
     3317        numwords  = numbytes / 4;               // number of words 
    33163318        op = 0xAB;                              // moving by words 
    33173319        c1 = getregs(mCX); 
    33183320        c1 = movregconst(c1,CX,numwords,I64?64:0);     // # of bytes/words 
    33193321    } 
    33203322    else 
    33213323    { 
    33223324        remainder = 0; 
    33233325        op = 0xAA;                              // must move by bytes 
    33243326        c1 = codelem(e2->E1,&retregs2,FALSE); 
    33253327    } 
    33263328 
    33273329    // Get val into AX 
    33283330 
    33293331    retregs3 = mAX; 
    33303332    if (!I16 && e2->E2->Eoper == OPconst) 
    33313333    { 
    33323334        c1 = regwithvalue(c1, mAX, value, NULL, I64?64:0); 
    33333335        freenode(e2->E2); 
    33343336    } 
    33353337    else 
  • branches/dmd-1.x/src/backend/cod3.c

    r760 r767  
    22872287 
    22882288    /* Skip over return address */ 
    22892289    thunkty = tybasic(sthunk->ty()); 
    22902290    if (tyfarfunc(thunkty)) 
    22912291        p += I32 ? 8 : tysize[TYfptr];          /* far function */ 
    22922292    else 
    22932293        p += tysize[TYnptr]; 
    22942294 
    22952295    if (!I16) 
    22962296    { 
    22972297        /* 
    22982298           Generate: 
    22992299            ADD p[ESP],d 
    23002300           For direct call: 
    23012301            JMP sfunc 
    23022302           For virtual call: 
    23032303            MOV EAX, p[ESP]                     EAX = this 
    23042304            MOV EAX, d2[EAX]                    EAX = this->vptr 
    23052305            JMP i[EAX]                          jump to virtual function 
    23062306         */ 
     2307        unsigned reg = 0; 
     2308        if ((targ_ptrdiff_t)d < 0) 
     2309        { 
     2310            d = -d; 
     2311            reg = 5;                            // switch from ADD to SUB 
     2312        } 
    23072313        if (thunkty == TYmfunc) 
    23082314        {                                       // ADD ECX,d 
    23092315            c = CNIL; 
    23102316            if (d) 
    2311                 c = genc2(c,0x81,modregrm(3,0,CX),d); 
     2317                c = genc2(c,0x81,modregrm(3,reg,CX),d); 
    23122318        } 
    23132319        else if (thunkty == TYjfunc) 
    23142320        {                                       // ADD EAX,d 
    23152321            c = CNIL; 
    23162322            if (d) 
    2317                 c = genc2(c,0x81,modregrm(3,0,AX),d); 
     2323                c = genc2(c,0x81,modregrm(3,reg,I64 ? DI : AX),d); 
    23182324        } 
    23192325        else 
    23202326        { 
    2321             c = genc(CNIL,0x81,modregrm(2,0,4), 
     2327            c = genc(CNIL,0x81,modregrm(2,reg,4), 
    23222328                FLconst,p,                      // to this 
    23232329                FLconst,d);                     // ADD p[ESP],d 
    23242330            c->Isib = modregrm(0,4,SP); 
    23252331        } 
    23262332        if (I64) 
    23272333            c->Irex |= REX_W; 
    23282334    } 
    23292335    else 
    23302336    { 
    23312337        /* 
    23322338           Generate: 
    23332339            MOV BX,SP 
    23342340            ADD [SS:] p[BX],d 
    23352341           For direct call: 
    23362342            JMP sfunc 
    23372343           For virtual call: 
    23382344            MOV BX, p[BX]                       BX = this 
    23392345            MOV BX, d2[BX]                      BX = this->vptr 
    23402346            JMP i[BX]                           jump to virtual function 
    23412347         */ 
     
    45524558    case FLfunc:                        /* function call                */ 
    45534559        s = uev->sp.Vsym;               /* symbol pointer               */ 
    45544560#if !TARGET_FLAT 
    45554561        if (tyfarfunc(s->ty())) 
    45564562        {       /* Large code references are always absolute    */ 
    45574563                FLUSH(); 
    45584564                offset += reftoident(cseg,offset,s,0,flags) - 4; 
    45594565        } 
    45604566        else if (s->Sseg == cseg && 
    45614567                 (s->Sclass == SCstatic || s->Sclass == SCglobal) && 
    45624568                 s->Sxtrnnum == 0 && flags & CFselfrel) 
    45634569        {       /* if we know it's relative address     */ 
    45644570                ad = s->Soffset - OFFSET() - 4; 
    45654571                goto L1; 
    45664572        } 
    45674573        else 
    45684574#endif 
    45694575        { 
    45704576                assert(!(TARGET_FLAT && tyfarfunc(s->ty()))); 
    45714577                FLUSH(); 
    4572                 reftoident(cseg,offset,s,0,flags); 
     4578                reftoident(cseg,offset,s,val,flags); 
    45734579        } 
    45744580        break; 
    45754581 
    45764582    case FLblock:                       /* displacement to another block */ 
    45774583        ad = uev->Vblock->Boffset - OFFSET() - 4; 
    45784584        //printf("FLblock: funcoffset = %x, OFFSET = %x, Boffset = %x, ad = %x\n", funcoffset, OFFSET(), uev->Vblock->Boffset, ad); 
    45794585        goto L1; 
    45804586 
    45814587    case FLblockoff: 
    45824588        FLUSH(); 
    45834589        assert(uev->Vblock); 
    45844590        //printf("FLblockoff: offset = %x, Boffset = %x, funcoffset = %x\n", offset, uev->Vblock->Boffset, funcoffset); 
    45854591        reftocodseg(cseg,offset,uev->Vblock->Boffset); 
    45864592        break; 
    45874593 
    45884594    default: 
    45894595#ifdef DEBUG 
    45904596        WRFL(fl); 
    45914597#endif 
    45924598        assert(0); 
  • branches/dmd-1.x/src/backend/cod4.c

    r738 r767  
    10061006        cs.Iop = op1 ^ 2;                       // toggle direction bit 
    10071007        if (forccs) 
    10081008            cs.Iflags |= CFpsw; 
    10091009        reverse = 2;                            // remember we toggled it 
    10101010        cl = gen(cl,&cs); 
    10111011        c = cat(cr,cl); 
    10121012        retregs = 0;            /* to trigger a bug if we attempt to use it */ 
    10131013  } 
    10141014  else // evaluate e2 into register 
    10151015  { 
    10161016        retregs = (byte) ? BYTEREGS : ALLREGS;  // pick working reg 
    10171017        if (tyml == TYhptr) 
    10181018            retregs &= ~mCX;                    // need CX for shift count 
    10191019        cr = scodelem(e->E2,&retregs,0,TRUE);   // get rvalue 
    10201020        cl = getlvalue(&cs,e1,retregs);         // get lvalue 
    10211021        cl = cat(cl,modEA(&cs)); 
    10221022        cs.Iop = op1; 
    10231023        if (sz <= REGSIZE || tyfv(tyml)) 
    10241024        {   reg = findreg(retregs); 
    10251025            code_newreg(&cs, reg);              // OP1 EA,reg 
     1026            if (sz == 1 && reg >= 4 && I64) 
     1027                cs.Irex |= REX; 
    10261028        } 
    10271029        else if (tyml == TYhptr) 
    10281030        {   unsigned mreg,lreg; 
    10291031 
    10301032            mreg = findregmsw(retregs); 
    10311033            lreg = findreglsw(retregs); 
    10321034            cl = cat(cl,getregs(retregs | mCX)); 
    10331035 
    10341036            // If h -= l, convert to h += -l 
    10351037            if (e->Eoper == OPminass) 
    10361038            { 
    10371039                cl = gen2(cl,0xF7,modregrm(3,3,mreg));  // NEG mreg 
    10381040                gen2(cl,0xF7,modregrm(3,3,lreg));       // NEG lreg 
    10391041                code_orflag(cl,CFpsw); 
    10401042                genc2(cl,0x81,modregrm(3,3,mreg),0);    // SBB mreg,0 
    10411043            } 
    10421044            cs.Iop = 0x01; 
    10431045            cs.Irm |= modregrm(0,lreg,0); 
    10441046            cl = gen(cl,&cs);                           // ADD EA,lreg 
    10451047            code_orflag(cl,CFpsw); 
  • branches/dmd-1.x/src/backend/elfobj.c

    r714 r767  
    27522752                                if (s->Sclass == SCstatic) 
    27532753                                    relinfo = RI_TYPE_TLS_LE;  // TLS_GD? 
    27542754                                else 
    27552755                                    relinfo = RI_TYPE_TLS_IE; 
    27562756                            } 
    27572757                            else 
    27582758                            { 
    27592759                                if (s->Sclass == SCstatic) 
    27602760                                    relinfo = RI_TYPE_TLS_LE; 
    27612761                                else 
    27622762                                    relinfo = RI_TYPE_TLS_IE; 
    27632763                            } 
    27642764                        } 
    27652765                    } 
    27662766                    if (flags & CFoffset64 && relinfo == R_X86_64_32) 
    27672767                    { 
    27682768                        relinfo = R_X86_64_64; 
    27692769                    } 
    27702770                    //printf("\t\t************* adding relocation\n"); 
    27712771                    targ_size_t v = 0; 
    2772                     if (I64 && relinfo == R_X86_64_PC32
     2772                    if (I64 && retsize == 4
    27732773                    { 
    27742774                        assert(retsize == 4); 
    27752775                        if (val > 0xFFFFFFFF) 
    27762776                        {   /* The value to be added is bigger than 32 bits, so we 
    27772777                             * transfer it to the 64 bit addend of the fixup record 
    27782778                             */ 
    27792779                            v = val; 
    27802780                            val = 0; 
    27812781                        } 
    27822782                    } 
    27832783#if 0 
    27842784                    targ_size_t v = (relinfo == R_X86_64_PC32) ? -4 : 0; 
    27852785                    if (relinfo == R_X86_64_PC32 && flags & CFaddend8) 
    27862786                        v = -8; 
    27872787#endif 
    27882788                    elf_addrel(seg,offset,relinfo,refseg,v); 
    27892789                } 
    27902790outaddrval: 
    27912791                if (retsize == 8) 
    27922792                    buf->write64(val); 
     
    29902990        if (I64) 
    29912991            buf->writeByte(REX | REX_W); 
    29922992        buf->writeByte(0x8B); buf->writeByte(0x11); /* movl (%ecx), %edx */ 
    29932993        if (I64) 
    29942994            buf->writeByte(REX | REX_W); 
    29952995        buf->writeByte(0x89); buf->writeByte(0x10); /* movl %edx, (%eax) */ 
    29962996        if (I64) 
    29972997            buf->writeByte(REX | REX_W); 
    29982998        buf->writeByte(0x89); buf->writeByte(0x01); /* movl %eax, (%ecx) */ 
    29992999 
    30003000        if (I32) buf->writeByte(0x61); // POPAD 
    30013001        buf->writeByte(0xC3); /* ret */ 
    30023002        SegData[seg]->SDoffset = buf->size(); 
    30033003    } 
    30043004 
    30053005    /* Add reference to constructor into ".ctors" segment 
    30063006     */ 
    30073007    const int seg = elf_getsegment(".ctors", NULL, SHT_PROGDEF, SHF_ALLOC|SHF_WRITE, NPTRSIZE); 
    30083008 
    30093009    Outbuffer *buf = SegData[seg]->SDbuf; 
    3010     buf->write32(codeOffset); 
     3010    if (I64) 
     3011        buf->write64(codeOffset); 
     3012    else 
     3013        buf->write32(codeOffset); 
    30113014    elf_addrel(seg, SegData[seg]->SDoffset, I64 ? R_X86_64_64 : RI_TYPE_SYM32, STI_TEXT, 0); 
    30123015    SegData[seg]->SDoffset += NPTRSIZE; 
    30133016} 
    30143017 
    30153018#endif 
    30163019 
    30173020/************************************* 
    30183021 */ 
    30193022 
    30203023void elfobj_gotref(symbol *s) 
    30213024{ 
    30223025    //printf("elfobj_gotref(%x '%s', %d)\n",s,s->Sident, s->Sclass); 
    30233026    switch(s->Sclass) 
    30243027    { 
    30253028        case SCstatic: 
    30263029        case SClocstat: 
    30273030            s->Sfl = FLgotoff; 
    30283031            break; 
    30293032 
    30303033        case SCextern: 
  • branches/dmd-1.x/src/backend/rtlsym.h

    r738 r767  
    4747SYMBOL_MARS(MONITOR_PROLOG,  FLfunc,FREGSAVED,"_d_monitor_prolog",0,t) \ 
    4848SYMBOL_MARS(MONITOR_EPILOG,  FLfunc,FREGSAVED,"_d_monitor_epilog",0,t) \ 
    4949SYMBOL_MARS(DCOVER,          FLfunc,FREGSAVED,"_d_cover_register", 0, t) \ 
    5050SYMBOL_MARS(DASSERT,         FLfunc,FREGSAVED,"_d_assert", SFLexit, t) \ 
    5151SYMBOL_MARS(DASSERTM,        FLfunc,FREGSAVED,"_d_assertm", SFLexit, t) \ 
    5252SYMBOL_MARS(DASSERT_MSG,     FLfunc,FREGSAVED,"_d_assert_msg", SFLexit, t) \ 
    5353SYMBOL_MARS(DUNITTEST,       FLfunc,FREGSAVED,"_d_unittest", 0, t) \ 
    5454SYMBOL_MARS(DUNITTESTM,      FLfunc,FREGSAVED,"_d_unittestm", 0, t) \ 
    5555SYMBOL_MARS(DUNITTEST_MSG,   FLfunc,FREGSAVED,"_d_unittest_msg", 0, t) \ 
    5656SYMBOL_MARS(DARRAY,          FLfunc,FREGSAVED,"_d_array_bounds", SFLexit, t) \ 
    5757SYMBOL_MARS(DINVARIANT,      FLfunc,FREGSAVED,"D9invariant12_d_invariantFC6ObjectZv", 0, tsdlib) \ 
    5858SYMBOL_MARS(_DINVARIANT,     FLfunc,FREGSAVED,"_D9invariant12_d_invariantFC6ObjectZv", 0, tsdlib) \ 
    5959SYMBOL_MARS(MEMCPY,          FLfunc,FREGSAVED,"memcpy",    0, t) \ 
    6060SYMBOL_MARS(MEMSET8,         FLfunc,FREGSAVED,"memset",    0, t) \ 
    6161SYMBOL_MARS(MEMSET16,        FLfunc,FREGSAVED,"_memset16", 0, t) \ 
    6262SYMBOL_MARS(MEMSET32,        FLfunc,FREGSAVED,"_memset32", 0, t) \ 
    6363SYMBOL_MARS(MEMSET64,        FLfunc,FREGSAVED,"_memset64", 0, t) \ 
    6464SYMBOL_MARS(MEMSET128,       FLfunc,FREGSAVED,"_memset128",0, t) \ 
    6565SYMBOL_MARS(MEMSET80,        FLfunc,FREGSAVED,"_memset80", 0, t) \ 
    6666SYMBOL_MARS(MEMSET160,       FLfunc,FREGSAVED,"_memset160",0, t) \ 
     67SYMBOL_MARS(MEMSETFLOAT,     FLfunc,FREGSAVED,"_memsetFloat", 0, t) \ 
     68SYMBOL_MARS(MEMSETDOUBLE,    FLfunc,FREGSAVED,"_memsetDouble", 0, t) \ 
    6769SYMBOL_MARS(MEMSETN,         FLfunc,FREGSAVED,"_memsetn",  0, t) \ 
    6870SYMBOL_MARS(MODULO,          FLfunc,FREGSAVED,"_modulo",   0, t) \ 
    6971SYMBOL_MARS(MONITORENTER,  FLfunc,FREGSAVED,"_d_monitorenter",0, t) \ 
    7072SYMBOL_MARS(MONITOREXIT,   FLfunc,FREGSAVED,"_d_monitorexit",0, t) \ 
    7173SYMBOL_MARS(CRITICALENTER, FLfunc,FREGSAVED,"_d_criticalenter",0, t) \ 
    7274SYMBOL_MARS(CRITICALEXIT,  FLfunc,FREGSAVED,"_d_criticalexit",0, t) \ 
    7375SYMBOL_MARS(SWITCH_STRING, FLfunc,FREGSAVED,"_d_switch_string", 0, t) \ 
    7476SYMBOL_MARS(SWITCH_USTRING,FLfunc,FREGSAVED,"_d_switch_ustring", 0, t) \ 
    7577SYMBOL_MARS(SWITCH_DSTRING,FLfunc,FREGSAVED,"_d_switch_dstring", 0, t) \ 
    7678SYMBOL_MARS(DSWITCHERR,    FLfunc,FREGSAVED,"_d_switch_error", SFLexit, t) \ 
    7779SYMBOL_MARS(DHIDDENFUNC,   FLfunc,FREGSAVED,"_d_hidden_func", 0, t) \ 
    7880SYMBOL_MARS(NEWCLASS,      FLfunc,FREGSAVED,"_d_newclass", 0, t) \ 
    7981SYMBOL_MARS(NEWARRAYT,     FLfunc,FREGSAVED,"_d_newarrayT", 0, t) \ 
    8082SYMBOL_MARS(NEWARRAYIT,    FLfunc,FREGSAVED,"_d_newarrayiT", 0, t) \ 
    8183SYMBOL_MARS(NEWARRAYMT,    FLfunc,FREGSAVED,"_d_newarraymT", 0, tv) \ 
    8284SYMBOL_MARS(NEWARRAYMIT,   FLfunc,FREGSAVED,"_d_newarraymiT", 0, tv) \ 
    8385SYMBOL_MARS(ARRAYLITERALT, FLfunc,FREGSAVED,"_d_arrayliteralT", 0, tv) \ 
    8486SYMBOL_MARS(ASSOCARRAYLITERALT, FLfunc,FREGSAVED,"_d_assocarrayliteralT", 0, tv) \ 
    8587SYMBOL_MARS(ASSOCARRAYLITERALTX, FLfunc,FREGSAVED,"_d_assocarrayliteralTX", 0, t) \ 
    8688SYMBOL_MARS(CALLFINALIZER, FLfunc,FREGSAVED,"_d_callfinalizer", 0, t) \ 
  • branches/dmd-1.x/src/e2ir.c

    r738 r767  
    495495/***************************************** 
    496496 * Evaluate elem and convert to dynamic array. 
    497497 */ 
    498498 
    499499elem *eval_Darray(IRState *irs, Expression *e) 
    500500{ 
    501501    elem *ex; 
    502502 
    503503    ex = e->toElem(irs); 
    504504    return array_toDarray(e->type, ex); 
    505505} 
    506506 
    507507/************************************ 
    508508 */ 
    509509 
    510510elem *sarray_toDarray(Loc loc, Type *tfrom, Type *tto, elem *e) 
    511511{ 
    512512    //printf("sarray_toDarray()\n"); 
    513513    //elem_print(e); 
    514514 
    515     elem *elen; 
    516515    unsigned dim = ((TypeSArray *)tfrom)->dim->toInteger(); 
    517516 
    518517    if (tto) 
    519518    { 
    520519        unsigned fsize = tfrom->nextOf()->size(); 
    521520        unsigned tsize = tto->nextOf()->size(); 
    522521 
    523522        if ((dim * fsize) % tsize != 0) 
    524523        { 
    525524          Lerr: 
    526525            error(loc, "cannot cast %s to %s since sizes don't line up", tfrom->toChars(), tto->toChars()); 
    527526        } 
    528527        dim = (dim * fsize) / tsize; 
    529528    } 
    530529  L1: 
    531     elen = el_long(TYsize_t, dim); 
     530    elem *elen = el_long(TYsize_t, dim); 
    532531    e = el_una(OPaddr, TYnptr, e); 
    533532    e = el_pair(TYdarray, elen, e); 
    534533    return e; 
    535534} 
    536535 
    537536/******************************************* 
    538537 * Set an array pointed to by eptr to evalue: 
    539538 *      eptr[0..edim] = evalue; 
    540539 * Input: 
    541540 *      eptr    where to write the data to 
    542541 *      evalue  value to write 
    543542 *      edim    number of times to write evalue to eptr[] 
    544543 *      tb      type of evalue 
    545544 */ 
    546545 
    547546elem *setArray(elem *eptr, elem *edim, Type *tb, elem *evalue) 
    548547{   int r; 
    549548    elem *e; 
    550549    int sz = tb->size(); 
    551550 
    552     if (tb->ty == Tfloat80 || tb->ty == Timaginary80) 
    553         r = RTLSYM_MEMSET80; 
    554     else if (tb->ty == Tcomplex80) 
    555         r = RTLSYM_MEMSET160; 
    556     else if (tb->ty == Tcomplex64) 
    557         r = RTLSYM_MEMSET128; 
    558     else 
    559     { 
    560         switch (sz) 
    561         { 
    562             case 1:      r = RTLSYM_MEMSET8;    break; 
    563             case 2:      r = RTLSYM_MEMSET16;   break; 
    564             case 4:      r = RTLSYM_MEMSET32;   break; 
    565             case 8:      r = RTLSYM_MEMSET64;   break; 
    566             case 16:     r = RTLSYM_MEMSET128;  break; 
    567  
    568             default: 
    569                 r = RTLSYM_MEMSETN; 
    570                 evalue = el_una(OPaddr, TYnptr, evalue); 
    571                 elem *esz = el_long(TYsize_t, sz); 
    572                 e = el_params(esz, edim, evalue, eptr, NULL); 
    573                 e = el_bin(OPcall,TYnptr,el_var(rtlsym[r]),e); 
    574                 return e; 
    575         } 
     551    switch (tb->ty) 
     552    { 
     553        case Tfloat80: 
     554        case Timaginary80: 
     555            r = RTLSYM_MEMSET80; 
     556            break; 
     557        case Tcomplex80: 
     558            r = RTLSYM_MEMSET160; 
     559            break; 
     560        case Tcomplex64: 
     561            r = RTLSYM_MEMSET128; 
     562            break; 
     563        case Tfloat32: 
     564        case Timaginary32: 
     565            if (I32) 
     566                goto Ldefault;          // legacy binary compatibility 
     567            r = RTLSYM_MEMSETFLOAT; 
     568            break; 
     569        case Tfloat64: 
     570        case Timaginary64: 
     571            if (I32) 
     572                goto Ldefault;          // legacy binary compatibility 
     573            r = RTLSYM_MEMSETDOUBLE; 
     574            break; 
     575 
     576        default: 
     577        Ldefault: 
     578            switch (sz) 
     579            { 
     580                case 1:      r = RTLSYM_MEMSET8;    break; 
     581                case 2:      r = RTLSYM_MEMSET16;   break; 
     582                case 4:      r = RTLSYM_MEMSET32;   break; 
     583                case 8:      r = RTLSYM_MEMSET64;   break; 
     584                case 16:     r = RTLSYM_MEMSET128;  break; 
     585 
     586                default: 
     587                    r = RTLSYM_MEMSETN; 
     588                    evalue = el_una(OPaddr, TYnptr, evalue); 
     589                    elem *esz = el_long(TYsize_t, sz); 
     590                    e = el_params(esz, edim, evalue, eptr, NULL); 
     591                    e = el_bin(OPcall,TYnptr,el_var(rtlsym[r]),e); 
     592                    return e; 
     593            } 
     594            break; 
    576595    } 
    577596    if (sz > 1 && sz <= 8 && 
    578597        evalue->Eoper == OPconst && el_allbits(evalue, 0)) 
    579598    { 
    580599        r = RTLSYM_MEMSET8; 
    581600        edim = el_bin(OPmul, TYsize_t, edim, el_long(TYsize_t, sz)); 
    582601    } 
    583602 
    584603    if (tybasic(evalue->Ety) == TYstruct) 
    585604    { 
    586605        evalue = el_una(OPstrpar, TYstruct, evalue); 
    587606        evalue->ET = evalue->E1->ET; 
    588607    } 
    589608 
    590609    // Be careful about parameter side effect ordering 
    591610    if (r == RTLSYM_MEMSET8) 
    592611    { 
    593612        e = el_param(edim, evalue); 
    594613        e = el_bin(OPmemset,TYnptr,eptr,e); 
    595614    } 
  • branches/dmd-1.x/src/imphint.c

    r606 r767  
    11 
    22 
    33// Compiler implementation of the D programming language 
    44// Copyright (c) 2010 by Digital Mars 
    55// All Rights Reserved 
    66// written by Walter Bright 
    77// http://www.digitalmars.com 
    88// License for redistribution is by either the Artistic License 
    99// in artistic.txt, or the GNU General Public License in gnu.txt. 
    1010// See the included readme.txt for details. 
    1111 
    1212#include <stdio.h> 
    1313#include <stdlib.h> 
    1414#include <ctype.h> 
    1515#include <assert.h> 
    1616#include <string.h> 
    1717 
     18#include "mars.h" 
     19 
    1820/****************************************** 
    1921 * Looks for undefined identifier s to see 
    2022 * if it might be undefined because an import 
    2123 * was not specified. 
    2224 * Not meant to be a comprehensive list of names in each module, 
    2325 * just the most common ones. 
    2426 */ 
    2527 
    2628const char *importHint(const char *s) 
    2729{ 
    2830#if DMDV1 
    2931    static const char *modules[] = 
    3032    {   "std.c.stdio", 
    3133        "std.stdio", 
    3234        "std.math", 
     35        "std.c.stdarg", 
    3336    }; 
    3437    static const char *names[] = 
    3538    { 
    3639        "printf", NULL, 
    3740        "writefln", NULL, 
    3841        "sin", "cos", "sqrt", "fabs", NULL, 
     42        "__va_argsave_t", NULL, 
    3943    }; 
    4044#else 
    4145    static const char *modules[] = 
    4246    {   "core.stdc.stdio", 
    4347        "std.stdio", 
    4448        "std.math", 
     49        "std.c.stdarg", 
    4550    }; 
    4651    static const char *names[] = 
    4752    { 
    4853        "printf", NULL, 
    4954        "writeln", NULL, 
    5055        "sin", "cos", "sqrt", "fabs", NULL, 
     56        "__va_argsave_t", NULL, 
    5157    }; 
    5258#endif 
    5359    int m = 0; 
    5460    for (int n = 0; n < sizeof(names)/sizeof(names[0]); n++) 
    5561    { 
    5662        const char *p = names[n]; 
    5763        if (p == NULL) 
    5864        {   m++; 
    5965            continue; 
    6066        } 
    6167        assert(m < sizeof(modules)/sizeof(modules[0])); 
    6268        if (strcmp(s, p) == 0) 
    6369            return modules[m]; 
    6470    } 
    6571    return NULL;        // didn't find it 
    6672} 
    6773 
    6874#if UNITTEST 
    6975 
    7076void unittest_importHint() 
  • branches/dmd-1.x/src/mtype.c

    r742 r767  
    34533454                            return; 
    34543455                        } 
    34553456                        if (scx->scopesym == scopesym) 
    34563457                        { 
    34573458                            t = t->semantic(loc, scx); 
    34583459                            break; 
    34593460                        } 
    34603461                    } 
    34613462                } 
    34623463            } 
    34633464        } 
    34643465        if (t->ty == Ttuple) 
    34653466            *pt = t; 
    34663467        else if (t->ty == Ttypeof) 
    34673468            *pt = t->semantic(loc, sc); 
    34683469        else 
    34693470            *pt = t->merge(); 
    34703471    } 
    34713472    if (!s) 
    34723473    { 
    3473         error(loc, "identifier '%s' is not defined", toChars()); 
     3474        const char *p = toChars(); 
     3475        const char *n = importHint(p); 
     3476        if (n) 
     3477            error(loc, "'%s' is not defined, perhaps you need to import %s; ?", p, n); 
     3478        else 
     3479        { 
     3480            Identifier *id = new Identifier(p, TOKidentifier); 
     3481            s = sc->search_correct(id); 
     3482            if (s) 
     3483                error(loc, "undefined identifier %s, did you mean %s %s?", p, s->kind(), s->toChars()); 
     3484            else 
     3485                error(loc, "undefined identifier %s", p); 
     3486        } 
    34743487    } 
    34753488} 
    34763489 
    34773490/***************************** TypeIdentifier *****************************/ 
    34783491 
    34793492TypeIdentifier::TypeIdentifier(Loc loc, Identifier *ident) 
    34803493    : TypeQualified(Tident, loc) 
    34813494{ 
    34823495    this->ident = ident; 
    34833496} 
    34843497 
    34853498 
    34863499Type *TypeIdentifier::syntaxCopy() 
    34873500{ 
    34883501    TypeIdentifier *t; 
    34893502 
    34903503    t = new TypeIdentifier(loc, ident); 
    34913504    t->syntaxCopyHelper(this); 
    34923505    return t; 
    34933506} 
  • branches/dmd-1.x/src/toir.c

    r728 r767  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2009 by Digital Mars 
     3// Copyright (c) 1999-2010 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111/* Code to help convert to the intermediate representation 
    1212 * of the compiler back end. 
    1313 */ 
    1414 
    1515#include        <stdio.h> 
    1616#include        <string.h> 
    1717#include        <time.h> 
    1818#include        <complex.h> 
    1919 
    2020#include        "lexer.h" 
    2121#include        "expression.h" 
    2222#include        "mtype.h" 
    2323#include        "dsymbol.h" 
     
    129129                ethis = el_una(OPaddr, TYnptr, ethis); 
    130130            } 
    131131        } 
    132132        else 
    133133        {   /* No 'this' pointer for current function, 
    134134             * use NULL if no references to the current function's frame 
    135135             */ 
    136136            ethis = el_long(TYnptr, 0); 
    137137#if DMDV2 
    138138            if (thisfd->closureVars.dim) 
    139139#else 
    140140            if (thisfd->nestedFrameRef) 
    141141#endif 
    142142            {   /* OPframeptr is an operator that gets the frame pointer 
    143143                 * for the current function, i.e. for the x86 it gets 
    144144                 * the value of EBP 
    145145                 */ 
    146146                ethis->Eoper = OPframeptr; 
    147147            } 
    148148        } 
     149//if (fdparent != thisfd) ethis = el_bin(OPadd, TYnptr, ethis, el_long(TYint, 0x18)); 
    149150    } 
    150151    else 
    151152    { 
    152153        if (!irs->sthis)                // if no frame pointer for this function 
    153154        { 
    154155            fd->error(loc, "is a nested function and cannot be accessed from %s", irs->getFunc()->toChars()); 
    155156            ethis = el_long(TYnptr, 0); // error recovery 
    156157        } 
    157158        else 
    158159        { 
    159160            ethis = el_var(irs->sthis); 
    160161            Dsymbol *s = thisfd; 
    161162            while (fd != s) 
    162163            {   /* Go up a nesting level, i.e. we need to find the 'this' 
    163164                 * of an enclosing function. 
    164165                 * Our 'enclosing function' may also be an inner class. 
    165166                 */ 
    166167 
    167168                //printf("\ts = '%s'\n", s->toChars()); 
    168169                thisfd = s->isFuncDeclaration(); 
     
    172173                    if (fdparent == s->toParent2()) 
    173174                        break; 
    174175                    if (thisfd->isNested()) 
    175176                    { 
    176177                        FuncDeclaration *p = s->toParent2()->isFuncDeclaration(); 
    177178#if DMDV2 
    178179                        if (!p || p->closureVars.dim) 
    179180#else 
    180181                        if (!p || p->nestedFrameRef) 
    181182#endif 
    182183                            ethis = el_una(OPind, TYnptr, ethis); 
    183184                    } 
    184185                    else if (thisfd->vthis) 
    185186                    { 
    186187                    } 
    187188                    else 
    188189                        // Error should have been caught by front end 
    189190                        assert(0); 
    190191                } 
    191192                else 
    192                 {   /* Enclosed by a class. That means the current 
    193                      * function must be a member function of that class
     193                {   /* Enclosed by an aggregate. That means the current 
     194                     * function must be a member function of that aggregate
    194195                     */ 
    195196                    ClassDeclaration *cd = s->isClassDeclaration(); 
    196197                    if (!cd) 
    197198                        goto Lnoframe; 
    198199                    if (//cd->baseClass == fd || 
    199200                        fd->isClassDeclaration() && 
    200201                        fd->isClassDeclaration()->isBaseOf(cd, NULL)) 
    201202                        break; 
    202203                    if (!cd->isNested() || !cd->vthis) 
    203204                    { 
    204205                      Lnoframe: 
    205206                        irs->getFunc()->error(loc, "cannot get frame pointer to %s", fd->toChars()); 
    206207                        return el_long(TYnptr, 0);      // error recovery 
    207208                    } 
    208                     ethis = el_bin(OPadd, TYnptr, ethis, el_long(TYint, cd->vthis->offset)); 
     209                    ethis = el_bin(OPadd, TYnptr, ethis, el_long(TYsize_t, cd->vthis->offset)); 
    209210                    ethis = el_una(OPind, TYnptr, ethis); 
    210211                    if (fdparent == s->toParent2()) 
    211212                        break; 
    212213                    if (fd == s->toParent2()) 
    213214                    { 
    214215                        /* Remember that frames for functions that have no 
    215216                         * nested references are skipped in the linked list 
    216217                         * of frames. 
    217218                         */ 
    218219#if DMDV2 
    219220                        if (s->toParent2()->isFuncDeclaration()->closureVars.dim) 
    220221#else 
    221222                        if (s->toParent2()->isFuncDeclaration()->nestedFrameRef) 
    222223#endif 
    223224                            ethis = el_una(OPind, TYnptr, ethis); 
    224225                        break; 
    225226                    } 
    226227                    if (s->toParent2()->isFuncDeclaration()) 
    227228                    { 
    228229                        /* Remember that frames for functions that have no 
     
    300301        } 
    301302    } 
    302303    else if (thisfd->vthis && 
    303304          (cdp == thisfd->toParent2() || 
    304305           (cdp->isClassDeclaration() && 
    305306            cdp->isClassDeclaration()->isBaseOf(thisfd->toParent2()->isClassDeclaration(), &offset) 
    306307           ) 
    307308          ) 
    308309        ) 
    309310    {   /* Class we're new'ing is at the same level as thisfd 
    310311         */ 
    311312        assert(offset == 0);    // BUG: should handle this case 
    312313        ethis = el_var(irs->sthis); 
    313314    } 
    314315    else 
    315316    { 
    316317        ethis = getEthis(loc, irs, ad->toParent2()); 
    317318        ethis = el_una(OPaddr, TYnptr, ethis); 
    318319    } 
    319320 
    320     ey = el_bin(OPadd, TYnptr, ey, el_long(TYint, ad->vthis->offset)); 
     321    ey = el_bin(OPadd, TYnptr, ey, el_long(TYsize_t, ad->vthis->offset)); 
    321322    ey = el_una(OPind, TYnptr, ey); 
    322323    ey = el_bin(OPeq, TYnptr, ey, ethis); 
    323324    return ey; 
    324325} 
    325326#endif 
    326327 
    327328/******************************************* 
    328329 * Convert intrinsic function to operator. 
    329330 * Returns that operator, -1 if not an intrinsic function. 
    330331 */ 
    331332 
    332333int intrinsic_op(char *name) 
    333334{ 
    334335    //printf("intrinsic_op(%s)\n", name); 
    335336    static const char *namearray[] = 
    336337    { 
    337338#if DMDV1 
    338339        "4math3cosFeZe", 
    339340        "4math3sinFeZe", 
    340341        "4math4fabsFeZe", 
     
    347348        "4math6rndtolFeZl", 
    348349        "4math6yl2xp1FeeZe", 
    349350 
    350351        "9intrinsic2btFPkkZi", 
    351352        "9intrinsic3bsfFkZi", 
    352353        "9intrinsic3bsrFkZi", 
    353354        "9intrinsic3btcFPkkZi", 
    354355        "9intrinsic3btrFPkkZi", 
    355356        "9intrinsic3btsFPkkZi", 
    356357        "9intrinsic3inpFkZh", 
    357358        "9intrinsic4inplFkZk", 
    358359        "9intrinsic4inpwFkZt", 
    359360        "9intrinsic4outpFkhZh", 
    360361        "9intrinsic5bswapFkZk", 
    361362        "9intrinsic5outplFkkZk", 
    362363        "9intrinsic5outpwFktZt", 
    363364#elif DMDV2 
    364365        /* The names are mangled differently because of the pure and 
    365366         * nothrow attributes. 
    366367         */ 
    367         "4math3cosFNaNbeZe", 
    368         "4math3sinFNaNbeZe", 
    369         "4math4fabsFNaNbeZe", 
    370         "4math4rintFNaNbeZe", 
    371         "4math4sqrtFNaNbdZd", 
    372         "4math4sqrtFNaNbeZe", 
    373         "4math4sqrtFNaNbfZf", 
    374         "4math4yl2xFNaNbeeZe", 
    375         "4math5ldexpFNaNbeiZe", 
    376         "4math6rndtolFNaNbeZl", 
    377         "4math6yl2xp1FNaNbeeZe", 
     368        "4math3cosFNaNbNfeZe", 
     369        "4math3sinFNaNbNfeZe", 
     370        "4math4fabsFNaNbNfeZe", 
     371        "4math4rintFNaNbNfeZe", 
     372        "4math4sqrtFNaNbNfdZd", 
     373        "4math4sqrtFNaNbNfeZe", 
     374        "4math4sqrtFNaNbNffZf", 
     375        "4math4yl2xFNaNbNfeeZe", 
     376        "4math5ldexpFNaNbNfeiZe", 
     377        "4math6rndtolFNaNbNfeZl", 
     378        "4math6yl2xp1FNaNbNfeeZe", 
    378379 
    379380        "9intrinsic2btFNaNbxPkkZi", 
    380381        "9intrinsic3bsfFNaNbkZi", 
    381382        "9intrinsic3bsrFNaNbkZi", 
    382383        "9intrinsic3btcFNbPkkZi", 
    383384        "9intrinsic3btrFNbPkkZi", 
    384385        "9intrinsic3btsFNbPkkZi", 
    385386        "9intrinsic3inpFNbkZh", 
    386387        "9intrinsic4inplFNbkZk", 
    387388        "9intrinsic4inpwFNbkZt", 
    388389        "9intrinsic4outpFNbkhZh", 
    389390        "9intrinsic5bswapFNaNbkZk", 
    390391        "9intrinsic5outplFNbkkZk", 
    391392        "9intrinsic5outpwFNbktZt", 
    392393#endif 
    393394    }; 
    394395    static const char *namearray64[] = 
    395396    { 
    396397#if DMDV1 
    397398        "4math3cosFeZe", 
    398399        "4math3sinFeZe", 
    399400        "4math4fabsFeZe", 
    400401        "4math4rintFeZe", 
    401402        "4math4sqrtFdZd", 
    402403        "4math4sqrtFeZe", 
    403404        "4math4sqrtFfZf", 
    404405        "4math4yl2xFeeZe", 
    405406        "4math5ldexpFeiZe", 
    406407        "4math6rndtolFeZl", 
    407408        "4math6yl2xp1FeeZe", 
    408409 
    409         "9intrinsic2btFPkkZi", 
     410        "9intrinsic2btFPmmZi", 
    410411        "9intrinsic3bsfFkZi", 
    411412        "9intrinsic3bsrFkZi", 
    412413        "9intrinsic3btcFPmmZi", 
    413414        "9intrinsic3btrFPmmZi", 
    414415        "9intrinsic3btsFPmmZi", 
    415416        "9intrinsic3inpFkZh", 
    416417        "9intrinsic4inplFkZk", 
    417418        "9intrinsic4inpwFkZt", 
    418419        "9intrinsic4outpFkhZh", 
    419420        "9intrinsic5bswapFkZk", 
    420421        "9intrinsic5outplFkkZk", 
    421422        "9intrinsic5outpwFktZt", 
    422423#elif DMDV2 
    423424        /* The names are mangled differently because of the pure and 
    424425         * nothrow attributes. 
    425426         */ 
    426         "4math3cosFNaNbeZe", 
    427         "4math3sinFNaNbeZe", 
    428         "4math4fabsFNaNbeZe", 
    429         "4math4rintFNaNbeZe", 
    430         "4math4sqrtFNaNbdZd", 
    431         "4math4sqrtFNaNbeZe", 
    432         "4math4sqrtFNaNbfZf", 
    433         "4math4yl2xFNaNbeeZe", 
    434         "4math5ldexpFNaNbeiZe", 
    435         "4math6rndtolFNaNbeZl", 
    436         "4math6yl2xp1FNaNbeeZe", 
     427        "4math3cosFNaNbNfeZe", 
     428        "4math3sinFNaNbNfeZe", 
     429        "4math4fabsFNaNbNfeZe", 
     430        "4math4rintFNaNbNfeZe", 
     431        "4math4sqrtFNaNbNfdZd", 
     432        "4math4sqrtFNaNbNfeZe", 
     433        "4math4sqrtFNaNbNffZf", 
     434        "4math4yl2xFNaNbNfeeZe", 
     435        "4math5ldexpFNaNbNfeiZe", 
     436        "4math6rndtolFNaNbNfeZl", 
     437        "4math6yl2xp1FNaNbNfeeZe", 
    437438 
    438439        "9intrinsic2btFNaNbxPkkZi", 
    439440        "9intrinsic3bsfFNaNbkZi", 
    440441        "9intrinsic3bsrFNaNbkZi", 
    441442        "9intrinsic3btcFNbPmmZi", 
    442443        "9intrinsic3btrFNbPmmZi", 
    443444        "9intrinsic3btsFNbPmmZi", 
    444445        "9intrinsic3inpFNbkZh", 
    445446        "9intrinsic4inplFNbkZk", 
    446447        "9intrinsic4inpwFNbkZt", 
    447448        "9intrinsic4outpFNbkhZh", 
    448449        "9intrinsic5bswapFNaNbkZk", 
    449450        "9intrinsic5outplFNbkkZk", 
    450451        "9intrinsic5outpwFNbktZt", 
    451452#endif 
    452453    }; 
    453454    static unsigned char ioptab[] = 
    454455    { 
    455456        OPcos, 
    456457        OPsin, 
     
    521522 *      t1      Type of the array 
    522523 * Output: 
    523524 *      e       is rewritten to avoid side effects 
    524525 * Returns: 
    525526 *      expression that initializes 'length' 
    526527 */ 
    527528 
    528529elem *resolveLengthVar(VarDeclaration *lengthVar, elem **pe, Type *t1) 
    529530{ 
    530531    //printf("resolveLengthVar()\n"); 
    531532    elem *einit = NULL; 
    532533 
    533534    if (lengthVar && !(lengthVar->storage_class & STCconst)) 
    534535    {   elem *elength; 
    535536        Symbol *slength; 
    536537 
    537538        if (t1->ty == Tsarray) 
    538539        {   TypeSArray *tsa = (TypeSArray *)t1; 
    539540            dinteger_t length = tsa->dim->toInteger(); 
    540541 
    541             elength = el_long(TYuint, length); 
     542            elength = el_long(TYsize_t, length); 
    542543            goto L3; 
    543544        } 
    544545        else if (t1->ty == Tarray) 
    545546        { 
    546547            elength = *pe; 
    547548            *pe = el_same(&elength); 
    548             elength = el_una(OP64_32, TYuint, elength); 
     549            elength = el_una(I64 ? OP128_64 : OP64_32, TYsize_t, elength); 
    549550 
    550551        L3: 
    551552            slength = lengthVar->toSymbol(); 
    552553            //symbol_add(slength); 
    553554 
    554             einit = el_bin(OPeq, TYuint, el_var(slength), elength); 
     555            einit = el_bin(OPeq, TYsize_t, el_var(slength), elength); 
    555556        } 
    556557    } 
    557558    return einit; 
    558559} 
    559560 
    560561/************************************* 
    561562 * Closures are implemented by taking the local variables that 
    562563 * need to survive the scope of the function, and copying them 
    563564 * into a gc allocated chuck of memory. That chunk, called the 
    564565 * closure here, is inserted into the linked list of stack 
    565566 * frames instead of the usual stack frame. 
    566567 * 
    567568 * buildClosure() inserts code just after the function prolog 
    568569 * is complete. It allocates memory for the closure, allocates 
    569570 * a local variable (sclosure) to point to it, inserts into it 
    570571 * the link to the enclosing frame, and copies into it the parameters 
    571572 * that are referred to in nested functions. 
    572573 * In VarExp::toElem and SymOffExp::toElem, when referring to a 
    573574 * variable that is in a closure, takes the offset from sclosure rather 
    574575 * than from the frame pointer. 
     
    596597         *        sthis 
    597598         *        ... closure variables ... 
    598599         *        ~this() { call destructor } 
    599600         *    } 
    600601         */ 
    601602#endif 
    602603        //printf("FuncDeclaration::buildClosure()\n"); 
    603604        Symbol *sclosure; 
    604605        sclosure = symbol_name("__closptr",SCauto,Type::tvoidptr->toCtype()); 
    605606        sclosure->Sflags |= SFLtrue | SFLfree; 
    606607        symbol_add(sclosure); 
    607608        irs->sclosure = sclosure; 
    608609 
    609610        unsigned offset = PTRSIZE;      // leave room for previous sthis 
    610611        for (int i = 0; i < closureVars.dim; i++) 
    611612        {   VarDeclaration *v = (VarDeclaration *)closureVars.data[i]; 
    612613            assert(v->isVarDeclaration()); 
    613614 
    614615#if DMDV2 
    615616            if (v->needsAutoDtor()) 
     617                /* Because the value needs to survive the end of the scope! 
     618                 */ 
    616619                v->error("has scoped destruction, cannot build closure"); 
     620            if (v->isargptr) 
     621                /* See Bugzilla 2479 
     622                 * This is actually a bug, but better to produce a nice 
     623                 * message at compile time rather than memory corruption at runtime 
     624                 */ 
     625                v->error("cannot reference variadic arguments from closure"); 
    617626#endif 
    618627            /* Align and allocate space for v in the closure 
    619628             * just like AggregateDeclaration::addField() does. 
    620629             */ 
    621630            unsigned memsize; 
    622631            unsigned memalignsize; 
    623632            unsigned xalign; 
    624633#if DMDV2 
    625634            if (v->storage_class & STClazy) 
    626635            { 
    627636                /* Lazy variables are really delegates, 
    628637                 * so give same answers that TypeDelegate would 
    629638                 */ 
    630639                memsize = PTRSIZE * 2; 
    631640                memalignsize = memsize; 
    632641                xalign = global.structalign; 
    633642            } 
     643            else if (v->isRef() || v->isOut()) 
     644            {    // reference parameters are just pointers 
     645                memsize = PTRSIZE; 
     646                memalignsize = memsize; 
     647                xalign = global.structalign; 
     648            } 
    634649            else 
    635650#endif 
    636651            { 
    637652                memsize = v->type->size(); 
    638653                memalignsize = v->type->alignsize(); 
    639654                xalign = v->type->memalign(global.structalign); 
    640655            } 
    641656            AggregateDeclaration::alignmember(xalign, memalignsize, &offset); 
    642657            v->offset = offset; 
    643658            offset += memsize; 
    644659 
    645660            /* Can't do nrvo if the variable is put in a closure, since 
    646661             * what the shidden points to may no longer exist. 
    647662             */ 
    648663            if (nrvo_can && nrvo_var == v) 
    649664            { 
    650665                nrvo_can = 0; 
    651666            } 
    652667        } 
    653668        // offset is now the size of the closure 
    654669 
    655670        // Allocate memory for the closure 
    656671        elem *e; 
    657         e = el_long(TYint, offset); 
     672        e = el_long(TYsize_t, offset); 
    658673        e = el_bin(OPcall, TYnptr, el_var(rtlsym[RTLSYM_ALLOCMEMORY]), e); 
    659674 
    660675        // Assign block of memory to sclosure 
    661676        //    sclosure = allocmemory(sz); 
    662677        e = el_bin(OPeq, TYvoid, el_var(sclosure), e); 
    663678 
    664679        // Set the first element to sthis 
    665680        //    *(sclosure + 0) = sthis; 
    666681        elem *ethis; 
    667682        if (irs->sthis) 
    668683            ethis = el_var(irs->sthis); 
    669684        else 
    670685            ethis = el_long(TYnptr, 0); 
    671686        elem *ex = el_una(OPind, TYnptr, el_var(sclosure)); 
    672687        ex = el_bin(OPeq, TYnptr, ex, ethis); 
    673688        e = el_combine(e, ex); 
    674689 
    675690        // Copy function parameters into closure 
    676691        for (int i = 0; i < closureVars.dim; i++) 
    677692        {   VarDeclaration *v = (VarDeclaration *)closureVars.data[i]; 
    678693 
    679694            if (!v->isParameter()) 
    680695                continue; 
    681696            tym_t tym = v->type->totym(); 
    682697            if (v->type->toBasetype()->ty == Tsarray || v->isOut() || v->isRef()) 
    683698                tym = TYnptr;   // reference parameters are just pointers 
    684699#if DMDV2 
    685700            else if (v->storage_class & STClazy) 
    686701                tym = TYdelegate; 
    687702#endif 
    688             ex = el_bin(OPadd, TYnptr, el_var(sclosure), el_long(TYint, v->offset)); 
     703            ex = el_bin(OPadd, TYnptr, el_var(sclosure), el_long(TYsize_t, v->offset)); 
    689704            ex = el_una(OPind, tym, ex); 
    690             if (ex->Ety == TYstruct) 
     705            if (tybasic(ex->Ety) == TYstruct) 
    691706            { 
    692707                ::type *t = v->type->toCtype(); 
    693708                ex->ET = t; 
    694709                ex = el_bin(OPstreq, tym, ex, el_var(v->toSymbol())); 
    695710                ex->ET = t; 
    696711            } 
    697712            else 
    698713                ex = el_bin(OPeq, tym, ex, el_var(v->toSymbol())); 
    699714 
    700715            e = el_combine(e, ex); 
    701716        } 
    702717 
    703718        block_appendexp(irs->blx->curblock, e); 
    704719    } 
    705720} 
    706721 
    707722#endif 
    708723 
    709724/*************************** 
    710725 * Determine return style of function - whether in registers or 
  • trunk/src/backend/cg87.c

    r720 r767  
    29082908            //  fldcw   roundto0 
    29092909            //  fistp   long64 ptr [ESP] 
    29102910            //  fldcw   8[ESP] 
    29112911            //  pop     lsw 
    29122912            //  pop     msw 
    29132913            //  add     ESP,4 
    29142914 
    29152915            unsigned szpush = szoff + 2; 
    29162916            if (config.flags3 & CFG3pic) 
    29172917                szpush += 2; 
    29182918            szpush = (szpush + REGSIZE - 1) & ~(REGSIZE - 1); 
    29192919 
    29202920            retregs = mST0; 
    29212921            c1 = codelem(e->E1,&retregs,FALSE); 
    29222922 
    29232923            if (szpush == REGSIZE) 
    29242924                c1 = gen1(c1,0x50 + AX);                // PUSH EAX 
    29252925            else 
    29262926                c1 = genc2(c1,0x81,grex | modregrm(3,5,SP), szpush);   // SUB ESP,12 
    29272927            c1 = genfwait(c1); 
    2928             genc1(c1,0xD9,grex | modregrm(2,7,4) + 256*modregrm(0,4,SP),FLconst,szoff); // FSTCW szoff[ESP] 
     2928            genc1(c1,0xD9,modregrm(2,7,4) + 256*modregrm(0,4,SP),FLconst,szoff); // FSTCW szoff[ESP] 
    29292929 
    29302930            c1 = genfwait(c1); 
    29312931 
    29322932            if (config.flags3 & CFG3pic) 
    29332933            { 
    2934                 genc(c1,0xC7,grex | modregrm(2,0,4) + 256*modregrm(0,4,SP),FLconst,szoff+2,FLconst,CW_roundto0); // MOV szoff+2[ESP], CW_roundto0 
     2934                genc(c1,0xC7,modregrm(2,0,4) + 256*modregrm(0,4,SP),FLconst,szoff+2,FLconst,CW_roundto0); // MOV szoff+2[ESP], CW_roundto0 
    29352935                code_orflag(c1, CFopsize); 
    2936                 genc1(c1,0xD9,grex | modregrm(2,5,4) + 256*modregrm(0,4,SP),FLconst,szoff+2); // FLDCW szoff+2[ESP] 
     2936                genc1(c1,0xD9,modregrm(2,5,4) + 256*modregrm(0,4,SP),FLconst,szoff+2); // FLDCW szoff+2[ESP] 
    29372937            } 
    29382938            else 
    29392939                c1 = genrnd(c1, CW_roundto0);   // FLDCW roundto0 
    29402940 
    29412941            pop87(); 
    29422942 
    29432943            c1 = genfwait(c1); 
    29442944            gen2sib(c1,mf,grex | modregrm(0,rf,4),modregrm(0,4,SP));                   // FISTP [ESP] 
    29452945 
    29462946            retregs = *pretregs & (ALLREGS | mBP); 
    29472947            if (!retregs) 
    29482948                    retregs = ALLREGS; 
    29492949            c2 = allocreg(&retregs,&reg,tym); 
    29502950 
    29512951            c2 = genfwait(c2);                                                          // FWAIT 
    29522952            c2 = genc1(c2,0xD9,grex | modregrm(2,5,4) + 256*modregrm(0,4,SP),FLconst,szoff);   // FLDCW szoff[ESP] 
    29532953 
    29542954            if (szoff > REGSIZE) 
    29552955            {   szpush -= REGSIZE; 
    29562956                c2 = genpop(c2,findreglsw(retregs));       // POP lsw 
  • trunk/src/backend/cgcod.c

    r738 r767  
    10901090            goto L2; 
    10911091 
    10921092        case BC_try: 
    10931093            if (config.flags2 & CFG2seh) 
    10941094            {   usednteh |= NTEH_try; 
    10951095                nteh_usevars(); 
    10961096            } 
    10971097            else 
    10981098                usednteh |= EHtry; 
    10991099            goto case_goto; 
    11001100 
    11011101        case BC_finally: 
    11021102            // Mark all registers as destroyed. This will prevent 
    11031103            // register assignments to variables used in finally blocks. 
    11041104            assert(!getregs(allregs)); 
    11051105            assert(!e); 
    11061106            assert(!bl->Bcode); 
    11071107#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 
    11081108            if (config.flags3 & CFG3pic) 
    11091109            { 
     1110                int nalign = 0; 
    11101111                if (STACKALIGN == 16) 
    1111                 {   c = genc2(c,0x81,modregrm(3,5,SP),12); // SUB ESP,12 
     1112                {   nalign = STACKALIGN - REGSIZE; 
     1113                    c = genc2(c,0x81,modregrm(3,5,SP),nalign); // SUB ESP,nalign 
    11121114                    if (I64) 
    11131115                        code_orrex(c, REX_W); 
    11141116                } 
    11151117                // CALL bl->Bsucc 
    11161118                c = genc(c,0xE8,0,0,0,FLblock,(long)list_block(bl->Bsucc)); 
    1117                 if (STACKALIGN == 16
    1118                 {   c = genc2(c,0x81,modregrm(3,0,SP),12); // ADD ESP,12 
     1119                if (nalign
     1120                {   c = genc2(c,0x81,modregrm(3,0,SP),nalign); // ADD ESP,nalign 
    11191121                    if (I64) 
    11201122                        code_orrex(c, REX_W); 
    11211123                } 
    11221124                // JMP list_next(bl->Bsucc) 
    11231125                nextb = list_block(list_next(bl->Bsucc)); 
    11241126                goto L2; 
    11251127            } 
    11261128            else 
    11271129#endif 
    11281130            { 
    11291131                // Generate a PUSH of the address of the successor to the 
    11301132                // corresponding BC_ret 
    11311133                //assert(list_block(list_next(bl->Bsucc))->BC == BC_ret); 
    11321134                // PUSH &succ 
    11331135                c = genc(c,0x68,0,0,0,FLblock,(long)list_block(list_next(bl->Bsucc))); 
    11341136                nextb = list_block(bl->Bsucc); 
    11351137                goto L2; 
    11361138            } 
    11371139 
    11381140        case BC_ret: 
  • trunk/src/backend/cgelem.c

    r738 r767  
    41374137 
    41384138STATIC elem * elarray(elem *e) 
    41394139{ 
    41404140    return e; 
    41414141} 
    41424142 
    41434143/******************************************** 
    41444144 */ 
    41454145 
    41464146STATIC elem * elfield(elem *e) 
    41474147{ 
    41484148    return e; 
    41494149} 
    41504150 
    41514151/****************************************** 
    41524152 * OPparam 
    41534153 */ 
    41544154 
    41554155STATIC void elparamx(elem *e) 
    41564156{ 
    4157     elem *ex; 
    4158  
    41594157    //printf("elparam()\n"); 
    41604158    if (e->E1->Eoper == OPrpair) 
    41614159    { 
    41624160        e->E1->Eoper = OPparam; 
    41634161    } 
    41644162    else if (e->E1->Eoper == OPpair && !el_sideeffect(e->E1)) 
    41654163    { 
    41664164        e->E1->Eoper = OPparam; 
    4167         ex = e->E1->E2; 
     4165        elem *ex = e->E1->E2; 
    41684166        e->E1->E2 = e->E1->E1; 
    41694167        e->E1->E1 = ex; 
    41704168    } 
    41714169#if 0 
    41724170    // Unfortunately, these don't work because if the last parameter 
    41734171    // is a pair, and it is a D function, the last parameter will get 
    41744172    // passed in EAX. 
    41754173    else if (e->E2->Eoper == OPrpair) 
    41764174    { 
    41774175        e->E2->Eoper = OPparam; 
    41784176    } 
    41794177    else if (e->E2->Eoper == OPpair) 
    41804178    { 
    41814179        e->E2->Eoper = OPparam; 
    4182         ex = e->E2->E2; 
     4180        elem *ex = e->E2->E2; 
    41834181        e->E2->E2 = e->E2->E1; 
    41844182        e->E2->E1 = ex; 
    41854183    } 
    41864184#endif 
    41874185} 
    41884186 
    41894187STATIC elem * elparam(elem *e) 
    41904188{ 
    41914189    if (!OPTIMIZER) 
    41924190    { 
    41934191        if (!I64) 
    41944192            elparamx(e); 
    41954193    } 
    41964194    return e; 
    41974195} 
    41984196 
    41994197/******************************** 
    42004198 * Optimize an element. This routine is recursive! 
    42014199 * Be careful not to do this if VBEs have been done (else the VBE 
    42024200 * work will be undone), or it DAGs have been built (will crash if 
     
    46904688                { 
    46914689                    error(filename, linnum, "null dereference in function %s", funcsym_p->Sident); 
    46924690                    e->E1->EV.Vlong = 4096;     // suppress redundant messages 
    46934691                } 
    46944692#endif 
    46954693            } 
    46964694            e = e->E1; 
    46974695        } 
    46984696        else if (OTbinary(e->Eoper)) 
    46994697        { 
    47004698#if MARS 
    47014699            /* This is necessary as the optimizer tends to lose this information 
    47024700             */ 
    47034701            if (e->Esrcpos.Slinnum > linnum) 
    47044702            {   linnum = e->Esrcpos.Slinnum; 
    47054703                filename = e->Esrcpos.Sfilename; 
    47064704            } 
    47074705#endif 
    47084706            if (e->Eoper == OPparam) 
    47094707            { 
    4710                 elparamx(e); 
     4708                if (!I64) 
     4709                    elparamx(e); 
    47114710            } 
    47124711            postoptelem(e->E2); 
    47134712            e = e->E1; 
    47144713        } 
    47154714        else 
    47164715            break; 
    47174716    } 
    47184717} 
    47194718 
    47204719#endif // !SPP 
  • trunk/src/backend/cod1.c

    r738 r767  
    956956                        {   t = 0; 
    957957                            rbase = 5; 
    958958                        } 
    959959                        else 
    960960                        {   t = 0; 
    961961                            rbase = reg; 
    962962                            if (rbase == BP) 
    963963                            {   static unsigned imm32[4] = {1+1,2+1,4+1,8+1}; 
    964964 
    965965                                // IMUL r,BP,imm32 
    966966                                c = genc2(c,0x69,modregxrm(3,r,BP),imm32[ss1]); 
    967967                                goto L7; 
    968968                            } 
    969969                        } 
    970970 
    971971                        c = gen2sib(c,0x8D,modregxrm(t,r,4),modregrm(ss1,reg & 7,rbase & 7)); 
    972972                        if (reg & 8) 
    973973                            code_orrex(c, REX_X); 
    974974                        if (rbase & 8) 
    975975                            code_orrex(c, REX_B); 
     976                        if (I64) 
     977                            code_orrex(c, REX_W); 
    976978 
    977979                        if (ssflags & SSFLnobase1) 
    978980                        {   code_last(c)->IFL1 = FLconst; 
    979981                            code_last(c)->IEV1.Vuns = 0; 
    980982                        } 
    981983                    L7: 
    982984                        if (ssflags & SSFLnobase) 
    983985                        {   t = stackfl[f] ? 2 : 0; 
    984986                            rbase = 5; 
    985987                        } 
    986988                        else 
    987989                        {   t = 2; 
    988990                            rbase = r; 
    989991                            assert(rbase != BP); 
    990992                        } 
    991993                        pcs->Irm = modregrm(t,0,4); 
    992994                        pcs->Isib = modregrm(ssindex_array[ssi].ss2,r & 7,rbase & 7); 
    993995                        if (r & 8) 
    994996                            code_orrex(pcs, REX_X); 
    995997                        if (rbase & 8) 
     
    10661068                c = cat(c,allocreg(&idxregs,&reg,TYoffset)); 
    10671069 
    10681070                /* If desired result is a far pointer, we'll have       */ 
    10691071                /* to load another register with the segment of v       */ 
    10701072                if (e1ty == TYfptr) 
    10711073                { 
    10721074                    unsigned msreg; 
    10731075 
    10741076                    idxregs |= mMSW & ALLREGS & ~keepmsk; 
    10751077                    c = cat(c,allocreg(&idxregs,&msreg,TYfptr)); 
    10761078                    msreg = findregmsw(idxregs); 
    10771079                                                /* MOV msreg,segreg     */ 
    10781080                    c = genregs(c,0x8C,segfl[f],msreg); 
    10791081                } 
    10801082                opsave = pcs->Iop; 
    10811083                flagsave = pcs->Iflags; 
    10821084                pcs->Iop = 0x8D; 
    10831085                code_newreg(pcs, reg); 
    10841086                if (!I16) 
    10851087                    pcs->Iflags &= ~CFopsize; 
     1088                if (I64) 
     1089                    pcs->Irex |= REX_W; 
    10861090                c = gen(c,pcs);                 /* LEA idxreg,EA        */ 
    10871091                cssave(e1,idxregs,TRUE); 
    10881092                if (!I16) 
    10891093                    pcs->Iflags = flagsave; 
    10901094                if (stackfl[f] && (config.wflags & WFssneds))   // if pointer into stack 
    10911095                    pcs->Iflags |= CFss;        // add SS: override 
    10921096                pcs->Iop = opsave; 
    10931097                pcs->IFL1 = FLoffset; 
    10941098                pcs->IEV1.Vuns = 0; 
    10951099                setaddrmode(pcs, idxregs); 
    10961100            } 
    10971101            freenode(e12); 
    10981102            if (e1free) 
    10991103                freenode(e1); 
    11001104            goto Lptr; 
    11011105        } 
    11021106 
    11031107        L1: 
    11041108 
    11051109        /* The rest of the cases could be a far pointer */ 
     
    28462850            {   unsigned lsreg; 
    28472851             LF1: 
    28482852                reg = findregmsw(retregs); 
    28492853                lsreg = findreglsw(retregs); 
    28502854                floatreg = TRUE;                /* use float register   */ 
    28512855                reflocal = TRUE; 
    28522856                ce = genc1(ce,0x89,             /* MOV floatreg+2,reg   */ 
    28532857                        modregrm(2,reg,BPRM),FLfltreg,REGSIZE); 
    28542858                genc1(ce,0x89,                  /* MOV floatreg,lsreg   */ 
    28552859                        modregrm(2,lsreg,BPRM),FLfltreg,0); 
    28562860                if (tym1 == TYifunc) 
    28572861                    gen1(ce,0x9C);              // PUSHF 
    28582862                genc1(ce,0xFF,                  /* CALL [floatreg]      */ 
    28592863                        modregrm(2,3,BPRM),FLfltreg,0); 
    28602864            } 
    28612865            else 
    28622866            { 
    28632867             LF2: 
    28642868                reg = findreg(retregs); 
    28652869                ce = gen2(ce,0xFF,modregrmx(3,2,reg));   /* CALL reg     */ 
     2870                if (I64) 
     2871                    code_orrex(ce, REX_W); 
    28662872            } 
    28672873        } 
    28682874        else 
    28692875        { 
    28702876            if (tym1 == TYifunc) 
    28712877                c = gen1(c,0x9C);               // PUSHF 
    28722878                                                // CALL [function] 
    28732879            cs.Iflags = 0; 
    28742880            cgstate.stackclean++; 
    28752881            ce = loadea(e11,&cs,0xFF,farfunc ? 3 : 2,0,keepmsk,(ALLREGS|mES|mBP) & ~fregsaved); 
    28762882            cgstate.stackclean--; 
    28772883            freenode(e11); 
    28782884        } 
    28792885        s = NULL; 
    28802886  } 
    28812887  c = cat(c,ce); 
    28822888  freenode(e1); 
    28832889 
    28842890  /* See if we will need the frame pointer. 
    28852891     Calculate it here so we can possibly use BP to fix the stack. 
  • trunk/src/backend/cod2.c

    r738 r767  
    636636                    } 
    637637                } 
    638638                rval = reghasvalue(byte ? BYTEREGS : ALLREGS,i,&rreg); 
    639639                cs.IEV2.Vint = i; 
    640640        L3: 
    641641                op1 ^= byte; 
    642642                cs.Iflags |= word; 
    643643                if (rval) 
    644644                {   cs.Iop = op1 ^ 2; 
    645645                    mode = rreg; 
    646646                } 
    647647                else 
    648648                    cs.Iop = 0x81; 
    649649                cs.Irm = modregrm(3,mode&7,reg&7); 
    650650                if (mode & 8) 
    651651                    cs.Irex |= REX_R; 
    652652                if (reg & 8) 
    653653                    cs.Irex |= REX_B; 
    654654                if (I64 && sz == 8) 
    655655                    cs.Irex |= REX_W; 
     656                if (I64 && byte && reg >= 4) 
     657                    cs.Irex |= REX; 
    656658                cs.IFL2 = (e2->Eoper == OPconst) ? FLconst : el_fl(e2); 
    657659                /* Modify instruction for special cases */ 
    658660                switch (e->Eoper) 
    659661                {   case OPadd: 
    660662                    {   int iop; 
    661663 
    662664                        if (i == 1) 
    663665                            iop = 0;                    /* INC reg      */ 
    664666                        else if (i == -1) 
    665667                            iop = 8;                    /* DEC reg      */ 
    666668                        else 
    667669                            break; 
    668670                        cs.Iop = (0x40 | iop | reg) ^ byte; 
    669671                        if ((byte && *pretregs & mPSW) || I64) 
    670672                        {   cs.Irm = modregrm(3,0,reg & 7) | iop; 
    671673                            cs.Iop = 0xFF; 
    672674                        } 
    673675                        break; 
    674676                    } 
    675677                    case OPand: 
     
    32943296                c2->Iflags = CFopsize; 
    32953297                offset += 2; 
    32963298                c3 = cat(c3,c2); 
    32973299            } 
    32983300            if (numbytes & 1) 
    32993301            {                           // MOV byte ptr offset[reg],vreg 
    33003302                c2 = gen2(CNIL,0x88,modregxrmx(2,vreg,reg)); 
    33013303                c2->IEVoffset1 = offset; 
    33023304                c2->IFL1 = FLconst; 
    33033305                c3 = cat(c3,c2); 
    33043306            } 
    33053307fixres: 
    33063308            return cat3(c1,c3,fixresult(e,retregs1,pretregs)); 
    33073309        } 
    33083310    } 
    33093311 
    33103312    // Get nbytes into CX 
    33113313    retregs2 = mCX; 
    33123314    if (!I16 && e2->E1->Eoper == OPconst && e2->E2->Eoper == OPconst) 
    33133315    { 
    3314         remainder = numbytes & (REGSIZE - 1); 
    3315         numwords  = numbytes / REGSIZE;         // number of words 
     3316        remainder = numbytes & (4 - 1); 
     3317        numwords  = numbytes / 4;               // number of words 
    33163318        op = 0xAB;                              // moving by words 
    33173319        c1 = getregs(mCX); 
    33183320        c1 = movregconst(c1,CX,numwords,I64?64:0);     // # of bytes/words 
    33193321    } 
    33203322    else 
    33213323    { 
    33223324        remainder = 0; 
    33233325        op = 0xAA;                              // must move by bytes 
    33243326        c1 = codelem(e2->E1,&retregs2,FALSE); 
    33253327    } 
    33263328 
    33273329    // Get val into AX 
    33283330 
    33293331    retregs3 = mAX; 
    33303332    if (!I16 && e2->E2->Eoper == OPconst) 
    33313333    { 
    33323334        c1 = regwithvalue(c1, mAX, value, NULL, I64?64:0); 
    33333335        freenode(e2->E2); 
    33343336    } 
    33353337    else 
  • trunk/src/backend/cod3.c

    r760 r767  
    22872287 
    22882288    /* Skip over return address */ 
    22892289    thunkty = tybasic(sthunk->ty()); 
    22902290    if (tyfarfunc(thunkty)) 
    22912291        p += I32 ? 8 : tysize[TYfptr];          /* far function */ 
    22922292    else 
    22932293        p += tysize[TYnptr]; 
    22942294 
    22952295    if (!I16) 
    22962296    { 
    22972297        /* 
    22982298           Generate: 
    22992299            ADD p[ESP],d 
    23002300           For direct call: 
    23012301            JMP sfunc 
    23022302           For virtual call: 
    23032303            MOV EAX, p[ESP]                     EAX = this 
    23042304            MOV EAX, d2[EAX]                    EAX = this->vptr 
    23052305            JMP i[EAX]                          jump to virtual function 
    23062306         */ 
     2307        unsigned reg = 0; 
     2308        if ((targ_ptrdiff_t)d < 0) 
     2309        { 
     2310            d = -d; 
     2311            reg = 5;                            // switch from ADD to SUB 
     2312        } 
    23072313        if (thunkty == TYmfunc) 
    23082314        {                                       // ADD ECX,d 
    23092315            c = CNIL; 
    23102316            if (d) 
    2311                 c = genc2(c,0x81,modregrm(3,0,CX),d); 
     2317                c = genc2(c,0x81,modregrm(3,reg,CX),d); 
    23122318        } 
    23132319        else if (thunkty == TYjfunc) 
    23142320        {                                       // ADD EAX,d 
    23152321            c = CNIL; 
    23162322            if (d) 
    2317                 c = genc2(c,0x81,modregrm(3,0,AX),d); 
     2323                c = genc2(c,0x81,modregrm(3,reg,I64 ? DI : AX),d); 
    23182324        } 
    23192325        else 
    23202326        { 
    2321             c = genc(CNIL,0x81,modregrm(2,0,4), 
     2327            c = genc(CNIL,0x81,modregrm(2,reg,4), 
    23222328                FLconst,p,                      // to this 
    23232329                FLconst,d);                     // ADD p[ESP],d 
    23242330            c->Isib = modregrm(0,4,SP); 
    23252331        } 
    23262332        if (I64) 
    23272333            c->Irex |= REX_W; 
    23282334    } 
    23292335    else 
    23302336    { 
    23312337        /* 
    23322338           Generate: 
    23332339            MOV BX,SP 
    23342340            ADD [SS:] p[BX],d 
    23352341           For direct call: 
    23362342            JMP sfunc 
    23372343           For virtual call: 
    23382344            MOV BX, p[BX]                       BX = this 
    23392345            MOV BX, d2[BX]                      BX = this->vptr 
    23402346            JMP i[BX]                           jump to virtual function 
    23412347         */ 
     
    45524558    case FLfunc:                        /* function call                */ 
    45534559        s = uev->sp.Vsym;               /* symbol pointer               */ 
    45544560#if !TARGET_FLAT 
    45554561        if (tyfarfunc(s->ty())) 
    45564562        {       /* Large code references are always absolute    */ 
    45574563                FLUSH(); 
    45584564                offset += reftoident(cseg,offset,s,0,flags) - 4; 
    45594565        } 
    45604566        else if (s->Sseg == cseg && 
    45614567                 (s->Sclass == SCstatic || s->Sclass == SCglobal) && 
    45624568                 s->Sxtrnnum == 0 && flags & CFselfrel) 
    45634569        {       /* if we know it's relative address     */ 
    45644570                ad = s->Soffset - OFFSET() - 4; 
    45654571                goto L1; 
    45664572        } 
    45674573        else 
    45684574#endif 
    45694575        { 
    45704576                assert(!(TARGET_FLAT && tyfarfunc(s->ty()))); 
    45714577                FLUSH(); 
    4572                 reftoident(cseg,offset,s,0,flags); 
     4578                reftoident(cseg,offset,s,val,flags); 
    45734579        } 
    45744580        break; 
    45754581 
    45764582    case FLblock:                       /* displacement to another block */ 
    45774583        ad = uev->Vblock->Boffset - OFFSET() - 4; 
    45784584        //printf("FLblock: funcoffset = %x, OFFSET = %x, Boffset = %x, ad = %x\n", funcoffset, OFFSET(), uev->Vblock->Boffset, ad); 
    45794585        goto L1; 
    45804586 
    45814587    case FLblockoff: 
    45824588        FLUSH(); 
    45834589        assert(uev->Vblock); 
    45844590        //printf("FLblockoff: offset = %x, Boffset = %x, funcoffset = %x\n", offset, uev->Vblock->Boffset, funcoffset); 
    45854591        reftocodseg(cseg,offset,uev->Vblock->Boffset); 
    45864592        break; 
    45874593 
    45884594    default: 
    45894595#ifdef DEBUG 
    45904596        WRFL(fl); 
    45914597#endif 
    45924598        assert(0); 
  • trunk/src/backend/cod4.c

    r738 r767  
    10061006        cs.Iop = op1 ^ 2;                       // toggle direction bit 
    10071007        if (forccs) 
    10081008            cs.Iflags |= CFpsw; 
    10091009        reverse = 2;                            // remember we toggled it 
    10101010        cl = gen(cl,&cs); 
    10111011        c = cat(cr,cl); 
    10121012        retregs = 0;            /* to trigger a bug if we attempt to use it */ 
    10131013  } 
    10141014  else // evaluate e2 into register 
    10151015  { 
    10161016        retregs = (byte) ? BYTEREGS : ALLREGS;  // pick working reg 
    10171017        if (tyml == TYhptr) 
    10181018            retregs &= ~mCX;                    // need CX for shift count 
    10191019        cr = scodelem(e->E2,&retregs,0,TRUE);   // get rvalue 
    10201020        cl = getlvalue(&cs,e1,retregs);         // get lvalue 
    10211021        cl = cat(cl,modEA(&cs)); 
    10221022        cs.Iop = op1; 
    10231023        if (sz <= REGSIZE || tyfv(tyml)) 
    10241024        {   reg = findreg(retregs); 
    10251025            code_newreg(&cs, reg);              // OP1 EA,reg 
     1026            if (sz == 1 && reg >= 4 && I64) 
     1027                cs.Irex |= REX; 
    10261028        } 
    10271029        else if (tyml == TYhptr) 
    10281030        {   unsigned mreg,lreg; 
    10291031 
    10301032            mreg = findregmsw(retregs); 
    10311033            lreg = findreglsw(retregs); 
    10321034            cl = cat(cl,getregs(retregs | mCX)); 
    10331035 
    10341036            // If h -= l, convert to h += -l 
    10351037            if (e->Eoper == OPminass) 
    10361038            { 
    10371039                cl = gen2(cl,0xF7,modregrm(3,3,mreg));  // NEG mreg 
    10381040                gen2(cl,0xF7,modregrm(3,3,lreg));       // NEG lreg 
    10391041                code_orflag(cl,CFpsw); 
    10401042                genc2(cl,0x81,modregrm(3,3,mreg),0);    // SBB mreg,0 
    10411043            } 
    10421044            cs.Iop = 0x01; 
    10431045            cs.Irm |= modregrm(0,lreg,0); 
    10441046            cl = gen(cl,&cs);                           // ADD EA,lreg 
    10451047            code_orflag(cl,CFpsw); 
  • trunk/src/backend/elfobj.c

    r714 r767  
    27522752                                if (s->Sclass == SCstatic) 
    27532753                                    relinfo = RI_TYPE_TLS_LE;  // TLS_GD? 
    27542754                                else 
    27552755                                    relinfo = RI_TYPE_TLS_IE; 
    27562756                            } 
    27572757                            else 
    27582758                            { 
    27592759                                if (s->Sclass == SCstatic) 
    27602760                                    relinfo = RI_TYPE_TLS_LE; 
    27612761                                else 
    27622762                                    relinfo = RI_TYPE_TLS_IE; 
    27632763                            } 
    27642764                        } 
    27652765                    } 
    27662766                    if (flags & CFoffset64 && relinfo == R_X86_64_32) 
    27672767                    { 
    27682768                        relinfo = R_X86_64_64; 
    27692769                    } 
    27702770                    //printf("\t\t************* adding relocation\n"); 
    27712771                    targ_size_t v = 0; 
    2772                     if (I64 && relinfo == R_X86_64_PC32
     2772                    if (I64 && retsize == 4
    27732773                    { 
    27742774                        assert(retsize == 4); 
    27752775                        if (val > 0xFFFFFFFF) 
    27762776                        {   /* The value to be added is bigger than 32 bits, so we 
    27772777                             * transfer it to the 64 bit addend of the fixup record 
    27782778                             */ 
    27792779                            v = val; 
    27802780                            val = 0; 
    27812781                        } 
    27822782                    } 
    27832783#if 0 
    27842784                    targ_size_t v = (relinfo == R_X86_64_PC32) ? -4 : 0; 
    27852785                    if (relinfo == R_X86_64_PC32 && flags & CFaddend8) 
    27862786                        v = -8; 
    27872787#endif 
    27882788                    elf_addrel(seg,offset,relinfo,refseg,v); 
    27892789                } 
    27902790outaddrval: 
    27912791                if (retsize == 8) 
    27922792                    buf->write64(val); 
     
    29902990        if (I64) 
    29912991            buf->writeByte(REX | REX_W); 
    29922992        buf->writeByte(0x8B); buf->writeByte(0x11); /* movl (%ecx), %edx */ 
    29932993        if (I64) 
    29942994            buf->writeByte(REX | REX_W); 
    29952995        buf->writeByte(0x89); buf->writeByte(0x10); /* movl %edx, (%eax) */ 
    29962996        if (I64) 
    29972997            buf->writeByte(REX | REX_W); 
    29982998        buf->writeByte(0x89); buf->writeByte(0x01); /* movl %eax, (%ecx) */ 
    29992999 
    30003000        if (I32) buf->writeByte(0x61); // POPAD 
    30013001        buf->writeByte(0xC3); /* ret */ 
    30023002        SegData[seg]->SDoffset = buf->size(); 
    30033003    } 
    30043004 
    30053005    /* Add reference to constructor into ".ctors" segment 
    30063006     */ 
    30073007    const int seg = elf_getsegment(".ctors", NULL, SHT_PROGDEF, SHF_ALLOC|SHF_WRITE, NPTRSIZE); 
    30083008 
    30093009    Outbuffer *buf = SegData[seg]->SDbuf; 
    3010     buf->write32(codeOffset); 
     3010    if (I64) 
     3011        buf->write64(codeOffset); 
     3012    else 
     3013        buf->write32(codeOffset); 
    30113014    elf_addrel(seg, SegData[seg]->SDoffset, I64 ? R_X86_64_64 : RI_TYPE_SYM32, STI_TEXT, 0); 
    30123015    SegData[seg]->SDoffset += NPTRSIZE; 
    30133016} 
    30143017 
    30153018#endif 
    30163019 
    30173020/************************************* 
    30183021 */ 
    30193022 
    30203023void elfobj_gotref(symbol *s) 
    30213024{ 
    30223025    //printf("elfobj_gotref(%x '%s', %d)\n",s,s->Sident, s->Sclass); 
    30233026    switch(s->Sclass) 
    30243027    { 
    30253028        case SCstatic: 
    30263029        case SClocstat: 
    30273030            s->Sfl = FLgotoff; 
    30283031            break; 
    30293032 
    30303033        case SCextern: 
  • trunk/src/backend/rtlsym.h

    r738 r767  
    4747SYMBOL_MARS(MONITOR_PROLOG,  FLfunc,FREGSAVED,"_d_monitor_prolog",0,t) \ 
    4848SYMBOL_MARS(MONITOR_EPILOG,  FLfunc,FREGSAVED,"_d_monitor_epilog",0,t) \ 
    4949SYMBOL_MARS(DCOVER,          FLfunc,FREGSAVED,"_d_cover_register", 0, t) \ 
    5050SYMBOL_MARS(DASSERT,         FLfunc,FREGSAVED,"_d_assert", SFLexit, t) \ 
    5151SYMBOL_MARS(DASSERTM,        FLfunc,FREGSAVED,"_d_assertm", SFLexit, t) \ 
    5252SYMBOL_MARS(DASSERT_MSG,     FLfunc,FREGSAVED,"_d_assert_msg", SFLexit, t) \ 
    5353SYMBOL_MARS(DUNITTEST,       FLfunc,FREGSAVED,"_d_unittest", 0, t) \ 
    5454SYMBOL_MARS(DUNITTESTM,      FLfunc,FREGSAVED,"_d_unittestm", 0, t) \ 
    5555SYMBOL_MARS(DUNITTEST_MSG,   FLfunc,FREGSAVED,"_d_unittest_msg", 0, t) \ 
    5656SYMBOL_MARS(DARRAY,          FLfunc,FREGSAVED,"_d_array_bounds", SFLexit, t) \ 
    5757SYMBOL_MARS(DINVARIANT,      FLfunc,FREGSAVED,"D9invariant12_d_invariantFC6ObjectZv", 0, tsdlib) \ 
    5858SYMBOL_MARS(_DINVARIANT,     FLfunc,FREGSAVED,"_D9invariant12_d_invariantFC6ObjectZv", 0, tsdlib) \ 
    5959SYMBOL_MARS(MEMCPY,          FLfunc,FREGSAVED,"memcpy",    0, t) \ 
    6060SYMBOL_MARS(MEMSET8,         FLfunc,FREGSAVED,"memset",    0, t) \ 
    6161SYMBOL_MARS(MEMSET16,        FLfunc,FREGSAVED,"_memset16", 0, t) \ 
    6262SYMBOL_MARS(MEMSET32,        FLfunc,FREGSAVED,"_memset32", 0, t) \ 
    6363SYMBOL_MARS(MEMSET64,        FLfunc,FREGSAVED,"_memset64", 0, t) \ 
    6464SYMBOL_MARS(MEMSET128,       FLfunc,FREGSAVED,"_memset128",0, t) \ 
    6565SYMBOL_MARS(MEMSET80,        FLfunc,FREGSAVED,"_memset80", 0, t) \ 
    6666SYMBOL_MARS(MEMSET160,       FLfunc,FREGSAVED,"_memset160",0, t) \ 
     67SYMBOL_MARS(MEMSETFLOAT,     FLfunc,FREGSAVED,"_memsetFloat", 0, t) \ 
     68SYMBOL_MARS(MEMSETDOUBLE,    FLfunc,FREGSAVED,"_memsetDouble", 0, t) \ 
    6769SYMBOL_MARS(MEMSETN,         FLfunc,FREGSAVED,"_memsetn",  0, t) \ 
    6870SYMBOL_MARS(MODULO,          FLfunc,FREGSAVED,"_modulo",   0, t) \ 
    6971SYMBOL_MARS(MONITORENTER,  FLfunc,FREGSAVED,"_d_monitorenter",0, t) \ 
    7072SYMBOL_MARS(MONITOREXIT,   FLfunc,FREGSAVED,"_d_monitorexit",0, t) \ 
    7173SYMBOL_MARS(CRITICALENTER, FLfunc,FREGSAVED,"_d_criticalenter",0, t) \ 
    7274SYMBOL_MARS(CRITICALEXIT,  FLfunc,FREGSAVED,"_d_criticalexit",0, t) \ 
    7375SYMBOL_MARS(SWITCH_STRING, FLfunc,FREGSAVED,"_d_switch_string", 0, t) \ 
    7476SYMBOL_MARS(SWITCH_USTRING,FLfunc,FREGSAVED,"_d_switch_ustring", 0, t) \ 
    7577SYMBOL_MARS(SWITCH_DSTRING,FLfunc,FREGSAVED,"_d_switch_dstring", 0, t) \ 
    7678SYMBOL_MARS(DSWITCHERR,    FLfunc,FREGSAVED,"_d_switch_error", SFLexit, t) \ 
    7779SYMBOL_MARS(DHIDDENFUNC,   FLfunc,FREGSAVED,"_d_hidden_func", 0, t) \ 
    7880SYMBOL_MARS(NEWCLASS,      FLfunc,FREGSAVED,"_d_newclass", 0, t) \ 
    7981SYMBOL_MARS(NEWARRAYT,     FLfunc,FREGSAVED,"_d_newarrayT", 0, t) \ 
    8082SYMBOL_MARS(NEWARRAYIT,    FLfunc,FREGSAVED,"_d_newarrayiT", 0, t) \ 
    8183SYMBOL_MARS(NEWARRAYMT,    FLfunc,FREGSAVED,"_d_newarraymT", 0, tv) \ 
    8284SYMBOL_MARS(NEWARRAYMIT,   FLfunc,FREGSAVED,"_d_newarraymiT", 0, tv) \ 
    8385SYMBOL_MARS(ARRAYLITERALT, FLfunc,FREGSAVED,"_d_arrayliteralT", 0, tv) \ 
    8486SYMBOL_MARS(ASSOCARRAYLITERALT, FLfunc,FREGSAVED,"_d_assocarrayliteralT", 0, tv) \ 
    8587SYMBOL_MARS(ASSOCARRAYLITERALTX, FLfunc,FREGSAVED,"_d_assocarrayliteralTX", 0, t) \ 
    8688SYMBOL_MARS(CALLFINALIZER, FLfunc,FREGSAVED,"_d_callfinalizer", 0, t) \ 
  • trunk/src/cast.c

    r562 r767  
    19221922 
    19231923int arrayTypeCompatible(Loc loc, Type *t1, Type *t2) 
    19241924{ 
    19251925    t1 = t1->toBasetype(); 
    19261926    t2 = t2->toBasetype(); 
    19271927 
    19281928    if ((t1->ty == Tarray || t1->ty == Tsarray || t1->ty == Tpointer) && 
    19291929        (t2->ty == Tarray || t2->ty == Tsarray || t2->ty == Tpointer)) 
    19301930    { 
    19311931        if (t1->nextOf()->implicitConvTo(t2->nextOf()) < MATCHconst && 
    19321932            t2->nextOf()->implicitConvTo(t1->nextOf()) < MATCHconst && 
    19331933            (t1->nextOf()->ty != Tvoid && t2->nextOf()->ty != Tvoid)) 
    19341934        { 
    19351935            error(loc, "array equality comparison type mismatch, %s vs %s", t1->toChars(), t2->toChars()); 
    19361936        } 
    19371937        return 1; 
    19381938    } 
    19391939    return 0; 
    19401940} 
    19411941 
     1942/*********************************** 
     1943 * See if both types are arrays that can be compared 
     1944 * for equality without any casting. Return !=0 if so. 
     1945 * This is to enable comparing things like an immutable 
     1946 * array with a mutable one. 
     1947 */ 
     1948int arrayTypeCompatibleWithoutCasting(Loc loc, Type *t1, Type *t2) 
     1949{ 
     1950    t1 = t1->toBasetype(); 
     1951    t2 = t2->toBasetype(); 
     1952 
     1953    if ((t1->ty == Tarray || t1->ty == Tsarray || t1->ty == Tpointer) && 
     1954        t2->ty == t1->ty) 
     1955    { 
     1956        if (t1->nextOf()->implicitConvTo(t2->nextOf()) >= MATCHconst || 
     1957            t2->nextOf()->implicitConvTo(t1->nextOf()) >= MATCHconst) 
     1958            return 1; 
     1959    } 
     1960    return 0; 
     1961} 
     1962 
     1963 
    19421964/******************************************************************/ 
    19431965 
    19441966/* Determine the integral ranges of an expression. 
    19451967 * This is used to determine if implicit narrowing conversions will 
    19461968 * be allowed. 
    19471969 */ 
    19481970 
    19491971uinteger_t getMask(uinteger_t v) 
    19501972{ 
    19511973    uinteger_t u = 0; 
    19521974    if (v >= 0x80) 
    19531975        u = 0xFF; 
    19541976    while (u < v) 
    19551977        u = (u << 1) | 1; 
    19561978    return u; 
    19571979} 
    19581980 
    19591981IntRange Expression::getIntRange() 
    19601982{ 
    19611983    IntRange ir; 
  • trunk/src/e2ir.c

    r738 r767  
    566566            return sd; 
    567567    } 
    568568    return NULL; 
    569569} 
    570570 
    571571/******************************************* 
    572572 * Set an array pointed to by eptr to evalue: 
    573573 *      eptr[0..edim] = evalue; 
    574574 * Input: 
    575575 *      eptr    where to write the data to 
    576576 *      evalue  value to write 
    577577 *      edim    number of times to write evalue to eptr[] 
    578578 *      tb      type of evalue 
    579579 */ 
    580580 
    581581elem *setArray(elem *eptr, elem *edim, Type *tb, elem *evalue, IRState *irs, int op) 
    582582{   int r; 
    583583    elem *e; 
    584584    int sz = tb->size(); 
    585585 
    586     if (tb->ty == Tfloat80 || tb->ty == Timaginary80) 
    587         r = RTLSYM_MEMSET80; 
    588     else if (tb->ty == Tcomplex80) 
    589         r = RTLSYM_MEMSET160; 
    590     else if (tb->ty == Tcomplex64) 
    591         r = RTLSYM_MEMSET128; 
    592     else 
    593     { 
    594         switch (sz) 
    595         { 
    596             case 1:      r = RTLSYM_MEMSET8;    break; 
    597             case 2:      r = RTLSYM_MEMSET16;   break; 
    598             case 4:      r = RTLSYM_MEMSET32;   break; 
    599             case 8:      r = RTLSYM_MEMSET64;   break; 
    600             case 16:     r = RTLSYM_MEMSET128;  break; 
    601             default:     r = RTLSYM_MEMSETN;    break; 
    602         } 
    603  
    604         /* Determine if we need to do postblit 
    605          */ 
    606         if (op != TOKblit) 
    607         { 
    608             StructDeclaration *sd = needsPostblit(tb); 
    609             if (sd) 
    610             {   /* Need to do postblit. 
    611                  *   void *_d_arraysetassign(void *p, void *value, int dim, TypeInfo ti); 
    612                  */ 
    613                 r = (op == TOKconstruct) ? RTLSYM_ARRAYSETCTOR : RTLSYM_ARRAYSETASSIGN; 
     586    switch (tb->ty) 
     587    { 
     588        case Tfloat80: 
     589        case Timaginary80: 
     590            r = RTLSYM_MEMSET80; 
     591            break; 
     592        case Tcomplex80: 
     593            r = RTLSYM_MEMSET160; 
     594            break; 
     595        case Tcomplex64: 
     596            r = RTLSYM_MEMSET128; 
     597            break; 
     598        case Tfloat32: 
     599        case Timaginary32: 
     600            if (I32) 
     601                goto Ldefault;          // legacy binary compatibility 
     602            r = RTLSYM_MEMSETFLOAT; 
     603            break; 
     604        case Tfloat64: 
     605        case Timaginary64: 
     606            if (I32) 
     607                goto Ldefault;          // legacy binary compatibility 
     608            r = RTLSYM_MEMSETDOUBLE; 
     609            break; 
     610 
     611        default: 
     612        Ldefault: 
     613            switch (sz) 
     614            { 
     615                case 1:      r = RTLSYM_MEMSET8;    break; 
     616                case 2:      r = RTLSYM_MEMSET16;   break; 
     617                case 4:      r = RTLSYM_MEMSET32;   break; 
     618                case 8:      r = RTLSYM_MEMSET64;   break; 
     619                case 16:     r = RTLSYM_MEMSET128;  break; 
     620                default:     r = RTLSYM_MEMSETN;    break; 
     621            } 
     622 
     623            /* Determine if we need to do postblit 
     624             */ 
     625            if (op != TOKblit) 
     626            { 
     627                StructDeclaration *sd = needsPostblit(tb); 
     628                if (sd) 
     629                {   /* Need to do postblit. 
     630                     *   void *_d_arraysetassign(void *p, void *value, int dim, TypeInfo ti); 
     631                     */ 
     632                    r = (op == TOKconstruct) ? RTLSYM_ARRAYSETCTOR : RTLSYM_ARRAYSETASSIGN; 
     633                    evalue = el_una(OPaddr, TYnptr, evalue); 
     634                    Expression *ti = tb->getTypeInfo(NULL); 
     635                    elem *eti = ti->toElem(irs); 
     636                    e = el_params(eti, edim, evalue, eptr, NULL); 
     637                    e = el_bin(OPcall,TYnptr,el_var(rtlsym[r]),e); 
     638                    return e; 
     639                } 
     640            } 
     641 
     642            if (r == RTLSYM_MEMSETN) 
     643            { 
     644                // void *_memsetn(void *p, void *value, int dim, int sizelem) 
    614645                evalue = el_una(OPaddr, TYnptr, evalue); 
    615                 Expression *ti = tb->getTypeInfo(NULL); 
    616                 elem *eti = ti->toElem(irs); 
    617                 e = el_params(eti, edim, evalue, eptr, NULL); 
     646                elem *esz = el_long(TYsize_t, sz); 
     647                e = el_params(esz, edim, evalue, eptr, NULL); 
    618648                e = el_bin(OPcall,TYnptr,el_var(rtlsym[r]),e); 
    619649                return e; 
    620650            } 
    621         } 
    622  
    623         if (r == RTLSYM_MEMSETN) 
    624         { 
    625             // void *_memsetn(void *p, void *value, int dim, int sizelem) 
    626             evalue = el_una(OPaddr, TYnptr, evalue); 
    627             elem *esz = el_long(TYsize_t, sz); 
    628             e = el_params(esz, edim, evalue, eptr, NULL); 
    629             e = el_bin(OPcall,TYnptr,el_var(rtlsym[r]),e); 
    630             return e; 
    631         } 
     651            break; 
    632652    } 
    633653    if (sz > 1 && sz <= 8 && 
    634654        evalue->Eoper == OPconst && el_allbits(evalue, 0)) 
    635655    { 
    636656        r = RTLSYM_MEMSET8; 
    637657        edim = el_bin(OPmul, TYsize_t, edim, el_long(TYsize_t, sz)); 
    638658    } 
    639659 
    640660    if (tybasic(evalue->Ety) == TYstruct || tybasic(evalue->Ety) == TYarray) 
    641661    { 
    642662        evalue = el_una(OPstrpar, TYstruct, evalue); 
    643663        evalue->ET = evalue->E1->ET; 
    644664    } 
    645665 
    646666    // Be careful about parameter side effect ordering 
    647667    if (r == RTLSYM_MEMSET8) 
    648668    { 
    649669        e = el_param(edim, evalue); 
    650670        e = el_bin(OPmemset,TYnptr,eptr,e); 
    651671    } 
  • trunk/src/expression.c

    r755 r767  
    85608560            TypeSArray *tsa = (TypeSArray *)t1; 
    85618561 
    85628562#if 0   // Don't do now, because it might be short-circuit evaluated 
    85638563            // Do compile time array bounds checking if possible 
    85648564            e2 = e2->optimize(WANTvalue); 
    85658565            if (e2->op == TOKint64) 
    85668566            { 
    85678567                dinteger_t index = e2->toInteger(); 
    85688568                dinteger_t length = tsa->dim->toInteger(); 
    85698569                if (index < 0 || index >= length) 
    85708570                    error("array index [%lld] is outside array bounds [0 .. %lld]", 
    85718571                            index, length); 
    85728572            } 
    85738573#endif 
    85748574            e->type = t1->nextOf(); 
    85758575            break; 
    85768576        } 
    85778577 
    85788578        case Taarray: 
    85798579        {   TypeAArray *taa = (TypeAArray *)t1; 
     8580            /* We can skip the implicit conversion if they differ only by 
     8581             * constness (Bugzilla 2684, see also bug 2954b) 
     8582             */ 
    85808583            if (!arrayTypeCompatible(e2->loc, e2->type, taa->index)) 
    85818584            { 
    85828585                e2 = e2->implicitCastTo(sc, taa->index);        // type checking 
    85838586            } 
    85848587            type = taa->next; 
    85858588            break; 
    85868589        } 
    85878590 
    85888591        case Ttuple: 
    85898592        { 
    85908593            e2 = e2->implicitCastTo(sc, Type::tsize_t); 
    85918594            e2 = e2->optimize(WANTvalue | WANTinterpret); 
    85928595            uinteger_t index = e2->toUInteger(); 
    85938596            size_t length; 
    85948597            TupleExp *te; 
    85958598            TypeTuple *tup; 
    85968599 
    85978600            if (e1->op == TOKtuple) 
    85988601            {   te = (TupleExp *)e1; 
    85998602                length = te->exps->dim; 
  • trunk/src/imphint.c

    r484 r767  
    11 
    22 
    33// Compiler implementation of the D programming language 
    44// Copyright (c) 2010 by Digital Mars 
    55// All Rights Reserved 
    66// written by Walter Bright 
    77// http://www.digitalmars.com 
    88// License for redistribution is by either the Artistic License 
    99// in artistic.txt, or the GNU General Public License in gnu.txt. 
    1010// See the included readme.txt for details. 
    1111 
    1212#include <stdio.h> 
    1313#include <stdlib.h> 
    1414#include <ctype.h> 
    1515#include <assert.h> 
    1616#include <string.h> 
    1717 
     18#include "mars.h" 
     19 
    1820/****************************************** 
    1921 * Looks for undefined identifier s to see 
    2022 * if it might be undefined because an import 
    2123 * was not specified. 
    2224 * Not meant to be a comprehensive list of names in each module, 
    2325 * just the most common ones. 
    2426 */ 
    2527 
    2628const char *importHint(const char *s) 
    2729{ 
    2830#if DMDV1 
    2931    static const char *modules[] = 
    3032    {   "std.c.stdio", 
    3133        "std.stdio", 
    3234        "std.math", 
     35        "std.c.stdarg", 
    3336    }; 
    3437    static const char *names[] = 
    3538    { 
    3639        "printf", NULL, 
    3740        "writefln", NULL, 
    3841        "sin", "cos", "sqrt", "fabs", NULL, 
     42        "__va_argsave_t", NULL, 
    3943    }; 
    4044#else 
    4145    static const char *modules[] = 
    4246    {   "core.stdc.stdio", 
    4347        "std.stdio", 
    4448        "std.math", 
     49        "std.c.stdarg", 
    4550    }; 
    4651    static const char *names[] = 
    4752    { 
    4853        "printf", NULL, 
    4954        "writeln", NULL, 
    5055        "sin", "cos", "sqrt", "fabs", NULL, 
     56        "__va_argsave_t", NULL, 
    5157    }; 
    5258#endif 
    5359    int m = 0; 
    5460    for (int n = 0; n < sizeof(names)/sizeof(names[0]); n++) 
    5561    { 
    5662        const char *p = names[n]; 
    5763        if (p == NULL) 
    5864        {   m++; 
    5965            continue; 
    6066        } 
    6167        assert(m < sizeof(modules)/sizeof(modules[0])); 
    6268        if (strcmp(s, p) == 0) 
    6369            return modules[m]; 
    6470    } 
    6571    return NULL;        // didn't find it 
    6672} 
    6773 
    6874#if UNITTEST 
    6975 
    7076void unittest_importHint() 
  • trunk/src/mtype.c

    r755 r767  
    56725672                        if (!scx) 
    56735673                        {   error(loc, "forward reference to '%s'", t->toChars()); 
    56745674                            return; 
    56755675                        } 
    56765676                        if (scx->scopesym == scopesym) 
    56775677                        { 
    56785678                            t = t->semantic(loc, scx); 
    56795679                            break; 
    56805680                        } 
    56815681                    } 
    56825682                } 
    56835683            } 
    56845684        } 
    56855685        if (t->ty == Ttuple) 
    56865686            *pt = t; 
    56875687        else 
    56885688            *pt = t->merge(); 
    56895689    } 
    56905690    if (!s) 
    56915691    { 
    5692         error(loc, "identifier '%s' is not defined", toChars()); 
     5692        const char *p = toChars(); 
     5693        const char *n = importHint(p); 
     5694        if (n) 
     5695            error(loc, "'%s' is not defined, perhaps you need to import %s; ?", p, n); 
     5696        else 
     5697        { 
     5698            Identifier *id = new Identifier(p, TOKidentifier); 
     5699            s = sc->search_correct(id); 
     5700            if (s) 
     5701                error(loc, "undefined identifier %s, did you mean %s %s?", p, s->kind(), s->toChars()); 
     5702            else 
     5703                error(loc, "undefined identifier %s", p); 
     5704        } 
    56935705    } 
    56945706} 
    56955707 
    56965708/***************************** TypeIdentifier *****************************/ 
    56975709 
    56985710TypeIdentifier::TypeIdentifier(Loc loc, Identifier *ident) 
    56995711    : TypeQualified(Tident, loc) 
    57005712{ 
    57015713    this->ident = ident; 
    57025714} 
    57035715 
    57045716 
    57055717Type *TypeIdentifier::syntaxCopy() 
    57065718{ 
    57075719    TypeIdentifier *t; 
    57085720 
    57095721    t = new TypeIdentifier(loc, ident); 
    57105722    t->syntaxCopyHelper(this); 
    57115723    t->mod = mod; 
    57125724    return t; 
  • trunk/src/mtype.h

    r734 r767  
    892892    Parameter *syntaxCopy(); 
    893893    Type *isLazyArray(); 
    894894    void toDecoBuffer(OutBuffer *buf); 
    895895    static Parameters *arraySyntaxCopy(Parameters *args); 
    896896    static char *argsTypesToChars(Parameters *args, int varargs); 
    897897    static void argsCppMangle(OutBuffer *buf, CppMangleState *cms, Parameters *arguments, int varargs); 
    898898    static void argsToCBuffer(OutBuffer *buf, HdrGenState *hgs, Parameters *arguments, int varargs); 
    899899    static void argsToDecoBuffer(OutBuffer *buf, Parameters *arguments); 
    900900    static int isTPL(Parameters *arguments); 
    901901    static size_t dim(Parameters *arguments); 
    902902    static Parameter *getNth(Parameters *arguments, size_t nth, size_t *pn = NULL); 
    903903}; 
    904904 
    905905extern int PTRSIZE; 
    906906extern int REALSIZE; 
    907907extern int REALPAD; 
    908908extern int Tsize_t; 
    909909extern int Tptrdiff_t; 
    910910 
    911911int arrayTypeCompatible(Loc loc, Type *t1, Type *t2); 
     912int arrayTypeCompatibleWithoutCasting(Loc loc, Type *t1, Type *t2); 
    912913void MODtoBuffer(OutBuffer *buf, unsigned char mod); 
    913914int MODimplicitConv(unsigned char modfrom, unsigned char modto); 
    914915int MODmerge(unsigned char mod1, unsigned char mod2); 
    915916 
    916917#endif /* DMD_MTYPE_H */ 
  • trunk/src/toir.c

    r728 r767  
    11 
    22// Compiler implementation of the D programming language 
    3 // Copyright (c) 1999-2009 by Digital Mars 
     3// Copyright (c) 1999-2010 by Digital Mars 
    44// All Rights Reserved 
    55// written by Walter Bright 
    66// http://www.digitalmars.com 
    77// License for redistribution is by either the Artistic License 
    88// in artistic.txt, or the GNU General Public License in gnu.txt. 
    99// See the included readme.txt for details. 
    1010 
    1111/* Code to help convert to the intermediate representation 
    1212 * of the compiler back end. 
    1313 */ 
    1414 
    1515#include        <stdio.h> 
    1616#include        <string.h> 
    1717#include        <time.h> 
    1818#include        <complex.h> 
    1919 
    2020#include        "lexer.h" 
    2121#include        "expression.h" 
    2222#include        "mtype.h" 
    2323#include        "dsymbol.h" 
     
    194194                     * function must be a member function of that aggregate. 
    195195                     */ 
    196196                    ClassDeclaration *cd; 
    197197                    StructDeclaration *sd; 
    198198                    AggregateDeclaration *ad = s->isAggregateDeclaration(); 
    199199                    if (!ad) 
    200200                        goto Lnoframe; 
    201201                    cd = s->isClassDeclaration(); 
    202202                    if (cd && fd->isClassDeclaration() && 
    203203                        fd->isClassDeclaration()->isBaseOf(cd, NULL)) 
    204204                        break; 
    205205                    sd = s->isStructDeclaration(); 
    206206                    if (fd == sd) 
    207207                        break; 
    208208                    if (!ad->isNested() || !ad->vthis) 
    209209                    { 
    210210                      Lnoframe: 
    211211                        irs->getFunc()->error(loc, "cannot get frame pointer to %s", fd->toChars()); 
    212212                        return el_long(TYnptr, 0);      // error recovery 
    213213                    } 
    214                     ethis = el_bin(OPadd, TYnptr, ethis, el_long(TYint, ad->vthis->offset)); 
     214                    ethis = el_bin(OPadd, TYnptr, ethis, el_long(TYsize_t, ad->vthis->offset)); 
    215215                    ethis = el_una(OPind, TYnptr, ethis); 
    216216                    if (fdparent == s->toParent2()) 
    217217                        break; 
    218218                    if (fd == s->toParent2()) 
    219219                    { 
    220220                        /* Remember that frames for functions that have no 
    221221                         * nested references are skipped in the linked list 
    222222                         * of frames. 
    223223                         */ 
    224224#if DMDV2 
    225225                        if (s->toParent2()->isFuncDeclaration()->closureVars.dim) 
    226226#else 
    227227                        if (s->toParent2()->isFuncDeclaration()->nestedFrameRef) 
    228228#endif 
    229229                            ethis = el_una(OPind, TYnptr, ethis); 
    230230                        break; 
    231231                    } 
    232232                    if (s->toParent2()->isFuncDeclaration()) 
    233233                    { 
    234234                        /* Remember that frames for functions that have no 
     
    306306        } 
    307307    } 
    308308    else if (thisfd->vthis && 
    309309          (cdp == thisfd->toParent2() || 
    310310           (cdp->isClassDeclaration() && 
    311311            cdp->isClassDeclaration()->isBaseOf(thisfd->toParent2()->isClassDeclaration(), &offset) 
    312312           ) 
    313313          ) 
    314314        ) 
    315315    {   /* Class we're new'ing is at the same level as thisfd 
    316316         */ 
    317317        assert(offset == 0);    // BUG: should handle this case 
    318318        ethis = el_var(irs->sthis); 
    319319    } 
    320320    else 
    321321    { 
    322322        ethis = getEthis(loc, irs, ad->toParent2()); 
    323323        ethis = el_una(OPaddr, TYnptr, ethis); 
    324324    } 
    325325 
    326     ey = el_bin(OPadd, TYnptr, ey, el_long(TYint, ad->vthis->offset)); 
     326    ey = el_bin(OPadd, TYnptr, ey, el_long(TYsize_t, ad->vthis->offset)); 
    327327    ey = el_una(OPind, TYnptr, ey); 
    328328    ey = el_bin(OPeq, TYnptr, ey, ethis); 
    329329    return ey; 
    330330} 
    331331#endif 
    332332 
    333333/******************************************* 
    334334 * Convert intrinsic function to operator. 
    335335 * Returns that operator, -1 if not an intrinsic function. 
    336336 */ 
    337337 
    338338int intrinsic_op(char *name) 
    339339{ 
    340340    //printf("intrinsic_op(%s)\n", name); 
    341341    static const char *namearray[] = 
    342342    { 
    343343#if DMDV1 
    344344        "4math3cosFeZe", 
    345345        "4math3sinFeZe", 
    346346        "4math4fabsFeZe", 
     
    395395        "9intrinsic5bswapFNaNbkZk", 
    396396        "9intrinsic5outplFNbkkZk", 
    397397        "9intrinsic5outpwFNbktZt", 
    398398#endif 
    399399    }; 
    400400    static const char *namearray64[] = 
    401401    { 
    402402#if DMDV1 
    403403        "4math3cosFeZe", 
    404404        "4math3sinFeZe", 
    405405        "4math4fabsFeZe", 
    406406        "4math4rintFeZe", 
    407407        "4math4sqrtFdZd", 
    408408        "4math4sqrtFeZe", 
    409409        "4math4sqrtFfZf", 
    410410        "4math4yl2xFeeZe", 
    411411        "4math5ldexpFeiZe", 
    412412        "4math6rndtolFeZl", 
    413413        "4math6yl2xp1FeeZe", 
    414414 
    415         "9intrinsic2btFPkkZi", 
     415        "9intrinsic2btFPmmZi", 
    416416        "9intrinsic3bsfFkZi", 
    417417        "9intrinsic3bsrFkZi", 
    418418        "9intrinsic3btcFPmmZi", 
    419419        "9intrinsic3btrFPmmZi", 
    420420        "9intrinsic3btsFPmmZi", 
    421421        "9intrinsic3inpFkZh", 
    422422        "9intrinsic4inplFkZk", 
    423423        "9intrinsic4inpwFkZt", 
    424424        "9intrinsic4outpFkhZh", 
    425425        "9intrinsic5bswapFkZk", 
    426426        "9intrinsic5outplFkkZk", 
    427427        "9intrinsic5outpwFktZt", 
    428428#elif DMDV2 
    429429        /* The names are mangled differently because of the pure and 
    430430         * nothrow attributes. 
    431431         */ 
    432432        "4math3cosFNaNbNfeZe", 
    433433        "4math3sinFNaNbNfeZe", 
    434434        "4math4fabsFNaNbNfeZe", 
    435435        "4math4rintFNaNbNfeZe", 
     
    527527 *      t1      Type of the array 
    528528 * Output: 
    529529 *      e       is rewritten to avoid side effects 
    530530 * Returns: 
    531531 *      expression that initializes 'length' 
    532532 */ 
    533533 
    534534elem *resolveLengthVar(VarDeclaration *lengthVar, elem **pe, Type *t1) 
    535535{ 
    536536    //printf("resolveLengthVar()\n"); 
    537537    elem *einit = NULL; 
    538538 
    539539    if (lengthVar && !(lengthVar->storage_class & STCconst)) 
    540540    {   elem *elength; 
    541541        Symbol *slength; 
    542542 
    543543        if (t1->ty == Tsarray) 
    544544        {   TypeSArray *tsa = (TypeSArray *)t1; 
    545545            dinteger_t length = tsa->dim->toInteger(); 
    546546 
    547             elength = el_long(TYuint, length); 
     547            elength = el_long(TYsize_t, length); 
    548548            goto L3; 
    549549        } 
    550550        else if (t1->ty == Tarray) 
    551551        { 
    552552            elength = *pe; 
    553553            *pe = el_same(&elength); 
    554             elength = el_una(OP64_32, TYuint, elength); 
     554            elength = el_una(I64 ? OP128_64 : OP64_32, TYsize_t, elength); 
    555555 
    556556        L3: 
    557557            slength = lengthVar->toSymbol(); 
    558558            //symbol_add(slength); 
    559559 
    560             einit = el_bin(OPeq, TYuint, el_var(slength), elength); 
     560            einit = el_bin(OPeq, TYsize_t, el_var(slength), elength); 
    561561        } 
    562562    } 
    563563    return einit; 
    564564} 
    565565 
    566566/************************************* 
    567567 * Closures are implemented by taking the local variables that 
    568568 * need to survive the scope of the function, and copying them 
    569569 * into a gc allocated chuck of memory. That chunk, called the 
    570570 * closure here, is inserted into the linked list of stack 
    571571 * frames instead of the usual stack frame. 
    572572 * 
    573573 * buildClosure() inserts code just after the function prolog 
    574574 * is complete. It allocates memory for the closure, allocates 
    575575 * a local variable (sclosure) to point to it, inserts into it 
    576576 * the link to the enclosing frame, and copies into it the parameters 
    577577 * that are referred to in nested functions. 
    578578 * In VarExp::toElem and SymOffExp::toElem, when referring to a 
    579579 * variable that is in a closure, takes the offset from sclosure rather 
    580580 * than from the frame pointer. 
     
    657657                memsize = v->type->size(); 
    658658                memalignsize = v->type->alignsize(); 
    659659                xalign = v->type->memalign(global.structalign); 
    660660            } 
    661661            AggregateDeclaration::alignmember(xalign, memalignsize, &offset); 
    662662            v->offset = offset; 
    663663            offset += memsize; 
    664664 
    665665            /* Can't do nrvo if the variable is put in a closure, since 
    666666             * what the shidden points to may no longer exist. 
    667667             */ 
    668668            if (nrvo_can && nrvo_var == v) 
    669669            { 
    670670                nrvo_can = 0; 
    671671            } 
    672672        } 
    673673        // offset is now the size of the closure 
    674674 
    675675        // Allocate memory for the closure 
    676676        elem *e; 
    677         e = el_long(TYint, offset); 
     677        e = el_long(TYsize_t, offset); 
    678678        e = el_bin(OPcall, TYnptr, el_var(rtlsym[RTLSYM_ALLOCMEMORY]), e); 
    679679 
    680680        // Assign block of memory to sclosure 
    681681        //    sclosure = allocmemory(sz); 
    682682        e = el_bin(OPeq, TYvoid, el_var(sclosure), e); 
    683683 
    684684        // Set the first element to sthis 
    685685        //    *(sclosure + 0) = sthis; 
    686686        elem *ethis; 
    687687        if (irs->sthis) 
    688688            ethis = el_var(irs->sthis); 
    689689        else 
    690690            ethis = el_long(TYnptr, 0); 
    691691        elem *ex = el_una(OPind, TYnptr, el_var(sclosure)); 
    692692        ex = el_bin(OPeq, TYnptr, ex, ethis); 
    693693        e = el_combine(e, ex); 
    694694 
    695695        // Copy function parameters into closure 
    696696        for (int i = 0; i < closureVars.dim; i++) 
    697697        {   VarDeclaration *v = (VarDeclaration *)closureVars.data[i]; 
    698698 
    699699            if (!v->isParameter()) 
    700700                continue; 
    701701            tym_t tym = v->type->totym(); 
    702702            if ( 
    703703#if !SARRAYVALUE 
    704704                v->type->toBasetype()->ty == Tsarray || 
    705705#endif 
    706706                v->isOut() || v->isRef()) 
    707707                tym = TYnptr;   // reference parameters are just pointers 
    708708#if DMDV2 
    709709            else if (v->storage_class & STClazy) 
    710710                tym = TYdelegate; 
    711711#endif 
    712             ex = el_bin(OPadd, TYnptr, el_var(sclosure), el_long(TYint, v->offset)); 
     712            ex = el_bin(OPadd, TYnptr, el_var(sclosure), el_long(TYsize_t, v->offset)); 
    713713            ex = el_una(OPind, tym, ex); 
    714714            if (tybasic(ex->Ety) == TYstruct || tybasic(ex->Ety) == TYarray) 
    715715            { 
    716716                ::type *t = v->type->toCtype(); 
    717717                ex->ET = t; 
    718718                ex = el_bin(OPstreq, tym, ex, el_var(v->toSymbol())); 
    719719                ex->ET = t; 
    720720            } 
    721721            else 
    722722                ex = el_bin(OPeq, tym, ex, el_var(v->toSymbol())); 
    723723 
    724724            e = el_combine(e, ex); 
    725725        } 
    726726 
    727727        block_appendexp(irs->blx->curblock, e); 
    728728    } 
    729729} 
    730730 
    731731#endif 
    732732