@@ -34,7 +34,7 @@ using SectionAddrMap = DenseMap<const MCSection *, uint64_t>;
34
34
// / needed for parsing.
35
35
class MCExpr {
36
36
public:
37
- enum ExprKind {
37
+ enum ExprKind : uint8_t {
38
38
Binary, // /< Binary expressions.
39
39
Constant, // /< Constant expressions.
40
40
SymbolRef, // /< References to labels and assigned expressions.
@@ -43,21 +43,34 @@ class MCExpr {
43
43
};
44
44
45
45
private:
46
+ static const unsigned NumSubclassDataBits = 24 ;
47
+ static_assert (
48
+ NumSubclassDataBits == CHAR_BIT * (sizeof (unsigned ) - sizeof (ExprKind)),
49
+ " ExprKind and SubclassData together should take up one word" );
50
+
46
51
ExprKind Kind;
52
+ // / Field reserved for use by MCExpr subclasses.
53
+ unsigned SubclassData : NumSubclassDataBits;
47
54
SMLoc Loc;
48
55
49
56
bool evaluateAsAbsolute (int64_t &Res, const MCAssembler *Asm,
50
57
const MCAsmLayout *Layout,
51
58
const SectionAddrMap *Addrs, bool InSet) const ;
52
59
53
60
protected:
54
- explicit MCExpr (ExprKind Kind, SMLoc Loc) : Kind(Kind), Loc(Loc) {}
61
+ explicit MCExpr (ExprKind Kind, SMLoc Loc, unsigned SubclassData = 0 )
62
+ : Kind(Kind), SubclassData(SubclassData), Loc(Loc) {
63
+ assert (SubclassData < (1 << NumSubclassDataBits) &&
64
+ " Subclass data too large" );
65
+ }
55
66
56
67
bool evaluateAsRelocatableImpl (MCValue &Res, const MCAssembler *Asm,
57
68
const MCAsmLayout *Layout,
58
69
const MCFixup *Fixup,
59
70
const SectionAddrMap *Addrs, bool InSet) const ;
60
71
72
+ unsigned getSubclassData () const { return SubclassData; }
73
+
61
74
public:
62
75
MCExpr (const MCExpr &) = delete ;
63
76
MCExpr &operator =(const MCExpr &) = delete ;
@@ -130,19 +143,20 @@ inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
130
143
// // Represent a constant integer expression.
131
144
class MCConstantExpr : public MCExpr {
132
145
int64_t Value;
133
- bool PrintInHex = false ;
134
- unsigned SizeInBytes = 0 ;
135
146
136
- explicit MCConstantExpr (int64_t Value)
137
- : MCExpr(MCExpr::Constant, SMLoc()), Value(Value) {}
147
+ // Subclass data stores SizeInBytes in bits 0..7 and PrintInHex in bit 8.
148
+ static const unsigned SizeInBytesBits = 8 ;
149
+ static const unsigned SizeInBytesMask = (1 << SizeInBytesBits) - 1 ;
150
+ static const unsigned PrintInHexBit = 1 << SizeInBytesBits;
138
151
139
- MCConstantExpr (int64_t Value, bool PrintInHex)
140
- : MCExpr(MCExpr::Constant, SMLoc()), Value(Value),
141
- PrintInHex (PrintInHex) {}
152
+ static unsigned encodeSubclassData (bool PrintInHex, unsigned SizeInBytes) {
153
+ assert (SizeInBytes <= sizeof (int64_t ) && " Excessive size" );
154
+ return SizeInBytes | (PrintInHex ? PrintInHexBit : 0 );
155
+ }
142
156
143
157
MCConstantExpr (int64_t Value, bool PrintInHex, unsigned SizeInBytes)
144
- : MCExpr(MCExpr::Constant, SMLoc()), Value(Value), PrintInHex(PrintInHex) ,
145
- SizeInBytes( SizeInBytes) {}
158
+ : MCExpr(MCExpr::Constant, SMLoc(),
159
+ encodeSubclassData (PrintInHex, SizeInBytes)), Value(Value ) {}
146
160
147
161
public:
148
162
// / \name Construction
@@ -157,9 +171,11 @@ class MCConstantExpr : public MCExpr {
157
171
// / @{
158
172
159
173
int64_t getValue () const { return Value; }
160
- unsigned getSizeInBytes () const { return SizeInBytes; }
174
+ unsigned getSizeInBytes () const {
175
+ return getSubclassData () & SizeInBytesMask;
176
+ }
161
177
162
- bool useHexFormat () const { return PrintInHex ; }
178
+ bool useHexFormat () const { return ( getSubclassData () & PrintInHexBit) != 0 ; }
163
179
164
180
// / @}
165
181
@@ -315,17 +331,32 @@ class MCSymbolRefExpr : public MCExpr {
315
331
};
316
332
317
333
private:
318
- // / The symbol reference modifier.
319
- const VariantKind Kind;
334
+ // / The symbol being referenced.
335
+ const MCSymbol *Symbol;
336
+
337
+ // Subclass data stores VariantKind in bits 0..15, UseParensForSymbolVariant
338
+ // in bit 16 and HasSubsectionsViaSymbols in bit 17.
339
+ static const unsigned VariantKindBits = 16 ;
340
+ static const unsigned VariantKindMask = (1 << VariantKindBits) - 1 ;
320
341
321
342
// / Specifies how the variant kind should be printed.
322
- const unsigned UseParensForSymbolVariant : 1 ;
343
+ static const unsigned UseParensForSymbolVariantBit = 1 << VariantKindBits ;
323
344
324
345
// FIXME: Remove this bit.
325
- const unsigned HasSubsectionsViaSymbols : 1 ;
346
+ static const unsigned HasSubsectionsViaSymbolsBit =
347
+ 1 << (VariantKindBits + 1 );
348
+
349
+ static unsigned encodeSubclassData (VariantKind Kind,
350
+ bool UseParensForSymbolVariant,
351
+ bool HasSubsectionsViaSymbols) {
352
+ return (unsigned )Kind |
353
+ (UseParensForSymbolVariant ? UseParensForSymbolVariantBit : 0 ) |
354
+ (HasSubsectionsViaSymbols ? HasSubsectionsViaSymbolsBit : 0 );
355
+ }
326
356
327
- // / The symbol being referenced.
328
- const MCSymbol *Symbol;
357
+ bool useParensForSymbolVariant () const {
358
+ return (getSubclassData () & UseParensForSymbolVariantBit) != 0 ;
359
+ }
329
360
330
361
explicit MCSymbolRefExpr (const MCSymbol *Symbol, VariantKind Kind,
331
362
const MCAsmInfo *MAI, SMLoc Loc = SMLoc());
@@ -349,11 +380,15 @@ class MCSymbolRefExpr : public MCExpr {
349
380
350
381
const MCSymbol &getSymbol () const { return *Symbol; }
351
382
352
- VariantKind getKind () const { return Kind; }
383
+ VariantKind getKind () const {
384
+ return (VariantKind)(getSubclassData () & VariantKindMask);
385
+ }
353
386
354
387
void printVariantKind (raw_ostream &OS) const ;
355
388
356
- bool hasSubsectionsViaSymbols () const { return HasSubsectionsViaSymbols; }
389
+ bool hasSubsectionsViaSymbols () const {
390
+ return (getSubclassData () & HasSubsectionsViaSymbolsBit) != 0 ;
391
+ }
357
392
358
393
// / @}
359
394
// / \name Static Utility Functions
@@ -381,11 +416,10 @@ class MCUnaryExpr : public MCExpr {
381
416
};
382
417
383
418
private:
384
- Opcode Op;
385
419
const MCExpr *Expr;
386
420
387
421
MCUnaryExpr (Opcode Op, const MCExpr *Expr, SMLoc Loc)
388
- : MCExpr(MCExpr::Unary, Loc), Op( Op), Expr(Expr) {}
422
+ : MCExpr(MCExpr::Unary, Loc, Op), Expr(Expr) {}
389
423
390
424
public:
391
425
// / \name Construction
@@ -415,7 +449,7 @@ class MCUnaryExpr : public MCExpr {
415
449
// / @{
416
450
417
451
// / Get the kind of this unary expression.
418
- Opcode getOpcode () const { return Op ; }
452
+ Opcode getOpcode () const { return (Opcode) getSubclassData () ; }
419
453
420
454
// / Get the child of this unary expression.
421
455
const MCExpr *getSubExpr () const { return Expr; }
@@ -457,12 +491,11 @@ class MCBinaryExpr : public MCExpr {
457
491
};
458
492
459
493
private:
460
- Opcode Op;
461
494
const MCExpr *LHS, *RHS;
462
495
463
496
MCBinaryExpr (Opcode Op, const MCExpr *LHS, const MCExpr *RHS,
464
497
SMLoc Loc = SMLoc())
465
- : MCExpr(MCExpr::Binary, Loc), Op( Op), LHS(LHS), RHS(RHS) {}
498
+ : MCExpr(MCExpr::Binary, Loc, Op), LHS(LHS), RHS(RHS) {}
466
499
467
500
public:
468
501
// / \name Construction
@@ -572,7 +605,7 @@ class MCBinaryExpr : public MCExpr {
572
605
// / @{
573
606
574
607
// / Get the kind of this binary expression.
575
- Opcode getOpcode () const { return Op ; }
608
+ Opcode getOpcode () const { return (Opcode) getSubclassData () ; }
576
609
577
610
// / Get the left-hand side expression of the binary operator.
578
611
const MCExpr *getLHS () const { return LHS; }
0 commit comments