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

Changeset 772

Show
Ignore:
Timestamp:
12/03/10 23:52:08 (14 years ago)
Author:
walter
Message:

64 bit fixes for Brad

Files:

Legend:

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

    r768 r772  
    5353 
    5454int stackused = 0;              /* number of items on the 8087 stack    */ 
    5555 
    5656/********************************* 
    5757 */ 
    5858 
    5959struct Dconst 
    6060{ 
    6161    int round; 
    6262    symbol *roundto0; 
    6363    symbol *roundtonearest; 
    6464}; 
    6565 
    6666static Dconst oldd; 
    6767 
    6868#define NDPP    0       // print out debugging info 
    6969 
    7070code *loadComplex(elem *e); 
    7171code *opmod_complex87(elem *e,regm_t *pretregs); 
    7272code *opass_complex87(elem *e,regm_t *pretregs); 
    73 STATIC code * genf2(code *c,unsigned op,unsigned rm); 
     73code * genf2(code *c,unsigned op,unsigned rm); 
    7474 
    7575#define CW_roundto0             0xFBF 
    7676#define CW_roundtonearest       0x3BF 
    7777 
    7878STATIC code *genrnd(code *c, short cw); 
    7979 
    8080/********************************** 
    8181 * When we need to temporarilly save 8087 registers, we record information 
    8282 * about the save into an array of NDP structs: 
    8383 */ 
    8484 
    8585NDP *NDP::save = NULL; 
    8686int NDP::savemax = 0;           /* # of entries in NDP::save[]          */ 
    8787int NDP::savetop = 0;           /* # of entries used in NDP::save[]     */ 
    8888 
    8989#ifdef DEBUG 
    9090#define NDPSAVEINC 2            /* flush reallocation bugs              */ 
    9191#else 
    9292#define NDPSAVEINC 8            /* allocation chunk sizes               */ 
    9393#endif 
     
    508508        if ((opcode & ~7) == 0xD8) 
    509509            c = genfwait(c); 
    510510        return genc1(c,opcode,modregxrm(2,reg,BPRM),FLfltreg,offset); 
    511511} 
    512512 
    513513/******************************* 
    514514 * Decide if we need to gen an FWAIT. 
    515515 */ 
    516516 
    517517code *genfwait(code *c) 
    518518{ 
    519519    if (ADDFWAIT()) 
    520520        c = gen1(c,FWAIT); 
    521521    return c; 
    522522} 
    523523 
    524524/*************************************** 
    525525 * Generate floating point instruction. 
    526526 */ 
    527527 
    528 STATIC code * genf2(code *c,unsigned op,unsigned rm) 
     528code * genf2(code *c,unsigned op,unsigned rm) 
    529529{ 
    530530    return gen2(genfwait(c),op,rm); 
    531531} 
    532532 
    533533/*************************** 
    534534 * Put the 8087 flags into the CPU flags. 
    535535 */ 
    536536 
    537537STATIC code * cg87_87topsw(code *c) 
    538538{ 
    539539        c = cat(c,getregs(mAX)); 
    540540        if (config.target_cpu >= TARGET_80286) 
    541541            c = genf2(c,0xDF,0xE0);             // FSTSW AX 
    542542        else 
    543543        {   c = genfltreg(c,0xD8+5,7,0);        /* FSTSW floatreg[BP]   */ 
    544544            genfwait(c);                        /* FWAIT                */ 
    545545            genfltreg(c,0x8A,4,1);              /* MOV AH,floatreg+1[BP] */ 
    546546        } 
    547547        gen1(c,0x9E);                           // SAHF 
    548548        code_orflag(c,CFpsw); 
     
    16721672                break; 
    16731673 
    16741674            case OPs64_d: 
    16751675                if (e->E1->Eoper == OPvar || 
    16761676                    (e->E1->Eoper == OPind && e->E1->Ecount == 0)) 
    16771677                { 
    16781678                    c = getlvalue(&cs,e->E1,0); 
    16791679                    cs.Iop = 0xDF; 
    16801680                    if (ADDFWAIT()) 
    16811681                        cs.Iflags |= CFwait; 
    16821682                    if (!I16) 
    16831683                        cs.Iflags &= ~CFopsize; 
    16841684                    c = cat(c,push87()); 
    16851685                    cs.Irm |= modregrm(0,5,0); 
    16861686                    c = gen(c,&cs);                     // FILD m64 
    16871687                    // Variable cannot be put into a register anymore 
    16881688                    if (e->E1->Eoper == OPvar) 
    16891689                        notreg(e->E1); 
    16901690                    freenode(e->E1); 
    16911691                } 
     1692                else if (I64) 
     1693                { 
     1694                    retregs = ALLREGS; 
     1695                    c = codelem(e->E1,&retregs,FALSE); 
     1696                    reg = findreg(retregs); 
     1697                    c = genfltreg(c,0x89,reg,0);        // MOV floatreg,reg 
     1698                    code_orrex(c, REX_W); 
     1699                    c = cat(c,push87()); 
     1700                    c = genfltreg(c,0xDF,5,0);          // FILD long long ptr floatreg 
     1701                } 
    16921702                else 
    16931703                { 
    16941704                    retregs = ALLREGS; 
    16951705                    c = codelem(e->E1,&retregs,FALSE); 
    16961706                    reg = findreglsw(retregs); 
    16971707                    c = genfltreg(c,0x89,reg,0);        // MOV floatreg,reglsw 
    16981708                    reg = findregmsw(retregs); 
    16991709                    c = genfltreg(c,0x89,reg,4);        // MOV floatreg+4,regmsw 
    17001710                    c = cat(c,push87()); 
    17011711                    c = genfltreg(c,0xDF,5,0);          // FILD long long ptr floatreg 
    17021712                } 
    17031713                if (op != -1) 
    17041714                {   c = cat(c,makesure87(eleft,eoffset,1,0)); 
    17051715                    c = genf2(c,0xDE,modregrm(3,opr,1)); // FopRP 
    17061716                    pop87(); 
    17071717                } 
    17081718                break; 
    17091719 
    17101720            case OPconst: 
    17111721                ldop = loadconst(e, 0); 
  • branches/dmd-1.x/src/backend/cgen.c

    r770 r772  
    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 
    2828/************************************* 
    2929 * Handy function to answer the question: who the heck is generating this piece of code? 
    3030 */ 
    3131inline void ccheck(code *cs) 
    3232{ 
    3333//    if (cs->Iop == LEA && (cs->Irm & 0x3F) == 0x34 && cs->Isib == 7) *(char*)0=0; 
     34//    if (cs->Iop == 0x31) *(char*)0=0; 
    3435} 
    3536 
    3637/***************************** 
    3738 * Find last code in list. 
    3839 */ 
    3940 
    4041code *code_last(code *c) 
    4142{ 
    4243    if (c) 
    4344    {   while (c->next) 
    4445            c = c->next; 
    4546    } 
    4647    return c; 
    4748} 
    4849 
    4950/***************************** 
    5051 * Set flag bits on last code in list. 
    5152 */ 
    5253 
    5354void code_orflag(code *c,unsigned flag) 
     
    587588        if (flags & 16 && reg & 4 &&    // if an H byte register 
    588589            regcon.immed.mval & mask[reg & 3] && 
    589590            (((regv = regcon.immed.value[reg & 3]) >> 8) & 0xFF) == value) 
    590591            goto L2; 
    591592 
    592593        /* Avoid byte register loads on Pentium Pro and Pentium II 
    593594         * to avoid dependency stalls. 
    594595         */ 
    595596        if (config.flags4 & CFG4speed && 
    596597            config.target_cpu >= TARGET_PentiumPro && !(flags & 4)) 
    597598            goto L3; 
    598599 
    599600        // See if another register has the right value 
    600601        r = 0; 
    601602        for (mreg = (regcon.immed.mval & BYTEREGS); mreg; mreg >>= 1) 
    602603        { 
    603604            if (mreg & 1) 
    604605            { 
    605606                if ((regcon.immed.value[r] & 0xFF) == value) 
    606607                {   c = genregs(c,0x8A,reg,r);          // MOV regL,rL 
     608                    if (I64 && r >= 4) 
     609                        code_orrex(c, REX); 
    607610                    goto L2; 
    608611                } 
    609612                if (r < 4 && ((regcon.immed.value[r] >> 8) & 0xFF) == value) 
    610613                {   c = genregs(c,0x8A,reg,r | 4);      // MOV regL,rH 
    611614                    goto L2; 
    612615                } 
    613616            } 
    614617            r++; 
    615618        } 
    616619 
    617620        if (value == 0 && !(flags & 8)) 
    618621        { 
    619622            if (!(flags & 4) &&                 // if we can set the whole register 
    620623                !(flags & 16 && reg & 4))       // and reg is not an H register 
    621624            {   c = genregs(c,0x31,reg,reg);    // XOR reg,reg 
    622625                regimmed_set(reg,value); 
    623626                regv = 0; 
    624627            } 
    625628            else 
    626629                c = genregs(c,0x30,reg,reg);    // XOR regL,regL 
  • branches/dmd-1.x/src/backend/cod1.c

    r771 r772  
    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        <stdlib.h> 
    1818#include        <time.h> 
    1919#include        "cc.h" 
    2020#include        "el.h" 
    2121#include        "oper.h" 
    2222#include        "code.h" 
    2323#include        "global.h" 
    2424#include        "type.h" 
    2525 
    2626static char __file__[] = __FILE__;      /* for tassert.h                */ 
    2727#include        "tassert.h" 
     28 
     29/* Generate the appropriate ESC instruction     */ 
     30#define ESC(MF,b)       (0xD8 + ((MF) << 1) + (b)) 
     31enum MF 
     32{       // Values for MF 
     33        MFfloat         = 0, 
     34        MFlong          = 1, 
     35        MFdouble        = 2, 
     36        MFword          = 3 
     37}; 
     38code * genf2(code *c,unsigned op,unsigned rm); 
    2839 
    2940targ_size_t paramsize(elem *e,unsigned stackalign); 
    3041STATIC code * funccall (elem *,unsigned,unsigned,regm_t *,regm_t); 
    3142 
    3243/* array to convert from index register to r/m field    */ 
    3344                                       /* AX CX DX BX SP BP SI DI       */ 
    3445static const signed char regtorm32[8] = {  0, 1, 2, 3,-1, 5, 6, 7 }; 
    3546             signed char regtorm  [8] = { -1,-1,-1, 7,-1, 6, 4, 5 }; 
    3647 
    3748/************************** 
    3849 * Determine if e is a 32 bit scaled index addressing mode. 
    3950 * Returns: 
    4051 *      0       not a scaled index addressing mode 
    4152 *      !=0     the value for ss in the SIB byte 
    4253 */ 
    4354 
    4455int isscaledindex(elem *e) 
    4556{   targ_uns ss; 
    4657 
    4758    assert(!I16); 
     
    37923803  if (e->Eoper == OPconst) 
    37933804  {     regm_t save; 
    37943805 
    37953806        if (sz == REGSIZE && reghasvalue(forregs,e->EV.Vint,&reg)) 
    37963807            forregs = mask[reg]; 
    37973808 
    37983809        save = regcon.immed.mval; 
    37993810        c = allocreg(&forregs,&reg,tym);        /* allocate registers   */ 
    38003811        regcon.immed.mval = save;               // KLUDGE! 
    38013812        if (sz <= REGSIZE) 
    38023813        { 
    38033814            if (sz == 1) 
    38043815                flags |= 1; 
    38053816            else if (!I16 && sz == SHORTSIZE && 
    38063817                     !(mask[reg] & regcon.mvar) && 
    38073818                     !(config.flags4 & CFG4speed) 
    38083819                    ) 
    38093820                flags |= 2; 
    38103821            if (sz == 8) 
    38113822                flags |= 64; 
    3812             ce = movregconst(CNIL,reg,e->EV.Vint,flags); 
    3813             flags = 0;                          // flags are already set 
     3823            if (reg >= XMM0) 
     3824            {   /* This comes about because 0, 1, pi, etc., constants don't get stored 
     3825                 * in the data segment, because they are x87 opcodes. 
     3826                 * Not so efficient. We should at least do a PXOR for 0. 
     3827                 */ 
     3828                unsigned r; 
     3829                targ_size_t value = e->EV.Vuns; 
     3830                if (sz == 8) 
     3831                    value = e->EV.Vullong; 
     3832                ce = regwithvalue(CNIL,ALLREGS,value,&r,flags); 
     3833                flags = 0;                              // flags are already set 
     3834                ce = genfltreg(ce,0x89,r,0);            // MOV floatreg,r 
     3835                if (sz == 8) 
     3836                    code_orrex(ce, REX_W); 
     3837                assert(sz == 4 || sz == 8);             // float or double 
     3838                unsigned op = (sz == 4) ? 0xF30F10 : 0xF20F10; 
     3839                ce = genfltreg(ce,op,reg - XMM0,0);     // MOVSS/MOVSD XMMreg,floatreg 
     3840            } 
     3841            else 
     3842            {   ce = movregconst(CNIL,reg,e->EV.Vint,flags); 
     3843                flags = 0;                          // flags are already set 
     3844            } 
    38143845        } 
    38153846        else if (sz < 8)        // far pointers, longs for 16 bit targets 
    38163847        { 
    38173848            targ_int msw,lsw; 
    38183849            regm_t mswflags; 
    38193850 
    38203851            msw = I32   ? e->EV.Vfp.Vseg 
    38213852                        : (e->EV.Vulong >> 16); 
    38223853            lsw = e->EV.Vfp.Voff; 
    38233854            mswflags = 0; 
    38243855            if (forregs & mES) 
    38253856            { 
    38263857                ce = movregconst(CNIL,reg,msw,0);       // MOV reg,segment 
    38273858                genregs(ce,0x8E,0,reg);                 // MOV ES,reg 
    38283859                msw = lsw;                              // MOV reg,offset 
    38293860            } 
    38303861            else 
    38313862            { 
    38323863                sreg = findreglsw(forregs); 
    38333864                ce = movregconst(CNIL,sreg,lsw,0); 
  • branches/dmd-1.x/src/backend/cod2.c

    r771 r772  
    15711571  code *cc,*c,*c1,*cnop1,*c2,*cnop2; 
    15721572  con_t regconold,regconsave; 
    15731573  unsigned stackpushold,stackpushsave; 
    15741574  int ehindexold,ehindexsave; 
    15751575  unsigned jop; 
    15761576  unsigned op1; 
    15771577  unsigned sz1; 
    15781578  unsigned sz2; 
    15791579  elem *e1; 
    15801580  elem *e2; 
    15811581  elem *e21; 
    15821582  elem *e22; 
    15831583 
    15841584  /* vars to save state of 8087 */ 
    15851585  int stackusedold,stackusedsave; 
    15861586  NDP _8087old[arraysize(_8087elems)]; 
    15871587  NDP _8087save[arraysize(_8087elems)]; 
    15881588 
    15891589  _chkstack(); 
    15901590 
    1591   //dbg_printf("cdcond(e = %p, *pretregs = x%x)\n",e,*pretregs); 
     1591  //printf("cdcond(e = %p, *pretregs = %s)\n",e,regm_str(*pretregs)); 
    15921592  e1 = e->E1; 
    15931593  e2 = e->E2; 
    15941594  e21 = e2->E1; 
    15951595  e22 = e2->E2; 
    15961596  cc = docommas(&e1); 
    15971597  cgstate.stackclean++; 
    15981598  psw = *pretregs & mPSW;               /* save PSW bit                 */ 
    15991599  op1 = e1->Eoper; 
    16001600  sz1 = tysize(e1->Ety); 
    16011601  unsigned rex = (I64 && sz1 == 8) ? REX_W : 0; 
    16021602  unsigned grex = rex << 16; 
    16031603  jop = jmpopcode(e1); 
    16041604 
    16051605  if (!OTrel(op1) && e1 == e21 && 
    16061606      sz1 <= REGSIZE && !tyfloating(e1->Ety)) 
    16071607  {     // Recognize (e ? e : f) 
    16081608        regm_t retregs; 
    16091609 
    16101610        cnop1 = gennop(CNIL); 
    16111611        retregs = *pretregs | mPSW; 
  • branches/dmd-1.x/src/backend/cod3.c

    r771 r772  
    12661266    for (regm_t x = topush; x; x >>= 1) 
    12671267        npush += x & 1; 
    12681268 
    12691269    // Keep the stack aligned by 8 for any subsequent function calls 
    12701270    if (!I16 && calledafunc && 
    12711271        (STACKALIGN == 16 || config.flags4 & CFG4stackalign)) 
    12721272    { 
    12731273        //printf("npush = %d Poff = x%x needframe = %d localsize = x%x\n", npush, Poff, needframe, localsize); 
    12741274 
    12751275        int sz = Poff + (needframe ? 0 : -REGSIZE) + localsize + npush * REGSIZE; 
    12761276        if (STACKALIGN == 16) 
    12771277        { 
    12781278            if (sz & (8|4)) 
    12791279                localsize += STACKALIGN - (sz & (8|4)); 
    12801280        } 
    12811281        else if (sz & 4) 
    12821282            localsize += 4; 
    12831283    } 
    12841284 
    12851285    //printf("Foff x%02x Aoff x%02x Toff x%02x NDPoff x%02x CSoff x%02x Poff x%02x localsize x%02x\n", 
    1286         //Foff,Aoff,Toff,NDPoff,CSoff,Poff,localsize); 
     1286        //(int)Foff,(int)Aoff,(int)Toff,(int)NDPoff,(int)CSoff,(int)Poff,(int)localsize); 
    12871287 
    12881288    xlocalsize = localsize; 
    12891289 
    12901290    if (tyf & mTYnaked)                 // if no prolog/epilog for function 
    12911291    { 
    12921292        hasframe = 1; 
    12931293        return NULL; 
    12941294    } 
    12951295 
    12961296    if (tym == TYifunc) 
    12971297    {   static unsigned char ops2[] = { 0x60,0x1E,0x06,0 }; 
    12981298        static unsigned char ops0[] = { 0x50,0x51,0x52,0x53, 
    12991299                                        0x54,0x55,0x56,0x57, 
    13001300                                        0x1E,0x06,0 }; 
    13011301 
    13021302        unsigned char *p; 
    13031303 
    13041304        p = (config.target_cpu >= TARGET_80286) ? ops2 : ops0; 
    13051305        do 
    13061306            c = gen1(c,*p); 
     
    18381838            } 
    18391839        } 
    18401840    } 
    18411841 
    18421842    /* Load arguments passed in registers into the varargs save area 
    18431843     * so they can be accessed by va_arg(). 
    18441844     */ 
    18451845    if (I64 && variadic(funcsym_p->Stype)) 
    18461846    { 
    18471847        /* Look for __va_argsave 
    18481848         */ 
    18491849        symbol *sv = NULL; 
    18501850        for (SYMIDX si = 0; si < globsym.top; si++) 
    18511851        {   symbol *s = globsym.tab[si]; 
    18521852            if (s->Sident[0] == '_' && strcmp(s->Sident, "__va_argsave") == 0) 
    18531853            {   sv = s; 
    18541854                break; 
    18551855            } 
    18561856        } 
    18571857 
    1858         if (sv
     1858        if (sv && !(sv->Sflags & SFLdead)
    18591859        { 
    18601860        /* Generate code to move any arguments passed in registers into 
    18611861         * the stack variable __va_argsave, 
    18621862         * so we can reference it via pointers through va_arg(). 
    18631863         *   struct __va_argsave_t { 
    18641864         *     size_t[6] regs; 
    18651865         *     real[8] fpregs; 
    18661866         *     uint offset_regs; 
    18671867         *     uint offset_fpregs; 
    18681868         *     void* stack_args; 
    18691869         *     void* reg_args; 
    18701870         *   } 
    18711871         * The MOVAPS instructions seg fault if data is not aligned on 
    18721872         * 16 bytes, so this gives us a nice check to ensure no mistakes. 
    18731873            MOV     voff+0*8[RBP],EDI 
    18741874            MOV     voff+1*8[RBP],ESI 
    18751875            MOV     voff+2*8[RBP],RDX 
    18761876            MOV     voff+3*8[RBP],RCX 
    18771877            MOV     voff+4*8[RBP],R8 
    18781878            MOV     voff+5*8[RBP],R9 
  • branches/dmd-1.x/src/backend/cod4.c

    r771 r772  
    24622462                    goto Lcomplex; 
    24632463                /* FALL-THROUGH */ 
    24642464            case OPs64_d: 
    24652465            case OPs32_d: 
    24662466            case OPs16_d: 
    24672467            case OPu16_d: 
    24682468                return load87(e,0,pretregs,NULL,-1); 
    24692469            case OPu32_d: 
    24702470                if (!I16) 
    24712471                { 
    24722472                    unsigned retregs = ALLREGS; 
    24732473                    c1 = codelem(e->E1, &retregs, FALSE); 
    24742474                    unsigned reg = findreg(retregs); 
    24752475                    c1 = genfltreg(c1, 0x89, reg, 0); 
    24762476                    regwithvalue(c1,ALLREGS,0,&reg,0); 
    24772477                    genfltreg(c1, 0x89, reg, REGSIZE); 
    24782478 
    24792479                    cat(c1, push87()); 
    24802480                    genfltreg(c1,0xDF,5,0);     // FILD m64int 
    24812481 
    2482                     retregs = mST0 | (*pretregs & mPSW)
     2482                    retregs = mST0 /*| (*pretregs & mPSW)*/
    24832483                    c2 = fixresult87(e, retregs, pretregs); 
    24842484                    return cat(c1, c2); 
    24852485                } 
    24862486                break; 
    24872487            case OPd_s16: 
    24882488            case OPd_s32: 
    24892489            case OPd_u16: 
    24902490            case OPd_s64: 
    24912491                return cnvt87(e,pretregs); 
    24922492            case OPd_u32:               // use subroutine, not 8087 
    24932493#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 
    24942494                retregs = mST0; 
    24952495#else 
    24962496                retregs = DOUBLEREGS; 
    24972497#endif 
    24982498                goto L1; 
    24992499 
    25002500            case OPd_u64: 
    25012501                retregs = DOUBLEREGS; 
    25022502                goto L1; 
  • branches/dmd-1.x/src/glue.c

    r705 r772  
    11351135} 
    11361136 
    11371137unsigned TypeFunction::totym() 
    11381138{ 
    11391139    tym_t tyf; 
    11401140 
    11411141    //printf("TypeFunction::totym(), linkage = %d\n", linkage); 
    11421142    switch (linkage) 
    11431143    { 
    11441144        case LINKwindows: 
    11451145            tyf = (varargs == 1) ? TYnfunc : TYnsfunc; 
    11461146            break; 
    11471147 
    11481148        case LINKpascal: 
    11491149            tyf = (varargs == 1) ? TYnfunc : TYnpfunc; 
    11501150            break; 
    11511151 
    11521152        case LINKc: 
    11531153            tyf = TYnfunc; 
    11541154#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 
    1155             if (retStyle() == RETstack) 
     1155            if (I32 && retStyle() == RETstack) 
    11561156                tyf = TYhfunc; 
    11571157#endif 
    11581158            break; 
    11591159 
    11601160        case LINKd: 
    11611161            tyf = (varargs == 1) ? TYnfunc : TYjfunc; 
    11621162            break; 
    11631163 
    11641164        case LINKcpp: 
    11651165            tyf = TYnfunc; 
    11661166            break; 
    11671167 
    11681168        default: 
    11691169            printf("linkage = %d\n", linkage); 
    11701170            assert(0); 
    11711171    } 
    11721172#if DMDV2 
    11731173    if (isnothrow) 
    11741174        tyf |= mTYnothrow; 
    11751175#endif 
  • trunk/src/backend/cg87.c

    r768 r772  
    5353 
    5454int stackused = 0;              /* number of items on the 8087 stack    */ 
    5555 
    5656/********************************* 
    5757 */ 
    5858 
    5959struct Dconst 
    6060{ 
    6161    int round; 
    6262    symbol *roundto0; 
    6363    symbol *roundtonearest; 
    6464}; 
    6565 
    6666static Dconst oldd; 
    6767 
    6868#define NDPP    0       // print out debugging info 
    6969 
    7070code *loadComplex(elem *e); 
    7171code *opmod_complex87(elem *e,regm_t *pretregs); 
    7272code *opass_complex87(elem *e,regm_t *pretregs); 
    73 STATIC code * genf2(code *c,unsigned op,unsigned rm); 
     73code * genf2(code *c,unsigned op,unsigned rm); 
    7474 
    7575#define CW_roundto0             0xFBF 
    7676#define CW_roundtonearest       0x3BF 
    7777 
    7878STATIC code *genrnd(code *c, short cw); 
    7979 
    8080/********************************** 
    8181 * When we need to temporarilly save 8087 registers, we record information 
    8282 * about the save into an array of NDP structs: 
    8383 */ 
    8484 
    8585NDP *NDP::save = NULL; 
    8686int NDP::savemax = 0;           /* # of entries in NDP::save[]          */ 
    8787int NDP::savetop = 0;           /* # of entries used in NDP::save[]     */ 
    8888 
    8989#ifdef DEBUG 
    9090#define NDPSAVEINC 2            /* flush reallocation bugs              */ 
    9191#else 
    9292#define NDPSAVEINC 8            /* allocation chunk sizes               */ 
    9393#endif 
     
    508508        if ((opcode & ~7) == 0xD8) 
    509509            c = genfwait(c); 
    510510        return genc1(c,opcode,modregxrm(2,reg,BPRM),FLfltreg,offset); 
    511511} 
    512512 
    513513/******************************* 
    514514 * Decide if we need to gen an FWAIT. 
    515515 */ 
    516516 
    517517code *genfwait(code *c) 
    518518{ 
    519519    if (ADDFWAIT()) 
    520520        c = gen1(c,FWAIT); 
    521521    return c; 
    522522} 
    523523 
    524524/*************************************** 
    525525 * Generate floating point instruction. 
    526526 */ 
    527527 
    528 STATIC code * genf2(code *c,unsigned op,unsigned rm) 
     528code * genf2(code *c,unsigned op,unsigned rm) 
    529529{ 
    530530    return gen2(genfwait(c),op,rm); 
    531531} 
    532532 
    533533/*************************** 
    534534 * Put the 8087 flags into the CPU flags. 
    535535 */ 
    536536 
    537537STATIC code * cg87_87topsw(code *c) 
    538538{ 
    539539        c = cat(c,getregs(mAX)); 
    540540        if (config.target_cpu >= TARGET_80286) 
    541541            c = genf2(c,0xDF,0xE0);             // FSTSW AX 
    542542        else 
    543543        {   c = genfltreg(c,0xD8+5,7,0);        /* FSTSW floatreg[BP]   */ 
    544544            genfwait(c);                        /* FWAIT                */ 
    545545            genfltreg(c,0x8A,4,1);              /* MOV AH,floatreg+1[BP] */ 
    546546        } 
    547547        gen1(c,0x9E);                           // SAHF 
    548548        code_orflag(c,CFpsw); 
     
    16721672                break; 
    16731673 
    16741674            case OPs64_d: 
    16751675                if (e->E1->Eoper == OPvar || 
    16761676                    (e->E1->Eoper == OPind && e->E1->Ecount == 0)) 
    16771677                { 
    16781678                    c = getlvalue(&cs,e->E1,0); 
    16791679                    cs.Iop = 0xDF; 
    16801680                    if (ADDFWAIT()) 
    16811681                        cs.Iflags |= CFwait; 
    16821682                    if (!I16) 
    16831683                        cs.Iflags &= ~CFopsize; 
    16841684                    c = cat(c,push87()); 
    16851685                    cs.Irm |= modregrm(0,5,0); 
    16861686                    c = gen(c,&cs);                     // FILD m64 
    16871687                    // Variable cannot be put into a register anymore 
    16881688                    if (e->E1->Eoper == OPvar) 
    16891689                        notreg(e->E1); 
    16901690                    freenode(e->E1); 
    16911691                } 
     1692                else if (I64) 
     1693                { 
     1694                    retregs = ALLREGS; 
     1695                    c = codelem(e->E1,&retregs,FALSE); 
     1696                    reg = findreg(retregs); 
     1697                    c = genfltreg(c,0x89,reg,0);        // MOV floatreg,reg 
     1698                    code_orrex(c, REX_W); 
     1699                    c = cat(c,push87()); 
     1700                    c = genfltreg(c,0xDF,5,0);          // FILD long long ptr floatreg 
     1701                } 
    16921702                else 
    16931703                { 
    16941704                    retregs = ALLREGS; 
    16951705                    c = codelem(e->E1,&retregs,FALSE); 
    16961706                    reg = findreglsw(retregs); 
    16971707                    c = genfltreg(c,0x89,reg,0);        // MOV floatreg,reglsw 
    16981708                    reg = findregmsw(retregs); 
    16991709                    c = genfltreg(c,0x89,reg,4);        // MOV floatreg+4,regmsw 
    17001710                    c = cat(c,push87()); 
    17011711                    c = genfltreg(c,0xDF,5,0);          // FILD long long ptr floatreg 
    17021712                } 
    17031713                if (op != -1) 
    17041714                {   c = cat(c,makesure87(eleft,eoffset,1,0)); 
    17051715                    c = genf2(c,0xDE,modregrm(3,opr,1)); // FopRP 
    17061716                    pop87(); 
    17071717                } 
    17081718                break; 
    17091719 
    17101720            case OPconst: 
    17111721                ldop = loadconst(e, 0); 
  • trunk/src/backend/cgen.c

    r769 r772  
    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 
    2828/************************************* 
    2929 * Handy function to answer the question: who the heck is generating this piece of code? 
    3030 */ 
    3131inline void ccheck(code *cs) 
    3232{ 
    3333//    if (cs->Iop == LEA && (cs->Irm & 0x3F) == 0x34 && cs->Isib == 7) *(char*)0=0; 
     34//    if (cs->Iop == 0x31) *(char*)0=0; 
    3435} 
    3536 
    3637/***************************** 
    3738 * Find last code in list. 
    3839 */ 
    3940 
    4041code *code_last(code *c) 
    4142{ 
    4243    if (c) 
    4344    {   while (c->next) 
    4445            c = c->next; 
    4546    } 
    4647    return c; 
    4748} 
    4849 
    4950/***************************** 
    5051 * Set flag bits on last code in list. 
    5152 */ 
    5253 
    5354void code_orflag(code *c,unsigned flag) 
     
    587588        if (flags & 16 && reg & 4 &&    // if an H byte register 
    588589            regcon.immed.mval & mask[reg & 3] && 
    589590            (((regv = regcon.immed.value[reg & 3]) >> 8) & 0xFF) == value) 
    590591            goto L2; 
    591592 
    592593        /* Avoid byte register loads on Pentium Pro and Pentium II 
    593594         * to avoid dependency stalls. 
    594595         */ 
    595596        if (config.flags4 & CFG4speed && 
    596597            config.target_cpu >= TARGET_PentiumPro && !(flags & 4)) 
    597598            goto L3; 
    598599 
    599600        // See if another register has the right value 
    600601        r = 0; 
    601602        for (mreg = (regcon.immed.mval & BYTEREGS); mreg; mreg >>= 1) 
    602603        { 
    603604            if (mreg & 1) 
    604605            { 
    605606                if ((regcon.immed.value[r] & 0xFF) == value) 
    606607                {   c = genregs(c,0x8A,reg,r);          // MOV regL,rL 
     608                    if (I64 && r >= 4) 
     609                        code_orrex(c, REX); 
    607610                    goto L2; 
    608611                } 
    609612                if (r < 4 && ((regcon.immed.value[r] >> 8) & 0xFF) == value) 
    610613                {   c = genregs(c,0x8A,reg,r | 4);      // MOV regL,rH 
    611614                    goto L2; 
    612615                } 
    613616            } 
    614617            r++; 
    615618        } 
    616619 
    617620        if (value == 0 && !(flags & 8)) 
    618621        { 
    619622            if (!(flags & 4) &&                 // if we can set the whole register 
    620623                !(flags & 16 && reg & 4))       // and reg is not an H register 
    621624            {   c = genregs(c,0x31,reg,reg);    // XOR reg,reg 
    622625                regimmed_set(reg,value); 
    623626                regv = 0; 
    624627            } 
    625628            else 
    626629                c = genregs(c,0x30,reg,reg);    // XOR regL,regL 
  • trunk/src/backend/cod1.c

    r771 r772  
    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        <stdlib.h> 
    1818#include        <time.h> 
    1919#include        "cc.h" 
    2020#include        "el.h" 
    2121#include        "oper.h" 
    2222#include        "code.h" 
    2323#include        "global.h" 
    2424#include        "type.h" 
    2525 
    2626static char __file__[] = __FILE__;      /* for tassert.h                */ 
    2727#include        "tassert.h" 
     28 
     29/* Generate the appropriate ESC instruction     */ 
     30#define ESC(MF,b)       (0xD8 + ((MF) << 1) + (b)) 
     31enum MF 
     32{       // Values for MF 
     33        MFfloat         = 0, 
     34        MFlong          = 1, 
     35        MFdouble        = 2, 
     36        MFword          = 3 
     37}; 
     38code * genf2(code *c,unsigned op,unsigned rm); 
    2839 
    2940targ_size_t paramsize(elem *e,unsigned stackalign); 
    3041STATIC code * funccall (elem *,unsigned,unsigned,regm_t *,regm_t); 
    3142 
    3243/* array to convert from index register to r/m field    */ 
    3344                                       /* AX CX DX BX SP BP SI DI       */ 
    3445static const signed char regtorm32[8] = {  0, 1, 2, 3,-1, 5, 6, 7 }; 
    3546             signed char regtorm  [8] = { -1,-1,-1, 7,-1, 6, 4, 5 }; 
    3647 
    3748/************************** 
    3849 * Determine if e is a 32 bit scaled index addressing mode. 
    3950 * Returns: 
    4051 *      0       not a scaled index addressing mode 
    4152 *      !=0     the value for ss in the SIB byte 
    4253 */ 
    4354 
    4455int isscaledindex(elem *e) 
    4556{   targ_uns ss; 
    4657 
    4758    assert(!I16); 
     
    37923803  if (e->Eoper == OPconst) 
    37933804  {     regm_t save; 
    37943805 
    37953806        if (sz == REGSIZE && reghasvalue(forregs,e->EV.Vint,&reg)) 
    37963807            forregs = mask[reg]; 
    37973808 
    37983809        save = regcon.immed.mval; 
    37993810        c = allocreg(&forregs,&reg,tym);        /* allocate registers   */ 
    38003811        regcon.immed.mval = save;               // KLUDGE! 
    38013812        if (sz <= REGSIZE) 
    38023813        { 
    38033814            if (sz == 1) 
    38043815                flags |= 1; 
    38053816            else if (!I16 && sz == SHORTSIZE && 
    38063817                     !(mask[reg] & regcon.mvar) && 
    38073818                     !(config.flags4 & CFG4speed) 
    38083819                    ) 
    38093820                flags |= 2; 
    38103821            if (sz == 8) 
    38113822                flags |= 64; 
    3812             ce = movregconst(CNIL,reg,e->EV.Vint,flags); 
    3813             flags = 0;                          // flags are already set 
     3823            if (reg >= XMM0) 
     3824            {   /* This comes about because 0, 1, pi, etc., constants don't get stored 
     3825                 * in the data segment, because they are x87 opcodes. 
     3826                 * Not so efficient. We should at least do a PXOR for 0. 
     3827                 */ 
     3828                unsigned r; 
     3829                targ_size_t value = e->EV.Vuns; 
     3830                if (sz == 8) 
     3831                    value = e->EV.Vullong; 
     3832                ce = regwithvalue(CNIL,ALLREGS,value,&r,flags); 
     3833                flags = 0;                              // flags are already set 
     3834                ce = genfltreg(ce,0x89,r,0);            // MOV floatreg,r 
     3835                if (sz == 8) 
     3836                    code_orrex(ce, REX_W); 
     3837                assert(sz == 4 || sz == 8);             // float or double 
     3838                unsigned op = (sz == 4) ? 0xF30F10 : 0xF20F10; 
     3839                ce = genfltreg(ce,op,reg - XMM0,0);     // MOVSS/MOVSD XMMreg,floatreg 
     3840            } 
     3841            else 
     3842            {   ce = movregconst(CNIL,reg,e->EV.Vint,flags); 
     3843                flags = 0;                          // flags are already set 
     3844            } 
    38143845        } 
    38153846        else if (sz < 8)        // far pointers, longs for 16 bit targets 
    38163847        { 
    38173848            targ_int msw,lsw; 
    38183849            regm_t mswflags; 
    38193850 
    38203851            msw = I32   ? e->EV.Vfp.Vseg 
    38213852                        : (e->EV.Vulong >> 16); 
    38223853            lsw = e->EV.Vfp.Voff; 
    38233854            mswflags = 0; 
    38243855            if (forregs & mES) 
    38253856            { 
    38263857                ce = movregconst(CNIL,reg,msw,0);       // MOV reg,segment 
    38273858                genregs(ce,0x8E,0,reg);                 // MOV ES,reg 
    38283859                msw = lsw;                              // MOV reg,offset 
    38293860            } 
    38303861            else 
    38313862            { 
    38323863                sreg = findreglsw(forregs); 
    38333864                ce = movregconst(CNIL,sreg,lsw,0); 
  • trunk/src/backend/cod2.c

    r771 r772  
    15711571  code *cc,*c,*c1,*cnop1,*c2,*cnop2; 
    15721572  con_t regconold,regconsave; 
    15731573  unsigned stackpushold,stackpushsave; 
    15741574  int ehindexold,ehindexsave; 
    15751575  unsigned jop; 
    15761576  unsigned op1; 
    15771577  unsigned sz1; 
    15781578  unsigned sz2; 
    15791579  elem *e1; 
    15801580  elem *e2; 
    15811581  elem *e21; 
    15821582  elem *e22; 
    15831583 
    15841584  /* vars to save state of 8087 */ 
    15851585  int stackusedold,stackusedsave; 
    15861586  NDP _8087old[arraysize(_8087elems)]; 
    15871587  NDP _8087save[arraysize(_8087elems)]; 
    15881588 
    15891589  _chkstack(); 
    15901590 
    1591   //dbg_printf("cdcond(e = %p, *pretregs = x%x)\n",e,*pretregs); 
     1591  //printf("cdcond(e = %p, *pretregs = %s)\n",e,regm_str(*pretregs)); 
    15921592  e1 = e->E1; 
    15931593  e2 = e->E2; 
    15941594  e21 = e2->E1; 
    15951595  e22 = e2->E2; 
    15961596  cc = docommas(&e1); 
    15971597  cgstate.stackclean++; 
    15981598  psw = *pretregs & mPSW;               /* save PSW bit                 */ 
    15991599  op1 = e1->Eoper; 
    16001600  sz1 = tysize(e1->Ety); 
    16011601  unsigned rex = (I64 && sz1 == 8) ? REX_W : 0; 
    16021602  unsigned grex = rex << 16; 
    16031603  jop = jmpopcode(e1); 
    16041604 
    16051605  if (!OTrel(op1) && e1 == e21 && 
    16061606      sz1 <= REGSIZE && !tyfloating(e1->Ety)) 
    16071607  {     // Recognize (e ? e : f) 
    16081608        regm_t retregs; 
    16091609 
    16101610        cnop1 = gennop(CNIL); 
    16111611        retregs = *pretregs | mPSW; 
  • trunk/src/backend/cod3.c

    r771 r772  
    12661266    for (regm_t x = topush; x; x >>= 1) 
    12671267        npush += x & 1; 
    12681268 
    12691269    // Keep the stack aligned by 8 for any subsequent function calls 
    12701270    if (!I16 && calledafunc && 
    12711271        (STACKALIGN == 16 || config.flags4 & CFG4stackalign)) 
    12721272    { 
    12731273        //printf("npush = %d Poff = x%x needframe = %d localsize = x%x\n", npush, Poff, needframe, localsize); 
    12741274 
    12751275        int sz = Poff + (needframe ? 0 : -REGSIZE) + localsize + npush * REGSIZE; 
    12761276        if (STACKALIGN == 16) 
    12771277        { 
    12781278            if (sz & (8|4)) 
    12791279                localsize += STACKALIGN - (sz & (8|4)); 
    12801280        } 
    12811281        else if (sz & 4) 
    12821282            localsize += 4; 
    12831283    } 
    12841284 
    12851285    //printf("Foff x%02x Aoff x%02x Toff x%02x NDPoff x%02x CSoff x%02x Poff x%02x localsize x%02x\n", 
    1286         //Foff,Aoff,Toff,NDPoff,CSoff,Poff,localsize); 
     1286        //(int)Foff,(int)Aoff,(int)Toff,(int)NDPoff,(int)CSoff,(int)Poff,(int)localsize); 
    12871287 
    12881288    xlocalsize = localsize; 
    12891289 
    12901290    if (tyf & mTYnaked)                 // if no prolog/epilog for function 
    12911291    { 
    12921292        hasframe = 1; 
    12931293        return NULL; 
    12941294    } 
    12951295 
    12961296    if (tym == TYifunc) 
    12971297    {   static unsigned char ops2[] = { 0x60,0x1E,0x06,0 }; 
    12981298        static unsigned char ops0[] = { 0x50,0x51,0x52,0x53, 
    12991299                                        0x54,0x55,0x56,0x57, 
    13001300                                        0x1E,0x06,0 }; 
    13011301 
    13021302        unsigned char *p; 
    13031303 
    13041304        p = (config.target_cpu >= TARGET_80286) ? ops2 : ops0; 
    13051305        do 
    13061306            c = gen1(c,*p); 
     
    18381838            } 
    18391839        } 
    18401840    } 
    18411841 
    18421842    /* Load arguments passed in registers into the varargs save area 
    18431843     * so they can be accessed by va_arg(). 
    18441844     */ 
    18451845    if (I64 && variadic(funcsym_p->Stype)) 
    18461846    { 
    18471847        /* Look for __va_argsave 
    18481848         */ 
    18491849        symbol *sv = NULL; 
    18501850        for (SYMIDX si = 0; si < globsym.top; si++) 
    18511851        {   symbol *s = globsym.tab[si]; 
    18521852            if (s->Sident[0] == '_' && strcmp(s->Sident, "__va_argsave") == 0) 
    18531853            {   sv = s; 
    18541854                break; 
    18551855            } 
    18561856        } 
    18571857 
    1858         if (sv
     1858        if (sv && !(sv->Sflags & SFLdead)
    18591859        { 
    18601860        /* Generate code to move any arguments passed in registers into 
    18611861         * the stack variable __va_argsave, 
    18621862         * so we can reference it via pointers through va_arg(). 
    18631863         *   struct __va_argsave_t { 
    18641864         *     size_t[6] regs; 
    18651865         *     real[8] fpregs; 
    18661866         *     uint offset_regs; 
    18671867         *     uint offset_fpregs; 
    18681868         *     void* stack_args; 
    18691869         *     void* reg_args; 
    18701870         *   } 
    18711871         * The MOVAPS instructions seg fault if data is not aligned on 
    18721872         * 16 bytes, so this gives us a nice check to ensure no mistakes. 
    18731873            MOV     voff+0*8[RBP],EDI 
    18741874            MOV     voff+1*8[RBP],ESI 
    18751875            MOV     voff+2*8[RBP],RDX 
    18761876            MOV     voff+3*8[RBP],RCX 
    18771877            MOV     voff+4*8[RBP],R8 
    18781878            MOV     voff+5*8[RBP],R9 
  • trunk/src/backend/cod4.c

    r771 r772  
    24622462                    goto Lcomplex; 
    24632463                /* FALL-THROUGH */ 
    24642464            case OPs64_d: 
    24652465            case OPs32_d: 
    24662466            case OPs16_d: 
    24672467            case OPu16_d: 
    24682468                return load87(e,0,pretregs,NULL,-1); 
    24692469            case OPu32_d: 
    24702470                if (!I16) 
    24712471                { 
    24722472                    unsigned retregs = ALLREGS; 
    24732473                    c1 = codelem(e->E1, &retregs, FALSE); 
    24742474                    unsigned reg = findreg(retregs); 
    24752475                    c1 = genfltreg(c1, 0x89, reg, 0); 
    24762476                    regwithvalue(c1,ALLREGS,0,&reg,0); 
    24772477                    genfltreg(c1, 0x89, reg, REGSIZE); 
    24782478 
    24792479                    cat(c1, push87()); 
    24802480                    genfltreg(c1,0xDF,5,0);     // FILD m64int 
    24812481 
    2482                     retregs = mST0 | (*pretregs & mPSW)
     2482                    retregs = mST0 /*| (*pretregs & mPSW)*/
    24832483                    c2 = fixresult87(e, retregs, pretregs); 
    24842484                    return cat(c1, c2); 
    24852485                } 
    24862486                break; 
    24872487            case OPd_s16: 
    24882488            case OPd_s32: 
    24892489            case OPd_u16: 
    24902490            case OPd_s64: 
    24912491                return cnvt87(e,pretregs); 
    24922492            case OPd_u32:               // use subroutine, not 8087 
    24932493#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 
    24942494                retregs = mST0; 
    24952495#else 
    24962496                retregs = DOUBLEREGS; 
    24972497#endif 
    24982498                goto L1; 
    24992499 
    25002500            case OPd_u64: 
    25012501                retregs = DOUBLEREGS; 
    25022502                goto L1; 
  • trunk/src/glue.c

    r705 r772  
    11321132} 
    11331133 
    11341134unsigned TypeFunction::totym() 
    11351135{ 
    11361136    tym_t tyf; 
    11371137 
    11381138    //printf("TypeFunction::totym(), linkage = %d\n", linkage); 
    11391139    switch (linkage) 
    11401140    { 
    11411141        case LINKwindows: 
    11421142            tyf = (varargs == 1) ? TYnfunc : TYnsfunc; 
    11431143            break; 
    11441144 
    11451145        case LINKpascal: 
    11461146            tyf = (varargs == 1) ? TYnfunc : TYnpfunc; 
    11471147            break; 
    11481148 
    11491149        case LINKc: 
    11501150            tyf = TYnfunc; 
    11511151#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 
    1152             if (retStyle() == RETstack) 
     1152            if (I32 && retStyle() == RETstack) 
    11531153                tyf = TYhfunc; 
    11541154#endif 
    11551155            break; 
    11561156 
    11571157        case LINKd: 
    11581158            tyf = (varargs == 1) ? TYnfunc : TYjfunc; 
    11591159            break; 
    11601160 
    11611161        case LINKcpp: 
    11621162            tyf = TYnfunc; 
    11631163            break; 
    11641164 
    11651165        default: 
    11661166            printf("linkage = %d\n", linkage); 
    11671167            assert(0); 
    11681168    } 
    11691169#if DMDV2 
    11701170    if (isnothrow) 
    11711171        tyf |= mTYnothrow; 
    11721172#endif