Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// | 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// |
| 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 InstX8632 and OperandX8632 classes, | 10 // This file implements the InstX8632 and OperandX8632 classes, |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 223 assert(Ecx->getRegNum() == RegX8632::Reg_ecx); | 223 assert(Ecx->getRegNum() == RegX8632::Reg_ecx); |
| 224 assert(Ebx->getRegNum() == RegX8632::Reg_ebx); | 224 assert(Ebx->getRegNum() == RegX8632::Reg_ebx); |
| 225 addSource(Addr); | 225 addSource(Addr); |
| 226 addSource(Edx); | 226 addSource(Edx); |
| 227 addSource(Eax); | 227 addSource(Eax); |
| 228 addSource(Ecx); | 228 addSource(Ecx); |
| 229 addSource(Ebx); | 229 addSource(Ebx); |
| 230 } | 230 } |
| 231 | 231 |
| 232 InstX8632Cvt::InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, | 232 InstX8632Cvt::InstX8632Cvt(Cfg *Func, Variable *Dest, Operand *Source, |
| 233 bool Trunc) | 233 CvtVariant Variant) |
| 234 : InstX8632(Func, InstX8632::Cvt, 1, Dest), Trunc(Trunc) { | 234 : InstX8632(Func, InstX8632::Cvt, 1, Dest), Variant(Variant) { |
| 235 addSource(Source); | 235 addSource(Source); |
| 236 } | 236 } |
| 237 | 237 |
| 238 InstX8632Icmp::InstX8632Icmp(Cfg *Func, Operand *Src0, Operand *Src1) | 238 InstX8632Icmp::InstX8632Icmp(Cfg *Func, Operand *Src0, Operand *Src1) |
| 239 : InstX8632(Func, InstX8632::Icmp, 2, NULL) { | 239 : InstX8632(Func, InstX8632::Icmp, 2, NULL) { |
| 240 addSource(Src0); | 240 addSource(Src0); |
| 241 addSource(Src1); | 241 addSource(Src1); |
| 242 } | 242 } |
| 243 | 243 |
| 244 InstX8632Ucomiss::InstX8632Ucomiss(Cfg *Func, Operand *Src0, Operand *Src1) | 244 InstX8632Ucomiss::InstX8632Ucomiss(Cfg *Func, Operand *Src0, Operand *Src1) |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 640 } else if (const Constant *Imm = llvm::dyn_cast<Constant>(Src)) { | 640 } else if (const Constant *Imm = llvm::dyn_cast<Constant>(Src)) { |
| 641 (Asm->*(Emitter.XmmAddr))( | 641 (Asm->*(Emitter.XmmAddr))( |
| 642 Ty, VarReg, x86::Address::ofConstPool(Func->getContext(), Asm, Imm)); | 642 Ty, VarReg, x86::Address::ofConstPool(Func->getContext(), Asm, Imm)); |
| 643 } else { | 643 } else { |
| 644 llvm_unreachable("Unexpected operand type"); | 644 llvm_unreachable("Unexpected operand type"); |
| 645 } | 645 } |
| 646 Ostream &Str = Func->getContext()->getStrEmit(); | 646 Ostream &Str = Func->getContext()->getStrEmit(); |
| 647 emitIASBytes(Str, Asm, StartPosition); | 647 emitIASBytes(Str, Asm, StartPosition); |
| 648 } | 648 } |
| 649 | 649 |
| 650 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t), | |
| 651 SReg_t (*srcEnc)(int32_t)> | |
| 652 void emitIASCastRegOp( | |
| 653 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src, | |
| 654 const x86::AssemblerX86::CastEmitterRegOp<DReg_t, SReg_t> Emitter) { | |
| 655 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | |
| 656 intptr_t StartPosition = Asm->GetPosition(); | |
| 657 assert(Dest->hasReg()); | |
| 658 DReg_t DestReg = destEnc(Dest->getRegNum()); | |
| 659 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { | |
| 660 if (SrcVar->hasReg()) { | |
| 661 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); | |
| 662 (Asm->*(Emitter.RegReg))(DispatchTy, DestReg, SrcReg); | |
| 663 } else { | |
| 664 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | |
| 665 ->stackVarToAsmOperand(SrcVar); | |
| 666 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, SrcStackAddr); | |
| 667 } | |
| 668 } else if (const OperandX8632Mem *Mem = | |
| 669 llvm::dyn_cast<OperandX8632Mem>(Src)) { | |
| 670 x86::Address SrcAddr = Mem->toAsmAddress(Asm); | |
| 671 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, SrcAddr); | |
| 672 } else { | |
| 673 llvm_unreachable("Unexpected operand type"); | |
| 674 } | |
| 675 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 676 emitIASBytes(Str, Asm, StartPosition); | |
| 677 } | |
| 678 | |
| 650 void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest, | 679 void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest, |
| 651 const Operand *Src, | 680 const Operand *Src, |
| 652 const x86::AssemblerX86::XmmEmitterMovOps Emitter) { | 681 const x86::AssemblerX86::XmmEmitterMovOps Emitter) { |
| 653 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 682 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 654 intptr_t StartPosition = Asm->GetPosition(); | 683 intptr_t StartPosition = Asm->GetPosition(); |
| 655 if (Dest->hasReg()) { | 684 if (Dest->hasReg()) { |
| 656 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); | 685 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); |
| 657 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { | 686 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 658 if (SrcVar->hasReg()) { | 687 if (SrcVar->hasReg()) { |
| 659 (Asm->*(Emitter.XmmXmm))(DestReg, | 688 (Asm->*(Emitter.XmmXmm))(DestReg, |
| (...skipping 740 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1400 Str << "lock "; | 1429 Str << "lock "; |
| 1401 } | 1430 } |
| 1402 Str << "cmpxchg8b "; | 1431 Str << "cmpxchg8b "; |
| 1403 dumpSources(Func); | 1432 dumpSources(Func); |
| 1404 } | 1433 } |
| 1405 | 1434 |
| 1406 void InstX8632Cvt::emit(const Cfg *Func) const { | 1435 void InstX8632Cvt::emit(const Cfg *Func) const { |
| 1407 Ostream &Str = Func->getContext()->getStrEmit(); | 1436 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1408 assert(getSrcSize() == 1); | 1437 assert(getSrcSize() == 1); |
| 1409 Str << "\tcvt"; | 1438 Str << "\tcvt"; |
| 1410 if (Trunc) | 1439 if (isTruncating()) |
| 1411 Str << "t"; | 1440 Str << "t"; |
| 1412 Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2" | 1441 Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2" |
| 1413 << TypeX8632Attributes[getDest()->getType()].CvtString << "\t"; | 1442 << TypeX8632Attributes[getDest()->getType()].CvtString << "\t"; |
| 1414 getDest()->emit(Func); | 1443 getDest()->emit(Func); |
| 1415 Str << ", "; | 1444 Str << ", "; |
| 1416 getSrc(0)->emit(Func); | 1445 getSrc(0)->emit(Func); |
| 1417 Str << "\n"; | 1446 Str << "\n"; |
| 1418 } | 1447 } |
| 1419 | 1448 |
| 1449 void InstX8632Cvt::emitIAS(const Cfg *Func) const { | |
| 1450 assert(getSrcSize() == 1); | |
| 1451 const Variable *Dest = getDest(); | |
| 1452 const Operand *Src = getSrc(0); | |
| 1453 Type DestTy = Dest->getType(); | |
| 1454 Type SrcTy = Src->getType(); | |
| 1455 assert(DestTy != SrcTy); | |
| 1456 switch (Variant) { | |
| 1457 case Si2ss: { | |
| 1458 assert(isScalarIntegerType(SrcTy)); | |
| 1459 assert(typeWidthInBytes(SrcTy) <= 4); | |
| 1460 assert(isScalarFloatingType(DestTy)); | |
| 1461 static const x86::AssemblerX86::CastEmitterRegOp< | |
| 1462 RegX8632::XmmRegister, RegX8632::GPRRegister> Emitter = { | |
| 1463 &x86::AssemblerX86::cvtsi2ss, &x86::AssemblerX86::cvtsi2ss}; | |
| 1464 emitIASCastRegOp<RegX8632::XmmRegister, RegX8632::GPRRegister, | |
| 1465 RegX8632::getEncodedXmm, RegX8632::getEncodedGPR>( | |
| 1466 Func, DestTy, Dest, Src, Emitter); | |
| 1467 return; | |
| 1468 } | |
| 1469 case Tss2si: { | |
| 1470 assert(isScalarFloatingType(SrcTy)); | |
| 1471 assert(isScalarIntegerType(DestTy)); | |
| 1472 assert(typeWidthInBytes(DestTy) <= 4); | |
| 1473 static const x86::AssemblerX86::CastEmitterRegOp< | |
| 1474 RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = { | |
| 1475 &x86::AssemblerX86::cvttss2si, &x86::AssemblerX86::cvttss2si}; | |
| 1476 emitIASCastRegOp<RegX8632::GPRRegister, RegX8632::XmmRegister, | |
| 1477 RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>( | |
| 1478 Func, SrcTy, Dest, Src, Emitter); | |
| 1479 return; | |
| 1480 } | |
| 1481 case Float2float: { | |
| 1482 assert(isScalarFloatingType(SrcTy)); | |
| 1483 assert(isScalarFloatingType(DestTy)); | |
|
Jim Stichnoth
2014/10/08 18:45:03
Maybe also assert(SrcTy != DestTy)?
jvoung (off chromium)
2014/10/08 20:20:12
Sounds good -- Moved the check from line 1455 here
| |
| 1484 static const x86::AssemblerX86::XmmEmitterRegOp Emitter = { | |
| 1485 &x86::AssemblerX86::cvtfloat2float, &x86::AssemblerX86::cvtfloat2float}; | |
| 1486 emitIASRegOpTyXMM(Func, SrcTy, Dest, Src, Emitter); | |
| 1487 return; | |
| 1488 } | |
| 1489 case Dq2ps: { | |
| 1490 assert(isVectorIntegerType(SrcTy)); | |
| 1491 assert(isVectorFloatingType(DestTy)); | |
| 1492 static const x86::AssemblerX86::XmmEmitterRegOp Emitter = { | |
| 1493 &x86::AssemblerX86::cvtdq2ps, &x86::AssemblerX86::cvtdq2ps}; | |
| 1494 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, Emitter); | |
| 1495 return; | |
| 1496 } | |
| 1497 case Tps2dq: { | |
| 1498 assert(isVectorFloatingType(SrcTy)); | |
| 1499 assert(isVectorIntegerType(DestTy)); | |
| 1500 static const x86::AssemblerX86::XmmEmitterRegOp Emitter = { | |
| 1501 &x86::AssemblerX86::cvttps2dq, &x86::AssemblerX86::cvttps2dq}; | |
| 1502 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, Emitter); | |
| 1503 return; | |
| 1504 } | |
| 1505 } | |
| 1506 } | |
| 1507 | |
| 1420 void InstX8632Cvt::dump(const Cfg *Func) const { | 1508 void InstX8632Cvt::dump(const Cfg *Func) const { |
| 1421 Ostream &Str = Func->getContext()->getStrDump(); | 1509 Ostream &Str = Func->getContext()->getStrDump(); |
| 1422 dumpDest(Func); | 1510 dumpDest(Func); |
| 1423 Str << " = cvt"; | 1511 Str << " = cvt"; |
| 1424 if (Trunc) | 1512 if (isTruncating()) |
| 1425 Str << "t"; | 1513 Str << "t"; |
| 1426 Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2" | 1514 Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2" |
| 1427 << TypeX8632Attributes[getDest()->getType()].CvtString << " "; | 1515 << TypeX8632Attributes[getDest()->getType()].CvtString << " "; |
| 1428 dumpSources(Func); | 1516 dumpSources(Func); |
| 1429 } | 1517 } |
| 1430 | 1518 |
| 1431 void InstX8632Icmp::emit(const Cfg *Func) const { | 1519 void InstX8632Icmp::emit(const Cfg *Func) const { |
| 1432 Ostream &Str = Func->getContext()->getStrEmit(); | 1520 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1433 assert(getSrcSize() == 2); | 1521 assert(getSrcSize() == 2); |
| 1434 Str << "\tcmp\t"; | 1522 Str << "\tcmp\t"; |
| (...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2378 } | 2466 } |
| 2379 Str << "("; | 2467 Str << "("; |
| 2380 if (Func) | 2468 if (Func) |
| 2381 Var->dump(Func); | 2469 Var->dump(Func); |
| 2382 else | 2470 else |
| 2383 Var->dump(Str); | 2471 Var->dump(Str); |
| 2384 Str << ")"; | 2472 Str << ")"; |
| 2385 } | 2473 } |
| 2386 | 2474 |
| 2387 } // end of namespace Ice | 2475 } // end of namespace Ice |
| OLD | NEW |