Changeset 619
- Timestamp:
- 08/17/10 19:39:11 (14 years ago)
- Files:
-
- branches/dmd-1.x/src/backend/cgcod.c (modified) (3 diffs)
- branches/dmd-1.x/src/backend/cod1.c (modified) (3 diffs)
- branches/dmd-1.x/src/backend/cod3.c (modified) (2 diffs)
- branches/dmd-1.x/src/backend/ptrntab.c (modified) (3 diffs)
- branches/dmd-1.x/src/mtype.c (modified) (1 diff)
- branches/dmd-1.x/src/mtype.h (modified) (1 diff)
- trunk/src/backend/cgcod.c (modified) (3 diffs)
- trunk/src/backend/cod1.c (modified) (3 diffs)
- trunk/src/backend/cod3.c (modified) (2 diffs)
- trunk/src/backend/ptrntab.c (modified) (3 diffs)
- trunk/src/mtype.c (modified) (1 diff)
- trunk/src/mtype.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/dmd-1.x/src/backend/cgcod.c
r618 r619 124 124 125 125 //printf("codgen('%s')\n",funcsym_p->Sident); 126 126 127 127 cgreg_init(); 128 128 csmax = 64; 129 129 csextab = (struct CSE *) util_calloc(sizeof(struct CSE),csmax); 130 130 functy = tybasic(funcsym_p->ty()); 131 131 #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 132 132 if (0 && config.flags3 & CFG3pic) 133 133 { 134 134 ALLREGS = ALLREGS_INIT_PIC; 135 135 BYTEREGS = BYTEREGS_INIT_PIC; 136 136 } 137 137 else 138 138 { 139 139 regm_t value = BYTEREGS_INIT; 140 140 ALLREGS = ALLREGS_INIT; 141 141 BYTEREGS = value; 142 142 } 143 143 if (I64) 144 ALLREGS = mAX|mBX|mCX|mDX|mSI|mDI| mR8|mR9|mR10|mR11|mR12|mR13|mR14|mR15; 144 { ALLREGS = mAX|mBX|mCX|mDX|mSI|mDI| mR8|mR9|mR10|mR11|mR12|mR13|mR14|mR15; 145 BYTEREGS = ALLREGS; 146 } 145 147 #endif 146 148 allregs = ALLREGS; 147 149 if (0 && config.flags3 & CFG3pic) 148 150 allregs &= ~mBX; 149 151 pass = PASSinit; 150 152 151 153 tryagain: 152 154 #ifdef DEBUG 153 155 if (debugr) 154 156 printf("------------------ PASS%s -----------------\n", 155 157 (pass == PASSinit) ? "init" : ((pass == PASSreg) ? "reg" : "final")); 156 158 #endif 157 159 lastretregs = last2retregs = last3retregs = last4retregs = last5retregs = 0; 158 160 159 161 // if no parameters, assume we don't need a stack frame 160 162 needframe = 0; 161 163 usedalloca = 0; 162 164 gotref = 0; 163 165 stackchanged = 0; 164 166 stackpush = 0; … … 2278 2280 regcon.immed.mval | regcon.params | mfuncreg); 2279 2281 } 2280 2282 return scratch; 2281 2283 } 2282 2284 2283 2285 2284 2286 /****************************** 2285 2287 * Evaluate an elem that is a common subexp that has been encountered 2286 2288 * before. 2287 2289 * Look first to see if it is already in a register. 2288 2290 */ 2289 2291 2290 2292 STATIC code * comsub(elem *e,regm_t *pretregs) 2291 2293 { tym_t tym; 2292 2294 regm_t regm,emask,csemask; 2293 2295 unsigned reg,i,byte,sz; 2294 2296 code *c; 2295 2297 int forcc; // !=0 if we evaluate for condition codes 2296 2298 int forregs; // !=0 if we evaluate into registers 2297 2299 2298 //printf("comsub(e = %p, *pretregs = x%x)\n",e,*pretregs);2300 //printf("comsub(e = %p, *pretregs = %s)\n",e,regm_str(*pretregs)); 2299 2301 elem_debug(e); 2300 2302 #ifdef DEBUG 2301 2303 if (e->Ecomsub > e->Ecount) 2302 2304 elem_print(e); 2303 2305 #endif 2304 2306 assert(e->Ecomsub <= e->Ecount); 2305 2307 2306 2308 c = CNIL; 2307 2309 if (*pretregs == 0) goto done; /* no possible side effects anyway */ 2308 2310 2309 2311 if (tyfloating(e->Ety) && config.inline8087) 2310 2312 return comsub87(e,pretregs); 2311 2313 2312 2314 /* First construct a mask, emask, of all the registers that */ 2313 2315 /* have the right contents. */ 2314 2316 2315 2317 emask = 0; 2316 2318 for (i = 0; i < arraysize(regcon.cse.value); i++) 2317 2319 { 2318 2320 //dbg_printf("regcon.cse.value[%d] = %p\n",i,regcon.cse.value[i]); … … 2566 2568 * Note: longs are in AX,BX or CX,DX or SI,DI 2567 2569 * doubles are AX,BX,CX,DX only 2568 2570 * constflag TRUE if user of result will not modify the 2569 2571 * registers returned in *pretregs. 2570 2572 * Output: 2571 2573 * *pretregs mask of registers result is returned in 2572 2574 * Returns: 2573 2575 * pointer to code sequence generated 2574 2576 */ 2575 2577 2576 2578 #include "cdxxx.c" /* jump table */ 2577 2579 2578 2580 code *codelem(elem *e,regm_t *pretregs,bool constflag) 2579 2581 { code *c; 2580 2582 Symbol *s; 2581 2583 tym_t tym; 2582 2584 unsigned op; 2583 2585 2584 2586 #ifdef DEBUG 2585 2587 if (debugw) 2586 { printf("+codelem(e=%p,*pretregs= x%x) ",e,*pretregs);2588 { printf("+codelem(e=%p,*pretregs=%s) ",e,regm_str(*pretregs)); 2587 2589 WROP(e->Eoper); 2588 2590 printf("msavereg=x%x regcon.cse.mval=x%x regcon.cse.mops=x%x\n", 2589 2591 msavereg,regcon.cse.mval,regcon.cse.mops); 2590 2592 printf("Ecount = %d, Ecomsub = %d\n", e->Ecount, e->Ecomsub); 2591 2593 } 2592 2594 #endif 2593 2595 assert(e); 2594 2596 elem_debug(e); 2595 2597 if ((regcon.cse.mops & regcon.cse.mval) != regcon.cse.mops) 2596 2598 { 2597 2599 #ifdef DEBUG 2598 2600 printf("+codelem(e=%p,*pretregs=x%x) ",e,*pretregs); 2599 2601 elem_print(e); 2600 2602 printf("msavereg=x%x regcon.cse.mval=x%x regcon.cse.mops=x%x\n", 2601 2603 msavereg,regcon.cse.mval,regcon.cse.mops); 2602 2604 printf("Ecount = %d, Ecomsub = %d\n", e->Ecount, e->Ecomsub); 2603 2605 #endif 2604 2606 assert(0); 2605 2607 } 2606 2608 branches/dmd-1.x/src/backend/cod1.c
r618 r619 596 596 } 597 597 for (unsigned i = 0; rm; i++) 598 598 { if (mask[i] & rm) 599 599 { if (regcon.cse.value[i] == e && // if register has elem 600 600 /* watch out for a CWD destroying DX */ 601 601 !(i == DX && op == 0xF7 && desmsk & mDX)) 602 602 { 603 603 /* if ES, then it can only be a load */ 604 604 if (i == ES) 605 605 { if (op != 0x8B) 606 606 goto L1; /* not a load */ 607 607 cs->Iop = 0x8C; /* MOV reg,ES */ 608 608 cs->Irm = modregrm(3,0,reg & 7); 609 609 if (reg & 8) 610 610 code_orrex(cs, REX_B); 611 611 } 612 612 else // XXX reg,i 613 613 { 614 614 cs->Irm = modregrm(3,reg & 7,i & 7); 615 615 if (reg & 8) 616 c ode_orrex(cs, REX_R);616 cs->Irex |= REX_R; 617 617 if (i & 8) 618 c ode_orrex(cs, REX_B);618 cs->Irex |= REX_B; 619 619 } 620 620 c = CNIL; 621 621 goto L2; 622 622 } 623 623 rm &= ~mask[i]; 624 624 } 625 625 } 626 626 } 627 627 628 628 L1: 629 629 c = getlvalue(cs,e,keepmsk); 630 630 if (offset == REGSIZE) 631 631 getlvalue_msw(cs); 632 632 else 633 633 cs->IEVoffset1 += offset; 634 634 code_newreg(cs, reg); // OR in reg field 635 635 if (!I16) 636 636 { 637 637 if (reg == 6 && op == 0xFF || /* don't PUSH a word */ 638 638 op == 0x0FB7 || op == 0x0FBF || /* MOVZX/MOVSX */ … … 1108 1107 break; 1109 1108 case TYsptr: /* if pointer to stack */ 1110 1109 if (config.wflags & WFssneds) // if SS != DS 1111 1110 pcs->Iflags |= CFss; /* then need SS: override */ 1112 1111 break; 1113 1112 case TYcptr: /* if pointer to code */ 1114 1113 pcs->Iflags |= CFcs; /* then need CS: override */ 1115 1114 break; 1116 1115 } 1117 1116 #endif 1118 1117 pcs->IFL1 = FLoffset; 1119 1118 pcs->IEV1.Vuns = 0; 1120 1119 1121 1120 /* see if we can replace *(e+c) with 1122 1121 * MOV idxreg,e 1123 1122 * [MOV ES,segment] 1124 1123 * EA = [ES:]c[idxreg] 1125 1124 */ 1126 1125 1127 1126 if (e1isadd && e12->Eoper == OPconst && 1128 tysize(e12->Ety) == REGSIZE&&1127 (tysize(e12->Ety) == REGSIZE || (I64 && tysize(e12->Ety) == 4)) && 1129 1128 (!e1->Ecount || !e1free) 1130 1129 ) 1131 1130 { int ss; 1132 1131 1133 1132 pcs->IEV1.Vuns = e12->EV.Vuns; 1134 1133 freenode(e12); 1135 1134 if (e1free) freenode(e1); 1136 if ( I32&& e11->Eoper == OPadd && !e11->Ecount &&1135 if (!I16 && e11->Eoper == OPadd && !e11->Ecount && 1137 1136 tysize(e11->Ety) == REGSIZE) 1138 1137 { 1139 1138 e12 = e11->E2; 1140 1139 e11 = e11->E1; 1141 1140 e1 = e1->E1; 1142 1141 e1free = TRUE; 1143 1142 goto L4; 1144 1143 } 1145 1144 if (!I16 && (ss = isscaledindex(e11)) != 0) 1146 1145 { // (v * scale) + const 1147 1146 c = cdisscaledindex(e11,&idxregs,keepmsk); 1148 1147 reg = findreg(idxregs); 1149 1148 pcs->Irm = modregrm(0,0,4); 1150 1149 pcs->Isib = modregrm(ss,reg & 7,5); 1151 1150 if (reg & 8) 1152 1151 pcs->Irex |= REX_X; 1153 1152 } 1154 1153 else 1155 1154 { 1156 1155 c = scodelem(e11,&idxregs,keepmsk,TRUE); // load index reg … … 1409 1408 } 1410 1409 1411 1410 /******************************* 1412 1411 * Same as codelem(), but do not destroy the registers in keepmsk. 1413 1412 * Use scratch registers as much as possible, then use stack. 1414 1413 * Input: 1415 1414 * constflag TRUE if user of result will not modify the 1416 1415 * registers returned in *pretregs. 1417 1416 */ 1418 1417 1419 1418 code *scodelem(elem *e,regm_t *pretregs,regm_t keepmsk,bool constflag) 1420 1419 { code *c,*cs1,*cs2,*cs3; 1421 1420 unsigned i,j; 1422 1421 regm_t oldmfuncreg,oldregcon,oldregimmed,overlap,tosave,touse; 1423 1422 int adjesp; 1424 1423 unsigned stackpushsave; 1425 1424 char calledafuncsave; 1426 1425 1427 1426 #ifdef DEBUG 1428 1427 if (debugw) 1429 printf("+scodelem(e=%p *pretregs= x%x keepmsk=x%xconstflag=%d\n",1430 e, *pretregs,keepmsk,constflag);1428 printf("+scodelem(e=%p *pretregs=%s keepmsk=%s constflag=%d\n", 1429 e,regm_str(*pretregs),regm_str(keepmsk),constflag); 1431 1430 #endif 1432 1431 elem_debug(e); 1433 1432 if (constflag) 1434 1433 { regm_t regm; 1435 1434 unsigned reg; 1436 1435 1437 1436 if (isregvar(e,®m,®) && // if e is a register variable 1438 1437 (regm & *pretregs) == regm && // in one of the right regs 1439 1438 e->EV.sp.Voffset == 0 1440 1439 ) 1441 { unsigned sz1,sz2; 1442 1443 sz1 = tysize(e->Ety); 1444 sz2 = tysize(e->EV.sp.Vsym->Stype->Tty); 1440 { 1441 unsigned sz1 = tysize(e->Ety); 1442 unsigned sz2 = tysize(e->EV.sp.Vsym->Stype->Tty); 1445 1443 if (sz1 <= REGSIZE && sz2 > REGSIZE) 1446 1444 regm &= mLSW; 1447 1445 c = fixresult(e,regm,pretregs); 1448 1446 cssave(e,regm,0); 1449 1447 freenode(e); 1450 1448 #ifdef DEBUG 1451 1449 if (debugw) 1452 1450 printf("-scodelem(e=%p *pretregs=x%x keepmsk=x%x constflag=%d\n", 1453 1451 e,*pretregs,keepmsk,constflag); 1454 1452 #endif 1455 1453 return c; 1456 1454 } 1457 1455 } 1458 1456 overlap = msavereg & keepmsk; 1459 1457 msavereg |= keepmsk; /* add to mask of regs to save */ 1460 1458 oldregcon = regcon.cse.mval; 1461 1459 oldregimmed = regcon.immed.mval; 1462 1460 oldmfuncreg = mfuncreg; /* remember old one */ 1463 1461 mfuncreg = (mBP | mES | ALLREGS) & ~regcon.mvar; 1464 1462 stackpushsave = stackpush; branches/dmd-1.x/src/backend/cod3.c
r606 r619 3645 3645 // If the instruction has a second operand that is not an 8 bit, 3646 3646 // and the operand size prefix is present, then fix the size computation 3647 3647 // because the operand size will be different. 3648 3648 // Walter, I had problems with this bit at the end. There can still be 3649 3649 // an ADDRSIZE prefix for these and it does indeed change the operand size. 3650 3650 3651 3651 if (iflags & (CFopsize | CFaddrsize)) 3652 3652 { 3653 3653 if ((ins & (T|E)) == T) 3654 3654 { 3655 3655 if ((op & 0xAC) == 0xA0) 3656 3656 { 3657 3657 if (iflags & CFaddrsize && !I64) 3658 3658 { if (I32) 3659 3659 size -= 2; 3660 3660 else 3661 3661 size += 2; 3662 3662 } 3663 3663 } 3664 3664 else if (iflags & CFopsize) 3665 { if (I32) 3665 { if (I16) 3666 size += 2; 3667 else 3666 3668 size -= 2; 3667 else3668 size += 2;3669 3669 } 3670 3670 } 3671 3671 if (iflags & CFaddrsize) 3672 3672 { if (!I64) 3673 3673 a32 ^= 1; 3674 3674 size++; 3675 3675 } 3676 3676 if (iflags & CFopsize) 3677 3677 size++; /* +1 for OPSIZE prefix */ 3678 3678 } 3679 3679 } 3680 3680 3681 3681 if ((op & ~0x0F) == 0x70) 3682 3682 { if (iflags & CFjmp16) // if long branch 3683 3683 size += I16 ? 3 : 4; // + 3(4) bytes for JMP 3684 3684 } 3685 3685 else if (ins & M) // if modregrm byte 3686 3686 { 3687 3687 rm = c->Irm; 3688 3688 mod = rm & 0xC0; … … 5002 5002 ; 5003 5003 pc = &code_next(c); 5004 5004 } 5005 5005 } 5006 5006 #endif 5007 5007 5008 5008 5009 5009 /*************************** 5010 5010 * Debug code to dump code stucture. 5011 5011 */ 5012 5012 5013 5013 #if DEBUG 5014 5014 5015 5015 void WRcodlst(code *c) 5016 5016 { for (; c; c = code_next(c)) 5017 5017 c->print(); 5018 5018 } 5019 5019 5020 5020 void code::print() 5021 5021 { 5022 unsigned op,rm; 5023 unsigned char ins; 5024 code *c = this; 5025 5026 if (c == CNIL) 5027 { printf("code 0\n"); 5022 unsigned char ins; 5023 code *c = this; 5024 5025 if (c == CNIL) 5026 { printf("code 0\n"); 5028 5027 return; 5029 }5030 op = c->Iop; 5031 5028 } 5029 5030 unsigned op = c->Iop; 5032 5031 if ((c->Iop & 0xFF00) == 0x0F00) 5033 5032 ins = inssize2[op & 0xFF]; 5034 5033 else 5035 5034 ins = inssize[op & 0xFF]; 5036 5035 5037 printf("code %p: nxt=%p op=%02x",c,code_next(c),op); 5036 printf("code %p: nxt=%p ",c,code_next(c)); 5037 if (c->Irex) 5038 printf("rex=%x ", c->Irex); 5039 printf("op=%02x",op); 5040 5038 5041 if ((op & 0xFF) == ESCAPE) 5039 5042 { if ((op & 0xFF00) == ESClinnum) 5040 5043 { printf(" linnum = %d\n",c->IEV2.Vsrcpos.Slinnum); 5041 5044 return; 5042 5045 } 5043 5046 printf(" ESCAPE %d",c->Iop >> 8); 5044 5047 } 5045 5048 if (c->Iflags) 5046 5049 printf(" flg=%x",c->Iflags); 5047 5050 if (ins & M) 5048 { rm = c->Irm;5051 { unsigned rm = c->Irm; 5049 5052 printf(" rm=%02x=%d,%d,%d",rm,(rm>>6)&3,(rm>>3)&7,rm&7); 5050 5053 if (I32 && issib(rm)) 5051 5054 { unsigned char sib = c->Isib; 5052 5055 printf(" sib=%02x=%d,%d,%d",sib,(sib>>6)&3,(sib>>3)&7,sib&7); 5053 5056 } 5054 5057 if ((rm & 0xC7) == BPRM || (rm & 0xC0) == 0x80 || (rm & 0xC0) == 0x40) 5055 5058 { 5056 5059 switch (c->IFL1) 5057 5060 { 5058 5061 case FLconst: 5059 5062 case FLoffset: 5060 5063 printf(" int = %4d",c->IEV1.Vuns); 5061 5064 break; 5062 5065 case FLblock: 5063 5066 printf(" block = %p",c->IEV1.Vblock); 5064 5067 break; 5065 5068 case FLswitch: 5066 5069 case FLblockoff: 5067 5070 case FLlocalsize: 5068 5071 case FLframehandler: branches/dmd-1.x/src/backend/ptrntab.c
r618 r619 809 809 }; 810 810 PTRNTAB2 aptb2CMPS[] = /* CMPS */ { 811 811 { 0xa6, _modsidi, _m8, _m8 }, 812 812 { 0xa7, _modsidi, _m16, _m16 }, 813 813 { 0xa7, _modsidi, _m32, _m32 }, 814 814 { ASM_END, 0, 0, 0 } 815 815 }; 816 816 PTRNTAB2 aptb2CMPXCHG[] = /* CMPXCHG */ { 817 817 { 0xfb0, _I386 | _cb|_mod2, _rm8, _r8 }, 818 818 // This is really a 486 only 819 819 // instruction 820 820 { 0xfb1, _I386 | _cw | _16_bit|_mod2, _rm16, _r16 }, 821 821 { 0xfb1, _I386 | _cd | _32_bit|_mod2, _rm32, _r32 }, 822 822 { 0xfb1, _I386 | _cq | _64_bit|_mod2, _rm64, _r64 }, 823 823 { ASM_END, 0, 0, 0 } 824 824 }; 825 825 PTRNTAB2 aptb2DIV[] = /* DIV */ { 826 826 { 0xf6, _6, _al, _rm8 }, 827 827 { 0xf7, _6 | _16_bit | _moddx, _ax, _rm16 }, 828 828 { 0xf7, _6 | _32_bit | _moddx, _eax, _rm32 }, 829 { 0xf7, _6 | _64_bit | _moddx, _rax, _rm64 }, 829 830 { 0xf6, _6 | _modax, _rm8, 0 }, 830 { 0xf7, _6 | _16_bit | _modaxdx, _rm16, 0 }, 831 { 0xf7, _6 | _32_bit | _modaxdx, _rm32, 0 }, 831 { 0xf7, _6 | _16_bit | _modaxdx, _rm16, 0 }, 832 { 0xf7, _6 | _32_bit | _modaxdx, _rm32, 0 }, 833 { 0xf7, _6 | _64_bit | _modaxdx, _rm64, 0 }, 832 834 { ASM_END, 0, 0, 0 } 833 835 }; 834 836 PTRNTAB2 aptb2ENTER[] = /* ENTER */ { 835 837 { 0xc8, _iw|_ib, _imm16, _imm8 }, 836 838 { ASM_END, 0, 0, 0 } 837 839 }; 838 840 PTRNTAB2 aptb2IDIV[] = /* IDIV */ { 839 841 { 0xf6, _7, _al, _rm8 }, 840 { 0xf7, _7|_16_bit|_moddx, _ax, _rm16 }, 841 { 0xf7, _7|_32_bit|_moddx, _eax, _rm32 }, 842 { 0xf6, _7 | _modax, _rm8, 0 }, 842 { 0xf7, _7|_16_bit|_moddx, _ax, _rm16 }, 843 { 0xf7, _7|_32_bit|_moddx, _eax, _rm32 }, 844 { 0xf7, _7|_64_bit|_moddx, _rax, _rm64 }, 845 { 0xf6, _7 | _modax, _rm8, 0 }, 843 846 { 0xf7, _7|_16_bit|_modaxdx, _rm16, 0 }, 844 847 { 0xf7, _7|_32_bit|_modaxdx, _rm32, 0 }, 848 { 0xf7, _7|_64_bit|_modaxdx, _rm64, 0 }, 845 849 { ASM_END, 0, 0, 0 } 846 850 }; 847 851 PTRNTAB2 aptb2IN[] = /* IN */ { 848 852 { 0xe4, _ib, _al, _imm8 }, 849 853 { 0xe5, _ib|_16_bit,_ax, _imm8 }, 850 854 { 0xe5, _ib|_32_bit,_eax, _imm8 }, 851 855 { 0xec, 0, _al, _dx }, 852 856 { 0xed, _16_bit, _ax, _dx }, 853 857 { 0xed, _32_bit, _eax, _dx }, 854 858 { ASM_END, 0, 0, 0 } 855 859 }; 856 860 PTRNTAB2 aptb2INS[] = /* INS */ { 857 861 { 0x6c, _modsi, _rm8, _dx }, 858 862 { 0x6d, _modsi|_16_bit, _rm16, _dx }, 859 863 { 0x6d, _32_bit|_modsi, _rm32, _dx }, 860 864 { ASM_END, 0, 0, 0 } 861 865 }; 862 866 863 867 PTRNTAB2 aptb2LAR[] = /* LAR */ { 864 868 { 0x0f02, _r|_16_bit, _r16, _rm16 }, … … 958 962 #else 959 963 { 0x0fbf, _r, _r32, _rm16 }, 960 964 #endif 961 965 { ASM_END, 0, 0, 0 } 962 966 }; 963 967 PTRNTAB2 aptb2MOVZX[] = /* MOVZX */ { 964 968 { 0x0fb6, _r|_16_bit, _r16, _rm8 }, 965 969 { 0x0fb6, _r|_32_bit, _r32, _rm8 }, 966 970 #if 1 967 971 { 0x0fb7, _r|_16_bit, _r16, _rm16 }, 968 972 { 0x0fb7, _r|_32_bit, _r32, _rm16 }, 969 973 #else 970 974 { 0x0fb7, _r, _r32, _rm16 }, 971 975 #endif 972 976 { ASM_END, 0, 0, 0 } 973 977 }; 974 978 PTRNTAB2 aptb2MUL[] = /* MUL */ { 975 979 { 0xf6, _4, _al, _rm8 }, 976 980 { 0xf7, _4|_16_bit|_moddx, _ax, _rm16 }, 977 981 { 0xf7, _4|_32_bit|_moddx, _eax, _rm32 }, 982 { 0xf7, _4|_64_bit|_moddx, _rax, _rm64 }, 978 983 { 0xf6, _4|_modax, _rm8, 0 }, 979 984 { 0xf7, _4|_16_bit|_modaxdx, _rm16, 0 }, 980 985 { 0xf7, _4|_32_bit|_modaxdx, _rm32, 0 }, 986 { 0xf7, _4|_64_bit|_modaxdx, _rm64, 0 }, 981 987 { ASM_END, 0, 0, 0 } 982 988 }; 983 989 PTRNTAB2 aptb2OR[] = /* OR */ { 984 990 { 0x0c, _ib, _al, _imm8 }, 985 991 { 0x83, _1|_ib|_16_bit, _rm16, _imm8 }, 986 992 { 0x0d, _iw|_16_bit, _ax, _imm16 }, 987 993 { 0x83, _1|_ib|_32_bit, _rm32, _imm8 }, 988 994 { 0x0d, _id|_32_bit, _eax, _imm32 }, 989 995 { 0x80, _1|_ib, _rm8, _imm8 }, 990 996 { 0x81, _1|_iw|_16_bit, _rm16, _imm16 }, 991 997 { 0x81, _1|_id|_32_bit, _rm32, _imm32 }, 992 998 { 0x08, _r, _rm8, _r8 }, 993 999 { 0x09, _r|_16_bit, _rm16, _r16 }, 994 1000 { 0x09, _r|_32_bit, _rm32, _r32 }, 995 1001 { 0x0a, _r, _r8, _rm8 }, 996 1002 { 0x0b, _r|_16_bit, _r16, _rm16 }, 997 1003 { 0x0b, _r|_32_bit, _r32, _rm32 }, 998 1004 { ASM_END, 0, 0, 0 } 999 1005 }; 1000 1006 PTRNTAB2 aptb2OUT[] = { … … 1263 1269 }; 1264 1270 PTRNTAB2 aptb2CMOVNL[] = { 1265 1271 { 0x0F4D, _r|_16_bit, _r16, _rm16 }, 1266 1272 { 0x0F4D, _r|_32_bit, _r32, _rm32 }, 1267 1273 { ASM_END, 0, 0, 0 } 1268 1274 }; 1269 1275 PTRNTAB2 aptb2CMOVLE[] = { 1270 1276 { 0x0F4E, _r|_16_bit, _r16, _rm16 }, 1271 1277 { 0x0F4E, _r|_32_bit, _r32, _rm32 }, 1272 1278 { ASM_END, 0, 0, 0 } 1273 1279 }; 1274 1280 PTRNTAB2 aptb2CMOVNLE[] = { 1275 1281 { 0x0F4F, _r|_16_bit, _r16, _rm16 }, 1276 1282 { 0x0F4F, _r|_32_bit, _r32, _rm32 }, 1277 1283 { ASM_END, 0, 0, 0 } 1278 1284 }; 1279 1285 1280 1286 PTRNTAB3 aptb3IMUL[] = /* IMUL */ { 1281 1287 { 0x0faf, _r|_16_bit, _r16, _rm16, 0 }, 1282 1288 { 0x0faf, _r|_32_bit, _r32, _rm32, 0 }, 1289 { 0x0faf, _r|_64_bit, _r64, _rm64, 0 }, 1283 1290 { 0xf6, _5|_modax, _rm8, 0, 0 }, 1284 1291 { 0xf7, _5|_16_bit|_modaxdx, _rm16, 0, 0 }, 1285 1292 { 0xf7, _5|_32_bit|_modaxdx, _rm32, 0, 0 }, 1293 { 0xf7, _5|_64_bit|_modaxdx, _rm64, 0, 0 }, 1286 1294 { 0x6b, _r|_ib|_16_bit, _r16, _imm8, 0 }, 1287 1295 { 0x6b, _r|_ib|_32_bit, _r32, _imm8, 0 }, 1288 1296 { 0x69, _r|_iw|_16_bit, _r16, _imm16, 0 }, 1289 1297 { 0x69, _r|_id|_32_bit, _r32, _imm32, 0 }, 1298 { 0x69, _r|_id|_64_bit, _r64, _imm32, 0 }, 1290 1299 { 0x6b, _r|_ib|_16_bit, _r16, _rm16, _imm8 }, 1291 1300 { 0x6b, _r|_ib|_32_bit, _r32, _rm32, _imm8 }, 1301 { 0x6b, _r|_ib|_64_bit, _r64, _rm64, _imm8 }, 1292 1302 { 0x69, _r|_iw|_16_bit, _r16, _rm16, _imm16 }, 1293 1303 { 0x69, _r|_id|_32_bit, _r32, _rm32, _imm32 }, 1304 { 0x69, _r|_id|_64_bit, _r64, _rm64, _imm32 }, 1294 1305 { ASM_END, 0, 0, 0 } 1295 1306 }; 1296 1307 PTRNTAB3 aptb3SHLD[] = /* SHLD */ { 1297 1308 { 0x0fa4, _cw|_16_bit, _rm16, _r16, _imm8 }, 1298 1309 { 0x0fa4, _cd|_32_bit, _rm32, _r32, _imm8 }, 1299 1310 { 0x0fa5, _cw|_16_bit, _rm16, _r16, _cl }, 1300 1311 { 0x0fa5, _cd|_32_bit, _rm32, _r32, _cl }, 1301 1312 { ASM_END, 0, 0, 0 } 1302 1313 }; 1303 1314 PTRNTAB3 aptb3SHRD[] = /* SHRD */ { 1304 1315 { 0x0fac, _cw|_16_bit, _rm16, _r16, _imm8 }, 1305 1316 { 0x0fac, _cd|_32_bit, _rm32, _r32, _imm8 }, 1306 1317 { 0x0fad, _cw|_16_bit, _rm16, _r16, _cl }, 1307 1318 { 0x0fad, _cd|_32_bit, _rm32, _r32, _cl }, 1308 1319 { ASM_END, 0, 0, 0 } 1309 1320 }; 1310 1321 // 1311 1322 // Floating point instructions which have entirely different flag 1312 1323 // interpretations 1313 1324 // branches/dmd-1.x/src/mtype.c
r604 r619 3105 3105 t = this; 3106 3106 else 3107 3107 t = new TypeDelegate(t); 3108 3108 return t; 3109 3109 } 3110 3110 3111 3111 Type *TypeDelegate::semantic(Loc loc, Scope *sc) 3112 3112 { 3113 3113 if (deco) // if semantic() already run 3114 3114 { 3115 3115 //printf("already done\n"); 3116 3116 return this; 3117 3117 } 3118 3118 next = next->semantic(loc,sc); 3119 3119 return merge(); 3120 3120 } 3121 3121 3122 3122 d_uns64 TypeDelegate::size(Loc loc) 3123 3123 { 3124 3124 return PTRSIZE * 2; 3125 } 3126 3127 unsigned TypeDelegate::alignsize() 3128 { 3129 // See Bugzilla 942 for discussion 3130 #if 0 3131 return PTRSIZE; 3132 #else 3133 return PTRSIZE * 2; 3134 #endif 3125 3135 } 3126 3136 3127 3137 void TypeDelegate::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) 3128 3138 { 3129 3139 if (mod != this->mod) 3130 3140 { toCBuffer3(buf, hgs, mod); 3131 3141 return; 3132 3142 } 3133 3143 TypeFunction *tf = (TypeFunction *)next; 3134 3144 3135 3145 tf->next->toCBuffer2(buf, hgs, 0); 3136 3146 buf->writestring(" delegate"); 3137 3147 Parameter::argsToCBuffer(buf, hgs, tf->parameters, tf->varargs); 3138 3148 } 3139 3149 3140 3150 Expression *TypeDelegate::defaultInit(Loc loc) 3141 3151 { 3142 3152 #if LOGDEFAULTINIT 3143 3153 printf("TypeDelegate::defaultInit() '%s'\n", toChars()); 3144 3154 #endif branches/dmd-1.x/src/mtype.h
r523 r619 465 465 void toDecoBuffer(OutBuffer *buf); 466 466 void toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs); 467 467 void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); 468 468 MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes); 469 469 TypeInfoDeclaration *getTypeInfoDeclaration(); 470 470 Type *reliesOnTident(); 471 471 472 472 int callMatch(Expressions *toargs); 473 473 type *toCtype(); 474 474 enum RET retStyle(); 475 475 476 476 unsigned totym(); 477 477 }; 478 478 479 479 struct TypeDelegate : Type 480 480 { 481 481 TypeDelegate(Type *t); 482 482 Type *syntaxCopy(); 483 483 Type *semantic(Loc loc, Scope *sc); 484 484 d_uns64 size(Loc loc); 485 unsigned alignsize(); 485 486 void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); 486 487 Expression *defaultInit(Loc loc); 487 488 int isZeroInit(Loc loc); 488 489 int checkBoolean(); 489 490 TypeInfoDeclaration *getTypeInfoDeclaration(); 490 491 Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); 491 492 int hasPointers(); 492 493 493 494 type *toCtype(); 494 495 }; 495 496 496 497 struct TypeQualified : Type 497 498 { 498 499 Loc loc; 499 500 Array idents; // array of Identifier's representing ident.ident.ident etc. 500 501 501 502 TypeQualified(TY ty, Loc loc); 502 503 void syntaxCopyHelper(TypeQualified *t); 503 504 void addIdent(Identifier *ident); 504 505 void toCBuffer2Helper(OutBuffer *buf, HdrGenState *hgs); trunk/src/backend/cgcod.c
r618 r619 124 124 125 125 //printf("codgen('%s')\n",funcsym_p->Sident); 126 126 127 127 cgreg_init(); 128 128 csmax = 64; 129 129 csextab = (struct CSE *) util_calloc(sizeof(struct CSE),csmax); 130 130 functy = tybasic(funcsym_p->ty()); 131 131 #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS 132 132 if (0 && config.flags3 & CFG3pic) 133 133 { 134 134 ALLREGS = ALLREGS_INIT_PIC; 135 135 BYTEREGS = BYTEREGS_INIT_PIC; 136 136 } 137 137 else 138 138 { 139 139 regm_t value = BYTEREGS_INIT; 140 140 ALLREGS = ALLREGS_INIT; 141 141 BYTEREGS = value; 142 142 } 143 143 if (I64) 144 ALLREGS = mAX|mBX|mCX|mDX|mSI|mDI| mR8|mR9|mR10|mR11|mR12|mR13|mR14|mR15; 144 { ALLREGS = mAX|mBX|mCX|mDX|mSI|mDI| mR8|mR9|mR10|mR11|mR12|mR13|mR14|mR15; 145 BYTEREGS = ALLREGS; 146 } 145 147 #endif 146 148 allregs = ALLREGS; 147 149 if (0 && config.flags3 & CFG3pic) 148 150 allregs &= ~mBX; 149 151 pass = PASSinit; 150 152 151 153 tryagain: 152 154 #ifdef DEBUG 153 155 if (debugr) 154 156 printf("------------------ PASS%s -----------------\n", 155 157 (pass == PASSinit) ? "init" : ((pass == PASSreg) ? "reg" : "final")); 156 158 #endif 157 159 lastretregs = last2retregs = last3retregs = last4retregs = last5retregs = 0; 158 160 159 161 // if no parameters, assume we don't need a stack frame 160 162 needframe = 0; 161 163 usedalloca = 0; 162 164 gotref = 0; 163 165 stackchanged = 0; 164 166 stackpush = 0; … … 2278 2280 regcon.immed.mval | regcon.params | mfuncreg); 2279 2281 } 2280 2282 return scratch; 2281 2283 } 2282 2284 2283 2285 2284 2286 /****************************** 2285 2287 * Evaluate an elem that is a common subexp that has been encountered 2286 2288 * before. 2287 2289 * Look first to see if it is already in a register. 2288 2290 */ 2289 2291 2290 2292 STATIC code * comsub(elem *e,regm_t *pretregs) 2291 2293 { tym_t tym; 2292 2294 regm_t regm,emask,csemask; 2293 2295 unsigned reg,i,byte,sz; 2294 2296 code *c; 2295 2297 int forcc; // !=0 if we evaluate for condition codes 2296 2298 int forregs; // !=0 if we evaluate into registers 2297 2299 2298 //printf("comsub(e = %p, *pretregs = x%x)\n",e,*pretregs);2300 //printf("comsub(e = %p, *pretregs = %s)\n",e,regm_str(*pretregs)); 2299 2301 elem_debug(e); 2300 2302 #ifdef DEBUG 2301 2303 if (e->Ecomsub > e->Ecount) 2302 2304 elem_print(e); 2303 2305 #endif 2304 2306 assert(e->Ecomsub <= e->Ecount); 2305 2307 2306 2308 c = CNIL; 2307 2309 if (*pretregs == 0) goto done; /* no possible side effects anyway */ 2308 2310 2309 2311 if (tyfloating(e->Ety) && config.inline8087) 2310 2312 return comsub87(e,pretregs); 2311 2313 2312 2314 /* First construct a mask, emask, of all the registers that */ 2313 2315 /* have the right contents. */ 2314 2316 2315 2317 emask = 0; 2316 2318 for (i = 0; i < arraysize(regcon.cse.value); i++) 2317 2319 { 2318 2320 //dbg_printf("regcon.cse.value[%d] = %p\n",i,regcon.cse.value[i]); … … 2566 2568 * Note: longs are in AX,BX or CX,DX or SI,DI 2567 2569 * doubles are AX,BX,CX,DX only 2568 2570 * constflag TRUE if user of result will not modify the 2569 2571 * registers returned in *pretregs. 2570 2572 * Output: 2571 2573 * *pretregs mask of registers result is returned in 2572 2574 * Returns: 2573 2575 * pointer to code sequence generated 2574 2576 */ 2575 2577 2576 2578 #include "cdxxx.c" /* jump table */ 2577 2579 2578 2580 code *codelem(elem *e,regm_t *pretregs,bool constflag) 2579 2581 { code *c; 2580 2582 Symbol *s; 2581 2583 tym_t tym; 2582 2584 unsigned op; 2583 2585 2584 2586 #ifdef DEBUG 2585 2587 if (debugw) 2586 { printf("+codelem(e=%p,*pretregs= x%x) ",e,*pretregs);2588 { printf("+codelem(e=%p,*pretregs=%s) ",e,regm_str(*pretregs)); 2587 2589 WROP(e->Eoper); 2588 2590 printf("msavereg=x%x regcon.cse.mval=x%x regcon.cse.mops=x%x\n", 2589 2591 msavereg,regcon.cse.mval,regcon.cse.mops); 2590 2592 printf("Ecount = %d, Ecomsub = %d\n", e->Ecount, e->Ecomsub); 2591 2593 } 2592 2594 #endif 2593 2595 assert(e); 2594 2596 elem_debug(e); 2595 2597 if ((regcon.cse.mops & regcon.cse.mval) != regcon.cse.mops) 2596 2598 { 2597 2599 #ifdef DEBUG 2598 2600 printf("+codelem(e=%p,*pretregs=x%x) ",e,*pretregs); 2599 2601 elem_print(e); 2600 2602 printf("msavereg=x%x regcon.cse.mval=x%x regcon.cse.mops=x%x\n", 2601 2603 msavereg,regcon.cse.mval,regcon.cse.mops); 2602 2604 printf("Ecount = %d, Ecomsub = %d\n", e->Ecount, e->Ecomsub); 2603 2605 #endif 2604 2606 assert(0); 2605 2607 } 2606 2608 trunk/src/backend/cod1.c
r618 r619 596 596 } 597 597 for (unsigned i = 0; rm; i++) 598 598 { if (mask[i] & rm) 599 599 { if (regcon.cse.value[i] == e && // if register has elem 600 600 /* watch out for a CWD destroying DX */ 601 601 !(i == DX && op == 0xF7 && desmsk & mDX)) 602 602 { 603 603 /* if ES, then it can only be a load */ 604 604 if (i == ES) 605 605 { if (op != 0x8B) 606 606 goto L1; /* not a load */ 607 607 cs->Iop = 0x8C; /* MOV reg,ES */ 608 608 cs->Irm = modregrm(3,0,reg & 7); 609 609 if (reg & 8) 610 610 code_orrex(cs, REX_B); 611 611 } 612 612 else // XXX reg,i 613 613 { 614 614 cs->Irm = modregrm(3,reg & 7,i & 7); 615 615 if (reg & 8) 616 c ode_orrex(cs, REX_R);616 cs->Irex |= REX_R; 617 617 if (i & 8) 618 c ode_orrex(cs, REX_B);618 cs->Irex |= REX_B; 619 619 } 620 620 c = CNIL; 621 621 goto L2; 622 622 } 623 623 rm &= ~mask[i]; 624 624 } 625 625 } 626 626 } 627 627 628 628 L1: 629 629 c = getlvalue(cs,e,keepmsk); 630 630 if (offset == REGSIZE) 631 631 getlvalue_msw(cs); 632 632 else 633 633 cs->IEVoffset1 += offset; 634 634 code_newreg(cs, reg); // OR in reg field 635 635 if (!I16) 636 636 { 637 637 if (reg == 6 && op == 0xFF || /* don't PUSH a word */ 638 638 op == 0x0FB7 || op == 0x0FBF || /* MOVZX/MOVSX */ … … 1108 1107 break; 1109 1108 case TYsptr: /* if pointer to stack */ 1110 1109 if (config.wflags & WFssneds) // if SS != DS 1111 1110 pcs->Iflags |= CFss; /* then need SS: override */ 1112 1111 break; 1113 1112 case TYcptr: /* if pointer to code */ 1114 1113 pcs->Iflags |= CFcs; /* then need CS: override */ 1115 1114 break; 1116 1115 } 1117 1116 #endif 1118 1117 pcs->IFL1 = FLoffset; 1119 1118 pcs->IEV1.Vuns = 0; 1120 1119 1121 1120 /* see if we can replace *(e+c) with 1122 1121 * MOV idxreg,e 1123 1122 * [MOV ES,segment] 1124 1123 * EA = [ES:]c[idxreg] 1125 1124 */ 1126 1125 1127 1126 if (e1isadd && e12->Eoper == OPconst && 1128 tysize(e12->Ety) == REGSIZE&&1127 (tysize(e12->Ety) == REGSIZE || (I64 && tysize(e12->Ety) == 4)) && 1129 1128 (!e1->Ecount || !e1free) 1130 1129 ) 1131 1130 { int ss; 1132 1131 1133 1132 pcs->IEV1.Vuns = e12->EV.Vuns; 1134 1133 freenode(e12); 1135 1134 if (e1free) freenode(e1); 1136 if ( I32&& e11->Eoper == OPadd && !e11->Ecount &&1135 if (!I16 && e11->Eoper == OPadd && !e11->Ecount && 1137 1136 tysize(e11->Ety) == REGSIZE) 1138 1137 { 1139 1138 e12 = e11->E2; 1140 1139 e11 = e11->E1; 1141 1140 e1 = e1->E1; 1142 1141 e1free = TRUE; 1143 1142 goto L4; 1144 1143 } 1145 1144 if (!I16 && (ss = isscaledindex(e11)) != 0) 1146 1145 { // (v * scale) + const 1147 1146 c = cdisscaledindex(e11,&idxregs,keepmsk); 1148 1147 reg = findreg(idxregs); 1149 1148 pcs->Irm = modregrm(0,0,4); 1150 1149 pcs->Isib = modregrm(ss,reg & 7,5); 1151 1150 if (reg & 8) 1152 1151 pcs->Irex |= REX_X; 1153 1152 } 1154 1153 else 1155 1154 { 1156 1155 c = scodelem(e11,&idxregs,keepmsk,TRUE); // load index reg … … 1409 1408 } 1410 1409 1411 1410 /******************************* 1412 1411 * Same as codelem(), but do not destroy the registers in keepmsk. 1413 1412 * Use scratch registers as much as possible, then use stack. 1414 1413 * Input: 1415 1414 * constflag TRUE if user of result will not modify the 1416 1415 * registers returned in *pretregs. 1417 1416 */ 1418 1417 1419 1418 code *scodelem(elem *e,regm_t *pretregs,regm_t keepmsk,bool constflag) 1420 1419 { code *c,*cs1,*cs2,*cs3; 1421 1420 unsigned i,j; 1422 1421 regm_t oldmfuncreg,oldregcon,oldregimmed,overlap,tosave,touse; 1423 1422 int adjesp; 1424 1423 unsigned stackpushsave; 1425 1424 char calledafuncsave; 1426 1425 1427 1426 #ifdef DEBUG 1428 1427 if (debugw) 1429 printf("+scodelem(e=%p *pretregs= x%x keepmsk=x%xconstflag=%d\n",1430 e, *pretregs,keepmsk,constflag);1428 printf("+scodelem(e=%p *pretregs=%s keepmsk=%s constflag=%d\n", 1429 e,regm_str(*pretregs),regm_str(keepmsk),constflag); 1431 1430 #endif 1432 1431 elem_debug(e); 1433 1432 if (constflag) 1434 1433 { regm_t regm; 1435 1434 unsigned reg; 1436 1435 1437 1436 if (isregvar(e,®m,®) && // if e is a register variable 1438 1437 (regm & *pretregs) == regm && // in one of the right regs 1439 1438 e->EV.sp.Voffset == 0 1440 1439 ) 1441 { unsigned sz1,sz2; 1442 1443 sz1 = tysize(e->Ety); 1444 sz2 = tysize(e->EV.sp.Vsym->Stype->Tty); 1440 { 1441 unsigned sz1 = tysize(e->Ety); 1442 unsigned sz2 = tysize(e->EV.sp.Vsym->Stype->Tty); 1445 1443 if (sz1 <= REGSIZE && sz2 > REGSIZE) 1446 1444 regm &= mLSW; 1447 1445 c = fixresult(e,regm,pretregs); 1448 1446 cssave(e,regm,0); 1449 1447 freenode(e); 1450 1448 #ifdef DEBUG 1451 1449 if (debugw) 1452 1450 printf("-scodelem(e=%p *pretregs=x%x keepmsk=x%x constflag=%d\n", 1453 1451 e,*pretregs,keepmsk,constflag); 1454 1452 #endif 1455 1453 return c; 1456 1454 } 1457 1455 } 1458 1456 overlap = msavereg & keepmsk; 1459 1457 msavereg |= keepmsk; /* add to mask of regs to save */ 1460 1458 oldregcon = regcon.cse.mval; 1461 1459 oldregimmed = regcon.immed.mval; 1462 1460 oldmfuncreg = mfuncreg; /* remember old one */ 1463 1461 mfuncreg = (mBP | mES | ALLREGS) & ~regcon.mvar; 1464 1462 stackpushsave = stackpush; trunk/src/backend/cod3.c
r605 r619 3645 3645 // If the instruction has a second operand that is not an 8 bit, 3646 3646 // and the operand size prefix is present, then fix the size computation 3647 3647 // because the operand size will be different. 3648 3648 // Walter, I had problems with this bit at the end. There can still be 3649 3649 // an ADDRSIZE prefix for these and it does indeed change the operand size. 3650 3650 3651 3651 if (iflags & (CFopsize | CFaddrsize)) 3652 3652 { 3653 3653 if ((ins & (T|E)) == T) 3654 3654 { 3655 3655 if ((op & 0xAC) == 0xA0) 3656 3656 { 3657 3657 if (iflags & CFaddrsize && !I64) 3658 3658 { if (I32) 3659 3659 size -= 2; 3660 3660 else 3661 3661 size += 2; 3662 3662 } 3663 3663 } 3664 3664 else if (iflags & CFopsize) 3665 { if (I32) 3665 { if (I16) 3666 size += 2; 3667 else 3666 3668 size -= 2; 3667 else3668 size += 2;3669 3669 } 3670 3670 } 3671 3671 if (iflags & CFaddrsize) 3672 3672 { if (!I64) 3673 3673 a32 ^= 1; 3674 3674 size++; 3675 3675 } 3676 3676 if (iflags & CFopsize) 3677 3677 size++; /* +1 for OPSIZE prefix */ 3678 3678 } 3679 3679 } 3680 3680 3681 3681 if ((op & ~0x0F) == 0x70) 3682 3682 { if (iflags & CFjmp16) // if long branch 3683 3683 size += I16 ? 3 : 4; // + 3(4) bytes for JMP 3684 3684 } 3685 3685 else if (ins & M) // if modregrm byte 3686 3686 { 3687 3687 rm = c->Irm; 3688 3688 mod = rm & 0xC0; … … 5002 5002 ; 5003 5003 pc = &code_next(c); 5004 5004 } 5005 5005 } 5006 5006 #endif 5007 5007 5008 5008 5009 5009 /*************************** 5010 5010 * Debug code to dump code stucture. 5011 5011 */ 5012 5012 5013 5013 #if DEBUG 5014 5014 5015 5015 void WRcodlst(code *c) 5016 5016 { for (; c; c = code_next(c)) 5017 5017 c->print(); 5018 5018 } 5019 5019 5020 5020 void code::print() 5021 5021 { 5022 unsigned op,rm; 5023 unsigned char ins; 5024 code *c = this; 5025 5026 if (c == CNIL) 5027 { printf("code 0\n"); 5022 unsigned char ins; 5023 code *c = this; 5024 5025 if (c == CNIL) 5026 { printf("code 0\n"); 5028 5027 return; 5029 }5030 op = c->Iop; 5031 5028 } 5029 5030 unsigned op = c->Iop; 5032 5031 if ((c->Iop & 0xFF00) == 0x0F00) 5033 5032 ins = inssize2[op & 0xFF]; 5034 5033 else 5035 5034 ins = inssize[op & 0xFF]; 5036 5035 5037 printf("code %p: nxt=%p op=%02x",c,code_next(c),op); 5036 printf("code %p: nxt=%p ",c,code_next(c)); 5037 if (c->Irex) 5038 printf("rex=%x ", c->Irex); 5039 printf("op=%02x",op); 5040 5038 5041 if ((op & 0xFF) == ESCAPE) 5039 5042 { if ((op & 0xFF00) == ESClinnum) 5040 5043 { printf(" linnum = %d\n",c->IEV2.Vsrcpos.Slinnum); 5041 5044 return; 5042 5045 } 5043 5046 printf(" ESCAPE %d",c->Iop >> 8); 5044 5047 } 5045 5048 if (c->Iflags) 5046 5049 printf(" flg=%x",c->Iflags); 5047 5050 if (ins & M) 5048 { rm = c->Irm;5051 { unsigned rm = c->Irm; 5049 5052 printf(" rm=%02x=%d,%d,%d",rm,(rm>>6)&3,(rm>>3)&7,rm&7); 5050 5053 if (I32 && issib(rm)) 5051 5054 { unsigned char sib = c->Isib; 5052 5055 printf(" sib=%02x=%d,%d,%d",sib,(sib>>6)&3,(sib>>3)&7,sib&7); 5053 5056 } 5054 5057 if ((rm & 0xC7) == BPRM || (rm & 0xC0) == 0x80 || (rm & 0xC0) == 0x40) 5055 5058 { 5056 5059 switch (c->IFL1) 5057 5060 { 5058 5061 case FLconst: 5059 5062 case FLoffset: 5060 5063 printf(" int = %4d",c->IEV1.Vuns); 5061 5064 break; 5062 5065 case FLblock: 5063 5066 printf(" block = %p",c->IEV1.Vblock); 5064 5067 break; 5065 5068 case FLswitch: 5066 5069 case FLblockoff: 5067 5070 case FLlocalsize: 5068 5071 case FLframehandler: trunk/src/backend/ptrntab.c
r618 r619 809 809 }; 810 810 PTRNTAB2 aptb2CMPS[] = /* CMPS */ { 811 811 { 0xa6, _modsidi, _m8, _m8 }, 812 812 { 0xa7, _modsidi, _m16, _m16 }, 813 813 { 0xa7, _modsidi, _m32, _m32 }, 814 814 { ASM_END, 0, 0, 0 } 815 815 }; 816 816 PTRNTAB2 aptb2CMPXCHG[] = /* CMPXCHG */ { 817 817 { 0xfb0, _I386 | _cb|_mod2, _rm8, _r8 }, 818 818 // This is really a 486 only 819 819 // instruction 820 820 { 0xfb1, _I386 | _cw | _16_bit|_mod2, _rm16, _r16 }, 821 821 { 0xfb1, _I386 | _cd | _32_bit|_mod2, _rm32, _r32 }, 822 822 { 0xfb1, _I386 | _cq | _64_bit|_mod2, _rm64, _r64 }, 823 823 { ASM_END, 0, 0, 0 } 824 824 }; 825 825 PTRNTAB2 aptb2DIV[] = /* DIV */ { 826 826 { 0xf6, _6, _al, _rm8 }, 827 827 { 0xf7, _6 | _16_bit | _moddx, _ax, _rm16 }, 828 828 { 0xf7, _6 | _32_bit | _moddx, _eax, _rm32 }, 829 { 0xf7, _6 | _64_bit | _moddx, _rax, _rm64 }, 829 830 { 0xf6, _6 | _modax, _rm8, 0 }, 830 { 0xf7, _6 | _16_bit | _modaxdx, _rm16, 0 }, 831 { 0xf7, _6 | _32_bit | _modaxdx, _rm32, 0 }, 831 { 0xf7, _6 | _16_bit | _modaxdx, _rm16, 0 }, 832 { 0xf7, _6 | _32_bit | _modaxdx, _rm32, 0 }, 833 { 0xf7, _6 | _64_bit | _modaxdx, _rm64, 0 }, 832 834 { ASM_END, 0, 0, 0 } 833 835 }; 834 836 PTRNTAB2 aptb2ENTER[] = /* ENTER */ { 835 837 { 0xc8, _iw|_ib, _imm16, _imm8 }, 836 838 { ASM_END, 0, 0, 0 } 837 839 }; 838 840 PTRNTAB2 aptb2IDIV[] = /* IDIV */ { 839 841 { 0xf6, _7, _al, _rm8 }, 840 { 0xf7, _7|_16_bit|_moddx, _ax, _rm16 }, 841 { 0xf7, _7|_32_bit|_moddx, _eax, _rm32 }, 842 { 0xf6, _7 | _modax, _rm8, 0 }, 842 { 0xf7, _7|_16_bit|_moddx, _ax, _rm16 }, 843 { 0xf7, _7|_32_bit|_moddx, _eax, _rm32 }, 844 { 0xf7, _7|_64_bit|_moddx, _rax, _rm64 }, 845 { 0xf6, _7 | _modax, _rm8, 0 }, 843 846 { 0xf7, _7|_16_bit|_modaxdx, _rm16, 0 }, 844 847 { 0xf7, _7|_32_bit|_modaxdx, _rm32, 0 }, 848 { 0xf7, _7|_64_bit|_modaxdx, _rm64, 0 }, 845 849 { ASM_END, 0, 0, 0 } 846 850 }; 847 851 PTRNTAB2 aptb2IN[] = /* IN */ { 848 852 { 0xe4, _ib, _al, _imm8 }, 849 853 { 0xe5, _ib|_16_bit,_ax, _imm8 }, 850 854 { 0xe5, _ib|_32_bit,_eax, _imm8 }, 851 855 { 0xec, 0, _al, _dx }, 852 856 { 0xed, _16_bit, _ax, _dx }, 853 857 { 0xed, _32_bit, _eax, _dx }, 854 858 { ASM_END, 0, 0, 0 } 855 859 }; 856 860 PTRNTAB2 aptb2INS[] = /* INS */ { 857 861 { 0x6c, _modsi, _rm8, _dx }, 858 862 { 0x6d, _modsi|_16_bit, _rm16, _dx }, 859 863 { 0x6d, _32_bit|_modsi, _rm32, _dx }, 860 864 { ASM_END, 0, 0, 0 } 861 865 }; 862 866 863 867 PTRNTAB2 aptb2LAR[] = /* LAR */ { 864 868 { 0x0f02, _r|_16_bit, _r16, _rm16 }, … … 958 962 #else 959 963 { 0x0fbf, _r, _r32, _rm16 }, 960 964 #endif 961 965 { ASM_END, 0, 0, 0 } 962 966 }; 963 967 PTRNTAB2 aptb2MOVZX[] = /* MOVZX */ { 964 968 { 0x0fb6, _r|_16_bit, _r16, _rm8 }, 965 969 { 0x0fb6, _r|_32_bit, _r32, _rm8 }, 966 970 #if 1 967 971 { 0x0fb7, _r|_16_bit, _r16, _rm16 }, 968 972 { 0x0fb7, _r|_32_bit, _r32, _rm16 }, 969 973 #else 970 974 { 0x0fb7, _r, _r32, _rm16 }, 971 975 #endif 972 976 { ASM_END, 0, 0, 0 } 973 977 }; 974 978 PTRNTAB2 aptb2MUL[] = /* MUL */ { 975 979 { 0xf6, _4, _al, _rm8 }, 976 980 { 0xf7, _4|_16_bit|_moddx, _ax, _rm16 }, 977 981 { 0xf7, _4|_32_bit|_moddx, _eax, _rm32 }, 982 { 0xf7, _4|_64_bit|_moddx, _rax, _rm64 }, 978 983 { 0xf6, _4|_modax, _rm8, 0 }, 979 984 { 0xf7, _4|_16_bit|_modaxdx, _rm16, 0 }, 980 985 { 0xf7, _4|_32_bit|_modaxdx, _rm32, 0 }, 986 { 0xf7, _4|_64_bit|_modaxdx, _rm64, 0 }, 981 987 { ASM_END, 0, 0, 0 } 982 988 }; 983 989 PTRNTAB2 aptb2OR[] = /* OR */ { 984 990 { 0x0c, _ib, _al, _imm8 }, 985 991 { 0x83, _1|_ib|_16_bit, _rm16, _imm8 }, 986 992 { 0x0d, _iw|_16_bit, _ax, _imm16 }, 987 993 { 0x83, _1|_ib|_32_bit, _rm32, _imm8 }, 988 994 { 0x0d, _id|_32_bit, _eax, _imm32 }, 989 995 { 0x80, _1|_ib, _rm8, _imm8 }, 990 996 { 0x81, _1|_iw|_16_bit, _rm16, _imm16 }, 991 997 { 0x81, _1|_id|_32_bit, _rm32, _imm32 }, 992 998 { 0x08, _r, _rm8, _r8 }, 993 999 { 0x09, _r|_16_bit, _rm16, _r16 }, 994 1000 { 0x09, _r|_32_bit, _rm32, _r32 }, 995 1001 { 0x0a, _r, _r8, _rm8 }, 996 1002 { 0x0b, _r|_16_bit, _r16, _rm16 }, 997 1003 { 0x0b, _r|_32_bit, _r32, _rm32 }, 998 1004 { ASM_END, 0, 0, 0 } 999 1005 }; 1000 1006 PTRNTAB2 aptb2OUT[] = { … … 1263 1269 }; 1264 1270 PTRNTAB2 aptb2CMOVNL[] = { 1265 1271 { 0x0F4D, _r|_16_bit, _r16, _rm16 }, 1266 1272 { 0x0F4D, _r|_32_bit, _r32, _rm32 }, 1267 1273 { ASM_END, 0, 0, 0 } 1268 1274 }; 1269 1275 PTRNTAB2 aptb2CMOVLE[] = { 1270 1276 { 0x0F4E, _r|_16_bit, _r16, _rm16 }, 1271 1277 { 0x0F4E, _r|_32_bit, _r32, _rm32 }, 1272 1278 { ASM_END, 0, 0, 0 } 1273 1279 }; 1274 1280 PTRNTAB2 aptb2CMOVNLE[] = { 1275 1281 { 0x0F4F, _r|_16_bit, _r16, _rm16 }, 1276 1282 { 0x0F4F, _r|_32_bit, _r32, _rm32 }, 1277 1283 { ASM_END, 0, 0, 0 } 1278 1284 }; 1279 1285 1280 1286 PTRNTAB3 aptb3IMUL[] = /* IMUL */ { 1281 1287 { 0x0faf, _r|_16_bit, _r16, _rm16, 0 }, 1282 1288 { 0x0faf, _r|_32_bit, _r32, _rm32, 0 }, 1289 { 0x0faf, _r|_64_bit, _r64, _rm64, 0 }, 1283 1290 { 0xf6, _5|_modax, _rm8, 0, 0 }, 1284 1291 { 0xf7, _5|_16_bit|_modaxdx, _rm16, 0, 0 }, 1285 1292 { 0xf7, _5|_32_bit|_modaxdx, _rm32, 0, 0 }, 1293 { 0xf7, _5|_64_bit|_modaxdx, _rm64, 0, 0 }, 1286 1294 { 0x6b, _r|_ib|_16_bit, _r16, _imm8, 0 }, 1287 1295 { 0x6b, _r|_ib|_32_bit, _r32, _imm8, 0 }, 1288 1296 { 0x69, _r|_iw|_16_bit, _r16, _imm16, 0 }, 1289 1297 { 0x69, _r|_id|_32_bit, _r32, _imm32, 0 }, 1298 { 0x69, _r|_id|_64_bit, _r64, _imm32, 0 }, 1290 1299 { 0x6b, _r|_ib|_16_bit, _r16, _rm16, _imm8 }, 1291 1300 { 0x6b, _r|_ib|_32_bit, _r32, _rm32, _imm8 }, 1301 { 0x6b, _r|_ib|_64_bit, _r64, _rm64, _imm8 }, 1292 1302 { 0x69, _r|_iw|_16_bit, _r16, _rm16, _imm16 }, 1293 1303 { 0x69, _r|_id|_32_bit, _r32, _rm32, _imm32 }, 1304 { 0x69, _r|_id|_64_bit, _r64, _rm64, _imm32 }, 1294 1305 { ASM_END, 0, 0, 0 } 1295 1306 }; 1296 1307 PTRNTAB3 aptb3SHLD[] = /* SHLD */ { 1297 1308 { 0x0fa4, _cw|_16_bit, _rm16, _r16, _imm8 }, 1298 1309 { 0x0fa4, _cd|_32_bit, _rm32, _r32, _imm8 }, 1299 1310 { 0x0fa5, _cw|_16_bit, _rm16, _r16, _cl }, 1300 1311 { 0x0fa5, _cd|_32_bit, _rm32, _r32, _cl }, 1301 1312 { ASM_END, 0, 0, 0 } 1302 1313 }; 1303 1314 PTRNTAB3 aptb3SHRD[] = /* SHRD */ { 1304 1315 { 0x0fac, _cw|_16_bit, _rm16, _r16, _imm8 }, 1305 1316 { 0x0fac, _cd|_32_bit, _rm32, _r32, _imm8 }, 1306 1317 { 0x0fad, _cw|_16_bit, _rm16, _r16, _cl }, 1307 1318 { 0x0fad, _cd|_32_bit, _rm32, _r32, _cl }, 1308 1319 { ASM_END, 0, 0, 0 } 1309 1320 }; 1310 1321 // 1311 1322 // Floating point instructions which have entirely different flag 1312 1323 // interpretations 1313 1324 // trunk/src/mtype.c
r605 r619 5241 5241 } 5242 5242 return t; 5243 5243 } 5244 5244 5245 5245 Type *TypeDelegate::semantic(Loc loc, Scope *sc) 5246 5246 { 5247 5247 if (deco) // if semantic() already run 5248 5248 { 5249 5249 //printf("already done\n"); 5250 5250 return this; 5251 5251 } 5252 5252 next = next->semantic(loc,sc); 5253 5253 return merge(); 5254 5254 } 5255 5255 5256 5256 d_uns64 TypeDelegate::size(Loc loc) 5257 5257 { 5258 5258 return PTRSIZE * 2; 5259 5259 } 5260 5260 5261 unsigned TypeDelegate::alignsize() 5262 { 5263 // See Bugzilla 942 for discussion 5264 #if 0 5265 return PTRSIZE; 5266 #else 5267 return PTRSIZE * 2; 5268 #endif 5269 } 5270 5261 5271 MATCH TypeDelegate::implicitConvTo(Type *to) 5262 5272 { 5263 5273 //printf("TypeDelegate::implicitConvTo(this=%p, to=%p)\n", this, to); 5264 5274 //printf("from: %s\n", toChars()); 5265 5275 //printf("to : %s\n", to->toChars()); 5266 5276 if (this == to) 5267 5277 return MATCHexact; 5268 5278 #if 0 // not allowing covariant conversions because it interferes with overriding 5269 5279 if (to->ty == Tdelegate && this->nextOf()->covariant(to->nextOf()) == 1) 5270 5280 return MATCHconvert; 5271 5281 #endif 5272 5282 return MATCHnomatch; 5273 5283 } 5274 5284 5275 5285 void TypeDelegate::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) 5276 5286 { 5277 5287 if (mod != this->mod) 5278 5288 { toCBuffer3(buf, hgs, mod); 5279 5289 return; 5280 5290 } trunk/src/mtype.h
r578 r619 575 575 #if CPP_MANGLE 576 576 void toCppMangle(OutBuffer *buf, CppMangleState *cms); 577 577 #endif 578 578 bool parameterEscapes(Parameter *p); 579 579 580 580 int callMatch(Expression *ethis, Expressions *toargs, int flag = 0); 581 581 type *toCtype(); 582 582 enum RET retStyle(); 583 583 584 584 unsigned totym(); 585 585 }; 586 586 587 587 struct TypeDelegate : TypeNext 588 588 { 589 589 // .next is a TypeFunction 590 590 591 591 TypeDelegate(Type *t); 592 592 Type *syntaxCopy(); 593 593 Type *semantic(Loc loc, Scope *sc); 594 594 d_uns64 size(Loc loc); 595 unsigned alignsize(); 595 596 MATCH implicitConvTo(Type *to); 596 597 void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); 597 598 Expression *defaultInit(Loc loc); 598 599 int isZeroInit(Loc loc); 599 600 int checkBoolean(); 600 601 TypeInfoDeclaration *getTypeInfoDeclaration(); 601 602 Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); 602 603 int hasPointers(); 603 604 #if CPP_MANGLE 604 605 void toCppMangle(OutBuffer *buf, CppMangleState *cms); 605 606 #endif 606 607 607 608 type *toCtype(); 608 609 }; 609 610 610 611 struct TypeQualified : Type 611 612 { 612 613 Loc loc; 613 614 Array idents; // array of Identifier's representing ident.ident.ident etc. 614 615
