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) { |
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 || LastFixup->position() == LastFixupLoc); |
386 } | 386 } |
387 for (intptr_t i = LastFixupLoc; i < EndPosition; ++i) { | 387 for (intptr_t i = LastFixupLoc; i < EndPosition; ++i) { |
388 Str << "\t.byte 0x"; | 388 Str << "\t.byte 0x"; |
389 Str.write_hex(Asm->LoadBuffer<uint8_t>(i)); | 389 Str.write_hex(Asm->LoadBuffer<uint8_t>(i)); |
390 Str << "\n"; | 390 Str << "\n"; |
391 } | 391 } |
392 } | 392 } |
393 | 393 |
394 void emitIASBytesBranch(const Cfg *Func, const x86::AssemblerX86 *Asm, | 394 void emitIASBytesBranch(const Cfg *Func, const x86::AssemblerX86 *Asm, |
395 intptr_t StartPosition, const x86::Label *Label, | 395 intptr_t StartPosition, const x86::Label *Label, |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after 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 (const auto CallTarget = |
| 539 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) { |
539 // TODO(stichnot): All constant targets should suppress the '$', | 540 // TODO(stichnot): All constant targets should suppress the '$', |
540 // not just relocatables. | 541 // not just relocatables. |
541 CallTarget->emitWithoutDollar(Func->getContext()); | 542 CallTarget->emitWithoutDollar(Func->getContext()); |
542 } else { | 543 } else { |
543 Str << "*"; | 544 Str << "*"; |
544 getCallTarget()->emit(Func); | 545 getCallTarget()->emit(Func); |
545 } | 546 } |
546 Func->getTarget()->resetStackAdjustment(); | 547 Func->getTarget()->resetStackAdjustment(); |
547 } | 548 } |
548 | 549 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 // Opcode parameter needs to be char* and not IceString because of | 609 // Opcode parameter needs to be char* and not IceString because of |
609 // template issues. | 610 // template issues. |
610 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, | 611 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, |
611 bool ShiftHack) { | 612 bool ShiftHack) { |
612 Ostream &Str = Func->getContext()->getStrEmit(); | 613 Ostream &Str = Func->getContext()->getStrEmit(); |
613 assert(Inst->getSrcSize() == 2); | 614 assert(Inst->getSrcSize() == 2); |
614 Variable *Dest = Inst->getDest(); | 615 Variable *Dest = Inst->getDest(); |
615 assert(Dest == Inst->getSrc(0)); | 616 assert(Dest == Inst->getSrc(0)); |
616 Operand *Src1 = Inst->getSrc(1); | 617 Operand *Src1 = Inst->getSrc(1); |
617 Str << "\t" << Opcode << InstX8632::getWidthString(Dest->getType()) << "\t"; | 618 Str << "\t" << Opcode << InstX8632::getWidthString(Dest->getType()) << "\t"; |
618 Variable *ShiftReg = llvm::dyn_cast<Variable>(Src1); | 619 const auto ShiftReg = llvm::dyn_cast<Variable>(Src1); |
619 if (ShiftHack && ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx) | 620 if (ShiftHack && ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx) |
620 Str << "%cl"; | 621 Str << "%cl"; |
621 else | 622 else |
622 Src1->emit(Func); | 623 Src1->emit(Func); |
623 Str << ", "; | 624 Str << ", "; |
624 Dest->emit(Func); | 625 Dest->emit(Func); |
625 } | 626 } |
626 | 627 |
627 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op, | 628 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op, |
628 const x86::AssemblerX86::GPREmitterOneOp &Emitter) { | 629 const x86::AssemblerX86::GPREmitterOneOp &Emitter) { |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
757 } | 758 } |
758 | 759 |
759 void emitIASGPRShiftDouble(const Cfg *Func, const Variable *Dest, | 760 void emitIASGPRShiftDouble(const Cfg *Func, const Variable *Dest, |
760 const Operand *Src1Op, const Operand *Src2Op, | 761 const Operand *Src1Op, const Operand *Src2Op, |
761 const x86::AssemblerX86::GPREmitterShiftD &Emitter) { | 762 const x86::AssemblerX86::GPREmitterShiftD &Emitter) { |
762 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 763 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
763 intptr_t StartPosition = Asm->GetPosition(); | 764 intptr_t StartPosition = Asm->GetPosition(); |
764 // Dest can be reg or mem, but we only use the reg variant. | 765 // Dest can be reg or mem, but we only use the reg variant. |
765 assert(Dest->hasReg()); | 766 assert(Dest->hasReg()); |
766 RegX8632::GPRRegister DestReg = RegX8632::getEncodedGPR(Dest->getRegNum()); | 767 RegX8632::GPRRegister DestReg = RegX8632::getEncodedGPR(Dest->getRegNum()); |
767 // Src1 must be reg. | 768 // SrcVar1 must be reg. |
768 const auto Src1 = llvm::cast<Variable>(Src1Op); | 769 const auto SrcVar1 = llvm::cast<Variable>(Src1Op); |
769 assert(Src1->hasReg()); | 770 assert(SrcVar1->hasReg()); |
770 RegX8632::GPRRegister SrcReg = RegX8632::getEncodedGPR(Src1->getRegNum()); | 771 RegX8632::GPRRegister SrcReg = RegX8632::getEncodedGPR(SrcVar1->getRegNum()); |
771 Type Ty = Src1->getType(); | 772 Type Ty = SrcVar1->getType(); |
772 // Src2 can be the implicit CL register or an immediate. | 773 // Src2 can be the implicit CL register or an immediate. |
773 if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src2Op)) { | 774 if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src2Op)) { |
774 (Asm->*(Emitter.GPRGPRImm))(Ty, DestReg, SrcReg, | 775 (Asm->*(Emitter.GPRGPRImm))(Ty, DestReg, SrcReg, |
775 x86::Immediate(Imm->getValue())); | 776 x86::Immediate(Imm->getValue())); |
776 } else { | 777 } else { |
777 assert(llvm::cast<Variable>(Src2Op)->getRegNum() == RegX8632::Reg_ecx); | 778 assert(llvm::cast<Variable>(Src2Op)->getRegNum() == RegX8632::Reg_ecx); |
778 (Asm->*(Emitter.GPRGPR))(Ty, DestReg, SrcReg); | 779 (Asm->*(Emitter.GPRGPR))(Ty, DestReg, SrcReg); |
779 } | 780 } |
780 emitIASBytes(Func, Asm, StartPosition); | 781 emitIASBytes(Func, Asm, StartPosition); |
781 } | 782 } |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
914 } else if (const auto SrcMem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 915 } else if (const auto SrcMem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
915 assert(SrcMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 916 assert(SrcMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
916 (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm)); | 917 (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm)); |
917 } else { | 918 } else { |
918 llvm_unreachable("Unexpected operand type"); | 919 llvm_unreachable("Unexpected operand type"); |
919 } | 920 } |
920 } else { | 921 } else { |
921 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 922 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
922 ->stackVarToAsmOperand(Dest)); | 923 ->stackVarToAsmOperand(Dest)); |
923 // Src must be a register in this case. | 924 // Src must be a register in this case. |
924 const Variable *SrcVar = llvm::cast<Variable>(Src); | 925 const auto SrcVar = llvm::cast<Variable>(Src); |
925 assert(SrcVar->hasReg()); | 926 assert(SrcVar->hasReg()); |
926 (Asm->*(Emitter.AddrXmm))(StackAddr, | 927 (Asm->*(Emitter.AddrXmm))(StackAddr, |
927 RegX8632::getEncodedXmm(SrcVar->getRegNum())); | 928 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
928 } | 929 } |
929 emitIASBytes(Func, Asm, StartPosition); | 930 emitIASBytes(Func, Asm, StartPosition); |
930 } | 931 } |
931 | 932 |
932 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) { | 933 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) { |
933 const Variable *Src = llvm::dyn_cast<const Variable>(Source); | 934 const auto SrcVar = llvm::dyn_cast<const Variable>(Source); |
934 if (Src == NULL) | 935 if (!SrcVar) |
935 return false; | 936 return false; |
936 if (Dest->hasReg() && Dest->getRegNum() == Src->getRegNum()) { | 937 if (Dest->hasReg() && Dest->getRegNum() == SrcVar->getRegNum()) { |
937 // TODO: On x86-64, instructions like "mov eax, eax" are used to | 938 // TODO: On x86-64, instructions like "mov eax, eax" are used to |
938 // clear the upper 32 bits of rax. We need to recognize and | 939 // clear the upper 32 bits of rax. We need to recognize and |
939 // preserve these. | 940 // preserve these. |
940 return true; | 941 return true; |
941 } | 942 } |
942 if (!Dest->hasReg() && !Src->hasReg() && | 943 if (!Dest->hasReg() && !SrcVar->hasReg() && |
943 Dest->getStackOffset() == Src->getStackOffset()) | 944 Dest->getStackOffset() == SrcVar->getStackOffset()) |
944 return true; | 945 return true; |
945 return false; | 946 return false; |
946 } | 947 } |
947 | 948 |
948 // In-place ops | 949 // In-place ops |
949 template <> const char *InstX8632Bswap::Opcode = "bswap"; | 950 template <> const char *InstX8632Bswap::Opcode = "bswap"; |
950 template <> const char *InstX8632Neg::Opcode = "neg"; | 951 template <> const char *InstX8632Neg::Opcode = "neg"; |
951 // Unary ops | 952 // Unary ops |
952 template <> const char *InstX8632Bsf::Opcode = "bsf"; | 953 template <> const char *InstX8632Bsf::Opcode = "bsf"; |
953 template <> const char *InstX8632Bsr::Opcode = "bsr"; | 954 template <> const char *InstX8632Bsr::Opcode = "bsr"; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1003 template <> const char *InstX8632Pinsr::Opcode = "pinsr"; | 1004 template <> const char *InstX8632Pinsr::Opcode = "pinsr"; |
1004 template <> const char *InstX8632Blendvps::Opcode = "blendvps"; | 1005 template <> const char *InstX8632Blendvps::Opcode = "blendvps"; |
1005 template <> const char *InstX8632Pblendvb::Opcode = "pblendvb"; | 1006 template <> const char *InstX8632Pblendvb::Opcode = "pblendvb"; |
1006 // Three address ops | 1007 // Three address ops |
1007 template <> const char *InstX8632Pextr::Opcode = "pextr"; | 1008 template <> const char *InstX8632Pextr::Opcode = "pextr"; |
1008 template <> const char *InstX8632Pshufd::Opcode = "pshufd"; | 1009 template <> const char *InstX8632Pshufd::Opcode = "pshufd"; |
1009 | 1010 |
1010 // Inplace GPR ops | 1011 // Inplace GPR ops |
1011 template <> | 1012 template <> |
1012 const x86::AssemblerX86::GPREmitterOneOp InstX8632Bswap::Emitter = { | 1013 const x86::AssemblerX86::GPREmitterOneOp InstX8632Bswap::Emitter = { |
1013 &x86::AssemblerX86::bswap, NULL /* only a reg form exists */}; | 1014 &x86::AssemblerX86::bswap, nullptr /* only a reg form exists */}; |
1014 template <> | 1015 template <> |
1015 const x86::AssemblerX86::GPREmitterOneOp InstX8632Neg::Emitter = { | 1016 const x86::AssemblerX86::GPREmitterOneOp InstX8632Neg::Emitter = { |
1016 &x86::AssemblerX86::neg, &x86::AssemblerX86::neg}; | 1017 &x86::AssemblerX86::neg, &x86::AssemblerX86::neg}; |
1017 | 1018 |
1018 // Unary GPR ops | 1019 // Unary GPR ops |
1019 template <> | 1020 template <> |
1020 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsf::Emitter = { | 1021 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsf::Emitter = { |
1021 &x86::AssemblerX86::bsf, &x86::AssemblerX86::bsf, NULL}; | 1022 &x86::AssemblerX86::bsf, &x86::AssemblerX86::bsf, nullptr}; |
1022 template <> | 1023 template <> |
1023 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsr::Emitter = { | 1024 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsr::Emitter = { |
1024 &x86::AssemblerX86::bsr, &x86::AssemblerX86::bsr, NULL}; | 1025 &x86::AssemblerX86::bsr, &x86::AssemblerX86::bsr, nullptr}; |
1025 template <> | 1026 template <> |
1026 const x86::AssemblerX86::GPREmitterRegOp InstX8632Lea::Emitter = { | 1027 const x86::AssemblerX86::GPREmitterRegOp InstX8632Lea::Emitter = { |
1027 /* reg/reg and reg/imm are illegal */ NULL, &x86::AssemblerX86::lea, NULL}; | 1028 /* reg/reg and reg/imm are illegal */ nullptr, &x86::AssemblerX86::lea, |
| 1029 nullptr}; |
1028 template <> | 1030 template <> |
1029 const x86::AssemblerX86::GPREmitterRegOp InstX8632Movsx::Emitter = { | 1031 const x86::AssemblerX86::GPREmitterRegOp InstX8632Movsx::Emitter = { |
1030 &x86::AssemblerX86::movsx, &x86::AssemblerX86::movsx, NULL}; | 1032 &x86::AssemblerX86::movsx, &x86::AssemblerX86::movsx, nullptr}; |
1031 template <> | 1033 template <> |
1032 const x86::AssemblerX86::GPREmitterRegOp InstX8632Movzx::Emitter = { | 1034 const x86::AssemblerX86::GPREmitterRegOp InstX8632Movzx::Emitter = { |
1033 &x86::AssemblerX86::movzx, &x86::AssemblerX86::movzx, NULL}; | 1035 &x86::AssemblerX86::movzx, &x86::AssemblerX86::movzx, nullptr}; |
1034 | 1036 |
1035 // Unary XMM ops | 1037 // Unary XMM ops |
1036 template <> | 1038 template <> |
1037 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Sqrtss::Emitter = { | 1039 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Sqrtss::Emitter = { |
1038 &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss | 1040 &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss |
1039 }; | 1041 }; |
1040 | 1042 |
1041 // Binary GPR ops | 1043 // Binary GPR ops |
1042 template <> | 1044 template <> |
1043 const x86::AssemblerX86::GPREmitterRegOp InstX8632Add::Emitter = { | 1045 const x86::AssemblerX86::GPREmitterRegOp InstX8632Add::Emitter = { |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1340 &x86::AssemblerX86::pblendvb, &x86::AssemblerX86::pblendvb}; | 1342 &x86::AssemblerX86::pblendvb, &x86::AssemblerX86::pblendvb}; |
1341 emitIASVariableBlendInst(this, Func, Emitter); | 1343 emitIASVariableBlendInst(this, Func, Emitter); |
1342 } | 1344 } |
1343 | 1345 |
1344 template <> void InstX8632Imul::emit(const Cfg *Func) const { | 1346 template <> void InstX8632Imul::emit(const Cfg *Func) const { |
1345 Ostream &Str = Func->getContext()->getStrEmit(); | 1347 Ostream &Str = Func->getContext()->getStrEmit(); |
1346 assert(getSrcSize() == 2); | 1348 assert(getSrcSize() == 2); |
1347 Variable *Dest = getDest(); | 1349 Variable *Dest = getDest(); |
1348 if (isByteSizedArithType(Dest->getType())) { | 1350 if (isByteSizedArithType(Dest->getType())) { |
1349 // The 8-bit version of imul only allows the form "imul r/m8". | 1351 // The 8-bit version of imul only allows the form "imul r/m8". |
1350 Variable *Src0 = llvm::dyn_cast<Variable>(getSrc(0)); | 1352 const auto Src0Var = llvm::dyn_cast<Variable>(getSrc(0)); |
1351 (void)Src0; | 1353 (void)Src0Var; |
1352 assert(Src0 && Src0->getRegNum() == RegX8632::Reg_eax); | 1354 assert(Src0Var && Src0Var->getRegNum() == RegX8632::Reg_eax); |
1353 Str << "\timulb\t"; | 1355 Str << "\timulb\t"; |
1354 getSrc(1)->emit(Func); | 1356 getSrc(1)->emit(Func); |
1355 } else if (llvm::isa<Constant>(getSrc(1))) { | 1357 } else if (llvm::isa<Constant>(getSrc(1))) { |
1356 Str << "\timul" << getWidthString(Dest->getType()) << "\t"; | 1358 Str << "\timul" << getWidthString(Dest->getType()) << "\t"; |
1357 getSrc(1)->emit(Func); | 1359 getSrc(1)->emit(Func); |
1358 Str << ", "; | 1360 Str << ", "; |
1359 getSrc(0)->emit(Func); | 1361 getSrc(0)->emit(Func); |
1360 Str << ", "; | 1362 Str << ", "; |
1361 Dest->emit(Func); | 1363 Dest->emit(Func); |
1362 } else { | 1364 } else { |
1363 emitTwoAddress("imul", this, Func); | 1365 emitTwoAddress("imul", this, Func); |
1364 } | 1366 } |
1365 } | 1367 } |
1366 | 1368 |
1367 template <> void InstX8632Imul::emitIAS(const Cfg *Func) const { | 1369 template <> void InstX8632Imul::emitIAS(const Cfg *Func) const { |
1368 assert(getSrcSize() == 2); | 1370 assert(getSrcSize() == 2); |
1369 const Variable *Var = getDest(); | 1371 const Variable *Var = getDest(); |
1370 Type Ty = Var->getType(); | 1372 Type Ty = Var->getType(); |
1371 const Operand *Src = getSrc(1); | 1373 const Operand *Src = getSrc(1); |
1372 if (isByteSizedArithType(Ty)) { | 1374 if (isByteSizedArithType(Ty)) { |
1373 // The 8-bit version of imul only allows the form "imul r/m8". | 1375 // The 8-bit version of imul only allows the form "imul r/m8". |
1374 Variable *Src0 = llvm::dyn_cast<Variable>(getSrc(0)); | 1376 const auto Src0Var = llvm::dyn_cast<Variable>(getSrc(0)); |
1375 (void)Src0; | 1377 (void)Src0Var; |
1376 assert(Src0 && Src0->getRegNum() == RegX8632::Reg_eax); | 1378 assert(Src0Var && Src0Var->getRegNum() == RegX8632::Reg_eax); |
1377 const x86::AssemblerX86::GPREmitterOneOp Emitter = { | 1379 const x86::AssemblerX86::GPREmitterOneOp Emitter = { |
1378 &x86::AssemblerX86::imul, &x86::AssemblerX86::imul}; | 1380 &x86::AssemblerX86::imul, &x86::AssemblerX86::imul}; |
1379 emitIASOpTyGPR(Func, Ty, getSrc(1), Emitter); | 1381 emitIASOpTyGPR(Func, Ty, getSrc(1), Emitter); |
1380 } else { | 1382 } else { |
1381 // We only use imul as a two-address instruction even though | 1383 // We only use imul as a two-address instruction even though |
1382 // there is a 3 operand version when one of the operands is a constant. | 1384 // there is a 3 operand version when one of the operands is a constant. |
1383 assert(Var == getSrc(0)); | 1385 assert(Var == getSrc(0)); |
1384 const x86::AssemblerX86::GPREmitterRegOp Emitter = { | 1386 const x86::AssemblerX86::GPREmitterRegOp Emitter = { |
1385 &x86::AssemblerX86::imul, &x86::AssemblerX86::imul, | 1387 &x86::AssemblerX86::imul, &x86::AssemblerX86::imul, |
1386 &x86::AssemblerX86::imul}; | 1388 &x86::AssemblerX86::imul}; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1452 Asm->cdq(); | 1454 Asm->cdq(); |
1453 break; | 1455 break; |
1454 } | 1456 } |
1455 emitIASBytes(Func, Asm, StartPosition); | 1457 emitIASBytes(Func, Asm, StartPosition); |
1456 } | 1458 } |
1457 | 1459 |
1458 void InstX8632Mul::emit(const Cfg *Func) const { | 1460 void InstX8632Mul::emit(const Cfg *Func) const { |
1459 Ostream &Str = Func->getContext()->getStrEmit(); | 1461 Ostream &Str = Func->getContext()->getStrEmit(); |
1460 assert(getSrcSize() == 2); | 1462 assert(getSrcSize() == 2); |
1461 assert(llvm::isa<Variable>(getSrc(0))); | 1463 assert(llvm::isa<Variable>(getSrc(0))); |
1462 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); | 1464 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); |
1463 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? | 1465 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? |
1464 Str << "\tmul" << getWidthString(getDest()->getType()) << "\t"; | 1466 Str << "\tmul" << getWidthString(getDest()->getType()) << "\t"; |
1465 getSrc(1)->emit(Func); | 1467 getSrc(1)->emit(Func); |
1466 } | 1468 } |
1467 | 1469 |
1468 void InstX8632Mul::emitIAS(const Cfg *Func) const { | 1470 void InstX8632Mul::emitIAS(const Cfg *Func) const { |
1469 assert(getSrcSize() == 2); | 1471 assert(getSrcSize() == 2); |
1470 assert(llvm::isa<Variable>(getSrc(0))); | 1472 assert(llvm::isa<Variable>(getSrc(0))); |
1471 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); | 1473 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); |
1472 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? | 1474 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? |
1473 const Operand *Src = getSrc(1); | 1475 const Operand *Src = getSrc(1); |
1474 Type Ty = Src->getType(); | 1476 Type Ty = Src->getType(); |
1475 const static x86::AssemblerX86::GPREmitterOneOp Emitter = { | 1477 const static x86::AssemblerX86::GPREmitterOneOp Emitter = { |
1476 &x86::AssemblerX86::mul, &x86::AssemblerX86::mul}; | 1478 &x86::AssemblerX86::mul, &x86::AssemblerX86::mul}; |
1477 emitIASOpTyGPR(Func, Ty, Src, Emitter); | 1479 emitIASOpTyGPR(Func, Ty, Src, Emitter); |
1478 } | 1480 } |
1479 | 1481 |
1480 void InstX8632Mul::dump(const Cfg *Func) const { | 1482 void InstX8632Mul::dump(const Cfg *Func) const { |
1481 Ostream &Str = Func->getContext()->getStrDump(); | 1483 Ostream &Str = Func->getContext()->getStrDump(); |
1482 dumpDest(Func); | 1484 dumpDest(Func); |
1483 Str << " = mul." << getDest()->getType() << " "; | 1485 Str << " = mul." << getDest()->getType() << " "; |
1484 dumpSources(Func); | 1486 dumpSources(Func); |
1485 } | 1487 } |
1486 | 1488 |
1487 void InstX8632Shld::emit(const Cfg *Func) const { | 1489 void InstX8632Shld::emit(const Cfg *Func) const { |
1488 Ostream &Str = Func->getContext()->getStrEmit(); | 1490 Ostream &Str = Func->getContext()->getStrEmit(); |
1489 Variable *Dest = getDest(); | 1491 Variable *Dest = getDest(); |
1490 assert(getSrcSize() == 3); | 1492 assert(getSrcSize() == 3); |
1491 assert(Dest == getSrc(0)); | 1493 assert(Dest == getSrc(0)); |
1492 Str << "\tshld" << getWidthString(Dest->getType()) << "\t"; | 1494 Str << "\tshld" << getWidthString(Dest->getType()) << "\t"; |
1493 if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { | 1495 if (const auto ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { |
1494 (void)ShiftReg; | 1496 (void)ShiftReg; |
1495 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); | 1497 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); |
1496 Str << "%cl"; | 1498 Str << "%cl"; |
1497 } else { | 1499 } else { |
1498 getSrc(2)->emit(Func); | 1500 getSrc(2)->emit(Func); |
1499 } | 1501 } |
1500 Str << ", "; | 1502 Str << ", "; |
1501 getSrc(1)->emit(Func); | 1503 getSrc(1)->emit(Func); |
1502 Str << ", "; | 1504 Str << ", "; |
1503 Dest->emit(Func); | 1505 Dest->emit(Func); |
(...skipping 16 matching lines...) Expand all Loading... |
1520 Str << " = shld." << getDest()->getType() << " "; | 1522 Str << " = shld." << getDest()->getType() << " "; |
1521 dumpSources(Func); | 1523 dumpSources(Func); |
1522 } | 1524 } |
1523 | 1525 |
1524 void InstX8632Shrd::emit(const Cfg *Func) const { | 1526 void InstX8632Shrd::emit(const Cfg *Func) const { |
1525 Ostream &Str = Func->getContext()->getStrEmit(); | 1527 Ostream &Str = Func->getContext()->getStrEmit(); |
1526 Variable *Dest = getDest(); | 1528 Variable *Dest = getDest(); |
1527 assert(getSrcSize() == 3); | 1529 assert(getSrcSize() == 3); |
1528 assert(Dest == getSrc(0)); | 1530 assert(Dest == getSrc(0)); |
1529 Str << "\tshrd" << getWidthString(Dest->getType()) << "\t"; | 1531 Str << "\tshrd" << getWidthString(Dest->getType()) << "\t"; |
1530 if (Variable *ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { | 1532 if (const auto ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { |
1531 (void)ShiftReg; | 1533 (void)ShiftReg; |
1532 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); | 1534 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); |
1533 Str << "%cl"; | 1535 Str << "%cl"; |
1534 } else { | 1536 } else { |
1535 getSrc(2)->emit(Func); | 1537 getSrc(2)->emit(Func); |
1536 } | 1538 } |
1537 Str << ", "; | 1539 Str << ", "; |
1538 getSrc(1)->emit(Func); | 1540 getSrc(1)->emit(Func); |
1539 Str << ", "; | 1541 Str << ", "; |
1540 Dest->emit(Func); | 1542 Dest->emit(Func); |
(...skipping 28 matching lines...) Expand all Loading... |
1569 getSrc(1)->emit(Func); | 1571 getSrc(1)->emit(Func); |
1570 Str << ", "; | 1572 Str << ", "; |
1571 Dest->emit(Func); | 1573 Dest->emit(Func); |
1572 } | 1574 } |
1573 | 1575 |
1574 void InstX8632Cmov::emitIAS(const Cfg *Func) const { | 1576 void InstX8632Cmov::emitIAS(const Cfg *Func) const { |
1575 assert(Condition != CondX86::Br_None); | 1577 assert(Condition != CondX86::Br_None); |
1576 assert(getDest()->hasReg()); | 1578 assert(getDest()->hasReg()); |
1577 assert(getSrcSize() == 2); | 1579 assert(getSrcSize() == 2); |
1578 // Only need the reg/reg form now. | 1580 // Only need the reg/reg form now. |
1579 const Variable *Src = llvm::cast<Variable>(getSrc(1)); | 1581 const auto SrcVar = llvm::cast<Variable>(getSrc(1)); |
1580 assert(Src->hasReg()); | 1582 assert(SrcVar->hasReg()); |
1581 assert(Src->getType() == IceType_i32); | 1583 assert(SrcVar->getType() == IceType_i32); |
1582 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1584 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
1583 intptr_t StartPosition = Asm->GetPosition(); | 1585 intptr_t StartPosition = Asm->GetPosition(); |
1584 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()), | 1586 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()), |
1585 RegX8632::getEncodedGPR(Src->getRegNum())); | 1587 RegX8632::getEncodedGPR(SrcVar->getRegNum())); |
1586 emitIASBytes(Func, Asm, StartPosition); | 1588 emitIASBytes(Func, Asm, StartPosition); |
1587 } | 1589 } |
1588 | 1590 |
1589 void InstX8632Cmov::dump(const Cfg *Func) const { | 1591 void InstX8632Cmov::dump(const Cfg *Func) const { |
1590 Ostream &Str = Func->getContext()->getStrDump(); | 1592 Ostream &Str = Func->getContext()->getStrDump(); |
1591 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; | 1593 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; |
1592 Str << getDest()->getType() << " "; | 1594 Str << getDest()->getType() << " "; |
1593 dumpDest(Func); | 1595 dumpDest(Func); |
1594 Str << ", "; | 1596 Str << ", "; |
1595 dumpSources(Func); | 1597 dumpSources(Func); |
(...skipping 12 matching lines...) Expand all Loading... |
1608 } | 1610 } |
1609 | 1611 |
1610 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { | 1612 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { |
1611 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1613 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
1612 intptr_t StartPosition = Asm->GetPosition(); | 1614 intptr_t StartPosition = Asm->GetPosition(); |
1613 assert(getSrcSize() == 2); | 1615 assert(getSrcSize() == 2); |
1614 assert(Condition < CondX86::Cmpps_Invalid); | 1616 assert(Condition < CondX86::Cmpps_Invalid); |
1615 // Assuming there isn't any load folding for cmpps, and vector constants | 1617 // Assuming there isn't any load folding for cmpps, and vector constants |
1616 // are not allowed in PNaCl. | 1618 // are not allowed in PNaCl. |
1617 assert(llvm::isa<Variable>(getSrc(1))); | 1619 assert(llvm::isa<Variable>(getSrc(1))); |
1618 const Variable *SrcVar = llvm::cast<Variable>(getSrc(1)); | 1620 const auto SrcVar = llvm::cast<Variable>(getSrc(1)); |
1619 if (SrcVar->hasReg()) { | 1621 if (SrcVar->hasReg()) { |
1620 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), | 1622 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), |
1621 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); | 1623 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); |
1622 } else { | 1624 } else { |
1623 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 1625 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) |
1624 ->stackVarToAsmOperand(SrcVar); | 1626 ->stackVarToAsmOperand(SrcVar); |
1625 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, | 1627 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, |
1626 Condition); | 1628 Condition); |
1627 } | 1629 } |
1628 emitIASBytes(Func, Asm, StartPosition); | 1630 emitIASBytes(Func, Asm, StartPosition); |
(...skipping 18 matching lines...) Expand all Loading... |
1647 getSrc(2)->emit(Func); | 1649 getSrc(2)->emit(Func); |
1648 Str << ", "; | 1650 Str << ", "; |
1649 getSrc(0)->emit(Func); | 1651 getSrc(0)->emit(Func); |
1650 } | 1652 } |
1651 | 1653 |
1652 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { | 1654 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { |
1653 assert(getSrcSize() == 3); | 1655 assert(getSrcSize() == 3); |
1654 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1656 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
1655 intptr_t StartPosition = Asm->GetPosition(); | 1657 intptr_t StartPosition = Asm->GetPosition(); |
1656 Type Ty = getSrc(0)->getType(); | 1658 Type Ty = getSrc(0)->getType(); |
1657 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 1659 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
1658 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 1660 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
1659 const x86::Address Addr = Mem->toAsmAddress(Asm); | 1661 const x86::Address Addr = Mem->toAsmAddress(Asm); |
1660 const Variable *VarReg = llvm::cast<Variable>(getSrc(2)); | 1662 const auto VarReg = llvm::cast<Variable>(getSrc(2)); |
1661 assert(VarReg->hasReg()); | 1663 assert(VarReg->hasReg()); |
1662 const RegX8632::GPRRegister Reg = | 1664 const RegX8632::GPRRegister Reg = |
1663 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 1665 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
1664 if (Locked) { | 1666 if (Locked) { |
1665 Asm->LockCmpxchg(Ty, Addr, Reg); | 1667 Asm->LockCmpxchg(Ty, Addr, Reg); |
1666 } else { | 1668 } else { |
1667 Asm->cmpxchg(Ty, Addr, Reg); | 1669 Asm->cmpxchg(Ty, Addr, Reg); |
1668 } | 1670 } |
1669 emitIASBytes(Func, Asm, StartPosition); | 1671 emitIASBytes(Func, Asm, StartPosition); |
1670 } | 1672 } |
(...skipping 14 matching lines...) Expand all Loading... |
1685 Str << "\tlock"; | 1687 Str << "\tlock"; |
1686 } | 1688 } |
1687 Str << "\tcmpxchg8b\t"; | 1689 Str << "\tcmpxchg8b\t"; |
1688 getSrc(0)->emit(Func); | 1690 getSrc(0)->emit(Func); |
1689 } | 1691 } |
1690 | 1692 |
1691 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { | 1693 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { |
1692 assert(getSrcSize() == 5); | 1694 assert(getSrcSize() == 5); |
1693 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1695 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
1694 intptr_t StartPosition = Asm->GetPosition(); | 1696 intptr_t StartPosition = Asm->GetPosition(); |
1695 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 1697 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
1696 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 1698 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
1697 const x86::Address Addr = Mem->toAsmAddress(Asm); | 1699 const x86::Address Addr = Mem->toAsmAddress(Asm); |
1698 if (Locked) { | 1700 if (Locked) { |
1699 Asm->lock(); | 1701 Asm->lock(); |
1700 } | 1702 } |
1701 Asm->cmpxchg8b(Addr); | 1703 Asm->cmpxchg8b(Addr); |
1702 emitIASBytes(Func, Asm, StartPosition); | 1704 emitIASBytes(Func, Asm, StartPosition); |
1703 } | 1705 } |
1704 | 1706 |
1705 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { | 1707 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1837 getSrc(1)->emit(Func); | 1839 getSrc(1)->emit(Func); |
1838 Str << ", "; | 1840 Str << ", "; |
1839 getSrc(0)->emit(Func); | 1841 getSrc(0)->emit(Func); |
1840 } | 1842 } |
1841 | 1843 |
1842 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const { | 1844 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const { |
1843 assert(getSrcSize() == 2); | 1845 assert(getSrcSize() == 2); |
1844 // Currently src0 is always a variable by convention, to avoid having | 1846 // Currently src0 is always a variable by convention, to avoid having |
1845 // two memory operands. | 1847 // two memory operands. |
1846 assert(llvm::isa<Variable>(getSrc(0))); | 1848 assert(llvm::isa<Variable>(getSrc(0))); |
1847 const Variable *Src0 = llvm::cast<Variable>(getSrc(0)); | 1849 const auto Src0Var = llvm::cast<Variable>(getSrc(0)); |
1848 Type Ty = Src0->getType(); | 1850 Type Ty = Src0Var->getType(); |
1849 const static x86::AssemblerX86::XmmEmitterRegOp Emitter = { | 1851 const static x86::AssemblerX86::XmmEmitterRegOp Emitter = { |
1850 &x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss | 1852 &x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss |
1851 }; | 1853 }; |
1852 emitIASRegOpTyXMM(Func, Ty, Src0, getSrc(1), Emitter); | 1854 emitIASRegOpTyXMM(Func, Ty, Src0Var, getSrc(1), Emitter); |
1853 } | 1855 } |
1854 | 1856 |
1855 void InstX8632Ucomiss::dump(const Cfg *Func) const { | 1857 void InstX8632Ucomiss::dump(const Cfg *Func) const { |
1856 Ostream &Str = Func->getContext()->getStrDump(); | 1858 Ostream &Str = Func->getContext()->getStrDump(); |
1857 Str << "ucomiss." << getSrc(0)->getType() << " "; | 1859 Str << "ucomiss." << getSrc(0)->getType() << " "; |
1858 dumpSources(Func); | 1860 dumpSources(Func); |
1859 } | 1861 } |
1860 | 1862 |
1861 void InstX8632UD2::emit(const Cfg *Func) const { | 1863 void InstX8632UD2::emit(const Cfg *Func) const { |
1862 Ostream &Str = Func->getContext()->getStrEmit(); | 1864 Ostream &Str = Func->getContext()->getStrEmit(); |
(...skipping 22 matching lines...) Expand all Loading... |
1885 getSrc(0)->emit(Func); | 1887 getSrc(0)->emit(Func); |
1886 } | 1888 } |
1887 | 1889 |
1888 void InstX8632Test::emitIAS(const Cfg *Func) const { | 1890 void InstX8632Test::emitIAS(const Cfg *Func) const { |
1889 assert(getSrcSize() == 2); | 1891 assert(getSrcSize() == 2); |
1890 const Operand *Src0 = getSrc(0); | 1892 const Operand *Src0 = getSrc(0); |
1891 const Operand *Src1 = getSrc(1); | 1893 const Operand *Src1 = getSrc(1); |
1892 Type Ty = Src0->getType(); | 1894 Type Ty = Src0->getType(); |
1893 // The Reg/Addr form of test is not encodeable. | 1895 // The Reg/Addr form of test is not encodeable. |
1894 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { | 1896 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { |
1895 &x86::AssemblerX86::test, NULL, &x86::AssemblerX86::test | 1897 &x86::AssemblerX86::test, nullptr, &x86::AssemblerX86::test}; |
1896 }; | |
1897 static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = { | 1898 static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = { |
1898 &x86::AssemblerX86::test, &x86::AssemblerX86::test | 1899 &x86::AssemblerX86::test, &x86::AssemblerX86::test |
1899 }; | 1900 }; |
1900 if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { | 1901 if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { |
1901 if (SrcVar0->hasReg()) { | 1902 if (SrcVar0->hasReg()) { |
1902 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); | 1903 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); |
1903 return; | 1904 return; |
1904 } | 1905 } |
1905 } | 1906 } |
1906 llvm_unreachable("Nothing actually generates this so it's untested"); | 1907 llvm_unreachable("Nothing actually generates this so it's untested"); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after 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 Src0Var = llvm::dyn_cast<Variable>(Src0)) { |
2054 Type Ty = VSrc0->getType(); | 2055 Type Ty = Src0Var->getType(); |
2055 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an | 2056 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an |
2056 // acceptable type. | 2057 // acceptable type. |
2057 VSrc0->asType(isVectorType(Ty) ? IceType_i32 : Ty).emit(Func); | 2058 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty).emit(Func); |
2058 } else { | 2059 } else { |
2059 Src0->emit(Func); | 2060 Src0->emit(Func); |
2060 } | 2061 } |
2061 Str << ", "; | 2062 Str << ", "; |
2062 getDest()->emit(Func); | 2063 getDest()->emit(Func); |
2063 } | 2064 } |
2064 | 2065 |
2065 template <> void InstX8632Mov::emit(const Cfg *Func) const { | 2066 template <> void InstX8632Mov::emit(const Cfg *Func) const { |
2066 Ostream &Str = Func->getContext()->getStrEmit(); | 2067 Ostream &Str = Func->getContext()->getStrEmit(); |
2067 assert(getSrcSize() == 1); | 2068 assert(getSrcSize() == 1); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after 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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2356 | 2357 |
2357 void InstX8632Fld::dump(const Cfg *Func) const { | 2358 void InstX8632Fld::dump(const Cfg *Func) const { |
2358 Ostream &Str = Func->getContext()->getStrDump(); | 2359 Ostream &Str = Func->getContext()->getStrDump(); |
2359 Str << "fld." << getSrc(0)->getType() << " "; | 2360 Str << "fld." << getSrc(0)->getType() << " "; |
2360 dumpSources(Func); | 2361 dumpSources(Func); |
2361 } | 2362 } |
2362 | 2363 |
2363 void InstX8632Fstp::emit(const Cfg *Func) const { | 2364 void InstX8632Fstp::emit(const Cfg *Func) const { |
2364 Ostream &Str = Func->getContext()->getStrEmit(); | 2365 Ostream &Str = Func->getContext()->getStrEmit(); |
2365 assert(getSrcSize() == 0); | 2366 assert(getSrcSize() == 0); |
2366 // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to | 2367 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to |
2367 // "partially" delete the fstp if the Dest is unused. | 2368 // "partially" delete the fstp if the Dest is unused. |
2368 // Even if Dest is unused, the fstp should be kept for the SideEffects | 2369 // Even if Dest is unused, the fstp should be kept for the SideEffects |
2369 // of popping the stack. | 2370 // of popping the stack. |
2370 if (getDest() == NULL) { | 2371 if (!getDest()) { |
2371 Str << "\tfstp\tst(0)"; | 2372 Str << "\tfstp\tst(0)"; |
2372 return; | 2373 return; |
2373 } | 2374 } |
2374 Type Ty = getDest()->getType(); | 2375 Type Ty = getDest()->getType(); |
2375 size_t Width = typeWidthInBytes(Ty); | 2376 size_t Width = typeWidthInBytes(Ty); |
2376 if (!getDest()->hasReg()) { | 2377 if (!getDest()->hasReg()) { |
2377 Str << "\tfstp" << getFldString(Ty) << "\t"; | 2378 Str << "\tfstp" << getFldString(Ty) << "\t"; |
2378 getDest()->emit(Func); | 2379 getDest()->emit(Func); |
2379 return; | 2380 return; |
2380 } | 2381 } |
2381 // Dest is a physical (xmm) register, so st(0) needs to go through | 2382 // Dest is a physical (xmm) register, so st(0) needs to go through |
2382 // memory. Hack this by creating a temporary stack slot, spilling | 2383 // memory. Hack this by creating a temporary stack slot, spilling |
2383 // st(0) there, loading it into the xmm register, and deallocating | 2384 // st(0) there, loading it into the xmm register, and deallocating |
2384 // the stack slot. | 2385 // the stack slot. |
2385 Str << "\tsubl\t$" << Width << ", %esp\n"; | 2386 Str << "\tsubl\t$" << Width << ", %esp\n"; |
2386 Str << "\tfstp" << getFldString(Ty) << "\t" | 2387 Str << "\tfstp" << getFldString(Ty) << "\t" |
2387 << "(%esp)\n"; | 2388 << "(%esp)\n"; |
2388 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t" | 2389 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t" |
2389 << "(%esp), "; | 2390 << "(%esp), "; |
2390 getDest()->emit(Func); | 2391 getDest()->emit(Func); |
2391 Str << "\n"; | 2392 Str << "\n"; |
2392 Str << "\taddl\t$" << Width << ", %esp"; | 2393 Str << "\taddl\t$" << Width << ", %esp"; |
2393 } | 2394 } |
2394 | 2395 |
2395 void InstX8632Fstp::emitIAS(const Cfg *Func) const { | 2396 void InstX8632Fstp::emitIAS(const Cfg *Func) const { |
2396 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2397 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
2397 intptr_t StartPosition = Asm->GetPosition(); | 2398 intptr_t StartPosition = Asm->GetPosition(); |
2398 assert(getSrcSize() == 0); | 2399 assert(getSrcSize() == 0); |
2399 const Variable *Dest = getDest(); | 2400 const Variable *Dest = getDest(); |
2400 // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to | 2401 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to |
2401 // "partially" delete the fstp if the Dest is unused. | 2402 // "partially" delete the fstp if the Dest is unused. |
2402 // Even if Dest is unused, the fstp should be kept for the SideEffects | 2403 // Even if Dest is unused, the fstp should be kept for the SideEffects |
2403 // of popping the stack. | 2404 // of popping the stack. |
2404 if (Dest == NULL) { | 2405 if (!Dest) { |
2405 Asm->fstp(RegX8632::getEncodedSTReg(0)); | 2406 Asm->fstp(RegX8632::getEncodedSTReg(0)); |
2406 emitIASBytes(Func, Asm, StartPosition); | 2407 emitIASBytes(Func, Asm, StartPosition); |
2407 return; | 2408 return; |
2408 } | 2409 } |
2409 Type Ty = Dest->getType(); | 2410 Type Ty = Dest->getType(); |
2410 if (!Dest->hasReg()) { | 2411 if (!Dest->hasReg()) { |
2411 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2412 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
2412 ->stackVarToAsmOperand(Dest)); | 2413 ->stackVarToAsmOperand(Dest)); |
2413 Asm->fstp(Ty, StackAddr); | 2414 Asm->fstp(Ty, StackAddr); |
2414 } else { | 2415 } else { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after 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 Src1Var = llvm::dyn_cast<Variable>(Src1)) { |
2508 // If src1 is a register, it should always be r32. | 2509 // If src1 is a register, it should always be r32. |
2509 if (VSrc1->hasReg()) { | 2510 if (Src1Var->hasReg()) { |
2510 VSrc1->asType(IceType_i32).emit(Func); | 2511 Src1Var->asType(IceType_i32).emit(Func); |
2511 } else { | 2512 } else { |
2512 VSrc1->emit(Func); | 2513 Src1Var->emit(Func); |
2513 } | 2514 } |
2514 } else { | 2515 } else { |
2515 Src1->emit(Func); | 2516 Src1->emit(Func); |
2516 } | 2517 } |
2517 Str << ", "; | 2518 Str << ", "; |
2518 getDest()->emit(Func); | 2519 getDest()->emit(Func); |
2519 } | 2520 } |
2520 | 2521 |
2521 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const { | 2522 template <> void InstX8632Pinsr::emitIAS(const Cfg *Func) const { |
2522 assert(getSrcSize() == 3); | 2523 assert(getSrcSize() == 3); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after 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==nullptr. |
2760 if (Offset == NULL) { | 2761 if (!Offset) { |
2761 // No offset, emit nothing. | 2762 // No offset, emit nothing. |
2762 } else if (auto CI = llvm::dyn_cast<ConstantInteger32>(Offset)) { | 2763 } else if (const auto CI = llvm::dyn_cast<ConstantInteger32>(Offset)) { |
2763 if (CI->getValue()) | 2764 if (CI->getValue()) |
2764 // Emit a non-zero offset without a leading '$'. | 2765 // Emit a non-zero offset without a leading '$'. |
2765 Str << CI->getValue(); | 2766 Str << CI->getValue(); |
2766 } else if (auto CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) { | 2767 } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) { |
2767 CR->emitWithoutDollar(Func->getContext()); | 2768 CR->emitWithoutDollar(Func->getContext()); |
2768 } else { | 2769 } else { |
2769 llvm_unreachable("Invalid offset type for x86 mem operand"); | 2770 llvm_unreachable("Invalid offset type for x86 mem operand"); |
2770 } | 2771 } |
2771 | 2772 |
2772 if (Base) { | 2773 if (Base) { |
2773 Str << "("; | 2774 Str << "("; |
2774 Base->emit(Func); | 2775 Base->emit(Func); |
2775 if (Index) { | 2776 if (Index) { |
2776 Str << ","; | 2777 Str << ","; |
(...skipping 26 matching lines...) Expand all Loading... |
2803 Str << (1u << Shift) << "*"; | 2804 Str << (1u << Shift) << "*"; |
2804 if (Func) | 2805 if (Func) |
2805 Index->dump(Func); | 2806 Index->dump(Func); |
2806 else | 2807 else |
2807 Index->dump(Str); | 2808 Index->dump(Str); |
2808 Dumped = true; | 2809 Dumped = true; |
2809 } | 2810 } |
2810 // Pretty-print the Offset. | 2811 // Pretty-print the Offset. |
2811 bool OffsetIsZero = false; | 2812 bool OffsetIsZero = false; |
2812 bool OffsetIsNegative = false; | 2813 bool OffsetIsNegative = false; |
2813 if (Offset == NULL) { | 2814 if (!Offset) { |
2814 OffsetIsZero = true; | 2815 OffsetIsZero = true; |
2815 } else if (ConstantInteger32 *CI = | 2816 } else if (const auto CI = llvm::dyn_cast<ConstantInteger32>(Offset)) { |
2816 llvm::dyn_cast<ConstantInteger32>(Offset)) { | |
2817 OffsetIsZero = (CI->getValue() == 0); | 2817 OffsetIsZero = (CI->getValue() == 0); |
2818 OffsetIsNegative = (static_cast<int32_t>(CI->getValue()) < 0); | 2818 OffsetIsNegative = (static_cast<int32_t>(CI->getValue()) < 0); |
2819 } else { | 2819 } else { |
2820 assert(llvm::isa<ConstantRelocatable>(Offset)); | 2820 assert(llvm::isa<ConstantRelocatable>(Offset)); |
2821 } | 2821 } |
2822 if (Dumped) { | 2822 if (Dumped) { |
2823 if (!OffsetIsZero) { // Suppress if Offset is known to be 0 | 2823 if (!OffsetIsZero) { // Suppress if Offset is known to be 0 |
2824 if (!OffsetIsNegative) // Suppress if Offset is known to be negative | 2824 if (!OffsetIsNegative) // Suppress if Offset is known to be negative |
2825 Str << "+"; | 2825 Str << "+"; |
2826 Offset->dump(Func, Str); | 2826 Offset->dump(Func, Str); |
2827 } | 2827 } |
2828 } else { | 2828 } else { |
2829 // There is only the offset. | 2829 // There is only the offset. |
2830 Offset->dump(Func, Str); | 2830 Offset->dump(Func, Str); |
2831 } | 2831 } |
2832 Str << "]"; | 2832 Str << "]"; |
2833 } | 2833 } |
2834 | 2834 |
2835 void OperandX8632Mem::emitSegmentOverride(x86::AssemblerX86 *Asm) const { | 2835 void OperandX8632Mem::emitSegmentOverride(x86::AssemblerX86 *Asm) const { |
2836 if (SegmentReg != DefaultSegment) { | 2836 if (SegmentReg != DefaultSegment) { |
2837 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); | 2837 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); |
2838 Asm->EmitSegmentOverride(InstX8632SegmentPrefixes[SegmentReg]); | 2838 Asm->EmitSegmentOverride(InstX8632SegmentPrefixes[SegmentReg]); |
2839 } | 2839 } |
2840 } | 2840 } |
2841 | 2841 |
2842 x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const { | 2842 x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const { |
2843 int32_t Disp = 0; | 2843 int32_t Disp = 0; |
2844 AssemblerFixup *Fixup = NULL; | 2844 AssemblerFixup *Fixup = nullptr; |
2845 // Determine the offset (is it relocatable?) | 2845 // Determine the offset (is it relocatable?) |
2846 if (getOffset()) { | 2846 if (getOffset()) { |
2847 if (ConstantInteger32 *CI = | 2847 if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { |
2848 llvm::dyn_cast<ConstantInteger32>(getOffset())) { | |
2849 Disp = static_cast<int32_t>(CI->getValue()); | 2848 Disp = static_cast<int32_t>(CI->getValue()); |
2850 } else if (ConstantRelocatable *CR = | 2849 } else if (const auto CR = |
2851 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { | 2850 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { |
2852 Fixup = x86::DisplacementRelocation::create(Asm, FK_Abs_4, CR); | 2851 Fixup = x86::DisplacementRelocation::create(Asm, FK_Abs_4, CR); |
2853 } else { | 2852 } else { |
2854 llvm_unreachable("Unexpected offset type"); | 2853 llvm_unreachable("Unexpected offset type"); |
2855 } | 2854 } |
2856 } | 2855 } |
2857 | 2856 |
2858 // Now convert to the various possible forms. | 2857 // Now convert to the various possible forms. |
2859 if (getBase() && getIndex()) { | 2858 if (getBase() && getIndex()) { |
2860 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), | 2859 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after 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 |