@@ -510,6 +510,53 @@ Z80LegalizerInfo::legalizeAddSub(LegalizerHelper &Helper, MachineInstr &MI,
510510 LLT LLTy = MRI.getType (DstReg);
511511 unsigned Size = LLTy.getSizeInBits ();
512512 bool LegalSize = Size == 16 || (Subtarget.is24Bit () && Size == 24 );
513+ Register SrcReg;
514+ const char *OneLibcallName = nullptr ;
515+
516+ if (Subtarget.is24Bit () && (Size == 32 || Size == 48 || Size == 64 )) {
517+ const Register LHS = MI.getOperand (1 ).getReg ();
518+ const Register RHS = MI.getOperand (2 ).getReg ();
519+ std::optional<ValueAndVReg> OneConst =
520+ getIConstantVRegValWithLookThrough (RHS, MRI);
521+
522+ SrcReg = LHS;
523+
524+ if (MI.getOpcode () == G_ADD && (!OneConst || (!OneConst->Value .isOne () &&
525+ !OneConst->Value .isAllOnes ()))) {
526+ OneConst = getIConstantVRegValWithLookThrough (LHS, MRI);
527+ SrcReg = RHS;
528+ }
529+
530+ if (OneConst && (OneConst->Value .isOne () || OneConst->Value .isAllOnes ())) {
531+ bool IsSub = MI.getOpcode () == G_SUB ? OneConst->Value .isOne ()
532+ : OneConst->Value .isAllOnes ();
533+ switch (Size) {
534+ case 32 :
535+ OneLibcallName = IsSub ? " _lsub_1" : " _ladd_1" ;
536+ break ;
537+ case 48 :
538+ OneLibcallName = IsSub ? " _i48sub_1" : " _i48add_1" ;
539+ break ;
540+ case 64 :
541+ OneLibcallName = IsSub ? " _llsub_1" : " _lladd_1" ;
542+ break ;
543+ }
544+ }
545+ }
546+
547+ if (OneLibcallName) {
548+ auto &Ctx = F.getContext ();
549+ Type *Ty = IntegerType::get (Ctx, Size);
550+ auto &TLI = *Helper.MIRBuilder .getMF ().getSubtarget ().getTargetLowering ();
551+
552+ auto Result = createLibcall (Helper.MIRBuilder , OneLibcallName,
553+ {DstReg, Ty, 0 }, {{SrcReg, Ty, 0 }},
554+ TLI.getLibcallCallingConv (RTLIB::ADD_I32),
555+ LocObserver, &MI);
556+ MI.eraseFromParent ();
557+ return Result;
558+ }
559+
513560 Register LHSReg;
514561 if (mi_match (MI, MRI, m_Neg (m_Reg (LHSReg)))) {
515562 if (!F.hasOptSize () && LegalSize)
0 commit comments