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

Changeset 579

Show
Ignore:
Timestamp:
07/17/10 09:30:24 (14 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  
    123123    // in that basic block. 
    124124 
    125125    //printf("codgen('%s')\n",funcsym_p->Sident); 
    126126 
    127127    cgreg_init(); 
    128128    csmax = 64; 
    129129    csextab = (struct CSE *) util_calloc(sizeof(struct CSE),csmax); 
    130130    functy = tybasic(funcsym_p->ty()); 
    131131#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 
    132132    if (0 && config.flags3 & CFG3pic) 
    133133    { 
    134134        ALLREGS = ALLREGS_INIT_PIC; 
    135135        BYTEREGS = BYTEREGS_INIT_PIC; 
    136136    } 
    137137    else 
    138138    { 
    139139        regm_t value = BYTEREGS_INIT; 
    140140        ALLREGS = ALLREGS_INIT; 
    141141        BYTEREGS = value; 
    142142    } 
     143    if (I64) 
     144        ALLREGS = mAX|mBX|mCX|mDX|mSI|mDI| mR8|mR9|mR10|mR11|mR12|mR13|mR14|mR15; 
    143145#endif 
    144146    allregs = ALLREGS; 
    145147    if (0 && config.flags3 & CFG3pic) 
    146148        allregs &= ~mBX; 
    147149    pass = PASSinit; 
    148150 
    149151tryagain: 
    150152    #ifdef DEBUG 
    151153    if (debugr) 
    152154        printf("------------------ PASS%s -----------------\n", 
    153155            (pass == PASSinit) ? "init" : ((pass == PASSreg) ? "reg" : "final")); 
    154156    #endif 
    155157    lastretregs = last2retregs = last3retregs = last4retregs = last5retregs = 0; 
    156158 
    157159    // if no parameters, assume we don't need a stack frame 
    158160    needframe = 0; 
    159161    usedalloca = 0; 
    160162    gotref = 0; 
    161163    stackchanged = 0; 
    162164    stackpush = 0; 
     
    19011903                {   retregs &= mMSW; 
    19021904                    goto L3; 
    19031905                } 
    19041906            } 
    19051907            reg = (msreg == ES) ? lsreg : msreg; 
    19061908            retregs = mask[msreg] | mask[lsreg]; 
    19071909        } 
    19081910        else if (I16 && (tym == TYdouble || tym == TYdouble_alias)) 
    19091911        { 
    19101912#ifdef DEBUG 
    19111913            if (retregs != DOUBLEREGS) 
    19121914                printf("retregs = x%x, *pretregs = x%x\n",retregs,*pretregs); 
    19131915#endif 
    19141916            assert(retregs == DOUBLEREGS); 
    19151917            reg = AX; 
    19161918        } 
    19171919        else 
    19181920        { 
    19191921#ifdef DEBUG 
    19201922            WRTYxx(tym); 
    1921             printf("\nallocreg: fil %s lin %d, regcon.mvar x%x msavereg x%x *pretregs x%x, reg %d, tym x%lx\n", 
     1923            printf("\nallocreg: fil %s lin %d, regcon.mvar x%x msavereg x%x *pretregs x%x, reg %d, tym x%x\n", 
    19221924                file,line,regcon.mvar,msavereg,*pretregs,*preg,tym); 
    19231925#endif 
    19241926            assert(0); 
    19251927        } 
    19261928        if (retregs & regcon.mvar)              // if conflict with reg vars 
    19271929        { 
    19281930            if (!(size > REGSIZE && *pretregs == (mAX | mDX))) 
    19291931            { 
    19301932                retregs = (*pretregs &= ~(retregs & regcon.mvar)); 
    19311933                goto L1;                // try other registers 
    19321934            } 
    19331935        } 
    19341936        *preg = reg; 
    19351937        *pretregs = retregs; 
    19361938 
    19371939        //printf("Allocating %s\n",regm_str(retregs)); 
    19381940        last5retregs = last4retregs; 
    19391941        last4retregs = last3retregs; 
    19401942        last3retregs = last2retregs; 
    19411943        last2retregs = lastretregs; 
     
    24702472        assert(I16); 
    24712473        if (((csemask | emask) & DOUBLEREGS_16) == DOUBLEREGS_16) 
    24722474        { 
    24732475            for (reg = AX; reg != -1; reg = dblreg[reg]) 
    24742476            {   assert((int) reg >= 0 && reg <= 7); 
    24752477                if (mask[reg] & csemask) 
    24762478                    c = cat(c,loadcse(e,reg,mask[reg])); 
    24772479            } 
    24782480            regm = DOUBLEREGS_16; 
    24792481            goto fix; 
    24802482        } 
    24812483        if (!EOP(e)) goto reload; 
    24822484#if DEBUG 
    24832485        printf("e = %p, csemask = x%x, emask = x%x\n",e,csemask,emask); 
    24842486#endif 
    24852487        assert(0); 
    24862488  } 
    24872489  else 
    24882490  { 
    24892491#if DEBUG 
    2490         printf("e = %p, tym = x%lx\n",e,tym); 
     2492        printf("e = %p, tym = x%x\n",e,tym); 
    24912493#endif 
    24922494        assert(0); 
    24932495  } 
    24942496 
    24952497reload:                                 /* reload result from memory    */ 
    24962498    switch (e->Eoper) 
    24972499    { 
    24982500        case OPrelconst: 
    24992501            c = cdrelconst(e,pretregs); 
    25002502            break; 
    25012503#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 
    25022504        case OPgot: 
    25032505            c = cdgot(e,pretregs); 
    25042506            break; 
    25052507#endif 
    25062508        default: 
    25072509            c = loaddata(e,pretregs); 
    25082510            break; 
    25092511    } 
    25102512    cssave(e,*pretregs,FALSE); 
  • branches/dmd-1.x/src/backend/cod1.c

    r577 r579  
    11// Copyright (C) 1984-1998 by Symantec 
    22// Copyright (C) 2000-2010 by Digital Mars 
    33// All Rights Reserved 
    44// http://www.digitalmars.com 
    55// Written by Walter Bright 
    66/* 
    77 * This source file is made available for personal use 
    88 * only. The license is in /dmd/src/dmd/backendlicense.txt 
    99 * or /dm/src/dmd/backendlicense.txt 
    1010 * For any other uses, please contact Digital Mars. 
    1111 */ 
    1212 
    1313#if !SPP 
    1414 
    1515#include        <stdio.h> 
    1616#include        <string.h> 
     17#include        <stdlib.h> 
    1718#include        <time.h> 
    1819#include        "cc.h" 
    1920#include        "el.h" 
    2021#include        "oper.h" 
    2122#include        "code.h" 
    2223#include        "global.h" 
    2324#include        "type.h" 
    2425 
    2526static char __file__[] = __FILE__;      /* for tassert.h                */ 
    2627#include        "tassert.h" 
    2728 
    2829targ_size_t paramsize(elem *e,unsigned stackalign); 
    2930STATIC code * funccall (elem *,unsigned,unsigned,regm_t *,regm_t); 
    3031 
    3132/* array to convert from index register to r/m field    */ 
    3233                                       /* AX CX DX BX SP BP SI DI       */ 
    3334static const signed char regtorm32[8] = {  0, 1, 2, 3,-1, 5, 6, 7 }; 
    3435             signed char regtorm  [8] = { -1,-1,-1, 7,-1, 6, 4, 5 }; 
    3536 
    3637/************************** 
     
    309310        stackpushsave = stackpush; 
    310311        stackcleansave = cgstate.stackclean; 
    311312        cgstate.stackclean = 0;                         // defer cleaning of stack 
    312313        c = cat(c,codelem(e,pretregs,constflag)); 
    313314        assert(cgstate.stackclean == 0); 
    314315        cgstate.stackclean = stackcleansave; 
    315316        c = genstackclean(c,stackpush - stackpushsave,*pretregs);       // do defered cleaning 
    316317    } 
    317318    return c; 
    318319} 
    319320 
    320321/******************************************** 
    321322 * Gen a save/restore sequence for mask of registers. 
    322323 */ 
    323324 
    324325void gensaverestore2(regm_t regm,code **csave,code **crestore) 
    325326{ 
    326327    code *cs1 = *csave; 
    327328    code *cs2 = *crestore; 
    328329 
     330    //printf("gensaverestore2(%x)\n", regm); 
    329331    regm &= mBP | mES | ALLREGS; 
    330332    for (int i = 0; regm; i++) 
    331333    { 
    332334        if (regm & 1) 
    333335        { 
    334336            if (i == ES) 
    335337            { 
    336338                cs1 = gen1(cs1, 0x06);                  // PUSH ES 
    337339                cs2 = cat(gen1(CNIL, 0x07),cs2);        // POP  ES 
    338340            } 
    339341            else 
    340342            { 
    341343                cs1 = gen1(cs1,0x50 + (i & 7));         // PUSH i 
    342344                code *c = gen1(NULL, 0x58 + (i & 7));   // POP  i 
    343345                if (i & 8) 
    344346                {   code_orrex(cs1, REX_B); 
    345347                    code_orrex(c, REX_B); 
    346348                } 
    347349                cs2 = cat(c,cs2); 
    348350            } 
     
    16481650        } 
    16491651    } 
    16501652    return c; 
    16511653} 
    16521654 
    16531655 
    16541656/***************************** 
    16551657 * Given a result in registers, test it for TRUE or FALSE. 
    16561658 * Will fail if TYfptr and the reg is ES! 
    16571659 * If saveflag is TRUE, preserve the contents of the 
    16581660 * registers. 
    16591661 */ 
    16601662 
    16611663code *tstresult(regm_t regm,tym_t tym,unsigned saveflag) 
    16621664{ 
    16631665  unsigned scrreg;                      /* scratch register             */ 
    16641666  regm_t scrregm; 
    16651667 
    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 
    16711673  assert(regm & (mBP | ALLREGS)); 
    16721674  tym = tybasic(tym); 
    16731675  code *ce = CNIL; 
    16741676  unsigned reg = findreg(regm); 
    16751677  unsigned sz = tysize[tym]; 
    16761678  if (sz == 1) 
    16771679  {     assert(regm & BYTEREGS); 
    16781680        return genregs(ce,0x84,reg,reg);        // TEST regL,regL 
    16791681  } 
    16801682  if (sz <= REGSIZE) 
    16811683  { 
    16821684    if (!I16) 
    16831685    { 
    16841686        if (tym == TYfloat) 
    16851687        {   if (saveflag) 
    16861688            { 
    16871689                scrregm = allregs & ~regm;              /* possible scratch regs */ 
    16881690                ce = allocreg(&scrregm,&scrreg,TYoffset); /* allocate scratch reg */ 
     
    22922294 
    22932295/******************************* 
    22942296 * Generate code sequence for function call. 
    22952297 */ 
    22962298 
    22972299code *cdfunc(elem *e,regm_t *pretregs) 
    22982300{ unsigned numpara = 0; 
    22992301  unsigned stackpushsave; 
    23002302  unsigned preg; 
    23012303  regm_t keepmsk; 
    23022304  unsigned numalign = 0; 
    23032305  code *c; 
    23042306 
    23052307  //printf("cdfunc()\n"); elem_print(e); 
    23062308  assert(e); 
    23072309  stackpushsave = stackpush;            /* so we can compute # of parameters */ 
    23082310  cgstate.stackclean++; 
    23092311  c = CNIL; 
    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: 
    23232327                    stackalign = 2; 
    23242328                    goto Ldefault; 
    23252329                case TYmfunc: 
    23262330                case TYjfunc: 
    23272331                    // last parameter goes into register 
    23282332                    elem *ep; 
    23292333                    for (ep = e->E2; ep->Eoper == OPparam; ep = ep->E2) 
    23302334                    { 
    23312335                        numpara += paramsize(ep->E1,stackalign); 
    23322336                    } 
    23332337                    if (tyf == TYjfunc && 
    23342338                        // This must match type_jparam() 
    23352339                        !(tyjparam(ep->Ety) || 
    23362340                          ((tybasic(ep->Ety) == TYstruct || tybasic(ep->Ety) == TYarray) && ep->Enumbytes <= intsize && ep->Enumbytes != 3 && ep->Enumbytes) 
    23372341                         ) 
    23382342                        ) 
    23392343                    { 
    23402344                        numpara += paramsize(ep,stackalign); 
     
    23482352            assert((numpara & (REGSIZE - 1)) == 0); 
    23492353            assert((stackpush & (REGSIZE - 1)) == 0); 
    23502354 
    23512355            /* Adjust start of the stack so after all args are pushed, 
    23522356             * the stack will be aligned. 
    23532357             */ 
    23542358            if (STACKALIGN == 16 && (numpara + stackpush) & (STACKALIGN - 1)) 
    23552359            { 
    23562360                numalign = STACKALIGN - ((numpara + stackpush) & (STACKALIGN - 1)); 
    23572361                c = genc2(NULL,0x81,modregrm(3,5,SP),numalign); // SUB ESP,numalign 
    23582362                if (I64) 
    23592363                    code_orrex(c, REX_W); 
    23602364                c = genadjesp(c, numalign); 
    23612365                stackpush += numalign; 
    23622366                stackpushsave += numalign; 
    23632367            } 
    23642368 
    23652369            switch (tyf) 
    23662370            {   case TYf16func: 
    23672371                    stackalign = 2; 
    2368                     break
     2372                    goto Ldefault2
    23692373                case TYmfunc:   // last parameter goes into ECX 
    23702374                    preg = CX; 
    23712375                    goto L1; 
    23722376                case TYjfunc:   // last parameter goes into EAX 
    23732377                    preg = AX; 
    23742378                    goto L1; 
    23752379 
    23762380                L1: 
    2377                     elem *ep; 
     2380                {   elem *ep; 
     2381                    elem *en; 
    23782382                    for (ep = e->E2; ep->Eoper == OPparam; ep = en) 
    23792383                    { 
    23802384                        c = cat(c,params(ep->E1,stackalign)); 
    23812385                        en = ep->E2; 
    23822386                        freenode(ep); 
    2383                         ep = en; 
    23842387                    } 
    23852388                    if (tyf == TYjfunc && 
    23862389                        // This must match type_jparam() 
    23872390                        !(tyjparam(ep->Ety) || 
    23882391                          ((tybasic(ep->Ety) == TYstruct || tybasic(ep->Ety) == TYarray) && ep->Enumbytes <= intsize && ep->Enumbytes != 3 && ep->Enumbytes) 
    23892392                         ) 
    23902393                        ) 
    23912394                    { 
    23922395                        c = cat(c,params(ep,stackalign)); 
    23932396                        goto Lret; 
    23942397                    } 
    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; 
    24002403 
    24012404                        code *c1 = getregs(retregs); 
    24022405                        // LEA preg,np[ESP] 
    24032406                        unsigned np = stackpush - ep->EV.Vuns;   // stack delta to parameter 
    24042407                        c2 = genc1(CNIL,0x8D,(modregrm(0,4,SP) << 8) | modregrm(2,preg,4),FLconst,np); 
    24052408                        if (I64) 
    24062409                            code_orrex(c2, REX_W); 
    24072410                        c = cat3(c,c1,c2); 
    24082411                    } 
    24092412                    else 
    24102413                    {   code *cp = codelem(ep,&retregs,FALSE); 
    24112414                        c = cat(c,cp); 
    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 
    24192546    { 
    24202547        /* Adjust start of the stack so 
    24212548         * the stack will be aligned. 
    24222549         */ 
    24232550        if (STACKALIGN == 16 && (stackpush) & (STACKALIGN - 1)) 
    24242551        { 
    24252552            numalign = STACKALIGN - ((stackpush) & (STACKALIGN - 1)); 
    24262553            c = genc2(NULL,0x81,modregrm(3,5,SP),numalign); // SUB ESP,numalign 
    24272554            if (I64) 
    24282555                code_orrex(c, REX_W); 
    24292556            c = genadjesp(c, numalign); 
    24302557            stackpush += numalign; 
    24312558            stackpushsave += numalign; 
    24322559        } 
    24332560 
    24342561    } 
    24352562Lret: 
    24362563    cgstate.stackclean--; 
    2437     if (!I16) 
     2564    if (I16) 
     2565        numpara = stackpush - stackpushsave; 
     2566    else 
    24382567    { 
    24392568        if (numpara != stackpush - stackpushsave) 
    24402569            printf("numpara = %d, stackpush = %d, stackpushsave = %d\n", 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} 
    24472574 
    24482575/*********************************** 
    24492576 */ 
    24502577 
    24512578code *cdstrthis(elem *e,regm_t *pretregs) 
    24522579{ 
    24532580    code *c1; 
    24542581    code *c2; 
    24552582 
    24562583    assert(tysize(e->Ety) == REGSIZE); 
    24572584    unsigned reg = findreg(*pretregs & allregs); 
    24582585    c1 = getregs(mask[reg]); 
    24592586    // LEA reg,np[ESP] 
    24602587    unsigned np = stackpush - e->EV.Vuns;        // stack delta to parameter 
    24612588    c2 = genc1(CNIL,0x8D,(modregrm(0,4,SP) << 8) | modregxrm(2,reg,4),FLconst,np); 
    24622589    if (I64) 
    24632590        code_orrex(c2, REX_W); 
    24642591    return cat3(c1,c2,fixresult(e,mask[reg],pretregs)); 
  • branches/dmd-1.x/src/backend/cod2.c

    r577 r579  
    37203720                fl = FLcsdata; 
    37213721            c = gen2(c,0x8C,            /* MOV mreg,SEG REGISTER        */ 
    37223722                modregrm(3,segfl[fl],mreg)); 
    37233723        } 
    37243724        if (*pretregs & mES) 
    37253725                gen2(c,0x8E,modregrm(3,0,mreg));        /* MOV ES,mreg  */ 
    37263726  } 
    37273727  return cat(c,getoffset(e,lreg)); 
    37283728} 
    37293729 
    37303730/********************************* 
    37313731 * Load the offset portion of the address represented by e into 
    37323732 * reg. 
    37333733 */ 
    37343734 
    37353735code *getoffset(elem *e,unsigned reg) 
    37363736{ code cs; 
    37373737  code *c; 
    37383738 
    37393739  cs.Iflags = 0; 
    3740   unsigned char rex = I64 ? REX_W : 0; 
     3740  unsigned char rex = 0; 
    37413741  cs.Irex = rex; 
    37423742  assert(e->Eoper == OPvar || e->Eoper == OPrelconst); 
    37433743  enum FL fl = el_fl(e); 
    37443744  switch (fl) 
    37453745  { 
    37463746    case FLdatseg: 
    37473747        cs.IEV2._EP.Vpointer = e->EV.Vpointer; 
    37483748        goto L3; 
    37493749 
    37503750    case FLfardata: 
    37513751        assert(!TARGET_FLAT); 
    37523752        goto L4; 
    37533753 
    37543754    case FLtlsdata: 
    37553755#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 
    37563756    {   /* Generate: 
    37573757         *      MOV reg,GS:[00000000] 
    37583758         *      ADD reg, offset s@TLS_LE 
    37593759         * for locals, and for globals: 
    37603760         *      MOV reg,GS:[00000000] 
  • branches/dmd-1.x/src/backend/cod3.c

    r577 r579  
    11591159    {   p[0] = len; 
    11601160        memcpy(p + 1,name,len); 
    11611161        len++; 
    11621162    } 
    11631163    return len; 
    11641164} 
    11651165#endif 
    11661166 
    11671167/******************************* 
    11681168 * Generate code for a function start. 
    11691169 * Input: 
    11701170 *      Coffset         address of start of code 
    11711171 * Output: 
    11721172 *      Coffset         adjusted for size of code generated 
    11731173 *      EBPtoESP 
    11741174 *      hasframe 
    11751175 *      BPoff 
    11761176 */ 
    11771177 
    11781178code *prolog() 
    1179 {   code *c; 
     1179{ 
    11801180    SYMIDX si; 
    11811181    unsigned reg; 
    1182     regm_t topush; 
    1183     tym_t tym; 
    1184     tym_t tyf; 
    11851182    char enter; 
    1186     char pushds; 
    1187     unsigned farfunc; 
    11881183    unsigned Foffset; 
    11891184    unsigned xlocalsize;     // amount to subtract from ESP to make room for locals 
    1190     int pushalloc; 
    11911185    unsigned pushallocreg; 
    11921186    char guessneedframe; 
    11931187 
    11941188    //printf("cod3.prolog(), needframe = %d, Aalign = %d\n", needframe, Aalign); 
    11951189    debugx(debugw && printf("funcstart()\n")); 
    11961190    regcon.immed.mval = 0;                      /* no values in registers yet   */ 
    11971191    EBPtoESP = -REGSIZE; 
    11981192    hasframe = 0; 
    1199     pushds = 0; 
     1193    char pushds = 0; 
    12001194    BPoff = 0; 
    1201     c = CNIL; 
    1202     pushalloc = 0; 
    1203     tyf = funcsym_p->ty(); 
    1204     tym = tybasic(tyf); 
    1205     farfunc = tyfarfunc(tym); 
     1195    code *c = CNIL; 
     1196    int pushalloc = 0; 
     1197    tym_t tyf = funcsym_p->ty(); 
     1198    tym_t tym = tybasic(tyf); 
     1199    unsigned farfunc = tyfarfunc(tym); 
    12061200    pushallocreg = (tyf == TYmfunc) ? CX : AX; 
    12071201    if (config.flags & CFGalwaysframe || funcsym_p->Sfunc->Fflags3 & Ffakeeh) 
    12081202        needframe = 1; 
    12091203 
    12101204Lagain: 
    12111205    guessneedframe = needframe; 
    12121206//    if (needframe && config.exe & (EX_LINUX | EX_FREEBSD | EX_SOLARIS) && !(usednteh & ~NTEHjmonitor)) 
    12131207//      usednteh |= NTEHpassthru; 
    12141208 
    12151209    /* Compute BP offsets for variables on stack. 
    12161210     * The organization is: 
    12171211     *  Poff    parameters 
    12181212     *          seg of return addr      (if far function) 
    12191213     *          IP of return addr 
    12201214     *  BP->    caller's BP 
    12211215     *          DS                      (if Windows prolog/epilog) 
    12221216     *          exception handling context symbol 
    12231217     *  Aoff    autos and regs 
    12241218     *  Foff    floating register 
    12251219     *  AAoff   alloca temporary 
     
    12511245 
    12521246    if (Aalign > REGSIZE) 
    12531247    { 
    12541248        // Adjust Aoff so that it is Aalign byte aligned, assuming that 
    12551249        // before function parameters were pushed the stack was 
    12561250        // Aalign byte aligned 
    12571251        int sz = Poffset + -Aoff + Poff + (needframe ? 0 : REGSIZE); 
    12581252        if (sz & (Aalign - 1)) 
    12591253            Aoff -= sz - (sz & (Aalign - 1)); 
    12601254    } 
    12611255 
    12621256    Foffset = floatreg ? DOUBLESIZE : 0; 
    12631257    Foff = Aoff - align(0,Foffset); 
    12641258    assert(usedalloca != 1); 
    12651259    AAoff = usedalloca ? (Foff - REGSIZE) : Foff; 
    12661260    CSoff = AAoff - align(0,cstop * REGSIZE); 
    12671261    NDPoff = CSoff - align(0,NDP::savetop * NDPSAVESIZE); 
    12681262    Toff = NDPoff - align(0,Toffset); 
    12691263    localsize = -Toff; 
    12701264 
    1271     topush = fregsaved & ~mfuncreg;     // mask of registers that need saving 
     1265    regm_t topush = fregsaved & ~mfuncreg;     // mask of registers that need saving 
    12721266    int npush = 0;                      // number of registers that need saving 
    12731267    for (regm_t x = topush; x; x >>= 1) 
    12741268        npush += x & 1; 
    12751269 
    12761270    // Keep the stack aligned by 8 for any subsequent function calls 
    12771271    if (!I16 && calledafunc && 
    12781272        (STACKALIGN == 16 || config.flags4 & CFG4stackalign)) 
    12791273    { 
    12801274        //printf("npush = %d Poff = x%x needframe = %d localsize = x%x\n", npush, Poff, needframe, localsize); 
    12811275 
    12821276        int sz = Poff + (needframe ? 0 : -REGSIZE) + localsize + npush * REGSIZE; 
    12831277        if (STACKALIGN == 16) 
    12841278        { 
    12851279            if (sz & (8|4)) 
    12861280                localsize += STACKALIGN - (sz & (8|4)); 
    12871281        } 
    12881282        else if (sz & 4) 
    12891283            localsize += 4; 
    12901284    } 
    12911285 
     
    13331327                farfunc || 
    13341328                config.flags & CFGstack || 
    13351329                xlocalsize >= 0x1000 || 
    13361330                (usednteh & ~NTEHjmonitor) || 
    13371331                anyiasm || 
    13381332                usedalloca 
    13391333               ) 
    13401334                needframe = 1; 
    13411335        } 
    13421336        if (refparam && (anyiasm || I16)) 
    13431337            needframe = 1; 
    13441338    } 
    13451339 
    13461340    if (needframe) 
    13471341    {   assert(mfuncreg & mBP);         // shouldn't have used mBP 
    13481342 
    13491343        if (!guessneedframe)            // if guessed wrong 
    13501344            goto Lagain; 
    13511345    } 
    13521346 
    1353 #if SIXTEENBIT 
    1354     if (config.wflags & WFwindows && farfunc) 
     1347    if (I16 && config.wflags & WFwindows && farfunc) 
    13551348    {   int wflags; 
    13561349        int segreg; 
    13571350 
     1351#if SCPP 
    13581352        // alloca() can't be because the 'special' parameter won't be at 
    13591353        // a known offset from BP. 
    13601354        if (usedalloca == 1) 
    13611355            synerr(EM_alloca_win);      // alloca() can't be in Windows functions 
     1356#endif 
    13621357 
    13631358        wflags = config.wflags; 
    13641359        if (wflags & WFreduced && !(tyf & mTYexport)) 
    13651360        {   // reduced prolog/epilog for non-exported functions 
    13661361            wflags &= ~(WFdgroup | WFds | WFss); 
    13671362        } 
    13681363 
    13691364        c = getregs(mAX); 
    13701365        assert(!c);                     /* should not have any value in AX */ 
    13711366 
    13721367        switch (wflags & (WFdgroup | WFds | WFss)) 
    13731368        {   case WFdgroup:                      // MOV  AX,DGROUP 
    13741369                if (wflags & WFreduced) 
    13751370                    tyf &= ~mTYloadds;          // remove redundancy 
    13761371                c = genc(c,0xC7,modregrm(3,0,AX),0,0,FLdatseg,(targ_uns) 0); 
    13771372                c->Iflags ^= CFseg | CFoff;     // turn off CFoff, on CFseg 
    13781373                break; 
    13791374            case WFss: 
    13801375                segreg = 2;                     // SS 
    13811376                goto Lmovax; 
     
    13931388                printf("config.wflags = x%x\n",config.wflags); 
    13941389#endif 
    13951390                assert(0); 
    13961391        } 
    13971392        if (wflags & WFincbp) 
    13981393            c = gen1(c,0x40 + BP);              // INC  BP 
    13991394        c = gen1(c,0x50 + BP);                  // PUSH BP 
    14001395        genregs(c,0x8B,BP,SP);                  // MOV  BP,SP 
    14011396        if (wflags & (WFsaveds | WFds | WFss | WFdgroup)) 
    14021397        {   gen1(c,0x1E);                       // PUSH DS 
    14031398            pushds = TRUE; 
    14041399            BPoff = -REGSIZE; 
    14051400        } 
    14061401        if (wflags & (WFds | WFss | WFdgroup)) 
    14071402            gen2(c,0x8E,modregrm(3,3,AX));      // MOV  DS,AX 
    14081403 
    14091404        enter = FALSE;                  /* don't use ENTER instruction  */ 
    14101405        hasframe = 1;                   /* we have a stack frame        */ 
    14111406    } 
    14121407    else 
    1413 #endif 
    14141408    if (needframe)                      // if variables or parameters 
    14151409    { 
    14161410        if (config.wflags & WFincbp && farfunc) 
    14171411            c = gen1(c,0x40 + BP);      /* INC  BP                      */ 
    14181412        if (config.target_cpu < TARGET_80286 || 
    14191413            config.exe & (EX_LINUX | EX_LINUX64 | EX_OSX | EX_OSX64 | EX_FREEBSD | EX_FREEBSD64 | EX_SOLARIS | EX_SOLARIS64) || 
    14201414            !localsize || 
    14211415            config.flags & CFGstack || 
    14221416            (xlocalsize >= 0x1000 && config.exe & EX_flat) || 
    14231417            localsize >= 0x10000 || 
    14241418#if NTEXCEPTIONS == 2 
    14251419            (usednteh & ~NTEHjmonitor && (config.flags2 & CFG2seh)) || 
    14261420#endif 
    14271421            (config.target_cpu >= TARGET_80386 && 
    14281422             config.flags4 & CFG4speed) 
    14291423           ) 
    14301424        { 
    14311425            c = gen1(c,0x50 + BP);      // PUSH BP 
    14321426            genregs(c,0x8B,BP,SP);      // MOV  BP,SP 
    14331427            if (I64) 
     
    16471641    } 
    16481642 
    16491643#if MARS 
    16501644    if (usednteh & NTEHjmonitor) 
    16511645    {   Symbol *sthis; 
    16521646 
    16531647        for (si = 0; 1; si++) 
    16541648        {   assert(si < globsym.top); 
    16551649            sthis = globsym.tab[si]; 
    16561650            if (strcmp(sthis->Sident,"this") == 0) 
    16571651                break; 
    16581652        } 
    16591653        c = cat(c,nteh_monitor_prolog(sthis)); 
    16601654        EBPtoESP += 3 * 4; 
    16611655    } 
    16621656#endif 
    16631657 
    16641658    while (topush)                      /* while registers to push      */ 
    16651659    {   reg = findreg(topush); 
    16661660        topush &= ~mask[reg]; 
    1667         c = gen1(c,0x50 + reg); 
     1661        c = gen1(c,0x50 + (reg & 7)); 
     1662        if (reg & 8) 
     1663            code_orrex(c, REX_B); 
    16681664        EBPtoESP += REGSIZE; 
    16691665#if ELFOBJ || MACHOBJ 
    16701666        if (config.fulltypes) 
    16711667        {   // Emit debug_frame data giving location of saved register 
    16721668            // relative to 0[EBP] 
    16731669            pinholeopt(c, NULL); 
    16741670            dwarf_CFA_set_loc(calcblksize(c));  // address after PUSH reg 
    16751671            dwarf_CFA_offset(reg, -EBPtoESP - REGSIZE); 
    16761672        } 
    16771673#endif 
    16781674    } 
    16791675 
    16801676Lcont: 
    16811677 
    16821678    /* Determine if we need to reload DS        */ 
    16831679    if (tyf & mTYloadds) 
    16841680    {   code *c1; 
    16851681 
    16861682        if (!pushds)                            // if not already pushed 
    16871683            c = gen1(c,0x1E);                   // PUSH DS 
     
    19001896    if (tyf & mTYloadds) 
    19011897    {   cpopds = gen1(cpopds,0x1F);             // POP DS 
    19021898        c = cat(c,cpopds); 
    19031899        spoff += intsize; 
    19041900    } 
    19051901 
    19061902    /* Pop all the general purpose registers saved on the stack 
    19071903     * by the prolog code. Remember to do them in the reverse 
    19081904     * order they were pushed. 
    19091905     */ 
    19101906    reg = I64 ? R15 : DI; 
    19111907    regm = 1 << reg; 
    19121908    topop = fregsaved & ~mfuncreg; 
    19131909#ifdef DEBUG 
    19141910    if (topop & ~0xFFFF) 
    19151911        printf("fregsaved = x%x, mfuncreg = x%x\n",fregsaved,mfuncreg); 
    19161912#endif 
    19171913    assert(!(topop & ~0xFFFF)); 
    19181914    while (topop) 
    19191915    {   if (topop & regm) 
    1920         {   c = gen1(c,0x58 + reg);         // POP reg 
     1916        {   c = gen1(c,0x58 + (reg & 7));         // POP reg 
    19211917            if (reg & 8) 
    19221918                code_orrex(c, REX_B); 
    19231919            topop &= ~regm; 
    19241920            spoff += intsize; 
    19251921        } 
    19261922        regm >>= 1; 
    19271923        reg--; 
    19281924    } 
    19291925 
    19301926#if MARS 
    19311927    if (usednteh & NTEHjmonitor) 
    19321928    { 
    19331929        regm_t retregs = 0; 
    19341930        if (b->BC == BCretexp) 
    19351931            retregs = regmask(b->Belem->Ety, tym); 
    19361932        code *cn = nteh_monitor_epilog(retregs); 
    19371933        c = cat(c,cn); 
    19381934        xlocalsize += 8; 
    19391935    } 
    19401936#endif 
     
    43424338#ifdef DEBUG 
    43434339        assert(uev->Vblock->Boffset > OFFSET() || c != 0x7F); 
    43444340#endif 
    43454341        break; 
    43464342    default: 
    43474343#ifdef DEBUG 
    43484344        fprintf(stderr,"fl = %d\n",fl); 
    43494345#endif 
    43504346        assert(0); 
    43514347  } 
    43524348  GEN(c); 
    43534349} 
    43544350 
    43554351 
    43564352/**************************** 
    43574353 * Add to the fix list. 
    43584354 */ 
    43594355 
    43604356void addtofixlist(symbol *s,targ_size_t soffset,int seg,targ_size_t val,int flags) 
    43614357{       fixlist *ln; 
    4362         static char zeros[6]; 
     4358        static char zeros[8]; 
    43634359        int numbytes; 
    43644360 
    43654361        //printf("addtofixlist(%p '%s')\n",s,s->Sident); 
    43664362        assert(flags); 
    43674363        ln = (fixlist *) mem_calloc(sizeof(fixlist)); 
    43684364        ln->Lsymbol = s; 
    43694365        ln->Loffset = soffset; 
    43704366        ln->Lseg = seg; 
    43714367        ln->Lflags = flags; 
    43724368        ln->Lval = val; 
    43734369#if TARGET_OSX 
    43744370        ln->Lfuncsym = funcsym_p; 
    43754371#endif 
    43764372        ln->Lnext = fixlist::start; 
    43774373        fixlist::start = ln; 
    43784374#if TARGET_FLAT 
    43794375        numbytes = tysize[TYnptr]; 
    43804376        assert(!(flags & CFseg)); 
    43814377#else 
    43824378        switch (flags & (CFoff | CFseg)) 
     
    48804876        {   printf(" linnum = %d\n",c->IEV2.Vsrcpos.Slinnum); 
    48814877            return; 
    48824878        } 
    48834879        printf(" ESCAPE %d",c->Iop2); 
    48844880  } 
    48854881  if (c->Iflags) 
    48864882        printf(" flg=%x",c->Iflags); 
    48874883  if (ins & M) 
    48884884  {     rm = c->Irm; 
    48894885        printf(" rm=%02x=%d,%d,%d",rm,(rm>>6)&3,(rm>>3)&7,rm&7); 
    48904886        if (I32 && issib(rm)) 
    48914887        {   unsigned char sib = c->Isib; 
    48924888            printf(" sib=%02x=%d,%d,%d",sib,(sib>>6)&3,(sib>>3)&7,sib&7); 
    48934889        } 
    48944890        if ((rm & 0xC7) == BPRM || (rm & 0xC0) == 0x80 || (rm & 0xC0) == 0x40) 
    48954891        { 
    48964892            switch (c->IFL1) 
    48974893            { 
    48984894                case FLconst: 
    48994895                case FLoffset: 
    4900                     printf(" int = %4ld",c->IEV1.Vuns); 
     4896                    printf(" int = %4d",c->IEV1.Vuns); 
    49014897                    break; 
    49024898                case FLblock: 
    49034899                    printf(" block = %p",c->IEV1.Vblock); 
    49044900                    break; 
    49054901                case FLswitch: 
    49064902                case FLblockoff: 
    49074903                case FLlocalsize: 
    49084904                case FLframehandler: 
    49094905                case 0: 
    49104906                    break; 
    49114907                case FLdatseg: 
    49124908                    printf(" %d.%lx",c->IEVseg1,c->IEVpointer1); 
    49134909                    break; 
    49144910                case FLauto: 
    49154911                case FLreg: 
    49164912                case FLdata: 
    49174913                case FLudata: 
    49184914                case FLpara: 
    49194915                case FLtmp: 
    49204916                case FLbprel: 
    49214917                case FLtlsdata: 
    49224918                    printf(" sym='%s'",c->IEVsym1->Sident); 
    49234919                    break; 
    49244920                default: 
    49254921                    WRFL((enum FL)c->IFL1); 
    49264922                    break; 
    49274923            } 
    49284924        } 
    49294925  } 
    49304926  if (ins & T) 
    49314927  {     printf(" "); WRFL((enum FL)c->IFL2); 
    49324928        switch (c->IFL2) 
    49334929        { 
    49344930            case FLconst: 
    4935                 printf(" int = %4ld",c->IEV2.Vuns); 
     4931                printf(" int = %4d",c->IEV2.Vuns); 
    49364932                break; 
    49374933            case FLblock: 
    49384934                printf(" block = %p",c->IEV2.Vblock); 
    49394935                break; 
    49404936            case FLswitch: 
    49414937            case FLblockoff: 
    49424938            case 0: 
    49434939            case FLlocalsize: 
    49444940            case FLframehandler: 
    49454941                break; 
    49464942            case FLdatseg: 
    49474943                printf(" %d.%lx",c->IEVseg2,c->IEVpointer2); 
    49484944                break; 
    49494945            case FLauto: 
    49504946            case FLreg: 
    49514947            case FLpara: 
    49524948            case FLtmp: 
    49534949            case FLbprel: 
    49544950            case FLfunc: 
    49554951            case FLdata: 
  • branches/dmd-1.x/src/backend/elfobj.c

    r572 r579  
    27012701            offset = (foffset + 31) & ~31; 
    27022702            break; 
    27032703        default: 
    27042704            dbg_printf("size was %d\n",(int)size); 
    27052705            assert(0); 
    27062706            break; 
    27072707    } 
    27082708    if (offset > foffset) 
    27092709        fobjbuf->writezeros(offset - foffset); 
    27102710    return offset; 
    27112711} 
    27122712 
    27132713/*************************************** 
    27142714 * Stuff pointer to ModuleInfo in its own segment. 
    27152715 */ 
    27162716 
    27172717#if MARS 
    27182718 
    27192719void obj_moduleinfo(Symbol *scc) 
    27202720{ 
     2721//    if (I64) return;          // for now, until Phobos64 works 
     2722 
    27212723    int codeOffset, refOffset; 
    27222724 
    27232725    /* Put in the ModuleReference. */ 
    27242726    { 
    27252727        /* struct ModuleReference 
    27262728         * { 
    27272729         *      void*   next; 
    27282730         *      ModuleReference* module; 
    27292731         * } 
    27302732         */ 
    27312733        const int seg = DATA; 
    27322734        alignOffset(seg, NPTRSIZE); 
    27332735        SegData[seg]->SDoffset = SegData[seg]->SDbuf->size(); 
    27342736        refOffset = SegData[seg]->SDoffset; 
    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 
    27412742    /* Constructor that links the ModuleReference to the head of 
    27422743     * the list pointed to by _Dmoduleref 
    27432744     */ 
    27442745    { 
    27452746        /*      ret 
    27462747         * codeOffset: 
    27472748         *      pushad 
    27482749         *      mov     EAX,&ModuleReference 
    27492750         *      mov     ECX,_DmoduleRef 
    27502751         *      mov     EDX,[ECX] 
    27512752         *      mov     [EAX],EDX 
    27522753         *      mov     [ECX],EAX 
    27532754         *      popad 
    27542755         *      ret 
    27552756         */ 
    27562757 
    27572758        const int reltype = I64 ? R_X86_64_32 : RI_TYPE_SYM32; 
    27582759        const int refsize = 4;                          // use 32 bit relocations, even in 64 bit mode 
    27592760 
    27602761        const int seg = CODE; 
    27612762        Outbuffer *buf = SegData[seg]->SDbuf; 
    27622763        SegData[seg]->SDoffset = buf->size(); 
    27632764        codeOffset = SegData[seg]->SDoffset + 1; 
    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 */ 
    27792784        buf->writeByte(0x89); buf->writeByte(0x10); /* movl %edx, (%eax) */ 
    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(); 
    27852790    } 
    27862791 
    27872792    /* Add reference to constructor into ".ctors" segment 
    27882793     */ 
    27892794    const int seg = elf_getsegment(".ctors", NULL, SHT_PROGDEF, SHF_ALLOC|SHF_WRITE, NPTRSIZE); 
    27902795 
    27912796    Outbuffer *buf = SegData[seg]->SDbuf; 
    27922797    buf->write32(codeOffset); 
    27932798    elf_addrel(seg, SegData[seg]->SDoffset, I64 ? R_X86_64_64 : RI_TYPE_SYM32, STI_TEXT, 0); 
    27942799    SegData[seg]->SDoffset += NPTRSIZE; 
    27952800} 
    27962801 
    27972802#endif 
    27982803 
    27992804/************************************* 
    28002805 */ 
    28012806 
    28022807void elfobj_gotref(symbol *s) 
  • branches/dmd-1.x/src/backend/el.h

    r572 r579  
    2626/****************************************** 
    2727 * Elems: 
    2828 *      Elems are the basic tree element. They can be either 
    2929 *      terminal elems (leaves), unary elems (left subtree exists) 
    3030 *      or binary elems (left and right subtrees exist). 
    3131 */ 
    3232 
    3333struct elem 
    3434{ 
    3535#ifdef DEBUG 
    3636    unsigned short      id; 
    3737#define IDelem 0x4C45   // 'EL' 
    3838#define elem_debug(e) assert((e)->id == IDelem) 
    3939#else 
    4040#define elem_debug(e) 
    4141#endif 
    4242 
    4343    unsigned char Eoper;        // operator (OPxxxx) 
    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 
    4851    { 
    4952        // PARSER 
    5053        struct 
    5154        { 
    5255            struct TYPE *ET_;   // pointer to type of elem 
    5356            #define ET _EU._EP.ET_ 
    5457 
    5558            unsigned PEFflags_; 
    5659            #define PEFflags _EU._EP.PEFflags_ 
    5760                #define PEFnotlvalue    1       // although elem may look like 
    5861                                                // an lvalue, it isn't 
    5962                #define PEFtemplate_id  0x10    // symbol is a template-id 
    6063                #define PEFparentheses  0x20    // expression was within () 
    6164                #define PEFaddrmem      0x40    // address of member 
    6265                #define PEFdependent    0x80    // value-dependent 
    6366                #define PEFmember       0x100   // was a class member access 
    6467#if !TX86 
    6568                #define PEFdblldbl      2       // long double return from dbl func 
  • branches/dmd-1.x/src/backend/symbol.c

    r487 r579  
    346346Symbol *symbol_genauto(elem *e) 
    347347{ 
    348348    return symbol_genauto(type_fake(e->Ety)); 
    349349} 
    350350 
    351351/****************************************** 
    352352 * Generate symbol into which we can copy the contents of expression e. 
    353353 */ 
    354354 
    355355Symbol *symbol_genauto(tym_t ty) 
    356356{ 
    357357    return symbol_genauto(type_fake(ty)); 
    358358} 
    359359 
    360360/**************************************** 
    361361 * Add in the variants for a function symbol. 
    362362 */ 
    363363 
    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; 
    368369    // Interrupt functions modify all registers 
    369370#if TX86 
    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 
    374376#endif 
    375377    if (!s->Sfunc) 
    376378        s->Sfunc = func_calloc(); 
    377379} 
    378380 
    379381/******************************** 
    380382 * Define symbol in specified symbol table. 
    381383 * Returns: 
    382384 *      pointer to symbol 
    383385 */ 
    384386 
    385387#if SCPP 
    386388 
    387389symbol * defsy(const char *p,symbol **parent) 
    388390{ 
    389391   symbol *s = symbol_calloc(p); 
    390392   symbol_addtotree(parent,s); 
    391393   return s; 
  • branches/dmd-1.x/src/backend/ty.h

    r557 r579  
    180180#define TYFLref         0x8000 
    181181 
    182182/* Groupings of types   */ 
    183183 
    184184#define tyintegral(ty)  (tytab[(ty) & 0xFF] & TYFLintegral) 
    185185 
    186186#define tyarithmetic(ty) (tytab[(ty) & 0xFF] & (TYFLintegral | TYFLreal | TYFLimaginary | TYFLcomplex)) 
    187187 
    188188#define tyaggregate(ty) (tytab[(ty) & 0xFF] & TYFLaggregate) 
    189189 
    190190#define tyscalar(ty)    (tytab[(ty) & 0xFF] & (TYFLintegral | TYFLreal | TYFLimaginary | TYFLcomplex | TYFLptr | TYFLmptr | TYFLnullptr)) 
    191191 
    192192#define tyfloating(ty)  (tytab[(ty) & 0xFF] & (TYFLreal | TYFLimaginary | TYFLcomplex)) 
    193193 
    194194#define tyimaginary(ty) (tytab[(ty) & 0xFF] & TYFLimaginary) 
    195195 
    196196#define tycomplex(ty)   (tytab[(ty) & 0xFF] & TYFLcomplex) 
    197197 
    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       */ 
    202205#define tyshort(ty)     (tytab[(ty) & 0xFF] & TYFLshort) 
    203206#endif 
    204207 
    205208/* Detect TYlong or TYulong     */ 
    206209#ifndef tylong 
    207210#define tylong(ty)      (tybasic(ty) == TYlong || tybasic(ty) == TYulong) 
    208211#endif 
    209212 
    210213/* Use to detect a pointer type */ 
    211214#ifndef typtr 
    212215#define typtr(ty)       (tytab[(ty) & 0xFF] & TYFLptr) 
    213216#endif 
    214217 
    215218/* Use to detect a reference type */ 
    216219#ifndef tyref 
    217220#define tyref(ty)       (tytab[(ty) & 0xFF] & TYFLref) 
    218221#endif 
    219222 
  • branches/dmd-1.x/src/e2ir.c

    r569 r579  
    263263            ep->Ety = tyret; 
    264264            e = ep; 
    265265            if (op == OPscale) 
    266266            { 
    267267                elem *et = e->E1; 
    268268                e->E1 = el_una(OPs32_d, TYdouble, e->E2); 
    269269                e->E1 = el_una(OPd_ld, TYldouble, e->E1); 
    270270                e->E2 = et; 
    271271            } 
    272272            else if (op == OPyl2x || op == OPyl2xp1) 
    273273            { 
    274274                elem *et = e->E1; 
    275275                e->E1 = e->E2; 
    276276                e->E2 = et; 
    277277            } 
    278278        } 
    279279        else 
    280280            e = el_una(op,tyret,ep); 
    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) 
    288294    { 
    289295        e->Ety = TYnptr; 
    290296        e = el_una(OPind, tyret, e); 
    291297    } 
    292298 
    293299#if DMDV2 
    294300    if (tf->isref) 
    295301    { 
    296302        e->Ety = TYnptr; 
    297303        e = el_una(OPind, tyret, e); 
    298304    } 
    299305#endif 
    300306 
    301307    if (tybasic(tyret) == TYstruct) 
    302308    { 
    303309        e->Enumbytes = tret->size(); 
    304310    } 
    305311    e = el_combine(eside, e); 
     
    17561762        { 
    17571763            elem *ep; 
    17581764            CatExp *ce = this; 
    17591765            int n = 2; 
    17601766 
    17611767            ep = eval_Darray(irs, ce->e2); 
    17621768            do 
    17631769            { 
    17641770                n++; 
    17651771                ce = (CatExp *)ce->e1; 
    17661772                ep = el_param(ep, eval_Darray(irs, ce->e2)); 
    17671773            } while (ce->e1->op == TOKcat); 
    17681774            ep = el_param(ep, eval_Darray(irs, ce->e1)); 
    17691775#if 1 
    17701776            ep = el_params( 
    17711777                           ep, 
    17721778                           el_long(TYint, n), 
    17731779                           ta->getTypeInfo(NULL)->toElem(irs), 
    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( 
    17781785                           ep, 
    17791786                           el_long(TYint, n), 
    17801787                           el_long(TYint, tn->size()), 
    17811788                           NULL); 
    17821789            e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCATN]), ep); 
     1790            e->Eflags |= EFLAGS_variadic; 
    17831791#endif 
    17841792        } 
    17851793        else 
    17861794        { 
    17871795            elem *e1; 
    17881796            elem *e2; 
    17891797            elem *ep; 
    17901798 
    17911799            e1 = eval_Darray(irs, this->e1); 
    17921800            e2 = eval_Darray(irs, this->e2); 
    17931801#if 1 
    17941802            ep = el_params(e2, e1, ta->getTypeInfo(NULL)->toElem(irs), NULL); 
    17951803            e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCATT]), ep); 
    17961804#else 
    17971805            ep = el_params(el_long(TYint, tn->size()), e2, e1, NULL); 
    17981806            e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCAT]), ep); 
    17991807#endif 
    18001808        } 
    18011809        el_setLoc(e,loc); 
    18021810    } 
     
    42004208            } 
    42014209            args.data[dim - (i + 1)] = (void *)ep; 
    42024210        } 
    42034211 
    42044212        /* Because the number of parameters can get very large, produce 
    42054213         * a balanced binary tree so we don't blow up the stack in 
    42064214         * the subsequent tree walking code. 
    42074215         */ 
    42084216        e = el_params(args.data, dim + 1); 
    42094217    } 
    42104218    else 
    42114219    {   dim = 0; 
    42124220        e = el_long(TYint, 0); 
    42134221    } 
    42144222    Type *tb = type->toBasetype(); 
    42154223#if 1 
    42164224    e = el_param(e, type->getTypeInfo(NULL)->toElem(irs)); 
    42174225 
    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())); 
    42224231 
    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) 
    42274237    { 
    42284238        e = el_pair(TYullong, el_long(TYint, dim), e); 
    42294239    } 
    42304240    else if (tb->ty == Tpointer) 
    42314241    { 
    42324242    } 
    42334243    else 
    42344244    { 
    42354245        e = el_una(OPind,TYstruct,e); 
    42364246        e->Enumbytes = type->size(); 
    42374247    } 
    42384248 
    42394249    el_setLoc(e,loc); 
    42404250    return e; 
    42414251} 
    42424252 
    42434253 
    42444254elem *AssocArrayLiteralExp::toElem(IRState *irs) 
     
    42534263 
    42544264        for (int j = 0; j < 2; j++) 
    42554265        { 
    42564266            elem *ep = el->toElem(irs); 
    42574267 
    42584268            if (tybasic(ep->Ety) == TYstruct || tybasic(ep->Ety) == TYarray) 
    42594269            { 
    42604270                ep = el_una(OPstrpar, TYstruct, ep); 
    42614271                ep->Enumbytes = el->type->size(); 
    42624272            } 
    42634273//printf("[%d] %s\n", i, el->toChars()); 
    42644274//elem_print(ep); 
    42654275            e = el_param(ep, e); 
    42664276            el = (Expression *)values->data[i]; 
    42674277        } 
    42684278    } 
    42694279    e = el_param(e, type->getTypeInfo(NULL)->toElem(irs)); 
    42704280 
    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); 
    42754286    return e; 
    42764287} 
    42774288 
    42784289 
    42794290/******************************************* 
    42804291 * Generate elem to zero fill contents of Symbol stmp 
    42814292 * from *poffset..offset2. 
    42824293 * May store anywhere from 0..maxoff, as this function 
    42834294 * tries to use aligned int stores whereever possible. 
    42844295 * Update *poffset to end of initialized hole; *poffset will be >= offset2. 
    42854296 */ 
    42864297 
    42874298elem *fillHole(Symbol *stmp, size_t *poffset, size_t offset2, size_t maxoff) 
    42884299{   elem *e = NULL; 
    42894300    int basealign = 1; 
    42904301 
    42914302    while (*poffset < offset2) 
    42924303    {   tym_t ty; 
  • branches/dmd-1.x/src/msc.c

    r569 r579  
    2323#include        "dt.h" 
    2424#include        "cgcv.h" 
    2525 
    2626static char __file__[] = __FILE__;      /* for tassert.h                */ 
    2727#include        "tassert.h" 
    2828 
    2929extern Global global; 
    3030extern int REALSIZE; 
    3131 
    3232Config config; 
    3333Configv configv; 
    3434 
    3535struct Environment; 
    3636 
    3737/************************************** 
    3838 * Initialize config variables. 
    3939 */ 
    4040 
    4141void out_config_init() 
    4242{ 
     43    //printf("out_config_init()\n"); 
    4344    Param *params = &global.params; 
    4445 
    4546    if (!config.target_cpu) 
    4647    {   config.target_cpu = TARGET_PentiumPro; 
    4748        config.target_scheduler = config.target_cpu; 
    4849    } 
    4950    config.fulltypes = CVNONE; 
    5051    config.inline8087 = 1; 
    5152    config.memmodel = 0; 
    5253    config.flags |= CFGuchar;   // make sure TYchar is unsigned 
    5354#if TARGET_WINDOS 
    5455    if (params->isX86_64) 
    5556        config.exe = EX_WIN64; 
    5657    else 
    5758        config.exe = EX_NT; 
    5859 
    5960    // Win32 eh 
    6061    config.flags2 |= CFG2seh; 
    6162 
    6263    if (params->run) 
  • trunk/src/backend/cgcod.c

    r577 r579  
    123123    // in that basic block. 
    124124 
    125125    //printf("codgen('%s')\n",funcsym_p->Sident); 
    126126 
    127127    cgreg_init(); 
    128128    csmax = 64; 
    129129    csextab = (struct CSE *) util_calloc(sizeof(struct CSE),csmax); 
    130130    functy = tybasic(funcsym_p->ty()); 
    131131#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 
    132132    if (0 && config.flags3 & CFG3pic) 
    133133    { 
    134134        ALLREGS = ALLREGS_INIT_PIC; 
    135135        BYTEREGS = BYTEREGS_INIT_PIC; 
    136136    } 
    137137    else 
    138138    { 
    139139        regm_t value = BYTEREGS_INIT; 
    140140        ALLREGS = ALLREGS_INIT; 
    141141        BYTEREGS = value; 
    142142    } 
     143    if (I64) 
     144        ALLREGS = mAX|mBX|mCX|mDX|mSI|mDI| mR8|mR9|mR10|mR11|mR12|mR13|mR14|mR15; 
    143145#endif 
    144146    allregs = ALLREGS; 
    145147    if (0 && config.flags3 & CFG3pic) 
    146148        allregs &= ~mBX; 
    147149    pass = PASSinit; 
    148150 
    149151tryagain: 
    150152    #ifdef DEBUG 
    151153    if (debugr) 
    152154        printf("------------------ PASS%s -----------------\n", 
    153155            (pass == PASSinit) ? "init" : ((pass == PASSreg) ? "reg" : "final")); 
    154156    #endif 
    155157    lastretregs = last2retregs = last3retregs = last4retregs = last5retregs = 0; 
    156158 
    157159    // if no parameters, assume we don't need a stack frame 
    158160    needframe = 0; 
    159161    usedalloca = 0; 
    160162    gotref = 0; 
    161163    stackchanged = 0; 
    162164    stackpush = 0; 
     
    19011903                {   retregs &= mMSW; 
    19021904                    goto L3; 
    19031905                } 
    19041906            } 
    19051907            reg = (msreg == ES) ? lsreg : msreg; 
    19061908            retregs = mask[msreg] | mask[lsreg]; 
    19071909        } 
    19081910        else if (I16 && (tym == TYdouble || tym == TYdouble_alias)) 
    19091911        { 
    19101912#ifdef DEBUG 
    19111913            if (retregs != DOUBLEREGS) 
    19121914                printf("retregs = x%x, *pretregs = x%x\n",retregs,*pretregs); 
    19131915#endif 
    19141916            assert(retregs == DOUBLEREGS); 
    19151917            reg = AX; 
    19161918        } 
    19171919        else 
    19181920        { 
    19191921#ifdef DEBUG 
    19201922            WRTYxx(tym); 
    1921             printf("\nallocreg: fil %s lin %d, regcon.mvar x%x msavereg x%x *pretregs x%x, reg %d, tym x%lx\n", 
     1923            printf("\nallocreg: fil %s lin %d, regcon.mvar x%x msavereg x%x *pretregs x%x, reg %d, tym x%x\n", 
    19221924                file,line,regcon.mvar,msavereg,*pretregs,*preg,tym); 
    19231925#endif 
    19241926            assert(0); 
    19251927        } 
    19261928        if (retregs & regcon.mvar)              // if conflict with reg vars 
    19271929        { 
    19281930            if (!(size > REGSIZE && *pretregs == (mAX | mDX))) 
    19291931            { 
    19301932                retregs = (*pretregs &= ~(retregs & regcon.mvar)); 
    19311933                goto L1;                // try other registers 
    19321934            } 
    19331935        } 
    19341936        *preg = reg; 
    19351937        *pretregs = retregs; 
    19361938 
    19371939        //printf("Allocating %s\n",regm_str(retregs)); 
    19381940        last5retregs = last4retregs; 
    19391941        last4retregs = last3retregs; 
    19401942        last3retregs = last2retregs; 
    19411943        last2retregs = lastretregs; 
     
    24702472        assert(I16); 
    24712473        if (((csemask | emask) & DOUBLEREGS_16) == DOUBLEREGS_16) 
    24722474        { 
    24732475            for (reg = AX; reg != -1; reg = dblreg[reg]) 
    24742476            {   assert((int) reg >= 0 && reg <= 7); 
    24752477                if (mask[reg] & csemask) 
    24762478                    c = cat(c,loadcse(e,reg,mask[reg])); 
    24772479            } 
    24782480            regm = DOUBLEREGS_16; 
    24792481            goto fix; 
    24802482        } 
    24812483        if (!EOP(e)) goto reload; 
    24822484#if DEBUG 
    24832485        printf("e = %p, csemask = x%x, emask = x%x\n",e,csemask,emask); 
    24842486#endif 
    24852487        assert(0); 
    24862488  } 
    24872489  else 
    24882490  { 
    24892491#if DEBUG 
    2490         printf("e = %p, tym = x%lx\n",e,tym); 
     2492        printf("e = %p, tym = x%x\n",e,tym); 
    24912493#endif 
    24922494        assert(0); 
    24932495  } 
    24942496 
    24952497reload:                                 /* reload result from memory    */ 
    24962498    switch (e->Eoper) 
    24972499    { 
    24982500        case OPrelconst: 
    24992501            c = cdrelconst(e,pretregs); 
    25002502            break; 
    25012503#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 
    25022504        case OPgot: 
    25032505            c = cdgot(e,pretregs); 
    25042506            break; 
    25052507#endif 
    25062508        default: 
    25072509            c = loaddata(e,pretregs); 
    25082510            break; 
    25092511    } 
    25102512    cssave(e,*pretregs,FALSE); 
  • trunk/src/backend/cod1.c

    r577 r579  
    11// Copyright (C) 1984-1998 by Symantec 
    22// Copyright (C) 2000-2010 by Digital Mars 
    33// All Rights Reserved 
    44// http://www.digitalmars.com 
    55// Written by Walter Bright 
    66/* 
    77 * This source file is made available for personal use 
    88 * only. The license is in /dmd/src/dmd/backendlicense.txt 
    99 * or /dm/src/dmd/backendlicense.txt 
    1010 * For any other uses, please contact Digital Mars. 
    1111 */ 
    1212 
    1313#if !SPP 
    1414 
    1515#include        <stdio.h> 
    1616#include        <string.h> 
     17#include        <stdlib.h> 
    1718#include        <time.h> 
    1819#include        "cc.h" 
    1920#include        "el.h" 
    2021#include        "oper.h" 
    2122#include        "code.h" 
    2223#include        "global.h" 
    2324#include        "type.h" 
    2425 
    2526static char __file__[] = __FILE__;      /* for tassert.h                */ 
    2627#include        "tassert.h" 
    2728 
    2829targ_size_t paramsize(elem *e,unsigned stackalign); 
    2930STATIC code * funccall (elem *,unsigned,unsigned,regm_t *,regm_t); 
    3031 
    3132/* array to convert from index register to r/m field    */ 
    3233                                       /* AX CX DX BX SP BP SI DI       */ 
    3334static const signed char regtorm32[8] = {  0, 1, 2, 3,-1, 5, 6, 7 }; 
    3435             signed char regtorm  [8] = { -1,-1,-1, 7,-1, 6, 4, 5 }; 
    3536 
    3637/************************** 
     
    309310        stackpushsave = stackpush; 
    310311        stackcleansave = cgstate.stackclean; 
    311312        cgstate.stackclean = 0;                         // defer cleaning of stack 
    312313        c = cat(c,codelem(e,pretregs,constflag)); 
    313314        assert(cgstate.stackclean == 0); 
    314315        cgstate.stackclean = stackcleansave; 
    315316        c = genstackclean(c,stackpush - stackpushsave,*pretregs);       // do defered cleaning 
    316317    } 
    317318    return c; 
    318319} 
    319320 
    320321/******************************************** 
    321322 * Gen a save/restore sequence for mask of registers. 
    322323 */ 
    323324 
    324325void gensaverestore2(regm_t regm,code **csave,code **crestore) 
    325326{ 
    326327    code *cs1 = *csave; 
    327328    code *cs2 = *crestore; 
    328329 
     330    //printf("gensaverestore2(%x)\n", regm); 
    329331    regm &= mBP | mES | ALLREGS; 
    330332    for (int i = 0; regm; i++) 
    331333    { 
    332334        if (regm & 1) 
    333335        { 
    334336            if (i == ES) 
    335337            { 
    336338                cs1 = gen1(cs1, 0x06);                  // PUSH ES 
    337339                cs2 = cat(gen1(CNIL, 0x07),cs2);        // POP  ES 
    338340            } 
    339341            else 
    340342            { 
    341343                cs1 = gen1(cs1,0x50 + (i & 7));         // PUSH i 
    342344                code *c = gen1(NULL, 0x58 + (i & 7));   // POP  i 
    343345                if (i & 8) 
    344346                {   code_orrex(cs1, REX_B); 
    345347                    code_orrex(c, REX_B); 
    346348                } 
    347349                cs2 = cat(c,cs2); 
    348350            } 
     
    16481650        } 
    16491651    } 
    16501652    return c; 
    16511653} 
    16521654 
    16531655 
    16541656/***************************** 
    16551657 * Given a result in registers, test it for TRUE or FALSE. 
    16561658 * Will fail if TYfptr and the reg is ES! 
    16571659 * If saveflag is TRUE, preserve the contents of the 
    16581660 * registers. 
    16591661 */ 
    16601662 
    16611663code *tstresult(regm_t regm,tym_t tym,unsigned saveflag) 
    16621664{ 
    16631665  unsigned scrreg;                      /* scratch register             */ 
    16641666  regm_t scrregm; 
    16651667 
    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 
    16711673  assert(regm & (mBP | ALLREGS)); 
    16721674  tym = tybasic(tym); 
    16731675  code *ce = CNIL; 
    16741676  unsigned reg = findreg(regm); 
    16751677  unsigned sz = tysize[tym]; 
    16761678  if (sz == 1) 
    16771679  {     assert(regm & BYTEREGS); 
    16781680        return genregs(ce,0x84,reg,reg);        // TEST regL,regL 
    16791681  } 
    16801682  if (sz <= REGSIZE) 
    16811683  { 
    16821684    if (!I16) 
    16831685    { 
    16841686        if (tym == TYfloat) 
    16851687        {   if (saveflag) 
    16861688            { 
    16871689                scrregm = allregs & ~regm;              /* possible scratch regs */ 
    16881690                ce = allocreg(&scrregm,&scrreg,TYoffset); /* allocate scratch reg */ 
     
    22922294 
    22932295/******************************* 
    22942296 * Generate code sequence for function call. 
    22952297 */ 
    22962298 
    22972299code *cdfunc(elem *e,regm_t *pretregs) 
    22982300{ unsigned numpara = 0; 
    22992301  unsigned stackpushsave; 
    23002302  unsigned preg; 
    23012303  regm_t keepmsk; 
    23022304  unsigned numalign = 0; 
    23032305  code *c; 
    23042306 
    23052307  //printf("cdfunc()\n"); elem_print(e); 
    23062308  assert(e); 
    23072309  stackpushsave = stackpush;            /* so we can compute # of parameters */ 
    23082310  cgstate.stackclean++; 
    23092311  c = CNIL; 
    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: 
    23232327                    stackalign = 2; 
    23242328                    goto Ldefault; 
    23252329                case TYmfunc: 
    23262330                case TYjfunc: 
    23272331                    // last parameter goes into register 
    23282332                    elem *ep; 
    23292333                    for (ep = e->E2; ep->Eoper == OPparam; ep = ep->E2) 
    23302334                    { 
    23312335                        numpara += paramsize(ep->E1,stackalign); 
    23322336                    } 
    23332337                    if (tyf == TYjfunc && 
    23342338                        // This must match type_jparam() 
    23352339                        !(tyjparam(ep->Ety) || 
    23362340                          ((tybasic(ep->Ety) == TYstruct || tybasic(ep->Ety) == TYarray) && ep->Enumbytes <= intsize && ep->Enumbytes != 3 && ep->Enumbytes) 
    23372341                         ) 
    23382342                        ) 
    23392343                    { 
    23402344                        numpara += paramsize(ep,stackalign); 
     
    23482352            assert((numpara & (REGSIZE - 1)) == 0); 
    23492353            assert((stackpush & (REGSIZE - 1)) == 0); 
    23502354 
    23512355            /* Adjust start of the stack so after all args are pushed, 
    23522356             * the stack will be aligned. 
    23532357             */ 
    23542358            if (STACKALIGN == 16 && (numpara + stackpush) & (STACKALIGN - 1)) 
    23552359            { 
    23562360                numalign = STACKALIGN - ((numpara + stackpush) & (STACKALIGN - 1)); 
    23572361                c = genc2(NULL,0x81,modregrm(3,5,SP),numalign); // SUB ESP,numalign 
    23582362                if (I64) 
    23592363                    code_orrex(c, REX_W); 
    23602364                c = genadjesp(c, numalign); 
    23612365                stackpush += numalign; 
    23622366                stackpushsave += numalign; 
    23632367            } 
    23642368 
    23652369            switch (tyf) 
    23662370            {   case TYf16func: 
    23672371                    stackalign = 2; 
    2368                     break
     2372                    goto Ldefault2
    23692373                case TYmfunc:   // last parameter goes into ECX 
    23702374                    preg = CX; 
    23712375                    goto L1; 
    23722376                case TYjfunc:   // last parameter goes into EAX 
    23732377                    preg = AX; 
    23742378                    goto L1; 
    23752379 
    23762380                L1: 
    2377                     elem *ep; 
     2380                {   elem *ep; 
     2381                    elem *en; 
    23782382                    for (ep = e->E2; ep->Eoper == OPparam; ep = en) 
    23792383                    { 
    23802384                        c = cat(c,params(ep->E1,stackalign)); 
    23812385                        en = ep->E2; 
    23822386                        freenode(ep); 
    2383                         ep = en; 
    23842387                    } 
    23852388                    if (tyf == TYjfunc && 
    23862389                        // This must match type_jparam() 
    23872390                        !(tyjparam(ep->Ety) || 
    23882391                          ((tybasic(ep->Ety) == TYstruct || tybasic(ep->Ety) == TYarray) && ep->Enumbytes <= intsize && ep->Enumbytes != 3 && ep->Enumbytes) 
    23892392                         ) 
    23902393                        ) 
    23912394                    { 
    23922395                        c = cat(c,params(ep,stackalign)); 
    23932396                        goto Lret; 
    23942397                    } 
    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; 
    24002403 
    24012404                        code *c1 = getregs(retregs); 
    24022405                        // LEA preg,np[ESP] 
    24032406                        unsigned np = stackpush - ep->EV.Vuns;   // stack delta to parameter 
    24042407                        c2 = genc1(CNIL,0x8D,(modregrm(0,4,SP) << 8) | modregrm(2,preg,4),FLconst,np); 
    24052408                        if (I64) 
    24062409                            code_orrex(c2, REX_W); 
    24072410                        c = cat3(c,c1,c2); 
    24082411                    } 
    24092412                    else 
    24102413                    {   code *cp = codelem(ep,&retregs,FALSE); 
    24112414                        c = cat(c,cp); 
    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 
    24192546    { 
    24202547        /* Adjust start of the stack so 
    24212548         * the stack will be aligned. 
    24222549         */ 
    24232550        if (STACKALIGN == 16 && (stackpush) & (STACKALIGN - 1)) 
    24242551        { 
    24252552            numalign = STACKALIGN - ((stackpush) & (STACKALIGN - 1)); 
    24262553            c = genc2(NULL,0x81,modregrm(3,5,SP),numalign); // SUB ESP,numalign 
    24272554            if (I64) 
    24282555                code_orrex(c, REX_W); 
    24292556            c = genadjesp(c, numalign); 
    24302557            stackpush += numalign; 
    24312558            stackpushsave += numalign; 
    24322559        } 
    24332560 
    24342561    } 
    24352562Lret: 
    24362563    cgstate.stackclean--; 
    2437     if (!I16) 
     2564    if (I16) 
     2565        numpara = stackpush - stackpushsave; 
     2566    else 
    24382567    { 
    24392568        if (numpara != stackpush - stackpushsave) 
    24402569            printf("numpara = %d, stackpush = %d, stackpushsave = %d\n", 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} 
    24472574 
    24482575/*********************************** 
    24492576 */ 
    24502577 
    24512578code *cdstrthis(elem *e,regm_t *pretregs) 
    24522579{ 
    24532580    code *c1; 
    24542581    code *c2; 
    24552582 
    24562583    assert(tysize(e->Ety) == REGSIZE); 
    24572584    unsigned reg = findreg(*pretregs & allregs); 
    24582585    c1 = getregs(mask[reg]); 
    24592586    // LEA reg,np[ESP] 
    24602587    unsigned np = stackpush - e->EV.Vuns;        // stack delta to parameter 
    24612588    c2 = genc1(CNIL,0x8D,(modregrm(0,4,SP) << 8) | modregxrm(2,reg,4),FLconst,np); 
    24622589    if (I64) 
    24632590        code_orrex(c2, REX_W); 
    24642591    return cat3(c1,c2,fixresult(e,mask[reg],pretregs)); 
  • trunk/src/backend/cod2.c

    r577 r579  
    37203720                fl = FLcsdata; 
    37213721            c = gen2(c,0x8C,            /* MOV mreg,SEG REGISTER        */ 
    37223722                modregrm(3,segfl[fl],mreg)); 
    37233723        } 
    37243724        if (*pretregs & mES) 
    37253725                gen2(c,0x8E,modregrm(3,0,mreg));        /* MOV ES,mreg  */ 
    37263726  } 
    37273727  return cat(c,getoffset(e,lreg)); 
    37283728} 
    37293729 
    37303730/********************************* 
    37313731 * Load the offset portion of the address represented by e into 
    37323732 * reg. 
    37333733 */ 
    37343734 
    37353735code *getoffset(elem *e,unsigned reg) 
    37363736{ code cs; 
    37373737  code *c; 
    37383738 
    37393739  cs.Iflags = 0; 
    3740   unsigned char rex = I64 ? REX_W : 0; 
     3740  unsigned char rex = 0; 
    37413741  cs.Irex = rex; 
    37423742  assert(e->Eoper == OPvar || e->Eoper == OPrelconst); 
    37433743  enum FL fl = el_fl(e); 
    37443744  switch (fl) 
    37453745  { 
    37463746    case FLdatseg: 
    37473747        cs.IEV2._EP.Vpointer = e->EV.Vpointer; 
    37483748        goto L3; 
    37493749 
    37503750    case FLfardata: 
    37513751        assert(!TARGET_FLAT); 
    37523752        goto L4; 
    37533753 
    37543754    case FLtlsdata: 
    37553755#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 
    37563756    {   /* Generate: 
    37573757         *      MOV reg,GS:[00000000] 
    37583758         *      ADD reg, offset s@TLS_LE 
    37593759         * for locals, and for globals: 
    37603760         *      MOV reg,GS:[00000000] 
  • trunk/src/backend/cod3.c

    r577 r579  
    11591159    {   p[0] = len; 
    11601160        memcpy(p + 1,name,len); 
    11611161        len++; 
    11621162    } 
    11631163    return len; 
    11641164} 
    11651165#endif 
    11661166 
    11671167/******************************* 
    11681168 * Generate code for a function start. 
    11691169 * Input: 
    11701170 *      Coffset         address of start of code 
    11711171 * Output: 
    11721172 *      Coffset         adjusted for size of code generated 
    11731173 *      EBPtoESP 
    11741174 *      hasframe 
    11751175 *      BPoff 
    11761176 */ 
    11771177 
    11781178code *prolog() 
    1179 {   code *c; 
     1179{ 
    11801180    SYMIDX si; 
    11811181    unsigned reg; 
    1182     regm_t topush; 
    1183     tym_t tym; 
    1184     tym_t tyf; 
    11851182    char enter; 
    1186     char pushds; 
    1187     unsigned farfunc; 
    11881183    unsigned Foffset; 
    11891184    unsigned xlocalsize;     // amount to subtract from ESP to make room for locals 
    1190     int pushalloc; 
    11911185    unsigned pushallocreg; 
    11921186    char guessneedframe; 
    11931187 
    11941188    //printf("cod3.prolog(), needframe = %d, Aalign = %d\n", needframe, Aalign); 
    11951189    debugx(debugw && printf("funcstart()\n")); 
    11961190    regcon.immed.mval = 0;                      /* no values in registers yet   */ 
    11971191    EBPtoESP = -REGSIZE; 
    11981192    hasframe = 0; 
    1199     pushds = 0; 
     1193    char pushds = 0; 
    12001194    BPoff = 0; 
    1201     c = CNIL; 
    1202     pushalloc = 0; 
    1203     tyf = funcsym_p->ty(); 
    1204     tym = tybasic(tyf); 
    1205     farfunc = tyfarfunc(tym); 
     1195    code *c = CNIL; 
     1196    int pushalloc = 0; 
     1197    tym_t tyf = funcsym_p->ty(); 
     1198    tym_t tym = tybasic(tyf); 
     1199    unsigned farfunc = tyfarfunc(tym); 
    12061200    pushallocreg = (tyf == TYmfunc) ? CX : AX; 
    12071201    if (config.flags & CFGalwaysframe || funcsym_p->Sfunc->Fflags3 & Ffakeeh) 
    12081202        needframe = 1; 
    12091203 
    12101204Lagain: 
    12111205    guessneedframe = needframe; 
    12121206//    if (needframe && config.exe & (EX_LINUX | EX_FREEBSD | EX_SOLARIS) && !(usednteh & ~NTEHjmonitor)) 
    12131207//      usednteh |= NTEHpassthru; 
    12141208 
    12151209    /* Compute BP offsets for variables on stack. 
    12161210     * The organization is: 
    12171211     *  Poff    parameters 
    12181212     *          seg of return addr      (if far function) 
    12191213     *          IP of return addr 
    12201214     *  BP->    caller's BP 
    12211215     *          DS                      (if Windows prolog/epilog) 
    12221216     *          exception handling context symbol 
    12231217     *  Aoff    autos and regs 
    12241218     *  Foff    floating register 
    12251219     *  AAoff   alloca temporary 
     
    12511245 
    12521246    if (Aalign > REGSIZE) 
    12531247    { 
    12541248        // Adjust Aoff so that it is Aalign byte aligned, assuming that 
    12551249        // before function parameters were pushed the stack was 
    12561250        // Aalign byte aligned 
    12571251        int sz = Poffset + -Aoff + Poff + (needframe ? 0 : REGSIZE); 
    12581252        if (sz & (Aalign - 1)) 
    12591253            Aoff -= sz - (sz & (Aalign - 1)); 
    12601254    } 
    12611255 
    12621256    Foffset = floatreg ? DOUBLESIZE : 0; 
    12631257    Foff = Aoff - align(0,Foffset); 
    12641258    assert(usedalloca != 1); 
    12651259    AAoff = usedalloca ? (Foff - REGSIZE) : Foff; 
    12661260    CSoff = AAoff - align(0,cstop * REGSIZE); 
    12671261    NDPoff = CSoff - align(0,NDP::savetop * NDPSAVESIZE); 
    12681262    Toff = NDPoff - align(0,Toffset); 
    12691263    localsize = -Toff; 
    12701264 
    1271     topush = fregsaved & ~mfuncreg;     // mask of registers that need saving 
     1265    regm_t topush = fregsaved & ~mfuncreg;     // mask of registers that need saving 
    12721266    int npush = 0;                      // number of registers that need saving 
    12731267    for (regm_t x = topush; x; x >>= 1) 
    12741268        npush += x & 1; 
    12751269 
    12761270    // Keep the stack aligned by 8 for any subsequent function calls 
    12771271    if (!I16 && calledafunc && 
    12781272        (STACKALIGN == 16 || config.flags4 & CFG4stackalign)) 
    12791273    { 
    12801274        //printf("npush = %d Poff = x%x needframe = %d localsize = x%x\n", npush, Poff, needframe, localsize); 
    12811275 
    12821276        int sz = Poff + (needframe ? 0 : -REGSIZE) + localsize + npush * REGSIZE; 
    12831277        if (STACKALIGN == 16) 
    12841278        { 
    12851279            if (sz & (8|4)) 
    12861280                localsize += STACKALIGN - (sz & (8|4)); 
    12871281        } 
    12881282        else if (sz & 4) 
    12891283            localsize += 4; 
    12901284    } 
    12911285 
     
    13331327                farfunc || 
    13341328                config.flags & CFGstack || 
    13351329                xlocalsize >= 0x1000 || 
    13361330                (usednteh & ~NTEHjmonitor) || 
    13371331                anyiasm || 
    13381332                usedalloca 
    13391333               ) 
    13401334                needframe = 1; 
    13411335        } 
    13421336        if (refparam && (anyiasm || I16)) 
    13431337            needframe = 1; 
    13441338    } 
    13451339 
    13461340    if (needframe) 
    13471341    {   assert(mfuncreg & mBP);         // shouldn't have used mBP 
    13481342 
    13491343        if (!guessneedframe)            // if guessed wrong 
    13501344            goto Lagain; 
    13511345    } 
    13521346 
    1353 #if SIXTEENBIT 
    1354     if (config.wflags & WFwindows && farfunc) 
     1347    if (I16 && config.wflags & WFwindows && farfunc) 
    13551348    {   int wflags; 
    13561349        int segreg; 
    13571350 
     1351#if SCPP 
    13581352        // alloca() can't be because the 'special' parameter won't be at 
    13591353        // a known offset from BP. 
    13601354        if (usedalloca == 1) 
    13611355            synerr(EM_alloca_win);      // alloca() can't be in Windows functions 
     1356#endif 
    13621357 
    13631358        wflags = config.wflags; 
    13641359        if (wflags & WFreduced && !(tyf & mTYexport)) 
    13651360        {   // reduced prolog/epilog for non-exported functions 
    13661361            wflags &= ~(WFdgroup | WFds | WFss); 
    13671362        } 
    13681363 
    13691364        c = getregs(mAX); 
    13701365        assert(!c);                     /* should not have any value in AX */ 
    13711366 
    13721367        switch (wflags & (WFdgroup | WFds | WFss)) 
    13731368        {   case WFdgroup:                      // MOV  AX,DGROUP 
    13741369                if (wflags & WFreduced) 
    13751370                    tyf &= ~mTYloadds;          // remove redundancy 
    13761371                c = genc(c,0xC7,modregrm(3,0,AX),0,0,FLdatseg,(targ_uns) 0); 
    13771372                c->Iflags ^= CFseg | CFoff;     // turn off CFoff, on CFseg 
    13781373                break; 
    13791374            case WFss: 
    13801375                segreg = 2;                     // SS 
    13811376                goto Lmovax; 
     
    13931388                printf("config.wflags = x%x\n",config.wflags); 
    13941389#endif 
    13951390                assert(0); 
    13961391        } 
    13971392        if (wflags & WFincbp) 
    13981393            c = gen1(c,0x40 + BP);              // INC  BP 
    13991394        c = gen1(c,0x50 + BP);                  // PUSH BP 
    14001395        genregs(c,0x8B,BP,SP);                  // MOV  BP,SP 
    14011396        if (wflags & (WFsaveds | WFds | WFss | WFdgroup)) 
    14021397        {   gen1(c,0x1E);                       // PUSH DS 
    14031398            pushds = TRUE; 
    14041399            BPoff = -REGSIZE; 
    14051400        } 
    14061401        if (wflags & (WFds | WFss | WFdgroup)) 
    14071402            gen2(c,0x8E,modregrm(3,3,AX));      // MOV  DS,AX 
    14081403 
    14091404        enter = FALSE;                  /* don't use ENTER instruction  */ 
    14101405        hasframe = 1;                   /* we have a stack frame        */ 
    14111406    } 
    14121407    else 
    1413 #endif 
    14141408    if (needframe)                      // if variables or parameters 
    14151409    { 
    14161410        if (config.wflags & WFincbp && farfunc) 
    14171411            c = gen1(c,0x40 + BP);      /* INC  BP                      */ 
    14181412        if (config.target_cpu < TARGET_80286 || 
    14191413            config.exe & (EX_LINUX | EX_LINUX64 | EX_OSX | EX_OSX64 | EX_FREEBSD | EX_FREEBSD64 | EX_SOLARIS | EX_SOLARIS64) || 
    14201414            !localsize || 
    14211415            config.flags & CFGstack || 
    14221416            (xlocalsize >= 0x1000 && config.exe & EX_flat) || 
    14231417            localsize >= 0x10000 || 
    14241418#if NTEXCEPTIONS == 2 
    14251419            (usednteh & ~NTEHjmonitor && (config.flags2 & CFG2seh)) || 
    14261420#endif 
    14271421            (config.target_cpu >= TARGET_80386 && 
    14281422             config.flags4 & CFG4speed) 
    14291423           ) 
    14301424        { 
    14311425            c = gen1(c,0x50 + BP);      // PUSH BP 
    14321426            genregs(c,0x8B,BP,SP);      // MOV  BP,SP 
    14331427            if (I64) 
     
    16471641    } 
    16481642 
    16491643#if MARS 
    16501644    if (usednteh & NTEHjmonitor) 
    16511645    {   Symbol *sthis; 
    16521646 
    16531647        for (si = 0; 1; si++) 
    16541648        {   assert(si < globsym.top); 
    16551649            sthis = globsym.tab[si]; 
    16561650            if (strcmp(sthis->Sident,"this") == 0) 
    16571651                break; 
    16581652        } 
    16591653        c = cat(c,nteh_monitor_prolog(sthis)); 
    16601654        EBPtoESP += 3 * 4; 
    16611655    } 
    16621656#endif 
    16631657 
    16641658    while (topush)                      /* while registers to push      */ 
    16651659    {   reg = findreg(topush); 
    16661660        topush &= ~mask[reg]; 
    1667         c = gen1(c,0x50 + reg); 
     1661        c = gen1(c,0x50 + (reg & 7)); 
     1662        if (reg & 8) 
     1663            code_orrex(c, REX_B); 
    16681664        EBPtoESP += REGSIZE; 
    16691665#if ELFOBJ || MACHOBJ 
    16701666        if (config.fulltypes) 
    16711667        {   // Emit debug_frame data giving location of saved register 
    16721668            // relative to 0[EBP] 
    16731669            pinholeopt(c, NULL); 
    16741670            dwarf_CFA_set_loc(calcblksize(c));  // address after PUSH reg 
    16751671            dwarf_CFA_offset(reg, -EBPtoESP - REGSIZE); 
    16761672        } 
    16771673#endif 
    16781674    } 
    16791675 
    16801676Lcont: 
    16811677 
    16821678    /* Determine if we need to reload DS        */ 
    16831679    if (tyf & mTYloadds) 
    16841680    {   code *c1; 
    16851681 
    16861682        if (!pushds)                            // if not already pushed 
    16871683            c = gen1(c,0x1E);                   // PUSH DS 
     
    19001896    if (tyf & mTYloadds) 
    19011897    {   cpopds = gen1(cpopds,0x1F);             // POP DS 
    19021898        c = cat(c,cpopds); 
    19031899        spoff += intsize; 
    19041900    } 
    19051901 
    19061902    /* Pop all the general purpose registers saved on the stack 
    19071903     * by the prolog code. Remember to do them in the reverse 
    19081904     * order they were pushed. 
    19091905     */ 
    19101906    reg = I64 ? R15 : DI; 
    19111907    regm = 1 << reg; 
    19121908    topop = fregsaved & ~mfuncreg; 
    19131909#ifdef DEBUG 
    19141910    if (topop & ~0xFFFF) 
    19151911        printf("fregsaved = x%x, mfuncreg = x%x\n",fregsaved,mfuncreg); 
    19161912#endif 
    19171913    assert(!(topop & ~0xFFFF)); 
    19181914    while (topop) 
    19191915    {   if (topop & regm) 
    1920         {   c = gen1(c,0x58 + reg);         // POP reg 
     1916        {   c = gen1(c,0x58 + (reg & 7));         // POP reg 
    19211917            if (reg & 8) 
    19221918                code_orrex(c, REX_B); 
    19231919            topop &= ~regm; 
    19241920            spoff += intsize; 
    19251921        } 
    19261922        regm >>= 1; 
    19271923        reg--; 
    19281924    } 
    19291925 
    19301926#if MARS 
    19311927    if (usednteh & NTEHjmonitor) 
    19321928    { 
    19331929        regm_t retregs = 0; 
    19341930        if (b->BC == BCretexp) 
    19351931            retregs = regmask(b->Belem->Ety, tym); 
    19361932        code *cn = nteh_monitor_epilog(retregs); 
    19371933        c = cat(c,cn); 
    19381934        xlocalsize += 8; 
    19391935    } 
    19401936#endif 
     
    43424338#ifdef DEBUG 
    43434339        assert(uev->Vblock->Boffset > OFFSET() || c != 0x7F); 
    43444340#endif 
    43454341        break; 
    43464342    default: 
    43474343#ifdef DEBUG 
    43484344        fprintf(stderr,"fl = %d\n",fl); 
    43494345#endif 
    43504346        assert(0); 
    43514347  } 
    43524348  GEN(c); 
    43534349} 
    43544350 
    43554351 
    43564352/**************************** 
    43574353 * Add to the fix list. 
    43584354 */ 
    43594355 
    43604356void addtofixlist(symbol *s,targ_size_t soffset,int seg,targ_size_t val,int flags) 
    43614357{       fixlist *ln; 
    4362         static char zeros[6]; 
     4358        static char zeros[8]; 
    43634359        int numbytes; 
    43644360 
    43654361        //printf("addtofixlist(%p '%s')\n",s,s->Sident); 
    43664362        assert(flags); 
    43674363        ln = (fixlist *) mem_calloc(sizeof(fixlist)); 
    43684364        ln->Lsymbol = s; 
    43694365        ln->Loffset = soffset; 
    43704366        ln->Lseg = seg; 
    43714367        ln->Lflags = flags; 
    43724368        ln->Lval = val; 
    43734369#if TARGET_OSX 
    43744370        ln->Lfuncsym = funcsym_p; 
    43754371#endif 
    43764372        ln->Lnext = fixlist::start; 
    43774373        fixlist::start = ln; 
    43784374#if TARGET_FLAT 
    43794375        numbytes = tysize[TYnptr]; 
    43804376        assert(!(flags & CFseg)); 
    43814377#else 
    43824378        switch (flags & (CFoff | CFseg)) 
     
    48804876        {   printf(" linnum = %d\n",c->IEV2.Vsrcpos.Slinnum); 
    48814877            return; 
    48824878        } 
    48834879        printf(" ESCAPE %d",c->Iop2); 
    48844880  } 
    48854881  if (c->Iflags) 
    48864882        printf(" flg=%x",c->Iflags); 
    48874883  if (ins & M) 
    48884884  {     rm = c->Irm; 
    48894885        printf(" rm=%02x=%d,%d,%d",rm,(rm>>6)&3,(rm>>3)&7,rm&7); 
    48904886        if (I32 && issib(rm)) 
    48914887        {   unsigned char sib = c->Isib; 
    48924888            printf(" sib=%02x=%d,%d,%d",sib,(sib>>6)&3,(sib>>3)&7,sib&7); 
    48934889        } 
    48944890        if ((rm & 0xC7) == BPRM || (rm & 0xC0) == 0x80 || (rm & 0xC0) == 0x40) 
    48954891        { 
    48964892            switch (c->IFL1) 
    48974893            { 
    48984894                case FLconst: 
    48994895                case FLoffset: 
    4900                     printf(" int = %4ld",c->IEV1.Vuns); 
     4896                    printf(" int = %4d",c->IEV1.Vuns); 
    49014897                    break; 
    49024898                case FLblock: 
    49034899                    printf(" block = %p",c->IEV1.Vblock); 
    49044900                    break; 
    49054901                case FLswitch: 
    49064902                case FLblockoff: 
    49074903                case FLlocalsize: 
    49084904                case FLframehandler: 
    49094905                case 0: 
    49104906                    break; 
    49114907                case FLdatseg: 
    49124908                    printf(" %d.%lx",c->IEVseg1,c->IEVpointer1); 
    49134909                    break; 
    49144910                case FLauto: 
    49154911                case FLreg: 
    49164912                case FLdata: 
    49174913                case FLudata: 
    49184914                case FLpara: 
    49194915                case FLtmp: 
    49204916                case FLbprel: 
    49214917                case FLtlsdata: 
    49224918                    printf(" sym='%s'",c->IEVsym1->Sident); 
    49234919                    break; 
    49244920                default: 
    49254921                    WRFL((enum FL)c->IFL1); 
    49264922                    break; 
    49274923            } 
    49284924        } 
    49294925  } 
    49304926  if (ins & T) 
    49314927  {     printf(" "); WRFL((enum FL)c->IFL2); 
    49324928        switch (c->IFL2) 
    49334929        { 
    49344930            case FLconst: 
    4935                 printf(" int = %4ld",c->IEV2.Vuns); 
     4931                printf(" int = %4d",c->IEV2.Vuns); 
    49364932                break; 
    49374933            case FLblock: 
    49384934                printf(" block = %p",c->IEV2.Vblock); 
    49394935                break; 
    49404936            case FLswitch: 
    49414937            case FLblockoff: 
    49424938            case 0: 
    49434939            case FLlocalsize: 
    49444940            case FLframehandler: 
    49454941                break; 
    49464942            case FLdatseg: 
    49474943                printf(" %d.%lx",c->IEVseg2,c->IEVpointer2); 
    49484944                break; 
    49494945            case FLauto: 
    49504946            case FLreg: 
    49514947            case FLpara: 
    49524948            case FLtmp: 
    49534949            case FLbprel: 
    49544950            case FLfunc: 
    49554951            case FLdata: 
  • trunk/src/backend/elfobj.c

    r572 r579  
    27012701            offset = (foffset + 31) & ~31; 
    27022702            break; 
    27032703        default: 
    27042704            dbg_printf("size was %d\n",(int)size); 
    27052705            assert(0); 
    27062706            break; 
    27072707    } 
    27082708    if (offset > foffset) 
    27092709        fobjbuf->writezeros(offset - foffset); 
    27102710    return offset; 
    27112711} 
    27122712 
    27132713/*************************************** 
    27142714 * Stuff pointer to ModuleInfo in its own segment. 
    27152715 */ 
    27162716 
    27172717#if MARS 
    27182718 
    27192719void obj_moduleinfo(Symbol *scc) 
    27202720{ 
     2721//    if (I64) return;          // for now, until Phobos64 works 
     2722 
    27212723    int codeOffset, refOffset; 
    27222724 
    27232725    /* Put in the ModuleReference. */ 
    27242726    { 
    27252727        /* struct ModuleReference 
    27262728         * { 
    27272729         *      void*   next; 
    27282730         *      ModuleReference* module; 
    27292731         * } 
    27302732         */ 
    27312733        const int seg = DATA; 
    27322734        alignOffset(seg, NPTRSIZE); 
    27332735        SegData[seg]->SDoffset = SegData[seg]->SDbuf->size(); 
    27342736        refOffset = SegData[seg]->SDoffset; 
    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 
    27412742    /* Constructor that links the ModuleReference to the head of 
    27422743     * the list pointed to by _Dmoduleref 
    27432744     */ 
    27442745    { 
    27452746        /*      ret 
    27462747         * codeOffset: 
    27472748         *      pushad 
    27482749         *      mov     EAX,&ModuleReference 
    27492750         *      mov     ECX,_DmoduleRef 
    27502751         *      mov     EDX,[ECX] 
    27512752         *      mov     [EAX],EDX 
    27522753         *      mov     [ECX],EAX 
    27532754         *      popad 
    27542755         *      ret 
    27552756         */ 
    27562757 
    27572758        const int reltype = I64 ? R_X86_64_32 : RI_TYPE_SYM32; 
    27582759        const int refsize = 4;                          // use 32 bit relocations, even in 64 bit mode 
    27592760 
    27602761        const int seg = CODE; 
    27612762        Outbuffer *buf = SegData[seg]->SDbuf; 
    27622763        SegData[seg]->SDoffset = buf->size(); 
    27632764        codeOffset = SegData[seg]->SDoffset + 1; 
    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 */ 
    27792784        buf->writeByte(0x89); buf->writeByte(0x10); /* movl %edx, (%eax) */ 
    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(); 
    27852790    } 
    27862791 
    27872792    /* Add reference to constructor into ".ctors" segment 
    27882793     */ 
    27892794    const int seg = elf_getsegment(".ctors", NULL, SHT_PROGDEF, SHF_ALLOC|SHF_WRITE, NPTRSIZE); 
    27902795 
    27912796    Outbuffer *buf = SegData[seg]->SDbuf; 
    27922797    buf->write32(codeOffset); 
    27932798    elf_addrel(seg, SegData[seg]->SDoffset, I64 ? R_X86_64_64 : RI_TYPE_SYM32, STI_TEXT, 0); 
    27942799    SegData[seg]->SDoffset += NPTRSIZE; 
    27952800} 
    27962801 
    27972802#endif 
    27982803 
    27992804/************************************* 
    28002805 */ 
    28012806 
    28022807void elfobj_gotref(symbol *s) 
  • trunk/src/backend/el.h

    r572 r579  
    2626/****************************************** 
    2727 * Elems: 
    2828 *      Elems are the basic tree element. They can be either 
    2929 *      terminal elems (leaves), unary elems (left subtree exists) 
    3030 *      or binary elems (left and right subtrees exist). 
    3131 */ 
    3232 
    3333struct elem 
    3434{ 
    3535#ifdef DEBUG 
    3636    unsigned short      id; 
    3737#define IDelem 0x4C45   // 'EL' 
    3838#define elem_debug(e) assert((e)->id == IDelem) 
    3939#else 
    4040#define elem_debug(e) 
    4141#endif 
    4242 
    4343    unsigned char Eoper;        // operator (OPxxxx) 
    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 
    4851    { 
    4952        // PARSER 
    5053        struct 
    5154        { 
    5255            struct TYPE *ET_;   // pointer to type of elem 
    5356            #define ET _EU._EP.ET_ 
    5457 
    5558            unsigned PEFflags_; 
    5659            #define PEFflags _EU._EP.PEFflags_ 
    5760                #define PEFnotlvalue    1       // although elem may look like 
    5861                                                // an lvalue, it isn't 
    5962                #define PEFtemplate_id  0x10    // symbol is a template-id 
    6063                #define PEFparentheses  0x20    // expression was within () 
    6164                #define PEFaddrmem      0x40    // address of member 
    6265                #define PEFdependent    0x80    // value-dependent 
    6366                #define PEFmember       0x100   // was a class member access 
    6467#if !TX86 
    6568                #define PEFdblldbl      2       // long double return from dbl func 
  • trunk/src/backend/symbol.c

    r487 r579  
    346346Symbol *symbol_genauto(elem *e) 
    347347{ 
    348348    return symbol_genauto(type_fake(e->Ety)); 
    349349} 
    350350 
    351351/****************************************** 
    352352 * Generate symbol into which we can copy the contents of expression e. 
    353353 */ 
    354354 
    355355Symbol *symbol_genauto(tym_t ty) 
    356356{ 
    357357    return symbol_genauto(type_fake(ty)); 
    358358} 
    359359 
    360360/**************************************** 
    361361 * Add in the variants for a function symbol. 
    362362 */ 
    363363 
    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; 
    368369    // Interrupt functions modify all registers 
    369370#if TX86 
    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 
    374376#endif 
    375377    if (!s->Sfunc) 
    376378        s->Sfunc = func_calloc(); 
    377379} 
    378380 
    379381/******************************** 
    380382 * Define symbol in specified symbol table. 
    381383 * Returns: 
    382384 *      pointer to symbol 
    383385 */ 
    384386 
    385387#if SCPP 
    386388 
    387389symbol * defsy(const char *p,symbol **parent) 
    388390{ 
    389391   symbol *s = symbol_calloc(p); 
    390392   symbol_addtotree(parent,s); 
    391393   return s; 
  • trunk/src/backend/ty.h

    r557 r579  
    180180#define TYFLref         0x8000 
    181181 
    182182/* Groupings of types   */ 
    183183 
    184184#define tyintegral(ty)  (tytab[(ty) & 0xFF] & TYFLintegral) 
    185185 
    186186#define tyarithmetic(ty) (tytab[(ty) & 0xFF] & (TYFLintegral | TYFLreal | TYFLimaginary | TYFLcomplex)) 
    187187 
    188188#define tyaggregate(ty) (tytab[(ty) & 0xFF] & TYFLaggregate) 
    189189 
    190190#define tyscalar(ty)    (tytab[(ty) & 0xFF] & (TYFLintegral | TYFLreal | TYFLimaginary | TYFLcomplex | TYFLptr | TYFLmptr | TYFLnullptr)) 
    191191 
    192192#define tyfloating(ty)  (tytab[(ty) & 0xFF] & (TYFLreal | TYFLimaginary | TYFLcomplex)) 
    193193 
    194194#define tyimaginary(ty) (tytab[(ty) & 0xFF] & TYFLimaginary) 
    195195 
    196196#define tycomplex(ty)   (tytab[(ty) & 0xFF] & TYFLcomplex) 
    197197 
    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       */ 
    202205#define tyshort(ty)     (tytab[(ty) & 0xFF] & TYFLshort) 
    203206#endif 
    204207 
    205208/* Detect TYlong or TYulong     */ 
    206209#ifndef tylong 
    207210#define tylong(ty)      (tybasic(ty) == TYlong || tybasic(ty) == TYulong) 
    208211#endif 
    209212 
    210213/* Use to detect a pointer type */ 
    211214#ifndef typtr 
    212215#define typtr(ty)       (tytab[(ty) & 0xFF] & TYFLptr) 
    213216#endif 
    214217 
    215218/* Use to detect a reference type */ 
    216219#ifndef tyref 
    217220#define tyref(ty)       (tytab[(ty) & 0xFF] & TYFLref) 
    218221#endif 
    219222 
  • trunk/src/e2ir.c

    r569 r579  
    269269            ep->Ety = tyret; 
    270270            e = ep; 
    271271            if (op == OPscale) 
    272272            { 
    273273                elem *et = e->E1; 
    274274                e->E1 = el_una(OPs32_d, TYdouble, e->E2); 
    275275                e->E1 = el_una(OPd_ld, TYldouble, e->E1); 
    276276                e->E2 = et; 
    277277            } 
    278278            else if (op == OPyl2x || op == OPyl2xp1) 
    279279            { 
    280280                elem *et = e->E1; 
    281281                e->E1 = e->E2; 
    282282                e->E2 = et; 
    283283            } 
    284284        } 
    285285        else 
    286286            e = el_una(op,tyret,ep); 
    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. 
    292292         */ 
    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) 
    300306    { 
    301307        e->Ety = TYnptr; 
    302308        e = el_una(OPind, tyret, e); 
    303309    } 
    304310 
    305311#if DMDV2 
    306312    if (tf->isref) 
    307313    { 
    308314        e->Ety = TYnptr; 
    309315        e = el_una(OPind, tyret, e); 
    310316    } 
    311317#endif 
    312318 
    313319    if (tybasic(tyret) == TYstruct) 
    314320    { 
    315321        e->Enumbytes = tret->size(); 
    316322    } 
    317323    e = el_combine(eside, e); 
     
    20602066        { 
    20612067            elem *ep; 
    20622068            CatExp *ce = this; 
    20632069            int n = 2; 
    20642070 
    20652071            ep = eval_Darray(irs, ce->e2); 
    20662072            do 
    20672073            { 
    20682074                n++; 
    20692075                ce = (CatExp *)ce->e1; 
    20702076                ep = el_param(ep, eval_Darray(irs, ce->e2)); 
    20712077            } while (ce->e1->op == TOKcat); 
    20722078            ep = el_param(ep, eval_Darray(irs, ce->e1)); 
    20732079#if 1 
    20742080            ep = el_params( 
    20752081                           ep, 
    20762082                           el_long(TYint, n), 
    20772083                           ta->getTypeInfo(NULL)->toElem(irs), 
    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( 
    20822089                           ep, 
    20832090                           el_long(TYint, n), 
    20842091                           el_long(TYint, tn->size()), 
    20852092                           NULL); 
    20862093            e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCATN]), ep); 
     2094            e->Eflags |= EFLAGS_variadic; 
    20872095#endif 
    20882096        } 
    20892097        else 
    20902098        { 
    20912099            elem *e1; 
    20922100            elem *e2; 
    20932101            elem *ep; 
    20942102 
    20952103            e1 = eval_Darray(irs, this->e1); 
    20962104            e2 = eval_Darray(irs, this->e2); 
    20972105#if 1 
    20982106            ep = el_params(e2, e1, ta->getTypeInfo(NULL)->toElem(irs), NULL); 
    20992107            e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCATT]), ep); 
    21002108#else 
    21012109            ep = el_params(el_long(TYint, tn->size()), e2, e1, NULL); 
    21022110            e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCAT]), ep); 
    21032111#endif 
    21042112        } 
    21052113        el_setLoc(e,loc); 
    21062114    } 
     
    45454553            } 
    45464554            args.data[dim - (i + 1)] = (void *)ep; 
    45474555        } 
    45484556 
    45494557        /* Because the number of parameters can get very large, produce 
    45504558         * a balanced binary tree so we don't blow up the stack in 
    45514559         * the subsequent tree walking code. 
    45524560         */ 
    45534561        e = el_params(args.data, dim + 1); 
    45544562    } 
    45554563    else 
    45564564    {   dim = 0; 
    45574565        e = el_long(TYint, 0); 
    45584566    } 
    45594567    Type *tb = type->toBasetype(); 
    45604568#if 1 
    45614569    e = el_param(e, type->getTypeInfo(NULL)->toElem(irs)); 
    45624570 
    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())); 
    45674576 
    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) 
    45724582    { 
    45734583        e = el_pair(TYullong, el_long(TYint, dim), e); 
    45744584    } 
    45754585    else if (tb->ty == Tpointer) 
    45764586    { 
    45774587    } 
    45784588    else 
    45794589    { 
    45804590        e = el_una(OPind,TYstruct,e); 
    45814591        e->Enumbytes = type->size(); 
    45824592    } 
    45834593 
    45844594    el_setLoc(e,loc); 
    45854595    return e; 
    45864596} 
    45874597 
    45884598 
    45894599elem *AssocArrayLiteralExp::toElem(IRState *irs) 
     
    46194629#if 0 
    46204630    /* Unfortunately, the hash function for Aa (array of chars) is custom and 
    46214631     * different from Axa and Aya, which get the generic hash function. 
    46224632     * So, rewrite the type of the AArray so that if it's key type 
    46234633     * is an array of const or invariant, make it an array of mutable. 
    46244634     */ 
    46254635    Type *tkey = ta->index->toBasetype(); 
    46264636    if (tkey->ty == Tarray) 
    46274637    { 
    46284638        tkey = tkey->nextOf()->mutableOf()->arrayOf(); 
    46294639        tkey = tkey->semantic(0, NULL); 
    46304640        ta = new TypeAArray(ta->nextOf(), tkey); 
    46314641        ta = (TypeAArray *)ta->merge(); 
    46324642    } 
    46334643#endif 
    46344644 
    46354645    e = el_param(e, ta->getTypeInfo(NULL)->toElem(irs)); 
    46364646 
    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); 
    46414652    return e; 
    46424653} 
    46434654 
    46444655 
    46454656/******************************************* 
    46464657 * Generate elem to zero fill contents of Symbol stmp 
    46474658 * from *poffset..offset2. 
    46484659 * May store anywhere from 0..maxoff, as this function 
    46494660 * tries to use aligned int stores whereever possible. 
    46504661 * Update *poffset to end of initialized hole; *poffset will be >= offset2. 
    46514662 */ 
    46524663 
    46534664elem *fillHole(Symbol *stmp, size_t *poffset, size_t offset2, size_t maxoff) 
    46544665{   elem *e = NULL; 
    46554666    int basealign = 1; 
    46564667 
    46574668    while (*poffset < offset2) 
    46584669    {   tym_t ty; 
  • trunk/src/msc.c

    r569 r579  
    2323#include        "dt.h" 
    2424#include        "cgcv.h" 
    2525 
    2626static char __file__[] = __FILE__;      /* for tassert.h                */ 
    2727#include        "tassert.h" 
    2828 
    2929extern Global global; 
    3030extern int REALSIZE; 
    3131 
    3232Config config; 
    3333Configv configv; 
    3434 
    3535struct Environment; 
    3636 
    3737/************************************** 
    3838 * Initialize config variables. 
    3939 */ 
    4040 
    4141void out_config_init() 
    4242{ 
     43    //printf("out_config_init()\n"); 
    4344    Param *params = &global.params; 
    4445 
    4546    if (!config.target_cpu) 
    4647    {   config.target_cpu = TARGET_PentiumPro; 
    4748        config.target_scheduler = config.target_cpu; 
    4849    } 
    4950    config.fulltypes = CVNONE; 
    5051    config.inline8087 = 1; 
    5152    config.memmodel = 0; 
    5253    config.flags |= CFGuchar;   // make sure TYchar is unsigned 
    5354#if TARGET_WINDOS 
    5455    if (params->isX86_64) 
    5556        config.exe = EX_WIN64; 
    5657    else 
    5758        config.exe = EX_NT; 
    5859 
    5960    // Win32 eh 
    6061    config.flags2 |= CFG2seh; 
    6162 
    6263    if (params->run)