@@ -272,48 +272,45 @@ class InlineAsm final : public Value {
272272 Max = ZT,
273273 };
274274
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.
277278 //
278279 // 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)
282284 // 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)
286286 // 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)
289288 // 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)
291290 //
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 .
295294 class Flag {
296295 uint32_t Storage;
297296 using KindField = Bitfield::Element<Kind, 0 , 3 , Kind::Func>;
298297 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 >;
300301 using IsMatched = Bitfield::Element<bool , 31 , 1 >;
301302
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); }
303306 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); }
308307
309308 public:
310309 Flag () : Storage(0 ) {}
311310 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);
317314 }
318315 operator uint32_t () { return Storage; }
319316 Kind getKind () const { return Bitfield::get<KindField>(Storage); }
@@ -356,7 +353,7 @@ class InlineAsm final : public Value {
356353 bool isUseOperandTiedToDef (unsigned &Idx) const {
357354 if (!isMatched ())
358355 return false ;
359- Idx = getData ();
356+ Idx = getMatchedOperandNo ();
360357 return true ;
361358 }
362359
@@ -367,28 +364,24 @@ class InlineAsm final : public Value {
367364 return false ;
368365 // setRegClass() uses 0 to mean no register class, and otherwise stores
369366 // RC + 1.
370- if (!getData ())
367+ if (!getRegClass ())
371368 return false ;
372- RC = getData () - 1 ;
369+ RC = getRegClass () - 1 ;
373370 return true ;
374371 }
375372
376373 ConstraintCode getMemoryConstraintID () const {
377374 assert ((isMemKind () || isFuncKind ()) &&
378375 " 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);
384377 }
385378
386379 // / setMatchingOp - Augment an existing flag with information indicating
387380 // / 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 );
392385 }
393386
394387 // / setRegClass - Augment an existing flag with the required register class
@@ -397,25 +390,23 @@ class InlineAsm final : public Value {
397390 void setRegClass (unsigned RC) {
398391 assert (!isImmKind () && " Immediates cannot have a register class" );
399392 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" );
401394 // Store RC + 1, reserve the value 0 to mean 'no register class'.
402- setData ( RC + 1 );
395+ Bitfield::set<RegClass>(Storage, RC + 1 );
403396 }
404397
405398 // / setMemConstraint - Augment an existing flag with the constraint code for
406399 // / a memory constraint.
407400 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);
412403 }
413404 // / clearMemConstraint - Similar to setMemConstraint(0), but without the
414405 // / assertion checking that the constraint has not been set previously.
415406 void clearMemConstraint () {
416407 assert ((isMemKind () || isFuncKind ()) &&
417408 " Flag is not a memory or function constraint!" );
418- setData ( 0 );
409+ Bitfield::set<MemConstraintCode>(Storage, ConstraintCode::Unknown );
419410 }
420411 };
421412
0 commit comments