Changeset 308
- Timestamp:
- 12/24/09 20:15:25 (15 years ago)
- Files:
-
- branches/dmd-1.x/src/backend/cod1.c (modified) (3 diffs)
- branches/dmd-1.x/src/msc.c (modified) (1 diff)
- trunk/src/backend/cod1.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/dmd-1.x/src/backend/cod1.c
r272 r308 1306 1306 default: 1307 1307 #ifdef DEBUG 1308 1308 WRFL((enum FL)fl); 1309 1309 symbol_print(s); 1310 1310 #endif 1311 1311 assert(0); 1312 1312 } 1313 1313 return c; 1314 1314 } 1315 1315 1316 1316 1317 1317 /******************************* 1318 1318 * Same as codelem(), but do not destroy the registers in keepmsk. 1319 1319 * Use scratch registers as much as possible, then use stack. 1320 1320 * Input: 1321 1321 * constflag TRUE if user of result will not modify the 1322 1322 * registers returned in *pretregs. 1323 1323 */ 1324 1324 1325 1325 code *scodelem(elem *e,regm_t *pretregs,regm_t keepmsk,bool constflag) 1326 { code *c,*cs1,*cs2 ;1326 { code *c,*cs1,*cs2,*cs3; 1327 1327 unsigned i,j; 1328 1328 regm_t oldmfuncreg,oldregcon,oldregimmed,overlap,tosave,touse; 1329 1329 int adjesp; 1330 1330 unsigned stackpushsave; 1331 1331 char calledafuncsave; 1332 1332 1333 1333 #ifdef DEBUG 1334 1334 if (debugw) 1335 1335 printf("+scodelem(e=%p *pretregs=x%x keepmsk=x%x constflag=%d\n", 1336 1336 e,*pretregs,keepmsk,constflag); 1337 1337 #endif 1338 1338 elem_debug(e); 1339 1339 if (constflag) 1340 1340 { regm_t regm; 1341 1341 unsigned reg; 1342 1342 1343 1343 if (isregvar(e,®m,®) && // if e is a register variable 1344 1344 (regm & *pretregs) == regm && // in one of the right regs 1345 1345 e->EV.sp.Voffset == 0 1346 1346 ) … … 1407 1407 { 1408 1408 //elem_print(e); 1409 1409 //printf("test1: regcon.mvar x%x tosave x%x\n", regcon.mvar, tosave); 1410 1410 cgreg_unregister(regcon.mvar & tosave); 1411 1411 } 1412 1412 1413 1413 /* which registers can we use to save other registers in? */ 1414 1414 if (config.flags4 & CFG4space || // if optimize for space 1415 1415 config.target_cpu >= TARGET_80486) // PUSH/POP ops are 1 cycle 1416 1416 touse = 0; // PUSH/POP pairs are always shorter 1417 1417 else 1418 1418 { touse = mfuncreg & allregs & ~(msavereg | oldregcon | regcon.cse.mval); 1419 1419 /* Don't use registers we'll have to save/restore */ 1420 1420 touse &= ~(fregsaved & oldmfuncreg); 1421 1421 /* Don't use registers that have constant values in them, since 1422 1422 the code generated might have used the value. 1423 1423 */ 1424 1424 touse &= ~oldregimmed; 1425 1425 } 1426 1426 1427 cs1 = cs2 = NULL;1427 cs1 = cs2 = cs3 = NULL; 1428 1428 adjesp = 0; 1429 1429 1430 1430 for (i = 0; tosave; i++) 1431 1431 { regm_t mi = mask[i]; 1432 1432 1433 1433 assert(i < REGMAX); 1434 1434 if (mi & tosave) /* i = register to save */ 1435 1435 { 1436 1436 if (touse) /* if any scratch registers */ 1437 1437 { for (j = 0; j < 8; j++) 1438 1438 { regm_t mj = mask[j]; 1439 1439 1440 1440 if (touse & mj) 1441 1441 { cs1 = genmovreg(cs1,j,i); 1442 1442 cs2 = cat(genmovreg(CNIL,i,j),cs2); 1443 1443 touse &= ~mj; 1444 1444 mfuncreg &= ~mj; 1445 1445 regcon.used |= mj; 1446 1446 break; 1447 1447 } 1448 1448 } 1449 1449 assert(j < 8); 1450 1450 } 1451 1451 else /* else use stack */ 1452 1452 { int push,pop; 1453 1453 1454 1454 stackchanged = 1; 1455 1455 adjesp += REGSIZE; 1456 1456 if (i == ES) 1457 1457 { push = 0x06; 1458 1458 pop = 0x07; 1459 1459 } 1460 1460 else 1461 1461 { push = 0x50 + i; 1462 1462 pop = push | 8; 1463 1463 } 1464 1464 cs1 = gen1(cs1,push); /* PUSH i */ 1465 1465 cs2 = cat(gen1(CNIL,pop),cs2); /* POP i */ 1466 1466 } 1467 cs 2 = cat(getregs(mi),cs2);1467 cs3 = cat(getregs(mi),cs3); 1468 1468 tosave &= ~mi; 1469 1469 } 1470 1470 } 1471 1471 if (adjesp) 1472 1472 { 1473 1473 // If this is done an odd number of times, it 1474 1474 // will throw off the 8 byte stack alignment. 1475 1475 // We should *only* worry about this if a function 1476 1476 // was called in the code generation by codelem(). 1477 1477 int sz; 1478 1478 if (STACKALIGN == 16) 1479 1479 sz = -(adjesp & (STACKALIGN - 1)) & (STACKALIGN - 1); 1480 1480 else 1481 1481 sz = -(adjesp & 7) & 7; 1482 1482 if (calledafunc && I32 && sz && (STACKALIGN == 16 || config.flags4 & CFG4stackalign)) 1483 1483 { code *cx; 1484 1484 1485 1485 regm_t mval_save = regcon.immed.mval; 1486 1486 regcon.immed.mval = 0; // prevent reghasvalue() optimizations 1487 1487 // because c hasn't been executed yet … … 1489 1489 regcon.immed.mval = mval_save; 1490 1490 cs1 = genadjesp(cs1, sz); 1491 1491 1492 1492 cx = genc2(CNIL,0x81,modregrm(3,0,SP),sz); // ADD ESP,sz 1493 1493 cx = genadjesp(cx, -sz); 1494 1494 cs2 = cat(cx, cs2); 1495 1495 } 1496 1496 1497 1497 cs1 = genadjesp(cs1,adjesp); 1498 1498 cs2 = genadjesp(cs2,-adjesp); 1499 1499 } 1500 1500 1501 1501 calledafunc |= calledafuncsave; 1502 1502 msavereg &= ~keepmsk | overlap; /* remove from mask of regs to save */ 1503 1503 mfuncreg &= oldmfuncreg; /* update original */ 1504 1504 #ifdef DEBUG 1505 1505 if (debugw) 1506 1506 printf("-scodelem(e=%p *pretregs=x%x keepmsk=x%x constflag=%d\n", 1507 1507 e,*pretregs,keepmsk,constflag); 1508 1508 #endif 1509 return cat 3(cs1,c,cs2);1509 return cat4(cs1,c,cs3,cs2); 1510 1510 } 1511 1511 1512 1512 1513 1513 /***************************** 1514 1514 * Given an opcode and EA in cs, generate code 1515 1515 * for each floating register in turn. 1516 1516 * Input: 1517 1517 * tym either TYdouble or TYfloat 1518 1518 */ 1519 1519 1520 1520 code *fltregs(code __ss *pcs,tym_t tym) 1521 1521 { code *c; 1522 1522 1523 1523 tym = tybasic(tym); 1524 1524 if (I32) 1525 1525 { 1526 1526 c = getregs((tym == TYfloat) ? mAX : mAX | mDX); 1527 1527 if (tym != TYfloat) 1528 1528 { 1529 1529 pcs->IEVoffset1 += REGSIZE; branches/dmd-1.x/src/msc.c
r189 r308 26 26 static char __file__[] = __FILE__; /* for tassert.h */ 27 27 #include "tassert.h" 28 28 29 29 extern Global global; 30 30 31 31 Config config; 32 32 Configv configv; 33 33 34 34 struct Environment; 35 35 36 36 /************************************** 37 37 * Initialize config variables. 38 38 */ 39 39 40 40 void out_config_init() 41 41 { 42 42 Param *params = &global.params; 43 43 44 44 if (!config.target_cpu) 45 45 { config.target_cpu = TARGET_PentiumPro; 46 config.target_scheduler = config.target_cpu;46 config.target_scheduler = 0; //config.target_cpu; 47 47 } 48 48 config.fulltypes = CVNONE; 49 49 config.inline8087 = 1; 50 50 config.memmodel = 0; 51 51 config.flags |= CFGuchar; // make sure TYchar is unsigned 52 52 #if TARGET_WINDOS 53 53 if (params->isX86_64) 54 54 config.exe = EX_WIN64; 55 55 else 56 56 config.exe = EX_NT; 57 57 58 58 // Win32 eh 59 59 config.flags2 |= CFG2seh; 60 60 61 61 if (params->run) 62 62 config.wflags |= WFexe; // EXE file only optimizations 63 63 else if (params->link && !global.params.deffile) 64 64 config.wflags |= WFexe; // EXE file only optimizations 65 65 else if (params->exefile) // if writing out EXE file 66 66 { size_t len = strlen(params->exefile); trunk/src/backend/cod1.c
r272 r308 1306 1306 default: 1307 1307 #ifdef DEBUG 1308 1308 WRFL((enum FL)fl); 1309 1309 symbol_print(s); 1310 1310 #endif 1311 1311 assert(0); 1312 1312 } 1313 1313 return c; 1314 1314 } 1315 1315 1316 1316 1317 1317 /******************************* 1318 1318 * Same as codelem(), but do not destroy the registers in keepmsk. 1319 1319 * Use scratch registers as much as possible, then use stack. 1320 1320 * Input: 1321 1321 * constflag TRUE if user of result will not modify the 1322 1322 * registers returned in *pretregs. 1323 1323 */ 1324 1324 1325 1325 code *scodelem(elem *e,regm_t *pretregs,regm_t keepmsk,bool constflag) 1326 { code *c,*cs1,*cs2 ;1326 { code *c,*cs1,*cs2,*cs3; 1327 1327 unsigned i,j; 1328 1328 regm_t oldmfuncreg,oldregcon,oldregimmed,overlap,tosave,touse; 1329 1329 int adjesp; 1330 1330 unsigned stackpushsave; 1331 1331 char calledafuncsave; 1332 1332 1333 1333 #ifdef DEBUG 1334 1334 if (debugw) 1335 1335 printf("+scodelem(e=%p *pretregs=x%x keepmsk=x%x constflag=%d\n", 1336 1336 e,*pretregs,keepmsk,constflag); 1337 1337 #endif 1338 1338 elem_debug(e); 1339 1339 if (constflag) 1340 1340 { regm_t regm; 1341 1341 unsigned reg; 1342 1342 1343 1343 if (isregvar(e,®m,®) && // if e is a register variable 1344 1344 (regm & *pretregs) == regm && // in one of the right regs 1345 1345 e->EV.sp.Voffset == 0 1346 1346 ) … … 1407 1407 { 1408 1408 //elem_print(e); 1409 1409 //printf("test1: regcon.mvar x%x tosave x%x\n", regcon.mvar, tosave); 1410 1410 cgreg_unregister(regcon.mvar & tosave); 1411 1411 } 1412 1412 1413 1413 /* which registers can we use to save other registers in? */ 1414 1414 if (config.flags4 & CFG4space || // if optimize for space 1415 1415 config.target_cpu >= TARGET_80486) // PUSH/POP ops are 1 cycle 1416 1416 touse = 0; // PUSH/POP pairs are always shorter 1417 1417 else 1418 1418 { touse = mfuncreg & allregs & ~(msavereg | oldregcon | regcon.cse.mval); 1419 1419 /* Don't use registers we'll have to save/restore */ 1420 1420 touse &= ~(fregsaved & oldmfuncreg); 1421 1421 /* Don't use registers that have constant values in them, since 1422 1422 the code generated might have used the value. 1423 1423 */ 1424 1424 touse &= ~oldregimmed; 1425 1425 } 1426 1426 1427 cs1 = cs2 = NULL;1427 cs1 = cs2 = cs3 = NULL; 1428 1428 adjesp = 0; 1429 1429 1430 1430 for (i = 0; tosave; i++) 1431 1431 { regm_t mi = mask[i]; 1432 1432 1433 1433 assert(i < REGMAX); 1434 1434 if (mi & tosave) /* i = register to save */ 1435 1435 { 1436 1436 if (touse) /* if any scratch registers */ 1437 1437 { for (j = 0; j < 8; j++) 1438 1438 { regm_t mj = mask[j]; 1439 1439 1440 1440 if (touse & mj) 1441 1441 { cs1 = genmovreg(cs1,j,i); 1442 1442 cs2 = cat(genmovreg(CNIL,i,j),cs2); 1443 1443 touse &= ~mj; 1444 1444 mfuncreg &= ~mj; 1445 1445 regcon.used |= mj; 1446 1446 break; 1447 1447 } 1448 1448 } 1449 1449 assert(j < 8); 1450 1450 } 1451 1451 else /* else use stack */ 1452 1452 { int push,pop; 1453 1453 1454 1454 stackchanged = 1; 1455 1455 adjesp += REGSIZE; 1456 1456 if (i == ES) 1457 1457 { push = 0x06; 1458 1458 pop = 0x07; 1459 1459 } 1460 1460 else 1461 1461 { push = 0x50 + i; 1462 1462 pop = push | 8; 1463 1463 } 1464 1464 cs1 = gen1(cs1,push); /* PUSH i */ 1465 1465 cs2 = cat(gen1(CNIL,pop),cs2); /* POP i */ 1466 1466 } 1467 cs 2 = cat(getregs(mi),cs2);1467 cs3 = cat(getregs(mi),cs3); 1468 1468 tosave &= ~mi; 1469 1469 } 1470 1470 } 1471 1471 if (adjesp) 1472 1472 { 1473 1473 // If this is done an odd number of times, it 1474 1474 // will throw off the 8 byte stack alignment. 1475 1475 // We should *only* worry about this if a function 1476 1476 // was called in the code generation by codelem(). 1477 1477 int sz; 1478 1478 if (STACKALIGN == 16) 1479 1479 sz = -(adjesp & (STACKALIGN - 1)) & (STACKALIGN - 1); 1480 1480 else 1481 1481 sz = -(adjesp & 7) & 7; 1482 1482 if (calledafunc && I32 && sz && (STACKALIGN == 16 || config.flags4 & CFG4stackalign)) 1483 1483 { code *cx; 1484 1484 1485 1485 regm_t mval_save = regcon.immed.mval; 1486 1486 regcon.immed.mval = 0; // prevent reghasvalue() optimizations 1487 1487 // because c hasn't been executed yet … … 1489 1489 regcon.immed.mval = mval_save; 1490 1490 cs1 = genadjesp(cs1, sz); 1491 1491 1492 1492 cx = genc2(CNIL,0x81,modregrm(3,0,SP),sz); // ADD ESP,sz 1493 1493 cx = genadjesp(cx, -sz); 1494 1494 cs2 = cat(cx, cs2); 1495 1495 } 1496 1496 1497 1497 cs1 = genadjesp(cs1,adjesp); 1498 1498 cs2 = genadjesp(cs2,-adjesp); 1499 1499 } 1500 1500 1501 1501 calledafunc |= calledafuncsave; 1502 1502 msavereg &= ~keepmsk | overlap; /* remove from mask of regs to save */ 1503 1503 mfuncreg &= oldmfuncreg; /* update original */ 1504 1504 #ifdef DEBUG 1505 1505 if (debugw) 1506 1506 printf("-scodelem(e=%p *pretregs=x%x keepmsk=x%x constflag=%d\n", 1507 1507 e,*pretregs,keepmsk,constflag); 1508 1508 #endif 1509 return cat 3(cs1,c,cs2);1509 return cat4(cs1,c,cs3,cs2); 1510 1510 } 1511 1511 1512 1512 1513 1513 /***************************** 1514 1514 * Given an opcode and EA in cs, generate code 1515 1515 * for each floating register in turn. 1516 1516 * Input: 1517 1517 * tym either TYdouble or TYfloat 1518 1518 */ 1519 1519 1520 1520 code *fltregs(code __ss *pcs,tym_t tym) 1521 1521 { code *c; 1522 1522 1523 1523 tym = tybasic(tym); 1524 1524 if (I32) 1525 1525 { 1526 1526 c = getregs((tym == TYfloat) ? mAX : mAX | mDX); 1527 1527 if (tym != TYfloat) 1528 1528 { 1529 1529 pcs->IEVoffset1 += REGSIZE;
