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 |