Skip to content

Commit 88b9fd3

Browse files
committed
Flag hax.
1 parent b3ee3c9 commit 88b9fd3

6 files changed

+141
-38
lines changed

llvm/lib/Target/Z80/GISel/Z80InstructionSelector.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,9 @@ const TargetRegisterClass *
176176
Z80InstructionSelector::getRegClass(Register Reg,
177177
MachineRegisterInfo &MRI) const {
178178
if (Reg.isPhysical()) {
179-
for (auto *RC : {&Z80::R8RegClass, &Z80::Z8RegClass, &Z80::R16RegClass,
180-
&Z80::Z16RegClass, &Z80::R24RegClass, &Z80::Z24RegClass})
179+
for (auto *RC : {&Z80::R8RegClass, &Z80::F8RegClass, &Z80::Z8RegClass,
180+
&Z80::R16RegClass, &Z80::Z16RegClass, &Z80::R24RegClass,
181+
&Z80::Z24RegClass})
181182
if (RC->contains(Reg))
182183
return RC;
183184
return nullptr;
@@ -226,9 +227,8 @@ bool Z80InstructionSelector::selectCopy(MachineInstr &I,
226227
if (DstReg.isPhysical()) {
227228
assert(I.isCopy() && "Generic operators do not allow physical registers");
228229

229-
if ((DstReg == Z80::F || DstReg == Z80::I || DstReg == Z80::R ||
230-
DstReg == Z80::MB) &&
231-
!RBI.constrainGenericRegister(SrcReg, Z80::Z8RegClass, MRI))
230+
if (Z80::F8RegClass.contains(DstReg) &&
231+
!RBI.constrainGenericRegister(SrcReg, Z80::F8RegClass, MRI))
232232
return false;
233233

234234
if (DstSize > SrcSize && SrcRegBank.getID() == Z80::GPRRegBankID &&
@@ -1227,8 +1227,8 @@ Z80InstructionSelector::foldCompare(MachineInstr &I, MachineIRBuilder &MIB,
12271227
CallLowering::ArgInfo::NoArgIndex);
12281228
createLibcall(MIB, RTLIB::SCMP, SignedFlagsArg, FlagsArg);
12291229
MIB.buildCopy(Register(Z80::F), SignedFlagsReg);
1230-
if (!RBI.constrainGenericRegister(FlagsReg, Z80::Z8RegClass, MRI) ||
1231-
!RBI.constrainGenericRegister(SignedFlagsReg, Z80::Z8RegClass, MRI))
1230+
if (!RBI.constrainGenericRegister(FlagsReg, Z80::F8RegClass, MRI) ||
1231+
!RBI.constrainGenericRegister(SignedFlagsReg, Z80::F8RegClass, MRI))
12321232
return Z80::COND_INVALID;
12331233
}
12341234
return CC;

llvm/lib/Target/Z80/GISel/Z80RegisterBankInfo.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ Z80RegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
4646
if (Z80::R8RegClass.hasSubClassEq(&RC) ||
4747
Z80::R16RegClass.hasSubClassEq(&RC) ||
4848
Z80::R24RegClass.hasSubClassEq(&RC) ||
49+
Z80::F8RegClass.hasSubClassEq(&RC) ||
4950
Z80::Z8RegClass.hasSubClassEq(&RC) ||
5051
Z80::Z16RegClass.hasSubClassEq(&RC) ||
5152
Z80::Z24RegClass.hasSubClassEq(&RC))

llvm/lib/Target/Z80/Z80ISelLowering.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -632,15 +632,15 @@ Z80TargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
632632
}
633633

634634
if (Z80::parseConstraintCode(Constraint) != Z80::COND_INVALID)
635-
return std::make_pair(Z80::F, &Z80::Z8RegClass);
635+
return std::make_pair(Z80::F, &Z80::F8RegClass);
636636

637637
// Use the default implementation in TargetLowering to convert the register
638638
// constraint into a member of a register class.
639639
auto Res = TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
640640

641641
if (!Res.second) {
642642
if (Constraint.equals_insensitive("{f}"))
643-
return std::make_pair(Z80::F, &Z80::Z8RegClass);
643+
return std::make_pair(Z80::F, &Z80::F8RegClass);
644644

645645
return Res;
646646
}

llvm/lib/Target/Z80/Z80InstrInfo.cpp

+124-21
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,60 @@ void Z80InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
561561
}
562562
return;
563563
}
564+
// Specialized byte copy.
565+
if (DstReg == Z80::F) {
566+
// Copies to F.
567+
bool NeedEX = false;
568+
switch (SrcReg) {
569+
case Z80::H: SrcReg = Z80::D; NeedEX = true; break;
570+
case Z80::L: SrcReg = Z80::E; NeedEX = true; break;
571+
}
572+
Register TempReg = Is24Bit ? Z80::UHL : Z80::HL;
573+
if (NeedEX)
574+
BuildMI(MBB, MI, DL, get(Is24Bit ? Z80::EX24DE : Z80::EX16DE))
575+
.addReg(Is24Bit ? Z80::UDE : Z80::DE, RegState::ImplicitDefine)
576+
.addReg(TempReg, RegState::ImplicitDefine);
577+
applySPAdjust(
578+
*BuildMI(MBB, MI, DL, get(Is24Bit ? Z80::PUSH24r : Z80::PUSH16r))
579+
.addReg(TempReg, RegState::Undef));
580+
copyPhysReg(MBB, MI, DL, Z80::L, SrcReg, KillSrc);
581+
BuildMI(MBB, MI, DL, get(TargetOpcode::COPY), Z80::H)
582+
.addReg(Z80::A, RegState::Undef); // Preserve A
583+
BuildMI(MBB, MI, DL, get(Is24Bit ? Z80::EX24SP : Z80::EX16SP), TempReg)
584+
.addReg(TempReg, RegState::Undef);
585+
applySPAdjust(
586+
*BuildMI(MBB, MI, DL, get(Is24Bit ? Z80::POP24AF : Z80::POP16AF)));
587+
if (NeedEX)
588+
BuildMI(MBB, MI, DL, get(Is24Bit ? Z80::EX24DE : Z80::EX16DE))
589+
.addReg(Is24Bit ? Z80::UDE : Z80::DE, RegState::ImplicitDefine)
590+
.addReg(TempReg, RegState::ImplicitDefine);
591+
return;
592+
}
593+
if (SrcReg == Z80::F) {
594+
// Copies from F.
595+
bool NeedEX = false;
596+
switch (DstReg) {
597+
case Z80::H: DstReg = Z80::D; NeedEX = true; break;
598+
case Z80::L: DstReg = Z80::E; NeedEX = true; break;
599+
}
600+
Register TempReg = Is24Bit ? Z80::UHL : Z80::HL;
601+
if (NeedEX)
602+
BuildMI(MBB, MI, DL, get(Is24Bit ? Z80::EX24DE : Z80::EX16DE))
603+
.addReg(Is24Bit ? Z80::UDE : Z80::DE, RegState::ImplicitDefine)
604+
.addReg(TempReg, RegState::ImplicitDefine);
605+
applySPAdjust(
606+
*BuildMI(MBB, MI, DL, get(Is24Bit ? Z80::PUSH24AF : Z80::PUSH16AF)));
607+
BuildMI(MBB, MI, DL, get(Is24Bit ? Z80::EX24SP : Z80::EX16SP), TempReg)
608+
.addReg(TempReg, RegState::Undef);
609+
copyPhysReg(MBB, MI, DL, DstReg, Z80::L, KillSrc);
610+
applySPAdjust(*BuildMI(MBB, MI, DL,
611+
get(Is24Bit ? Z80::POP24r : Z80::POP16r), TempReg));
612+
if (NeedEX)
613+
BuildMI(MBB, MI, DL, get(Is24Bit ? Z80::EX24DE : Z80::EX16DE))
614+
.addReg(Is24Bit ? Z80::UDE : Z80::DE, RegState::ImplicitDefine)
615+
.addReg(TempReg, RegState::ImplicitDefine);
616+
return;
617+
}
564618
// Specialized word copy.
565619
if (DstReg == Z80::SPS || DstReg == Z80::SPL) {
566620
// Copies to SP.
@@ -731,6 +785,24 @@ void Z80InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
731785
Register SrcReg, bool IsKill, int FI,
732786
const TargetRegisterClass *TRC,
733787
const TargetRegisterInfo *TRI) const {
788+
const DebugLoc &DL = MBB.findDebugLoc(MI);
789+
bool Is24Bit = Subtarget.is24Bit();
790+
791+
// Special cases
792+
switch (SrcReg) {
793+
case Z80::F: {
794+
Register TempReg = Is24Bit ? Z80::UHL : Z80::HL;
795+
applySPAdjust(
796+
*BuildMI(MBB, MI, DL, get(Is24Bit ? Z80::PUSH24AF : Z80::PUSH16AF)));
797+
BuildMI(MBB, MI, DL, get(Is24Bit ? Z80::EX24SP : Z80::EX16SP), TempReg)
798+
.addReg(TempReg, RegState::Undef);
799+
storeRegToStackSlot(MBB, MI, Z80::L, true, FI, &Z80::R8RegClass, TRI);
800+
applySPAdjust(*BuildMI(MBB, MI, DL,
801+
get(Is24Bit ? Z80::POP24r : Z80::POP16r), TempReg));
802+
return;
803+
}
804+
}
805+
734806
unsigned Opc;
735807
switch (TRI->getSpillSize(*TRC)) {
736808
default:
@@ -742,19 +814,40 @@ void Z80InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
742814
Opc = Subtarget.has16BitEZ80Ops() ? Z80::LD16or : Z80::LD88or;
743815
break;
744816
case 3:
745-
assert(Subtarget.is24Bit() && "Only 24-bit should have 3 byte stack slots");
817+
assert(Is24Bit && "Only 24-bit should have 3 byte stack slots");
746818
Opc = Z80::LD24or;
747819
break;
748820
}
749-
BuildMI(MBB, MI, MBB.findDebugLoc(MI), get(Opc)).addFrameIndex(FI).addImm(0)
750-
.addReg(SrcReg, getKillRegState(IsKill));
821+
BuildMI(MBB, MI, DL, get(Opc))
822+
.addFrameIndex(FI).addImm(0).addReg(SrcReg, getKillRegState(IsKill));
751823
}
752824

753825
void Z80InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
754826
MachineBasicBlock::iterator MI,
755827
Register DstReg, int FI,
756828
const TargetRegisterClass *TRC,
757829
const TargetRegisterInfo *TRI) const {
830+
const DebugLoc &DL = MBB.findDebugLoc(MI);
831+
bool Is24Bit = Subtarget.is24Bit();
832+
833+
// Special cases
834+
switch (DstReg) {
835+
case Z80::F: {
836+
Register TempReg = Is24Bit ? Z80::UHL : Z80::HL;
837+
applySPAdjust(
838+
*BuildMI(MBB, MI, DL, get(Is24Bit ? Z80::PUSH24r : Z80::PUSH16r))
839+
.addReg(TempReg, RegState::Undef));
840+
loadRegFromStackSlot(MBB, MI, Z80::L, FI, &Z80::R8RegClass, TRI);
841+
BuildMI(MBB, MI, DL, get(TargetOpcode::COPY), Z80::H)
842+
.addReg(Z80::A, RegState::Undef); // Preserve A
843+
BuildMI(MBB, MI, DL, get(Is24Bit ? Z80::EX24SP : Z80::EX16SP), TempReg)
844+
.addReg(TempReg, RegState::Undef);
845+
applySPAdjust(
846+
*BuildMI(MBB, MI, DL, get(Is24Bit ? Z80::POP24AF : Z80::POP16AF)));
847+
return;
848+
}
849+
}
850+
758851
unsigned Opc;
759852
switch (TRI->getSpillSize(*TRC)) {
760853
default:
@@ -763,17 +856,19 @@ void Z80InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
763856
Opc = Z80::LD8ro;
764857
break;
765858
case 2:
766-
Opc = Subtarget.has16BitEZ80Ops() ? Z80::LD16ro : Z80::LD88ro;
767-
if (Subtarget.is24Bit())
768-
Opc = Z80::LD24ro;
769-
break;
859+
if (!Is24Bit) {
860+
Opc = Subtarget.has16BitEZ80Ops() ? Z80::LD16ro : Z80::LD88ro;
861+
break;
862+
}
863+
TRC = &Z80::R24RegClass;
864+
DstReg = TRI->getMatchingSuperReg(DstReg, Z80::sub_short, TRC);
865+
LLVM_FALLTHROUGH;
770866
case 3:
771-
assert(Subtarget.is24Bit() && "Only 24-bit should have 3 byte stack slots");
867+
assert(Is24Bit && "Only 24-bit should have 3 byte stack slots");
772868
Opc = Z80::LD24ro;
773869
break;
774870
}
775-
BuildMI(MBB, MI, MBB.findDebugLoc(MI), get(Opc), DstReg).addFrameIndex(FI)
776-
.addImm(0);
871+
BuildMI(MBB, MI, DL, get(Opc), DstReg).addFrameIndex(FI).addImm(0);
777872
}
778873

