OLD | NEW |
---|---|
1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// | 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file implements the TargetLoweringX8632 class, which | 10 // This file implements the TargetLoweringX8632 class, which |
(...skipping 1358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1369 _fstp(Dest); | 1369 _fstp(Dest); |
1370 // If Dest ends up being a physical xmm register, the fstp emit | 1370 // If Dest ends up being a physical xmm register, the fstp emit |
1371 // code will route st(0) through a temporary stack slot. | 1371 // code will route st(0) through a temporary stack slot. |
1372 } | 1372 } |
1373 } | 1373 } |
1374 | 1374 |
1375 void TargetX8632::lowerCast(const InstCast *Inst) { | 1375 void TargetX8632::lowerCast(const InstCast *Inst) { |
1376 // a = cast(b) ==> t=cast(b); a=t; (link t->b, link a->t, no overlap) | 1376 // a = cast(b) ==> t=cast(b); a=t; (link t->b, link a->t, no overlap) |
1377 InstCast::OpKind CastKind = Inst->getCastKind(); | 1377 InstCast::OpKind CastKind = Inst->getCastKind(); |
1378 Variable *Dest = Inst->getDest(); | 1378 Variable *Dest = Inst->getDest(); |
1379 // Src0RM is the source operand legalized to physical register or memory, but | |
1380 // not immediate, since the relevant x86 native instructions don't allow an | |
1381 // immediate operand. If the operand is an immediate, we could consider | |
1382 // computing the strength-reduced result at translation time, but we're | |
1383 // unlikely to see something like that in the bitcode that the optimizer | |
1384 // wouldn't have already taken care of. | |
1385 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | |
1386 switch (CastKind) { | 1379 switch (CastKind) { |
1387 default: | 1380 default: |
1388 Func->setError("Cast type not supported"); | 1381 Func->setError("Cast type not supported"); |
1389 return; | 1382 return; |
1390 case InstCast::Sext: | 1383 case InstCast::Sext: { |
1384 // Src0RM is the source operand legalized to physical register or memory, | |
1385 // but not immediate, since the relevant x86 native instructions don't | |
1386 // allow an immediate operand. If the operand is an immediate, we could | |
1387 // consider computing the strength-reduced result at translation time, | |
1388 // but we're unlikely to see something like that in the bitcode that | |
1389 // the optimizer wouldn't have already taken care of. | |
1390 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | |
1391 if (Dest->getType() == IceType_i64) { | 1391 if (Dest->getType() == IceType_i64) { |
1392 // t1=movsx src; t2=t1; t2=sar t2, 31; dst.lo=t1; dst.hi=t2 | 1392 // t1=movsx src; t2=t1; t2=sar t2, 31; dst.lo=t1; dst.hi=t2 |
1393 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 1393 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
1394 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 1394 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
1395 Variable *T_Lo = makeReg(DestLo->getType()); | 1395 Variable *T_Lo = makeReg(DestLo->getType()); |
1396 if (Src0RM->getType() == IceType_i32) | 1396 if (Src0RM->getType() == IceType_i32) |
1397 _mov(T_Lo, Src0RM); | 1397 _mov(T_Lo, Src0RM); |
1398 else | 1398 else |
1399 _movsx(T_Lo, Src0RM); | 1399 _movsx(T_Lo, Src0RM); |
1400 _mov(DestLo, T_Lo); | 1400 _mov(DestLo, T_Lo); |
1401 Variable *T_Hi = NULL; | 1401 Variable *T_Hi = NULL; |
1402 Constant *Shift = Ctx->getConstantInt(IceType_i32, 31); | 1402 Constant *Shift = Ctx->getConstantInt(IceType_i32, 31); |
1403 _mov(T_Hi, T_Lo); | 1403 _mov(T_Hi, T_Lo); |
1404 _sar(T_Hi, Shift); | 1404 _sar(T_Hi, Shift); |
1405 _mov(DestHi, T_Hi); | 1405 _mov(DestHi, T_Hi); |
1406 } else { | 1406 } else { |
1407 // TODO: Sign-extend an i1 via "shl reg, 31; sar reg, 31", and | 1407 // TODO: Sign-extend an i1 via "shl reg, 31; sar reg, 31", and |
1408 // also copy to the high operand of a 64-bit variable. | 1408 // also copy to the high operand of a 64-bit variable. |
1409 // t1 = movsx src; dst = t1 | 1409 // t1 = movsx src; dst = t1 |
1410 Variable *T = makeReg(Dest->getType()); | 1410 Variable *T = makeReg(Dest->getType()); |
1411 _movsx(T, Src0RM); | 1411 _movsx(T, Src0RM); |
1412 _mov(Dest, T); | 1412 _mov(Dest, T); |
1413 } | 1413 } |
1414 break; | 1414 break; |
1415 case InstCast::Zext: | 1415 } |
1416 case InstCast::Zext: { | |
1417 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | |
1416 if (Dest->getType() == IceType_i64) { | 1418 if (Dest->getType() == IceType_i64) { |
1417 // t1=movzx src; dst.lo=t1; dst.hi=0 | 1419 // t1=movzx src; dst.lo=t1; dst.hi=0 |
1418 Constant *Zero = Ctx->getConstantZero(IceType_i32); | 1420 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
1419 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 1421 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
1420 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 1422 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
1421 Variable *Tmp = makeReg(DestLo->getType()); | 1423 Variable *Tmp = makeReg(DestLo->getType()); |
1422 if (Src0RM->getType() == IceType_i32) | 1424 if (Src0RM->getType() == IceType_i32) |
1423 _mov(Tmp, Src0RM); | 1425 _mov(Tmp, Src0RM); |
1424 else | 1426 else |
1425 _movzx(Tmp, Src0RM); | 1427 _movzx(Tmp, Src0RM); |
1426 _mov(DestLo, Tmp); | 1428 _mov(DestLo, Tmp); |
1427 _mov(DestHi, Zero); | 1429 _mov(DestHi, Zero); |
1428 } else if (Src0RM->getType() == IceType_i1) { | 1430 } else if (Src0RM->getType() == IceType_i1) { |
1429 // t = Src0RM; t &= 1; Dest = t | 1431 // t = Src0RM; t &= 1; Dest = t |
1430 Operand *One = Ctx->getConstantInt(IceType_i32, 1); | 1432 Operand *One = Ctx->getConstantInt(IceType_i32, 1); |
1431 Variable *T = makeReg(IceType_i32); | 1433 Variable *T = makeReg(IceType_i32); |
1432 _movzx(T, Src0RM); | 1434 _movzx(T, Src0RM); |
1433 _and(T, One); | 1435 _and(T, One); |
1434 _mov(Dest, T); | 1436 _mov(Dest, T); |
1435 } else { | 1437 } else { |
1436 // t1 = movzx src; dst = t1 | 1438 // t1 = movzx src; dst = t1 |
1437 Variable *T = makeReg(Dest->getType()); | 1439 Variable *T = makeReg(Dest->getType()); |
1438 _movzx(T, Src0RM); | 1440 _movzx(T, Src0RM); |
1439 _mov(Dest, T); | 1441 _mov(Dest, T); |
1440 } | 1442 } |
1441 break; | 1443 break; |
1444 } | |
1442 case InstCast::Trunc: { | 1445 case InstCast::Trunc: { |
1443 if (Src0RM->getType() == IceType_i64) | 1446 Operand *Src0 = Inst->getSrc(0); |
1444 Src0RM = loOperand(Src0RM); | 1447 if (Src0->getType() == IceType_i64) |
1448 Src0 = loOperand(Src0); | |
1449 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); | |
1445 // t1 = trunc Src0RM; Dest = t1 | 1450 // t1 = trunc Src0RM; Dest = t1 |
1446 Variable *T = NULL; | 1451 Variable *T = NULL; |
1447 _mov(T, Src0RM); | 1452 _mov(T, Src0RM); |
1448 _mov(Dest, T); | 1453 _mov(Dest, T); |
1449 break; | 1454 break; |
1450 } | 1455 } |
1451 case InstCast::Fptrunc: | 1456 case InstCast::Fptrunc: |
1452 case InstCast::Fpext: { | 1457 case InstCast::Fpext: { |
1458 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | |
1453 // t1 = cvt Src0RM; Dest = t1 | 1459 // t1 = cvt Src0RM; Dest = t1 |
1454 Variable *T = makeReg(Dest->getType()); | 1460 Variable *T = makeReg(Dest->getType()); |
1455 _cvt(T, Src0RM); | 1461 _cvt(T, Src0RM); |
1456 _mov(Dest, T); | 1462 _mov(Dest, T); |
1457 break; | 1463 break; |
1458 } | 1464 } |
1459 case InstCast::Fptosi: | 1465 case InstCast::Fptosi: |
1460 if (Dest->getType() == IceType_i64) { | 1466 if (Dest->getType() == IceType_i64) { |
1461 // Use a helper for converting floating-point values to 64-bit | 1467 // Use a helper for converting floating-point values to 64-bit |
1462 // integers. SSE2 appears to have no way to convert from xmm | 1468 // integers. SSE2 appears to have no way to convert from xmm |
1463 // registers to something like the edx:eax register pair, and | 1469 // registers to something like the edx:eax register pair, and |
1464 // gcc and clang both want to use x87 instructions complete with | 1470 // gcc and clang both want to use x87 instructions complete with |
1465 // temporary manipulation of the status word. This helper is | 1471 // temporary manipulation of the status word. This helper is |
1466 // not needed for x86-64. | 1472 // not needed for x86-64. |
1467 split64(Dest); | 1473 split64(Dest); |
1468 const SizeT MaxSrcs = 1; | 1474 const SizeT MaxSrcs = 1; |
1469 Type SrcType = Inst->getSrc(0)->getType(); | 1475 Type SrcType = Inst->getSrc(0)->getType(); |
1470 InstCall *Call = makeHelperCall( | 1476 InstCall *Call = makeHelperCall( |
1471 SrcType == IceType_f32 ? "cvtftosi64" : "cvtdtosi64", Dest, MaxSrcs); | 1477 SrcType == IceType_f32 ? "cvtftosi64" : "cvtdtosi64", Dest, MaxSrcs); |
1472 // TODO: Call the correct compiler-rt helper function. | 1478 // TODO: Call the correct compiler-rt helper function. |
1473 Call->addArg(Inst->getSrc(0)); | 1479 Call->addArg(Inst->getSrc(0)); |
1474 lowerCall(Call); | 1480 lowerCall(Call); |
1475 } else { | 1481 } else { |
1482 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | |
1476 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type | 1483 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type |
1477 Variable *T_1 = makeReg(IceType_i32); | 1484 Variable *T_1 = makeReg(IceType_i32); |
1478 Variable *T_2 = makeReg(Dest->getType()); | 1485 Variable *T_2 = makeReg(Dest->getType()); |
1479 _cvt(T_1, Src0RM); | 1486 _cvt(T_1, Src0RM); |
1480 _mov(T_2, T_1); // T_1 and T_2 may have different integer types | 1487 _mov(T_2, T_1); // T_1 and T_2 may have different integer types |
1481 _mov(Dest, T_2); | 1488 _mov(Dest, T_2); |
1482 T_2->setPreferredRegister(T_1, true); | 1489 T_2->setPreferredRegister(T_1, true); |
1483 } | 1490 } |
1484 break; | 1491 break; |
1485 case InstCast::Fptoui: | 1492 case InstCast::Fptoui: |
1486 if (Dest->getType() == IceType_i64 || Dest->getType() == IceType_i32) { | 1493 if (Dest->getType() == IceType_i64 || Dest->getType() == IceType_i32) { |
1487 // Use a helper for both x86-32 and x86-64. | 1494 // Use a helper for both x86-32 and x86-64. |
1488 split64(Dest); | 1495 split64(Dest); |
1489 const SizeT MaxSrcs = 1; | 1496 const SizeT MaxSrcs = 1; |
1490 Type DestType = Dest->getType(); | 1497 Type DestType = Dest->getType(); |
1491 Type SrcType = Src0RM->getType(); | 1498 Type SrcType = Inst->getSrc(0)->getType(); |
1492 IceString DstSubstring = (DestType == IceType_i64 ? "64" : "32"); | 1499 IceString DstSubstring = (DestType == IceType_i64 ? "64" : "32"); |
1493 IceString SrcSubstring = (SrcType == IceType_f32 ? "f" : "d"); | 1500 IceString SrcSubstring = (SrcType == IceType_f32 ? "f" : "d"); |
1494 // Possibilities are cvtftoui32, cvtdtoui32, cvtftoui64, cvtdtoui64 | 1501 // Possibilities are cvtftoui32, cvtdtoui32, cvtftoui64, cvtdtoui64 |
1495 IceString TargetString = "cvt" + SrcSubstring + "toui" + DstSubstring; | 1502 IceString TargetString = "cvt" + SrcSubstring + "toui" + DstSubstring; |
1496 // TODO: Call the correct compiler-rt helper function. | 1503 // TODO: Call the correct compiler-rt helper function. |
1497 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs); | 1504 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs); |
1498 Call->addArg(Inst->getSrc(0)); | 1505 Call->addArg(Inst->getSrc(0)); |
1499 lowerCall(Call); | 1506 lowerCall(Call); |
1500 return; | 1507 return; |
1501 } else { | 1508 } else { |
1509 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | |
1502 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type | 1510 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type |
1503 Variable *T_1 = makeReg(IceType_i32); | 1511 Variable *T_1 = makeReg(IceType_i32); |
1504 Variable *T_2 = makeReg(Dest->getType()); | 1512 Variable *T_2 = makeReg(Dest->getType()); |
1505 _cvt(T_1, Src0RM); | 1513 _cvt(T_1, Src0RM); |
1506 _mov(T_2, T_1); // T_1 and T_2 may have different integer types | 1514 _mov(T_2, T_1); // T_1 and T_2 may have different integer types |
1507 _mov(Dest, T_2); | 1515 _mov(Dest, T_2); |
1508 T_2->setPreferredRegister(T_1, true); | 1516 T_2->setPreferredRegister(T_1, true); |
1509 } | 1517 } |
1510 break; | 1518 break; |
1511 case InstCast::Sitofp: | 1519 case InstCast::Sitofp: |
1512 if (Src0RM->getType() == IceType_i64) { | 1520 if (Inst->getSrc(0)->getType() == IceType_i64) { |
1513 // Use a helper for x86-32. | 1521 // Use a helper for x86-32. |
1514 const SizeT MaxSrcs = 1; | 1522 const SizeT MaxSrcs = 1; |
1515 Type DestType = Dest->getType(); | 1523 Type DestType = Dest->getType(); |
1516 InstCall *Call = makeHelperCall( | 1524 InstCall *Call = makeHelperCall( |
1517 DestType == IceType_f32 ? "cvtsi64tof" : "cvtsi64tod", Dest, MaxSrcs); | 1525 DestType == IceType_f32 ? "cvtsi64tof" : "cvtsi64tod", Dest, MaxSrcs); |
1518 // TODO: Call the correct compiler-rt helper function. | 1526 // TODO: Call the correct compiler-rt helper function. |
1519 Call->addArg(Inst->getSrc(0)); | 1527 Call->addArg(Inst->getSrc(0)); |
1520 lowerCall(Call); | 1528 lowerCall(Call); |
1521 return; | 1529 return; |
1522 } else { | 1530 } else { |
1531 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | |
1523 // Sign-extend the operand. | 1532 // Sign-extend the operand. |
1524 // t1.i32 = movsx Src0RM; t2 = Cvt t1.i32; Dest = t2 | 1533 // t1.i32 = movsx Src0RM; t2 = Cvt t1.i32; Dest = t2 |
1525 Variable *T_1 = makeReg(IceType_i32); | 1534 Variable *T_1 = makeReg(IceType_i32); |
1526 Variable *T_2 = makeReg(Dest->getType()); | 1535 Variable *T_2 = makeReg(Dest->getType()); |
1527 if (Src0RM->getType() == IceType_i32) | 1536 if (Src0RM->getType() == IceType_i32) |
1528 _mov(T_1, Src0RM); | 1537 _mov(T_1, Src0RM); |
1529 else | 1538 else |
1530 _movsx(T_1, Src0RM); | 1539 _movsx(T_1, Src0RM); |
1531 _cvt(T_2, T_1); | 1540 _cvt(T_2, T_1); |
1532 _mov(Dest, T_2); | 1541 _mov(Dest, T_2); |
1533 } | 1542 } |
1534 break; | 1543 break; |
1535 case InstCast::Uitofp: | 1544 case InstCast::Uitofp: { |
1536 if (Src0RM->getType() == IceType_i64 || Src0RM->getType() == IceType_i32) { | 1545 Operand *Src0 = Inst->getSrc(0); |
1546 if (Src0->getType() == IceType_i64 || Src0->getType() == IceType_i32) { | |
1537 // Use a helper for x86-32 and x86-64. Also use a helper for | 1547 // Use a helper for x86-32 and x86-64. Also use a helper for |
1538 // i32 on x86-32. | 1548 // i32 on x86-32. |
1539 const SizeT MaxSrcs = 1; | 1549 const SizeT MaxSrcs = 1; |
1540 Type DestType = Dest->getType(); | 1550 Type DestType = Dest->getType(); |
1541 IceString SrcSubstring = (Src0RM->getType() == IceType_i64 ? "64" : "32"); | 1551 IceString SrcSubstring = (Src0->getType() == IceType_i64 ? "64" : "32"); |
1542 IceString DstSubstring = (DestType == IceType_f32 ? "f" : "d"); | 1552 IceString DstSubstring = (DestType == IceType_f32 ? "f" : "d"); |
1543 // Possibilities are cvtui32tof, cvtui32tod, cvtui64tof, cvtui64tod | 1553 // Possibilities are cvtui32tof, cvtui32tod, cvtui64tof, cvtui64tod |
1544 IceString TargetString = "cvtui" + SrcSubstring + "to" + DstSubstring; | 1554 IceString TargetString = "cvtui" + SrcSubstring + "to" + DstSubstring; |
1545 // TODO: Call the correct compiler-rt helper function. | 1555 // TODO: Call the correct compiler-rt helper function. |
1546 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs); | 1556 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs); |
1547 Call->addArg(Inst->getSrc(0)); | 1557 Call->addArg(Src0); |
1548 lowerCall(Call); | 1558 lowerCall(Call); |
1549 return; | 1559 return; |
1550 } else { | 1560 } else { |
1561 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); | |
1551 // Zero-extend the operand. | 1562 // Zero-extend the operand. |
1552 // t1.i32 = movzx Src0RM; t2 = Cvt t1.i32; Dest = t2 | 1563 // t1.i32 = movzx Src0RM; t2 = Cvt t1.i32; Dest = t2 |
1553 Variable *T_1 = makeReg(IceType_i32); | 1564 Variable *T_1 = makeReg(IceType_i32); |
1554 Variable *T_2 = makeReg(Dest->getType()); | 1565 Variable *T_2 = makeReg(Dest->getType()); |
1555 if (Src0RM->getType() == IceType_i32) | 1566 if (Src0RM->getType() == IceType_i32) |
1556 _mov(T_1, Src0RM); | 1567 _mov(T_1, Src0RM); |
1557 else | 1568 else |
1558 _movzx(T_1, Src0RM); | 1569 _movzx(T_1, Src0RM); |
1559 _cvt(T_2, T_1); | 1570 _cvt(T_2, T_1); |
1560 _mov(Dest, T_2); | 1571 _mov(Dest, T_2); |
1561 } | 1572 } |
1562 break; | 1573 break; |
1563 case InstCast::Bitcast: | 1574 } |
1564 if (Dest->getType() == Src0RM->getType()) { | 1575 case InstCast::Bitcast: { |
1565 InstAssign *Assign = InstAssign::create(Func, Dest, Src0RM); | 1576 Operand *Src0 = Inst->getSrc(0); |
1577 if (Dest->getType() == Src0->getType()) { | |
1578 InstAssign *Assign = InstAssign::create(Func, Dest, Src0); | |
1566 lowerAssign(Assign); | 1579 lowerAssign(Assign); |
1567 return; | 1580 return; |
1568 } | 1581 } |
1569 switch (Dest->getType()) { | 1582 switch (Dest->getType()) { |
1570 default: | 1583 default: |
1571 llvm_unreachable("Unexpected Bitcast dest type"); | 1584 llvm_unreachable("Unexpected Bitcast dest type"); |
1572 case IceType_i32: | 1585 case IceType_i32: |
1573 case IceType_f32: { | 1586 case IceType_f32: { |
1587 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); | |
1574 Type DestType = Dest->getType(); | 1588 Type DestType = Dest->getType(); |
1575 Type SrcType = Src0RM->getType(); | 1589 Type SrcType = Src0RM->getType(); |
1576 assert((DestType == IceType_i32 && SrcType == IceType_f32) || | 1590 assert((DestType == IceType_i32 && SrcType == IceType_f32) || |
1577 (DestType == IceType_f32 && SrcType == IceType_i32)); | 1591 (DestType == IceType_f32 && SrcType == IceType_i32)); |
1578 // a.i32 = bitcast b.f32 ==> | 1592 // a.i32 = bitcast b.f32 ==> |
1579 // t.f32 = b.f32 | 1593 // t.f32 = b.f32 |
1580 // s.f32 = spill t.f32 | 1594 // s.f32 = spill t.f32 |
1581 // a.i32 = s.f32 | 1595 // a.i32 = s.f32 |
1582 Variable *T = NULL; | 1596 Variable *T = NULL; |
1583 // TODO: Should be able to force a spill setup by calling legalize() with | 1597 // TODO: Should be able to force a spill setup by calling legalize() with |
1584 // Legal_Mem and not Legal_Reg or Legal_Imm. | 1598 // Legal_Mem and not Legal_Reg or Legal_Imm. |
1585 Variable *Spill = Func->makeVariable(SrcType, Context.getNode()); | 1599 Variable *Spill = Func->makeVariable(SrcType, Context.getNode()); |
1586 Spill->setWeight(RegWeight::Zero); | 1600 Spill->setWeight(RegWeight::Zero); |
1587 Spill->setPreferredRegister(Dest, true); | 1601 Spill->setPreferredRegister(Dest, true); |
1588 _mov(T, Src0RM); | 1602 _mov(T, Src0RM); |
1589 _mov(Spill, T); | 1603 _mov(Spill, T); |
1590 _mov(Dest, Spill); | 1604 _mov(Dest, Spill); |
1591 } break; | 1605 } break; |
1592 case IceType_i64: { | 1606 case IceType_i64: { |
1607 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); | |
1593 assert(Src0RM->getType() == IceType_f64); | 1608 assert(Src0RM->getType() == IceType_f64); |
1594 // a.i64 = bitcast b.f64 ==> | 1609 // a.i64 = bitcast b.f64 ==> |
1595 // s.f64 = spill b.f64 | 1610 // s.f64 = spill b.f64 |
1596 // t_lo.i32 = lo(s.f64) | 1611 // t_lo.i32 = lo(s.f64) |
1597 // a_lo.i32 = t_lo.i32 | 1612 // a_lo.i32 = t_lo.i32 |
1598 // t_hi.i32 = hi(s.f64) | 1613 // t_hi.i32 = hi(s.f64) |
1599 // a_hi.i32 = t_hi.i32 | 1614 // a_hi.i32 = t_hi.i32 |
1600 Variable *Spill = Func->makeVariable(IceType_f64, Context.getNode()); | 1615 Variable *Spill = Func->makeVariable(IceType_f64, Context.getNode()); |
1601 Spill->setWeight(RegWeight::Zero); | 1616 Spill->setWeight(RegWeight::Zero); |
1602 Spill->setPreferredRegister(llvm::dyn_cast<Variable>(Src0RM), true); | 1617 Spill->setPreferredRegister(llvm::dyn_cast<Variable>(Src0RM), true); |
1603 _mov(Spill, Src0RM); | 1618 _mov(Spill, Src0RM); |
1604 | 1619 |
1605 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 1620 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
1606 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 1621 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
1607 Variable *T_Lo = makeReg(IceType_i32); | 1622 Variable *T_Lo = makeReg(IceType_i32); |
1608 Variable *T_Hi = makeReg(IceType_i32); | 1623 Variable *T_Hi = makeReg(IceType_i32); |
1609 VariableSplit *SpillLo = | 1624 VariableSplit *SpillLo = |
1610 VariableSplit::create(Func, Spill, VariableSplit::Low); | 1625 VariableSplit::create(Func, Spill, VariableSplit::Low); |
1611 VariableSplit *SpillHi = | 1626 VariableSplit *SpillHi = |
1612 VariableSplit::create(Func, Spill, VariableSplit::High); | 1627 VariableSplit::create(Func, Spill, VariableSplit::High); |
1613 | 1628 |
1614 _mov(T_Lo, SpillLo); | 1629 _mov(T_Lo, SpillLo); |
1615 _mov(DestLo, T_Lo); | 1630 _mov(DestLo, T_Lo); |
1616 _mov(T_Hi, SpillHi); | 1631 _mov(T_Hi, SpillHi); |
1617 _mov(DestHi, T_Hi); | 1632 _mov(DestHi, T_Hi); |
1618 } break; | 1633 } break; |
1619 case IceType_f64: { | 1634 case IceType_f64: { |
1620 assert(Src0RM->getType() == IceType_i64); | 1635 Src0 = legalize(Src0); |
1636 assert(Src0->getType() == IceType_i64); | |
1621 // a.f64 = bitcast b.i64 ==> | 1637 // a.f64 = bitcast b.i64 ==> |
1638 // FakeDef(s.f64) | |
Jim Stichnoth
2014/06/23 22:40:58
I realize this comment was changed to match the co
jvoung (off chromium)
2014/06/24 00:13:26
I moved it to right before the _store(). The store
| |
1622 // t_lo.i32 = b_lo.i32 | 1639 // t_lo.i32 = b_lo.i32 |
1623 // lo(s.f64) = t_lo.i32 | 1640 // lo(s.f64) = t_lo.i32 |
1624 // FakeUse(s.f64) | |
1625 // t_hi.i32 = b_hi.i32 | 1641 // t_hi.i32 = b_hi.i32 |
1626 // hi(s.f64) = t_hi.i32 | 1642 // hi(s.f64) = t_hi.i32 |
1627 // a.f64 = s.f64 | 1643 // a.f64 = s.f64 |
1628 Variable *Spill = Func->makeVariable(IceType_f64, Context.getNode()); | 1644 Variable *Spill = Func->makeVariable(IceType_f64, Context.getNode()); |
1629 Spill->setWeight(RegWeight::Zero); | 1645 Spill->setWeight(RegWeight::Zero); |
1630 Spill->setPreferredRegister(Dest, true); | 1646 Spill->setPreferredRegister(Dest, true); |
1631 | 1647 |
1632 Context.insert(InstFakeDef::create(Func, Spill)); | 1648 Context.insert(InstFakeDef::create(Func, Spill)); |
1633 | 1649 |
1634 Variable *T_Lo = NULL, *T_Hi = NULL; | 1650 Variable *T_Lo = NULL, *T_Hi = NULL; |
1635 VariableSplit *SpillLo = | 1651 VariableSplit *SpillLo = |
1636 VariableSplit::create(Func, Spill, VariableSplit::Low); | 1652 VariableSplit::create(Func, Spill, VariableSplit::Low); |
1637 VariableSplit *SpillHi = | 1653 VariableSplit *SpillHi = |
1638 VariableSplit::create(Func, Spill, VariableSplit::High); | 1654 VariableSplit::create(Func, Spill, VariableSplit::High); |
1639 _mov(T_Lo, loOperand(Src0RM)); | 1655 _mov(T_Lo, loOperand(Src0)); |
1640 _store(T_Lo, SpillLo); | 1656 _store(T_Lo, SpillLo); |
1641 _mov(T_Hi, hiOperand(Src0RM)); | 1657 _mov(T_Hi, hiOperand(Src0)); |
1642 _store(T_Hi, SpillHi); | 1658 _store(T_Hi, SpillHi); |
1643 _mov(Dest, Spill); | 1659 _mov(Dest, Spill); |
1644 } break; | 1660 } break; |
1645 } | 1661 } |
1646 break; | 1662 break; |
1647 } | 1663 } |
1664 } | |
1648 } | 1665 } |
1649 | 1666 |
1650 void TargetX8632::lowerFcmp(const InstFcmp *Inst) { | 1667 void TargetX8632::lowerFcmp(const InstFcmp *Inst) { |
1651 Operand *Src0 = Inst->getSrc(0); | 1668 Operand *Src0 = Inst->getSrc(0); |
1652 Operand *Src1 = Inst->getSrc(1); | 1669 Operand *Src1 = Inst->getSrc(1); |
1653 Variable *Dest = Inst->getDest(); | 1670 Variable *Dest = Inst->getDest(); |
1654 // Lowering a = fcmp cond, b, c | 1671 // Lowering a = fcmp cond, b, c |
1655 // ucomiss b, c /* only if C1 != Br_None */ | 1672 // ucomiss b, c /* only if C1 != Br_None */ |
1656 // /* but swap b,c order if SwapOperands==true */ | 1673 // /* but swap b,c order if SwapOperands==true */ |
1657 // mov a, <default> | 1674 // mov a, <default> |
(...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2305 return From; | 2322 return From; |
2306 } | 2323 } |
2307 | 2324 |
2308 // Provide a trivial wrapper to legalize() for this common usage. | 2325 // Provide a trivial wrapper to legalize() for this common usage. |
2309 Variable *TargetX8632::legalizeToVar(Operand *From, bool AllowOverlap, | 2326 Variable *TargetX8632::legalizeToVar(Operand *From, bool AllowOverlap, |
2310 int32_t RegNum) { | 2327 int32_t RegNum) { |
2311 return llvm::cast<Variable>(legalize(From, Legal_Reg, AllowOverlap, RegNum)); | 2328 return llvm::cast<Variable>(legalize(From, Legal_Reg, AllowOverlap, RegNum)); |
2312 } | 2329 } |
2313 | 2330 |
2314 Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) { | 2331 Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) { |
2332 // There aren't any 64-bit integer registers for x86-32. | |
2333 assert(Type != IceType_i64); | |
2315 Variable *Reg = Func->makeVariable(Type, Context.getNode()); | 2334 Variable *Reg = Func->makeVariable(Type, Context.getNode()); |
2316 if (RegNum == Variable::NoRegister) | 2335 if (RegNum == Variable::NoRegister) |
2317 Reg->setWeightInfinite(); | 2336 Reg->setWeightInfinite(); |
2318 else | 2337 else |
2319 Reg->setRegNum(RegNum); | 2338 Reg->setRegNum(RegNum); |
2320 return Reg; | 2339 return Reg; |
2321 } | 2340 } |
2322 | 2341 |
2323 void TargetX8632::postLower() { | 2342 void TargetX8632::postLower() { |
2324 if (Ctx->getOptLevel() != Opt_m1) | 2343 if (Ctx->getOptLevel() != Opt_m1) |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2388 // llvm-mc doesn't parse "dword ptr [.L$foo]". | 2407 // llvm-mc doesn't parse "dword ptr [.L$foo]". |
2389 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]"; | 2408 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]"; |
2390 } | 2409 } |
2391 | 2410 |
2392 template <> void ConstantDouble::emit(GlobalContext *Ctx) const { | 2411 template <> void ConstantDouble::emit(GlobalContext *Ctx) const { |
2393 Ostream &Str = Ctx->getStrEmit(); | 2412 Ostream &Str = Ctx->getStrEmit(); |
2394 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]"; | 2413 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]"; |
2395 } | 2414 } |
2396 | 2415 |
2397 } // end of namespace Ice | 2416 } // end of namespace Ice |
OLD | NEW |