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

Side by Side Diff: src/IceInstX8632.cpp

Issue 699923002: More consistently use auto for emit*, nullptr in asm code. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: review Created 6 years, 1 month 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 | « no previous file | src/assembler.cpp » ('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 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 // ======================== Dump routines ======================== // 343 // ======================== Dump routines ======================== //
344 344
345 namespace { 345 namespace {
346 346
347 void emitIASBytes(const Cfg *Func, const x86::AssemblerX86 *Asm, 347 void emitIASBytes(const Cfg *Func, const x86::AssemblerX86 *Asm,
348 intptr_t StartPosition) { 348 intptr_t StartPosition) {
349 GlobalContext *Ctx = Func->getContext(); 349 GlobalContext *Ctx = Func->getContext();
350 Ostream &Str = Ctx->getStrEmit(); 350 Ostream &Str = Ctx->getStrEmit();
351 intptr_t EndPosition = Asm->GetPosition(); 351 intptr_t EndPosition = Asm->GetPosition();
352 AssemblerFixup *LastFixup = Asm->GetLatestFixup(StartPosition); 352 AssemblerFixup *LastFixup = Asm->GetLatestFixup(StartPosition);
353 if (LastFixup == NULL) { 353 if (!LastFixup) {
354 // The fixup doesn't apply to this current block. 354 // The fixup doesn't apply to this current block.
355 for (intptr_t i = StartPosition; i < EndPosition; ++i) { 355 for (intptr_t i = StartPosition; i < EndPosition; ++i) {
356 Str << "\t.byte 0x"; 356 Str << "\t.byte 0x";
357 Str.write_hex(Asm->LoadBuffer<uint8_t>(i)); 357 Str.write_hex(Asm->LoadBuffer<uint8_t>(i));
358 Str << "\n"; 358 Str << "\n";
359 } 359 }
360 return; 360 return;
361 } 361 }
362 intptr_t LastFixupLoc = LastFixup->position(); 362 intptr_t LastFixupLoc = LastFixup->position();
363 const intptr_t FixupSize = 4; 363 const intptr_t FixupSize = 4;
(...skipping 11 matching lines...) Expand all
375 else 375 else
376 Str << Ctx->mangleName(Reloc->getName()); 376 Str << Ctx->mangleName(Reloc->getName());
377 if (LastFixup->value()->getOffset()) { 377 if (LastFixup->value()->getOffset()) {
378 Str << " + " << LastFixup->value()->getOffset(); 378 Str << " + " << LastFixup->value()->getOffset();
379 } 379 }
380 Str << "\n"; 380 Str << "\n";
381 LastFixupLoc += FixupSize; 381 LastFixupLoc += FixupSize;
382 assert(LastFixupLoc <= EndPosition); 382 assert(LastFixupLoc <= EndPosition);
383 LastFixup = Asm->GetLatestFixup(LastFixupLoc); 383 LastFixup = Asm->GetLatestFixup(LastFixupLoc);
384 // Assume multi-fixups are adjacent in the instruction encoding. 384 // Assume multi-fixups are adjacent in the instruction encoding.
385 assert(LastFixup == NULL || LastFixup->position() == LastFixupLoc); 385 assert(!LastFixup || LastFixup->position() == LastFixupLoc);
386 } 386 }
387 for (intptr_t i = LastFixupLoc; i < EndPosition; ++i) { 387 for (intptr_t i = LastFixupLoc; i < EndPosition; ++i) {
388 Str << "\t.byte 0x"; 388 Str << "\t.byte 0x";
389 Str.write_hex(Asm->LoadBuffer<uint8_t>(i)); 389 Str.write_hex(Asm->LoadBuffer<uint8_t>(i));
390 Str << "\n"; 390 Str << "\n";
391 } 391 }
392 } 392 }
393 393
394 void emitIASBytesBranch(const Cfg *Func, const x86::AssemblerX86 *Asm, 394 void emitIASBytesBranch(const Cfg *Func, const x86::AssemblerX86 *Asm,
395 intptr_t StartPosition, const x86::Label *Label, 395 intptr_t StartPosition, const x86::Label *Label,
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 if (getTargetFalse()) { 528 if (getTargetFalse()) {
529 Str << ", label %" << getTargetFalse()->getName(); 529 Str << ", label %" << getTargetFalse()->getName();
530 } 530 }
531 } 531 }
532 } 532 }
533 533
534 void InstX8632Call::emit(const Cfg *Func) const { 534 void InstX8632Call::emit(const Cfg *Func) const {
535 Ostream &Str = Func->getContext()->getStrEmit(); 535 Ostream &Str = Func->getContext()->getStrEmit();
536 assert(getSrcSize() == 1); 536 assert(getSrcSize() == 1);
537 Str << "\tcall\t"; 537 Str << "\tcall\t";
538 if (auto CallTarget = llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) { 538 if (const auto CallTarget =
539 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) {
539 // TODO(stichnot): All constant targets should suppress the '$', 540 // TODO(stichnot): All constant targets should suppress the '$',
540 // not just relocatables. 541 // not just relocatables.
541 CallTarget->emitWithoutDollar(Func->getContext()); 542 CallTarget->emitWithoutDollar(Func->getContext());
542 } else { 543 } else {
543 Str << "*"; 544 Str << "*";
544 getCallTarget()->emit(Func); 545 getCallTarget()->emit(Func);
545 } 546 }
546 Func->getTarget()->resetStackAdjustment(); 547 Func->getTarget()->resetStackAdjustment();
547 } 548 }
548 549
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 // Opcode parameter needs to be char* and not IceString because of 609 // Opcode parameter needs to be char* and not IceString because of
609 // template issues. 610 // template issues.
610 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, 611 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func,
611 bool ShiftHack) { 612 bool ShiftHack) {
612 Ostream &Str = Func->getContext()->getStrEmit(); 613 Ostream &Str = Func->getContext()->getStrEmit();
613 assert(Inst->getSrcSize() == 2); 614 assert(Inst->getSrcSize() == 2);
614 Variable *Dest = Inst->getDest(); 615 Variable *Dest = Inst->getDest();
615 assert(Dest == Inst->getSrc(0)); 616 assert(Dest == Inst->getSrc(0));
616 Operand *Src1 = Inst->getSrc(1); 617 Operand *Src1 = Inst->getSrc(1);
617 Str << "\t" << Opcode << InstX8632::getWidthString(Dest->getType()) << "\t"; 618 Str << "\t" << Opcode << InstX8632::getWidthString(Dest->getType()) << "\t";
618 Variable *ShiftReg = llvm::dyn_cast<Variable>(Src1); 619 const auto ShiftReg = llvm::dyn_cast<Variable>(Src1);
619 if (ShiftHack && ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx) 620 if (ShiftHack && ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx)
620 Str << "%cl"; 621 Str << "%cl";
621 else 622 else
622 Src1->emit(Func); 623 Src1->emit(Func);
623 Str << ", "; 624 Str << ", ";
624 Dest->emit(Func); 625 Dest->emit(Func);
625 } 626 }
626 627
627 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op, 628 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op,
628 const x86::AssemblerX86::GPREmitterOneOp &Emitter) { 629 const x86::AssemblerX86::GPREmitterOneOp &Emitter) {
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 } 758 }
758 759
759 void emitIASGPRShiftDouble(const Cfg *Func, const Variable *Dest, 760 void emitIASGPRShiftDouble(const Cfg *Func, const Variable *Dest,
760 const Operand *Src1Op, const Operand *Src2Op, 761 const Operand *Src1Op, const Operand *Src2Op,
761 const x86::AssemblerX86::GPREmitterShiftD &Emitter) { 762 const x86::AssemblerX86::GPREmitterShiftD &Emitter) {
762 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 763 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
763 intptr_t StartPosition = Asm->GetPosition(); 764 intptr_t StartPosition = Asm->GetPosition();
764 // Dest can be reg or mem, but we only use the reg variant. 765 // Dest can be reg or mem, but we only use the reg variant.
765 assert(Dest->hasReg()); 766 assert(Dest->hasReg());
766 RegX8632::GPRRegister DestReg = RegX8632::getEncodedGPR(Dest->getRegNum()); 767 RegX8632::GPRRegister DestReg = RegX8632::getEncodedGPR(Dest->getRegNum());
767 // Src1 must be reg. 768 // SrcVar1 must be reg.
768 const auto Src1 = llvm::cast<Variable>(Src1Op); 769 const auto SrcVar1 = llvm::cast<Variable>(Src1Op);
769 assert(Src1->hasReg()); 770 assert(SrcVar1->hasReg());
770 RegX8632::GPRRegister SrcReg = RegX8632::getEncodedGPR(Src1->getRegNum()); 771 RegX8632::GPRRegister SrcReg = RegX8632::getEncodedGPR(SrcVar1->getRegNum());
771 Type Ty = Src1->getType(); 772 Type Ty = SrcVar1->getType();
772 // Src2 can be the implicit CL register or an immediate. 773 // Src2 can be the implicit CL register or an immediate.
773 if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src2Op)) { 774 if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src2Op)) {
774 (Asm->*(Emitter.GPRGPRImm))(Ty, DestReg, SrcReg, 775 (Asm->*(Emitter.GPRGPRImm))(Ty, DestReg, SrcReg,
775 x86::Immediate(Imm->getValue())); 776 x86::Immediate(Imm->getValue()));
776 } else { 777 } else {
777 assert(llvm::cast<Variable>(Src2Op)->getRegNum() == RegX8632::Reg_ecx); 778 assert(llvm::cast<Variable>(Src2Op)->getRegNum() == RegX8632::Reg_ecx);
778 (Asm->*(Emitter.GPRGPR))(Ty, DestReg, SrcReg); 779 (Asm->*(Emitter.GPRGPR))(Ty, DestReg, SrcReg);
779 } 780 }
780 emitIASBytes(Func, Asm, StartPosition); 781 emitIASBytes(Func, Asm, StartPosition);
781 } 782 }
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 } else if (const auto SrcMem = llvm::dyn_cast<OperandX8632Mem>(Src)) { 915 } else if (const auto SrcMem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
915 assert(SrcMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 916 assert(SrcMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
916 (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm)); 917 (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm));
917 } else { 918 } else {
918 llvm_unreachable("Unexpected operand type"); 919 llvm_unreachable("Unexpected operand type");
919 } 920 }
920 } else { 921 } else {
921 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 922 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
922 ->stackVarToAsmOperand(Dest)); 923 ->stackVarToAsmOperand(Dest));
923 // Src must be a register in this case. 924 // Src must be a register in this case.
924 const Variable *SrcVar = llvm::cast<Variable>(Src); 925 const auto SrcVar = llvm::cast<Variable>(Src);
925 assert(SrcVar->hasReg()); 926 assert(SrcVar->hasReg());
926 (Asm->*(Emitter.AddrXmm))(StackAddr, 927 (Asm->*(Emitter.AddrXmm))(StackAddr,
927 RegX8632::getEncodedXmm(SrcVar->getRegNum())); 928 RegX8632::getEncodedXmm(SrcVar->getRegNum()));
928 } 929 }
929 emitIASBytes(Func, Asm, StartPosition); 930 emitIASBytes(Func, Asm, StartPosition);
930 } 931 }
931 932
932 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) { 933 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) {
933 const Variable *Src = llvm::dyn_cast<const Variable>(Source); 934 const auto SrcVar = llvm::dyn_cast<const Variable>(Source);
934 if (Src == NULL) 935 if (!SrcVar)
935 return false; 936 return false;
936 if (Dest->hasReg() && Dest->getRegNum() == Src->getRegNum()) { 937 if (Dest->hasReg() && Dest->getRegNum() == SrcVar->getRegNum()) {
937 // TODO: On x86-64, instructions like "mov eax, eax" are used to 938 // TODO: On x86-64, instructions like "mov eax, eax" are used to
938 // clear the upper 32 bits of rax. We need to recognize and 939 // clear the upper 32 bits of rax. We need to recognize and
939 // preserve these. 940 // preserve these.
940 return true; 941 return true;
941 } 942 }
942 if (!Dest->hasReg() && !Src->hasReg() && 943 if (!Dest->hasReg() && !SrcVar->hasReg() &&
943 Dest->getStackOffset() == Src->getStackOffset()) 944 Dest->getStackOffset() == SrcVar->getStackOffset())
944 return true; 945 return true;
945 return false; 946 return false;
946 } 947 }
947 948
948 // In-place ops 949 // In-place ops
949 template <> const char *InstX8632Bswap::Opcode = "bswap"; 950 template <> const char *InstX8632Bswap::Opcode = "bswap";
950 template <> const char *InstX8632Neg::Opcode = "neg"; 951 template <> const char *InstX8632Neg::Opcode = "neg";
951 // Unary ops 952 // Unary ops
952 template <> const char *InstX8632Bsf::Opcode = "bsf"; 953 template <> const char *InstX8632Bsf::Opcode = "bsf";
953 template <> const char *InstX8632Bsr::Opcode = "bsr"; 954 template <> const char *InstX8632Bsr::Opcode = "bsr";
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1003 template <> const char *InstX8632Pinsr::Opcode = "pinsr"; 1004 template <> const char *InstX8632Pinsr::Opcode = "pinsr";
1004 template <> const char *InstX8632Blendvps::Opcode = "blendvps"; 1005 template <> const char *InstX8632Blendvps::Opcode = "blendvps";
1005 template <> const char *InstX8632Pblendvb::Opcode = "pblendvb"; 1006 template <> const char *InstX8632Pblendvb::Opcode = "pblendvb";
1006 // Three address ops 1007 // Three address ops
1007 template <> const char *InstX8632Pextr::Opcode = "pextr"; 1008 template <> const char *InstX8632Pextr::Opcode = "pextr";
1008 template <> const char *InstX8632Pshufd::Opcode = "pshufd"; 1009 template <> const char *InstX8632Pshufd::Opcode = "pshufd";
1009 1010
1010 // Inplace GPR ops 1011 // Inplace GPR ops
1011 template <> 1012 template <>
1012 const x86::AssemblerX86::GPREmitterOneOp InstX8632Bswap::Emitter = { 1013 const x86::AssemblerX86::GPREmitterOneOp InstX8632Bswap::Emitter = {
1013 &x86::AssemblerX86::bswap, NULL /* only a reg form exists */}; 1014 &x86::AssemblerX86::bswap, nullptr /* only a reg form exists */};
1014 template <> 1015 template <>
1015 const x86::AssemblerX86::GPREmitterOneOp InstX8632Neg::Emitter = { 1016 const x86::AssemblerX86::GPREmitterOneOp InstX8632Neg::Emitter = {
1016 &x86::AssemblerX86::neg, &x86::AssemblerX86::neg}; 1017 &x86::AssemblerX86::neg, &x86::AssemblerX86::neg};
1017 1018
1018 // Unary GPR ops 1019 // Unary GPR ops
1019 template <> 1020 template <>
1020 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsf::Emitter = { 1021 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsf::Emitter = {
1021 &x86::AssemblerX86::bsf, &x86::AssemblerX86::bsf, NULL}; 1022 &x86::AssemblerX86::bsf, &x86::AssemblerX86::bsf, nullptr};
1022 template <> 1023 template <>
1023 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsr::Emitter = { 1024 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsr::Emitter = {
1024 &x86::AssemblerX86::bsr, &x86::AssemblerX86::bsr, NULL}; 1025 &x86::AssemblerX86::bsr, &x86::AssemblerX86::bsr, nullptr};
1025 template <> 1026 template <>
1026 const x86::AssemblerX86::GPREmitterRegOp InstX8632Lea::Emitter = { 1027 const x86::AssemblerX86::GPREmitterRegOp InstX8632Lea::Emitter = {
1027 /* reg/reg and reg/imm are illegal */ NULL, &x86::AssemblerX86::lea, NULL}; 1028 /* reg/reg and reg/imm are illegal */ nullptr, &x86::AssemblerX86::lea,
1029 nullptr};
1028 template <> 1030 template <>
1029 const x86::AssemblerX86::GPREmitterRegOp InstX8632Movsx::Emitter = { 1031 const x86::AssemblerX86::GPREmitterRegOp InstX8632Movsx::Emitter = {
1030 &x86::AssemblerX86::movsx, &x86::AssemblerX86::movsx, NULL}; 1032 &x86::AssemblerX86::movsx, &x86::AssemblerX86::movsx, nullptr};
1031 template <> 1033 template <>
1032 const x86::AssemblerX86::GPREmitterRegOp InstX8632Movzx::Emitter = { 1034 const x86::AssemblerX86::GPREmitterRegOp InstX8632Movzx::Emitter = {
1033 &x86::AssemblerX86::movzx, &x86::AssemblerX86::movzx, NULL}; 1035 &x86::AssemblerX86::movzx, &x86::AssemblerX86::movzx, nullptr};
1034 1036
1035 // Unary XMM ops 1037 // Unary XMM ops
1036 template <> 1038 template <>
1037 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Sqrtss::Emitter = { 1039 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Sqrtss::Emitter = {
1038 &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss 1040 &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss
1039 }; 1041 };
1040 1042
1041 // Binary GPR ops 1043 // Binary GPR ops
1042 template <> 1044 template <>
1043 const x86::AssemblerX86::GPREmitterRegOp InstX8632Add::Emitter = { 1045 const x86::AssemblerX86::GPREmitterRegOp InstX8632Add::Emitter = {
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
1340 &x86::AssemblerX86::pblendvb, &x86::AssemblerX86::pblendvb}; 1342 &x86::AssemblerX86::pblendvb, &x86::AssemblerX86::pblendvb};
1341 emitIASVariableBlendInst(this, Func, Emitter); 1343 emitIASVariableBlendInst(this, Func, Emitter);
1342 } 1344 }
1343 1345
1344 template <> void InstX8632Imul::emit(const Cfg *Func) const { 1346 template <> void InstX8632Imul::emit(const Cfg *Func) const {
1345 Ostream &Str = Func->getContext()->getStrEmit(); 1347 Ostream &Str = Func->getContext()->getStrEmit();
1346 assert(getSrcSize() == 2); 1348 assert(getSrcSize() == 2);
1347 Variable *Dest = getDest(); 1349 Variable *Dest = getDest();
1348 if (isByteSizedArithType(Dest->getType())) { 1350 if (isByteSizedArithType(Dest->getType())) {
1349 // The 8-bit version of imul only allows the form "imul r/m8". 1351 // The 8-bit version of imul only allows the form "imul r/m8".
1350 Variable *Src0 = llvm::dyn_cast<Variable>(getSrc(0)); 1352 const auto Src0Var = llvm::dyn_cast<Variable>(getSrc(0));
1351 (void)Src0; 1353 (void)Src0Var;
1352 assert(Src0 && Src0->getRegNum() == RegX8632::Reg_eax); 1354 assert(Src0Var && Src0Var->getRegNum() == RegX8632::Reg_eax);
1353 Str << "\timulb\t"; 1355 Str << "\timulb\t";
1354 getSrc(1)->emit(Func); 1356 getSrc(1)->emit(Func);
1355 } else if (llvm::isa<Constant>(getSrc(1))) { 1357 } else if (llvm::isa<Constant>(getSrc(1))) {
1356 Str << "\timul" << getWidthString(Dest->getType()) << "\t"; 1358 Str << "\timul" << getWidthString(Dest->getType()) << "\t";
1357 getSrc(1)->emit(Func); 1359 getSrc(1)->emit(Func);
1358 Str << ", "; 1360 Str << ", ";
1359 getSrc(0)->emit(Func); 1361 getSrc(0)->emit(Func);
1360 Str << ", "; 1362 Str << ", ";
1361 Dest->emit(Func); 1363 Dest->emit(Func);
1362 } else { 1364 } else {
1363 emitTwoAddress("imul", this, Func); 1365 emitTwoAddress("imul", this, Func);
1364 } 1366 }
1365 } 1367 }
1366 1368
1367 template <> void InstX8632Imul::emitIAS(const Cfg *Func) const { 1369 template <> void InstX8632Imul::emitIAS(const Cfg *Func) const {
1368 assert(getSrcSize() == 2); 1370 assert(getSrcSize() == 2);
1369 const Variable *Var = getDest(); 1371 const Variable *Var = getDest();
1370 Type Ty = Var->getType(); 1372 Type Ty = Var->getType();
1371 const Operand *Src = getSrc(1); 1373 const Operand *Src = getSrc(1);
1372 if (isByteSizedArithType(Ty)) { 1374 if (isByteSizedArithType(Ty)) {
1373 // The 8-bit version of imul only allows the form "imul r/m8". 1375 // The 8-bit version of imul only allows the form "imul r/m8".
1374 Variable *Src0 = llvm::dyn_cast<Variable>(getSrc(0)); 1376 const auto Src0Var = llvm::dyn_cast<Variable>(getSrc(0));
1375 (void)Src0; 1377 (void)Src0Var;
1376 assert(Src0 && Src0->getRegNum() == RegX8632::Reg_eax); 1378 assert(Src0Var && Src0Var->getRegNum() == RegX8632::Reg_eax);
1377 const x86::AssemblerX86::GPREmitterOneOp Emitter = { 1379 const x86::AssemblerX86::GPREmitterOneOp Emitter = {
1378 &x86::AssemblerX86::imul, &x86::AssemblerX86::imul}; 1380 &x86::AssemblerX86::imul, &x86::AssemblerX86::imul};
1379 emitIASOpTyGPR(Func, Ty, getSrc(1), Emitter); 1381 emitIASOpTyGPR(Func, Ty, getSrc(1), Emitter);
1380 } else { 1382 } else {
1381 // We only use imul as a two-address instruction even though 1383 // We only use imul as a two-address instruction even though
1382 // there is a 3 operand version when one of the operands is a constant. 1384 // there is a 3 operand version when one of the operands is a constant.
1383 assert(Var == getSrc(0)); 1385 assert(Var == getSrc(0));
1384 const x86::AssemblerX86::GPREmitterRegOp Emitter = { 1386 const x86::AssemblerX86::GPREmitterRegOp Emitter = {
1385 &x86::AssemblerX86::imul, &x86::AssemblerX86::imul, 1387 &x86::AssemblerX86::imul, &x86::AssemblerX86::imul,
1386 &x86::AssemblerX86::imul}; 1388 &x86::AssemblerX86::imul};
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1452 Asm->cdq(); 1454 Asm->cdq();
1453 break; 1455 break;
1454 } 1456 }
1455 emitIASBytes(Func, Asm, StartPosition); 1457 emitIASBytes(Func, Asm, StartPosition);
1456 } 1458 }
1457 1459
1458 void InstX8632Mul::emit(const Cfg *Func) const { 1460 void InstX8632Mul::emit(const Cfg *Func) const {
1459 Ostream &Str = Func->getContext()->getStrEmit(); 1461 Ostream &Str = Func->getContext()->getStrEmit();
1460 assert(getSrcSize() == 2); 1462 assert(getSrcSize() == 2);
1461 assert(llvm::isa<Variable>(getSrc(0))); 1463 assert(llvm::isa<Variable>(getSrc(0)));
1462 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); 1464 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax);
1463 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? 1465 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx?
1464 Str << "\tmul" << getWidthString(getDest()->getType()) << "\t"; 1466 Str << "\tmul" << getWidthString(getDest()->getType()) << "\t";
1465 getSrc(1)->emit(Func); 1467 getSrc(1)->emit(Func);
1466 } 1468 }
1467 1469
1468 void InstX8632Mul::emitIAS(const Cfg *Func) const { 1470 void InstX8632Mul::emitIAS(const Cfg *Func) const {
1469 assert(getSrcSize() == 2); 1471 assert(getSrcSize() == 2);
1470 assert(llvm::isa<Variable>(getSrc(0))); 1472 assert(llvm::isa<Variable>(getSrc(0)));
1471 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); 1473 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax);
1472 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? 1474 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx?
1473 const Operand *Src = getSrc(1); 1475 const Operand *Src = getSrc(1);
1474 Type Ty = Src->getType(); 1476 Type Ty = Src->getType();
1475 const static x86::AssemblerX86::GPREmitterOneOp Emitter = { 1477 const static x86::AssemblerX86::GPREmitterOneOp Emitter = {
1476 &x86::AssemblerX86::mul, &x86::AssemblerX86::mul}; 1478 &x86::AssemblerX86::mul, &x86::AssemblerX86::mul};
1477 emitIASOpTyGPR(Func, Ty, Src, Emitter); 1479 emitIASOpTyGPR(Func, Ty, Src, Emitter);
1478 } 1480 }
1479 1481
1480 void InstX8632Mul::dump(const Cfg *Func) const { 1482 void InstX8632Mul::dump(const Cfg *Func) const {
1481 Ostream &Str = Func->getContext()->getStrDump(); 1483 Ostream &Str = Func->getContext()->getStrDump();
1482 dumpDest(Func); 1484 dumpDest(Func);
1483 Str << " = mul." << getDest()->getType() << " "; 1485 Str << " = mul." << getDest()->getType() << " ";
1484 dumpSources(Func); 1486 dumpSources(Func);
1485 } 1487 }
1486 1488
1487 void InstX8632Shld::emit(const Cfg *Func) const { 1489 void InstX8632Shld::emit(const Cfg *Func) const {
1488 Ostream &Str = Func->getContext()->getStrEmit(); 1490 Ostream &Str = Func->getContext()->getStrEmit();
1489 Variable *Dest = getDest(); 1491 Variable *Dest = getDest();
1490 assert(getSrcSize() == 3); 1492 assert(getSrcSize() == 3);
1491 assert(Dest == getSrc(0)); 1493 assert(Dest == getSrc(0));
1492 Str << "\tshld" << getWidthString(Dest->getType()) << "\t"; 1494 Str << "\tshld" << getWidthString(Dest->getType()) << "\t";
1493 if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { 1495 if (const auto ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) {
1494 (void)ShiftReg; 1496 (void)ShiftReg;
1495 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); 1497 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx);
1496 Str << "%cl"; 1498 Str << "%cl";
1497 } else { 1499 } else {
1498 getSrc(2)->emit(Func); 1500 getSrc(2)->emit(Func);
1499 } 1501 }
1500 Str << ", "; 1502 Str << ", ";
1501 getSrc(1)->emit(Func); 1503 getSrc(1)->emit(Func);
1502 Str << ", "; 1504 Str << ", ";
1503 Dest->emit(Func); 1505 Dest->emit(Func);
(...skipping 16 matching lines...) Expand all
1520 Str << " = shld." << getDest()->getType() << " "; 1522 Str << " = shld." << getDest()->getType() << " ";
1521 dumpSources(Func); 1523 dumpSources(Func);
1522 } 1524 }
1523 1525
1524 void InstX8632Shrd::emit(const Cfg *Func) const { 1526 void InstX8632Shrd::emit(const Cfg *Func) const {
1525 Ostream &Str = Func->getContext()->getStrEmit(); 1527 Ostream &Str = Func->getContext()->getStrEmit();
1526 Variable *Dest = getDest(); 1528 Variable *Dest = getDest();
1527 assert(getSrcSize() == 3); 1529 assert(getSrcSize() == 3);
1528 assert(Dest == getSrc(0)); 1530 assert(Dest == getSrc(0));
1529 Str << "\tshrd" << getWidthString(Dest->getType()) << "\t"; 1531 Str << "\tshrd" << getWidthString(Dest->getType()) << "\t";
1530 if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { 1532 if (const auto ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) {
1531 (void)ShiftReg; 1533 (void)ShiftReg;
1532 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); 1534 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx);
1533 Str << "%cl"; 1535 Str << "%cl";
1534 } else { 1536 } else {
1535 getSrc(2)->emit(Func); 1537 getSrc(2)->emit(Func);
1536 } 1538 }
1537 Str << ", "; 1539 Str << ", ";
1538 getSrc(1)->emit(Func); 1540 getSrc(1)->emit(Func);
1539 Str << ", "; 1541 Str << ", ";
1540 Dest->emit(Func); 1542 Dest->emit(Func);
(...skipping 28 matching lines...) Expand all
1569 getSrc(1)->emit(Func); 1571 getSrc(1)->emit(Func);
1570 Str << ", "; 1572 Str << ", ";
1571 Dest->emit(Func); 1573 Dest->emit(Func);
1572 } 1574 }
1573 1575
1574 void InstX8632Cmov::emitIAS(const Cfg *Func) const { 1576 void InstX8632Cmov::emitIAS(const Cfg *Func) const {
1575 assert(Condition != CondX86::Br_None); 1577 assert(Condition != CondX86::Br_None);
1576 assert(getDest()->hasReg()); 1578 assert(getDest()->hasReg());
1577 assert(getSrcSize() == 2); 1579 assert(getSrcSize() == 2);
1578 // Only need the reg/reg form now. 1580 // Only need the reg/reg form now.
1579 const Variable *Src = llvm::cast<Variable>(getSrc(1)); 1581 const auto SrcVar = llvm::cast<Variable>(getSrc(1));
1580 assert(Src->hasReg()); 1582 assert(SrcVar->hasReg());
1581 assert(Src->getType() == IceType_i32); 1583 assert(SrcVar->getType() == IceType_i32);
1582 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1584 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1583 intptr_t StartPosition = Asm->GetPosition(); 1585 intptr_t StartPosition = Asm->GetPosition();
1584 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()), 1586 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()),
1585 RegX8632::getEncodedGPR(Src->getRegNum())); 1587 RegX8632::getEncodedGPR(SrcVar->getRegNum()));
1586 emitIASBytes(Func, Asm, StartPosition); 1588 emitIASBytes(Func, Asm, StartPosition);
1587 } 1589 }
1588 1590
1589 void InstX8632Cmov::dump(const Cfg *Func) const { 1591 void InstX8632Cmov::dump(const Cfg *Func) const {
1590 Ostream &Str = Func->getContext()->getStrDump(); 1592 Ostream &Str = Func->getContext()->getStrDump();
1591 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; 1593 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << ".";
1592 Str << getDest()->getType() << " "; 1594 Str << getDest()->getType() << " ";
1593 dumpDest(Func); 1595 dumpDest(Func);
1594 Str << ", "; 1596 Str << ", ";
1595 dumpSources(Func); 1597 dumpSources(Func);
(...skipping 12 matching lines...) Expand all
1608 } 1610 }
1609 1611
1610 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { 1612 void InstX8632Cmpps::emitIAS(const Cfg *Func) const {
1611 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1613 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1612 intptr_t StartPosition = Asm->GetPosition(); 1614 intptr_t StartPosition = Asm->GetPosition();
1613 assert(getSrcSize() == 2); 1615 assert(getSrcSize() == 2);
1614 assert(Condition < CondX86::Cmpps_Invalid); 1616 assert(Condition < CondX86::Cmpps_Invalid);
1615 // Assuming there isn't any load folding for cmpps, and vector constants 1617 // Assuming there isn't any load folding for cmpps, and vector constants
1616 // are not allowed in PNaCl. 1618 // are not allowed in PNaCl.
1617 assert(llvm::isa<Variable>(getSrc(1))); 1619 assert(llvm::isa<Variable>(getSrc(1)));
1618 const Variable *SrcVar = llvm::cast<Variable>(getSrc(1)); 1620 const auto SrcVar = llvm::cast<Variable>(getSrc(1));
1619 if (SrcVar->hasReg()) { 1621 if (SrcVar->hasReg()) {
1620 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), 1622 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()),
1621 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); 1623 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition);
1622 } else { 1624 } else {
1623 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) 1625 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget())
1624 ->stackVarToAsmOperand(SrcVar); 1626 ->stackVarToAsmOperand(SrcVar);
1625 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, 1627 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr,
1626 Condition); 1628 Condition);
1627 } 1629 }
1628 emitIASBytes(Func, Asm, StartPosition); 1630 emitIASBytes(Func, Asm, StartPosition);
(...skipping 18 matching lines...) Expand all
1647 getSrc(2)->emit(Func); 1649 getSrc(2)->emit(Func);
1648 Str << ", "; 1650 Str << ", ";
1649 getSrc(0)->emit(Func); 1651 getSrc(0)->emit(Func);
1650 } 1652 }
1651 1653
1652 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { 1654 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const {
1653 assert(getSrcSize() == 3); 1655 assert(getSrcSize() == 3);
1654 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1656 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1655 intptr_t StartPosition = Asm->GetPosition(); 1657 intptr_t StartPosition = Asm->GetPosition();
1656 Type Ty = getSrc(0)->getType(); 1658 Type Ty = getSrc(0)->getType();
1657 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); 1659 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
1658 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 1660 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
1659 const x86::Address Addr = Mem->toAsmAddress(Asm); 1661 const x86::Address Addr = Mem->toAsmAddress(Asm);
1660 const Variable *VarReg = llvm::cast<Variable>(getSrc(2)); 1662 const auto VarReg = llvm::cast<Variable>(getSrc(2));
1661 assert(VarReg->hasReg()); 1663 assert(VarReg->hasReg());
1662 const RegX8632::GPRRegister Reg = 1664 const RegX8632::GPRRegister Reg =
1663 RegX8632::getEncodedGPR(VarReg->getRegNum()); 1665 RegX8632::getEncodedGPR(VarReg->getRegNum());
1664 if (Locked) { 1666 if (Locked) {
1665 Asm->LockCmpxchg(Ty, Addr, Reg); 1667 Asm->LockCmpxchg(Ty, Addr, Reg);
1666 } else { 1668 } else {
1667 Asm->cmpxchg(Ty, Addr, Reg); 1669 Asm->cmpxchg(Ty, Addr, Reg);
1668 } 1670 }
1669 emitIASBytes(Func, Asm, StartPosition); 1671 emitIASBytes(Func, Asm, StartPosition);
1670 } 1672 }
(...skipping 14 matching lines...) Expand all
1685 Str << "\tlock"; 1687 Str << "\tlock";
1686 } 1688 }
1687 Str << "\tcmpxchg8b\t"; 1689 Str << "\tcmpxchg8b\t";
1688 getSrc(0)->emit(Func); 1690 getSrc(0)->emit(Func);
1689 } 1691 }
1690 1692
1691 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { 1693 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const {
1692 assert(getSrcSize() == 5); 1694 assert(getSrcSize() == 5);
1693 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1695 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1694 intptr_t StartPosition = Asm->GetPosition(); 1696 intptr_t StartPosition = Asm->GetPosition();
1695 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); 1697 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
1696 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 1698 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
1697 const x86::Address Addr = Mem->toAsmAddress(Asm); 1699 const x86::Address Addr = Mem->toAsmAddress(Asm);
1698 if (Locked) { 1700 if (Locked) {
1699 Asm->lock(); 1701 Asm->lock();
1700 } 1702 }
1701 Asm->cmpxchg8b(Addr); 1703 Asm->cmpxchg8b(Addr);
1702 emitIASBytes(Func, Asm, StartPosition); 1704 emitIASBytes(Func, Asm, StartPosition);
1703 } 1705 }
1704 1706
1705 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { 1707 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const {
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1837 getSrc(1)->emit(Func); 1839 getSrc(1)->emit(Func);
1838 Str << ", "; 1840 Str << ", ";
1839 getSrc(0)->emit(Func); 1841 getSrc(0)->emit(Func);
1840 } 1842 }
1841 1843
1842 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const { 1844 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const {
1843 assert(getSrcSize() == 2); 1845 assert(getSrcSize() == 2);
1844 // Currently src0 is always a variable by convention, to avoid having 1846 // Currently src0 is always a variable by convention, to avoid having
1845 // two memory operands. 1847 // two memory operands.
1846 assert(llvm::isa<Variable>(getSrc(0))); 1848 assert(llvm::isa<Variable>(getSrc(0)));
1847 const Variable *Src0 = llvm::cast<Variable>(getSrc(0)); 1849 const auto Src0Var = llvm::cast<Variable>(getSrc(0));
1848 Type Ty = Src0->getType(); 1850 Type Ty = Src0Var->getType();
1849 const static x86::AssemblerX86::XmmEmitterRegOp Emitter = { 1851 const static x86::AssemblerX86::XmmEmitterRegOp Emitter = {
1850 &x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss 1852 &x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss
1851 }; 1853 };
1852 emitIASRegOpTyXMM(Func, Ty, Src0, getSrc(1), Emitter); 1854 emitIASRegOpTyXMM(Func, Ty, Src0Var, getSrc(1), Emitter);
1853 } 1855 }
1854 1856
1855 void InstX8632Ucomiss::dump(const Cfg *Func) const { 1857 void InstX8632Ucomiss::dump(const Cfg *Func) const {
1856 Ostream &Str = Func->getContext()->getStrDump(); 1858 Ostream &Str = Func->getContext()->getStrDump();
1857 Str << "ucomiss." << getSrc(0)->getType() << " "; 1859 Str << "ucomiss." << getSrc(0)->getType() << " ";
1858 dumpSources(Func); 1860 dumpSources(Func);
1859 } 1861 }
1860 1862
1861 void InstX8632UD2::emit(const Cfg *Func) const { 1863 void InstX8632UD2::emit(const Cfg *Func) const {
1862 Ostream &Str = Func->getContext()->getStrEmit(); 1864 Ostream &Str = Func->getContext()->getStrEmit();
(...skipping 22 matching lines...) Expand all
1885 getSrc(0)->emit(Func); 1887 getSrc(0)->emit(Func);
1886 } 1888 }
1887 1889
1888 void InstX8632Test::emitIAS(const Cfg *Func) const { 1890 void InstX8632Test::emitIAS(const Cfg *Func) const {
1889 assert(getSrcSize() == 2); 1891 assert(getSrcSize() == 2);
1890 const Operand *Src0 = getSrc(0); 1892 const Operand *Src0 = getSrc(0);
1891 const Operand *Src1 = getSrc(1); 1893 const Operand *Src1 = getSrc(1);
1892 Type Ty = Src0->getType(); 1894 Type Ty = Src0->getType();
1893 // The Reg/Addr form of test is not encodeable. 1895 // The Reg/Addr form of test is not encodeable.
1894 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { 1896 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = {
1895 &x86::AssemblerX86::test, NULL, &x86::AssemblerX86::test 1897 &x86::AssemblerX86::test, nullptr, &x86::AssemblerX86::test};
1896 };
1897 static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = { 1898 static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = {
1898 &x86::AssemblerX86::test, &x86::AssemblerX86::test 1899 &x86::AssemblerX86::test, &x86::AssemblerX86::test
1899 }; 1900 };
1900 if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { 1901 if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) {
1901 if (SrcVar0->hasReg()) { 1902 if (SrcVar0->hasReg()) {
1902 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); 1903 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter);
1903 return; 1904 return;
1904 } 1905 }
1905 } 1906 }
1906 llvm_unreachable("Nothing actually generates this so it's untested"); 1907 llvm_unreachable("Nothing actually generates this so it's untested");
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1942 getSrc(1)->emit(Func); 1943 getSrc(1)->emit(Func);
1943 } 1944 }
1944 1945
1945 void InstX8632Store::emitIAS(const Cfg *Func) const { 1946 void InstX8632Store::emitIAS(const Cfg *Func) const {
1946 assert(getSrcSize() == 2); 1947 assert(getSrcSize() == 2);
1947 const Operand *Dest = getSrc(1); 1948 const Operand *Dest = getSrc(1);
1948 const Operand *Src = getSrc(0); 1949 const Operand *Src = getSrc(0);
1949 Type DestTy = Dest->getType(); 1950 Type DestTy = Dest->getType();
1950 if (isScalarFloatingType(DestTy)) { 1951 if (isScalarFloatingType(DestTy)) {
1951 // Src must be a register, since Dest is a Mem operand of some kind. 1952 // Src must be a register, since Dest is a Mem operand of some kind.
1952 const Variable *SrcVar = llvm::cast<Variable>(Src); 1953 const auto SrcVar = llvm::cast<Variable>(Src);
1953 assert(SrcVar->hasReg()); 1954 assert(SrcVar->hasReg());
1954 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum()); 1955 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum());
1955 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1956 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1956 intptr_t StartPosition = Asm->GetPosition(); 1957 intptr_t StartPosition = Asm->GetPosition();
1957 if (const auto DestVar = llvm::dyn_cast<Variable>(Dest)) { 1958 if (const auto DestVar = llvm::dyn_cast<Variable>(Dest)) {
1958 assert(!DestVar->hasReg()); 1959 assert(!DestVar->hasReg());
1959 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 1960 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
1960 ->stackVarToAsmOperand(DestVar)); 1961 ->stackVarToAsmOperand(DestVar));
1961 Asm->movss(DestTy, StackAddr, SrcReg); 1962 Asm->movss(DestTy, StackAddr, SrcReg);
1962 } else { 1963 } else {
(...skipping 25 matching lines...) Expand all
1988 Str << "\tmovups\t"; 1989 Str << "\tmovups\t";
1989 getSrc(0)->emit(Func); 1990 getSrc(0)->emit(Func);
1990 Str << ", "; 1991 Str << ", ";
1991 getSrc(1)->emit(Func); 1992 getSrc(1)->emit(Func);
1992 } 1993 }
1993 1994
1994 void InstX8632StoreP::emitIAS(const Cfg *Func) const { 1995 void InstX8632StoreP::emitIAS(const Cfg *Func) const {
1995 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1996 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1996 intptr_t StartPosition = Asm->GetPosition(); 1997 intptr_t StartPosition = Asm->GetPosition();
1997 assert(getSrcSize() == 2); 1998 assert(getSrcSize() == 2);
1998 const Variable *Src = llvm::cast<Variable>(getSrc(0)); 1999 const auto SrcVar = llvm::cast<Variable>(getSrc(0));
1999 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); 2000 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1));
2000 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 2001 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
2001 assert(Src->hasReg()); 2002 assert(SrcVar->hasReg());
2002 Asm->movups(DestMem->toAsmAddress(Asm), 2003 Asm->movups(DestMem->toAsmAddress(Asm),
2003 RegX8632::getEncodedXmm(Src->getRegNum())); 2004 RegX8632::getEncodedXmm(SrcVar->getRegNum()));
2004 emitIASBytes(Func, Asm, StartPosition); 2005 emitIASBytes(Func, Asm, StartPosition);
2005 } 2006 }
2006 2007
2007 void InstX8632StoreP::dump(const Cfg *Func) const { 2008 void InstX8632StoreP::dump(const Cfg *Func) const {
2008 Ostream &Str = Func->getContext()->getStrDump(); 2009 Ostream &Str = Func->getContext()->getStrDump();
2009 Str << "storep." << getSrc(0)->getType() << " "; 2010 Str << "storep." << getSrc(0)->getType() << " ";
2010 getSrc(1)->dump(Func); 2011 getSrc(1)->dump(Func);
2011 Str << ", "; 2012 Str << ", ";
2012 getSrc(0)->dump(Func); 2013 getSrc(0)->dump(Func);
2013 } 2014 }
2014 2015
2015 void InstX8632StoreQ::emit(const Cfg *Func) const { 2016 void InstX8632StoreQ::emit(const Cfg *Func) const {
2016 Ostream &Str = Func->getContext()->getStrEmit(); 2017 Ostream &Str = Func->getContext()->getStrEmit();
2017 assert(getSrcSize() == 2); 2018 assert(getSrcSize() == 2);
2018 assert(getSrc(1)->getType() == IceType_i64 || 2019 assert(getSrc(1)->getType() == IceType_i64 ||
2019 getSrc(1)->getType() == IceType_f64); 2020 getSrc(1)->getType() == IceType_f64);
2020 Str << "\tmovq\t"; 2021 Str << "\tmovq\t";
2021 getSrc(0)->emit(Func); 2022 getSrc(0)->emit(Func);
2022 Str << ", "; 2023 Str << ", ";
2023 getSrc(1)->emit(Func); 2024 getSrc(1)->emit(Func);
2024 } 2025 }
2025 2026
2026 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { 2027 void InstX8632StoreQ::emitIAS(const Cfg *Func) const {
2027 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2028 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2028 intptr_t StartPosition = Asm->GetPosition(); 2029 intptr_t StartPosition = Asm->GetPosition();
2029 assert(getSrcSize() == 2); 2030 assert(getSrcSize() == 2);
2030 const Variable *Src = llvm::cast<Variable>(getSrc(0)); 2031 const auto SrcVar = llvm::cast<Variable>(getSrc(0));
2031 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); 2032 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1));
2032 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 2033 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
2033 assert(Src->hasReg()); 2034 assert(SrcVar->hasReg());
2034 Asm->movq(DestMem->toAsmAddress(Asm), 2035 Asm->movq(DestMem->toAsmAddress(Asm),
2035 RegX8632::getEncodedXmm(Src->getRegNum())); 2036 RegX8632::getEncodedXmm(SrcVar->getRegNum()));
2036 emitIASBytes(Func, Asm, StartPosition); 2037 emitIASBytes(Func, Asm, StartPosition);
2037 } 2038 }
2038 2039
2039 void InstX8632StoreQ::dump(const Cfg *Func) const { 2040 void InstX8632StoreQ::dump(const Cfg *Func) const {
2040 Ostream &Str = Func->getContext()->getStrDump(); 2041 Ostream &Str = Func->getContext()->getStrDump();
2041 Str << "storeq." << getSrc(0)->getType() << " "; 2042 Str << "storeq." << getSrc(0)->getType() << " ";
2042 getSrc(1)->dump(Func); 2043 getSrc(1)->dump(Func);
2043 Str << ", "; 2044 Str << ", ";
2044 getSrc(0)->dump(Func); 2045 getSrc(0)->dump(Func);
2045 } 2046 }
2046 2047
2047 template <> void InstX8632Lea::emit(const Cfg *Func) const { 2048 template <> void InstX8632Lea::emit(const Cfg *Func) const {
2048 Ostream &Str = Func->getContext()->getStrEmit(); 2049 Ostream &Str = Func->getContext()->getStrEmit();
2049 assert(getSrcSize() == 1); 2050 assert(getSrcSize() == 1);
2050 assert(getDest()->hasReg()); 2051 assert(getDest()->hasReg());
2051 Str << "\tleal\t"; 2052 Str << "\tleal\t";
2052 Operand *Src0 = getSrc(0); 2053 Operand *Src0 = getSrc(0);
2053 if (Variable *VSrc0 = llvm::dyn_cast<Variable>(Src0)) { 2054 if (const auto Src0Var = llvm::dyn_cast<Variable>(Src0)) {
2054 Type Ty = VSrc0->getType(); 2055 Type Ty = Src0Var->getType();
2055 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an 2056 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an
2056 // acceptable type. 2057 // acceptable type.
2057 VSrc0->asType(isVectorType(Ty) ? IceType_i32 : Ty).emit(Func); 2058 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty).emit(Func);
2058 } else { 2059 } else {
2059 Src0->emit(Func); 2060 Src0->emit(Func);
2060 } 2061 }
2061 Str << ", "; 2062 Str << ", ";
2062 getDest()->emit(Func); 2063 getDest()->emit(Func);
2063 } 2064 }
2064 2065
2065 template <> void InstX8632Mov::emit(const Cfg *Func) const { 2066 template <> void InstX8632Mov::emit(const Cfg *Func) const {
2066 Ostream &Str = Func->getContext()->getStrEmit(); 2067 Ostream &Str = Func->getContext()->getStrEmit();
2067 assert(getSrcSize() == 1); 2068 assert(getSrcSize() == 1);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
2134 emitIASRegOpTyGPR(Func, DestTy, Dest, Src, GPRRegEmitter); 2135 emitIASRegOpTyGPR(Func, DestTy, Dest, Src, GPRRegEmitter);
2135 return; 2136 return;
2136 } 2137 }
2137 } else { 2138 } else {
2138 // Dest must be Stack and Src *could* be a register. Use Src's type 2139 // Dest must be Stack and Src *could* be a register. Use Src's type
2139 // to decide on the emitters. 2140 // to decide on the emitters.
2140 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 2141 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
2141 ->stackVarToAsmOperand(Dest)); 2142 ->stackVarToAsmOperand(Dest));
2142 if (isScalarFloatingType(SrcTy)) { 2143 if (isScalarFloatingType(SrcTy)) {
2143 // Src must be a register. 2144 // Src must be a register.
2144 const Variable *SrcVar = llvm::cast<Variable>(Src); 2145 const auto SrcVar = llvm::cast<Variable>(Src);
2145 assert(SrcVar->hasReg()); 2146 assert(SrcVar->hasReg());
2146 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2147 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2147 intptr_t StartPosition = Asm->GetPosition(); 2148 intptr_t StartPosition = Asm->GetPosition();
2148 Asm->movss(SrcTy, StackAddr, 2149 Asm->movss(SrcTy, StackAddr,
2149 RegX8632::getEncodedXmm(SrcVar->getRegNum())); 2150 RegX8632::getEncodedXmm(SrcVar->getRegNum()));
2150 emitIASBytes(Func, Asm, StartPosition); 2151 emitIASBytes(Func, Asm, StartPosition);
2151 return; 2152 return;
2152 } else { 2153 } else {
2153 // Src can be a register or immediate. 2154 // Src can be a register or immediate.
2154 assert(isScalarIntegerType(SrcTy)); 2155 assert(isScalarIntegerType(SrcTy));
2155 emitIASAddrOpTyGPR(Func, SrcTy, StackAddr, Src, GPRAddrEmitter); 2156 emitIASAddrOpTyGPR(Func, SrcTy, StackAddr, Src, GPRAddrEmitter);
2156 return; 2157 return;
2157 } 2158 }
2158 return; 2159 return;
2159 } 2160 }
2160 } 2161 }
2161 2162
2162 template <> void InstX8632Movd::emitIAS(const Cfg *Func) const { 2163 template <> void InstX8632Movd::emitIAS(const Cfg *Func) const {
2163 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2164 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2164 intptr_t StartPosition = Asm->GetPosition(); 2165 intptr_t StartPosition = Asm->GetPosition();
2165 assert(getSrcSize() == 1); 2166 assert(getSrcSize() == 1);
2166 const Variable *Dest = getDest(); 2167 const Variable *Dest = getDest();
2167 const Variable *Src = llvm::cast<Variable>(getSrc(0)); 2168 const auto SrcVar = llvm::cast<Variable>(getSrc(0));
2168 // For insert/extract element (one of Src/Dest is an Xmm vector and 2169 // For insert/extract element (one of Src/Dest is an Xmm vector and
2169 // the other is an int type). 2170 // the other is an int type).
2170 if (Src->getType() == IceType_i32) { 2171 if (SrcVar->getType() == IceType_i32) {
2171 assert(isVectorType(Dest->getType())); 2172 assert(isVectorType(Dest->getType()));
2172 assert(Dest->hasReg()); 2173 assert(Dest->hasReg());
2173 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); 2174 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum());
2174 if (Src->hasReg()) { 2175 if (SrcVar->hasReg()) {
2175 Asm->movd(DestReg, RegX8632::getEncodedGPR(Src->getRegNum())); 2176 Asm->movd(DestReg, RegX8632::getEncodedGPR(SrcVar->getRegNum()));
2176 } else { 2177 } else {
2177 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 2178 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
2178 ->stackVarToAsmOperand(Src)); 2179 ->stackVarToAsmOperand(SrcVar));
2179 Asm->movd(DestReg, StackAddr); 2180 Asm->movd(DestReg, StackAddr);
2180 } 2181 }
2181 } else { 2182 } else {
2182 assert(isVectorType(Src->getType())); 2183 assert(isVectorType(SrcVar->getType()));
2183 assert(Src->hasReg()); 2184 assert(SrcVar->hasReg());
2184 assert(Dest->getType() == IceType_i32); 2185 assert(Dest->getType() == IceType_i32);
2185 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(Src->getRegNum()); 2186 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum());
2186 if (Dest->hasReg()) { 2187 if (Dest->hasReg()) {
2187 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg); 2188 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg);
2188 } else { 2189 } else {
2189 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 2190 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
2190 ->stackVarToAsmOperand(Dest)); 2191 ->stackVarToAsmOperand(Dest));
2191 Asm->movd(StackAddr, SrcReg); 2192 Asm->movd(StackAddr, SrcReg);
2192 } 2193 }
2193 } 2194 }
2194 emitIASBytes(Func, Asm, StartPosition); 2195 emitIASBytes(Func, Asm, StartPosition);
2195 } 2196 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2241 }; 2242 };
2242 emitIASMovlikeXMM(Func, Dest, Src, Emitter); 2243 emitIASMovlikeXMM(Func, Dest, Src, Emitter);
2243 } 2244 }
2244 2245
2245 template <> void InstX8632MovssRegs::emitIAS(const Cfg *Func) const { 2246 template <> void InstX8632MovssRegs::emitIAS(const Cfg *Func) const {
2246 // This is Binop variant is only intended to be used for reg-reg moves 2247 // This is Binop variant is only intended to be used for reg-reg moves
2247 // where part of the Dest register is untouched. 2248 // where part of the Dest register is untouched.
2248 assert(getSrcSize() == 2); 2249 assert(getSrcSize() == 2);
2249 const Variable *Dest = getDest(); 2250 const Variable *Dest = getDest();
2250 assert(Dest == getSrc(0)); 2251 assert(Dest == getSrc(0));
2251 const Variable *Src = llvm::cast<Variable>(getSrc(1)); 2252 const auto SrcVar = llvm::cast<Variable>(getSrc(1));
2252 assert(Dest->hasReg() && Src->hasReg()); 2253 assert(Dest->hasReg() && SrcVar->hasReg());
2253 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2254 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2254 intptr_t StartPosition = Asm->GetPosition(); 2255 intptr_t StartPosition = Asm->GetPosition();
2255 Asm->movss(IceType_f32, RegX8632::getEncodedXmm(Dest->getRegNum()), 2256 Asm->movss(IceType_f32, RegX8632::getEncodedXmm(Dest->getRegNum()),
2256 RegX8632::getEncodedXmm(Src->getRegNum())); 2257 RegX8632::getEncodedXmm(SrcVar->getRegNum()));
2257 emitIASBytes(Func, Asm, StartPosition); 2258 emitIASBytes(Func, Asm, StartPosition);
2258 } 2259 }
2259 2260
2260 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const { 2261 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const {
2261 assert(getSrcSize() == 1); 2262 assert(getSrcSize() == 1);
2262 const Variable *Dest = getDest(); 2263 const Variable *Dest = getDest();
2263 const Operand *Src = getSrc(0); 2264 const Operand *Src = getSrc(0);
2264 // Dest must be a > 8-bit register, but Src can be 8-bit. In practice 2265 // Dest must be a > 8-bit register, but Src can be 8-bit. In practice
2265 // we just use the full register for Dest to avoid having an 2266 // we just use the full register for Dest to avoid having an
2266 // OperandSizeOverride prefix. It also allows us to only dispatch on SrcTy. 2267 // OperandSizeOverride prefix. It also allows us to only dispatch on SrcTy.
(...skipping 30 matching lines...) Expand all
2297 void InstX8632Nop::dump(const Cfg *Func) const { 2298 void InstX8632Nop::dump(const Cfg *Func) const {
2298 Ostream &Str = Func->getContext()->getStrDump(); 2299 Ostream &Str = Func->getContext()->getStrDump();
2299 Str << "nop (variant = " << Variant << ")"; 2300 Str << "nop (variant = " << Variant << ")";
2300 } 2301 }
2301 2302
2302 void InstX8632Fld::emit(const Cfg *Func) const { 2303 void InstX8632Fld::emit(const Cfg *Func) const {
2303 Ostream &Str = Func->getContext()->getStrEmit(); 2304 Ostream &Str = Func->getContext()->getStrEmit();
2304 assert(getSrcSize() == 1); 2305 assert(getSrcSize() == 1);
2305 Type Ty = getSrc(0)->getType(); 2306 Type Ty = getSrc(0)->getType();
2306 SizeT Width = typeWidthInBytes(Ty); 2307 SizeT Width = typeWidthInBytes(Ty);
2307 Variable *Var = llvm::dyn_cast<Variable>(getSrc(0)); 2308 const auto Var = llvm::dyn_cast<Variable>(getSrc(0));
2308 if (Var && Var->hasReg()) { 2309 if (Var && Var->hasReg()) {
2309 // This is a physical xmm register, so we need to spill it to a 2310 // This is a physical xmm register, so we need to spill it to a
2310 // temporary stack slot. 2311 // temporary stack slot.
2311 Str << "\tsubl\t$" << Width << ", %esp" 2312 Str << "\tsubl\t$" << Width << ", %esp"
2312 << "\n"; 2313 << "\n";
2313 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t"; 2314 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t";
2314 Var->emit(Func); 2315 Var->emit(Func);
2315 Str << ", (%esp)\n"; 2316 Str << ", (%esp)\n";
2316 Str << "\tfld" << getFldString(Ty) << "\t" 2317 Str << "\tfld" << getFldString(Ty) << "\t"
2317 << "(%esp)\n"; 2318 << "(%esp)\n";
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2356 2357
2357 void InstX8632Fld::dump(const Cfg *Func) const { 2358 void InstX8632Fld::dump(const Cfg *Func) const {
2358 Ostream &Str = Func->getContext()->getStrDump(); 2359 Ostream &Str = Func->getContext()->getStrDump();
2359 Str << "fld." << getSrc(0)->getType() << " "; 2360 Str << "fld." << getSrc(0)->getType() << " ";
2360 dumpSources(Func); 2361 dumpSources(Func);
2361 } 2362 }
2362 2363
2363 void InstX8632Fstp::emit(const Cfg *Func) const { 2364 void InstX8632Fstp::emit(const Cfg *Func) const {
2364 Ostream &Str = Func->getContext()->getStrEmit(); 2365 Ostream &Str = Func->getContext()->getStrEmit();
2365 assert(getSrcSize() == 0); 2366 assert(getSrcSize() == 0);
2366 // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to 2367 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to
2367 // "partially" delete the fstp if the Dest is unused. 2368 // "partially" delete the fstp if the Dest is unused.
2368 // Even if Dest is unused, the fstp should be kept for the SideEffects 2369 // Even if Dest is unused, the fstp should be kept for the SideEffects
2369 // of popping the stack. 2370 // of popping the stack.
2370 if (getDest() == NULL) { 2371 if (!getDest()) {
2371 Str << "\tfstp\tst(0)"; 2372 Str << "\tfstp\tst(0)";
2372 return; 2373 return;
2373 } 2374 }
2374 Type Ty = getDest()->getType(); 2375 Type Ty = getDest()->getType();
2375 size_t Width = typeWidthInBytes(Ty); 2376 size_t Width = typeWidthInBytes(Ty);
2376 if (!getDest()->hasReg()) { 2377 if (!getDest()->hasReg()) {
2377 Str << "\tfstp" << getFldString(Ty) << "\t"; 2378 Str << "\tfstp" << getFldString(Ty) << "\t";
2378 getDest()->emit(Func); 2379 getDest()->emit(Func);
2379 return; 2380 return;
2380 } 2381 }
2381 // Dest is a physical (xmm) register, so st(0) needs to go through 2382 // Dest is a physical (xmm) register, so st(0) needs to go through
2382 // memory. Hack this by creating a temporary stack slot, spilling 2383 // memory. Hack this by creating a temporary stack slot, spilling
2383 // st(0) there, loading it into the xmm register, and deallocating 2384 // st(0) there, loading it into the xmm register, and deallocating
2384 // the stack slot. 2385 // the stack slot.
2385 Str << "\tsubl\t$" << Width << ", %esp\n"; 2386 Str << "\tsubl\t$" << Width << ", %esp\n";
2386 Str << "\tfstp" << getFldString(Ty) << "\t" 2387 Str << "\tfstp" << getFldString(Ty) << "\t"
2387 << "(%esp)\n"; 2388 << "(%esp)\n";
2388 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t" 2389 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t"
2389 << "(%esp), "; 2390 << "(%esp), ";
2390 getDest()->emit(Func); 2391 getDest()->emit(Func);
2391 Str << "\n"; 2392 Str << "\n";
2392 Str << "\taddl\t$" << Width << ", %esp"; 2393 Str << "\taddl\t$" << Width << ", %esp";
2393 } 2394 }
2394 2395
2395 void InstX8632Fstp::emitIAS(const Cfg *Func) const { 2396 void InstX8632Fstp::emitIAS(const Cfg *Func) const {
2396 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2397 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2397 intptr_t StartPosition = Asm->GetPosition(); 2398 intptr_t StartPosition = Asm->GetPosition();
2398 assert(getSrcSize() == 0); 2399 assert(getSrcSize() == 0);
2399 const Variable *Dest = getDest(); 2400 const Variable *Dest = getDest();
2400 // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to 2401 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to
2401 // "partially" delete the fstp if the Dest is unused. 2402 // "partially" delete the fstp if the Dest is unused.
2402 // Even if Dest is unused, the fstp should be kept for the SideEffects 2403 // Even if Dest is unused, the fstp should be kept for the SideEffects
2403 // of popping the stack. 2404 // of popping the stack.
2404 if (Dest == NULL) { 2405 if (!Dest) {
2405 Asm->fstp(RegX8632::getEncodedSTReg(0)); 2406 Asm->fstp(RegX8632::getEncodedSTReg(0));
2406 emitIASBytes(Func, Asm, StartPosition); 2407 emitIASBytes(Func, Asm, StartPosition);
2407 return; 2408 return;
2408 } 2409 }
2409 Type Ty = Dest->getType(); 2410 Type Ty = Dest->getType();
2410 if (!Dest->hasReg()) { 2411 if (!Dest->hasReg()) {
2411 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 2412 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
2412 ->stackVarToAsmOperand(Dest)); 2413 ->stackVarToAsmOperand(Dest));
2413 Asm->fstp(Ty, StackAddr); 2414 Asm->fstp(Ty, StackAddr);
2414 } else { 2415 } else {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2478 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= 2479 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
2479 TargetX8632::SSE4_1); 2480 TargetX8632::SSE4_1);
2480 // pextrw must take a register dest. There is an SSE4.1 version that takes 2481 // pextrw must take a register dest. There is an SSE4.1 version that takes
2481 // a memory dest, but we aren't using it. For uniformity, just restrict 2482 // a memory dest, but we aren't using it. For uniformity, just restrict
2482 // them all to have a register dest for now. 2483 // them all to have a register dest for now.
2483 assert(Dest->hasReg()); 2484 assert(Dest->hasReg());
2484 // pextrw's Src(0) must be a register (both SSE4.1 and SSE2). 2485 // pextrw's Src(0) must be a register (both SSE4.1 and SSE2).
2485 assert(llvm::cast<Variable>(getSrc(0))->hasReg()); 2486 assert(llvm::cast<Variable>(getSrc(0))->hasReg());
2486 static const x86::AssemblerX86::ThreeOpImmEmitter< 2487 static const x86::AssemblerX86::ThreeOpImmEmitter<
2487 RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = { 2488 RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = {
2488 &x86::AssemblerX86::pextr, NULL}; 2489 &x86::AssemblerX86::pextr, nullptr};
2489 emitIASThreeOpImmOps<RegX8632::GPRRegister, RegX8632::XmmRegister, 2490 emitIASThreeOpImmOps<RegX8632::GPRRegister, RegX8632::XmmRegister,
2490 RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>( 2491 RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>(
2491 Func, DispatchTy, Dest, getSrc(0), getSrc(1), Emitter); 2492 Func, DispatchTy, Dest, getSrc(0), getSrc(1), Emitter);
2492 } 2493 }
2493 2494
2494 template <> void InstX8632Pinsr::emit(const Cfg *Func) const { 2495 template <> void InstX8632Pinsr::emit(const Cfg *Func) const {
2495 Ostream &Str = Func->getContext()->getStrEmit(); 2496 Ostream &Str = Func->getContext()->getStrEmit();
2496 assert(getSrcSize() == 3); 2497 assert(getSrcSize() == 3);
2497 // pinsrb and pinsrd are SSE4.1 instructions. 2498 // pinsrb and pinsrd are SSE4.1 instructions.
2498 assert(getDest()->getType() == IceType_v8i16 || 2499 assert(getDest()->getType() == IceType_v8i16 ||
2499 getDest()->getType() == IceType_v8i1 || 2500 getDest()->getType() == IceType_v8i1 ||
2500 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() 2501 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet()
2501 >= TargetX8632::SSE4_1); 2502 >= TargetX8632::SSE4_1);
2502 Str << "\t" << Opcode 2503 Str << "\t" << Opcode
2503 << TypeX8632Attributes[getDest()->getType()].PackString << "\t"; 2504 << TypeX8632Attributes[getDest()->getType()].PackString << "\t";
2504 getSrc(2)->emit(Func); 2505 getSrc(2)->emit(Func);
2505 Str << ", "; 2506 Str << ", ";
2506 Operand *Src1 = getSrc(1); 2507 Operand *Src1 = getSrc(1);
2507 if (Variable *VSrc1 = llvm::dyn_cast<Variable>(Src1)) { 2508 if (const auto Src1Var = llvm::dyn_cast<Variable>(Src1)) {
2508 // If src1 is a register, it should always be r32. 2509 // If src1 is a register, it should always be r32.
2509 if (VSrc1->hasReg()) { 2510 if (Src1Var->hasReg()) {
2510 VSrc1->asType(IceType_i32).emit(Func); 2511 Src1Var->asType(IceType_i32).emit(Func);
2511 } else { 2512 } else {
2512 VSrc1->emit(Func); 2513 Src1Var->emit(Func);
2513 } 2514 }
2514 } else { 2515 } else {
2515 Src1->emit(Func); 2516 Src1->emit(Func);
2516 } 2517 }
2517 Str << ", "; 2518 Str << ", ";
2518 getDest()->emit(Func); 2519 getDest()->emit(Func);
2519 } 2520 }
2520 2521
2521 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const { 2522 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const {
2522 assert(getSrcSize() == 3); 2523 assert(getSrcSize() == 3);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
2606 2607
2607 void InstX8632AdjustStack::dump(const Cfg *Func) const { 2608 void InstX8632AdjustStack::dump(const Cfg *Func) const {
2608 Ostream &Str = Func->getContext()->getStrDump(); 2609 Ostream &Str = Func->getContext()->getStrDump();
2609 Str << "esp = sub.i32 esp, " << Amount; 2610 Str << "esp = sub.i32 esp, " << Amount;
2610 } 2611 }
2611 2612
2612 void InstX8632Push::emit(const Cfg *Func) const { 2613 void InstX8632Push::emit(const Cfg *Func) const {
2613 Ostream &Str = Func->getContext()->getStrEmit(); 2614 Ostream &Str = Func->getContext()->getStrEmit();
2614 assert(getSrcSize() == 1); 2615 assert(getSrcSize() == 1);
2615 // Push is currently only used for saving GPRs. 2616 // Push is currently only used for saving GPRs.
2616 Variable *Var = llvm::cast<Variable>(getSrc(0)); 2617 const auto Var = llvm::cast<Variable>(getSrc(0));
2617 assert(Var->hasReg()); 2618 assert(Var->hasReg());
2618 Str << "\tpush\t"; 2619 Str << "\tpush\t";
2619 Var->emit(Func); 2620 Var->emit(Func);
2620 } 2621 }
2621 2622
2622 void InstX8632Push::emitIAS(const Cfg *Func) const { 2623 void InstX8632Push::emitIAS(const Cfg *Func) const {
2623 assert(getSrcSize() == 1); 2624 assert(getSrcSize() == 1);
2624 // Push is currently only used for saving GPRs. 2625 // Push is currently only used for saving GPRs.
2625 Variable *Var = llvm::cast<Variable>(getSrc(0)); 2626 const auto Var = llvm::cast<Variable>(getSrc(0));
2626 assert(Var->hasReg()); 2627 assert(Var->hasReg());
2627 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2628 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2628 intptr_t StartPosition = Asm->GetPosition(); 2629 intptr_t StartPosition = Asm->GetPosition();
2629 Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum())); 2630 Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum()));
2630 emitIASBytes(Func, Asm, StartPosition); 2631 emitIASBytes(Func, Asm, StartPosition);
2631 } 2632 }
2632 2633
2633 void InstX8632Push::dump(const Cfg *Func) const { 2634 void InstX8632Push::dump(const Cfg *Func) const {
2634 Ostream &Str = Func->getContext()->getStrDump(); 2635 Ostream &Str = Func->getContext()->getStrDump();
2635 Str << "push." << getSrc(0)->getType() << " "; 2636 Str << "push." << getSrc(0)->getType() << " ";
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2686 getSrc(1)->emit(Func); 2687 getSrc(1)->emit(Func);
2687 Str << ", "; 2688 Str << ", ";
2688 getSrc(0)->emit(Func); 2689 getSrc(0)->emit(Func);
2689 } 2690 }
2690 2691
2691 void InstX8632Xadd::emitIAS(const Cfg *Func) const { 2692 void InstX8632Xadd::emitIAS(const Cfg *Func) const {
2692 assert(getSrcSize() == 2); 2693 assert(getSrcSize() == 2);
2693 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2694 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2694 intptr_t StartPosition = Asm->GetPosition(); 2695 intptr_t StartPosition = Asm->GetPosition();
2695 Type Ty = getSrc(0)->getType(); 2696 Type Ty = getSrc(0)->getType();
2696 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); 2697 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
2697 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 2698 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
2698 const x86::Address Addr = Mem->toAsmAddress(Asm); 2699 const x86::Address Addr = Mem->toAsmAddress(Asm);
2699 const Variable *VarReg = llvm::cast<Variable>(getSrc(1)); 2700 const auto VarReg = llvm::cast<Variable>(getSrc(1));
2700 assert(VarReg->hasReg()); 2701 assert(VarReg->hasReg());
2701 const RegX8632::GPRRegister Reg = 2702 const RegX8632::GPRRegister Reg =
2702 RegX8632::getEncodedGPR(VarReg->getRegNum()); 2703 RegX8632::getEncodedGPR(VarReg->getRegNum());
2703 if (Locked) { 2704 if (Locked) {
2704 Asm->lock(); 2705 Asm->lock();
2705 } 2706 }
2706 Asm->xadd(Ty, Addr, Reg); 2707 Asm->xadd(Ty, Addr, Reg);
2707 emitIASBytes(Func, Asm, StartPosition); 2708 emitIASBytes(Func, Asm, StartPosition);
2708 } 2709 }
2709 2710
(...skipping 13 matching lines...) Expand all
2723 getSrc(1)->emit(Func); 2724 getSrc(1)->emit(Func);
2724 Str << ", "; 2725 Str << ", ";
2725 getSrc(0)->emit(Func); 2726 getSrc(0)->emit(Func);
2726 } 2727 }
2727 2728
2728 void InstX8632Xchg::emitIAS(const Cfg *Func) const { 2729 void InstX8632Xchg::emitIAS(const Cfg *Func) const {
2729 assert(getSrcSize() == 2); 2730 assert(getSrcSize() == 2);
2730 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2731 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2731 intptr_t StartPosition = Asm->GetPosition(); 2732 intptr_t StartPosition = Asm->GetPosition();
2732 Type Ty = getSrc(0)->getType(); 2733 Type Ty = getSrc(0)->getType();
2733 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); 2734 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
2734 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 2735 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
2735 const x86::Address Addr = Mem->toAsmAddress(Asm); 2736 const x86::Address Addr = Mem->toAsmAddress(Asm);
2736 const Variable *VarReg = llvm::cast<Variable>(getSrc(1)); 2737 const auto VarReg = llvm::cast<Variable>(getSrc(1));
2737 assert(VarReg->hasReg()); 2738 assert(VarReg->hasReg());
2738 const RegX8632::GPRRegister Reg = 2739 const RegX8632::GPRRegister Reg =
2739 RegX8632::getEncodedGPR(VarReg->getRegNum()); 2740 RegX8632::getEncodedGPR(VarReg->getRegNum());
2740 Asm->xchg(Ty, Addr, Reg); 2741 Asm->xchg(Ty, Addr, Reg);
2741 emitIASBytes(Func, Asm, StartPosition); 2742 emitIASBytes(Func, Asm, StartPosition);
2742 } 2743 }
2743 2744
2744 void InstX8632Xchg::dump(const Cfg *Func) const { 2745 void InstX8632Xchg::dump(const Cfg *Func) const {
2745 Ostream &Str = Func->getContext()->getStrDump(); 2746 Ostream &Str = Func->getContext()->getStrDump();
2746 Type Ty = getSrc(0)->getType(); 2747 Type Ty = getSrc(0)->getType();
2747 Str << "xchg." << Ty << " "; 2748 Str << "xchg." << Ty << " ";
2748 dumpSources(Func); 2749 dumpSources(Func);
2749 } 2750 }
2750 2751
2751 void OperandX8632Mem::emit(const Cfg *Func) const { 2752 void OperandX8632Mem::emit(const Cfg *Func) const {
2752 Ostream &Str = Func->getContext()->getStrEmit(); 2753 Ostream &Str = Func->getContext()->getStrEmit();
2753 if (SegmentReg != DefaultSegment) { 2754 if (SegmentReg != DefaultSegment) {
2754 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); 2755 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM);
2755 Str << InstX8632SegmentRegNames[SegmentReg] << ":"; 2756 Str << InstX8632SegmentRegNames[SegmentReg] << ":";
2756 } 2757 }
2757 // Emit as Offset(Base,Index,1<<Shift). 2758 // Emit as Offset(Base,Index,1<<Shift).
2758 // Offset is emitted without the leading '$'. 2759 // Offset is emitted without the leading '$'.
2759 // Omit the (Base,Index,1<<Shift) part if Base==NULL. 2760 // Omit the (Base,Index,1<<Shift) part if Base==nullptr.
2760 if (Offset == NULL) { 2761 if (!Offset) {
2761 // No offset, emit nothing. 2762 // No offset, emit nothing.
2762 } else if (auto CI = llvm::dyn_cast<ConstantInteger32>(Offset)) { 2763 } else if (const auto CI = llvm::dyn_cast<ConstantInteger32>(Offset)) {
2763 if (CI->getValue()) 2764 if (CI->getValue())
2764 // Emit a non-zero offset without a leading '$'. 2765 // Emit a non-zero offset without a leading '$'.
2765 Str << CI->getValue(); 2766 Str << CI->getValue();
2766 } else if (auto CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) { 2767 } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) {
2767 CR->emitWithoutDollar(Func->getContext()); 2768 CR->emitWithoutDollar(Func->getContext());
2768 } else { 2769 } else {
2769 llvm_unreachable("Invalid offset type for x86 mem operand"); 2770 llvm_unreachable("Invalid offset type for x86 mem operand");
2770 } 2771 }
2771 2772
2772 if (Base) { 2773 if (Base) {
2773 Str << "("; 2774 Str << "(";
2774 Base->emit(Func); 2775 Base->emit(Func);
2775 if (Index) { 2776 if (Index) {
2776 Str << ","; 2777 Str << ",";
(...skipping 26 matching lines...) Expand all
2803 Str << (1u << Shift) << "*"; 2804 Str << (1u << Shift) << "*";
2804 if (Func) 2805 if (Func)
2805 Index->dump(Func); 2806 Index->dump(Func);
2806 else 2807 else
2807 Index->dump(Str); 2808 Index->dump(Str);
2808 Dumped = true; 2809 Dumped = true;
2809 } 2810 }
2810 // Pretty-print the Offset. 2811 // Pretty-print the Offset.
2811 bool OffsetIsZero = false; 2812 bool OffsetIsZero = false;
2812 bool OffsetIsNegative = false; 2813 bool OffsetIsNegative = false;
2813 if (Offset == NULL) { 2814 if (!Offset) {
2814 OffsetIsZero = true; 2815 OffsetIsZero = true;
2815 } else if (ConstantInteger32 *CI = 2816 } else if (const auto CI = llvm::dyn_cast<ConstantInteger32>(Offset)) {
2816 llvm::dyn_cast<ConstantInteger32>(Offset)) {
2817 OffsetIsZero = (CI->getValue() == 0); 2817 OffsetIsZero = (CI->getValue() == 0);
2818 OffsetIsNegative = (static_cast<int32_t>(CI->getValue()) < 0); 2818 OffsetIsNegative = (static_cast<int32_t>(CI->getValue()) < 0);
2819 } else { 2819 } else {
2820 assert(llvm::isa<ConstantRelocatable>(Offset)); 2820 assert(llvm::isa<ConstantRelocatable>(Offset));
2821 } 2821 }
2822 if (Dumped) { 2822 if (Dumped) {
2823 if (!OffsetIsZero) { // Suppress if Offset is known to be 0 2823 if (!OffsetIsZero) { // Suppress if Offset is known to be 0
2824 if (!OffsetIsNegative) // Suppress if Offset is known to be negative 2824 if (!OffsetIsNegative) // Suppress if Offset is known to be negative
2825 Str << "+"; 2825 Str << "+";
2826 Offset->dump(Func, Str); 2826 Offset->dump(Func, Str);
2827 } 2827 }
2828 } else { 2828 } else {
2829 // There is only the offset. 2829 // There is only the offset.
2830 Offset->dump(Func, Str); 2830 Offset->dump(Func, Str);
2831 } 2831 }
2832 Str << "]"; 2832 Str << "]";
2833 } 2833 }
2834 2834
2835 void OperandX8632Mem::emitSegmentOverride(x86::AssemblerX86 *Asm) const { 2835 void OperandX8632Mem::emitSegmentOverride(x86::AssemblerX86 *Asm) const {
2836 if (SegmentReg != DefaultSegment) { 2836 if (SegmentReg != DefaultSegment) {
2837 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); 2837 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM);
2838 Asm->EmitSegmentOverride(InstX8632SegmentPrefixes[SegmentReg]); 2838 Asm->EmitSegmentOverride(InstX8632SegmentPrefixes[SegmentReg]);
2839 } 2839 }
2840 } 2840 }
2841 2841
2842 x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const { 2842 x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const {
2843 int32_t Disp = 0; 2843 int32_t Disp = 0;
2844 AssemblerFixup *Fixup = NULL; 2844 AssemblerFixup *Fixup = nullptr;
2845 // Determine the offset (is it relocatable?) 2845 // Determine the offset (is it relocatable?)
2846 if (getOffset()) { 2846 if (getOffset()) {
2847 if (ConstantInteger32 *CI = 2847 if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) {
2848 llvm::dyn_cast<ConstantInteger32>(getOffset())) {
2849 Disp = static_cast<int32_t>(CI->getValue()); 2848 Disp = static_cast<int32_t>(CI->getValue());
2850 } else if (ConstantRelocatable *CR = 2849 } else if (const auto CR =
2851 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { 2850 llvm::dyn_cast<ConstantRelocatable>(getOffset())) {
2852 Fixup = x86::DisplacementRelocation::create(Asm, FK_Abs_4, CR); 2851 Fixup = x86::DisplacementRelocation::create(Asm, FK_Abs_4, CR);
2853 } else { 2852 } else {
2854 llvm_unreachable("Unexpected offset type"); 2853 llvm_unreachable("Unexpected offset type");
2855 } 2854 }
2856 } 2855 }
2857 2856
2858 // Now convert to the various possible forms. 2857 // Now convert to the various possible forms.
2859 if (getBase() && getIndex()) { 2858 if (getBase() && getIndex()) {
2860 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), 2859 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()),
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2910 } 2909 }
2911 Str << "("; 2910 Str << "(";
2912 if (Func) 2911 if (Func)
2913 Var->dump(Func); 2912 Var->dump(Func);
2914 else 2913 else
2915 Var->dump(Str); 2914 Var->dump(Str);
2916 Str << ")"; 2915 Str << ")";
2917 } 2916 }
2918 2917
2919 } // end of namespace Ice 2918 } // end of namespace Ice
OLDNEW
« no previous file with comments | « no previous file | src/assembler.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698