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 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 } | 364 } |
365 | 365 |
366 void InstX8632Label::emit(const Cfg *Func) const { | 366 void InstX8632Label::emit(const Cfg *Func) const { |
367 if (!ALLOW_DUMP) | 367 if (!ALLOW_DUMP) |
368 return; | 368 return; |
369 Ostream &Str = Func->getContext()->getStrEmit(); | 369 Ostream &Str = Func->getContext()->getStrEmit(); |
370 Str << getName(Func) << ":"; | 370 Str << getName(Func) << ":"; |
371 } | 371 } |
372 | 372 |
373 void InstX8632Label::emitIAS(const Cfg *Func) const { | 373 void InstX8632Label::emitIAS(const Cfg *Func) const { |
374 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 374 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
375 Asm->BindLocalLabel(Number); | 375 Asm->BindLocalLabel(Number); |
376 } | 376 } |
377 | 377 |
378 void InstX8632Label::dump(const Cfg *Func) const { | 378 void InstX8632Label::dump(const Cfg *Func) const { |
379 if (!ALLOW_DUMP) | 379 if (!ALLOW_DUMP) |
380 return; | 380 return; |
381 Ostream &Str = Func->getContext()->getStrDump(); | 381 Ostream &Str = Func->getContext()->getStrDump(); |
382 Str << getName(Func) << ":"; | 382 Str << getName(Func) << ":"; |
383 } | 383 } |
384 | 384 |
(...skipping 17 matching lines...) Expand all Loading... |
402 } else { | 402 } else { |
403 Str << "\t" << getTargetTrue()->getAsmName(); | 403 Str << "\t" << getTargetTrue()->getAsmName(); |
404 if (getTargetFalse()) { | 404 if (getTargetFalse()) { |
405 Str << "\n\tjmp\t" << getTargetFalse()->getAsmName(); | 405 Str << "\n\tjmp\t" << getTargetFalse()->getAsmName(); |
406 } | 406 } |
407 } | 407 } |
408 } | 408 } |
409 } | 409 } |
410 | 410 |
411 void InstX8632Br::emitIAS(const Cfg *Func) const { | 411 void InstX8632Br::emitIAS(const Cfg *Func) const { |
412 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 412 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
413 if (Label) { | 413 if (Label) { |
414 x86::Label *L = Asm->GetOrCreateLocalLabel(Label->getNumber()); | 414 X8632::Label *L = Asm->GetOrCreateLocalLabel(Label->getNumber()); |
415 // In all these cases, local Labels should only be used for Near. | 415 // In all these cases, local Labels should only be used for Near. |
416 const bool Near = true; | 416 const bool Near = true; |
417 if (Condition == CondX86::Br_None) { | 417 if (Condition == CondX86::Br_None) { |
418 Asm->jmp(L, Near); | 418 Asm->jmp(L, Near); |
419 } else { | 419 } else { |
420 Asm->j(Condition, L, Near); | 420 Asm->j(Condition, L, Near); |
421 } | 421 } |
422 } else { | 422 } else { |
423 // Pessimistically assume it's far. This only affects Labels that | 423 // Pessimistically assume it's far. This only affects Labels that |
424 // are not Bound. | 424 // are not Bound. |
425 const bool Near = false; | 425 const bool Near = false; |
426 if (Condition == CondX86::Br_None) { | 426 if (Condition == CondX86::Br_None) { |
427 x86::Label *L = | 427 X8632::Label *L = |
428 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); | 428 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); |
429 assert(!getTargetTrue()); | 429 assert(!getTargetTrue()); |
430 Asm->jmp(L, Near); | 430 Asm->jmp(L, Near); |
431 } else { | 431 } else { |
432 x86::Label *L = Asm->GetOrCreateCfgNodeLabel(getTargetTrue()->getIndex()); | 432 X8632::Label *L = |
| 433 Asm->GetOrCreateCfgNodeLabel(getTargetTrue()->getIndex()); |
433 Asm->j(Condition, L, Near); | 434 Asm->j(Condition, L, Near); |
434 if (getTargetFalse()) { | 435 if (getTargetFalse()) { |
435 x86::Label *L2 = | 436 X8632::Label *L2 = |
436 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); | 437 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); |
437 Asm->jmp(L2, Near); | 438 Asm->jmp(L2, Near); |
438 } | 439 } |
439 } | 440 } |
440 } | 441 } |
441 } | 442 } |
442 | 443 |
443 void InstX8632Br::dump(const Cfg *Func) const { | 444 void InstX8632Br::dump(const Cfg *Func) const { |
444 if (!ALLOW_DUMP) | 445 if (!ALLOW_DUMP) |
445 return; | 446 return; |
(...skipping 21 matching lines...) Expand all Loading... |
467 if (!ALLOW_DUMP) | 468 if (!ALLOW_DUMP) |
468 return; | 469 return; |
469 Ostream &Str = Func->getContext()->getStrEmit(); | 470 Ostream &Str = Func->getContext()->getStrEmit(); |
470 assert(getSrcSize() == 1); | 471 assert(getSrcSize() == 1); |
471 Str << "\tjmp\t*"; | 472 Str << "\tjmp\t*"; |
472 getJmpTarget()->emit(Func); | 473 getJmpTarget()->emit(Func); |
473 } | 474 } |
474 | 475 |
475 void InstX8632Jmp::emitIAS(const Cfg *Func) const { | 476 void InstX8632Jmp::emitIAS(const Cfg *Func) const { |
476 // Note: Adapted (mostly copied) from InstX8632Call::emitIAS(). | 477 // Note: Adapted (mostly copied) from InstX8632Call::emitIAS(). |
477 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 478 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
478 Operand *Target = getJmpTarget(); | 479 Operand *Target = getJmpTarget(); |
479 if (const auto Var = llvm::dyn_cast<Variable>(Target)) { | 480 if (const auto Var = llvm::dyn_cast<Variable>(Target)) { |
480 if (Var->hasReg()) { | 481 if (Var->hasReg()) { |
481 Asm->jmp(RegX8632::getEncodedGPR(Var->getRegNum())); | 482 Asm->jmp(RegX8632::getEncodedGPR(Var->getRegNum())); |
482 } else { | 483 } else { |
483 // The jmp instruction with a memory operand should be possible | 484 // The jmp instruction with a memory operand should be possible |
484 // to encode, but it isn't a valid sandboxed instruction, and | 485 // to encode, but it isn't a valid sandboxed instruction, and |
485 // there shouldn't be a register allocation issue to jump | 486 // there shouldn't be a register allocation issue to jump |
486 // through a scratch register, so we don't really need to bother | 487 // through a scratch register, so we don't really need to bother |
487 // implementing it. | 488 // implementing it. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 if (const auto CallTarget = llvm::dyn_cast<Constant>(getCallTarget())) { | 526 if (const auto CallTarget = llvm::dyn_cast<Constant>(getCallTarget())) { |
526 CallTarget->emitWithoutDollar(Func->getContext()); | 527 CallTarget->emitWithoutDollar(Func->getContext()); |
527 } else { | 528 } else { |
528 Str << "*"; | 529 Str << "*"; |
529 getCallTarget()->emit(Func); | 530 getCallTarget()->emit(Func); |
530 } | 531 } |
531 Func->getTarget()->resetStackAdjustment(); | 532 Func->getTarget()->resetStackAdjustment(); |
532 } | 533 } |
533 | 534 |
534 void InstX8632Call::emitIAS(const Cfg *Func) const { | 535 void InstX8632Call::emitIAS(const Cfg *Func) const { |
535 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 536 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
536 Operand *Target = getCallTarget(); | 537 Operand *Target = getCallTarget(); |
537 if (const auto Var = llvm::dyn_cast<Variable>(Target)) { | 538 if (const auto Var = llvm::dyn_cast<Variable>(Target)) { |
538 if (Var->hasReg()) { | 539 if (Var->hasReg()) { |
539 Asm->call(RegX8632::getEncodedGPR(Var->getRegNum())); | 540 Asm->call(RegX8632::getEncodedGPR(Var->getRegNum())); |
540 } else { | 541 } else { |
541 Asm->call(static_cast<TargetX8632 *>(Func->getTarget()) | 542 Asm->call(static_cast<TargetX8632 *>(Func->getTarget()) |
542 ->stackVarToAsmOperand(Var)); | 543 ->stackVarToAsmOperand(Var)); |
543 } | 544 } |
544 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Target)) { | 545 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Target)) { |
545 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 546 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
546 Asm->call(Mem->toAsmAddress(Asm)); | 547 Asm->call(Mem->toAsmAddress(Asm)); |
547 } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) { | 548 } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) { |
548 assert(CR->getOffset() == 0 && "We only support calling a function"); | 549 assert(CR->getOffset() == 0 && "We only support calling a function"); |
549 Asm->call(CR); | 550 Asm->call(CR); |
550 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) { | 551 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) { |
551 Asm->call(x86::Immediate(Imm->getValue())); | 552 Asm->call(X8632::Immediate(Imm->getValue())); |
552 } else { | 553 } else { |
553 llvm_unreachable("Unexpected operand type"); | 554 llvm_unreachable("Unexpected operand type"); |
554 } | 555 } |
555 Func->getTarget()->resetStackAdjustment(); | 556 Func->getTarget()->resetStackAdjustment(); |
556 } | 557 } |
557 | 558 |
558 void InstX8632Call::dump(const Cfg *Func) const { | 559 void InstX8632Call::dump(const Cfg *Func) const { |
559 if (!ALLOW_DUMP) | 560 if (!ALLOW_DUMP) |
560 return; | 561 return; |
561 Ostream &Str = Func->getContext()->getStrDump(); | 562 Ostream &Str = Func->getContext()->getStrDump(); |
(...skipping 22 matching lines...) Expand all Loading... |
584 const auto ShiftReg = llvm::dyn_cast<Variable>(Src1); | 585 const auto ShiftReg = llvm::dyn_cast<Variable>(Src1); |
585 if (ShiftHack && ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx) | 586 if (ShiftHack && ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx) |
586 Str << "%cl"; | 587 Str << "%cl"; |
587 else | 588 else |
588 Src1->emit(Func); | 589 Src1->emit(Func); |
589 Str << ", "; | 590 Str << ", "; |
590 Dest->emit(Func); | 591 Dest->emit(Func); |
591 } | 592 } |
592 | 593 |
593 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op, | 594 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op, |
594 const x86::AssemblerX86::GPREmitterOneOp &Emitter) { | 595 const X8632::AssemblerX8632::GPREmitterOneOp &Emitter) { |
595 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 596 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
596 if (const auto Var = llvm::dyn_cast<Variable>(Op)) { | 597 if (const auto Var = llvm::dyn_cast<Variable>(Op)) { |
597 if (Var->hasReg()) { | 598 if (Var->hasReg()) { |
598 // We cheat a little and use GPRRegister even for byte operations. | 599 // We cheat a little and use GPRRegister even for byte operations. |
599 RegX8632::GPRRegister VarReg = | 600 RegX8632::GPRRegister VarReg = |
600 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); | 601 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); |
601 (Asm->*(Emitter.Reg))(Ty, VarReg); | 602 (Asm->*(Emitter.Reg))(Ty, VarReg); |
602 } else { | 603 } else { |
603 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 604 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
604 ->stackVarToAsmOperand(Var)); | 605 ->stackVarToAsmOperand(Var)); |
605 (Asm->*(Emitter.Addr))(Ty, StackAddr); | 606 (Asm->*(Emitter.Addr))(Ty, StackAddr); |
606 } | 607 } |
607 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Op)) { | 608 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Op)) { |
608 Mem->emitSegmentOverride(Asm); | 609 Mem->emitSegmentOverride(Asm); |
609 (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm)); | 610 (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm)); |
610 } else { | 611 } else { |
611 llvm_unreachable("Unexpected operand type"); | 612 llvm_unreachable("Unexpected operand type"); |
612 } | 613 } |
613 } | 614 } |
614 | 615 |
615 template <bool VarCanBeByte, bool SrcCanBeByte> | 616 template <bool VarCanBeByte, bool SrcCanBeByte> |
616 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var, | 617 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var, |
617 const Operand *Src, | 618 const Operand *Src, |
618 const x86::AssemblerX86::GPREmitterRegOp &Emitter) { | 619 const X8632::AssemblerX8632::GPREmitterRegOp &Emitter) { |
619 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 620 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
620 assert(Var->hasReg()); | 621 assert(Var->hasReg()); |
621 // We cheat a little and use GPRRegister even for byte operations. | 622 // We cheat a little and use GPRRegister even for byte operations. |
622 RegX8632::GPRRegister VarReg = | 623 RegX8632::GPRRegister VarReg = |
623 VarCanBeByte ? RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()) | 624 VarCanBeByte ? RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()) |
624 : RegX8632::getEncodedGPR(Var->getRegNum()); | 625 : RegX8632::getEncodedGPR(Var->getRegNum()); |
625 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 626 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
626 if (SrcVar->hasReg()) { | 627 if (SrcVar->hasReg()) { |
627 RegX8632::GPRRegister SrcReg = | 628 RegX8632::GPRRegister SrcReg = |
628 SrcCanBeByte | 629 SrcCanBeByte |
629 ? RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()) | 630 ? RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()) |
630 : RegX8632::getEncodedGPR(SrcVar->getRegNum()); | 631 : RegX8632::getEncodedGPR(SrcVar->getRegNum()); |
631 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); | 632 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); |
632 } else { | 633 } else { |
633 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 634 X8632::Address SrcStackAddr = |
634 ->stackVarToAsmOperand(SrcVar); | 635 static_cast<TargetX8632 *>(Func->getTarget()) |
| 636 ->stackVarToAsmOperand(SrcVar); |
635 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr); | 637 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr); |
636 } | 638 } |
637 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 639 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
638 Mem->emitSegmentOverride(Asm); | 640 Mem->emitSegmentOverride(Asm); |
639 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); | 641 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); |
640 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 642 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
641 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); | 643 (Asm->*(Emitter.GPRImm))(Ty, VarReg, X8632::Immediate(Imm->getValue())); |
642 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { | 644 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
643 AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc); | 645 AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc); |
644 (Asm->*(Emitter.GPRImm))(Ty, VarReg, | 646 (Asm->*(Emitter.GPRImm))(Ty, VarReg, |
645 x86::Immediate(Reloc->getOffset(), Fixup)); | 647 X8632::Immediate(Reloc->getOffset(), Fixup)); |
646 } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Src)) { | 648 } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Src)) { |
647 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func)); | 649 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func)); |
648 } else { | 650 } else { |
649 llvm_unreachable("Unexpected operand type"); | 651 llvm_unreachable("Unexpected operand type"); |
650 } | 652 } |
651 } | 653 } |
652 | 654 |
653 void emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, const x86::Address &Addr, | 655 void emitIASAddrOpTyGPR( |
654 const Operand *Src, | 656 const Cfg *Func, Type Ty, const X8632::Address &Addr, const Operand *Src, |
655 const x86::AssemblerX86::GPREmitterAddrOp &Emitter) { | 657 const X8632::AssemblerX8632::GPREmitterAddrOp &Emitter) { |
656 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 658 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
657 // Src can only be Reg or Immediate. | 659 // Src can only be Reg or Immediate. |
658 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 660 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
659 assert(SrcVar->hasReg()); | 661 assert(SrcVar->hasReg()); |
660 RegX8632::GPRRegister SrcReg = | 662 RegX8632::GPRRegister SrcReg = |
661 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); | 663 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); |
662 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); | 664 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); |
663 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 665 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
664 (Asm->*(Emitter.AddrImm))(Ty, Addr, x86::Immediate(Imm->getValue())); | 666 (Asm->*(Emitter.AddrImm))(Ty, Addr, X8632::Immediate(Imm->getValue())); |
665 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { | 667 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { |
666 AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc); | 668 AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Reloc); |
667 (Asm->*(Emitter.AddrImm))(Ty, Addr, | 669 (Asm->*(Emitter.AddrImm))(Ty, Addr, |
668 x86::Immediate(Reloc->getOffset(), Fixup)); | 670 X8632::Immediate(Reloc->getOffset(), Fixup)); |
669 } else { | 671 } else { |
670 llvm_unreachable("Unexpected operand type"); | 672 llvm_unreachable("Unexpected operand type"); |
671 } | 673 } |
672 } | 674 } |
673 | 675 |
674 void emitIASAsAddrOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op0, | 676 void emitIASAsAddrOpTyGPR( |
675 const Operand *Op1, | 677 const Cfg *Func, Type Ty, const Operand *Op0, const Operand *Op1, |
676 const x86::AssemblerX86::GPREmitterAddrOp &Emitter) { | 678 const X8632::AssemblerX8632::GPREmitterAddrOp &Emitter) { |
677 if (const auto Op0Var = llvm::dyn_cast<Variable>(Op0)) { | 679 if (const auto Op0Var = llvm::dyn_cast<Variable>(Op0)) { |
678 assert(!Op0Var->hasReg()); | 680 assert(!Op0Var->hasReg()); |
679 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 681 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
680 ->stackVarToAsmOperand(Op0Var)); | 682 ->stackVarToAsmOperand(Op0Var)); |
681 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Op1, Emitter); | 683 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Op1, Emitter); |
682 } else if (const auto Op0Mem = llvm::dyn_cast<OperandX8632Mem>(Op0)) { | 684 } else if (const auto Op0Mem = llvm::dyn_cast<OperandX8632Mem>(Op0)) { |
683 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 685 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
684 Op0Mem->emitSegmentOverride(Asm); | 686 Op0Mem->emitSegmentOverride(Asm); |
685 emitIASAddrOpTyGPR(Func, Ty, Op0Mem->toAsmAddress(Asm), Op1, Emitter); | 687 emitIASAddrOpTyGPR(Func, Ty, Op0Mem->toAsmAddress(Asm), Op1, Emitter); |
686 } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Op0)) { | 688 } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Op0)) { |
687 emitIASAddrOpTyGPR(Func, Ty, Split->toAsmAddress(Func), Op1, Emitter); | 689 emitIASAddrOpTyGPR(Func, Ty, Split->toAsmAddress(Func), Op1, Emitter); |
688 } else { | 690 } else { |
689 llvm_unreachable("Unexpected operand type"); | 691 llvm_unreachable("Unexpected operand type"); |
690 } | 692 } |
691 } | 693 } |
692 | 694 |
693 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, | 695 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, |
694 const Operand *Src, | 696 const Operand *Src, |
695 const x86::AssemblerX86::GPREmitterShiftOp &Emitter) { | 697 const X8632::AssemblerX8632::GPREmitterShiftOp &Emitter) { |
696 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 698 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
697 // Technically, the Dest Var can be mem as well, but we only use Reg. | 699 // Technically, the Dest Var can be mem as well, but we only use Reg. |
698 // We can extend this to check Dest if we decide to use that form. | 700 // We can extend this to check Dest if we decide to use that form. |
699 assert(Var->hasReg()); | 701 assert(Var->hasReg()); |
700 // We cheat a little and use GPRRegister even for byte operations. | 702 // We cheat a little and use GPRRegister even for byte operations. |
701 RegX8632::GPRRegister VarReg = | 703 RegX8632::GPRRegister VarReg = |
702 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); | 704 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); |
703 // Src must be reg == ECX or an Imm8. | 705 // Src must be reg == ECX or an Imm8. |
704 // This is asserted by the assembler. | 706 // This is asserted by the assembler. |
705 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 707 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
706 assert(SrcVar->hasReg()); | 708 assert(SrcVar->hasReg()); |
707 RegX8632::GPRRegister SrcReg = | 709 RegX8632::GPRRegister SrcReg = |
708 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); | 710 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); |
709 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); | 711 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); |
710 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 712 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
711 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); | 713 (Asm->*(Emitter.GPRImm))(Ty, VarReg, X8632::Immediate(Imm->getValue())); |
712 } else { | 714 } else { |
713 llvm_unreachable("Unexpected operand type"); | 715 llvm_unreachable("Unexpected operand type"); |
714 } | 716 } |
715 } | 717 } |
716 | 718 |
717 void emitIASGPRShiftDouble(const Cfg *Func, const Variable *Dest, | 719 void emitIASGPRShiftDouble( |
718 const Operand *Src1Op, const Operand *Src2Op, | 720 const Cfg *Func, const Variable *Dest, const Operand *Src1Op, |
719 const x86::AssemblerX86::GPREmitterShiftD &Emitter) { | 721 const Operand *Src2Op, |
720 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 722 const X8632::AssemblerX8632::GPREmitterShiftD &Emitter) { |
| 723 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
721 // Dest can be reg or mem, but we only use the reg variant. | 724 // Dest can be reg or mem, but we only use the reg variant. |
722 assert(Dest->hasReg()); | 725 assert(Dest->hasReg()); |
723 RegX8632::GPRRegister DestReg = RegX8632::getEncodedGPR(Dest->getRegNum()); | 726 RegX8632::GPRRegister DestReg = RegX8632::getEncodedGPR(Dest->getRegNum()); |
724 // SrcVar1 must be reg. | 727 // SrcVar1 must be reg. |
725 const auto SrcVar1 = llvm::cast<Variable>(Src1Op); | 728 const auto SrcVar1 = llvm::cast<Variable>(Src1Op); |
726 assert(SrcVar1->hasReg()); | 729 assert(SrcVar1->hasReg()); |
727 RegX8632::GPRRegister SrcReg = RegX8632::getEncodedGPR(SrcVar1->getRegNum()); | 730 RegX8632::GPRRegister SrcReg = RegX8632::getEncodedGPR(SrcVar1->getRegNum()); |
728 Type Ty = SrcVar1->getType(); | 731 Type Ty = SrcVar1->getType(); |
729 // Src2 can be the implicit CL register or an immediate. | 732 // Src2 can be the implicit CL register or an immediate. |
730 if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src2Op)) { | 733 if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src2Op)) { |
731 (Asm->*(Emitter.GPRGPRImm))(Ty, DestReg, SrcReg, | 734 (Asm->*(Emitter.GPRGPRImm))(Ty, DestReg, SrcReg, |
732 x86::Immediate(Imm->getValue())); | 735 X8632::Immediate(Imm->getValue())); |
733 } else { | 736 } else { |
734 assert(llvm::cast<Variable>(Src2Op)->getRegNum() == RegX8632::Reg_ecx); | 737 assert(llvm::cast<Variable>(Src2Op)->getRegNum() == RegX8632::Reg_ecx); |
735 (Asm->*(Emitter.GPRGPR))(Ty, DestReg, SrcReg); | 738 (Asm->*(Emitter.GPRGPR))(Ty, DestReg, SrcReg); |
736 } | 739 } |
737 } | 740 } |
738 | 741 |
739 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, | 742 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, |
740 const Operand *Src, | 743 const Operand *Src, |
741 const x86::AssemblerX86::XmmEmitterShiftOp &Emitter) { | 744 const X8632::AssemblerX8632::XmmEmitterShiftOp &Emitter) { |
742 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 745 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
743 assert(Var->hasReg()); | 746 assert(Var->hasReg()); |
744 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); | 747 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); |
745 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 748 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
746 if (SrcVar->hasReg()) { | 749 if (SrcVar->hasReg()) { |
747 RegX8632::XmmRegister SrcReg = | 750 RegX8632::XmmRegister SrcReg = |
748 RegX8632::getEncodedXmm(SrcVar->getRegNum()); | 751 RegX8632::getEncodedXmm(SrcVar->getRegNum()); |
749 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); | 752 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); |
750 } else { | 753 } else { |
751 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 754 X8632::Address SrcStackAddr = |
752 ->stackVarToAsmOperand(SrcVar); | 755 static_cast<TargetX8632 *>(Func->getTarget()) |
| 756 ->stackVarToAsmOperand(SrcVar); |
753 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); | 757 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); |
754 } | 758 } |
755 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 759 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
756 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 760 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
757 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); | 761 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); |
758 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { | 762 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { |
759 (Asm->*(Emitter.XmmImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); | 763 (Asm->*(Emitter.XmmImm))(Ty, VarReg, X8632::Immediate(Imm->getValue())); |
760 } else { | 764 } else { |
761 llvm_unreachable("Unexpected operand type"); | 765 llvm_unreachable("Unexpected operand type"); |
762 } | 766 } |
763 } | 767 } |
764 | 768 |
765 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var, | 769 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var, |
766 const Operand *Src, | 770 const Operand *Src, |
767 const x86::AssemblerX86::XmmEmitterRegOp &Emitter) { | 771 const X8632::AssemblerX8632::XmmEmitterRegOp &Emitter) { |
768 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 772 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
769 assert(Var->hasReg()); | 773 assert(Var->hasReg()); |
770 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); | 774 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); |
771 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 775 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
772 if (SrcVar->hasReg()) { | 776 if (SrcVar->hasReg()) { |
773 RegX8632::XmmRegister SrcReg = | 777 RegX8632::XmmRegister SrcReg = |
774 RegX8632::getEncodedXmm(SrcVar->getRegNum()); | 778 RegX8632::getEncodedXmm(SrcVar->getRegNum()); |
775 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); | 779 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); |
776 } else { | 780 } else { |
777 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 781 X8632::Address SrcStackAddr = |
778 ->stackVarToAsmOperand(SrcVar); | 782 static_cast<TargetX8632 *>(Func->getTarget()) |
| 783 ->stackVarToAsmOperand(SrcVar); |
779 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); | 784 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); |
780 } | 785 } |
781 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 786 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
782 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 787 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
783 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); | 788 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); |
784 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { | 789 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { |
785 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, x86::Address::ofConstPool(Asm, Imm)); | 790 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, |
| 791 X8632::Address::ofConstPool(Asm, Imm)); |
786 } else { | 792 } else { |
787 llvm_unreachable("Unexpected operand type"); | 793 llvm_unreachable("Unexpected operand type"); |
788 } | 794 } |
789 } | 795 } |
790 | 796 |
791 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t), | 797 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t), |
792 SReg_t (*srcEnc)(int32_t)> | 798 SReg_t (*srcEnc)(int32_t)> |
793 void emitIASCastRegOp( | 799 void emitIASCastRegOp( |
794 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src, | 800 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src, |
795 const x86::AssemblerX86::CastEmitterRegOp<DReg_t, SReg_t> Emitter) { | 801 const X8632::AssemblerX8632::CastEmitterRegOp<DReg_t, SReg_t> Emitter) { |
796 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 802 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
797 assert(Dest->hasReg()); | 803 assert(Dest->hasReg()); |
798 DReg_t DestReg = destEnc(Dest->getRegNum()); | 804 DReg_t DestReg = destEnc(Dest->getRegNum()); |
799 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 805 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
800 if (SrcVar->hasReg()) { | 806 if (SrcVar->hasReg()) { |
801 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); | 807 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); |
802 (Asm->*(Emitter.RegReg))(DispatchTy, DestReg, SrcReg); | 808 (Asm->*(Emitter.RegReg))(DispatchTy, DestReg, SrcReg); |
803 } else { | 809 } else { |
804 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 810 X8632::Address SrcStackAddr = |
805 ->stackVarToAsmOperand(SrcVar); | 811 static_cast<TargetX8632 *>(Func->getTarget()) |
| 812 ->stackVarToAsmOperand(SrcVar); |
806 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, SrcStackAddr); | 813 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, SrcStackAddr); |
807 } | 814 } |
808 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 815 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
809 Mem->emitSegmentOverride(Asm); | 816 Mem->emitSegmentOverride(Asm); |
810 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, Mem->toAsmAddress(Asm)); | 817 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, Mem->toAsmAddress(Asm)); |
811 } else { | 818 } else { |
812 llvm_unreachable("Unexpected operand type"); | 819 llvm_unreachable("Unexpected operand type"); |
813 } | 820 } |
814 } | 821 } |
815 | 822 |
816 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t), | 823 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t), |
817 SReg_t (*srcEnc)(int32_t)> | 824 SReg_t (*srcEnc)(int32_t)> |
818 void emitIASThreeOpImmOps( | 825 void emitIASThreeOpImmOps( |
819 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src0, | 826 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src0, |
820 const Operand *Src1, | 827 const Operand *Src1, |
821 const x86::AssemblerX86::ThreeOpImmEmitter<DReg_t, SReg_t> Emitter) { | 828 const X8632::AssemblerX8632::ThreeOpImmEmitter<DReg_t, SReg_t> Emitter) { |
822 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 829 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
823 // This only handles Dest being a register, and Src1 being an immediate. | 830 // This only handles Dest being a register, and Src1 being an immediate. |
824 assert(Dest->hasReg()); | 831 assert(Dest->hasReg()); |
825 DReg_t DestReg = destEnc(Dest->getRegNum()); | 832 DReg_t DestReg = destEnc(Dest->getRegNum()); |
826 x86::Immediate Imm(llvm::cast<ConstantInteger32>(Src1)->getValue()); | 833 X8632::Immediate Imm(llvm::cast<ConstantInteger32>(Src1)->getValue()); |
827 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src0)) { | 834 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src0)) { |
828 if (SrcVar->hasReg()) { | 835 if (SrcVar->hasReg()) { |
829 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); | 836 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); |
830 (Asm->*(Emitter.RegRegImm))(DispatchTy, DestReg, SrcReg, Imm); | 837 (Asm->*(Emitter.RegRegImm))(DispatchTy, DestReg, SrcReg, Imm); |
831 } else { | 838 } else { |
832 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 839 X8632::Address SrcStackAddr = |
833 ->stackVarToAsmOperand(SrcVar); | 840 static_cast<TargetX8632 *>(Func->getTarget()) |
| 841 ->stackVarToAsmOperand(SrcVar); |
834 (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, SrcStackAddr, Imm); | 842 (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, SrcStackAddr, Imm); |
835 } | 843 } |
836 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src0)) { | 844 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src0)) { |
837 Mem->emitSegmentOverride(Asm); | 845 Mem->emitSegmentOverride(Asm); |
838 (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, Mem->toAsmAddress(Asm), | 846 (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, Mem->toAsmAddress(Asm), |
839 Imm); | 847 Imm); |
840 } else { | 848 } else { |
841 llvm_unreachable("Unexpected operand type"); | 849 llvm_unreachable("Unexpected operand type"); |
842 } | 850 } |
843 } | 851 } |
844 | 852 |
845 void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest, | 853 void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest, |
846 const Operand *Src, | 854 const Operand *Src, |
847 const x86::AssemblerX86::XmmEmitterMovOps Emitter) { | 855 const X8632::AssemblerX8632::XmmEmitterMovOps Emitter) { |
848 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 856 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
849 if (Dest->hasReg()) { | 857 if (Dest->hasReg()) { |
850 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); | 858 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); |
851 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { | 859 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { |
852 if (SrcVar->hasReg()) { | 860 if (SrcVar->hasReg()) { |
853 (Asm->*(Emitter.XmmXmm))(DestReg, | 861 (Asm->*(Emitter.XmmXmm))(DestReg, |
854 RegX8632::getEncodedXmm(SrcVar->getRegNum())); | 862 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
855 } else { | 863 } else { |
856 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 864 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
857 ->stackVarToAsmOperand(SrcVar)); | 865 ->stackVarToAsmOperand(SrcVar)); |
858 (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr); | 866 (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr); |
859 } | 867 } |
860 } else if (const auto SrcMem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 868 } else if (const auto SrcMem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
861 assert(SrcMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 869 assert(SrcMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
862 (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm)); | 870 (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm)); |
863 } else { | 871 } else { |
864 llvm_unreachable("Unexpected operand type"); | 872 llvm_unreachable("Unexpected operand type"); |
865 } | 873 } |
866 } else { | 874 } else { |
867 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 875 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
868 ->stackVarToAsmOperand(Dest)); | 876 ->stackVarToAsmOperand(Dest)); |
869 // Src must be a register in this case. | 877 // Src must be a register in this case. |
870 const auto SrcVar = llvm::cast<Variable>(Src); | 878 const auto SrcVar = llvm::cast<Variable>(Src); |
871 assert(SrcVar->hasReg()); | 879 assert(SrcVar->hasReg()); |
872 (Asm->*(Emitter.AddrXmm))(StackAddr, | 880 (Asm->*(Emitter.AddrXmm))(StackAddr, |
873 RegX8632::getEncodedXmm(SrcVar->getRegNum())); | 881 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
874 } | 882 } |
875 } | 883 } |
876 | 884 |
877 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) { | 885 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) { |
878 const auto SrcVar = llvm::dyn_cast<const Variable>(Source); | 886 const auto SrcVar = llvm::dyn_cast<const Variable>(Source); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
948 template <> const char *InstX8632Shufps::Opcode = "shufps"; | 956 template <> const char *InstX8632Shufps::Opcode = "shufps"; |
949 template <> const char *InstX8632Pinsr::Opcode = "pinsr"; | 957 template <> const char *InstX8632Pinsr::Opcode = "pinsr"; |
950 template <> const char *InstX8632Blendvps::Opcode = "blendvps"; | 958 template <> const char *InstX8632Blendvps::Opcode = "blendvps"; |
951 template <> const char *InstX8632Pblendvb::Opcode = "pblendvb"; | 959 template <> const char *InstX8632Pblendvb::Opcode = "pblendvb"; |
952 // Three address ops | 960 // Three address ops |
953 template <> const char *InstX8632Pextr::Opcode = "pextr"; | 961 template <> const char *InstX8632Pextr::Opcode = "pextr"; |
954 template <> const char *InstX8632Pshufd::Opcode = "pshufd"; | 962 template <> const char *InstX8632Pshufd::Opcode = "pshufd"; |
955 | 963 |
956 // Inplace GPR ops | 964 // Inplace GPR ops |
957 template <> | 965 template <> |
958 const x86::AssemblerX86::GPREmitterOneOp InstX8632Bswap::Emitter = { | 966 const X8632::AssemblerX8632::GPREmitterOneOp InstX8632Bswap::Emitter = { |
959 &x86::AssemblerX86::bswap, nullptr /* only a reg form exists */ | 967 &X8632::AssemblerX8632::bswap, nullptr /* only a reg form exists */ |
960 }; | 968 }; |
961 template <> | 969 template <> |
962 const x86::AssemblerX86::GPREmitterOneOp InstX8632Neg::Emitter = { | 970 const X8632::AssemblerX8632::GPREmitterOneOp InstX8632Neg::Emitter = { |
963 &x86::AssemblerX86::neg, &x86::AssemblerX86::neg}; | 971 &X8632::AssemblerX8632::neg, &X8632::AssemblerX8632::neg}; |
964 | 972 |
965 // Unary GPR ops | 973 // Unary GPR ops |
966 template <> | 974 template <> |
967 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsf::Emitter = { | 975 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Bsf::Emitter = { |
968 &x86::AssemblerX86::bsf, &x86::AssemblerX86::bsf, nullptr}; | 976 &X8632::AssemblerX8632::bsf, &X8632::AssemblerX8632::bsf, nullptr}; |
969 template <> | 977 template <> |
970 const x86::AssemblerX86::GPREmitterRegOp InstX8632Bsr::Emitter = { | 978 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Bsr::Emitter = { |
971 &x86::AssemblerX86::bsr, &x86::AssemblerX86::bsr, nullptr}; | 979 &X8632::AssemblerX8632::bsr, &X8632::AssemblerX8632::bsr, nullptr}; |
972 template <> | 980 template <> |
973 const x86::AssemblerX86::GPREmitterRegOp InstX8632Lea::Emitter = { | 981 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Lea::Emitter = { |
974 /* reg/reg and reg/imm are illegal */ nullptr, &x86::AssemblerX86::lea, | 982 /* reg/reg and reg/imm are illegal */ nullptr, &X8632::AssemblerX8632::lea, |
975 nullptr}; | 983 nullptr}; |
976 template <> | 984 template <> |
977 const x86::AssemblerX86::GPREmitterRegOp InstX8632Movsx::Emitter = { | 985 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Movsx::Emitter = { |
978 &x86::AssemblerX86::movsx, &x86::AssemblerX86::movsx, nullptr}; | 986 &X8632::AssemblerX8632::movsx, &X8632::AssemblerX8632::movsx, nullptr}; |
979 template <> | 987 template <> |
980 const x86::AssemblerX86::GPREmitterRegOp InstX8632Movzx::Emitter = { | 988 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Movzx::Emitter = { |
981 &x86::AssemblerX86::movzx, &x86::AssemblerX86::movzx, nullptr}; | 989 &X8632::AssemblerX8632::movzx, &X8632::AssemblerX8632::movzx, nullptr}; |
982 | 990 |
983 // Unary XMM ops | 991 // Unary XMM ops |
984 template <> | 992 template <> |
985 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Sqrtss::Emitter = { | 993 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Sqrtss::Emitter = { |
986 &x86::AssemblerX86::sqrtss, &x86::AssemblerX86::sqrtss}; | 994 &X8632::AssemblerX8632::sqrtss, &X8632::AssemblerX8632::sqrtss}; |
987 | 995 |
988 // Binary GPR ops | 996 // Binary GPR ops |
989 template <> | 997 template <> |
990 const x86::AssemblerX86::GPREmitterRegOp InstX8632Add::Emitter = { | 998 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Add::Emitter = { |
991 &x86::AssemblerX86::add, &x86::AssemblerX86::add, &x86::AssemblerX86::add}; | 999 &X8632::AssemblerX8632::add, &X8632::AssemblerX8632::add, |
| 1000 &X8632::AssemblerX8632::add}; |
992 template <> | 1001 template <> |
993 const x86::AssemblerX86::GPREmitterRegOp InstX8632Adc::Emitter = { | 1002 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Adc::Emitter = { |
994 &x86::AssemblerX86::adc, &x86::AssemblerX86::adc, &x86::AssemblerX86::adc}; | 1003 &X8632::AssemblerX8632::adc, &X8632::AssemblerX8632::adc, |
| 1004 &X8632::AssemblerX8632::adc}; |
995 template <> | 1005 template <> |
996 const x86::AssemblerX86::GPREmitterRegOp InstX8632And::Emitter = { | 1006 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632And::Emitter = { |
997 &x86::AssemblerX86::And, &x86::AssemblerX86::And, &x86::AssemblerX86::And}; | 1007 &X8632::AssemblerX8632::And, &X8632::AssemblerX8632::And, |
| 1008 &X8632::AssemblerX8632::And}; |
998 template <> | 1009 template <> |
999 const x86::AssemblerX86::GPREmitterRegOp InstX8632Or::Emitter = { | 1010 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Or::Emitter = { |
1000 &x86::AssemblerX86::Or, &x86::AssemblerX86::Or, &x86::AssemblerX86::Or}; | 1011 &X8632::AssemblerX8632::Or, &X8632::AssemblerX8632::Or, |
| 1012 &X8632::AssemblerX8632::Or}; |
1001 template <> | 1013 template <> |
1002 const x86::AssemblerX86::GPREmitterRegOp InstX8632Sbb::Emitter = { | 1014 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Sbb::Emitter = { |
1003 &x86::AssemblerX86::sbb, &x86::AssemblerX86::sbb, &x86::AssemblerX86::sbb}; | 1015 &X8632::AssemblerX8632::sbb, &X8632::AssemblerX8632::sbb, |
| 1016 &X8632::AssemblerX8632::sbb}; |
1004 template <> | 1017 template <> |
1005 const x86::AssemblerX86::GPREmitterRegOp InstX8632Sub::Emitter = { | 1018 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Sub::Emitter = { |
1006 &x86::AssemblerX86::sub, &x86::AssemblerX86::sub, &x86::AssemblerX86::sub}; | 1019 &X8632::AssemblerX8632::sub, &X8632::AssemblerX8632::sub, |
| 1020 &X8632::AssemblerX8632::sub}; |
1007 template <> | 1021 template <> |
1008 const x86::AssemblerX86::GPREmitterRegOp InstX8632Xor::Emitter = { | 1022 const X8632::AssemblerX8632::GPREmitterRegOp InstX8632Xor::Emitter = { |
1009 &x86::AssemblerX86::Xor, &x86::AssemblerX86::Xor, &x86::AssemblerX86::Xor}; | 1023 &X8632::AssemblerX8632::Xor, &X8632::AssemblerX8632::Xor, |
| 1024 &X8632::AssemblerX8632::Xor}; |
1010 | 1025 |
1011 // Binary Shift GPR ops | 1026 // Binary Shift GPR ops |
1012 template <> | 1027 template <> |
1013 const x86::AssemblerX86::GPREmitterShiftOp InstX8632Rol::Emitter = { | 1028 const X8632::AssemblerX8632::GPREmitterShiftOp InstX8632Rol::Emitter = { |
1014 &x86::AssemblerX86::rol, &x86::AssemblerX86::rol}; | 1029 &X8632::AssemblerX8632::rol, &X8632::AssemblerX8632::rol}; |
1015 template <> | 1030 template <> |
1016 const x86::AssemblerX86::GPREmitterShiftOp InstX8632Sar::Emitter = { | 1031 const X8632::AssemblerX8632::GPREmitterShiftOp InstX8632Sar::Emitter = { |
1017 &x86::AssemblerX86::sar, &x86::AssemblerX86::sar}; | 1032 &X8632::AssemblerX8632::sar, &X8632::AssemblerX8632::sar}; |
1018 template <> | 1033 template <> |
1019 const x86::AssemblerX86::GPREmitterShiftOp InstX8632Shl::Emitter = { | 1034 const X8632::AssemblerX8632::GPREmitterShiftOp InstX8632Shl::Emitter = { |
1020 &x86::AssemblerX86::shl, &x86::AssemblerX86::shl}; | 1035 &X8632::AssemblerX8632::shl, &X8632::AssemblerX8632::shl}; |
1021 template <> | 1036 template <> |
1022 const x86::AssemblerX86::GPREmitterShiftOp InstX8632Shr::Emitter = { | 1037 const X8632::AssemblerX8632::GPREmitterShiftOp InstX8632Shr::Emitter = { |
1023 &x86::AssemblerX86::shr, &x86::AssemblerX86::shr}; | 1038 &X8632::AssemblerX8632::shr, &X8632::AssemblerX8632::shr}; |
1024 | 1039 |
1025 // Binary XMM ops | 1040 // Binary XMM ops |
1026 template <> | 1041 template <> |
1027 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Addss::Emitter = { | 1042 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Addss::Emitter = { |
1028 &x86::AssemblerX86::addss, &x86::AssemblerX86::addss}; | 1043 &X8632::AssemblerX8632::addss, &X8632::AssemblerX8632::addss}; |
1029 template <> | 1044 template <> |
1030 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Addps::Emitter = { | 1045 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Addps::Emitter = { |
1031 &x86::AssemblerX86::addps, &x86::AssemblerX86::addps}; | 1046 &X8632::AssemblerX8632::addps, &X8632::AssemblerX8632::addps}; |
1032 template <> | 1047 template <> |
1033 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Divss::Emitter = { | 1048 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Divss::Emitter = { |
1034 &x86::AssemblerX86::divss, &x86::AssemblerX86::divss}; | 1049 &X8632::AssemblerX8632::divss, &X8632::AssemblerX8632::divss}; |
1035 template <> | 1050 template <> |
1036 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Divps::Emitter = { | 1051 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Divps::Emitter = { |
1037 &x86::AssemblerX86::divps, &x86::AssemblerX86::divps}; | 1052 &X8632::AssemblerX8632::divps, &X8632::AssemblerX8632::divps}; |
1038 template <> | 1053 template <> |
1039 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Mulss::Emitter = { | 1054 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Mulss::Emitter = { |
1040 &x86::AssemblerX86::mulss, &x86::AssemblerX86::mulss}; | 1055 &X8632::AssemblerX8632::mulss, &X8632::AssemblerX8632::mulss}; |
1041 template <> | 1056 template <> |
1042 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Mulps::Emitter = { | 1057 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Mulps::Emitter = { |
1043 &x86::AssemblerX86::mulps, &x86::AssemblerX86::mulps}; | 1058 &X8632::AssemblerX8632::mulps, &X8632::AssemblerX8632::mulps}; |
1044 template <> | 1059 template <> |
1045 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Padd::Emitter = { | 1060 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Padd::Emitter = { |
1046 &x86::AssemblerX86::padd, &x86::AssemblerX86::padd}; | 1061 &X8632::AssemblerX8632::padd, &X8632::AssemblerX8632::padd}; |
1047 template <> | 1062 template <> |
1048 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pand::Emitter = { | 1063 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Pand::Emitter = { |
1049 &x86::AssemblerX86::pand, &x86::AssemblerX86::pand}; | 1064 &X8632::AssemblerX8632::pand, &X8632::AssemblerX8632::pand}; |
1050 template <> | 1065 template <> |
1051 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pandn::Emitter = { | 1066 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Pandn::Emitter = { |
1052 &x86::AssemblerX86::pandn, &x86::AssemblerX86::pandn}; | 1067 &X8632::AssemblerX8632::pandn, &X8632::AssemblerX8632::pandn}; |
1053 template <> | 1068 template <> |
1054 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pcmpeq::Emitter = { | 1069 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Pcmpeq::Emitter = { |
1055 &x86::AssemblerX86::pcmpeq, &x86::AssemblerX86::pcmpeq}; | 1070 &X8632::AssemblerX8632::pcmpeq, &X8632::AssemblerX8632::pcmpeq}; |
1056 template <> | 1071 template <> |
1057 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pcmpgt::Emitter = { | 1072 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Pcmpgt::Emitter = { |
1058 &x86::AssemblerX86::pcmpgt, &x86::AssemblerX86::pcmpgt}; | 1073 &X8632::AssemblerX8632::pcmpgt, &X8632::AssemblerX8632::pcmpgt}; |
1059 template <> | 1074 template <> |
1060 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pmull::Emitter = { | 1075 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Pmull::Emitter = { |
1061 &x86::AssemblerX86::pmull, &x86::AssemblerX86::pmull}; | 1076 &X8632::AssemblerX8632::pmull, &X8632::AssemblerX8632::pmull}; |
1062 template <> | 1077 template <> |
1063 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pmuludq::Emitter = { | 1078 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Pmuludq::Emitter = { |
1064 &x86::AssemblerX86::pmuludq, &x86::AssemblerX86::pmuludq}; | 1079 &X8632::AssemblerX8632::pmuludq, &X8632::AssemblerX8632::pmuludq}; |
1065 template <> | 1080 template <> |
1066 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Por::Emitter = { | 1081 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Por::Emitter = { |
1067 &x86::AssemblerX86::por, &x86::AssemblerX86::por}; | 1082 &X8632::AssemblerX8632::por, &X8632::AssemblerX8632::por}; |
1068 template <> | 1083 template <> |
1069 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Psub::Emitter = { | 1084 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Psub::Emitter = { |
1070 &x86::AssemblerX86::psub, &x86::AssemblerX86::psub}; | 1085 &X8632::AssemblerX8632::psub, &X8632::AssemblerX8632::psub}; |
1071 template <> | 1086 template <> |
1072 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Pxor::Emitter = { | 1087 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Pxor::Emitter = { |
1073 &x86::AssemblerX86::pxor, &x86::AssemblerX86::pxor}; | 1088 &X8632::AssemblerX8632::pxor, &X8632::AssemblerX8632::pxor}; |
1074 template <> | 1089 template <> |
1075 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Subss::Emitter = { | 1090 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Subss::Emitter = { |
1076 &x86::AssemblerX86::subss, &x86::AssemblerX86::subss}; | 1091 &X8632::AssemblerX8632::subss, &X8632::AssemblerX8632::subss}; |
1077 template <> | 1092 template <> |
1078 const x86::AssemblerX86::XmmEmitterRegOp InstX8632Subps::Emitter = { | 1093 const X8632::AssemblerX8632::XmmEmitterRegOp InstX8632Subps::Emitter = { |
1079 &x86::AssemblerX86::subps, &x86::AssemblerX86::subps}; | 1094 &X8632::AssemblerX8632::subps, &X8632::AssemblerX8632::subps}; |
1080 | 1095 |
1081 // Binary XMM Shift ops | 1096 // Binary XMM Shift ops |
1082 template <> | 1097 template <> |
1083 const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psll::Emitter = { | 1098 const X8632::AssemblerX8632::XmmEmitterShiftOp InstX8632Psll::Emitter = { |
1084 &x86::AssemblerX86::psll, &x86::AssemblerX86::psll, | 1099 &X8632::AssemblerX8632::psll, &X8632::AssemblerX8632::psll, |
1085 &x86::AssemblerX86::psll}; | 1100 &X8632::AssemblerX8632::psll}; |
1086 template <> | 1101 template <> |
1087 const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psra::Emitter = { | 1102 const X8632::AssemblerX8632::XmmEmitterShiftOp InstX8632Psra::Emitter = { |
1088 &x86::AssemblerX86::psra, &x86::AssemblerX86::psra, | 1103 &X8632::AssemblerX8632::psra, &X8632::AssemblerX8632::psra, |
1089 &x86::AssemblerX86::psra}; | 1104 &X8632::AssemblerX8632::psra}; |
1090 template <> | 1105 template <> |
1091 const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psrl::Emitter = { | 1106 const X8632::AssemblerX8632::XmmEmitterShiftOp InstX8632Psrl::Emitter = { |
1092 &x86::AssemblerX86::psrl, &x86::AssemblerX86::psrl, | 1107 &X8632::AssemblerX8632::psrl, &X8632::AssemblerX8632::psrl, |
1093 &x86::AssemblerX86::psrl}; | 1108 &X8632::AssemblerX8632::psrl}; |
1094 | 1109 |
1095 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const { | 1110 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const { |
1096 if (!ALLOW_DUMP) | 1111 if (!ALLOW_DUMP) |
1097 return; | 1112 return; |
1098 Ostream &Str = Func->getContext()->getStrEmit(); | 1113 Ostream &Str = Func->getContext()->getStrEmit(); |
1099 assert(getSrcSize() == 1); | 1114 assert(getSrcSize() == 1); |
1100 Type Ty = getSrc(0)->getType(); | 1115 Type Ty = getSrc(0)->getType(); |
1101 assert(isScalarFloatingType(Ty)); | 1116 assert(isScalarFloatingType(Ty)); |
1102 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; | 1117 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; |
1103 getSrc(0)->emit(Func); | 1118 getSrc(0)->emit(Func); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1209 assert(getSrcSize() == 3); | 1224 assert(getSrcSize() == 3); |
1210 Operand *Src1 = getSrc(1); | 1225 Operand *Src1 = getSrc(1); |
1211 Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t"; | 1226 Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t"; |
1212 Src1->emit(Func); | 1227 Src1->emit(Func); |
1213 } | 1228 } |
1214 | 1229 |
1215 template <> void InstX8632Div::emitIAS(const Cfg *Func) const { | 1230 template <> void InstX8632Div::emitIAS(const Cfg *Func) const { |
1216 assert(getSrcSize() == 3); | 1231 assert(getSrcSize() == 3); |
1217 const Operand *Src = getSrc(1); | 1232 const Operand *Src = getSrc(1); |
1218 Type Ty = Src->getType(); | 1233 Type Ty = Src->getType(); |
1219 const static x86::AssemblerX86::GPREmitterOneOp Emitter = { | 1234 const static X8632::AssemblerX8632::GPREmitterOneOp Emitter = { |
1220 &x86::AssemblerX86::div, &x86::AssemblerX86::div}; | 1235 &X8632::AssemblerX8632::div, &X8632::AssemblerX8632::div}; |
1221 emitIASOpTyGPR(Func, Ty, Src, Emitter); | 1236 emitIASOpTyGPR(Func, Ty, Src, Emitter); |
1222 } | 1237 } |
1223 | 1238 |
1224 template <> void InstX8632Idiv::emit(const Cfg *Func) const { | 1239 template <> void InstX8632Idiv::emit(const Cfg *Func) const { |
1225 if (!ALLOW_DUMP) | 1240 if (!ALLOW_DUMP) |
1226 return; | 1241 return; |
1227 Ostream &Str = Func->getContext()->getStrEmit(); | 1242 Ostream &Str = Func->getContext()->getStrEmit(); |
1228 assert(getSrcSize() == 3); | 1243 assert(getSrcSize() == 3); |
1229 Operand *Src1 = getSrc(1); | 1244 Operand *Src1 = getSrc(1); |
1230 Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t"; | 1245 Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t"; |
1231 Src1->emit(Func); | 1246 Src1->emit(Func); |
1232 } | 1247 } |
1233 | 1248 |
1234 template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const { | 1249 template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const { |
1235 assert(getSrcSize() == 3); | 1250 assert(getSrcSize() == 3); |
1236 const Operand *Src = getSrc(1); | 1251 const Operand *Src = getSrc(1); |
1237 Type Ty = Src->getType(); | 1252 Type Ty = Src->getType(); |
1238 const static x86::AssemblerX86::GPREmitterOneOp Emitter = { | 1253 const static X8632::AssemblerX8632::GPREmitterOneOp Emitter = { |
1239 &x86::AssemblerX86::idiv, &x86::AssemblerX86::idiv}; | 1254 &X8632::AssemblerX8632::idiv, &X8632::AssemblerX8632::idiv}; |
1240 emitIASOpTyGPR(Func, Ty, Src, Emitter); | 1255 emitIASOpTyGPR(Func, Ty, Src, Emitter); |
1241 } | 1256 } |
1242 | 1257 |
1243 namespace { | 1258 namespace { |
1244 | 1259 |
1245 // pblendvb and blendvps take xmm0 as a final implicit argument. | 1260 // pblendvb and blendvps take xmm0 as a final implicit argument. |
1246 void emitVariableBlendInst(const char *Opcode, const Inst *Inst, | 1261 void emitVariableBlendInst(const char *Opcode, const Inst *Inst, |
1247 const Cfg *Func) { | 1262 const Cfg *Func) { |
1248 if (!ALLOW_DUMP) | 1263 if (!ALLOW_DUMP) |
1249 return; | 1264 return; |
1250 Ostream &Str = Func->getContext()->getStrEmit(); | 1265 Ostream &Str = Func->getContext()->getStrEmit(); |
1251 assert(Inst->getSrcSize() == 3); | 1266 assert(Inst->getSrcSize() == 3); |
1252 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == | 1267 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == |
1253 RegX8632::Reg_xmm0); | 1268 RegX8632::Reg_xmm0); |
1254 Str << "\t" << Opcode << "\t"; | 1269 Str << "\t" << Opcode << "\t"; |
1255 Inst->getSrc(1)->emit(Func); | 1270 Inst->getSrc(1)->emit(Func); |
1256 Str << ", "; | 1271 Str << ", "; |
1257 Inst->getDest()->emit(Func); | 1272 Inst->getDest()->emit(Func); |
1258 } | 1273 } |
1259 | 1274 |
1260 void emitIASVariableBlendInst( | 1275 void emitIASVariableBlendInst( |
1261 const Inst *Inst, const Cfg *Func, | 1276 const Inst *Inst, const Cfg *Func, |
1262 const x86::AssemblerX86::XmmEmitterRegOp &Emitter) { | 1277 const X8632::AssemblerX8632::XmmEmitterRegOp &Emitter) { |
1263 assert(Inst->getSrcSize() == 3); | 1278 assert(Inst->getSrcSize() == 3); |
1264 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == | 1279 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == |
1265 RegX8632::Reg_xmm0); | 1280 RegX8632::Reg_xmm0); |
1266 const Variable *Dest = Inst->getDest(); | 1281 const Variable *Dest = Inst->getDest(); |
1267 const Operand *Src = Inst->getSrc(1); | 1282 const Operand *Src = Inst->getSrc(1); |
1268 emitIASRegOpTyXMM(Func, Dest->getType(), Dest, Src, Emitter); | 1283 emitIASRegOpTyXMM(Func, Dest->getType(), Dest, Src, Emitter); |
1269 } | 1284 } |
1270 | 1285 |
1271 } // end anonymous namespace | 1286 } // end anonymous namespace |
1272 | 1287 |
1273 template <> void InstX8632Blendvps::emit(const Cfg *Func) const { | 1288 template <> void InstX8632Blendvps::emit(const Cfg *Func) const { |
1274 if (!ALLOW_DUMP) | 1289 if (!ALLOW_DUMP) |
1275 return; | 1290 return; |
1276 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1291 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
1277 TargetX8632::SSE4_1); | 1292 TargetX8632::SSE4_1); |
1278 emitVariableBlendInst(Opcode, this, Func); | 1293 emitVariableBlendInst(Opcode, this, Func); |
1279 } | 1294 } |
1280 | 1295 |
1281 template <> void InstX8632Blendvps::emitIAS(const Cfg *Func) const { | 1296 template <> void InstX8632Blendvps::emitIAS(const Cfg *Func) const { |
1282 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1297 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
1283 TargetX8632::SSE4_1); | 1298 TargetX8632::SSE4_1); |
1284 static const x86::AssemblerX86::XmmEmitterRegOp Emitter = { | 1299 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { |
1285 &x86::AssemblerX86::blendvps, &x86::AssemblerX86::blendvps}; | 1300 &X8632::AssemblerX8632::blendvps, &X8632::AssemblerX8632::blendvps}; |
1286 emitIASVariableBlendInst(this, Func, Emitter); | 1301 emitIASVariableBlendInst(this, Func, Emitter); |
1287 } | 1302 } |
1288 | 1303 |
1289 template <> void InstX8632Pblendvb::emit(const Cfg *Func) const { | 1304 template <> void InstX8632Pblendvb::emit(const Cfg *Func) const { |
1290 if (!ALLOW_DUMP) | 1305 if (!ALLOW_DUMP) |
1291 return; | 1306 return; |
1292 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1307 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
1293 TargetX8632::SSE4_1); | 1308 TargetX8632::SSE4_1); |
1294 emitVariableBlendInst(Opcode, this, Func); | 1309 emitVariableBlendInst(Opcode, this, Func); |
1295 } | 1310 } |
1296 | 1311 |
1297 template <> void InstX8632Pblendvb::emitIAS(const Cfg *Func) const { | 1312 template <> void InstX8632Pblendvb::emitIAS(const Cfg *Func) const { |
1298 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1313 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
1299 TargetX8632::SSE4_1); | 1314 TargetX8632::SSE4_1); |
1300 static const x86::AssemblerX86::XmmEmitterRegOp Emitter = { | 1315 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { |
1301 &x86::AssemblerX86::pblendvb, &x86::AssemblerX86::pblendvb}; | 1316 &X8632::AssemblerX8632::pblendvb, &X8632::AssemblerX8632::pblendvb}; |
1302 emitIASVariableBlendInst(this, Func, Emitter); | 1317 emitIASVariableBlendInst(this, Func, Emitter); |
1303 } | 1318 } |
1304 | 1319 |
1305 template <> void InstX8632Imul::emit(const Cfg *Func) const { | 1320 template <> void InstX8632Imul::emit(const Cfg *Func) const { |
1306 if (!ALLOW_DUMP) | 1321 if (!ALLOW_DUMP) |
1307 return; | 1322 return; |
1308 Ostream &Str = Func->getContext()->getStrEmit(); | 1323 Ostream &Str = Func->getContext()->getStrEmit(); |
1309 assert(getSrcSize() == 2); | 1324 assert(getSrcSize() == 2); |
1310 Variable *Dest = getDest(); | 1325 Variable *Dest = getDest(); |
1311 if (isByteSizedArithType(Dest->getType())) { | 1326 if (isByteSizedArithType(Dest->getType())) { |
(...skipping 18 matching lines...) Expand all Loading... |
1330 template <> void InstX8632Imul::emitIAS(const Cfg *Func) const { | 1345 template <> void InstX8632Imul::emitIAS(const Cfg *Func) const { |
1331 assert(getSrcSize() == 2); | 1346 assert(getSrcSize() == 2); |
1332 const Variable *Var = getDest(); | 1347 const Variable *Var = getDest(); |
1333 Type Ty = Var->getType(); | 1348 Type Ty = Var->getType(); |
1334 const Operand *Src = getSrc(1); | 1349 const Operand *Src = getSrc(1); |
1335 if (isByteSizedArithType(Ty)) { | 1350 if (isByteSizedArithType(Ty)) { |
1336 // 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". |
1337 const auto Src0Var = llvm::dyn_cast<Variable>(getSrc(0)); | 1352 const auto Src0Var = llvm::dyn_cast<Variable>(getSrc(0)); |
1338 (void)Src0Var; | 1353 (void)Src0Var; |
1339 assert(Src0Var && Src0Var->getRegNum() == RegX8632::Reg_eax); | 1354 assert(Src0Var && Src0Var->getRegNum() == RegX8632::Reg_eax); |
1340 const x86::AssemblerX86::GPREmitterOneOp Emitter = { | 1355 const X8632::AssemblerX8632::GPREmitterOneOp Emitter = { |
1341 &x86::AssemblerX86::imul, &x86::AssemblerX86::imul}; | 1356 &X8632::AssemblerX8632::imul, &X8632::AssemblerX8632::imul}; |
1342 emitIASOpTyGPR(Func, Ty, getSrc(1), Emitter); | 1357 emitIASOpTyGPR(Func, Ty, getSrc(1), Emitter); |
1343 } else { | 1358 } else { |
1344 // We only use imul as a two-address instruction even though | 1359 // We only use imul as a two-address instruction even though |
1345 // there is a 3 operand version when one of the operands is a constant. | 1360 // there is a 3 operand version when one of the operands is a constant. |
1346 assert(Var == getSrc(0)); | 1361 assert(Var == getSrc(0)); |
1347 const x86::AssemblerX86::GPREmitterRegOp Emitter = { | 1362 const X8632::AssemblerX8632::GPREmitterRegOp Emitter = { |
1348 &x86::AssemblerX86::imul, &x86::AssemblerX86::imul, | 1363 &X8632::AssemblerX8632::imul, &X8632::AssemblerX8632::imul, |
1349 &x86::AssemblerX86::imul}; | 1364 &X8632::AssemblerX8632::imul}; |
1350 emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter); | 1365 emitIASRegOpTyGPR(Func, Ty, Var, Src, Emitter); |
1351 } | 1366 } |
1352 } | 1367 } |
1353 | 1368 |
1354 template <> void InstX8632Insertps::emitIAS(const Cfg *Func) const { | 1369 template <> void InstX8632Insertps::emitIAS(const Cfg *Func) const { |
1355 assert(getSrcSize() == 3); | 1370 assert(getSrcSize() == 3); |
1356 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1371 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
1357 TargetX8632::SSE4_1); | 1372 TargetX8632::SSE4_1); |
1358 const Variable *Dest = getDest(); | 1373 const Variable *Dest = getDest(); |
1359 assert(Dest == getSrc(0)); | 1374 assert(Dest == getSrc(0)); |
1360 Type Ty = Dest->getType(); | 1375 Type Ty = Dest->getType(); |
1361 static const x86::AssemblerX86::ThreeOpImmEmitter< | 1376 static const X8632::AssemblerX8632::ThreeOpImmEmitter< |
1362 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { | 1377 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { |
1363 &x86::AssemblerX86::insertps, &x86::AssemblerX86::insertps}; | 1378 &X8632::AssemblerX8632::insertps, &X8632::AssemblerX8632::insertps}; |
1364 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, | 1379 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, |
1365 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( | 1380 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( |
1366 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); | 1381 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); |
1367 } | 1382 } |
1368 | 1383 |
1369 template <> void InstX8632Cbwdq::emit(const Cfg *Func) const { | 1384 template <> void InstX8632Cbwdq::emit(const Cfg *Func) const { |
1370 if (!ALLOW_DUMP) | 1385 if (!ALLOW_DUMP) |
1371 return; | 1386 return; |
1372 Ostream &Str = Func->getContext()->getStrEmit(); | 1387 Ostream &Str = Func->getContext()->getStrEmit(); |
1373 assert(getSrcSize() == 1); | 1388 assert(getSrcSize() == 1); |
(...skipping 13 matching lines...) Expand all Loading... |
1387 Str << "\tcwtd"; | 1402 Str << "\tcwtd"; |
1388 break; | 1403 break; |
1389 case IceType_i32: | 1404 case IceType_i32: |
1390 assert(getDest()->getRegNum() == RegX8632::Reg_edx); | 1405 assert(getDest()->getRegNum() == RegX8632::Reg_edx); |
1391 Str << "\tcltd"; | 1406 Str << "\tcltd"; |
1392 break; | 1407 break; |
1393 } | 1408 } |
1394 } | 1409 } |
1395 | 1410 |
1396 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const { | 1411 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const { |
1397 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1412 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
1398 assert(getSrcSize() == 1); | 1413 assert(getSrcSize() == 1); |
1399 Operand *Src0 = getSrc(0); | 1414 Operand *Src0 = getSrc(0); |
1400 assert(llvm::isa<Variable>(Src0)); | 1415 assert(llvm::isa<Variable>(Src0)); |
1401 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); | 1416 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); |
1402 switch (Src0->getType()) { | 1417 switch (Src0->getType()) { |
1403 default: | 1418 default: |
1404 llvm_unreachable("unexpected source type!"); | 1419 llvm_unreachable("unexpected source type!"); |
1405 break; | 1420 break; |
1406 case IceType_i8: | 1421 case IceType_i8: |
1407 assert(getDest()->getRegNum() == RegX8632::Reg_eax); | 1422 assert(getDest()->getRegNum() == RegX8632::Reg_eax); |
(...skipping 22 matching lines...) Expand all Loading... |
1430 getSrc(1)->emit(Func); | 1445 getSrc(1)->emit(Func); |
1431 } | 1446 } |
1432 | 1447 |
1433 void InstX8632Mul::emitIAS(const Cfg *Func) const { | 1448 void InstX8632Mul::emitIAS(const Cfg *Func) const { |
1434 assert(getSrcSize() == 2); | 1449 assert(getSrcSize() == 2); |
1435 assert(llvm::isa<Variable>(getSrc(0))); | 1450 assert(llvm::isa<Variable>(getSrc(0))); |
1436 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); | 1451 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); |
1437 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? | 1452 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? |
1438 const Operand *Src = getSrc(1); | 1453 const Operand *Src = getSrc(1); |
1439 Type Ty = Src->getType(); | 1454 Type Ty = Src->getType(); |
1440 const static x86::AssemblerX86::GPREmitterOneOp Emitter = { | 1455 const static X8632::AssemblerX8632::GPREmitterOneOp Emitter = { |
1441 &x86::AssemblerX86::mul, &x86::AssemblerX86::mul}; | 1456 &X8632::AssemblerX8632::mul, &X8632::AssemblerX8632::mul}; |
1442 emitIASOpTyGPR(Func, Ty, Src, Emitter); | 1457 emitIASOpTyGPR(Func, Ty, Src, Emitter); |
1443 } | 1458 } |
1444 | 1459 |
1445 void InstX8632Mul::dump(const Cfg *Func) const { | 1460 void InstX8632Mul::dump(const Cfg *Func) const { |
1446 if (!ALLOW_DUMP) | 1461 if (!ALLOW_DUMP) |
1447 return; | 1462 return; |
1448 Ostream &Str = Func->getContext()->getStrDump(); | 1463 Ostream &Str = Func->getContext()->getStrDump(); |
1449 dumpDest(Func); | 1464 dumpDest(Func); |
1450 Str << " = mul." << getDest()->getType() << " "; | 1465 Str << " = mul." << getDest()->getType() << " "; |
1451 dumpSources(Func); | 1466 dumpSources(Func); |
(...skipping 19 matching lines...) Expand all Loading... |
1471 Str << ", "; | 1486 Str << ", "; |
1472 Dest->emit(Func); | 1487 Dest->emit(Func); |
1473 } | 1488 } |
1474 | 1489 |
1475 void InstX8632Shld::emitIAS(const Cfg *Func) const { | 1490 void InstX8632Shld::emitIAS(const Cfg *Func) const { |
1476 assert(getSrcSize() == 3); | 1491 assert(getSrcSize() == 3); |
1477 assert(getDest() == getSrc(0)); | 1492 assert(getDest() == getSrc(0)); |
1478 const Variable *Dest = getDest(); | 1493 const Variable *Dest = getDest(); |
1479 const Operand *Src1 = getSrc(1); | 1494 const Operand *Src1 = getSrc(1); |
1480 const Operand *Src2 = getSrc(2); | 1495 const Operand *Src2 = getSrc(2); |
1481 static const x86::AssemblerX86::GPREmitterShiftD Emitter = { | 1496 static const X8632::AssemblerX8632::GPREmitterShiftD Emitter = { |
1482 &x86::AssemblerX86::shld, &x86::AssemblerX86::shld}; | 1497 &X8632::AssemblerX8632::shld, &X8632::AssemblerX8632::shld}; |
1483 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); | 1498 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); |
1484 } | 1499 } |
1485 | 1500 |
1486 void InstX8632Shld::dump(const Cfg *Func) const { | 1501 void InstX8632Shld::dump(const Cfg *Func) const { |
1487 if (!ALLOW_DUMP) | 1502 if (!ALLOW_DUMP) |
1488 return; | 1503 return; |
1489 Ostream &Str = Func->getContext()->getStrDump(); | 1504 Ostream &Str = Func->getContext()->getStrDump(); |
1490 dumpDest(Func); | 1505 dumpDest(Func); |
1491 Str << " = shld." << getDest()->getType() << " "; | 1506 Str << " = shld." << getDest()->getType() << " "; |
1492 dumpSources(Func); | 1507 dumpSources(Func); |
(...skipping 19 matching lines...) Expand all Loading... |
1512 Str << ", "; | 1527 Str << ", "; |
1513 Dest->emit(Func); | 1528 Dest->emit(Func); |
1514 } | 1529 } |
1515 | 1530 |
1516 void InstX8632Shrd::emitIAS(const Cfg *Func) const { | 1531 void InstX8632Shrd::emitIAS(const Cfg *Func) const { |
1517 assert(getSrcSize() == 3); | 1532 assert(getSrcSize() == 3); |
1518 assert(getDest() == getSrc(0)); | 1533 assert(getDest() == getSrc(0)); |
1519 const Variable *Dest = getDest(); | 1534 const Variable *Dest = getDest(); |
1520 const Operand *Src1 = getSrc(1); | 1535 const Operand *Src1 = getSrc(1); |
1521 const Operand *Src2 = getSrc(2); | 1536 const Operand *Src2 = getSrc(2); |
1522 static const x86::AssemblerX86::GPREmitterShiftD Emitter = { | 1537 static const X8632::AssemblerX8632::GPREmitterShiftD Emitter = { |
1523 &x86::AssemblerX86::shrd, &x86::AssemblerX86::shrd}; | 1538 &X8632::AssemblerX8632::shrd, &X8632::AssemblerX8632::shrd}; |
1524 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); | 1539 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); |
1525 } | 1540 } |
1526 | 1541 |
1527 void InstX8632Shrd::dump(const Cfg *Func) const { | 1542 void InstX8632Shrd::dump(const Cfg *Func) const { |
1528 if (!ALLOW_DUMP) | 1543 if (!ALLOW_DUMP) |
1529 return; | 1544 return; |
1530 Ostream &Str = Func->getContext()->getStrDump(); | 1545 Ostream &Str = Func->getContext()->getStrDump(); |
1531 dumpDest(Func); | 1546 dumpDest(Func); |
1532 Str << " = shrd." << getDest()->getType() << " "; | 1547 Str << " = shrd." << getDest()->getType() << " "; |
1533 dumpSources(Func); | 1548 dumpSources(Func); |
(...skipping 15 matching lines...) Expand all Loading... |
1549 } | 1564 } |
1550 | 1565 |
1551 void InstX8632Cmov::emitIAS(const Cfg *Func) const { | 1566 void InstX8632Cmov::emitIAS(const Cfg *Func) const { |
1552 assert(Condition != CondX86::Br_None); | 1567 assert(Condition != CondX86::Br_None); |
1553 assert(getDest()->hasReg()); | 1568 assert(getDest()->hasReg()); |
1554 assert(getSrcSize() == 2); | 1569 assert(getSrcSize() == 2); |
1555 // Only need the reg/reg form now. | 1570 // Only need the reg/reg form now. |
1556 const auto SrcVar = llvm::cast<Variable>(getSrc(1)); | 1571 const auto SrcVar = llvm::cast<Variable>(getSrc(1)); |
1557 assert(SrcVar->hasReg()); | 1572 assert(SrcVar->hasReg()); |
1558 assert(SrcVar->getType() == IceType_i32); | 1573 assert(SrcVar->getType() == IceType_i32); |
1559 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1574 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
1560 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()), | 1575 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()), |
1561 RegX8632::getEncodedGPR(SrcVar->getRegNum())); | 1576 RegX8632::getEncodedGPR(SrcVar->getRegNum())); |
1562 } | 1577 } |
1563 | 1578 |
1564 void InstX8632Cmov::dump(const Cfg *Func) const { | 1579 void InstX8632Cmov::dump(const Cfg *Func) const { |
1565 if (!ALLOW_DUMP) | 1580 if (!ALLOW_DUMP) |
1566 return; | 1581 return; |
1567 Ostream &Str = Func->getContext()->getStrDump(); | 1582 Ostream &Str = Func->getContext()->getStrDump(); |
1568 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; | 1583 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; |
1569 Str << getDest()->getType() << " "; | 1584 Str << getDest()->getType() << " "; |
(...skipping 10 matching lines...) Expand all Loading... |
1580 assert(Condition < CondX86::Cmpps_Invalid); | 1595 assert(Condition < CondX86::Cmpps_Invalid); |
1581 Str << "\t"; | 1596 Str << "\t"; |
1582 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" | 1597 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" |
1583 << "\t"; | 1598 << "\t"; |
1584 getSrc(1)->emit(Func); | 1599 getSrc(1)->emit(Func); |
1585 Str << ", "; | 1600 Str << ", "; |
1586 getDest()->emit(Func); | 1601 getDest()->emit(Func); |
1587 } | 1602 } |
1588 | 1603 |
1589 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { | 1604 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { |
1590 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1605 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
1591 assert(getSrcSize() == 2); | 1606 assert(getSrcSize() == 2); |
1592 assert(Condition < CondX86::Cmpps_Invalid); | 1607 assert(Condition < CondX86::Cmpps_Invalid); |
1593 // Assuming there isn't any load folding for cmpps, and vector constants | 1608 // Assuming there isn't any load folding for cmpps, and vector constants |
1594 // are not allowed in PNaCl. | 1609 // are not allowed in PNaCl. |
1595 assert(llvm::isa<Variable>(getSrc(1))); | 1610 assert(llvm::isa<Variable>(getSrc(1))); |
1596 const auto SrcVar = llvm::cast<Variable>(getSrc(1)); | 1611 const auto SrcVar = llvm::cast<Variable>(getSrc(1)); |
1597 if (SrcVar->hasReg()) { | 1612 if (SrcVar->hasReg()) { |
1598 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), | 1613 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), |
1599 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); | 1614 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); |
1600 } else { | 1615 } else { |
1601 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 1616 X8632::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) |
1602 ->stackVarToAsmOperand(SrcVar); | 1617 ->stackVarToAsmOperand(SrcVar); |
1603 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, | 1618 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, |
1604 Condition); | 1619 Condition); |
1605 } | 1620 } |
1606 } | 1621 } |
1607 | 1622 |
1608 void InstX8632Cmpps::dump(const Cfg *Func) const { | 1623 void InstX8632Cmpps::dump(const Cfg *Func) const { |
1609 if (!ALLOW_DUMP) | 1624 if (!ALLOW_DUMP) |
1610 return; | 1625 return; |
1611 Ostream &Str = Func->getContext()->getStrDump(); | 1626 Ostream &Str = Func->getContext()->getStrDump(); |
1612 assert(Condition < CondX86::Cmpps_Invalid); | 1627 assert(Condition < CondX86::Cmpps_Invalid); |
(...skipping 12 matching lines...) Expand all Loading... |
1625 Str << "\tlock"; | 1640 Str << "\tlock"; |
1626 } | 1641 } |
1627 Str << "\tcmpxchg" << getWidthString(getSrc(0)->getType()) << "\t"; | 1642 Str << "\tcmpxchg" << getWidthString(getSrc(0)->getType()) << "\t"; |
1628 getSrc(2)->emit(Func); | 1643 getSrc(2)->emit(Func); |
1629 Str << ", "; | 1644 Str << ", "; |
1630 getSrc(0)->emit(Func); | 1645 getSrc(0)->emit(Func); |
1631 } | 1646 } |
1632 | 1647 |
1633 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { | 1648 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { |
1634 assert(getSrcSize() == 3); | 1649 assert(getSrcSize() == 3); |
1635 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1650 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
1636 Type Ty = getSrc(0)->getType(); | 1651 Type Ty = getSrc(0)->getType(); |
1637 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 1652 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
1638 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 1653 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
1639 const x86::Address Addr = Mem->toAsmAddress(Asm); | 1654 const X8632::Address Addr = Mem->toAsmAddress(Asm); |
1640 const auto VarReg = llvm::cast<Variable>(getSrc(2)); | 1655 const auto VarReg = llvm::cast<Variable>(getSrc(2)); |
1641 assert(VarReg->hasReg()); | 1656 assert(VarReg->hasReg()); |
1642 const RegX8632::GPRRegister Reg = | 1657 const RegX8632::GPRRegister Reg = |
1643 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 1658 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
1644 Asm->cmpxchg(Ty, Addr, Reg, Locked); | 1659 Asm->cmpxchg(Ty, Addr, Reg, Locked); |
1645 } | 1660 } |
1646 | 1661 |
1647 void InstX8632Cmpxchg::dump(const Cfg *Func) const { | 1662 void InstX8632Cmpxchg::dump(const Cfg *Func) const { |
1648 if (!ALLOW_DUMP) | 1663 if (!ALLOW_DUMP) |
1649 return; | 1664 return; |
(...skipping 12 matching lines...) Expand all Loading... |
1662 assert(getSrcSize() == 5); | 1677 assert(getSrcSize() == 5); |
1663 if (Locked) { | 1678 if (Locked) { |
1664 Str << "\tlock"; | 1679 Str << "\tlock"; |
1665 } | 1680 } |
1666 Str << "\tcmpxchg8b\t"; | 1681 Str << "\tcmpxchg8b\t"; |
1667 getSrc(0)->emit(Func); | 1682 getSrc(0)->emit(Func); |
1668 } | 1683 } |
1669 | 1684 |
1670 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { | 1685 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { |
1671 assert(getSrcSize() == 5); | 1686 assert(getSrcSize() == 5); |
1672 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1687 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
1673 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 1688 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
1674 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 1689 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
1675 const x86::Address Addr = Mem->toAsmAddress(Asm); | 1690 const X8632::Address Addr = Mem->toAsmAddress(Asm); |
1676 Asm->cmpxchg8b(Addr, Locked); | 1691 Asm->cmpxchg8b(Addr, Locked); |
1677 } | 1692 } |
1678 | 1693 |
1679 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { | 1694 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { |
1680 if (!ALLOW_DUMP) | 1695 if (!ALLOW_DUMP) |
1681 return; | 1696 return; |
1682 Ostream &Str = Func->getContext()->getStrDump(); | 1697 Ostream &Str = Func->getContext()->getStrDump(); |
1683 if (Locked) { | 1698 if (Locked) { |
1684 Str << "lock "; | 1699 Str << "lock "; |
1685 } | 1700 } |
(...skipping 20 matching lines...) Expand all Loading... |
1706 assert(getSrcSize() == 1); | 1721 assert(getSrcSize() == 1); |
1707 const Variable *Dest = getDest(); | 1722 const Variable *Dest = getDest(); |
1708 const Operand *Src = getSrc(0); | 1723 const Operand *Src = getSrc(0); |
1709 Type DestTy = Dest->getType(); | 1724 Type DestTy = Dest->getType(); |
1710 Type SrcTy = Src->getType(); | 1725 Type SrcTy = Src->getType(); |
1711 switch (Variant) { | 1726 switch (Variant) { |
1712 case Si2ss: { | 1727 case Si2ss: { |
1713 assert(isScalarIntegerType(SrcTy)); | 1728 assert(isScalarIntegerType(SrcTy)); |
1714 assert(typeWidthInBytes(SrcTy) <= 4); | 1729 assert(typeWidthInBytes(SrcTy) <= 4); |
1715 assert(isScalarFloatingType(DestTy)); | 1730 assert(isScalarFloatingType(DestTy)); |
1716 static const x86::AssemblerX86::CastEmitterRegOp< | 1731 static const X8632::AssemblerX8632::CastEmitterRegOp< |
1717 RegX8632::XmmRegister, RegX8632::GPRRegister> Emitter = { | 1732 RegX8632::XmmRegister, RegX8632::GPRRegister> Emitter = { |
1718 &x86::AssemblerX86::cvtsi2ss, &x86::AssemblerX86::cvtsi2ss}; | 1733 &X8632::AssemblerX8632::cvtsi2ss, &X8632::AssemblerX8632::cvtsi2ss}; |
1719 emitIASCastRegOp<RegX8632::XmmRegister, RegX8632::GPRRegister, | 1734 emitIASCastRegOp<RegX8632::XmmRegister, RegX8632::GPRRegister, |
1720 RegX8632::getEncodedXmm, RegX8632::getEncodedGPR>( | 1735 RegX8632::getEncodedXmm, RegX8632::getEncodedGPR>( |
1721 Func, DestTy, Dest, Src, Emitter); | 1736 Func, DestTy, Dest, Src, Emitter); |
1722 return; | 1737 return; |
1723 } | 1738 } |
1724 case Tss2si: { | 1739 case Tss2si: { |
1725 assert(isScalarFloatingType(SrcTy)); | 1740 assert(isScalarFloatingType(SrcTy)); |
1726 assert(isScalarIntegerType(DestTy)); | 1741 assert(isScalarIntegerType(DestTy)); |
1727 assert(typeWidthInBytes(DestTy) <= 4); | 1742 assert(typeWidthInBytes(DestTy) <= 4); |
1728 static const x86::AssemblerX86::CastEmitterRegOp< | 1743 static const X8632::AssemblerX8632::CastEmitterRegOp< |
1729 RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = { | 1744 RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = { |
1730 &x86::AssemblerX86::cvttss2si, &x86::AssemblerX86::cvttss2si}; | 1745 &X8632::AssemblerX8632::cvttss2si, &X8632::AssemblerX8632::cvttss2si}; |
1731 emitIASCastRegOp<RegX8632::GPRRegister, RegX8632::XmmRegister, | 1746 emitIASCastRegOp<RegX8632::GPRRegister, RegX8632::XmmRegister, |
1732 RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>( | 1747 RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>( |
1733 Func, SrcTy, Dest, Src, Emitter); | 1748 Func, SrcTy, Dest, Src, Emitter); |
1734 return; | 1749 return; |
1735 } | 1750 } |
1736 case Float2float: { | 1751 case Float2float: { |
1737 assert(isScalarFloatingType(SrcTy)); | 1752 assert(isScalarFloatingType(SrcTy)); |
1738 assert(isScalarFloatingType(DestTy)); | 1753 assert(isScalarFloatingType(DestTy)); |
1739 assert(DestTy != SrcTy); | 1754 assert(DestTy != SrcTy); |
1740 static const x86::AssemblerX86::XmmEmitterRegOp Emitter = { | 1755 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { |
1741 &x86::AssemblerX86::cvtfloat2float, &x86::AssemblerX86::cvtfloat2float}; | 1756 &X8632::AssemblerX8632::cvtfloat2float, |
| 1757 &X8632::AssemblerX8632::cvtfloat2float}; |
1742 emitIASRegOpTyXMM(Func, SrcTy, Dest, Src, Emitter); | 1758 emitIASRegOpTyXMM(Func, SrcTy, Dest, Src, Emitter); |
1743 return; | 1759 return; |
1744 } | 1760 } |
1745 case Dq2ps: { | 1761 case Dq2ps: { |
1746 assert(isVectorIntegerType(SrcTy)); | 1762 assert(isVectorIntegerType(SrcTy)); |
1747 assert(isVectorFloatingType(DestTy)); | 1763 assert(isVectorFloatingType(DestTy)); |
1748 static const x86::AssemblerX86::XmmEmitterRegOp Emitter = { | 1764 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { |
1749 &x86::AssemblerX86::cvtdq2ps, &x86::AssemblerX86::cvtdq2ps}; | 1765 &X8632::AssemblerX8632::cvtdq2ps, &X8632::AssemblerX8632::cvtdq2ps}; |
1750 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, Emitter); | 1766 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, Emitter); |
1751 return; | 1767 return; |
1752 } | 1768 } |
1753 case Tps2dq: { | 1769 case Tps2dq: { |
1754 assert(isVectorFloatingType(SrcTy)); | 1770 assert(isVectorFloatingType(SrcTy)); |
1755 assert(isVectorIntegerType(DestTy)); | 1771 assert(isVectorIntegerType(DestTy)); |
1756 static const x86::AssemblerX86::XmmEmitterRegOp Emitter = { | 1772 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { |
1757 &x86::AssemblerX86::cvttps2dq, &x86::AssemblerX86::cvttps2dq}; | 1773 &X8632::AssemblerX8632::cvttps2dq, &X8632::AssemblerX8632::cvttps2dq}; |
1758 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, Emitter); | 1774 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, Emitter); |
1759 return; | 1775 return; |
1760 } | 1776 } |
1761 } | 1777 } |
1762 } | 1778 } |
1763 | 1779 |
1764 void InstX8632Cvt::dump(const Cfg *Func) const { | 1780 void InstX8632Cvt::dump(const Cfg *Func) const { |
1765 if (!ALLOW_DUMP) | 1781 if (!ALLOW_DUMP) |
1766 return; | 1782 return; |
1767 Ostream &Str = Func->getContext()->getStrDump(); | 1783 Ostream &Str = Func->getContext()->getStrDump(); |
(...skipping 15 matching lines...) Expand all Loading... |
1783 getSrc(1)->emit(Func); | 1799 getSrc(1)->emit(Func); |
1784 Str << ", "; | 1800 Str << ", "; |
1785 getSrc(0)->emit(Func); | 1801 getSrc(0)->emit(Func); |
1786 } | 1802 } |
1787 | 1803 |
1788 void InstX8632Icmp::emitIAS(const Cfg *Func) const { | 1804 void InstX8632Icmp::emitIAS(const Cfg *Func) const { |
1789 assert(getSrcSize() == 2); | 1805 assert(getSrcSize() == 2); |
1790 const Operand *Src0 = getSrc(0); | 1806 const Operand *Src0 = getSrc(0); |
1791 const Operand *Src1 = getSrc(1); | 1807 const Operand *Src1 = getSrc(1); |
1792 Type Ty = Src0->getType(); | 1808 Type Ty = Src0->getType(); |
1793 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { | 1809 static const X8632::AssemblerX8632::GPREmitterRegOp RegEmitter = { |
1794 &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp, | 1810 &X8632::AssemblerX8632::cmp, &X8632::AssemblerX8632::cmp, |
1795 &x86::AssemblerX86::cmp}; | 1811 &X8632::AssemblerX8632::cmp}; |
1796 static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = { | 1812 static const X8632::AssemblerX8632::GPREmitterAddrOp AddrEmitter = { |
1797 &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp}; | 1813 &X8632::AssemblerX8632::cmp, &X8632::AssemblerX8632::cmp}; |
1798 if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { | 1814 if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { |
1799 if (SrcVar0->hasReg()) { | 1815 if (SrcVar0->hasReg()) { |
1800 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); | 1816 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); |
1801 return; | 1817 return; |
1802 } | 1818 } |
1803 } | 1819 } |
1804 emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter); | 1820 emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter); |
1805 } | 1821 } |
1806 | 1822 |
1807 void InstX8632Icmp::dump(const Cfg *Func) const { | 1823 void InstX8632Icmp::dump(const Cfg *Func) const { |
(...skipping 16 matching lines...) Expand all Loading... |
1824 getSrc(0)->emit(Func); | 1840 getSrc(0)->emit(Func); |
1825 } | 1841 } |
1826 | 1842 |
1827 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const { | 1843 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const { |
1828 assert(getSrcSize() == 2); | 1844 assert(getSrcSize() == 2); |
1829 // Currently src0 is always a variable by convention, to avoid having | 1845 // Currently src0 is always a variable by convention, to avoid having |
1830 // two memory operands. | 1846 // two memory operands. |
1831 assert(llvm::isa<Variable>(getSrc(0))); | 1847 assert(llvm::isa<Variable>(getSrc(0))); |
1832 const auto Src0Var = llvm::cast<Variable>(getSrc(0)); | 1848 const auto Src0Var = llvm::cast<Variable>(getSrc(0)); |
1833 Type Ty = Src0Var->getType(); | 1849 Type Ty = Src0Var->getType(); |
1834 const static x86::AssemblerX86::XmmEmitterRegOp Emitter = { | 1850 const static X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { |
1835 &x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss}; | 1851 &X8632::AssemblerX8632::ucomiss, &X8632::AssemblerX8632::ucomiss}; |
1836 emitIASRegOpTyXMM(Func, Ty, Src0Var, getSrc(1), Emitter); | 1852 emitIASRegOpTyXMM(Func, Ty, Src0Var, getSrc(1), Emitter); |
1837 } | 1853 } |
1838 | 1854 |
1839 void InstX8632Ucomiss::dump(const Cfg *Func) const { | 1855 void InstX8632Ucomiss::dump(const Cfg *Func) const { |
1840 if (!ALLOW_DUMP) | 1856 if (!ALLOW_DUMP) |
1841 return; | 1857 return; |
1842 Ostream &Str = Func->getContext()->getStrDump(); | 1858 Ostream &Str = Func->getContext()->getStrDump(); |
1843 Str << "ucomiss." << getSrc(0)->getType() << " "; | 1859 Str << "ucomiss." << getSrc(0)->getType() << " "; |
1844 dumpSources(Func); | 1860 dumpSources(Func); |
1845 } | 1861 } |
1846 | 1862 |
1847 void InstX8632UD2::emit(const Cfg *Func) const { | 1863 void InstX8632UD2::emit(const Cfg *Func) const { |
1848 if (!ALLOW_DUMP) | 1864 if (!ALLOW_DUMP) |
1849 return; | 1865 return; |
1850 Ostream &Str = Func->getContext()->getStrEmit(); | 1866 Ostream &Str = Func->getContext()->getStrEmit(); |
1851 assert(getSrcSize() == 0); | 1867 assert(getSrcSize() == 0); |
1852 Str << "\tud2"; | 1868 Str << "\tud2"; |
1853 } | 1869 } |
1854 | 1870 |
1855 void InstX8632UD2::emitIAS(const Cfg *Func) const { | 1871 void InstX8632UD2::emitIAS(const Cfg *Func) const { |
1856 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1872 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
1857 Asm->ud2(); | 1873 Asm->ud2(); |
1858 } | 1874 } |
1859 | 1875 |
1860 void InstX8632UD2::dump(const Cfg *Func) const { | 1876 void InstX8632UD2::dump(const Cfg *Func) const { |
1861 if (!ALLOW_DUMP) | 1877 if (!ALLOW_DUMP) |
1862 return; | 1878 return; |
1863 Ostream &Str = Func->getContext()->getStrDump(); | 1879 Ostream &Str = Func->getContext()->getStrDump(); |
1864 Str << "ud2\n"; | 1880 Str << "ud2\n"; |
1865 } | 1881 } |
1866 | 1882 |
1867 void InstX8632Test::emit(const Cfg *Func) const { | 1883 void InstX8632Test::emit(const Cfg *Func) const { |
1868 if (!ALLOW_DUMP) | 1884 if (!ALLOW_DUMP) |
1869 return; | 1885 return; |
1870 Ostream &Str = Func->getContext()->getStrEmit(); | 1886 Ostream &Str = Func->getContext()->getStrEmit(); |
1871 assert(getSrcSize() == 2); | 1887 assert(getSrcSize() == 2); |
1872 Str << "\ttest" << getWidthString(getSrc(0)->getType()) << "\t"; | 1888 Str << "\ttest" << getWidthString(getSrc(0)->getType()) << "\t"; |
1873 getSrc(1)->emit(Func); | 1889 getSrc(1)->emit(Func); |
1874 Str << ", "; | 1890 Str << ", "; |
1875 getSrc(0)->emit(Func); | 1891 getSrc(0)->emit(Func); |
1876 } | 1892 } |
1877 | 1893 |
1878 void InstX8632Test::emitIAS(const Cfg *Func) const { | 1894 void InstX8632Test::emitIAS(const Cfg *Func) const { |
1879 assert(getSrcSize() == 2); | 1895 assert(getSrcSize() == 2); |
1880 const Operand *Src0 = getSrc(0); | 1896 const Operand *Src0 = getSrc(0); |
1881 const Operand *Src1 = getSrc(1); | 1897 const Operand *Src1 = getSrc(1); |
1882 Type Ty = Src0->getType(); | 1898 Type Ty = Src0->getType(); |
1883 // The Reg/Addr form of test is not encodeable. | 1899 // The Reg/Addr form of test is not encodeable. |
1884 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { | 1900 static const X8632::AssemblerX8632::GPREmitterRegOp RegEmitter = { |
1885 &x86::AssemblerX86::test, nullptr, &x86::AssemblerX86::test}; | 1901 &X8632::AssemblerX8632::test, nullptr, &X8632::AssemblerX8632::test}; |
1886 static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = { | 1902 static const X8632::AssemblerX8632::GPREmitterAddrOp AddrEmitter = { |
1887 &x86::AssemblerX86::test, &x86::AssemblerX86::test}; | 1903 &X8632::AssemblerX8632::test, &X8632::AssemblerX8632::test}; |
1888 if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { | 1904 if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { |
1889 if (SrcVar0->hasReg()) { | 1905 if (SrcVar0->hasReg()) { |
1890 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); | 1906 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); |
1891 return; | 1907 return; |
1892 } | 1908 } |
1893 } | 1909 } |
1894 llvm_unreachable("Nothing actually generates this so it's untested"); | 1910 llvm_unreachable("Nothing actually generates this so it's untested"); |
1895 emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter); | 1911 emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter); |
1896 } | 1912 } |
1897 | 1913 |
1898 void InstX8632Test::dump(const Cfg *Func) const { | 1914 void InstX8632Test::dump(const Cfg *Func) const { |
1899 if (!ALLOW_DUMP) | 1915 if (!ALLOW_DUMP) |
1900 return; | 1916 return; |
1901 Ostream &Str = Func->getContext()->getStrDump(); | 1917 Ostream &Str = Func->getContext()->getStrDump(); |
1902 Str << "test." << getSrc(0)->getType() << " "; | 1918 Str << "test." << getSrc(0)->getType() << " "; |
1903 dumpSources(Func); | 1919 dumpSources(Func); |
1904 } | 1920 } |
1905 | 1921 |
1906 void InstX8632Mfence::emit(const Cfg *Func) const { | 1922 void InstX8632Mfence::emit(const Cfg *Func) const { |
1907 if (!ALLOW_DUMP) | 1923 if (!ALLOW_DUMP) |
1908 return; | 1924 return; |
1909 Ostream &Str = Func->getContext()->getStrEmit(); | 1925 Ostream &Str = Func->getContext()->getStrEmit(); |
1910 assert(getSrcSize() == 0); | 1926 assert(getSrcSize() == 0); |
1911 Str << "\tmfence"; | 1927 Str << "\tmfence"; |
1912 } | 1928 } |
1913 | 1929 |
1914 void InstX8632Mfence::emitIAS(const Cfg *Func) const { | 1930 void InstX8632Mfence::emitIAS(const Cfg *Func) const { |
1915 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1931 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
1916 Asm->mfence(); | 1932 Asm->mfence(); |
1917 } | 1933 } |
1918 | 1934 |
1919 void InstX8632Mfence::dump(const Cfg *Func) const { | 1935 void InstX8632Mfence::dump(const Cfg *Func) const { |
1920 if (!ALLOW_DUMP) | 1936 if (!ALLOW_DUMP) |
1921 return; | 1937 return; |
1922 Ostream &Str = Func->getContext()->getStrDump(); | 1938 Ostream &Str = Func->getContext()->getStrDump(); |
1923 Str << "mfence\n"; | 1939 Str << "mfence\n"; |
1924 } | 1940 } |
1925 | 1941 |
(...skipping 13 matching lines...) Expand all Loading... |
1939 void InstX8632Store::emitIAS(const Cfg *Func) const { | 1955 void InstX8632Store::emitIAS(const Cfg *Func) const { |
1940 assert(getSrcSize() == 2); | 1956 assert(getSrcSize() == 2); |
1941 const Operand *Dest = getSrc(1); | 1957 const Operand *Dest = getSrc(1); |
1942 const Operand *Src = getSrc(0); | 1958 const Operand *Src = getSrc(0); |
1943 Type DestTy = Dest->getType(); | 1959 Type DestTy = Dest->getType(); |
1944 if (isScalarFloatingType(DestTy)) { | 1960 if (isScalarFloatingType(DestTy)) { |
1945 // Src must be a register, since Dest is a Mem operand of some kind. | 1961 // Src must be a register, since Dest is a Mem operand of some kind. |
1946 const auto SrcVar = llvm::cast<Variable>(Src); | 1962 const auto SrcVar = llvm::cast<Variable>(Src); |
1947 assert(SrcVar->hasReg()); | 1963 assert(SrcVar->hasReg()); |
1948 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum()); | 1964 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum()); |
1949 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1965 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
1950 if (const auto DestVar = llvm::dyn_cast<Variable>(Dest)) { | 1966 if (const auto DestVar = llvm::dyn_cast<Variable>(Dest)) { |
1951 assert(!DestVar->hasReg()); | 1967 assert(!DestVar->hasReg()); |
1952 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 1968 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
1953 ->stackVarToAsmOperand(DestVar)); | 1969 ->stackVarToAsmOperand(DestVar)); |
1954 Asm->movss(DestTy, StackAddr, SrcReg); | 1970 Asm->movss(DestTy, StackAddr, SrcReg); |
1955 } else { | 1971 } else { |
1956 const auto DestMem = llvm::cast<OperandX8632Mem>(Dest); | 1972 const auto DestMem = llvm::cast<OperandX8632Mem>(Dest); |
1957 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 1973 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
1958 Asm->movss(DestTy, DestMem->toAsmAddress(Asm), SrcReg); | 1974 Asm->movss(DestTy, DestMem->toAsmAddress(Asm), SrcReg); |
1959 } | 1975 } |
1960 return; | 1976 return; |
1961 } else { | 1977 } else { |
1962 assert(isScalarIntegerType(DestTy)); | 1978 assert(isScalarIntegerType(DestTy)); |
1963 static const x86::AssemblerX86::GPREmitterAddrOp GPRAddrEmitter = { | 1979 static const X8632::AssemblerX8632::GPREmitterAddrOp GPRAddrEmitter = { |
1964 &x86::AssemblerX86::mov, &x86::AssemblerX86::mov}; | 1980 &X8632::AssemblerX8632::mov, &X8632::AssemblerX8632::mov}; |
1965 emitIASAsAddrOpTyGPR(Func, DestTy, Dest, Src, GPRAddrEmitter); | 1981 emitIASAsAddrOpTyGPR(Func, DestTy, Dest, Src, GPRAddrEmitter); |
1966 } | 1982 } |
1967 } | 1983 } |
1968 | 1984 |
1969 void InstX8632Store::dump(const Cfg *Func) const { | 1985 void InstX8632Store::dump(const Cfg *Func) const { |
1970 if (!ALLOW_DUMP) | 1986 if (!ALLOW_DUMP) |
1971 return; | 1987 return; |
1972 Ostream &Str = Func->getContext()->getStrDump(); | 1988 Ostream &Str = Func->getContext()->getStrDump(); |
1973 Str << "mov." << getSrc(0)->getType() << " "; | 1989 Str << "mov." << getSrc(0)->getType() << " "; |
1974 getSrc(1)->dump(Func); | 1990 getSrc(1)->dump(Func); |
1975 Str << ", "; | 1991 Str << ", "; |
1976 getSrc(0)->dump(Func); | 1992 getSrc(0)->dump(Func); |
1977 } | 1993 } |
1978 | 1994 |
1979 void InstX8632StoreP::emit(const Cfg *Func) const { | 1995 void InstX8632StoreP::emit(const Cfg *Func) const { |
1980 if (!ALLOW_DUMP) | 1996 if (!ALLOW_DUMP) |
1981 return; | 1997 return; |
1982 Ostream &Str = Func->getContext()->getStrEmit(); | 1998 Ostream &Str = Func->getContext()->getStrEmit(); |
1983 assert(getSrcSize() == 2); | 1999 assert(getSrcSize() == 2); |
1984 Str << "\tmovups\t"; | 2000 Str << "\tmovups\t"; |
1985 getSrc(0)->emit(Func); | 2001 getSrc(0)->emit(Func); |
1986 Str << ", "; | 2002 Str << ", "; |
1987 getSrc(1)->emit(Func); | 2003 getSrc(1)->emit(Func); |
1988 } | 2004 } |
1989 | 2005 |
1990 void InstX8632StoreP::emitIAS(const Cfg *Func) const { | 2006 void InstX8632StoreP::emitIAS(const Cfg *Func) const { |
1991 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2007 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
1992 assert(getSrcSize() == 2); | 2008 assert(getSrcSize() == 2); |
1993 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); | 2009 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); |
1994 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); | 2010 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); |
1995 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2011 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
1996 assert(SrcVar->hasReg()); | 2012 assert(SrcVar->hasReg()); |
1997 Asm->movups(DestMem->toAsmAddress(Asm), | 2013 Asm->movups(DestMem->toAsmAddress(Asm), |
1998 RegX8632::getEncodedXmm(SrcVar->getRegNum())); | 2014 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
1999 } | 2015 } |
2000 | 2016 |
2001 void InstX8632StoreP::dump(const Cfg *Func) const { | 2017 void InstX8632StoreP::dump(const Cfg *Func) const { |
(...skipping 13 matching lines...) Expand all Loading... |
2015 assert(getSrcSize() == 2); | 2031 assert(getSrcSize() == 2); |
2016 assert(getSrc(1)->getType() == IceType_i64 || | 2032 assert(getSrc(1)->getType() == IceType_i64 || |
2017 getSrc(1)->getType() == IceType_f64); | 2033 getSrc(1)->getType() == IceType_f64); |
2018 Str << "\tmovq\t"; | 2034 Str << "\tmovq\t"; |
2019 getSrc(0)->emit(Func); | 2035 getSrc(0)->emit(Func); |
2020 Str << ", "; | 2036 Str << ", "; |
2021 getSrc(1)->emit(Func); | 2037 getSrc(1)->emit(Func); |
2022 } | 2038 } |
2023 | 2039 |
2024 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { | 2040 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { |
2025 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2041 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2026 assert(getSrcSize() == 2); | 2042 assert(getSrcSize() == 2); |
2027 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); | 2043 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); |
2028 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); | 2044 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); |
2029 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2045 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
2030 assert(SrcVar->hasReg()); | 2046 assert(SrcVar->hasReg()); |
2031 Asm->movq(DestMem->toAsmAddress(Asm), | 2047 Asm->movq(DestMem->toAsmAddress(Asm), |
2032 RegX8632::getEncodedXmm(SrcVar->getRegNum())); | 2048 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
2033 } | 2049 } |
2034 | 2050 |
2035 void InstX8632StoreQ::dump(const Cfg *Func) const { | 2051 void InstX8632StoreQ::dump(const Cfg *Func) const { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2096 const Operand *Src = getSrc(0); | 2112 const Operand *Src = getSrc(0); |
2097 Type DestTy = Dest->getType(); | 2113 Type DestTy = Dest->getType(); |
2098 Type SrcTy = Src->getType(); | 2114 Type SrcTy = Src->getType(); |
2099 // Mov can be used for GPRs or XMM registers. Also, the type does not | 2115 // Mov can be used for GPRs or XMM registers. Also, the type does not |
2100 // necessarily match (Mov can be used for bitcasts). However, when | 2116 // necessarily match (Mov can be used for bitcasts). However, when |
2101 // the type does not match, one of the operands must be a register. | 2117 // the type does not match, one of the operands must be a register. |
2102 // Thus, the strategy is to find out if Src or Dest are a register, | 2118 // Thus, the strategy is to find out if Src or Dest are a register, |
2103 // then use that register's type to decide on which emitter set to use. | 2119 // then use that register's type to decide on which emitter set to use. |
2104 // The emitter set will include reg-reg movs, but that case should | 2120 // The emitter set will include reg-reg movs, but that case should |
2105 // be unused when the types don't match. | 2121 // be unused when the types don't match. |
2106 static const x86::AssemblerX86::XmmEmitterRegOp XmmRegEmitter = { | 2122 static const X8632::AssemblerX8632::XmmEmitterRegOp XmmRegEmitter = { |
2107 &x86::AssemblerX86::movss, &x86::AssemblerX86::movss}; | 2123 &X8632::AssemblerX8632::movss, &X8632::AssemblerX8632::movss}; |
2108 static const x86::AssemblerX86::GPREmitterRegOp GPRRegEmitter = { | 2124 static const X8632::AssemblerX8632::GPREmitterRegOp GPRRegEmitter = { |
2109 &x86::AssemblerX86::mov, &x86::AssemblerX86::mov, | 2125 &X8632::AssemblerX8632::mov, &X8632::AssemblerX8632::mov, |
2110 &x86::AssemblerX86::mov}; | 2126 &X8632::AssemblerX8632::mov}; |
2111 static const x86::AssemblerX86::GPREmitterAddrOp GPRAddrEmitter = { | 2127 static const X8632::AssemblerX8632::GPREmitterAddrOp GPRAddrEmitter = { |
2112 &x86::AssemblerX86::mov, &x86::AssemblerX86::mov}; | 2128 &X8632::AssemblerX8632::mov, &X8632::AssemblerX8632::mov}; |
2113 // For an integer truncation operation, src is wider than dest. | 2129 // For an integer truncation operation, src is wider than dest. |
2114 // Ideally, we use a mov instruction whose data width matches the | 2130 // Ideally, we use a mov instruction whose data width matches the |
2115 // narrower dest. This is a problem if e.g. src is a register like | 2131 // narrower dest. This is a problem if e.g. src is a register like |
2116 // esi or si where there is no 8-bit version of the register. To be | 2132 // esi or si where there is no 8-bit version of the register. To be |
2117 // safe, we instead widen the dest to match src. This works even | 2133 // safe, we instead widen the dest to match src. This works even |
2118 // for stack-allocated dest variables because typeWidthOnStack() | 2134 // for stack-allocated dest variables because typeWidthOnStack() |
2119 // pads to a 4-byte boundary even if only a lower portion is used. | 2135 // pads to a 4-byte boundary even if only a lower portion is used. |
2120 // TODO: This assert disallows usages such as copying a floating point | 2136 // TODO: This assert disallows usages such as copying a floating point |
2121 // value between a vector and a scalar (which movss is used for). | 2137 // value between a vector and a scalar (which movss is used for). |
2122 // Clean this up. | 2138 // Clean this up. |
2123 assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) == | 2139 assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) == |
2124 Func->getTarget()->typeWidthInBytesOnStack(Src->getType())); | 2140 Func->getTarget()->typeWidthInBytesOnStack(Src->getType())); |
2125 if (Dest->hasReg()) { | 2141 if (Dest->hasReg()) { |
2126 if (isScalarFloatingType(DestTy)) { | 2142 if (isScalarFloatingType(DestTy)) { |
2127 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, XmmRegEmitter); | 2143 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, XmmRegEmitter); |
2128 return; | 2144 return; |
2129 } else { | 2145 } else { |
2130 assert(isScalarIntegerType(DestTy)); | 2146 assert(isScalarIntegerType(DestTy)); |
2131 // Widen DestTy for truncation (see above note). We should only do this | 2147 // Widen DestTy for truncation (see above note). We should only do this |
2132 // when both Src and Dest are integer types. | 2148 // when both Src and Dest are integer types. |
2133 if (isScalarIntegerType(SrcTy)) { | 2149 if (isScalarIntegerType(SrcTy)) { |
2134 DestTy = SrcTy; | 2150 DestTy = SrcTy; |
2135 } | 2151 } |
2136 emitIASRegOpTyGPR(Func, DestTy, Dest, Src, GPRRegEmitter); | 2152 emitIASRegOpTyGPR(Func, DestTy, Dest, Src, GPRRegEmitter); |
2137 return; | 2153 return; |
2138 } | 2154 } |
2139 } else { | 2155 } else { |
2140 // Dest must be Stack and Src *could* be a register. Use Src's type | 2156 // Dest must be Stack and Src *could* be a register. Use Src's type |
2141 // to decide on the emitters. | 2157 // to decide on the emitters. |
2142 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2158 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
2143 ->stackVarToAsmOperand(Dest)); | 2159 ->stackVarToAsmOperand(Dest)); |
2144 if (isScalarFloatingType(SrcTy)) { | 2160 if (isScalarFloatingType(SrcTy)) { |
2145 // Src must be a register. | 2161 // Src must be a register. |
2146 const auto SrcVar = llvm::cast<Variable>(Src); | 2162 const auto SrcVar = llvm::cast<Variable>(Src); |
2147 assert(SrcVar->hasReg()); | 2163 assert(SrcVar->hasReg()); |
2148 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2164 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2149 Asm->movss(SrcTy, StackAddr, | 2165 Asm->movss(SrcTy, StackAddr, |
2150 RegX8632::getEncodedXmm(SrcVar->getRegNum())); | 2166 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
2151 return; | 2167 return; |
2152 } else { | 2168 } else { |
2153 // Src can be a register or immediate. | 2169 // Src can be a register or immediate. |
2154 assert(isScalarIntegerType(SrcTy)); | 2170 assert(isScalarIntegerType(SrcTy)); |
2155 emitIASAddrOpTyGPR(Func, SrcTy, StackAddr, Src, GPRAddrEmitter); | 2171 emitIASAddrOpTyGPR(Func, SrcTy, StackAddr, Src, GPRAddrEmitter); |
2156 return; | 2172 return; |
2157 } | 2173 } |
2158 return; | 2174 return; |
2159 } | 2175 } |
2160 } | 2176 } |
2161 | 2177 |
2162 template <> void InstX8632Movd::emitIAS(const Cfg *Func) const { | 2178 template <> void InstX8632Movd::emitIAS(const Cfg *Func) const { |
2163 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2179 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2164 assert(getSrcSize() == 1); | 2180 assert(getSrcSize() == 1); |
2165 const Variable *Dest = getDest(); | 2181 const Variable *Dest = getDest(); |
2166 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); | 2182 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); |
2167 // For insert/extract element (one of Src/Dest is an Xmm vector and | 2183 // For insert/extract element (one of Src/Dest is an Xmm vector and |
2168 // the other is an int type). | 2184 // the other is an int type). |
2169 if (SrcVar->getType() == IceType_i32) { | 2185 if (SrcVar->getType() == IceType_i32) { |
2170 assert(isVectorType(Dest->getType())); | 2186 assert(isVectorType(Dest->getType())); |
2171 assert(Dest->hasReg()); | 2187 assert(Dest->hasReg()); |
2172 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); | 2188 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); |
2173 if (SrcVar->hasReg()) { | 2189 if (SrcVar->hasReg()) { |
2174 Asm->movd(DestReg, RegX8632::getEncodedGPR(SrcVar->getRegNum())); | 2190 Asm->movd(DestReg, RegX8632::getEncodedGPR(SrcVar->getRegNum())); |
2175 } else { | 2191 } else { |
2176 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2192 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
2177 ->stackVarToAsmOperand(SrcVar)); | 2193 ->stackVarToAsmOperand(SrcVar)); |
2178 Asm->movd(DestReg, StackAddr); | 2194 Asm->movd(DestReg, StackAddr); |
2179 } | 2195 } |
2180 } else { | 2196 } else { |
2181 assert(isVectorType(SrcVar->getType())); | 2197 assert(isVectorType(SrcVar->getType())); |
2182 assert(SrcVar->hasReg()); | 2198 assert(SrcVar->hasReg()); |
2183 assert(Dest->getType() == IceType_i32); | 2199 assert(Dest->getType() == IceType_i32); |
2184 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum()); | 2200 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum()); |
2185 if (Dest->hasReg()) { | 2201 if (Dest->hasReg()) { |
2186 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg); | 2202 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg); |
2187 } else { | 2203 } else { |
2188 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2204 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
2189 ->stackVarToAsmOperand(Dest)); | 2205 ->stackVarToAsmOperand(Dest)); |
2190 Asm->movd(StackAddr, SrcReg); | 2206 Asm->movd(StackAddr, SrcReg); |
2191 } | 2207 } |
2192 } | 2208 } |
2193 } | 2209 } |
2194 | 2210 |
2195 template <> void InstX8632Movp::emit(const Cfg *Func) const { | 2211 template <> void InstX8632Movp::emit(const Cfg *Func) const { |
2196 if (!ALLOW_DUMP) | 2212 if (!ALLOW_DUMP) |
2197 return; | 2213 return; |
2198 // TODO(wala,stichnot): movups works with all vector operands, but | 2214 // TODO(wala,stichnot): movups works with all vector operands, but |
2199 // there exist other instructions (movaps, movdqa, movdqu) that may | 2215 // there exist other instructions (movaps, movdqa, movdqu) that may |
2200 // perform better, depending on the data type and alignment of the | 2216 // perform better, depending on the data type and alignment of the |
2201 // operands. | 2217 // operands. |
2202 Ostream &Str = Func->getContext()->getStrEmit(); | 2218 Ostream &Str = Func->getContext()->getStrEmit(); |
2203 assert(getSrcSize() == 1); | 2219 assert(getSrcSize() == 1); |
2204 Str << "\tmovups\t"; | 2220 Str << "\tmovups\t"; |
2205 getSrc(0)->emit(Func); | 2221 getSrc(0)->emit(Func); |
2206 Str << ", "; | 2222 Str << ", "; |
2207 getDest()->emit(Func); | 2223 getDest()->emit(Func); |
2208 } | 2224 } |
2209 | 2225 |
2210 template <> void InstX8632Movp::emitIAS(const Cfg *Func) const { | 2226 template <> void InstX8632Movp::emitIAS(const Cfg *Func) const { |
2211 assert(getSrcSize() == 1); | 2227 assert(getSrcSize() == 1); |
2212 assert(isVectorType(getDest()->getType())); | 2228 assert(isVectorType(getDest()->getType())); |
2213 const Variable *Dest = getDest(); | 2229 const Variable *Dest = getDest(); |
2214 const Operand *Src = getSrc(0); | 2230 const Operand *Src = getSrc(0); |
2215 const static x86::AssemblerX86::XmmEmitterMovOps Emitter = { | 2231 const static X8632::AssemblerX8632::XmmEmitterMovOps Emitter = { |
2216 &x86::AssemblerX86::movups, &x86::AssemblerX86::movups, | 2232 &X8632::AssemblerX8632::movups, &X8632::AssemblerX8632::movups, |
2217 &x86::AssemblerX86::movups}; | 2233 &X8632::AssemblerX8632::movups}; |
2218 emitIASMovlikeXMM(Func, Dest, Src, Emitter); | 2234 emitIASMovlikeXMM(Func, Dest, Src, Emitter); |
2219 } | 2235 } |
2220 | 2236 |
2221 template <> void InstX8632Movq::emit(const Cfg *Func) const { | 2237 template <> void InstX8632Movq::emit(const Cfg *Func) const { |
2222 if (!ALLOW_DUMP) | 2238 if (!ALLOW_DUMP) |
2223 return; | 2239 return; |
2224 Ostream &Str = Func->getContext()->getStrEmit(); | 2240 Ostream &Str = Func->getContext()->getStrEmit(); |
2225 assert(getSrcSize() == 1); | 2241 assert(getSrcSize() == 1); |
2226 assert(getDest()->getType() == IceType_i64 || | 2242 assert(getDest()->getType() == IceType_i64 || |
2227 getDest()->getType() == IceType_f64); | 2243 getDest()->getType() == IceType_f64); |
2228 Str << "\tmovq\t"; | 2244 Str << "\tmovq\t"; |
2229 getSrc(0)->emit(Func); | 2245 getSrc(0)->emit(Func); |
2230 Str << ", "; | 2246 Str << ", "; |
2231 getDest()->emit(Func); | 2247 getDest()->emit(Func); |
2232 } | 2248 } |
2233 | 2249 |
2234 template <> void InstX8632Movq::emitIAS(const Cfg *Func) const { | 2250 template <> void InstX8632Movq::emitIAS(const Cfg *Func) const { |
2235 assert(getSrcSize() == 1); | 2251 assert(getSrcSize() == 1); |
2236 assert(getDest()->getType() == IceType_i64 || | 2252 assert(getDest()->getType() == IceType_i64 || |
2237 getDest()->getType() == IceType_f64); | 2253 getDest()->getType() == IceType_f64); |
2238 const Variable *Dest = getDest(); | 2254 const Variable *Dest = getDest(); |
2239 const Operand *Src = getSrc(0); | 2255 const Operand *Src = getSrc(0); |
2240 const static x86::AssemblerX86::XmmEmitterMovOps Emitter = { | 2256 const static X8632::AssemblerX8632::XmmEmitterMovOps Emitter = { |
2241 &x86::AssemblerX86::movq, &x86::AssemblerX86::movq, | 2257 &X8632::AssemblerX8632::movq, &X8632::AssemblerX8632::movq, |
2242 &x86::AssemblerX86::movq}; | 2258 &X8632::AssemblerX8632::movq}; |
2243 emitIASMovlikeXMM(Func, Dest, Src, Emitter); | 2259 emitIASMovlikeXMM(Func, Dest, Src, Emitter); |
2244 } | 2260 } |
2245 | 2261 |
2246 template <> void InstX8632MovssRegs::emitIAS(const Cfg *Func) const { | 2262 template <> void InstX8632MovssRegs::emitIAS(const Cfg *Func) const { |
2247 // This is Binop variant is only intended to be used for reg-reg moves | 2263 // This is Binop variant is only intended to be used for reg-reg moves |
2248 // where part of the Dest register is untouched. | 2264 // where part of the Dest register is untouched. |
2249 assert(getSrcSize() == 2); | 2265 assert(getSrcSize() == 2); |
2250 const Variable *Dest = getDest(); | 2266 const Variable *Dest = getDest(); |
2251 assert(Dest == getSrc(0)); | 2267 assert(Dest == getSrc(0)); |
2252 const auto SrcVar = llvm::cast<Variable>(getSrc(1)); | 2268 const auto SrcVar = llvm::cast<Variable>(getSrc(1)); |
2253 assert(Dest->hasReg() && SrcVar->hasReg()); | 2269 assert(Dest->hasReg() && SrcVar->hasReg()); |
2254 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2270 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2255 Asm->movss(IceType_f32, RegX8632::getEncodedXmm(Dest->getRegNum()), | 2271 Asm->movss(IceType_f32, RegX8632::getEncodedXmm(Dest->getRegNum()), |
2256 RegX8632::getEncodedXmm(SrcVar->getRegNum())); | 2272 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
2257 } | 2273 } |
2258 | 2274 |
2259 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const { | 2275 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const { |
2260 assert(getSrcSize() == 1); | 2276 assert(getSrcSize() == 1); |
2261 const Variable *Dest = getDest(); | 2277 const Variable *Dest = getDest(); |
2262 const Operand *Src = getSrc(0); | 2278 const Operand *Src = getSrc(0); |
2263 // Dest must be a > 8-bit register, but Src can be 8-bit. In practice | 2279 // Dest must be a > 8-bit register, but Src can be 8-bit. In practice |
2264 // we just use the full register for Dest to avoid having an | 2280 // we just use the full register for Dest to avoid having an |
(...skipping 16 matching lines...) Expand all Loading... |
2281 | 2297 |
2282 void InstX8632Nop::emit(const Cfg *Func) const { | 2298 void InstX8632Nop::emit(const Cfg *Func) const { |
2283 if (!ALLOW_DUMP) | 2299 if (!ALLOW_DUMP) |
2284 return; | 2300 return; |
2285 Ostream &Str = Func->getContext()->getStrEmit(); | 2301 Ostream &Str = Func->getContext()->getStrEmit(); |
2286 // TODO: Emit the right code for each variant. | 2302 // TODO: Emit the right code for each variant. |
2287 Str << "\tnop\t# variant = " << Variant; | 2303 Str << "\tnop\t# variant = " << Variant; |
2288 } | 2304 } |
2289 | 2305 |
2290 void InstX8632Nop::emitIAS(const Cfg *Func) const { | 2306 void InstX8632Nop::emitIAS(const Cfg *Func) const { |
2291 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2307 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2292 // TODO: Emit the right code for the variant. | 2308 // TODO: Emit the right code for the variant. |
2293 Asm->nop(); | 2309 Asm->nop(); |
2294 } | 2310 } |
2295 | 2311 |
2296 void InstX8632Nop::dump(const Cfg *Func) const { | 2312 void InstX8632Nop::dump(const Cfg *Func) const { |
2297 if (!ALLOW_DUMP) | 2313 if (!ALLOW_DUMP) |
2298 return; | 2314 return; |
2299 Ostream &Str = Func->getContext()->getStrDump(); | 2315 Ostream &Str = Func->getContext()->getStrDump(); |
2300 Str << "nop (variant = " << Variant << ")"; | 2316 Str << "nop (variant = " << Variant << ")"; |
2301 } | 2317 } |
(...skipping 17 matching lines...) Expand all Loading... |
2319 Str << "\tfld" << getFldString(Ty) << "\t" | 2335 Str << "\tfld" << getFldString(Ty) << "\t" |
2320 << "(%esp)\n"; | 2336 << "(%esp)\n"; |
2321 Str << "\taddl\t$" << Width << ", %esp"; | 2337 Str << "\taddl\t$" << Width << ", %esp"; |
2322 return; | 2338 return; |
2323 } | 2339 } |
2324 Str << "\tfld" << getFldString(Ty) << "\t"; | 2340 Str << "\tfld" << getFldString(Ty) << "\t"; |
2325 getSrc(0)->emit(Func); | 2341 getSrc(0)->emit(Func); |
2326 } | 2342 } |
2327 | 2343 |
2328 void InstX8632Fld::emitIAS(const Cfg *Func) const { | 2344 void InstX8632Fld::emitIAS(const Cfg *Func) const { |
2329 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2345 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2330 assert(getSrcSize() == 1); | 2346 assert(getSrcSize() == 1); |
2331 const Operand *Src = getSrc(0); | 2347 const Operand *Src = getSrc(0); |
2332 Type Ty = Src->getType(); | 2348 Type Ty = Src->getType(); |
2333 if (const auto Var = llvm::dyn_cast<Variable>(Src)) { | 2349 if (const auto Var = llvm::dyn_cast<Variable>(Src)) { |
2334 if (Var->hasReg()) { | 2350 if (Var->hasReg()) { |
2335 // This is a physical xmm register, so we need to spill it to a | 2351 // This is a physical xmm register, so we need to spill it to a |
2336 // temporary stack slot. | 2352 // temporary stack slot. |
2337 x86::Immediate Width(typeWidthInBytes(Ty)); | 2353 X8632::Immediate Width(typeWidthInBytes(Ty)); |
2338 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2354 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
2339 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0); | 2355 X8632::Address StackSlot = X8632::Address(RegX8632::Encoded_Reg_esp, 0); |
2340 Asm->movss(Ty, StackSlot, RegX8632::getEncodedXmm(Var->getRegNum())); | 2356 Asm->movss(Ty, StackSlot, RegX8632::getEncodedXmm(Var->getRegNum())); |
2341 Asm->fld(Ty, StackSlot); | 2357 Asm->fld(Ty, StackSlot); |
2342 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2358 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
2343 } else { | 2359 } else { |
2344 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2360 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
2345 ->stackVarToAsmOperand(Var)); | 2361 ->stackVarToAsmOperand(Var)); |
2346 Asm->fld(Ty, StackAddr); | 2362 Asm->fld(Ty, StackAddr); |
2347 } | 2363 } |
2348 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 2364 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
2349 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2365 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
2350 Asm->fld(Ty, Mem->toAsmAddress(Asm)); | 2366 Asm->fld(Ty, Mem->toAsmAddress(Asm)); |
2351 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { | 2367 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { |
2352 Asm->fld(Ty, x86::Address::ofConstPool(Asm, Imm)); | 2368 Asm->fld(Ty, X8632::Address::ofConstPool(Asm, Imm)); |
2353 } else { | 2369 } else { |
2354 llvm_unreachable("Unexpected operand type"); | 2370 llvm_unreachable("Unexpected operand type"); |
2355 } | 2371 } |
2356 } | 2372 } |
2357 | 2373 |
2358 void InstX8632Fld::dump(const Cfg *Func) const { | 2374 void InstX8632Fld::dump(const Cfg *Func) const { |
2359 if (!ALLOW_DUMP) | 2375 if (!ALLOW_DUMP) |
2360 return; | 2376 return; |
2361 Ostream &Str = Func->getContext()->getStrDump(); | 2377 Ostream &Str = Func->getContext()->getStrDump(); |
2362 Str << "fld." << getSrc(0)->getType() << " "; | 2378 Str << "fld." << getSrc(0)->getType() << " "; |
(...skipping 28 matching lines...) Expand all Loading... |
2391 Str << "\tfstp" << getFldString(Ty) << "\t" | 2407 Str << "\tfstp" << getFldString(Ty) << "\t" |
2392 << "(%esp)\n"; | 2408 << "(%esp)\n"; |
2393 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t" | 2409 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t" |
2394 << "(%esp), "; | 2410 << "(%esp), "; |
2395 getDest()->emit(Func); | 2411 getDest()->emit(Func); |
2396 Str << "\n"; | 2412 Str << "\n"; |
2397 Str << "\taddl\t$" << Width << ", %esp"; | 2413 Str << "\taddl\t$" << Width << ", %esp"; |
2398 } | 2414 } |
2399 | 2415 |
2400 void InstX8632Fstp::emitIAS(const Cfg *Func) const { | 2416 void InstX8632Fstp::emitIAS(const Cfg *Func) const { |
2401 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2417 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2402 assert(getSrcSize() == 0); | 2418 assert(getSrcSize() == 0); |
2403 const Variable *Dest = getDest(); | 2419 const Variable *Dest = getDest(); |
2404 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to | 2420 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to |
2405 // "partially" delete the fstp if the Dest is unused. | 2421 // "partially" delete the fstp if the Dest is unused. |
2406 // Even if Dest is unused, the fstp should be kept for the SideEffects | 2422 // Even if Dest is unused, the fstp should be kept for the SideEffects |
2407 // of popping the stack. | 2423 // of popping the stack. |
2408 if (!Dest) { | 2424 if (!Dest) { |
2409 Asm->fstp(RegX8632::getEncodedSTReg(0)); | 2425 Asm->fstp(RegX8632::getEncodedSTReg(0)); |
2410 return; | 2426 return; |
2411 } | 2427 } |
2412 Type Ty = Dest->getType(); | 2428 Type Ty = Dest->getType(); |
2413 if (!Dest->hasReg()) { | 2429 if (!Dest->hasReg()) { |
2414 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2430 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
2415 ->stackVarToAsmOperand(Dest)); | 2431 ->stackVarToAsmOperand(Dest)); |
2416 Asm->fstp(Ty, StackAddr); | 2432 Asm->fstp(Ty, StackAddr); |
2417 } else { | 2433 } else { |
2418 // Dest is a physical (xmm) register, so st(0) needs to go through | 2434 // Dest is a physical (xmm) register, so st(0) needs to go through |
2419 // memory. Hack this by creating a temporary stack slot, spilling | 2435 // memory. Hack this by creating a temporary stack slot, spilling |
2420 // st(0) there, loading it into the xmm register, and deallocating | 2436 // st(0) there, loading it into the xmm register, and deallocating |
2421 // the stack slot. | 2437 // the stack slot. |
2422 x86::Immediate Width(typeWidthInBytes(Ty)); | 2438 X8632::Immediate Width(typeWidthInBytes(Ty)); |
2423 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2439 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
2424 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0); | 2440 X8632::Address StackSlot = X8632::Address(RegX8632::Encoded_Reg_esp, 0); |
2425 Asm->fstp(Ty, StackSlot); | 2441 Asm->fstp(Ty, StackSlot); |
2426 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot); | 2442 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot); |
2427 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2443 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
2428 } | 2444 } |
2429 } | 2445 } |
2430 | 2446 |
2431 void InstX8632Fstp::dump(const Cfg *Func) const { | 2447 void InstX8632Fstp::dump(const Cfg *Func) const { |
2432 if (!ALLOW_DUMP) | 2448 if (!ALLOW_DUMP) |
2433 return; | 2449 return; |
2434 Ostream &Str = Func->getContext()->getStrDump(); | 2450 Ostream &Str = Func->getContext()->getStrDump(); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2486 Type DispatchTy = Dest->getType(); | 2502 Type DispatchTy = Dest->getType(); |
2487 assert(DispatchTy == IceType_i16 || | 2503 assert(DispatchTy == IceType_i16 || |
2488 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 2504 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
2489 TargetX8632::SSE4_1); | 2505 TargetX8632::SSE4_1); |
2490 // pextrw must take a register dest. There is an SSE4.1 version that takes | 2506 // pextrw must take a register dest. There is an SSE4.1 version that takes |
2491 // a memory dest, but we aren't using it. For uniformity, just restrict | 2507 // a memory dest, but we aren't using it. For uniformity, just restrict |
2492 // them all to have a register dest for now. | 2508 // them all to have a register dest for now. |
2493 assert(Dest->hasReg()); | 2509 assert(Dest->hasReg()); |
2494 // pextrw's Src(0) must be a register (both SSE4.1 and SSE2). | 2510 // pextrw's Src(0) must be a register (both SSE4.1 and SSE2). |
2495 assert(llvm::cast<Variable>(getSrc(0))->hasReg()); | 2511 assert(llvm::cast<Variable>(getSrc(0))->hasReg()); |
2496 static const x86::AssemblerX86::ThreeOpImmEmitter< | 2512 static const X8632::AssemblerX8632::ThreeOpImmEmitter< |
2497 RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = { | 2513 RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = { |
2498 &x86::AssemblerX86::pextr, nullptr}; | 2514 &X8632::AssemblerX8632::pextr, nullptr}; |
2499 emitIASThreeOpImmOps<RegX8632::GPRRegister, RegX8632::XmmRegister, | 2515 emitIASThreeOpImmOps<RegX8632::GPRRegister, RegX8632::XmmRegister, |
2500 RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>( | 2516 RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>( |
2501 Func, DispatchTy, Dest, getSrc(0), getSrc(1), Emitter); | 2517 Func, DispatchTy, Dest, getSrc(0), getSrc(1), Emitter); |
2502 } | 2518 } |
2503 | 2519 |
2504 template <> void InstX8632Pinsr::emit(const Cfg *Func) const { | 2520 template <> void InstX8632Pinsr::emit(const Cfg *Func) const { |
2505 if (!ALLOW_DUMP) | 2521 if (!ALLOW_DUMP) |
2506 return; | 2522 return; |
2507 Ostream &Str = Func->getContext()->getStrEmit(); | 2523 Ostream &Str = Func->getContext()->getStrEmit(); |
2508 assert(getSrcSize() == 3); | 2524 assert(getSrcSize() == 3); |
(...skipping 27 matching lines...) Expand all Loading... |
2536 // pinsrb and pinsrd are SSE4.1 instructions. | 2552 // pinsrb and pinsrd are SSE4.1 instructions. |
2537 const Operand *Src0 = getSrc(1); | 2553 const Operand *Src0 = getSrc(1); |
2538 Type DispatchTy = Src0->getType(); | 2554 Type DispatchTy = Src0->getType(); |
2539 assert(DispatchTy == IceType_i16 || | 2555 assert(DispatchTy == IceType_i16 || |
2540 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 2556 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
2541 TargetX8632::SSE4_1); | 2557 TargetX8632::SSE4_1); |
2542 // If src1 is a register, it should always be r32 (this should fall out | 2558 // If src1 is a register, it should always be r32 (this should fall out |
2543 // from the encodings for ByteRegs overlapping the encodings for r32), | 2559 // from the encodings for ByteRegs overlapping the encodings for r32), |
2544 // but we have to trust the regalloc to not choose "ah", where it | 2560 // but we have to trust the regalloc to not choose "ah", where it |
2545 // doesn't overlap. | 2561 // doesn't overlap. |
2546 static const x86::AssemblerX86::ThreeOpImmEmitter< | 2562 static const X8632::AssemblerX8632::ThreeOpImmEmitter< |
2547 RegX8632::XmmRegister, RegX8632::GPRRegister> Emitter = { | 2563 RegX8632::XmmRegister, RegX8632::GPRRegister> Emitter = { |
2548 &x86::AssemblerX86::pinsr, &x86::AssemblerX86::pinsr}; | 2564 &X8632::AssemblerX8632::pinsr, &X8632::AssemblerX8632::pinsr}; |
2549 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::GPRRegister, | 2565 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::GPRRegister, |
2550 RegX8632::getEncodedXmm, RegX8632::getEncodedGPR>( | 2566 RegX8632::getEncodedXmm, RegX8632::getEncodedGPR>( |
2551 Func, DispatchTy, getDest(), Src0, getSrc(2), Emitter); | 2567 Func, DispatchTy, getDest(), Src0, getSrc(2), Emitter); |
2552 } | 2568 } |
2553 | 2569 |
2554 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const { | 2570 template <> void InstX8632Pshufd::emitIAS(const Cfg *Func) const { |
2555 assert(getSrcSize() == 2); | 2571 assert(getSrcSize() == 2); |
2556 const Variable *Dest = getDest(); | 2572 const Variable *Dest = getDest(); |
2557 Type Ty = Dest->getType(); | 2573 Type Ty = Dest->getType(); |
2558 static const x86::AssemblerX86::ThreeOpImmEmitter< | 2574 static const X8632::AssemblerX8632::ThreeOpImmEmitter< |
2559 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { | 2575 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { |
2560 &x86::AssemblerX86::pshufd, &x86::AssemblerX86::pshufd}; | 2576 &X8632::AssemblerX8632::pshufd, &X8632::AssemblerX8632::pshufd}; |
2561 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, | 2577 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, |
2562 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( | 2578 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( |
2563 Func, Ty, Dest, getSrc(0), getSrc(1), Emitter); | 2579 Func, Ty, Dest, getSrc(0), getSrc(1), Emitter); |
2564 } | 2580 } |
2565 | 2581 |
2566 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const { | 2582 template <> void InstX8632Shufps::emitIAS(const Cfg *Func) const { |
2567 assert(getSrcSize() == 3); | 2583 assert(getSrcSize() == 3); |
2568 const Variable *Dest = getDest(); | 2584 const Variable *Dest = getDest(); |
2569 assert(Dest == getSrc(0)); | 2585 assert(Dest == getSrc(0)); |
2570 Type Ty = Dest->getType(); | 2586 Type Ty = Dest->getType(); |
2571 static const x86::AssemblerX86::ThreeOpImmEmitter< | 2587 static const X8632::AssemblerX8632::ThreeOpImmEmitter< |
2572 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { | 2588 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { |
2573 &x86::AssemblerX86::shufps, &x86::AssemblerX86::shufps}; | 2589 &X8632::AssemblerX8632::shufps, &X8632::AssemblerX8632::shufps}; |
2574 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, | 2590 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, |
2575 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( | 2591 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( |
2576 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); | 2592 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); |
2577 } | 2593 } |
2578 | 2594 |
2579 void InstX8632Pop::emit(const Cfg *Func) const { | 2595 void InstX8632Pop::emit(const Cfg *Func) const { |
2580 if (!ALLOW_DUMP) | 2596 if (!ALLOW_DUMP) |
2581 return; | 2597 return; |
2582 Ostream &Str = Func->getContext()->getStrEmit(); | 2598 Ostream &Str = Func->getContext()->getStrEmit(); |
2583 assert(getSrcSize() == 0); | 2599 assert(getSrcSize() == 0); |
2584 Str << "\tpop\t"; | 2600 Str << "\tpop\t"; |
2585 getDest()->emit(Func); | 2601 getDest()->emit(Func); |
2586 } | 2602 } |
2587 | 2603 |
2588 void InstX8632Pop::emitIAS(const Cfg *Func) const { | 2604 void InstX8632Pop::emitIAS(const Cfg *Func) const { |
2589 assert(getSrcSize() == 0); | 2605 assert(getSrcSize() == 0); |
2590 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2606 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2591 if (getDest()->hasReg()) { | 2607 if (getDest()->hasReg()) { |
2592 Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum())); | 2608 Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum())); |
2593 } else { | 2609 } else { |
2594 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget()) | 2610 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget()) |
2595 ->stackVarToAsmOperand(getDest())); | 2611 ->stackVarToAsmOperand(getDest())); |
2596 } | 2612 } |
2597 } | 2613 } |
2598 | 2614 |
2599 void InstX8632Pop::dump(const Cfg *Func) const { | 2615 void InstX8632Pop::dump(const Cfg *Func) const { |
2600 if (!ALLOW_DUMP) | 2616 if (!ALLOW_DUMP) |
2601 return; | 2617 return; |
2602 Ostream &Str = Func->getContext()->getStrDump(); | 2618 Ostream &Str = Func->getContext()->getStrDump(); |
2603 dumpDest(Func); | 2619 dumpDest(Func); |
2604 Str << " = pop." << getDest()->getType() << " "; | 2620 Str << " = pop." << getDest()->getType() << " "; |
2605 } | 2621 } |
2606 | 2622 |
2607 void InstX8632AdjustStack::emit(const Cfg *Func) const { | 2623 void InstX8632AdjustStack::emit(const Cfg *Func) const { |
2608 if (!ALLOW_DUMP) | 2624 if (!ALLOW_DUMP) |
2609 return; | 2625 return; |
2610 Ostream &Str = Func->getContext()->getStrEmit(); | 2626 Ostream &Str = Func->getContext()->getStrEmit(); |
2611 Str << "\tsubl\t$" << Amount << ", %esp"; | 2627 Str << "\tsubl\t$" << Amount << ", %esp"; |
2612 Func->getTarget()->updateStackAdjustment(Amount); | 2628 Func->getTarget()->updateStackAdjustment(Amount); |
2613 } | 2629 } |
2614 | 2630 |
2615 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { | 2631 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { |
2616 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2632 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2617 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount)); | 2633 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, X8632::Immediate(Amount)); |
2618 Func->getTarget()->updateStackAdjustment(Amount); | 2634 Func->getTarget()->updateStackAdjustment(Amount); |
2619 } | 2635 } |
2620 | 2636 |
2621 void InstX8632AdjustStack::dump(const Cfg *Func) const { | 2637 void InstX8632AdjustStack::dump(const Cfg *Func) const { |
2622 if (!ALLOW_DUMP) | 2638 if (!ALLOW_DUMP) |
2623 return; | 2639 return; |
2624 Ostream &Str = Func->getContext()->getStrDump(); | 2640 Ostream &Str = Func->getContext()->getStrDump(); |
2625 Str << "esp = sub.i32 esp, " << Amount; | 2641 Str << "esp = sub.i32 esp, " << Amount; |
2626 } | 2642 } |
2627 | 2643 |
2628 void InstX8632Push::emit(const Cfg *Func) const { | 2644 void InstX8632Push::emit(const Cfg *Func) const { |
2629 if (!ALLOW_DUMP) | 2645 if (!ALLOW_DUMP) |
2630 return; | 2646 return; |
2631 Ostream &Str = Func->getContext()->getStrEmit(); | 2647 Ostream &Str = Func->getContext()->getStrEmit(); |
2632 assert(getSrcSize() == 1); | 2648 assert(getSrcSize() == 1); |
2633 // Push is currently only used for saving GPRs. | 2649 // Push is currently only used for saving GPRs. |
2634 const auto Var = llvm::cast<Variable>(getSrc(0)); | 2650 const auto Var = llvm::cast<Variable>(getSrc(0)); |
2635 assert(Var->hasReg()); | 2651 assert(Var->hasReg()); |
2636 Str << "\tpush\t"; | 2652 Str << "\tpush\t"; |
2637 Var->emit(Func); | 2653 Var->emit(Func); |
2638 } | 2654 } |
2639 | 2655 |
2640 void InstX8632Push::emitIAS(const Cfg *Func) const { | 2656 void InstX8632Push::emitIAS(const Cfg *Func) const { |
2641 assert(getSrcSize() == 1); | 2657 assert(getSrcSize() == 1); |
2642 // Push is currently only used for saving GPRs. | 2658 // Push is currently only used for saving GPRs. |
2643 const auto Var = llvm::cast<Variable>(getSrc(0)); | 2659 const auto Var = llvm::cast<Variable>(getSrc(0)); |
2644 assert(Var->hasReg()); | 2660 assert(Var->hasReg()); |
2645 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2661 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2646 Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum())); | 2662 Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum())); |
2647 } | 2663 } |
2648 | 2664 |
2649 void InstX8632Push::dump(const Cfg *Func) const { | 2665 void InstX8632Push::dump(const Cfg *Func) const { |
2650 if (!ALLOW_DUMP) | 2666 if (!ALLOW_DUMP) |
2651 return; | 2667 return; |
2652 Ostream &Str = Func->getContext()->getStrDump(); | 2668 Ostream &Str = Func->getContext()->getStrDump(); |
2653 Str << "push." << getSrc(0)->getType() << " "; | 2669 Str << "push." << getSrc(0)->getType() << " "; |
2654 dumpSources(Func); | 2670 dumpSources(Func); |
2655 } | 2671 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2690 } | 2706 } |
2691 | 2707 |
2692 void InstX8632Ret::emit(const Cfg *Func) const { | 2708 void InstX8632Ret::emit(const Cfg *Func) const { |
2693 if (!ALLOW_DUMP) | 2709 if (!ALLOW_DUMP) |
2694 return; | 2710 return; |
2695 Ostream &Str = Func->getContext()->getStrEmit(); | 2711 Ostream &Str = Func->getContext()->getStrEmit(); |
2696 Str << "\tret"; | 2712 Str << "\tret"; |
2697 } | 2713 } |
2698 | 2714 |
2699 void InstX8632Ret::emitIAS(const Cfg *Func) const { | 2715 void InstX8632Ret::emitIAS(const Cfg *Func) const { |
2700 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2716 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2701 Asm->ret(); | 2717 Asm->ret(); |
2702 } | 2718 } |
2703 | 2719 |
2704 void InstX8632Ret::dump(const Cfg *Func) const { | 2720 void InstX8632Ret::dump(const Cfg *Func) const { |
2705 if (!ALLOW_DUMP) | 2721 if (!ALLOW_DUMP) |
2706 return; | 2722 return; |
2707 Ostream &Str = Func->getContext()->getStrDump(); | 2723 Ostream &Str = Func->getContext()->getStrDump(); |
2708 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); | 2724 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); |
2709 Str << "ret." << Ty << " "; | 2725 Str << "ret." << Ty << " "; |
2710 dumpSources(Func); | 2726 dumpSources(Func); |
2711 } | 2727 } |
2712 | 2728 |
2713 void InstX8632Xadd::emit(const Cfg *Func) const { | 2729 void InstX8632Xadd::emit(const Cfg *Func) const { |
2714 if (!ALLOW_DUMP) | 2730 if (!ALLOW_DUMP) |
2715 return; | 2731 return; |
2716 Ostream &Str = Func->getContext()->getStrEmit(); | 2732 Ostream &Str = Func->getContext()->getStrEmit(); |
2717 if (Locked) { | 2733 if (Locked) { |
2718 Str << "\tlock"; | 2734 Str << "\tlock"; |
2719 } | 2735 } |
2720 Str << "\txadd" << getWidthString(getSrc(0)->getType()) << "\t"; | 2736 Str << "\txadd" << getWidthString(getSrc(0)->getType()) << "\t"; |
2721 getSrc(1)->emit(Func); | 2737 getSrc(1)->emit(Func); |
2722 Str << ", "; | 2738 Str << ", "; |
2723 getSrc(0)->emit(Func); | 2739 getSrc(0)->emit(Func); |
2724 } | 2740 } |
2725 | 2741 |
2726 void InstX8632Xadd::emitIAS(const Cfg *Func) const { | 2742 void InstX8632Xadd::emitIAS(const Cfg *Func) const { |
2727 assert(getSrcSize() == 2); | 2743 assert(getSrcSize() == 2); |
2728 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2744 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2729 Type Ty = getSrc(0)->getType(); | 2745 Type Ty = getSrc(0)->getType(); |
2730 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 2746 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
2731 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2747 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
2732 const x86::Address Addr = Mem->toAsmAddress(Asm); | 2748 const X8632::Address Addr = Mem->toAsmAddress(Asm); |
2733 const auto VarReg = llvm::cast<Variable>(getSrc(1)); | 2749 const auto VarReg = llvm::cast<Variable>(getSrc(1)); |
2734 assert(VarReg->hasReg()); | 2750 assert(VarReg->hasReg()); |
2735 const RegX8632::GPRRegister Reg = | 2751 const RegX8632::GPRRegister Reg = |
2736 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 2752 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
2737 Asm->xadd(Ty, Addr, Reg, Locked); | 2753 Asm->xadd(Ty, Addr, Reg, Locked); |
2738 } | 2754 } |
2739 | 2755 |
2740 void InstX8632Xadd::dump(const Cfg *Func) const { | 2756 void InstX8632Xadd::dump(const Cfg *Func) const { |
2741 if (!ALLOW_DUMP) | 2757 if (!ALLOW_DUMP) |
2742 return; | 2758 return; |
(...skipping 11 matching lines...) Expand all Loading... |
2754 return; | 2770 return; |
2755 Ostream &Str = Func->getContext()->getStrEmit(); | 2771 Ostream &Str = Func->getContext()->getStrEmit(); |
2756 Str << "\txchg" << getWidthString(getSrc(0)->getType()) << "\t"; | 2772 Str << "\txchg" << getWidthString(getSrc(0)->getType()) << "\t"; |
2757 getSrc(1)->emit(Func); | 2773 getSrc(1)->emit(Func); |
2758 Str << ", "; | 2774 Str << ", "; |
2759 getSrc(0)->emit(Func); | 2775 getSrc(0)->emit(Func); |
2760 } | 2776 } |
2761 | 2777 |
2762 void InstX8632Xchg::emitIAS(const Cfg *Func) const { | 2778 void InstX8632Xchg::emitIAS(const Cfg *Func) const { |
2763 assert(getSrcSize() == 2); | 2779 assert(getSrcSize() == 2); |
2764 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2780 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2765 Type Ty = getSrc(0)->getType(); | 2781 Type Ty = getSrc(0)->getType(); |
2766 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 2782 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
2767 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2783 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
2768 const x86::Address Addr = Mem->toAsmAddress(Asm); | 2784 const X8632::Address Addr = Mem->toAsmAddress(Asm); |
2769 const auto VarReg = llvm::cast<Variable>(getSrc(1)); | 2785 const auto VarReg = llvm::cast<Variable>(getSrc(1)); |
2770 assert(VarReg->hasReg()); | 2786 assert(VarReg->hasReg()); |
2771 const RegX8632::GPRRegister Reg = | 2787 const RegX8632::GPRRegister Reg = |
2772 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 2788 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
2773 Asm->xchg(Ty, Addr, Reg); | 2789 Asm->xchg(Ty, Addr, Reg); |
2774 } | 2790 } |
2775 | 2791 |
2776 void InstX8632Xchg::dump(const Cfg *Func) const { | 2792 void InstX8632Xchg::dump(const Cfg *Func) const { |
2777 if (!ALLOW_DUMP) | 2793 if (!ALLOW_DUMP) |
2778 return; | 2794 return; |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2862 Str << "+"; | 2878 Str << "+"; |
2863 Offset->dump(Func, Str); | 2879 Offset->dump(Func, Str); |
2864 } | 2880 } |
2865 } else { | 2881 } else { |
2866 // There is only the offset. | 2882 // There is only the offset. |
2867 Offset->dump(Func, Str); | 2883 Offset->dump(Func, Str); |
2868 } | 2884 } |
2869 Str << "]"; | 2885 Str << "]"; |
2870 } | 2886 } |
2871 | 2887 |
2872 void OperandX8632Mem::emitSegmentOverride(x86::AssemblerX86 *Asm) const { | 2888 void OperandX8632Mem::emitSegmentOverride(X8632::AssemblerX8632 *Asm) const { |
2873 if (SegmentReg != DefaultSegment) { | 2889 if (SegmentReg != DefaultSegment) { |
2874 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); | 2890 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); |
2875 Asm->EmitSegmentOverride(InstX8632SegmentPrefixes[SegmentReg]); | 2891 Asm->EmitSegmentOverride(InstX8632SegmentPrefixes[SegmentReg]); |
2876 } | 2892 } |
2877 } | 2893 } |
2878 | 2894 |
2879 x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const { | 2895 X8632::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const { |
2880 int32_t Disp = 0; | 2896 int32_t Disp = 0; |
2881 AssemblerFixup *Fixup = nullptr; | 2897 AssemblerFixup *Fixup = nullptr; |
2882 // Determine the offset (is it relocatable?) | 2898 // Determine the offset (is it relocatable?) |
2883 if (getOffset()) { | 2899 if (getOffset()) { |
2884 if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { | 2900 if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) { |
2885 Disp = static_cast<int32_t>(CI->getValue()); | 2901 Disp = static_cast<int32_t>(CI->getValue()); |
2886 } else if (const auto CR = | 2902 } else if (const auto CR = |
2887 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { | 2903 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { |
2888 Disp = CR->getOffset(); | 2904 Disp = CR->getOffset(); |
2889 Fixup = Asm->createFixup(llvm::ELF::R_386_32, CR); | 2905 Fixup = Asm->createFixup(llvm::ELF::R_386_32, CR); |
2890 } else { | 2906 } else { |
2891 llvm_unreachable("Unexpected offset type"); | 2907 llvm_unreachable("Unexpected offset type"); |
2892 } | 2908 } |
2893 } | 2909 } |
2894 | 2910 |
2895 // Now convert to the various possible forms. | 2911 // Now convert to the various possible forms. |
2896 if (getBase() && getIndex()) { | 2912 if (getBase() && getIndex()) { |
2897 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), | 2913 return X8632::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), |
2898 RegX8632::getEncodedGPR(getIndex()->getRegNum()), | 2914 RegX8632::getEncodedGPR(getIndex()->getRegNum()), |
2899 x86::ScaleFactor(getShift()), Disp); | 2915 X8632::ScaleFactor(getShift()), Disp); |
2900 } else if (getBase()) { | 2916 } else if (getBase()) { |
2901 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), Disp); | 2917 return X8632::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), |
| 2918 Disp); |
2902 } else if (getIndex()) { | 2919 } else if (getIndex()) { |
2903 return x86::Address(RegX8632::getEncodedGPR(getIndex()->getRegNum()), | 2920 return X8632::Address(RegX8632::getEncodedGPR(getIndex()->getRegNum()), |
2904 x86::ScaleFactor(getShift()), Disp); | 2921 X8632::ScaleFactor(getShift()), Disp); |
2905 } else if (Fixup) { | 2922 } else if (Fixup) { |
2906 return x86::Address::Absolute(Disp, Fixup); | 2923 return X8632::Address::Absolute(Disp, Fixup); |
2907 } else { | 2924 } else { |
2908 return x86::Address::Absolute(Disp); | 2925 return X8632::Address::Absolute(Disp); |
2909 } | 2926 } |
2910 } | 2927 } |
2911 | 2928 |
2912 x86::Address VariableSplit::toAsmAddress(const Cfg *Func) const { | 2929 X8632::Address VariableSplit::toAsmAddress(const Cfg *Func) const { |
2913 assert(!Var->hasReg()); | 2930 assert(!Var->hasReg()); |
2914 const TargetLowering *Target = Func->getTarget(); | 2931 const TargetLowering *Target = Func->getTarget(); |
2915 int32_t Offset = | 2932 int32_t Offset = |
2916 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); | 2933 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); |
2917 return x86::Address(RegX8632::getEncodedGPR(Target->getFrameOrStackReg()), | 2934 return X8632::Address(RegX8632::getEncodedGPR(Target->getFrameOrStackReg()), |
2918 Offset); | 2935 Offset); |
2919 } | 2936 } |
2920 | 2937 |
2921 void VariableSplit::emit(const Cfg *Func) const { | 2938 void VariableSplit::emit(const Cfg *Func) const { |
2922 if (!ALLOW_DUMP) | 2939 if (!ALLOW_DUMP) |
2923 return; | 2940 return; |
2924 Ostream &Str = Func->getContext()->getStrEmit(); | 2941 Ostream &Str = Func->getContext()->getStrEmit(); |
2925 assert(!Var->hasReg()); | 2942 assert(!Var->hasReg()); |
2926 // The following is copied/adapted from TargetX8632::emitVariable(). | 2943 // The following is copied/adapted from TargetX8632::emitVariable(). |
2927 const TargetLowering *Target = Func->getTarget(); | 2944 const TargetLowering *Target = Func->getTarget(); |
2928 const Type Ty = IceType_i32; | 2945 const Type Ty = IceType_i32; |
(...skipping 17 matching lines...) Expand all Loading... |
2946 } | 2963 } |
2947 Str << "("; | 2964 Str << "("; |
2948 if (Func) | 2965 if (Func) |
2949 Var->dump(Func); | 2966 Var->dump(Func); |
2950 else | 2967 else |
2951 Var->dump(Str); | 2968 Var->dump(Str); |
2952 Str << ")"; | 2969 Str << ")"; |
2953 } | 2970 } |
2954 | 2971 |
2955 } // end of namespace Ice | 2972 } // end of namespace Ice |
OLD | NEW |