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 |