1 | //=== HexagonMCCompound.cpp - Hexagon Compound checker -------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file is looks at a packet and tries to form compound insns |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "MCTargetDesc/HexagonBaseInfo.h" |
14 | #include "MCTargetDesc/HexagonMCInstrInfo.h" |
15 | #include "MCTargetDesc/HexagonMCShuffler.h" |
16 | #include "llvm/MC/MCContext.h" |
17 | #include "llvm/MC/MCExpr.h" |
18 | #include "llvm/MC/MCInst.h" |
19 | #include "llvm/Support/Debug.h" |
20 | #include "llvm/Support/ErrorHandling.h" |
21 | #include "llvm/Support/raw_ostream.h" |
22 | #include <cassert> |
23 | #include <cstdint> |
24 | |
25 | using namespace llvm; |
26 | using namespace Hexagon; |
27 | |
28 | #define DEBUG_TYPE "hexagon-mccompound" |
29 | |
30 | enum OpcodeIndex { |
31 | fp0_jump_nt = 0, |
32 | fp0_jump_t, |
33 | fp1_jump_nt, |
34 | fp1_jump_t, |
35 | tp0_jump_nt, |
36 | tp0_jump_t, |
37 | tp1_jump_nt, |
38 | tp1_jump_t |
39 | }; |
40 | |
41 | static const unsigned tstBitOpcode[8] = { |
42 | J4_tstbit0_fp0_jump_nt, J4_tstbit0_fp0_jump_t, J4_tstbit0_fp1_jump_nt, |
43 | J4_tstbit0_fp1_jump_t, J4_tstbit0_tp0_jump_nt, J4_tstbit0_tp0_jump_t, |
44 | J4_tstbit0_tp1_jump_nt, J4_tstbit0_tp1_jump_t}; |
45 | static const unsigned cmpeqBitOpcode[8] = { |
46 | J4_cmpeq_fp0_jump_nt, J4_cmpeq_fp0_jump_t, J4_cmpeq_fp1_jump_nt, |
47 | J4_cmpeq_fp1_jump_t, J4_cmpeq_tp0_jump_nt, J4_cmpeq_tp0_jump_t, |
48 | J4_cmpeq_tp1_jump_nt, J4_cmpeq_tp1_jump_t}; |
49 | static const unsigned cmpgtBitOpcode[8] = { |
50 | J4_cmpgt_fp0_jump_nt, J4_cmpgt_fp0_jump_t, J4_cmpgt_fp1_jump_nt, |
51 | J4_cmpgt_fp1_jump_t, J4_cmpgt_tp0_jump_nt, J4_cmpgt_tp0_jump_t, |
52 | J4_cmpgt_tp1_jump_nt, J4_cmpgt_tp1_jump_t}; |
53 | static const unsigned cmpgtuBitOpcode[8] = { |
54 | J4_cmpgtu_fp0_jump_nt, J4_cmpgtu_fp0_jump_t, J4_cmpgtu_fp1_jump_nt, |
55 | J4_cmpgtu_fp1_jump_t, J4_cmpgtu_tp0_jump_nt, J4_cmpgtu_tp0_jump_t, |
56 | J4_cmpgtu_tp1_jump_nt, J4_cmpgtu_tp1_jump_t}; |
57 | static const unsigned cmpeqiBitOpcode[8] = { |
58 | J4_cmpeqi_fp0_jump_nt, J4_cmpeqi_fp0_jump_t, J4_cmpeqi_fp1_jump_nt, |
59 | J4_cmpeqi_fp1_jump_t, J4_cmpeqi_tp0_jump_nt, J4_cmpeqi_tp0_jump_t, |
60 | J4_cmpeqi_tp1_jump_nt, J4_cmpeqi_tp1_jump_t}; |
61 | static const unsigned cmpgtiBitOpcode[8] = { |
62 | J4_cmpgti_fp0_jump_nt, J4_cmpgti_fp0_jump_t, J4_cmpgti_fp1_jump_nt, |
63 | J4_cmpgti_fp1_jump_t, J4_cmpgti_tp0_jump_nt, J4_cmpgti_tp0_jump_t, |
64 | J4_cmpgti_tp1_jump_nt, J4_cmpgti_tp1_jump_t}; |
65 | static const unsigned cmpgtuiBitOpcode[8] = { |
66 | J4_cmpgtui_fp0_jump_nt, J4_cmpgtui_fp0_jump_t, J4_cmpgtui_fp1_jump_nt, |
67 | J4_cmpgtui_fp1_jump_t, J4_cmpgtui_tp0_jump_nt, J4_cmpgtui_tp0_jump_t, |
68 | J4_cmpgtui_tp1_jump_nt, J4_cmpgtui_tp1_jump_t}; |
69 | static const unsigned cmpeqn1BitOpcode[8] = { |
70 | J4_cmpeqn1_fp0_jump_nt, J4_cmpeqn1_fp0_jump_t, J4_cmpeqn1_fp1_jump_nt, |
71 | J4_cmpeqn1_fp1_jump_t, J4_cmpeqn1_tp0_jump_nt, J4_cmpeqn1_tp0_jump_t, |
72 | J4_cmpeqn1_tp1_jump_nt, J4_cmpeqn1_tp1_jump_t}; |
73 | static const unsigned cmpgtn1BitOpcode[8] = { |
74 | J4_cmpgtn1_fp0_jump_nt, J4_cmpgtn1_fp0_jump_t, J4_cmpgtn1_fp1_jump_nt, |
75 | J4_cmpgtn1_fp1_jump_t, J4_cmpgtn1_tp0_jump_nt, J4_cmpgtn1_tp0_jump_t, |
76 | J4_cmpgtn1_tp1_jump_nt, J4_cmpgtn1_tp1_jump_t, |
77 | }; |
78 | |
79 | // enum HexagonII::CompoundGroup |
80 | static unsigned getCompoundCandidateGroup(MCInst const &MI, bool IsExtended) { |
81 | unsigned DstReg, SrcReg, Src1Reg, Src2Reg; |
82 | |
83 | switch (MI.getOpcode()) { |
84 | default: |
85 | return HexagonII::HCG_None; |
86 | // |
87 | // Compound pairs. |
88 | // "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2" |
89 | // "Rd16=#U6 ; jump #r9:2" |
90 | // "Rd16=Rs16 ; jump #r9:2" |
91 | // |
92 | case Hexagon::C2_cmpeq: |
93 | case Hexagon::C2_cmpgt: |
94 | case Hexagon::C2_cmpgtu: |
95 | if (IsExtended) |
96 | return HexagonII::HCG_None; |
97 | DstReg = MI.getOperand(i: 0).getReg(); |
98 | Src1Reg = MI.getOperand(i: 1).getReg(); |
99 | Src2Reg = MI.getOperand(i: 2).getReg(); |
100 | if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) && |
101 | HexagonMCInstrInfo::isIntRegForSubInst(Reg: Src1Reg) && |
102 | HexagonMCInstrInfo::isIntRegForSubInst(Reg: Src2Reg)) |
103 | return HexagonII::HCG_A; |
104 | break; |
105 | case Hexagon::C2_cmpeqi: |
106 | case Hexagon::C2_cmpgti: |
107 | case Hexagon::C2_cmpgtui: |
108 | if (IsExtended) |
109 | return HexagonII::HCG_None; |
110 | // P0 = cmp.eq(Rs,#u2) |
111 | DstReg = MI.getOperand(i: 0).getReg(); |
112 | SrcReg = MI.getOperand(i: 1).getReg(); |
113 | if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) && |
114 | HexagonMCInstrInfo::isIntRegForSubInst(Reg: SrcReg) && |
115 | (HexagonMCInstrInfo::inRange<5>(MCI: MI, Index: 2) || |
116 | HexagonMCInstrInfo::minConstant(MCI: MI, Index: 2) == -1)) |
117 | return HexagonII::HCG_A; |
118 | break; |
119 | case Hexagon::A2_tfr: |
120 | if (IsExtended) |
121 | return HexagonII::HCG_None; |
122 | // Rd = Rs |
123 | DstReg = MI.getOperand(i: 0).getReg(); |
124 | SrcReg = MI.getOperand(i: 1).getReg(); |
125 | if (HexagonMCInstrInfo::isIntRegForSubInst(Reg: DstReg) && |
126 | HexagonMCInstrInfo::isIntRegForSubInst(Reg: SrcReg)) |
127 | return HexagonII::HCG_A; |
128 | break; |
129 | case Hexagon::A2_tfrsi: |
130 | if (IsExtended) |
131 | return HexagonII::HCG_None; |
132 | // Rd = #u6 |
133 | DstReg = MI.getOperand(i: 0).getReg(); |
134 | if (HexagonMCInstrInfo::minConstant(MCI: MI, Index: 1) <= 63 && |
135 | HexagonMCInstrInfo::minConstant(MCI: MI, Index: 1) >= 0 && |
136 | HexagonMCInstrInfo::isIntRegForSubInst(Reg: DstReg)) |
137 | return HexagonII::HCG_A; |
138 | break; |
139 | case Hexagon::S2_tstbit_i: |
140 | if (IsExtended) |
141 | return HexagonII::HCG_None; |
142 | DstReg = MI.getOperand(i: 0).getReg(); |
143 | Src1Reg = MI.getOperand(i: 1).getReg(); |
144 | if ((Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) && |
145 | HexagonMCInstrInfo::isIntRegForSubInst(Reg: Src1Reg) && |
146 | HexagonMCInstrInfo::minConstant(MCI: MI, Index: 2) == 0) |
147 | return HexagonII::HCG_A; |
148 | break; |
149 | // The fact that .new form is used pretty much guarantees |
150 | // that predicate register will match. Nevertheless, |
151 | // there could be some false positives without additional |
152 | // checking. |
153 | case Hexagon::J2_jumptnew: |
154 | case Hexagon::J2_jumpfnew: |
155 | case Hexagon::J2_jumptnewpt: |
156 | case Hexagon::J2_jumpfnewpt: |
157 | Src1Reg = MI.getOperand(i: 0).getReg(); |
158 | if (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg) |
159 | return HexagonII::HCG_B; |
160 | break; |
161 | // Transfer and jump: |
162 | // Rd=#U6 ; jump #r9:2 |
163 | // Rd=Rs ; jump #r9:2 |
164 | // Do not test for jump range here. |
165 | case Hexagon::J2_jump: |
166 | case Hexagon::RESTORE_DEALLOC_RET_JMP_V4: |
167 | return HexagonII::HCG_C; |
168 | break; |
169 | } |
170 | |
171 | return HexagonII::HCG_None; |
172 | } |
173 | |
174 | /// getCompoundOp - Return the index from 0-7 into the above opcode lists. |
175 | static unsigned getCompoundOp(MCInst const &HMCI) { |
176 | const MCOperand &Predicate = HMCI.getOperand(i: 0); |
177 | unsigned PredReg = Predicate.getReg(); |
178 | |
179 | assert((PredReg == Hexagon::P0) || (PredReg == Hexagon::P1) || |
180 | (PredReg == Hexagon::P2) || (PredReg == Hexagon::P3)); |
181 | |
182 | switch (HMCI.getOpcode()) { |
183 | default: |
184 | llvm_unreachable("Expected match not found.\n" ); |
185 | break; |
186 | case Hexagon::J2_jumpfnew: |
187 | return (PredReg == Hexagon::P0) ? fp0_jump_nt : fp1_jump_nt; |
188 | case Hexagon::J2_jumpfnewpt: |
189 | return (PredReg == Hexagon::P0) ? fp0_jump_t : fp1_jump_t; |
190 | case Hexagon::J2_jumptnew: |
191 | return (PredReg == Hexagon::P0) ? tp0_jump_nt : tp1_jump_nt; |
192 | case Hexagon::J2_jumptnewpt: |
193 | return (PredReg == Hexagon::P0) ? tp0_jump_t : tp1_jump_t; |
194 | } |
195 | } |
196 | |
197 | static MCInst *getCompoundInsn(MCContext &Context, MCInst const &L, |
198 | MCInst const &R) { |
199 | MCInst *CompoundInsn = nullptr; |
200 | unsigned compoundOpcode; |
201 | MCOperand Rs, Rt; |
202 | int64_t Value; |
203 | bool Success; |
204 | |
205 | switch (L.getOpcode()) { |
206 | default: |
207 | LLVM_DEBUG(dbgs() << "Possible compound ignored\n" ); |
208 | return CompoundInsn; |
209 | |
210 | case Hexagon::A2_tfrsi: |
211 | Rt = L.getOperand(i: 0); |
212 | compoundOpcode = J4_jumpseti; |
213 | CompoundInsn = Context.createMCInst(); |
214 | CompoundInsn->setOpcode(compoundOpcode); |
215 | |
216 | CompoundInsn->addOperand(Op: Rt); |
217 | CompoundInsn->addOperand(Op: L.getOperand(i: 1)); // Immediate |
218 | CompoundInsn->addOperand(Op: R.getOperand(i: 0)); // Jump target |
219 | break; |
220 | |
221 | case Hexagon::A2_tfr: |
222 | Rt = L.getOperand(i: 0); |
223 | Rs = L.getOperand(i: 1); |
224 | |
225 | compoundOpcode = J4_jumpsetr; |
226 | CompoundInsn = Context.createMCInst(); |
227 | CompoundInsn->setOpcode(compoundOpcode); |
228 | CompoundInsn->addOperand(Op: Rt); |
229 | CompoundInsn->addOperand(Op: Rs); |
230 | CompoundInsn->addOperand(Op: R.getOperand(i: 0)); // Jump target. |
231 | |
232 | break; |
233 | |
234 | case Hexagon::C2_cmpeq: |
235 | LLVM_DEBUG(dbgs() << "CX: C2_cmpeq\n" ); |
236 | Rs = L.getOperand(i: 1); |
237 | Rt = L.getOperand(i: 2); |
238 | |
239 | compoundOpcode = cmpeqBitOpcode[getCompoundOp(HMCI: R)]; |
240 | CompoundInsn = Context.createMCInst(); |
241 | CompoundInsn->setOpcode(compoundOpcode); |
242 | CompoundInsn->addOperand(Op: Rs); |
243 | CompoundInsn->addOperand(Op: Rt); |
244 | CompoundInsn->addOperand(Op: R.getOperand(i: 1)); |
245 | break; |
246 | |
247 | case Hexagon::C2_cmpgt: |
248 | LLVM_DEBUG(dbgs() << "CX: C2_cmpgt\n" ); |
249 | Rs = L.getOperand(i: 1); |
250 | Rt = L.getOperand(i: 2); |
251 | |
252 | compoundOpcode = cmpgtBitOpcode[getCompoundOp(HMCI: R)]; |
253 | CompoundInsn = Context.createMCInst(); |
254 | CompoundInsn->setOpcode(compoundOpcode); |
255 | CompoundInsn->addOperand(Op: Rs); |
256 | CompoundInsn->addOperand(Op: Rt); |
257 | CompoundInsn->addOperand(Op: R.getOperand(i: 1)); |
258 | break; |
259 | |
260 | case Hexagon::C2_cmpgtu: |
261 | LLVM_DEBUG(dbgs() << "CX: C2_cmpgtu\n" ); |
262 | Rs = L.getOperand(i: 1); |
263 | Rt = L.getOperand(i: 2); |
264 | |
265 | compoundOpcode = cmpgtuBitOpcode[getCompoundOp(HMCI: R)]; |
266 | CompoundInsn = Context.createMCInst(); |
267 | CompoundInsn->setOpcode(compoundOpcode); |
268 | CompoundInsn->addOperand(Op: Rs); |
269 | CompoundInsn->addOperand(Op: Rt); |
270 | CompoundInsn->addOperand(Op: R.getOperand(i: 1)); |
271 | break; |
272 | |
273 | case Hexagon::C2_cmpeqi: |
274 | LLVM_DEBUG(dbgs() << "CX: C2_cmpeqi\n" ); |
275 | Success = L.getOperand(i: 2).getExpr()->evaluateAsAbsolute(Res&: Value); |
276 | (void)Success; |
277 | assert(Success); |
278 | if (Value == -1) |
279 | compoundOpcode = cmpeqn1BitOpcode[getCompoundOp(HMCI: R)]; |
280 | else |
281 | compoundOpcode = cmpeqiBitOpcode[getCompoundOp(HMCI: R)]; |
282 | |
283 | Rs = L.getOperand(i: 1); |
284 | CompoundInsn = Context.createMCInst(); |
285 | CompoundInsn->setOpcode(compoundOpcode); |
286 | CompoundInsn->addOperand(Op: Rs); |
287 | CompoundInsn->addOperand(Op: L.getOperand(i: 2)); |
288 | CompoundInsn->addOperand(Op: R.getOperand(i: 1)); |
289 | break; |
290 | |
291 | case Hexagon::C2_cmpgti: |
292 | LLVM_DEBUG(dbgs() << "CX: C2_cmpgti\n" ); |
293 | Success = L.getOperand(i: 2).getExpr()->evaluateAsAbsolute(Res&: Value); |
294 | (void)Success; |
295 | assert(Success); |
296 | if (Value == -1) |
297 | compoundOpcode = cmpgtn1BitOpcode[getCompoundOp(HMCI: R)]; |
298 | else |
299 | compoundOpcode = cmpgtiBitOpcode[getCompoundOp(HMCI: R)]; |
300 | |
301 | Rs = L.getOperand(i: 1); |
302 | CompoundInsn = Context.createMCInst(); |
303 | CompoundInsn->setOpcode(compoundOpcode); |
304 | CompoundInsn->addOperand(Op: Rs); |
305 | CompoundInsn->addOperand(Op: L.getOperand(i: 2)); |
306 | CompoundInsn->addOperand(Op: R.getOperand(i: 1)); |
307 | break; |
308 | |
309 | case Hexagon::C2_cmpgtui: |
310 | LLVM_DEBUG(dbgs() << "CX: C2_cmpgtui\n" ); |
311 | Rs = L.getOperand(i: 1); |
312 | compoundOpcode = cmpgtuiBitOpcode[getCompoundOp(HMCI: R)]; |
313 | CompoundInsn = Context.createMCInst(); |
314 | CompoundInsn->setOpcode(compoundOpcode); |
315 | CompoundInsn->addOperand(Op: Rs); |
316 | CompoundInsn->addOperand(Op: L.getOperand(i: 2)); |
317 | CompoundInsn->addOperand(Op: R.getOperand(i: 1)); |
318 | break; |
319 | |
320 | case Hexagon::S2_tstbit_i: |
321 | LLVM_DEBUG(dbgs() << "CX: S2_tstbit_i\n" ); |
322 | Rs = L.getOperand(i: 1); |
323 | compoundOpcode = tstBitOpcode[getCompoundOp(HMCI: R)]; |
324 | CompoundInsn = Context.createMCInst(); |
325 | CompoundInsn->setOpcode(compoundOpcode); |
326 | CompoundInsn->addOperand(Op: Rs); |
327 | CompoundInsn->addOperand(Op: R.getOperand(i: 1)); |
328 | break; |
329 | } |
330 | |
331 | return CompoundInsn; |
332 | } |
333 | |
334 | /// Non-Symmetrical. See if these two instructions are fit for compound pair. |
335 | static bool isOrderedCompoundPair(MCInst const &MIa, bool IsExtendedA, |
336 | MCInst const &MIb, bool IsExtendedB) { |
337 | unsigned MIaG = getCompoundCandidateGroup(MI: MIa, IsExtended: IsExtendedA); |
338 | unsigned MIbG = getCompoundCandidateGroup(MI: MIb, IsExtended: IsExtendedB); |
339 | // We have two candidates - check that this is the same register |
340 | // we are talking about. |
341 | unsigned Opca = MIa.getOpcode(); |
342 | if (MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_C && |
343 | (Opca == Hexagon::A2_tfr || Opca == Hexagon::A2_tfrsi)) |
344 | return true; |
345 | return ((MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_B) && |
346 | (MIa.getOperand(i: 0).getReg() == MIb.getOperand(i: 0).getReg())); |
347 | } |
348 | |
349 | static bool lookForCompound(MCInstrInfo const &MCII, MCContext &Context, |
350 | MCInst &MCI) { |
351 | assert(HexagonMCInstrInfo::isBundle(MCI)); |
352 | bool JExtended = false; |
353 | for (MCInst::iterator J = |
354 | MCI.begin() + HexagonMCInstrInfo::bundleInstructionsOffset; |
355 | J != MCI.end(); ++J) { |
356 | MCInst const *JumpInst = J->getInst(); |
357 | if (HexagonMCInstrInfo::isImmext(MCI: *JumpInst)) { |
358 | JExtended = true; |
359 | continue; |
360 | } |
361 | if (HexagonMCInstrInfo::getType(MCII, MCI: *JumpInst) == HexagonII::TypeJ) { |
362 | // Try to pair with another insn (B)undled with jump. |
363 | bool BExtended = false; |
364 | for (MCInst::iterator B = |
365 | MCI.begin() + HexagonMCInstrInfo::bundleInstructionsOffset; |
366 | B != MCI.end(); ++B) { |
367 | MCInst const *Inst = B->getInst(); |
368 | if (JumpInst == Inst) { |
369 | BExtended = false; |
370 | continue; |
371 | } |
372 | if (HexagonMCInstrInfo::isImmext(MCI: *Inst)) { |
373 | BExtended = true; |
374 | continue; |
375 | } |
376 | LLVM_DEBUG(dbgs() << "J,B: " << JumpInst->getOpcode() << "," |
377 | << Inst->getOpcode() << "\n" ); |
378 | if (isOrderedCompoundPair(MIa: *Inst, IsExtendedA: BExtended, MIb: *JumpInst, IsExtendedB: JExtended)) { |
379 | MCInst *CompoundInsn = getCompoundInsn(Context, L: *Inst, R: *JumpInst); |
380 | if (CompoundInsn) { |
381 | LLVM_DEBUG(dbgs() << "B: " << Inst->getOpcode() << "," |
382 | << JumpInst->getOpcode() << " Compounds to " |
383 | << CompoundInsn->getOpcode() << "\n" ); |
384 | J->setInst(CompoundInsn); |
385 | MCI.erase(I: B); |
386 | return true; |
387 | } |
388 | } |
389 | BExtended = false; |
390 | } |
391 | } |
392 | JExtended = false; |
393 | } |
394 | return false; |
395 | } |
396 | |
397 | /// tryCompound - Given a bundle check for compound insns when one |
398 | /// is found update the contents fo the bundle with the compound insn. |
399 | /// If a compound instruction is found then the bundle will have one |
400 | /// additional slot. |
401 | void HexagonMCInstrInfo::tryCompound(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, |
402 | MCContext &Context, MCInst &MCI) { |
403 | assert(HexagonMCInstrInfo::isBundle(MCI) && |
404 | "Non-Bundle where Bundle expected" ); |
405 | |
406 | // By definition a compound must have 2 insn. |
407 | if (MCI.size() < 2) |
408 | return; |
409 | |
410 | // Create a vector, needed to keep the order of jump instructions. |
411 | MCInst CheckList(MCI); |
412 | |
413 | // Keep the last known good bundle around in case the shuffle fails. |
414 | MCInst LastValidBundle(MCI); |
415 | |
416 | bool PreviouslyValid = llvm::HexagonMCShuffle(Context, ReportErrors: false, MCII, STI, MCB&: MCI); |
417 | |
418 | // Look for compounds until none are found, only update the bundle when |
419 | // a compound is found. |
420 | while (lookForCompound(MCII, Context, MCI&: CheckList)) { |
421 | // Need to update the bundle. |
422 | MCI = CheckList; |
423 | |
424 | const bool IsValid = llvm::HexagonMCShuffle(Context, ReportErrors: false, MCII, STI, MCB&: MCI); |
425 | if (PreviouslyValid && !IsValid) { |
426 | LLVM_DEBUG(dbgs() << "Found ERROR\n" ); |
427 | MCI = LastValidBundle; |
428 | } else if (IsValid) { |
429 | LastValidBundle = MCI; |
430 | PreviouslyValid = true; |
431 | } |
432 | } |
433 | } |
434 | |