779874
/// Return true and the FrameIndex if the specified
@@ -1739,22 +1834,30 @@ MachineInstr *Z80InstrInfo::foldMemoryOperandImpl(
17391834
case 0:
17401835
switch (MI.getOpcode()) {
17411836
default: return nullptr;
1742-
case TargetOpcode:: COPY: Opc = IsOff ? Z80:: LD8or : Z80:: LD8pr; break;
1837+
case TargetOpcode::COPY:
1838+
if (!Z80::R8RegClass.contains(MI.getOperand(1).getReg()))
1839+
return nullptr;
1840+
Opc = IsOff ? Z80::LD8or : Z80::LD8pr;
1841+
break;
17431842
}
17441843
break;
17451844
case 1:
17461845
switch (MI.getOpcode()) {
17471846
default: return nullptr;
1748-
case Z80::BIT8bg: Opc = IsOff ? Z80::BIT8bo : Z80::BIT8bp; break;
1749-
case Z80::ADD8ar: Opc = IsOff ? Z80::ADD8ao : Z80::ADD8ap; break;
1750-
case Z80::ADC8ar: Opc = IsOff ? Z80::ADC8ao : Z80::ADC8ap; break;
1751-
case Z80::SUB8ar: Opc = IsOff ? Z80::SUB8ao : Z80::SUB8ap; break;
1752-
case Z80::SBC8ar: Opc = IsOff ? Z80::SBC8ao : Z80::SBC8ap; break;
1753-
case Z80::AND8ar: Opc = IsOff ? Z80::AND8ao : Z80::AND8ap; break;
1754-
case Z80::XOR8ar: Opc = IsOff ? Z80::XOR8ao : Z80::XOR8ap; break;
1755-
case Z80:: OR8ar: Opc = IsOff ? Z80:: OR8ao : Z80:: OR8ap; break;
1756-
case Z80::TST8ar: Opc = IsOff ? Z80::TST8ao : Z80::TST8ap; break;
1757-
case TargetOpcode:: COPY: Opc = IsOff ? Z80:: LD8ro : Z80:: LD8rp; break;
1847+
case Z80::BIT8bg: Opc = IsOff ? Z80::BIT8bo : Z80::BIT8bp; break;
1848+
case Z80::ADD8ar: Opc = IsOff ? Z80::ADD8ao : Z80::ADD8ap; break;
1849+
case Z80::ADC8ar: Opc = IsOff ? Z80::ADC8ao : Z80::ADC8ap; break;
1850+
case Z80::SUB8ar: Opc = IsOff ? Z80::SUB8ao : Z80::SUB8ap; break;
1851+
case Z80::SBC8ar: Opc = IsOff ? Z80::SBC8ao : Z80::SBC8ap; break;
1852+
case Z80::AND8ar: Opc = IsOff ? Z80::AND8ao : Z80::AND8ap; break;
1853+
case Z80::XOR8ar: Opc = IsOff ? Z80::XOR8ao : Z80::XOR8ap; break;
1854+
case Z80:: OR8ar: Opc = IsOff ? Z80:: OR8ao : Z80:: OR8ap; break;
1855+
case Z80::TST8ar: Opc = IsOff ? Z80::TST8ao : Z80::TST8ap; break;
1856+
case TargetOpcode::COPY:
1857+
if (!Z80::R8RegClass.contains(MI.getOperand(0).getReg()))
1858+
return nullptr;
1859+
Opc = IsOff ? Z80::LD8ro : Z80::LD8rp;
1860+
break;
17581861
}
17591862
break;
17601863
}

