Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(97)

Side by Side Diff: src/IceInstX8632.cpp

Issue 656983002: emitIAS for Shld and Shrd and the ternary and three-address ops. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: stuff Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceInstX8632.h ('k') | src/assembler_ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/IceInstX8632.h ('k') | src/assembler_ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698