Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(278)

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 348373005: Bitcast of 64-bit immediates may need to split the immediate, not a var. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: move and add a comment Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tests_lit/llvm2ice_tests/64bit.pnacl.ll » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 ==>
1622 // t_lo.i32 = b_lo.i32 1638 // t_lo.i32 = b_lo.i32
1639 // FakeDef(s.f64)
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));
1633
1634 Variable *T_Lo = NULL, *T_Hi = NULL; 1648 Variable *T_Lo = NULL, *T_Hi = NULL;
1635 VariableSplit *SpillLo = 1649 VariableSplit *SpillLo =
1636 VariableSplit::create(Func, Spill, VariableSplit::Low); 1650 VariableSplit::create(Func, Spill, VariableSplit::Low);
1637 VariableSplit *SpillHi = 1651 VariableSplit *SpillHi =
1638 VariableSplit::create(Func, Spill, VariableSplit::High); 1652 VariableSplit::create(Func, Spill, VariableSplit::High);
1639 _mov(T_Lo, loOperand(Src0RM)); 1653 _mov(T_Lo, loOperand(Src0));
1654 // Technically, the Spill is defined after the _store happens, but
1655 // SpillLo is considered a "use" of Spill so define Spill before it
1656 // is used.
1657 Context.insert(InstFakeDef::create(Func, Spill));
1640 _store(T_Lo, SpillLo); 1658 _store(T_Lo, SpillLo);
1641 _mov(T_Hi, hiOperand(Src0RM)); 1659 _mov(T_Hi, hiOperand(Src0));
1642 _store(T_Hi, SpillHi); 1660 _store(T_Hi, SpillHi);
1643 _mov(Dest, Spill); 1661 _mov(Dest, Spill);
1644 } break; 1662 } break;
1645 } 1663 }
1646 break; 1664 break;
1647 } 1665 }
1666 }
1648 } 1667 }
1649 1668
1650 void TargetX8632::lowerFcmp(const InstFcmp *Inst) { 1669 void TargetX8632::lowerFcmp(const InstFcmp *Inst) {
1651 Operand *Src0 = Inst->getSrc(0); 1670 Operand *Src0 = Inst->getSrc(0);
1652 Operand *Src1 = Inst->getSrc(1); 1671 Operand *Src1 = Inst->getSrc(1);
1653 Variable *Dest = Inst->getDest(); 1672 Variable *Dest = Inst->getDest();
1654 // Lowering a = fcmp cond, b, c 1673 // Lowering a = fcmp cond, b, c
1655 // ucomiss b, c /* only if C1 != Br_None */ 1674 // ucomiss b, c /* only if C1 != Br_None */
1656 // /* but swap b,c order if SwapOperands==true */ 1675 // /* but swap b,c order if SwapOperands==true */
1657 // mov a, <default> 1676 // mov a, <default>
(...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after
2305 return From; 2324 return From;
2306 } 2325 }
2307 2326
2308 // Provide a trivial wrapper to legalize() for this common usage. 2327 // Provide a trivial wrapper to legalize() for this common usage.
2309 Variable *TargetX8632::legalizeToVar(Operand *From, bool AllowOverlap, 2328 Variable *TargetX8632::legalizeToVar(Operand *From, bool AllowOverlap,
2310 int32_t RegNum) { 2329 int32_t RegNum) {
2311 return llvm::cast<Variable>(legalize(From, Legal_Reg, AllowOverlap, RegNum)); 2330 return llvm::cast<Variable>(legalize(From, Legal_Reg, AllowOverlap, RegNum));
2312 } 2331 }
2313 2332
2314 Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) { 2333 Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) {
2334 // There aren't any 64-bit integer registers for x86-32.
2335 assert(Type != IceType_i64);
2315 Variable *Reg = Func->makeVariable(Type, Context.getNode()); 2336 Variable *Reg = Func->makeVariable(Type, Context.getNode());
2316 if (RegNum == Variable::NoRegister) 2337 if (RegNum == Variable::NoRegister)
2317 Reg->setWeightInfinite(); 2338 Reg->setWeightInfinite();
2318 else 2339 else
2319 Reg->setRegNum(RegNum); 2340 Reg->setRegNum(RegNum);
2320 return Reg; 2341 return Reg;
2321 } 2342 }
2322 2343
2323 void TargetX8632::postLower() { 2344 void TargetX8632::postLower() {
2324 if (Ctx->getOptLevel() != Opt_m1) 2345 if (Ctx->getOptLevel() != Opt_m1)
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2388 // llvm-mc doesn't parse "dword ptr [.L$foo]". 2409 // llvm-mc doesn't parse "dword ptr [.L$foo]".
2389 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]"; 2410 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]";
2390 } 2411 }
2391 2412
2392 template <> void ConstantDouble::emit(GlobalContext *Ctx) const { 2413 template <> void ConstantDouble::emit(GlobalContext *Ctx) const {
2393 Ostream &Str = Ctx->getStrEmit(); 2414 Ostream &Str = Ctx->getStrEmit();
2394 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]"; 2415 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]";
2395 } 2416 }
2396 2417
2397 } // end of namespace Ice 2418 } // end of namespace Ice
OLDNEW
« no previous file with comments | « no previous file | tests_lit/llvm2ice_tests/64bit.pnacl.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698