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

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: formatting / missed one 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) {
Jim Stichnoth 2014/11/04 17:41:25 Using !ptr here, and ptr==nullptr below. Make it
jvoung (off chromium) 2014/11/04 18:22:34 Yep -- no strong preference, but I'll just go with
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 == nullptr || LastFixup->position() == LastFixupLoc);
Jim Stichnoth 2014/11/04 17:41:25 Does it make sense to change all NULL-->nullptr st
jvoung (off chromium) 2014/11/04 18:22:34 Most of them are checks against NULL, so I ended u
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 (auto CallTarget = llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) {
Jim Stichnoth 2014/11/04 17:41:25 const auto?
jvoung (off chromium) 2014/11/04 18:22:34 Done.
539 // TODO(stichnot): All constant targets should suppress the '$', 539 // TODO(stichnot): All constant targets should suppress the '$',
540 // not just relocatables. 540 // not just relocatables.
541 CallTarget->emitWithoutDollar(Func->getContext()); 541 CallTarget->emitWithoutDollar(Func->getContext());
542 } else { 542 } else {
543 Str << "*"; 543 Str << "*";
544 getCallTarget()->emit(Func); 544 getCallTarget()->emit(Func);
545 } 545 }
546 Func->getTarget()->resetStackAdjustment(); 546 Func->getTarget()->resetStackAdjustment();
547 } 547 }
548 548
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 // Opcode parameter needs to be char* and not IceString because of 608 // Opcode parameter needs to be char* and not IceString because of
609 // template issues. 609 // template issues.
610 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, 610 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func,
611 bool ShiftHack) { 611 bool ShiftHack) {
612 Ostream &Str = Func->getContext()->getStrEmit(); 612 Ostream &Str = Func->getContext()->getStrEmit();
613 assert(Inst->getSrcSize() == 2); 613 assert(Inst->getSrcSize() == 2);
614 Variable *Dest = Inst->getDest(); 614 Variable *Dest = Inst->getDest();
615 assert(Dest == Inst->getSrc(0)); 615 assert(Dest == Inst->getSrc(0));
616 Operand *Src1 = Inst->getSrc(1); 616 Operand *Src1 = Inst->getSrc(1);
617 Str << "\t" << Opcode << InstX8632::getWidthString(Dest->getType()) << "\t"; 617 Str << "\t" << Opcode << InstX8632::getWidthString(Dest->getType()) << "\t";
618 Variable *ShiftReg = llvm::dyn_cast<Variable>(Src1); 618 const auto ShiftReg = llvm::dyn_cast<Variable>(Src1);
619 if (ShiftHack && ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx) 619 if (ShiftHack && ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx)
620 Str << "%cl"; 620 Str << "%cl";
621 else 621 else
622 Src1->emit(Func); 622 Src1->emit(Func);
623 Str << ", "; 623 Str << ", ";
624 Dest->emit(Func); 624 Dest->emit(Func);
625 } 625 }
626 626
627 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op, 627 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op,
628 const x86::AssemblerX86::GPREmitterOneOp &Emitter) { 628 const x86::AssemblerX86::GPREmitterOneOp &Emitter) {
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 758
759 void emitIASGPRShiftDouble(const Cfg *Func, const Variable *Dest, 759 void emitIASGPRShiftDouble(const Cfg *Func, const Variable *Dest,
760 const Operand *Src1Op, const Operand *Src2Op, 760 const Operand *Src1Op, const Operand *Src2Op,
761 const x86::AssemblerX86::GPREmitterShiftD &Emitter) { 761 const x86::AssemblerX86::GPREmitterShiftD &Emitter) {
762 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 762 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
763 intptr_t StartPosition = Asm->GetPosition(); 763 intptr_t StartPosition = Asm->GetPosition();
764 // Dest can be reg or mem, but we only use the reg variant. 764 // Dest can be reg or mem, but we only use the reg variant.
765 assert(Dest->hasReg()); 765 assert(Dest->hasReg());
766 RegX8632::GPRRegister DestReg = RegX8632::getEncodedGPR(Dest->getRegNum()); 766 RegX8632::GPRRegister DestReg = RegX8632::getEncodedGPR(Dest->getRegNum());
767 // Src1 must be reg. 767 // Src1 must be reg.
768 const auto Src1 = llvm::cast<Variable>(Src1Op); 768 const auto Src1 = llvm::cast<Variable>(Src1Op);
Jim Stichnoth 2014/11/04 17:41:25 rename to SrcVar1?
jvoung (off chromium) 2014/11/04 18:22:34 Done.
769 assert(Src1->hasReg()); 769 assert(Src1->hasReg());
770 RegX8632::GPRRegister SrcReg = RegX8632::getEncodedGPR(Src1->getRegNum()); 770 RegX8632::GPRRegister SrcReg = RegX8632::getEncodedGPR(Src1->getRegNum());
771 Type Ty = Src1->getType(); 771 Type Ty = Src1->getType();
772 // Src2 can be the implicit CL register or an immediate. 772 // Src2 can be the implicit CL register or an immediate.
773 if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src2Op)) { 773 if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src2Op)) {
774 (Asm->*(Emitter.GPRGPRImm))(Ty, DestReg, SrcReg, 774 (Asm->*(Emitter.GPRGPRImm))(Ty, DestReg, SrcReg,
775 x86::Immediate(Imm->getValue())); 775 x86::Immediate(Imm->getValue()));
776 } else { 776 } else {
777 assert(llvm::cast<Variable>(Src2Op)->getRegNum() == RegX8632::Reg_ecx); 777 assert(llvm::cast<Variable>(Src2Op)->getRegNum() == RegX8632::Reg_ecx);
778 (Asm->*(Emitter.GPRGPR))(Ty, DestReg, SrcReg); 778 (Asm->*(Emitter.GPRGPR))(Ty, DestReg, SrcReg);
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 } else if (const auto SrcMem = llvm::dyn_cast<OperandX8632Mem>(Src)) { 914 } else if (const auto SrcMem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
915 assert(SrcMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 915 assert(SrcMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
916 (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm)); 916 (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm));
917 } else { 917 } else {
918 llvm_unreachable("Unexpected operand type"); 918 llvm_unreachable("Unexpected operand type");
919 } 919 }
920 } else { 920 } else {
921 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 921 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
922 ->stackVarToAsmOperand(Dest)); 922 ->stackVarToAsmOperand(Dest));
923 // Src must be a register in this case. 923 // Src must be a register in this case.
924 const Variable *SrcVar = llvm::cast<Variable>(Src); 924 const auto SrcVar = llvm::cast<Variable>(Src);
925 assert(SrcVar->hasReg()); 925 assert(SrcVar->hasReg());
926 (Asm->*(Emitter.AddrXmm))(StackAddr, 926 (Asm->*(Emitter.AddrXmm))(StackAddr,
927 RegX8632::getEncodedXmm(SrcVar->getRegNum())); 927 RegX8632::getEncodedXmm(SrcVar->getRegNum()));
928 } 928 }
929 emitIASBytes(Func, Asm, StartPosition); 929 emitIASBytes(Func, Asm, StartPosition);
930 } 930 }
931 931
932 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) { 932 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) {
933 const Variable *Src = llvm::dyn_cast<const Variable>(Source); 933 const auto SrcVar = llvm::dyn_cast<const Variable>(Source);
934 if (Src == NULL) 934 if (SrcVar == NULL)
Jim Stichnoth 2014/11/04 17:41:25 nullptr like elsewhere?
jvoung (off chromium) 2014/11/04 18:22:34 Done.
935 return false; 935 return false;
936 if (Dest->hasReg() && Dest->getRegNum() == Src->getRegNum()) { 936 if (Dest->hasReg() && Dest->getRegNum() == SrcVar->getRegNum()) {
937 // TODO: On x86-64, instructions like "mov eax, eax" are used to 937 // 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 938 // clear the upper 32 bits of rax. We need to recognize and
939 // preserve these. 939 // preserve these.
940 return true; 940 return true;
941 } 941 }
942 if (!Dest->hasReg() && !Src->hasReg() && 942 if (!Dest->hasReg() && !SrcVar->hasReg() &&
943 Dest->getStackOffset() == Src->getStackOffset()) 943 Dest->getStackOffset() == SrcVar->getStackOffset())
944 return true; 944 return true;
945 return false; 945 return false;
946 } 946 }
947 947
948 // In-place ops 948 // In-place ops
949 template <> const char *InstX8632Bswap::Opcode = "bswap"; 949 template <> const char *InstX8632Bswap::Opcode = "bswap";
950 template <> const char *InstX8632Neg::Opcode = "neg"; 950 template <> const char *InstX8632Neg::Opcode = "neg";
951 // Unary ops 951 // Unary ops
952 template <> const char *InstX8632Bsf::Opcode = "bsf"; 952 template <> const char *InstX8632Bsf::Opcode = "bsf";
953 template <> const char *InstX8632Bsr::Opcode = "bsr"; 953 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"; 1003 template <> const char *InstX8632Pinsr::Opcode = "pinsr";
1004 template <> const char *InstX8632Blendvps::Opcode = "blendvps"; 1004 template <> const char *InstX8632Blendvps::Opcode = "blendvps";
1005 template <> const char *InstX8632Pblendvb::Opcode = "pblendvb"; 1005 template <> const char *InstX8632Pblendvb::Opcode = "pblendvb";
1006 // Three address ops 1006 // Three address ops
1007 template <> const char *InstX8632Pextr::Opcode = "pextr"; 1007 template <> const char *InstX8632Pextr::Opcode = "pextr";
1008 template <> const char *InstX8632Pshufd::Opcode = "pshufd"; 1008 template <> const char *InstX8632Pshufd::Opcode = "pshufd";
1009 1009
1010 // Inplace GPR ops 1010 // Inplace GPR ops
1011 template <> 1011 template <>
1012 const x86::AssemblerX86::GPREmitterOneOp InstX8632Bswap::Emitter = { 1012 const x86::AssemblerX86::GPREmitterOneOp InstX8632Bswap::Emitter = {
1013 &x86::AssemblerX86::bswap, NULL /* only a reg form exists */}; 1013 &x86::AssemblerX86::bswap, nullptr /* only a reg form exists */};
1014 template <> 1014 template <>
1015 const x86::AssemblerX86::GPREmitterOneOp InstX8632Neg::Emitter = { 1015 const x86::AssemblerX86::GPREmitterOneOp InstX8632Neg::Emitter = {
1016 &x86::AssemblerX86::neg, &x86::AssemblerX86::neg}; 1016 &x86::AssemblerX86::neg, &x86::AssemblerX86::neg};
1017 1017
1018 // Unary GPR ops 1018 // Unary GPR ops
1019 template <> 1019 template <>
1020 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsf::Emitter = { 1020 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsf::Emitter = {
1021 &x86::AssemblerX86::bsf, &x86::AssemblerX86::bsf, NULL}; 1021 &x86::AssemblerX86::bsf, &x86::AssemblerX86::bsf, nullptr};
1022 template <> 1022 template <>
1023 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsr::Emitter = { 1023 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsr::Emitter = {
1024 &x86::AssemblerX86::bsr, &x86::AssemblerX86::bsr, NULL}; 1024 &x86::AssemblerX86::bsr, &x86::AssemblerX86::bsr, nullptr};
1025 template <> 1025 template <>
1026 const x86::AssemblerX86::GPREmitterRegOp InstX8632Lea::Emitter = { 1026 const x86::AssemblerX86::GPREmitterRegOp InstX8632Lea::Emitter = {
1027 /* reg/reg and reg/imm are illegal */ NULL, &x86::AssemblerX86::lea, NULL}; 1027 /* reg/reg and reg/imm are illegal */ nullptr, &x86::AssemblerX86::lea,
1028 nullptr};
1028 template <> 1029 template <>
1029 const x86::AssemblerX86::GPREmitterRegOp InstX8632Movsx::Emitter = { 1030 const x86::AssemblerX86::GPREmitterRegOp InstX8632Movsx::Emitter = {
1030 &x86::AssemblerX86::movsx, &x86::AssemblerX86::movsx, NULL}; 1031 &x86::AssemblerX86::movsx, &x86::AssemblerX86::movsx, nullptr};
1031 template <> 1032 template <>
1032 const x86::AssemblerX86::GPREmitterRegOp InstX8632Movzx::Emitter = { 1033 const x86::AssemblerX86::GPREmitterRegOp InstX8632Movzx::Emitter = {
1033 &x86::AssemblerX86::movzx, &x86::AssemblerX86::movzx, NULL}; 1034 &x86::AssemblerX86::movzx, &x86::AssemblerX86::movzx, nullptr};
1034 1035
1035 // Unary XMM ops 1036 // Unary XMM ops
1036 template <> 1037 template <>
1037 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Sqrtss::Emitter = { 1038 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Sqrtss::Emitter = {
1038 &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss 1039 &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss
1039 }; 1040 };
1040 1041
1041 // Binary GPR ops 1042 // Binary GPR ops
1042 template <> 1043 template <>
1043 const x86::AssemblerX86::GPREmitterRegOp InstX8632Add::Emitter = { 1044 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}; 1341 &x86::AssemblerX86::pblendvb, &x86::AssemblerX86::pblendvb};
1341 emitIASVariableBlendInst(this, Func, Emitter); 1342 emitIASVariableBlendInst(this, Func, Emitter);
1342 } 1343 }
1343 1344
1344 template <> void InstX8632Imul::emit(const Cfg *Func) const { 1345 template <> void InstX8632Imul::emit(const Cfg *Func) const {
1345 Ostream &Str = Func->getContext()->getStrEmit(); 1346 Ostream &Str = Func->getContext()->getStrEmit();
1346 assert(getSrcSize() == 2); 1347 assert(getSrcSize() == 2);
1347 Variable *Dest = getDest(); 1348 Variable *Dest = getDest();
1348 if (isByteSizedArithType(Dest->getType())) { 1349 if (isByteSizedArithType(Dest->getType())) {
1349 // The 8-bit version of imul only allows the form "imul r/m8". 1350 // The 8-bit version of imul only allows the form "imul r/m8".
1350 Variable *Src0 = llvm::dyn_cast<Variable>(getSrc(0)); 1351 const auto Src0 = llvm::dyn_cast<Variable>(getSrc(0));
Jim Stichnoth 2014/11/04 17:41:25 rename Src0Var or SrcVar?
jvoung (off chromium) 2014/11/04 18:22:34 Done.
1351 (void)Src0; 1352 (void)Src0;
1352 assert(Src0 && Src0->getRegNum() == RegX8632::Reg_eax); 1353 assert(Src0 && Src0->getRegNum() == RegX8632::Reg_eax);
1353 Str << "\timulb\t"; 1354 Str << "\timulb\t";
1354 getSrc(1)->emit(Func); 1355 getSrc(1)->emit(Func);
1355 } else if (llvm::isa<Constant>(getSrc(1))) { 1356 } else if (llvm::isa<Constant>(getSrc(1))) {
1356 Str << "\timul" << getWidthString(Dest->getType()) << "\t"; 1357 Str << "\timul" << getWidthString(Dest->getType()) << "\t";
1357 getSrc(1)->emit(Func); 1358 getSrc(1)->emit(Func);
1358 Str << ", "; 1359 Str << ", ";
1359 getSrc(0)->emit(Func); 1360 getSrc(0)->emit(Func);
1360 Str << ", "; 1361 Str << ", ";
1361 Dest->emit(Func); 1362 Dest->emit(Func);
1362 } else { 1363 } else {
1363 emitTwoAddress("imul", this, Func); 1364 emitTwoAddress("imul", this, Func);
1364 } 1365 }
1365 } 1366 }
1366 1367
1367 template <> void InstX8632Imul::emitIAS(const Cfg *Func) const { 1368 template <> void InstX8632Imul::emitIAS(const Cfg *Func) const {
1368 assert(getSrcSize() == 2); 1369 assert(getSrcSize() == 2);
1369 const Variable *Var = getDest(); 1370 const Variable *Var = getDest();
1370 Type Ty = Var->getType(); 1371 Type Ty = Var->getType();
1371 const Operand *Src = getSrc(1); 1372 const Operand *Src = getSrc(1);
1372 if (isByteSizedArithType(Ty)) { 1373 if (isByteSizedArithType(Ty)) {
1373 // The 8-bit version of imul only allows the form "imul r/m8". 1374 // The 8-bit version of imul only allows the form "imul r/m8".
1374 Variable *Src0 = llvm::dyn_cast<Variable>(getSrc(0)); 1375 const auto Src0 = llvm::dyn_cast<Variable>(getSrc(0));
Jim Stichnoth 2014/11/04 17:41:25 rename Src0Var or SrcVar?
jvoung (off chromium) 2014/11/04 18:22:35 Done.
1375 (void)Src0; 1376 (void)Src0;
1376 assert(Src0 && Src0->getRegNum() == RegX8632::Reg_eax); 1377 assert(Src0 && Src0->getRegNum() == RegX8632::Reg_eax);
1377 const x86::AssemblerX86::GPREmitterOneOp Emitter = { 1378 const x86::AssemblerX86::GPREmitterOneOp Emitter = {
1378 &x86::AssemblerX86::imul, &x86::AssemblerX86::imul}; 1379 &x86::AssemblerX86::imul, &x86::AssemblerX86::imul};
1379 emitIASOpTyGPR(Func, Ty, getSrc(1), Emitter); 1380 emitIASOpTyGPR(Func, Ty, getSrc(1), Emitter);
1380 } else { 1381 } else {
1381 // We only use imul as a two-address instruction even though 1382 // 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. 1383 // there is a 3 operand version when one of the operands is a constant.
1383 assert(Var == getSrc(0)); 1384 assert(Var == getSrc(0));
1384 const x86::AssemblerX86::GPREmitterRegOp Emitter = { 1385 const x86::AssemblerX86::GPREmitterRegOp Emitter = {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1452 Asm->cdq(); 1453 Asm->cdq();
1453 break; 1454 break;
1454 } 1455 }
1455 emitIASBytes(Func, Asm, StartPosition); 1456 emitIASBytes(Func, Asm, StartPosition);
1456 } 1457 }
1457 1458
1458 void InstX8632Mul::emit(const Cfg *Func) const { 1459 void InstX8632Mul::emit(const Cfg *Func) const {
1459 Ostream &Str = Func->getContext()->getStrEmit(); 1460 Ostream &Str = Func->getContext()->getStrEmit();
1460 assert(getSrcSize() == 2); 1461 assert(getSrcSize() == 2);
1461 assert(llvm::isa<Variable>(getSrc(0))); 1462 assert(llvm::isa<Variable>(getSrc(0)));
1462 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); 1463 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax);
1463 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? 1464 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx?
1464 Str << "\tmul" << getWidthString(getDest()->getType()) << "\t"; 1465 Str << "\tmul" << getWidthString(getDest()->getType()) << "\t";
1465 getSrc(1)->emit(Func); 1466 getSrc(1)->emit(Func);
1466 } 1467 }
1467 1468
1468 void InstX8632Mul::emitIAS(const Cfg *Func) const { 1469 void InstX8632Mul::emitIAS(const Cfg *Func) const {
1469 assert(getSrcSize() == 2); 1470 assert(getSrcSize() == 2);
1470 assert(llvm::isa<Variable>(getSrc(0))); 1471 assert(llvm::isa<Variable>(getSrc(0)));
1471 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); 1472 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax);
1472 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? 1473 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx?
1473 const Operand *Src = getSrc(1); 1474 const Operand *Src = getSrc(1);
1474 Type Ty = Src->getType(); 1475 Type Ty = Src->getType();
1475 const static x86::AssemblerX86::GPREmitterOneOp Emitter = { 1476 const static x86::AssemblerX86::GPREmitterOneOp Emitter = {
1476 &x86::AssemblerX86::mul, &x86::AssemblerX86::mul}; 1477 &x86::AssemblerX86::mul, &x86::AssemblerX86::mul};
1477 emitIASOpTyGPR(Func, Ty, Src, Emitter); 1478 emitIASOpTyGPR(Func, Ty, Src, Emitter);
1478 } 1479 }
1479 1480
1480 void InstX8632Mul::dump(const Cfg *Func) const { 1481 void InstX8632Mul::dump(const Cfg *Func) const {
1481 Ostream &Str = Func->getContext()->getStrDump(); 1482 Ostream &Str = Func->getContext()->getStrDump();
1482 dumpDest(Func); 1483 dumpDest(Func);
1483 Str << " = mul." << getDest()->getType() << " "; 1484 Str << " = mul." << getDest()->getType() << " ";
1484 dumpSources(Func); 1485 dumpSources(Func);
1485 } 1486 }
1486 1487
1487 void InstX8632Shld::emit(const Cfg *Func) const { 1488 void InstX8632Shld::emit(const Cfg *Func) const {
1488 Ostream &Str = Func->getContext()->getStrEmit(); 1489 Ostream &Str = Func->getContext()->getStrEmit();
1489 Variable *Dest = getDest(); 1490 Variable *Dest = getDest();
1490 assert(getSrcSize() == 3); 1491 assert(getSrcSize() == 3);
1491 assert(Dest == getSrc(0)); 1492 assert(Dest == getSrc(0));
1492 Str << "\tshld" << getWidthString(Dest->getType()) << "\t"; 1493 Str << "\tshld" << getWidthString(Dest->getType()) << "\t";
1493 if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { 1494 if (const auto ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) {
1494 (void)ShiftReg; 1495 (void)ShiftReg;
1495 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); 1496 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx);
1496 Str << "%cl"; 1497 Str << "%cl";
1497 } else { 1498 } else {
1498 getSrc(2)->emit(Func); 1499 getSrc(2)->emit(Func);
1499 } 1500 }
1500 Str << ", "; 1501 Str << ", ";
1501 getSrc(1)->emit(Func); 1502 getSrc(1)->emit(Func);
1502 Str << ", "; 1503 Str << ", ";
1503 Dest->emit(Func); 1504 Dest->emit(Func);
(...skipping 16 matching lines...) Expand all
1520 Str << " = shld." << getDest()->getType() << " "; 1521 Str << " = shld." << getDest()->getType() << " ";
1521 dumpSources(Func); 1522 dumpSources(Func);
1522 } 1523 }
1523 1524
1524 void InstX8632Shrd::emit(const Cfg *Func) const { 1525 void InstX8632Shrd::emit(const Cfg *Func) const {
1525 Ostream &Str = Func->getContext()->getStrEmit(); 1526 Ostream &Str = Func->getContext()->getStrEmit();
1526 Variable *Dest = getDest(); 1527 Variable *Dest = getDest();
1527 assert(getSrcSize() == 3); 1528 assert(getSrcSize() == 3);
1528 assert(Dest == getSrc(0)); 1529 assert(Dest == getSrc(0));
1529 Str << "\tshrd" << getWidthString(Dest->getType()) << "\t"; 1530 Str << "\tshrd" << getWidthString(Dest->getType()) << "\t";
1530 if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { 1531 if (const auto ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) {
1531 (void)ShiftReg; 1532 (void)ShiftReg;
1532 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); 1533 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx);
1533 Str << "%cl"; 1534 Str << "%cl";
1534 } else { 1535 } else {
1535 getSrc(2)->emit(Func); 1536 getSrc(2)->emit(Func);
1536 } 1537 }
1537 Str << ", "; 1538 Str << ", ";
1538 getSrc(1)->emit(Func); 1539 getSrc(1)->emit(Func);
1539 Str << ", "; 1540 Str << ", ";
1540 Dest->emit(Func); 1541 Dest->emit(Func);
(...skipping 28 matching lines...) Expand all
1569 getSrc(1)->emit(Func); 1570 getSrc(1)->emit(Func);
1570 Str << ", "; 1571 Str << ", ";
1571 Dest->emit(Func); 1572 Dest->emit(Func);
1572 } 1573 }
1573 1574
1574 void InstX8632Cmov::emitIAS(const Cfg *Func) const { 1575 void InstX8632Cmov::emitIAS(const Cfg *Func) const {
1575 assert(Condition != CondX86::Br_None); 1576 assert(Condition != CondX86::Br_None);
1576 assert(getDest()->hasReg()); 1577 assert(getDest()->hasReg());
1577 assert(getSrcSize() == 2); 1578 assert(getSrcSize() == 2);
1578 // Only need the reg/reg form now. 1579 // Only need the reg/reg form now.
1579 const Variable *Src = llvm::cast<Variable>(getSrc(1)); 1580 const auto SrcVar = llvm::cast<Variable>(getSrc(1));
1580 assert(Src->hasReg()); 1581 assert(SrcVar->hasReg());
1581 assert(Src->getType() == IceType_i32); 1582 assert(SrcVar->getType() == IceType_i32);
1582 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1583 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1583 intptr_t StartPosition = Asm->GetPosition(); 1584 intptr_t StartPosition = Asm->GetPosition();
1584 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()), 1585 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()),
1585 RegX8632::getEncodedGPR(Src->getRegNum())); 1586 RegX8632::getEncodedGPR(SrcVar->getRegNum()));
1586 emitIASBytes(Func, Asm, StartPosition); 1587 emitIASBytes(Func, Asm, StartPosition);
1587 } 1588 }
1588 1589
1589 void InstX8632Cmov::dump(const Cfg *Func) const { 1590 void InstX8632Cmov::dump(const Cfg *Func) const {
1590 Ostream &Str = Func->getContext()->getStrDump(); 1591 Ostream &Str = Func->getContext()->getStrDump();
1591 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; 1592 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << ".";
1592 Str << getDest()->getType() << " "; 1593 Str << getDest()->getType() << " ";
1593 dumpDest(Func); 1594 dumpDest(Func);
1594 Str << ", "; 1595 Str << ", ";
1595 dumpSources(Func); 1596 dumpSources(Func);
(...skipping 12 matching lines...) Expand all
1608 } 1609 }
1609 1610
1610 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { 1611 void InstX8632Cmpps::emitIAS(const Cfg *Func) const {
1611 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1612 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1612 intptr_t StartPosition = Asm->GetPosition(); 1613 intptr_t StartPosition = Asm->GetPosition();
1613 assert(getSrcSize() == 2); 1614 assert(getSrcSize() == 2);
1614 assert(Condition < CondX86::Cmpps_Invalid); 1615 assert(Condition < CondX86::Cmpps_Invalid);
1615 // Assuming there isn't any load folding for cmpps, and vector constants 1616 // Assuming there isn't any load folding for cmpps, and vector constants
1616 // are not allowed in PNaCl. 1617 // are not allowed in PNaCl.
1617 assert(llvm::isa<Variable>(getSrc(1))); 1618 assert(llvm::isa<Variable>(getSrc(1)));
1618 const Variable *SrcVar = llvm::cast<Variable>(getSrc(1)); 1619 const auto SrcVar = llvm::cast<Variable>(getSrc(1));
1619 if (SrcVar->hasReg()) { 1620 if (SrcVar->hasReg()) {
1620 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), 1621 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()),
1621 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); 1622 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition);
1622 } else { 1623 } else {
1623 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) 1624 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget())
1624 ->stackVarToAsmOperand(SrcVar); 1625 ->stackVarToAsmOperand(SrcVar);
1625 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, 1626 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr,
1626 Condition); 1627 Condition);
1627 } 1628 }
1628 emitIASBytes(Func, Asm, StartPosition); 1629 emitIASBytes(Func, Asm, StartPosition);
(...skipping 18 matching lines...) Expand all
1647 getSrc(2)->emit(Func); 1648 getSrc(2)->emit(Func);
1648 Str << ", "; 1649 Str << ", ";
1649 getSrc(0)->emit(Func); 1650 getSrc(0)->emit(Func);
1650 } 1651 }
1651 1652
1652 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { 1653 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const {
1653 assert(getSrcSize() == 3); 1654 assert(getSrcSize() == 3);
1654 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1655 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1655 intptr_t StartPosition = Asm->GetPosition(); 1656 intptr_t StartPosition = Asm->GetPosition();
1656 Type Ty = getSrc(0)->getType(); 1657 Type Ty = getSrc(0)->getType();
1657 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); 1658 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
1658 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 1659 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
1659 const x86::Address Addr = Mem->toAsmAddress(Asm); 1660 const x86::Address Addr = Mem->toAsmAddress(Asm);
1660 const Variable *VarReg = llvm::cast<Variable>(getSrc(2)); 1661 const auto VarReg = llvm::cast<Variable>(getSrc(2));
1661 assert(VarReg->hasReg()); 1662 assert(VarReg->hasReg());
1662 const RegX8632::GPRRegister Reg = 1663 const RegX8632::GPRRegister Reg =
1663 RegX8632::getEncodedGPR(VarReg->getRegNum()); 1664 RegX8632::getEncodedGPR(VarReg->getRegNum());
1664 if (Locked) { 1665 if (Locked) {
1665 Asm->LockCmpxchg(Ty, Addr, Reg); 1666 Asm->LockCmpxchg(Ty, Addr, Reg);
1666 } else { 1667 } else {
1667 Asm->cmpxchg(Ty, Addr, Reg); 1668 Asm->cmpxchg(Ty, Addr, Reg);
1668 } 1669 }
1669 emitIASBytes(Func, Asm, StartPosition); 1670 emitIASBytes(Func, Asm, StartPosition);
1670 } 1671 }
(...skipping 14 matching lines...) Expand all
1685 Str << "\tlock"; 1686 Str << "\tlock";
1686 } 1687 }
1687 Str << "\tcmpxchg8b\t"; 1688 Str << "\tcmpxchg8b\t";
1688 getSrc(0)->emit(Func); 1689 getSrc(0)->emit(Func);
1689 } 1690 }
1690 1691
1691 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { 1692 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const {
1692 assert(getSrcSize() == 5); 1693 assert(getSrcSize() == 5);
1693 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1694 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1694 intptr_t StartPosition = Asm->GetPosition(); 1695 intptr_t StartPosition = Asm->GetPosition();
1695 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); 1696 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
1696 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 1697 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
1697 const x86::Address Addr = Mem->toAsmAddress(Asm); 1698 const x86::Address Addr = Mem->toAsmAddress(Asm);
1698 if (Locked) { 1699 if (Locked) {
1699 Asm->lock(); 1700 Asm->lock();
1700 } 1701 }
1701 Asm->cmpxchg8b(Addr); 1702 Asm->cmpxchg8b(Addr);
1702 emitIASBytes(Func, Asm, StartPosition); 1703 emitIASBytes(Func, Asm, StartPosition);
1703 } 1704 }
1704 1705
1705 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { 1706 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const {
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1837 getSrc(1)->emit(Func); 1838 getSrc(1)->emit(Func);
1838 Str << ", "; 1839 Str << ", ";
1839 getSrc(0)->emit(Func); 1840 getSrc(0)->emit(Func);
1840 } 1841 }
1841 1842
1842 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const { 1843 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const {
1843 assert(getSrcSize() == 2); 1844 assert(getSrcSize() == 2);
1844 // Currently src0 is always a variable by convention, to avoid having 1845 // Currently src0 is always a variable by convention, to avoid having
1845 // two memory operands. 1846 // two memory operands.
1846 assert(llvm::isa<Variable>(getSrc(0))); 1847 assert(llvm::isa<Variable>(getSrc(0)));
1847 const Variable *Src0 = llvm::cast<Variable>(getSrc(0)); 1848 const auto Src0 = llvm::cast<Variable>(getSrc(0));
Jim Stichnoth 2014/11/04 17:41:25 rename Src0Var or SrcVar?
jvoung (off chromium) 2014/11/04 18:22:34 Done.
1848 Type Ty = Src0->getType(); 1849 Type Ty = Src0->getType();
1849 const static x86::AssemblerX86::XmmEmitterRegOp Emitter = { 1850 const static x86::AssemblerX86::XmmEmitterRegOp Emitter = {
1850 &x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss 1851 &x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss
1851 }; 1852 };
1852 emitIASRegOpTyXMM(Func, Ty, Src0, getSrc(1), Emitter); 1853 emitIASRegOpTyXMM(Func, Ty, Src0, getSrc(1), Emitter);
1853 } 1854 }
1854 1855
1855 void InstX8632Ucomiss::dump(const Cfg *Func) const { 1856 void InstX8632Ucomiss::dump(const Cfg *Func) const {
1856 Ostream &Str = Func->getContext()->getStrDump(); 1857 Ostream &Str = Func->getContext()->getStrDump();
1857 Str << "ucomiss." << getSrc(0)->getType() << " "; 1858 Str << "ucomiss." << getSrc(0)->getType() << " ";
(...skipping 27 matching lines...) Expand all
1885 getSrc(0)->emit(Func); 1886 getSrc(0)->emit(Func);
1886 } 1887 }
1887 1888
1888 void InstX8632Test::emitIAS(const Cfg *Func) const { 1889 void InstX8632Test::emitIAS(const Cfg *Func) const {
1889 assert(getSrcSize() == 2); 1890 assert(getSrcSize() == 2);
1890 const Operand *Src0 = getSrc(0); 1891 const Operand *Src0 = getSrc(0);
1891 const Operand *Src1 = getSrc(1); 1892 const Operand *Src1 = getSrc(1);
1892 Type Ty = Src0->getType(); 1893 Type Ty = Src0->getType();
1893 // The Reg/Addr form of test is not encodeable. 1894 // The Reg/Addr form of test is not encodeable.
1894 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { 1895 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = {
1895 &x86::AssemblerX86::test, NULL, &x86::AssemblerX86::test 1896 &x86::AssemblerX86::test, nullptr, &x86::AssemblerX86::test
1896 }; 1897 };
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 }
(...skipping 36 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 VSrc0 = llvm::dyn_cast<Variable>(Src0)) {
Jim Stichnoth 2014/11/04 17:41:25 rename Src0Var or SrcVar?
jvoung (off chromium) 2014/11/04 18:22:34 Done.
2054 Type Ty = VSrc0->getType(); 2055 Type Ty = VSrc0->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 VSrc0->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 }
(...skipping 70 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 160 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 VSrc1 = llvm::dyn_cast<Variable>(Src1)) {
Jim Stichnoth 2014/11/04 17:41:25 rename Src1Var?
jvoung (off chromium) 2014/11/04 18:22:34 Done.
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 (VSrc1->hasReg()) {
2510 VSrc1->asType(IceType_i32).emit(Func); 2511 VSrc1->asType(IceType_i32).emit(Func);
2511 } else { 2512 } else {
2512 VSrc1->emit(Func); 2513 VSrc1->emit(Func);
2513 } 2514 }
2514 } else { 2515 } else {
2515 Src1->emit(Func); 2516 Src1->emit(Func);
2516 } 2517 }
2517 Str << ", "; 2518 Str << ", ";
(...skipping 88 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==NULL.
2760 if (Offset == NULL) { 2761 if (Offset == NULL) {
2761 // No offset, emit nothing. 2762 // No offset, emit nothing.
2762 } else if (auto CI = llvm::dyn_cast<ConstantInteger32>(Offset)) { 2763 } else if (auto CI = llvm::dyn_cast<ConstantInteger32>(Offset)) {
Jim Stichnoth 2014/11/04 17:41:25 const auto?
jvoung (off chromium) 2014/11/04 18:22:34 Done.
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 (auto CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) {
Jim Stichnoth 2014/11/04 17:41:25 const auto?
jvoung (off chromium) 2014/11/04 18:22:34 Done.
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 28 matching lines...) Expand all
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 == NULL) {
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