Changeset 579
- Timestamp:
- 07/17/10 05:30:24 (2 years ago)
- Files:
-
- branches/dmd-1.x/src/backend/cgcod.c (modified) (3 diffs)
- branches/dmd-1.x/src/backend/cod1.c (modified) (11 diffs)
- branches/dmd-1.x/src/backend/cod2.c (modified) (1 diff)
- branches/dmd-1.x/src/backend/cod3.c (modified) (10 diffs)
- branches/dmd-1.x/src/backend/el.h (modified) (1 diff)
- branches/dmd-1.x/src/backend/elfobj.c (modified) (4 diffs)
- branches/dmd-1.x/src/backend/symbol.c (modified) (2 diffs)
- branches/dmd-1.x/src/backend/ty.h (modified) (1 diff)
- branches/dmd-1.x/src/e2ir.c (modified) (6 diffs)
- branches/dmd-1.x/src/msc.c (modified) (1 diff)
- trunk/src/backend/cgcod.c (modified) (3 diffs)
- trunk/src/backend/cod1.c (modified) (11 diffs)
- trunk/src/backend/cod2.c (modified) (1 diff)
- trunk/src/backend/cod3.c (modified) (10 diffs)
- trunk/src/backend/el.h (modified) (1 diff)
- trunk/src/backend/elfobj.c (modified) (4 diffs)
- trunk/src/backend/symbol.c (modified) (2 diffs)
- trunk/src/backend/ty.h (modified) (1 diff)
- trunk/src/e2ir.c (modified) (7 diffs)
- trunk/src/msc.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/dmd-1.x/src/backend/cgcod.c
r577 r579 140 140 BYTEREGS = value; 141 141 } 142 if (I64) 143 ALLREGS = mAX|mBX|mCX|mDX|mSI|mDI| mR8|mR9|mR10|mR11|mR12|mR13|mR14|mR15; 142 144 #endif 143 145 allregs = ALLREGS; … … 1913 1915 #ifdef DEBUG 1914 1916 WRTYxx(tym); 1915 printf("\nallocreg: fil %s lin %d, regcon.mvar x%x msavereg x%x *pretregs x%x, reg %d, tym x% lx\n",1917 printf("\nallocreg: fil %s lin %d, regcon.mvar x%x msavereg x%x *pretregs x%x, reg %d, tym x%x\n", 1916 1918 file,line,regcon.mvar,msavereg,*pretregs,*preg,tym); 1917 1919 #endif … … 2478 2480 { 2479 2481 #if DEBUG 2480 printf("e = %p, tym = x% lx\n",e,tym);2482 printf("e = %p, tym = x%x\n",e,tym); 2481 2483 #endif 2482 2484 assert(0); branches/dmd-1.x/src/backend/cod1.c
r577 r579 15 15 #include <stdio.h> 16 16 #include <string.h> 17 #include <stdlib.h> 17 18 #include <time.h> 18 19 #include "cc.h" … … 327 328 code *cs2 = *crestore; 328 329 330 //printf("gensaverestore2(%x)\n", regm); 329 331 regm &= mBP | mES | ALLREGS; 330 332 for (int i = 0; regm; i++) … … 1666 1668 #ifdef DEBUG 1667 1669 if (!(regm & (mBP | ALLREGS))) 1668 printf("tstresult(regm = x%x, tym = x% lx, saveflag = %d)\n",1670 printf("tstresult(regm = x%x, tym = x%x, saveflag = %d)\n", 1669 1671 regm,tym,saveflag); 1670 1672 #endif … … 2310 2312 keepmsk = 0; 2311 2313 if (OTbinary(e->Eoper)) // if parameters 2312 { unsigned stackalign = REGSIZE; 2313 elem *en; 2314 regm_t retregs; 2315 2316 if (!I16) 2314 { 2315 if (I16) 2317 2316 { 2317 c = cat(c, params(e->E2,2)); // push parameters 2318 } 2319 else if (I32) 2320 { 2321 unsigned stackalign = REGSIZE; 2318 2322 tym_t tyf = tybasic(e->E1->Ety); 2319 2323 2320 // First compute numpara, the total pushed on the stack2324 // First compute numpara, the total bytes pushed on the stack 2321 2325 switch (tyf) 2322 2326 { case TYf16func: … … 2366 2370 { case TYf16func: 2367 2371 stackalign = 2; 2368 break;2372 goto Ldefault2; 2369 2373 case TYmfunc: // last parameter goes into ECX 2370 2374 preg = CX; … … 2373 2377 preg = AX; 2374 2378 goto L1; 2375 2376 2379 L1: 2377 elem *ep; 2380 { elem *ep; 2381 elem *en; 2378 2382 for (ep = e->E2; ep->Eoper == OPparam; ep = en) 2379 2383 { … … 2381 2385 en = ep->E2; 2382 2386 freenode(ep); 2383 ep = en;2384 2387 } 2385 2388 if (tyf == TYjfunc && … … 2395 2398 // preg is the register to put the parameter ep in 2396 2399 keepmsk = mask[preg]; // don't change preg when evaluating func address 2397 re tregs = keepmsk;2400 regm_t retregs = keepmsk; 2398 2401 if (ep->Eoper == OPstrthis) 2399 2402 { code *c2; … … 2412 2415 } 2413 2416 goto Lret; 2414 } 2415 } 2416 c = cat(c, params(e->E2,stackalign)); // push parameters 2417 } 2418 default: 2419 Ldefault2: 2420 c = cat(c, params(e->E2,stackalign)); // push parameters 2421 break; 2422 } 2423 } 2424 else 2425 { assert(I64); 2426 2427 struct Parameter { elem *e; int reg; }; 2428 2429 #ifdef DEBUG 2430 #define PARAMETERS_DIM 3 2431 #else 2432 #define PARAMETERS_DIM 10 2433 #endif 2434 Parameter parameters_tmp[PARAMETERS_DIM]; 2435 Parameter *parameters = parameters_tmp; 2436 size_t parameters_dim = PARAMETERS_DIM; 2437 2438 // Load up parameters[] 2439 elem *ep; 2440 elem *en; 2441 int np = 0; 2442 for (ep = e->E2; ep->Eoper == OPparam; ep = en) 2443 { 2444 if (np + 1 == parameters_dim) // if not space for 2 more 2445 { // Grow parameters[] 2446 parameters_dim = np + 16; 2447 Parameter *p = (Parameter *)alloca(parameters_dim * sizeof(Parameter)); 2448 parameters = (Parameter *)memcpy(p, parameters, np * sizeof(Parameter)); 2449 } 2450 parameters[np++].e = ep->E1; 2451 en = ep->E2; 2452 freenode(ep); 2453 } 2454 parameters[np++].e = ep; 2455 2456 unsigned stackalign = REGSIZE; 2457 tym_t tyf = tybasic(e->E1->Ety); 2458 2459 // Compute numpara, the total bytes pushed on the stack 2460 int r = 0; 2461 int xmmcnt = XMM0; 2462 for (int i = np; --i >= 0;) 2463 { 2464 static const unsigned char argregs[6] = { DI,SI,DX,CX,R8,R9 }; 2465 elem *ep = parameters[i].e; 2466 tym_t ty = ep->Ety; 2467 if (r < sizeof(argregs)/sizeof(argregs[0])) // if more arg regs 2468 { 2469 if ( 2470 // This must match type_jparam() 2471 ty64reg(ty) || 2472 ((tybasic(ty) == TYstruct || tybasic(ty) == TYarray) && 2473 ep->Enumbytes <= REGSIZE && ep->Enumbytes != 3 && ep->Enumbytes) 2474 ) 2475 { 2476 parameters[i].reg = argregs[r]; 2477 r++; 2478 continue; // goes in register, not stack 2479 } 2480 } 2481 else if (xmmcnt < XMM7) 2482 { 2483 if (tyfloating(ty) && tysize(ty) <= 8) 2484 { 2485 parameters[i].reg = xmmcnt; 2486 xmmcnt++; 2487 continue; // goes in register, not stack 2488 } 2489 } 2490 parameters[i].reg = -1; // -1 means no register 2491 numpara += paramsize(ep,stackalign); 2492 } 2493 assert((numpara & (REGSIZE - 1)) == 0); 2494 assert((stackpush & (REGSIZE - 1)) == 0); 2495 2496 /* Adjust start of the stack so after all args are pushed, 2497 * the stack will be aligned. 2498 */ 2499 if (STACKALIGN == 16 && (numpara + stackpush) & (STACKALIGN - 1)) 2500 { 2501 numalign = STACKALIGN - ((numpara + stackpush) & (STACKALIGN - 1)); 2502 c = genc2(NULL,0x81,(REX_W << 16) | modregrm(3,5,SP),numalign); // SUB ESP,numalign 2503 c = genadjesp(c, numalign); 2504 stackpush += numalign; 2505 stackpushsave += numalign; 2506 } 2507 2508 /* Parameters go into the registers RDI,RSI,RDX,RCX,R8,R9 2509 * float and double parameters go into XMM0..XMM7 2510 * For variadic functions, count of XMM registers used goes in AL 2511 */ 2512 for (int i = 0; i < np; i++) 2513 { 2514 elem *ep = parameters[i].e; 2515 int preg = parameters[i].reg; 2516 if (preg == -1) 2517 c = cat(c,params(ep,stackalign)); 2518 else 2519 { 2520 // Goes in register preg, not stack 2521 regm_t retregs = mask[preg]; 2522 if (ep->Eoper == OPstrthis) 2523 { 2524 code *c1 = getregs(retregs); 2525 // LEA preg,np[ESP] 2526 unsigned np = stackpush - ep->EV.Vuns; // stack delta to parameter 2527 code *c2 = genc1(CNIL,0x8D,(REX_W << 16) | 2528 (modregrm(0,4,SP) << 8) | 2529 modregxrm(2,preg,4), FLconst,np); 2530 c = cat3(c,c1,c2); 2531 } 2532 else 2533 { code *cp = scodelem(ep,&retregs,keepmsk,FALSE); 2534 c = cat(c,cp); 2535 } 2536 keepmsk |= retregs; // don't change preg when evaluating func address 2537 } 2538 } 2539 if (e->Eflags & EFLAGS_variadic) 2540 { movregconst(c,AX,xmmcnt - XMM0,1); 2541 keepmsk |= mAX; 2542 } 2543 } 2417 2544 } 2418 2545 else … … 2435 2562 Lret: 2436 2563 cgstate.stackclean--; 2437 if (!I16) 2564 if (I16) 2565 numpara = stackpush - stackpushsave; 2566 else 2438 2567 { 2439 2568 if (numpara != stackpush - stackpushsave) … … 2441 2570 assert(numpara == stackpush - stackpushsave); 2442 2571 } 2443 else2444 numpara = stackpush - stackpushsave;2445 2572 return cat(c,funccall(e,numpara,numalign,pretregs,keepmsk)); 2446 2573 } branches/dmd-1.x/src/backend/cod2.c
r577 r579 3736 3736 3737 3737 cs.Iflags = 0; 3738 unsigned char rex = I64 ? REX_W :0;3738 unsigned char rex = 0; 3739 3739 cs.Irex = rex; 3740 3740 assert(e->Eoper == OPvar || e->Eoper == OPrelconst); branches/dmd-1.x/src/backend/cod3.c
r577 r579 1172 1172 1173 1173 code *prolog() 1174 { code *c;1174 { 1175 1175 SYMIDX si; 1176 1176 unsigned reg; 1177 regm_t topush;1178 tym_t tym;1179 tym_t tyf;1180 1177 char enter; 1181 char pushds;1182 unsigned farfunc;1183 1178 unsigned Foffset; 1184 1179 unsigned xlocalsize; // amount to subtract from ESP to make room for locals 1185 int pushalloc;1186 1180 unsigned pushallocreg; 1187 1181 char guessneedframe; … … 1192 1186 EBPtoESP = -REGSIZE; 1193 1187 hasframe = 0; 1194 pushds = 0;1188 char pushds = 0; 1195 1189 BPoff = 0; 1196 c = CNIL;1197 pushalloc = 0;1198 ty f = funcsym_p->ty();1199 tym = tybasic(tyf);1200 farfunc = tyfarfunc(tym);1190 code *c = CNIL; 1191 int pushalloc = 0; 1192 tym_t tyf = funcsym_p->ty(); 1193 tym_t tym = tybasic(tyf); 1194 unsigned farfunc = tyfarfunc(tym); 1201 1195 pushallocreg = (tyf == TYmfunc) ? CX : AX; 1202 1196 if (config.flags & CFGalwaysframe || funcsym_p->Sfunc->Fflags3 & Ffakeeh) … … 1264 1258 localsize = -Toff; 1265 1259 1266 topush = fregsaved & ~mfuncreg; // mask of registers that need saving1260 regm_t topush = fregsaved & ~mfuncreg; // mask of registers that need saving 1267 1261 int npush = 0; // number of registers that need saving 1268 1262 for (regm_t x = topush; x; x >>= 1) … … 1346 1340 } 1347 1341 1348 #if SIXTEENBIT 1349 if (config.wflags & WFwindows && farfunc) 1342 if (I16 && config.wflags & WFwindows && farfunc) 1350 1343 { int wflags; 1351 1344 int segreg; 1352 1345 1346 #if SCPP 1353 1347 // alloca() can't be because the 'special' parameter won't be at 1354 1348 // a known offset from BP. 1355 1349 if (usedalloca == 1) 1356 1350 synerr(EM_alloca_win); // alloca() can't be in Windows functions 1351 #endif 1357 1352 1358 1353 wflags = config.wflags; … … 1406 1401 } 1407 1402 else 1408 #endif1409 1403 if (needframe) // if variables or parameters 1410 1404 { … … 1660 1654 { reg = findreg(topush); 1661 1655 topush &= ~mask[reg]; 1662 c = gen1(c,0x50 + reg); 1656 c = gen1(c,0x50 + (reg & 7)); 1657 if (reg & 8) 1658 code_orrex(c, REX_B); 1663 1659 EBPtoESP += REGSIZE; 1664 1660 #if ELFOBJ || MACHOBJ … … 1913 1909 while (topop) 1914 1910 { if (topop & regm) 1915 { c = gen1(c,0x58 + reg); // POP reg1911 { c = gen1(c,0x58 + (reg & 7)); // POP reg 1916 1912 if (reg & 8) 1917 1913 code_orrex(c, REX_B); … … 4348 4344 void addtofixlist(symbol *s,targ_size_t soffset,int seg,targ_size_t val,int flags) 4349 4345 { fixlist *ln; 4350 static char zeros[ 6];4346 static char zeros[8]; 4351 4347 int numbytes; 4352 4348 … … 4884 4880 case FLconst: 4885 4881 case FLoffset: 4886 printf(" int = %4 ld",c->IEV1.Vuns);4882 printf(" int = %4d",c->IEV1.Vuns); 4887 4883 break; 4888 4884 case FLblock: … … 4919 4915 { 4920 4916 case FLconst: 4921 printf(" int = %4 ld",c->IEV2.Vuns);4917 printf(" int = %4d",c->IEV2.Vuns); 4922 4918 break; 4923 4919 case FLblock: branches/dmd-1.x/src/backend/el.h
r572 r579 44 44 unsigned char Ecount; // # of parents of this elem - 1, 45 45 // always 0 until CSE elimination is done 46 unsigned char Eflags; 47 #define EFLAGS_variadic 1 // variadic function call 48 46 49 union eve EV; // variants for each type of elem 47 50 union branches/dmd-1.x/src/backend/elfobj.c
r572 r579 2719 2719 void obj_moduleinfo(Symbol *scc) 2720 2720 { 2721 // if (I64) return; // for now, until Phobos64 works 2722 2721 2723 int codeOffset, refOffset; 2722 2724 … … 2735 2737 SegData[seg]->SDbuf->writezeros(NPTRSIZE); 2736 2738 SegData[seg]->SDoffset += NPTRSIZE; 2737 SegData[seg]->SDoffset += reftoident(seg, SegData[seg]->SDoffset, scc, 0, CFoff); 2738 alignOffset(seg, NPTRSIZE); 2739 SegData[seg]->SDoffset += reftoident(seg, SegData[seg]->SDoffset, scc, 0, CFoffset64 | CFoff); 2739 2740 } 2740 2741 … … 2764 2765 buf->writeByte(0xC3); /* ret */ 2765 2766 2766 buf->writeByte(0x60); /* pushad */ 2767 int off = 0; 2768 if (I32) 2769 { buf->writeByte(0x60); // PUSHAD 2770 off = 1; 2771 } 2767 2772 2768 2773 /* movl ModuleReference*, %eax */ 2769 2774 buf->writeByte(0xB8); 2770 2775 buf->write32(refOffset); 2771 elf_addrel(seg, codeOffset + 2, reltype, STI_DATA, 0);2776 elf_addrel(seg, codeOffset + off + 1, reltype, STI_DATA, 0); 2772 2777 2773 2778 /* movl _Dmodule_ref, %ecx */ 2774 2779 buf->writeByte(0xB9); 2775 2780 buf->write32(0); 2776 elf_addrel(seg, codeOffset + 7, reltype, objextern("_Dmodule_ref"), 0);2781 elf_addrel(seg, codeOffset + off + 6, reltype, objextern("_Dmodule_ref"), 0); 2777 2782 2778 2783 buf->writeByte(0x8B); buf->writeByte(0x11); /* movl (%ecx), %edx */ … … 2780 2785 buf->writeByte(0x89); buf->writeByte(0x01); /* movl %eax, (%ecx) */ 2781 2786 2782 buf->writeByte(0x61); /* popad */2787 if (I32) buf->writeByte(0x61); // POPAD 2783 2788 buf->writeByte(0xC3); /* ret */ 2784 2789 SegData[seg]->SDoffset = buf->size(); branches/dmd-1.x/src/backend/symbol.c
r487 r579 364 364 void symbol_func(symbol *s) 365 365 { 366 //printf("symbol_func(%s, x%x)\n", s->Sident, fregsaved); 366 367 symbol_debug(s); 367 368 s->Sfl = FLfunc; … … 370 371 // BUG: do interrupt functions really save BP? 371 372 #define mBP 0x20 373 // Note that fregsaved may not be set yet 372 374 s->Sregsaved = (s->Stype && tybasic(s->Stype->Tty) == TYifunc) ? mBP : fregsaved; 373 375 s->Sseg = UNKNOWN; // don't know what segment it is in branches/dmd-1.x/src/backend/ty.h
r557 r579 198 198 #define tyreal(ty) (tytab[(ty) & 0xFF] & TYFLreal) 199 199 200 // Fits into 64 bit register 201 #define ty64reg(ty) (tytab[(ty) & 0xFF] & (TYFLintegral | TYFLptr)) 202 200 203 #ifndef tyshort 201 204 /* Types that are chars or shorts */ branches/dmd-1.x/src/e2ir.c
r569 r579 281 281 } 282 282 else if (ep) 283 e = el_bin(OPcall,tyret,ec,ep); 283 { e = el_bin(OPcall,tyret,ec,ep); 284 if (tf->varargs) 285 e->Eflags |= EFLAGS_variadic; 286 } 284 287 else 285 e = el_una(OPucall,tyret,ec); 288 { e = el_una(OPucall,tyret,ec); 289 if (tf->varargs) 290 e->Eflags |= EFLAGS_variadic; 291 } 286 292 287 293 if (retmethod == RETstack) … … 1774 1780 NULL); 1775 1781 e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCATNT]), ep); 1782 e->Eflags |= EFLAGS_variadic; 1776 1783 #else 1777 1784 ep = el_params( … … 1781 1788 NULL); 1782 1789 e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCATN]), ep); 1790 e->Eflags |= EFLAGS_variadic; 1783 1791 #endif 1784 1792 } … … 4218 4226 // call _d_arrayliteralT(ti, dim, ...) 4219 4227 e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ARRAYLITERALT]),e); 4228 e->Eflags |= EFLAGS_variadic; 4220 4229 #else 4221 4230 e = el_param(e, el_long(TYint, tb->next->size())); … … 4223 4232 // call _d_arrayliteral(size, dim, ...) 4224 4233 e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ARRAYLITERAL]),e); 4234 e->Eflags |= EFLAGS_variadic; 4225 4235 #endif 4226 4236 if (tb->ty == Tarray) … … 4271 4281 // call _d_assocarrayliteralT(ti, dim, ...) 4272 4282 e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ASSOCARRAYLITERALT]),e); 4283 e->Eflags |= EFLAGS_variadic; 4273 4284 4274 4285 el_setLoc(e,loc); branches/dmd-1.x/src/msc.c
r569 r579 41 41 void out_config_init() 42 42 { 43 //printf("out_config_init()\n"); 43 44 Param *params = &global.params; 44 45 trunk/src/backend/cgcod.c
r577 r579 140 140 BYTEREGS = value; 141 141 } 142 if (I64) 143 ALLREGS = mAX|mBX|mCX|mDX|mSI|mDI| mR8|mR9|mR10|mR11|mR12|mR13|mR14|mR15; 142 144 #endif 143 145 allregs = ALLREGS; … … 1913 1915 #ifdef DEBUG 1914 1916 WRTYxx(tym); 1915 printf("\nallocreg: fil %s lin %d, regcon.mvar x%x msavereg x%x *pretregs x%x, reg %d, tym x% lx\n",1917 printf("\nallocreg: fil %s lin %d, regcon.mvar x%x msavereg x%x *pretregs x%x, reg %d, tym x%x\n", 1916 1918 file,line,regcon.mvar,msavereg,*pretregs,*preg,tym); 1917 1919 #endif … … 2478 2480 { 2479 2481 #if DEBUG 2480 printf("e = %p, tym = x% lx\n",e,tym);2482 printf("e = %p, tym = x%x\n",e,tym); 2481 2483 #endif 2482 2484 assert(0); trunk/src/backend/cod1.c
r577 r579 15 15 #include <stdio.h> 16 16 #include <string.h> 17 #include <stdlib.h> 17 18 #include <time.h> 18 19 #include "cc.h" … … 327 328 code *cs2 = *crestore; 328 329 330 //printf("gensaverestore2(%x)\n", regm); 329 331 regm &= mBP | mES | ALLREGS; 330 332 for (int i = 0; regm; i++) … … 1666 1668 #ifdef DEBUG 1667 1669 if (!(regm & (mBP | ALLREGS))) 1668 printf("tstresult(regm = x%x, tym = x% lx, saveflag = %d)\n",1670 printf("tstresult(regm = x%x, tym = x%x, saveflag = %d)\n", 1669 1671 regm,tym,saveflag); 1670 1672 #endif … … 2310 2312 keepmsk = 0; 2311 2313 if (OTbinary(e->Eoper)) // if parameters 2312 { unsigned stackalign = REGSIZE; 2313 elem *en; 2314 regm_t retregs; 2315 2316 if (!I16) 2314 { 2315 if (I16) 2317 2316 { 2317 c = cat(c, params(e->E2,2)); // push parameters 2318 } 2319 else if (I32) 2320 { 2321 unsigned stackalign = REGSIZE; 2318 2322 tym_t tyf = tybasic(e->E1->Ety); 2319 2323 2320 // First compute numpara, the total pushed on the stack2324 // First compute numpara, the total bytes pushed on the stack 2321 2325 switch (tyf) 2322 2326 { case TYf16func: … … 2366 2370 { case TYf16func: 2367 2371 stackalign = 2; 2368 break;2372 goto Ldefault2; 2369 2373 case TYmfunc: // last parameter goes into ECX 2370 2374 preg = CX; … … 2373 2377 preg = AX; 2374 2378 goto L1; 2375 2376 2379 L1: 2377 elem *ep; 2380 { elem *ep; 2381 elem *en; 2378 2382 for (ep = e->E2; ep->Eoper == OPparam; ep = en) 2379 2383 { … … 2381 2385 en = ep->E2; 2382 2386 freenode(ep); 2383 ep = en;2384 2387 } 2385 2388 if (tyf == TYjfunc && … … 2395 2398 // preg is the register to put the parameter ep in 2396 2399 keepmsk = mask[preg]; // don't change preg when evaluating func address 2397 re tregs = keepmsk;2400 regm_t retregs = keepmsk; 2398 2401 if (ep->Eoper == OPstrthis) 2399 2402 { code *c2; … … 2412 2415 } 2413 2416 goto Lret; 2414 } 2415 } 2416 c = cat(c, params(e->E2,stackalign)); // push parameters 2417 } 2418 default: 2419 Ldefault2: 2420 c = cat(c, params(e->E2,stackalign)); // push parameters 2421 break; 2422 } 2423 } 2424 else 2425 { assert(I64); 2426 2427 struct Parameter { elem *e; int reg; }; 2428 2429 #ifdef DEBUG 2430 #define PARAMETERS_DIM 3 2431 #else 2432 #define PARAMETERS_DIM 10 2433 #endif 2434 Parameter parameters_tmp[PARAMETERS_DIM]; 2435 Parameter *parameters = parameters_tmp; 2436 size_t parameters_dim = PARAMETERS_DIM; 2437 2438 // Load up parameters[] 2439 elem *ep; 2440 elem *en; 2441 int np = 0; 2442 for (ep = e->E2; ep->Eoper == OPparam; ep = en) 2443 { 2444 if (np + 1 == parameters_dim) // if not space for 2 more 2445 { // Grow parameters[] 2446 parameters_dim = np + 16; 2447 Parameter *p = (Parameter *)alloca(parameters_dim * sizeof(Parameter)); 2448 parameters = (Parameter *)memcpy(p, parameters, np * sizeof(Parameter)); 2449 } 2450 parameters[np++].e = ep->E1; 2451 en = ep->E2; 2452 freenode(ep); 2453 } 2454 parameters[np++].e = ep; 2455 2456 unsigned stackalign = REGSIZE; 2457 tym_t tyf = tybasic(e->E1->Ety); 2458 2459 // Compute numpara, the total bytes pushed on the stack 2460 int r = 0; 2461 int xmmcnt = XMM0; 2462 for (int i = np; --i >= 0;) 2463 { 2464 static const unsigned char argregs[6] = { DI,SI,DX,CX,R8,R9 }; 2465 elem *ep = parameters[i].e; 2466 tym_t ty = ep->Ety; 2467 if (r < sizeof(argregs)/sizeof(argregs[0])) // if more arg regs 2468 { 2469 if ( 2470 // This must match type_jparam() 2471 ty64reg(ty) || 2472 ((tybasic(ty) == TYstruct || tybasic(ty) == TYarray) && 2473 ep->Enumbytes <= REGSIZE && ep->Enumbytes != 3 && ep->Enumbytes) 2474 ) 2475 { 2476 parameters[i].reg = argregs[r]; 2477 r++; 2478 continue; // goes in register, not stack 2479 } 2480 } 2481 else if (xmmcnt < XMM7) 2482 { 2483 if (tyfloating(ty) && tysize(ty) <= 8) 2484 { 2485 parameters[i].reg = xmmcnt; 2486 xmmcnt++; 2487 continue; // goes in register, not stack 2488 } 2489 } 2490 parameters[i].reg = -1; // -1 means no register 2491 numpara += paramsize(ep,stackalign); 2492 } 2493 assert((numpara & (REGSIZE - 1)) == 0); 2494 assert((stackpush & (REGSIZE - 1)) == 0); 2495 2496 /* Adjust start of the stack so after all args are pushed, 2497 * the stack will be aligned. 2498 */ 2499 if (STACKALIGN == 16 && (numpara + stackpush) & (STACKALIGN - 1)) 2500 { 2501 numalign = STACKALIGN - ((numpara + stackpush) & (STACKALIGN - 1)); 2502 c = genc2(NULL,0x81,(REX_W << 16) | modregrm(3,5,SP),numalign); // SUB ESP,numalign 2503 c = genadjesp(c, numalign); 2504 stackpush += numalign; 2505 stackpushsave += numalign; 2506 } 2507 2508 /* Parameters go into the registers RDI,RSI,RDX,RCX,R8,R9 2509 * float and double parameters go into XMM0..XMM7 2510 * For variadic functions, count of XMM registers used goes in AL 2511 */ 2512 for (int i = 0; i < np; i++) 2513 { 2514 elem *ep = parameters[i].e; 2515 int preg = parameters[i].reg; 2516 if (preg == -1) 2517 c = cat(c,params(ep,stackalign)); 2518 else 2519 { 2520 // Goes in register preg, not stack 2521 regm_t retregs = mask[preg]; 2522 if (ep->Eoper == OPstrthis) 2523 { 2524 code *c1 = getregs(retregs); 2525 // LEA preg,np[ESP] 2526 unsigned np = stackpush - ep->EV.Vuns; // stack delta to parameter 2527 code *c2 = genc1(CNIL,0x8D,(REX_W << 16) | 2528 (modregrm(0,4,SP) << 8) | 2529 modregxrm(2,preg,4), FLconst,np); 2530 c = cat3(c,c1,c2); 2531 } 2532 else 2533 { code *cp = scodelem(ep,&retregs,keepmsk,FALSE); 2534 c = cat(c,cp); 2535 } 2536 keepmsk |= retregs; // don't change preg when evaluating func address 2537 } 2538 } 2539 if (e->Eflags & EFLAGS_variadic) 2540 { movregconst(c,AX,xmmcnt - XMM0,1); 2541 keepmsk |= mAX; 2542 } 2543 } 2417 2544 } 2418 2545 else … … 2435 2562 Lret: 2436 2563 cgstate.stackclean--; 2437 if (!I16) 2564 if (I16) 2565 numpara = stackpush - stackpushsave; 2566 else 2438 2567 { 2439 2568 if (numpara != stackpush - stackpushsave) … … 2441 2570 assert(numpara == stackpush - stackpushsave); 2442 2571 } 2443 else2444 numpara = stackpush - stackpushsave;2445 2572 return cat(c,funccall(e,numpara,numalign,pretregs,keepmsk)); 2446 2573 } trunk/src/backend/cod2.c
r577 r579 3736 3736 3737 3737 cs.Iflags = 0; 3738 unsigned char rex = I64 ? REX_W :0;3738 unsigned char rex = 0; 3739 3739 cs.Irex = rex; 3740 3740 assert(e->Eoper == OPvar || e->Eoper == OPrelconst); trunk/src/backend/cod3.c
r577 r579 1172 1172 1173 1173 code *prolog() 1174 { code *c;1174 { 1175 1175 SYMIDX si; 1176 1176 unsigned reg; 1177 regm_t topush;1178 tym_t tym;1179 tym_t tyf;1180 1177 char enter; 1181 char pushds;1182 unsigned farfunc;1183 1178 unsigned Foffset; 1184 1179 unsigned xlocalsize; // amount to subtract from ESP to make room for locals 1185 int pushalloc;1186 1180 unsigned pushallocreg; 1187 1181 char guessneedframe; … … 1192 1186 EBPtoESP = -REGSIZE; 1193 1187 hasframe = 0; 1194 pushds = 0;1188 char pushds = 0; 1195 1189 BPoff = 0; 1196 c = CNIL;1197 pushalloc = 0;1198 ty f = funcsym_p->ty();1199 tym = tybasic(tyf);1200 farfunc = tyfarfunc(tym);1190 code *c = CNIL; 1191 int pushalloc = 0; 1192 tym_t tyf = funcsym_p->ty(); 1193 tym_t tym = tybasic(tyf); 1194 unsigned farfunc = tyfarfunc(tym); 1201 1195 pushallocreg = (tyf == TYmfunc) ? CX : AX; 1202 1196 if (config.flags & CFGalwaysframe || funcsym_p->Sfunc->Fflags3 & Ffakeeh) … … 1264 1258 localsize = -Toff; 1265 1259 1266 topush = fregsaved & ~mfuncreg; // mask of registers that need saving1260 regm_t topush = fregsaved & ~mfuncreg; // mask of registers that need saving 1267 1261 int npush = 0; // number of registers that need saving 1268 1262 for (regm_t x = topush; x; x >>= 1) … … 1346 1340 } 1347 1341 1348 #if SIXTEENBIT 1349 if (config.wflags & WFwindows && farfunc) 1342 if (I16 && config.wflags & WFwindows && farfunc) 1350 1343 { int wflags; 1351 1344 int segreg; 1352 1345 1346 #if SCPP 1353 1347 // alloca() can't be because the 'special' parameter won't be at 1354 1348 // a known offset from BP. 1355 1349 if (usedalloca == 1) 1356 1350 synerr(EM_alloca_win); // alloca() can't be in Windows functions 1351 #endif 1357 1352 1358 1353 wflags = config.wflags; … … 1406 1401 } 1407 1402 else 1408 #endif1409 1403 if (needframe) // if variables or parameters 1410 1404 { … … 1660 1654 { reg = findreg(topush); 1661 1655 topush &= ~mask[reg]; 1662 c = gen1(c,0x50 + reg); 1656 c = gen1(c,0x50 + (reg & 7)); 1657 if (reg & 8) 1658 code_orrex(c, REX_B); 1663 1659 EBPtoESP += REGSIZE; 1664 1660 #if ELFOBJ || MACHOBJ … … 1913 1909 while (topop) 1914 1910 { if (topop & regm) 1915 { c = gen1(c,0x58 + reg); // POP reg1911 { c = gen1(c,0x58 + (reg & 7)); // POP reg 1916 1912 if (reg & 8) 1917 1913 code_orrex(c, REX_B); … … 4348 4344 void addtofixlist(symbol *s,targ_size_t soffset,int seg,targ_size_t val,int flags) 4349 4345 { fixlist *ln; 4350 static char zeros[ 6];4346 static char zeros[8]; 4351 4347 int numbytes; 4352 4348 … … 4884 4880 case FLconst: 4885 4881 case FLoffset: 4886 printf(" int = %4 ld",c->IEV1.Vuns);4882 printf(" int = %4d",c->IEV1.Vuns); 4887 4883 break; 4888 4884 case FLblock: … … 4919 4915 { 4920 4916 case FLconst: 4921 printf(" int = %4 ld",c->IEV2.Vuns);4917 printf(" int = %4d",c->IEV2.Vuns); 4922 4918 break; 4923 4919 case FLblock: trunk/src/backend/el.h
r572 r579 44 44 unsigned char Ecount; // # of parents of this elem - 1, 45 45 // always 0 until CSE elimination is done 46 unsigned char Eflags; 47 #define EFLAGS_variadic 1 // variadic function call 48 46 49 union eve EV; // variants for each type of elem 47 50 union trunk/src/backend/elfobj.c
r572 r579 2719 2719 void obj_moduleinfo(Symbol *scc) 2720 2720 { 2721 // if (I64) return; // for now, until Phobos64 works 2722 2721 2723 int codeOffset, refOffset; 2722 2724 … … 2735 2737 SegData[seg]->SDbuf->writezeros(NPTRSIZE); 2736 2738 SegData[seg]->SDoffset += NPTRSIZE; 2737 SegData[seg]->SDoffset += reftoident(seg, SegData[seg]->SDoffset, scc, 0, CFoff); 2738 alignOffset(seg, NPTRSIZE); 2739 SegData[seg]->SDoffset += reftoident(seg, SegData[seg]->SDoffset, scc, 0, CFoffset64 | CFoff); 2739 2740 } 2740 2741 … … 2764 2765 buf->writeByte(0xC3); /* ret */ 2765 2766 2766 buf->writeByte(0x60); /* pushad */ 2767 int off = 0; 2768 if (I32) 2769 { buf->writeByte(0x60); // PUSHAD 2770 off = 1; 2771 } 2767 2772 2768 2773 /* movl ModuleReference*, %eax */ 2769 2774 buf->writeByte(0xB8); 2770 2775 buf->write32(refOffset); 2771 elf_addrel(seg, codeOffset + 2, reltype, STI_DATA, 0);2776 elf_addrel(seg, codeOffset + off + 1, reltype, STI_DATA, 0); 2772 2777 2773 2778 /* movl _Dmodule_ref, %ecx */ 2774 2779 buf->writeByte(0xB9); 2775 2780 buf->write32(0); 2776 elf_addrel(seg, codeOffset + 7, reltype, objextern("_Dmodule_ref"), 0);2781 elf_addrel(seg, codeOffset + off + 6, reltype, objextern("_Dmodule_ref"), 0); 2777 2782 2778 2783 buf->writeByte(0x8B); buf->writeByte(0x11); /* movl (%ecx), %edx */ … … 2780 2785 buf->writeByte(0x89); buf->writeByte(0x01); /* movl %eax, (%ecx) */ 2781 2786 2782 buf->writeByte(0x61); /* popad */2787 if (I32) buf->writeByte(0x61); // POPAD 2783 2788 buf->writeByte(0xC3); /* ret */ 2784 2789 SegData[seg]->SDoffset = buf->size(); trunk/src/backend/symbol.c
r487 r579 364 364 void symbol_func(symbol *s) 365 365 { 366 //printf("symbol_func(%s, x%x)\n", s->Sident, fregsaved); 366 367 symbol_debug(s); 367 368 s->Sfl = FLfunc; … … 370 371 // BUG: do interrupt functions really save BP? 371 372 #define mBP 0x20 373 // Note that fregsaved may not be set yet 372 374 s->Sregsaved = (s->Stype && tybasic(s->Stype->Tty) == TYifunc) ? mBP : fregsaved; 373 375 s->Sseg = UNKNOWN; // don't know what segment it is in trunk/src/backend/ty.h
r557 r579 198 198 #define tyreal(ty) (tytab[(ty) & 0xFF] & TYFLreal) 199 199 200 // Fits into 64 bit register 201 #define ty64reg(ty) (tytab[(ty) & 0xFF] & (TYFLintegral | TYFLptr)) 202 200 203 #ifndef tyshort 201 204 /* Types that are chars or shorts */ trunk/src/e2ir.c
r569 r579 287 287 } 288 288 else if (ep) 289 /* Do not do "no side effect" calls if a hidden parameter is passed,289 { /* Do not do "no side effect" calls if a hidden parameter is passed, 290 290 * as the return value is stored through the hidden parameter, which 291 291 * is a side effect. … … 293 293 e = el_bin((tf->ispure && tf->isnothrow && (retmethod != RETstack)) ? 294 294 OPcallns : OPcall,tyret,ec,ep); 295 if (tf->varargs) 296 e->Eflags |= EFLAGS_variadic; 297 } 295 298 else 296 e = el_una((tf->ispure && tf->isnothrow && (retmethod != RETstack)) ?299 { e = el_una((tf->ispure && tf->isnothrow && (retmethod != RETstack)) ? 297 300 OPucallns : OPucall,tyret,ec); 301 if (tf->varargs) 302 e->Eflags |= EFLAGS_variadic; 303 } 298 304 299 305 if (retmethod == RETstack) … … 2078 2084 NULL); 2079 2085 e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCATNT]), ep); 2086 e->Eflags |= EFLAGS_variadic; 2080 2087 #else 2081 2088 ep = el_params( … … 2085 2092 NULL); 2086 2093 e = el_bin(OPcall, TYdarray, el_var(rtlsym[RTLSYM_ARRAYCATN]), ep); 2094 e->Eflags |= EFLAGS_variadic; 2087 2095 #endif 2088 2096 } … … 4563 4571 // call _d_arrayliteralT(ti, dim, ...) 4564 4572 e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ARRAYLITERALT]),e); 4573 e->Eflags |= EFLAGS_variadic; 4565 4574 #else 4566 4575 e = el_param(e, el_long(TYint, tb->next->size())); … … 4568 4577 // call _d_arrayliteral(size, dim, ...) 4569 4578 e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ARRAYLITERAL]),e); 4579 e->Eflags |= EFLAGS_variadic; 4570 4580 #endif 4571 4581 if (tb->ty == Tarray) … … 4637 4647 // call _d_assocarrayliteralT(ti, dim, ...) 4638 4648 e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ASSOCARRAYLITERALT]),e); 4649 e->Eflags |= EFLAGS_variadic; 4639 4650 4640 4651 el_setLoc(e,loc); trunk/src/msc.c
r569 r579 41 41 void out_config_init() 42 42 { 43 //printf("out_config_init()\n"); 43 44 Param *params = &global.params; 44 45
