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 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 595 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); | 595 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); |
| 596 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); | 596 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); |
| 597 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 597 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
| 598 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); | 598 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); |
| 599 } else { | 599 } else { |
| 600 llvm_unreachable("Unexpected operand type"); | 600 llvm_unreachable("Unexpected operand type"); |
| 601 } | 601 } |
| 602 emitIASBytes(Func, Asm, StartPosition); | 602 emitIASBytes(Func, Asm, StartPosition); |
| 603 } | 603 } |
| 604 | 604 |
| 605 void emitIASGPRShiftDouble(const Cfg *Func, const Variable *Dest, | |
| 606 const Operand *Src1Op, const Operand *Src2Op, | |
| 607 const x86::AssemblerX86::GPREmitterShiftD &Emitter) { | |
| 608 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | |
| 609 intptr_t StartPosition = Asm->GetPosition(); | |
| 610 // Dest can be reg or mem, but we only use the reg variant. | |
| 611 assert(Dest->hasReg()); | |
| 612 RegX8632::GPRRegister DestReg = RegX8632::getEncodedGPR(Dest->getRegNum()); | |
| 613 // Src1 must be reg. | |
| 614 const auto Src1 = llvm::cast<Variable>(Src1Op); | |
| 615 assert(Src1->hasReg()); | |
| 616 RegX8632::GPRRegister SrcReg = RegX8632::getEncodedGPR(Src1->getRegNum()); | |
| 617 Type Ty = Src1->getType(); | |
| 618 // Src2 can be the implicit CL register or an immediate. | |
| 619 if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src2Op)) { | |
| 620 (Asm->*(Emitter.GPRGPRImm))(Ty, DestReg, SrcReg, | |
| 621 x86::Immediate(Imm->getValue())); | |
| 622 } else { | |
| 623 assert(llvm::cast<Variable>(Src2Op)->getRegNum() == RegX8632::Reg_ecx); | |
| 624 (Asm->*(Emitter.GPRGPR))(Ty, DestReg, SrcReg); | |
| 625 } | |
| 626 emitIASBytes(Func, Asm, StartPosition); | |
| 627 } | |
| 628 | |
| 605 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, | 629 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, |
| 606 const Operand *Src, | 630 const Operand *Src, |
| 607 const x86::AssemblerX86::XmmEmitterShiftOp &Emitter) { | 631 const x86::AssemblerX86::XmmEmitterShiftOp &Emitter) { |
| 608 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 632 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 609 intptr_t StartPosition = Asm->GetPosition(); | 633 intptr_t StartPosition = Asm->GetPosition(); |
| 610 assert(Var->hasReg()); | 634 assert(Var->hasReg()); |
| 611 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); | 635 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); |
| 612 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 636 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 613 if (SrcVar->hasReg()) { | 637 if (SrcVar->hasReg()) { |
| 614 RegX8632::XmmRegister SrcReg = | 638 RegX8632::XmmRegister SrcReg = |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 679 } | 703 } |
| 680 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 704 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 681 Mem->emitSegmentOverride(Asm); | 705 Mem->emitSegmentOverride(Asm); |
| 682 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, Mem->toAsmAddress(Asm)); | 706 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, Mem->toAsmAddress(Asm)); |
| 683 } else { | 707 } else { |
| 684 llvm_unreachable("Unexpected operand type"); | 708 llvm_unreachable("Unexpected operand type"); |
| 685 } | 709 } |
| 686 emitIASBytes(Func, Asm, StartPosition); | 710 emitIASBytes(Func, Asm, StartPosition); |
| 687 } | 711 } |
| 688 | 712 |
| 713 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t), | |
| 714 SReg_t (*srcEnc)(int32_t)> | |
| 715 void emitIASThreeOpImmOps( | |
| 716 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src0, | |
| 717 const Operand *Src1, | |
| 718 const x86::AssemblerX86::ThreeOpImmEmitter<DReg_t, SReg_t> Emitter) { | |
| 719 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | |
| 720 intptr_t StartPosition = Asm->GetPosition(); | |
| 721 // This only handles Dest being a register, and Src1 being an immediate. | |
| 722 assert(Dest->hasReg()); | |
| 723 DReg_t DestReg = destEnc(Dest->getRegNum()); | |
| 724 x86::Immediate Imm(llvm::cast<ConstantInteger32>(Src1)->getValue()); | |
| 725 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src0)) { | |
| 726 if (SrcVar->hasReg()) { | |
| 727 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); | |
| 728 (Asm->*(Emitter.RegRegImm))(DispatchTy, DestReg, SrcReg, Imm); | |
| 729 } else { | |
| 730 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | |
| 731 ->stackVarToAsmOperand(SrcVar); | |
| 732 (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, SrcStackAddr, Imm); | |
| 733 } | |
| 734 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src0)) { | |
| 735 Mem->emitSegmentOverride(Asm); | |
| 736 (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, Mem->toAsmAddress(Asm), | |
| 737 Imm); | |
| 738 } else { | |
| 739 llvm_unreachable("Unexpected operand type"); | |
| 740 } | |
| 741 emitIASBytes(Func, Asm, StartPosition); | |
| 742 } | |
| 743 | |
| 689 void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest, | 744 void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest, |
| 690 const Operand *Src, | 745 const Operand *Src, |
| 691 const x86::AssemblerX86::XmmEmitterMovOps Emitter) { | 746 const x86::AssemblerX86::XmmEmitterMovOps Emitter) { |
| 692 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 747 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 693 intptr_t StartPosition = Asm->GetPosition(); | 748 intptr_t StartPosition = Asm->GetPosition(); |
| 694 if (Dest->hasReg()) { | 749 if (Dest->hasReg()) { |
| 695 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); | 750 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); |
| 696 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 751 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
| 697 if (SrcVar->hasReg()) { | 752 if (SrcVar->hasReg()) { |
| 698 (Asm->*(Emitter.XmmXmm))(DestReg, | 753 (Asm->*(Emitter.XmmXmm))(DestReg, |
| (...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1167 // We only use imul as a two-address instruction even though | 1222 // We only use imul as a two-address instruction even though |
| 1168 // there is a 3 operand version when one of the operands is a constant. | 1223 // there is a 3 operand version when one of the operands is a constant. |
| 1169 assert(Var == getSrc(0)); | 1224 assert(Var == getSrc(0)); |
| 1170 const x86::AssemblerX86::GPREmitterRegOp Emitter = { | 1225 const x86::AssemblerX86::GPREmitterRegOp Emitter = { |
| 1171 &x86::AssemblerX86::imul, &x86::AssemblerX86::imul, | 1226 &x86::AssemblerX86::imul, &x86::AssemblerX86::imul, |
| 1172 &x86::AssemblerX86::imul}; | 1227 &x86::AssemblerX86::imul}; |
| 1173 emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter); | 1228 emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter); |
| 1174 } | 1229 } |
| 1175 } | 1230 } |
| 1176 | 1231 |
| 1232 template <> void InstX8632Insertps::emitIAS(const Cfg *Func) const { | |
| 1233 assert(getSrcSize() == 3); | |
| 1234 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | |
| 1235 TargetX8632::SSE4_1); | |
| 1236 const Variable *Dest = getDest(); | |
| 1237 assert(Dest == getSrc(0)); | |
| 1238 Type Ty = Dest->getType(); | |
| 1239 static const x86::AssemblerX86::ThreeOpImmEmitter< | |
| 1240 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { | |
| 1241 &x86::AssemblerX86::insertps, &x86::AssemblerX86::insertps}; | |
| 1242 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, | |
| 1243 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( | |
| 1244 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); | |
| 1245 } | |
| 1246 | |
| 1177 template <> void InstX8632Cbwdq::emit(const Cfg *Func) const { | 1247 template <> void InstX8632Cbwdq::emit(const Cfg *Func) const { |
| 1178 Ostream &Str = Func->getContext()->getStrEmit(); | 1248 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1179 assert(getSrcSize() == 1); | 1249 assert(getSrcSize() == 1); |
| 1180 Operand *Src0 = getSrc(0); | 1250 Operand *Src0 = getSrc(0); |
| 1181 assert(llvm::isa<Variable>(Src0)); | 1251 assert(llvm::isa<Variable>(Src0)); |
| 1182 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); | 1252 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); |
| 1183 switch (Src0->getType()) { | 1253 switch (Src0->getType()) { |
| 1184 default: | 1254 default: |
| 1185 llvm_unreachable("unexpected source type!"); | 1255 llvm_unreachable("unexpected source type!"); |
| 1186 break; | 1256 break; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1268 if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { | 1338 if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { |
| 1269 (void)ShiftReg; | 1339 (void)ShiftReg; |
| 1270 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); | 1340 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); |
| 1271 Str << "cl"; | 1341 Str << "cl"; |
| 1272 } else { | 1342 } else { |
| 1273 getSrc(2)->emit(Func); | 1343 getSrc(2)->emit(Func); |
| 1274 } | 1344 } |
| 1275 Str << "\n"; | 1345 Str << "\n"; |
| 1276 } | 1346 } |
| 1277 | 1347 |
| 1348 void InstX8632Shld::emitIAS(const Cfg *Func) const { | |
| 1349 assert(getSrcSize() == 3); | |
| 1350 assert(getDest() == getSrc(0)); | |
| 1351 const Variable *Dest = getDest(); | |
| 1352 const Operand *Src1 = getSrc(1); | |
| 1353 const Operand *Src2 = getSrc(2); | |
| 1354 static const x86::AssemblerX86::GPREmitterShiftD Emitter = { | |
| 1355 &x86::AssemblerX86::shld, &x86::AssemblerX86::shld}; | |
| 1356 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); | |
| 1357 } | |
| 1358 | |
| 1278 void InstX8632Shld::dump(const Cfg *Func) const { | 1359 void InstX8632Shld::dump(const Cfg *Func) const { |
| 1279 Ostream &Str = Func->getContext()->getStrDump(); | 1360 Ostream &Str = Func->getContext()->getStrDump(); |
| 1280 dumpDest(Func); | 1361 dumpDest(Func); |
| 1281 Str << " = shld." << getDest()->getType() << " "; | 1362 Str << " = shld." << getDest()->getType() << " "; |
| 1282 dumpSources(Func); | 1363 dumpSources(Func); |
| 1283 } | 1364 } |
| 1284 | 1365 |
| 1285 void InstX8632Shrd::emit(const Cfg *Func) const { | 1366 void InstX8632Shrd::emit(const Cfg *Func) const { |
| 1286 Ostream &Str = Func->getContext()->getStrEmit(); | 1367 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1287 assert(getSrcSize() == 3); | 1368 assert(getSrcSize() == 3); |
| 1288 assert(getDest() == getSrc(0)); | 1369 assert(getDest() == getSrc(0)); |
| 1289 Str << "\tshrd\t"; | 1370 Str << "\tshrd\t"; |
| 1290 getDest()->emit(Func); | 1371 getDest()->emit(Func); |
| 1291 Str << ", "; | 1372 Str << ", "; |
| 1292 getSrc(1)->emit(Func); | 1373 getSrc(1)->emit(Func); |
| 1293 Str << ", "; | 1374 Str << ", "; |
| 1294 if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { | 1375 if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { |
| 1295 (void)ShiftReg; | 1376 (void)ShiftReg; |
| 1296 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); | 1377 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); |
| 1297 Str << "cl"; | 1378 Str << "cl"; |
| 1298 } else { | 1379 } else { |
| 1299 getSrc(2)->emit(Func); | 1380 getSrc(2)->emit(Func); |
| 1300 } | 1381 } |
| 1301 Str << "\n"; | 1382 Str << "\n"; |
| 1302 } | 1383 } |
| 1303 | 1384 |
| 1385 void InstX8632Shrd::emitIAS(const Cfg *Func) const { | |
| 1386 assert(getSrcSize() == 3); | |
| 1387 assert(getDest() == getSrc(0)); | |
| 1388 const Variable *Dest = getDest(); | |
| 1389 const Operand *Src1 = getSrc(1); | |
| 1390 const Operand *Src2 = getSrc(2); | |
| 1391 static const x86::AssemblerX86::GPREmitterShiftD Emitter = { | |
| 1392 &x86::AssemblerX86::shrd, &x86::AssemblerX86::shrd}; | |
| 1393 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); | |
| 1394 } | |
| 1395 | |
| 1304 void InstX8632Shrd::dump(const Cfg *Func) const { | 1396 void InstX8632Shrd::dump(const Cfg *Func) const { |
| 1305 Ostream &Str = Func->getContext()->getStrDump(); | 1397 Ostream &Str = Func->getContext()->getStrDump(); |
| 1306 dumpDest(Func); | 1398 dumpDest(Func); |
| 1307 Str << " = shrd." << getDest()->getType() << " "; | 1399 Str << " = shrd." << getDest()->getType() << " "; |
| 1308 dumpSources(Func); | 1400 dumpSources(Func); |
| 1309 } | 1401 } |
| 1310 | 1402 |
| 1311 void InstX8632Cmov::emit(const Cfg *Func) const { | 1403 void InstX8632Cmov::emit(const Cfg *Func) const { |
| 1312 Ostream &Str = Func->getContext()->getStrEmit(); | 1404 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1313 Str << "\t"; | 1405 Str << "\t"; |
| (...skipping 919 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2233 Ostream &Str = Func->getContext()->getStrEmit(); | 2325 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2234 assert(getSrcSize() == 2); | 2326 assert(getSrcSize() == 2); |
| 2235 // pextrb and pextrd are SSE4.1 instructions. | 2327 // pextrb and pextrd are SSE4.1 instructions. |
| 2236 assert(getSrc(0)->getType() == IceType_v8i16 || | 2328 assert(getSrc(0)->getType() == IceType_v8i16 || |
| 2237 getSrc(0)->getType() == IceType_v8i1 || | 2329 getSrc(0)->getType() == IceType_v8i1 || |
| 2238 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() | 2330 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() |
| 2239 >= TargetX8632::SSE4_1); | 2331 >= TargetX8632::SSE4_1); |
| 2240 Str << "\t" << Opcode | 2332 Str << "\t" << Opcode |
| 2241 << TypeX8632Attributes[getSrc(0)->getType()].PackString << "\t"; | 2333 << TypeX8632Attributes[getSrc(0)->getType()].PackString << "\t"; |
| 2242 Variable *Dest = getDest(); | 2334 Variable *Dest = getDest(); |
| 2243 // pextrw must take a register dest. | 2335 // pextrw must take a register dest. There is an SSE4.1 version that takes |
| 2244 assert(Dest->getType() != IceType_i16 || Dest->hasReg()); | 2336 // a memory dest, but we aren't using it. For uniformity, just restrict |
| 2337 // them all to have a register dest for now. | |
|
Jim Stichnoth
2014/10/15 02:09:27
Just wondering if you've thought about what happen
jvoung (off chromium)
2014/10/15 16:23:43
I think we would have to impose some legalizations
Jim Stichnoth
2014/10/15 16:45:59
After writing my comment, I convinced myself that
| |
| 2338 assert(Dest->hasReg()); | |
| 2245 Dest->asType(IceType_i32).emit(Func); | 2339 Dest->asType(IceType_i32).emit(Func); |
| 2246 Str << ", "; | 2340 Str << ", "; |
| 2247 getSrc(0)->emit(Func); | 2341 getSrc(0)->emit(Func); |
| 2248 Str << ", "; | 2342 Str << ", "; |
| 2249 getSrc(1)->emit(Func); | 2343 getSrc(1)->emit(Func); |
| 2250 Str << "\n"; | 2344 Str << "\n"; |
| 2251 } | 2345 } |
| 2252 | 2346 |
| 2347 template <> void InstX8632Pextr::emitIAS(const Cfg *Func) const { | |
| 2348 assert(getSrcSize() == 2); | |
| 2349 // pextrb and pextrd are SSE4.1 instructions. | |
| 2350 const Variable *Dest = getDest(); | |
| 2351 Type DispatchTy = Dest->getType(); | |
| 2352 assert(DispatchTy == IceType_i16 || | |
| 2353 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | |
| 2354 TargetX8632::SSE4_1); | |
| 2355 // pextrw must take a register dest. There is an SSE4.1 version that takes | |
| 2356 // a memory dest, but we aren't using it. For uniformity, just restrict | |
| 2357 // them all to have a register dest for now. | |
| 2358 assert(Dest->hasReg()); | |
| 2359 // pextrw's Src(0) must be a register (both SSE4.1 and SSE2). | |
| 2360 assert(llvm::cast<Variable>(getSrc(0))->hasReg()); | |
| 2361 static const x86::AssemblerX86::ThreeOpImmEmitter< | |
| 2362 RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = { | |
| 2363 &x86::AssemblerX86::pextr, NULL}; | |
| 2364 emitIASThreeOpImmOps<RegX8632::GPRRegister, RegX8632::XmmRegister, | |
| 2365 RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>( | |
| 2366 Func, DispatchTy, Dest, getSrc(0), getSrc(1), Emitter); | |
| 2367 } | |
| 2368 | |
| 2253 template <> void InstX8632Pinsr::emit(const Cfg *Func) const { | 2369 template <> void InstX8632Pinsr::emit(const Cfg *Func) const { |
| 2254 Ostream &Str = Func->getContext()->getStrEmit(); | 2370 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2255 assert(getSrcSize() == 3); | 2371 assert(getSrcSize() == 3); |
| 2256 // pinsrb and pinsrd are SSE4.1 instructions. | 2372 // pinsrb and pinsrd are SSE4.1 instructions. |
| 2257 assert(getDest()->getType() == IceType_v8i16 || | 2373 assert(getDest()->getType() == IceType_v8i16 || |
| 2258 getDest()->getType() == IceType_v8i1 || | 2374 getDest()->getType() == IceType_v8i1 || |
| 2259 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() | 2375 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() |
| 2260 >= TargetX8632::SSE4_1); | 2376 >= TargetX8632::SSE4_1); |
| 2261 Str << "\t" << Opcode | 2377 Str << "\t" << Opcode |
| 2262 << TypeX8632Attributes[getDest()->getType()].PackString << "\t"; | 2378 << TypeX8632Attributes[getDest()->getType()].PackString << "\t"; |
| 2263 getDest()->emit(Func); | 2379 getDest()->emit(Func); |
| 2264 Str << ", "; | 2380 Str << ", "; |
| 2265 Operand *Src1 = getSrc(1); | 2381 Operand *Src1 = getSrc(1); |
| 2266 if (Variable *VSrc1 = llvm::dyn_cast<Variable>(Src1)) { | 2382 if (Variable *VSrc1 = llvm::dyn_cast<Variable>(Src1)) { |
| 2267 // If src1 is a register, it should always be r32. | 2383 // If src1 is a register, it should always be r32. |
| 2268 if (VSrc1->hasReg()) { | 2384 if (VSrc1->hasReg()) { |
| 2269 VSrc1->asType(IceType_i32).emit(Func); | 2385 VSrc1->asType(IceType_i32).emit(Func); |
| 2270 } else { | 2386 } else { |
| 2271 VSrc1->emit(Func); | 2387 VSrc1->emit(Func); |
| 2272 } | 2388 } |
| 2273 } else { | 2389 } else { |
| 2274 Src1->emit(Func); | 2390 Src1->emit(Func); |
| 2275 } | 2391 } |
| 2276 Str << ", "; | 2392 Str << ", "; |
| 2277 getSrc(2)->emit(Func); | 2393 getSrc(2)->emit(Func); |
| 2278 Str << "\n"; | 2394 Str << "\n"; |
| 2279 } | 2395 } |
| 2280 | 2396 |
| 2397 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const { | |
| 2398 assert(getSrcSize() == 3); | |
| 2399 assert(getDest() == getSrc(0)); | |
| 2400 // pinsrb and pinsrd are SSE4.1 instructions. | |
| 2401 const Operand *Src0 = getSrc(1); | |
| 2402 Type DispatchTy = Src0->getType(); | |
| 2403 assert(DispatchTy == IceType_i16 || | |
| 2404 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | |
| 2405 TargetX8632::SSE4_1); | |
| 2406 // If src1 is a register, it should always be r32 (this should fall out | |
| 2407 // from the encodings for ByteRegs overlapping the encodings for r32), | |
| 2408 // but we have to trust the regalloc to not choose "ah", where it | |
| 2409 // doesn't overlap. | |
| 2410 static const x86::AssemblerX86::ThreeOpImmEmitter< | |
| 2411 RegX8632::XmmRegister, RegX8632::GPRRegister> Emitter = { | |
| 2412 &x86::AssemblerX86::pinsr, &x86::AssemblerX86::pinsr}; | |
| 2413 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::GPRRegister, | |
| 2414 RegX8632::getEncodedXmm, RegX8632::getEncodedGPR>( | |
| 2415 Func, DispatchTy, getDest(), Src0, getSrc(2), Emitter); | |
| 2416 } | |
| 2417 | |
| 2418 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const { | |
| 2419 assert(getSrcSize() == 2); | |
| 2420 const Variable *Dest = getDest(); | |
| 2421 Type Ty = Dest->getType(); | |
| 2422 static const x86::AssemblerX86::ThreeOpImmEmitter< | |
| 2423 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { | |
| 2424 &x86::AssemblerX86::pshufd, &x86::AssemblerX86::pshufd}; | |
| 2425 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, | |
| 2426 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( | |
| 2427 Func, Ty, Dest, getSrc(0), getSrc(1), Emitter); | |
| 2428 } | |
| 2429 | |
| 2430 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const { | |
| 2431 assert(getSrcSize() == 3); | |
| 2432 const Variable *Dest = getDest(); | |
| 2433 assert(Dest == getSrc(0)); | |
| 2434 Type Ty = Dest->getType(); | |
| 2435 static const x86::AssemblerX86::ThreeOpImmEmitter< | |
| 2436 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { | |
| 2437 &x86::AssemblerX86::shufps, &x86::AssemblerX86::shufps}; | |
| 2438 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, | |
| 2439 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( | |
| 2440 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); | |
| 2441 } | |
| 2442 | |
| 2281 void InstX8632Pop::emit(const Cfg *Func) const { | 2443 void InstX8632Pop::emit(const Cfg *Func) const { |
| 2282 Ostream &Str = Func->getContext()->getStrEmit(); | 2444 Ostream &Str = Func->getContext()->getStrEmit(); |
| 2283 assert(getSrcSize() == 0); | 2445 assert(getSrcSize() == 0); |
| 2284 Str << "\tpop\t"; | 2446 Str << "\tpop\t"; |
| 2285 getDest()->emit(Func); | 2447 getDest()->emit(Func); |
| 2286 Str << "\n"; | 2448 Str << "\n"; |
| 2287 } | 2449 } |
| 2288 | 2450 |
| 2289 void InstX8632Pop::emitIAS(const Cfg *Func) const { | 2451 void InstX8632Pop::emitIAS(const Cfg *Func) const { |
| 2290 assert(getSrcSize() == 0); | 2452 assert(getSrcSize() == 0); |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2646 } | 2808 } |
| 2647 Str << "("; | 2809 Str << "("; |
| 2648 if (Func) | 2810 if (Func) |
| 2649 Var->dump(Func); | 2811 Var->dump(Func); |
| 2650 else | 2812 else |
| 2651 Var->dump(Str); | 2813 Var->dump(Str); |
| 2652 Str << ")"; | 2814 Str << ")"; |
| 2653 } | 2815 } |
| 2654 | 2816 |
| 2655 } // end of namespace Ice | 2817 } // end of namespace Ice |
| OLD | NEW |