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 switch (Variant) { |
| 1456 case Si2ss: { |
| 1457 assert(isScalarIntegerType(SrcTy)); |
| 1458 assert(typeWidthInBytes(SrcTy) <= 4); |
| 1459 assert(isScalarFloatingType(DestTy)); |
| 1460 static const x86::AssemblerX86::CastEmitterRegOp< |
| 1461 RegX8632::XmmRegister, RegX8632::GPRRegister> Emitter = { |
| 1462 &x86::AssemblerX86::cvtsi2ss, &x86::AssemblerX86::cvtsi2ss}; |
| 1463 emitIASCastRegOp<RegX8632::XmmRegister, RegX8632::GPRRegister, |
| 1464 RegX8632::getEncodedXmm, RegX8632::getEncodedGPR>( |
| 1465 Func, DestTy, Dest, Src, Emitter); |
| 1466 return; |
| 1467 } |
| 1468 case Tss2si: { |
| 1469 assert(isScalarFloatingType(SrcTy)); |
| 1470 assert(isScalarIntegerType(DestTy)); |
| 1471 assert(typeWidthInBytes(DestTy) <= 4); |
| 1472 static const x86::AssemblerX86::CastEmitterRegOp< |
| 1473 RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = { |
| 1474 &x86::AssemblerX86::cvttss2si, &x86::AssemblerX86::cvttss2si}; |
| 1475 emitIASCastRegOp<RegX8632::GPRRegister, RegX8632::XmmRegister, |
| 1476 RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>( |
| 1477 Func, SrcTy, Dest, Src, Emitter); |
| 1478 return; |
| 1479 } |
| 1480 case Float2float: { |
| 1481 assert(isScalarFloatingType(SrcTy)); |
| 1482 assert(isScalarFloatingType(DestTy)); |
| 1483 assert(DestTy != SrcTy); |
| 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 |