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

Changeset 770

Show
Ignore:
Timestamp:
11/29/10 03:41:47 (14 years ago)
Author:
walter
Message:

bugzilla 5275 x86_64 related hidden function parameter mishandled

Files:

Legend:

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

    r738 r770  
    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> 
    1717#include        <time.h> 
    1818#include        "cc.h" 
    1919#include        "el.h" 
    2020#include        "oper.h" 
    2121#include        "code.h" 
    2222#include        "type.h" 
    2323#include        "global.h" 
    2424 
    2525static char __file__[] = __FILE__;      /* for tassert.h                */ 
    2626#include        "tassert.h" 
    2727 
     28/************************************* 
     29 * Handy function to answer the question: who the heck is generating this piece of code? 
     30 */ 
     31inline void ccheck(code *cs) 
     32{ 
     33//    if (cs->Iop == LEA && (cs->Irm & 0x3F) == 0x34 && cs->Isib == 7) *(char*)0=0; 
     34} 
     35 
    2836/***************************** 
    2937 * Find last code in list. 
    3038 */ 
    3139 
    3240code *code_last(code *c) 
    3341{ 
    3442    if (c) 
    3543    {   while (c->next) 
    3644            c = c->next; 
    3745    } 
    3846    return c; 
    3947} 
    4048 
    4149/***************************** 
    4250 * Set flag bits on last code in list. 
    4351 */ 
    4452 
    4553void code_orflag(code *c,unsigned flag) 
    4654{ 
    4755    if (flag && c) 
     
    145153 * Note that unused operands are garbage. 
    146154 * gen1() and gen2() are shortcut routines. 
    147155 * Input: 
    148156 *      c ->    linked list that code is to be added to end of 
    149157 *      cs ->   data for the code 
    150158 * Returns: 
    151159 *      pointer to start of code list 
    152160 */ 
    153161 
    154162code *gen(code *c,code *cs) 
    155163{   code *ce,*cstart; 
    156164    unsigned reg; 
    157165 
    158166#ifdef DEBUG                            /* this is a high usage routine */ 
    159167    assert(cs); 
    160168#endif 
    161169    assert(I64 || cs->Irex == 0); 
    162170    ce = code_calloc(); 
    163171    *ce = *cs; 
    164172    //printf("ce = %p %02x\n", ce, ce->Iop); 
    165     if (ce->Iop == LEA && ce->Irm == 4 && ce->Isib == 0x6D && ce->IFL1 == FLunde) *(char*)0=0
     173    ccheck(ce)
    166174    if (config.flags4 & CFG4optimized && 
    167175        ce->IFL2 == FLconst && 
    168176        (ce->Iop == 0x81 || ce->Iop == 0x80) && 
    169177        reghasvalue((ce->Iop == 0x80) ? BYTEREGS : ALLREGS,ce->IEV2.Vlong,&reg) && 
    170178        !(ce->Iflags & CFopsize && I16) 
    171179       ) 
    172180    {   // See if we can replace immediate instruction with register instruction 
    173181        static unsigned char regop[8] = 
    174182                { 0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38 }; 
    175183 
    176184        //printf("replacing 0x%02x, val = x%lx\n",ce->Iop,ce->IEV2.Vlong); 
    177185        ce->Iop = regop[(ce->Irm & modregrm(0,7,0)) >> 3] | (ce->Iop & 1); 
    178186        code_newreg(ce, reg); 
    179187    } 
    180188    code_next(ce) = CNIL; 
    181189    if (c) 
    182190    {   cstart = c; 
    183191        while (code_next(c)) c = code_next(c);  /* find end of list     */ 
    184192        code_next(c) = ce;                      /* link into list       */ 
    185193        return cstart; 
     
    192200 
    193201  ce = code_calloc(); 
    194202  ce->Iop = op; 
    195203  assert(op != LEA); 
    196204  if (c) 
    197205  {     cstart = c; 
    198206        while (code_next(c)) c = code_next(c);  /* find end of list     */ 
    199207        code_next(c) = ce;                      /* link into list       */ 
    200208        return cstart; 
    201209  } 
    202210  return ce; 
    203211} 
    204212 
    205213code *gen2(code *c,unsigned op,unsigned rm) 
    206214{ code *ce,*cstart; 
    207215 
    208216  cstart = ce = code_calloc(); 
    209217  /*cxcalloc++;*/ 
    210218  ce->Iop = op; 
    211219  ce->Iea = rm; 
     220  ccheck(ce); 
    212221  if (c) 
    213222  {     cstart = c; 
    214223        while (code_next(c)) c = code_next(c);  /* find end of list     */ 
    215224        code_next(c) = ce;                      /* link into list       */ 
    216225  } 
    217226  return cstart; 
    218227} 
    219228 
    220229code *gen2sib(code *c,unsigned op,unsigned rm,unsigned sib) 
    221230{ code *ce,*cstart; 
    222231 
    223232  cstart = ce = code_calloc(); 
    224233  /*cxcalloc++;*/ 
    225   if (op == LEA && (rm & 0xFF) == 4 && (sib & 0xFF) == 0x6D) *(char*)0=0; 
    226234  ce->Iop = op; 
    227235  ce->Irm = rm; 
    228236  ce->Isib = sib; 
    229237  ce->Irex = (rm | (sib & (REX_B << 16))) >> 16; 
    230238  if (sib & (REX_R << 16)) 
    231239        ce->Irex |= REX_X; 
     240  ccheck(ce); 
    232241  if (c) 
    233242  {     cstart = c; 
    234243        while (code_next(c)) c = code_next(c);  /* find end of list     */ 
    235244        code_next(c) = ce;                      /* link into list       */ 
    236245  } 
    237246  return cstart; 
    238247} 
    239248 
    240249code *genregs(code *c,unsigned op,unsigned dstreg,unsigned srcreg) 
    241250{ return gen2(c,op,modregxrmx(3,dstreg,srcreg)); } 
    242251 
    243252code *gentstreg(code *c,unsigned t) 
    244253{ 
    245254    c = gen2(c,0x85,modregxrmx(3,t,t));   // TEST t,t 
    246255    code_orflag(c,CFpsw); 
    247256    return c; 
    248257} 
    249258 
    250259code *genpush(code *c, unsigned reg) 
    251260{ 
     
    342351            c = genjmp(c,JP,FLcode,(block *) cnop); 
    343352            cat(cj,cnop); 
    344353            break; 
    345354        case 1 << 8:                    /* toggled no jump              */ 
    346355        case 0 << 8: 
    347356            break; 
    348357        default: 
    349358#ifdef DEBUG 
    350359            printf("jop = x%x\n",op); 
    351360#endif 
    352361            assert(0); 
    353362    } 
    354363    return cat(c,cj); 
    355364} 
    356365 
    357366code *gencs(code *c,unsigned op,unsigned ea,unsigned FL2,symbol *s) 
    358367{   code cs; 
    359368 
    360369    cs.Iop = op; 
    361370    cs.Iea = ea; 
     371    ccheck(&cs); 
    362372    cs.Iflags = 0; 
    363373    cs.IFL2 = FL2; 
    364374    cs.IEVsym2 = s; 
    365375    cs.IEVoffset2 = 0; 
    366376 
    367377    return gen(c,&cs); 
    368378} 
    369379 
    370380code *genc2(code *c,unsigned op,unsigned ea,targ_size_t EV2) 
    371381{   code cs; 
    372382 
    373383    cs.Iop = op; 
    374384    cs.Iea = ea; 
     385    ccheck(&cs); 
    375386    cs.Iflags = CFoff; 
    376387    cs.IFL2 = FLconst; 
    377388    cs.IEV2.Vsize_t = EV2; 
    378389    return gen(c,&cs); 
    379390} 
    380391 
    381392/***************** 
    382393 * Generate code. 
    383394 */ 
    384395 
    385396code *genc1(code *c,unsigned op,unsigned ea,unsigned FL1,targ_size_t EV1) 
    386397{   code cs; 
    387398 
    388399    assert(FL1 < FLMAX); 
    389400    cs.Iop = op; 
    390401    cs.Iflags = CFoff; 
    391402    cs.Iea = ea; 
     403    ccheck(&cs); 
    392404    cs.IFL1 = FL1; 
    393405    cs.IEV1.Vsize_t = EV1; 
    394 if (cs.Iop == LEA && cs.IFL1 == FLunde) *(char*)0=0; 
    395406    return gen(c,&cs); 
    396407} 
    397408 
    398409/***************** 
    399410 * Generate code. 
    400411 */ 
    401412 
    402413code *genc(code *c,unsigned op,unsigned ea,unsigned FL1,targ_size_t EV1,unsigned FL2,targ_size_t EV2) 
    403414{   code cs; 
    404415 
    405416    assert(FL1 < FLMAX); 
    406417    cs.Iop = op; 
    407418    cs.Iea = ea; 
     419    ccheck(&cs); 
    408420    cs.Iflags = CFoff; 
    409421    cs.IFL1 = FL1; 
    410422    cs.IEV1.Vsize_t = EV1; 
    411423    assert(FL2 < FLMAX); 
    412424    cs.IFL2 = FL2; 
    413425    cs.IEV2.Vsize_t = EV2; 
    414426    return gen(c,&cs); 
    415427} 
    416428 
    417429/*************************************** 
    418430 * Generate immediate multiply instruction for r1=r2*imm. 
    419431 * Optimize it into LEA's if we can. 
    420432 */ 
    421433 
    422434code *genmulimm(code *c,unsigned r1,unsigned r2,targ_int imm) 
    423435{   code cs; 
    424436 
    425437    // These optimizations should probably be put into pinholeopt() 
    426438    switch (imm) 
    427439    {   case 1: 
     
    539551 *      set flags based on result 
    540552 * Else if flags & 8 
    541553 *      do not disturb flags 
    542554 * Else 
    543555 *      don't care about flags 
    544556 * If flags & 1 then byte move 
    545557 * If flags & 2 then short move (for I32 and I64) 
    546558 * If flags & 4 then don't disturb unused portion of register 
    547559 * If flags & 16 then reg is a byte register AL..BH 
    548560 * If flags & 64 then 64 bit move (I64 only) 
    549561 * Returns: 
    550562 *      code (if any) generated 
    551563 */ 
    552564 
    553565code *movregconst(code *c,unsigned reg,targ_size_t value,regm_t flags) 
    554566{   unsigned r; 
    555567    regm_t regm; 
    556568    regm_t mreg; 
    557569    targ_size_t regv; 
    558570 
     571    //printf("movregconst(%llx)\n", value); 
    559572#define genclrreg(a,r) genregs(a,0x31,r,r) 
    560573 
    561574    regm = regcon.immed.mval & mask[reg]; 
    562575    regv = regcon.immed.value[reg]; 
    563576 
    564577    if (flags & 1)      // 8 bits 
    565578    {   unsigned msk; 
    566579 
    567580        value &= 0xFF; 
    568581        regm &= BYTEREGS; 
    569582 
    570583        // If we already have the right value in the right register 
    571584        if (regm && (regv & 0xFF) == value) 
    572585            goto L2; 
    573586 
    574587        if (flags & 16 && reg & 4 &&    // if an H byte register 
    575588            regcon.immed.mval & mask[reg & 3] && 
    576589            (((regv = regcon.immed.value[reg & 3]) >> 8) & 0xFF) == value) 
    577590            goto L2; 
    578591 
  • branches/dmd-1.x/src/backend/cod1.c

    r768 r770  
    29482948                    {   if (mfuncreg == 0)      /* if no registers left */ 
    29492949                        {   needframe = TRUE; 
    29502950                            break; 
    29512951                        } 
    29522952                    } 
    29532953                } 
    29542954            } 
    29552955        } 
    29562956  } 
    29572957#endif 
    29582958 
    29592959    retregs = regmask(e->Ety, tym1); 
    29602960 
    29612961    // If stack needs cleanup 
    29622962    if (OTbinary(e->Eoper) && 
    29632963        !typfunc(tym1) && 
    29642964      !(s && s->Sflags & SFLexit)) 
    29652965    { 
    29662966        if (tym1 == TYhfunc) 
    29672967        {   // Hidden parameter is popped off by the callee 
    2968             c = genadjesp(c, -4); 
    2969             stackpush -= 4
    2970             if (numpara + numalign > 4
    2971                 c = genstackclean(c, numpara + numalign - 4, retregs); 
     2968            c = genadjesp(c, -REGSIZE); 
     2969            stackpush -= REGSIZE
     2970            if (numpara + numalign > REGSIZE
     2971                c = genstackclean(c, numpara + numalign - REGSIZE, retregs); 
    29722972        } 
    29732973        else 
    29742974            c = genstackclean(c,numpara + numalign,retregs); 
    29752975    } 
    29762976    else 
    29772977    { 
    29782978        c = genadjesp(c,-numpara); 
    29792979        stackpush -= numpara; 
    29802980        if (numalign) 
    29812981            c = genstackclean(c,numalign,retregs); 
    29822982    } 
    29832983 
    29842984    /* Special handling for functions which return a floating point 
    29852985       value in the top of the 8087 stack. 
    29862986     */ 
    29872987 
    29882988    if (retregs & mST0) 
    29892989    { 
    29902990        if (*pretregs)                  // if we want the result 
    29912991        {   //assert(stackused == 0); 
  • trunk/src/backend/cod1.c

    r768 r770  
    29482948                    {   if (mfuncreg == 0)      /* if no registers left */ 
    29492949                        {   needframe = TRUE; 
    29502950                            break; 
    29512951                        } 
    29522952                    } 
    29532953                } 
    29542954            } 
    29552955        } 
    29562956  } 
    29572957#endif 
    29582958 
    29592959    retregs = regmask(e->Ety, tym1); 
    29602960 
    29612961    // If stack needs cleanup 
    29622962    if (OTbinary(e->Eoper) && 
    29632963        !typfunc(tym1) && 
    29642964      !(s && s->Sflags & SFLexit)) 
    29652965    { 
    29662966        if (tym1 == TYhfunc) 
    29672967        {   // Hidden parameter is popped off by the callee 
    2968             c = genadjesp(c, -4); 
    2969             stackpush -= 4
    2970             if (numpara + numalign > 4
    2971                 c = genstackclean(c, numpara + numalign - 4, retregs); 
     2968            c = genadjesp(c, -REGSIZE); 
     2969            stackpush -= REGSIZE
     2970            if (numpara + numalign > REGSIZE
     2971                c = genstackclean(c, numpara + numalign - REGSIZE, retregs); 
    29722972        } 
    29732973        else 
    29742974            c = genstackclean(c,numpara + numalign,retregs); 
    29752975    } 
    29762976    else 
    29772977    { 
    29782978        c = genadjesp(c,-numpara); 
    29792979        stackpush -= numpara; 
    29802980        if (numalign) 
    29812981            c = genstackclean(c,numalign,retregs); 
    29822982    } 
    29832983 
    29842984    /* Special handling for functions which return a floating point 
    29852985       value in the top of the 8087 stack. 
    29862986     */ 
    29872987 
    29882988    if (retregs & mST0) 
    29892989    { 
    29902990        if (*pretregs)                  // if we want the result 
    29912991        {   //assert(stackused == 0);