Skip to content

Commit 7e02a49

Browse files
committed
Change TSFlags format again to correctly compute instruction sizes involving (ix) with no offset.
1 parent 7284a60 commit 7e02a49

File tree

6 files changed

+1586
-1509
lines changed

6 files changed

+1586
-1509
lines changed

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

+7-7
Original file line numberDiff line numberDiff line change
@@ -677,13 +677,13 @@ bool Z80InstructionSelector::selectLoadStore(MachineInstr &I,
677677
case TargetOpcode::G_AND: {
678678
auto Bit = (~ImmConst->zextOrTrunc(8)).exactLogBase2();
679679
if (Bit >= 0)
680-
RMWOps = {Z80::RES8bp, Z80::RES8bo, unsigned(Bit)};
680+
RMWOps = {Z80::RES8pb, Z80::RES8ob, unsigned(Bit)};
681681
break;
682682
}
683683
case TargetOpcode::G_OR: {
684684
auto Bit = ImmConst->zextOrTrunc(8).exactLogBase2();
685685
if (Bit >= 0)
686-
RMWOps = {Z80::SET8bp, Z80::SET8bo, unsigned(Bit)};
686+
RMWOps = {Z80::SET8pb, Z80::SET8ob, unsigned(Bit)};
687687
break;
688688
}
689689
case TargetOpcode::G_ADD:
@@ -843,10 +843,10 @@ bool Z80InstructionSelector::selectLoadStore(MachineInstr &I,
843843
} else {
844844
assert(Ty == LLT::scalar(8) && "Expected RMW operation to be 8 bits");
845845
I.setDesc(TII.get(RMWOps[IsOff]));
846-
if (RMWOps.size() > 2)
847-
MIB.addImm(RMWOps[2]);
848846
for (auto &MO : MOs)
849847
MIB.add(MO);
848+
if (RMWOps.size() > 2)
849+
MIB.addImm(RMWOps[2]);
850850
I.addImplicitDefUseOperands(MF);
851851
MIB.cloneMergedMemRefs(MemMOs);
852852
if (!MRI.use_empty(ValReg)) {
@@ -1280,9 +1280,9 @@ Z80InstructionSelector::foldCompare(MachineInstr &I, MachineIRBuilder &MIB,
12801280
if (mi_match(LHSReg, MRI,
12811281
m_OneUse(m_GAnd(m_Reg(SrcReg), m_ICst(Mask)))) &&
12821282
isPowerOf2_32(Mask)) {
1283-
Opc = Z80::BIT8bg;
1283+
Opc = Z80::BIT8gb;
12841284
Reg = {};
1285-
Ops = {uint64_t(findFirstSet(Mask)), SrcReg};
1285+
Ops = {SrcReg, uint64_t(findFirstSet(Mask))};
12861286
} else {
12871287
Opc = Z80::OR8ar;
12881288
Ops = {Reg};
@@ -1544,7 +1544,7 @@ Z80InstructionSelector::foldCond(Register CondReg, MachineIRBuilder &MIB,
15441544
case Z80::COND_NZ:
15451545
case Z80::COND_PE: {
15461546
CondRC = selectGRegClass(CondReg, MRI);
1547-
auto BitI = MIB.buildInstr(Z80::BIT8bg, {}, {int64_t(0), CondReg});
1547+
auto BitI = MIB.buildInstr(Z80::BIT8gb, {}, {CondReg, int64_t(0)});
15481548
if (CondRC != &Z80::G8RegClass)
15491549
BitI->getOperand(1).setSubReg(Z80::sub_low);
15501550
if (!constrainSelectedInstRegOperands(*BitI, TII, TRI, RBI))

llvm/lib/Target/Z80/Z80InstrFormats.td

+20-12
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,27 @@ def CurMode : Mode<1>;
1919
def Z80Mode : Mode<2>;
2020
def EZ80Mode : Mode<3>;
2121

22-
class Prefix<bits<2> val, bit cb = false, bit indexed = false> {
23-
bits<4> Value = { indexed, cb, val };
22+
class Prefix {
23+
bits<4> Value = 0;
2424
}
25-
def NoPre : Prefix<0>;
26-
def CBPre : Prefix<0, true>;
27-
def DDPre : Prefix<1>;
28-
def DDCBPre : Prefix<1, true>;
29-
def EDPre : Prefix<2>;
30-
def FDPre : Prefix<3>;
31-
def FDCBPre : Prefix<3, true>;
32-
foreach i = 0-3 in {
33-
def Idx#i#Pre : Prefix<i, false, true>;
34-
def Idx#i#CBPre : Prefix<i, true, true>;
25+
26+
class IndexPrefix<bit index0, bit index1> : Prefix {
27+
let Value{0-1} = {index0, index1};
28+
}
29+
def NoIdxPre : IndexPrefix<false, false>;
30+
def Idx0Pre : IndexPrefix< true, false>;
31+
def Idx1Pre : IndexPrefix<false, true>;
32+
def Idx01Pre : IndexPrefix< true, true>;
33+
34+
class OtherPrefix<bit cb, bit ed> : Prefix {
35+
let Value{2-3} = {cb, ed};
36+
}
37+
def NoPre : OtherPrefix<false, false>;
38+
def CBPre : OtherPrefix< true, false>;
39+
def EDPre : OtherPrefix<false, true>;
40+
41+
class Pre<IndexPrefix index = NoIdxPre, OtherPrefix other = NoPre> : Prefix {
42+
let Value{0-3} = {index.Value{0-1}, other.Value{2-3}};
3543
}
3644

3745
class ImmType<bits<2> val> {

llvm/lib/Target/Z80/Z80InstrInfo.cpp

+36-18
Original file line numberDiff line numberDiff line change
@@ -99,37 +99,54 @@ static bool isIndex(const MachineOperand &MO, const MCRegisterInfo &RI) {
9999
}
100100

101101
unsigned Z80InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
102+
unsigned Size = 0;
102103
auto TSFlags = MI.getDesc().TSFlags;
103-
// opcode byte
104-
unsigned Size = 1;
104+
105+
// compute the prefix and offset
106+
bool IdxPre = false;
107+
bool CBPre = TSFlags & Z80II::CBPre;
108+
bool EDPre = TSFlags & Z80II::EDPre;
109+
bool HasOff = TSFlags & Z80II::HasOff;
110+
assert(!(CBPre && EDPre));
111+
for (unsigned OpIdx = 0; OpIdx != 2; ++OpIdx) {
112+
if (!(TSFlags & Z80II::Idx0Pre << OpIdx) ||
113+
!isIndex(MI.getOperand(OpIdx), getRegisterInfo()))
114+
continue;
115+
IdxPre = true;
116+
// index prefix cannot be combined with ED prefix
117+
EDPre = false;
118+
// (ix) gains an offset
119+
if (MI.getDesc().OpInfo[OpIdx].OperandType == MCOI::OPERAND_MEMORY)
120+
HasOff = true;
121+
}
122+
105123
// suffix byte
106124
switch (TSFlags & Z80II::ModeMask) {
107125
case Z80II::AnyMode:
108126
case Z80II::CurMode:
109127
break;
110128
case Z80II::Z80Mode:
111-
Size += Subtarget.is24Bit();
129+
Size += !Subtarget.is16Bit();
112130
break;
113131
case Z80II::EZ80Mode:
114-
Size += Subtarget.is16Bit();
132+
Size += !Subtarget.is24Bit();
115133
break;
116134
}
135+
117136
// prefix byte(s)
118-
Size += TSFlags & Z80II::HasIndexedPrefix
119-
? isIndex(MI.getOperand((TSFlags & Z80II::IndexMask) >>
120-
Z80II::PrefixShift),
121-
getRegisterInfo())
122-
: (TSFlags & Z80II::IndexMask) != Z80II::NoPrefix;
123-
if (TSFlags & Z80II::HasCBPrefix)
124-
Size += 1;
137+
Size += IdxPre + CBPre + EDPre;
138+
139+
// opcode byte
140+
Size += 1;
141+
125142
// immediate byte(s)
126143
if (TSFlags & Z80II::HasImm)
127144
switch (TSFlags & Z80II::ModeMask) {
128145
case Z80II::AnyMode:
129146
Size += 1;
130147
break;
131148
case Z80II::CurMode:
132-
Size += Subtarget.is24Bit() ? 3 : 2;
149+
Size += 2 + Subtarget.is24Bit();;
133150
break;
134151
case Z80II::Z80Mode:
135152
Size += 2;
@@ -138,9 +155,10 @@ unsigned Z80InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
138155
Size += 3;
139156
break;
140157
}
158+
141159
// offset byte
142-
if (TSFlags & Z80II::HasOff)
143-
Size += 1;
160+
Size += HasOff;
161+
144162
return Size;
145163
}
146164

@@ -1016,9 +1034,9 @@ void Z80InstrInfo::rewriteFrameIndex(MachineInstr &MI, unsigned FIOperandNum,
10161034
case Z80::SLA8o: Opc = Z80::SLA8p; break;
10171035
case Z80::SRA8o: Opc = Z80::SRA8p; break;
10181036
case Z80::SRL8o: Opc = Z80::SRL8p; break;
1019-
case Z80::BIT8bo: Opc = Z80::BIT8bp; break;
1020-
case Z80::RES8bo: Opc = Z80::RES8bp; break;
1021-
case Z80::SET8bo: Opc = Z80::SET8bp; break;
1037+
case Z80::BIT8ob: Opc = Z80::BIT8pb; break;
1038+
case Z80::RES8ob: Opc = Z80::RES8pb; break;
1039+
case Z80::SET8ob: Opc = Z80::SET8pb; break;
10221040
case Z80::INC8o: Opc = Z80::INC8p; break;
10231041
case Z80::DEC8o: Opc = Z80::DEC8p; break;
10241042
case Z80::ADD8ao: Opc = Z80::ADD8ap; break;
@@ -1867,7 +1885,7 @@ MachineInstr *Z80InstrInfo::foldMemoryOperandImpl(
18671885
case 1:
18681886
switch (MI.getOpcode()) {
18691887
default: return nullptr;
1870-
case Z80::BIT8bg: Opc = IsOff ? Z80::BIT8bo : Z80::BIT8bp; break;
1888+
case Z80::BIT8gb: Opc = IsOff ? Z80::BIT8ob : Z80::BIT8pb; break;
18711889
case Z80::ADD8ar: Opc = IsOff ? Z80::ADD8ao : Z80::ADD8ap; break;
18721890
case Z80::ADC8ar: Opc = IsOff ? Z80::ADC8ao : Z80::ADC8ap; break;
18731891
case Z80::SUB8ar: Opc = IsOff ? Z80::SUB8ao : Z80::SUB8ap; break;

llvm/lib/Target/Z80/Z80InstrInfo.h

+26-28
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ namespace llvm {
2424
class Z80Subtarget;
2525

2626
namespace Z80 {
27-
// Z80 specific condition code. These correspond to Z80_*_COND in
28-
// Z80InstrInfo.td. They must be kept in synch.
27+
// Z80 specific condition code. These correspond to Z80_*_COND in
28+
// Z80InstrInfo.td. They must be kept in synch.
2929
enum CondCode {
3030
COND_NZ = 0,
3131
COND_Z = 1,
@@ -54,33 +54,31 @@ CondCode parseConstraintCode(StringRef Constraint);
5454
bool splitReg(unsigned ByteSize, unsigned Opc8, unsigned Opc16, unsigned Opc24,
5555
unsigned &RC, unsigned &LoOpc, unsigned &LoIdx, unsigned &HiOpc,
5656
unsigned &HiIdx, unsigned &HiOff, bool Has16BitEZ80Ops);
57-
} // end namespace Z80;
57+
} // namespace Z80
5858

5959
namespace Z80II {
60-
enum {
61-
ModeShift = 0,
62-
AnyMode = 0 << ModeShift,
63-
CurMode = 1 << ModeShift,
64-
Z80Mode = 2 << ModeShift,
65-
EZ80Mode = 3 << ModeShift,
66-
ModeMask = 3 << ModeShift,
67-
68-
PrefixShift = 2,
69-
NoPrefix = 0 << PrefixShift,
70-
DDPrefix = 1 << PrefixShift,
71-
EDPrefix = 2 << PrefixShift,
72-
FDPrefix = 3 << PrefixShift,
73-
IndexMask = 3 << PrefixShift,
74-
HasCBPrefix = 1 << (PrefixShift + 2),
75-
HasIndexedPrefix = 1 << (PrefixShift + 3),
76-
77-
HasImm = 1 << 6,
78-
HasOff = 1 << 7,
79-
80-
OpcodeShift = 8,
81-
OpcodeMask = 0xFF << OpcodeShift
82-
};
83-
} // end namespace Z80II;
60+
enum {
61+
ModeShift = 0,
62+
AnyMode = 0 << ModeShift,
63+
CurMode = 1 << ModeShift,
64+
Z80Mode = 2 << ModeShift,
65+
EZ80Mode = 3 << ModeShift,
66+
ModeMask = 3 << ModeShift,
67+
68+
PrefixShift = 2,
69+
Idx0Pre = 1 << 0 << PrefixShift,
70+
Idx1Pre = 1 << 1 << PrefixShift,
71+
CBPre = 1 << 2 << PrefixShift,
72+
EDPre = 1 << 3 << PrefixShift,
73+
PrefixMask = ((1 << 4) - 1) << PrefixShift,
74+
75+
HasImm = 1 << 6,
76+
HasOff = 1 << 7,
77+
78+
OpcodeShift = 8,
79+
OpcodeMask = 0xFF << OpcodeShift
80+
};
81+
}
8482

8583
class Z80InstrInfo final : public Z80GenInstrInfo {
8684
Z80Subtarget &Subtarget;
@@ -215,6 +213,6 @@ class Z80InstrInfo final : public Z80GenInstrInfo {
215213
MachineInstr &MI, unsigned RegIdx) const;
216214
};
217215

218-
} // End llvm namespace
216+
} // namespace llvm
219217

220218
#endif

0 commit comments

Comments
 (0)