@@ -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