@@ -86,16 +86,22 @@ namespace {
86
86
class CompressInstEmitter {
87
87
struct OpData {
88
88
enum MapKind { Operand, Imm, Reg } Kind;
89
- union {
89
+ // Info for an operand.
90
+ struct OpndInfo {
91
+ // Record from the Dag.
92
+ const Record *DagRec;
90
93
// Operand number mapped to.
91
- unsigned OpNo;
94
+ unsigned Idx;
95
+ // Tied operand index within the instruction.
96
+ int TiedOpIdx;
97
+ };
98
+ union {
99
+ OpndInfo OpInfo;
92
100
// Integer immediate value.
93
101
int64_t ImmVal;
94
102
// Physical register.
95
103
const Record *RegRec;
96
104
};
97
- // Tied operand index within the instruction.
98
- int TiedOpIdx = -1 ;
99
105
};
100
106
struct ArgData {
101
107
unsigned DAGOpNo;
@@ -273,6 +279,31 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
273
279
" ' in the corresponding instruction operand!" );
274
280
275
281
OperandMap[OpNo].Kind = OpData::Operand;
282
+ OperandMap[OpNo].OpInfo .DagRec = DI->getDef ();
283
+ OperandMap[OpNo].OpInfo .TiedOpIdx = -1 ;
284
+
285
+ // Create a mapping between the operand name in the Dag (e.g. $rs1) and
286
+ // its index in the list of Dag operands and check that operands with
287
+ // the same name have the same type. For example in 'C_ADD $rs1, $rs2'
288
+ // we generate the mapping $rs1 --> 0, $rs2 ---> 1. If the operand
289
+ // appears twice in the same Dag (tied in the compressed instruction),
290
+ // we note the previous index in the TiedOpIdx field.
291
+ StringRef ArgName = Dag->getArgNameStr (DAGOpNo);
292
+ if (ArgName.empty ())
293
+ continue ;
294
+
295
+ if (IsSourceInst) {
296
+ auto It = Operands.find (ArgName);
297
+ if (It != Operands.end ()) {
298
+ OperandMap[OpNo].OpInfo .TiedOpIdx = It->getValue ().MIOpNo ;
299
+ if (OperandMap[It->getValue ().MIOpNo ].OpInfo .DagRec != DI->getDef ())
300
+ PrintFatalError (Rec->getLoc (),
301
+ " Input Operand '" + ArgName +
302
+ " ' has a mismatched tied operand!" );
303
+ }
304
+ }
305
+
306
+ Operands[ArgName] = {DAGOpNo, OpNo};
276
307
} else if (const auto *II = dyn_cast<IntInit>(Dag->getArg (DAGOpNo))) {
277
308
// Validate that corresponding instruction operand expects an immediate.
278
309
if (!OpndRec->isSubClassOf (" Operand" ))
@@ -292,30 +323,6 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
292
323
} else {
293
324
llvm_unreachable (" Unhandled CompressPat argument type!" );
294
325
}
295
-
296
- // Create a mapping between the operand name in the Dag (e.g. $rs1) and
297
- // its index in the list of Dag operands and check that operands with the
298
- // same name have the same type. For example in 'C_ADD $rs1, $rs2' we
299
- // generate the mapping $rs1 --> 0, $rs2 ---> 1. If the operand appears
300
- // twice in the same Dag (tied in the compressed instruction), we note
301
- // the previous index in the TiedOpIdx field.
302
- StringRef ArgName = Dag->getArgNameStr (DAGOpNo);
303
- if (ArgName.empty ())
304
- continue ;
305
-
306
- if (IsSourceInst) {
307
- auto It = Operands.find (ArgName);
308
- if (It != Operands.end ()) {
309
- OperandMap[OpNo].TiedOpIdx = It->getValue ().MIOpNo ;
310
- if (!validateArgsTypes (Dag->getArg (It->getValue ().DAGOpNo ),
311
- Dag->getArg (DAGOpNo)))
312
- PrintFatalError (Rec->getLoc (),
313
- " Input Operand '" + ArgName +
314
- " ' has a mismatched tied operand!" );
315
- }
316
- }
317
-
318
- Operands[ArgName] = {DAGOpNo, OpNo};
319
326
}
320
327
}
321
328
@@ -372,8 +379,9 @@ void CompressInstEmitter::createInstOperandMapping(
372
379
if (DestOperandMap[OpNo].Kind == OpData::Operand)
373
380
// No need to fill the SourceOperandMap here since it was mapped to
374
381
// destination operand 'TiedInstOpIdx' in a previous iteration.
375
- LLVM_DEBUG (dbgs () << " " << DestOperandMap[OpNo].OpNo << " ====> "
376
- << OpNo << " Dest operand tied with operand '"
382
+ LLVM_DEBUG (dbgs () << " " << DestOperandMap[OpNo].OpInfo .Idx
383
+ << " ====> " << OpNo
384
+ << " Dest operand tied with operand '"
377
385
<< TiedInstOpIdx << " '\n " );
378
386
++OpNo;
379
387
continue ;
@@ -398,8 +406,8 @@ void CompressInstEmitter::createInstOperandMapping(
398
406
" Incorrect operand mapping detected!\n " );
399
407
400
408
unsigned SourceOpNo = SourceOp->getValue ().MIOpNo ;
401
- DestOperandMap[OpNo].OpNo = SourceOpNo;
402
- SourceOperandMap[SourceOpNo].OpNo = OpNo;
409
+ DestOperandMap[OpNo].OpInfo . Idx = SourceOpNo;
410
+ SourceOperandMap[SourceOpNo].OpInfo . Idx = OpNo;
403
411
LLVM_DEBUG (dbgs () << " " << SourceOpNo << " ====> " << OpNo << " \n " );
404
412
}
405
413
}
@@ -721,21 +729,24 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
721
729
// Start Source Inst operands validation.
722
730
unsigned OpNo = 0 ;
723
731
for (const auto &SourceOperand : Source.Operands ) {
724
- if (SourceOperandMap[OpNo].TiedOpIdx != -1 ) {
725
- if (Source.Operands [OpNo].Rec ->isSubClassOf (" RegisterClass" ))
726
- CondStream.indent (8 )
727
- << " (MI.getOperand(" << OpNo << " ).isReg()) && (MI.getOperand("
728
- << SourceOperandMap[OpNo].TiedOpIdx << " ).isReg()) &&\n "
729
- << indent (8 ) << " (MI.getOperand(" << OpNo
730
- << " ).getReg() == MI.getOperand("
731
- << SourceOperandMap[OpNo].TiedOpIdx << " ).getReg()) &&\n " ;
732
- else
733
- PrintFatalError (" Unexpected tied operand types!" );
734
- }
735
732
for (unsigned SubOp = 0 ; SubOp != SourceOperand.MINumOperands ; ++SubOp) {
736
733
// Check for fixed immediates\registers in the source instruction.
737
734
switch (SourceOperandMap[OpNo].Kind ) {
738
735
case OpData::Operand:
736
+ if (SourceOperandMap[OpNo].OpInfo .TiedOpIdx != -1 ) {
737
+ if (Source.Operands [OpNo].Rec ->isSubClassOf (" RegisterClass" ))
738
+ CondStream.indent (8 ) << " (MI.getOperand(" << OpNo
739
+ << " ).isReg()) && (MI.getOperand("
740
+ << SourceOperandMap[OpNo].OpInfo .TiedOpIdx
741
+ << " ).isReg()) &&\n "
742
+ << indent (8 ) << " (MI.getOperand(" << OpNo
743
+ << " ).getReg() == MI.getOperand("
744
+ << SourceOperandMap[OpNo].OpInfo .TiedOpIdx
745
+ << " ).getReg()) &&\n " ;
746
+ else
747
+ PrintFatalError (" Unexpected tied operand types!" );
748
+ }
749
+
739
750
// We don't need to do anything for source instruction operand checks.
740
751
break ;
741
752
case OpData::Imm:
@@ -773,7 +784,8 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
773
784
774
785
switch (DestOperandMap[OpNo].Kind ) {
775
786
case OpData::Operand: {
776
- unsigned OpIdx = DestOperandMap[OpNo].OpNo ;
787
+ unsigned OpIdx = DestOperandMap[OpNo].OpInfo .Idx ;
788
+ DestRec = DestOperandMap[OpNo].OpInfo .DagRec ;
777
789
// Check that the operand in the Source instruction fits
778
790
// the type for the Dest instruction.
779
791
if (DestRec->isSubClassOf (" RegisterClass" ) ||
@@ -783,7 +795,7 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS,
783
795
: DestRec->getValueAsDef (" RegClass" );
784
796
// This is a register operand. Check the register class.
785
797
// Don't check register class if this is a tied operand, it was done
786
- // for the operand its tied to.
798
+ // for the operand it's tied to.
787
799
if (DestOperand.getTiedRegister () == -1 ) {
788
800
CondStream.indent (8 ) << " MI.getOperand(" << OpIdx << " ).isReg()" ;
789
801
if (EType == EmitterType::CheckCompress)
0 commit comments