OLD | NEW |
---|---|
1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// | 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file implements the InstX8632 and OperandX8632 classes, | 10 // This file implements the InstX8632 and OperandX8632 classes, |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |