@@ -756,6 +756,83 @@ LoongArchInstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {
756756 return ArrayRef (TargetFlags);
757757}
758758
759+ bool LoongArchInstrInfo::canFoldIntoAddrMode (const MachineInstr &MemI,
760+ Register Reg,
761+ const MachineInstr &AddrI,
762+ ExtAddrMode &AM) const {
763+ unsigned OffsetWidth = 0 ;
764+ switch (MemI.getOpcode ()) {
765+ default :
766+ return false ;
767+ case LoongArch::LD_B:
768+ case LoongArch::LD_H:
769+ case LoongArch::LD_W:
770+ case LoongArch::LD_D:
771+ case LoongArch::LD_BU:
772+ case LoongArch::LD_HU:
773+ case LoongArch::LD_WU:
774+ case LoongArch::ST_B:
775+ case LoongArch::ST_H:
776+ case LoongArch::ST_W:
777+ case LoongArch::ST_D:
778+ case LoongArch::FLD_S:
779+ case LoongArch::FLD_D:
780+ case LoongArch::FST_S:
781+ case LoongArch::FST_D:
782+ OffsetWidth = 12 ;
783+ break ;
784+ case LoongArch::LDPTR_W:
785+ case LoongArch::LDPTR_D:
786+ case LoongArch::STPTR_W:
787+ case LoongArch::STPTR_D:
788+ OffsetWidth = 14 ;
789+ break ;
790+ }
791+
792+ if (MemI.getOperand (0 ).getReg () == Reg)
793+ return false ;
794+
795+ if ((AddrI.getOpcode () != LoongArch::ADDI_W &&
796+ AddrI.getOpcode () != LoongArch::ADDI_D) ||
797+ !AddrI.getOperand (1 ).isReg () || !AddrI.getOperand (2 ).isImm ())
798+ return false ;
799+
800+ int64_t OldOffset = MemI.getOperand (2 ).getImm ();
801+ int64_t Disp = AddrI.getOperand (2 ).getImm ();
802+ int64_t NewOffset = OldOffset + Disp;
803+ if (!STI.is64Bit ())
804+ NewOffset = SignExtend64<32 >(NewOffset);
805+
806+ if (!(OffsetWidth == 12 && isInt<12 >(NewOffset)) &&
807+ !(OffsetWidth == 14 && isShiftedInt<14 , 2 >(NewOffset) && STI.hasUAL ()))
808+ return false ;
809+
810+ AM.BaseReg = AddrI.getOperand (1 ).getReg ();
811+ AM.ScaledReg = 0 ;
812+ AM.Scale = 0 ;
813+ AM.Displacement = NewOffset;
814+ AM.Form = ExtAddrMode::Formula::Basic;
815+ return true ;
816+ }
817+
818+ MachineInstr *
819+ LoongArchInstrInfo::emitLdStWithAddr (MachineInstr &MemI,
820+ const ExtAddrMode &AM) const {
821+ const DebugLoc &DL = MemI.getDebugLoc ();
822+ MachineBasicBlock &MBB = *MemI.getParent ();
823+
824+ assert (AM.ScaledReg == 0 && AM.Scale == 0 &&
825+ " Addressing mode not supported for folding" );
826+
827+ return BuildMI (MBB, MemI, DL, get (MemI.getOpcode ()))
828+ .addReg (MemI.getOperand (0 ).getReg (),
829+ MemI.mayLoad () ? RegState::Define : 0 )
830+ .addReg (AM.BaseReg )
831+ .addImm (AM.Displacement )
832+ .setMemRefs (MemI.memoperands ())
833+ .setMIFlags (MemI.getFlags ());
834+ }
835+
759836// Returns true if this is the sext.w pattern, addi.w rd, rs, 0.
760837bool LoongArch::isSEXT_W (const MachineInstr &MI) {
761838 return MI.getOpcode () == LoongArch::ADDI_W && MI.getOperand (1 ).isReg () &&
0 commit comments