@@ -272,48 +272,45 @@ class InlineAsm final : public Value {
272
272
Max = ZT,
273
273
};
274
274
275
- // These are helper methods for dealing with flags in the INLINEASM SDNode
276
- // in the backend.
275
+ // This class is intentionally packed into a 32b value as it is used as a
276
+ // MVT::i32 ConstantSDNode SDValue for SelectionDAG and as immediate operands
277
+ // on INLINEASM and INLINEASM_BR MachineInstr's.
277
278
//
278
279
// The encoding of Flag is currently:
279
- // Bits 2-0 - A Kind::* value indicating the kind of the operand.
280
- // Bits 15-3 - The number of SDNode operands associated with this inline
281
- // assembly operand.
280
+ // Bits 2-0 - A Kind::* value indicating the kind of the operand. (KindField)
281
+ // Bits 15-3 - The number of SDNode operands associated with
282
+ // this inline assembly operand. (NumOperands)
283
+ // Bit 31 - determines if this is a matched operand. (IsMatched)
282
284
// If bit 31 is set:
283
- // Bit 30-16 - The operand number that this operand must match.
284
- // When bits 2-0 are Kind::Mem, the Constraint_* value must be
285
- // obtained from the flags for this operand number.
285
+ // Bits 30-16 - The operand number that this operand must match. (MatchedOperandNo)
286
286
// Else if bits 2-0 are Kind::Mem:
287
- // Bit 30-16 - A Constraint_* value indicating the original constraint
288
- // code.
287
+ // Bits 30-16 - A ConstraintCode:: value indicating the original constraint code. (MemConstraintCode)
289
288
// Else:
290
- // Bit 30-16 - The register class ID to use for the operand.
289
+ // Bits 30-16 - The register class ID to use for the operand. (RegClass)
291
290
//
292
- // Bits 30-16 are called "Data" for lack of a better name. The getter is
293
- // intentionally private; the public methods that rely on that private method
294
- // should be used to check invariants first before accessing Data .
291
+ // As such, MatchedOperandNo, MemConstraintCode, and RegClass are views of
292
+ // the same slice of bits, but are mutually exclusive depending on the
293
+ // fields IsMatched then KindField .
295
294
class Flag {
296
295
uint32_t Storage;
297
296
using KindField = Bitfield::Element<Kind, 0 , 3 , Kind::Func>;
298
297
using NumOperands = Bitfield::Element<unsigned , 3 , 13 >;
299
- using Data = Bitfield::Element<unsigned , 16 , 15 >;
298
+ using MatchedOperandNo = Bitfield::Element<unsigned , 16 , 15 >;
299
+ using MemConstraintCode = Bitfield::Element<ConstraintCode, 16 , 15 , ConstraintCode::Max>;
300
+ using RegClass = Bitfield::Element<unsigned , 16 , 15 >;
300
301
using IsMatched = Bitfield::Element<bool , 31 , 1 >;
301
302
302
- unsigned getData () const { return Bitfield::get<Data>(Storage); }
303
+
304
+ unsigned getMatchedOperandNo () const { return Bitfield::get<MatchedOperandNo>(Storage); }
305
+ unsigned getRegClass () const { return Bitfield::get<RegClass>(Storage); }
303
306
bool isMatched () const { return Bitfield::get<IsMatched>(Storage); }
304
- void setKind (Kind K) { Bitfield::set<KindField>(Storage, K); }
305
- void setNumOperands (unsigned N) { Bitfield::set<NumOperands>(Storage, N); }
306
- void setData (unsigned D) { Bitfield::set<Data>(Storage, D); }
307
- void setIsMatched (bool B) { Bitfield::set<IsMatched>(Storage, B); }
308
307
309
308
public:
310
309
Flag () : Storage(0 ) {}
311
310
explicit Flag (uint32_t F) : Storage(F) {}
312
- Flag (enum Kind K, unsigned NumOps) {
313
- setKind (K);
314
- setNumOperands (NumOps);
315
- setData (0 );
316
- setIsMatched (false );
311
+ Flag (enum Kind K, unsigned NumOps) : Storage(0 ) {
312
+ Bitfield::set<KindField>(Storage, K);
313
+ Bitfield::set<NumOperands>(Storage, NumOps);
317
314
}
318
315
operator uint32_t () { return Storage; }
319
316
Kind getKind () const { return Bitfield::get<KindField>(Storage); }
@@ -356,7 +353,7 @@ class InlineAsm final : public Value {
356
353
bool isUseOperandTiedToDef (unsigned &Idx) const {
357
354
if (!isMatched ())
358
355
return false ;
359
- Idx = getData ();
356
+ Idx = getMatchedOperandNo ();
360
357
return true ;
361
358
}
362
359
@@ -367,28 +364,24 @@ class InlineAsm final : public Value {
367
364
return false ;
368
365
// setRegClass() uses 0 to mean no register class, and otherwise stores
369
366
// RC + 1.
370
- if (!getData ())
367
+ if (!getRegClass ())
371
368
return false ;
372
- RC = getData () - 1 ;
369
+ RC = getRegClass () - 1 ;
373
370
return true ;
374
371
}
375
372
376
373
ConstraintCode getMemoryConstraintID () const {
377
374
assert ((isMemKind () || isFuncKind ()) &&
378
375
" Not expected mem or function flag!" );
379
- uint32_t D = getData ();
380
- assert (D <= static_cast <uint32_t >(ConstraintCode::Max) &&
381
- D >= static_cast <uint32_t >(ConstraintCode::Unknown) &&
382
- " unexpected value for memory constraint" );
383
- return static_cast <ConstraintCode>(D);
376
+ return Bitfield::get<MemConstraintCode>(Storage);
384
377
}
385
378
386
379
// / setMatchingOp - Augment an existing flag with information indicating
387
380
// / that this input operand is tied to a previous output operand.
388
- void setMatchingOp (unsigned MatchedOperandNo ) {
389
- assert (getData () == 0 && " Matching operand already set" );
390
- setData ( MatchedOperandNo);
391
- setIsMatched ( true );
381
+ void setMatchingOp (unsigned OperandNo ) {
382
+ assert (getMatchedOperandNo () == 0 && " Matching operand already set" );
383
+ Bitfield::set< MatchedOperandNo>(Storage, OperandNo );
384
+ Bitfield::set<IsMatched>(Storage, true );
392
385
}
393
386
394
387
// / setRegClass - Augment an existing flag with the required register class
@@ -397,25 +390,23 @@ class InlineAsm final : public Value {
397
390
void setRegClass (unsigned RC) {
398
391
assert (!isImmKind () && " Immediates cannot have a register class" );
399
392
assert (!isMemKind () && " Memory operand cannot have a register class" );
400
- assert (getData () == 0 && " Register class already set" );
393
+ assert (getRegClass () == 0 && " Register class already set" );
401
394
// Store RC + 1, reserve the value 0 to mean 'no register class'.
402
- setData ( RC + 1 );
395
+ Bitfield::set<RegClass>(Storage, RC + 1 );
403
396
}
404
397
405
398
// / setMemConstraint - Augment an existing flag with the constraint code for
406
399
// / a memory constraint.
407
400
void setMemConstraint (ConstraintCode C) {
408
- assert ((isMemKind () || isFuncKind ()) &&
409
- " Flag is not a memory or function constraint!" );
410
- assert (getData () == 0 && " Mem constraint already set" );
411
- setData (static_cast <uint32_t >(C));
401
+ assert (getMemoryConstraintID () == ConstraintCode::Unknown && " Mem constraint already set" );
402
+ Bitfield::set<MemConstraintCode>(Storage, C);
412
403
}
413
404
// / clearMemConstraint - Similar to setMemConstraint(0), but without the
414
405
// / assertion checking that the constraint has not been set previously.
415
406
void clearMemConstraint () {
416
407
assert ((isMemKind () || isFuncKind ()) &&
417
408
" Flag is not a memory or function constraint!" );
418
- setData ( 0 );
409
+ Bitfield::set<MemConstraintCode>(Storage, ConstraintCode::Unknown );
419
410
}
420
411
};
421
412
0 commit comments