Changeset 579

Show
Ignore:
Timestamp:
07/17/10 05:30:24 (2 years ago)
Author:
walter
Message:

hello world now works for 64

Files:

Legend:

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

    r577 r579  
    140140        BYTEREGS = value; 
    141141    } 
     142    if (I64) 
     143        ALLREGS = mAX|mBX|mCX|mDX|mSI|mDI| mR8|mR9|mR10|mR11|mR12|mR13|mR14|mR15; 
    142144#endif 
    143145    allregs = ALLREGS; 
     
    19131915#ifdef DEBUG 
    19141916            WRTYxx(tym); 
    1915             printf("\nallocreg: fil %s lin %d, regcon.mvar x%x msavereg x%x *pretregs x%x, reg %d, tym x%lx\n", 
     1917            printf("\nallocreg: fil %s lin %d, regcon.mvar x%x msavereg x%x *pretregs x%x, reg %d, tym x%x\n", 
    19161918                file,line,regcon.mvar,msavereg,*pretregs,*preg,tym); 
    19171919#endif 
     
    24782480  { 
    24792481#if DEBUG 
    2480         printf("e = %p, tym = x%lx\n",e,tym); 
     2482        printf("e = %p, tym = x%x\n",e,tym); 
    24812483#endif 
    24822484        assert(0); 
  • branches/dmd-1.x/src/backend/cod1.c

    r577 r579  
    1515#include        <stdio.h> 
    1616#include        <string.h> 
     17#include        <stdlib.h> 
    1718#include        <time.h> 
    1819#include        "cc.h" 
     
    327328    code *cs2 = *crestore; 
    328329 
     330    //printf("gensaverestore2(%x)\n", regm); 
    329331    regm &= mBP | mES | ALLREGS; 
    330332    for (int i = 0; regm; i++) 
     
    16661668#ifdef DEBUG 
    16671669  if (!(regm & (mBP | ALLREGS))) 
    1668         printf("tstresult(regm = x%x, tym = x%lx, saveflag = %d)\n", 
     1670        printf("tstresult(regm = x%x, tym = x%x, saveflag = %d)\n", 
    16691671            regm,tym,saveflag); 
    16701672#endif 
     
    23102312  keepmsk = 0; 
    23112313  if (OTbinary(e->Eoper))               // if parameters 
    2312   {     unsigned stackalign = REGSIZE; 
    2313         elem *en; 
    2314         regm_t retregs; 
    2315  
    2316         if (!I16) 
     2314  { 
     2315        if (I16) 
    23172316        { 
     2317            c = cat(c, params(e->E2,2));   // push parameters 
     2318        } 
     2319        else if (I32) 
     2320        { 
     2321            unsigned stackalign = REGSIZE; 
    23182322            tym_t tyf = tybasic(e->E1->Ety); 
    23192323 
    2320             // First compute numpara, the total pushed on the stack 
     2324            // First compute numpara, the total bytes pushed on the stack 
    23212325            switch (tyf) 
    23222326            {   case TYf16func: 
     
    23662370            {   case TYf16func: 
    23672371                    stackalign = 2; 
    2368                     break
     2372                    goto Ldefault2
    23692373                case TYmfunc:   // last parameter goes into ECX 
    23702374                    preg = CX; 
     
    23732377                    preg = AX; 
    23742378                    goto L1; 
    2375  
    23762379                L1: 
    2377                     elem *ep; 
     2380                {   elem *ep; 
     2381                    elem *en; 
    23782382                    for (ep = e->E2; ep->Eoper == OPparam; ep = en) 
    23792383                    { 
     
    23812385                        en = ep->E2; 
    23822386                        freenode(ep); 
    2383                         ep = en; 
    23842387                    } 
    23852388                    if (tyf == TYjfunc && 
     
    23952398                    // preg is the register to put the parameter ep in 
    23962399                    keepmsk = mask[preg];       // don't change preg when evaluating func address 
    2397                     retregs = keepmsk; 
     2400                    regm_t retregs = keepmsk; 
    23982401                    if (ep->Eoper == OPstrthis) 
    23992402                    {   code *c2; 
     
    24122415                    } 
    24132416                    goto Lret; 
    2414             } 
    2415         } 
    2416         c = cat(c, params(e->E2,stackalign));   // push parameters 
     2417                } 
     2418                default: 
     2419                Ldefault2: 
     2420                    c = cat(c, params(e->E2,stackalign));   // push parameters 
     2421                    break; 
     2422            } 
     2423        } 
     2424        else 
     2425        {   assert(I64); 
     2426 
     2427            struct Parameter { elem *e; int reg; }; 
     2428 
     2429            #ifdef DEBUG 
     2430            #define PARAMETERS_DIM 3 
     2431            #else 
     2432            #define PARAMETERS_DIM 10 
     2433            #endif 
     2434            Parameter parameters_tmp[PARAMETERS_DIM]; 
     2435            Parameter *parameters = parameters_tmp; 
     2436            size_t parameters_dim = PARAMETERS_DIM; 
     2437 
     2438            // Load up parameters[] 
     2439            elem *ep; 
     2440            elem *en; 
     2441            int np = 0; 
     2442            for (ep = e->E2; ep->Eoper == OPparam; ep = en) 
     2443            { 
     2444                if (np + 1 == parameters_dim)   // if not space for 2 more 
     2445                {   // Grow parameters[] 
     2446                    parameters_dim = np + 16; 
     2447                    Parameter *p = (Parameter *)alloca(parameters_dim * sizeof(Parameter)); 
     2448                    parameters = (Parameter *)memcpy(p, parameters, np * sizeof(Parameter)); 
     2449                } 
     2450                parameters[np++].e = ep->E1; 
     2451                en = ep->E2; 
     2452                freenode(ep); 
     2453            } 
     2454            parameters[np++].e = ep; 
     2455 
     2456            unsigned stackalign = REGSIZE; 
     2457            tym_t tyf = tybasic(e->E1->Ety); 
     2458 
     2459            // Compute numpara, the total bytes pushed on the stack 
     2460            int r = 0; 
     2461            int xmmcnt = XMM0; 
     2462            for (int i = np; --i >= 0;) 
     2463            { 
     2464                static const unsigned char argregs[6] = { DI,SI,DX,CX,R8,R9 }; 
     2465                elem *ep = parameters[i].e; 
     2466                tym_t ty = ep->Ety; 
     2467                if (r < sizeof(argregs)/sizeof(argregs[0]))     // if more arg regs 
     2468                { 
     2469                    if ( 
     2470                        // This must match type_jparam() 
     2471                        ty64reg(ty) || 
     2472                        ((tybasic(ty) == TYstruct || tybasic(ty) == TYarray) && 
     2473                         ep->Enumbytes <= REGSIZE && ep->Enumbytes != 3 && ep->Enumbytes) 
     2474                        ) 
     2475                    { 
     2476                        parameters[i].reg = argregs[r]; 
     2477                        r++; 
     2478                        continue;       // goes in register, not stack 
     2479                    } 
     2480                } 
     2481                else if (xmmcnt < XMM7) 
     2482                { 
     2483                    if (tyfloating(ty) && tysize(ty) <= 8) 
     2484                    { 
     2485                        parameters[i].reg = xmmcnt; 
     2486                        xmmcnt++; 
     2487                        continue;       // goes in register, not stack 
     2488                    } 
     2489                } 
     2490                parameters[i].reg = -1;         // -1 means no register 
     2491                numpara += paramsize(ep,stackalign); 
     2492            } 
     2493            assert((numpara & (REGSIZE - 1)) == 0); 
     2494            assert((stackpush & (REGSIZE - 1)) == 0); 
     2495 
     2496            /* Adjust start of the stack so after all args are pushed, 
     2497             * the stack will be aligned. 
     2498             */ 
     2499            if (STACKALIGN == 16 && (numpara + stackpush) & (STACKALIGN - 1)) 
     2500            { 
     2501                numalign = STACKALIGN - ((numpara + stackpush) & (STACKALIGN - 1)); 
     2502                c = genc2(NULL,0x81,(REX_W << 16) | modregrm(3,5,SP),numalign); // SUB ESP,numalign 
     2503                c = genadjesp(c, numalign); 
     2504                stackpush += numalign; 
     2505                stackpushsave += numalign; 
     2506            } 
     2507 
     2508            /* Parameters go into the registers RDI,RSI,RDX,RCX,R8,R9 
     2509             * float and double parameters go into XMM0..XMM7 
     2510             * For variadic functions, count of XMM registers used goes in AL 
     2511             */ 
     2512            for (int i = 0; i < np; i++) 
     2513            { 
     2514                elem *ep = parameters[i].e; 
     2515                int preg = parameters[i].reg; 
     2516                if (preg == -1) 
     2517                    c = cat(c,params(ep,stackalign)); 
     2518                else 
     2519                { 
     2520                    // Goes in register preg, not stack 
     2521                    regm_t retregs = mask[preg]; 
     2522                    if (ep->Eoper == OPstrthis) 
     2523                    { 
     2524                        code *c1 = getregs(retregs); 
     2525                        // LEA preg,np[ESP] 
     2526                        unsigned np = stackpush - ep->EV.Vuns;   // stack delta to parameter 
     2527                        code *c2 = genc1(CNIL,0x8D,(REX_W << 16) | 
     2528                                             (modregrm(0,4,SP) << 8) | 
     2529                                              modregxrm(2,preg,4), FLconst,np); 
     2530                        c = cat3(c,c1,c2); 
     2531                    } 
     2532                    else 
     2533                    {   code *cp = scodelem(ep,&retregs,keepmsk,FALSE); 
     2534                        c = cat(c,cp); 
     2535                    } 
     2536                    keepmsk |= retregs;      // don't change preg when evaluating func address 
     2537                } 
     2538            } 
     2539            if (e->Eflags & EFLAGS_variadic) 
     2540            {   movregconst(c,AX,xmmcnt - XMM0,1); 
     2541                keepmsk |= mAX; 
     2542            } 
     2543        } 
    24172544    } 
    24182545    else 
     
    24352562Lret: 
    24362563    cgstate.stackclean--; 
    2437     if (!I16) 
     2564    if (I16) 
     2565        numpara = stackpush - stackpushsave; 
     2566    else 
    24382567    { 
    24392568        if (numpara != stackpush - stackpushsave) 
     
    24412570        assert(numpara == stackpush - stackpushsave); 
    24422571    } 
    2443     else 
    2444         numpara = stackpush - stackpushsave; 
    24452572    return cat(c,funccall(e,numpara,numalign,pretregs,keepmsk)); 
    24462573} 
  • branches/dmd-1.x/src/backend/cod2.c

    r577 r579  
    37363736 
    37373737  cs.Iflags = 0; 
    3738   unsigned char rex = I64 ? REX_W : 0; 
     3738  unsigned char rex = 0; 
    37393739  cs.Irex = rex; 
    37403740  assert(e->Eoper == OPvar || e->Eoper == OPrelconst); 
  • branches/dmd-1.x/src/backend/cod3.c

    r577 r579  
    11721172 
    11731173code *prolog() 
    1174 {   code *c; 
     1174{ 
    11751175    SYMIDX si; 
    11761176    unsigned reg; 
    1177     regm_t topush; 
    1178     tym_t tym; 
    1179     tym_t tyf; 
    11801177    char enter; 
    1181     char pushds; 
    1182     unsigned farfunc; 
    11831178    unsigned Foffset; 
    11841179    unsigned xlocalsize;     // amount to subtract from ESP to make room for locals 
    1185     int pushalloc; 
    11861180    unsigned pushallocreg; 
    11871181    char guessneedframe; 
     
    11921186    EBPtoESP = -REGSIZE; 
    11931187    hasframe = 0; 
    1194     pushds = 0; 
     1188    char pushds = 0; 
    11951189    BPoff = 0; 
    1196     c = CNIL; 
    1197     pushalloc = 0; 
    1198     tyf = funcsym_p->ty(); 
    1199     tym = tybasic(tyf); 
    1200     farfunc = tyfarfunc(tym); 
     1190    code *c = CNIL; 
     1191    int pushalloc = 0; 
     1192    tym_t tyf = funcsym_p->ty(); 
     1193    tym_t tym = tybasic(tyf); 
     1194    unsigned farfunc = tyfarfunc(tym); 
    12011195    pushallocreg = (tyf == TYmfunc) ? CX : AX; 
    12021196    if (config.flags & CFGalwaysframe || funcsym_p->Sfunc->Fflags3 & Ffakeeh) 
     
    12641258    localsize = -Toff; 
    12651259 
    1266     topush = fregsaved & ~mfuncreg;     // mask of registers that need saving 
     1260    regm_t topush = fregsaved & ~mfuncreg;     // mask of registers that need saving 
    12671261    int npush = 0;                      // number of registers that need saving 
    12681262    for (regm_t x = topush; x; x >>= 1) 
     
    13461340    } 
    13471341 
    1348 #if SIXTEENBIT 
    1349     if (config.wflags & WFwindows && farfunc) 
     1342    if (I16 && config.wflags & WFwindows && farfunc) 
    13501343    {   int wflags; 
    13511344        int segreg; 
    13521345 
     1346#if SCPP 
    13531347        // alloca() can't be because the 'special' parameter won't be at 
    13541348        // a known offset from BP. 
    13551349        if (usedalloca == 1) 
    13561350            synerr(EM_alloca_win);      // alloca() can't be in Windows functions 
     1351#endif 
    13571352 
    13581353        wflags = config.wflags; 
     
    14061401    } 
    14071402    else 
    1408 #endif 
    14091403    if (needframe)                      // if variables or parameters 
    14101404    { 
     
    16601654    {   reg = findreg(topush); 
    16611655        topush &= ~mask[reg]; 
    1662         c = gen1(c,0x50 + reg); 
     1656        c = gen1(c,0x50 + (reg & 7)); 
     1657        if (reg & 8) 
     1658            code_orrex(c, REX_B); 
    16631659        EBPtoESP += REGSIZE; 
    16641660#if ELFOBJ || MACHOBJ 
     
    19131909    while (topop) 
    19141910    {   if (topop & regm) 
    1915         {   c = gen1(c,0x58 + reg);         // POP reg 
     1911        {   c = gen1(c,0x58 + (reg & 7));         // POP reg 
    19161912            if (reg & 8) 
    19171913                code_orrex(c, REX_B); 
     
    43484344void addtofixlist(symbol *s,targ_size_t soffset,int seg,targ_size_t val,int flags) 
    43494345{       fixlist *ln; 
    4350         static char zeros[6]; 
     4346        static char zeros[8]; 
    43514347        int numbytes; 
    43524348 
     
    48844880                case FLconst: 
    48854881                case FLoffset: 
    4886                     printf(" int = %4ld",c->IEV1.Vuns); 
     4882                    printf(" int = %4d",c->IEV1.Vuns); 
    48874883                    break; 
    48884884                case FLblock: 
     
    49194915        { 
    49204916            case FLconst: 
    4921                 printf(" int = %4ld",c->IEV2.Vuns); 
     4917                printf(" int = %4d",c->IEV2.Vuns); 
    49224918                break; 
    49234919            case FLblock: 
  • branches/dmd-1.x/src/backend/el.h

    r572 r579  
    4444    unsigned char Ecount;       // # of parents of this elem - 1, 
    4545                                // always 0 until CSE elimination is done 
     46    unsigned char Eflags; 
     47    #define EFLAGS_variadic 1   // variadic function call 
     48 
    4649    union eve EV;               // variants for each type of elem 
    4750    union 
  • branches/dmd-1.x/src/backend/elfobj.c

    r572 r579  
    27192719void obj_moduleinfo(Symbol *scc) 
    27202720{ 
     2721//    if (I64) return;          // for now, until Phobos64 works 
     2722 
    27212723    int codeOffset, refOffset; 
    27222724 
     
    27352737        SegData[seg]->SDbuf->writezeros(NPTRSIZE); 
    27362738        SegData[seg]->SDoffset += NPTRSIZE; 
    2737         SegData[seg]->SDoffset += reftoident(seg, SegData[seg]->SDoffset, scc, 0, CFoff); 
    2738         alignOffset(seg, NPTRSIZE); 
     2739        SegData[seg]->SDoffset += reftoident(seg, SegData[seg]->SDoffset, scc, 0, CFoffset64 | CFoff); 
    27392740    } 
    27402741 
     
    27642765        buf->writeByte(0xC3); /* ret */ 
    27652766 
    2766         buf->writeByte(0x60); /* pushad */ 
     2767        int off = 0; 
     2768        if (I32) 
     2769        {   buf->writeByte(0x60); // PUSHAD 
     2770            off = 1; 
     2771        } 
    27672772 
    27682773        /* movl ModuleReference*, %eax */ 
    27692774        buf->writeByte(0xB8); 
    27702775        buf->write32(refOffset); 
    2771         elf_addrel(seg, codeOffset + 2, reltype, STI_DATA, 0); 
     2776        elf_addrel(seg, codeOffset + off + 1, reltype, STI_DATA, 0); 
    27722777 
    27732778        /* movl _Dmodule_ref, %ecx */ 
    27742779        buf->writeByte(0xB9); 
    27752780        buf->write32(0); 
    2776         elf_addrel(seg, codeOffset + 7, reltype, objextern("_Dmodule_ref"), 0); 
     2781        elf_addrel(seg, codeOffset + off + 6, reltype, objextern("_Dmodule_ref"), 0); 
    27772782 
    27782783        buf->writeByte(0x8B); buf->writeByte(0x11); /* movl (%ecx), %edx */ 
     
    27802785        buf->writeByte(0x89); buf->writeByte(0x01); /* movl %eax, (%ecx) */ 
    27812786 
    2782         buf->writeByte(0x61); /* popad */ 
     2787        if (I32) buf->writeByte(0x61); // POPAD 
    27832788        buf->writeByte(0xC3); /* ret */ 
    27842789        SegData[seg]->SDoffset = buf->size(); 
  • branches/dmd-1.x/src/backend/symbol.c

    r487 r579  
    364364void symbol_func(symbol *s) 
    365365{ 
     366    //printf("symbol_func(%s, x%x)\n", s->Sident, fregsaved); 
    366367    symbol_debug(s); 
    367368    s->Sfl = FLfunc; 
     
    370371    // BUG: do interrupt functions really save BP? 
    371372    #define mBP 0x20 
     373    // Note that fregsaved may not be set yet 
    372374    s->Sregsaved = (s->Stype && tybasic(s->Stype->Tty) == TYifunc) ? mBP : fregsaved; 
    373375    s->Sseg = UNKNOWN;          // don't know what segment it is in 
  • branches/dmd-1.x/src/backend/ty.h

    r557 r579  
    198198#define tyreal(ty)      (tytab[(ty) & 0xFF] & TYFLreal) 
    199199 
     200// Fits into 64 bit register 
     201#define ty64reg(ty)     (tytab[(ty) & 0xFF] & (TYFLintegral | TYFLptr)) 
     202 
    200203#ifndef tyshort 
    201204/* Types that are chars or shorts       */ 
  • branches/dmd-1.x/src/e2ir.c

    r569 r579  
    281281    } 
    282282    else if (ep) 
    283         e = el_bin(OPcall,tyret,ec,ep); 
     283    {   e = el_bin(OPcall,tyret,ec,ep); 
     284        if (tf->varargs) 
     285            e->Eflags |= EFLAGS_variadic; 
     286    } 
    284287    else 
    285         e = el_una(OPucall,tyret,ec); 
     288    {   e = el_una(OPucall,tyret,ec); 
     289        if (tf->varargs) 
     290            e->Eflags |= EFLAGS_variadic; 
     291    } 
    286292 
    287293    if (retmethod == RETstack) 
     
    17741780                           NULL); 
    17751781            e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCATNT]), ep); 
     1782            e->Eflags |= EFLAGS_variadic; 
    17761783#else 
    17771784            ep = el_params( 
     
    17811788                           NULL); 
    17821789            e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCATN]), ep); 
     1790            e->Eflags |= EFLAGS_variadic; 
    17831791#endif 
    17841792        } 
     
    42184226    // call _d_arrayliteralT(ti, dim, ...) 
    42194227    e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ARRAYLITERALT]),e); 
     4228    e->Eflags |= EFLAGS_variadic; 
    42204229#else 
    42214230    e = el_param(e, el_long(TYint, tb->next->size())); 
     
    42234232    // call _d_arrayliteral(size, dim, ...) 
    42244233    e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ARRAYLITERAL]),e); 
     4234    e->Eflags |= EFLAGS_variadic; 
    42254235#endif 
    42264236    if (tb->ty == Tarray) 
     
    42714281    // call _d_assocarrayliteralT(ti, dim, ...) 
    42724282    e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ASSOCARRAYLITERALT]),e); 
     4283    e->Eflags |= EFLAGS_variadic; 
    42734284 
    42744285    el_setLoc(e,loc); 
  • branches/dmd-1.x/src/msc.c

    r569 r579  
    4141void out_config_init() 
    4242{ 
     43    //printf("out_config_init()\n"); 
    4344    Param *params = &global.params; 
    4445 
  • trunk/src/backend/cgcod.c

    r577 r579  
    140140        BYTEREGS = value; 
    141141    } 
     142    if (I64) 
     143        ALLREGS = mAX|mBX|mCX|mDX|mSI|mDI| mR8|mR9|mR10|mR11|mR12|mR13|mR14|mR15; 
    142144#endif 
    143145    allregs = ALLREGS; 
     
    19131915#ifdef DEBUG 
    19141916            WRTYxx(tym); 
    1915             printf("\nallocreg: fil %s lin %d, regcon.mvar x%x msavereg x%x *pretregs x%x, reg %d, tym x%lx\n", 
     1917            printf("\nallocreg: fil %s lin %d, regcon.mvar x%x msavereg x%x *pretregs x%x, reg %d, tym x%x\n", 
    19161918                file,line,regcon.mvar,msavereg,*pretregs,*preg,tym); 
    19171919#endif 
     
    24782480  { 
    24792481#if DEBUG 
    2480         printf("e = %p, tym = x%lx\n",e,tym); 
     2482        printf("e = %p, tym = x%x\n",e,tym); 
    24812483#endif 
    24822484        assert(0); 
  • trunk/src/backend/cod1.c

    r577 r579  
    1515#include        <stdio.h> 
    1616#include        <string.h> 
     17#include        <stdlib.h> 
    1718#include        <time.h> 
    1819#include        "cc.h" 
     
    327328    code *cs2 = *crestore; 
    328329 
     330    //printf("gensaverestore2(%x)\n", regm); 
    329331    regm &= mBP | mES | ALLREGS; 
    330332    for (int i = 0; regm; i++) 
     
    16661668#ifdef DEBUG 
    16671669  if (!(regm & (mBP | ALLREGS))) 
    1668         printf("tstresult(regm = x%x, tym = x%lx, saveflag = %d)\n", 
     1670        printf("tstresult(regm = x%x, tym = x%x, saveflag = %d)\n", 
    16691671            regm,tym,saveflag); 
    16701672#endif 
     
    23102312  keepmsk = 0; 
    23112313  if (OTbinary(e->Eoper))               // if parameters 
    2312   {     unsigned stackalign = REGSIZE; 
    2313         elem *en; 
    2314         regm_t retregs; 
    2315  
    2316         if (!I16) 
     2314  { 
     2315        if (I16) 
    23172316        { 
     2317            c = cat(c, params(e->E2,2));   // push parameters 
     2318        } 
     2319        else if (I32) 
     2320        { 
     2321            unsigned stackalign = REGSIZE; 
    23182322            tym_t tyf = tybasic(e->E1->Ety); 
    23192323 
    2320             // First compute numpara, the total pushed on the stack 
     2324            // First compute numpara, the total bytes pushed on the stack 
    23212325            switch (tyf) 
    23222326            {   case TYf16func: 
     
    23662370            {   case TYf16func: 
    23672371                    stackalign = 2; 
    2368                     break
     2372                    goto Ldefault2
    23692373                case TYmfunc:   // last parameter goes into ECX 
    23702374                    preg = CX; 
     
    23732377                    preg = AX; 
    23742378                    goto L1; 
    2375  
    23762379                L1: 
    2377                     elem *ep; 
     2380                {   elem *ep; 
     2381                    elem *en; 
    23782382                    for (ep = e->E2; ep->Eoper == OPparam; ep = en) 
    23792383                    { 
     
    23812385                        en = ep->E2; 
    23822386                        freenode(ep); 
    2383                         ep = en; 
    23842387                    } 
    23852388                    if (tyf == TYjfunc && 
     
    23952398                    // preg is the register to put the parameter ep in 
    23962399                    keepmsk = mask[preg];       // don't change preg when evaluating func address 
    2397                     retregs = keepmsk; 
     2400                    regm_t retregs = keepmsk; 
    23982401                    if (ep->Eoper == OPstrthis) 
    23992402                    {   code *c2; 
     
    24122415                    } 
    24132416                    goto Lret; 
    2414             } 
    2415         } 
    2416         c = cat(c, params(e->E2,stackalign));   // push parameters 
     2417                } 
     2418                default: 
     2419                Ldefault2: 
     2420                    c = cat(c, params(e->E2,stackalign));   // push parameters 
     2421                    break; 
     2422            } 
     2423        } 
     2424        else 
     2425        {   assert(I64); 
     2426 
     2427            struct Parameter { elem *e; int reg; }; 
     2428 
     2429            #ifdef DEBUG 
     2430            #define PARAMETERS_DIM 3 
     2431            #else 
     2432            #define PARAMETERS_DIM 10 
     2433            #endif 
     2434            Parameter parameters_tmp[PARAMETERS_DIM]; 
     2435            Parameter *parameters = parameters_tmp; 
     2436            size_t parameters_dim = PARAMETERS_DIM; 
     2437 
     2438            // Load up parameters[] 
     2439            elem *ep; 
     2440            elem *en; 
     2441            int np = 0; 
     2442            for (ep = e->E2; ep->Eoper == OPparam; ep = en) 
     2443            { 
     2444                if (np + 1 == parameters_dim)   // if not space for 2 more 
     2445                {   // Grow parameters[] 
     2446                    parameters_dim = np + 16; 
     2447                    Parameter *p = (Parameter *)alloca(parameters_dim * sizeof(Parameter)); 
     2448                    parameters = (Parameter *)memcpy(p, parameters, np * sizeof(Parameter)); 
     2449                } 
     2450                parameters[np++].e = ep->E1; 
     2451                en = ep->E2; 
     2452                freenode(ep); 
     2453            } 
     2454            parameters[np++].e = ep; 
     2455 
     2456            unsigned stackalign = REGSIZE; 
     2457            tym_t tyf = tybasic(e->E1->Ety); 
     2458 
     2459            // Compute numpara, the total bytes pushed on the stack 
     2460            int r = 0; 
     2461            int xmmcnt = XMM0; 
     2462            for (int i = np; --i >= 0;) 
     2463            { 
     2464                static const unsigned char argregs[6] = { DI,SI,DX,CX,R8,R9 }; 
     2465                elem *ep = parameters[i].e; 
     2466                tym_t ty = ep->Ety; 
     2467                if (r < sizeof(argregs)/sizeof(argregs[0]))     // if more arg regs 
     2468                { 
     2469                    if ( 
     2470                        // This must match type_jparam() 
     2471                        ty64reg(ty) || 
     2472                        ((tybasic(ty) == TYstruct || tybasic(ty) == TYarray) && 
     2473                         ep->Enumbytes <= REGSIZE && ep->Enumbytes != 3 && ep->Enumbytes) 
     2474                        ) 
     2475                    { 
     2476                        parameters[i].reg = argregs[r]; 
     2477                        r++; 
     2478                        continue;       // goes in register, not stack 
     2479                    } 
     2480                } 
     2481                else if (xmmcnt < XMM7) 
     2482                { 
     2483                    if (tyfloating(ty) && tysize(ty) <= 8) 
     2484                    { 
     2485                        parameters[i].reg = xmmcnt; 
     2486                        xmmcnt++; 
     2487                        continue;       // goes in register, not stack 
     2488                    } 
     2489                } 
     2490                parameters[i].reg = -1;         // -1 means no register 
     2491                numpara += paramsize(ep,stackalign); 
     2492            } 
     2493            assert((numpara & (REGSIZE - 1)) == 0); 
     2494            assert((stackpush & (REGSIZE - 1)) == 0); 
     2495 
     2496            /* Adjust start of the stack so after all args are pushed, 
     2497             * the stack will be aligned. 
     2498             */ 
     2499            if (STACKALIGN == 16 && (numpara + stackpush) & (STACKALIGN - 1)) 
     2500            { 
     2501                numalign = STACKALIGN - ((numpara + stackpush) & (STACKALIGN - 1)); 
     2502                c = genc2(NULL,0x81,(REX_W << 16) | modregrm(3,5,SP),numalign); // SUB ESP,numalign 
     2503                c = genadjesp(c, numalign); 
     2504                stackpush += numalign; 
     2505                stackpushsave += numalign; 
     2506            } 
     2507 
     2508            /* Parameters go into the registers RDI,RSI,RDX,RCX,R8,R9 
     2509             * float and double parameters go into XMM0..XMM7 
     2510             * For variadic functions, count of XMM registers used goes in AL 
     2511             */ 
     2512            for (int i = 0; i < np; i++) 
     2513            { 
     2514                elem *ep = parameters[i].e; 
     2515                int preg = parameters[i].reg; 
     2516                if (preg == -1) 
     2517                    c = cat(c,params(ep,stackalign)); 
     2518                else 
     2519                { 
     2520                    // Goes in register preg, not stack 
     2521                    regm_t retregs = mask[preg]; 
     2522                    if (ep->Eoper == OPstrthis) 
     2523                    { 
     2524                        code *c1 = getregs(retregs); 
     2525                        // LEA preg,np[ESP] 
     2526                        unsigned np = stackpush - ep->EV.Vuns;   // stack delta to parameter 
     2527                        code *c2 = genc1(CNIL,0x8D,(REX_W << 16) | 
     2528                                             (modregrm(0,4,SP) << 8) | 
     2529                                              modregxrm(2,preg,4), FLconst,np); 
     2530                        c = cat3(c,c1,c2); 
     2531                    } 
     2532                    else 
     2533                    {   code *cp = scodelem(ep,&retregs,keepmsk,FALSE); 
     2534                        c = cat(c,cp); 
     2535                    } 
     2536                    keepmsk |= retregs;      // don't change preg when evaluating func address 
     2537                } 
     2538            } 
     2539            if (e->Eflags & EFLAGS_variadic) 
     2540            {   movregconst(c,AX,xmmcnt - XMM0,1); 
     2541                keepmsk |= mAX; 
     2542            } 
     2543        } 
    24172544    } 
    24182545    else 
     
    24352562Lret: 
    24362563    cgstate.stackclean--; 
    2437     if (!I16) 
     2564    if (I16) 
     2565        numpara = stackpush - stackpushsave; 
     2566    else 
    24382567    { 
    24392568        if (numpara != stackpush - stackpushsave) 
     
    24412570        assert(numpara == stackpush - stackpushsave); 
    24422571    } 
    2443     else 
    2444         numpara = stackpush - stackpushsave; 
    24452572    return cat(c,funccall(e,numpara,numalign,pretregs,keepmsk)); 
    24462573} 
  • trunk/src/backend/cod2.c

    r577 r579  
    37363736 
    37373737  cs.Iflags = 0; 
    3738   unsigned char rex = I64 ? REX_W : 0; 
     3738  unsigned char rex = 0; 
    37393739  cs.Irex = rex; 
    37403740  assert(e->Eoper == OPvar || e->Eoper == OPrelconst); 
  • trunk/src/backend/cod3.c

    r577 r579  
    11721172 
    11731173code *prolog() 
    1174 {   code *c; 
     1174{ 
    11751175    SYMIDX si; 
    11761176    unsigned reg; 
    1177     regm_t topush; 
    1178     tym_t tym; 
    1179     tym_t tyf; 
    11801177    char enter; 
    1181     char pushds; 
    1182     unsigned farfunc; 
    11831178    unsigned Foffset; 
    11841179    unsigned xlocalsize;     // amount to subtract from ESP to make room for locals 
    1185     int pushalloc; 
    11861180    unsigned pushallocreg; 
    11871181    char guessneedframe; 
     
    11921186    EBPtoESP = -REGSIZE; 
    11931187    hasframe = 0; 
    1194     pushds = 0; 
     1188    char pushds = 0; 
    11951189    BPoff = 0; 
    1196     c = CNIL; 
    1197     pushalloc = 0; 
    1198     tyf = funcsym_p->ty(); 
    1199     tym = tybasic(tyf); 
    1200     farfunc = tyfarfunc(tym); 
     1190    code *c = CNIL; 
     1191    int pushalloc = 0; 
     1192    tym_t tyf = funcsym_p->ty(); 
     1193    tym_t tym = tybasic(tyf); 
     1194    unsigned farfunc = tyfarfunc(tym); 
    12011195    pushallocreg = (tyf == TYmfunc) ? CX : AX; 
    12021196    if (config.flags & CFGalwaysframe || funcsym_p->Sfunc->Fflags3 & Ffakeeh) 
     
    12641258    localsize = -Toff; 
    12651259 
    1266     topush = fregsaved & ~mfuncreg;     // mask of registers that need saving 
     1260    regm_t topush = fregsaved & ~mfuncreg;     // mask of registers that need saving 
    12671261    int npush = 0;                      // number of registers that need saving 
    12681262    for (regm_t x = topush; x; x >>= 1) 
     
    13461340    } 
    13471341 
    1348 #if SIXTEENBIT 
    1349     if (config.wflags & WFwindows && farfunc) 
     1342    if (I16 && config.wflags & WFwindows && farfunc) 
    13501343    {   int wflags; 
    13511344        int segreg; 
    13521345 
     1346#if SCPP 
    13531347        // alloca() can't be because the 'special' parameter won't be at 
    13541348        // a known offset from BP. 
    13551349        if (usedalloca == 1) 
    13561350            synerr(EM_alloca_win);      // alloca() can't be in Windows functions 
     1351#endif 
    13571352 
    13581353        wflags = config.wflags; 
     
    14061401    } 
    14071402    else 
    1408 #endif 
    14091403    if (needframe)                      // if variables or parameters 
    14101404    { 
     
    16601654    {   reg = findreg(topush); 
    16611655        topush &= ~mask[reg]; 
    1662         c = gen1(c,0x50 + reg); 
     1656        c = gen1(c,0x50 + (reg & 7)); 
     1657        if (reg & 8) 
     1658            code_orrex(c, REX_B); 
    16631659        EBPtoESP += REGSIZE; 
    16641660#if ELFOBJ || MACHOBJ 
     
    19131909    while (topop) 
    19141910    {   if (topop & regm) 
    1915         {   c = gen1(c,0x58 + reg);         // POP reg 
     1911        {   c = gen1(c,0x58 + (reg & 7));         // POP reg 
    19161912            if (reg & 8) 
    19171913                code_orrex(c, REX_B); 
     
    43484344void addtofixlist(symbol *s,targ_size_t soffset,int seg,targ_size_t val,int flags) 
    43494345{       fixlist *ln; 
    4350         static char zeros[6]; 
     4346        static char zeros[8]; 
    43514347        int numbytes; 
    43524348 
     
    48844880                case FLconst: 
    48854881                case FLoffset: 
    4886                     printf(" int = %4ld",c->IEV1.Vuns); 
     4882                    printf(" int = %4d",c->IEV1.Vuns); 
    48874883                    break; 
    48884884                case FLblock: 
     
    49194915        { 
    49204916            case FLconst: 
    4921                 printf(" int = %4ld",c->IEV2.Vuns); 
     4917                printf(" int = %4d",c->IEV2.Vuns); 
    49224918                break; 
    49234919            case FLblock: 
  • trunk/src/backend/el.h

    r572 r579  
    4444    unsigned char Ecount;       // # of parents of this elem - 1, 
    4545                                // always 0 until CSE elimination is done 
     46    unsigned char Eflags; 
     47    #define EFLAGS_variadic 1   // variadic function call 
     48 
    4649    union eve EV;               // variants for each type of elem 
    4750    union 
  • trunk/src/backend/elfobj.c

    r572 r579  
    27192719void obj_moduleinfo(Symbol *scc) 
    27202720{ 
     2721//    if (I64) return;          // for now, until Phobos64 works 
     2722 
    27212723    int codeOffset, refOffset; 
    27222724 
     
    27352737        SegData[seg]->SDbuf->writezeros(NPTRSIZE); 
    27362738        SegData[seg]->SDoffset += NPTRSIZE; 
    2737         SegData[seg]->SDoffset += reftoident(seg, SegData[seg]->SDoffset, scc, 0, CFoff); 
    2738         alignOffset(seg, NPTRSIZE); 
     2739        SegData[seg]->SDoffset += reftoident(seg, SegData[seg]->SDoffset, scc, 0, CFoffset64 | CFoff); 
    27392740    } 
    27402741 
     
    27642765        buf->writeByte(0xC3); /* ret */ 
    27652766 
    2766         buf->writeByte(0x60); /* pushad */ 
     2767        int off = 0; 
     2768        if (I32) 
     2769        {   buf->writeByte(0x60); // PUSHAD 
     2770            off = 1; 
     2771        } 
    27672772 
    27682773        /* movl ModuleReference*, %eax */ 
    27692774        buf->writeByte(0xB8); 
    27702775        buf->write32(refOffset); 
    2771         elf_addrel(seg, codeOffset + 2, reltype, STI_DATA, 0); 
     2776        elf_addrel(seg, codeOffset + off + 1, reltype, STI_DATA, 0); 
    27722777 
    27732778        /* movl _Dmodule_ref, %ecx */ 
    27742779        buf->writeByte(0xB9); 
    27752780        buf->write32(0); 
    2776         elf_addrel(seg, codeOffset + 7, reltype, objextern("_Dmodule_ref"), 0); 
     2781        elf_addrel(seg, codeOffset + off + 6, reltype, objextern("_Dmodule_ref"), 0); 
    27772782 
    27782783        buf->writeByte(0x8B); buf->writeByte(0x11); /* movl (%ecx), %edx */ 
     
    27802785        buf->writeByte(0x89); buf->writeByte(0x01); /* movl %eax, (%ecx) */ 
    27812786 
    2782         buf->writeByte(0x61); /* popad */ 
     2787        if (I32) buf->writeByte(0x61); // POPAD 
    27832788        buf->writeByte(0xC3); /* ret */ 
    27842789        SegData[seg]->SDoffset = buf->size(); 
  • trunk/src/backend/symbol.c

    r487 r579  
    364364void symbol_func(symbol *s) 
    365365{ 
     366    //printf("symbol_func(%s, x%x)\n", s->Sident, fregsaved); 
    366367    symbol_debug(s); 
    367368    s->Sfl = FLfunc; 
     
    370371    // BUG: do interrupt functions really save BP? 
    371372    #define mBP 0x20 
     373    // Note that fregsaved may not be set yet 
    372374    s->Sregsaved = (s->Stype && tybasic(s->Stype->Tty) == TYifunc) ? mBP : fregsaved; 
    373375    s->Sseg = UNKNOWN;          // don't know what segment it is in 
  • trunk/src/backend/ty.h

    r557 r579  
    198198#define tyreal(ty)      (tytab[(ty) & 0xFF] & TYFLreal) 
    199199 
     200// Fits into 64 bit register 
     201#define ty64reg(ty)     (tytab[(ty) & 0xFF] & (TYFLintegral | TYFLptr)) 
     202 
    200203#ifndef tyshort 
    201204/* Types that are chars or shorts       */ 
  • trunk/src/e2ir.c

    r569 r579  
    287287    } 
    288288    else if (ep) 
    289        /* Do not do "no side effect" calls if a hidden parameter is passed, 
     289    {   /* Do not do "no side effect" calls if a hidden parameter is passed, 
    290290         * as the return value is stored through the hidden parameter, which 
    291291         * is a side effect. 
     
    293293        e = el_bin((tf->ispure && tf->isnothrow && (retmethod != RETstack)) ? 
    294294                OPcallns : OPcall,tyret,ec,ep); 
     295        if (tf->varargs) 
     296            e->Eflags |= EFLAGS_variadic; 
     297    } 
    295298    else 
    296        e = el_una((tf->ispure && tf->isnothrow && (retmethod != RETstack)) ? 
     299    {   e = el_una((tf->ispure && tf->isnothrow && (retmethod != RETstack)) ? 
    297300                OPucallns : OPucall,tyret,ec); 
     301        if (tf->varargs) 
     302            e->Eflags |= EFLAGS_variadic; 
     303    } 
    298304 
    299305    if (retmethod == RETstack) 
     
    20782084                           NULL); 
    20792085            e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCATNT]), ep); 
     2086            e->Eflags |= EFLAGS_variadic; 
    20802087#else 
    20812088            ep = el_params( 
     
    20852092                           NULL); 
    20862093            e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCATN]), ep); 
     2094            e->Eflags |= EFLAGS_variadic; 
    20872095#endif 
    20882096        } 
     
    45634571    // call _d_arrayliteralT(ti, dim, ...) 
    45644572    e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ARRAYLITERALT]),e); 
     4573    e->Eflags |= EFLAGS_variadic; 
    45654574#else 
    45664575    e = el_param(e, el_long(TYint, tb->next->size())); 
     
    45684577    // call _d_arrayliteral(size, dim, ...) 
    45694578    e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ARRAYLITERAL]),e); 
     4579    e->Eflags |= EFLAGS_variadic; 
    45704580#endif 
    45714581    if (tb->ty == Tarray) 
     
    46374647    // call _d_assocarrayliteralT(ti, dim, ...) 
    46384648    e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ASSOCARRAYLITERALT]),e); 
     4649    e->Eflags |= EFLAGS_variadic; 
    46394650 
    46404651    el_setLoc(e,loc); 
  • trunk/src/msc.c

    r569 r579  
    4141void out_config_init() 
    4242{ 
     43    //printf("out_config_init()\n"); 
    4344    Param *params = &global.params; 
    4445