@@ -506,8 +506,10 @@ Z80TargetLowering::EmitLoweredMemMove(MachineInstr &MI,
506506  Register HL = Is24Bit ? Z80::UHL : Z80::HL;
507507  Register BC = Is24Bit ? Z80::UBC : Z80::BC;
508508  Register PhysRegs[] = { DE, HL, BC };
509+   Register VirtRegs[3 ] = {};
509510  assert ((Is24Bit || MI.getOpcode () == Z80::LDR16) && " Unexpected opcode" 
510511
512+   const  TargetRegisterInfo *TRI = Subtarget.getRegisterInfo ();
511513  const  TargetInstrInfo *TII = Subtarget.getInstrInfo ();
512514  DebugLoc DL = MI.getDebugLoc ();
513515
@@ -516,12 +518,13 @@ Z80TargetLowering::EmitLoweredMemMove(MachineInstr &MI,
516518  MachineFunction::iterator I = ++BB->getIterator ();
517519
518520  MachineFunction *F = BB->getParent ();
521+   MachineRegisterInfo &MRI = F->getRegInfo ();
519522  MachineBasicBlock *LDIR_BB = F->CreateMachineBasicBlock (LLVM_BB);
520523  MachineBasicBlock *LDDR_BB = F->CreateMachineBasicBlock (LLVM_BB);
521524  MachineBasicBlock *NextBB = F->CreateMachineBasicBlock (LLVM_BB);
522525  for  (auto  *MBB : {LDIR_BB, LDDR_BB}) {
523526    F->insert (I, MBB);
524-     for  (auto  LiveIn : {BC, DE, HL} )
527+     for  (auto  LiveIn : PhysRegs )
525528      MBB->addLiveIn (LiveIn);
526529  }
527530  F->insert (I, NextBB);
@@ -533,47 +536,66 @@ Z80TargetLowering::EmitLoweredMemMove(MachineInstr &MI,
533536  NextBB->transferSuccessorsAndUpdatePHIs (BB);
534537
535538  //  BB:
539+   //    SUB HL,DE
536540  //    JP C,LDDR_BB
537541  //    fallthrough --> LDIR_BB
542+   for  (int  I = 0 ; I != 3 ; ++I)
543+     BuildMI (BB, DL, TII->get (Z80::COPY), PhysRegs[I])
544+         .add (MI.getOperand (I));
545+   BuildMI (BB, DL, TII->get (Is24Bit ? Z80::Sub24ao : Z80::Sub16ao))
546+       .addReg (DE);
547+   //  Preserve physical registers for the successors.
548+   for  (int  I = 0 ; I != 3 ; ++I) {
549+     VirtRegs[I] = MRI.createVirtualRegister (TRI->getRegClass (PhysRegs[I]));
550+     BuildMI (BB, DL, TII->get (Z80::COPY), VirtRegs[I]).addReg (PhysRegs[I]);
551+   }
538552  BuildMI (BB, DL, TII->get (Z80::JQCC)).addMBB (LDDR_BB)
539553      .addImm (Z80::COND_C);
540554  //  Next, add the LDIR and LDDR blocks as its successors.
541555  BB->addSuccessor (LDIR_BB);
542556  BB->addSuccessor (LDDR_BB);
543557
544558  //  LDIR_BB:
559+   //    ADD HL,DE
545560  //    LDIR
546561  //    JP NextBB
547562  for  (int  I = 0 ; I != 3 ; ++I)
548563    BuildMI (LDIR_BB, DL, TII->get (Z80::COPY), PhysRegs[I])
549-         .add (MI.getOperand (I));
564+         .addReg (VirtRegs[I]);
565+   BuildMI (LDIR_BB, DL, TII->get (Is24Bit ? Z80::ADD24ao : Z80::ADD16ao), HL)
566+       .addReg (HL).addReg (DE);
550567  BuildMI (LDIR_BB, DL, TII->get (Is24Bit ? Z80::LDIR24 : Z80::LDIR16));
551568  BuildMI (LDIR_BB, DL, TII->get (Z80::JQ)).addMBB (NextBB);
552569  //  Update machine-CFG edges
553570  LDIR_BB->addSuccessor (NextBB);
554571
555572  //  LDDR_BB:
556-   //    ADD HL,BC
557-   //    DEC HL
558573  //    EX DE,HL
559574  //    ADD HL,BC
560575  //    DEC HL
561576  //    EX DE,HL
577+   //    ADD HL,DE
562578  //    LDDR
563579  //  # Fallthrough to Next MBB
564580  for  (int  I = 0 ; I != 3 ; ++I)
565581    BuildMI (LDDR_BB, DL, TII->get (Z80::COPY), PhysRegs[I])
566-         .add (MI.getOperand (I));
567-   for  (int  I = 0 ; I != 2 ; ++I) {
568-     BuildMI (LDDR_BB, DL, TII->get (Is24Bit ? Z80::ADD24ao : Z80::ADD16ao), HL)
569-         .addReg (HL).addReg (BC);
570-     BuildMI (LDDR_BB, DL, TII->get (Is24Bit ? Z80::DEC24r : Z80::DEC16r), HL)
571-         .addReg (HL);
572-     BuildMI (LDDR_BB, DL, TII->get (Is24Bit ? Z80::EX24DE : Z80::EX16DE));
573-   }
582+         .addReg (VirtRegs[I]);
583+   BuildMI (LDDR_BB, DL, TII->get (Is24Bit ? Z80::EX24DE : Z80::EX16DE));
584+   BuildMI (LDDR_BB, DL, TII->get (Is24Bit ? Z80::ADD24ao : Z80::ADD16ao), HL)
585+       .addReg (HL).addReg (BC);
586+   BuildMI (LDDR_BB, DL, TII->get (Is24Bit ? Z80::DEC24r : Z80::DEC16r), HL)
587+       .addReg (HL);
588+   BuildMI (LDDR_BB, DL, TII->get (Is24Bit ? Z80::EX24DE : Z80::EX16DE));
589+   BuildMI (LDDR_BB, DL, TII->get (Is24Bit ? Z80::ADD24ao : Z80::ADD16ao), HL)
590+       .addReg (HL).addReg (DE);
574591  BuildMI (LDDR_BB, DL, TII->get (Is24Bit ? Z80::LDDR24 : Z80::LDDR16));
575592  LDDR_BB->addSuccessor (NextBB);
576593
594+   //  Replace virtual register usages with the corresponding physical
595+   //  registers to ensure no-op copies.
596+   for  (int  I = 0 ; I != 3 ; ++I)
597+     MRI.replaceRegWith (VirtRegs[I], PhysRegs[I]);
598+ 
577599  MI.eraseFromParent ();   //  The pseudo instruction is gone now.
578600  LLVM_DEBUG (F->dump ());
579601  return  NextBB;
0 commit comments