llvm/lib/Target/Z80/Z80MachineEarlyOptimization.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ bool Z80MachineEarlyOptimization::runOnMachineFunction(MachineFunction &MF) {
154154
}
155155
}
156156
if (CallMI && Cost < CondCallThreshold) {
157-
Register TempReg = MRI.createVirtualRegister(&Z80::Z8RegClass);
157+
Register TempReg = MRI.createVirtualRegister(&Z80::F8RegClass);
158158
DebugLoc DL = MBB.findBranchDebugLoc();
159159
MBB.removeSuccessor(FalseMBB);
160160
TII.removeBranch(MBB);

llvm/lib/Target/Z80/Z80RegisterInfo.td

+6-7
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,6 @@ let CostPerUse = [1] in {
8484
def IY : Z80RegPair<IYH, IYL, 2, 5>;
8585
}
8686

87-
// 16-bit misc registers
88-
def SPS : Z80Reg<"sp", 3>, DwarfRegNum<[6]>;
8987

9088
// 24-bit registers
9189
def UBC : EZ80ExtReg<BC>;
@@ -97,10 +95,9 @@ let CostPerUse = [1] in {
9795
def UIY : EZ80ExtReg<IY>;
9896
}
9997

100-
// 24-bit misc registers
101-
def SPL : Z80Reg<"sp", 3>, DwarfRegNum<[7]>;
102-
10398
// misc registers
99+
def SPS : Z80Reg<"sp", 3>, DwarfRegNum<[6]>;
100+
def SPL : Z80Reg<"sp", 3>, DwarfRegNum<[7]>;
104101
def PC : Z80Reg<"pc">, DwarfRegNum<[8]>;
105102
def I : Z80Reg<"i">;
106103
let SubRegs = [I], SubRegIndices = [sub_low] in
@@ -122,8 +119,10 @@ def Y8 : Z80RC8 <(add O8, IYL, IYH)>;
122119
def X8 : Z80RC8 <(add O8, IXL, IXH)>;
123120
def I8 : Z80RC8 <(add IYL, IYH, IXL, IXH)>;
124121
def R8 : Z80RC8 <(add G8, I8)>;
125-
let CopyCost = -1 in
126-
def Z8 : Z80RC8 <(add F, I, R, MB)>;
122+
let CopyCost = -1 in {
123+
def F8 : Z80RC8 <(add F)>;
124+
def Z8 : Z80RC8 <(add I, R, MB)>;
125+
}
127126

128127
def O16 : Z80RC16<(add DE, BC)>;
129128
def G16 : Z80RC16<(add HL, O16)>;

0 commit comments

Comments
 (0)