// unnecessarily since the GC-ness of the second register is only needed for call instructions.
// The instrDescCGCA struct's member keeping the GC-ness of the first return register is _idcSecondRetRegGCType.
GCtype _idGCref : 2; // GCref operand? (value is a "GCtype")
-#ifdef _TARGET_ARM64_
- GCtype _idGCref2 : 2;
-#endif
// Note that we use the _idReg1 and _idReg2 fields to hold
// the live gcrefReg mask for the call instructions on x86/x64
// x86: 30 bits
// amd64: 38 bits
// arm: 32 bits
- // arm64: 32 bits
+ // arm64: 30 bits
CLANG_FORMAT_COMMENT_ANCHOR;
#if HAS_TINY_DESC
#define ID_EXTRA_BITFIELD_BITS (16)
#elif defined(_TARGET_ARM64_)
-// For Arm64, we have used 18 bits from the second DWORD.
-#define ID_EXTRA_BITFIELD_BITS (18)
+// For Arm64, we have used 16 bits from the second DWORD.
+#define ID_EXTRA_BITFIELD_BITS (16)
#elif defined(_TARGET_XARCH_) && !defined(LEGACY_BACKEND)
// For xarch !LEGACY_BACKEND, we have used 14 bits from the second DWORD.
#define ID_EXTRA_BITFIELD_BITS (14)
// x86: 38 bits // if HAS_TINY_DESC is not defined (which it is)
// amd64: 46 bits
// arm: 48 bits
- // arm64: 50 bits
+ // arm64: 48 bits
CLANG_FORMAT_COMMENT_ANCHOR;
unsigned _idCnsReloc : 1; // LargeCns is an RVA and needs reloc tag
// x86: 40 bits
// amd64: 48 bits
// arm: 50 bits
- // arm64: 52 bits
+ // arm64: 50 bits
CLANG_FORMAT_COMMENT_ANCHOR;
#define ID_EXTRA_BITS (ID_EXTRA_RELOC_BITS + ID_EXTRA_BITFIELD_BITS)
// x86: 24 bits
// amd64: 16 bits
// arm: 14 bits
- // arm64: 12 bits
+ // arm64: 14 bits
unsigned _idSmallCns : ID_BIT_SMALL_CNS;
struct
{
#ifdef _TARGET_ARM64_
+ // For 64-bit architecture this 32-bit structure can pack with these unsigned bit fields
emitLclVarAddr iiaLclVar;
unsigned _idReg3Scaled : 1; // Reg3 is scaled by idOpSize bits
+ GCtype _idGCref2 : 2;
#endif
regNumber _idReg3 : REGNUM_BITS;
regNumber _idReg4 : REGNUM_BITS;
#ifdef _TARGET_ARM64_
GCtype idGCrefReg2() const
{
- return (GCtype)_idGCref2;
+ assert(!idIsTiny());
+ assert(!idIsSmallDsc());
+ return (GCtype)idAddr()->_idGCref2;
}
void idGCrefReg2(GCtype gctype)
{
- _idGCref2 = gctype;
+ assert(!idIsTiny());
+ assert(!idIsSmallDsc());
+ idAddr()->_idGCref2 = gctype;
}
#endif // _TARGET_ARM64_
id->idReg2(reg2);
id->idReg3(reg3);
+ // Record the attribute for the second register in the pair
+ id->idGCrefReg2(GCT_NONE);
if (attrReg2 != EA_UNKNOWN)
{
+ // Record the attribute for the second register in the pair
assert((fmt == IF_LS_3B) || (fmt == IF_LS_3C));
if (EA_IS_GCREF(attrReg2))
{
- /* A special value indicates a GCref pointer value */
-
id->idGCrefReg2(GCT_GCREF);
}
else if (EA_IS_BYREF(attrReg2))
{
- /* A special value indicates a Byref pointer value */
-
id->idGCrefReg2(GCT_BYREF);
}
}
id->idInsFmt(fmt);
id->idInsOpt(INS_OPTS_NONE);
+ // Record the attribute for the second register in the pair
if (EA_IS_GCREF(attr2))
{
- /* A special value indicates a GCref pointer value */
-
id->idGCrefReg2(GCT_GCREF);
}
else if (EA_IS_BYREF(attr2))
{
- /* A special value indicates a Byref pointer value */
-
id->idGCrefReg2(GCT_BYREF);
}
+ else
+ {
+ id->idGCrefReg2(GCT_NONE);
+ }
id->idReg1(reg1);
id->idReg2(reg2);
id->idInsFmt(fmt);
id->idInsOpt(INS_OPTS_NONE);
+ // Record the attribute for the second register in the pair
if (EA_IS_GCREF(attr2))
{
- /* A special value indicates a GCref pointer value */
-
id->idGCrefReg2(GCT_GCREF);
}
else if (EA_IS_BYREF(attr2))
{
- /* A special value indicates a Byref pointer value */
-
id->idGCrefReg2(GCT_BYREF);
}
+ else
+ {
+ id->idGCrefReg2(GCT_NONE);
+ }
id->idReg1(reg1);
id->idReg2(reg2);